Cambiar la etiqueta Exif "Orientación" de una imagen

Dec 14 2020

Estoy intentando cambiar la etiqueta Exif "Orientación" (0x0112) para una imagen dada por código.

Aquí encontré un ejemplo práctico sobre lectura, pero no puedo escribir la misma etiqueta.

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;

En tiempo de ejecución, genera lo siguiente EAccessViolationen la GPImage.SetPropertyItem(PI);línea:

Infracción de acceso en la dirección 757A8E30 en el módulo 'msvcrt.dll'. Lectura de la dirección 00000006.

Este es mi test_up.jpg :

Respuestas

1 fpiette Dec 14 2020 at 16:09

Estoy usando con éxito este código:

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;

Esta es una función que escribí en mi aplicación. Código fuente completo en GitHub .