Recent

Author Topic: [SOLVED] How to assign a TPicture to a BGRABitmap and rotate it?  (Read 8366 times)

CM630

  • Hero Member
  • *****
  • Posts: 1091
  • Не съм сигурен, че те разбирам.
    • http://sourceforge.net/u/cm630/profile/
[SOLVED] How to assign a TPicture to a BGRABitmap and rotate it?
« on: September 27, 2017, 01:31:24 pm »
I need to rotate an image. As far as I understood I have to use BGRABitmap or another non-native lazarus component.
My image is stored in Picture: tPicture;

I did
Code: Pascal  [Select][+][-]
  1. ..uses... BGRABitmap..
  2.  
  3. function Some(Picture: tPicture)...
  4. var
  5.   Bitmap: tBGRABitmap;
  6. begin
  7. ...
  8.     Bitmap:=TBGRABitmap.Create(width, height) ;
  9. ...
  10. end.
  11.  

And I am stuck...
How am I to put the image from Picture into Bitmap? And how to put it back from Bitmap into Picture after rotating it?

I tried Bitmap.Assign(DispPicture.Picture);    but application crashes when doing it.
« Last Edit: September 29, 2017, 07:20:45 pm by CM630 »
Лазар 3,2 32 bit (sometimes 64 bit); FPC3,2,2; rev: Lazarus_3_0 on Win10 64bit.

Handoko

  • Hero Member
  • *****
  • Posts: 5158
  • My goal: build my own game engine using Lazarus
Re: How to assign a TPicture to a BGRABitmap?
« Reply #1 on: September 27, 2017, 02:51:33 pm »
You can find BGRABitmap tutorials here:
http://wiki.lazarus.freepascal.org/BGRABitmap_tutorial

Rotating image is in tutorial #14.

CM630

  • Hero Member
  • *****
  • Posts: 1091
  • Не съм сигурен, че те разбирам.
    • http://sourceforge.net/u/cm630/profile/
Re: How to assign a TPicture to a BGRABitmap?
« Reply #2 on: September 27, 2017, 03:54:17 pm »
Rotating image is in tutorial #14.
Thanks, but I cannot even get to rotation, since I have no idea how to put the image into the bitmap.


I tried also
   Bitmap.Assign(Picture.Bitmap);
and
   Bitmap.Canvas.Assign(Picture.Bitmap.Canvas); 
but the app keeps crashing.
« Last Edit: September 27, 2017, 04:02:20 pm by CM630 »
Лазар 3,2 32 bit (sometimes 64 bit); FPC3,2,2; rev: Lazarus_3_0 on Win10 64bit.

Almir.Bispo

  • Jr. Member
  • **
  • Posts: 91
  • CSV Comp DB is the Best NoSQL
    • CSV Comp DB (NoSQL)
Re: How to assign a TPicture to a BGRABitmap?
« Reply #3 on: September 27, 2017, 04:01:12 pm »
I did it:
Code: Pascal  [Select][+][-]
  1. image1.canvas.draw(0,0,mybitmap);
  2. //mybitmap must be a Tbitmap class object
  3.  
my blog:http://adltecnologia.blogspot.com.br
CSV Comp DB Developer {Pascal Lover}

CM630

  • Hero Member
  • *****
  • Posts: 1091
  • Не съм сигурен, че те разбирам.
    • http://sourceforge.net/u/cm630/profile/
Re: How to assign a TPicture to a BGRABitmap?
« Reply #4 on: September 27, 2017, 04:08:31 pm »

I just did:
Bitmap.Canvas.StretchDraw(Rect(0,0,100,100),DispPicture.Picture.Graphic); and nothing crashes.
I will try Almir.Bispo's solution.

[EDIT] Almir's thing works for me, but Bitmap.RotateCCW;   seems to do nothing. I will keep digging.
« Last Edit: September 27, 2017, 04:21:39 pm by CM630 »
Лазар 3,2 32 bit (sometimes 64 bit); FPC3,2,2; rev: Lazarus_3_0 on Win10 64bit.

