Recent

Author Topic: Copying images from a Lazarus application  (Read 5150 times)

hakelm

  • Full Member
  • ***
  • Posts: 153
Copying images from a Lazarus application
« on: February 17, 2018, 04:00:10 pm »
If I copy an image with
  clipboard.Assign(image1.Picture.Graphic);
I can paste the result into say Gimp or Thunderbird but not into for instance Libre Office. Looking into the clipboard formats with the code below I get

*********************
0 image/jpeg: 120
*********************

If I on the other hand copy an image from Gimp or a browser I get format contents like:

*********************
0 TIMESTAMP: 140
1 TARGETS: 137
2 MULTIPLE: 139
3 SAVE_TARGETS: 141
4 image/png: 119
5 image/tiff: 160
6 image/x-icon: 161
7 image/x-ico: 162
8 image/x-win-bitmap: 163
9 image/bmp: 117
10 image/x-bmp: 164
11 image/x-MS-bmp: 165
12 image/jpeg: 120
13 : 0
14 : 0
15 : 65765505
16 : 140737354051384
17 : 0
18 : 0
19 : 0
20 : 0
21 : 0
22 : 0
23 : 0
24 : 0
25 : 0
*********************

and the clipboard content seems to be acceptable by most applications.
How can I get the same or similar behaviour in a Lazarus application?
Thanks for any tip.
H

procedure TForm1.BitBtn1Click(Sender: TObject);
var n:integer;  l:tstringlist;
begin
  writeln('*********************');
  l:=tstringlist.create;
  clipboard.SupportedFormats(l);
  for n:=0 to l.Count-1 do
    writeln(n,' ',l[n],': ',clipboard.formats[n]);
  writeln('*********************');
  l.free;
end;

taazz

  • Hero Member
  • *****
  • Posts: 5368
Re: Copying images from a Lazarus application
« Reply #1 on: February 17, 2018, 04:26:47 pm »
1) you have to ask the libre office team which formats it supports and make sure that you copy one of those in memory
2) You can add multiple formats to the clipbaord by using
Code: Pascal  [Select][+][-]
  1.   Clipboard.AddFormat(CF_Bitmap, aStream);
  2.  
you create multiple image classes (png, bmp, jpg etc) you use bmp.assign(primarygraphic) to copy the contents for each supported class you create a memory stream and call the savetostream method keep in mind you can't use one memory stream for all and you do not free the memory stream after to pass it to the clipboard or the data will be lost.
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

hakelm

  • Full Member
  • ***
  • Posts: 153
Re: Copying images from a Lazarus application
« Reply #2 on: February 17, 2018, 06:03:20 pm »
Thanks,
but what do I put into the stream?
H

taazz

  • Hero Member
  • *****
  • Posts: 5368
Re: Copying images from a Lazarus application
« Reply #3 on: February 17, 2018, 06:15:33 pm »
Thanks,
but what do I put into the stream?
H
the images. for example
Code: Pascal  [Select][+][-]
  1. uses clipbrd, lclintf,......;
  2. procedure mageToClipboard(const aBitmap :string);
  3. var
  4.   vBmp:TBitmap;
  5.   vPng:TPortableNetworkGraphic;
  6.   vJpg:TJPEGImage;
  7.   vMs:TMemoryStream;
  8. begin
  9.   vBmp := TBitmap.Create;
  10.   vPng := TPortableNetworkGraphic.Create;
  11.   vJpg := TJPEGImage.Create;
  12.   try
  13.     vBmp.LoadFromFile(aBitmap);
  14.     vPng.Assign(vBmp);
  15.     vJpg.Assign(vBmp);
  16.     vMs := TMemoryStream.Create;
  17.     vBmp.SaveToStream(vMs);
  18.     Clipboard.AddFormat(ClipboardRegisterFormat(vBmp.MimeType), vMs);
  19.     vMs := TMemoryStream.Create;
  20.     vPng.SaveToStream(vMs);
  21.     Clipboard.AddFormat(ClipboardRegisterFormat(vPng.MimeType), vMs);
  22.     vMs := TMemoryStream.Create;
  23.     vJpg.SaveToStream(vMs);
  24.     Clipboard.AddFormat(ClipboardRegisterFormat(vJpg.MimeType), vMs);
  25.   finally
  26.     vBmp.Free;
  27.     vPng.Free;
  28.     vJpg.Free;
  29.   end;
  30. end;
  31.  
keep in mind the above sample was typed directly in the browser it was never compiled or tested, consider it a pseudo code that showcases how to add multiple image formats on the clipboard not a working sample.
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

hakelm

  • Full Member
  • ***
  • Posts: 153
Re: Copying images from a Lazarus application
« Reply #4 on: February 18, 2018, 08:47:51 am »
Thank you!
Brilliant, this does exactly what I needed.
I can also report that Libre Office doesn't understand  image/jpeg but listens to image/bmp and image/png.
In the case of image/bmp, however, the size of the image is not respected, the pasted image will fill the whole document page width.
H

wp

  • Hero Member
  • *****
  • Posts: 11855
Re: Copying images from a Lazarus application
« Reply #5 on: February 18, 2018, 11:51:13 am »
Make sure that the bitmap has the correct pixel density in the bitmap header. Normally this is given in pixels per inch, but bmp has "PelsPerMeter" in its header, pixels per meter. If the program creating the bitmap writes PPI into the PelsPerMeter field LibreOffice will calculate a huge image size from the small PelsPerMeter value! Conversely I know that the fpc bitmap writer had or still has a problem in respecting the correct pixel density (https://bugs.freepascal.org/view.php?id=29852, https://bugs.freepascal.org/view.php?id=29865).

Maybe the following code helps. It reads the pixeldensity from the stream's bitmap header and multiplies it by 100/2.54 if its value is below some limit (which would mean that it had been entered as pixels per inch). Call this in Taaz's code after "vBmp.SaveToStream(vMs)". No warranty, of course.

Code: Pascal  [Select][+][-]
  1. procedure FixBmpPPI(AStream: TMemoryStream);
  2. var
  3.   p: Int64;
  4.   phdr: Int64;
  5.   fileHdr: TBitmapFileHeader;
  6.   infoHdr: TBitmapInfoHeader;
  7.   ppi: Integer;
  8. begin
  9.   p := AStream.Position;
  10.   try
  11.     AStream.Position := 0;
  12.     AStream.ReadBuffer(fileHdr, SizeOf(TBitmapFileHeader));
  13.     phdr := AStream.Position;
  14.     AStream.ReadBuffer(infoHdr, SizeOf(TBitmapInfoHeader));
  15.     if infoHdr.XPelsPerMeter < 1000 then
  16.       infoHdr.XPelsPerMeter := round(infoHdr.XPelsPerMeter * 100 / 2.54);
  17.     if infoHdr.YPelsPerMeter < 1000 then
  18.       infoHdr.YPelsPerMeter := round(infoHdr.YPelsPerMeter * 100 / 2.54);
  19.     AStream.Position := phdr;
  20.     AStream.WriteBuffer(infoHdr, SizeOf(TBitmapInfoHeader));
  21.   finally
  22.     AStream.Position;
  23.   end;
  24. end;
« Last Edit: February 18, 2018, 01:12:53 pm by wp »

hakelm

  • Full Member
  • ***
  • Posts: 153
Re: Copying images from a Lazarus application
« Reply #6 on: February 18, 2018, 06:35:39 pm »
I always thought of bitmaps as rows and columns of pixels an pixel/m etc. was something for WYSIWYG applications and the printer.
But you always learn something.
H

HeavyUser

  • Sr. Member
  • ****
  • Posts: 397
Re: Copying images from a Lazarus application
« Reply #7 on: February 18, 2018, 07:47:08 pm »
I always thought of bitmaps as rows and columns of pixels an pixel/m etc. was something for WYSIWYG applications and the printer.
But you always learn something.
H
so where do you group an office application then if not in WYSIWYG?

Julius7

  • New Member
  • *
  • Posts: 19
Re: Copying images from a Lazarus application
« Reply #8 on: February 19, 2018, 05:36:00 am »
Here is a specification file for explaining the layout of bmp format

http://www.digicamsoft.com/bmp/bmp.html

..
Graphics File Formats

This topic describes the graphics-file formats used by the Microsoft Windows
....

Julius7

  • New Member
  • *
  • Posts: 19
Re: Copying images from a Lazarus application
« Reply #9 on: February 19, 2018, 05:39:53 am »
here is another page


http://paulbourke.net/dataformats/bmp/


[ this is the first few lines of the page]
...

BMP image format
Written by Paul Bourke
 July 1998
Russian translation by Alex Marchenko. 





Introduction
 

BMP files are an historic (but still commonly used) file format for the historic (but still commonly used) operating system called "Windows". BMP images can range from black and white (1 bit per pixel) up to 24 bit colour (16.7 million colours). While the images can be compressed, this is rarely used in practice and won't be discussed in detail here.
Structure
 

A BMP file consists of either 3 or 4 parts as shown in the diagram on the right.
..............

 

TinyPortal © 2005-2018