Просмотров: 4536

PHP - получение черно-белых изображений.

Универсальная функция для работы со всеми типами графических файлов (PNG, JPG, GIF) создает копию исходного цветного изображения в черно-белом варианте (градации серого). При работе с PNG сохраняет прозрачность. Использует библиотеку GD.

Пример:



Описание:

function image2GrayColor( $img_path, $output_path )
Первый аргумент - путь к файлу оригиналу. Второй - путь к файлу что должен получится на выходе (в серых тонах).

$type_img = exif_imagetype( $img_path );
exif_imagetype - определяем тип изображения. Плюсы: Данная функция работает быстрее чем image_type_to_mime_type Минусы: возвращаемый результат цифра (1-GIF, 2-JPEG, 3-PNG и пр.), что не совсем понятно в отличии от image_type_to_mime_type.
$gd = gd_info();
Возвращает информацию о текущей установленной библиотеке GD.

PNG

if( $type_img == 3 AND $gd['PNG Support'] == 1 )
Провереряем если тип изображения PNG и библиотека GD поддерживает работу с PNG файлами.

$img_png = imagecreatefromPNG( $img_path );
Создаём новое изображение из оригинального файла. Изображение не в привычном понимании этого слова в виде какого-нибудь файла-картинки, а говоря человеческим языком - виртуальной заготовки для последующих манипуляций.

imagesavealpha( $img_png, TRUE );
Позволяет сохранить изображение с информацией полного альфа-канала. Говоря проще сохраняет прозрачность, без этой строчки прозрачные фрагменты изображения станут черного цвета.

if( $img_png AND imagefilter( $img_png, IMG_FILTER_GRAYSCALE ))
А вот и главная операция по преобразованию цветов в серые оттенки. Для этого мы воспользуемся imagefilter - задав в качестве фильтра IMG_FILTER_GRAYSCALE. Все казалось бы просто, но не расслабляемся с JPG и GIF такой фокус не пройдет grin
@unlink( $output_path );
На всякий случай принудительно удаляем конечный файл.
imagepng( $img_png, $output_path );
Сохраняем наше "виртуальное" изображение в файл. Не забываем установить соответствующие права доступа на папку с файлами wink

imagedestroy( $img_png );
Уничтожаем наше "виртуальное" изображение нам оно больше не нужно, ведь мы сохранили результат нашей работы smile

JPG и GIF

if ( !$color_total = imagecolorstotal( $img_jpg )) {
$color_total = 256;
}
Так как палитра (количество цветов) у каждого изображения разное, узнаем это число при помощи imagecolorstotal.
imagetruecolortopalette( $img_jpg, FALSE, $color_total );
Конвертирует изображение true color в палитровое изображение. Второй параметр устанавливаем в FALSE так как цвет нам не нужен.

for( $c = 0; $c < $color_total; $c++ ) {    
$col = imagecolorsforindex( $img_jpg, $c );
$i = ( $col['red']+$col['green']+$col['blue'] )/3;
imagecolorset( $img_jpg, $c, $i, $i, $i );
}

Прогоняем файл по всей цветовой палитре. imagecolorsforindex возвращает цвет, содержащийся в индексе цветовой палитры изображения, в виде ассоциативного массива [red][green][blue] . А теперь немного магии grin Оттенок серого получается уравниванием R,G,B каналов. Чтобы привести изображение к оттенкам серого мы должны установить их на среднее число насыщения каналов (переменная $i). Ну а теперь перезаписываем наш многострадальный индекс цветовой палитры в градации серого - imagecolorset.

Функция image2GrayColor()


