Ooops
November 30, 2020, 02:10:42 AM

Author Topic: [bb] Read image and write to bb data file by markcw [ 1+ years ago ]  (Read 534 times)

Offline BlitzBot

  • Jr. Member
  • **
  • Posts: 1
Title : Read image and write to bb data file
Author : markcw
Posted : 1+ years ago

Description : 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.


Code :
Code: BlitzBasic
  1. ;Read Image Write Data, on 21/9/06
  2.  
  3. Graphics 640,480,0,2
  4. SetBuffer BackBuffer()
  5.  
  6. fileout$="temp.bb"
  7. filein$="yourname.bmp" ;image in
  8.  
  9. image=LoadImage(filein$)
  10. ok=ReadImageWriteData(filein$,fileout$,image)
  11.  
  12. ;Main loop
  13. While Not KeyHit(1)
  14.  Cls
  15.  
  16.  DrawImage image,50,50 ;draw image in
  17.  
  18.  Text 0,0,"ok="+ok+" filein$="+filein$+" fileout$="+fileout$
  19.  Text 0,20,"width="+ImageWidth(image)+" height="+ImageHeight(image)
  20.  
  21.  Flip
  22. Wend
  23.  
  24. ;Functions
  25. Function ReadImageWriteData(filein$,fileout$,image)
  26.  ;Read an image and write 24-bit color data to bb file
  27.  ;filein$=image file, fileout$=bb file, image=image handle
  28.  
  29.  Local file,width,height,buffer,imagesize,x,y,rgb,nextrgb,count
  30.  
  31.  ;Write fileout.bb
  32.  If fileout$="" Then Return False ;fail code
  33.  file=WriteFile(fileout$)
  34.  If Not file Then Return False ;write fail
  35.  
  36.  width=ImageWidth(image)
  37.  height=ImageHeight(image)
  38.  buffer=ImageBuffer(image)
  39.  imagesize=width Or (height Shl 16)
  40.  
  41.  ;write title comment, image data label and data command
  42.  WriteStringAscii(file,";"+fileout$)
  43.  WriteByte file,13 : WriteByte file,10 ;newline
  44.  WriteByte file,13 : WriteByte file,10 ;newline
  45.  WriteStringAscii(file,"."+Left(filein$,Len(filein$)-4))
  46.  WriteStringAscii(file,"_"+Right(filein$,3))
  47.  WriteByte file,13 : WriteByte file,10 ;newline
  48.  WriteStringAscii(file,"Data ")
  49.  WriteValueAscii(file,imagesize) ;first value is width/height
  50.  
  51.  ;read pixels to 8-bit run/24-bit color integer
  52.  LockBuffer buffer
  53.  For y=0 To height-1
  54.   For x=0 To width-1
  55.    rgb=ReadPixelFast(x,y,buffer) And $00FFFFFF
  56.    If x<width-1
  57.     nextrgb=ReadPixelFast(x+1,y,buffer) And $00FFFFFF
  58.    Else
  59.     nextrgb=$FF000000
  60.    EndIf
  61.    If rgb=nextrgb Then count=count+1
  62.    If rgb<>nextrgb Or x=width-1 Or count=254
  63.     integer=(count+1) Or (rgb Shl 8)
  64.     WriteByte file,Asc(",")
  65.     WriteValueAscii(file,integer)
  66.     If count=254 Then count=-1 Else count=0
  67.    EndIf
  68.   Next
  69.  Next
  70.  UnlockBuffer buffer
  71.  
  72.  ;write end comment
  73.  WriteByte file,13 : WriteByte file,10 ;newline
  74.  WriteStringAscii(file,";end "+Left(filein$,Len(filein$)-4))
  75.  WriteStringAscii(file,"_"+Right(filein$,3))
  76.  
  77.  CloseFile file
  78.  Return True ;success code
  79.  
  80. End Function
  81.  
  82. Function WriteValueAscii(file,value)
  83.  ;file=file handle, value=byte/short/integer
  84.  
  85.  Local ascii$,i,char$
  86.  ascii$=Str(value)
  87.  For i=1 To Len(ascii$)
  88.   char$=Mid(ascii$,i,1)
  89.   WriteByte(file,Asc(char$))
  90.  Next
  91.  
  92. End Function
  93.  
  94. Function WriteStringAscii(file,ascii$)
  95.  ;file=file handle, ascii$=ascii string
  96.  
  97.  Local i,char$
  98.  For i=1 To Len(ascii$)
  99.   char$=Mid(ascii$,i,1)
  100.   WriteByte(file,Asc(char$))
  101.  Next
  102.  
  103. End Function


Comments :


markcw(Posted 1+ years ago)

 This is the second part. It writes images from the data labels.
Code: [Select]
;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 1+ 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.
Code: [Select]
;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 1+ 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.


mv333(Posted 1+ years ago)

 What's the difference between this, and the older code you posted <a href="codearcs78db.html?code=1505" target="_blank">here[/url]?I tried to see which one creates smaller bb data files. With my first pic, the older was better. But with another pic, this one was better......


markcw(Posted 1+ years ago)

 The run length encoding is not a very good compression algorithm, sometimes it may be longer than the straight data. It works best on simple graphics with large areas of the same color, it would be good for masked/simple graphics but I would recommend the older code for all other purposes. [/i]

 

SimplePortal 2.3.6 © 2008-2014, SimplePortal