Code archives/File Utilities/Read image and write to bb data file

This code has been declared by its author to be Public Domain code.

Download source code

Read image and write to bb data file by markcw
(Posted 20 years ago)
This is a 2-part code entry. It is designed to pack any images inside a blitz executable and then write them from data labels.

The first part is to read an image and write the data to a bb data file. The second is to read the data (as an include) and create the image.

It uses a run-length encoded system for 24-bit color (where the run count is the first byte and the 24-bit color is the higher 3 bytes). Since it is RLE it is best used on images with few colors.

It uses the width and height to calculate the end of data instead of an end of data signature.

I'm actually really surprised i got this working as i found it very tricky to work out.
;Read Image Write Data, on 21/9/06

Graphics 640,480,0,2
SetBuffer BackBuffer()

fileout$="temp.bb"
filein$="yourname.bmp" ;image in

image=LoadImage(filein$)
ok=ReadImageWriteData(filein$,fileout$,image)

;Main loop
While Not KeyHit(1)
 Cls

 DrawImage image,50,50 ;draw image in

 Text 0,0,"ok="+ok+" filein$="+filein$+" fileout$="+fileout$
 Text 0,20,"width="+ImageWidth(image)+" height="+ImageHeight(image)

 Flip
Wend

;Functions
Function ReadImageWriteData(filein$,fileout$,image)
 ;Read an image and write 24-bit color data to bb file
 ;filein$=image file, fileout$=bb file, image=image handle

 Local file,width,height,buffer,imagesize,x,y,rgb,nextrgb,count

 ;Write fileout.bb
 If fileout$="" Then Return False ;fail code
 file=WriteFile(fileout$)
 If Not file Then Return False ;write fail

 width=ImageWidth(image)
 height=ImageHeight(image)
 buffer=ImageBuffer(image)
 imagesize=width Or (height Shl 16)

 ;write title comment, image data label and data command
 WriteStringAscii(file,";"+fileout$)
 WriteByte file,13 : WriteByte file,10 ;newline
 WriteByte file,13 : WriteByte file,10 ;newline
 WriteStringAscii(file,"."+Left(filein$,Len(filein$)-4))
 WriteStringAscii(file,"_"+Right(filein$,3))
 WriteByte file,13 : WriteByte file,10 ;newline
 WriteStringAscii(file,"Data ")
 WriteValueAscii(file,imagesize) ;first value is width/height

 ;read pixels to 8-bit run/24-bit color integer
 LockBuffer buffer
 For y=0 To height-1
  For x=0 To width-1
   rgb=ReadPixelFast(x,y,buffer) And $00FFFFFF
   If x<width-1
    nextrgb=ReadPixelFast(x+1,y,buffer) And $00FFFFFF
   Else
    nextrgb=$FF000000
   EndIf
   If rgb=nextrgb Then count=count+1
   If rgb<>nextrgb Or x=width-1 Or count=254
    integer=(count+1) Or (rgb Shl 8)
    WriteByte file,Asc(",")
    WriteValueAscii(file,integer)
    If count=254 Then count=-1 Else count=0
   EndIf
  Next
 Next
 UnlockBuffer buffer

 ;write end comment
 WriteByte file,13 : WriteByte file,10 ;newline
 WriteStringAscii(file,";end "+Left(filein$,Len(filein$)-4))
 WriteStringAscii(file,"_"+Right(filein$,3))

 CloseFile file
 Return True ;success code

End Function

Function WriteValueAscii(file,value)
 ;file=file handle, value=byte/short/integer

 Local ascii$,i,char$
 ascii$=Str(value)
 For i=1 To Len(ascii$)
  char$=Mid(ascii$,i,1)
  WriteByte(file,Asc(char$))
 Next

End Function

Function WriteStringAscii(file,ascii$)
 ;file=file handle, ascii$=ascii string

 Local i,char$
 For i=1 To Len(ascii$)
  char$=Mid(ascii$,i,1)
  WriteByte(file,Asc(char$))
 Next

End Function

Comments

markcw
(Posted 20 years ago)
This is the second part. It writes images from the data labels.

;Read Data Write Image, on 21/9/06

Graphics3D 640,480,0,2
SetBuffer BackBuffer()

Restore yourname_bmp ;image data label

image=ReadDataWriteImage() ;image out

;Main loop
While Not KeyHit(1)
 Cls

 DrawImage image,50,50 ;draw image out

 Text 0,0,"width="+ImageWidth(image)+" height="+ImageHeight(image)

 Flip
Wend

;Includes
Include "temp.bb"

;Functions
Function ReadDataWriteImage()
 ;Read a data label, create image and write 24-bit color data

 Local imagesize,width,height,image,buffer,i,integer,count,rgb,x,y,ix

 ;create image
 Read imagesize ;first value is width/height
 width=imagesize And $0000FFFF
 height=(imagesize And $FFFF0000) Shr 16
 image=CreateImage(width,height)
 buffer=ImageBuffer(image)

 ;write pixels from 8-bit run/24-bit color integer
 LockBuffer buffer
 While i<width*height
  Read integer
  count=integer And $000000FF
  rgb=(integer And $FFFFFF00) Shr 8
  For x=ix To ix+count-1
   WritePixelFast x,y,rgb,buffer
  Next
  ix=ix+count
  i=i+count
  If ix>=width Then y=y+1 : ix=0
 Wend
 UnlockBuffer buffer

 Return image ;image handle

End Function


markcw
(Posted 20 years ago)
Here is the second part for textures.

edit: I just noticed CreateTexture only works on ^2 sizes. Maybe it is just my gfx card, i don't know.

;Read Data Write Texture, on 21/9/06

Graphics3D 640,480,0,2
SetBuffer BackBuffer()

camera=CreateCamera()
light=CreateLight()
RotateEntity light,45,45,0

Restore yourname_bmp ;image data label

tex=ReadDataWriteTexture() ;texture out

cube=CreateCube()
PositionEntity cube,0,0,5
EntityTexture cube,tex

;Main loop
While Not KeyHit(1)
 RenderWorld

 TurnEntity cube,0.4,0.3,0.2

 Text 0,0,"width="+TextureWidth(tex)+" height="+TextureHeight(tex)

 Flip
Wend

;Includes
Include "temp.bb"

;Functions
Function ReadDataWriteTexture()
 ;Read a data label, create texture and write 24-bit color data

 Local texsize,width,height,tex,buffer,i,integer,count,rgb,x,y,ix

 ;create texture
 Read texsize ;first value is width/height
 width=texsize And $0000FFFF
 height=(texsize And $FFFF0000) Shr 16
 tex=CreateTexture(width,height)
 buffer=TextureBuffer(tex)

 ;write pixels from 8-bit run/24-bit color integer
 LockBuffer buffer
 While i<width*height
  Read integer
  count=integer And $000000FF
  rgb=(integer And $FFFFFF00) Shr 8
  For x=ix To ix+count-1
   WritePixelFast x,y,rgb,buffer
  Next
  ix=ix+count
  i=i+count
  If ix>=width Then y=y+1 : ix=0
 Wend
 UnlockBuffer buffer

 Return tex ;texture handle

End Function


Terra1
(Posted 19 years ago)
...your a genius. Works a charm, now I don't have to include images with my .exe file, which people are tempted to edit.
Thanks.

Code Archives Forum