Przejdź do treści

Tworzenie miniatur obrazków (GD)

  • Pliki i obrazy
  • poziom: średni
  • aktualizacja: 12 lipca 2026

Wstawianie na stronę zdjęć prosto z aparatu to proszenie się o wolne ładowanie. Rozwiązaniem są miniatury — pomniejszone kopie obrazków generowane raz, po stronie serwera. Ta funkcja korzysta z biblioteki GD (dostępnej praktycznie na każdym hostingu), zachowuje proporcje i przezroczystość PNG/WebP.

PHP 102 linii Pobierz .php
<?php
/**
 * Miniatury obrazków (GD) — skryptyPHP.com
 * Zapisz jako: miniatury.php
 * Wymaga rozszerzenia GD (na hostingach zwykle włączone domyślnie).
 */

/**
 * Tworzy miniaturę obrazka z zachowaniem proporcji.
 *
 * @param string $zrodlo   ścieżka do oryginału (jpg/png/webp/gif)
 * @param string $cel      ścieżka zapisu miniatury (format wg rozszerzenia)
 * @param int    $maxSzer  maksymalna szerokość miniatury
 * @param int    $maxWys   maksymalna wysokość miniatury
 */
function utworz_miniature(
    string $zrodlo,
    string $cel,
    int $maxSzer = 400,
    int $maxWys = 400
): bool {
    $info = @getimagesize($zrodlo);
    if ($info === false) {
        return false; // to nie jest obrazek
    }
    [$szer, $wys, $typ] = $info;

    // Wczytanie oryginału
    $obraz = match ($typ) {
        IMAGETYPE_JPEG => imagecreatefromjpeg($zrodlo),
        IMAGETYPE_PNG  => imagecreatefrompng($zrodlo),
        IMAGETYPE_GIF  => imagecreatefromgif($zrodlo),
        IMAGETYPE_WEBP => function_exists('imagecreatefromwebp')
                            ? imagecreatefromwebp($zrodlo) : false,
        default        => false,
    };
    if ($obraz === false) {
        return false;
    }

    // Skala: nie powiększamy małych obrazków (min(..., 1))
    $skala    = min($maxSzer / $szer, $maxWys / $wys, 1);
    $nowaSzer = max(1, (int) round($szer * $skala));
    $nowaWys  = max(1, (int) round($wys  * $skala));

    $miniatura = imagecreatetruecolor($nowaSzer, $nowaWys);

    // Zachowanie przezroczystości dla PNG/WebP/GIF
    $rozszerzenie = strtolower(pathinfo($cel, PATHINFO_EXTENSION));
    if (in_array($rozszerzenie, ['png', 'webp', 'gif'], true)) {
        imagealphablending($miniatura, false);
        imagesavealpha($miniatura, true);
        $przezroczysty = imagecolorallocatealpha($miniatura, 0, 0, 0, 127);
        imagefilledrectangle($miniatura, 0, 0, $nowaSzer, $nowaWys, $przezroczysty);
    }

    // Przeskalowanie z wygładzaniem
    imagecopyresampled(
        $miniatura, $obraz,
        0, 0, 0, 0,
        $nowaSzer, $nowaWys, $szer, $wys
    );

    // Zapis w formacie zgodnym z rozszerzeniem pliku docelowego
    $ok = match ($rozszerzenie) {
        'jpg', 'jpeg' => imagejpeg($miniatura, $cel, 85),
        'png'         => imagepng($miniatura, $cel, 6),
        'webp'        => function_exists('imagewebp')
                            ? imagewebp($miniatura, $cel, 82) : false,
        'gif'         => imagegif($miniatura, $cel),
        default       => false,
    };

    imagedestroy($obraz);
    imagedestroy($miniatura);

    return $ok;
}

// ── PRZYKŁAD 1: jedna miniatura ─────────────────────────────
if (utworz_miniature('zdjecia/wakacje.jpg', 'miniatury/wakacje.jpg', 400, 300)) {
    echo "Miniatura utworzona!<br>";
}

// ── PRZYKŁAD 2: cały katalog naraz ──────────────────────────
$zrodlowy = __DIR__ . '/zdjecia';
$docelowy = __DIR__ . '/miniatury';

if (!is_dir($docelowy)) {
    mkdir($docelowy, 0755, true);
}

$obrazki = glob($zrodlowy . '/*.{jpg,jpeg,png,webp}', GLOB_BRACE) ?: [];

foreach ($obrazki as $sciezka) {
    $nazwa = basename($sciezka);
    if (utworz_miniature($sciezka, $docelowy . '/' . $nazwa, 400, 400)) {
        echo "OK: " . htmlspecialchars($nazwa) . "<br>";
    } else {
        echo "Pominięto: " . htmlspecialchars($nazwa) . "<br>";
    }
}

Jak użyć tego skryptu

  1. Skopiuj funkcję utworz_miniature() do swojego projektu (np. do pliku miniatury.php).
  2. Podaj ścieżkę oryginału, ścieżkę docelową i maksymalne wymiary — format miniatury wynika z rozszerzenia pliku docelowego, więc możesz np. z PNG zrobić lżejszy JPEG.
  3. Do zdjęć w galerii najlepiej generować miniatury raz — zaraz po wgraniu pliku (połącz ze skryptem „Bezpieczny upload plików").

Warto wiedzieć

  • imagecopyresampled() daje wyraźnie lepszą jakość niż starsze imagecopyresized() — używaj zawsze tej pierwszej.
  • Funkcja nie powiększa obrazków mniejszych niż zadane wymiary (czynnik min(..., 1)) — powiększanie tylko psuje jakość.
  • Duże zdjęcia potrafią zjeść dużo pamięci (w przybliżeniu szerokość × wysokość × 5 bajtów) — przy zdjęciach z aparatu może być potrzebne ini_set('memory_limit', '256M').
  • Jeśli hosting ma rozszerzenie Imagick, warto je rozważyć przy bardzo dużych plikach — ale GD wystarcza w 95% zastosowań.
#miniatury #gd #obrazki #galeria #webp

Podobne skrypty