我有一个有4张图像的图像文件(.tiff)。 我无法在TImage中查看或显示这4个图像。 TImage组件仅显示第一帧。
如何按图像显示图像?
答案 0 :(得分:4)
VCL通过Windows映像组件支持tif映像,该映像由TWICImage
封装。但是,虽然微不足道,但VCL已经忽略了WIC的 frame 支持(这是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和运行时错误,当它是本地时我无法解决。