Delphi:如何在Timage组件中按图像显示

标签 delphi tiff

我有一个图像文件 (.tiff),其中包含 4 个图像。 我无法在 TImage 中查看或显示这 4 个图像。 TImage组件仅显示第一帧。

如何按图显示?

最佳答案

VCL 通过 Windows 成像组件支持 tif 图像,该组件由 TWICImage 封装。 。然而,虽然微不足道,VCL 却忽略了 WIC 的支持(术语 MS documentation 用于指代图像中的多个图像)。

以下引用来自XE2的“Vcl.Graphics.pas”。

procedure TWICImage.LoadFromStream(Stream: TStream);
var
  ..
  BitmapDecoder: IWICBitmapDecoder;
  ...
begin
  ...
  WicCheck(BitmapDecoder.GetFrame(0, LBitmapFrame));
  ...
end;

我只引用了一行,它立即显示了问题。 “解码器”能够提供总帧计数信息并检索其中的任何一个。但是,按照编码,只使用了第一个。

仍然可以使用TWICImage本身来检索帧,然后将其分配给TImage的图片。下面是我这样做的尝试,它本质上重复了 TWICImage.LoadFromStream 中的代码,不同之处在于只使用了第二帧:)。不管怎样,应该很容易模块化才能得到 frame count并显示所需的内容。

type
  TForm1 = class(TForm)
    Image1: TImage;
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    WICImage: TWICImage;
  end;

var
  Form1: TForm1;

implementation

uses
  activex, wincodec, consts;

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);

  procedure Check(Result: HRESULT);
  begin
    if Failed(Result) then
      raise EInvalidGraphic.Create(SInvalidImage);
  end;

var
  fs: TFileStream;
  Adapter: IStream;
  Decoder: IWICBitmapDecoder;
  Frame: IWICBitmapFrameDecode;
  WICBmp: IWICBitmap;
  Width, Height: DWORD;
begin
  fs := TFileStream.Create('....tif', fmShareDenyWrite);
  try
    Adapter := TStreamAdapter.Create(fs);
    Check(WICImage.ImagingFactory.CreateDecoderFromStream(Adapter,
        GUID_ContainerFormatTiff, WICDecodeMetadataCacheOnDemand, Decoder));
    Check(Decoder.GetFrame(1, Frame));
    Check(WICImage.ImagingFactory.CreateBitmapFromSource(Frame,
        WICBitmapCacheOnLoad, WICBmp));
    Check(WICBmp.GetSize(Width, Height));
    Image1.Width := Width;
    Image1.Height := Height;
    WICImage.Handle := WICBmp;
    Image1.Picture.Bitmap.Assign(WICImage);
  finally
    fs.Free;
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  WICImage := TWICImage.Create;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  WICImage.Free;
end;

请注意,我不喜欢将 WIC 图像作为表单的字段而不是局部变量。但我在程序关闭时不断收到 AV 和运行时错误,当它是本地时我无法解决。

关于Delphi:如何在Timage组件中按图像显示,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40512621/

相关文章:

delphi - Delphi 中的流畅调用风格自引用记录可能吗?

delphi - 如何将 Ctrl+R 设置为 Delphi 中 "Rename"重构的快捷方式?

delphi - Delphi中的一元++运算符

ios - 如何在 iPad 上创建 TIFF

Python:在 PIL 和/或 pygame 中操作 16 位 .tiff 图像:以某种方式转换为 8 位?

c++ - 获取 .tiff map 中的最短路径

android - 在 XE5 Delphi 中删除 Android 选项菜单

arrays - 是否可能:记录中的数组

html - 关于在 HTML 中渲染 .tiff 图像的问题

c++ - 如何从 C++ 中的 Base64 编码字符串在 GDI+ 中创建图像?