RAW

  • Hero Member
  • *****
  • Posts: 868
Re: How to assign a TPicture to a BGRABitmap?
« Reply #5 on: September 27, 2017, 07:27:54 pm »
Play around with this...   :)

Code: Pascal  [Select][+][-]
  1. Procedure TwndMS.FormClick(Sender: TObject);
  2.   Var
  3.    PIC : TPicture;
  4.    BGRA: TBGRABitmap;
  5.  Begin
  6.   PIC:= TPicture.Create;
  7.    Try
  8.     PIC.LoadFromFile('C:\...\LazLogo Blue.png');
  9.  
  10.     BGRA:= TBGRABitmap.Create(PIC.Bitmap);
  11.      Try
  12.       //BGRA.PutImageAngle();
  13.       PIC.Assign(BGRA);
  14.      Finally
  15.       BGRA.Free;
  16.      End;
  17.     imgMS.Picture.Assign(PIC);
  18.    Finally
  19.     PIC.Free;
  20.    End;
  21.  End;
Windows 7 Pro (x64 Sp1) & Windows XP Pro (x86 Sp3).

RAW

  • Hero Member
  • *****
  • Posts: 868
Re: How to assign a TPicture to a BGRABitmap?
« Reply #6 on: September 28, 2017, 01:15:30 am »
This works for me...

Code: Pascal  [Select][+][-]
  1. Procedure TwndMS.FormClick(Sender: TObject);
  2.   Var
  3.    PIC: TPicture;
  4.    BGRAout, BGRAin: TBGRABitmap;
  5.  Begin
  6.   PIC:= TPicture.Create;
  7.    Try
  8.     PIC.LoadFromFile('C:\...\LazLogo Blue.png');
  9.  
  10.     BGRAout:= TBGRABitmap.Create(PIC.Width, PIC.Height, BGRAPixelTransparent);
  11.      Try
  12.       BGRAin:= TBGRABitmap.Create(PIC.Bitmap);
  13.        Try
  14.         BGRAout.PutImageAngle(PIC.Width, PIC.Height, BGRAin, 180, rfBestQuality);
  15.        Finally
  16.         BGRAin.Free;
  17.        End;
  18.       PIC.Assign(BGRAout);
  19.      Finally
  20.       BGRAout.Free;
  21.      End;
  22.     imgMS.Picture.Assign(PIC);
  23.    Finally
  24.     PIC.Free;
  25.    End;
  26.  End;

GDI+ Example
// USES GDIPObj, GDIPApi (and you need to include the PAS files inside GDI+.zip) 
Code: Pascal  [Select][+][-]
  1. Procedure TwndMS.FormClick(Sender: TObject);
  2.   Var
  3.    GP  : TGPImage;
  4.    GPGR: TGPGraphics;
  5.  Begin
  6.   GP:= TGPImage.Create('C:\LazLogo Blue.png', True);
  7.    Try
  8.     GP.RotateFlip(Rotate180FlipNone);
  9.     GPGR:= TGPGraphics.Create(wndMS.Canvas.Handle);
  10.      Try
  11.       GPGR.DrawImage(GP, 0, 0);
  12.      Finally
  13.       GPGR.Free;
  14.      End;
  15.    Finally
  16.     GP.Free;
  17.    End;
  18.  End;

Result: GDI+ is sharper and looks better, but it's not much... And on the other hand GDI+ wants to establish a global hook and needs a direct memory access... BGRABitmap doesn't need this...
« Last Edit: September 30, 2017, 09:02:52 pm by RAW »
Windows 7 Pro (x64 Sp1) & Windows XP Pro (x86 Sp3).

CM630

  • Hero Member
  • *****
  • Posts: 1091
  • Не съм сигурен, че те разбирам.
    • http://sourceforge.net/u/cm630/profile/
Re: How to assign a TPicture to a BGRABitmap?
« Reply #7 on: September 28, 2017, 09:12:15 am »


