减少jpeg文件的字节大小

时间:2014-05-29 05:42:30

标签: c# image-processing

使用C#。

我有一个jpeg。

当我将其加载到位图对象时,其pixelformat是Format24bppRgb。

如果我'转换'格式为16bppRgb565的位图文件的字节大小较大。

我认为通过减少像素格式,我会减小文件的大小。实际上这样做已经在文件中重新实现了实际增加的大小。

这个期望是否存在根本错误?

这是我的代码(这只是一个快速的解决方法)......

// imgConverted是24bpp

Bitmap bmp24bit = imgConverted.Clone(new Rectangle(0, 0, img.Width, img.Height), PixelFormat.Format16bppRgb565);

这是我用来将位图转换为字节数组以比较字节大小的代码:

    private byte[] ImageToByteArray(System.Drawing.Image imageIn)
    {
        byte[] data = null;
        try
        {
            using (MemoryStream ms = new MemoryStream())
            {
                imageIn.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
                imageIn.Dispose();
                data = ms.ToArray();
            }
        }
        catch (Exception ex)
        {

        }
        finally
        {
            if (imageIn != null)
            {
                imageIn.Dispose();
            }
        }
        return data;
    }

1 个答案:

答案 0 :(得分:6)

PixelFormat枚举涉及当图像数据处于未压缩位图格式时(例如,加载图像文件时计算机内存中)每个像素占用的位数。像JPEG和PNG这样的文件格式没有类似的每像素位的概念,因为它们的压缩格式不必将每个像素存储在磁盘上24位的空间中。

另外,JPEG总是使用24位来存储颜色信息(在存储颜色的程度上,JPEG算法实际上非常复杂),并且PNG至少支持索引颜色,24位RGB和32位ARGB颜色深度。 PNG也支持48位颜色深度。

返回主题:您看到JPEG文件大小增加,因为JPEG是一种有损算法,具有引入压缩伪像的副作用。将原始照片保存为高度压缩的JPEG图像会导致信息丢失,这些假象实际上会为图像添加(不需要的)新细节,因此在重新保存这些新文物时,您需要增加数量"信息"需要存储,因此文件大小增加的原因。这也会导致图像在每次重新保存时逐渐失去质量 - 因为现在应该用来表示原始图像的压缩位被浪费来表示先前重新引入的人工制品。编码JPEG图像。

(有一些方法可以无损地重新保存JPEG图像而无需再次运行JPEG算法,但大多数图像编辑器和GDI都支持它们,搜索" jpegtrans"和#34; jpegcrop&# 34;更多信息)。

如果要减小JPEG图像的文件大小,请使用" JPEG质量"参数,这是JPEG算法独有的一个特殊功能,它允许主观"质量"待修改:

此处记录了这些内容:http://msdn.microsoft.com/en-us/library/bb882583(v=vs.110).aspx

复制&粘贴:

private void VaryQualityLevel()
{
// Get a bitmap.
Bitmap bmp1 = new Bitmap(@"c:\TestPhoto.jpg");
ImageCodecInfo jgpEncoder = GetEncoder(ImageFormat.Jpeg);

// Create an Encoder object based on the GUID 
// for the Quality parameter category.
System.Drawing.Imaging.Encoder myEncoder =
    System.Drawing.Imaging.Encoder.Quality;

// Create an EncoderParameters object. 
// An EncoderParameters object has an array of EncoderParameter 
// objects. In this case, there is only one 
// EncoderParameter object in the array.
EncoderParameters myEncoderParameters = new EncoderParameters(1);

EncoderParameter myEncoderParameter = new EncoderParameter(myEncoder, 50L);
myEncoderParameters.Param[0] = myEncoderParameter;
bmp1.Save(@"c:\TestPhotoQualityFifty.jpg", jgpEncoder, myEncoderParameters);

myEncoderParameter = new EncoderParameter(myEncoder, 100L);
myEncoderParameters.Param[0] = myEncoderParameter;
bmp1.Save(@"c:\TestPhotoQualityHundred.jpg", jgpEncoder, myEncoderParameters);

// Save the bitmap as a JPG file with zero quality level compression.
myEncoderParameter = new EncoderParameter(myEncoder, 0L);
myEncoderParameters.Param[0] = myEncoderParameter;
bmp1.Save(@"c:\TestPhotoQualityZero.jpg", jgpEncoder, myEncoderParameters);

}


private ImageCodecInfo GetEncoder(ImageFormat format)
{

ImageCodecInfo[] codecs = ImageCodecInfo.GetImageDecoders();

foreach (ImageCodecInfo codec in codecs)
{
    if (codec.FormatID == format.Guid)
    {
        return codec;
    }
}
return null;
}
相关问题