Как сделать sharpening средствами php (не imagemagick)

Статус
В этой теме нельзя размещать новые ответы.

PaulMinelly

Новичок
Как сделать sharpening средствами php (не imagemagick)

Вопрос который задавал еще неделю назад, но тема закрылась, а ответа так и не получил.

Как можно увеличить четкость фотографии средствами одного php+gd, посоветуйте скритпы. (Встроенная возможность патченной версии GD2.0 не подходит из-за малой распространенности). Кто может посоветовать?
 

Anarki

Новичок
unsharp

Тот старый код
PHP:
function unsharp_mask($img, $amount, $radius, $threshold) {
  /*
  Unsharp Mask for PHP - version 2.0
  Unsharp mask algorithm by Torstein H�nsi 2003-06.
  Please leave this notice.
  */
 
  // $img is an image that is already created within php using
  // imgcreatetruecolor. No url! $img must be a truecolor image.
 
  // Attempt to calibrate the parameters to Photoshop:
  if ($amount > 500)    $amount = 500;
  $amount = $amount * 0.016;
  if ($radius > 50)    $radius = 50;
  $radius = $radius * 2;
  if ($threshold > 255)    $threshold = 255;
 
  $radius = abs(round($radius));     // Only integers make sense.
  if ($radius == 0) return $img;
  $w = imagesx($img); $h = imagesy($img);
  $imgCanvas = imagecreatetruecolor($w, $h);
  $imgCanvas2 = imagecreatetruecolor($w, $h);
  $imgBlur = imagecreatetruecolor($w, $h);
  $imgBlur2 = imagecreatetruecolor($w, $h);
  imagecopy ($imgCanvas, $img, 0, 0, 0, 0, $w, $h);
  imagecopy ($imgCanvas2, $img, 0, 0, 0, 0, $w, $h);
 
 
  // Gaussian blur matrix:
  //    1    2    1
  //    2    4    2
  //    1    2    1
  //////////////////////////////////////////////////
 
  imagecopy($imgBlur, $imgCanvas, 0, 0, 0, 0, $w, $h); // background    
 
  for ($i = 0; $i < $radius; $i++)    {
    if (function_exists('imageconvolution')) { // PHP >= 5.1
      $matrix = array(
        array( 1, 2, 1 ),
        array( 2, 4, 2 ),
        array( 1, 2, 1 )
      );
      imageconvolution($imgCanvas, $matrix, 16, 0);
    } else {
 
      // Move copies of the image around one pixel at the time and merge them with weight
      // according to the matrix. The same matrix is simply repeated for higher radii.
 
      imagecopy      ($imgBlur, $imgCanvas, 0, 0, 1, 1, $w - 1, $h - 1); // up left
      imagecopymerge ($imgBlur, $imgCanvas, 1, 1, 0, 0, $w, $h, 50); // down right
      imagecopymerge ($imgBlur, $imgCanvas, 0, 1, 1, 0, $w - 1, $h, 33.33333); // down left
      imagecopymerge ($imgBlur, $imgCanvas, 1, 0, 0, 1, $w, $h - 1, 25); // up right
      imagecopymerge ($imgBlur, $imgCanvas, 0, 0, 1, 0, $w - 1, $h, 33.33333); // left
      imagecopymerge ($imgBlur, $imgCanvas, 1, 0, 0, 0, $w, $h, 25); // right
      imagecopymerge ($imgBlur, $imgCanvas, 0, 0, 0, 1, $w, $h - 1, 20 ); // up
      imagecopymerge ($imgBlur, $imgCanvas, 0, 1, 0, 0, $w, $h, 16.666667); // down
      imagecopymerge ($imgBlur, $imgCanvas, 0, 0, 0, 0, $w, $h, 50); // center
      imagecopy      ($imgCanvas, $imgBlur, 0, 0, 0, 0, $w, $h);
 
      // During the loop above the blurred copy darkens, possibly due to a roundoff
      // error. Therefore the sharp picture has to go through the same loop to
      // produce a similar image for comparison. This is not a good thing, as processing
      // time increases heavily.
      imagecopy      ($imgBlur2, $imgCanvas2, 0, 0, 0, 0, $w, $h);
      imagecopymerge ($imgBlur2, $imgCanvas2, 0, 0, 0, 0, $w, $h, 50);
      imagecopymerge ($imgBlur2, $imgCanvas2, 0, 0, 0, 0, $w, $h, 33.33333);
      imagecopymerge ($imgBlur2, $imgCanvas2, 0, 0, 0, 0, $w, $h, 25);
      imagecopymerge ($imgBlur2, $imgCanvas2, 0, 0, 0, 0, $w, $h, 33.33333);
      imagecopymerge ($imgBlur2, $imgCanvas2, 0, 0, 0, 0, $w, $h, 25);
      imagecopymerge ($imgBlur2, $imgCanvas2, 0, 0, 0, 0, $w, $h, 20 );
      imagecopymerge ($imgBlur2, $imgCanvas2, 0, 0, 0, 0, $w, $h, 16.666667);
      imagecopymerge ($imgBlur2, $imgCanvas2, 0, 0, 0, 0, $w, $h, 50);
      imagecopy      ($imgCanvas2, $imgBlur2, 0, 0, 0, 0, $w, $h);
    }
  }
 
  // Calculate the difference between the blurred pixels and the original
  // and set the pixels
  for ($x = 0; $x < $w; $x++)    { // each row
    for ($y = 0; $y < $h; $y++)    { // each pixel
 
      $rgbOrig = ImageColorAt($imgCanvas2, $x, $y);
      $rOrig = (($rgbOrig >> 16) & 0xFF);
      $gOrig = (($rgbOrig >> 8) & 0xFF);
      $bOrig = ($rgbOrig & 0xFF);
 
      $rgbBlur = ImageColorAt($imgCanvas, $x, $y);
 
      $rBlur = (($rgbBlur >> 16) & 0xFF);
      $gBlur = (($rgbBlur >> 8) & 0xFF);
      $bBlur = ($rgbBlur & 0xFF);
 
      // When the masked pixels differ less from the original
      // than the threshold specifies, they are set to their original value.
      $rNew = (abs($rOrig - $rBlur) >= $threshold)
          ? max(0, min(255, ($amount * ($rOrig - $rBlur)) + $rOrig))
          : $rOrig;
      $gNew = (abs($gOrig - $gBlur) >= $threshold)
          ? max(0, min(255, ($amount * ($gOrig - $gBlur)) + $gOrig))
          : $gOrig;
      $bNew = (abs($bOrig - $bBlur) >= $threshold)
          ? max(0, min(255, ($amount * ($bOrig - $bBlur)) + $bOrig))
          : $bOrig;
 
      if (($rOrig != $rNew) || ($gOrig != $gNew) || ($bOrig != $bNew)) {
        $pixCol = ImageColorAllocate($img, $rNew, $gNew, $bNew);
        ImageSetPixel($img, $x, $y, $pixCol);
      }
    }
  }
  return $img;
}
 

PaulMinelly

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

Надо чтобы вот так было

а не вот так ужасно как тут:
 

Фанат

oncle terrible
Команда форума

PaulMinelly

Новичок
Что вы хотите сказать однаково зашарплены тамбнейлы что на баннере, что в той картинке?

-~{}~ 10.05.07 04:04:

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

Подобное делается с помощью ImageMagick
-enhance -unsharp 0.2x2.3+1.1+0.1
Но мне надо без него, а аналога на PHP хорошего пока не вижу. Попробуйте морду на баннере зашарпить этим делом. Сразу станет понятно. Будет менее блевотинны вид.
 

Фанат

oncle terrible
Команда форума
ё.
да это кросспостинг был.
нифига себе наглость
 
Статус
В этой теме нельзя размещать новые ответы.
Сверху