我正在使用Graphics.DrawImage方法调整jpegs的大小(请参阅下面的代码片段)。任何人都可以确认这不会影响新图像的压缩吗? 我见过this thread,但我特别谈到压缩jpegs。
private byte[] getResizedImage(String url, int newWidth)
{
Bitmap bmpOut = null;
System.IO.MemoryStream outStream = new System.IO.MemoryStream();
//input image is disposable
using (Bitmap inputImage = LoadImageFromURL(url))
{
ImageFormat format = inputImage.RawFormat;
decimal ratio; //ratio old width:new width
int newHeight = 0;
//*** If the image is smaller than a thumbnail just return it
if (inputImage.Width < newWidth)
return null;
ratio = (decimal)newWidth / inputImage.Width;
decimal h = inputImage.Height * ratio;
newHeight = (int)h;
bmpOut = new Bitmap(newWidth, newHeight);
Graphics g = Graphics.FromImage(bmpOut);
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
// try testing with following options:
//g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
//g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
//g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
//g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
g.FillRectangle(Brushes.White, 0, 0, newWidth, newHeight);
g.DrawImage(inputImage, 0, 0, newWidth, newHeight);
bmpOut.Save(outStream, getImageFormat(url));
}
return outStream.ToArray();
}
答案 0 :(得分:6)
JPEG中没有保存“压缩”值。当您调整大小并保存它们时,它们会使用您告诉保存函数使用的任何值进行压缩。由于您没有传递值,它只会使用库的默认值。
答案 1 :(得分:4)
调整图像大小会影响压缩,如果通过“压缩”指的是可以将多少细节拟合到多少像素中。
JPEG压缩算法支持具有渐变和平面色块的模糊或均匀图像。因此,图像尺寸与结果文件大小之间没有直接关联。最重要的是图像中的细节数量(所有图像都保存为JPEG,丢失率为80%):
最初的SO徽标:
Original http://magnetiq.com/exports/sologo/original.jpg
File size: 4,483 bytes
保留尺寸并应用重高斯模糊:
Blurred http://magnetiq.com/exports/sologo/blurred.jpg
File size: 1,578 bytes
将原稿调整为1/4:
Shrunk http://magnetiq.com/exports/sologo/shrunk.jpg
File size: 2,063 bytes
注意,模糊图像(2),即使它是缩小的图像(3)的4倍,文件大小比(1)和(2)都小。模糊添加了漂亮的渐变,使JPEG压缩感到愉快。
小图像(3)虽然只有原始图像(1)的1/4,但不是文件大小的1/4。这是因为缩小图像会产生更精细的细节,而JPEG压缩则不会那样。
答案 2 :(得分:3)
当您调用“bmpOut.Save”时,您必须传入一些EncoderParameters来告诉方法您希望保存它的质量级别。
http://msdn.microsoft.com/en-us/library/system.drawing.imaging.encoderparameters(VS.80).aspx
答案 3 :(得分:0)
在您的代码中,“HighQualityBicubic
”是您正在使用的压缩。调整为较小的尺寸会删除细节,但这与压缩无关,只需要更少的像素。
答案 4 :(得分:0)
JPEG压缩是lossy - 并非所有原始数据都是精确存储的。如果将图像压缩为JPEG并对其进行解压缩,则无法获得准确的原始图像。每次压缩和解压缩时,都会失去一点质量。
对于一些简单的转换,例如旋转JPEG,您可以使用jpegtran等程序无损地进行转换。
但是,要调整图像大小,您无法无损地执行此操作。当你这样做时,你肯定会降低质量,尽管可能不是很多。如果可能,尝试使用原始无损图像作为调整大小操作的源以获得尽可能高的质量,如果连接多个调整大小操作,而只是从原始操作中执行单个调整大小。
答案 5 :(得分:0)
请勿将存储格式(JPEG)与使用Graphics
对象操作的格式混淆。压缩存储格式,Graphics
对象与解压缩数据一起使用。
在
LoadImageFromURL
方法解压缩存储在JPEG中的信息,对解压缩的数据执行调整大小操作,当您将其保存为JPEG文件时,会再次压缩。
由于JPEG压缩不是无损的,因此每次执行此过程时图像质量都会降低:解压缩,变异,重新压缩。
如果我错过了您的问题:用于保存代码中设置的图像的压缩因子,因此它将处于某个默认值。如果您希望通过使用较小的压缩因子进行保存来降低质量损失,则需要明确设置它。
答案 6 :(得分:0)
与您已经找到的相同,但这是来自Circumventing GDI+ default image compression的VB.NET版本。
我个人建议将JPEG质量设置为90L。