148 lines
6.8 KiB
PHP
148 lines
6.8 KiB
PHP
<?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);
|
||
}
|
||
});
|