Jump to content
  • Sky
  • Blueberry
  • Slate
  • Blackcurrant
  • Watermelon
  • Strawberry
  • Orange
  • Banana
  • Apple
  • Emerald
  • Chocolate
  • Charcoal
TehSomeLuigi

libPNGimage - a (preliminary) library for decoding & encoding PNG images

Recommended Posts

Today I present to you a library I have been working on: libPNGimage

The library allows you to decode and encode PNG images. Please note that at the time of writing, it is missing some features and is not therefore fully standards-compliant.

 

The library makes use of slightly-modified versions of DeflateLua and CRC32Lua by David Manura, which are both licensed under MIT.

As for libPNGimage itself, as long as you leave my little credits header there, you can do whatever you want with it :).

 

I have a quick demonstration application 'pngview' which I will release to the forums shortly after this is written up.

API Functions:


PNGImage = require('libPNGimage')
 

PNGImage.newFromScratch(width: number, height: number, bkcol: table): pngimage
Creates a new pngimage object with the specified width and height. Bkcol is a table with either {R, G, B, A} or {R, G, B} to be filled onto the canvas.

PNGImage.newFromFileHandle(fh:handle): pngimage
Creates a new pngimage object by reading a PNG file from the IO file handle.

PNGImage.newFromFile(filename: string): pngimage
Creates a new pngimage object by loading the PNG file at the absolute path given.


pngimage.ihdr
is a table with IHDR data:
pngimage.ihdr.width - the width of the image

pngimage.ihdr.height - the height of the image

pngimage.ihdr.bit_depth - the bit depth of the image

pngimage.ihdr.color_type - the color type of the image
pngimage.ihdr.compression_method - the compression method of the image

pngimage.ihdr.filter_method - the filter method of the image
pngimage.ihdr.interlace_method - the interlacing method of the image
 

pngimage:getSize(): width: number, height: number
returns the width and height of the image

pngimage:getPixel(x: zerobased-number, y: zerobased-number): r: number, g: number, b: number, a: number
returns the R, G, B and A values for the pixel at the coordinates specified.
WARNING: Coordinates are zero-based i.e. they start at 0!

pngimage:setPixel(x: zerobased-number, y: zerobased-number, col: table)
sets the pixel at the coordinates specified to the colour specified. The colour is to be specified as a table of the {R, G, B, A} components.
WARNING: Coordinates are zero-based i.e. they start at 0!

pngimage:saveToFile(filename: string)
saves the image in PNG format to file using absolute file path.

pngimage:saveToFileHandle(fh: handle)
saves the image in PNG format to the IO file handle specified.

 

pngimage:lineXAB(ax: number, y: number, bx: number, col: table)
draws a line of pixels in along the X axis from (ax, y) to (bx, y).
The colour is to be specified as a table of the {R, G, B, A} components.
 

pngimage:lineYAB(x: number, ay: number, by: number, col: table)
draws a line of pixels in along the Y axis from (x, ay) to (x, by).
The colour is to be specified as a table of the {R, G, B, A} components.

 

pngimage:lineRectangleAB(ax: number, ay: number, bx:number, by: number, col: table)
draws a (non-filled) rectangle from (ax, ay) to (bx, by).
The colour is to be specified as a table of the {R, G, B, A} components.
 

pngimage:fillRectangleAB(ax: number, ay: number, bx:number, by: number, col: table)
draws a filled rectangle from (ax, ay) to (bx, by).
The colour is to be specified as a table of the {R, G, B, A} components.

 



Please note that the current version (r001) has some limitations:

  • Images using Interlacing are not supported.
  • Images not using Truecolour or Truecolour+Alpha colour types are not supported. This means Grayscale/Indexed images are not supported.
  • Images not using bitdepth of 8 are not supported.
  • When exporting, the PNG data is not compressed so it will generate files bigger than it loads. These are still PNG-compliant though.

libPNGimage-r001.zip

Also included in the download is my 'pngview' program which I have yet to write up. You can probably figure out how to use it though.

Link to post
Share on other sites

i must try this out...

 

i was wanting to do exactly this for automatically sensing a player with a motion sensor/ct radar and displaying a hologram projection of the player's skin by wrapping the png data around a hologram model...

 

i'll report back on how that works out for me :)

Link to post
Share on other sites

righty...

 

i've got it happily pulling down my skin and drawing it in the hologram... i just need to define a matrix of x,y -> x,y,z points to UV wrap it now...

 

i decided, since the colour depth is much lower, to use an algorithm of

    col = (r or 0) * 256 ^ 2 + (g or 0) * 256 + (b or 0)
    
    paletteindex = col == 0 and 0 or col < 0x555555 and 1 or col < 0xAAAAAA and 2 or 3

to get the index for the hologam voxel colour... 

 

seems to work ok, naturally weirdly different colours, but the contrast is right between the shades that should be there... 

 

i'll report further tomorrow i hope... 

 

 

edit: oh, screenshot or it didn't happen, i guess: [ that's my moustache over there on the right, that's what my IRL one is like, but more green, i think ] 

 

skin.png

Link to post
Share on other sites

... one thing i think i'm noticing, the "zeroth" value in both axes seems to be missing when doing the "getPixel(x,y) ...

 

i.e. from my image above, it's missing the far left and top row of pixels...

[ and i'm just going from 0,63 x 0,31 y  and transferring that to the hologram ]

 

if i pull any pixel from x == 0 or y == 0 then i always get 0,0,0,0 back... 

the base is correct, as if i pull from row/column 1, then i DO get the correct value for column 1 [ = the 2nd row or column from base zero ] 

 

compare to my actual skin: http://s3.amazonaws.com/MinecraftSkins/ingie_.png

 

i've checked and double checked, and i can't see it as a bug in my code - as i can just loop over row 0 or column 0 and always get nothing... 

 

 

or maybe it'd be better if i didn't try and plot voxel row/column(0,1,0)  :)

 

damn option base 0, horrible thing. or 1, either :)

Link to post
Share on other sites

righty... here we are then

 

https://www.dropbox.com/s/ye2lihjabxc6ic6/holoskin.lua?dl=0

 

usage is: holoskin [iGN]

 

note: by default it saves into a folder "skins" - create that or change the option at the end of the code before the main call.

 

for other options see the bottom of the code. 

 

examples

 

me:

 

ingie_.png?dl=0

 

tehsomeluigi:

 

tehsomeluigi.png?dl=0

 

sangar:

 

kethtar.png?dl=0

Link to post
Share on other sites

 

hmm... i only had that when i got the capitalisation of the IGN wrong or the servers were being lame...

 

I just tried it and it worked fine...  do you have an internet card in the case? as - rather obviously, i guess - it needs to download the skin :)

if you have, then i'd just try again - i had the odd time when it just didn't but it was connection issues rather than the code itself - although I could

make it error check and try again a few times, it didn't seem worth it at this stage as my plan is to expand it into a library for further things.

 

Link to post
Share on other sites

can you make them stand up?

Yes, you can make the images stand up. This is apparent because on some of the screenies posted there was 3D graphical output (because of the Y values changing in the blocks).

Probably some changes in the code could easily make this happen. Experiment around and tell me how it works out for you.

Link to post
Share on other sites

What is the max resolution of a PNG image in pixels for this library?

 

Sorry if this is a stupid question, I assume it's 160x50, same as the T3 GPU's max res?

 

I'm asking as I've been playing around with it, but I'm having some trouble getting anything over 64 pixels wide to display.

 

EDIT: I'm testing images with pngview.lua

Link to post
Share on other sites

Hey all,

I ended up getting a PNG of 160x50 pixels and cutting it into 3 segments, 64x50, 64x50, 32x50, then stitching those together. That seems to have worked for now.

 

If anyone happens to know why I can't just use a single 160x50 png I'd love to know, particularly if I'm doing it wrong.

 

The main error I'm getting is a context error of 8, though I was also getting noeof related errors and others too.

 

Specifically the error is as below...

 

While attempting to load '/zel4.png' as PNG, libPNGImage erred:

/lib/deflatelua.lua:115: unexpected end of file with context 8

 

Cheers!

Link to post
Share on other sites

Turns out I need some practice reading.

 

For some reason I thought "When exporting, the PNG data is not compressed so it will generate files bigger than it loads. These are still PNG-compliant though." meant I should not use compressed PNGs

 

Works really well, thanks a lot!

Link to post
Share on other sites
Hi, Daraketh!

I'm sorry it has taken me so long to get back to you, I've been very busy lately.

 

Maximal size for images that I have used - 160x100 px. To improve the picture quality, I used a trick with Unicode characters - half blocks (http://www.alanwood.net/unicode/block_elements.html).

 

I have modified "show" script a bit, to render images properly. Here you can find it: http://pastebin.com/UqM8dTjH

You will need "libPNGimage", "deflatelua" and "crc32lua" libs.

 

Images:

miku.png miku3.png

Link to post
Share on other sites

Hey! I've got a Question:

How do I show the images? I've got everything on the hard drive, made a 50x50 Picture for testing (test.png), I put it on my harddrive,rejoined the world started pngviewer and entered "test.png" into the field.

Then I've got the following error:

PNGView: PNG loading Error
While attempting to load '/test.png' as PNG,libPNGImage erred:
/deflatelua.lua:115: unexpected end of file with content 8

How do I fix this?

Link to post
Share on other sites

I am having just a bit of trouble using this plugin. I'm fairly new to OpenComputers as a whole, so please correct me if I'm wrong in any of these steps I've taken.
From the start, I:

1. got a T3 case with a T3 graphics card, 2 T2.5 RAM, and a T1 hard drive

2. installed openos on the hard drive

3. Pasted the contents of the zip file in the OP into my /lib/ folder corresponding to the hard drive

4. placed the same miku picture Moonlight used in /home/ to use as a test

5. Ran "pngview", and input "miku.png"

Similar to simon, I recieved an error:

 

* PNG Loading Error *
While attempting to load '/home/miku.png' as PNG, libPNGImage errored:
/lib/deflatelua.lua:115: unexpected end of file with context 1

Similar but not the same as mine is with the "context 1". If anyone could assist or let me know if I'm missing something, it would be greatly appreciated.

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use and Privacy Policy.