Autor Zpráva
CZghost
Profil
Zkoušel jsem různé postupy, od jednodušších, které však vracely fatální chybu s odkazem na neexistující, přes různá složitější, až jsem dospěl k tomuto bodu:
<?php
# VYKRESLENÍ OBRÁZKU ZE SOUBORU

# Inicializace proměnných
$address = $_GET['address'];    // konverze proměnné typu GET do globální
$size    = $_GET['size'];
$type    = $_GET['type'];
if(isset($_GET['depth'])) {
    $depth = $_GET['depth'];    // podmíněná konverze (hloubka se nastavuje pouze pro formát GIF)
}

$address         = urldecode($address);              // dekódování z URL
$addressArray    = explode('.',$address);            // rozdělení adresy podle teček (bude se brát přípona souboru jako formát)
$pocetPolozek    = count($addressArray);             // zjištění počtu položek v poli
$posledniPolozka = $pocetPolozek - 1;                // označení poslední položky, číslování od nuly
$fileExtension   = $addressArray[$posledniPolozka];  // výběr poslední položky z pole (přípona souboru)

$pomer           = $size / 100;                      // Poměr v jednotkovém vyjádření (desetinné číslo)

$error           = "";
$error          .= "<strong>Fatal error!</strong> ";
$error          .= "The image located in <strong>$address</strong> is not in a valid format! ";
$error          .= "Select JP(E)G, PNG or GIF format!";

# Nový obrázek na základě formátu (pokud není ani jeden z formátů, výpis chyby)
switch($fileExtension) {
    case 'jpg':  // JPG a JPEG jsou totožné formáty, přeskok na další formát
    case 'jpeg': $obrazek = imagecreatefromjpeg($address);
                 break;
    case 'png':  $obrazek = imagecreatefrompng($address);
                 break;
    case 'gif':  $obrazek = imagecreatefromgif($address);
                 imagepalettetotruecolor($obrazek); // převod z palety do true color (GIF nepodporuje true color)
                 break;
    default:     return $error; //ukončit program, není-li obrázek ani v jednom z uvedených formátů a vypsat chybu
}

# Nastavení rozměrů na základě původních
$sirkaVychozi = imagesx($obrazek); // Šířka výchozího obrázku
$vyskaVychozi = imagesy($obrazek); // Výška výchozího obrázku

$sirkaNova    = $sirkaVychozi * $pomer; // Definice nové šířky
$vyskaNova    = $vyskaVychozi * $pomer; // Definice nové výšky

$sirkaNova    = round($sirkaNova,0);    // Zaohrouhlení na celé číslo
$vyskaNova    = round($vyskaNova,0);

# Změna velikosti obrázku podle zadaných hodnot
header("Content-Type: image/png");                                // dočasné nastavení HTTP hlavičky na PNG obrázek pro nejvyšší možnou kvalitu
$obrazekNovy  = imagecreatetruecolor($sirkaNova,$vyskaNova);      // Vytvoření nového obrázku, pro změnu velikosti
imagecopyresampled($obrazekNovy,$obrazek,0,0,0,0,$sirkaNova,$vyskaNova,$sirkaVychozi,$vyskaVychozi); // Zkopírování a transformace obrázku do nového
imagedestroy($obrazek);                                         // původní obrázek již není potřeba, vymazat
# Render obrázku na základě zvoleného typu
switch($type) {
    case 'jpg': header("Content-Type: image/jpeg");             // nastavení HTTP hlavičky na JPEG obrázek
                imagejpeg($obrazekNovy);                        // render JPEG obrázku
                break;
    case 'png': header("Content-Type: image/png");              // nastavení HTTP hlavičky na PNG obrázek
                imagepng($obrazekNovy);                         // render PNG obrázku
                break;
    case 'gif': imagetruecolortopalette($obrazekNovy,$depth);   // převod z true color do palety o počtu barev definovaném ve formuláři
                header("Content-Type: image/gif");              // nastavení HTTP hlavičky na GIF obrázek
                imagegif($obrazekNovy);                         // render GIF obrázku
                break;
    default:    return $error;                                  // v případě jiných hodnot ukončit program
}

imagedestroy($obrazekNovy);                                     // vyčištění paměti
?>

Jenže skript mi pořád vrací obrázek bez dat, jakoby neexistoval. Neví někdo, v čem může být problém? Jak už jsem psal dříve, v PHP teprve začínám. Je to vlastně jen experiment, zkouším, co všechno PHP dokáže :-)



Tak jsem ještě zkusil zapracovat na kódu, zaměnil jsem switch za if, elseif a else (je to v podstatě stejný zápis, jen složitější), imagedestroy($obrazek); jsem přesunul dolů k druhému imagedestroy, bohužel se nic nezměnilo. Obrázek se stále neukazuje, prohlížeč však neukazuje žádnou chybu. Neví někdo, čím to může být?



Tak jsem vyzkoušel jiný formát (konkrétně JPG), skript funguje napůl. Místo zmenšení obrázku ho jen kopíruje, opravdu teď nevím, co jsem podělal.
CZghost
Profil
Tak právě jsem zjistil, že skript funguje téměř bez problémů - nevšiml jsem si nastavení velikosti na 100% :-) ale stále nefunguje render obrázku ve formátu GIF. Kdyžtak tady je nový kód:
<?php
# VYKRESLENÍ OBRÁZKU ZE SOUBORU

