Firemonkey:为什么TBitmap.LoadFromFile()会失败?

时间:2014-01-02 14:33:05

标签: delphi directx firemonkey delphi-xe5

环境:Delphi XE5,Win7

我有VCL申请。 想要使用Firemonkey类来进行小的图像处理。 任务是从图像文件中获取缩略图。

bmp: TBitmap;
...
bmp := FMX.Graphics.TBitmap.Create(100, 100);
bmp.LoadThumbnailFromFile(filename, 100, 100);

TBitmap和LoadFromFile,LoadFromStream,CreateFromFile的任何组合都会失败,但有例外。

我试着加载bmp,png,tif,jpg ...总是一样的结果。

在调试器中,我在FMX.Canvas.D2D.pas的行中看到了访问冲突异常:

TCanvasD2D.ImagingFactory.CreateDecoderFromStream(stream, GUID_NULL, WICDecodeMetadataCacheOnDemand, dec);

我应该怎么做才能避免异常并获得正常工作的代码?要启用一些编解码器?

UPDATE:根本......我可以在VCL应用程序中使用Firemonkey类吗?它找我,我不能。我是对的吗?

UPDATE2:现在我尝试采用下一个方法Writing a FireMonkey DLL for use with a VCL application.

我的Firemonkey DLL完整代码

library wnimage;

uses
  System.SysUtils,
  System.Classes,
  FMX.Graphics;

{$R *.res}


function GetThumbnail(filename: String; width, height: Integer): TStream;
var
  bmp, th: TBitmap;
begin
  bmp := TBitmap.CreateFromFile(filename);
  th := bmp.CreateThumbnail(width, height);
  Result := TMemoryStream.Create;
  th.SaveToStream(Result);
  th.Free;
  bmp.Free;
end;

exports
  GetThumbnail;

begin
end.

我再次在库行中获得相同的访问冲突异常:

bmp := TBitmap.CreateFromFile(filename);

2 个答案:

答案 0 :(得分:1)

我不确定您可以在VCL中使用哪些firemonkey部分,但VCL的tbitmap在任何情况下都不会与firemonkey的tbitmap兼容。不确定在VCL中使用它有多大用处,但为了避免错误,你需要将变量bmp声明为fmx tbitmap。

var bmp:FMX.Graphics.TBitmap

答案 1 :(得分:0)

以下内容将在XE5中使用update2和hotfixes 1 + 3进行测试。您必须使用Tbitmapsurface才能使savetostream使用加载到VCL Timage时可识别的格式。您不能只将fmx tbitmap复制到vcl tbitmap。

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, fmx.graphics, Vcl.ExtCtrls, fmx.surfaces;

type
  TForm1 = class(TForm)
    Button1: TButton;
    OpenDialog1: TOpenDialog;
    Image1: TImage;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);

var bmp:fmx.graphics.tbitmap;
    astream:tmemorystream;
    surface:tbitmapsurface;

begin
  if opendialog1.Execute then
  begin
    bmp := FMX.Graphics.TBitmap.Create(100, 100);
    bmp.LoadThumbnailFromFile(opendialog1.filename, 100, 100);

    astream:=tmemorystream.Create;
    surface:=tbitmapsurface.Create;
    surface.Assign(bmp);
    try
    tbitmapcodecmanager.SaveToStream(astream,surface,'bmp');
    astream.Seek(0,tseekorigin.soBeginning);
    image1.Picture.bitmap.LoadFromStream(astream);
    finally
      astream.free;
      bmp.free;
      surface.free
    end;
  end;
end;

end.