.NET 以与加载时相同的质量保存 jpeg
我有一台大炮数码相机,我将它设置为拍摄超精细质量的照片,它输出一个 3 兆大小的 .jpg 文件。 如果我在 ASP.NET 中像这样加载它(这对于更改它的 dpi 分辨率或裁剪它或其他什么很有用)
imgPicture = Image.FromFile(Config.WorkDirectory + this.TempPhotoName);
bmpPicture = new Bitmap(imgPicture);
,然后我像这样再次保存它:
bmpModified.Save(Config.WorkDirectory + this.TempPhotoName,System.Drawing.Imaging.ImageFormat.Jpeg);
它输出一个大小仅为 700KB 左右的 jpg。 存在质量损失。
我也尝试像这样保存它:
bmpPicture.Save(Config.WorkDirectory + this.TempPhotoName, codecJpeg, encparams);
其中 codecJpeg
ImageCodecInfo codecJpeg = this.getEncoderInfo("image/jpeg");
private ImageCodecInfo getEncoderInfo(string mimeType)
{
// Get image codecs for all image formats
ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders();
// Find the correct image codec
for (int i = 0; i < codecs.Length; i++)
if (codecs[i].MimeType == mimeType)
return codecs[i];
return null;
}
和 encparams:
EncoderParameters encparams = new EncoderParameters(1);
encparams.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 97L);
这样可以保持大小(并且我怀疑质量),但我手动输入质量。
我想问:
有没有办法在不硬编码质量值的情况下以与加载时相同的质量保存图像?
先感谢您
I have a cannon digital camera and I set it to take pictures with superfine quality and it outputs a .jpg file 3 mega in size.
If I load it like this in ASP.NET(this is useful to change it's dpi resolution or crop it or whaterver)
imgPicture = Image.FromFile(Config.WorkDirectory + this.TempPhotoName);
bmpPicture = new Bitmap(imgPicture);
and then I save it again like this:
bmpModified.Save(Config.WorkDirectory + this.TempPhotoName,System.Drawing.Imaging.ImageFormat.Jpeg);
it outputs a jpg that is only 700KB or so in size. There is a loss of quality.
I also tried saving it like this:
bmpPicture.Save(Config.WorkDirectory + this.TempPhotoName, codecJpeg, encparams);
where codecJpeg is
ImageCodecInfo codecJpeg = this.getEncoderInfo("image/jpeg");
private ImageCodecInfo getEncoderInfo(string mimeType)
{
// Get image codecs for all image formats
ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders();
// Find the correct image codec
for (int i = 0; i < codecs.Length; i++)
if (codecs[i].MimeType == mimeType)
return codecs[i];
return null;
}
and encparams:
EncoderParameters encparams = new EncoderParameters(1);
encparams.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 97L);
This way the size(and I suspect also the quality) is maintained but I am inputing the quality by hand.
I want to ask:
Is there a way to save the image with the same quality as it was loaded without hardcoding the quality value?
Thank you in advance
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
所以听起来你知道如何设置质量,你真的只需要知道如何从原始图像中获取质量?
我怀疑
Image.PropertyItems
是你的朋友,如果质量首先体现在元数据中。 (我不知道 JPEG 编码器中是否有质量标准。)编辑:我刚刚检查过,我下载的 jpeg 没有任何质量标签。
一种选择可能是计算出文件应该有多大才能具有大致相同的质量,然后保存多次,进行二分搜索以找出最合适的质量。 恶心,但它可能会起作用。
我有一种偷偷的怀疑,没有一种方法可以只保留原始的质量设置,尽管我没有很好的理由来支持这种怀疑......
So it sounds like you know how to set the quality, you really just need to know how to fetch the quality from the original image?
I suspect that
Image.PropertyItems
is your friend, if the quality is in the metadata to start with. (I don't know if there's even a standard scale for quality within JPEG encoders.)EDIT: I've just checked, and a jpeg I downloaded didn't have any tags for quality.
One option might be to work out how big the file should end up to have roughly the same quality, and then save it several times, doing a binary search to work out the most appropriate quality. Icky, but it might just work.
I have a sneaking suspicion that there isn't a way to just preserve the original quality setting, although I don't have very good grounds for that suspicion...
请阅读此处如何保存图像而不重新编码图像: 操作方法:使用元数据重新编码 JPEG 图像。
但是,如果您进行裁剪或其他图像处理,则不可能在没有质量损失的情况下做到这一点(从技术上讲,如果您使用乘以 16 的边界,则可以进行无损裁剪,但据我所知,这是无法通过库完成的在 .net 中可用)。
Read here how to save image without re-encoding image: How-to: Re-encode a JPEG Image with Metadata.
However, if you do cropping or another image manipulation it impossible to do it without quality loss (well technically it is possible to do loss-less crop, if you work with boundaries that multiply of 16, but AFAIK it is cannot be done with libraries available in .net).
您必须使用告诉 GDI+ 检测颜色方案的附加参数。
例如:
You must use the additional parameters which tell GDI+ to detect the color scheme.
For instance: