IceCold
IceCold

Reputation: 21194

Fast way to resize an image (Mixing FMX and VCL code)

I want to quickly resize an image (shrink/enlarge). The resulted image should be of high quality so I cannot use the classic StretchDraw or something like this. The JanFX and Graphics32 libraries offer high quality resamplers. The quality is high but they are terribly slow (seconds to process a 2000x1000 image).

I want to try FMX CreateThumbnail to see how fast it is:

FMX.Graphics.BMP.CreateThumbnail

I created a FMX bitmap in a VCL application and tried to assign a 'normal' bitmap to it.

fmxBMP.Assign(vclBMP);

But I get an error: Cannot assign TBitmap to a TBitmap. Obviously the two bitmaps are different.

My questions:
1. Are the image processing routines in FMX much faster then the normal VCL routines?
2. Most important: how can I assign a VCL bitmap to a FMX bitmap (and vice versa)?

Upvotes: 4

Views: 2776

Answers (2)

IceCold
IceCold

Reputation: 21194

I created a small tool to compare misc resizing algorithms. The StretchBlt seems by far the best as quality, speed and memory. Of course, this is if you develop for Windows only.

PS: GDI+ is not included yet but I will try to include it as soon as I have the time.

Update: GDI is 3 times slower than StretchBlt and produces the same quality.

Upvotes: 1

Dalija Prasnikar
Dalija Prasnikar

Reputation: 28512

You can use GDI+ scaling.

You can alter result quality and speed specifying different interpolation, pixel offset and smoothing modes defined in GDIPAPI.

uses
  GDIPAPI,
  GDIPOBJ;

procedure ScaleBitmap(Source, Dest: TBitmap; OutWidth, OutHeight: integer);
var
  src, dst: TGPBitmap;
  g: TGPGraphics;
  h: HBITMAP;
begin
  src := TGPBitmap.Create(Source.Handle, 0);
  try
    dst := TGPBitmap.Create(OutWidth, OutHeight);
    try
      g := TGPGraphics.Create(dst);
      try
        g.SetInterpolationMode(InterpolationModeHighQuality);
        g.SetPixelOffsetMode(PixelOffsetModeHighQuality);
        g.SetSmoothingMode(SmoothingModeHighQuality);
        g.DrawImage(src, 0, 0, dst.GetWidth, dst.GetHeight);
      finally
        g.Free;
      end;
      dst.GetHBITMAP(0, h);
      Dest.Handle := h;
    finally
      dst.Free;
    end;
  finally
    src.Free;
  end;
end;

Upvotes: 4

Related Questions