调整 jpeg 图像大小会影响其压缩吗?
我正在使用 Graphics.DrawImage 方法调整 jpeg 的大小(请参阅下面的代码片段)。 谁能确认这不会影响新图像的压缩? 我已经看到这个线程,但我具体讨论的是压缩jpeg。
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();
}
I'm resizing jpegs by using the Graphics.DrawImage method (see code fragment below). Can anyone confirm that this will not affect the compression of the new image?
I have seen this thread, but I am talking specifically about compression of 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();
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
JPEG 中没有保存“压缩”值。 当您调整大小并保存它们时,它们会被压缩为您告诉保存函数使用的任何值。 由于您没有传递值,因此它将仅使用库的默认值。
JPEGs have no "compression" value saved within them. When you resize and save them, they are compressed with whatever value you tell your save function to use. As you are not passing a value, it will just use whatever default for the library is.
调整图像大小会影响压缩,如果“压缩”指的是可以将多少细节放入多少像素中。
JPEG 压缩算法支持具有渐变和平坦颜色块的模糊或均匀图像。 因此,图像尺寸和生成的文件大小之间没有直接关联。 最重要的是图像中的细节量(所有图像均保存为 JPEG,损失系数为 80%):
原始 SO 徽标:
原始 http://magnetiq.com/exports/sologo/original.jpg
文件大小:4,483 字节
保留尺寸并应用重度高斯模糊:
模糊 http://magnetiq.com/exports/sologo/blurred.jpg
文件大小:1,578 字节
将原始大小调整为 1/4:
缩小了 http://magnetiq.com/exports/sologo/shrunk.jpg
文件大小:2,063 字节
请注意,模糊的图像 (2),尽管它是 4 (3) 的文件大小比 (1) 和 (2) 的文件小。 模糊添加了漂亮的渐变,使 JPEG 压缩更满意。
小图像 (3) 虽然只有原始图像 (1) 的 1/4 像素,但还不到文件大小的 1/4。 这是因为缩小图像会产生更精细的细节,而 JPEG 压缩则不喜欢这样。
Resizing an image effects the compression, if by "compression" you refer to how much detail can be fitted into how many pixels.
The JPEG compression algorithm favors blurry or homogeneous images with gradients and flat patches of colors. Therefore there isn't a direct correlation between image dimensions and the resultant file size. What matters most is the amount of detail in the image (all images were saved as JPEG with 80% loss factor):
The original SO logo:
Original http://magnetiq.com/exports/sologo/original.jpg
File size: 4,483 bytes
Preserve the dimensions and apply a heavy Gaussian blur:
Blurred http://magnetiq.com/exports/sologo/blurred.jpg
File size: 1,578 bytes
Resize the original to 1/4:
Shrunk http://magnetiq.com/exports/sologo/shrunk.jpg
File size: 2,063 bytes
Note that the blurred image (2), even though it's 4 times as large as the shrunk one (3) is tinier in file size than both (1) and (2). Blurring adds nice gradients that make JPEG compression happy.
The small image (3), although it only has 1/4 the pixels that the original has (1), isn't quite 1/4 the file size. This is because shrinking the image results in finer details and JPEG compression doesn't like that.
当您调用“bmpOut.Save”时,您必须传入一些 EncoderParameters 来告诉该方法您想要以什么质量级别保存它。
http://msdn.microsoft .com/en-us/library/system.drawing.imaging.encoderparameters(VS.80).aspx
When you call "bmpOut.Save" you have to pass in some EncoderParameters to tell the method what quality level you would like to save it with.
http://msdn.microsoft.com/en-us/library/system.drawing.imaging.encoderparameters(VS.80).aspx
不要将存储格式 (JPEG) 与使用
Graphics
对象操作的格式混淆。 存储格式是压缩的,Graphics
对象使用解压缩的数据。这
LoadImageFromURL
方法解压缩存储在 JPEG 中的信息,您对解压缩的数据执行调整大小操作,当您将其保存到 JPEG 文件时,它会再次压缩。由于 JPEG 压缩不是无损的,因此每次执行此过程时图片质量都会降低:解压缩、变异、重新压缩。
如果我误解了你的问题:你用于保存图像的压缩因子未在代码中设置,因此它将处于某个默认值。 如果您想通过使用较小的压缩因子进行保存来减少质量损失,则需要显式设置它。
Do not confuse the storage format (JPEG) with the format you operate on using the
Graphics
object. The storage format is compressed, theGraphics
object works with decompressed data.The
LoadImageFromURL
method decompresses the information stored in the JPEG, you perform your resize operation on the decompressed data, and when you save it to a JPEG file, it gets compressed again.Since JPEG compression is not lossless, the picture quality will be reduced every time you perform this process: Decompress, mutate, recompress.
If I missunderstood your question: The compression factor you use for saving the image inot set in your code, so it will be at some default value. If you want to reduce quality loss by saving with a small compression factor, you need to explicitly set it.
在您的代码中,“
HighQualityBicubic
”是您正在使用的压缩。 调整到较小的尺寸确实会删除细节,但这与压缩无关,它只与更少的像素有关。In your code "
HighQualityBicubic
" is the compression you are using. Resizing to a smaller size does remove detail, but that has nothing to do with compression, it just has to do with fewer pixels.JPEG 压缩是有损——并非所有原始数据实际上都被准确存储。 如果将图像压缩为 JPEG 并解压缩,您将无法获得确切的原始图像。 每次压缩和解压缩时,都会损失一点质量。
对于一些简单的转换,例如旋转 JPEG,您可以使用 jpegtran 等程序无损地进行转换。
但是,对于调整图像大小,您无法无损地进行。 当你这样做时,你肯定会稍微降低质量,尽管可能不会太多。 如果可能,请尝试使用原始无损图像作为调整大小操作的源,以获得尽可能高的质量,如果连接多个调整大小操作,则只需对原始图像进行一次调整大小即可。
JPEG compression is lossy -- not all of the original data is actually stored exactly. If you compress an image as a JPEG and decompress it, you won't get back the exact original image. Every time you compress and decompress, you lose a bit of quality.
For some simple transformations, such as rotating a JPEG, you can do it losslessly with programs such as jpegtran.
However, for resizing images, you can't do it losslessly. You're definitely going to degrade the quality somewhat when you do this, although probably not by very much. If possible, try to use original lossless images as the source for the resize operation to get the highest possible quality, and if you concatenate multiple resize operations, instead just do a single resize from the original.
与您已经找到的相同,但这里是 规避 GDI+ 默认图像的 VB.NET 版本压缩。
我个人推荐 JPEG 质量设置为 90L。
Same as what you already found, but here is the VB.NET version from Circumventing GDI+ default image compression.
I personally recommend JPEG quality setting of 90L.