Page 2 of 2 FirstFirst 12
Results 11 to 18 of 18

Thread: Code to load PNG

  1. #11

    Re: Code to load PNG

    Quote Originally Posted by User137
    Quote Originally Posted by jdarling
    Nuno, never found a stand along PNG loader myself . The one that is included in FPC/Lazarus requires 3rd party libs
    What do you mean by this? Lazarus's PNG works without getting anything extra. And after i just opened PNG source files (packages\fcl_image\src) they really don't have anything 3rd party in them.

    TPortableNetworkGraphic is found in Graphics unit.
    Just took another look at the Lazarus version and your right about that . But, it doesn't always load a PNG properly (see attached image below). I never figured out what exactly was wrong with the loader, but I know it has to do with transparency layers generated from some graphics editing software.

    For the below image (and similar) I have to load them into PhotoShop and re-save them for them to work properly. Never had such problems with Vampyre.



    Course, I could be wrong about the latest versions of Delphi too, I've only read about the details of how they implemented PNG support. I know a while back the concern was in the LZH compression and its licensing.

    - Jeremy

  2. #12

    Re: Code to load PNG

    The green arrow image loaded up quite nicely, and i have never had any problems with PNG whatever format, alphachanneled or not, i save or get them from. I haven't tested TImage behaviour much but mainly just dig into its data to put in OpenGL

    Edit: Oh, i have a little ImageViewer tool to test if anyone wants to:
    http://www.easy-share.com/1910530660/ImageViewer.zip
    (Better no ads-link): http://www.eonclash.com/PGD/User137_ImageViewer.zip

    It's made with Lazarus and Next3D, mainly for watching manga and other cartoony folders full of images. Quite a bit of optimization and stuff done to make it finished i hope.

  3. #13

    Re: Code to load PNG

    Should have mentioned, that one of the other ways I've found to "fix" an image is to right click and save it as from a web browser LOL. seems they tweak the heards when they download an image.

    Anyways, did you a favor and here is an alternative download link that doesn't fill the screen with AD's http://www.eonclash.com/PGD/User137_ImageViewer.zip

    Interesting little app, I'll post more on my thoughts if you want to startup and link out a thread

    - Jeremy

  4. #14

    Re: Code to load PNG

    Thank you all for your replies.

    I was looking few Pascal implementations of PNG and seems to be more complex as I thought. I'm not sure I understand it -- I have this problem with most technical documents written in English.

    About the suggestion about "Vampyre", I'll give it a chance. I hope it doesn't "overload" or adds a lot of stuff to the executable. Actually I need the PNG loader because I want to use Battle for Wesnoth graphics and I don't want to translate hundreds of pictures to other format.

    Quote Originally Posted by Luuk van Venrooij
    Also If you need my image converter just drop a line and I`ll upload it again.
    Yes please. If I don't use it now but I'll use in the future. And a lot of people will "thanks" it a lot.
    No signature provided yet.

  5. #15

    Re: Code to load PNG

    Quote Originally Posted by jdarling
    So far, Vampyre (http://imaginglib.sourceforge.net/) is the best solution I've found, though I wish I could find a PNG only loader
    I'm planning to make a standalone MiniPNG unit based on Imaging's PNG handler so there is still hope
    I guess only loading of PNGs is ok (no saving)?

    use Vampyre, there is an .inc file where you can disable some unwanted features.
    This can remove a lot of bloat from your exe (JPEG2000, TIFF, ...).
    Vampyre Imaging Library
    Earth Under Fire (PGD Big Boss 3rd place)
    Domains Of Chaos (PGD Multiplexity 5th place)

  6. #16

    Re: Code to load PNG

    Quote Originally Posted by Galfar
    I'm planning to make a standalone MiniPNG unit based on Imaging's PNG handler so there is still hope
    I guess only loading of PNGs is ok (no saving)?
    Loading would be excellent if absolutely NO (as in 0) 3rd party libraries or etc are required! Creating, Saving, whatever is easy enough. Loading the lil buggers is a real problem.

    At least, that's my opinion.

  7. #17

    Re: Code to load PNG

    Quote Originally Posted by Galfar
    I'm planning to make a standalone MiniPNG unit based on Imaging's PNG handler so there is still hope
    I guess only loading of PNGs is ok (no saving)?
    Yes: loading only should be enough.
    No signature provided yet.

  8. #18
    Co-Founder / PGD Elder WILL's Avatar
    Join Date
    Apr 2003
    Location
    Canada
    Posts
    6,107
    Blog Entries
    25

    Re: Code to load PNG

    I'd love to be able to make all my screenshots in PNG format (which would mean writing to PNG) I've gone as far as to

    Here is my incomplete implimentation of a PNG screenshot generator: (taken from Garland's Quest)
    Code:
    type
     TPNGStart = packed Array[0 .. 8] of Byte;
    
     TPNG_IHDR = packed record
      Width       : DWord;
      Height      : DWord;
      BitDepth     : Byte;
      ColorType     : Byte;
      CompressionMethod : Byte;
      FilterMethod   : Byte;
      InterlaceMethod  : Byte;
     end;
     TPNG_Chunk = packed record
      Length  : DWord;
      ChunkType : Array[0 .. 3] of Byte;
      ChunkCRC : DWord;
     end;
    
    
    procedure ScreenShot_PNG(Filename: String);
    var
     i: Integer;
     pngStartBytes: TPNGStart;
     pngIHDR: TPNG_IHDR;
     pngChunk: TPNG_Chunk;
    
     vport: array[0 .. 3] of Integer;
     Buffer: PChar;
     BufferLength: Integer;
     f: TMemoryStream;
     crc: Cardinal;
    begin
       // First 8 bytes //
       pngStartBytes[0] := 137;
       pngStartBytes[1] := 80;
       pngStartBytes[2] := 78;
       pngStartBytes[3] := 71;
       pngStartBytes[4] := 13;
       pngStartBytes[5] := 10;
       pngStartBytes[6] := 26;
       pngStartBytes[7] := 10;
    
       // Get OpenGL ViewPort Data
       glGetIntegerv(GL_VIEWPORT, @vport);
       glPixelStorei(GL_PACK_ALIGNMENT, 1);
    
       // Chunk Information //
       FillChar(pngChunk, SizeOf(pngChunk), 0);
       pngChunk.Length := SizeOf(pngIHDR);
       pngChunk.ChunkType[0] := ord('I');
       pngChunk.ChunkType[1] := ord('H');
       pngChunk.ChunkType[2] := ord('D');
       pngChunk.ChunkType[3] := ord('R');
    
       // IHDR Chunk Data //
       FillChar(pngIHDR, SizeOf(pngIHDR), 0);
       pngIHDR.Width       := vport[2];
       pngIHDR.Height      := vport[3];
       pngIHDR.BitDepth     := 8;
       pngIHDR.ColorType     := 2; // 2 = Each pixel is an R,G,B triple. 6 = Each pixel is an R,G,B triple, followed by an alpha sample.
       pngIHDR.CompressionMethod := 0; // deflate/inflate compression with a sliding window of at most 32768 bytes
       pngIHDR.FilterMethod   := 0; // adaptive filtering with five basic filter types
       pngIHDR.InterlaceMethod  := 0; // 0 (no interlace) or 1 (Adam7 interlace)
    
       // Temp Store Chunk Type & Data into Buffer for processing
       BufferLength := (4 + SizeOf(pngIHDR)); // ChunkType + ChunkData
       GetMem(Buffer, BufferLength);
       for i := 0 to 3 do             // Chunk Type to Buffer
         Write(Buffer^, pngChunk.ChunkType[i]);
    //   Write(Buffer^, pngIHDR);          // Chunk Data to Buffer
    
       // CRC for Chunk Data //
       crc := crc32(0, nil, 0);
    //   pngChunk.ChunkCRC := crc32(crc, Buffer, BufferLength);
    
       // Start Writing PNG File
       f := TMemoryStream.Create;
       for i := 0 to 7 do
         f.Write(pngStartBytes[0], 1);           // First 8 bytes
       f.Write(pngChunk.Length, SizeOf(pngChunk.Length));   // IHDR Chunk Length
       f.Write(buffer, BufferLength);             // IHDR Chunk Type & Data
       f.Write(pngChunk.ChunkCRC, SizeOf(pngChunk.ChunkCRC)); // IHDR Chunk CRC
    
       FreeMem(Buffer);
    
       // --- IDAT Chunk --- //
    
       // Chunk Information //
       FillChar(pngChunk, SizeOf(pngChunk), 0);
       pngChunk.Length := SizeOf(pngIHDR);
       pngChunk.ChunkType[0] := ord('I');
       pngChunk.ChunkType[1] := ord('H');
       pngChunk.ChunkType[2] := ord('D');
       pngChunk.ChunkType[3] := ord('R');
    
       // Temp Store Chunk Type & Data into Buffer for processing
       BufferLength := (4 + (pngIHDR.Width * pngIHDR.Height * 3)); // rgb
       GetMem(Buffer, BufferLength);
       glReadPixels(0, 0, vport[2], vport[3], GL_RGB8, GL_UNSIGNED_BYTE, Buffer);
    
       FreeMem(Buffer);
    
    
    //   crc32(crc : cardinal; buf : Pbyte; len : cardinal)
    //   f.Write(Buffer^, BufferLength);
    
       // IEND Chunk
    
       f.SaveToFile(Filename);
       f.Free;
    end;
    it should work if you can modify it to generate the proper LZH compression for whatever pixel format you will be using. Oh and it is OpenGL dependent.
    Jason McMillen
    Pascal Game Development
    Co-Founder





Page 2 of 2 FirstFirst 12

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •