Xpoint
   [напомнить пароль]

imagecolorat + imagesetpixel = очень медленно работает

Метки: [без меток]
2009-09-12 00:36:55 [обр] Vladimir Sobolev(0/6)[досье]
Столкнулся с очень малой производительностью пары этих операций. Обработать необходимо порядка 8000 точек на картинке. Взять цвет пиксела, произвести вычисления (поделить, умножить, проверить 0<>255 и тд) и положить новый пиксел обратно, вот что мне нужно. Есть ли более быстрый вариант сделать это? Хостинг стандартный, и инструменты нужны тоже стандартные.
спустя 4 минуты [обр] Давид Мзареулян(536/1003)[досье]
8000 — это совсем немного. Вы уверены, что тормоза именно на этих функциях?
спустя 7 минут [обр] Vladimir Sobolev(0/6)[досье]
да, тк таких картипнок скрипт за одно выполнение должен обратать порядка сотни - все дело в них. хотя я для уверенности попробую поставить таймер :)
спустя 32 минуты [обр] Vladimir Sobolev(0/6)[досье]

Init time: 3.726 sec
Data loading time: 0.440 sec

Rendering tile time: 3.512 sec
Rendering tile time: 3.454 sec
Rendering tile time: 3.409 sec
Rendering tile time: 3.302 sec
Rendering tile time: 3.496 sec
Rendering tile time: 2.911 sec
Rendering tile time: 2.795 sec
Rendering tile time: 3.580 sec
Rendering tile time: 2.734 sec
Rendering tile time: 2.630 sec
Rendering tile time: 3.345 sec
Rendering tile time: 2.426 sec
Rendering tile time: 2.768 sec
Rendering tile time: 5.082 sec
Rendering tile time: 3.596 sec
Rendering tile time: 3.629 sec
Rendering tile time: 3.003 sec
Rendering tile time: 3.540 sec
Rendering tile time: 3.513 sec
Rendering tile time: 3.356 sec
Rendering tile time: 2.747 sec
Rendering tile time: 2.805 sec
Rendering tile time: 3.710 sec
Rendering tile time: 4.523 sec
Rendering tile time: 3.791 sec
Rendering tile time: 3.986 sec
Rendering tile time: 3.759 sec
Rendering tile time: 3.901 sec
Rendering tile time: 2.799 sec
Rendering tile time: 4.147 sec
Rendering tile time: 3.386 sec
Rendering tile time: 2.323 sec
Rendering tile time: 3.595 sec
Rendering tile time: 3.403 sec
Rendering tile time: 4.096 sec
Rendering tile time: 3.021 sec
Rendering tile time: 2.773 sec
Rendering tile time: 3.345 sec
Rendering tile time: 4.042 sec
Rendering tile time: 3.512 sec
Rendering tile time: 3.573 sec
Rendering tile time: 3.526 sec
Rendering tile time: 4.226 sec
Rendering tile time: 3.602 sec
Rendering tile time: 4.089 sec
Rendering tile time: 3.584 sec
Rendering tile time: 3.199 sec
Rendering tile time: 4.448 sec

Rendering full image time: 1.371 sec
Croping image time: 1.321 sec

Stop

спустя 1 минуту [обр] Vladimir Sobolev(0/6)[досье]
вот, на каждый спрайт уходит в среднем по 3-4 секунды
спустя 8 минут [обр] Vladimir Sobolev(0/6)[досье]
уточнил, 3-4 секунды - это вместе с закачкой картинки с внешнего сайта, чистое время выполнения для каждой картинки получатеся в среднем 1 секунда.
спустя 17 часов [обр] Давид Мзареулян(536/1003)[досье]

А дайте-ка минимальный проблемный код. Помимо загрузки картинок с внешнего сайта там наверняка будут другие источники тормозов…

Потому что я при помощи imagecolorat строю гистограмму для картинок ~500x500 пикселей, и это делается за очень небольшие доли секунды.

спустя 21 час [обр] Vladimir Sobolev(0/6)[досье]
   for ($n=0; $n < $bsteps; $n++ ) {

      $b = $burn[$n];
      @$d = $dodge[$n];
      
      $bx = $b[0];
      $by = $b[1];
      
      $rgb = rgb (imagecolorat ($img, $bx, $by));

      for ($z = 0; $z < 3; $z++) {
         $rgb[$z] = colorburn ($rgb[$z], $b[$z+2]);
         if ($d) $rgb[$z] = colordodge ($rgb[$z], $d[$z+2]);
      }
      
      $rgb = imagecolorallocate($img, $rgb[0], $rgb[1], $rgb[2]);         
      imagesetpixel($img, $bx, $by, $rgb);
   }

function colorburn($a, $b) {
   if ($b == 0) {return 0;}
   else {
      $c = (int)(255 - (((255-$a) << 8) / $b));
      return ($c < 0) ? 0 : $c;
   }
}
function colordodge($a, $b) {
   if ($b == 255) {return 255;}
   else {
      $c = (int)(($a << 8) / (255-$b));
      return ($c > 255) ? 255 : $c;
   }
}
этот фрагмент выполняется в среднем за 0.5 - 1 секунду.
$burn и $dodge - заранее просчитанные массивы с координатами нужных точек (чтобы обрабатывать только нужные области а не всю картинку)+--
спустя 12 минут [обр] Vladimir Sobolev(0/6)[досье]
промахнулся с замером :) извините.
время выполнения - в среднем 0.02 сек. это уже после оптимизации (на сколько это позволяют мое НЕзнание PHP).
так что вопрос видимо уже снимается, и я занимаюсь оптимизацией загрузки файлов со стороннего хостнга, и тут, как я понял, по простому ничего не сделать, только последовательная загрузка всех 100 частей. Пока я сделал так, что после загрузки и обработки 1 части - у пользователя перегружается страница.
спустя 2 часа 39 минут [обр] Давид Мзареулян(536/1003)[досье]

Vladimir Sobolev[досье] если Вы работаете с truecolor-картинками, то imagecolorallocate Вам не нужен, в imagesetpixel можно подставлять обычный int вида 0x00RRGGBB. Его же выдаёт и imagecolorat.

А с загрузкой файлов — это уже другой вопрос…

спустя 1 час 22 минуты [обр] Vladimir Sobolev(0/6)[досье]

Давид Мзареулян[досье] ок, избавился от этого.
из INT я преобразовывал в RGB так:

function rgb($rgb) {
   $r = ($rgb >> 16) & 255;
   $g = ($rgb >> 8) & 255;
   $b = $rgb & 255;
   return array($r,$g,$b);
}

а теперь добавил обратную функцию:

function fromrgb($rgb) {
   return $rgb[0]*65536 + $rgb[1]*256 + $rgb[2];;
}

нормально?

спустя 14 часов [обр] Филипп Ткачев(20/112)[досье]
Vladimir Sobolev[досье], используйте для обратной функции такие же операции сдвига. Они выполняются намного быстрее умножения.
спустя 6 часов [обр] Vladimir Sobolev(0/6)[досье]
Филипп Ткачев[досье] можно пример? а то я первую функцию нагуглил, а вторую уже сам сделал :)
спустя 15 часов [обр] Филипп Ткачев(20/112)[досье]
битовые операции
return $rgb[0] << 16 + дальше сами ;)
спустя 9 дней [обр] Vladimir Sobolev(0/6)[досье]
Филипп Ткачев[досье] return $rgb[0] << 16 + $rgb[1] << 8 + $rgb[2]; — вот так? что-то не то, поправьте меня, пожалуйста.
спустя 7 часов [обр] Филипп Ткачев(20/112)[досье]
да
спустя 17 часов [обр] Vladimir Sobolev(0/6)[досье]
Филипп Ткачев[досье] я говорю, что что-то не то, результат не идентичен работе предыдущей функции
спустя 1 час 17 минут [обр] Давид Мзареулян(536/1003)[досье]

($rgb[0] << 16) + ($rgb[1] << 8) + $rgb[2]

Неужели две недели сидеть на форуме проще, чем один раз прочесть документацию?

спустя 2 минуты [обр] Vladimir Sobolev(0/6)[досье]
Давид Мзареулян[досье] сидеть две недели и заглядывать раз в две недели — немного разные вещи, согласитесь?
спустя 14 минут [обр] Давид Мзареулян(536/1003)[досье]

Раз «заглядываете» — значит ждёте, что Вам тут кто-то что-то решит, а сами ничего не делаете. Вы вообще себя считаете программистом или как? Если считаете, то эту задачу должны были решить, даже на совершенно незнакомом языке, за полчаса максимум. Но нет, надо две недели тупить в форуме.

А потом удивляемся, отчего у нас сайты тормозные и дырявые как решето.

спустя 22 минуты [обр] Vladimir Sobolev(0/6)[досье]
Давид Мзареулян[досье] нет, не считаю. и задача - не задача вовсе, а небольшое улучшение, и сайт не дырявый, а просто экспериментальная страница для одного концепта. да и я сделал как надо, ошибка в синтаксисе и все, что вы так разволновались за судьбы сайтов? :)
Powered by POEM™ Engine Copyright © 2002-2005