Thanks!
  BGRAout.PutImageAngle(PIC.Width, PIC.Height, BGRAin, 180, rfBestQuality); works!

  Still I have no clue why Bitmap.RotateCCW does not work, maybe it should be faster, but I guess PutImageAngle will be fast enough for my needs.


Update:
BGRAout.PutImageAngle(PIC.Width, PIC.Height, BGRAin, 0, rfBestQuality);
does not work for me. Instead of having a non-rotated image, I get an empty one.
« Last Edit: September 29, 2017, 07:41:33 am by CM630 »
Лазар 3,2 32 bit (sometimes 64 bit); FPC3,2,2; rev: Lazarus_3_0 on Win10 64bit.

lainz

  • Hero Member
  • *****
  • Posts: 4473
    • https://lainz.github.io/
Re: How to assign a TPicture to a BGRABitmap and rotate it?
« Reply #8 on: September 29, 2017, 04:22:20 pm »
See attached project.

Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ExtCtrls,
  9.   BGRABitmap;
  10.  
  11. type
  12.  
  13.   { TForm1 }
  14.  
  15.   TForm1 = class(TForm)
  16.     Image1: TImage;
  17.     procedure FormCreate(Sender: TObject);
  18.     procedure FormDestroy(Sender: TObject);
  19.     procedure Image1Click(Sender: TObject);
  20.   private
  21.     bmp: TBGRABitmap;
  22.     procedure Rotate(Picture: TPicture);
  23.  
  24.   public
  25.  
  26.   end;
  27.  
  28. var
  29.   Form1: TForm1;
  30.  
  31. implementation
  32.  
  33. {$R *.lfm}
  34.  
  35. { TForm1 }
  36.  
  37. procedure TForm1.Image1Click(Sender: TObject);
  38. begin
  39.   Rotate(Image1.Picture);
  40. end;
  41.  
  42. procedure TForm1.FormCreate(Sender: TObject);
  43. begin
  44.   bmp := TBGRABitmap.Create();
  45. end;
  46.  
  47. procedure TForm1.FormDestroy(Sender: TObject);
  48. begin
  49.   bmp.Free;
  50. end;
  51.  
  52. procedure TForm1.Rotate(Picture: TPicture);
  53. begin
  54.   bmp.Free;
  55.   bmp := TBGRABitmap.Create(Picture.Bitmap);
  56.   BGRAReplace(bmp, bmp.RotateCW);
  57.   Picture.Assign(bmp.Bitmap);
  58. end;
  59.  
  60. end.

Edit, I think this Rotate method is better than the previous one:

Code: Pascal  [Select][+][-]
  1. procedure TForm1.Rotate(Picture: TPicture);
  2. begin
  3.   bmp.Assign(Picture.Bitmap);
  4.   BGRAReplace(bmp, bmp.RotateCW);
  5.   Picture.Assign(bmp.Bitmap);
  6. end;  
« Last Edit: September 29, 2017, 04:33:49 pm by lainz »

CM630

  • Hero Member
  • *****
  • Posts: 1091
  • Не съм сигурен, че те разбирам.
    • http://sourceforge.net/u/cm630/profile/
Re: How to assign a TPicture to a BGRABitmap and rotate it?
« Reply #9 on: September 29, 2017, 04:49:51 pm »
Thanks, as far as I tried it BGRAReplace(bmpRotateCW); works for me.
But how am I to rotate the image at 180 degrees? Shall I run bmp.RotateCW twice or it could be done faster?
I found no other „Rotate‟ routine.


Edit: Thanks, I saw you've answered while I was editing my post.
« Last Edit: September 29, 2017, 04:54:06 pm by CM630 »
Лазар 3,2 32 bit (sometimes 64 bit); FPC3,2,2; rev: Lazarus_3_0 on Win10 64bit.

lainz

  • Hero Member
  • *****
  • Posts: 4473
    • https://lainz.github.io/
Re: How to assign a TPicture to a BGRABitmap and rotate it?
« Reply #10 on: September 29, 2017, 04:53:19 pm »
That post says that is a layers feature. Just run it twice and you will be fine.

