Longblob(JPG) aus MySQL in TImage ausgeben



  • Wenn jemand noch Lust und Laune hat, ich hätte da noch ein "kleines" Problem.
    Es bezieht sich auch auf ein Image und meine Datenbank.

    Ich versuche aus einem Image heraus, ein Bild (JPG) in der Datenbank zu speichern.
    Ohne Erfolg!!!

    Als erstes habe ich über TOpenPictureDialog ein Bild geladen. Funktioniert!!!

    void __fastcall TForm4::Button2Click(TObject *Sender)
    {
    if (OpenPictureDialog1->Execute())
      { 
      Image1->Picture->LoadFromFile(OpenPictureDialog1->FileName);
      }
    }
    

    Danach habe ich versucht, das Image auszulesen und in einen TJPEGImage zu speichern. Funktioniert auch!!!
    Doch aus dem TJPEGImage die Daten in ein TBlobStream zu bekommen schlägt fehl.

    Mein Versuch:

    TBlobStream *pBlob;
    TJPEGImage *pJPG = new TJPEGImage();
    pBlob = dynamic_cast<TBlobStream*>(Form1->Query1->CreateBlobStream(Form1->Query1->FieldByName("image"),bmRead));
    Image1->Picture->Graphic->SaveToStream(pBlob);
    

    Leider komme ich dann hier auch nicht weiter. 😕
    Ich kann den pBlob wieder in einem Image ausgeben, aber nicht an die Datenbank.

    INSERT mit den "Normalen" Datensätzen aus den Edit- feldern funktioniert.
    (Textbasiert)

    Form1->Query1->Close();
    Form1->Query1->SQL->Clear();
    Form1->Query1->SQL->Add("INSERT INTO film (titel, jahr, fsk, laufzeit, genre_id, beschreibung, [b]image[/b]) VALUES ('"+Edit1->Text+"','"+Edit2->Text+"','"+ Edit3->Text+"','"+Edit4->Text+"','"+iRB+"','"+RichEdit1->Text+"','"+[b]pBlob[/b]+"')");
    Form1->Query1->ExecSQL();
    

    Fehlermeldung hier: pBlob ist kein AnsiString. Der Rest funzt!

    MfG

    @Braunstein
    Vielleicht hast du wieder einen spitzen Vorschlag. 😃



  • Hallo

    Doch aus dem TJPEGImage die Daten in ein TBlobStream zu bekommen schlägt fehl.

    Das heißt? Fehlerbeschreibung?

    Fehlermeldung hier: pBlob ist kein AnsiString. Der Rest funzt!

    Die Fehlermeldung ist doch aussagekräftig : SQL-Anweisungen sind immer Text. Du kannst nicht einfach einen Byte-Strteam hinzuaddieren. Sondern der muß Byte für Byte in Textformat konvertiert werden, wo die nicht darstellbaren Zeichen durch Hex- oder Oktalwerte maskiert werden. Als Beispiel hier die Umsetzungstabelle für PostgreSQL. Ob das so standardisiert ist weiß ich nicht, vermute aber schon.

    bis bald
    akari



  • Hallo

    Hier ist die entsprechende Beschreibung für MySQL

    bis bald
    akari



  • Den Blob-Stream sollte man doch besser über einen Parameter einfügen.
    Evtl. so

    Form1->Query1->SQL->Add("INSERT INTO film (titel, jahr, fsk, laufzeit, genre_id, beschreibung, image) VALUES ('"+Edit1->Text+"','"+Edit2->Text+"','"+ Edit3->Text+"','"+Edit4->Text+"','"+iRB+"','"+RichEdit1->Text+"',:imageblob)");
    Form1->Query1->Params->ByName("imageblob")->LoadFromStream(pBlob);
    Form1->Query1->ExecSQL();
    

    Ist jetzt nicht getestet.



  • @Braunstein

    Danke für Deine Hilfe.
    Ich hab das Ganze mal eingegeben, jedoch ByName ist kein Bestandteil von Parms. (laut CBuilder)

    Form1->Query1->Params->ByName("imageblob")->LoadFromStream(pBlob);
    

    Dann hab ich mal nachgesehen was es denn unter Parms mit "ByName" so gibt.

    Form1->Query1->SQL->Add("INSERT INTO film (titel, jahr, fsk, laufzeit, genre_id, beschreibung, image) VALUES ('"+Edit1->Text+"','"+Edit2->Text+"','"+ Edit3->Text+"','"+Edit4->Text+"','"+iRB+"','"+RichEdit1->Text+"',:imageblob)");
    Form1->Query1->Params->[b]ParamByName[/b]("imageblob")->LoadFromStream(pBlob);
    Form1->Query1->ExecSQL();
    

    Soweit ganz gut, jedoch kommt dann die Meldung LoadFromStream hat zu wenig Argumente.

    Ok, dann hab ich mir gedacht, da es sich um den Feldtyp LongBlob in der Datenbank handelt, übergebe ich diesen auch mit ftBlob

    Form1->Query1->SQL->Add("INSERT INTO film (titel, jahr, fsk, laufzeit, genre_id, beschreibung, image) VALUES ('"+Edit1->Text+"','"+Edit2->Text+"','"+ Edit3->Text+"','"+Edit4->Text+"','"+iRB+"','"+RichEdit1->Text+"',:imageblob)");
    Form1->Query1->Params->ParamByName("imageblob")->LoadFromStream(pBlob,[b]ftBlob[/b]);
    Form1->Query1->ExecSQL();
    

    Falsch gedacht, jetzt bekomme ich die Fehlermeldung EAccessViolation in Adresse 4002EAEF im Modul "rtl60.bpl". Lesen von Adresse 5D010AAB gestoppt.
    😕

    @akari

    Ich hab mir das von MySQL durchgelesen, die sagen ja zum Schluß man solle lieber einen Blob-Typen verwenden, welchen ich ja benutze.

    Meinst Du ich solle die Datenbank überarbeiten, oder nur die SQL-Anweisung???



  • Hallo

    Ich hab mir das von MySQL durchgelesen, die sagen ja zum Schluß man solle lieber einen Blob-Typen verwenden, welchen ich ja benutze.

    Meinst Du ich solle die Datenbank überarbeiten, oder nur die SQL-Anweisung???

    Nein du must hier zwischen dem MySQL-Spaltentyp Blob und der Builder-Klasse TBlobStream unterscheiden. Die Aussage aus der MySQL-Doku bezieht sich auf ersteres, was bei dir aber schon erledigt ist (wenn du den Spaltentyp Blob schon verwendest)

    Sondern bei dir geht es um die korrekte Integration des BlobStreams in eine bereits korrekte SQL-Anweisung. Offenbar brauchst du die Umwandlung nicht selber machen. Worum du den Fehler bekommst kann ich aber nicht nachvollziehen.

    bis bald
    akari



  • @akari

    Anscheinend muß der BlobStream doch gewandelt werden, denn wenn ich versuche pBlob
    in der SQL-Anweisung zu integrieren, bekomme ich die Meldung:
    *'operator+' not implemented in type 'AnsiString' for arguments of type 'TBlobStream '

    SQL Anweisung:

    Form1->Query1->SQL->Add("INSERT INTO film (titel, jahr, fsk, laufzeit, genre_id, beschreibung, image) VALUES ('"+Edit1->Text+"','"+Edit2->Text+"','"+ Edit3->Text+"','"+Edit4->Text+"','"+iRB+"','"+RichEdit1->Text+"','"[b]+pBlob+[/b]"')");
    

    Die gleiche Fehlermeldung kommt auch, wenn ich versuche pJPG anstatt pBlob zu verwenden. Auch Image1 direkt anzugeben schlägt fehl, gleiche Meldung.

    Herkunft pJPG

    TJPEGImage *pJPG = new TJPEGImage();
    pJPG->Assign(Image1->Picture); // Übergabe des Images an pJPG
    

    Ist es denn nicht möglich, das Image in Binärdaten zu wandeln.
    Denn alle Informationen innerhalb des LongBlob-Feldes werden ja auch Binär gespeichert.

    MfG



  • Hallo

    Das einfache Addieren ist natürlich komplett flasch, und das habe ich auch schon vor 2 Posts gesagt.
    Mit eingebauter Konvertierung meine ich Braunsteins Methode. Und dort kann ich den Fehler den du meldest (Speicherzugriffsverletzung) nicht erklären.

    Du must gar nichts in Binärdaten umwandeln, ganz im Gegenteil. Die Daten im (Blob-) Stream (auf keinen Fall das Image selber nehmen) sind bereits binär. Wnn dann müßtest du die Binärdaten ins textorientierte SQL-Format umwandelön, indem du byte für Byte des Streams durchgehst und wie in den Links beschrieben die Nichtdruckbaren Zeichen in Hexadezimal-Zahlen umwandeln.

    bis bald
    akari



  • Hallo,

    Kann es sein, dass der Parameter nicht gefunden wird? Kontrollier das mal

    TParam* param = Form1->Query1->Params->ParamByName("imageblob")->LoadFromStream(pBlob,ftBlob);
    if( param == 0 )
    {
    // Fehlermeldung
    }
    

    Du kannst statt ParamByName ja auch folgendes verwenden

    Form1->Query1->Params->Items[0]->LoadFromStream(pBlob, ftBlob);
    

    Bei mir war das ein TIBSQL und kein TQuery. Deswegen die anderen Bezeichner und Parameter.



  • Super es läuft!!! :p

    @Braustein

    Der LoadFromStream hat mich auf die Idee gebracht, einen TMemoryStream zu testen, da LFS nicht funktioniert hatte.

    TMemoryStream *pMS = new TMemoryStream;
    Image1->Picture->Graphic->SaveToStream(pMS);
    
    Form1->Query1->Close();
    Form1->Query1->SQL->Clear();
    Form1->Query1->SQL->Add("INSERT INTO film (titel, jahr, fsk, laufzeit, genre_id, beschreibung, image) VALUES ('"+Edit1->Text+"','"+Edit2->Text+"','"+ Edit3->Text+"','"+Edit4->Text+"','"+iRB+"','"+RichEdit1->Text+"',:imageblob)");
    Form1->Query1->Params->ParamByName("imageblob")->LoadFromStream(pMS,ftBlob); 
    Form1->Query1->ExecSQL();
    
    delete pMS;
    

    Ohne Deine Hilfe mit :imageblob, würde ich aber immer noch hier sitzen und versuchen mir den Kopf zu zerbrechen.

    SUPER FORUM, SUPER LEUTE!!!

    Vielen Dank an alle!!!!!!


Anmelden zum Antworten