ФорумПрограммированиеПыхнуть хотите?Готовые решения → Вычисление преобладающего цвета

Вычисление преобладающего цвета

  • Timur

    Сообщения: 1068 Репутация: N Группа: Джедаи

    Spritz 31 мая 2008 г. 5:42

    int averageColor(resource image, float & dispersion, [float frequency = 1])

    Функция вычисляет среднее RGB-значение цвета изображения, переданного в аргументе image.

    В параметр dispersion помещается величина "разброса" цветов. Т.е. если image представляет собой совершенно одноцветную картинку, он будет равным 0. Если же в картинке одинаково представлено множество различных цветов этот параметр будет больше (причем значения могут быть очень большие, вне зависимости ни от размера изображения, ни от параметра frequency).

    Третий аргумент frequency определяет процент точек изображения, которые будут обработаны. Должен быть больше 0 и не больше 100. Работает по формуле: [tt]высота * ширина * frequency / 100[/tt]. Например, для картинки 800x600, при значении параметра 1, будет обработано 4800 точек. Т.о. время работы функции растет линейно, вместе с увеличением параметра и использовать значения больше 1-2 не рекомендуется. Но и брать значения меньше 0.1 тоже не стоит - результат будет неточным.

    Пример работы, есть ниже, в конце сообщения, в аттаче.

    function averageColor($image, & $dispersion, $frequency = 1)
    {
    if (!is_resource($image) || get_resource_type($image) != 'gd') {
    trigger_error('Argument image is not valid GD-resource', E_USER_ERROR);
    }
    if ($frequency <= 0 || $frequency > 100) {
    trigger_error('Frequency should be in the range of 0 to 100)', E_USER_WARNING);
    if ($frequency > 100) {
    $frequency = 100;
    } else {
    $frequency = 0.1;
    }
    }

    $width = imageSx($image);
    $height = imageSy($image);
    $count = round($frequency * ($width * $height) / 100);

    $sumR = 0;
    $sumG = 0;
    $sumB = 0;

    $squareR = 0;
    $squareG = 0;
    $squareB = 0;

    $rgb = array();
    for ($i = 0; $i < $count; ++$i) {
    $x = rand(0, $width - 1);
    $y = rand(0, $height - 1);

    $color = imageColorAt($image, $x, $y);
    $colR = ($color >> 16) & 0xFF;
    $colG = ($color >> 8) & 0xFF;
    $colB = ($color) & 0xFF;

    $sumR += $colR;
    $sumG += $colG;
    $sumB += $colB;

    $squareR += $colR * $colR;
    $squareG += $colG * $colG;
    $squareB += $colB * $colB;
    }
    $averR = intval(($sumR / $count) << 16);
    $averG = intval(($sumG / $count) << 8);
    $averB = intval( $sumB / $count);
    $average = $averR + $averG + $averB;

    $dispR = ($squareR / $count - ($averR >> 16) * ($averR >> 16));
    $dispG = ($squareG / $count - ($averG >> 8) * ($averG >> 8));
    $dispB = ($squareB / $count - $averB * $averB);
    $dispersion = ($dispR + $dispG + $dispB) / 3;

    return $average;
    }


    На законный вопрос "А кой это нужно? 0_o" попробую привести пример: галерея обоев (фотографий, картин), которые нужно сгрупировать по цветам, а вручну это делать влом. По-хорошему, лучше в этом случае получать несколько основных цветов, может позже напишу что-нибудь подобное.
  • kendo

    Сообщения: 446 Репутация: N Группа: Адекваты

    Spritz 31 мая 2008 г. 5:55, спустя 13 минут 8 секунд

    Ох, пытался сделать в сое время нечто отдаленно похожее, чтобы делать контрастную надпись на картку (© мой_сайт, к примеру) :)
  • adw0rd

    Сообщения: 22902 Репутация: N Группа: в ухо

    Spritz 1 июня 2008 г. 14:51, спустя 1 день 8 часов 55 минут

    Timur, куул)) незнаю только для чего ее заюзать, но мне понравилось, спасибо! :)
    adw/0
  • Trej Gun

    Сообщения: 5299 Репутация: N Группа: в ухо

    Spritz 1 июня 2008 г. 16:05, спустя 1 час 14 минут 12 секунд

    немного не в тему но вот еще прикольный класс для определения цвета
    точнее определения цвета(ов) человеческой кожи
    http://www.phpclasses.org/browse/file/15408.html
  • artoodetoo

    Сообщения: 5138 Репутация: N Группа: в ухо

    Spritz 15 декабря 2008 г. 22:38, спустя 197 дней 7 часов 32 минуты

    Timur, огромный риспект! я знаю где это можно применить
    ιιlllιlllι унц-унц

Пожалуйста, авторизуйтесь, чтобы написать комментарий!