php gd pixelate too sharp - php

i have this script for pixelize my images the script is working but i want more smooth edges:
$imgfile = 'batman.jpg';
$image = ImageCreateFromJPEG($imgfile);
$imagex = imagesx($image);
$imagey = imagesy($image);
$pixelate_amount = 10;
$tmpImage = ImageCreateTrueColor($imagex, $imagey);
imagecopyresized($tmpImage, $image, 0, 0, 0, 0, round($imagex / $pixelate_amount), round($imagey / $pixelate_amount), $imagex, $imagey);
$pixelated = ImageCreateTrueColor($imagex, $imagey);
imagecopyresized($pixelated, $tmpImage, 0, 0, 0, 0, $imagex, $imagey, round($imagex / $pixelate_amount), round($imagey / $pixelate_amount));
header("Content-Type: image/jpeg");
imageJPEG($pixelated, "", 100);
I have:
this produce:
is there anything i miss?

Here's what you need (script I currently use). This script is based from the script at http://www.talkphp.com/19670-post1.html:
function convertToPixel($im, $size) {
$size = (int)$size;
$sizeX = imagesx($im);
$sizeY = imagesy($im);
if($sizeX < 3 && $sizeX < 3) { // or you can choose any size you want
return;
}
for($i = 0;$i < $sizeX; $i += $size) {
for($j = 0;$j < $sizeY; $j += $size) {
$colors = Array('alpha' => 0, 'red' => 0, 'green' => 0, 'blue' => 0, 'total' => 0);
for($k = 0; $k < $size; ++$k) {
for($l = 0; $l < $size; ++$l) {
if($i + $k >= $sizeX || $j + $l >= $sizeY) {
continue;
}
$color = imagecolorat($im, $i + $k, $j + $l);
imagecolordeallocate($im, $color);
$colors['alpha'] += ($color >> 24) & 0xFF;
$colors['red'] += ($color >> 16) & 0xFF;
$colors['green'] += ($color >> 8) & 0xFF;
$colors['blue'] += $color & 0xFF;
++$colors['total'];
}
}
$color = imagecolorallocatealpha($im, $colors['red'] / $colors['total'], $colors['green'] / $colors['total'], $colors['blue'] / $colors['total'], $colors['alpha'] / $colors['total']);
imagefilledrectangle($im, $i, $j, ($i + $size - 1), ($j + $size - 1), $color);
}
}
}
header('Content-type: image/jpg');
$im = imagecreatefromjpeg($imgfile);
convertToPixel($im, 15);
imagejpeg($im, '', 100);
This will produce:
You can also change the value passed in convertToPixel to modify the pixel size.
)

Use imagecopyresampled() instead of imagecopyresized().
http://php.net/manual/en/function.imagecopyresampled.php

Related

Calculate image variance in Imagick

How can I calculate the variation of an image in Imagick? I already converted the image in greyscale, but through native functions I can only get Mean and Standard Deviation.
My approach is generating two noise images and calculate the Euclidian difference between both RGB pixel color values.
This will certainly look better with real images for example of a webcam.
$getRandomNoiseImage = function ($x, $y, $steps): Imagick {
$draw = new ImagickDraw();
$draw->setResolution($x, $y);
$draw->setStrokeWidth(1);
$pixel = new ImagickPixel();
for ($i = 0; $i < $x; $i += $steps) {
for ($j = 0; $j < $y; $j += $steps) {
$color = join(',', [rand(0, 255), rand(0, 255), rand(0, 255)]);
$pixel->setColor("rgb($color)");
$draw->setFillColor($pixel);
$draw->setStrokeColor($pixel);
$draw->rectangle($i, $j, $i + $steps, $j + $steps);
}
}
$im = new Imagick();
$im->newImage($x, $y, new ImagickPixel('black'));
$im->drawImage($draw);
return $im;
};
$width = 64;
$height = 64;
$im1 = $getRandomNoiseImage($width, $height, 16);
$im2 = $getRandomNoiseImage($width, $height, 16);
$draw = new ImagickDraw();
$draw->setResolution($width, $height);
$draw->setStrokeWidth(1);
$pixel = new ImagickPixel();
for ($i = 0; $i < $width; $i++) {
for ($j = 0; $j < $height; $j++) {
$c1 = $im1->getImagePixelColor($i, $j)->getColor(0);
$c2 = $im2->getImagePixelColor($i, $j)->getColor(0);
$color = [
sqrt(abs($c2['r']**2 - $c1['r']**2)),
sqrt(abs($c2['g']**2 - $c1['g']**2)),
sqrt(abs($c2['b']**2 - $c1['b']**2)),
];
$pixel->setColor(sprintf('rgb(%d,%d,%d)', ...$color));
$draw->setFillColor($pixel);
$draw->setStrokeColor($pixel);
$draw->rectangle($i, $j, $i + 1, $j + 1);
}
}
$im3 = new Imagick();
$im3->newImage($width, $height, new ImagickPixel('black'));
$im3->drawImage($draw);
$im1->writeImage('image1.png');
$im2->writeImage('image2.png');
$im3->writeImage('image3.png');

PHP Remove black bar from image

I have a script that crops and rotates an image.
But i end up with a black bar in my image:
http://prntscr.com/r9l1w5 (screenshot)
I found a script on the internet, that is able to remove black bars on images. But i am unable to make it work together on 1 page.
(view-image.php) My script:
<?php
$filenamegetter = $_GET['imgid'];
$degree = 0;
// File and rotation
$filename = 'img/' . $filenamegetter . '';
$degrees = $degree;
$percent = 0.30;
// Content type
header('Content-type: image/jpeg');
// Get new sizes
list($width, $height) = getimagesize($filename);
if ($width > "1000") {
$newwidth = $width * $percent;
$newheight = $height * $percent;
} else {
$newwidth = $width;
$newheight = $height;
}
// Load
$thumb = imagecreatetruecolor($newwidth, $newheight);
$source = imagecreatefromjpeg($filename);
// Rotate
$rotate = imagerotate($source, $degrees, 0);
imagecopyresized($thumb, $rotate, 0, 0, 0, 0, $newwidth, $newheight, $width, $height);
imagejpeg($thumb);
// Free the memory
imagedestroy($source);
imagedestroy($thumb);
?>
The anti black bar script i wish it works together with:
<?php
$image_path = "image.jpg";
$jpg = imagecreatefromjpeg($image_path);
$black = array("red" => 0, "green" => 0, "blue" => 0, "alpha" => 0);
$removeLeft = 0;
for($x = 0; $x < imagesx($jpg); $x++) {
for($y = 0; $y < imagesy($jpg); $y++) {
if(imagecolorsforindex($jpg, imagecolorat($jpg, $x, $y)) != $black){
break 2;
}
}
$removeLeft += 1;
}
$removeRight = 0;
for($x = imagesx($jpg)-1; $x > 0; $x--) {
for($y = 0; $y < imagesy($jpg); $y++) {
if(imagecolorsforindex($jpg, imagecolorat($jpg, $x, $y)) != $black){
break 2;
}
}
$removeRight += 1;
}
$removeTop = 0;
for($y = 0; $y < imagesy($jpg); $y++) {
for($x = 0; $x < imagesx($jpg); $x++) {
if(imagecolorsforindex($jpg, imagecolorat($jpg, $x, $y)) != $black){
break 2;
}
}
$removeTop += 1;
}
$removeBottom = 0;
for($y = imagesy($jpg)-1; $y > 0; $y--) {
for($x = 0; $x < imagesx($jpg); $x++) {
if(imagecolorsforindex($jpg, imagecolorat($jpg, $x, $y)) != $black){
break 2;
}
}
$removeBottom += 1;
}
$cropped = imagecreatetruecolor(imagesx($jpg) - ($removeLeft + $removeRight), imagesy($jpg) - ($removeTop + $removeBottom));
imagecopy($cropped, $jpg, 0, 0, $removeLeft, $removeTop, imagesx($cropped), imagesy($cropped));
header("Content-type: image/jpeg");
imagejpeg($cropped); //change to `imagejpeg($cropped, $image_path);` to save
imagedestroy($cropped);
imagedestroy($jpg);
I'd like to know how i can implent the anti black bar script in my script. I tried multiple ways but i end up with a empty page.
For anyone having problems with imagecopyresampled or imagerotate with black bars on background, I have found a code example here:
There are a lot of factors but for me the problem was the new size after rotating the image.
https://qna.habr.com/q/646622#answer_1417035
// get image sizes (X,Y)
$wx = imagesx($imageW);
$wy = imagesy($imageW);
// create a new image from the sizes on transparent canvas
$new = imagecreatetruecolor($wx, $wy);
$transparent = imagecolorallocatealpha($new, 0, 0, 0, 127);
$rotate = imagerotate($imageW, 280, $transparent);
imagealphablending($rotate, true);
imagesavealpha($rotate, true);
// get the newest image X and Y
$ix = imagesx($rotate);
$iy = imagesy($rotate);
//copy the image to the canvas
imagecopyresampled($destImg, $rotate, 940, 2050, 0, 0, $ix, $iy, $ix, $iy);

