>> zmorris at zsculpt dot com
I don't have the imageColorMatch() function on my server, but I could slighty improve the quality of the GIF/PNG image by converting it first to 256 colors, then to true colors and finally to the desired number of colors.
<?php
$dither = true;
$colors = 64;
$tmp = imageCreateFromJpeg('example.jpg');
$width = imagesX($tmp);
$height = imagesY($tmp);
imageTrueColorToPalette($tmp, $dither, 256);
$image = imageCreateTrueColor($width, $height);
imageCopy($image, $tmp, 0, 0, 0, 0, $width, $height);
imageDestroy($tmp);
imageTrueColorToPalette($image, $dither, $colors);
?>
Final $image will still have less than 64 colors, but more than if it was directly converted to 64 colors, and they match the JPEG image more.
Dunno why true colors to palette conversions are such a problem...
imagetruecolortopalette
(PHP 4 >= 4.0.6, PHP 5)
imagetruecolortopalette — Convertir una imagen de color verdadero en una imagen de paleta
Descripción
$image
, bool $dither
, int $ncolors
)imagetruecolortopalette() convierte una imagen de color verdadero en una imagen de paleta. El código para esta función fue sacado originalmente del código de la biblioteca de Independent JPEG Group, el cual es excelente. El código ha sido modificado para preservar tanta información alfa como sea posible en la paleta resultante, además de preservar colores tanto como sea posible. Esto no funciona tan bien como se podría esperar. Normalmente es mejor simplemente producir una imagen de salida de color verdadero en su lugar, lo que garantiza la calidad más alta de salida.
Parámetros
-
image -
Un recurso image, es devuelto por una de las funciones de creación de imágenes, como imagecreatetruecolor().
-
dither -
Indica si la imagen debería ser entramada - si es
TRUEse usará el entramado, lo que resultará en una imágen más moteada pero con una aproximación de color mejor. -
ncolors -
Establece el número máximo de colores que se deberían retener en la paleta.
Valores devueltos
Devuelve TRUE en caso de éxito o FALSE en caso de error.
Ejemplos
Ejemplo #1 Convertir una imagen de color verdadero en una imagen de paleta
<?php
// Crear una nueva imagen de color verdadero
$im = imagecreatetruecolor(100, 100);
// Convertirla a paleta sin entramado y 255 colores
imagetruecolortopalette($im, false, 255);
// Guardar la imagen
imagepng($im, './paletteimage.png');
imagedestroy($im);
?>
Notas
Nota: Esta función require GD 2.0.1 o superior (se recomienda 2.0.28 o superior).
a basic palette to true color function
<?php
function imagepalettetotruecolor(&$img)
{
if (!imageistruecolor($img))
{
$w = imagesx($img);
$h = imagesy($img);
$img1 = imagecreatetruecolor($w,$h);
imagecopy($img1,$img,0,0,0,0,$w,$h);
$img = $img1;
}
}
?>
Sometimes this function gives ugly/dull colors (especially when ncolors < 256). Here is a replacement that uses a temporary image and ImageColorMatch() to match the colors more accurately. It might be a hair slower, but the file size ends up the same:
<?php
function ImageTrueColorToPalette2( $image, $dither, $ncolors )
{
$width = imagesx( $image );
$height = imagesy( $image );
$colors_handle = ImageCreateTrueColor( $width, $height );
ImageCopyMerge( $colors_handle, $image, 0, 0, 0, 0, $width, $height, 100 );
ImageTrueColorToPalette( $image, $dither, $ncolors );
ImageColorMatch( $colors_handle, $image );
ImageDestroy( $colors_handle );
}
?>
The palette created by this function often looks quite awful (at least it did on all of my test images). A better way to convert your true-colour images is by first making a resized copy of them with imagecopyresampled() to a 16x16 pixel destination. The resized image then contains only 256 pixels, which is exactly the number of colours you need. These colours usually look a lot better than the ones generated by imagetruecolortopalette().
The only disadvantage to this method I have found is that different-coloured details in the original image are lost in the conversion.
If you open a truecolor image (with imageCreateFromPng for example), and you save it directly to GIF format with imagegif, you can have a 500 internal server error. You must use imageTrueColorToPalette to reduce to 256 colors before saving the image in GIF format.
TrueColor images should be converted to Palette images with this function. So, if you want to use imagecolorstotal() function [ http://php.net/manual/en/function.imagecolorstotal.php ] , you should first convert the image to a palette image with imagetruecolortopalette();
If You know which palette to use (e.g. 255 colors greyscale) You may achieve better results using the following way:
1. Create new image
2. Apply palette
3. imagecopy() the content
This is especially helpful if you created a greyscale picture in trucolor-mode (to use antialiasing for example) but need to send it as palette (to use transparency in Internet Explorer).
The following example will *not* create great results from "real" truecolor images but works well on grey truecolor images:
<?PHP
function imageTruecolorToGrayscale(&$image) {
$copy = $image;
$dx = imagesx($image);
$dy = imagesy($image);
$image = imagecreate($dx, $dy);
// 254 Colors + 1 reserved for transparency
$transparency = imagecolorallocate($image, 0, 255, 0);
$max = 255; $dd = 254;
for ($i=0; $i<$dd; $i++) {
$val = round($max * $i / ($dd-1));
imagecolorallocate($image, $val, $val, $val);
}
imagecopy($image, $copy, 0, 0, 0, 0, $dx, $dy);
imagedestroy($copy);
return $transparency;
}
?>
