Обработка PNG с прозрачностью

Sunday

Cōgitō ergō sum
Регистрация
13 Дек 2009
Сообщения
823
Реакции
342
Есть функция обработки изображений.
На большие фотки накладывается логотип сайта. Проблема в том, что если логотип в PNG и имеет прозрачность, то на выходе прозрачность теряется.
А если лого в GIF, то прозрачность остается, но GIF не устраивает по той причине, что он не поддерживает полупрозрачность и края получаются рваные.
Всё, что нагуглил как-то не очень помогло. Может кто знает как решить эту проблему?
 
А функцию не догадались выложить, или должны по кофейной гуще гадать, что у вас там?
 
  • Заблокирован
  • #3
А функцию не догадались выложить, или должны по кофейной гуще гадать, что у вас там?
А зачем тебе функция? По вопросу проблема понятна, вот только непонятно что этого программиста в будущем ждёт если он гуглить не умеет;) .
Для просмотра ссылки Войди или Зарегистрируйся ответ.
 
А зачем тебе функция? По вопросу проблема понятна, вот только непонятно что этого программиста в будущем ждёт если он гуглить не умеет;) .
Уважаемый, я думаю, что ТС и без вас гуглить умеет и раз уж он задал вопрос здесь, то, вероятно, ему этот вариант не подходит. Как пример - приведенный вами вариант не обработает jpeg. Именно поэтому нужна сама функция, чтобы посмотреть, чем она там занимается и как ее можно исправить в целом.
 
Вот набросал код
Код:
$srcfile=htmlspecialchars($_GET['pic']);
$path=realpath('.');
 
list($width, $height, $type) = getimagesize($path.'/pic/'.$srcfile);
 
switch($type) {
  case 1: { // GIF
    $dst_img = @imagecreatefromgif($path.'/pic/'.$srcfile);
    break;
  }
  case 2: { // JPG
    $dst_img = @imagecreatefromjpeg($path.'/pic/'.$srcfile);
    break;
  }
  case 3: { // PNG
    $dst_img = @imagecreatefrompng($path.'/pic/'.$srcfile);
    break;
  }
  case 6: { // BMP
    $dst_img = @imagecreatefromwbmp($path.'/pic/'.$srcfile);
    break;
    }
  default: {
    return;
  }
}
 
list($watermark_width, $watermark_height) = getimagesize('watermark.png');
$watermark_img_obj =  ImageCreateFromPNG("watermark.png");
$padding_x = ($width - $watermark_width) / 2;
$padding_y = ($height - $watermark_height) / 2;
imagecopy($dst_img, $watermark_img_obj, $padding_x, $padding_y, 0, 0, $watermark_width, $watermark_height);
header("Content-type: image/jpeg");
imagejpeg($dst_img);
imagedestroy($dst_img);
watermark.png в корне папки (проверял 8-битную и 16-ти битную картинки), в папке "pic" тестовые картинки. Запускать "test.php?pic=blablalbla.gif" . Проверил на gif,png,jpg,jpeg,bmp - прозрачность сохраняется. Правда, если заменить imagecopy на imagecopymerge с указанием альфа-канала, то прозрачность теряется, т.ч. может быть проблема у ТС в чем-то подобном. Но Doctor прав, нужно увидеть проблемную функцию.
 
В идеале лучше не видеть функцию, а ТС почитать Для просмотра ссылки Войди или Зарегистрируйся + Для просмотра ссылки Войди или Зарегистрируйся - тама все написано что де как бывает.
А обработку такую(и сложнее) я в свое время таки на bash писал т.к. там одних только ключей на 5 строк было. Тем более, что такие финты чаще в фоне курятся или нужны для уже существующих картинок...
Хотя у всех по разному.
 
А функцию не догадались выложить, или должны по кофейной гуще гадать, что у вас там?
PHP:
function img_resize($src,$dest,$width,$tolarge,$bgcolor,$ext,$imgwidth,$imgheight,$logomerge){
if(!file_exists($src))return false;
$icfunc="imagecreatefrom".$ext;
if(!function_exists($icfunc))return false;
if($tolarge!='1' && $imgheight<$width)$width=$imgheight;
$x_ratio=$width/$imgheight;
$y_ratio=$width/$imgwidth;
$ratio=min($x_ratio,$y_ratio);
$use_x_ratio=($x_ratio==$ratio);
$new_width=$use_x_ratio?$width:floor($imgheight*$ratio);
$new_height=!$use_x_ratio?$width:floor($imgwidth*$ratio);
$isrc=$icfunc($src);
if($bgcolor!=0){
$new_left=$use_x_ratio?0:floor(($width-$new_width)/2);
$new_top=!$use_x_ratio?0:floor(($width-$new_height)/2);
$nn_width=$nn_height=$width;
$bgc=$bgcolor;
}else{
$new_left=0;
$new_top=0;
$nn_width=$new_width;
$nn_height=$new_height;
$bgc=0xFFFFFF;
}
$idest=imagecreatetruecolor($nn_width,$nn_height);
imagefill($idest,0,0,$bgc);
imagecopyresampled($idest,$isrc,$new_left,$new_top,0,0,$new_width,$new_height,$imgheight,$imgwidth);
if($logomerge=="1"){
$mergelogo=$_SERVER['DOCUMENT_ROOT'].$GLOBALS['p']."/images/logo_merge/logoj.png";
if(file_exists($mergelogo)){
$size_logo=getimagesize($mergelogo);
if($size_logo[2]==1)$logo=imagecreatefromgif($mergelogo);
elseif($size_logo[2]==2)$logo=imagecreatefromjpeg($mergelogo);
elseif($size_logo[2]==3)$logo=imagecreatefrompng($mergelogo);
if(@$logo){
if($nn_width>($size_logo[0]+50)&&$nn_height>($size_logo[1]+50)){
  $coordmerge_x=$nn_width-($size_logo[0]+20);
  $coordmerge_y=$nn_height-($size_logo[1]+20);
  imagecopymerge($idest,$logo,$coordmerge_x,$coordmerge_y,0,0,$size_logo[0],$size_logo[1],100);
}} else {return false;}
} else {return false;}
} 
if($ext=="gif")imagegif($idest,$dest);
elseif($ext=="png")imagepng($idest,$dest);
else imagejpeg($idest,$dest,100);
imagedestroy($isrc);
imagedestroy($idest);
return true;
}
 
попробуйте строку
imagecopymerge($idest,$logo,$coordmerge_x,$coordmerge_y,0,0,$size_logo[0],$size_logo[1],100);
заменить на

imagecopy($idest,$logo,$coordmerge_x,$coordmerge_y,0,0,$size_logo[0],$size_logo[1]);
 
Функция просто обрезает фотки и на выходе сохраняет в том же формате. Стоит задача переделать функцию, что бы добавлять изображениям прозрачные поля.
GIF и PNG-8 для этого не годятся, т.к. они не поддерживают полноцветность и на выходе будет лажа. JPG тоже не подходит, т.к. нужны именно прозрачные поля. Остается PNG-24, который тоже пока под вопросом из-за своего конечного объема.
Это реально сделать средствами PHP и GD?
 
Назад
Сверху