Recent

Author Topic: I need to rotate a picture in a TImage 90°  (Read 1907 times)

RedOctober

  • Sr. Member
  • ****
  • Posts: 330
I need to rotate a picture in a TImage 90°
« on: May 18, 2020, 09:09:01 pm »
Platform:  Microsfot Windows, FPC 3.0.4, Lazarus 1.8.4
I can't find a method on a TImage to do this, so did some quick research in this forum and I found a post about a package called BGRABit, so I found it listed in the on-line package manager and selected both the bitmap and the controls.  The controls install failed (no other info given) and I clicked "Yes to all" to attempt to install the remaining package.   At the moment, I seem to have an OpenGL component on my IDE tool bar, nothing new regarding the BGRABit (probably due to the failed package install).

I have two questions: 
1) How do I determine what is wrong with the install so I can maybe fix it and use it to rotate my image
2) Is there an easier way to rotate an image in a TImage (or some other Lazarus component that comes in the basic new installation)
3) Is there an alternative component set that will allow me to rotate my image that is not BGRABit, and will install correctly.

Thanks in advance for any help you can provide.


winni

  • Hero Member
  • *****
  • Posts: 1778
Re: I need to rotate a picture in a TImage 90°
« Reply #1 on: May 18, 2020, 09:32:57 pm »
Hi!


I think you should update your Lazarus.

1.84 is two years old.

Maybe that is the reason for the broken BGRA installation,

I updated BGRA on Win7/64 and Laz 2.08 with no problems.

Winni

RedOctober

  • Sr. Member
  • ****
  • Posts: 330
Re: I need to rotate a picture in a TImage 90°
« Reply #2 on: May 18, 2020, 09:38:34 pm »
I can't update my Lazarus.  Too many custom fixes for bugs in existing code base.  Upgrading risks being unable to install older components into the latest Lazarus version. I could spent a week trying to resolve all the issue.  Running out of time trying to meet an end-of-year deadline.
« Last Edit: May 18, 2020, 09:42:01 pm by RedOctober »

GetMem

  • Hero Member
  • *****
  • Posts: 3757
Re: I need to rotate a picture in a TImage 90°
« Reply #3 on: May 18, 2020, 09:52:16 pm »
@RedOctober
Quote
How do I determine what is wrong with the install so I can maybe fix it and use it to rotate my image
Look at the message window. Usually it's not obscured by OPM.

Quote
I can't update my Lazarus.  Too many custom fixes for bugs in existing code base.  Upgrading risks being unable to install older components into the latest Lazarus version. I could spent a week trying to resolve all the issue.  Running out of time trying to meet an end-of-year deadline.
Then perhaps you should install an older version of BGRABitmap. AFAIK version 9.1 worked fine with Lazarus 1.8.4.

winni

  • Hero Member
  • *****
  • Posts: 1778
Re: I need to rotate a picture in a TImage 90°
« Reply #4 on: May 18, 2020, 10:35:46 pm »
Hi!

If nothing else helps - awful slow:

Code: Pascal  [Select][+][-]
  1. function rotate90 (Source: TBitmap) : TBitmap;
  2. var dest : TBitmap;
  3.       x,y : Integer;
  4.       col : TColor;
  5.  
  6. begin
  7. dest := TBitmap.create;
  8. dest.setSize (Source.height,source.width);
  9. for x := 0 to Source.width - 1 do
  10.   begin
  11.      for y := 0 to Source.Height - 1 do
  12.        begin
  13.        col := Source.Canvas.pixels[x,y];
  14.        dest.canvas.pixels[y, dest.Height-x-1] := col;
  15.        end;//y
  16.      end; // x
  17.  result := dest;
  18. end; // proc
  19.  

Winni
« Last Edit: May 18, 2020, 10:37:47 pm by winni »

marcov

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 8722
  • FPC developer.
Re: I need to rotate a picture in a TImage 90°
« Reply #5 on: May 18, 2020, 10:49:12 pm »
For high speed and colour apps, I rotate using Opengl's coordinate system.

For smaller apps it is sometimes easier to just rotate using SSE/AVX (so you don't have to redo the coordinate systems of everything else to match)

For pf8bit I use http://www.stack.nl/~marcov/rot8x8.txt
« Last Edit: May 18, 2020, 11:02:29 pm by marcov »

RedOctober

  • Sr. Member
  • ****
  • Posts: 330
Re: I need to rotate a picture in a TImage 90°
« Reply #6 on: May 19, 2020, 12:04:27 am »
Hi Winni, your code works, but as you say, it's quite slow.  I will keep that snippet for future reference.
Hi GetMem, you are correct.  I DL'd and installed version 991 successfully.
Now I'm almost there but, have no idea with I'm doing with TBGRABitmap.  My goal is to load a file, rotate it either 90°, 180° or 270° and save it.
Here is my code.  I end up with a file containing only the color black, and I can tell by the size, it's not rotated.  Can you give me the correct code to accomplish this?  Thanks.

Code: Pascal  [Select][+][-]
  1. // Does NOT work
  2. procedure GrabItRotate(const src_fnm: String; const dgr: Integer);
  3. var bmp1, bmp2: TBGRABitmap;  trfm: TBGRAAffineBitmapTransform;
  4. begin
  5.   bmp1 := TBGRABitmap.Create(src_fnm);
  6.   bmp2 := TBGRABitmap.Create(bmp1.Width, bmp1.Height, BGRABlack);
  7.   trfm := TBGRAAffineBitmapTransform.Create(bmp2, False);
  8.   trfm.RotateDeg(dgr);
  9.   bmp2.SaveToFile(src_fnm);
  10. end;  
  11.  
« Last Edit: May 19, 2020, 12:27:01 am by RedOctober »

winni

  • Hero Member
  • *****
  • Posts: 1778
Re: I need to rotate a picture in a TImage 90°
« Reply #7 on: May 19, 2020, 12:47:52 am »
Hi!

BGRAbitmap has in the Filters also the rotation.


Code: Pascal  [Select][+][-]
  1. var
  2. bmp : TBGRAbitmap;
  3. Center : TPointF;
  4. AngleDegree : single;
  5. .....
  6. BGRAReplace(bmp,bmp.Filterrotate(Center,angleDegree,false));
  7.  
  8.  

The third boolean parameter is

correctBlur: Boolean;



Heavy rotation on monday night!

Winni

jamie

  • Hero Member
  • *****
  • Posts: 3520
Re: I need to rotate a picture in a TImage 90°
« Reply #8 on: May 19, 2020, 02:03:22 am »
It used to be and I don't know if it is supported in other widgets but you can rotate an image using the Tbitmap  Rectangle copy over to another bitmap..

The trick is to specify the the LEFT,TOP value as the bottom, right values.

So reversing the Top and bottom will do the 180, left to right 270 etc..
I may need to experiment a little here.
The only true wisdom is knowing you know nothing

RedOctober

  • Sr. Member
  • ****
  • Posts: 330
Re: I need to rotate a picture in a TImage 90°
« Reply #9 on: May 19, 2020, 02:04:16 am »
Still struggling.  I can get the 180° rotation to work, but the 90° and 270° always leaves black bars along the sides and the image is rotated "within" the original dimensional picture frame, if that makes sense.  Can you fix this code so it works in all cases?  thanks.

Code: Pascal  [Select][+][-]
  1. procedure GrabItRotate(const src_fnm: String; const dgr: Integer);
  2. var bmp1, bmp2: TBGRABitmap;  Center : TPointF;
  3. begin
  4.  
  5.   if (dgr = 180) then
  6.     begin
  7.   // Works
  8.       bmp1 := TBGRABitmap.Create(src_fnm);
  9.       bmp2 := TBGRABitmap.Create(bmp1.Width, bmp1.Height);
  10.       Center.x := bmp1.Width div 2;
  11.       Center.y := bmp1.Height div 2;
  12.       BGRAReplace(bmp2, bmp1.FilterRotate(Center, dgr, False));
  13.       bmp2.SaveToFile(src_fnm);
  14.     end;
  15.  
  16.   if (dgr = 90) or (dgr = 270) then
  17.     begin
  18.   // Does NOT work
  19.       bmp1 := TBGRABitmap.Create(src_fnm);
  20.       bmp2 := TBGRABitmap.Create(bmp1.Height, bmp1.Width);
  21.       Center.x := bmp1.Width div 2;
  22.       Center.y := bmp1.Height div 2;
  23.       BGRAReplace(bmp2, bmp1.FilterRotate(Center, dgr, False));
  24.       bmp2.SaveToFile(src_fnm);
  25.     end;
  26. end;

RedOctober

  • Sr. Member
  • ****
  • Posts: 330
Re: I need to rotate a picture in a TImage 90°
« Reply #10 on: May 19, 2020, 02:09:03 am »
Hi Jamie, I see where you are going with this.  Can you give me a code snippet?  I'm looking for RectangleCopy or CopyRectangle on a TBitmpap.. not there.

jamie

  • Hero Member
  • *****
  • Posts: 3520
Re: I need to rotate a picture in a TImage 90°
« Reply #11 on: May 19, 2020, 02:49:40 am »
what I was talking about is more of a mirror..


https://www.lazarusforum.de/viewtopic.php?p=33489#p33489

That is a fast 90 rotate...

and the other code is just a simple CopyRect with reverse logic on the source or destination cords for the up/down or left/right
for 90s, perform one of the simple up/down left right then do a 90.

 This is a left and top flip.

Canvas.CopyRect(Rect(100,100,0,0),Canvas,Rect(0,0,100,100));
The only true wisdom is knowing you know nothing

Thaddy

  • Hero Member
  • *****
  • Posts: 10449
Re: I need to rotate a picture in a TImage 90°
« Reply #12 on: May 19, 2020, 08:00:07 am »
On Windows, the plgblt api  is still the fasted way to rotate images at any angle.
When you ask a question that is actually answered in the documentation, you are either lazy or a moron.

winni

  • Hero Member
  • *****
  • Posts: 1778
Re: I need to rotate a picture in a TImage 90°
« Reply #13 on: May 19, 2020, 10:55:21 am »
Still struggling.  I can get the 180° rotation to work, but the 90° and 270° always leaves black bars along the sides and the image is rotated "within" the original dimensional picture frame, if that makes sense.  Can you fix this code so it works in all cases?  thanks.

Code: Pascal  [Select][+][-]
  1. procedure GrabItRotate(const src_fnm: String; const dgr: Integer);
  2. var bmp1, bmp2: TBGRABitmap;  Center : TPointF;
  3. begin
  4.  
  5.   if (dgr = 180) then
  6.     begin
  7.   // Works
  8.       bmp1 := TBGRABitmap.Create(src_fnm);
  9.       bmp2 := TBGRABitmap.Create(bmp1.Width, bmp1.Height);
  10.       Center.x := bmp1.Width div 2;
  11.       Center.y := bmp1.Height div 2;
  12.       BGRAReplace(bmp2, bmp1.FilterRotate(Center, dgr, False));
  13.       bmp2.SaveToFile(src_fnm);
  14.     end;
  15.  
  16.   if (dgr = 90) or (dgr = 270) then
  17.     begin
  18.   // Does NOT work
  19.       bmp1 := TBGRABitmap.Create(src_fnm);
  20.       bmp2 := TBGRABitmap.Create(bmp1.Height, bmp1.Width);
  21.       Center.x := bmp1.Width div 2;
  22.       Center.y := bmp1.Height div 2;
  23.       BGRAReplace(bmp2, bmp1.FilterRotate(Center, dgr, False));
  24.       bmp2.SaveToFile(src_fnm);
  25.     end;
  26. end;

Hi!

As the angles 90°,180° and 270° are only special cases there will allways be a border.
This is needed if you rotate with other angles.

You can cut the border off:
you know the center and the width and height of the original.
So you can compute the bounding box of the new bitmap.

Code: Pascal  [Select][+][-]
  1. var R : Trect;
  2.  
  3. .....
  4. CroppedBitmap := TBGRABitmap (RotatedBitmap.GetPart(R));
  5.  

The problem with 180° I don't know but I think I never tested it.

The workaround is:

Code: Pascal  [Select][+][-]
  1. OrigBitmap.VerticalFlip;
  2. OrigBitmap.HorzontalFlip;
  3.  

Winni


« Last Edit: May 19, 2020, 11:00:23 am by winni »

winni

  • Hero Member
  • *****
  • Posts: 1778
Re: I need to rotate a picture in a TImage 90°
« Reply #14 on: May 19, 2020, 11:30:43 am »
@RedOctober

I have just tested

FilterRotateAngle(center,180,false);

For me it works as it should - no problems.

There must be an other error in the code.

Winni

 

TinyPortal © 2005-2018