Why is my image being rotated when loaded into a TImage component?
Asked Answered
I

3

11

Writing a mobile application - it's pulling images from a secure website, and shown below (the first image) pulls incorrectly (notice web version vs mobile version), the second image shows correctly on the website, but Delphi's TImage is rotating it for some reason and I can't figure out why. Rotate is set to 0 and Fit is set on the TImage component.

Thoughts?

Correct:

Image loaded correctly in my FMX Mobile App using Delphi Programming Code

Incorrect (rotated): Image loaded incorrectly (rotated) in my FMX Mobile App using Delphi Programming Code.

Impending answered 12/1, 2017 at 17:47 Comment(1)
I see this happen all the time within Windows Explorer even. Pretty sure it has something to do with the image itself, something which flags the file as "rotated", or along those lines.Mishear
P
15

Jpeg and Tiff have Exif (Exchangeable image file format) metadata that specify image orientation (among other data).

It's not that "TImage rotating my image". the TImage is not handling the Exif orientation metadata. Ideally, TImage should auto-rotate the image according to the orientation metadata, but it does not. You need to read the Exif orientation property and rotate the image accordingly.

The Exif tag "Orientation" (0x0112) spec is:

1 = Horizontal (normal) 
2 = Mirror horizontal 
3 = Rotate 180 
4 = Mirror vertical 
5 = Mirror horizontal and rotate 270 CW 
6 = Rotate 90 CW 
7 = Mirror horizontal and rotate 90 CW 
8 = Rotate 270 CW

You can use some free Exif components such TExif/NativeJpg/CCR Exif, and rotate your image if needed according to the orientation tag.

Here is an example using GDI+ (VCL/Windows) e.g:

uses GDIPAPI, GDIPOBJ;

procedure TForm1.Button1Click(Sender: TObject);
var
  GPImage: TGPImage;
  GPGraphics: TGPGraphics;
  pPropItem: PPropertyItem;
  BufferSize: Cardinal;
  Orientation: Byte;
  RotateType: TRotateFlipType;
  Bitmap: TBitmap;
begin
  GPImage := TGPImage.Create('D:\Test\image.jpg');
  try
    BufferSize := GPImage.GetPropertyItemSize(PropertyTagOrientation);
    if BufferSize > 0 then
    begin
      GetMem(pPropItem, BufferSize);
      try
        GDPImage.GetPropertyItem(PropertyTagOrientation, BufferSize, pPropItem);
        Orientation := PByte(pPropItem.value)^;
        case Orientation of
          1: RotateType := RotateNoneFlipNone; // Horizontal - No rotation required
          2: RotateType := RotateNoneFlipX;
          3: RotateType := Rotate180FlipNone;
          4: RotateType := Rotate180FlipX;
          5: RotateType := Rotate90FlipX;
          6: RotateType := Rotate90FlipNone;
          7: RotateType := Rotate270FlipX;
          8: RotateType := Rotate270FlipNone;
        else
          RotateType := RotateNoneFlipNone; // Unknown rotation?
        end;
        if RotateType <> RotateNoneFlipNone then
          GPImage.RotateFlip(RotateType);
        Bitmap := TBitmap.Create;
        try
          Bitmap.Width := GPImage.GetWidth;
          Bitmap.Height := GPImage.GetHeight;
          Bitmap.Canvas.Lock;
          try
            GPGraphics := TGPGraphics.Create(Bitmap.Canvas.Handle);
            try
              GPGraphics.DrawImage(GPImage, 0, 0, GPImage.GetWidth, GPImage.GetHeight);
              Image1.Picture.Assign(Bitmap);              
            finally
              GPGraphics.Free;
            end;
          finally
            Bitmap.Canvas.Unlock;
          end;    
        finally
          Bitmap.Free;
        end;
      finally
        FreeMem(pPropItem);
      end;
    end;
  finally
    GPImage.Free
  end;
end;
Penis answered 13/1, 2017 at 19:44 Comment(0)
Z
7

The Exif specification defines an Orientation Tag to indicate the orientation of the camera relative to the captured scene. Some apps can therefore auto-rotate the image corresponding to this EXIF-Flag. I would guess that your web-version does this auto-rotate. TImage does it not.

Zaporozhye answered 12/1, 2017 at 18:58 Comment(0)
S
2

Web site certainly read exif data of the picture, which contain orientation of the photo, and then rotate the image accordingly. Delphi does not. You have to read picture metadata for that (search "exif" on google)

Schaaff answered 12/1, 2017 at 18:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.