Embedded graphics

General FreeBASIC programming questions.
Gablea
Posts: 1063
Joined: Apr 06, 2010 0:05
Location: Northampton, United Kingdom
Contact:

Embedded graphics

Postby Gablea » Oct 10, 2021 20:45

Hi everyone,

Is it possible to embedded within a program a graphical image and display this when the app is running

I ask as at the moment I am loading images from file but for some reason they are black at the moment.

If I could embed this into the application I know the graphical screen layout will work every time and I wouldn't have to worry about the images being on the hard drive

Or am I thinking along a wrong direction?
badidea
Posts: 2387
Joined: May 24, 2007 22:10
Location: The Netherlands

Re: Embedded graphics

Postby badidea » Oct 10, 2021 21:05

Gablea wrote:Is it possible to embedded within a program a graphical image and display this when the app is running

You mean, embed in source code? Yes that is possible, I have seen on this forum posts with many data statements and base64 encoding containing the image. It will slow down compilation.

Gablea wrote:I ask as at the moment I am loading images from file but for some reason they are black at the moment.

If I could embed this into the application I know the graphical screen layout will work every time and I wouldn't have to worry about the images being on the hard drive

Or am I thinking along a wrong direction?

If you cannot trust the hard drive in a computer, then you have a big problem. Add some debugging code. Check if file exists. Check if image pointer is zero. Etc.
Last edited by badidea on Oct 11, 2021 0:03, edited 1 time in total.
D.J.Peters
Posts: 8336
Joined: May 28, 2005 3:28
Contact:

Re: Embedded graphics

Postby D.J.Peters » Oct 10, 2021 21:28

@Gablea with FBImage you can read JPG, PNG, BMP etc. from memory also !
https://www.freebasic.net/forum/viewtopic.php?f=14&t=24105

you can encode/decode images as well see at "test_encode.bas" "test_decode.bas"

Joshy

Code: Select all

#include once "FBImage.bi"
* loading image from memory
var img = LoadRGBAMemory(RamAdr, nBytes)
put (0,0),img,PSET
sleep
Gablea
Posts: 1063
Joined: Apr 06, 2010 0:05
Location: Northampton, United Kingdom
Contact:

Re: Embedded graphics

Postby Gablea » Oct 10, 2021 22:23

Thanks for teh replay everyone

I have updated my code to use

BackGround_Loading = LoadRGBAFile(ExePath & FileSeperator & "images" & FileSeperator & "boot.png")

And this loads fine but I get no text showing on screen


This loads my screen

Code: Select all

Sub StartupScreenBackground(ByVal ScreenType As String)
   ScreenSet 1, 0
      Select Case ScreenType
         Case "BootUp"
            Put (0,0), BackGround_Loading, Alpha
            DisplayTaskBar(0)            
               
         Case "Download"
            Put (0,0), BackGround_Loading, Alpha
               With font
                  .fontindex = 3
                  .backcolor = TransparentColour
                  .forecolor = Black
                  .drawstring (,"Downloading Data Files....",300,1)
               End With
            DisplayTaskBar(1)
      End Select
   
      Wait &h3DA, 8
   ScreenCopy
End Sub



This code displays text on scteen (this worked before i changed to the New load format)

Code: Select all