php gd image png watermark on jpg file produces weird result

Trying to add a transparent PNG watermark to jpg images get's me different results either if i'm on localhost or production server.
Here's the results...
On my localhost (PHP Version 5.6.24)
On production server (PHP Version 5.5.9-1ubuntu4.21)
I don't even know what to call this problem of the blue color turning pink and the logo doesn't get correctly rendered...
The code is this:
function getBrightness($gdHandle) {
$width = imagesx($gdHandle);
$height = imagesy($gdHandle);
$totalBrightness = 0;
for ($x = 0; $x < $width; $x++) {
for ($y = 0; $y < $height; $y++) {
$rgb = imagecolorat($gdHandle, $x, $y);
$red = ($rgb >> 16) & 0xFF;
$green = ($rgb >> 8) & 0xFF;
$blue = $rgb & 0xFF;
$totalBrightness += (max($red, $green, $blue) + min($red, $green, $blue)) / 2;
}
}
// imagedestroy($gdHandle);
return ($totalBrightness / ($width * $height)) / 2.55;
}
function render_text_on_gd_image(&$source_gd_image, $text, $font, $size, $color, $opacity, $rotation, $bpx, $bpy, $wnewx) {
$source_width = imagesx($source_gd_image);
$source_height = imagesy($source_gd_image);
$bb = imagettfbbox($size, $rotation, $font, $text);
$x0 = min($bb[0], $bb[2], $bb[4], $bb[6]);
$x1 = max($bb[0], $bb[2], $bb[4], $bb[6]);
$y0 = min($bb[1], $bb[3], $bb[5], $bb[7]);
$y1 = max($bb[1], $bb[3], $bb[5], $bb[7]);
$bb_width = abs($x1 - $x0);
$bb_height = abs($y1 - $y0);
$alpha_color = imagecolorallocatealpha(
$source_gd_image,
hexdec(substr($color, 0, 2)),
hexdec(substr($color, 2, 2)),
hexdec(substr($color, 4, 2)),
127 * (100 - $opacity) / 100
);
return imagettftext($source_gd_image, $size, $rotation, $bpx + $wnewx/2 - $bb_width/2 , $bpy, $alpha_color, $font, $text);
}
$val = array();
//$val["displayName"] = "Administrador";
$val["displayName"] = "Afonso Ferreira Gomes";
$val["relFile"] = "imagem.jpg";
list($val["width_original"], $val["height_original"]) = getimagesize($val["relFile"]);
if ($val["width_original"] > $val["height_original"] && $val["width_original"] >= 1200) {
$val["height_resized"] = $val["height_original"] * (1200/$val["width_original"]);
$val["width_resized"] = 1200;
} elseif ($val["height_original"] > $val["width_original"] && $val["height_original"] >= 1200) {
$val["height_resized"] = 1200;
$val["width_resized"] = (1200/$val["height_original"]) * $val["width_original"];
} else {
$val["height_resized"] = $val["height_original"];
$val["width_resized"] = $val["width_original"];
}
$i = imagecreatefromjpeg($val["relFile"]);
$i = imagescale($i, $val["width_resized"], $val["height_resized"]);
$val["width_new"] = imagesx($i);
$val["height_new"] = imagesy($i);
if ($val["width_new"] < $val["height_new"]) {
$val["portait"] = true;
$val["smallest"] = $val["width_new"];
} else {
$val["portait"] = false;
$val["smallest"] = $val["height_new"];
}
/* GERAR WATERMARK LOGOTIPO */
$val["racio"] = 0.20;
$val["marLeft"] = 40;
$val["marBottom"] = 40;
$val["bright"] = getBrightness($i);
if ($val["bright"] < 30) {
$val["opacidade"] = 20;
} else {
$val["opacidade"] = 40;
}
$w = imagecreatefrompng("jbw_260_40.png");
if ($val["portait"]) {
$val["water_width"] = $val["width_new"] * $val["racio"];
$val["water_height"] = $val["width_new"] * $val["racio"];
} else {
$val["water_width"] = $val["height_new"] * $val["racio"];
$val["water_height"] = $val["height_new"] * $val["racio"];
}
$wnew = imagescale($w, $val["water_width"], $val["water_height"]);
$val["water_width"] = imagesx($wnew);
$val["water_height"] = imagesy($wnew);
/* GERAR WATERMARK TEXTO AUTOR */
if ($val["displayName"] == "Administrador") {
$val["autor"] = "";
$val["marBottom"] = 20;
$val["marLeft"] = 20;
} else {
$val["autor"] = $val["displayName"];
}
// PRIMEIRO E ULTIMO NOME SÓ!!
$autorNomes = explode(" ", $val["autor"]);
if (count($autorNomes) >= 2) {
$val["autor"] = $autorNomes[0] . " " . $autorNomes[count($autorNomes) - 1];
} else {
$val["autor"] = $autorNomes[0];
}
$font = "../font/Montserrat.ttf";
$color = "FFFFFF";
$flagSize = false;
$val["fontSize"] = 12;
for ($size = 7; $size <= 50; $size += 0.5) {
$bb = imagettfbbox($size, 0, $font, $val["autor"]);
$x0 = min($bb[0], $bb[2], $bb[4], $bb[6]);
$x1 = max($bb[0], $bb[2], $bb[4], $bb[6]);
$y0 = min($bb[1], $bb[3], $bb[5], $bb[7]);
$y1 = max($bb[1], $bb[3], $bb[5], $bb[7]);
$val["bbox_width"] = abs($x1 - $x0);
$val["bbox_height"] = abs($y1 - $y0);
if (($val["bbox_width"] >= $val["water_width"] && !$flagSize) || $size == 50) {
$val["fontSize"] = $size;
$flagSize = true;
break;
}
}
$val["posY_water"] = $val["height_new"] - $val["water_height"] - $val["marBottom"];
$val["posY_text"] = $val["height_new"] - $val["marBottom"] + $val["bbox_height"] - 5;
imagecopy($i, $wnew, $val["marLeft"], $val["posY_water"] , 0, 0, $val["water_width"], $val["water_height"]);
render_text_on_gd_image($i, $val["autor"], $font, $val["fontSize"], $color, $val["opacidade"] ,0 , $val["marLeft"] , $val["posY_text"], $val["water_width"]);
// echo "<pre>"; print_r($val); echo "</pre>"; die;
/* OUTPUT IMAGEM E LIMPA BUFFER */
header('Content-type: image/png');
imagepng($i);
imagedestroy($i);
imagedestroy($w);
And this are the gd section of phpinfo for localhost and production server
What am I missing? this is driving me insane!
Those issues almost always object to the alpha channel of either the source or destination not beeing preserved or the output not really beeing true color.
Try using the imagesavealpha() function and search for "alpha" in the comments of the PHP documentation because there are many people having solutions to similiar issues.
This comment might be helpful and is kinda what Esko said:
http://php.net/manual/en/function.imagecreatefrompng.php#90364
Basically it copies an image to a buffer using imagecreatetruecolor().
I'm having the same issue. The imageScale function in Ubuntu seems to turn greens and blues to pink. Solution could be to use imagecopyresampled and imagecreatetruecolor. However this solution is way slower.

Replace the specific RGB color with another image using PHP

I derived a perfect color replace script from https://stackoverflow.com/a/32710756/1620626. I want to replace the target color with the image background. The original image is backgrounded with light green (rgb:0b255b1). I can replace it with blue but I don't have an idea how to replace with the image. Here's the script.
This is the original image.
Once I process this photo with the script. I've got this.
The script is perfectly replace the target color with the new one. Now I want to change from blue into the background. So the final idea is. This girl on the background image I chosen.
Here is the code:
<?php
//https://stackoverflow.com/a/32710756/1620626
function RGBtoHSL( $r, $g, $b ) {
$r /= 255;
$g /= 255;
$b /= 255;
$max = max( $r, $g, $b );
$min = min( $r, $g, $b );
$l = ( $max + $min ) / 2;
$d = $max - $min;
if( $d == 0 ){
$h = $s = 0;
} else {
$s = $d / ( 1 - abs( 2 * $l - 1 ) );
switch( $max ){
case $r:
$h = 60 * fmod( ( ( $g - $b ) / $d ), 6 );
if ($b > $g) {
$h += 360;
}
break;
case $g:
$h = 60 * ( ( $b - $r ) / $d + 2 );
break;
case $b:
$h = 60 * ( ( $r - $g ) / $d + 4 );
break;
}
}
return array( round( $h, 2 ), round( $s, 2 ), round( $l, 2 ) );
}
function HSLtoRGB( $h, $s, $l ){
$c = ( 1 - abs( 2 * $l - 1 ) ) * $s;
$x = $c * ( 1 - abs( fmod( ( $h / 60 ), 2 ) - 1 ) );
$m = $l - ( $c / 2 );
if ( $h < 60 ) {
$r = $c;
$g = $x;
$b = 0;
} else if ( $h < 120 ) {
$r = $x;
$g = $c;
$b = 0;
} else if ( $h < 180 ) {
$r = 0;
$g = $c;
$b = $x;
} else if ( $h < 240 ) {
$r = 0;
$g = $x;
$b = $c;
} else if ( $h < 300 ) {
$r = $x;
$g = 0;
$b = $c;
} else {
$r = $c;
$g = 0;
$b = $x;
}
$r = ( $r + $m ) * 255;
$g = ( $g + $m ) * 255;
$b = ( $b + $m ) * 255;
return array( floor( $r ), floor( $g ), floor( $b ) );
}
/* ---------------CHANGE THESE------------------- */
$colorToReplace = RGBtoHSL(0,255,1);//target color
$hueAbsoluteError = 7;//the more the clearer
$replacementColor = RGBtoHSL(0, 192, 239);//new color
/* ---------------------------------------------- */
$filename = 'images/01.png';
$im = imagecreatefrompng($filename);
$out = imagecreatetruecolor(imagesx($im), imagesy($im));
$transColor = imagecolorallocatealpha($out, 254, 254, 254, 127);
imagefill($out, 0, 0, $transColor);
for ($x = 0; $x < imagesx($im); $x++) {
for ($y = 0; $y < imagesy($im); $y++) {
$pixel = imagecolorat($im, $x, $y);
$red = ($pixel >> 16) & 0xFF;
$green = ($pixel >> 8) & 0xFF;
$blue = $pixel & 0xFF;
$alpha = ($pixel & 0x7F000000) >> 24;
$colorHSL = RGBtoHSL($red, $green, $blue);
if ((($colorHSL[0] >= $colorToReplace[0] - $hueAbsoluteError) && ($colorToReplace[0] + $hueAbsoluteError) >= $colorHSL[0])){
$color = HSLtoRGB($replacementColor[0], $replacementColor[1], $colorHSL[2]);
$red = $color[0];
$green= $color[1];
$blue = $color[2];
}
if ($alpha == 127) {
imagesetpixel($out, $x, $y, $transColor);
}
else {
imagesetpixel($out, $x, $y, imagecolorallocatealpha($out, $red, $green, $blue, $alpha));
}
}
}
imagecolortransparent($out, $transColor);
imagesavealpha($out, TRUE);
header('Content-type: image/png');
imagepng($out);
?>
You can just read two images, source and background, and take pixels from background image and set to the source.
Below is the last part of your code above which shows this idea:
$filename = 'images/01.png';
$bgFilename = 'images/background.png';
$im = imagecreatefrompng($filename);
$bg = imagecreatefrompng($bgFilename);
$out = imagecreatetruecolor(imagesx($im), imagesy($im));
$transColor = imagecolorallocatealpha($out, 254, 254, 254, 127);
imagefill($out, 0, 0, $transColor);
for ($x = 0; $x < imagesx($im); $x++) {
for ($y = 0; $y < imagesy($im); $y++) {
$pixel = imagecolorat($im, $x, $y);
$bgPixel = imagecolorat($bg, $x, $y);
$red = ($pixel >> 16) & 0xFF;
$green = ($pixel >> 8) & 0xFF;
$blue = $pixel & 0xFF;
$alpha = ($pixel & 0x7F000000) >> 24;
$colorHSL = RGBtoHSL($red, $green, $blue);
if ((($colorHSL[0] >= $colorToReplace[0] - $hueAbsoluteError) && ($colorToReplace[0] + $hueAbsoluteError) >= $colorHSL[0])){
// Instead of taking the replacementColor
/* $color = HSLtoRGB($replacementColor[0], $replacementColor[1], $colorHSL[2]); */
/* $red = $color[0]; */
/* $green= $color[1]; */
/* $blue = $color[2]; */
// We just take colors from the backround image pixel
$red = ($bgPixel >> 16) & 0xFF;
$green = ($bgPixel >> 8) & 0xFF;
$blue = $bgPixel & 0xFF;
}
if ($alpha == 127) {
imagesetpixel($out, $x, $y, $transColor);
}
else {
imagesetpixel($out, $x, $y, imagecolorallocatealpha($out, $red, $green, $blue, $alpha));
}
}
}
imagecolortransparent($out, $transColor);
imagesavealpha($out, TRUE);
header('Content-type: image/png');
imagepng($out);
The result can look like this:

Replace a color with another color in an image with PHP

Yes I know there are related questions available on stackoverflow but they are not perfectly work as per my need. I am trying to replace a color of an image with another color. In below code I am replacing (255,0,255) with (0,192,239).
Below code works but not perfectly replacing new color over pink(255,0,255) color some minor dots or border of pink color is still remaining as you can see in output image.
How can i get its perfect solution ?
<?php
$filename = 'img/Mascots_Aviators_General-copy.png';
$im = imagecreatefrompng($filename);
$out = imagecreatetruecolor(imagesx($im), imagesy($im));
$transColor = imagecolorallocatealpha($out, 254, 254, 254, 127);
imagefill($out, 0, 0, $transColor);
for ($x = 0; $x < imagesx($im); $x++) {
for ($y = 0; $y < imagesy($im); $y++) {
$pixel = imagecolorat($im, $x, $y);
$red = ($pixel >> 16) & 0xFF;
$green = ($pixel >> 8) & 0xFF;
$blue = $pixel & 0xFF;
$alpha = ($pixel & 0x7F000000) >> 24;
if ($red == 255 && $green == 0 && $blue == 255) {
$red = 0;
$green=192;
$blue =239;
}
if ($alpha == 127) {
imagesetpixel($out, $x, $y, $transColor);
}
else {
imagesetpixel($out, $x, $y, imagecolorallocatealpha($out, $red, $green, $blue, $alpha));
}
}
}
imagecolortransparent($out, $transColor);
imagesavealpha($out, TRUE);
header('Content-type: image/png');
imagepng($out);
EDIT 2 :
You might need to optimize something and change hueAbsoluteError to suit your needs, but hue is the way to enlightenment and sharper picture quality (functions taken from https://gist.github.com/brandonheyer/5254516):
<?php
function RGBtoHSL( $r, $g, $b ) {
$r /= 255;
$g /= 255;
$b /= 255;
$max = max( $r, $g, $b );
$min = min( $r, $g, $b );
$l = ( $max + $min ) / 2;
$d = $max - $min;
if( $d == 0 ){
$h = $s = 0;
} else {
$s = $d / ( 1 - abs( 2 * $l - 1 ) );
switch( $max ){
case $r:
$h = 60 * fmod( ( ( $g - $b ) / $d ), 6 );
if ($b > $g) {
$h += 360;
}
break;
case $g:
$h = 60 * ( ( $b - $r ) / $d + 2 );
break;
case $b:
$h = 60 * ( ( $r - $g ) / $d + 4 );
break;
}
}
return array( round( $h, 2 ), round( $s, 2 ), round( $l, 2 ) );
}
function HSLtoRGB( $h, $s, $l ){
$c = ( 1 - abs( 2 * $l - 1 ) ) * $s;
$x = $c * ( 1 - abs( fmod( ( $h / 60 ), 2 ) - 1 ) );
$m = $l - ( $c / 2 );
if ( $h < 60 ) {
$r = $c;
$g = $x;
$b = 0;
} else if ( $h < 120 ) {
$r = $x;
$g = $c;
$b = 0;
} else if ( $h < 180 ) {
$r = 0;
$g = $c;
$b = $x;
} else if ( $h < 240 ) {
$r = 0;
$g = $x;
$b = $c;
} else if ( $h < 300 ) {
$r = $x;
$g = 0;
$b = $c;
} else {
$r = $c;
$g = 0;
$b = $x;
}
$r = ( $r + $m ) * 255;
$g = ( $g + $m ) * 255;
$b = ( $b + $m ) * 255;
return array( floor( $r ), floor( $g ), floor( $b ) );
}
/* ---------------CHANGE THESE------------------- */
$colorToReplace = RGBtoHSL(255, 0, 255);
$hueAbsoluteError = 0.4;
$replacementColor = RGBtoHSL(0, 192, 239);
/* ---------------------------------------------- */
$filename = 'img/Mascots_Aviators_General-copy.png';
$im = imagecreatefrompng($filename);
$out = imagecreatetruecolor(imagesx($im), imagesy($im));
$transColor = imagecolorallocatealpha($out, 254, 254, 254, 127);
imagefill($out, 0, 0, $transColor);
for ($x = 0; $x < imagesx($im); $x++) {
for ($y = 0; $y < imagesy($im); $y++) {
$pixel = imagecolorat($im, $x, $y);
$red = ($pixel >> 16) & 0xFF;
$green = ($pixel >> 8) & 0xFF;
$blue = $pixel & 0xFF;
$alpha = ($pixel & 0x7F000000) >> 24;
$colorHSL = RGBtoHSL($red, $green, $blue);
if ((($colorHSL[0] >= $colorToReplace[0] - $hueAbsoluteError) && ($colorToReplace[0] + $hueAbsoluteError) >= $colorHSL[0])){
$color = HSLtoRGB($replacementColor[0], $replacementColor[1], $colorHSL[2]);
$red = $color[0];
$green= $color[1];
$blue = $color[2];
}
if ($alpha == 127) {
imagesetpixel($out, $x, $y, $transColor);
}
else {
imagesetpixel($out, $x, $y, imagecolorallocatealpha($out, $red, $green, $blue, $alpha));
}
}
}
imagecolortransparent($out, $transColor);
imagesavealpha($out, TRUE);
header('Content-type: image/png');
imagepng($out);
EDIT :
Better solution - determine if color needs replacement (using this method). Determine replaced color's hue (I have no idea if it's correct term, what I mean is lightness and darkness). Apply it to replacement color to give it a shade or AA feeling.
So, as I have said in my comment, you need to determine if this color is really ping (dark, light, etc.). Easiest solution is to apply absolute error method for specific color channels. There may be (there definitely is) better universal method, but I hope this will do:
$color = [255, 0, 255];
$colorAbsoluteError = [150, 0, 150];
$replacementColor = [0, 192, 239];
$filename = 'img/Mascots_Aviators_General-copy.png';
$im = imagecreatefrompng($filename);
$out = imagecreatetruecolor(imagesx($im), imagesy($im));
$transColor = imagecolorallocatealpha($out, 254, 254, 254, 127);
imagefill($out, 0, 0, $transColor);
for ($x = 0; $x < imagesx($im); $x++) {
for ($y = 0; $y < imagesy($im); $y++) {
$pixel = imagecolorat($im, $x, $y);
$red = ($pixel >> 16) & 0xFF;
$green = ($pixel >> 8) & 0xFF;
$blue = $pixel & 0xFF;
$alpha = ($pixel & 0x7F000000) >> 24;
if ((($red >= $color[0] - $colorAbsoluteError[0]) && ($color[0] + $colorAbsoluteError[0]) >= $red) &&
(($green >= $color[1] - $colorAbsoluteError[1]) && ($color[1] + $colorAbsoluteError[1]) >= $green) &&
(($blue >= $color[2] - $colorAbsoluteError[2]) && ($color[2] + $colorAbsoluteError[2]) >= $blue)){
$red = $replacementColor[0];
$green= $replacementColor[1];
$blue = $replacementColor[2];
}
if ($alpha == 127) {
imagesetpixel($out, $x, $y, $transColor);
}
else {
imagesetpixel($out, $x, $y, imagecolorallocatealpha($out, $red, $green, $blue, $alpha));
}
}
}
imagecolortransparent($out, $transColor);
imagesavealpha($out, TRUE);
header('Content-type: image/png');
imagepng($out);

Categories