# Inicializace proměnných
$address = $_GET['address'];    // konverze proměnné typu GET do globální
$size    = $_GET['size'];
$type    = $_GET['type'];
if(isset($_GET['depth'])) {
    $depth = $_GET['depth'];    // podmíněná konverze (hloubka se nastavuje pouze pro formát GIF)
}

$address         = urldecode($address);                   // dekódování z URL
$address         = iconv("utf-8","iso-8859-2",$address);  // převod do formátu Latin-2
$addressArray    = explode('.',$address);                 // rozdělení adresy podle teček (bude se brát přípona souboru jako formát)
$pocetPolozek    = count($addressArray);                  // zjištění počtu položek v poli
$posledniPolozka = $pocetPolozek - 1;                     // označení poslední položky, číslování od nuly
$fileExtension   = $addressArray[$posledniPolozka];       // výběr poslední položky z pole (přípona souboru)

$pomer           = $size / 100;                           // Poměr v jednotkovém vyjádření (desetinné číslo)

$error           = "";
$error          .= "<strong>Fatal error!</strong> ";
$error          .= "The image located in <strong>$address</strong> is not in a valid format! ";
$error          .= "Select JP(E)G, PNG or GIF format!";

# Nový obrázek na základě formátu (pokud není ani jeden z formátů, výpis chyby)
if($fileExtension=='jpg'||$fileExtension=='jpeg') {
    $obrazek = imagecreatefromjpeg($address);
} elseif($fileExtension=='png') {
    $obrazek = imagecreatefrompng($address);
} elseif($fileExtension=='gif') {
    $obrazek = imagecreatefromgif($address);
    imagepalettetotruecolor($obrazek);              // převod z palety do true color (GIF nepodporuje true color)
} else {
    return $error;             //ukončit program, není-li obrázek ani v jednom z uvedených formátů a vypsat chybu
}

# Nastavení rozměrů na základě původních
$sirkaVychozi = imagesx($obrazek);      // Šířka výchozího obrázku
$vyskaVychozi = imagesy($obrazek);      // Výška výchozího obrázku

$sirkaNova    = $sirkaVychozi * $pomer; // Definice nové šířky
$vyskaNova    = $vyskaVychozi * $pomer; // Definice nové výšky

$sirkaNova    = round($sirkaNova,0);    // Zaohrouhlení na celé číslo
$vyskaNova    = round($vyskaNova,0);

# Změna velikosti obrázku podle zadaných hodnot
header("Content-Type: image/png");                                // dočasné nastavení HTTP hlavičky na PNG obrázek pro nejvyšší možnou kvalitu
$obrazekNovy  = imagecreatetruecolor($sirkaNova,$vyskaNova);      // Vytvoření nového obrázku, pro změnu velikosti
imagecopyresampled($obrazekNovy,$obrazek,0,0,0,0,$sirkaNova,$vyskaNova,$sirkaVychozi,$vyskaVychozi); // Zkopírování a transformace obrázku do nového

# Render obrázku na základě zvoleného typu
$error           = "";
$error          .= "<strong>Fatal error!</strong> ";
$error          .= "The image in requested type <strong>$type</strong> is not a valid format! ";
$error          .= "Select JP(E)G, PNG or GIF format!";

if($type=='jpg') {
    header("Content-Type: image/jpeg");             // nastavení HTTP hlavičky na JPEG obrázek
    imagejpeg($obrazekNovy);                        // render JPEG obrázku
} elseif($type=='png') {
    header("Content-Type: image/png");              // nastavení HTTP hlavičky na PNG obrázek
    imagepng($obrazekNovy);                         // render PNG obrázku
} elseif($type=='gif') {
    imagetruecolortopalette($obrazekNovy,$depth);   // převod z true color do palety o počtu barev definovaném ve formuláři
    header("Content-Type: image/gif");              // nastavení HTTP hlavičky na GIF obrázek
    imagegif($obrazekNovy);                         // render GIF obrázku
} else {
    return $error;                                  // v případě jiných hodnot ukončit program
}

imagedestroy($obrazek);
imagedestroy($obrazekNovy);                         // vyčištění paměti
?>



EDIT: Právě jsem zjistil, že funkce imagetruecolortopalette má mezi obrázkem a počtem barev ještě booleanskou proměnnou pro dithering :D Nějak jsem na to zapomněl, upravím to až přijdu domů, teď jsem ve škole.
CZghost
Profil
Tak definitivní odpověď:

Našel jsem svou chybu, převod z true color do palety nefungoval kvůli opomněnému parametru dithering. Zde je nový kód dané části:
header("Content-Type: image/gif");                      
imagetruecolortopalette($obrazekNovy,$dithering,$depth);
imagegif($obrazekNovy);                                 

Ještě jsem zjistil, že převod z palety do true color není definován, v tomto případě bych musel každopádně kopírovat obsah obrázku do nového s nastavením truecolor. Kdoví, třeba se někdy dočkáme implementace množství nových funkcí pro obrázky (mezi spekulovanými v dokumentaci také imagescale) :-)

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: