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

 

ImageEn Forum
Profile    Join    Active Topics    Forum FAQ    Search this forumSearch
 All Forums
 ImageEn Library for Delphi, C++ and .Net
 ImageEn and IEvolution Support Forum
 low render quality image rotation

Note: You must be registered in order to post a reply.
To register, click here. Registration is FREE!

View 
UserName:
Password:
Format  Bold Italicized Underline  Align Left Centered Align Right  Horizontal Rule  Insert Hyperlink   Browse for an image to attach to your post Browse for a zip to attach to your post Insert Code  Insert Quote Insert List
   
Message 

 

Emoji
Smile [:)] Big Smile [:D] Cool [8D] Blush [:I]
Tongue [:P] Evil [):] Wink [;)] Black Eye [B)]
Frown [:(] Shocked [:0] Angry [:(!] Sleepy [|)]
Kisses [:X] Approve [^] Disapprove [V] Question [?]

 
Check here to subscribe to this topic.
   

T O P I C    R E V I E W
uko Posted - Feb 23 2015 : 07:51:05
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
2   L A T E S T    R E P L I E S    (Newest First)
uko Posted - Feb 24 2015 : 02:56:43
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
xequte Posted - Feb 24 2015 : 02:42:54
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