Не корректно работает imageColorAllocate()

265
29 октября 2017, 20:41

функция imageColorAllocate() перестает работать в цикле

$i = imageCreate(count($hAr), 360);
$color = imageColorAllocate($i, 255, 255, 255);
/*$c = imageColorAllocate($i, 0, 0, 0);*/
$nn = 0;
foreach ($hAr as $key => $hh) {
    $c = imageColorAllocate($i, $ar[$key][3], $ar[$key][4], $ar[$key][4]);
    imageSetPixel($i, $nn, $hh,   $c);
    imageSetPixel($i, $nn, $hh+1, $c);
    imageSetPixel($i, $nn, $hh-1, $c);
    $nn++;
}

Если изменять $c(цвет точки) в цикле линия обрывается. Но если цвет статичен все в порядке. Заранее скажу: в ($ar[$key][n]) 0 < n < 255 и в массиве нет белого цвета.

Изменив цвет все равно получаю обрыв линии:

foreach ($hAr as $key => $hh) {
    ...
    $c = imageColorAllocate($i, 255, 0, 0);
    ...
}

Кто сталкивался с таким? Подскажите как исправить

Answer 1
Причины возникновения проблемы

Прочитайте первый комментарий к этой функции на php.net: http://php.net/manual/ru/function.imagecolorallocate.php#94785

Note that you can only assign 255 colors to any image palette. If you try assigning more, imagecolorallocate() will fail.

Also, imagecolorallocate() will assign a new color EVERY time the function is called, even if the color already exists in the palette

У Вас в цикле выделяется 255 цветов на изображение, а затем (вероятно) функция перестаёт их выделять и начинает возвращать FALSE. При этом, как поясняется по вышеуказанной ссылке, неважно одинаковые цвета вы резервируете этой функцией или разные.

Решение для случая, когда количество цветов менее 256

Возможно, оно неидеально. Это просто идея для дальнейшей проработки:

function getColor($i, $r, $g, $b) {
    static $colors = [];
    $rgb = $r . $g . $b;
    if (!array_key_exists($rgb, $colors)) {
        $colors[$rgb] = imageColorAllocate($i, $r, $g, $b);
    }
    return $colors[$rgb];
}
$i = imageCreate(count($hAr), 360);
$color = imageColorAllocate($i, 255, 255, 255);
$nn = 0;
foreach ($hAr as $key => $hh) {
    $c = getColor($i, $ar[$key][3], $ar[$key][4], $ar[$key][4]);
    imageSetPixel($i, $nn, $hh,   $c);
    imageSetPixel($i, $nn, $hh+1, $c);
    imageSetPixel($i, $nn, $hh-1, $c);
    $nn++;
}

При этом следует понимать, что это решение не спасёт от выделения более 255 разных цветов на изображение. Оно спасает лишь от исчерпания лимита при повторном резервировании одинаковых цветов.

Решение для случая, когда цветов более 255

В этом случае для создания изображения вместо функции imagecreate() следует использовать функцию imagecreatetruecolor(): http://php.net/manual/ru/function.imagecreatetruecolor.php

Следует помнить, что функция imagecreatetruecolor() расходует больше памяти (в 2-3 раза больше) и меньше подходит для работы с GIF-изображениями.

READ ALSO
Помогите понять логику функцию strtotime

Помогите понять логику функцию strtotime

почему так происходит?

217
Долгий mysqli запрос

Долгий mysqli запрос

Имеется таблица alog с содержанием:

351
Как получить значения поля типа enum в yii2

Как получить значения поля типа enum в yii2

В таблице бд есть поле типа enumНужно получить все возможные значения этого поля

288
Слетает язык после завершения сессии

Слетает язык после завершения сессии

Работаю над локализацией сайта, столкнулся с такой проблемой, при смене языка в настройках сайта все работает, как нужно, но стоит только...

253