Getting picture width and height without LCL lazarus / 39-Graphics ---------------------------------------------------------------------- wp · 2016-03-01 22:25 For image support in fpspreadsheet I need to know the pixel width and height of pictures. Since the basic fpspreadsheet units do not use the LCL I am not allowed to apply the Graphics unit. What is the best way to determine these quantities based on non-LCL procedures for the typical graphics formats? ---------------------------------------------------------------------- Jurassic Pork · 2016-03-02 00:54 hello, maybe you can use the fpimage and the fpreadxxx  (ex: fpreadpng ) units. Example to read the height and width of a png picture : Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i Uses  fpreadpng, fpimage;var  image: TFPCustomImage;  reader: TFPCustomImageReader;begin  Image := TFPMemoryImage.Create(10,10);  Reader := TFPReaderPNG.Create;  Image.LoadFromFile('F:\temp\images\1111.png', Reader);  Writeln( 'image Width : ' + InttoStr(Image.Width) +           ' - image Height : ' + InttoStr(Image.Height) );  Readln;  Image.Free;  Reader.Free; end. Friendly, J.P ---------------------------------------------------------------------- engkin · 2016-03-02 03:57 There is another version of LoadFromFile that recognizes image types that were added to the ImageHandlers (this happened in the initialization section of every FPReadXXX unit): Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i program Project1; Uses  sysutils, fpimage, fpreadbmp, fpreadjpeg, fpreadpng {... find the rest in fpc\3.0.0\source\packages\fcl-image\src folder}; var  image: TFPCustomImage;begin  Image := TFPMemoryImage.Create(10,10);  Image.LoadFromFile('YourImageFileName<===');  Writeln( 'image Width : ' + InttoStr(Image.Width) +           ' - image Height : ' + InttoStr(Image.Height) );  Image.Free;  Readln;end. ---------------------------------------------------------------------- wp · 2016-03-02 06:17 Ah, thank you. I had seen this before but was confused because the FPCustomImage dimensions must be specified in the constructor. Next question: How to get the pixel density (dpi)? This would allow to specify the 100%-size of the image. ---------------------------------------------------------------------- Bart · 2016-03-02 16:25 http://svn.code.sf.net/p/flyingsheep/code/trunk/MijnLib/picslib.pp. Provides: Code: [Select]type   TImageFormat = (ifUnknown, ifBmp, ifPng, ifGif, ifJpg); function GetImageSize(const Fn: String; out Width, Height: dword): Boolean; function GetImageSizeAndFormat(const Fn: String; out Width, Height: dword): TImageFormat; Bart ---------------------------------------------------------------------- wp · 2016-03-02 17:12 Bart, thanks for sharing. In fact, I've set up something similar in the meantime. Because FPCustomImage does not return the dpi values I have to read the jpeg and bmp headers like you do - and it has the advantage that the entire image machinery is kept out of fpspreadsheet. Would you allow me to copy some snippets over to the new fpspreadsheet unit fpsimages? ---------------------------------------------------------------------- Bart · 2016-03-02 17:55 Quote from: wp on March 02, 2016, 06:12:22 pmBart, thanks for sharing.  .... Would you allow me to copy some snippets over to the new fpspreadsheet unit fpsimages? It's LGPL, so be my guest. Bart ---------------------------------------------------------------------- wp · 2016-03-03 19:31 Bart, as a "guest present" I am donating my function how to get image size (and dpi - but this is not in your lib) from TIFF files, you may have to edit it a bit to fit it into your lib: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i type  TByteOrder = (boLE, boBE);  // little edian, or big endian { Makes sure that the byte order of w is the same as specified by the parameter }function FixByteOrder(w: Word; AByteOrder: TByteOrder): Word; overload;begin  Result := IfThen(AByteOrder = boLE, LEToN(w), BEToN(w));end; { Makes sure that the byte order of dw is the same as specified by the parameter }function FixByteOrder(dw: DWord; AByteOrder: TByteOrder): DWord; overload;begin  Result := IfThen(AByteOrder = boLE, LEToN(dw), BEToN(dw));end; function GetTIFSize(AStream: TStream; out AWidth, AHeight: DWord;  out dpiX, dpiY: Double): Boolean;type  TTifHeader = packed record     BOM: word;     // 'II' for little endian, 'MM' for big endian     Sig: word;     // Signature (42)     IFD: DWORD;    // Offset where image data begin  end;  TIFD_Field = packed record    Tag: word;    FieldType: word;    ValCount: DWord;    ValOffset: DWord;  end;var  header: TTifHeader = (BOM:0; Sig:0; IFD:0);  dirEntries: Word;  field: TIFD_Field = (Tag:0; FieldType:0; ValCount:0; ValOffset:0);  i: Integer;  bo: TByteOrder;  num, denom: LongInt;  units: Word;  p, pStart: Int64;begin  Result := false;  AWidth := 0;  AHeight := 0;  dpiX := 0;  dpiY := 0;  units := 0;   // Remember current stream position because procedure is called also from  // jpeg Exif block.  pStart := AStream.Position;   if AStream.Read(header, SizeOf(TTifHeader)) < SizeOf(TTifHeader) then exit;  if not ((header.BOM = $4949) or (header.BOM = $4D4D)) then exit;  if header.BOM = $4949 then bo := boLE else bo := boBE; // 'II' --> little endian, 'MM' --> big endian  if FixByteOrder(header.Sig, bo) <> 42 then exit;   AStream.Position := pStart + FixByteOrder(header.IFD, bo);  dirEntries := FixByteOrder(AStream.ReadWord, bo);  for i := 1 to dirEntries do  begin    AStream.Read(field, SizeOf(field));    field.Tag := FixByteOrder(field.Tag, bo);    field.ValOffset := FixByteOrder(field.ValOffset, bo);    field.FieldType := FixByteOrder(field.FieldType, bo);    p := AStream.Position;    case field.Tag OF      $0100 : AWidth := field.ValOffset;      $0101 : AHeight := field.ValOffset;      $011A : begin    // XResolution as RATIONAL value                AStream.Position := pStart + field.ValOffset;                num := FixByteOrder(AStream.ReadDWord, bo);                denom := FixByteOrder(AStream.ReadDWord, bo);              dpiX := num/denom;              end;      $011B : begin    // YResolution as RATIONAL value                AStream.Position := pStart + field.ValOffset;                num := FixByteOrder(AStream.ReadDWord, bo);                denom := FixByteOrder(AStream.ReadDWord, bo);                dpiY := num/denom;              end;      $0128 : begin                units := field.ValOffset;   // 1: non-square 2: inches, 3: cm              end;    end;    if (AWidth > 0) and (AHeight > 0) and (dpiX > 0) and (dpiY > 0) and (units > 0)    then      break;    AStream.Position := p;  end;   case units of    1: begin dpiX := 96; dpiY := 96; end;    2: ;  // is already inches, nothing to do    3: begin dpiX := dpiX * 2.54; dpiY := dpiY * 2.54; end;  end;   Result := true;end; ---------------------------------------------------------------------- Bart · 2016-03-03 23:52 Quote from: wp on March 03, 2016, 08:31:22 pmBart, as a "guest present" I am donating my function how to get image size (and dpi - but this is not in your lib) from TIFF files, you may have to edit it a bit to fit it into your lib: Thanks, I'll look into it. Do the other filetypes have DPI info as well, and do you have code to extract that? Bart ---------------------------------------------------------------------- wp · 2016-03-04 00:21 Yes. You can have a look at it, it's all online now in fpspreadsheet's fpsimages (https://sourceforge.net/p/lazarus- ccr/svn/HEAD/tree/components/fpspreadsheet/fpsimages.pas). You can remove the dependence on fpsutils which brings in just some length unit conversion needed for svg (which does not have a true dpi either). ---------------------------------------------------------------------- Bart · 2024-01-07 00:15 Quote from: wp on March 03, 2016, 08:31:22 pmBart, as a "guest present" I am donating my function how to get image size (and dpi - but this is not in your lib) from TIFF files, you may have to edit it a bit to fit it into your lib: Integrated into my picslib unit. Took me just shy of 8 years  Thanks.