Модераторы: Aliance, skyboy, MoLeX, ksnk
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Trim при помощи gd 
:(
    Опции темы
NLspieler
Дата 28.3.2011, 22:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 619
Регистрация: 13.10.2008
Где: Берлин

Репутация: нет
Всего: 19



Можно ли используя gd-библиотеку сделать грамотный trim изображения, т.е. убрать лишние белые (или почти белые) полосы сверху, снизу и побокам?
PM MAIL   Вверх
KLeonid
Дата 4.4.2011, 18:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Entropy
*


Профиль
Группа: Участник
Сообщений: 51
Регистрация: 5.7.2007
Где: Shpongleland

Репутация: нет
Всего: 1



Т.е. нужно сделать crop по краям объекта в изображении?
PM MAIL   Вверх
Task
Дата 27.2.2012, 09:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 17
Регистрация: 25.2.2012

Репутация: нет
Всего: нет



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

PS. Забыл сказать, что для сравнения удобнее, если преобразовывать RGB к HSB цветовой модели. 

Это сообщение отредактировал(а) Task - 27.2.2012, 10:54
PM MAIL   Вверх
Task
Дата 28.2.2012, 16:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 17
Регистрация: 25.2.2012

Репутация: нет
Всего: нет



Задача не так и проста, как кажется изначально, если учитывать "грамотность", а вернее "интеллект". Что-то заставило меня вернуться к этому вопросу, а может, кому и сгодится для первичных размышлений.

И так.  

Для этого, как я говорил выше, достаточно знать две составляющих цвета в HSB модели (пока две). Почему эта модель предпочтительна можно понять (для тех, кто не в курсе), выполняя выбор цвета, например, в Photoshop, или иной программе, которая одновременно может отображать выбранное значение в двух цветовых моделях - RGB и HSB. Станет понятным, что при выборе первой модели (для решения поставленной задачи) нам потребуется проверять на условия все цветовые компоненты, что неудобно, а во второй модели только S (насыщенность) и B (яркость), так как значение H (оттенок) не оказывает никакого влияния на значения компонентов SB у выбранных для вырезки диапазона цветов (от белого до N). 

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

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

А далее все просто:

Код

function clearLine($im, $b) {
   $w = imagesx($im)-1;
   $h = imagesy($im)-1;
   $x0 = $x1 = $y0 = $y1 = null;
   $x = $w/2;
   $y = $h/2;
   $k = $w>$h ? $x : $y;
   
   function RGBtoHSB($rgb) { //конвертируем в серое и получаем яркость
      return round((round(($rgb['red']*0.299)+($rgb['green']*0.587)+($rgb['blue']*0.114))/255)*100);
   }
   
   for($i=0; $i<$k; $i++) {
      //проверка слева
      if($x0===null) {
         $hsb = RGBtoHSB(imagecolorsforindex($im, imagecolorat($im, $i, $x)));
         if($hsb<$b) $x0 = $i;
      }
      //проверка сверху
      if($y0===null) {
         $hsb = RGBtoHSB(imagecolorsforindex($im, imagecolorat($im, $x, $i)));
         if($hsb<$b) $y0 = $i; 
      }   
      //проверка справа
      if($x1===null) {
         $hsb = RGBtoHSB(imagecolorsforindex($im, imagecolorat($im, $w-$i, $y)));
         if($hsb<$b) $x1 = $w-$i;
      }
      //проверка снизу
      if($y1===null) {
         $hsb = RGBtoHSB(imagecolorsforindex($im, imagecolorat($im, $x, $h-$i)));
         if($hsb<$b) $y1 = $h-$i;
      }
      if($x0 && $y0 && $x1 && $y1) break;
  }
   return array('x0'=>$x0, 'y0'=>$y0, 'x1'=>$x1, 'y1'=>$y1); //возвращаем найденные координаты
}

$b = 83; //граница яркости по которой обрезаем
$img = 'name.ext';
$mime = getimagesize($img);

$im = $mime['mime']=='image/jpeg' ? imagecreatefromjpeg($img) 
                                  : ($mime['mime']=='image/png' 
                                  ? imagecreatefrompng($img)
                                  : imagecreatefromgif($img));

$crd = clearLine($im, $b);
$w = $crd['x1']-$crd['x0'];
$h = $crd['y1']-$crd['y0'];
$dst = imagecreatetruecolor($w, $h);
imagecopy($dst, $im, 0, 0, $crd['x0'], $crd['y0'], $w, $h);

header ("Content-type:".$mime['mime']);
$mime['mime']=='image/jpeg' ? imagejpeg($dst)
                            :($mime['mime']=='image/png'
                            ? imagepng($dst)
                            : imagegif($dst));

imagedestroy($im);
imagedestroy($dst);


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

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

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

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

Чтобы такого не происходило нужно писать действительно интеллектуальный автомат, но на РНР, думаю, слишком "задумчивым" он будет.

Так что выбирайте - резать или не резать.      

Это сообщение отредактировал(а) Task - 29.2.2012, 10:46
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | PHP: Графика | Следующая тема »


 




[ Время генерации скрипта: 0.1096 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.