Files
KantSites/scripts/build-luximmo-assets.php
T
2026-11-09 08:02:38 +01:00

148 lines
6.8 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
/**
* Bereitet die Bilder des Luximmo-Entwurfs (luximmo-website.zip) für die Mediathek vor.
*
* Aus dem Ordner „assets“ des Pakets entstehen:
* - logo.png: das Logo ohne Rand, 640 px breit (Original 2596 × 2274, Zeichen und Schriftzug),
* - favicon.png: nur das goldene Zeichen (Kreis mit Häusern), quadratisch auf Weiß, 512 px,
* - mietverwaltung.webp, weg.webp, sonder.webp: die drei Leistungsfotos als WebP,
* - hero.webm: das Hero-Video unverändert,
* - hero-poster.webp: das Standbild aus dem Video (vorher mit build-luximmo-poster.mjs als PNG).
*
* Aufruf: php scripts/build-luximmo-assets.php <assets-Ordner des Pakets> <Zielordner> [poster.png]
*/
$quelle = rtrim($argv[1] ?? '', '/\\');
$ziel = rtrim($argv[2] ?? '', '/\\');
$poster = $argv[3] ?? '';
if ('' === $quelle || '' === $ziel || !is_file($quelle.'/luximmo-logo.png')) {
fwrite(STDERR, "Aufruf: php scripts/build-luximmo-assets.php <Ordner mit luximmo-logo.png usw.> <Zielordner> [poster.png]\n");
exit(1);
}
if (!is_dir($ziel) && !mkdir($ziel, 0775, true)) {
fwrite(STDERR, "Zielordner lässt sich nicht anlegen: $ziel\n");
exit(1);
}
/** Verkleinert ein Bild auf eine Zielbreite und speichert es als WebP. */
$webp = static function (GdImage $bild, string $name, int $breite) use ($ziel): void {
$breite = min($breite, imagesx($bild));
$hoehe = (int) round(imagesy($bild) * $breite / imagesx($bild));
$neu = imagecreatetruecolor($breite, $hoehe);
imagecopyresampled($neu, $bild, 0, 0, 0, 0, $breite, $hoehe, imagesx($bild), imagesy($bild));
imagewebp($neu, $ziel.'/'.$name, 80);
echo "$name: {$breite} × {$hoehe}\n";
};
foreach (['mietverwaltung', 'weg', 'sonder'] as $foto) {
$bild = imagecreatefromjpeg($quelle.'/'.$foto.'.jpg') ?: exit("Foto fehlt: $foto.jpg\n");
$webp($bild, $foto.'.webp', 1600);
}
if ('' !== $poster) {
$webp(imagecreatefrompng($poster) ?: exit("Standbild lässt sich nicht lesen: $poster\n"), 'hero-poster.webp', 1920);
}
copy($quelle.'/hero.webm', $ziel.'/hero.webm');
echo "hero.webm übernommen\n";
// Das Logo: Grenzen aller nicht weißen, nicht durchsichtigen Punkte, dazu die des Goldtons allein.
$logo = imagecreatefrompng($quelle.'/luximmo-logo.png');
imagepalettetotruecolor($logo);
$alles = [PHP_INT_MAX, PHP_INT_MAX, 0, 0];
$gold = [PHP_INT_MAX, PHP_INT_MAX, 0, 0];
for ($y = 0; $y < imagesy($logo); $y += 2) {
for ($x = 0; $x < imagesx($logo); $x += 2) {
$c = imagecolorat($logo, $x, $y);
[$a, $r, $g, $b] = [$c >> 24 & 0x7F, $c >> 16 & 0xFF, $c >> 8 & 0xFF, $c & 0xFF];
if ($a > 100 || ($r > 235 && $g > 235 && $b > 235)) {
continue;
}
$alles = [min($alles[0], $x), min($alles[1], $y), max($alles[2], $x), max($alles[3], $y)];
if ($r - $b > 40) {
$gold = [min($gold[0], $x), min($gold[1], $y), max($gold[2], $x), max($gold[3], $y)];
}
}
}
/** Ein Ausschnitt des Logos auf eine Fläche gesetzt: durchsichtig oder weiß. */
$ausschnitt = static function (array $kasten, int $breite, int $hoehe, int $rand, bool $weiss) use ($logo): GdImage {
$neu = imagecreatetruecolor($breite, $hoehe);
imagealphablending($neu, false);
imagesavealpha($neu, true);
imagefill($neu, 0, 0, $weiss ? imagecolorallocate($neu, 255, 255, 255) : imagecolorallocatealpha($neu, 255, 255, 255, 127));
imagealphablending($neu, true);
[$x1, $y1, $x2, $y2] = $kasten;
$b = $x2 - $x1 + 1;
$h = $y2 - $y1 + 1;
$faktor = min(($breite - 2 * $rand) / $b, ($hoehe - 2 * $rand) / $h);
$zb = (int) round($b * $faktor);
$zh = (int) round($h * $faktor);
imagecopyresampled($neu, $logo, (int) (($breite - $zb) / 2), (int) (($hoehe - $zh) / 2), $x1, $y1, $zb, $zh, $b, $h);
return $neu;
};
$breite = 640;
$hoehe = (int) round(($alles[3] - $alles[1] + 1) * $breite / ($alles[2] - $alles[0] + 1));
imagepng($ausschnitt($alles, $breite, $hoehe, 0, false), $ziel.'/logo.png', 9);
echo "logo.png: {$breite} × {$hoehe}\n";
imagepng($ausschnitt($gold, 512, 512, 36, true), $ziel.'/favicon.png', 9);
echo "favicon.png: 512 × 512 (Zeichen ohne Schriftzug)\n";
// Piktogramme für die Objektart der Immobilienbewertung: goldene Linien auf Creme, wie das Logo.
// Vierfach gezeichnet und verkleinert, damit die dicken Linien glatte Kanten bekommen.
$piktogramm = static function (string $name, callable $zeichnen) use ($ziel): void {
$s = 4;
$gross = imagecreatetruecolor(480 * $s, 360 * $s);
imagefill($gross, 0, 0, imagecolorallocate($gross, 0xF7, 0xF4, 0xEF));
$gold = imagecolorallocate($gross, 0xBD, 0xA0, 0x76);
imagesetthickness($gross, 5 * $s);
$p = static fn (array $punkte): array => array_map(static fn (int $v): int => $v * $s, $punkte);
$linie = static fn (int $x1, int $y1, int $x2, int $y2) => imageline($gross, $x1 * $s, $y1 * $s, $x2 * $s, $y2 * $s, $gold);
$rahmen = static fn (int $x1, int $y1, int $x2, int $y2) => imagepolygon($gross, $p([$x1, $y1, $x2, $y1, $x2, $y2, $x1, $y2]), $gold);
$flaeche = static fn (int $x1, int $y1, int $x2, int $y2) => imagefilledrectangle($gross, $x1 * $s, $y1 * $s, $x2 * $s, $y2 * $s, $gold);
$zeichnen($linie, $rahmen, $flaeche, static fn (array $punkte) => imagepolygon($gross, $p($punkte), $gold));
$klein = imagecreatetruecolor(480, 360);
imagecopyresampled($klein, $gross, 0, 0, 0, 0, 480, 360, 480 * $s, 360 * $s);
imagewebp($klein, $ziel.'/'.$name, 90);
echo "$name: 480 × 360\n";
};
$piktogramm('option-wohnung.webp', static function ($linie, $rahmen, $flaeche): void {
$linie(110, 300, 370, 300);
$rahmen(180, 80, 300, 300);
foreach ([110, 150, 190, 230] as $y) {
foreach ([200, 228, 256] as $x) {
150 === $y && 228 === $x ? $flaeche($x, $y, $x + 22, $y + 22) : $rahmen($x, $y, $x + 22, $y + 22);
}
}
$rahmen(225, 262, 255, 300);
});
$piktogramm('option-haus.webp', static function ($linie, $rahmen, $flaeche, $vieleck): void {
$linie(110, 300, 370, 300);
$vieleck([150, 175, 240, 98, 330, 175]);
$rahmen(170, 175, 310, 300);
$rahmen(226, 240, 256, 300);
$rahmen(186, 198, 214, 226);
$rahmen(268, 198, 296, 226);
});
$piktogramm('option-mehrfamilienhaus.webp', static function ($linie, $rahmen): void {
$linie(100, 300, 380, 300);
$rahmen(140, 100, 340, 300);
$linie(140, 122, 340, 122);
foreach ([140, 178, 216] as $y) {
foreach ([162, 202, 256, 296] as $x) {
$rahmen($x, $y, $x + 22, $y + 22);
}
}
$rahmen(224, 256, 256, 300);
});
$piktogramm('option-grundstueck.webp', static function ($linie, $rahmen, $flaeche, $vieleck): void {
$vieleck([100, 290, 380, 290, 325, 195, 155, 195]);
$linie(240, 245, 240, 120);
$vieleck([240, 120, 290, 138, 240, 156]);
foreach ([[100, 290], [380, 290], [325, 195], [155, 195]] as [$x, $y]) {
$flaeche($x - 7, $y - 7, $x + 7, $y + 7);
}
});