Sub UpdateScreen_Loading(ByVal DisplayText As String, ByVal ScreenName As String)

   Print DisplayText

   ScreenSet 1, 0
   StartupScreenBackground(ScreenName)
   
      For x as integer = 32 to 1 step -1
         ScreenTextList(x) = ScreenTextList(x-1)
      Next x   
      ScreenTextList(0) = DisplayText
      
      With font
         .fontindex = 2 ' small text
         .backcolor = White
         .forecolor = black
         .drawstring(,ScreenTextList(32),15,70)
         .drawstring(,ScreenTextList(31),15,85)
         .drawstring(,ScreenTextList(30),15,100)
         .drawstring(,ScreenTextList(29),15,115)
         .drawstring(,ScreenTextList(28),15,130)
         .drawstring(,ScreenTextList(27),15,145)
         .drawstring(,ScreenTextList(26),15,160)
         .drawstring(,ScreenTextList(25),15,175)
         .drawstring(,ScreenTextList(24),15,190)
         .drawstring(,ScreenTextList(23),15,205)
         .drawstring(,ScreenTextList(22),15,220)
         .drawstring(,ScreenTextList(21),15,235)
         .drawstring(,ScreenTextList(20),15,250)
         .drawstring(,ScreenTextList(19),15,265)
         .drawstring(,ScreenTextList(18),15,280)
         .drawstring(,ScreenTextList(17),15,295)
         .drawstring(,ScreenTextList(16),15,310)
         .drawstring(,ScreenTextList(15),15,325)
         .drawstring(,ScreenTextList(14),15,340)
         .drawstring(,ScreenTextList(13),15,355)
         .drawstring(,ScreenTextList(12),15,370)
         .drawstring(,ScreenTextList(11),15,385)
         .drawstring(,ScreenTextList(10),15,400)
          .drawstring(,ScreenTextList(9),15,415)
          .drawstring(,ScreenTextList(8),15,430)
          .drawstring(,ScreenTextList(7),15,445)
          .drawstring(,ScreenTextList(6),15,460)
          .drawstring(,ScreenTextList(5),15,475)
          .drawstring(,ScreenTextList(4),15,490)
          .drawstring(,ScreenTextList(3),15,505)
          .drawstring(,ScreenTextList(2),15,520)
          .drawstring(,ScreenTextList(1),15,535)
          .drawstring(,ScreenTextList(0),15,550)
      End With
      
      Wait &h3DA, 8
   ScreenCopy      
End Sub


what have i missed? as if i click on the app for a breif second the text i want to show is shown and then it vanishes again
Gablea
Posts: 1063
Joined: Apr 06, 2010 0:05
Location: Northampton, United Kingdom
Contact:

Re: Embedded graphics

Postby Gablea » Oct 10, 2021 22:24

badidea wrote:If you cannot trust the hard drive in a computer, then you have a big problem. Add some debugging code. Check if file exists. Check if image pointer is zero. Etc.


No the hard drive is fine on the machines I use (as they are SSD or DOM (Disk on module))
I am more worried about myself forgetting to copy over the /images/ folder
coderJeff
Site Admin
Posts: 3644
Joined: Nov 04, 2005 14:23
Location: Ontario, Canada
Contact:

Re: Embedded graphics

Postby coderJeff » Oct 10, 2021 23:19

badidea wrote:I have seen on this forum posts with many data statements and base64 encoding containing the image. It will slow down compilation.

I believe that the slow compilation was fixed in fbc 1.08.0 -- #917 Long complile times for gcc backend
caseih
Posts: 1782
Joined: Feb 26, 2007 5:32

Re: Embedded graphics

Postby caseih » Oct 11, 2021 2:52

Can't you embed images in an executable on Windows using the resource compiler? On Linux there's even a utility to convert any file into a .o file you can link into an exe. See https://stackoverflow.com/questions/415 ... -using-gcc. In short the linker converts your file into a symbol that you can then access from your FB program much like you'd access any other shared variable.
UEZ
Posts: 753
Joined: May 05, 2017 19:59
Location: Germany

Re: Embedded graphics

Postby UEZ » Oct 11, 2021 6:22

For Windows you may use FB File2Bas Code Generator. It converts a file to base 64, 91, 128 or Hex32 bit which can be used within your code to embed binary files such as images.
D.J.Peters
Posts: 8336
Joined: May 28, 2005 3:28
Contact:

Re: Embedded graphics

Postby D.J.Peters » Oct 11, 2021 8:54

