PNG Dimensions Question
-
- Posts: 355
- Joined: May 29, 2015 20:37
PNG Dimensions Question
Hi all,
In my program I load dozens of images. Rn I have to hard-code all the dimensions of each PNG image along with the loading code. But to help me add more images to this list faster, I was wondering if I could gather such dimensional information with each file instead.
I have researched into the PNG format, and I have found this, the IHDR chunk. I figured reading the figures directly from the file instead of having to use FreeImage functions was preferable. Within the chunk is supposed to be the information I am after (i.e. the width and height of the image), right after the declaration of the chunk using the bytes "IHDR".
I have used a hex editor with a few images and I can't seem to find their dimensions at all within the chunk, using any sized register i.e. 4bytes, 8bytes etc., and at any position within the chunk.
AFAI knew, this chunk wasn't compressed because it is "(13 data bytes total)" and the wiki page doesn't mention compression at this point of the article.
In short, where exactly are these bytes of information (width and height of image) located in a PNG file, and what size are the values storing the width and height (I am assuming 4 bytes but idrk)?
Thanks for reading
In my program I load dozens of images. Rn I have to hard-code all the dimensions of each PNG image along with the loading code. But to help me add more images to this list faster, I was wondering if I could gather such dimensional information with each file instead.
I have researched into the PNG format, and I have found this, the IHDR chunk. I figured reading the figures directly from the file instead of having to use FreeImage functions was preferable. Within the chunk is supposed to be the information I am after (i.e. the width and height of the image), right after the declaration of the chunk using the bytes "IHDR".
I have used a hex editor with a few images and I can't seem to find their dimensions at all within the chunk, using any sized register i.e. 4bytes, 8bytes etc., and at any position within the chunk.
AFAI knew, this chunk wasn't compressed because it is "(13 data bytes total)" and the wiki page doesn't mention compression at this point of the article.
In short, where exactly are these bytes of information (width and height of image) located in a PNG file, and what size are the values storing the width and height (I am assuming 4 bytes but idrk)?
Thanks for reading
Re: PNG Dimensions Question
try this, no guarantee it will work on all your png's
Code: Select all
dim as ubyte n
dim as long x, y
open "yourimage.png" for binary as 1
Get #1,19 , n
x=n*256
Get #1,20 , n
x=x+n
? x
Get #1,23 , n
y=n*256
Get #1,24 , n
y=y+n
? y
close 1
Re: PNG Dimensions Question
the image I looked at had the bytes 17 and 18 as 0 and bytes 21 and 22 as 0 so I don't know if they are part of the image dimension or not.
-
- Posts: 355
- Joined: May 29, 2015 20:37
Re: PNG Dimensions Question
It appears as 0 too for all the images I've tried with it...srvaldez wrote:the image I looked at had the bytes 17 and 18 as 0 and bytes 21 and 22 as 0 so I don't know if they are part of the image dimension or not.
EDIT: Whoops... I used the wrong path for the image files, that's why it wasn't working xD.
Fixed that and it works very well! Thanks srvaldez!
Re: PNG Dimensions Question
the problem is that the size info is big endian?
I thought FB had a byte-swap macro but can't find it in the help.
I thought FB had a byte-swap macro but can't find it in the help.
Code: Select all
dim as ushort x, y
open "yourimage.png" for binary as 1
Get #1,19 , x
asm
mov ax, [x]
xchg al, ah
mov [x], ax
end asm
? x
Get #1,23 , y
asm
mov ax, [y]
xchg al, ah
mov [y], ax
end asm
? y
close 1
Re: PNG Dimensions Question
For example:
Code: Select all
#macro byte_swap(short_variable)
Swap Cptr(Byte Ptr, @(short_variable))[0], Cptr(Byte Ptr, @(short_variable))[1]
#endmacro
Re: PNG Dimensions Question
thank you fxm :-)
Re: PNG Dimensions Question
after thinking about it, more than likely the size info is a long, though you'd have to have a really huge image, nevertheless thanks to fxm's macro modified a bit.
Code: Select all
dim as ulong x, y
#macro byte_reverse(long_variable)
Swap Cptr(Byte Ptr, @(long_variable))[0], Cptr(Byte Ptr, @(long_variable))[3]
Swap Cptr(Byte Ptr, @(long_variable))[1], Cptr(Byte Ptr, @(long_variable))[2]
#endmacro
open "yourimage.png" for binary as 1
Get #1,17 , x
byte_reverse(x)
Print x
Get #1,21 , y
byte_reverse(y)
Print y
close 1
Re: PNG Dimensions Question
PNG can easily be loaded with FBImage (by D.J.Peters), thereafter, because it's a FBImage,
one can use ImageInfo(), to obtain the Image's sizes (if still required, after loading).
one can use ImageInfo(), to obtain the Image's sizes (if still required, after loading).
-
- Posts: 355
- Joined: May 29, 2015 20:37
Re: PNG Dimensions Question
Thanks for the help guys, and the info!
-
- Site Admin
- Posts: 6323
- Joined: Jul 05, 2005 17:32
- Location: Manchester, Lancs
Re: PNG Dimensions Question
From an endian-neutral point of view, it would be better to avoid byte-swapping, and just compose the bytes into a long yourself. e.g. a(0) shl 24 + a(1) shl 16 + a(2) shl 8 + a(3).
Re: PNG Dimensions Question
Yes:
-The faster:- The slower:- Between the two previous ones:
-The faster:
Code: Select all
#macro byte_reverse(long_variable)
long_variable = Cptr(Byte Ptr, @(long_variable))[0] Shl 24 + _
Cptr(Byte Ptr, @(long_variable))[1] Shl 16 + _
Cptr(Byte Ptr, @(long_variable))[2] Shl 08 + _
Cptr(Byte Ptr, @(long_variable))[3]
#endmacro
Code: Select all
#macro byte_reverse(long_variable)
long_variable = ((long_variable) And &h000000FF) Shl 24 + _
((long_variable) And &h0000FF00) Shl 08 + _
((long_variable) And &h00FF0000) Shr 08 + _
((long_variable) And &hFF000000) Shr 24
#endmacro
Code: Select all
#macro byte_reverse(long_variable)
Swap Cptr(Byte Ptr, @(long_variable))[0], Cptr(Byte Ptr, @(long_variable))[3]
Swap Cptr(Byte Ptr, @(long_variable))[1], Cptr(Byte Ptr, @(long_variable))[2]
#endmacro