Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
953 views
in Technique[技术] by (71.8m points)

delphi - Converting Jpeg images to Bmp - some images come out blue

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.).

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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The reason your file is blue is because the encoding is BGR isntead of RGB.
If you modify the jpeg.pas source file and use the pixel swapping (remove {.$IFDEF JPEGSO} in TJPEGImage.GetBitmap) you'll see your sample file correctly brown.

So, I guess the bottom line is that the stock jpeg source does not detect the correct (reverse) encoding; probably in jc.d.out_color_space...

Update:
The C source file (and jpeg.pas) should declare (and use) the Color Spaces with the new Extensions 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
}

Update 2:
jpeg.pas can be found (XE) in C:...RAD Studio8.0sourcevcl with the C files in the jpg subfolder.

If you're ready to bet that all Adobe files with an RGB colorspace need to have their bits swapped, you can easily hack the jpeg.pas source to detect your special files and conditionnally do the swap mentioned above in 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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...