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

Тема в разделе "Как сделать...", создана пользователем Sunday, 12 окт 2012.

  1. Sunday

    Sunday

    Регистр.:
    13 дек 2009
    Сообщения:
    726
    Симпатии:
    315
    Есть функция обработки изображений.
    На большие фотки накладывается логотип сайта. Проблема в том, что если логотип в PNG и имеет прозрачность, то на выходе прозрачность теряется.
    А если лого в GIF, то прозрачность остается, но GIF не устраивает по той причине, что он не поддерживает полупрозрачность и края получаются рваные.
    Всё, что нагуглил как-то не очень помогло. Может кто знает как решить эту проблему?
     
  2. Doctor_Chaos

    Doctor_Chaos Проктолог-гинеколог

    Moderator
    • Супермодератор
    Регистр.:
    7 сен 2013
    Сообщения:
    950
    Симпатии:
    645
    А функцию не догадались выложить, или должны по кофейной гуще гадать, что у вас там?
     
  3. Extalionez

    Extalionez Клоун

    Заблокирован
    Регистр.:
    21 авг 2008
    Сообщения:
    368
    Симпатии:
    185
    А зачем тебе функция? По вопросу проблема понятна, вот только непонятно что этого программиста в будущем ждёт если он гуглить не умеет;) .
    Вот ответ.
     
  4. Doctor_Chaos

    Doctor_Chaos Проктолог-гинеколог

    Moderator
    • Супермодератор
    Регистр.:
    7 сен 2013
    Сообщения:
    950
    Симпатии:
    645
    Уважаемый, я думаю, что ТС и без вас гуглить умеет и раз уж он задал вопрос здесь, то, вероятно, ему этот вариант не подходит. Как пример - приведенный вами вариант не обработает jpeg. Именно поэтому нужна сама функция, чтобы посмотреть, чем она там занимается и как ее можно исправить в целом.
     
  5. dima2k

    dima2k

    Регистр.:
    20 апр 2007
    Сообщения:
    276
    Симпатии:
    261
    Вот набросал код
    Код:
    $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 прав, нужно увидеть проблемную функцию.
     
    Sunday нравится это.
  6. mcdir

    mcdir

    Регистр.:
    6 ноя 2007
    Сообщения:
    202
    Симпатии:
    37
    В идеале лучше не видеть функцию, а ТС почитать http://www.imagemagick.org/script/index.php + http://www.imagemagick.org/script/command-line-options.php - тама все написано что де как бывает.
    А обработку такую(и сложнее) я в свое время таки на bash писал т.к. там одних только ключей на 5 строк было. Тем более, что такие финты чаще в фоне курятся или нужны для уже существующих картинок...
    Хотя у всех по разному.
     
  7. Sunday

    Sunday

    Регистр.:
    13 дек 2009
    Сообщения:
    726
    Симпатии:
    315
    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;
    }
     
  8. Doctor_Chaos

    Doctor_Chaos Проктолог-гинеколог

    Moderator
    • Супермодератор
    Регистр.:
    7 сен 2013
    Сообщения:
    950
    Симпатии:
    645
    попробуйте строку
    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]);
     
    Sunday нравится это.
  9. Sunday

    Sunday

    Регистр.:
    13 дек 2009
    Сообщения:
    726
    Симпатии:
    315
    Функция просто обрезает фотки и на выходе сохраняет в том же формате. Стоит задача переделать функцию, что бы добавлять изображениям прозрачные поля.
    GIF и PNG-8 для этого не годятся, т.к. они не поддерживают полноцветность и на выходе будет лажа. JPG тоже не подходит, т.к. нужны именно прозрачные поля. Остается PNG-24, который тоже пока под вопросом из-за своего конечного объема.
    Это реально сделать средствами PHP и GD?