• Welcome to Dark Bit Factory & Gravity.
 

[BMAX] Getting image width and height without loading the entire image

Started by zawran, April 11, 2008

Previous topic - Next topic

0 Members and 0 Guests are viewing this topic.

zawran

I did the following functions for a post on the official blitz forum. It will find the width and heights of images without loading the entire images into memory first. It has worked on all png images I have tested it with. [edit] I figured out why it did not work with all jpg files. It turns out that some jpg files has embedded thumbnail images which needs to be passed before getting to the actual image info. I have manged to fix the function and I have not found any jpg image it does not work with.

The code is fairly straight forward and should be easy enough to translate into other languages.


Local width:Int = 0
Local height:Int = 0

imageWidthHeightPNG("5.png",width,height)
Print Hex(width)+","+width
Print Hex(height)+","+height

imageWidthHeightJPG("5.jpg",width,height)
Print Hex(width)+","+width
Print Hex(height)+","+height

End

Function imageWidthHeightPNG(imagePath:String,width:Int Var, height:Int Var)
Local file:TStream = OpenStream(imagePath)
If ReadShort(file) <> $5089 Then Return False ' not a png image file
SeekStream(file,18)
width = ReadByte(file)*256
width :+ ReadByte(file)
SeekStream(file,22)
height = ReadByte(file)*256
height :+ ReadByte(file)
CloseStream(file)
End Function

Function imageWidthHeightJPG(imagePath:String,width:Int Var, height:Int Var)
Local file:TStream = OpenStream(imagePath)
If ReadShort(file) <> $D8FF Then Return False ' not a jpg image file
Local b1:Byte,b2:Byte,test:Byte=$E1
Local jump:Int
While Not Eof(file)
' locate jump instructions
Repeat
b1 = ReadByte(file)
Until b1 = $FF
b2 = ReadByte(file)
If b2 > $E0 And b2 < $EE Then ' jump instruction found
jump = ReadByte(file)*256+ReadByte(file)
SeekStream(file,StreamPos(file)+jump-2)
End If
If b2 = $EE Then ' no more jumps
' find width & height info
Repeat
b1 = ReadByte(file)
If b1 = $FF Then b2 = ReadByte(file)
Until (b1 = $FF And b2 = $C0) Or (b1 = $FF And b2 = $C1) Or (b1 = $FF And b2 = $C2) Or (b1 = $FF And b2 = $C3)
' skip 3 bytes
SeekStream(file,StreamPos(file)+3)
height = ReadByte(file)*256
height :+ ReadByte(file)
width = ReadByte(file)*256
width :+ ReadByte(file)
CloseFile(file)
Return
End If
Wend
End Function

Pixel_Outlaw

Wow! Thanks for sharing this code with us. Have some Karma.  :inspired:
Challenge Trophies Won:

Jim

Challenge Trophies Won:

zawran

Thanks guys, I wish I had more time for coding so I could do more, but lately its just these small quick ones. Glad you find it useful.