Author Topic: Convert  (Read 4696 times)

0 Members and 1 Guest are viewing this topic.

Offline rdc

  • Pentium
  • *****
  • Posts: 1495
  • Karma: 140
  • Yes, it is me.
    • View Profile
    • Clark Productions
Convert
« on: December 25, 2008 »
This short program will convert a 24/32 bit bitmap into a color data array that can then be used to draw on the screen. I use this quite a bit in my programs since accessing an array is much faster than accessing image data. Do not compile this with -s gui since it uses the console to gather input. You would use the output array in this fashion: (uinteger) pixel = arrayname(x + y * bmpwidth). Real world example: prch = parch(x + y * parchw), where prch is a uniteger, x and y are the pixel coordinates, and parchw is the bitmap width.

It might be useful for someone.

Code: [Select]
'Convert.bas
'Richard Clark
'Extracts the color information from a 24/32 bit bitmap
'to an include file for use in an FB program.
'Using a graphic screen and the Point function.
'Do not compile with -s gui, as this uses the console screen
'for input.
'Public doman, use any way you like.

dim as integer iw, ih, sw, sh, dp = 32
dim as string iname, aname, oname
dim as integer x, y, i, fh, cnt

Input "Enter bitmap width";iw
if iw = 0 then iw = 256
Input "Enter bitmap height";ih
if ih = 0 then ih = 256
Input "Enter bitmap filename (including extension)";iname
Input "Enter data array name";aname
Input "Enter export file name (including extension ex: pic.bi)";oname
Input "Enter graphic screen width";sw
if sw = 0 then sw = 640
Input "Enter graphic screen height";sh
if sh = 0 then sh = 480

if iw <= 0 or ih <= 0 then
    print "Width and height must be greater than zero."
    sleep
    end
end if
if len(iname) = 0 or len(aname) = 0 or len(oname) = 0 then
    print "No values given for filename, array name or output file name."
    sleep
    end
end if
if sw <= 0 or sh <= 0 or dp <= 0 then
    print "Screen dimensions and depth must be greater than zero."
    sleep
    end
end if
if len(dir(iname)) = 0 then
    print "Cannot find " & iname &"."
    sleep
    end
end if

fh = freefile
if open(oname for output as #fh) <> 0 then
    print "Cannot open output file."
    sleep
    end
end if

dim bmvals(iw * ih) as uinteger
screenres sw, sh, dp
if Screenptr = 0 then
    print "Cannot set graphic screen."
    sleep
    close fh
    end
end if

bload iname

'Print out header information
Print #fh, "'Useage: (uinteger) pixel = ";aname; "(x + y * ";aname & "w)"
print #fh, "Const ";Trim(aname);"w = ";Str(iw)
print #fh, "Const ";trim(aname);"h = ";Str(ih)
print #fh, "Dim Shared " & trim(aname) & "(" & str(iw * ih) & ") As UInteger = { _"
 
for x = 0 to iw - 1
    for y = 0 to ih - 1
        bmvals(x + y * iw) = point(x, y)
    next
next

for i = lbound(bmvals) to ubound(bmvals)
    cnt += 1
    if i = ubound(bmvals) then
        print #fh, "&h" & hex(bmvals(i)) & "}"
    else
        if cnt < 8 then
            print #fh, "&h" & hex(bmvals(i)) & ",";
        else
            print #fh, "&h" & hex(bmvals(i)) & ", _"
            cnt = 0
        end if
    end if
next
close fh
end

Offline Clyde

  • A Little Fuzzy Wuzzy
  • DBF Aficionado
  • ******
  • Posts: 7271
  • Karma: 71
    • View Profile
Re: Convert
« Reply #1 on: February 17, 2009 »
Cheers for sharing it dude, nice one :)
Still Putting The IT Into Gravy
If Only I Knew Then What I Know Now.

Challenge Trophies Won:

Offline Shockwave

  • good/evil
  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 17409
  • Karma: 498
  • evil/good
    • View Profile
    • My Homepage
Re: Convert
« Reply #2 on: February 17, 2009 »
Cheers Rick :) Have some good karma for this useful tool :D
Shockwave ^ Codigos
Challenge Trophies Won:

Offline Clyde

  • A Little Fuzzy Wuzzy
  • DBF Aficionado
  • ******
  • Posts: 7271
  • Karma: 71
    • View Profile
Re: Convert
« Reply #3 on: February 18, 2009 »
Not only is it very usefull, you have also taught me about saving data.

Cheers Squire,
Clyde.
Still Putting The IT Into Gravy
If Only I Knew Then What I Know Now.

Challenge Trophies Won:

Offline rdc

  • Pentium
  • *****
  • Posts: 1495
  • Karma: 140
  • Yes, it is me.
    • View Profile
    • Clark Productions
