ImageEn for Delphi and C++ Builder ImageEn for Delphi and C++ Builder

 

ImageEn Forum
Profile    Join    Active Topics    Forum FAQ    Search this forumSearch
Forum membership is Free!  Click Join to sign-up
Username:
Password:
Save Password
Forgot your Password?

 All Forums
 ImageEn Library for Delphi, C++ and .Net
 ImageEn and IEvolution Support Forum
 low render quality image rotation
 New Topic  Reply to Topic
Author Previous Topic Topic Next Topic  

uko

Germany
31 Posts

Posted - Feb 23 2015 :  07:51:05  Show Profile  Reply
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

xequte

38610 Posts

Posted - Feb 24 2015 :  02:42:54  Show Profile  Reply
Hi Ulrich

This is to do with it being 32bit. It anti-aliases correctly in 24bit.



I'll investigate further...



Nigel
Xequte Software
www.xequte.com
nigel@xequte.com
Go to Top of Page

uko

Germany
31 Posts

Posted - Feb 24 2015 :  02:56:43  Show Profile  Reply
Hi Nigel,

thank you for looking on this. I have done the 32bit conversion only to rotate the alpha layer the same way as the image. Should I do the rotation for image and alpha image separate (I think I found other problems doing it this way: but I will check again)?
Well, just implemented the rotation by 24bit and it works fine. I guess I'm still thinking too much in concepts of GR32: I have to say sorry!

The only thing I have to make sure: always ensure to have an alpha channel assigned to image so that rotation sets the surrounding new areas to become transparent (here was my fault when testing: I used an image recorded by MediaFoundationSourceReader that had no alpha channel)


best regards,
Ulrich
Go to Top of Page
  Previous Topic Topic Next Topic  
 New Topic  Reply to Topic
Jump To: