Load image from MySQL

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

Load image from MySQL

Post by Gablea »

Hi everyone

Just wanted to get your input on a function that I would like to intoduce into some of my software.

I have stored in my MySQL database a image that has been converted to base64 code. Now in the VB app I can easily convert this back into a image and display it I was just wondering if that is possible with freebasic?

I would need to create the images on the fly
badidea
Posts: 2586
Joined: May 24, 2007 22:10
Location: The Netherlands

Re: Load image from MySQL

Post by badidea »

Gablea wrote:I have stored in my MySQL database a image that has been converted to base64 code. Now in the VB app I can easily convert this back into a image and display it I was just wondering if that is possible with freebasic?
Why not? Conversion between binary blob and base64 string is relative simple, see e.g.:
https://freebasic.net/forum/viewtopic.p ... 30#p245436
https://freebasic.net/forum/viewtopic.p ... 64#p245435
But you do need to know the format of the binary blob. Bytes per pixel, size image of image, etc. Is this included in the data, fixed, or stored separately in the database? In other words, is it raw pixel data or a gif/jpeg/bitmap/png which is stored as base64 encoded string?
Gablea
Posts: 1104
Joined: Apr 06, 2010 0:05
Location: Northampton, United Kingdom
Contact:

Re: Load image from MySQL

Post by Gablea »

the image that is stored in the database is a jpeg image that is just converted to BASE64

Code: Select all

    Public EncodingType As ImageFormat = ImageFormat.Jpeg
    Public EncodingTypeSting As String = "data:image/jpeg;base64,"

Public Function ConvertToBASE64(ByVal image As Image) As String
        Dim Image64Code As String = EncodingTypeSting & imageToBASE64(image, EncodingType)
        Return Image64Code
End Function
This is the code I use to convert the image to a BASE64

Code: Select all

UpdateButtonImage_Indatabase("", ButtonNumberToUse, "PLUMenu", ConvertToBASE64(bmp))
then I call the above function

Code: Select all

Public Sub UpdateButtonImage_Indatabase(ByVal PLUListNumber As String, ByVal ButtonNumber As String, ByVal PLUSide As String, ByVal BASE64Code As String)
        SQLCommand = vbNullString
        Select Case PLUSide
            Case "PLUMenu"
                SQLCommand += "Update plumenu "
                SQLCommand += "SET "
                SQLCommand += "button_image='" & BASE64Code & "' "
                SQLCommand += "Where button_Number='" & ButtonNumber & "';"

            Case "PLUList"
                SQLCommand += "Update plulist "
                SQLCommand += "SET "
                SQLCommand += "button_image='" & BASE64Code & "' "
                SQLCommand += "Where button_Number='" & ButtonNumber & "' and plulistid='" & PLUListNumber & "';"
        End Select

        SendToDatabase(SQLCommand)
    End Sub
This works fine in VB.net

Say i can get this to work how would I bind the image to a "button"


this is the sub I was given from this forum that I use to draw the command keys

Code: Select all

Sub drawButton(ByVal btn as Button, ByVal FontSize As Integer)
    dim as uinteger c1,c2
    if btn.a = 1 then
        c1 = rgb(20,20,20)
        c2 = rgb(200,200,200)
    else
        c1 = rgb(200,200,200)
        c2 = rgb(20,20,20)
    end if
    line (btn.x,btn.y)-(btn.x+btn.w,btn.y+btn.h),rgb(100,100,100),bf
    line (btn.x,btn.y)-(btn.x+btn.w,btn.y),c1  'top line
    line (btn.x,btn.y)-(btn.x,btn.y+btn.h),c1  'left line
    line (btn.x,btn.y+btn.h)-(btn.x+btn.w,btn.y+btn.h),c2
    line (btn.x+btn.w,btn.y)-(btn.x+btn.w,btn.y+btn.h),c2

  	With font
  		Dim FontSizeLocal As String
  		FontSizeLocal = (fontSize-1) & "1"
  		
  		If FontSizeLocal = "11" Then
  			FontSizeLocal = "15"
  		EndIf
  		
  		.fontindex = FontSize 
	   .backcolor = TransparentColour
	   .forecolor = Black
		.drawstring (,btn.t1,btn.x+5-btn.a,btn.y+5-btn.a)
    	.drawstring (,btn.t2,btn.x+5-btn.a,btn.y+Val(FontSizeLocal)-btn.a)		
  	End With
end Sub
badidea
Posts: 2586
Joined: May 24, 2007 22:10
Location: The Netherlands

Re: Load image from MySQL

Post by badidea »

