Oznámení

Provoz fóra byl ukončen

Automatický zmenšovač obrázků

před 10 lety

gmvasek
Člen | 1283

Napsal jsem si do své wiki jednoduchý kód, který místo zmenšování obrázků pomocí HTML v syntaxi [ * obrazek.gif 50 X 30 *] při generování obrázek vezme, podívá se jestli už takový zmenšený neexistuje a případně ho uloží:

// If it exists...
if(file_exists(WWW_DIR . '/uploads/' . $image->URL))
{
    // If any of image dimensions is specified, create new resized image
    if($image->width || $image->height)
    {
        $originalsize = getimagesize(WWW_DIR . '/uploads/' . $image->URL);

        // Step 1: Calculate new image dimension
        if($image->width && $image->height)
        {
            $newsize = RSWImage::calculateSize($originalsize[0], $originalsize[1], $image->width, $image->height, Image::ENLARGE | Image::STRETCH);
        }
        else
        {
            $newsize = RSWImage::calculateSize($originalsize[0], $originalsize[1], $image->width, $image->height, Image::ENLARGE);
        }

        // Step 2: If it exists...
        $dest_path = 'resized/' . pathinfo($image->URL, PATHINFO_FILENAME) . '-' . $newsize[0] . 'x' . $newsize[1] . '.' . pathinfo($image->URL, PATHINFO_EXTENSION);
        if(file_exists(WWW_DIR . '/uploads/' . $dest_path))
        {
            // Step 3a: ...then return the new image's URL
            $image->URL = $dest_path;
        }
        else
        {
            // Step 3b: ... and if not, create the image and save it
            $img = Image::fromFile(WWW_DIR . '/uploads/' . $image->URL);

            if($image->width && $image->height)
            {
                $img->resize($image->width, $image->height, Image::ENLARGE | Image::STRETCH);
            }
            else
            {
                $img->resize($image->width, $image->height, Image::ENLARGE);
            }

            $img->sharpen();
            // Already defined
            // $dest_path = 'resized/' . pathinfo($image->URL, PATHINFO_FILENAME) . '-' . $img->getWidth() . 'x' . $img->getHeight() . '.' . pathinfo($image->URL, PATHINFO_EXTENSION);
            $img->save(WWW_DIR . '/uploads/' . $dest_path);

            $image->URL = $dest_path;
        }
    }

    return $invocation->proceed($image, $link);
}

Je využívána třída Image z Nette, RSWImage je třída obsahující jedinou metodu calculateSize: (stejná jako u Image::calculateSize až na přidané dva parametry)

class RSWImage extends Object
{
    /**
     * Calculates dimensions of resized image.
     * @param  mixed  width in pixels or percent
     * @param  mixed  height in pixels or percent
     * @param  int    flags
     * @return array
     */
    public static function calculateSize($width, $height, $newWidth, $newHeight, $flags = 0)
    {
        if (substr($newWidth, -1) === '%') {
            $newWidth = round($width / 100 * $newWidth);
            $flags |= Image::ENLARGE;
            $percents = TRUE;
        } else {
            $newWidth = (int) $newWidth;
        }

        if (substr($newHeight, -1) === '%') {
            $newHeight = round($height / 100 * $newHeight);
            $flags |= empty($percents) ? Image::ENLARGE : Image::STRETCH;
        } else {
            $newHeight = (int) $newHeight;
        }

        if ($flags & Image::STRETCH) { // non-proportional
            if ($newWidth < 1 || $newHeight < 1) {
                throw new InvalidArgumentException('For stretching must be both width and height specified.');
            }

            if (($flags & Image::ENLARGE) === 0) {
                $newWidth = round($width * min(1, $newWidth / $width));
                $newHeight = round($height * min(1, $newHeight / $height));
            }

        } else {  // proportional
            if ($newWidth < 1 && $newHeight < 1) {
                throw new InvalidArgumentException('At least width or height must be specified.');
            }

            $scale = array();
            if ($newWidth > 0) { // fit width
                $scale[] = $newWidth / $width;
            }

            if ($newHeight > 0) { // fit height
                $scale[] = $newHeight / $height;
            }

            if ($flags & Image::FILL) {
                $scale = array(max($scale));
            }

            if (($flags & Image::ENLARGE) === 0) {
                $scale[] = 1;
            }

            $scale = min($scale);
            $newWidth = round($width * $scale);
            $newHeight = round($height * $scale);
        }

        return array($newWidth, $newHeight);
    }
}

Předpokládá se upload obrázků do složky /uploads/, $texy->imageModule->root taky /uploads/, složka pro zmenšené obrázky je /uploads/resized/. Na obě dvě složky se předpokládá nastavený CHMOD 777.

před 9 lety

uestla
Backer | 743

Přidávám vlastní řešení, také v kombinaci s Nette:

$texy->imageModule->root = Environment::getVariable('baseUri') . 'images/';
$texy->imageModule->fileRoot = WWW_DIR . '/images/';
$texy->addHandler('image', 'thumbHandler');

function thumbHandler($invocation, $image, $link)
{
    $image->URL = LayoutHelpers::thumb($image->URL, $image->width, $image->height);
    return $invocation->proceed();
}

Čili následující kód vygeneruje miniaturu a uloží (aby se nemusela pořád vytvářet znovu). Znovu se vytvoří až když ji ručně smažete, nebo až dojde ke změně originálního obrázku:

<!-- Texy! -->
[* obrazek.jpg 150x? *]

<!-- Latte - ekvivalent -->
<img src="{=$basePath}/{='images/obrazek.jpg'|thumb:150}">

Jak vidíte, moje řešení využívá třídu LayoutHelpers uveřejněnou na fóru Nette tak, aby se zmenšování dalo použít i samostatně v šablonách (vizte tamní příspěvek).

Editoval uestla (23. 10. 2010 5:40)