bilder in eine mysql datenbank speichern

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
rogen

ich habe ein script mit dem ich ein bild verkleinere
jetzt möchte ich es gerne in eine mysqldatenbank speicher
dazu müsste ich das bild binäre darstellen können .

wie geht das.

Code: Alles auswählen

#! /usr/bin/python
from Tkinter import *
from MySQLdb import *
import os, sys
import Image
import JpegImagePlugin
import TgaImagePlugin
import PngImagePlugin
#import GifImagePlugin
import ImageFilter
import cStringIO

import Tkinter
size = 300,300

out = Image.open(str(sys.argv[1:][0]))

#out3 = out.filter(ImageFilter.MinFilter(3))

out.thumbnail(size, Image.ANTIALIAS)

out.save(str(sys.argv[1:][0][:-4]+"klein.jpg"),"JPEG", quality=80)
print str(out) Hier 

conn = connect("**************************")
cursor = conn.cursor()
a = "INSERT INTO flash VALUES(0,'ima','"+str(out)+"')"
cursor.execute(a)

Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

Hi rogen,

schau dir mal das Modul StringIO bzw. cStringIO an.


Gruß

Dookie
[code]#!/usr/bin/env python
import this[/code]
piddon
Gründer
Beiträge: 410
Registriert: Dienstag 30. Juli 2002, 18:03
Wohnort: Oestrich-Winkel
Kontaktdaten:

Hallo,

nur mal so zur Info:

Man speichert keine Bilder in der Datenbank, damit bremst du perfomance deine DB. Speichere die Bilder in ein Verzeichniss, und nur den Pfad/Namen, alle eigenschaften und kommentare des Bildes in der Datenbank.

Eine Datenbank an sich ist nicht entwicklet worden, um Binäre objekte zu enthalten, sondern um Daten wie Texte usw. zu halten und einfach "Durchsuchbar" und indexierbach zu machen.
irc: #python.de @ irc.freenode.net | [url=http://pythonwiki.pocoo.org]python-wiki[/url] | [url=http://www.pythonwiki.de/PythonDeForum/Faq]python-forum FAQ[/url]
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

Ich dachte es geht um Thumbnails, die sind ja meist recht klein und da kann es sinvoll sein diese in einer Datenbank zu speichern, aber bei 300x300 Pixel würd ich auch dazu raten diese in ein Verzeichnis und nur den Pfad in der Datenbank zu speichern.

Gruß

Dookie
[code]#!/usr/bin/env python
import this[/code]
Christopy
User
Beiträge: 131
Registriert: Montag 15. Dezember 2003, 22:39

Vermutlich habt ihr für den Fall Otto-Normal-Verbraucher Recht.

Aber generell können auch Rasterbilder in einer Datenbank sehr performant gespeichert werden. -> Geodatabase, ArcSDE usw.
rogen

aber bilder in die datenbank speichern ist übersichtlich.
und ich speichere insgesamt 800 kb ab.

nichts destotroz
habe ich es nocht nicht gefunden.

mfg
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

statt einem Dateinamen, kannst Du beim Speichern auch ein file-Objekt übergeben, in das dann das Bild gespeichert wird. Statt einem Fileobjekt geht auch ein StringIO Objekt.

Code: Alles auswählen

...
buffer = cStringIO.StringIO()
out.save(buffer, 'JPEG', quality=80)

conn = connect("**************************")
cursor = conn.cursor()
a = "INSERT INTO flash VALUES(0,'ima','%s')" % buffer
cursor.execute(a) 
nicht getestet, sollte aber so klappen.


Gruß

Dookie
[code]#!/usr/bin/env python
import this[/code]
Milan
User
Beiträge: 1078
Registriert: Mittwoch 16. Oktober 2002, 20:52

Hi. Das hier geht besser :wink: ... ein cStringIO-Objekt hat zwar eine Methode __str__ , aber die liefert nicht den Inhalt des Buffers, sondern gleicht __repr__ . Die Methode getvalue bringts dann.

Code: Alles auswählen

a = "INSERT INTO flash VALUES(0,'ima','%s')" % buffer.getvalue()
rogen

ich weiss zwar nicht woher der buffer seine daten bekommt
.. es wird aber noch ein fehler ausgegeben.:


buffer = cStringIO.StringIO()
out.save(buffer, 'JPEG', quality=80)

conn = connect(host="192.168.0.1",db="forster",user="rogen",passwd="gega")
cursor = conn.cursor()
a = "INSERT INTO flash VALUES(0,'ima',%s)" % buffer.getvalue()
cursor.execute(a)
----------------------------
fehler:



rogen@linux:~> python /home/rogen/ima.py logo.jpg
Traceback (most recent call last):
File "/home/rogen/ima.py", line 28, in ?
cursor.execute(a)
File "/usr/lib/python2.3/site-packages/MySQLdb/cursors.py", line 95, in execute
return self._execute(query, args)
File "/usr/lib/python2.3/site-packages/MySQLdb/cursors.py", line 114, in _execute
self.errorhandler(self, exc, value)
File "/usr/lib/python2.3/site-packages/MySQLdb/connections.py", line 33, in defaulterrorhandler
raise errorclass, errorvalue
_mysql_exceptions.ProgrammingError: (1064, "You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '*)\x19\x1f-0-(0%()(\xff\xdb' at line 1")
rogen@linux:~>

mfg
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

tja, is irgendwie klar, im buffer kann ja auch ein ) Ziechen sein oder sonstiges. Also muss der buffer in ascii convertiert werden. Laut MySQL-Doku in einen hexadezimalstring.

Code: Alles auswählen

