The employer
Новичок
Привет всем.
К сожалению, сейчас загрузка по работе превысила все разумные пределы, так что продвигается дело не так быстро как хотелось бы. Но очередной кусок готов, я начинаю его выыкладывать по частям - он довольно объемный.
Вот что будет выложено за пару дней:
-~{}~ 15.07.09 11:40:
Работа с цветом и прозрачностью для изображений с палитрой
Общие принципы
Описание цвета
Цвет пикселя в изображениях с палитрой определяется цветом той ячейки
палитры, на которую ссылается данный пиксель.
Цвет в ячейке палитры описывается тремя значениями для красной, зеленой
и синей компонент (RGB). Каждая компонента может иметь значение от 0 до 255,
отражающее яркость соответствующего цвета в данной точке изображения.
Нулевая яркость говорит о том, что этот цвет просто отсутствует.
Таким образом, набор значений RGB (0,0,0) соответствует черному цвету точки,
RGB (255,0,0) - красному, RGB (0,255,0) - зеленому, RGB (0,0,255) - синему,
RGB (255,255,255) - белому цвету точки.
Описание прозрачности
Прозрачность в палитре описывается сразу двумя способами.
Во-первых, в каждой ячейке хранится степень прозрачности для пикселей,
ссылающихся на эту ячейку. Значение 0 соответствует полной непрозрачности,
значение 127 соответствует полной прозрачности.
Во-вторых, в палитре фиксируется номер ячейки, которая назначена "прозрачной".
Все пиксели изображения, ссылающиеся на данную ячейку палитры,
будут полностью прозрачными - независимо от установленных значений RGB.
По умолчанию, при создании нового изображения, ни одна ячейка палитры
не назначена прозрачной.
В палитре может быть только одна ячейка с признаком "прозрачный цвет".
При попытке сделать прозрачной еще одну ячейку - именно она станет прозрачной,
а предыдущая это свойство потеряет.
Поведение при экспорте в различные форматы
При сохранении изображения в формат, поддерживающий альфа-канал (PNG), каждой
точке изображения будет сопоставлен уровень прозрачности той ячейки палитры,
из которой берется цвет данной точки. Интересно, что при этом не нужно
вызывать функцию imagesavealpha. Более того, вызов этой функции с параметром
false, запрещающим сохранение альфа-канала, будет проигнорирован, и альфа-канал
для результирующей PNG-картинки будет создан и сохранен.
При сохранении изображения в формат GIF - будет учтено только свойство
"прозрачный цвет". Если в палитре есть "прозрачная" ячейка - то все ссылающиеся
на нее пикселы будут полностью прозрачными. Степень прозрачности, установленная
для всех прочих ячеек палитры, будет проигнорирована.
При экспорте в JPEG любая информация о прозрачности будет проигнорирована.
Размер палитры
Во внутреннем представлении GD, каждое изображение с палитрой всегда содержит
полную палитру размером 256 ячеек. При создании изображения все ячейки палитры
заполнены черным непрозрачным цветом.
Однако, не всем изображениям необходимы все 256 ячеек - например, палитре
для черно-белых изображений достаточно иметь палитру всего лишь из двух ячеек.
Поэтому бИблиотека GD "притворяется", будто у нее палитра может иметь
разное число ячеек, и будто бы при создании нового изображения в его палитре
нет ни одной ячейки.
На самом деле, библиотека просто ведет счетчик занятых ячеек палитры. При
распределении новой ячейки (об этой операции написано в следующем разделе)
библиотека увеличивает на единицу счетчик занятых ячеек.
Получить текущее значение счетчика занятых ячеек можно при помощи функции
imagecolorstotal:
Код:
Кстати, для truecolor-изображений данная функция всегда возвращает ноль.
Управление составом палитры при помощи стандартных средств GD
Распределение ячейки
Чтобы добавить цвет в палитру, нужно воспользоваться функцией
imagecolorallocate либо функцией imagecolorallocatealpha. Первая функция
позволяет задать только компоненты RGB для новой ячейки палитры, вторая
помимо этого позволяет задать степень прозрачности.
Код:
Этот код добавил в палитру два цвета - черный и при этом полностью прозрачный,
и полностью непрозрачный красный.
Вызов imagecolorallocate( $img, $r, $g, $b ) эквивалентен вызову
imagecolorallocatealpha( $img, $r, $g, $b, 0 ).
Важный момент - эти функции не пытаются определить, есть ли в палитре
ячейка, которой уже назначен такой же цвет. В любом случае будет задействована
новая ячейка палитры.
На случай, если хочется по-максимуму использовать существующие цвета палитры,
добавляя новые ячейки лишь при необходимости, в GD предусмотрены функции
imagecolorresolve и imagecolorresolvealpha. Эти функции пытаются отыскать
в палитре ячейку, содержащую те же самые значения RGB и альфа-канала,
которые переданы им в качестве параметров. Если удается отыскать такую ячейку,
функции возвращают ее номер; если такой ячейки не находится - функции добавляют
в палитру еще одну ячейку, устанавливают ей соответствующие параметры цвета
и прозрачности и возвращают номер добавленной ячейки.
Вызов imagecolorresolve( $img, $r, $g, $b ) эквиваелентен вызову
imagecolorresolvealpha( $img, $r, $g, $b, 0 ).
Код:
В результате выполнения этого кода переменная $p1 будет равна нулю,
переменная $p2 будет равна двум, $p3 - трем. Значение переменной
$new_foreground будет равно значению переменной $foreground,
в то же время значение переменной $new_background не будет равно
значению $background.
Освобождение ячейки
Освобождение ячейки в палитре не означает очистки описания цвета в палитре
и не приводит к уменьшению счетчика занятых ячеек. Единственный эффект
от освобождения ячейки состоит в том, что при следующем распределении цвета
функциями imagecolorallocate* эта ячейка будет занята новым описанием цвета
и значение счетчика занятых ячеек увеличено не будет.
Освобождение ячейки из палитры производится при помощи функции
imagecolordeallocate. В качестве параметров функции передается ссылка
на изображение и номер той ячейки в палитре, которую следует освободить.
Код:
В результате выполнения этого кода переменные $p1, $p1 и $p3 будут равны двум.
Значение переменной $new_foreground будет равно значению переменной $foreground,
Использование "нераспределенных" ячеек палитры
Как мы уже знаем, внутри GD всегда присутствует полная палитра на 256 ячеек,
все ячейки которой по умолчанию содержат черный непрозрачный цвет.
Библиотека ведет счетчик задействованных ячеек, причем предполагает
что пропусков в ряду занятых ячеек нет. То есть, если вы распределили 200 ячеек,
а затем 150 ячеек освободили - библиотека по прежнему будет считать что все
200 ячеек используются. Соответственно, вы можете спокойно использовать
в теле изображения пиксели, ссылающиеся на "освобожденные" ячейки.
Проблемы будут при экспорте изображения в формат PNG - пиксели, ссылающиеся
на "нераспределенные" ячейки, всегда будут отображаться черным
непрозрачным цветом. В форматах GIF и JPEG эти пикселы будут отображаться
теми цветами, которые были назначены соответствующим ячейкам до их освобождения,
причем свойство "прозрачный цвет" у освобожденных ячеек тоже сохранится.
Интересно, что если вы сохраните изображение с нераспределенными ячейками
палитры в формате gd2, а затем снова импортируете его в бибилиотеку - то после
этой операции экспорт в формат PNG пройдет нормально, с полным сохранением
информации о цвете и прозрачности в нераспределенных ячейках.
К сожалению, сейчас загрузка по работе превысила все разумные пределы, так что продвигается дело не так быстро как хотелось бы. Но очередной кусок готов, я начинаю его выыкладывать по частям - он довольно объемный.
Вот что будет выложено за пару дней:
PHP:
Работа с цветом и прозрачностью для изображений с палитрой
Общие принципы
Описание цвета
Описание прозрачности
Поведение при экспорте в различные форматы
Размер палитры
Управление составом палитры при помощи стандартных средств GD
Распределение ячейки
Освобождение ячейки
Использование "нераспределенных" ячеек палитры
Управление содержимым палитры при помощи стандартных средств GD
Получение цвета в ячейке
Изменение цвета в ячейке
Получение номера прозрачной ячейки
Назначение прозрачной ячейки
Поиск ячейки с определенным цветом
Поиск точного соответствия
Поиск ближайшего цвета
Чего GD делать не дает, и как заставить ее вести себя прилично
Получение палитры в бинарном виде
Формат палитры
Замена палитры изображения
Недостающие функции библиотеки GD
Функция, позволяющая отличить изображения с палитрой от всего прочего
Функция получения палитры в виде массива
Функция прямой записи палитры из массива в изображение
Функция прямой установки количества цветов в палитре
Функция прямой установки цвета в ячейке палитры
Работа с цветом и прозрачностью для изображений с палитрой
Общие принципы
Описание цвета
Цвет пикселя в изображениях с палитрой определяется цветом той ячейки
палитры, на которую ссылается данный пиксель.
Цвет в ячейке палитры описывается тремя значениями для красной, зеленой
и синей компонент (RGB). Каждая компонента может иметь значение от 0 до 255,
отражающее яркость соответствующего цвета в данной точке изображения.
Нулевая яркость говорит о том, что этот цвет просто отсутствует.
Таким образом, набор значений RGB (0,0,0) соответствует черному цвету точки,
RGB (255,0,0) - красному, RGB (0,255,0) - зеленому, RGB (0,0,255) - синему,
RGB (255,255,255) - белому цвету точки.
Описание прозрачности
Прозрачность в палитре описывается сразу двумя способами.
Во-первых, в каждой ячейке хранится степень прозрачности для пикселей,
ссылающихся на эту ячейку. Значение 0 соответствует полной непрозрачности,
значение 127 соответствует полной прозрачности.
Во-вторых, в палитре фиксируется номер ячейки, которая назначена "прозрачной".
Все пиксели изображения, ссылающиеся на данную ячейку палитры,
будут полностью прозрачными - независимо от установленных значений RGB.
По умолчанию, при создании нового изображения, ни одна ячейка палитры
не назначена прозрачной.
В палитре может быть только одна ячейка с признаком "прозрачный цвет".
При попытке сделать прозрачной еще одну ячейку - именно она станет прозрачной,
а предыдущая это свойство потеряет.
Поведение при экспорте в различные форматы
При сохранении изображения в формат, поддерживающий альфа-канал (PNG), каждой
точке изображения будет сопоставлен уровень прозрачности той ячейки палитры,
из которой берется цвет данной точки. Интересно, что при этом не нужно
вызывать функцию imagesavealpha. Более того, вызов этой функции с параметром
false, запрещающим сохранение альфа-канала, будет проигнорирован, и альфа-канал
для результирующей PNG-картинки будет создан и сохранен.
При сохранении изображения в формат GIF - будет учтено только свойство
"прозрачный цвет". Если в палитре есть "прозрачная" ячейка - то все ссылающиеся
на нее пикселы будут полностью прозрачными. Степень прозрачности, установленная
для всех прочих ячеек палитры, будет проигнорирована.
При экспорте в JPEG любая информация о прозрачности будет проигнорирована.
Размер палитры
Во внутреннем представлении GD, каждое изображение с палитрой всегда содержит
полную палитру размером 256 ячеек. При создании изображения все ячейки палитры
заполнены черным непрозрачным цветом.
Однако, не всем изображениям необходимы все 256 ячеек - например, палитре
для черно-белых изображений достаточно иметь палитру всего лишь из двух ячеек.
Поэтому бИблиотека GD "притворяется", будто у нее палитра может иметь
разное число ячеек, и будто бы при создании нового изображения в его палитре
нет ни одной ячейки.
На самом деле, библиотека просто ведет счетчик занятых ячеек палитры. При
распределении новой ячейки (об этой операции написано в следующем разделе)
библиотека увеличивает на единицу счетчик занятых ячеек.
Получить текущее значение счетчика занятых ячеек можно при помощи функции
imagecolorstotal:
Код:
PHP:
$palette_size = imagecolorstotal( $img );
Управление составом палитры при помощи стандартных средств GD
Распределение ячейки
Чтобы добавить цвет в палитру, нужно воспользоваться функцией
imagecolorallocate либо функцией imagecolorallocatealpha. Первая функция
позволяет задать только компоненты RGB для новой ячейки палитры, вторая
помимо этого позволяет задать степень прозрачности.
Код:
PHP:
$background = imagecolorallocatealpha( $img, 0, 0, 0, 127 );
$foreground = imagecolorallocate( $img, 255, 0, 0 );
и полностью непрозрачный красный.
Вызов imagecolorallocate( $img, $r, $g, $b ) эквивалентен вызову
imagecolorallocatealpha( $img, $r, $g, $b, 0 ).
Важный момент - эти функции не пытаются определить, есть ли в палитре
ячейка, которой уже назначен такой же цвет. В любом случае будет задействована
новая ячейка палитры.
На случай, если хочется по-максимуму использовать существующие цвета палитры,
добавляя новые ячейки лишь при необходимости, в GD предусмотрены функции
imagecolorresolve и imagecolorresolvealpha. Эти функции пытаются отыскать
в палитре ячейку, содержащую те же самые значения RGB и альфа-канала,
которые переданы им в качестве параметров. Если удается отыскать такую ячейку,
функции возвращают ее номер; если такой ячейки не находится - функции добавляют
в палитру еще одну ячейку, устанавливают ей соответствующие параметры цвета
и прозрачности и возвращают номер добавленной ячейки.
Вызов imagecolorresolve( $img, $r, $g, $b ) эквиваелентен вызову
imagecolorresolvealpha( $img, $r, $g, $b, 0 ).
Код:
PHP:
$img = imagecreate( 100, 100 );
$p1 = imagecolorstotal( $img );
$background = imagecolorallocatealpha( $img, 0, 0, 0, 127 );
$foreground = imagecolorallocate( $img, 255, 0, 0 );
$p2 = imagecolorstotal( $img );
$new_foreground = imagecolorresolve( $img, 255, 0, 0 );
$new_background = imagecolorresolve( $img, 0, 0, 0 );
$p3 = imagecolorstotal( $img );
переменная $p2 будет равна двум, $p3 - трем. Значение переменной
$new_foreground будет равно значению переменной $foreground,
в то же время значение переменной $new_background не будет равно
значению $background.
Освобождение ячейки
Освобождение ячейки в палитре не означает очистки описания цвета в палитре
и не приводит к уменьшению счетчика занятых ячеек. Единственный эффект
от освобождения ячейки состоит в том, что при следующем распределении цвета
функциями imagecolorallocate* эта ячейка будет занята новым описанием цвета
и значение счетчика занятых ячеек увеличено не будет.
Освобождение ячейки из палитры производится при помощи функции
imagecolordeallocate. В качестве параметров функции передается ссылка
на изображение и номер той ячейки в палитре, которую следует освободить.
Код:
PHP:
$img = imagecreate( 100, 100 );
$background = imagecolorallocatealpha( $img, 0, 0, 0, 127 );
$foreground = imagecolorallocate( $img, 255, 0, 0 );
$p1 = imagecolorstotal( $img );
imagecolordeallocate( $img, $foreground );
$p2 = imagecolorstotal( $img );
$new_foreground = imagecolorallocate( $img, 255, 255, 255 );
$p3 = imagecolorstotal( $img );
Значение переменной $new_foreground будет равно значению переменной $foreground,
Использование "нераспределенных" ячеек палитры
Как мы уже знаем, внутри GD всегда присутствует полная палитра на 256 ячеек,
все ячейки которой по умолчанию содержат черный непрозрачный цвет.
Библиотека ведет счетчик задействованных ячеек, причем предполагает
что пропусков в ряду занятых ячеек нет. То есть, если вы распределили 200 ячеек,
а затем 150 ячеек освободили - библиотека по прежнему будет считать что все
200 ячеек используются. Соответственно, вы можете спокойно использовать
в теле изображения пиксели, ссылающиеся на "освобожденные" ячейки.
Проблемы будут при экспорте изображения в формат PNG - пиксели, ссылающиеся
на "нераспределенные" ячейки, всегда будут отображаться черным
непрозрачным цветом. В форматах GIF и JPEG эти пикселы будут отображаться
теми цветами, которые были назначены соответствующим ячейкам до их освобождения,
причем свойство "прозрачный цвет" у освобожденных ячеек тоже сохранится.
Интересно, что если вы сохраните изображение с нераспределенными ячейками
палитры в формате gd2, а затем снова импортируете его в бибилиотеку - то после
этой операции экспорт в формат PNG пройдет нормально, с полным сохранением
информации о цвете и прозрачности в нераспределенных ячейках.