2016-07-26 22 views
1

Ich schrieb ein einfaches PHP-Skript, um zusätzliche Informationen zu einer Webcam-JPG-Datei hinzuzufügen. Es fügt Kopf- und Fußzeile mit etwas Text hinzu. Dazu erstelle ich ein neues Bild mit diesen Informationen und kopiere dann das Original-JPG mit imagecopy. Und alles funktioniert gut.imagecopy schlägt fehl, wenn Quellbild beschädigt ist

Die Webcam hat eine schlechte WLAN-Verbindung zum Internet, so dass es selten passiert, dass die per FTP hochgeladene JPG-Datei unvollständig oder beschädigt ist: Ich kann sie mit GIMP oder anderer Bildsoftware öffnen und sehe fehlende Informationen zum Boden. Wenn das passiert, scheint das obige imagecopy beim Kopieren von Bilddaten zu versagen, und das Zielbild bleibt leer (für den Bildbereich).

versuchte ich alles, was ich das Original JPG gilt überprüfen gefunden:

// Check image 
if (exif_imagetype($last) != IMAGETYPE_JPEG) // Not a valid jpeg 
    continue; 
$details = getimagesize($last); 
if ($details === FALSE) // Not a valid mage 
    continue; 
$im = imagecreatefromjpeg($last); 

aber alle Tests bestanden. Ich fügte auch hinzu:

aber ich kann immer noch nicht abgeschlossen einen Upload. Wie kann ich überprüfen, ob das Bild für die GD-Verarbeitung gültig ist?

bearbeitet: das ist, wie das Quellbild in GIMP erscheint: image showing the error

Dies ist ein Teil der ursprünglichen hochgeladenen Datei.

Wie gewünscht habe ich hinzugefügt, wie ich die Datei öffne, mit imagecreatefromjpeg. Es kann kein Berechtigungsproblem sein, weil das Skript in 90% der Fälle fehlerfrei funktioniert. Wenn es auf solche Bilder stößt, schlägt es fehl.

edit2: Ich dachte ursprünglich ein Gleichzeitigkeit Problem sein könnte, ist, dass ich das Skript über cron jede Minute laufen, aber der FTP-Upload ist außer Kontrolle geraten Server, so dass sie laufen asynchron. Vielleicht hat das Skript während des Uploads genau auf die Datei zugegriffen, aber ich habe überprüft, dass dies nicht der Fall ist. Wie oben beschrieben, ist die hochgeladene Datei am Anfang beschädigt.

EDIT3: die vorgeschlagene imagecolorat ist keine Lösung (zumindest nicht für alle Fälle): Ich habe gerade eine verkorkste Bild, das diesen Test bestehen würde. jpeginfo sagt: Corrupt JPEG-Daten: 10839 Fremd Bytes vor der Markierung 0xd9 sample failing imagecolorat test

+0

Es ist wahrscheinlich, dass die Image-Datei per se nicht beschädigt ist, hat nur eine Menge nicht gefüllt (also Standardwert) leere Pixel (s). Es ist auch möglich, dass Berechtigungsprobleme oder Zugriffsprobleme die Dateieingabe beeinträchtigen. Können Sie Ihre Frage bearbeiten und veröffentlichen, wie Sie auf die Datei zugreifen, sowie die Dateieigenschaften (wenn zum Beispiel Linux). Denken Sie daran, dass sich Ihr "angemeldeter Benutzer" von Ihrem "php-Benutzer" im Computer unterscheidet. – Bonatti

+0

Ich habe mit zusätzlichen Informationen bearbeitet. Aber ich bin 100% sicher, dass es kein Berechtigungsproblem ist, die Datei wird zu 90% korrekt geöffnet. – Maxxer

+1

Können Sie überprüfen, ob die letzten Bytes der Bilddatei 'EOI' sind (Ende des Bildes:' FF D9'). Wenn nicht, könnte das Bild "Probleme haben". Sie könnten die letzten Bytes dieser Datei selbst neu schreiben und dann das Skript ausführen. – Bonatti

Antwort

1

Vielen Dank für alle Anregungen, aber am Ende fand ich eine andere Art und Weise.

Wie oben erwähnt und in other answers das Kommandozeilen-Tool jpeginfo -c filename überprüft, ob das Bild eine gültige JPEG ist, das Drucken eine Warnung oder und Fehler (und einen Return-Code! = 0). So ist es die genaueste Lösung so weit, aber beinhaltet einen externen Befehl.

Auf der PHP-Seite scheint es keine perfekte Prüfung zu geben, da auch das Gegenstück Imagick::valid keine Gültigkeitsprüfung für das gesamte Bild durchführt.

An diesen very same page gibt es eine andere Lösung vorgeschlagen:

// check for the existence of the EOI segment header at the end of the file 
$file = fopen($image_file, "r"); 
if (0 !== fseek($file, -2, SEEK_END) || "\xFF\xD9" !== fread($file, 2)) { 
    // jpeg is not valid 
    fclose($file); 
    return FALSE; 
} 

Diese funktioniert super, aber nur für unfertige Bilder (erster Fall). Das in edit 3 veröffentlichte Beispiel besteht diesen Test noch.