In the previous note by -> lukeross at sys3175 dot co dot uk <- there is a coding error in the for() loops. After correcting the error, I found that this function did a great job of converting color images to 2 colors.
The following is the corrected function code:
function ImageColorFloydSteinberg($dst_img, $src_img) {
ImageColorAllocate($dst_img, 0,0,0);
ImageColorAllocate($dst_img, 255,255,255);
$isx = ImageSX($src_img);
$isy = ImageSY($src_img);
$grey_img = ImageCreate($isx, $isy);
for ($a = 0; $a <= 255; $a++) ImageColorAllocate($grey_img, $a,$a,$a);
$isx -= 1; // To correct pixel count in source image width starting from 0
$isy -= 1; // Correcting pixel count in source image height starting from 0
for($x = 0; $x <= $isx; $x++) {
for($y = 0; $y <= $isy; $y++) {
$color = ImageColorsForIndex($src_img, ImageColorAt($src_img, $x, $y));
$greyscale = .299 * $color["red"] + .587 * $color["green"] + .114 * $color["blue"];
ImageSetPixel($grey_img, $x, $y, ImageColorClosest($grey_img, $greyscale, $greyscale, $greyscale));
}
}
for($x = 0; $x <= $isx; $x++) {
for($y = 0; $y <= $isy; $y++) {
$color = ImageColorsForIndex($grey_img, ImageColorAt($grey_img, $x, $y));
if ($color["red"] > 128) {
ImageSetPixel($dst_img, $x, $y, ImageColorClosest($dst_img,255,255,255));
$err = $color["red"] - 255;
} else {
ImageSetPixel($dst_img, $x, $y, ImageColorClosest($dst_img,0,0,0));
$err = $color["red"];
}
if ($x != $isx) {
$color2 = ImageColorsForIndex($grey_img, ImageColorAt($grey_img, $x+1, $y));
$newgrey = $color2["red"] + $err * 7 / 16;
ImageSetPixel($grey_img, $x+1, $y, ImageColorClosest($grey_img,$newgrey, $newgrey, $newgrey));
}
if ($x != 0) {
$color2 = ImageColorsForIndex($grey_img, ImageColorAt($grey_img, $x-1, $y));
$newgrey = $color2["red"] + $err * 3 / 16;
ImageSetPixel($grey_img, $x-1, $y, ImageColorClosest($grey_img,$newgrey, $newgrey, $newgrey));
}
if ($y != $isy) {
$color2 = ImageColorsForIndex($grey_img, ImageColorAt($grey_img, $x, $y+1));
$newgrey = $color2["red"] + $err * 5 / 16;
ImageSetPixel($grey_img, $x, $y+1, ImageColorClosest($grey_img,$newgrey, $newgrey, $newgrey));
}
if ($x != $isx && $y != $isy) {
$color2 = ImageColorsForIndex($grey_img, ImageColorAt($grey_img, $x+1, $y+1));
$newgrey = $color2["red"] + $err / 16;
ImageSetPixel($grey_img, $x+1, $y+1, ImageColorClosest($grey_img,$newgrey, $newgrey, $newgrey));
}
}
}
imagedestroy($grey_img);
}
imagewbmp
(PHP 4 >= 4.0.1, PHP 5)
imagewbmp — Resmi bir dosyaya veya tarayıcıya çıktılar
Açıklama
$resim
[, string $dosyaismi
[, int $artalan
]] )Belirtilen resmi WBMP biçemli olarak çıktılar veya kaydeder.
Değiştirgeler
-
resim -
imagecreatetruecolor() gibi bir resim oluşturma işlevinden dönen bir resim verisi.
-
dosyaismi -
Resmin kaydedileceği dosyanın yolu. Belirtilmez veya
NULLverilirse doğrudan ham resim akımı çıktılanır. -
artalan -
imagecolorallocate() tarafından sağlanmış bir tanıtıcı ile bir artalan rengi tanımlayabilirsiniz. Öntanımlı artalan rengi siyahtır.
Dönen Değerler
Başarı durumunda TRUE, başarısızlık durumunda FALSE döner.
Örnekler
Örnek 1 - Bir WBMP resmini çıktılamak
<?php
// Boş bir resim oluşturup üzerine bir metin ekleyelim
$resim = imagecreatetruecolor(120, 20);
$metin_rengi = imagecolorallocate($resim, 233, 14, 91);
imagestring($resim, 1, 5, 5, 'Bir deneme dizgesi', $metin_rengi);
// İçerik türü başlığını ayarlayalım: image/vnd.wap.wbmp
// İpucu: içerik türleri için image_type_to_mime_type() işlevine bakınız
header('Content-type: image/vnd.wap.wbmp');
// Resmi çıktılayalım
imagewbmp($resim);
// Belleği serbest bırakalım
imagedestroy($resim);
?>
Örnek 2 - Bir WBMP resminin kaydedilmesi
<?php
// Boş bir resim oluşturup üzerine bir metin ekleyelim
$resim = imagecreatetruecolor(120, 20);
$metin_rengi = imagecolorallocate($resim, 233, 14, 91);
imagestring($resim, 1, 5, 5, 'Bir deneme dizgesi', $metin_rengi);
// Resmi kaydedelim
imagewbmp($im, 'dnm.wbmp');
// Belleği serbest bırakalım
imagedestroy($im);
?>
Örnek 3 - Resmi farklı bir artalan rengi ile çıktılamak
<?php
// Boş bir resim oluşturup üzerine bir metin ekleyelim
$resim = imagecreatetruecolor(120, 20);
$metin_rengi = imagecolorallocate($resim, 233, 14, 91);
imagestring($resim, 1, 5, 5, 'Bir deneme dizgesi', $metin_rengi);
// İçerik türü başlığını ayarlayalım: image/vnd.wap.wbmp
// İpucu: içerik türleri için image_type_to_mime_type() işlevine bakınız
header('Content-type: image/vnd.wap.wbmp');
// Yeni artalan rengini ayarlayalım
$artalan_rengi = imagecolorallocate($resim, 255, 0, 0);
imagewbmp($resim, NULL, $artalan_rengi);
// Free up memory
imagedestroy($resim);
?>
Notlar
Bilginize:
WBMP desteği sadece PHP, GD kütüphanesinin 1.8 veya sonraki sürümleri ile derlenmişse mevcuttur.
Ayrıca Bakınız
- image2wbmp() - Bir dosyaya veya tarayıcıya bir WBMP resmi çıktılar
- imagepng() - Tarayıcıya veya bir dosyaya bir PNG resmi çıktılar
- imagegif() - Bir dosyaya veya tarayıcıya bir GIF resmi çıktılar
- imagejpeg() - Tarayıcıya veya bir dosyaya bir JPEG resmi çıktılar
- imagetypes() - Kurulu PHP'nin desteklediği resim türlerini döndürür
As has been commented before, GD doesnt do a very good translation to 2-colours, especially for photos. The following routine converts to two colours, I believe using error diffusion (the algorithm's nicked off news). It's slow, but just about adequate for small images and low load. I suspect it can be made much more efficient :-)
function ImageColorFloydSteinberg($dst_img, $src_img) {
ImageColorAllocate($dst_img, 0,0,0);
ImageColorAllocate($dst_img, 255,255,255);
$grey_img = ImageCreate(ImageSX($src_img), ImageSY($src_img));
for ($a = 0; $a <= 255; $a++) ImageColorAllocate($grey_img, $a,$a,$a);
for($x = 0; $x <= ImageSX($src_img); $x++) {
for($y = 0; $y <= ImageSY($src_img); $y++) {
$color = ImageColorsForIndex($src_img, ImageColorAt($src_img, $x, $y));
$greyscale = .299 * $color["red"] + .587 * $color["green"] + .114 * $color["blue"];
ImageSetPixel($grey_img, $x, $y, ImageColorClosest($grey_img, $greyscale, $greyscale, $greyscale));
}
}
for($x = 0; $x <= ImageSX($src_img); $x++) {
for($y = 0; $y <= ImageSY($src_img); $y++) {
$color = ImageColorsForIndex($grey_img, ImageColorAt($grey_img, $x, $y));
if ($color["red"] > 128) {
ImageSetPixel($dst_img, $x, $y, ImageColorClosest($dst_img,255,255,255));
$err = $color["red"] - 255;
} else {
ImageSetPixel($dst_img, $x, $y, ImageColorClosest($dst_img,0,0,0));
$err = $color["red"];
}
if ($x != ImageSx($src_img)) {
$color2 = ImageColorsForIndex($grey_img, ImageColorAt($grey_img, $x+1, $y));
$newgrey = $color2["red"] + $err * 7 / 16;
ImageSetPixel($grey_img, $x+1, $y, ImageColorClosest($grey_img,$newgrey, $newgrey, $newgrey));
}
if ($x != 0) {
$color2 = ImageColorsForIndex($grey_img, ImageColorAt($grey_img, $x-1, $y));
$newgrey = $color2["red"] + $err * 3 / 16;
ImageSetPixel($grey_img, $x-1, $y, ImageColorClosest($grey_img,$newgrey, $newgrey, $newgrey));
}
if ($y != ImageSy($src_img)) {
$color2 = ImageColorsForIndex($grey_img, ImageColorAt($grey_img, $x, $y+1));
$newgrey = $color2["red"] + $err * 5 / 16;
ImageSetPixel($grey_img, $x, $y+1, ImageColorClosest($grey_img,$newgrey, $newgrey, $newgrey));
}
if ($x != ImageSx($src_img) && $y != ImageSy($src_img)) {
$color2 = ImageColorsForIndex($grey_img, ImageColorAt($grey_img, $x+1, $y+1));
$newgrey = $color2["red"] + $err / 16;
ImageSetPixel($grey_img, $x+1, $y+1, ImageColorClosest($grey_img,$newgrey, $newgrey, $newgrey));
}
}
}
imagedestroy($grey_img);
}
To output your WBMP, use
ImageWBMP($final_img, "", ImageColorClosest(255,255,255));
