Bild aus dem Speicher in DB speichern und wieder laden

Anfängerfragen zum Programmieren mit PureBasic.
Benutzeravatar
The_Dark_Zim-.-
Beiträge: 372
Registriert: 18.03.2008 16:53

Bild aus dem Speicher in DB speichern und wieder laden

Beitrag von The_Dark_Zim-.- »

Moin,

ich würde gerne ein Bild, dass zuvor mit loadImage() geladen wurde, als blob in einer sqlite DB hinterlegen und später wieder laden.
Dabei will ich aber nicht den Umweg über eine Datei gehen, sprich das Bild direkt aus dem Speicher nehmen und später einfach aus der DB laden weiter nutzen. Geht das so ohne weiteres?
Ich hatte mir catchimage angesehen, aber wenn ich das richtig sehe, muss das Bild als "Datei" im Speicher sein.

Pseudocode, der so nicht funktioniert:
img = loadImage(#pb_any, "Bild.jpg")
SetDatabaseBlob(0,0,@img, imgsize)
...

GetDatabaseBlob(0,0,*img, blobsize)
img = catchimage(#pb_any, *img, blobsize)
...

Leider geht es so halt nicht. Einzige Möglichkeit, die ich momentan sehe, ist das Bild temporär zu speichern und die Datei als Blob zu speichern und diese dann zu laden.

Mit freundlichen Grüßen
Zim
PB: 5.xx LTS x86/x64 | WIN: 10 Pro x64, Linux Mint x64
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7028
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: Bild aus dem Speicher in DB speichern und wieder laden

Beitrag von STARGÅTE »

Guck dir mal EncodeImage() an.
Es gibt dir einen Speicherpuffer des "gespeicherten" Bilds zurück.
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Benutzeravatar
kpeters58
Beiträge: 26
Registriert: 16.12.2014 18:51

Re: Bild aus dem Speicher in DB speichern und wieder laden

Beitrag von kpeters58 »

Etwa so?

Code: Alles auswählen

 Procedure LoadImageGadgetFromDB(DatabaseHandle, SQLExpr.s, ImageGadget, ColIndex)
  Protected tmpimage, bytecount, *membuffer
  
  If DatabaseQuery(DatabaseHandle, SQLExpr)
    If NextDatabaseRow(DatabaseHandle)
      bytecount = DatabaseColumnSize(DatabaseHandle, ColIndex) 
      If bytecount > 0
        *membuffer = AllocateMemory(bytecount)
        If *membuffer
          GetDatabaseBlob(DatabaseHandle, ColIndex, *membuffer, bytecount)
          tmpimage = CatchImage(#PB_Any, *membuffer, bytecount)
          SetGadgetState(ImageGadget, ImageID(tmpimage))
          FreeMemory(*membuffer)
          FreeImage(tmpimage)
        Else ; allocation error
          FinishDatabaseQuery(DatabaseHandle)
          ProcedureReturn #False
        EndIf  
      Else ; no data in column
        FinishDatabaseQuery(DatabaseHandle)
        ProcedureReturn #False
      EndIf  
    Else ; no record found
      FinishDatabaseQuery(DatabaseHandle)
      ProcedureReturn #False
    EndIf  
    FinishDatabaseQuery(DatabaseHandle)
    ProcedureReturn #True
  Else ; query failed
    ProcedureReturn #False
  EndIf
EndProcedure
Benutzeravatar
Pelagio
Beiträge: 424
Registriert: 11.11.2004 17:52
Computerausstattung: AMD Ryzen 5 7600 6-Core Prozessor 3.80 GHz
16,0 GB Arbeitsspeicher
Windows 11 Pro Betriebssystem
Wohnort: Bremen

Re: Bild aus dem Speicher in DB speichern und wieder laden

Beitrag von Pelagio »

Guten Morgen,

ich weiß nicht aber man sollte sich mal die Hilfe genau anschauen, besonders 'SetDatabaseBlob' einschließlich 'DatabaseUpdate'
; SQLite, MySQL und ODBC verwenden den gleichen Syntax, um Blobs einzufügen. Diese werden mit dem '?' Zeichen angegeben.
;
; Die Datenbank sollte geöffnet sein und eine Tabelle PHOTOS mit 3 Feldern (BLOB, VARCHAR(255), BLOB) haben.
;
SetDatabaseBlob(0, 0, ?Picture, PictureLength)
SetDatabaseBlob(0, 1, ?SmallPicture, SmallPictureLength)
DatabaseUpdate(0, "INSERT INTO PHOTOS (picture, name, small_picture) values (?, 'my description', ?);")
Ohne Zeit kein Fleiß
Auf neustem Stand zu sein ist eine Kunst die nicht jeder perfektioniert [Win11Pro; PB6.20 LTS]. :allright:
Benutzeravatar
The_Dark_Zim-.-
Beiträge: 372
Registriert: 18.03.2008 16:53

Re: Bild aus dem Speicher in DB speichern und wieder laden

Beitrag von The_Dark_Zim-.- »

Hey,

danke für eure Antworten. Daten in die DB und wieder heraus zu bekommen ist nicht das Problem. Die Funktion CatchImage scheint jedoch quasi eine Datei zu erwarten. Wenn jedoch den Speicherbereich eines Bildes verwendet, funktioniert es nicht. Vermutlich muss ich wohl die Datei einlesen und dann mit CatchImage arbeiten, sowohl beim ersten Laden, als auch beim Speichern und wieder laden.
PB: 5.xx LTS x86/x64 | WIN: 10 Pro x64, Linux Mint x64
Benutzeravatar
HeX0R
Beiträge: 3040
Registriert: 10.09.2004 09:59
Computerausstattung: AMD Ryzen 7 5800X
96Gig Ram
NVIDIA GEFORCE RTX 3060TI/8Gig
Win11 64Bit
G19 Tastatur
2x 24" + 1x27" Monitore
Glorious O Wireless Maus
PB 3.x-PB 6.x
Oculus Quest 2 + 3
Kontaktdaten:

Re: Bild aus dem Speicher in DB speichern und wieder laden

Beitrag von HeX0R »

...oder Du liest die Antwort von STARGÅTE nochmal.
Benutzeravatar
The_Dark_Zim-.-
Beiträge: 372
Registriert: 18.03.2008 16:53

Re: Bild aus dem Speicher in DB speichern und wieder laden

Beitrag von The_Dark_Zim-.- »

Bei EncodeImage() habe ich das "Problem", dass ich jedes mal entscheiden muss, welcher Dateityp bzw. Bildtyp gewählt werden soll.
Vllt. zum besseren Verständnis, was ich überhaupt mache bzw. vor habe: User legt Datensatz an, dabei hat er auch die Möglichkeit ein Bild zu hinterlegen. Dieses muss er entspechend auswählen, file requestor dingen. Dabei hatte ich bisher das Bild direkt per LoadImage laden wollen und in ein ImageGadget gesetzt. Außerdem noch den Dateinamen gemerkt.

Hier ist es jetzt einfacher, für mich, statt direkt über LoadImage die Datei in einen *Buffer zu lesen und dann den Buffer sowohl für das ImageGadget ( CatchImage) als auch für die DB zu verwenden. Dateityp interessiert mich dann nicht mehr :)
PB: 5.xx LTS x86/x64 | WIN: 10 Pro x64, Linux Mint x64
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7028
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: Bild aus dem Speicher in DB speichern und wieder laden

Beitrag von STARGÅTE »

Wenn du das Bild (wobei das Format ja egal ist) einfach von einer Datei in einen Buffer laden willst, nimmst du einfach ReadFile ließt die Gesamte Datei in einen Memory (ReadData) und später kannst du dann diesen Speicher mit CatchImage() laden.

Und ja, das Bild in dann "codiert" (als "Datei") in der Datenbank, das rohe Bild kannst du da auch speichern, aber dann musst du halt das Format definieren. Das ginge dann z.B. indem du DrawingBuffer() nutzt, aber das geht glaube ich zuweit.

Wenn du bereits ein Image hast, dann halt EncodeImage, und da du musst das Format festlegen.
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Benutzeravatar
kpeters58
Beiträge: 26
Registriert: 16.12.2014 18:51

Re: Bild aus dem Speicher in DB speichern und wieder laden

Beitrag von kpeters58 »

EncodeImage functioniert auch ohne Angabe des Formats (siehe unten). ImagePlugin ist in der Hilfe als optional ausgewiesen.

Ich nehme mal an, daß EncodeImage das Format des vorliegenden Images erkennt und als Default verwendet.
Format scheint also nur erforderlich zu sein, wenn das vorliegende Format geändert werden soll (von .PNG zu .JPG oder so...)

Code: Alles auswählen

Procedure SaveLoadedImageToDB(DatabaseHandle, SqlExpr.s, Image)  
  Protected *membuffer, result
  
  If IsImage(Image)
    *membuffer = EncodeImage(Image)
    SetDatabaseBlob(DatabaseHandle, 0, *membuffer, MemorySize(*membuffer))
    result = DatabaseUpdate(DatabaseHandle, SQLExpr) ; sqlexpr = either an insert or update, must use parameter substitution
    FreeMemory(*membuffer)    
    ProcedureReturn result
  Else
    ProcedureReturn #False
  EndIf  
EndProcedure
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7028
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: Bild aus dem Speicher in DB speichern und wieder laden

Beitrag von STARGÅTE »

kpeters58 hat geschrieben:EncodeImage functioniert auch ohne Angabe des Formats (siehe unten). ImagePlugin ist in der Hilfe als optional ausgewiesen.

Ich nehme mal an, daß EncodeImage das Format des vorliegenden Images erkennt und als Default verwendet.
Format scheint also nur erforderlich zu sein, wenn das vorliegende Format geändert werden soll (von .PNG zu .JPG oder so...)
Nein so ist es nicht.
Wird das ImagePlugin weggelassen, wird das Image im BMP-Format gespeichert.
Ferner kann EncodeImage kein Format "erkennen". Ein Image liegt in Pure Basic im rohen Pixel-Format vor (siehe DrawingBufferPixelFormat()). Wird ein JPG oder PNG in PureBasic eingeladen, ist das Format (also der Kompressionsalgorithmus) "weg". Du musst also in jedem Fall entscheiden wie dein Bild kodiert werden soll (verlustbehaftet in JPG, mit Alpha-Kanal in PNG, usw.).
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Antworten