Ich verwende den folgenden Code, um ein hochgeladenes JPEG-Bild zu drehen, wenn die Ausrichtung nicht stimmt. Ich habe nur Probleme mit Bildern, die von iPhones und Android hochgeladen wurden.
if(move_uploaded_file($_FILES['photo']['tmp_name'], $upload_path . $newfilename)){
chmod($upload_path . $newfilename, 0755);
$exif = exif_read_data($upload_path . $newfilename);
$ort = $exif['IFD0']['Orientation'];
switch($ort)
{
case 3: // 180 rotate left
$image->imagerotate($upload_path . $newfilename, 180, -1);
break;
case 6: // 90 rotate right
$image->imagerotate($upload_path . $newfilename, -90, -1);
break;
case 8: // 90 rotate left
$image->imagerotate($upload_path . $newfilename, 90, -1);
break;
}
imagejpeg($image, $upload_path . $newfilename, 100);
$success_message = 'Photo Successfully Uploaded';
}else{
$error_count++;
$error_message = 'Error: Upload Unsuccessful<br />Please Try Again';
}
Mache ich etwas falsch mit der Art und Weise, wie ich die EXIF-Daten vom JPEG lese? Es dreht die Bilder nicht so, wie es soll.
Dies passiert, wenn ich einen var_dump ($ exif) ausführe.
array(41) {
["FileName"]=> string(36) "126e7c0efcac2b76b3320e6187d03cfd.JPG"
["FileDateTime"]=> int(1316545667)
["FileSize"]=> int(1312472)
["FileType"]=> int(2)
["MimeType"]=> string(10) "image/jpeg"
["SectionsFound"]=> string(30) "ANY_TAG, IFD0, THUMBNAIL, EXIF"
["COMPUTED"]=> array(8) {
["html"]=> string(26) "width="2048" height="1536""
["Height"]=> int(1536)
["Width"]=> int(2048)
["IsColor"]=> int(1)
["ByteOrderMotorola"]=> int(1)
["ApertureFNumber"]=> string(5) "f/2.8"
["Thumbnail.FileType"]=> int(2)
["Thumbnail.MimeType"]=> string(10) "image/jpeg" }
["Make"]=> string(5) "Apple"
["Model"]=> string(10) "iPhone 3GS"
["Orientation"]=> int(6)
["XResolution"]=> string(4) "72/1"
["YResolution"]=> string(4) "72/1" ["ResolutionUnit"]=> int(2) ["Software"]=> string(5) "4.3.5" ["DateTime"]=> string(19) "2011:09:16 21:18:46" ["YCbCrPositioning"]=> int(1) ["Exif_IFD_Pointer"]=> int(194) ["THUMBNAIL"]=> array(6) { ["Compression"]=> int(6) ["XResolution"]=> string(4) "72/1" ["YResolution"]=> string(4) "72/1" ["ResolutionUnit"]=> int(2) ["JPEGInterchangeFormat"]=> int(658) ["JPEGInterchangeFormatLength"]=> int(8231) } ["ExposureTime"]=> string(4) "1/15" ["FNumber"]=> string(4) "14/5" ["ExposureProgram"]=> int(2) ["ISOSpeedRatings"]=> int(200) ["ExifVersion"]=> string(4) "0221" ["DateTimeOriginal"]=> string(19) "2011:09:16 21:18:46" ["DateTimeDigitized"]=> string(19) "2011:09:16 21:18:46" ["ComponentsConfiguration"]=> string(4) "" ["ShutterSpeedValue"]=> string(8) "3711/949" ["ApertureValue"]=> string(9) "4281/1441" ["MeteringMode"]=> int(1) ["Flash"]=> int(32) ["FocalLength"]=> string(5) "77/20" ["SubjectLocation"]=> array(4) { [0]=> int(1023) [1]=> int(767) [2]=> int(614) [3]=> int(614) } ["FlashPixVersion"]=> string(4) "0100" ["ColorSpace"]=> int(1) ["ExifImageWidth"]=> int(2048) ["ExifImageLength"]=> int(1536) ["SensingMethod"]=> int(2) ["ExposureMode"]=> int(0) ["WhiteBalance"]=> int(0) ["SceneCaptureType"]=> int(0) ["Sharpness"]=> int(1) }
php
orientation
exif
Jeff Thomas
quelle
quelle
var_dump($exif)
zu sehen, was die Android-Handys in Bezug auf Rotationsdaten produzieren.$exif['COMPUTED']['Orientation']
hat den Wert 6.Antworten:
Die Dokumentation für imagerotate bezieht sich auf einen anderen Typ für den ersten Parameter als Sie verwenden:
Hier ist ein kleines Beispiel für die Verwendung dieser Funktion:
function resample($jpgFile, $thumbFile, $width, $orientation) { // Get new dimensions list($width_orig, $height_orig) = getimagesize($jpgFile); $height = (int) (($width / $width_orig) * $height_orig); // Resample $image_p = imagecreatetruecolor($width, $height); $image = imagecreatefromjpeg($jpgFile); imagecopyresampled($image_p, $image, 0, 0, 0, 0, $width, $height, $width_orig, $height_orig); // Fix Orientation switch($orientation) { case 3: $image_p = imagerotate($image_p, 180, 0); break; case 6: $image_p = imagerotate($image_p, -90, 0); break; case 8: $image_p = imagerotate($image_p, 90, 0); break; } // Output imagejpeg($image_p, $thumbFile, 90); }
quelle
Basierend auf Daniels Code habe ich eine Funktion geschrieben, die bei Bedarf einfach ein Bild dreht, ohne es erneut abzutasten.
GD
function image_fix_orientation(&$image, $filename) { $exif = exif_read_data($filename); if (!empty($exif['Orientation'])) { switch ($exif['Orientation']) { case 3: $image = imagerotate($image, 180, 0); break; case 6: $image = imagerotate($image, -90, 0); break; case 8: $image = imagerotate($image, 90, 0); break; } } }
Einzeilige Version (GD)
function image_fix_orientation(&$image, $filename) { $image = imagerotate($image, array_values([0, 0, 0, 180, 0, 0, -90, 0, 90])[@exif_read_data($filename)['Orientation'] ?: 0], 0); }
ImageMagick
function image_fix_orientation($image) { if (method_exists($image, 'getImageProperty')) { $orientation = $image->getImageProperty('exif:Orientation'); } else { $filename = $image->getImageFilename(); if (empty($filename)) { $filename = 'data://image/jpeg;base64,' . base64_encode($image->getImageBlob()); } $exif = exif_read_data($filename); $orientation = isset($exif['Orientation']) ? $exif['Orientation'] : null; } if (!empty($orientation)) { switch ($orientation) { case 3: $image->rotateImage('#000000', 180); break; case 6: $image->rotateImage('#000000', 90); break; case 8: $image->rotateImage('#000000', -90); break; } } }
quelle
getImageOrientation()
bei mir selbst bei konvertierten Rohbildern nicht richtig. Der obige Code hat perfekt funktioniert.Einfachere Funktion für diejenigen, die ein Bild hochladen. Bei Bedarf wird nur eine Autorotation durchgeführt.
function image_fix_orientation($filename) { $exif = exif_read_data($filename); if (!empty($exif['Orientation'])) { $image = imagecreatefromjpeg($filename); switch ($exif['Orientation']) { case 3: $image = imagerotate($image, 180, 0); break; case 6: $image = imagerotate($image, -90, 0); break; case 8: $image = imagerotate($image, 90, 0); break; } imagejpeg($image, $filename, 90); } }
quelle
$exif = @exif_read_data($filename);
Warum erwägt niemand gespiegelte Fälle 2,4,5,7? Es gibt 4 weitere Fälle im Exif-Orientierungsland:
Hier ist eine vollständige Lösung mit einem Dateinamen:
function __image_orientate($source, $quality = 90, $destination = null) { if ($destination === null) { $destination = $source; } $info = getimagesize($source); if ($info['mime'] === 'image/jpeg') { $exif = exif_read_data($source); if (!empty($exif['Orientation']) && in_array($exif['Orientation'], [2, 3, 4, 5, 6, 7, 8])) { $image = imagecreatefromjpeg($source); if (in_array($exif['Orientation'], [3, 4])) { $image = imagerotate($image, 180, 0); } if (in_array($exif['Orientation'], [5, 6])) { $image = imagerotate($image, -90, 0); } if (in_array($exif['Orientation'], [7, 8])) { $image = imagerotate($image, 90, 0); } if (in_array($exif['Orientation'], [2, 5, 7, 4])) { imageflip($image, IMG_FLIP_HORIZONTAL); } imagejpeg($image, $destination, $quality); } } return true; }
quelle
Nur für den Fall, dass jemand darauf stößt. Soweit ich das beurteilen kann, sind einige der obigen switch-Anweisungen falsch.
Basierend auf Informationen hier sollte es sein:
switch ($exif['Orientation']) { case 3: $image = imagerotate($image, -180, 0); break; case 6: $image = imagerotate($image, 90, 0); break; case 8: $image = imagerotate($image, -90, 0); break; }
quelle
Es ist wahrscheinlich erwähnenswert, dass Sie, wenn Sie ImageMagick über die Befehlszeile verwenden, die Option -auto-orient verwenden können, mit der das Bild basierend auf den vorhandenen EXIF-Orientierungsdaten automatisch gedreht wird.
Bitte beachten Sie: Wenn die EXIF-Daten vor dem Vorgang entfernt wurden, funktionieren sie nicht wie beschrieben.
quelle
Hier erkläre ich das Ganze, ich benutze Laravel und benutze das Image Intervention Package.
Zunächst erhalte ich mein Bild und sende es an meine andere Funktion zum Ändern der Größe und für einige andere Funktionen. Wenn wir dies nicht benötigen, können Sie ...
Holen Sie sich die Datei mit einer Methode in meinem Controller,
public function getImageFile(Request $request){ $image = $request->image; $this->imageUpload($image); }
Jetzt sende ich es, um die Größe zu ändern und den Bildnamen und die Erweiterung zu erhalten ...
public function imageUpload($file){ ini_set('memory_limit', '-1'); $directory = 'uploads/'; $name = str_replace([" ", "."], "_", $file->getClientOriginalName()) . "_"; $file_name = $name . time() . rand(1111, 9999) . '.' . $file->getClientOriginalExtension(); //path set $img_url = $directory.$file_name; list($width, $height) = getimagesize($file); $h = ($height/$width)*600; Image::make($file)->resize(600, $h)->save(public_path($img_url)); $this->image_fix_orientation($file,$img_url); return $img_url; }
Jetzt rufe ich meine Bildorientierungsfunktion auf,
public function image_fix_orientation($file,$img_url ) { $data = Image::make($file)->exif(); if (!empty($data['Orientation'])) { $image = imagecreatefromjpeg($file); switch ($data['Orientation']) { case 3: $image = imagerotate($image, 180, 0); break; case 6: $image = imagerotate($image, -90, 0); break; case 8: $image = imagerotate($image, 90, 0); break; } imagejpeg($image, $img_url, 90); } }
Und das ist alles...
quelle
Ich hasse es, noch einen weiteren Satz von Orientierungswerten zu verwenden, aber meiner Erfahrung nach habe ich beim Hochladen von Porträt-Orientierungsaufnahmen direkt von einem iPhone immer verkehrte Bilder erhalten. Hier ist die switch-Anweisung, mit der ich gelandet bin.
switch ($exif['Orientation']) { case 3: $image = imagerotate($image, -180, 0); break; case 6: $image = imagerotate($image, -90, 0); break; case 8: $image = imagerotate($image, 90, 0); break; }
quelle
jhead -autorot jpegfile.jpg
Ist auch ein nützlicher Weg, um dies zu erreichen.
jhead ist ein Standardprogramm unter Linux (verwenden Sie zum Installieren 'sudo apt-get install jhead'). Diese Option überprüft die Ausrichtung und dreht das Bild nur dann korrekt und verlustfrei, wenn dies erforderlich ist. Anschließend werden auch die EXIF-Daten korrekt aktualisiert.
Auf diese Weise können Sie ein JPEG (oder mehrere JPEGs in einem Ordner) auf einfache Weise in einem Durchgang verarbeiten, um Rotationsprobleme dauerhaft zu beheben.
Beispiel: jhead -autorot * .jpg repariert einen ganzen Ordner mit JPEG-Bildern genau so, wie es das OP in der ersten Frage benötigt.
Obwohl es technisch gesehen kein PHP ist, habe ich diesen Thread gelesen und stattdessen meinen jhead-Vorschlag verwendet, der von einem PHP-System () -Aufruf aufgerufen wurde, um die Ergebnisse zu erzielen, nach denen ich mit den OPs übereinstimmte: Bilder so zu drehen, dass jede Software (wie 'fbi 'in Raspbian) könnte sie korrekt anzeigen.
Vor diesem Hintergrund dachte ich, andere könnten davon profitieren, zu wissen, wie einfach jhead dieses Problem löst, und veröffentlichte die Informationen hier nur zu Informationszwecken - weil sie zuvor noch niemand erwähnt hatte.
quelle
Ich habe auch
orientate()
Form Intervention verwendet und es funktioniert einwandfrei.$image_resize = Image::make($request->file('photo')); $image_resize->resize(1600, null,function ($constraint) { $constraint->aspectRatio(); }); $filename = $this->checkFilename(); $image_resize->orientate()->save($this->photo_path.$filename,80);
quelle
Hier ist meine PHP 7-Funktion, inspiriert von @ user462990:
/** * @param string $filePath * * @return resource|null */ function rotateImageByExifOrientation(string $filePath) { $result = null; $exif = exif_read_data($filePath); if (!empty($exif['Orientation'])) { $image = imagecreatefromjpeg($filePath); if (is_resource($image)) { switch ($exif['Orientation']) { case 3: $result = imagerotate($image, 180, 0); break; case 6: $result = imagerotate($image, -90, 0); break; case 8: $result = imagerotate($image, 90, 0); break; } } } return $result; }
Verwendung:
$rotatedFile = rotateImageByExifOrientation($absoluteFilePath); if (is_resource($rotatedFile)) { imagejpeg($rotatedFile, $absoluteFilePath, 100); }
quelle
Interventionsbild hat eine Methode
orientate()
.$img = Image::make('foo.jpg')->orientate();
quelle