circular

  • Hero Member
  • *****
  • Posts: 4221
    • Personal webpage
Re: [SOLVED] How to assign a TPicture to a BGRABitmap and rotate it?
« Reply #11 on: October 03, 2017, 07:14:40 pm »
You can rotate 180 degrees by calling HorizontalFlip and VerticalFlip:
Code: Delphi  [Select][+][-]
  1. procedure TForm1.Rotate180(Picture: TPicture);
  2. var bmp: TBGRABitmap;
  3. begin
  4.   bmp := TBGRABitmap.Create;
  5.   bmp.Assign(Picture.Bitmap);
  6.   bmp.HorizontalFlip;
  7.   bmp.VerticalFlip;
  8.   Picture.Assign(bmp.Bitmap);
  9.   bmp.Free;
  10. end;
Conscience is the debugger of the mind

RAW

  • Hero Member
  • *****
  • Posts: 868
Re: [SOLVED] How to assign a TPicture to a BGRABitmap and rotate it?
« Reply #12 on: October 07, 2017, 05:54:49 pm »
@circular: Thanks for the example...
I tried to rotate a PNG with BGRACanvas2D, but I think it's not intended to work like this... Probably only for rotating the canvas or I did it totally wrong...  :)

Code: Pascal  [Select][+][-]
  1. Procedure TwndMS.FormClick(Sender: TObject);
  2.   Var
  3.    BMP, BMP2: TBGRABitmap;
  4.    gpIMG    : TGPImage;
  5.    gpGR     : TGPGraphics;
  6.  Begin
  7.   BMP := TBGRABitmap.Create('C:\LazLogo Blue.png');
  8.   BMP2:= TBGRABitmap.Create(BMP);
  9.    Try
  10.     // BGRA Flip
  11.     BMP2.HorizontalFlip;
  12.     BMP2.VerticalFlip;
  13.     BMP2.Draw(Canvas, 0, 0, False);
  14.  
  15.     // BGRA CW
  16.     BMP2.Assign(BMP);
  17.     BGRAReplace(BMP2, BMP2.RotateCW);
  18.     BGRAReplace(BMP2, BMP2.RotateCW);
  19.     BMP2.Draw(Canvas, 100, 0, False);
  20.  
  21.     // GDI+
  22.     gpIMG:= TGPImage.Create('C:\LazLogo Blue.png', True);
  23.      Try
  24.       gpIMG.RotateFlip(Rotate180FlipNone);
  25.       gpGR:= TGPGraphics.Create(Canvas.Handle);
  26.        Try
  27.         gpGR.DrawImage(gpIMG, 200, 0);
  28.        Finally
  29.         gpGR.Free;
  30.        End;
  31.      Finally
  32.       gpIMG.Free;
  33.      End;
  34.  
  35.     // BGRA PutImageAngle
  36.     BMP2.Free;
  37.     BMP2:= TBGRABitmap.Create(BMP.Width, BMP.Height, BGRAPixelTransparent);
  38.     BMP2.PutImageAngle(BMP.Width, BMP.Height, BMP, 180, rfBestQuality);
  39.     BMP2.Draw(Canvas, 300, 0, False);
  40.    Finally
  41.     BMP.Free;
  42.     BMP2.Free;
  43.    End;
  44.  End;

Windows 7 Pro (x64 Sp1) & Windows XP Pro (x86 Sp3).

RAW

  • Hero Member
  • *****
  • Posts: 868
Re: [SOLVED] How to assign a TPicture to a BGRABitmap and rotate it?
« Reply #13 on: October 07, 2017, 07:31:39 pm »
BTW: I get an error in BgraReadPng.pas if I switch to DebugMode...
If I use the ReleaseMode then everything is fine (XPx86 SP3, LAZ 1.6.4 FPC 3.0.2).
Windows 7 Pro (x64 Sp1) & Windows XP Pro (x86 Sp3).

 

TinyPortal © 2005-2018