Hi,
when rotating an image, the quality of result is poor, when compared doing the same thing with Graphics32. So I want to ask, what I am doing wrong here?
Here the one created by current ImageEn:
And this Is what I get when converting from ImageEn to GR32, rotate there and convert back:
The original image is this:
How was rotation done:
nOldPixelFormat := imgPreview.IEBitmap.PixelFormat;
imgPreview.IEBitmap.PixelFormat := ie32RGB;
try
imgPreview.IEBitmap.SynchronizeRGBA(False);
try
// rotate be nAngle degree (15 in sample)
imgPreview.Proc.Rotate(nAngle, true, ierBicubic, $00FFFFFF);
finally
imgPreview.IEBitmap.SynchronizeRGBA(True);
end;
finally
imgPreview.IEBitmap.PixelFormat := nOldPixelFormat;
end;
For the GR32 method I used this code:
AdjustResampler(bmp32);
_RotateImageByFreeAngle(bmp32, nAngle);
where
procedure _RotateImageByFreeAngle(AImage: TBitMap32; AAngle: integer);
var
bmpSource: TBitmap32;
T: TAffineTransformation;
nNewWidth: integer;
nNewHeight: integer;
begin
// Kopie des Bildes erstellen als Hilfsbild
bmpSource := TBitmap32.Create;
try
bmpSource.Assign(AImage);
T := TAffineTransformation.Create;
try
// Ausgangsgroesse Transformation festlegen
T.SrcRect := FloatRect(0, 0, bmpSource.Width + 1, bmpSource.Height + 1);
// Transformation zuruecksetzen
T.Clear;
// Ursprung in das Zentrum des Bildes verschieben
T.Translate(-AImage.Width / 2, -AImage.Height / 2);
// dann Bild rotieren
T.Rotate(0, 0, - AAngle);
// nun neue Groesse des Bildes berechnen
nNewWidth := Round5(T.GetTransformedBounds.Right - T.GetTransformedBounds.Left);
nNewHeight := Round5(T.GetTransformedBounds.Bottom - T.GetTransformedBounds.Top);
// und von dessen Zentrum aus in Ursprung zurueck verschieben (Bild ist
// durch Rotation ja eventuell groesser geworden)
T.Translate(nNewWidth / 2, nNewHeight / 2);
// Transformation vorbereiten
AImage.BeginUpdate;
try
// im Zielbild die neue Groesse setzen
AImage.Width := nNewWidth;
AImage.Height := nNewHeight;
// Zielbild erst einmal loeschen und dafuer sorgen, dass es transparent auf den
// Hintergrund gezeichnet wird
AImage.Clear(bmpSource.OuterColor);
AImage.ResetAlpha(0); // voll transparent
AImage.DrawMode := dmblend;
// Zeichenoptionen fuer Source setzen
bmpSource.OuterColor := clBlack; // Wegen freiwerdenden Hintergrund bei Transformation
bmpSource.DrawMode := dmOpaque;
// Und Transformation durchfuehren (Teile des Bildes, die bei der Transformation
// geleert werden, werden mit OuterColor gefüllt!)
Transform(AImage, bmpSource, T);
finally
AImage.EndUpdate;
end;
finally
T.Free;
end;
finally
bmpSource.Free;
end;
end;
and
procedure AdjustResampler(const ABitmap: TBitmap32);
begin
if Assigned(ABitmap) then
begin
ABitmap.ResamplerClassName := TKernelResampler.ClassName;
if ABitmap.Resampler is TKernelResampler then
TKernelResampler(ABitmap.Resampler).Kernel := TLanczosKernel.Create;
end;
end;
The conversion between TIEBitmap and TBitmap32 is done by assignment and manual copy of alpha channel
As I really would like to replace GR32 by ImageEn on a certain part of real world application, I need to find a way to enhance image quality of rotation with ImageEn.
Any ideas?
best regards,
Ulrich