@Gablea if you use ScreenSet 1,0 and use Put (x,y),image,ALPHA on the hidden work page
normally you have to use the Flip command to refresh the visible page with the hidden work page !

You used the WAIT command also looks like QBASIC not FreeBASIC for me.

Joshy
Gablea
Posts: 1063
Joined: Apr 06, 2010 0:05
Location: Northampton, United Kingdom
Contact:

Re: Embedded graphics

Postby Gablea » Oct 11, 2021 11:52

D.J.Peters wrote:@Gablea if you use ScreenSet 1,0 and use Put (x,y),image,ALPHA on the hidden work page
normally you have to use the Flip command to refresh the visible page with the hidden work page !

You used the WAIT command also looks like QBASIC not FreeBASIC for me.

Joshy

Hi Joshua

What would be the command I need them to flip the screen?

That function worked when I used the old format of the image loading (dim image as any ptr) I think i used.
paul doe
Moderator
Posts: 1461
Joined: Jul 25, 2017 17:22
Location: Argentina

Re: Embedded graphics

Postby paul doe » Oct 11, 2021 17:17

dodicat
Posts: 7119
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Embedded graphics

Postby dodicat » Oct 12, 2021 22:48

hello gablea.
From what I can deduce about bitmap files is that you cannot load them in a .o or static library so they become embedded in the binary file.
You can tell this immediately from the size of the .o or .a file, much smaller than the loaded bitmap, thus you must carry the bitmap around.
I reckon you will have to hard code the data to avoid this.
It results in a large file.
Here is an example to hard code a bitmap.

Code: Select all


'Data maker

Function convertto128(Byval i As Ulong) As String
   Dim As String g
   Dim As Ulong d,m,begin=32
   Do
            d=i\128
            m=i And 127
            g=Chr((m)+begin)+g
            i=d
      Loop Until i=0 
   Return  Ltrim(g,"/")
End Function

Screen 20,32
' "colours.bas" wii be the output file

Type bitmap_size
      As Long across,down
End Type

'========================  YOUR BITMAP ===============
Dim  mybitmap As String =Command(1)'"bob.bmp" '<--- here
'==============================================

Redim Shared As Ulong pixel_colours(0,0) 'shared to increase potential size

Function size(bmp As String) As bitmap_size 'fetch bitmap width/height
      Dim As Long w,h
      Open bmp For Binary As #1
      Get #1, 19, w
      Get #1, 23, h
      Close #1
      Return Type<bitmap_size>(w,h)
End Function

Function replace(s As String) As String
   For n As Long=0 To Len(s)
      If s[n]=34 Then s[n]=165
      Next
   Return s
End Function

Sub load(bmp As String,pixels() As Long) 'load bitmap into array of point colours
      Bload bmp
      Dim count As Long
      Dim flag As Long
      Dim As String comma=","
      Dim As String dash="_"
      Dim temp As bitmap_size=size(bmp)
      Redim pixels(temp.across,temp.down)
      If temp.across*temp.down=0 Then Print bmp;" Not found ":Sleep:End
      Windowtitle Str(temp.across) + ", " + Str(temp.down)+" Press escape to finalize . . ."
      Dim max As Long=(1+temp.across)*(1+temp.down)
      For x As Long=0 To temp.across
            For y As Long=0 To temp.down
                  count+=1
            Next y
      Next x
      Dim As Long c=count'- count mod 8
      count=0
      For x As Long=0 To temp.across
            For y As Long=0 To temp.down
                  count=count+1
                  If count>c-1 Then flag=1:comma="":dash=""
                  Dim As Ulong clr=Point(x,y)
                  If clr=0 Then clr=Rgb(0,0,0)
                  pixels(x,y)=clr
                  If count=max Then
                        comma=""
                        dash=""
                  End If
                  'THIS IS THE CONVERSION
                  If count Mod 8=1 Then Print #2,"""";
                  Dim As String g= Right("0000"+convertto128(pixels(x,y)),4)
                  Var i=Instr(g,Chr(34))
                  If i Then replace(g)
                  Print #2, g ;
                  If count Mod 8=0 Then Print #2,"""" & comma + dash
                  If flag Then Print #2, """": Exit Sub
            Next y
      Next x
     
