问题描述
有些Delphi似乎不喜欢的Jpg图片。它似乎是特定于我正在加载的文件。程序很简单 - a)将Jpg图像加载到 TJpegImage
,b)将Jpg对象分配给一个 TBitmap
对象,和c)保存和/或显示Bmp图像。由于某些原因,这些图片不断出现,带有蓝色的色调。
这些图像完美地显示在任何地方,加载它们的地方(Windows图片查看器,油漆,photoshop等) 。)。
这里是一个特定文件(数百个)的链接,它没有蓝色,但是当加载到Delphi中时,会出现蓝色...
(使用sentpace.com,以便我知道网站不尝试转换图像格式)
我正在做的很简单...
procedure Load;
var
J:TJpegImage;
B:TBitmap;
begin
J:= TJpegImage.Create;
B:= TBitmap.Create;
J.LoadFromFile('C:\SomeFile.jpg');
B.Assign(J);
//保存或显示B,此时显示为蓝色
....
我想避免尽可能多的获得任何第三方的东西。 Delphi版本7,2010和XE2中存在这个问题。至少XE2中的TImage控件可以正确显示(而不是较旧的两个),但是如果TBitmap仍然不起作用,则无关紧要。这个文件有什么问题?和/或Delphi的渲染有什么问题?
添加信息
我最近发现了一些关于这些图像的东西。当他们来自供应商(产品图片)时,他们是CMYK格式。那时候,Delphi 7并没有正确的支持这些文件(访问冲突和坏的图像),所以所有的图片都通过一个转换器过滤到RGB颜色格式。许多原始图像也是TIFF,并被转换为JPG。因此,软件 FastStone Image Resizer
似乎无法正确保存这些文件。所有这些都不会发生蓝色图像,只是一次随机批量。该软件处理数千种产品,所以有数千种可能的图片。
我想出了这个问题。这很可能是Delphi中的一个错误。
提供的图像是一种特殊格式的JPEG文件,称为Adobe JPEG。 Adobe JPEG可能是最特别的事情,它允许以RGB格式存储图像,尽管它也允许其他格式。大多数JPEG是JFIF或EXIF格式,不使用RGB。
当复制RGB数据时,无论是Delphi做什么,它在加载红色和蓝色数据时都会反转到画布上它加载它作为BGR而不是RGB。这可能是因为Windows(24位和32位)DIB(BMP)以BGR格式存储。
我猜这个bug会出现在Delphi适用于任何RGB JPEG。由于大多数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。
There are some Jpg images which Delphi doesn't seem to like. It appears to be specific with the files I'm loading. And the procedure is simple - a) load Jpg image to TJpegImage
, b) Assign Jpg object to a TBitmap
object, and c) Save and/or display Bmp image. For some reason, these pictures keep coming out with a blueish tint.
These images show perfectly anywhere and everywhere else I load them (windows picture viewer, paint, photoshop, etc.).
Here's a link to one particular file (of hundreds) which has no blue in it - but when loaded into Delphi, comes out blue...
http://www.sendspace.com/file/1owbzh
(Used sendspace.com so that I know the website's not trying to convert the image format)
And what I'm doing is very simple...
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
....
I want to avoid getting any third party stuff as much as possible. This problem has existed in Delphi versions 7, 2010, and XE2. At least the TImage control in XE2 displays it properly (as opposed to the older two) but that doesn't matter if the TBitmap still doesn't work. What is wrong with this file? And/or, what is wrong with Delphi's rendering?
Added Info
I recently found out something about these images. When they came from the vendors (product pictures), they were in CMYK format. At that time, Delphi 7 didn't properly support these files (with access violations and bad images) so all the pictures were filtered through a converter to RGB color format. Many original images were also TIFF and were converted to JPG. So it appears that the software FastStone Image Resizer
must not properly save these files when they go through. The blue image doesn't happen on all of them, just some random batches at a time. The software handles thousands of products, so there are thousands of possible pictures.
I figured out the issue. It's most likely a bug in Delphi.
The provided image is a peculiar format for a JPEG file called Adobe JPEG. Probably the most peculiar thing about an Adobe JPEG is that it allows storing the image in RGB format, though it also allows other formats. Most JPEGs are JFIF or EXIF format, which do not use RGB.
When copying the RGB data, whatever Delphi's doing, it's reversing the red and blue data when it's loading it onto the canvas. It's loading it as BGR instead of RGB. This may be because Windows (24-bit and 32-bit) DIBs (BMPs) are stored in BGR format.
I'm guessing that the bug will appear in Delphi for any RGB JPEG. Since most JPEGs do not use RGB, the incidence of the bug is low. The easy fix, if you have the source to the JPEG unit, is to reverse the order when loading an RGB JPEG.
If you don't have the source, then continue on.
The Adobe JPEG specifies the order of the colors in a format like this (in Hex) 43 11 00 47 11 00 42 11 00
that looks like this in a hex editor R..G..B
. If you reverse the R
and B
here via a Hex editor, it shows wrong in Windows, and right in Delphi.
To recognize an Adobe JPEG, the first four bytes are either (in Hex) FF D8 FF ED
or FF D8 FF EE
, with the ED
and EE
being the differentiating bytes. All JPEG files start with FF D8 FF
.
After those bytes are two bytes that represent the length of the type marker, followed by (In ASCII) Adobe
, followed by six more bytes (representing the version, etc.) and finally, (the 18th byte) is the byte that specifies the format. 0
means RGB. So, check for those significant bytes, and then act accordingly.
You'll have to reverse the RGB order in the file header (to lie to Delphi), or copy it to a TBitmap and use ScanLine to reverse the RGB to the proper order.
The format details are from reading the libJPEG source in C.
这篇关于将Jpeg图像转换为Bmp - 某些图像变成蓝色的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!