Display a bitmap in a Picture Gui control with a bitmap retrieved from a SQLite database

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
User avatar
JnLlnd
Posts: 490
Joined: 29 Sep 2013, 21:29
Location: Montreal, Quebec, Canada
Contact:

Display a bitmap in a Picture Gui control with a bitmap retrieved from a SQLite database

23 Dec 2023, 17:44

After I retrieve a bitmap BLOB from an SQLite database, how can I display it in a Picture Gui control without having to write it to a file like in this working example?

Code: Select all

#SingleInstance Force
#requires AutoHotkey v1.1

#Include %A_ScriptDir%\Class_SQLiteDB.ahk ; SQLite wrapper from just_me (https://autohotkey.com/boards/viewtopic.php?t=1064)
; not used #Include %A_ScriptDir%\Gdip_All.ahk ; https://github.com/marius-sucan/AHK-GDIp-Library-Compilation/blob/master/ahk-v1-1/Gdip_All.ahk
SetWorkingDir, %A_ScriptDir%

; ======================================================================================================================
; Get the Google logo or store a picture named Original.gif in the script's folder and comment this out
FileDelete, Original.gif
URLDownloadToFile, http://www.google.de/intl/de_ALL/images/logos/images_logo_lg.gif, Original.gif

Gui, 1:Add, Picture, +Border, Original.gif
Gui, 1:Show, AutoSize x50 y50, Original

; Start
FileDelete, Blob.gif
DBFileName := A_ScriptDir . "\TEST_B.DB"
If FileExist(DBFileName) {
   SB_SetText("Deleting " . DBFileName)
   FileDelete, %DBFileName%
}

; Use Class SQLiteDB : Create new instance
DB := new SQLiteDB

; Use Class SQLiteDB : Open/create database and table, insert a BLOB from a GIF file
If !DB.OpenDB(DBFileName) {
   MsgBox, 16, SQLite Error, % "Msg:`t" . DB.ErrorMsg . "`nCode:`t" . DB.ErrorCode
   ExitApp
}

; Write GIF BLOB
HFILE := FileOpen("Original.gif", "r")
Size := HFILE.RawRead(BLOB, HFILE.Length)
HFILE.Close()
If !DB.Exec("CREATE TABLE Test (TextType, BlobType);")
   MsgBox, 16, SQLite Error, % "Msg:`t" . DB.ErrorMsg . "`nCode:`t" . DB.ErrorCode
DB.Exec("BEGIN TRANSACTION;")
; ? stands for an automatically numbered parameter (here: 1) to use in BlobArray
SQL := "INSERT INTO Test VALUES('Text', ?);"
; Create the BLOB array
BlobArray := []
BlobArray.Insert({Addr: &BLOB, Size: Size}) ; will be inserted as element 1
If !DB.StoreBLOB(SQL, BlobArray)
   MsgBox, 16, SQLite Error, % "Msg:`t" . DB.ErrorMsg . "`nCode:`t" . DB.ErrorCode
DB.Exec("COMMIT TRANSACTION;")

; Get the BLOB form the database

If !DB.Query("SELECT * FROM Test;", RecordSet)
   MsgBox, 16, SQLite Error: Query, % "Msg:`t" . RecordSet.ErrorMsg . "`nCode:`t" . RecordSet.ErrorCode
RecordSet.Next(Row) ; get first (and only) row in the Test table

