我遇到了一个奇怪的问题 - 我有大约1450万个位图图像,据说是未压缩的。我需要将这些位图转换为JPG并将它们存储在数据库中。
当我使用.NET System.Drawing库中提供的类将位图保存为ImageFormat.Jpeg时,生成的JPEG大约是两倍原始位图的大小。这是代码:
byte[] bitmapBytes = //get from the db
using(MemoryStream bitmapStream = new MemoryStream(bitmapBytes))
{
using(Bitmap bitmap = (Bitmap)Bitmap.FromStream(bitmapStream))
{
bitmap.Save("jpg.jpg", ImageFormat.Jpeg);
}
}
我查看了其中几个图像的HEX,看起来压缩设置为“无”。所以我假设他们没有压缩。此外,原始文件的HEX具有“BMP”代码,结果文件具有您期望的“JFIF”代码。
图像是黑白的,没有颜色。
有关为何会发生这种情况的任何想法?寻找正确方向的指针......
编辑:
图片属性:
答案 0 :(得分:6)
这可能是因为您保存的jpeg图像现在是24位RGB彩色图像,其中位图是1 bpp黑白图像。
如果位图是1 bpp,jpeg可能不是将它们转换为的最佳格式。
答案 1 :(得分:5)
黑白或灰度?
来自http://www.faqs.org/faqs/compression-faq/part2/section-6.html:
“JPEG适用于全彩色或灰度图像;它无法处理 双层(黑白)图像,至少不太好。它无法处理 彩色图像图像;你必须预先将它们扩展为未映射的 全彩色表示。 JPEG在“连续色调”图像上效果最佳。 突然跳跃颜色值的图像不能很好地压缩。“
答案 2 :(得分:4)
您需要为编码器设置一个属性,以告诉它要使用的压缩级别。
另见
答案 3 :(得分:2)
您需要切换为使用this overload of Bitmap.Save,以便指定EncoderParameter。
至于为什么你的文件越来越大,可能是你的BMP运行长度编码,或使用较小的(不是24位)位图。
答案 4 :(得分:2)
比较2色61x64图像的尺寸:
因此,如果必须使用jpegs,请先将它们转换为8位。在.Net中执行此操作会很尴尬,但CodeProject和其他人可以使用示例代码。
答案 5 :(得分:1)
我想跟进我的解决方案。我能够让系统的其余部分支持PNG格式的图形,所以我所做的是将位图转换为PNG图形,并使它们每像素1位黑白。这使它们小而有效。
所以问题是JPG只是不能很好地制作几种颜色的图像。
答案 6 :(得分:0)
Check out here (How to: Set JPEG Compression Level) for some insight and examples,ImageCodecInfo和EncoderParameters是键
答案 7 :(得分:0)
只是想一想:你说系统的一部分需要文件是JPEG文件。这是真的还是只需要文件才能拥有JPG扩展名? 如果是这样,你可以 - 虽然它很难看 - 只需重命名文件扩展名,因为你的案例中的BMP文件较小。
例如,在Windows中,您可以获取BMP文件并将其扩展名更改为JPG,当您打开它时,Windows无需关心并正确显示它。
答案 8 :(得分:-1)
这篇kb文章应该告诉你如何做到这一点