Re: Convert
« Reply #4 on: February 19, 2009 »
No problem guys. counting_pine posted a trick for getting the dimensions of a bitmap:

Code: [Select]
'' open BMP file
filenum = FreeFile()
If Open( iname For Binary Access Read As #filenum ) <> 0 Then
Print "Cannot find " & iname & "."
Sleep
End
EndIf

' retrieve BMP dimensions
Get #filenum, 19, iw
Get #filenum, 23, ih
Close #filenum
dim bmvals(iw * ih) as uinteger


The iw is the width, and the ih is the height. Make things a bit easier. Here is a loader he made and posted on the FB forums:

Code: [Select]
'' A function that creates an image buffer with the same
'' dimensions as a BMP image, and loads a file into it.
'' Code by counting_pine
Function bmp_load( ByRef filename As String ) As Any Ptr

    Dim As Integer filenum, bmpwidth, bmpheight
    Dim img As Any Ptr

    '' open BMP file
    filenum = FreeFile()
    If Open( filename For Binary Access Read As #filenum ) <> 0 Then Return 0

        '' retrieve BMP dimensions
        Get #filenum, 19, bmpwidth
        Get #filenum, 23, bmpheight

    Close #filenum

    '' create image with BMP dimensions
    img = ImageCreate( bmpwidth, Abs(bmpheight) )

    If img = 0 Then Return 0

    '' load BMP file into image buffer
    If BLoad( filename, img ) <> 0 Then ImageDestroy( img ): Return 0

    Return img

End Function

This returns an FB image. I am using it like this:

Code: [Select]
  'Load the font into the buffer.
  fontbuffer = bmp_load("media/bradley.bmp")
  If fontbuffer = 0 Then
    Print "Could not load font file: bradley.bmp."
    Sleep
    Exit Sub
EndIf

Makes it real easy to load up your graphic data in FB. counting-pine gets the props here.

Offline zawran

  • Sponsor
  • Pentium
  • *******
  • Posts: 909
  • Karma: 67
    • View Profile
Re: Convert
« Reply #5 on: February 19, 2009 »
I am not sure it useful to you, but I did some code long time ago to get the width and height of .png and .jpg images without loading the complete file. It is written in bmax, but should be fairly straight forward to convert to other basic type languages. I have not used freebasic for years, so unfortunaltely I have forgotten most of the syntax, otherwise I might have given it a try myself.

But if this sounds useful to you, then here is the code:

Code: [Select]

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

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

imageWidthHeightJPG("4.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

Offline Clyde

  • A Little Fuzzy Wuzzy
  • DBF Aficionado
  • ******
  • Posts: 7271
  • Karma: 71
    • View Profile
Re: Convert
« Reply #6 on: February 20, 2009 »
Splendid stuff both of yas! Thanks :)

I think I know why Im having bitmap troubles; just noticed the abs on the heght. Either that or my bitmaps are being corrupted by the conversion process some how.
Still Putting The IT Into Gravy
If Only I Knew Then What I Know Now.

Challenge Trophies Won:

Offline Jim

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 5301
  • Karma: 402
    • View Profile
Re: Convert
« Reply #7 on: February 20, 2009 »
The abs() is there because Windows BMP files are most often stored upside down.  When it does this, it negates the height.

You might find that even with the abs, your images appear upside down.

Jim
Challenge Trophies Won:

Offline zawran

  • Sponsor
  • Pentium
  • *******
  • Posts: 909
  • Karma: 67
    • View Profile
Re: Convert
« Reply #8 on: February 20, 2009 »
You might as well use .png instead of .bmp since its a packaged format, but without quality loss, so you will still get the image as it was ment, but you save a lot on the file size.

Offline Jim

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 5301
  • Karma: 402
    • View Profile
Re: Convert
« Reply #9 on: February 20, 2009 »
I think that's true in nearly every case when you want a 24bit graphic, but when BMP is the win is when you use it to do a 4bit or 8bit  bitmap, especially with RLE encoding.  In that case you get a 16 or 256 colour graphic which is  truly tiny, and PNG cannot match it.

Jim
Challenge Trophies Won:

Offline Clyde

  • A Little Fuzzy Wuzzy
  • DBF Aficionado
  • ******
  • Posts: 7271
  • Karma: 71
    • View Profile
Re: Convert
« Reply #10 on: February 20, 2009 »
Great snippets of wisdom, I must say so myself.

Zawran: With your png source, do you need ZLib ?
Still Putting The IT Into Gravy
If Only I Knew Then What I Know Now.

Challenge Trophies Won:

Offline zawran

  • Sponsor
  • Pentium
  • *******
  • Posts: 909
  • Karma: 67
    • View Profile
Re: Convert
« Reply #11 on: February 20, 2009 »
Quote
do you need ZLib

It should work just as it is.