; write the blob to a file (THIS IS WHAT I'D PREFER TO AVOID)
; second field in the row is the blob
Size := Row[2].Size 
Addr := Row[2].GetAddress("Blob")
VarSetCapacity(MyBLOBVar, Size)
DllCall("Kernel32.dll\RtlMoveMemory", "Ptr", &MyBLOBVar, "Ptr", Addr, "Ptr", Size)
HFILE := FileOpen("MyBlob.gif", "w")
HFILE.RawWrite(&MyBLOBVar, Size) ; changed
RecordSet.Free()
HFILE.Close()

Gui, 2:Add, Picture, +Border, MyBlob.gif
; COULD I REPLACE THIS USING HBITMAP:* ?
; Gui,Add, Picture, +Border, % "HBITMAP:*" . ???
Gui, 2:Show, AutoSize x100 y100, Blob

return

2GuiClose:
ExitApp
What I need is to get the correct for value HBITMAP:*

Gui,Add, Picture, +Border, % "HBITMAP:*" . ???

Thanks!
:thumbup: Author of freeware Quick Access Popup, the powerful Windows folders, apps and documents launcher!
:P Now working on Quick Clipboard Editor
:ugeek: The Automator's Courses on AutoHotkey
just me
Posts: 9528
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Display a bitmap in a Picture Gui control with a bitmap retrieved from a SQLite database

24 Dec 2023, 05:35

Hi @JnLlnd,

you can try the following passing the pointer to the and the size of the BLOB-Data to Gdip_CreateHBitmapFomData().

Code: Select all

Gdip_CreateHBitmapFomData(DataPtr, DataSize) {
   Local Bitmap := 0, HBitMap := 0
   If (Bitmap := Gdip_CreateBitmapFromData(DataPtr, DataSize)) {
      HBitMap := Gdip_CreateHBITMAPFromBitmap(Bitmap)
      Gdip_DisposeImage(Bitmap)
   }
   Return HBitmap
}
Gdip_CreateBitmapFromData(DataPtr, DataSize) {
   Local Bitmap := 0, Stream := 0, HR := 0
   If (Stream := DllCall("Shlwapi.dll\SHCreateMemStream", "Ptr", DataPtr, "UInt", DataSize, "UPtr")) {
      HR := DllCall("Gdiplus.dll\GdipCreateBitmapFromStream", "Ptr", Stream, "PtrP", Bitmap, "UInt")
      Stream.Release()
   }
   Return (HR ? 0 : Bitmap)
}
*not tested*

Merry Christmas and a happy new year!
User avatar
JnLlnd
Posts: 490
Joined: 29 Sep 2013, 21:29
Location: Montreal, Quebec, Canada
Contact:

Re: Display a bitmap in a Picture Gui control with a bitmap retrieved from a SQLite database

24 Dec 2023, 08:49

just me wrote:
24 Dec 2023, 05:35
Hi @JnLlnd,

you can try the following passing the pointer to the and the size of the BLOB-Data to Gdip_CreateHBitmapFomData().
Merry Christmas and a happy new year!
Hi just_me

Merry Christmas to you :-)

I tested the code and it did not work yet. The Gdip_CreateHBitmapFomData() function returns 0. More precisely, this is the call to GdipCreateBitmapFromStream that returns 0 in Bitmap.

Yes, that worked. Thanks @just me for the solution and to @william_ahk for the error fixed.

Code: Select all

#SingleInstance Force
#requires AutoHotkey v1.1

#Include %A_ScriptDir%\Class_SQLiteDB.ahk ; SQLite wrapper from just_me (https://autohotkey.com/boards/viewtopic.php?t=1064)
#Include %A_ScriptDir%\Gdip_All.ahk ; https://github.com/marius-sucan/AHK-GDIp-Library-Compilation/blob/master/ahk-v1-1/Gdip_All.ahk
SetWorkingDir, %A_ScriptDir%

; ======================================================================================================================
; Get the Google logo or store a picture named Original.gif in the script's folder and comment this out
FileDelete, Original.gif
URLDownloadToFile, http://www.google.de/intl/de_ALL/images/logos/images_logo_lg.gif, Original.gif

Gui, 1:Add, Picture, +Border, Original.gif
Gui, 1:Show, AutoSize x50 y50, Original

; Start
FileDelete, Blob.gif
DBFileName := A_ScriptDir . "\TEST_B.DB"
If FileExist(DBFileName) {
   SB_SetText("Deleting " . DBFileName)
   FileDelete, %DBFileName%
}

; Use Class SQLiteDB : Create new instance
DB := new SQLiteDB

; Use Class SQLiteDB : Open/create database and table, insert a BLOB from a GIF file
If !DB.OpenDB(DBFileName) {
   MsgBox, 16, SQLite Error, % "Msg:`t" . DB.ErrorMsg . "`nCode:`t" . DB.ErrorCode
   ExitApp
}

; Write GIF BLOB
HFILE := FileOpen("Original.gif", "r")
Size := HFILE.RawRead(BLOB, HFILE.Length)
HFILE.Close()
If !DB.Exec("CREATE TABLE Test (TextType, BlobType);")
   MsgBox, 16, SQLite Error, % "Msg:`t" . DB.ErrorMsg . "`nCode:`t" . DB.ErrorCode
DB.Exec("BEGIN TRANSACTION;")
; ? stands for an automatically numbered parameter (here: 1) to use in BlobArray
SQL := "INSERT INTO Test VALUES('Text', ?);"
; Create the BLOB array
BlobArray := []
BlobArray.Insert({Addr: &BLOB, Size: Size}) ; will be inserted as element 1
If !DB.StoreBLOB(SQL, BlobArray)
   MsgBox, 16, SQLite Error, % "Msg:`t" . DB.ErrorMsg . "`nCode:`t" . DB.ErrorCode
DB.Exec("COMMIT TRANSACTION;")

; Get the BLOB from the database

If !DB.Query("SELECT * FROM Test;", RecordSet)
   MsgBox, 16, SQLite Error: Query, % "Msg:`t" . RecordSet.ErrorMsg . "`nCode:`t" . RecordSet.ErrorCode
RecordSet.Next(Row) ; get first (and only) row in the Test table

; write the blob to hBitmap *** EDIT: NOW WORKING ***
; second field in the row is the blob
Size := Row[2].Size 
Addr := Row[2].GetAddress("Blob")
pToken := Gdip_Startup()
hBitmap := Gdip_CreateHBitmapFomData(Addr, Size)
Gui, 2:Add, Picture, +Border, % "HBITMAP:*" . hBitmap
Gui, 2:Show, AutoSize x100 y100, Blob

RecordSet.Free()
Gdip_Shutdown(pToken )
return

2GuiClose:
ExitApp

Gdip_CreateHBitmapFomData(DataPtr, DataSize) {
   Local Bitmap := 0, HBitMap := 0
   If (Bitmap := Gdip_CreateBitmapFromData(DataPtr, DataSize)) {
      HBitMap := Gdip_CreateHBITMAPFromBitmap(Bitmap)
      Gdip_DisposeImage(Bitmap)
   }
   Return HBitmap
}

Gdip_CreateBitmapFromData(DataPtr, DataSize) {
   Local Bitmap := 0, Stream := 0, HR := 0
   If (Stream := DllCall("Shlwapi.dll\SHCreateMemStream", "Ptr", DataPtr, "UInt", DataSize, "UPtr")) {
      HR := DllCall("Gdiplus.dll\GdipCreateBitmapFromStream", "Ptr", Stream, "PtrP", Bitmap, "UInt")
      Stream.Release()
   }
   Return (HR ? 0 : Bitmap)
}
Last edited by JnLlnd on 26 Dec 2023, 11:07, edited 2 times in total.
:thumbup: Author of freeware Quick Access Popup, the powerful Windows folders, apps and documents launcher!
:P Now working on Quick Clipboard Editor
:ugeek: The Automator's Courses on AutoHotkey
User avatar
JnLlnd
Posts: 490
Joined: 29 Sep 2013, 21:29
Location: Montreal, Quebec, Canada
Contact:

Re: Display a bitmap in a Picture Gui control with a bitmap retrieved from a SQLite database

25 Dec 2023, 00:27

@william_ahk You got it! I'll post the code fixed when I have a little more time. Thanks.

PS: viewtopic.php?p=552284#p552284 fixed.
:thumbup: Author of freeware Quick Access Popup, the powerful Windows folders, apps and documents launcher!
:P Now working on Quick Clipboard Editor
:ugeek: The Automator's Courses on AutoHotkey

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: No registered users and 74 guests