Fix: EXIF-Orientierung beim Bild-Crop normalisieren
This commit is contained in:
parent
e1f356d0cf
commit
bd9d0c670d
2 changed files with 51 additions and 2 deletions
|
|
@ -13,7 +13,7 @@ RUN apt-get update && apt-get install -y \
|
|||
tesseract-ocr \
|
||||
tesseract-ocr-deu \
|
||||
&& docker-php-ext-configure gd --with-freetype --with-jpeg \
|
||||
&& docker-php-ext-install pdo pdo_mysql zip gd \
|
||||
&& docker-php-ext-install pdo pdo_mysql zip gd exif \
|
||||
&& apt-get clean && rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Install Composer
|
||||
|
|
|
|||
|
|
@ -12,7 +12,8 @@ class ImageCropService
|
|||
|
||||
/**
|
||||
* Schneidet ein Bild auf den angegebenen Bereich zu (manueller Zuschnitt).
|
||||
* Koordinaten und Maße beziehen sich auf das Originalbild in Pixeln.
|
||||
* Koordinaten und Maße beziehen sich auf das EXIF-normalisierte Bild,
|
||||
* also auf das, was der Browser dem Nutzer anzeigt.
|
||||
* Gibt true zurück, wenn das Bild gespeichert wurde.
|
||||
*/
|
||||
public function cropToRect(string $path, int $x, int $y, int $w, int $h): bool
|
||||
|
|
@ -29,6 +30,10 @@ class ImageCropService
|
|||
return false;
|
||||
}
|
||||
|
||||
// EXIF-Orientierung anwenden, damit Crop-Koordinaten mit der
|
||||
// Browser-Darstellung übereinstimmen.
|
||||
$img = $this->applyExifOrientation($img, $path, $mime);
|
||||
|
||||
$imgW = imagesx($img);
|
||||
$imgH = imagesy($img);
|
||||
|
||||
|
|
@ -72,6 +77,10 @@ class ImageCropService
|
|||
return false;
|
||||
}
|
||||
|
||||
// EXIF-Orientierung normalisieren, damit Randerkennnung auf dem
|
||||
// korrekt ausgerichteten Bild arbeitet.
|
||||
$img = $this->applyExifOrientation($img, $path, $mime);
|
||||
|
||||
$w = imagesx($img);
|
||||
$h = imagesy($img);
|
||||
|
||||
|
|
@ -178,6 +187,46 @@ class ImageCropService
|
|||
return ['top' => $top, 'bottom' => $bottom, 'left' => $left, 'right' => $right];
|
||||
}
|
||||
|
||||
/**
|
||||
* Wendet die EXIF-Orientierung eines JPEGs auf das GdImage an und gibt
|
||||
* ein korrekt ausgerichtetes Bild zurück. PNG-Bilder werden unverändert
|
||||
* zurückgegeben. Nach dem Anwenden ist die Orientierung im Pixelinhalt
|
||||
* kodiert; beim Speichern via imagejpeg() entfällt der EXIF-Tag.
|
||||
*/
|
||||
private function applyExifOrientation(\GdImage $img, string $path, string $mime): \GdImage
|
||||
{
|
||||
if ($mime !== 'image/jpeg' || !function_exists('exif_read_data')) {
|
||||
return $img;
|
||||
}
|
||||
|
||||
$exif = @exif_read_data($path);
|
||||
$orientation = (int)($exif['Orientation'] ?? 1);
|
||||
|
||||
if ($orientation <= 1) {
|
||||
return $img; // keine Drehung nötig
|
||||
}
|
||||
|
||||
// Horizontale Spiegelung vor einer etwaigen Drehung
|
||||
if (in_array($orientation, [2, 5, 7], true)) {
|
||||
imageflip($img, IMG_FLIP_HORIZONTAL);
|
||||
}
|
||||
|
||||
$degrees = match ($orientation) {
|
||||
3, 4 => 180,
|
||||
5, 6 => -90, // 90° im Uhrzeigersinn
|
||||
7, 8 => 90, // 90° gegen den Uhrzeigersinn
|
||||
default => 0,
|
||||
};
|
||||
|
||||
if ($degrees !== 0) {
|
||||
$rotated = imagerotate($img, $degrees, 0);
|
||||
imagedestroy($img);
|
||||
return $rotated instanceof \GdImage ? $rotated : $img;
|
||||
}
|
||||
|
||||
return $img;
|
||||
}
|
||||
|
||||
private function isWhite(int $color): bool
|
||||
{
|
||||
$r = ($color >> 16) & 0xFF;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue