为什么使用System.Drawing创建的JPEG图像比原始位图大?

时间:2009-05-05 15:39:32

标签: .net image-processing image-manipulation system.drawing

我遇到了一个奇怪的问题 - 我有大约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”代码。

图像是黑白的,没有颜色。

有关为何会发生这种情况的任何想法?寻找正确方向的指针......

编辑:

  • 我尝试使用备用重载进行保存,以便您指定质量。没有看到任何好处。
  • 我还应该指明我在某种程度上坚持使用JPEG。这是一个遗留系统,系统的其他部分需要JPEG。

图片属性:

  • 位图尺寸:152x48
  • 位图文件大小:1022字节
  • JPEG:相同维度
  • JPEG尺寸:2.2 kb
  • 位图信息:索引,1层(2种颜色)
  • 位图分辨率:96.012x 96.012 ppi

9 个答案:

答案 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图像的尺寸:

  • 传真-4 tiff:268字节
  • 2色bmp(如上所述):550字节
  • 8位jpeg:1502字节
  • 32位jpeg(作为System.Drawing会 创建):2015字节

因此,如果必须使用jpegs,请先将它们转换为8位。在.Net中执行此操作会很尴尬,但CodeProject和其他人可以使用示例代码。

答案 5 :(得分:1)

我想跟进我的解决方案。我能够让系统的其余部分支持PNG格式的图形,所以我所做的是将位图转换为PNG图形,并使它们每像素1位黑白。这使它们小而有效。

所以问题是JPG只是不能很好地制作几种颜色的图像。

答案 6 :(得分:0)

答案 7 :(得分:0)

只是想一想:你说系统的一部分需要文件是JPEG文件。这是真的还是只需要文件才能拥有JPG扩展名? 如果是这样,你可以 - 虽然它很难看 - 只需重命名文件扩展名,因为你的案例中的BMP文件较小。

例如,在Windows中,您可以获取BMP文件并将其扩展名更改为JPG,当您打开它时,Windows无需关心并正确显示它。

答案 8 :(得分:-1)

这篇kb文章应该告诉你如何做到这一点

http://support.microsoft.com/kb/324790