Search code examples
delphigdi+exifdelphi-xe7

Changing an image's Exif tag "Orientation"


I'm trying to change the Exif tag "Orientation" (0x0112) for a given image by code.

Here I've found a working example about reading but I'm failing in writing the same tag.

uses
  GDIPAPI, GDIPOBJ, GDIPUTIL;

var
  GPImage: TGPImage;
  BufferSize: Cardinal;
  Orientation: Byte;
  RotateType: TRotateFlipType;
  EncoderClsid: TGUID;
  PI : PropertyItem;
begin
  GPImage := TGPImage.Create('.\test_up.jpg');
  try
    BufferSize := GPImage.GetPropertyItemSize(PropertyTagOrientation);
    if BufferSize <= 0
    then raise Exception.Create('BufferSize <= 0');

    Orientation := 6; //this should be Rotate90FlipNone

    PI.id := PropertyTagOrientation;
    PI.type_ := 3;
    PI.length := BufferSize;
    PI.value := PByte(Orientation);

    GPImage.SetPropertyItem(PI);

    GetEncoderClsid('image/jpeg', EncoderClsid);
    GPImage.Save('.\test_up_Rotate90FlipNone.jpg', EncoderClsid);
  finally
    GPImage.Free
  end;
end;

At runtime it raises the following EAccessViolation at the GPImage.SetPropertyItem(PI); line:

Access violation at address 757A8E30 in module 'msvcrt.dll'. Read of address 00000006.

This is my test_up.jpg:

Picture of an arrow pointing up


Solution

  • I am successfully using this code:

    procedure TOvbCustomImage.SetImageOrientation(AGPImage: TGPImage; Value: WORD);
    var
        PropItem : TPropertyItem;
    begin
        if not Assigned(AGPImage) then
            Exit;
        PropItem.Id            := PropertyTagOrientation;
        PropItem.Length        := SizeOf(WORD);
        PropItem.Type_         := PropertyTagTypeShort;
        PropItem.Value         := @Value;
        AGPImage.SetPropertyItem(PropItem);
    end;
    

    This is a function I wrote in my application. Full source code at GitHub.