And*_*son 0 c# image-processing
使用C#.
我有一个jpeg.
当我将其加载到位图对象时,其pixelformat是Format24bppRgb.
如果我将位图"转换"为Format16bppRgb565,则文件的字节大小会更大.
我认为通过减少pixelformat我会减小文件的大小.实际上这样做已经在文件中重新实现了实际增加的大小.
在这个期望中,这是一个根本错误吗?
这是我的代码(这只是一个快速的解决方法)......
// imgConverted是24bpp
Bitmap bmp24bit = imgConverted.Clone(new Rectangle(0, 0, img.Width, img.Height), PixelFormat.Format16bppRgb565);
Run Code Online (Sandbox Code Playgroud)
这是我用来将位图转换为字节数组以比较我的字节大小的代码:
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;
}
Run Code Online (Sandbox Code Playgroud)
该PixelFormat
枚举涉及每个像素在图像数据是未压缩的位图形式多少位占用(如内存您的计算机上,当您加载图像文件).像JPEG和PNG这样的文件格式没有类似的每像素位的概念,因为它们是压缩格式,不一定将每个像素存储在磁盘上的24位空间中.
另外,JPEG总是使用24位来存储颜色信息(在存储颜色的程度上,JPEG的算法实际上非常复杂),并且PNG至少支持索引颜色,24位RGB和32位ARGB颜色深度.PNG也支持48位颜色深度.
回到主题:您看到JPEG文件大小增加,因为JPEG是一种有损算法,具有引入压缩伪像的副作用.将原始照片保存为高度压缩的JPEG图像会导致信息丢失,这些假象实际上会为图像添加(不需要的)新细节,因此在重新保存这些新文物时,您需要增加需要的"信息"数量.存储,因此文件大小增加的原因.这也会导致图像在每次重新保存时逐渐失去质量 - 因为现在应该用来表示原始图像的压缩位被浪费来表示先前重新编码JPEG所引入的伪像图片.
(有些方法可以无损地重新保存JPEG图像而无需再次运行JPEG算法,但大多数图像编辑器和GDI都支持它们,搜索"jpegtrans"和"jpegcrop"以获取更多信息).
如果要减小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;
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
5757 次 |
最近记录: |