Author Topic: [BMAX] Getting image width and height without loading the entire image  (Read 448 times)

0 Members and 1 Guest are viewing this topic.

Offline zawran

  • Sponsor
  • Pentium
  • *******
  • Posts: 886
  • Karma: 63
    • View Profile
    • zac-interactive


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.

Code: [Select]
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
« Last Edit: April 11, 2008 by zawran »

Offline Pixel_Outlaw

  • Pentium
  • *****
  • Posts: 1343
  • Karma: 79
    • View Profile
Wow! Thanks for sharing this code with us. Have some Karma.  :inspired:
Challenge Trophies Won:

Offline Jim

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 5098
  • Karma: 380
    • View Profile
Very useful.  Thanks!

Jim
Challenge Trophies Won:

Offline zawran

  • Sponsor
  • Pentium
  • *******
  • Posts: 886
  • Karma: 63
    • View Profile
    • zac-interactive
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.