За последние 24 часа нас посетили 20424 программиста и 1644 робота. Сейчас ищут 1317 программистов ...

Почти убрал водяной знак! Но есть некоторые глюки. Помогите!

Тема в разделе "Обработка изображений средствами PHP", создана пользователем xmoder, 25 апр 2010.

  1. xmoder

    xmoder Активный пользователь

    С нами с:
    21 сен 2008
    Сообщения:
    11
    Симпатии:
    0
    Прошу помощи у гуру РНР по работе с GD.
    Не подумайте, что я собираюсь своровать чьи-то картинки. Просто для одно своего сайта вставлял водяные знаки на все картинки и тут понабилось, сделать еще один сайт с этими же картинками, но уже без водяных знаков.

    Алгоритм убирания водяного знака прост: делаем обратные операции, что б получить исходную картинку.
    На тех картинках, которые заполненены полностью (мало белых участнков скрипт работает олично).

    Пример:
    Берем
    [​IMG]

    Ставим:
    [​IMG]

    Убираем обратным алгоритмом:
    [​IMG]

    Теперь проблема. Берем картинку с белыми полями:

    [​IMG]

    Ставим:
    [​IMG]

    Убираем обратным алгоритмом:
    [​IMG]


    Почему-то появляются черные точки.

    Сами файлы:
    index.php
    PHP:
    1. <?php
    2. include 'api.watermark.php';
    3.  
    4. set_wm('1.jpg', '1_wm.jpg', "watermark.png", 90);
    5. set_wm('1_wm.jpg', '1_no_wm.jpg', "watermark.png", 90, true);
    6.  
    7. set_wm('2.jpg', '2_wm.jpg', "watermark.png", 90);
    8. set_wm('2_wm.jpg', '2_no_wm.jpg', "watermark.png", 90, true);
    9.  
    10. echo "Готово";
    11.  
    12. ?>
    api.watermark.php:

    PHP:
    1. <?php
    2.  
    3. ini_set('memory_limit', '320M');
    4.  
    5. class watermark{
    6.  
    7.  
    8.         function create_watermark( $main_img_obj, $watermark_img_obj, $alpha_level = 100, $remove = false ) {
    9.                 $alpha_level        /= 100;
    10.  
    11.  
    12.                 $main_img_obj_w        = imagesx( $main_img_obj );
    13.                 $main_img_obj_h        = imagesy( $main_img_obj );
    14.                 $watermark_img_obj_w        = imagesx( $watermark_img_obj );
    15.                 $watermark_img_obj_h        = imagesy( $watermark_img_obj );
    16.  
    17.  
    18.                 $main_img_obj_min_x        = floor( ( $main_img_obj_w / 2 ) - ( $watermark_img_obj_w / 2 ) );
    19.                 $main_img_obj_max_x        = ceil( ( $main_img_obj_w / 2 ) + ( $watermark_img_obj_w / 2 ) );
    20.                 $main_img_obj_min_y        = floor( ( $main_img_obj_h / 2 ) - ( $watermark_img_obj_h / 2 ) );
    21.                 $main_img_obj_max_y        = ceil( ( $main_img_obj_h / 2 ) + ( $watermark_img_obj_h / 2 ) );
    22.  
    23.  
    24.                 $return_img        = imagecreatetruecolor( $main_img_obj_w, $main_img_obj_h );
    25.  
    26.         $return_img_wm        = imagecreatetruecolor( $watermark_img_obj_w, $watermark_img_obj_h );
    27.  
    28.  
    29.                 for( $y = 0; $y < $main_img_obj_h; $y++ ) {
    30.                         for( $x = 0; $x < $main_img_obj_w; $x++ ) {
    31.                                 $return_color        = NULL;
    32.  
    33.  
    34.                                 $watermark_x        = $x - $main_img_obj_min_x;
    35.                                 $watermark_y        = $y - $main_img_obj_min_y;
    36.  
    37.  
    38.                                 $main_rgb = imagecolorsforindex( $main_img_obj, imagecolorat( $main_img_obj, $x, $y ) );
    39.  
    40.  
    41.                                 if (        $watermark_x >= 0 && $watermark_x < $watermark_img_obj_w &&
    42.                                                         $watermark_y >= 0 && $watermark_y < $watermark_img_obj_h ) {
    43.                                         $watermark_rbg = imagecolorsforindex( $watermark_img_obj, imagecolorat( $watermark_img_obj, $watermark_x, $watermark_y ) );
    44.  
    45.  
    46.                                         $watermark_alpha        = round( ( ( 127 - $watermark_rbg['alpha'] ) / 127 ), 2 );
    47.                                         $watermark_alpha        = $watermark_alpha * $alpha_level;
    48.  
    49.  
    50.                                         $avg_red                = $this->_get_ave_color( $main_rgb['red'],                $watermark_rbg['red'],                $watermark_alpha, $remove );
    51.                                         $avg_green        = $this->_get_ave_color( $main_rgb['green'],        $watermark_rbg['green'],        $watermark_alpha, $remove );
    52.                                         $avg_blue                = $this->_get_ave_color( $main_rgb['blue'],        $watermark_rbg['blue'],                $watermark_alpha, $remove );
    53.  
    54.                                         $return_color        = $this->_get_image_color( $return_img, $avg_red, $avg_green, $avg_blue );
    55.                
    56.                                 } else {
    57.                                         $return_color        = imagecolorat( $main_img_obj, $x, $y );
    58.                                 }
    59.  
    60.                                 imagesetpixel( $return_img, $x, $y, $return_color );
    61.                                 imagesetpixel( $return_img, $x, $y, $return_color );
    62.  
    63.                         }
    64.                 }
    65.  
    66.                 return $return_img;
    67.  
    68.         }
    69.  
    70.  
    71.         function _get_ave_color( $color_a, $color_b, $alpha_level, $remove ) {
    72.  
    73.         if(!$remove)
    74.             $ret_color = round( ( ( $color_a * ( 1 - $alpha_level ) ) + ( $color_b        * $alpha_level ) ) );
    75.         else
    76.             $ret_color = round(  (  ($color_a - $color_b * $alpha_level)/(1-$alpha_level)  )   ); // обратная функция           
    77.  
    78.         return $ret_color;
    79.         }
    80.  
    81.  
    82.         function _get_image_color($im, $r, $g, $b) {
    83.                 $c=imagecolorexact($im, $r, $g, $b);
    84.                 if ($c!=-1)  return $c;
    85.                 $c=imagecolorallocate($im, $r, $g, $b);
    86.                 if ($c!=-1) return $c;
    87.                 return imagecolorclosest($im, $r, $g, $b);
    88.         }
    89.  
    90. }
    91.  
    92. function set_wm($image_from, $image_to, $water_mark, $quality=90, $remove = false)
    93. {
    94.         $watermark = new watermark();
    95.         $main_img_obj = imagecreatefromjpeg($image_from);
    96.         $watermark_img_obj = imagecreatefrompng($water_mark);
    97.         $return_img_obj = $watermark->create_watermark($main_img_obj, $watermark_img_obj, 100, $remove);
    98.  
    99.         imagejpeg($return_img_obj, $image_to, $quality);
    100.     return 1;
    101. }
    102.  
    103. ?>

    Откуда появляются некоторые неточности, это ясно, из-за round () в _get_image_color() , но откуда появляются черные точки вообще ума не приложу. Уже кучу тестов делал, все равно они появляются.

    Помогите, пожулуйста, исправить этот баг.

    Заранее всем большое спасибо!
     
  2. [vs]

    [vs] Суперстар
    Команда форума Модератор

    С нами с:
    27 сен 2007
    Сообщения:
    10.559
    Симпатии:
    632
    Элементарно, Ватсон - это JPEG! Храни картинки в PNG =)
     
  3. xmoder

    xmoder Активный пользователь

    С нами с:
    21 сен 2008
    Сообщения:
    11
    Симпатии:
    0
    Блин, точно. Сработало :)

    СПАСИБО!

    Еще чуть надо было подправить, что б сделать проверку на диапазон:

    PHP:
    1.  
    2.         function _get_ave_color( $color_a, $color_b, $alpha_level, $remove ) {
    3.  
    4.         if(!$remove)
    5.             $ret_color = round( ( ( $color_a * ( 1 - $alpha_level ) ) + ( $color_b        * $alpha_level ) ) );
    6.         else
    7.             $ret_color = round(  (  ($color_a - $color_b * $alpha_level)/(1-$alpha_level)  )   ); // обратная функция           
    8.         if($ret_color<0) $ret_color = 0;
    9.         if($ret_color>255) $ret_color = 255;
    10.         return $ret_color;
    11.         }
    12.  
     
  4. xmoder

    xmoder Активный пользователь

    С нами с:
    21 сен 2008
    Сообщения:
    11
    Симпатии:
    0
    Нет, таки дело было не в PNG, a в проверке на диапазон.
     
  5. Anonymous

    Anonymous Guest

    you can pop Berserker Rage right before you Charge into a mob. Cheap wow gold buy wow power leveling aion wedding dresses wow power leveling A typical pull will be Bloodrage–Heroic Throw–back away from the mob–Berserker Rage–Charge. This pull-style will provide you a very large amount of instant rage for that instant threat, and keep the rage coming in for those 8-9 Berserker Rage seconds, with no drawbacks.Thanks for reading and have fun.Here wedding dresses is the best online service for you to buy the cheapest wow gold. As you can see you are a lvl 80 rogue, and you could have the same problem than you guys, but not any more. Your 10 man DPS is around 2,5k Watches rolex and your 25 man DPS is WoW +- 2,9k, depending on you not screwing up your rotation and the fighting style of the boss. Your build is 51 poins Ass, Sub till Sereded Blades and a little in combat.You could get 2 pieces of T7 one 10 and other 25 man. You could solve your problems DPSing by using wow gold the addon recount. sjbwyxlhly Therefore you may watch the grafics of your moves and realised that most of your DPS was coming from your regular auto-attacks, and most of then were missing, so what you did was to get your hit rating to 330, and up your AP as well and you could do with your problems. By the way, you can get the most Louis Vuitton Bags secure WoW powerleveling.You could make your build, so you could get the most of your Slice'n'dice ability and the rupture, you could use evicerate to refresh your wow power leveling Slice'n'dice, not mattering how many combo points you have at the time, trying to refresh at the last time possible. Hope this could help you more or less.Here are some information on Armory census data gotten from other websites,zdm