Recent

Author Topic: TBitMap to TBGRABitmap then resize.  (Read 5088 times)

ghamm

  • New Member
  • *
  • Posts: 29
TBitMap to TBGRABitmap then resize.
« on: March 14, 2020, 10:52:51 pm »
Im new to this lib. I have a bitmap from another source.. I need to use BRGA to downscale it, then display it.. I cant for the life of me get this to work. Im sure Im doing something stupid. Heres a stripped down version.



procedure Resize;
var  BRGAbitmap: TBGRABitmap;
var aBitmap : Tbitmap;
begin
  aBitmap:=Tbitmap.Create;
  aBitmap.SetSize(100, 100);
  BRGABitmap := TBGRABitmap.Create(100, 100, BGRAPixelTransparent);
  Try
    //Bitmap.Bitmap.PixelFormat:= pf24bit;
    BRGABitmap.Bitmap.Assign(aBitmap);

    BRGABitmap.ResampleFilter:=rfBestQuality;
    BRGABitmap.Resample(90, 90, rmFineResample); <<< access violation here..
    BRGABitmap.Draw(canvas,0,0);   << access violation here
  Finally
    BRGABitmap.Free;
    ABitmap.Free;
  End;


circular

  • Hero Member
  • *****
  • Posts: 4467
    • Personal webpage
Re: TBitMap to TBGRABitmap then resize.
« Reply #1 on: March 14, 2020, 11:48:22 pm »
Hi ghamm,

To assign the bitmap you can do:
Code: Delphi  [Select][+][-]
  1. bgra := TBGRABitmap.Create(aBitmap);
or
Code: Delphi  [Select][+][-]
  1. bgra := TBGRABitmap.Create(0,0);
  2. bgra.Assign(aBitmap);

To resample, you need to retrieve the result:
Code: Delphi  [Select][+][-]
  1. BGRAReplace(bgra, bgra.Resample(90, 90, rmFineResample));

Does it solve the problem?
Conscience is the debugger of the mind

winni

  • Hero Member
  • *****
  • Posts: 3197
Re: TBitMap to TBGRABitmap then resize.
« Reply #2 on: March 14, 2020, 11:57:11 pm »
Hi!

BGRAbitmap often helps you shorten your code.
But it is not good documented ....

Here we go:

Code: Pascal  [Select][+][-]
  1. procedure TForm1.ResizeMap;
  2. var  BRGAbitmap: TBGRABitmap;
  3. var aBitmap : Tbitmap;
  4. begin
  5.   aBitmap:=Tbitmap.Create;
  6.   aBitmap.SetSize(100, 100);
  7.   BRGABitmap := TBGRABitmap.Create(aBitmap);
  8.   BGRABitmap.DrawLineAntialias(0,0,100,100,clRed,5);
  9.  
  10.   BRGABitmap.ResampleFilter:=rfBestQuality;
  11.   BGRAReplace (BGRAbitmap, BRGABitmap.Resample(90, 90, rmFineResample) );
  12.   BGRAbitmap.draw(Canvas, 0,0);
  13.    BRGABitmap.Free;
  14.   ABitmap.Free;
  15.   End;


Winni

ghamm

  • New Member
  • *
  • Posts: 29
Re: TBitMap to TBGRABitmap then resize.
« Reply #3 on: March 15, 2020, 01:50:37 am »
Ok, that worked fine.. Thanks so much.

Im using that resample function to downscale a Tbitmap/photo to 64x64. It will of course be very pixelated.
It shows find on my canvas now.. but its very small of course..

On the canvas on my panel, I want to zoom or expand my 64x64 image to fill the panel and show the grainy photo.
If I use scale, I assume thats the same as resample? Im assuming I dont want that?

Im thinking I want to show my image using zoom of sorts?
what function would I use?



winni

  • Hero Member
  • *****
  • Posts: 3197
Re: TBitMap to TBGRABitmap then resize.
« Reply #4 on: March 15, 2020, 02:20:45 am »
Hi!

