Recent

Author Topic: Capturing a specific part of the screen.  (Read 9047 times)

Mr.Madguy

  • Hero Member
  • *****
  • Posts: 670
Re: Capturing a specific part of the screen.
« Reply #15 on: February 04, 2021, 07:18:38 am »
You always forget, that Canvas.Handle is actually DC.

So, it's:
Code: Pascal  [Select][+][-]
  1. procedure TForm1.Button1Click(Sender: TObject);
  2.   var ScreenCanvas:TCanvas;
  3.   Bitmap:TBitmap;
  4. begin
  5.   ScreenCanvas := TCanvas.Create;
  6.   ScreenCanvas.Handle := GetDC(0);
  7.   Bitmap := TBitmap.Create;
  8.   Bitmap.Width := 500;
  9.   Bitmap.Height := 500;
  10.   Bitmap.Canvas.CopyRect(
  11.     TRect.Create(TPoint.Create(0, 0), Bitmap.Width, Bitmap.Height),
  12.     ScreenCanvas,
  13.     TRect.Create(TPoint.Create(100, 100), Bitmap.Width, Bitmap.Height)
  14.   );
  15.   Image1.Picture.Bitmap.Assign(Bitmap);
  16.   ScreenCanvas.Free;
  17. end;
  18.  
30.04.2021 - DynamicData 4.0 is released and migration to it is completed.
It's more Lazarus-friendly, but still requires full Delphi 2009 support to be ported to Lazarus.
It's time to finally do it, because Delphi 2009 is 12 years old.

BosseB

  • Sr. Member
  • ****
  • Posts: 358
Re: Capturing a specific part of the screen.
« Reply #16 on: April 29, 2021, 04:14:41 pm »
hello,
try this :
Code: Pascal  [Select][+][-]
  1.  Clipboard.Assign(MyCapture.Bitmap);

Friendly, J.P

Hi J.P.,
I am back now since I need another function and I thought it would be consistent to use the same thread...

Now a need for saving the screenshot to disk has come up (from my wife), so I tried to add a function to my app where I could save the captured image on disk.

I tested with this piece of code before adding the save dialogue etc:
Code: Pascal  [Select][+][-]
  1. procedure TfrmMain.CopyScreenRect(arg: PtrInt);
  2. var
  3.   MyCapture : TBgraBitmap;
  4.   Clip: TRect;
  5.   X, Y, W, H: integer;
  6. begin
  7.   try
  8.     Clip := Bounds(Self.Left, Self.Top, Self.Width, Self.Height);
  9.     X := Self.Left;
  10.     Y := Self.Top;
  11.     W := Self.Width;
  12.     H := Self.Height;
  13.     Self.Visible := false;
  14.     MyCapture := TBgraBitmap.Create();
  15.     try
  16.       MyCapture.TakeScreenShot(Clip);
  17.       Self.Visible := true;
  18.       Self.Left := X;
  19.       Self.Top :=  Y;
  20.       Self.Width := W;
  21.       Self.Height := H;
  22.       Clipboard.Assign(MyCapture.Bitmap);
  23.       MyCapture.Bitmap.SaveToFile(ChangeFileExt(ParamStr(0), '.jpg')); //<<= This is new for testing
  24.     finally
  25.       MyCapture.Free;
  26.     end;
  27.   except
  28.     on E: exception do
  29.       Clipboard.AsText := E.Message;
  30.   end;
  31. end;
  32.  

When I run the program it creates the file in the application directory, but it is not a valid jpg file...
So now I wonder how I can save to a format given by the file extension (jpg, png, bmp etc)?
--
Bo Berglund
Sweden

winni

  • Hero Member
  • *****
  • Posts: 2478
Re: Capturing a specific part of the screen.
« Reply #17 on: April 29, 2021, 06:18:18 pm »
Hi!

If you only want a part of the screen use BGRAbitmap.getpart:


Code: Pascal  [Select][+][-]
  1. MyCapture.TakeScreenShot(Clip);
  2. R := Rect .....
  3. BGRAreplace (MyCapture, MyCapture.getPart(R) );
  4.  

Second : Save the BGRAbitmap to a PNG file without problems:

Code: Pascal  [Select][+][-]
  1. MyCapture.SaveToFile('Filename.png');
  2.  
And last: Draw the BGRAbitmap to the Canvas of the Image:
Code: Pascal  [Select][+][-]
  1. MyCapture.Draw(Image1.Canvas,0,0);

And to have a first look at the huge amount of options read the BGRAdefaultBitmap.pas.

Winni


BosseB

  • Sr. Member
  • ****
  • Posts: 358
Re: Capturing a specific part of the screen.
« Reply #18 on: April 29, 2021, 06:25:20 pm »
OK thanks,
but what I asked was how to save the already captured image to disk in jpg, png and bmp formats....
All of the capturing stuff is working fine already.

