【问题标题】:Changing an image's Exif tag "Orientation"更改图像的 Exif 标签“方向”
【发布时间】:2020-12-14 08:30:34
【问题描述】:

我正在尝试通过代码更改给定图像的Exif tag“方向”(0x0112)。

Here我找到了一个关于阅读的工作示例,但我无法编写相同的标签。

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;

在运行时,它会在 GPImage.SetPropertyItem(PI); 行引发以下 EAccessViolation:

模块“msvcrt.dll”中地址 757A8E30 的访问冲突。阅读 地址 00000006。

这是我的 test_up.jpg:

【问题讨论】:

  • PByte(Orientation) 是一个巨大的错误 - 永远不要将类型转换与指针混淆!另一个错误是PI.length 的长度必须是Orientation。您是否注意到Read of address 00000006 与Orientation := 6; 惊人的相同?

标签: delphi gdi+ exif delphi-xe7


【解决方案1】:

我已成功使用此代码:

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;

这是我在应用程序中编写的函数。完整源代码在GitHub。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-02-08
    • 2016-04-12
    • 2022-01-02
    • 2018-12-26
    • 1970-01-01
    • 2014-03-29
    • 2016-04-16
    • 1970-01-01
    相关资源
    最近更新 更多