delphi - 将 Jpeg 图像转换为 Bmp - 某些图像显示为蓝色

标签 delphi image-processing graphics jpeg

Delphi 似乎不喜欢一些 Jpg 图像。它似乎与我正在加载的文件有关。过程很简单 - a) 将 Jpg 图像加载到 TJpegImage,b) 将 Jpg 对象分配给 TBitmap 对象,以及 c) 保存和/或显示 Bmp 图像。由于某种原因,这些图片总是带有蓝色色调。

这些图像可以在我加载它们的任何地方完美显示(Windows 图片查看器、绘画、Photoshop 等)。

我正在做的事情非常简单......

procedure Load;
var
  J: TJpegImage;
  B: TBitmap;
begin
  J:= TJpegImage.Create;
  B:= TBitmap.Create;
  J.LoadFromFile('C:\SomeFile.jpg');
  B.Assign(J);
  //Either save or display `B` and it appears blueish at this point
....

我想尽可能避免获得任何第三方的东西。这个问题在Delphi 7、2010、XE2版本中都存在。至少 XE2 中的 TImage 控件可以正确显示它(与旧的两个控件相反),但如果 TBitmap 仍然不起作用,那也没关系。这个文件有什么问题吗?和/或,Delphi 的渲染有什么问题?

添加信息

我最近发现了一些关于这些图像的信息。当它们来自供应商时(产品图片),它们是 CMYK 格式。当时,Delphi 7 无法正确支持这些文件(存在访问冲突和不良图像),因此所有图片都通过转换器过滤为 RGB 颜色格式。许多原始图像也是 TIFF,并转换为 JPG。因此,FastStone Image Resizer 软件在浏览这些文件时似乎无法正确保存它们。蓝色图像并非全部出现,只是一次随机出现一些批处理。该软件可处理数千种产品,因此有数千种可能的图片。

最佳答案

你的文件是蓝色的原因是编码是 BGR 而不是 RGB。
如果您修改 jpeg.pas 源文件并使用像素交换(删除 TJPEGImage.GetBitmap 中的 {.$IFDEF JPEGSO}),您'将看到您的示例文件正确为棕色。

所以,我想底线是库存 jpeg 源没有检测到正确的(反向)编码;可能在jc.d.out_color_space...

更新:
C 源文件(和 jpeg.pas)应声明(并使用)带有新扩展 JCS_EXT_...的颜色空间:

enum J_COLOR_SPACE {
  JCS_UNKNOWN, JCS_GRAYSCALE, JCS_RGB, JCS_YCbCr,
  JCS_CMYK, JCS_YCCK, JCS_EXT_RGB, JCS_EXT_RGBX,
  JCS_EXT_BGR, JCS_EXT_BGRX, JCS_EXT_XBGR, JCS_EXT_XRGB
}

更新2:
jpeg.pas 可以在 C:...\RAD Studio\8.0\source\vcl 中找到 (XE),C 文件位于 jpg 子文件夹。

如果您准备好打赌所有具有 RGB 色彩空间的 Adob​​e 文件都需要交换其位,您可以轻松破解 jpeg.pas 源来检测您的特殊文件,并有条件地执行上面提到的交换 TJPEGImage.GetBitmap

{.$IFDEF JPEGSO}
          if (jc.c.in_color_space=JCS_RGB)and
            (smallint(jc.c.jpeg_color_space)=Ord(JCS_UNKNOWN))and   //comes 1072693248 = $3FF00000 = 111111111100000000000000000000
            jc.d.saw_Adobe_marker  and
            (PixelFormat = jf24bit) then
          begin

关于delphi - 将 Jpeg 图像转换为 Bmp - 某些图像显示为蓝色,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8915466/

相关文章:

performance - Windows 7 中的 explorer.exe 和 dwm.exe 问题

c++ - Qt 中屏幕绘制和键盘按键事件的精确延迟

java - FireMonkey Android - JAR对象的处理回调消息(JHandle)

image - 写入超过 256 个标签的图像

delphi - 如何运行项目组中的所有项目?

java - AffineTransform 截断图像

machine-learning - 根据相似度对图像进行聚类

delphi - TPaintBox 到 JPEG/BMP - 缓冲区

delphi - 使用 FastMM 和退出代码检测内存泄漏

delphi - 使用 Delphi 在 cmd 中运行多个命令