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 \
|
||||||
tesseract-ocr-deu \
|
tesseract-ocr-deu \
|
||||||
&& docker-php-ext-configure gd --with-freetype --with-jpeg \
|
&& 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/*
|
&& apt-get clean && rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
# Install Composer
|
# Install Composer
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,8 @@ class ImageCropService
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Schneidet ein Bild auf den angegebenen Bereich zu (manueller Zuschnitt).
|
* 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.
|
* Gibt true zurück, wenn das Bild gespeichert wurde.
|
||||||
*/
|
*/
|
||||||
public function cropToRect(string $path, int $x, int $y, int $w, int $h): bool
|
public function cropToRect(string $path, int $x, int $y, int $w, int $h): bool
|
||||||
|
|
@ -29,6 +30,10 @@ class ImageCropService
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// EXIF-Orientierung anwenden, damit Crop-Koordinaten mit der
|
||||||
|
// Browser-Darstellung übereinstimmen.
|
||||||
|
$img = $this->applyExifOrientation($img, $path, $mime);
|
||||||
|
|
||||||
$imgW = imagesx($img);
|
$imgW = imagesx($img);
|
||||||
$imgH = imagesy($img);
|
$imgH = imagesy($img);
|
||||||
|
|
||||||
|
|
@ -72,6 +77,10 @@ class ImageCropService
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// EXIF-Orientierung normalisieren, damit Randerkennnung auf dem
|
||||||
|
// korrekt ausgerichteten Bild arbeitet.
|
||||||
|
$img = $this->applyExifOrientation($img, $path, $mime);
|
||||||
|
|
||||||
$w = imagesx($img);
|
$w = imagesx($img);
|
||||||
$h = imagesy($img);
|
$h = imagesy($img);
|
||||||
|
|
||||||
|
|
@ -178,6 +187,46 @@ class ImageCropService
|
||||||
return ['top' => $top, 'bottom' => $bottom, 'left' => $left, 'right' => $right];
|
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
|
private function isWhite(int $color): bool
|
||||||
{
|
{
|
||||||
$r = ($color >> 16) & 0xFF;
|
$r = ($color >> 16) & 0xFF;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue