Skip to content

Instantly share code, notes, and snippets.

@michabbb
Created October 6, 2024 15:50
Show Gist options
  • Save michabbb/486990ec6c6c97d5d65f8adf7922042e to your computer and use it in GitHub Desktop.
Save michabbb/486990ec6c6c97d5d65f8adf7922042e to your computer and use it in GitHub Desktop.
intelligent Crop Transparent in PHP
private function intelligentCropTransparent(
string $inputPath,
string $outputPath,
int $padding = 5,
bool $makeSquare = false,
bool $transparentBackground = true
): void
{
$image = new Imagick($inputPath);
$originalWidth = $image->getImageWidth();
$originalHeight = $image->getImageHeight();
$format = $image->getImageFormat();
echo "Ursprüngliche Bildgröße: {$originalWidth}x{$originalHeight}, Format: $format\n";
$hasAlpha = $image->getImageAlphaChannel();
echo "Hat Alphakanal: " . ($hasAlpha ? "Ja" : "Nein") . "\n";
$width = $image->getImageWidth();
$height = $image->getImageHeight();
$left = $width;
$top = $height;
$right = 0;
$bottom = 0;
$foundNonTransparent = false;
$pixelCount = [
'transparent' => 0,
'non_transparent' => 0
];
// Durchsuche das Bild nach nicht-transparenten Pixeln
for ($x = 0; $x < $width; $x++) {
for ($y = 0; $y < $height; $y++) {
$pixel = $image->getImagePixelColor($x, $y);
$colors = $pixel->getColor();
// Behandle Pixel mit Alpha-Wert 1 oder höher als nicht-transparent
if ($colors['a'] >= 1) {
$left = min($left, $x);
$top = min($top, $y);
$right = max($right, $x);
$bottom = max($bottom, $y);
$foundNonTransparent = true;
$pixelCount['non_transparent']++;
} else {
$pixelCount['transparent']++;
}
}
}
echo "Gefundene Grenzen: Links: $left, Oben: $top, Rechts: $right, Unten: $bottom\n";
echo "Transparente Pixel: {$pixelCount['transparent']}, Nicht-transparente Pixel: {$pixelCount['non_transparent']}\n";
if (!$foundNonTransparent) {
throw new RuntimeException("Keine nicht-transparenten Pixel gefunden. Das Bild könnte vollständig transparent sein.");
}
// Füge Padding hinzu
$left = max(0, $left - $padding);
$top = max(0, $top - $padding);
$right = min($width - 1, $right + $padding);
$bottom = min($height - 1, $bottom + $padding);
$newWidth = $right - $left + 1;
$newHeight = $bottom - $top + 1;
if ($makeSquare) {
$size = max($newWidth, $newHeight);
$verticalPadding = $size - $newHeight;
$topPadding = floor($verticalPadding / 2);
$bottomPadding = ceil($verticalPadding / 2);
$top = max(0, $top - $topPadding);
$bottom = min($height - 1, $bottom + $bottomPadding);
$newHeight = $size;
$newWidth = $size;
echo "Quadratische Bildgröße: {$size}x{$size}\n";
} else {
echo "Neue Bildgröße: {$newWidth}x{$newHeight}\n";
}
echo "Finale Grenzen: Links: $left, Oben: $top, Rechts: $right, Unten: $bottom\n";
// Beschneide das Bild
$image->cropImage($newWidth, $newHeight, $left, $top);
// Erstelle ein neues Bild
$newImage = new Imagick();
if ($transparentBackground) {
// Transparenter Hintergrund
$newImage->newImage($newWidth, $newHeight, new ImagickPixel('transparent'));
} else {
// Weißer Hintergrund
$newImage->newImage($newWidth, $newHeight, new ImagickPixel('white'));
}
$newImage->setImageFormat('png');
// Kopiere das beschnittene Bild auf das neue Bild
$newImage->compositeImage($image, Imagick::COMPOSITE_OVER, 0, 0);
// Speichere das neue Bild
$newImage->writeImage($outputPath);
$image->clear();
$newImage->clear();
$outputImage = new Imagick($outputPath);
$finalWidth = $outputImage->getImageWidth();
$finalHeight = $outputImage->getImageHeight();
echo "Finale Bildgröße: {$finalWidth}x{$finalHeight}\n";
$outputImage->clear();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment