-1

Enviroment: Delphi XE5, Win7

I have VCL application. Want to use Firemonkey classes to little image processing. Task is to get thumbnails from image files.

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

Any combination of TBitmap and LoadFromFile, LoadFromStream, CreateFromFile fails with exception.

I tryed to load bmp, png, tif, jpg... always the same result.

In debugger I see the access violation exception in FMX.Canvas.D2D.pas in row:

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

What should I do to avoid exception and get working code? To enable some codecs?

UPDATE: At all... can I use Firemonkey classes in VCL Application? It looks for me I can not. Am I right?

UPDATE2: Now I try to go with next approach Writing a FireMonkey DLL for use with a VCL application.

My Firemonkey DLL full code

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.

And again I get the same Access violation exception at library row:

bmp := TBitmap.CreateFromFile(filename);
Sir Rufo
  • 18,395
  • 2
  • 39
  • 73
mad
  • 1,029
  • 3
  • 17
  • 38
  • Why do you feel the need to use FMX? – David Heffernan Jan 02 '14 at 23:29
  • 1
    There is really no need to use FMX for this. The 'CreateThumbnail' implementation doesn't actually look for an embedded thumbnail - all it does is create a new TBitmap instance at the specified size and draw the source bitmap to it, something you can do easily enough with the VCL. In fact, for JPEG images, the VCL actually offers more facilities to the extent the TJpegImage class has a Scale property - set this to jsEighth before loading the image and you'll avoid the penalty of having to load the full image first. – Chris Rolliston Jan 03 '14 at 00:20
  • Problem is I need thumbnails not only for bmp/jpeg but as well as png/tif and so on. And FMX can do it... – mad Jan 03 '14 at 10:15
  • @mad VCL can do it fine too. FMX is the wrong solution. – David Heffernan Jan 04 '14 at 08:55
  • @David Please show me how to process tiff file (for example, make a thumbnail) in vcl without commercial third party libraries. Thanks. – mad Jan 05 '14 at 19:29
  • Load a tiff with [GraphicEx](http://www.delphi-gems.com/index.php/libs/graphicex-library) or `TWICImage`. There's also http://www.awaresystems.be/imaging/tiff/delphi.html – David Heffernan Jan 05 '14 at 19:37

2 Answers2

1

I am not sure what parts of firemonkey you can use in VCL but the tbitmap from VCL will not be compatible with the tbitmap from firemonkey in any case. Not sure how useful it will be to use it in VCL but to avoid the error, you need to declare the variable bmp as an fmx tbitmap.

var bmp:FMX.Graphics.TBitmap

David Peters
  • 220
  • 1
  • 10
  • I tryed... does not help. Now I tryed to go with next approach:http://blogs.embarcadero.com/stephenball/2011/10/10/writing-a-firemonkey-dll-for-use-with-a-vcl-application/ – mad Jan 02 '14 at 16:57
1

The following will work and is tested in XE5 with update2 and hot fixes 1 + 3. You must use Tbitmapsurface in order to get savetostream to use a format that will be recognised when loaded into the VCL Timage. You can't just copy the fmx tbitmap to a 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.
David Peters
  • 220
  • 1
  • 10
  • Yes, when I have FM form and make bitmap conversion inside it then everything is OK. But I need clear function without form and so on. Just lod bitmap and save to stream without any form and so on. And it does not work. – mad Jan 04 '14 at 13:25
  • There is no FM form just a VCL form for the purposes of selecting a file and proving that the thumbnail is correct by loading the stream into a VCL image. So its using VCL to choose a file, Firemonkey to produce the thumbnail and write to the stream and VCL to load the stream and display it. – David Peters Jan 05 '14 at 01:22