Now after searching a bit more I have done this:
Code: Pascal  [Select][+][-]
  1. var
  2.   ...
  3.   Jpg: TJpegImage;
  4.   Png: TPortableNetworkGraphic;
  5. begin
  6.   ...
  7.     Jpg := TJpegImage.Create;
  8.     Png := TPortableNetworkGraphic.Create;
  9.   ...
  10.       Clipboard.Assign(MyCapture.Bitmap);
  11.       Jpg.Assign(MyCapture.Bitmap);
  12.       Png.Assign(MyCapture.Bitmap);
  13.       Jpg.SaveToFile(ChangeFileExt(ParamStr(0), '.jpg'));
  14.       Png.SaveToFile(ChangeFileExt(ParamStr(0), '.png'));
  15.   ...
  16.     finally
  17.       Png.Free;
  18.       Jpg.Free;
  19.       MyCapture.Free;
  20.     end;
  21.  

And it works fine, so now I will integrate a file save dialog into the application so the user can select which path, name and type to save to.
--
Bo Berglund
Sweden

winni

  • Hero Member
  • *****
  • Posts: 2478
Re: Capturing a specific part of the screen.
« Reply #19 on: April 29, 2021, 07:11:29 pm »
Hi!

I dont know why you want to go the complicated way.
It is already all there in the BGRAbitmap:

Code: Pascal  [Select][+][-]
  1. var BM : TBGRAbitmap:
  2. ...
  3. BM.SaveToFile ('Test.jpg');
  4. BM.SaveToFile ('Test.png');
  5. BM.SaveToFile ('Test.tif');
  6. BM.SaveToFile ('Test.bmp');
  7. ....
  8.  

Winni



winni

  • Hero Member
  • *****
  • Posts: 2478
Re: Capturing a specific part of the screen.
« Reply #20 on: April 29, 2021, 07:34:00 pm »
Hi!

A list of supported file types you can find in the unit BGRAbitmapTypes:

Code: Pascal  [Select][+][-]
  1.   {* List of image formats }
  2.   TBGRAImageFormat = (
  3.     {** Unknown format }
  4.     ifUnknown,
  5.     {** JPEG format, opaque, lossy compression }
  6.     ifJpeg,
  7.     {** PNG format, transparency, lossless compression }
  8.     ifPng,
  9.     {** GIF format, single transparent color, lossless in theory but only low number of colors allowed }
  10.     ifGif,
  11.     {** BMP format, transparency, no compression. Note that transparency is
  12.         not supported by all BMP readers so it is recommended to avoid
  13.         storing images with transparency in this format }
  14.     ifBmp,
  15.     {** iGO BMP (16-bit, rudimentary lossless compression) }
  16.     ifBmpMioMap,
  17.     {** ICO format, contains different sizes of the same image }
  18.     ifIco,
  19.     {** CUR format, has hotspot, contains different sizes of the same image }
  20.     ifCur,
  21.     {** PCX format, opaque, rudimentary lossless compression }
  22.     ifPcx,
  23.     {** Paint.NET format, layers, lossless compression }
  24.     ifPaintDotNet,
  25.     {** LazPaint format, layers, lossless compression }
  26.     ifLazPaint,
  27.     {** OpenRaster format, layers, lossless compression }
  28.     ifOpenRaster,
  29.     {** Phoxo format, layers }
  30.     ifPhoxo,
  31.     {** Photoshop format, layers, rudimentary lossless compression }
  32.     ifPsd,
  33.     {** Targa format (TGA), transparency, rudimentary lossless compression }
  34.     ifTarga,
  35.     {** TIFF format, limited support }
  36.     ifTiff,
  37.     {** X-Window capture, limited support }
  38.     ifXwd,
  39.     {** X-Pixmap, text encoded image, limited support }
  40.     ifXPixMap,
  41.     {** text or binary encoded image, no compression, extension PBM, PGM, PPM }
  42.     ifPortableAnyMap,
  43.     {** Scalable Vector Graphic, vectorial, read-only as raster }
  44.     ifSvg,
  45.     {** Lossless or lossy compression using V8 algorithm (need libwebp library) }
  46.     ifWebP);
  47.  
  48.  

Winni

BosseB

  • Sr. Member
  • ****
  • Posts: 358
Re: Capturing a specific part of the screen.
« Reply #21 on: April 29, 2021, 11:53:42 pm »
Hi!

I dont know why you want to go the complicated way.
It is already all there in the BGRAbitmap:

Code: Pascal  [Select][+][-]
  1. var BM : TBGRAbitmap:
  2. ...
  3. BM.SaveToFile ('Test.jpg');
  4. BM.SaveToFile ('Test.png');
  5. BM.SaveToFile ('Test.tif');
  6. BM.SaveToFile ('Test.bmp');
  7. ....
  8.  

Winni

So you mean that if the TBgraBitmap object can do this all by itself, basically just defined by the name of the target file (or the extension of the file name)?
Well, now I have made a test and sure enough! I can cut away a whole lot of code because the capture object (TBgraBitmap) can in fact save all by itself to such files!

Boy, did I not realize the versatility of this imaging class!
Thanks for pointing it out, I am now removing a LOT of un-needed code...
--
Bo Berglund
Sweden

 

TinyPortal © 2005-2018