End Sub

Sub drawbitmap(mx As Long,my As Long,mybitmap As bitmap_size,scale As Single=1)
      #macro magnify(pivotx,pivoty,px,py,scale)
      Var rotx=scale*(px-pivotx)+pivotx
      Var roty=scale*(py-pivoty)+pivoty
      #endmacro
      For x As Long=mx To mx+mybitmap.across
            For y As Long=my To my+mybitmap.down
                  magnify(mx,my,x,y,scale)
                  Line(rotx-scale/2,roty-scale/2)-(rotx+scale/2,roty+scale/2),pixel_colours(x-mx,y-my),BF
            Next y
      Next x
     
End Sub

Dim As bitmap_size bitmap_info=size(mybitmap) 'get height/width of bitmap

'initial running code for external file
Open "colours.bas" For Output As #2
Print #2,"dim shared as long w,h"
Print #2,"w=";;Str(bitmap_info.across)
Print #2,"h=";Str(bitmap_info.down)
Print #2,"redim shared as ulong a((w+1)*(h+1))"
Print #2 ,"DATA _"



load mybitmap,pixel_colours() 'set bitmap colours into an array


drawbitmap(0,0,bitmap_info,1) 'SCALE

Sleep

'More running code for external file:

Print #2,""
Print #2,"screen 20,32"
Print #2,"dim shared as double magnification"
Print #2,"dim shared as any pointer image"
Print #2,"image=imagecreate(w,h)"
Print #2,"magnification= "; 1


Print #2," Function ConvertToBase10(ByVal Number As String) As ULong"
Print #2,"       number=""/""+number"
Print #2,"          Dim As ULong sum,begin=32"
Print #2,"            sum=(Asc(Left(Number,1))-begin)"
Print #2,"           For n As Integer=2 To Len(Number)"
Print #2,"                    Var z=(Number[n-1])"
Print #2,"                    If z=165 Then z=34"
Print #2,"                    sum=(sum Shl 7)+ z-begin"
Print #2,"           Next n"
Print #2,"           Return sum"
Print #2,"End Function"


Print #2,"'function ULongFromBase(N as string,_base as byte) as ulong"
Print #2,"   'return strtoul(n,0,_base)"
Print #2,"'end function"

Print #2,"function map(a as single,b as single,x as single,c as single,d as single) as single"
Print #2,"   return ((d)-(c))*((x)-(a))/((b)-(a))+(c)"
Print #2,"end function"

Print #2,"function scaler(im as any ptr) as any ptr"
Print #2,"    dim as integer w,h"
Print #2,"    dim as long x,y,xpos,ypos"
Print #2,"    imageinfo im,w,h"
Print #2,"    dim as long nx=w*magnification,ny=h*magnification"
Print #2,"    dim as any ptr im2=imagecreate(nx,ny)"
Print #2,"    for x=0 to nx"
Print #2,"        for y =0 to ny"
Print #2,"            xpos=map(0,nx,x,0,w)"
Print #2,"            ypos=map(0,ny,y,0,h)"
Print #2,"            pset im2,(x,y),point(xpos,ypos,im)"
Print #2,"        next y"
Print #2,"    next x"
Print #2,"    return im2"
Print #2,"end function"

Print #2,"sub read_data()"
Print #2,"    dim as long ctr"
Print #2,"  dim as single c=ubound(a)\8"
Print #2,"redim as string s(1 to c)"
Print #2,"for n as long=1 to c"
Print #2,"   read s(n)"
Print #2,"    for m as long=1 to len(s(n)) step 4"
Print #2,"       ctr+=1"
Print #2,"        dim as ulong x= ConvertToBase10( mid(s(n),m,4))"
Print #2,"        a(ctr)=x"
Print #2,"        next m"
Print #2,"    next n"
Print #2,"end sub"

