Язык страницы:

Thumbnails: Теория и практика создания миниатюрных изображений

Введение

Интернет позволяет пользователям публиковать собственные графические изображения, например, созданные с помощью компьютера, или фотографии, выполненные цифровыми камерами. Чаще всего эти работы выполнены на высоком художественном уровне и такие файлы значительны по размеру (как геометрически, так и в объеме хранимой информации). Современные серверные технологии позволяют создать уменьшенные копии изображений для их предварительного просмотра.

В англоязычной литературе для обозначения уменьшенных копий оригиналов существуют два термина - preview и thumbnail. Ни одно их не имеет адекватного перевода в русскоязычной литературе кроме более близкого по смыслу термина - миниатюра. В дальнейшем, в данной статье будет использоваться именно это слово и производные от него (с целью исключения повторов в тексте) либо близкие по смыслу выражения.

Обозначения, принятые в статье

Все способы создания миниатюр предполагают выполнение предварительных арифметических операций для вычисления начальной точки копирования фрагмента оригинального изображения, размеров копируемой области. На протяжении данной работы будут использоваться следующие обозначения (выраженные в пикселях):

  • W, H - ширина и высота оригинального изображения, соответственно;
  • X, Y - координаты начальной точки копирования (левого верхнего угла);
  • width, height - ширина и высота миниатюры, соответственно;
  • R, ratio - отношения меньшей стороны к большей стороне прямоугольников оригинала и миниатюры, соответственно;
  • Ww - отношение ширины большого прямоугольника к ширине маленького;
  • Hh - отношение высоты большого прямоугольника к ширине маленького.

Методы создания миниатюр

Основное место использования миниатюр - тематически структурированные коллекции и фото-галереи, где на главных страницах разделов выводятся уменьшенные копии изображений со ссылкой на оригинал. Для более подробного ознакомления с работой пользователь может посмотреть полную версию оригинала.

Размер миниатюры устанавливается администратором фото-галереи и имеет фиксированный размер, соответствующий общему дизайну. В настоящее время существует два наиболее распространенных способа создания миниатюр:

  • пропорционально уменьшенная копия;
  • вырезание некоторого фрагмента оригинала.

Каждый из способов имеет свои достоинства и недостатки. Например, миниатюры, созданные по первому способу позволяют увидеть миниатюрную копию цельного изображения, но могут испортить общий дизайн вследствие различной ориентации изображений (книжная или альбомная). А второй способ не дает полного представления о представленном изображении.

Однако можно выделить еще один, третий способ создания миниатюр, который можно представить как комбинацию первых двух. В данной статье будут рассмотрены все возможные способы.

Дополнительно, в противовес традиционным методам создания миниатюрных копий фиксированного размера, выраженного в пикселях, будет рассмотрено пропорциональное сжатие, выраженное в процентах от геометрического размера оригинального изображения. Будет показано, что этот способ не может рассматриваться как полноценный метод создания миниатюр, но имеет право на существование в определенных случаях.

По-видимому, не существует терминов, обозначающих способы создания миниатюр (по крайней мере, автор статьи их не обнаружил, кроме существующих терминов - масштабирование и обрезка), поэтому в статье будет использовать собственные. Эта терминология не претендует быть общепринятой, однако если это случится - автор будет рад.

Метод максимального сжатия

Используемый термин метод максимального сжатия означает сжатие большей стороны оригинала, так чтобы он был вписан полностью в размеры предлагаемой миниатюры. Для этого необходимо:

  1. определить большую сторону прямоугольника первоначального изображения;
  2. вычислить отношение R;
  3. вычислить меньшую сторону прямоугольника миниатюры путем умножения отношения R и большей стороны.

На псевдокоде это будет описано так:

if W > H
then
    height = H * width / W
else
    width  = W * height / H
end if

Таким образом, будут определены размеры будущей копии. Это необходимо, для создания уменьшенной копии, которая будет вписана в заданные рамки миниатюры без искажений. Дальнейшие действия заключаются в использовании соответствующих графических средств на стороне сервера по преобразованию изображений. Следующий пример иллюстрирует преобразование, реализованное на PHP (в предположении, что исходное изображение уже загружено в программу - переменная $srcImage, и его размеры получены в $width и $height):

$dstImage = imagecreate($width, $height);
imagecopyresized(
    $dstImage, $srcImage,
    0, 0, 0, 0,
    $width, $height, $W, $H);

Описание данного метода завершим рисунком, иллюстрирующим данный подход.

Рисунок 1. Метод максимального сжатия

Вырезать фрагмент технически достаточно простой способ - все-таки вся работа заключается лишь в копирования части изображения. Однако эстетическая сторона явно не соблюдена. В лучшем случае, если программистом заложена возможность - позволить пользователям выбрать подходящий фрагмент для показа на миниатюре. В худшем - будет создана копия, например, центральной части. Тем не менее техническую сторону мы рассмотрим. Так же рассмотрим вариант выбора фрагмента.

Следующий код на PHP иллюстрирует данный подход:

$dstImage = imagecreate($width, $height);
imagecopy(
    $dstImage, $srcImage
    0, 0, $X, $Y,
    $width, $height);

При всем многообразии начальных координат источника копирования автор считает, что источник копии может иметь только девять фиксированных позиций:

  1. центральная;
  2. крайние левая и правая стороны;
  3. крайние верхняя и нижняя границы;
  4. углы прямоугольника.

Соответственно, можно говорить о вертикальном и горизонтальном выравнивании. Алгоритм вычисления координат источника описан на псевдокоде:

if horizontal align = left
then
    X = 0
else if horizontal align = right
    X = W - width
else
    X = (W - width) / 2
end if

if vertical align = top
then
    Y = 0
else if vertical align = bottom
    Y = H - height
else
    Y = (H - height) / 2
end if

Рисунок 2. Фрагмент целого

Метод минимального сжатия

Рассмотрим вертикально расположенное изображение, которое необходимо вписать в квадрат. Если метод максимального сжатия, предполагает, что необходимо сжать большую сторону на столько, чтобы она полностью была вписана в соответствующую сторону миниатюры, то для реализации этого метода необходимо сжать меньшую, чтобы добиться требуемого результата.

Рисунок 3. Метод минимального сжатия

В общем случае, одна из сторон большого прямоугольника должна быть вписана в соответствующую сторону малого. При этом коэффициент сжатия (масштабирования) должен быть минимален. Этого легко добиться сравнивая соотношения соответствующих сторон - большее соотношение определяет сторону, которое будет обрезано при масштабировании.

Ww = W / width
Hh = H / height
if Ww > Hh
then
    W = width * Hh
    X = ...
else
    H = height * Ww
    Y = ...
end if

Здесь используется алгоритм вычисления начальных координат источника фрагмента, идентичный описанному ранее алгоритму.

Так как одна из сторон большего прямоугольника будет полностью вписана в соответствующую сторону меньшего, а другая - обрезана, то здесь тоже можно говорить о выравнивании - или вертикальном, или горизонтальном.

Пропорциональное сжатие в процентах

Последний способ создания миниатюр сложно отнести к действительно полноценному методу, однако он тоже требует своего рассмотрения. Причина кроется в том что, это фактически метод максимального сжатия и метод вырезания фрагмента целого, выраженные в пропорциональном уменьшении геометрических размеров изображения, но выраженное в процентах. Этот способ логично использовать в двух случаях:

  1. в проектах, где жестко заданы размеры исходного изображения (фиксированная ширина и/или фиксированная высота);
  2. при преобразовании очень больших изображений, когда создание миниатюры в один проход может привести к переполнению памяти.

При этом следует иметь в виду, что пропорции относятся к соответствующим сторонам исходного изображения и результирующего.

Иллюстрация создания миниатюр на PHP

В этом разделе будет подробно рассмотрен реализованный на PHP в рамках объектно-ориентированного похода модуль Thumbnail на основе описанного алгоритма.

Основным публичным методом является метод output(). В своей работе он использует результат работы метода render(), определяет приемник для вывода изображения (браузер или файл на сервере):

function output($input, $output=null, $options=array())
{
    // Load source file and render image
    $renderImage = Thumbnail::render($input, $options);
    if ( ! $renderImage ) {
        user_error('Error rendering image', 
            E_USER_NOTICE);
        return false;
    }
 
    // Set output image type
    // By default PNG image
    $type = isset($options['type']) ? $options['type'] : IMAGETYPE_PNG;
 
    // Before output to browsers send appropriate headers
    if ( empty($output) ) {
        $content_type = image_type_to_mime_type($type);
        if ( ! headers_sent() ) {
            header('Content-Type: ' . $content_type);
        } else {
            user_error('Headers have already been sent. Could not display image.', 
                E_USER_NOTICE);
            return false;
        }
    }
 
    // Define outputing function
    switch ($type) {
    case IMAGETYPE_PNG:
        $result = empty($output) 
            ? imagepng($renderImage) 
            : imagepng($renderImage, $output);
        break;
    case IMAGETYPE_JPEG:
        $result = empty($output) 
            ? imagejpeg($renderImage) 
            : imagejpeg($renderImage, $output);
        break;
    default:
        user_error('Image type ' . $content_type . ' not supported by PHP', 
            E_USER_NOTICE);
        return false;
    }
 
    // Output image (to browser or to file)
    if ( ! $result ) {
        user_error('Error output image', 
            E_USER_NOTICE);
        return false;
    }
 
    // Free a memory from the target image
    imagedestroy($renderImage);
 
    return true;
}

Обязательный аргумент функции - имя файла исходного изображения. По умолчанию, метод выводит результирующее изображение в браузер. Если будет указан второй аргумент - имя выходного файла, будет создан файл. Третий, аргумент метода, ассоциативный массив, содержит необязательные параметры обработки изображений. По умолчанию, используются собственные установки - методом максимального сжатия создается миниатюра в формате PNG размером 150х150 пикселей.

Логика класса по созданию миниатюр реализована в методе render(), который загружает файл изображения в память, определяет размеры исходного изображения, рассчитывает размеры будущей миниатюрной копии, создает новое изображение и возвращает ссылку на него в случае успешного выполнения. При этом данный метод использует вспомогательные методы для загрузки объекта и расчета необходимых переменных:

function render($input, $options=array())
{
    // Create the source image
    $sourceImage = Thumbnail::imageСreate($input);
    if ( ! is_resource($sourceImage) ) {
        user_error('Invalid image resource', 
            E_USER_NOTICE);
        return false;
    }
    $sourceWidth  = imagesx($sourceImage);
    $sourceHeight = imagesy($sourceImage);
 
    // Set default options
    static $defOptions = array(
        'width'   => 150,
        'height'  => 150,
        'method'  => THUMBNAIL_METHOD_SCALE_MAX,
        'percent' => 0,
        'halign'  => THUMBNAIL_ALIGN_CENTER,
        'valign'  => THUMBNAIL_ALIGN_CENTER,
    );
    foreach ($defOptions as $k => $v) {
        if ( ! isset($options[$k]) ) {
            $options[$k] = $v;
        }
    }
 
    // Estimate a rectangular portion of the source image and a size of the target image
    if ( $options['method'] == THUMBNAIL_METHOD_CROP ) {
        if ( $options['percent'] ) {
            $W = floor($options['percent'] * $sourceWidth);
            $H = floor($options['percent'] * $sourceHeight);
        } else {
            $W = $options['width'];
            $H = $options['height'];
        }
 
        $width  = $W;
        $height = $H;
 
        $Y = Thumbnail::_coord($options['valign'], $sourceHeight, $H);
        $X = Thumbnail::_coord($options['halign'], $sourceWidth,  $W);
    } else {
        $X = 0;
        $Y = 0;
 
        $W = $sourceWidth;
        $H = $sourceHeight;
 
        if ( $options['percent'] ) {
            $width  = floor($options['percent'] * $W);
            $height = floor($options['percent'] * $H);
        } else {
            $width  = $options['width'];
            $height = $options['height'];
 
            if ( $options['method'] == THUMBNAIL_METHOD_SCALE_MIN ) {
                $Ww = $W / $width;
                $Hh = $H / $height;
                if ( $Ww > $Hh ) {
                    $W = floor($width * $Hh);
                    $X = Thumbnail::_coord($options['halign'], $sourceWidth,  $W);
                } else {
                    $H = floor($height * $Ww);
                    $Y = Thumbnail::_coord($options['valign'], $sourceHeight, $H);
                }
            } else {
                if ( $H > $W ) {
                    $width  = floor($height / $H * $W);
                } else {
                    $height = floor($width / $W * $H);
                }
            }
        }
    }
 
    // Create the target image
    if ( function_exists('imagecreatetruecolor') ) {
        $targetImage = imagecreatetruecolor($width, $height);
    } else {
        $targetImage = imagecreate($width, $height);
    }
    if ( ! is_resource($targetImage) ) {
        user_error('Cannot initialize new GD image stream', 
            E_USER_NOTICE);
        return false;
    }
 
    // Copy the source image to the target image
    if ( $options['method'] == THUMBNAIL_METHOD_CROP ) {
        $result = imagecopy(
            $targetImage, $sourceImage, 
            0, 0, $X, $Y, 
            $W, $H);
    } elseif ( function_exists('imagecopyresampled') ) {
        $result = imagecopyresampled(
            $targetImage, $sourceImage, 
            0, 0, $X, $Y, 
            $width, $height, $W, $H);
    } else {
        $result = imagecopyresized(
            $targetImage, $sourceImage, 
            0, 0, $X, $Y, 
            $width, $height, $W, $H);
    }
    if ( ! $result ) {
        user_error('Cannot resize image', 
            E_USER_NOTICE);
        return false;
    }
 
    // Free a memory from the source image
    imagedestroy($sourceImage);
 
    // Save the resulting thumbnail
    return $targetImage;
}

Данный метод учитывает особенности работы PHP с графическими изображениями - при отсутствии функций библиотеки GD для работы с изображениями высокого качества imagecreatetruecolor и imagecopyresampled используются их менее качественные аналоги imagecreate и imagecopyresized.

Опции обработки изображения

При необходимости, можно указать аргумент $options (ассоциативный массив параметров - третий аргумент метода output() и второй - метода render()) для реализации собственной обработки изображений. Для этого необходимо лишь указать требуемые опции

  1. width - ширина миниатюры в пикселях (целое положительное число, по умолчанию 150);
  2. height - высота миниатюры в пикселях (целое положительное число, по умолчанию 150);
  3. method - метод обработки - максимальное/минимальное сжатие, вырезание фрагмента целого(целое число, по умолчанию максимальное сжатие);
  4. percent - масштабирование в процентах от оригинала (положительное вещественное число на интервале от 0 до 1, по умолчанию 0);
  5. halign - вертикальное выравнивание (допустимые значения 0 - по центру, < 0 - выравнивание по верхнему краю, > 0 - выравнивание по нижнему краю, по умолчанию - 0);
  6. valign - горизонтальное выравнивание (допустимые значения 0 - по центру, < 0 - выравнивание влево, > 0 - выравнивание вправо, по умолчанию - 0);
  7. type - тип выводимого изображения (IMAGETYPE_PNG или IMAGETYPE_JPEG, по умолчанию - IMAGETYPE_PNG).

Обработка ошибок

Никто не застрахован от ошибок, поэтому модуль реализует минимальную обработку типовых ошибок (неверный формат входных данных, невозможность инициализации графического формата) посредством генерации пользовательских сообщений встроенной функцией user_error.

Ошибки передачи некорректных опций отсутствуют. По мнению автора, эти ошибки должны обрабатываться и корректироваться на уровне приложения до передачи их в модуль.

Вспомогательные методы

Эти методы необходимы для загрузки изображения и расчета координат и размеров области копирования исходного и результирующего изображений.

Методы загрузки изображения из файла - основное их назначение определить источник изображения (файл, строка или образ изображения в памяти)

function imageCreate($input)
{
    if ( is_file($input) ) {
        return Thumbnail::imageCreateFromFile($input);
    } else if ( is_string($input) ) {
        return Thumbnail::imageCreateFromString($input);
    } else {
        return $input;
    }
}
 
function imageCreateFromFile($filename)
{
    if ( ! is_file($filename) || ! is_readable($filename) ) {
        user_error('Unable to open file "' . $filename . '"', 
            E_USER_NOTICE);
        return false;
    }
 
    // determine image format
    list( , , $type) = getimagesize($filename);
 
    switch ($type) {
    case IMAGETYPE_JPEG:
        return imagecreatefromjpeg($filename);
        break;
    case IMAGETYPE_PNG:
        return imagecreatefrompng($filename);
        break;
    }
    user_error('Unsupport image type', E_USER_NOTICE);
    return false;
}
 
function imageCreateFromString($string)
{
    if ( ! is_string($string) || empty($string) ) {
        user_error('Invalid image value in string', 
            E_USER_NOTICE);
        return false;
    }
 
    return imagecreatefromstring($string);
}

Метод расчета координат и размеров области копирования исходного и результирующего изображений

function _coord($align, $param, $src)
{
    if ( $align < THUMBNAIL_ALIGN_CENTER ) {
        $result = 0;
    } elseif ( $align > THUMBNAIL_ALIGN_CENTER ) {
        $result = $param - $src;
    } else {
        $result = ($param - $src) >> 1;
    }
    return $result;
}

Вся логика класса реализована в методе render(), который загружает файл изображения в память, определяет размеры исходного изображения, рассчитывает размеры будущей миниатюрной копии и возвращает ссылку на новое изображение в случае успешного выполнения. При этом данный метод использует вспомогательные методы для загрузки объекта и расчета необходимых переменных:

Предопределенные константы класса

В модуле предопределено несколько констант для управления методом создания миниатюр и выравнивания изображений

/**
 * Maximal scaling
 */
define('THUMBNAIL_METHOD_SCALE_MAX', 0);
 
/**
 * Minimal scaling
 */
define('THUMBNAIL_METHOD_SCALE_MIN', 1);
 
/**
 * Cropping of fragment
 */
define('THUMBNAIL_METHOD_CROP',      2);
 
/**
 * Align constants
 */
define('THUMBNAIL_ALIGN_CENTER', 0);
define('THUMBNAIL_ALIGN_LEFT',   -1);
define('THUMBNAIL_ALIGN_RIGHT',  +1);
define('THUMBNAIL_ALIGN_TOP',    -1);
define('THUMBNAIL_ALIGN_BOTTOM', +1);

Примеры использования

Пример 1. Простое создание миниатюры в браузер

include_once 'includes/Thumbnail.php';

$filename = 'files/image.jpg';
Thumbnail::output($filename);

Пример 2. Простое создание миниатюры в файл

include_once 'includes/Thumbnail.php';

$input_file = 'files/image.jpg';
$output_file = 'files/thumb.jpg';
Thumbnail::output($input_file, $output_file);

Пример 3. Использование собственных параметров (JPEG, 200х200 пикселей)

include_once 'includes/Thumbnail.php';

$filename = 'files/image.jpg';
$options = array(
    'width'  => 200,
    'height' => 200,
    'type'   => IMAGETYPE_JPEG,
);
Thumbnail::output($filename, null, $options);

По умолчанию, из любого изображения создается маленькое изображение в формате PNG. Указывая явно тип можно изменить формат графического потока (в примере - JPEG). Для вывода в браузер второй аргумент установлен в значение null.

Пример 4. Каскадное создание миниатюры из очень большого изображения

include_once 'includes/Thumbnail.php';
 
$filename = 'files/image.jpg';
$middleImage = Thumbnail::render($filename, array(
    'percent' => 0.5,
    'method'  => THUMBNAIL_METHOD_CROP,
));
 
Thumbnail::output($middleImage);

Последний пример стоит разобрать более подробно.

Вначале из исходного изображения вырезается центральный прямоугольник, стороны которого составляют ровно половину оригинала (50%). Затем, за второй проход из полученного промежуточного изображения создается обычная уменьшенная копия (стандартные размеры 150х150 пикселей). После этого полученное окончательное изображение отображается в браузере.

Заключение

Хотя задача создания миниатюр не самая сложная задача, решаемая разработчиками интернет-приложений, тем не менее, она не всегда решается на должном уровне и в полном объеме. В настоящей статье были разобраны все варианты создания миниатюр, кратко рассмотрены особенности работы с изображениями в PHP.

Методы загрузки и создания реализуют работу с изображениями только в форматах PNG и JPEG. Однако модуль расширяем, и добавить отсутствующую функциональность будет достаточно легко.

Как ни странно, но в богатой коллекции PEAR нет полноценных классов или методов для работы с миниатюрами, хотя существуют пакеты, реализующие отдельные методы обработки изображений (обрезки, масштабирования, поворота и т.д.) Однако описанный модуль может быть с легкостью интегрирован.

Исходные коды и демонстрационные файлы представлены в архиве на googlecode. На странице sourceforge старая (слегка подправленная) копия статьи со ссылками на примеры.

Благодарности

Автор искренне признателен Илье Лебедеву за реальную помощь в публикации данной статьи.


  • Закладки и социальные сети
  • Сохранить "Thumbnails: Теория и практика создания миниатюрных изображений" на del.icio.us
  • Сохранить "Thumbnails: Теория и практика создания миниатюрных изображений" на Digg
  • Сохранить "Thumbnails: Теория и практика создания миниатюрных изображений" на Furl
  • Сохранить "Thumbnails: Теория и практика создания миниатюрных изображений" на Reddit
  • Сохранить "Thumbnails: Теория и практика создания миниатюрных изображений" на Ask
  • Сохранить "Thumbnails: Теория и практика создания миниатюрных изображений" на BlinkList
  • Сохранить "Thumbnails: Теория и практика создания миниатюрных изображений" на blogmarks
  • Сохранить "Thumbnails: Теория и практика создания миниатюрных изображений" на Google
  • Сохранить "Thumbnails: Теория и практика создания миниатюрных изображений" на Ma.gnolia
  • Сохранить "Thumbnails: Теория и практика создания миниатюрных изображений" на Netscape
  • Сохранить "Thumbnails: Теория и практика создания миниатюрных изображений" на ppnow
  • Сохранить "Thumbnails: Теория и практика создания миниатюрных изображений" на Rojo
  • Сохранить "Thumbnails: Теория и практика создания миниатюрных изображений" на Shadows
  • Сохранить "Thumbnails: Теория и практика создания миниатюрных изображений" на Simpy
  • Сохранить "Thumbnails: Теория и практика создания миниатюрных изображений" на Socializer
  • Сохранить "Thumbnails: Теория и практика создания миниатюрных изображений" на Spurl
  • Сохранить "Thumbnails: Теория и практика создания миниатюрных изображений" на StumbleUpon
  • Сохранить "Thumbnails: Теория и практика создания миниатюрных изображений" на Tailrank
  • Сохранить "Thumbnails: Теория и практика создания миниатюрных изображений" на Technorati
  • Сохранить "Thumbnails: Теория и практика создания миниатюрных изображений" на Live Bookmarks
  • Сохранить "Thumbnails: Теория и практика создания миниатюрных изображений" на Wists
  • Сохранить "Thumbnails: Теория и практика создания миниатюрных изображений" на Yahoo! Myweb
  • Сохранить "Thumbnails: Теория и практика создания миниатюрных изображений" на BobrDobr
  • Сохранить "Thumbnails: Теория и практика создания миниатюрных изображений" на Memori
  • Сохранить "Thumbnails: Теория и практика создания миниатюрных изображений" на Faves
  • Сохранить "Thumbnails: Теория и практика создания миниатюрных изображений" на Favorites
  • Сохранить "Thumbnails: Теория и практика создания миниатюрных изображений" на Facebook
  • Сохранить "Thumbnails: Теория и практика создания миниатюрных изображений" на Newsvine
  • Сохранить "Thumbnails: Теория и практика создания миниатюрных изображений" на Yahoo! Bookmarks
  • Сохранить "Thumbnails: Теория и практика создания миниатюрных изображений" на Twitter
  • Сохранить "Thumbnails: Теория и практика создания миниатюрных изображений" на myAOL
  • Сохранить "Thumbnails: Теория и практика создания миниатюрных изображений" на Slashdot
  • Сохранить "Thumbnails: Теория и практика создания миниатюрных изображений" на Fark
  • Сохранить "Thumbnails: Теория и практика создания миниатюрных изображений" на RawSugar
  • Сохранить "Thumbnails: Теория и практика создания миниатюрных изображений" на LinkaGoGo
  • Сохранить "Thumbnails: Теория и практика создания миниатюрных изображений" на Mister Wong
  • Сохранить "Thumbnails: Теория и практика создания миниатюрных изображений" на Wink
  • Сохранить "Thumbnails: Теория и практика создания миниатюрных изображений" на BackFlip
  • Сохранить "Thumbnails: Теория и практика создания миниатюрных изображений" на Diigo
  • Сохранить "Thumbnails: Теория и практика создания миниатюрных изображений" на Segnalo
  • Сохранить "Thumbnails: Теория и практика создания миниатюрных изображений" на Netvouz
  • Сохранить "Thumbnails: Теория и практика создания миниатюрных изображений" на DropJack
  • Сохранить "Thumbnails: Теория и практика создания миниатюрных изображений" на Feed Me Links
  • Сохранить "Thumbnails: Теория и практика создания миниатюрных изображений" на funP
  • Сохранить "Thumbnails: Теория и практика создания миниатюрных изображений" на HEMiDEMi

Дискуссия

, 2008/10/03 06:33

очень плохое качество сжатия.

как исправить?

, 2008/10/03 21:06

Возможно Ваша версия PHP не поддерживает функцию imagecopyresampled. Возможно надо производить сжатие поэтапно. Возможно Вы пытаетесь сжать очень большое изображение.

Уточните, пожалуйста - Что значит плохое качество?

, 2008/11/06 15:36

2 метод на мой взгляд не очень хорош. На практике столкнулся с тем, что пользователи зачастую грузят изображения с размерами порядка 3000 на 4000 px. А превью нам надо получить 50х50. В итоге на изображении вообще не поймёшь ничего.

Я использую третий метод с небольшим (на мой взгляд) улучшением - для вертикально ориентированных изображений я помещаю вырезаемую область чуть выше (так, чтобы сверху оставалось 1/3 удаляемого, а снизу - 2/3) - обычно значимая часть изображения находится ближе к верху.

Другой способ вычисления размеров изображения - вырезание квадрата (или прямоугольника) из случайного места. Но чтобы было, откуда вырезать, изображение уменьшяется до размеров больших, чем превью, раза в три.

Например, есть картинка 1000 на 10000 px, нужно случайное превью 50х50 px. Уменьшаем исходное изображение так, чтобы меньшая сторона его стала 50*3=150px, а большая соответственно 1500. И из этой области уже случайно вырезаем нужный нам квадратик. Так мы будем уверены, что на нём будет что-то осмысленное.

, 2008/11/07 14:09

Хорошее замечание. Согласен с Вами, что очень большие изображения дадут трудноразличимые мелкие картинки. Попробуйте каскадный метод:

  • уменьшить в половину или втрое;
  • из полученного вырезать половину;
  • полученное уменьшить до 50х50.

Хотя примерно тоже самое делаете и Вы.

Вообще существует черновик второй версии, как статьи так и библиотеки (маленький класс вырос до целой библиотеки, только GD). Но необходимо время на шлифовку. Веб-разработка в настоящее время - хобби. А на хобби времени не хватает.

, 2008/12/05 12:33

Возник вопрос. В моем случае мне необходимо в обязательном порядке получить миниатюру строго заданного размера, поскольку на экран она выдается еще и с указанными в html параметрами width и height. Таким образом, если размер полученной миниатюры отличается от заданных, на экране она все равно изуродуется, даже если само изображение будет пропорциональным. Для себя ввел следующие принципы: 1.Произвожу первичное сравнение размеров изображения с заданными. 2.Вычисляю Ww и Hh. 3. Нахожу «коэффициент ужаса» -параметр, равный отношению max(Ww, Hh)/min(Ww, Hh). На мой взгляд этот параметр определяет степень несоответствия исходного и заданного изображений. Если этот коэффициент превышает 1.25 ,считаю, что без обрезки на экране в моем случае начнется ужас. 4. В этом случае перехожу к предварительной обрезке исходного изображения. Для этого умножаю заданные размеры на min(Ww, Hh). То есть фактически определяю рамку, одна из сторон которой надежно впишется в исходное изображение. Теперь эта рамка должна встать по центру и обрезать исходное изображение. 5.Обрезанный вариант уменьшаю обычным путем и сохраняю в файл. Так, на мой взгляд, должно получиться более-менее приемлемое решение проблемы.

Теперь вопрос: как можно с помощью библиотеки произвести предварительную обрезку исходного изображения по заданной рамке, центрировав ее относительно исходного изображения. Пожалуйста, если можно-код. В общем смысле я и сам понимаю:) Спасибо! Извините за туповатый вопрос.

, http://rapvokzal.com, 2009/01/25 13:02

Очень огорчило что ссылка http://phpmrtgadmin.sourceforge.net/download/demo/thumbnail/ не работает.

, 2009/01/27 15:53

Видимо на sourceforge запретили просмотр каталога. Изменил заключение статьи - добавил правильную ссылку на рабочие примеры и ссылку на архив.

, 2009/01/28 07:26

Всё равно ссылка не работает…

, 2009/01/28 08:41

поправил еще раз

, 2009/01/29 05:25

Спасибо большое! Скачалось :)

, 2009/04/03 10:14

Мне пришлось заняться созданием миниатюрной галлереи. Начал с того, что открыл справочник функций, попытался реализовать всё сам. Когда не вышло, нашёл вашу библиотеку и попытался воспользоваться написанным вами объектом. В обоих случаях происходит одно и то же. Картинка попадает на экран, при некоторых изменениях, но почему-то в виде текста побайтно (видна служебная информация файла jpg, а далее видимо коды пикселей, перекодированных в символы). В первозданном виде ошибка вылетает на 185й строке, не проходя условия функции !headers_sent(). Подскажите пожалуйста, как решить эту проблемму и с чего начинать. Видимо код модуля нельзя считать недействующим, поэтому проблемма в чём-то другом (возможно настройки сервера или совместимость версий).

, 2009/04/03 11:54

Библиотека корректно обработала отправку данных клиенту. Скорее всего Ваш скрипт уже отправил некие данные. Проверьте свои скрипты - возможно где-то присутствует пустая строка или пробел в начале. Удалите их - они препятствуют нормальному выводу картинки. Убедитесь, что Ваш скрипт не производит редирект, например header('Location: …');.

, 2009/05/05 17:05

В фотопечати есть такой термин - кадрирование. Это как раз то, чем мы тут занимаемся. Есть два варианта кадрирования - «кадр целиком» и «кадр в обрез». В первом случае (мы говорим о горизонтальных изображениях) это Ваш «метод максимального сжатия», во втором - некое подобие «фрагмент целого». В фотопечати в первом случае берется высота фотографии, пропорционально сжимается относительно этой высоты и засовывается в изображение необходимого формата (10х15 и тд). Во втором случае - за основу берется ширина фотографии и уменьшается пропорционально - соответственно при превышении необходимых на эскизе размеров фотография обрезается снизу и сверху.

, 2010/02/02 15:41

В связи с актуальностью материала перенес архив на гулокод http://code.google.com/p/php-funs/downloads/list. Демоверсия на sourceforge http://phpmrtgadmin.sourceforge.net/download/demo/thumbnail/theory.html.

articles/thumbnails.txt · Последние изменения: 2010/02/02 15:20 От Ildar Shaimordanov
GNU Free Documentation License 1.2 www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0