function image2GrayColor( $img_path, $output_path ){

$type_img = exif_imagetype( $img_path );
$gd = gd_info();

if( $type_img == 3 AND $gd['PNG Support'] == 1 ){

$img_png = imagecreatefromPNG( $img_path );
imagesavealpha( $img_png, TRUE );

if( $img_png AND imagefilter( $img_png, IMG_FILTER_GRAYSCALE )) {
@unlink( $output_path );
imagepng( $img_png, $output_path );
}
imagedestroy( $img_png );
}
elseif( $type_img == 2 AND $gd['JPG Support'] == 1 ) {

$img_jpg = imagecreatefromJPEG( $img_path );
if ( !$color_total = imagecolorstotal( $img_jpg )) {
$color_total = 256;
}
imagetruecolortopalette( $img_jpg, FALSE, $color_total );

for( $c = 0; $c < $color_total; $c++ ) {
$col = imagecolorsforindex( $img_jpg, $c );
$i = ( $col['red']+$col['green']+$col['blue'] )/3;
imagecolorset( $img_jpg, $c, $i, $i, $i );
}
@unlink( $output_path );
imagejpeg( $img_jpg, $output_path );
imagedestroy( $img_jpg );
}
elseif( $type_img == 1 AND $gd['GIF Create Support'] == 1 ) {

$img_gif = imagecreatefromGIF( $img_path );
if ( !$color_total = imagecolorstotal( $img_gif )) {
$color_total = 256;
}
imagetruecolortopalette( $img_gif, FALSE, $color_total );

for( $c = 0; $c < $color_total; $c++ ) {
$col = imagecolorsforindex( $img_gif, $c );
$i = ( $col['red']+$col['green']+$col['blue'] )/3;
imagecolorset( $img_gif, $c, $i, $i, $i );
}
@unlink( $output_path );
imagegif( $img_gif, $output_path );
imagedestroy( $img_gif );
}
else{
return 'Error: This format is not supported.';
}
}


Скачать.

Готового решения не нашел пришлось написать эту функцию smile Буду раз если кому нибудь пригодится.

Дополнительная информация по теме:
]]>twitter.com Google Buzz google.com bobrdobr.ru del.icio.us technorati.com linkstore.ru news2.ru rumarkz.ru memori.ru moemesto.ru]]>



Эта запись опубликована: Четверг, 27 ноября 2008 в рубрике PHP.

7 комментариев

Следите за комментариями по RSS
  1. +1

  2. однозначно must have

  3. Приму на заметку, а вообще неплохо бы сделать шикарный класс для работы с изображениями.

  4. Respect, good style!

  5. red faceну не можу я понять как правильно поставить в функцию ссылки на фотку и конечную фотку....

    $img_path="http://image.azartstyle.com/logo_yes/20100502114958.jpg";

    $output_path="http://image.azartstyle.com/logo_yes/20100502114958.jpg";

    $image=image2GrayColor ($img_path, $output_path);

    echo "$image";

  6. Штембуляк Андрей aka Zmei

    Костя - я модернизировал алгоритм, прочитать можно в этой статье - http://zmei.name/page/modifikacija-image2graycolor

    Во вторых, на вскидку - надо использовать пути файловой системы - копать в этом направлении - $_SERVER['DOCUMENT_ROOT'].'/pics/example.jpg';

  7. Спасибо большое! Лучшая на данный момент функция подобного рода, которую я нашел. Была проблема: сервер не поддерживал функцию "exif_imagetype", тогда я сравнивал через расширение оригинального файла(расширение получал через pathinfo). Я понимаю что это есть не самый лучший способ, может быть подскажите другой?

Оставьте комментарий!

Не регистрировать/аноним

Используйте нормальные имена. Ваш комментарий будет опубликован после проверки.

Зарегистрировать/комментатор

Для регистрации укажите свой действующий email и пароль. Связка email-пароль позволяет вам комментировать и редактировать данные в вашем персональном аккаунте, такие как адрес сайта, ник и т.п. (Письмо с активацией придет в ящик, указанный при регистрации)

grin LOL cheese smile wink smirk rolleyes confused surprised big surprise tongue laugh tongue rolleye tongue wink raspberry blank stare long face ohh grrr gulp oh oh downer red face sick shut eye hmmm mad angry zipper kiss shock cool smile cool smirk cool grin cool hmm cool mad cool cheese vampire snake excaim question

(обязательно)