If you work with photos then one hint:
Use a Timage. This is persistent and you dont have to take care about the onPaint event.

The next demo assumes that you have a TImage lets say minimum 300x300 on your Form.
To make different zooms just keep a master in the RAM and make copies to zoom out.
The rmFineResample is a very good filter.
In the source you must change the const path and name of MyPicture to your needs.

Code: Pascal  [Select][+][-]
  1. procedure TForm1.ZoomTest;
  2. const MyPicture = 'C:\users\WhoAmI\Holdiday.png';
  3. var master, work : TBGRABitmap;
  4. begin
  5. master := TBGRAbitmap.create (MyPicture); // loads photo
  6. work := TBGRAbitmap.create (master);  // makes a copy
  7. // eye test:
  8. BGRAReplace (work, work.resample (32,32) ); //   rmFineResample is default
  9. work.draw (Image1.Canvas,0,0);
  10. work.free;
  11. // icon:
  12. work := TBGRAbitmap.create (master);  // makes a copy
  13. BGRAReplace (work, work.resample (96,96) );
  14. work.draw (Image1.Canvas,50,0);
  15. work.free;
  16. // master - shows only a part because it will not fit
  17. master.draw (Image1.Canvas,0,100);
  18. master.free;
  19. end;
  20.  

Winni

ghamm

  • New Member
  • *
  • Posts: 29
Re: TBitMap to TBGRABitmap then resize.
« Reply #5 on: March 15, 2020, 02:37:32 am »
Writing to the Timage canvas works fine.. but the image is very very small in the corner. I would like to see my 32x32 image blown up large, and grainy and pixelated. I tried to set the property stretch=true but not working .. I assume its because it writing straight to the canvas. Since Im capturing this as a single  frame from a webcam, it needs to write several frames per second as a converted bitmap very fast. When I tried the picture method, it worked, and blew up fine.. but died  very fast as I am sending it about 10 bitmaps per second.

Any thoughts?

circular

  • Hero Member
  • *****
  • Posts: 4467
    • Personal webpage
Re: TBitMap to TBGRABitmap then resize.
« Reply #6 on: March 15, 2020, 10:15:32 am »
I think that writing to the Image1.Canvas is like drawing directly like you would do with OnPaint. Instead you would rather need to do:
Code: Delphi  [Select][+][-]
  1. procedure TForm1.ZoomTest;
  2. const MyPicture = 'C:\users\WhoAmI\Holdiday.png';
  3.       SizeX = 32; SizeY = 32;
  4. var source, work : TBGRABitmap;
  5. begin
  6.   source := TBGRAbitmap.create (MyPicture); // loads photo
  7.   work := source.resample (SizeX,SizeY); //   rmFineResample is default
  8.   Image1.Picture.Bitmap.SetSize(SizeX,SizeY);
  9.   work.draw (Image1.Picture.Bitmap.Canvas,0,0);
  10.   work.free;
  11.   source.free;
  12.   Image1.Stretch := true;
  13. end;

Now the Stretch property will not discard the image. Note that sometimes the stretched image is not pixelated. If you want to ensure it is pixelated then you can do:

Code: Delphi  [Select][+][-]
  1. uses BGRABitmap, BGRABitmapTypes;
  2.  
  3. { TForm1 }
  4.  
  5. procedure TForm1.FormCreate(Sender: TObject);
  6. const MyPicture = 'C:\users\WhoAmI\Holdiday.png';
  7. var
  8.   bgra: TBGRABitmap;
  9.   bmpCopy: TBitmap;
  10. begin
  11.   bgra := TBGRABitmap.Create(MyPicture, true); //code is in UTF8
  12.   BGRAReplace(bgra, bgra.Resample(32,32)); //make it smaller
  13.   BGRAReplace(bgra, bgra.Resample(Image1.Width,image1.Height, rmSimpleStretch)); //stretch it pixelated
  14.   bmpCopy := bgra.MakeBitmapCopy(clBtnFace); //make opaque bitmap to display
  15.   Image1.Picture.Bitmap.Assign(bmpCopy); //assign it to TImage
  16.   bmpCopy.Free;
  17.   bgra.Free;
  18. end;
Conscience is the debugger of the mind

ghamm

  • New Member
  • *
  • Posts: 29
Re: TBitMap to TBGRABitmap then resize.
« Reply #7 on: March 16, 2020, 02:26:44 am »
Thankyou!

ghamm

  • New Member
  • *
  • Posts: 29
Re: TBitMap to TBGRABitmap then resize.
« Reply #8 on: March 23, 2020, 05:52:27 pm »
I am able to grab an image from my video stream.. Works great using the BGRAReplace(bgra, bgra.Resample(32,32))  etc..

Now, Im trying to display it to the TImage on my main form.

I want to see every pixel.. but many times it applies some sort of interpolation or antialiasing.. I dont want that. If I turn off the Antialiasing, it doesnt work either..

Look at both pics.. I want the one that shows the pixel blocks.. NOT the blended one.. How can i force it NOT interpolate? I am using the stretch property on the Timage to zoom in.

The only time I can get it to work right is by calling a video function that has nothing to do with my bitmap, its actually a video filter function.. So weird that that actually makes it work when it has nothing to do with my Timage.


« Last Edit: March 23, 2020, 05:59:04 pm by ghamm »

winni

  • Hero Member
  • *****
  • Posts: 3197
Re: TBitMap to TBGRABitmap then resize.
« Reply #9 on: March 23, 2020, 06:32:57 pm »
Hi!

For the BGRAbitmap there is a function

Code: Pascal  [Select][+][-]
  1. function FilterPixelate(pixelSize: integer; useResample: boolean; filter: TResampleFilter = rfLinear): TBGRACustomBitmap; override;
  2.  
Perhaps it works for you.

Winni

ghamm

  • New Member
  • *
  • Posts: 29
Re: TBitMap to TBGRABitmap then resize.
« Reply #10 on: March 23, 2020, 06:37:25 pm »
I dont think there is any issue with the new bitmap.. Its the way that TImage is showing on the screen. It is modifying it, smoothing it, trying to make it look better.

I want the TImage to show the raw image.

winni

  • Hero Member
  • *****
  • Posts: 3197
Re: TBitMap to TBGRABitmap then resize.
« Reply #11 on: March 23, 2020, 06:49:36 pm »
If you only do a draw from the BGRAbitmap to the TBitmap of the TImage it just makes an exact copy.

When you turn the Stretch in the TImage you loose  control over the quality. Turn that off. and then  resize your BGRAbitmap to the size of the TImage. And then do a draw.

Winni

circular

  • Hero Member
  • *****
  • Posts: 4467
    • Personal webpage
Re: TBitMap to TBGRABitmap then resize.
« Reply #12 on: March 23, 2020, 07:35:39 pm »
@ghamm: Stretching is done with this line in the second example I gave you
Code: Delphi  [Select][+][-]
  1. BGRAReplace(bgra, bgra.Resample(Image1.Width,image1.Height, rmSimpleStretch));
Conscience is the debugger of the mind

ghamm

  • New Member
  • *
  • Posts: 29
Re: TBitMap to TBGRABitmap then resize.
« Reply #13 on: March 24, 2020, 08:32:11 pm »
Ahh yes, I see it..

I needed both lines of code If I want to blow it up and see the pixels..

 BGRAReplace(tmp, tmp.Resample(LEDPixelCols, LEDPixelRows, rmFineResample));
 BGRAReplace(tmp, tmp.Resample(NewImageWidth, NewImageHeight, rmSimpleStretch));       


Thanks..

circular

  • Hero Member
  • *****
  • Posts: 4467
    • Personal webpage
Re: TBitMap to TBGRABitmap then resize.
« Reply #14 on: March 25, 2020, 07:17:24 pm »
No problem  :)
Conscience is the debugger of the mind

 

TinyPortal © 2005-2018