代码之家  ›  专栏  ›  技术社区  ›  contactmatt

使用.NET图像转换是否足够?

  •  5
  • contactmatt  · 技术社区  · 16 年前

    我见过很多人试图用自己的图像转换技术来编码。它通常看起来非常复杂,最后使用gdi+函数调用和操作图像的位。这让我想知道,在保存图像时,是否在.NET的图像转换调用的简单性中缺少了一些东西。这是我的代码:

    Bitmap tempBmp = new Bitmap("c:\temp\img.jpg");
    Bitmap bmp = new Bitmap(tempBmp, 800, 600);
    bmp.Save(c:\temp\img.bmp, //extension depends on format
        ImageFormat.Bmp) //These are all the ImageFormats I allow conversion to within the program.  Ignore the syntax for a second ;) 
        ImageFormat.Gif) //or 
        ImageFormat.Jpeg) //or
        ImageFormat.Png) //or
        ImageFormat.Tiff) //or
        ImageFormat.Wmf) //or
        ImageFormat.Bmp)//or
        );
    

    这就是我在图像转换中所做的一切。只需设置保存图像的位置,并将图像格式类型传递给它。我已经尽我所能地测试了它,但是我想知道在这个简单的格式转换中我是否遗漏了什么,或者这是否足够?

    3 回复  |  直到 16 年前
        1
  •  5
  •   harpo Binary Worrier    16 年前

    System.Drawing.Imaging 如果传入jpeg编解码器并为质量设置编码器参数(本质上是保留百分比),则会对图像压缩提供额外的控制。

    这是一个与参数一起使用的函数 "image/jpeg" 获取jpeg编解码器。(这与压缩无关 本身 但是 Image.Save 接受的重载 EncoderParameters 要求 ImageCodecInfo 而不是 ImageFormat )

    //  assumes an encoder for "image/jpeg" will be available.
    public static ImageCodecInfo GetCodec( string mimeType )
    { 
        ImageCodecInfo[] encoders = ImageCodecInfo.GetImageEncoders(); 
    
        for( int i = 0;  i < encoders.Length;  i++ )
            if( encoders[i].MimeType == mimeType )
                return encoders[i];
    
        return null; 
    }
    

    然后可以在保存图像之前设置编码器参数。

    EncoderParameters ep = new EncoderParameters(2);
    ep.Param[0] = new EncoderParameter( Encoder.Quality,    percentRetention ); // 1-100
    ep.Param[1] = new EncoderParameter( Encoder.ColorDepth, colorDepth ); // e.g. 24L
    

    (还有其他编码器参数-请参阅文档。

    所以,把它们放在一起,你可以说

    image.Save( outFile, GetCodec("image/jpeg"), ep );
    

    (我将编解码器和参数存储在静态值中,因为它们被反复使用,但我想简化这里的示例。)

    希望这有帮助!

    编辑: 如果要缩放图像,还可以对质量进行一些控制。是的,这是一个“黑匣子”,但我发现它工作得很好。以下是“好”和“慢”设置(在调用DrawImage之前需要进行设置,但您可以查找“快”和“脏”版本。

    // good & slow
    graphics.SmoothingMode      = SmoothingMode.HighQuality;
    graphics.InterpolationMode  = InterpolationMode.HighQualityBicubic;
    graphics.PixelOffsetMode    = PixelOffsetMode.HighQuality;
    graphics.CompositingQuality = CompositingQuality.HighQuality;
    
        2
  •  0
  •   Steav    16 年前

    我认为通过传递imageformat.net可以为您进行与imageformat相关联的压缩。

    但是,当涉及到图形压缩时,可能会有更多(请参阅Photoshop或图形程序另存为对话框作为示例)。

    例如,jpeg只是一个标准…对于很多网络图形,你仍然可以通过模糊或去掉更多的颜色来缩小尺寸,而不会造成明显的质量损失。

    将取决于你将使用哪种技术,或者你是否符合标准。

        3
  •  0
  •   Sky Sanders    16 年前

    你所做的工作是可行的,但目前为止不是最有效的,也不是最经济的文件大小。

    在处理图像时,您看到复杂GDI代码的原因是,在使用默认的“一刀切”所有方法和甚至最适度的微调之间没有合理的中间地带。

    .NET<->gdi interop在黑色魔术的边界上,隐藏的bug比比皆是。幸运的是,谷歌拥有你在这个雷区导航所需的一切。

    (我画的画够脏了吗?;(-))

    不过,说真的,您可以很好地使用gdi interop,但这绝对不是一个显而易见的任务。如果你愿意做这项研究,花时间去解决这些问题,你最终会得到一些好的代码。

    否则,找一个能为你完成大部分工作的图像库。

    推荐文章