Bildformat aus Blob extrahieren
Multi
- php
0 Multi0 bleicher0 Der Martin0 bleicher0 Tom0 Vinzenz Mai0 Multi0 ChrisB
Hi,
ich hab ein Problem. Ich hab Bilder in einer Datenbank gespeichert.
Auslesen und Ausgeben ist ja kein Problem, aber gibt es ne Möglichkeit, festzustellen, ob es ein Gif, ein Jpeg oder Png ist?
Es sollte ja möglich sein, die ersten paar bytes auszulesen, da stehts ja, aber wenns dafür was fertiges gibt, wär das ne feine Sache.
Es geht mir darum, den richtigen Content-Type auszugeben.
thx4hlp
Nachtrag:
das Blob ist in einer Mysql-DB und das Auslesen erfolgt per PHP
Ich würde den MimeType bereits beim speichern in die DB ermitteln und im extra Feld speichern.
Ansonsten: wenn du PHP >= 5.3.0 incl. FileInfo-Extension zur Verfügung hast.
http://www.php.net/manual/en/function.finfo-buffer.php
Sonst bleibt dir nur noch, temp. abspeichern und mit getimagesize() ermitteln.
Ich würde den MimeType bereits beim speichern in die DB ermitteln und im extra Feld speichern.
Tja, dummerweise wird der Softwarehersteller nicht wegen mir seine Datenbankstruktur ändern ...
Ansonsten: wenn du PHP >= 5.3.0 incl. FileInfo-Extension zur Verfügung hast.
http://www.php.net/manual/en/function.finfo-buffer.php
Schau ich mir an. Da eigener Server, nur ein relatives Problem ;)
Sonst bleibt dir nur noch, temp. abspeichern und mit getimagesize() ermitteln.
Das wollte ich vermeiden, aber hab ich als letzte Lösung im Hinterkopf.
Danke für die Hilfe :)
Ob das jetzt alle Images abdeckt, kann ich nicht versprechen.
[code=sql]
SELECT
CASE
WHEN SUBSTR(data, 1, 3) = 'GIF' THEN 'image/gif'
WHEN SUBSTR(data, 2, 3) = 'PNG' THEN 'image/png'
WHEN SUBSTR(data, 7, 4) = 'JFIF' THEN 'image/jpeg'
ELSE ''
END mime
FROM tabelle
[/code]
Hallo,
SELECT
CASE
WHEN SUBSTR(data, 1, 3) = 'GIF' THEN 'image/gif'
WHEN SUBSTR(data, 2, 3) = 'PNG' THEN 'image/png'
plus/minus-eins-Problem? Der String "GIF87a" oder "GIF89a" steht ganz am Anfang, also ab Index 0, und "PNG" steht ab Dateiindex 1.
Ciao,
Martin
--
Die Natur ist gnädig: Wer viel verspricht, dem schenkt sie zum Ausgleich ein schlechtes Gedächtnis.
Selfcode: fo:) ch:{ rl:| br:< n4:( ie:| mo:| va:) de:] zu:) fl:{ ss:) ls:µ js:(
plus/minus-eins-Problem? Der String "GIF87a" oder "GIF89a" steht ganz am Anfang, also ab Index 0, und "PNG" steht ab Dateiindex 1.
MySQL SUBSTR() berechnet den Index ab 1 nicht (wie etwa PHP) ab 0.
Hallo,
plus/minus-eins-Problem? Der String "GIF87a" oder "GIF89a" steht ganz am Anfang, also ab Index 0, und "PNG" steht ab Dateiindex 1.
MySQL SUBSTR() berechnet den Index ab 1 nicht (wie etwa PHP) ab 0.
tatsächlich? Pfui, das ist ja pervers ...
So long,
Martin
tatsächlich? Pfui, das ist ja pervers ...
Ist bei allen mir bekannten SQL-Dialekten so.
Hello,
tatsächlich? Pfui, das ist ja pervers ...
Ist bei allen mir bekannten SQL-Dialekten so.
Nicht nur bei SQL-Dialekten, auch bei XBase und anderen.
Liebe Grüße aus dem schönen Oberharz
Tom vom Berg
Hello,
plus/minus-eins-Problem? Der String "GIF87a" oder "GIF89a" steht ganz am Anfang, also ab Index 0, und "PNG" steht ab Dateiindex 1.
MySQL SUBSTR() berechnet den Index ab 1 nicht (wie etwa PHP) ab 0.tatsächlich? Pfui, das ist ja pervers ...
Das machen alle Datenbanken, die ich kenne, über ihre Textschnittstellen so.
Der Index 0 bedeutet: gesuchter String ist nicht enthalten
Liebe Grüße aus dem schönen Oberharz
Tom vom Berg
WHEN SUBSTR(data, 7, 4) = 'JFIF' THEN 'image/jpeg'
Zumindest bei Bildern mit Exif-Erweiterung klappt das nicht. Ich habs zwar nur kurz getestet, weil ich das Bild jetzt erst abspeichere, dann per getimagesize() die nötigen Daten hole und die Datei dann umbenenne.
Somit benutze ich nur Boardmittel von PHP und da das nur dann durchgeführt wird, wenn sich der Artikel geändert hat, ist es auch relativ egal ob es eine etwas schnellere Lösung gibt.
WHEN SUBSTR(data, 7, 4) = 'JFIF' THEN 'image/jpeg'
Zumindest bei Bildern mit Exif-Erweiterung klappt das nicht.
Stimmt, der Exif-Header überschreibt, aber eine Gemeinsamkeit haben alle Jpegs.
[code=sql] WHEN HEX(SUBSTR(data, 1, 2)) = 'FFD8' THEN 'image/jpeg'
[/code]
Grüße,
wenn es das nciht gibt, solltest du es schreiben :) so komplex ist es nciht, die header musst du ja nur unterscheiden können und die sind osgar bei wikipedia dokumentiert, sparere audi!
MFG
bleicher
Hallo,
wenn es das nciht gibt, solltest du es schreiben :) so komplex ist es nciht, die header musst du ja nur unterscheiden können und die sind osgar bei wikipedia dokumentiert, sparere audi!
die Grafikformate zu erkennen, ist sicher nicht das Problem, erst recht nicht, wenn es wirklich nur die drei genannten sind. Aber soweit ich weiß, kann man BLOBs aus einer mySQL-DB nicht partiell auslesen, sondern nur komplett. Man würde also pro Bild mehrere hundert kB bewegen, obwohl die ersten vier Bytes schon genügen würden.
Klar, das ist möglich und sehr einfach. Aber außerordentlich ineffizient.
Ich finde übrigens den Vorschlag von DiBo33 sehr gut, den MIME-Type als separates Feld mit zu speichern. Für die schon in der DB existierenden Bilder müsste man das halt dann auf die beschriebene ineffiziente Weise nachtragen. Das wäre dann aber eine einmalige Operation.
Ciao,
Martin
Grüße,
Ich finde übrigens den Vorschlag von DiBo33 sehr gut, den MIME-Type als separates Feld mit zu speichern.
ist das nicht die übliche/normale/immer verwendete Lösung?
MFG
bleicher
Hi,
Ich finde übrigens den Vorschlag von DiBo33 sehr gut, den MIME-Type als separates Feld mit zu speichern.
ist das nicht die übliche/normale/immer verwendete Lösung?
keine Ahnung, ob das üblich oder normal ist - ich finde es zumindest sinnvoll.
Aber wenn Multi von dieser Voraussetzung ausgehen könnte, bräuchte er nicht zu fragen, oder?
Wir müssen also annehmen, dass er den jetzigen ungünstigen DB-Entwurf entweder von Dritten erhalten hat und damit zurechtkommen muss, oder dass er selber irgendwann früher mal nicht ausreichend nachgedacht hat und nun die Quittung bekommt. Aber das ist im Moment völlig nebensächlich.
So long,
Martin
Hallo,
Ich finde übrigens den Vorschlag von DiBo33 sehr gut, den MIME-Type als separates Feld mit zu speichern.
ist das nicht die übliche/normale/immer verwendete Lösung?
wenn man schon Bilder als BLOB abspeichert, wäre man sehr d***h, wenn man für Metadaten keine zusätzlichen Felder vorsähe.
Freundliche Grüße
Vinzenz
wenn man schon Bilder als BLOB abspeichert, wäre man sehr d***h, wenn man für Metadaten keine zusätzlichen Felder vorsähe.
Dann erklär denen das doch. Bei einem solchen Kassensystem sind Bilder völlig Nebensache. Für den Onlineshop, den ich dazu programmiere aber nicht.
Da ich aber sowieso mit der fremden Struktur leben muss, ist es völlig unerheblich, wieso die Metadaten nicht mitgespeichert wurden, sie sind einfach nicht da ;)
Grüße,
so nebensächliche frage - woz ubrauchst du die daten?
die jedes mal zu ermitteln ist zwar fraglich, aber wenn du kontrolle hast, kannst du doch einfach dafür sogren, dass alle bilder gleciehs ofrmat haben? das ist oft der fall.
MFG
bleicher
Grüße,
so nebensächliche frage - woz ubrauchst du die daten?
Ich übernehme die Daten aus dem Kassensystem-Bestand direkt in einen Onlineshop.
die jedes mal zu ermitteln ist zwar fraglich, aber wenn du kontrolle hast, kannst du doch einfach dafür sogren, dass alle bilder gleciehs ofrmat haben? das ist oft der fall.
Ich tendiere im Moment dahin, dass ich die Bilder auf die Festplatte speicher. Ich muss mir nur noch überlegen, wie ich das mache ohne jedesmal alle Bilder prüfen zu müssen ob schon vorhanden. Mal sehen ob in der Datenbank irgendwo eine Timestamp zu finden ist, wann der Artikel geändertt wurde, dann könnte ich diesen nutzen um festzustellen ob ich die Bilder neu generieren muss.
Die Bilder sind aktuell im PNG-Format. Da ich aber nicht wissen kann, ob das beim nächsten Release so bleibt, will ich lieber gleich flexibel bleiben.
Hi,
Ich tendiere im Moment dahin, dass ich die Bilder auf die Festplatte speicher.
Das würde ich auch machen.
Ich muss mir nur noch überlegen, wie ich das mache ohne jedesmal alle Bilder prüfen zu müssen ob schon vorhanden.
Du musst nicht jedes Mal alle Bilder prüfen, sondern nur das jeweils angeforderte.
Die Nutzung von mod_rewrite o.ä. bietet sich an, um nur bei nicht vorhandener Bilddatei ein Script aufzurufen, welches das Bild ausliest, ausgibt, und auf Platte speichert.
Mal sehen ob in der Datenbank irgendwo eine Timestamp zu finden ist, wann der Artikel geändertt wurde, dann könnte ich diesen nutzen um festzustellen ob ich die Bilder neu generieren muss.
Oder du versuchst dich an der Stelle einzuklinken, wo der Artikel geändert wird - und löschst dort einfach die ggf. bestehende Bilddatei, damit bei der nächsten Anforderung dann wieder das erzeugende Script aufgerufen wird, s.o.
MfG ChrisB
Du musst nicht jedes Mal alle Bilder prüfen, sondern nur das jeweils angeforderte.
In der Übersicht können bis zu 50 Bilder angefordert werden, je nach Einstellung des Users.
Die Nutzung von mod_rewrite o.ä. bietet sich an, um nur bei nicht vorhandener Bilddatei ein Script aufzurufen, welches das Bild ausliest, ausgibt, und auf Platte speichert.
Ja, hab ich mir auch schon überlegt, ich will aber mod_rewrite bei meinem Systemnur als Option aber nicht als Vorraussetzung nutzen.
Oder du versuchst dich an der Stelle einzuklinken, wo der Artikel geändert wird - und löschst dort einfach die ggf. bestehende Bilddatei, damit bei der nächsten Anforderung dann wieder das erzeugende Script aufgerufen wird, s.o.
Auch das hab ich mir überlegt. Da das Kassensystem Scriptfähig ist, dürfte das machbar sein. Zumindest könnte das Kassensystem einen Flag setzen der von nem Cron-Job ausgewertet wird. das würde verhindern, dass beim Anlegen von vielen Prokdukten nacheinander jedesmal Zeit verbraucht wird obwohl nur ein Artikel geändert wurde.
Ich muss mir das nochmal genau überlegen, vom direkten Auslesen aus der Datenbank bin ich momentan komplett weg. Jezt schau ich mir die Scripting-Doku an ob ein Event existiert der nach dem Speichern des Artikels ausgelöst wird. Wenn ja, mach ich es damit.
Danke an den Schubs in die richtige Richtung.
Hi,
In der Übersicht können bis zu 50 Bilder angefordert werden, je nach Einstellung des Users.
Die im Idealfall alle schon auf Platte liegen, weil sie vorher bereits mindestens ein Mal angefordert wurden.
Die Nutzung von mod_rewrite o.ä. bietet sich an, um nur bei nicht vorhandener Bilddatei ein Script aufzurufen, welches das Bild ausliest, ausgibt, und auf Platte speichert.
Ja, hab ich mir auch schon überlegt, ich will aber mod_rewrite bei meinem Systemnur als Option aber nicht als Vorraussetzung nutzen.
mod_rewrite halte ich für Quasi-Standard.
Wer Webspace nutzt, wo dies nicht verfügbar ist, ist selber Schuld.
Ich halte absolut nichts davon, die sinnvollste Technik nicht einzusetzen, weil sie mit geringer Wahrscheinlichkeit nicht verfügbar sein könnte.
Man definiert Systemanforderungen, und dann hat der Nutzer sich darum zu kümmern, dass diese gegeben sind.
MfG ChrisB
Die im Idealfall alle schon auf Platte liegen, weil sie vorher bereits mindestens ein Mal angefordert wurden.
Richtig. Aber trotzdem müsste ich das jedesmal prüfen inkl. der Prüfung ob sich das Bild evtl. geändert hat.
mod_rewrite halte ich für Quasi-Standard.
Wer Webspace nutzt, wo dies nicht verfügbar ist, ist selber Schuld.Ich halte absolut nichts davon, die sinnvollste Technik nicht einzusetzen, weil sie mit geringer Wahrscheinlichkeit nicht verfügbar sein könnte.
Man definiert Systemanforderungen, und dann hat der Nutzer sich darum zu kümmern, dass diese gegeben sind.
Dummerweise sehen manche Kunden das anders. Und so selten ist es in meinem Umfeld nicht, das mod_rewrite nicht aktiviert ist oder nur gegen Aufpreis. Wie solche (meist winzig kleinen) Hoster noch Kunden haben können, weiss ich nicht, aber einige dieser Kunden wollen nicht wechseln (Ist ein Kumpel ... da bin ich schon seit Jahren ... usw.)
Somit hab ich das System von Grundauf so aufgebaut, dass mod_rewrite optional ist. War nicht so viel Arbeit, macht aber IMO Sinn.
Zu meinem Problem: Ich werde jetzt in der Datenbank einen Trigger einsetzen, der beim Ändern von Produkten in eine andere Tabelle die Artikelnummer inkl. Zeitstempel schreibt. Und diese Datenbank wird per Cron abgefragt und dann die Bilder neu auf die Platte geschrieben.
Dadurch muss ich keine Änderung an der Kassensoftware vornehmen (gibt leider keinen Event, der ausgelöst wird, wenn ein Artikel geändert wird,also kein Script möglich) und der Shop muss sich nicht um die Bilder kümmern, der zeit einfach ne normale Bild-Ressource im img an.
Ich denke, das ist die beste Lösung. Wenn jemand nen besseren Vorschlag hat, immer her damit ;)
Hello,
die Grafikformate zu erkennen, ist sicher nicht das Problem, erst recht nicht, wenn es wirklich nur die drei genannten sind. Aber soweit ich weiß, kann man BLOBs aus einer mySQL-DB nicht partiell auslesen, sondern nur komplett. Man würde also pro Bild mehrere hundert kB bewegen, obwohl die ersten vier Bytes schon genügen würden.
MMn geht das ganz normal mit der Substring-Funktion.
Liebe Grüße aus dem schönen Oberharz
Tom vom Berg
Hallo,
Aber soweit ich weiß, kann man BLOBs aus einer mySQL-DB nicht partiell auslesen, sondern nur komplett. Man würde also pro Bild mehrere hundert kB bewegen, obwohl die ersten vier Bytes schon genügen würden.
was spricht gegen LEFT()? Selbstverständlich kann LEFT() auch mit den BLOB- und TEXT-Datemtypen umgehen.
Dass das keine besonders gute Idee ist, um das Problem des OP zu lösen, hab' ich bereits angemerkt ...
Freundliche Grüße
Vinzenz
Hi,
Aber soweit ich weiß, kann man BLOBs aus einer mySQL-DB nicht partiell auslesen, sondern nur komplett. Man würde also pro Bild mehrere hundert kB bewegen, obwohl die ersten vier Bytes schon genügen würden.
was spricht gegen LEFT()? Selbstverständlich kann LEFT() auch mit den BLOB- und TEXT-Datemtypen umgehen.
das war mir nicht klar; ich dachte, diese Funktionen könnten nur mit "echten" String-Typen umgehen. Dann ist auch Toms Anmerkung ein Posting weiter oben ein Schritt in die richtige Richtung.
Dass das keine besonders gute Idee ist, um das Problem des OP zu lösen, hab' ich bereits angemerkt ...
Richtig, das sehe ich auch so. Ich betrachte das auch nur als Hilfskonstruktion, um die Metainformationen nachträglich zu generieren, die von Anfang an in der DB hätten sein sollen - obwohl man andererseits so nicht von MIME-Typen abhängig wäre, die möglicherweise falsch sind.
Ciao,
Martin
Klar, das ist möglich und sehr einfach. Aber außerordentlich ineffizient.
Ich muss das Bild ja sowieso komplett einlesen um es auszugeben. Da kann ich auch erstmal ein paar Byte überprüfen um welches Format es sich handelt.
Schau ich mir an, wie ich das umsetze. Wäre halt schön gewesen wenn da schon jemand was fertiges hätte, würde Zeit sparen *g*
Hi,
Ich muss das Bild ja sowieso komplett einlesen um es auszugeben.
Und dich selber um HTTP-Caching kümmern, wenn du es vernünftig umsetzen willst - eine Aufgabe, die sonst auch der Webserver übernehmen würde, wenn die Bilder da liegen würden, wo sie hin gehören, im Dateisystem.
Wäre halt schön gewesen wenn da schon jemand was fertiges hätte, würde Zeit sparen *g*
getimagesize ist fertig.
php://memory existiert, wenn nicht extra eine Temp-Datei erstellt werden soll. (Geht natürlich zu Lasten des RAM.)
MfG ChrisB