Jer*_*dge 10 delphi graphics jpeg image-processing
Delphi似乎不喜欢一些Jpg图像.它似乎特定于我正在加载的文件.并且过程很简单 - a)将Jpg图像加载到TJpegImage
,b)将Jpg对象分配给TBitmap
对象,以及c)保存和/或显示Bmp图像.出于某种原因,这些图片不断出现蓝色调.
这些图像完美地展示了我装载它们的任何地方和任何地方(windows picture viewer,paint,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
....
Run Code Online (Sandbox Code Playgroud)
我想尽可能避免收到任何第三方的东西.Delphi版本7,2010和XE2中存在此问题.至少XE2中的TImage控件正确显示它(而不是旧的两个),但是如果TBitmap仍然不起作用则无关紧要.这个文件有什么问题?和/或,Delphi的渲染有什么问题?
添加了信息
我最近发现了一些关于这些图像的东西.当他们来自供应商(产品图片)时,他们采用CMYK格式.那时,Delphi 7没有正确支持这些文件(具有访问冲突和坏图像),因此所有图片都通过转换器过滤为RGB颜色格式.许多原始图像也是TIFF并转换为JPG.因此,软件似乎FastStone Image Resizer
无法正常保存这些文件.所有这些都不会发生蓝色图像,一次只能进行一些随机批次.该软件处理数千种产品,因此有数千种可能的图片.
Fra*_*ois 11
你的文件是蓝色的原因是因为编码是BGR而不是RGB.
如果修改了jpeg.pas
源文件,并使用像素交换(除去{.$IFDEF JPEGSO}
中TJPEGImage.GetBitmap
),你会看到你的示例文件正确褐色.
所以,我想底线是股票jpeg源没有检测到正确的(反向)编码; 可能在jc.d.out_color_space
......
更新:
C源文件(和jpeg.pas)应该使用新扩展JCS_EXT _...声明(并使用)Color Spaces:
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
}
Run Code Online (Sandbox Code Playgroud)
更新2:
jpeg.pas
可以C:...\RAD Studio\8.0\source\vcl
在jpg
子文件夹中的C文件中找到(XE).
如果您准备打赌所有具有RGB色彩空间的Adobe文件需要交换它们的位,您可以轻松地破解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
Run Code Online (Sandbox Code Playgroud)
WIC(适用于XP及以上版本)可以处理此图像.这个组件很好地包含在Delphi 2010及更高版本中.对于早期的Delphi版本,使用COM接口调用WIC很容易.
这是我的概念证明代码:
var
Image: TWICImage;
Bitmap: TBitmap;
begin
Image := TWICImage.Create;
Image.LoadFromFile('C:\desktop\ABrownImage.jpg');
Bitmap := TBitmap.Create;
Bitmap.Assign(Image);
Bitmap.SaveToFile('C:\desktop\ABrownImage.bmp');
end;
Run Code Online (Sandbox Code Playgroud)
注1:WIC随Vista一起提供,但必须为XP重新分发.一个明显的选择是使用WIC(如果可用),但是否则返回Delphi JPEG解码器.
注2:我找不到WIC的可重新分发包.我怀疑它可能需要最终用户下载XP.这就是说,如果绝大多数XP机器现在安装它,我都不会感到惊讶.
我想出了这个问题.它很可能是Delphi中的一个错误.
提供的图像是一种称为Adobe JPEG的JPEG文件的特殊格式.关于Adobe JPEG最奇怪的可能是它允许以RGB格式存储图像,尽管它也允许其他格式.大多数JPEG是JFIF或EXIF格式,不使用RGB.
当复制RGB数据时,无论Delphi做什么,它都会在将红色和蓝色数据加载到画布上时将其反转.它将其加载为BGR而不是RGB.这可能是因为Windows(24位和32位)DIB(BMP)以BGR格式存储.
我猜这个bug会出现在任何RGB JPEG的Delphi中.由于大多数JPEG不使用RGB,因此bug的发生率很低.如果您有JPEG单元的源,那么轻松修复是在加载RGB JPEG时反转顺序.
如果您没有源,请继续.
Adobe JPEG 43 11 00 47 11 00 42 11 00
以十六进制编辑器中的这种格式(十六进制)指定颜色的顺序R..G..B
.如果您通过十六进制编辑器反转R
并B
在此处,它在Windows中显示错误,在Delphi中显示错误.
为了识别一个Adobe JPEG,前四个字节或者是(在己烷中)FF D8 FF ED
或FF D8 FF EE
与ED
和EE
被微分字节.所有JPEG文件都以FF D8 FF
.
在这些字节之后是两个字节,表示类型标记的长度,然后是(在ASCII中)Adobe
,接着是六个字节(表示版本等),最后,(第18个字节)是指定格式的字节.0
意味着RGB.因此,检查那些重要的字节,然后相应地采取行动.
你必须反转文件头中的RGB顺序(骗到Delphi),或者将它复制到TBitmap并使用ScanLine将RGB反转到正确的顺序.
格式细节来自于读取C中的libJPEG源.
归档时间: |
|
查看次数: |
12413 次 |
最近记录: |