2010-09-16 11 views
5

Trong PHP GD làm thế nào bạn có thể chuyển đổi một truecolor hình ảnh đến một bảng mà không làm mất bất kỳ màu sắc. Với imagetruecolortopalletekhông hoạt động. Tôi có một chức năng chạy qua tất cả các màu sắc và lọc chúng (ví dụ: màu xám). và Nó không giữ lại tất cả các màu, chẳng hạn như hình ảnh này của một Lamborghini-PHP GD bảng màu

Hình

alt text

Đây là mã của tôi

$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); 

Và nó trông giống như thế này

alt text

Bạn có thể thấy nó mất màu. Có bất kỳ giải pháp nào?

Ngoài ra tôi không nghĩ rằng nó đã làm với mã của tôi nhưng làm thế nào imagetruecolortopalette đầu ra nó

+0

Chuyển đổi bảng màu của thư viện GD nhanh nhưng rất không chính xác. Nếu bạn muốn sử dụng bảng màu, tôi khuyên bạn nên sử dụng dòng lệnh [pngquant] (https://github.com/pornel/improved-pngquant) thông qua [popen()] (http://php.net/popen) - trong khi điều này sẽ lỏng * một số * màu sắc, sự mất mát sẽ không được như xấu. – Kornel

Trả lời

5

Kiểm tra lợi tức trên imagecolorstotal, bạn luôn nhận được 256 màu khi trả lại bất kể bạn đặt số lượng màu được dithered đến mức nào. PNG-8 & Định dạng GIF chỉ hỗ trợ các bảng màu có tối đa 256 màu. Vì vậy, ngay cả khi bạn có thể sử dụng nhiều hơn 256 trong một bảng màu, bạn sẽ phải lưu nó trở lại như màu sắc thực sự cho bất cứ ai để có thể sử dụng nó, do đó làm cho toàn bộ quá trình chuyển đổi một sự lãng phí thời gian. Nói cách khác, imagetruecolortopallete có giới hạn trên 256 màu, bạn không thể lên cao hơn.

Dưới đây là cách bạn có thể làm điều đó trong truecolor, mặc dù đó là tài nguyên chuyên sâu. Có thể nhìn vào imagemagick nếu bạn muốn làm điều này hiệu quả hơn.

$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'); 

Chỉnh sửa: Thêm rgbtohsv & chức năng hsvtorgb. Tôi không viết những chức năng này.

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; 
} 
+0

'rgbtohsv' và' hsvtorgb' – EscoMaji

+0

@EscoMaji Tôi đã thêm những chức năng này vào bài đăng là gì. – Klinky

0

Làm thế nào về chức năng này: http://www.php.net/manual/en/function.imagetruecolortopalette.php. Nó có thể mất một số rối tung với số lượng màu sắc để có được nó, mặc dù.

+0

Đó là những gì tôi đã cố gắng, xem chỉnh sửa của tôi –

+0

Bạn đã bật tính năng 'dither' chưa? Và bạn đã chỉ định bao nhiêu màu? –

+0

Đây là những gì tôi có 'imagetruecolortopalette ($ img, true, 256);' do đó, có –

2

chuyển đổi truecolor thành bảng màu luôn liên quan đến việc mất màu, trừ khi bảng pallette đủ lớn để giữ mọi màu duy nhất trong hình ảnh. Lamborghini có thể có nhiều hơn (nói) 255 sắc thái của màu vàng một mình, và sau đó bạn vẫn cần các khe bảng màu cho phần còn lại của hình ảnh trên đó. Đó là lý do tại sao có hình ảnh truecolor. Không có bảng màu, nhưng mỗi điểm ảnh có thể có bộ ba RGB riêng để thể hiện chính xác hơn cảnh gốc.

Điều đó đang được nói, tôi không thể thấy cách chuyển đổi hình ảnh truecolor sẽ thay đổi màu vàng sang màu đỏ như trong hình ảnh mẫu của bạn. Làm thế nào chính xác là bạn đang làm chuyển đổi bảng màu này? Lấy mẫu từng pixel và thực hiện một số loại chuyển đổi trên nó?

+0

Hãy để tôi chỉnh sửa để giải thích –

+0

Điều gì sẽ xảy ra nếu bạn loại bỏ rgb-> hsv-> rgb roundtrip? Xem những gì imagetruecolortopalette sản xuất? Tôi đoán bạn đã có một lỗi trong rgbtohsv và/hoặc hsvtorgb chức năng, như ngay cả một 'xấu' máy phát điện bảng sẽ không sản xuất nhiều màu đỏ từ một nguồn hình ảnh mà về cơ bản không có. –

+0

Không, tôi đã giải quyết vấn đề bằng cách sử dụng bảng màu tùy chọn (cho tốc độ) và truecolor về chất lượng. –