3

我遇到了一个奇怪的问题——我有大约 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
4

8 回答 8

6

这可能是因为您保存的 jpeg 图像现在是 24 位 RGB 彩色图像,其中位图是 1 bpp 黑白图像。

如果位图为 1 bpp,则 jpeg 可能不是将它们转换为的最佳格式。

于 2009-05-05T15:45:46.420 回答
5

黑白还是灰度?

来自http://www.faqs.org/faqs/compression-faq/part2/section-6.html

“JPEG 适用于全彩色或灰度图像;它不能处理双层(黑白)图像,至少不是很好。它也不处理彩色映射图像;您必须将它们预先扩展为未映射的图像“

于 2009-05-05T15:59:38.760 回答
4

您需要为编码器设置一个属性来告诉它要使用的压缩级别。

也可以看看

于 2009-05-05T15:43:30.933 回答
2

您将希望切换到使用此重载 Bitmap.Save,因此您可以指定EncoderParameter

至于为什么您的文件越来越大,可能是您的 BMP 是运行长度编码的,或者使用了更小的(不是 24 位)位图。

于 2009-05-05T15:44:23.740 回答
2

2 色 61x64 图像的尺寸比较:

  • Fax-4 tiff:268 字节
  • 2色bmp(如上):550字节
  • 8 位 jpeg:1502 字节
  • 32 位 jpeg(如 System.Drawing 将创建):2015 字节

因此,如果您必须使用 jpeg,请先将它们转换为 8 位。在 .Net 中这样做会很尴尬,但 CodeProject 和其他网站上有示例代码。

于 2009-05-05T18:19:11.450 回答
1

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

所以问题是 JPG 不能很好地处理少色图像。

于 2009-05-07T20:23:19.480 回答
0

在此处查看(如何:设置 JPEG 压缩级别)以获得一些见解和示例,ImageCodecInfo 和 EncoderParameters 是关键

于 2009-05-05T15:44:02.167 回答
0

只是一个想法:您说系统的一部分需要文件是 JPEG 文件。这是真的还是只需要文件具有 JPG 扩展名?如果是这样,您可以 - 尽管它很难看 - 只需重命名文件扩展名,因为您的 BMP 文件更小。

例如在 Windows 中,您可以获取一个 BMP 文件并将其扩展名更改为 JPG,当您打开它时,Windows 不会在意并正确显示它。

于 2009-05-05T18:29:14.407 回答