Print #2,"Sub drawbitmap_to_image(scale as single=1,mx As long=0,my As long=0)"
Print #2,"dim as long ctr"
Print #2,"For x As long=0 To w"
Print #2,"For y As long=0 To h"
Print #2,"pset image,(x,y),a(ctr)"
Print #2,"ctr+=1"
Print #2,"Next y"
Print #2,"Next x"
Print #2,"End Sub"

Print #2,"read_data()"

Print #2,"drawbitmap_to_image(magnification)"

Print #2,"var image2=scaler(image)"

'BITMAP image is now in image
'This just displays the image

Print #2,"locate 2,2"
Print #2,"windowtitle " ;Chr(34)+ " magnification = " + "1";Chr(34)
Print #2,"put( 0, 0),image2,pset"

Print #2,"Sleep"

Print #2,"imagedestroy image"
Print #2,"imagedestroy image2"

Close #2
Locate 10,10
Print "SAVED -- colours.bas is your file"
Print "Press a key to end"
Sleep


 

You should compile the above code to .exe, I have made it drag and drop a bitmap into it.
The resultant .bas code is colours.bas, and this is the hard coded data which is a runner.
caseih
Posts: 1782
Joined: Feb 26, 2007 5:32

Re: Embedded graphics

Postby caseih » Oct 12, 2021 23:37

dodicat wrote:From what I can deduce about bitmap files is that you cannot load them in a .o or static library so they become embedded in the binary file.

Why not? Sure you can embed a bitmap file in a .o file. Except for sheer file size, which converting to a .bas file does not solve, there's no limit to what you can embed in your executable. If embedding a binary image causes the exe to be too large, then reading the image file off of the disk on demand is required.
dodicat
Posts: 7119
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Embedded graphics

Postby dodicat » Oct 13, 2021 17:28

Thanks caseih.
Tested this way.
My bitmap is bob.bmp
Went into bin/win64 to use ld and ar
shell command
ld -r -b binary -o bob.o bob.bmp
(got bob.o)
then
ar rcs -o libbob.a bob.o
(got the static library)
Note the static library is optional, using bob.o will do fine.
Then this code

Code: Select all


#inclib "bob"
screen 20,32

sub save(file as string,u as string)
    var h=freefile
    open file for binary access write as #h
    put #h, ,u
    close #h
end sub

extern bob_bmp_start alias "_binary_bob_bmp_start" as byte
extern bob_bmp_end alias "_binary_bob_bmp_end" as byte

dim ub as ubyte ptr
dim ub_length as long

ub = @bob_bmp_start
ub_length = @bob_bmp_end - @bob_bmp_start

dim as long ctr
dim as string s=string(ub_length,0)
for n as ubyte ptr=(@bob_bmp_start) to (@bob_bmp_end)
      s[ctr]=*n
      ctr+=1
next

save("newbob.bmp",s)
bload "newbob.bmp"
kill "newbob.bmp"

sleep

 

So I stand corrected, you can embed a bitmap into a .exe file.
Thank you.
(Win 10)
caseih
Posts: 1782
Joined: Feb 26, 2007 5:32

Re: Embedded graphics

Postby caseih » Oct 14, 2021 3:37

Too bad bload can't "load" directly from a byte pointer. Then it would be able to copy the embedded image directly to screen memory without going through the disk first. I looked at the source code and unfortunately gfx_bload() and all the helper functions are pretty heavily built around file i/o. Could be done but would take some work.

Edit. Actually it looks like it could be done using fmemopen(), but that's on Linux only. There are some implementations I've seen on github for Windows and MacOS, but I don't know about the suitability of using them with FB proper. Probably not the best way to go.

Return to “General”

Who is online

Users browsing this forum: No registered users and 8 guests