import binascii
...
data = "0x"+binascii.hexlify(buffer.getvalue())
a = "INSERT INTO flash VALUES(0,'ima',%s)" % data
cursor.execute(a)
So ein JPEG wird dann aber sicher ein dicker Hund. Nach dem Auslesen musst Du die Daten dann wieder mit binascii.unhexlify decodieren.


Gruß

Dookie
[code]#!/usr/bin/env python
import this[/code]
rogen

leider muss das bild so in der datenbank ankommen wie es in der datei steht.

da das python programm das bild in ein php projekt einspielen soll.
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

das wird wohl nicht gehen, da in der Bilddatei jedes beliebige Byte vorkommen kann also wie soll MySQL dann erkennen, wo die Daten zu ende sind und die abschließende ")" ist, wenn auch 0x29 vorkommen kann?


Gruß

Dookie
[code]#!/usr/bin/env python
import this[/code]
rogen

wenn ich ' durch \' ersetzte kommt das bild zwar an schaut aber nicht mehr schön aus.

Code: Alles auswählen

bild = open(str(sys.argv[1:][0][:-4]+"klein.jpg"),"r")
bild = bild.read().replace("\'","\\'")

a = "INSERT INTO flash (id,richtung,bild) VALUES(0,'ima','%s')" % bild

vielleicht gibt es eine andere möglichkeit
rayo
User
Beiträge: 773
Registriert: Mittwoch 5. November 2003, 18:06
Wohnort: Schweiz
Kontaktdaten:

probier mal ein urlencode oder sowas, also es soll ein Leerzeichein in %20 umwandeln

php könnte das auch wieder zurückwandeln

also schau mal ob urllib.urlencode diese zeichen so umwandelt

gruss
JR
User
Beiträge: 286
Registriert: Montag 20. Februar 2006, 16:43
Wohnort: Berlin

Hi!

Habe mir gerade mal eben obige Posts durchgelesen. Schlauer bin ich aber nicht wirklich geworden.
Es kann doch nicht so wild sein, aus Python heraus eine Bilddatei von der Festplatte einzulesen, um sie dann in eine MySQL-Spalte einzulesen.

In meinem Fall habe ich eine Spalte vom Typ BLOB.

Folgendes ging nicht:

Code: Alles auswählen

import cStringIO
f = file(file_path, 'r')
if f:
    data = f.read()
    stream = cStringIO.StringIO()
    stream.write(data)
    pic_data = stream
    f.close()
    statement = 'INSERT INTO <table> SET pic_data=' + pic_data + ';'
Mit cPickle habe ich es auch nicht hinbekommen.

Also wenn jemand das schon mal geschafft hat, würde ich mich freuen, wenn er/ sie mir verrät, wie es geht :-)

Viele Grüße und guten Morgähn
JR
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Hilft dir dieser Thread weiter? Du kannst mal abschauen, wie jens das gemacht hat.

Ansonsten wenn du mit SQL unter Python arbeitest, solltest du unbedingt die Seite [wiki]Parametrisierte SQL Queries[/wiki] lesen.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Jup, sourcecode gibt es hier: http://pylucid.net/trac/browser/PyLucid ... Storage.py

Das wichstigste steckt in def insert() :)

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
JR
User
Beiträge: 286
Registriert: Montag 20. Februar 2006, 16:43
Wohnort: Berlin

Hi Leonidas und Jens!

Danke für eure Antworten und danke für den Hinweis Leonidas.
Habe mir PyLucid und das Script FileStorage mal runtergeladen.

Ist das Speichern von Binärdaten Festplatte -> BLOB-Spalte komplizierter, so dass ich mich da in den Code einarbeiten muss?

Soweit ich weiß, kann man doch in MySQL direkt ein Statement absetzen, bei welchem man einen konkreten Dateipfad angibt, wenn man eine Datei in eine BLOB-Spalte schreiben möchte. Das ist doch bestimmt am einfachsten und auch am sichersten (was es Zeichensatzprobleme etc. angeht).

Auf den ersten Blick, habe ich in der Funktion "insert" nicht erkannt, was da passiert.
Aber vielelicht steige ich ja heute abend da durch...

Viele Grüße
Jamil
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Also im Grunde ist es ganz einfach:

Code: Alles auswählen

# Die Tabelle für die Daten sieht so aus:
"""CREATE TABLE TabellenName (
    id INT(11) NOT NULL auto_increment,
    data LONGBLOB,
    PRIMARY KEY (id)
);"""


# Ich hab festgestellt, das 4es ohne ein base64 encoding nicht geht, sollte
# es aber eigentlich
data = base64.encodestring(data)


# Daten eintragen
cursor.execute(
    "INSERT INTO TabellenName (data) VALUES (%s);",
    (data,)
)
Generell ist es allerdings nicht zu empfehlen Binärdaten in die DB zu packen. Bei meinem FileStorage mache ich da allerdings eine Ausnahme.

Einfach ist es allerdings ein Verz. zu erstellen, das Schreibrechte für alle zu geben und dann dorthin die Daten zu speichern. Ich mag es alledings nicht so gern, ein Verz. mit Schreibrechte für alle :)

Ansonsten erzähl mal, was du überhaupt vor hast!

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
JR
User
Beiträge: 286
Registriert: Montag 20. Februar 2006, 16:43
Wohnort: Berlin

HI Jens!

Das "data" in der Klammer (Zeile 11). Wie ermittest du das?

Ich habe zum Beispiel eine Bilddatei "C:\Bild.jpg"


Und nun? so?

Code: Alles auswählen

f = file('C:\\Bild.jpg', 'r')
if f:
    data = f.read()
    f.close()
    data = base64.encodestring(data)


    # Daten eintragen
    cursor.execute(
        "INSERT INTO TabellenName (data) VALUES (%s);",
        (data,)
    )
Melde mich gegen 19 Uhr, da ich jetzt erst mal weg bin :-(

Grüße
Jamil
Antworten