3
votes

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)?

1
High quality resizing is expensive. Very hard to believe that FMX could help. WIC is pretty capable too.David Heffernan
Why a downvote? The question provides all information necessary.Z80
Who knows? If the downvoter doesn't identify themselves then you'll never know.David Heffernan
So typical for StackOverflow.Z80
@DavidHeffernan-Most games are doing high quality resizing on multiple (hundreds) images in REAL TIME. But, yes... I know... that's done in hardware :)Z80

1 Answers

3
votes

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;