Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
PHP 5/6. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В. MySQL на примерах. Авторы: Кузнецов М.В., Симдянов И.В. Самоучитель MySQL 5. Авторы: Кузнецов М.В., Симдянов И.В. MySQL 5. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В. Самоучитель PHP 5 / 6 (3 издание). Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум PHP

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Поворот изображения c помощью GD - прозрачность???
 
 автор: xxxLEOxxx   (17.04.2009 в 15:55)   письмо автору
 
 

Здравствуйте.

Я пишу функцию поварачивающую изображение на определенный угол. Пользуюсь GD.


$rotate = imagerotate($image, 10, $trans_color); - функция отлично поворачивает изображение, но области фона полученные при повороте заливаются черным цветом(ну вообщем то любым по желанию)

imagecolortransparent($image, $trans_color); - почему то не хочет стирать цвет и делать изображение прозрачным.

Кто может помочь?

  Ответить  
 
 автор: sim5   (17.04.2009 в 16:11)   письмо автору
 
   для: xxxLEOxxx   (17.04.2009 в 15:55)
 

А когда вы определяете цвет прозрачный?

  Ответить  
 
 автор: xxxleoxxx   (17.04.2009 в 17:07)   письмо автору
 
   для: sim5   (17.04.2009 в 16:11)
 

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


function free_rotate($id_user, $id_project)
    {
        $filename = "users/$id_user/project_$id_project/tmp/work_photo.jpg";
        $degrees = $_GET['rotate'];
        $source = imagecreatefromjpeg($filename);
        
        //Рассчитываем ширину и высоту
        $width_transparent = imagesx($source);
        $height_transparent = imagesy($source);
        
        
        //Создаем новое изображение для прозрачности
        $image_transparent = imagecreatetruecolor($width_transparent, $height_transparent);
        $trans_color = imagecolorallocate($image_transparent, 255, 255, 255);
        imagefill($image_transparent, 0, 0, $trans_color);
        
        
        //Копируем старое изображение, на новое, с прозрачностью фона
        imagecopyresampled($image_transparent,$source,0,0,0,0,$width_transparent,$height_transparent,$width_transparent,$height_transparent);
        
        
        $rotate = imagerotate($image_transparent, $degrees, $trans_color);
        
        
        imagecolortransparent($image_transparent, $trans_color);
        
        
        imagepng($rotate, "users/$id_user/project_$id_project/tmp/work_photo.png", 9);
        //imagedestroy($source);
        //imagedestroy($rotate);
        //echo "<script language='javascript'>
        //        document.location = 'work_zone.php';
        //    </script>";

  Ответить  
 
 автор: sim5   (17.04.2009 в 17:14)   письмо автору
 
   для: xxxleoxxx   (17.04.2009 в 17:07)
 

Объявлять прозрачным цвет нужно перед его использованием, а не после того, как вы им отрисовали.

  Ответить  
 
 автор: xxxleoxxx   (17.04.2009 в 17:49)   письмо автору
 
   для: sim5   (17.04.2009 в 17:14)
 

Переставил в самое начало, по прежнему белый фон

//Создаем новое изображение для прозрачности
        $image_transparent = imagecreatetruecolor($width_transparent, $height_transparent);
        $trans_color = imagecolorallocate($image_transparent, 255, 255, 255);
        imagecolortransparent($image_transparent, $trans_color);
        imagefill($image_transparent, 0, 0, $trans_color);

  Ответить  
 
 автор: sim5   (17.04.2009 в 18:57)   письмо автору
 
   для: xxxleoxxx   (17.04.2009 в 17:49)
 

<?
//создаем произвольное изображение
$im imagecreatetruecolor(300,300);
//заливаем произвольным цветом
$col imagecolorallocate($im125178240);
imagefill($im00$col);
//создаем прозрачное изображение
$ims imagecreatetruecolor(300,300);
//цвет заливки прозрачный
$black imagecolorallocate($im000);
imagecolortransparent($ims$black);
imagefill($ims00$black);
//накладываем прозрачное изображение на первое
imagecopymerge($im$ims0000300300100);
//смотрим результат
header ("Content-type: image/png");
imagepng($im);
?>

И.... Если повернуть изображение, то оно будет вписано в рамку, которая никак не будет соответствовать исходному размеру изображения, а это что значит?

  Ответить  
 
 автор: xxxleoxxx   (17.04.2009 в 20:42)   письмо автору
 
   для: sim5   (17.04.2009 в 18:57)
 

Извините не очень понимаю к чему все... Что это значит?

  Ответить  
 
 автор: sim5   (17.04.2009 в 21:36)   письмо автору
 
   для: xxxleoxxx   (17.04.2009 в 20:42)
 

Это значит - нарисовать прозрачным и наложить на непрозрачное. Это пример, или вам более расширенные комментарии нужны?

  Ответить  
 
 автор: xxxleoxxx   (17.04.2009 в 22:57)   письмо автору
 
   для: sim5   (17.04.2009 в 21:36)
 

Если не затруднит нужны более расширенные коментарии.

Как я могу нарисовать прозрачным если изначально беру фотографию из jpeg?

В приведенном выше коде, уже пытался создовать изображение с прозрачным фоном, копировать на него изображение взятое из jpeg, а затем поворачивать его указывая в качестве фонового цвета для rotate прозрачность.

Если нарисовать прозрачным и наложить на непрозрачное, вроде как в итоге получится непрозрачное?

  Ответить  
 
 автор: sim5   (18.04.2009 в 06:46)   письмо автору
 
   для: xxxleoxxx   (17.04.2009 в 22:57)
 

>Как я могу нарисовать прозрачным если изначально беру фотографию из jpeg?

А вы разве исходный jpeg делаете непрозрачным? Вы хоть свой код можете проанализировать, что вы в нем пытаетесь делать? Или мне это сделать?

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

  Ответить  
 
 автор: xxxleoxxx   (18.04.2009 в 23:28)   письмо автору
 
   для: sim5   (18.04.2009 в 06:46)
 

Вы уж извините я еще не профи, только учусь.

Давайте на примере

<?php
header
('Content: image/png');


        
$filename "1.jpg";
        
$degrees $_GET['rotate'];
        
$source imagecreatefromjpeg($filename);
        
$trans_color imagecolorallocate($source255255255);
        
imagecolortransparent($source$trans_color);
        
$rotate imagerotate($source15$trans_color);
        
        
        
//создаем произвольное изображение 
        
$im imagecreatetruecolor(3000,3000); 
        
//заливаем произвольным цветом 
        
$col imagecolorallocate($im125178240); 
        
imagefill($im00$col);    
        
        
imagecopymerge($im$rotate000030003000100);
        
        
imagepng($im);
        
?>


Я так понимаю должно быть повернуто изображние 1.jpg на 15 градусов => затем создаю подложку(непрозрачную) что бы посмотреть прозрачно ли изображение = > но увы...

Кстати я еще прочел, что у imagerotate есть параметр отвечающий за прозрачность ignore_transparent, добавленный с версии 5,1... Может дело в нем?

  Ответить  
 
 автор: sim5   (19.04.2009 в 07:03)   письмо автору
 
   для: xxxleoxxx   (18.04.2009 в 23:28)
 

Вы опять повторяете ошибку касающуюся размеров подложки - с чего вы вдруг решили, что она должна быть 3000х3000? А не многовато для дисплея? Любое изображение всегда вписано в прямоугольник, вот его нужно и получать после поворота изображения. Если вы хотите вписать в заведомо установленные размеры, то, хотя бы для приличия, проверяйте - войдет ли в них изображение после поворота.
<?
$filename 
"1.jpg";
//получаем угол 
$degrees intval($_GET['rotate']);
$im imagecreatefromjpeg($filename);
//этим цветом заливаем
$col imagecolorallocate($im125174240);
//поворот изображения
//заметьте, что четвертый параметр функции проигнорирован
//просто в нашем случае его можно и опустить
$im imagerotate($im$degrees$col);
//и вот только теперь мы можем узнать размеры нужной нам подложки
//создаем ее по новым размерам исходного изображения (после поворота)
$ims imagecreatetruecolor(imagesx($im),imagesy($im));
//устанавливаем цвет кисти для подложки (ранее определенный уже)
//и указываем его как прозрачный
imagecolortransparent($ims$col);
//заливаем подложку прозрачным цветом
imagefill($ims00$col);
//объеденяем изображение с подложкой
imagecopymerge($ims$im0000imagesx($im), imagesy($im), 100);
//выводим результат
header ("Content-type: image/png");
imagepng($ims);
//освобождаем память
imagedestroy($im);
imagedestroy($ims);
?>

Смотреть работу этого кода нужно в браузере, например, Опера. В IE вы не увидите прозрачную подложку с цветом, который определен в примере. Если хотите, чтобы она была прозрачна и в IE, то выбирайте прозрачным цветом черный цвет.

  Ответить  
 
 автор: xxxleoxxx   (19.04.2009 в 09:15)   письмо автору
 
   для: sim5   (19.04.2009 в 07:03)
 

Спасибо Вам большое, здесь все понял.

Последние пару вопросов. Почему при сохранении в png вместо прозрачности появляется белый фон, все таки конечная цель моих мучений - сохранение в png?

И как можно бороться с голубой каемкой появлющейся по краяям изображения?

  Ответить  
 
 автор: sim5   (19.04.2009 в 09:27)   письмо автору
 
   для: xxxleoxxx   (19.04.2009 в 09:15)
 

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

Что касается каемки, то это проблема. Дело в том, что при повороте, слиянии изображения, цвета будут интерполированы, и у границы накладываемого изображения появится цвет с индексом отличным от цвета назначенного подложке (в данном примере голубуго). Проще не каемку убрать, а назначать цвет прозрачности подложке такой, который будет иметь фон, на который вы и будете накладывать развернутое изображение с подложкой. Тогда каемка будет сливаться с фоном.

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

  Ответить  
 
 автор: Trianon   (19.04.2009 в 09:52)   письмо автору
 
   для: sim5   (19.04.2009 в 09:27)
 

>Учтите еще следующее - если в изоражении будут присутствовать цвета, индексы которых будут равны цвету, который установлен как прозрачный, то и они станут прозрачными.

А откуда в полноцветных изображениях индексы?

  Ответить  
 
 автор: sim5   (19.04.2009 в 13:09)   письмо автору
 
   для: Trianon   (19.04.2009 в 09:52)
 

Trianon не запутывайте молодому человеку извилины. :)) Индекс цвета (не путать с индексированной палитрой) - это номер цвета пикселя, кой термин применяется в GD.

  Ответить  
 
 автор: Trianon   (19.04.2009 в 13:16)   письмо автору
 
   для: sim5   (19.04.2009 в 13:09)
 

Я спросил Вас, а не молодого человека.
Термин "индекс цвета" вне контекста палитры мне неизвестен.
В описании GD я его тоже не нашел.

сдается мне, мозги пудрите извилины запутывайте Вы.

  Ответить  
 
 автор: sim5   (19.04.2009 в 13:35)   письмо автору
 
   для: Trianon   (19.04.2009 в 13:16)
 

imagecolorat - получает индекс цвета пиксела.

Описание
int imagecolorat (resource image, int x, int y)

Возвращает индекс цвета пиксела в специфицированном месте в изображении image.

и т.д....

  Ответить  
 
 автор: Trianon   (19.04.2009 в 13:56)   письмо автору
 
   для: sim5   (19.04.2009 в 13:35)
 

imagecolorat — Get the index of the color of a pixel
Описание
int imagecolorat ( resource $image , int $x , int $y )

Returns the index of the color of the pixel at the specified location in the image specified by image .

If PHP is compiled against GD library 2.0 or higher and the image is a truecolor image, this function returns the RGB value of that pixel as integer. Use bitshifting and masking to access the distinct red, green and blue component values:

так что не надо ляля.

  Ответить  
 
 автор: sim5   (19.04.2009 в 14:23)   письмо автору
 
   для: Trianon   (19.04.2009 в 13:56)
 