Gablea wrote:the image that is stored in the database is a jpeg image that is just converted to BASE64
That makes it more complex I think, as FreeBASIC does not support jpeg natively, but requires an external library. I never try jpeg with FreeBASIC myself.
Gablea wrote:Say i can get this to work how would I bind the image to a "button"
That depends on on what kind of graphics toolkit / GUI / widget library. If you mean the Windows API for a button, I cannot help much. The only one I used with FreeBasic is FLTK (see e.g.: https://freebasic.net/forum/viewtopic.p ... tk#p259922)
Last edited by badidea on Apr 11, 2019 22:39, edited 1 time in total.
dodicat
Posts: 7976
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Load image from MySQL

Post by dodicat »

Did you get your Xfont to work?
Here are encode64/decode64 (windows)
Test with a bitmap.

Code: Select all


Declare Function CryptBinaryToString Lib "Crypt32"Alias "CryptBinaryToStringA"(As zstring Ptr,As Long,As Long,As zstring Ptr,As Long Ptr) As Long

Declare Function CryptStringToBinary Lib "Crypt32"Alias "CryptStringToBinaryA"(As zstring Ptr,As Long,As Long,As Byte Ptr,As Long Ptr,As Long,As Long Ptr) As Long


 Function Base64Decode(s As String) As string 
    Dim As Long  Length = Len(s)
    static As ubyte b()
    redim b(length)
    CryptStringToBinary( (s),Length,1,@b(0),@Length,0, 0)
    dim as string result=string(length,0)'+1
    for n as long=0 to length
        result[n]=b(n)
        next
    Function=result
End Function   

Function Base64Encode(p As String ) As string
    Dim As Long L=Len(p)*2,lp=len(p)
    static As ubyte  s()
    redim s(L)
   CryptBinaryToString(Strptr(p),Lp,1,@s(0),@L)
    dim as string st=string(L,0)
   for n as long=0 to L
       st[n]=s(n)
       next
    Function=st
End Function

 #Include "file.bi"
Sub savefile(filename As String,p As String)
    Dim As Integer n
    n=Freefile
    If Open (filename For Binary Access Write As #n)=0 Then
        Put #n,,p
        Close
    Else
        Print "Unable to save " + filename
    End If
End Sub

Function loadfile(file as string) as String
	If FileExists(file)=0 Then Print file;" not found":Sleep:end
   var  f=freefile
    Open file For Binary Access Read As #f
    Dim As String text
    If Lof(f) > 0 Then
      text = String(Lof(f), 0)
      Get #f, , text
    End If
    Close #f
    return text
end Function

dim as string f="gb.bmp" '<-------- YOUR BITMAP HERE
dim as string s=loadfile(f)

var a=Base64Encode(s)
print a
savefile(f+".txt",a)
a=loadfile(f+".txt")
var b= Base64Decode(a)
print b=s
savefile("new"+f,b)
screen 20,32

bload("new"+f)
sleep
'shell "newbase64.exe"  
badidea
Posts: 2586
Joined: May 24, 2007 22:10
Location: The Netherlands

Re: Load image from MySQL

Post by badidea »

I misread, you use a custom button I see. That should not be too hard... I'll try something...
Last edited by badidea on Apr 11, 2019 23:55, edited 1 time in total.
dodicat
Posts: 7976
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Load image from MySQL

Post by dodicat »

Here is a bitmap to a button idea.

Code: Select all

 

#include once "windows.bi"


sub getsize(picture as string,byref dimensionx as long,byref dimensiony as long)
     Open picture For Binary access read As #1
    Get #1, 19, dimensionx
    Get #1, 23, dimensiony
    Close #1
end sub

DIM szBitmap AS STRING  = "C:\Users\User\Desktop\gb.bmp"  '' path to a bitmap

dim as long w,h
getsize(szbitmap,w,h)
if w*h then print "OK" else print "Loading error":sleep:end

Dim As MSG msg
Dim Shared As HWND hWnd, edit
hWnd = CreateWindowEx( 0, "#32770", "Bitmap Button Test", WS_OVERLAPPEDWINDOW Or WS_VISIBLE , 100, 0, 800, 600, 0, 0, 0, 0 )

edit = CreateWindowEx( 0, "BUTTON", "Button" , WS_BORDER Or WS_VISIBLE Or WS_CHILD or ANSI_CHARSET OR BS_PUSHBUTTON OR BS_BITMAP, 10 , 10 , w ,h , hWnd, 0, 0, 0 )

' Load the bitmap and set its handle

DIM hBitmap AS HANDLE = LoadImage(0, szBitmap, IMAGE_BITMAP, w, h,  LR_LOADFROMFILE )

IF hbitmap THEN SendMessage(edit, BM_SETIMAGE, IMAGE_BITMAP, CAST(LPARAM, hbitmap))

While GetMessage( @msg, 0, 0, 0 )
    
    TranslateMessage( @msg )
    DispatchMessage( @msg )
    
    Select Case msg.hwnd
        Case hWnd
            Select Case msg.message
                Case 273 : PostQuitMessage(0)
            End Select 
    End Select
    
Wend
PostQuitMessage(0)
End 
badidea
Posts: 2586
Joined: May 24, 2007 22:10
Location: The Netherlands

Re: Load image from MySQL

Post by badidea »

Here is my 'quick hack' 'hover over' button code (windows/linux/dos?):

Code: Select all

#include once "file.bi"

type bitmap_header field = 1
	bfType          as ushort
	bfsize          as ulong
	bfReserved1     as ushort
	bfReserved2     as ushort
	bfOffBits       as ulong
	biSize          as ulong
	biWidth         as ulong
	biHeight        as ulong
	biPlanes        as ushort
	biBitCount      as ushort
	biCompression   as ulong
	biSizeImage     as ulong
	biXPelsPerMeter as ulong
	biYPelsPerMeter as ulong
	biClrUsed       as ulong
	biClrImportant  as ulong
end type

type image_type
	dim as any ptr pFbImg
	dim as long xSize, ySize
	declare function createFromBmp(fileName as string) as integer
	declare sub destroy()
	'~ declare destructor()
end type

function image_type.createFromBmp(fileName as string) as integer
	dim as bitmap_header bmp_header
	if fileExists(filename) then
		open fileName for binary as #1
			get #1, , bmp_header
		close #1
		xSize = bmp_header.biWidth
		ySize = bmp_header.biHeight
		pFbImg = imagecreate(xSize, ySize, &hff000000)
		bload fileName, pFbImg
		print "Bitmap loaded: " & filename
	else
		print "File not found: " & filename
		sleep 1000
		return -1
	end if
	return 0
end function

sub image_type.destroy()
	if (pFbImg <> 0) then
		imagedestroy(pFbImg)
		pFbImg = 0
	end if
end sub

'~ destructor image_type()
	'~ destroy()
'~ end destructor

'===============================================================================

type Button
	dim as long x, y 'position
	dim as long w, h 'size
	dim as long a 'some property the changes the colors
	dim as image_type image
end type

Sub drawButton(ByVal btn as Button, ByVal FontSize As Integer)
	dim as uinteger c1,c2
	if btn.a = 1 then
		c1 = rgb(20,20,20)
		c2 = rgb(200,200,200)
	else
		c1 = rgb(200,200,200)
		c2 = rgb(20,20,20)
	end if
	line (btn.x,btn.y)-(btn.x+btn.w,btn.y+btn.h),rgb(100,100,100),bf
	line (btn.x,btn.y)-(btn.x+btn.w,btn.y),c1  'top line
	line (btn.x,btn.y)-(btn.x,btn.y+btn.h),c1  'left line
	line (btn.x,btn.y+btn.h)-(btn.x+btn.w,btn.y+btn.h),c2
	line (btn.x+btn.w,btn.y)-(btn.x+btn.w,btn.y+btn.h),c2
	if btn.a then
		put (btn.x + 3, btn.y + 1), btn.image.pFbImg, alpha
	else
		put (btn.x + 1, btn.y - 1), btn.image.pFbImg, alpha
	end if
	'~ With font
		'~ Dim FontSizeLocal As String
		'~ FontSizeLocal = (fontSize-1) & "1"

		'~ If FontSizeLocal = "11" Then
		'~ FontSizeLocal = "15"
		'~ EndIf

		'~ .fontindex = FontSize
		'~ .backcolor = TransparentColour
		'~ .forecolor = Black
		'~ .drawstring (,btn.t1,btn.x+5-btn.a,btn.y+5-btn.a)
		'~ .drawstring (,btn.t2,btn.x+5-btn.a,btn.y+Val(FontSizeLocal)-btn.a)      
	'~ End With
end Sub

'===============================================================================

screenres 800, 600, 32

dim as integer mx, my, mw, mb 'mouse position, wheel, buttons
dim as Button myButton = type(200, 100, 120, 40, 1)

myButton.image.createFromBmp("mybutton.bmp")

while not multikey(1) 'loop until escape
	getmouse mx, my, mw, mb
	myButton.a = 0
	if mx > myButton.x and mx < myButton.x + myButton.w then
		if my > myButton.y and my < myButton.y + myButton.h then myButton.a = 1
	end if 

	screenlock
	line(0, 0)-(800-1, 600-1), rgb(0, 0, 0), bf
	
	drawButton(myButton, 0)
	locate 1,1: print "mouse:", mx, my, mw, mb;
	locate 2,1: print "above:", myButton.a
	screenunlock

	sleep 1,1
wend

sleep

Uses this bitmap:
Image
(https://nr100.home.xs4all.nl/badidea/mybutton.bmp)

It most likely contains a bug, because I had to disable destructor to prevent it from crashing :-)
dodicat
Posts: 7976
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Load image from MySQL

Post by dodicat »

Badidea.
You pass byval btn as Button to the drawbutton sub, your destructor is getting called each time you access drawbutton.
If you pass byref (the default for a udt) your destructor is called only when you exit the program.
Post Reply