Вопрос

В PHP GD. Как вы можете преобразовать истинный цвет изображение к а. палитра не потерять Любые цвета. С участием imagetruecolortopallete Это не работает. Отказ У меня есть функция, которая проходит через все цвета и фильтрует их (например, оттенки серого). и это не сохраняет все цвета, такие как эта картина ламбаргини-

Картина

alt text

Это мой код

$im = imagecreatefrompng("lamborghini.png");
$degrees = 0;

$img = imagecreatetruecolor(imagesx($im), imagesy($im));
imagecopy($img, $im, 0, 0, 0, 0, imagesx($im), imagesy($im));
imagetruecolortopalette($img, true, 256);
$t = imagecolorstotal($img);
for ($i = 0; $i < $t; $i++) {
  $rgb = imagecolorsforindex($img, $i);
  $hsv =rgbtohsv($rgb['red'], $rgb['green'], $rgb['blue']);
  $h = $degrees;
  $s = $hsv['s'];
  $v = $hsv['v'];
  while ($h > 360) {$h -= 360;};
        $nrgb = hsvtorgb($h, $s, $v);
  imagecolorset($img, $i, $nrgb['r'], $nrgb['g'], $nrgb['b']);
}
imagecopy($im, $img, 0, 0, 0, 0, imagesx($img), imagesy($img));

header('Content-type: image/png');

imagepng($im);
imagedestroy($im);

И это Похоже на это

alt text

Ты можешь видеть Он теряет цвета. Отказ Здесь Любое решение?

Также я не думаю, что это связано с моим кодом, но как imagetruecolortopalette выводит его

Это было полезно?

Решение

Проверьте возврат imagecolorstotal, Вы всегда получаете 256 цветов в качестве возврата, независимо от того, насколько высоко вы устанавливаете количество цветов, которые будут раскрыты. PNG-8 & GIF форматы поддерживают палитры до 256 цветов. Итак, даже если вы можете использовать более 256 в палитре, вам придется сохранить его обратно как True Color для тех, кто сможет его использовать, что делает весь процесс преобразования пустой тратой времени. Другими словами imagetruecolortopallete Имеет верхний предел 256 цветов, вы не можете идти выше.

Вот как вы можете сделать это в TrueColor, хотя это ресурс интенсивно. Может быть, посмотрите в ImageMagick, если вы хотите сделать это более эффективно.

$im = imagecreatefrompng("lamb.png");
$img = imagecreatetruecolor(imagesx($im), imagesy($im));
$degrees = 0;
if ($degrees > 360) {$degrees = $degrees % 360 ;}

foreach (range(0, imagesx($im) - 1) as $x ) {
    foreach (range(0, imagesy($im) - 1) as $y) {
        $rgb = imagecolorat($im, $x, $y);
        $r = ($rgb >> 16) & 0xFF;
        $g = ($rgb >> 8) & 0xFF;
        $b = $rgb & 0xFF;
        $hsv = rgbtohsv($r,$g,$b);
        $rgb = hsvtorgb($degrees, $hsv['s'], $hsv['v']);
        imagesetpixel($img, $x,$y,imagecolorallocate($img, $rgb['r'], $rgb['g'], $rgb['b']));
    }
}

imagepng($img, 'lamb2.png');

Редактировать: Добавление функций RGBTOHSV и HSVTORGB. Я не писал эти функции.

function rgbtohsv ($R, $G, $B) {
 // HSV Results:Number 0-1
$HSL = array();

$var_R = ($R / 255);
$var_G = ($G / 255);
$var_B = ($B / 255);

$var_Min = min($var_R, $var_G, $var_B);
$var_Max = max($var_R, $var_G, $var_B);
$del_Max = $var_Max - $var_Min;

$V = $var_Max;

if ($del_Max == 0)
{
$H = 0;
$S = 0;
}
else
{
$S = $del_Max / $var_Max;

$del_R = ( ( ( $var_Max  - $var_R ) / 6 ) + ( $del_Max / 2 ) ) / $del_Max;
$del_G = ( ( ( $var_Max  - $var_G ) / 6 ) + ( $del_Max / 2 ) ) / $del_Max;
$del_B = ( ( ( $var_Max  - $var_B ) / 6 ) + ( $del_Max / 2 ) ) / $del_Max;

if ($var_R == $var_Max) $H = $del_B - $del_G;
else if ($var_G == $var_Max) $H = ( 1 / 3 ) + $del_R - $del_B;
else if ($var_B == $var_Max) $H = ( 2 / 3 ) + $del_G - $del_R;

if ($H<0) $H++;
if ($H>1) $H--;
}

$HSL['h'] = $H;
$HSL['s'] = $S;
$HSL['v'] = $V;

return $HSL;
}

function hsvtorgb ($H, $S, $V) 
{
$RGB = array();

if($S == 0)
{
$R = $G = $B = $V * 255;
}
else
{
$var_H = $H * 6;
$var_i = floor( $var_H );
$var_1 = $V * ( 1 - $S );
$var_2 = $V * ( 1 - $S * ( $var_H - $var_i ) );
$var_3 = $V * ( 1 - $S * (1 - ( $var_H - $var_i ) ) );

if ($var_i == 0) { $var_R = $V ; $var_G = $var_3 ; $var_B = $var_1 ; }
else if ($var_i == 1) { $var_R = $var_2 ; $var_G = $V ; $var_B = $var_1 ; }
else if ($var_i == 2) { $var_R = $var_1 ; $var_G = $V ; $var_B = $var_3 ; }
else if ($var_i == 3) { $var_R = $var_1 ; $var_G = $var_2 ; $var_B = $V ; }
else if ($var_i == 4) { $var_R = $var_3 ; $var_G = $var_1 ; $var_B = $V ; }
else { $var_R = $V ; $var_G = $var_1 ; $var_B = $var_2 ; }

$R = $var_R * 255;
$G = $var_G * 255;
$B = $var_B * 255;
}

$RGB['r'] = $R;
$RGB['g'] = $G;
$RGB['b'] = $B;

return $RGB;
}

Другие советы

Преобразование TrueColor в палитру всегда собирается включать потери цвета, если только ваша палтовая таблица достаточно большая, чтобы удерживать каждый уникальный цвет на изображении. Lamborghini может очень хорошо иметь больше, чем (сказать) 255 оттенков желтого, а затем вам все еще нуждаются в палитрах для остальной части изображения сверху этого. Вот почему есть триколорные изображения. Там нет палитры, но каждый пиксель может иметь свой собственный триплет RGB, чтобы более точно представлять оригинальную сцену.

Что говорят, я не вижу, как преобразование трюсиновой картинки изменится желтею на красный, как в ваших образцах изображения. Как именно вы делаете эту преобразование палитры? Отборка каждого пикселя и делая какую-то трансформацию на нем?

Как насчет этой функции: http://www.php.net/manual/en/function.imagetruecolortopalette.php.. Отказ Может возникнуть немного возиться с количеством цветов, чтобы получить его правильно.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top