Не я придумал это GD. Почитайте о других функциях.

  Ответить  
 
 автор: xxxleoxxx   (19.04.2009 в 10:45)   письмо автору
 
   для: sim5   (19.04.2009 в 09:27)
 

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


С каемкой грустно конечно. Заранее не известно какой будет фон, и он может быть неоднородным, а может быть вообще другой фотографией.

  Ответить  
 
 автор: sim5   (19.04.2009 в 15:28)   письмо автору
 
   для: xxxleoxxx   (19.04.2009 в 10:45)
 

Было бы лучше в плане "каемочек", если бы определять прозрачные области не по цвету, а по альфа-каналу. Но формат PNG не может сохранять в себе такой канал, это может быть в TGA формате, например.
А то, что цвет неодонородный, это проблемы - "дырки" на изображении могут быть.

  Ответить  
 
 автор: xxxleoxxx   (19.04.2009 в 15:34)   письмо автору
 
   для: sim5   (19.04.2009 в 15:28)
 

Ну насчет дырок я уже думал, выберу цвет для прозрачности редкий, какой нибудь едко фиолетовый.

В принципе все понятно. Но как из полученного в ходе беседы кода сохранить эту картинку в png, что бы в фотошопе было видно что фона нету.

  Ответить  
 
 автор: sim5   (19.04.2009 в 15:51)   письмо автору
 
   для: xxxleoxxx   (19.04.2009 в 15:34)
 

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

  Ответить  
 
 автор: xxxleoxxx   (19.04.2009 в 19:45)   письмо автору
 
   для: sim5   (19.04.2009 в 15:51)
 

Картинки конечно для веба. Зачем нужна... Долго описывать. Если в кратце то нужно реализовать что то вроде слоев в фотошопе, после поворота картинки. Т.е. что бы после поворота эту картинку можно было потаскать по фону(причем заранее не известно что это будет за фон, кому то однородный синий понравится, а кто-то картинку с травой или деревьями захочет) и выбрать ее положение. Перетаскивание организовано на jquery, работает на ура, но только если файл видится прозрачным в фотошопе.

  Ответить  
 
 автор: sim5   (19.04.2009 в 20:18)   письмо автору
 
   для: xxxleoxxx   (19.04.2009 в 19:45)
 

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

  Ответить  
 
 автор: xxxleoxxx   (19.04.2009 в 22:11)   письмо автору
 
   для: sim5   (19.04.2009 в 20:18)
 

Спасибо Вам огромное за помощь.

Вот нашел один урок с текстом - в результате него получается то о чем я говорил. Даже в PS открываешь видны и шашечки и прозрачность., может полезно будет :))) - http://visionmasterdesigns.com/tutorial-convert-text-into-transparent-png-image-using-php/

А на счет каемки придумал такую штуку. Мне тут надо было еще градиент сделать, так сказать красивые растворяющиеся каемочки. Такой функции в GD вроде нету, сделал нехитрые расчеты и написал цикл, которые рисует 4 линии шириной в 1 пиксель(по краям фото) каждый раз с меньшей прозрачностью. Поскольку фотки обрабатываю довольно крупные (3000 х 3000)
можно сделать каемку в пикселей 25 - за 25 шагов получается довольно мягкий переход.

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

Единственная проблема, с которой я пока не могу справиться так это долгое выполнение, мне даже выдало ошибку о том что превышен интервал в 30 секунд. Выполняется примерно 90 секунд, компьютер вроде не слабый, завтра буду пробовать на сервере.

  Ответить  
 
 автор: sim5   (20.04.2009 в 06:56)   письмо автору
 
   для: xxxleoxxx   (19.04.2009 в 22:11)
 

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

  Ответить  
 
 автор: Trianon   (19.04.2009 в 15:54)   письмо автору
 
   для: sim5   (19.04.2009 в 15:28)
 

>Было бы лучше в плане "каемочек", если бы определять прозрачные области не по цвету, а по альфа-каналу.
>Но формат PNG не может сохранять в себе такой канал,

C чего бы это?

  Ответить  
 
 автор: sim5   (19.04.2009 в 16:00)   письмо автору
 
   для: Trianon   (19.04.2009 в 15:54)
 

Что с чего? Сохранить канал? Сохраните.

  Ответить  
 
 автор: Trianon   (19.04.2009 в 16:38)   письмо автору
25.9 Кб
 
   для: sim5   (19.04.2009 в 16:00)
 

откуда информация, что png-формат не поддерживает альфа-канал?

  Ответить  
 
 автор: sim5   (19.04.2009 в 16:45)   письмо автору
 
   для: Trianon   (19.04.2009 в 16:38)
 

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

  Ответить  
 
 автор: Trianon   (19.04.2009 в 16:47)   письмо автору
 
   для: sim5   (19.04.2009 в 16:45)
 

какой нахрен слой?
В этом файле каждый пиксель представлен четырьмя сэмплами: красным, зеленым, синим и альфа.

  Ответить  
 
 автор: sim5   (19.04.2009 в 16:52)   письмо автору
 
   для: Trianon   (19.04.2009 в 16:47)
 

Вы когда будете сохранять это изображение, то делайте это не как "Сохранить для веб...", а просто "Сохранить как...". Выберите формат PNG, и если ваш фотошоп разрешит отметить галочку "Альфа канал", значит у вас он эксклюзивный.
Вы говорите о цвете альфа, а я говорю о канале альфа, такой канал может содержать в себе (или отдельным файлом), например, формат TGA.

  Ответить  
 
 автор: Trianon   (19.04.2009 в 16:56)   письмо автору
 
   для: sim5   (19.04.2009 в 16:52)
 

а при чем здесь, простите, фотошоп?

  Ответить  
 
 автор: sim5   (19.04.2009 в 17:01)   письмо автору
 
   для: Trianon   (19.04.2009 в 16:56)
 

А при том, что вы увидите в нем, что PNG формат никак не может содержать в себе альфа-канала, это нечто другое, это отдельный слой. Хотите для интерса, хотя бы, посмотреть как это работает, могу сказать как. :)

  Ответить  
 
 автор: Trianon   (19.04.2009 в 17:03)   письмо автору
 
   для: sim5   (19.04.2009 в 17:01)
 

понятно. То есть ссылок на авторитетный источник не будет.

  Ответить  
 
 автор: sim5   (19.04.2009 в 17:14)   письмо автору
 
   для: Trianon   (19.04.2009 в 17:03)
 

Ну почему не будет - можете почитать о TGA (TARGA) формате. Можете еще установить Adobe Premiere (авторитетный источник), в дополнении к фотошопу, и импортируя в него файлы формата фотошопа, указывать в качестве прозрачного альфа-канал (а PSD это подразумевает). А еще лучше, сделать это в 3D Max Studio, например, и сохранить свой ролик как последовательность TGA-изображений. Вот тут вы можете сохранять альфа-канал как в самом изображении, так отдельным файлом (альфа-изображение). Откройте такое и посмотрите, ну, а эффект в том же Adobe Premiere можно посмотрть.
Ну или, чего проще - в фотошопе, во вкладке "Каналы" добавьте новый канал (альфа), выбирая одно из двух, либо выделенное, либо подложку, а потом сохраните это изображение в двух форматах: TGA и PNG, а затем посмотрите сохраненные результаты.
Собственно цвет альфа, он и будет работать подобно, но чтобы это работало корректно, не затрагивая объект нам нужный, нам нужно собственно выделить его, вот как это сделать в GD.... Только приготовить саму подложку в два цвета, и назначить алфа цвет, но при объеденении.....

  Ответить  
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования