PHP GD for merging two icons - php

I am using PHP GD library to merge two icons into one. But in one of the cases the smaller icon goes into back and bigger icon overlaps it completely, I need the small icon to be on top.
Here is my code for merging two icons,
MergeIcons.php
$firstIcon = $_GET['icon1'];
$secondIcon = $_GET['icon2'];
$image = imagecreatefrompng($firstIcon);
$x1 = -1;
$y1 = -1;
$i = 0;
$xCords = array(); // Array to save non-transperent x cords
$yCords = array(); // Array to save non-transperent y cords
for($x=0;$x<16;$x++)
{
for($y=0;$y<16;$y++)
{
if (!transparent(imagecolorat($image, $x, $y)))
{
$xCords[$i] = $x;
$yCords[$i] = $y;
$i++;
}
}
}
$minX = min($xCords);
$minY = min($yCords);
$width = 16 - $minX;
$height = 16 - $minY;
$canvas = imagecreatetruecolor(16,16);
$col = imagecolorallocatealpha($canvas,0,0,0,127);
imagefilledrectangle($canvas,0,0,16,16,$col);
imagealphablending($canvas, true);
imagesavealpha($canvas, true);
imagefill($canvas, 0, 0, $col);
imagecopy($canvas, $image, 0, 0, $minX , $minY, $width, $height);
$dest = $canvas;
$src = imagecreatefrompng($secondIcon);
imagealphablending($dest, true);
imagesavealpha($dest, true);
$swidth = imagesx($src);
$sheight = imagesy($src);
imagecopy($dest, $src, 0,0,0,0,$swidth,$sheight);
header('Content-Type: image/png');
imagepng($dest);
imagedestroy($dest);
imagedestroy($src);
function transparent($pixelValue)
{
$alpha = ($pixelValue & 0x7F000000) >> 24;
$red = ($pixelValue & 0xFF0000) >> 16;
$green = ($pixelValue & 0x00FF00) >> 8;
$blue = ($pixelValue & 0x0000FF);
if($alpha == 127)
return true;
else
return false;
}
Here is how I call the mergeicons.php
echo '<li><img src="MergeIcons.php?icon1='.$secondIconPath.'&icon2='.$firstIconPath.'"/></li>';
In this case, second icon is a small icon and first icon is bigger icon, I want smaller icon on top of bigger icon ( assume its like "Bring it to Front ").
Is that possible?

"bring it front " - i think you want to put one image as a layer on the other
http://phpimageworkshop.com/

Related

Converting text to image is returning a small white box - php

I'm working on a project where I have to convert some instructions text to images and send them by email.
For testing purpose, I'm trying a simple code to output a converted text as an image on the browser, but it's always returning a small white box like this:
I have GD installed on my server.
Here's my code:
<?php
header("Content-type: image/png");
function drawImage()
{
$width = 0;
$height = 0;
$offset_x = 0;
$offset_y = 0;
$bounds = array();
$image = "";
$msg = "Some Sample Text....";
$font = "ARIAL.TTF";
$size = 24; // default font size.
$rot = 0; // rotation in degrees.
$pad = 0; // padding.
$transparent = 1; // transparency set to on.
$red = 0; // black text...
$grn = 0;
$blu = 0;
$bg_red = 255; // on white background.
$bg_grn = 255;
$bg_blu = 255;
// get the font height.
$bounds = ImageTTFBBox($size, $rot, $font, "W");
if ($rot < 0)
{
$font_height = abs($bounds[7]-$bounds[1]);
}
else if ($rot > 0)
{
$font_height = abs($bounds[1]-$bounds[7]);
}
else
{
$font_height = abs($bounds[7]-$bounds[1]);
}
// determine bounding box.
$bounds = ImageTTFBBox($size, $rot, $font, $msg);
if ($rot < 0)
{
$width = abs($bounds[4]-$bounds[0]);
$height = abs($bounds[3]-$bounds[7]);
$offset_y = $font_height;
$offset_x = 0;
}
else if ($rot > 0)
{
$width = abs($bounds[2]-$bounds[6]);
$height = abs($bounds[1]-$bounds[5]);
$offset_y = abs($bounds[7]-$bounds[5])+$font_height;
$offset_x = abs($bounds[0]-$bounds[6]);
}
else
{
$width = abs($bounds[4]-$bounds[6]);
$height = abs($bounds[7]-$bounds[1]);
$offset_y = $font_height;;
$offset_x = 0;
}
$image = imagecreate($width+($pad*2)+1,$height+($pad*2)+1);
$background = ImageColorAllocate($image, $bg_red, $bg_grn, $bg_blu);
$foreground = ImageColorAllocate($image, $red, $grn, $blu);
if ($transparent) ImageColorTransparent($image, $background);
ImageInterlace($image, false);
// render the image
ImageTTFText($image, $size, $rot, $offset_x+$pad, $offset_y+$pad, $foreground, $font, $msg);
// output PNG object.
imagePNG($image);
}
drawImage();
?>
Is this as simple as changing:
$image = imagereate
to
$image = imagecreate
Looks like a typo to me.

Multiply filter with PHP's GD library

I've tried experimenting with the GD library to simulate Photoshop's muliply effect, but I haven't found a working solution yet.
According to Wikipedia, the multiply blend mode:
[...] multiplies the numbers for each pixel of the top layer with the corresponding pixel for the bottom layer. The result is a darker picture.
Does anyone know of a way to achieve this using PHP? Any help would be much appreciated.
You need to take every pixel of your image, then multiply each RGB value with your background color / 255 (it's the Photoshop formula). For example, a JPG file with a red background color multiply filter, saved as a PNG file for better results:
<?php
$filter_r=216;
$filter_g=0;
$filter_b=26;
$suffixe="_red";
$path=YOURPATHFILE;
if(is_file($path)){
$image=#imagecreatefromjpeg($path);
$new_path=substr($path,0,strlen($path)-4).$suffixe.".png";
$imagex = imagesx($image);
$imagey = imagesy($image);
for ($x = 0; $x <$imagex; ++$x) {
for ($y = 0; $y <$imagey; ++$y) {
$rgb = imagecolorat($image, $x, $y);
$TabColors=imagecolorsforindex ( $image , $rgb );
$color_r=floor($TabColors['red']*$filter_r/255);
$color_g=floor($TabColors['green']*$filter_g/255);
$color_b=floor($TabColors['blue']*$filter_b/255);
$newcol = imagecolorallocate($image, $color_r,$color_g,$color_b);
imagesetpixel($image, $x, $y, $newcol);
}
}
imagepng($image,$new_path);
}
?>
I've been looking for Multiply blend between two images as well and couldn't find any native-php solution for it. It appears that only way (for now) is to "manually" set pixels, pixel-by-pixel. Here's my code that does Multiply blend between two images, assuming that images are of the same size. You can adjust it to handle different sizes if you like.
function multiplyImage($dst,$src)
{
$ow = imagesx($dst);
$oh = imagesy($dst);
$inv255 = 1.0/255.0;
$c = imagecreatetruecolor($ow,$oh);
for ($x = 0; $x <$ow; ++$x)
{
for ($y = 0; $y <$oh; ++$y)
{
$rgb_src = imagecolorsforindex($src,imagecolorat($src, $x, $y));
$rgb_dst = imagecolorsforindex($dst,imagecolorat($dst, $x, $y));
$r = $rgb_src['red'] * $rgb_dst['red']*$inv255;
$g = $rgb_src['green'] * $rgb_dst['green']*$inv255;
$b = $rgb_src['blue'] * $rgb_dst['blue']*$inv255;
$rgb = imagecolorallocate($c,$r,$g,$b);
imagesetpixel($c, $x, $y, $rgb);
}
}
return $c;
}
Function returns image object so you should ensure to do imagedestroy after you're done using it.
There should be a workaround using overlay native-php blend, which suggests that 50% gray pixels of destination image will be affected by source pixels. In theory, if you do need to blend two black-and-white images (no gray tones), if you set contrast of destination image so white will become 50%-gray, and then overlay-blend source image over it, should give you something similar to multiply. But for color images, or grayscale images, this wouldn't work - above method appears to be the only option.
I was led into this thread when I needed to blend two images in GD. It seems there is no code specifically for that so I will just leave this here for future visitors to this page.
This is a fork from the answer of colivier that supports multiply-blending of two images.
The two images need not be of the same size BUT the overlaying image will be resized and cropped to the size of the bottom layer. I made a fit helper function to do just that but don't bother with that.
imagecolorat returns the base color, even with PNGs with transparency. That is, a 50% black (visible as (128, 128, 128)) will be returned as (0, 0, 0, 64) 64 being the alpha value. This code takes into consideration translucency and converts the translucent colors to the visible color values.
// bottom layer
$img1 = imagecreatefromjpeg(realpath(__DIR__.'/profilePic.jpg'));
// top layer
$img2 = imagecreatefrompng(realpath(__DIR__.'/border2.png'));
imagealphablending($img2, false);
imagesavealpha($img2, true);
$imagex = imagesx($img1);
$imagey = imagesy($img1);
$imagex2 = imagesx($img2);
$imagey2 = imagesy($img2);
// Prereq: Resize img2 to match img1, cropping beyond the aspect ratio
$w1 = max(min($imagex2, $imagex), $imagex);
$h1 = max(min($imagey2, $imagey), $imagey);
$w_using_h1 = round($h1 * $imagex2 / $imagey2);
$h_using_w1 = round($w1 * $imagey2 / $imagex2);
if ($w_using_h1 > $imagex) {
fit($img2, $imagex, $imagey, 'HEIGHT', true);
}
fit($img2, $imagex, $imagey, 'WIDTH', true);
// Actual multiply filter
for ($x = 0; $x < $imagex; ++$x) {
for ($y = 0; $y < $imagey; ++$y) {
$rgb1 = imagecolorat($img1, $x, $y);
$rgb2 = imagecolorat($img2, $x, $y);
$idx1 = imagecolorsforindex($img1, $rgb1);
$idx2 = imagecolorsforindex($img2, $rgb2);
// Shift left 8, then shift right 7
// same as multiply by 256 then divide by 128
// approximate multiply by 255 then divide by 127
// This is basically multiply by 2 but, expanded to show that
// we are adding a fraction of white to the translucent image
// $adder = ($idx2['alpha'] << 8 >> 7);
$adder = ($idx2['alpha'] << 1);
$rmul = min(255, $idx2['red'] + $adder);
$gmul = min(255, $idx2['green'] + $adder);
$bmul = min(255, $idx2['blue'] + $adder);
$color_r = floor($idx1['red'] * $rmul / 255);
$color_g = floor($idx1['green'] * $gmul / 255);
$color_b = floor($idx1['blue'] * $bmul / 255);
$newcol = imagecolorallocatealpha($img1, $color_r, $color_g, $color_b, 0);
imagesetpixel($img1, $x, $y, $newcol);
}
}
imagejpeg($img1, __DIR__.'/out.jpg');
/**
* Fits an image to a $w x $h canvas
*
* #param type $w Target width
* #param type $h Target height
* #param int $fit_which Which dimension to fit
* #param bool $upscale If set to true, will scale a smaller image to fit the given dimensions
* #param bool $padded If set to true, will add padding to achieve given dimensions
*
* #return Image object
*/
function fit(&$img, $w, $h, $fit_which = 'BOTH', $upscale = false, $padded = true) {
if (!in_array($fit_which, array('WIDTH', 'HEIGHT', 'BOTH'))) {
$fit_which = 'BOTH';
}
$w0 = imagesx($img);
$h0 = imagesy($img);
if (!$upscale && $w0 <= $w && $h0 <= $h)
return $this;
if ($padded) {
$w1 = max(min($w0, $w), $w);
$h1 = max(min($h0, $h), $h);
}
else {
$w1 = min($w0, $w);
$h1 = min($h0, $h);
}
$w_using_h1 = round($h1 * $w0 / $h0);
$h_using_w1 = round($w1 * $h0 / $w0);
// Assume width, crop height
if ($fit_which == 'WIDTH') {
$w2 = $w1;
$h2 = $h_using_w1;
}
// Assume height, crop width
elseif ($fit_which == 'HEIGHT') {
$w2 = $w_using_h1;
$h2 = $h1;
}
elseif ($fit_which == 'BOTH') {
if (!$padded) {
$w2 = $w = min($w, $w_using_h1);
$h2 = $h = min($h, $h_using_w1);
}
else {
// Extend vertically
if ($h_using_w1 <= $h) {
$w2 = $w1;
$h2 = $h_using_w1;
}
// Extend horizontally
else {
$w2 = $w_using_h1;
$h2 = $h1;
}
}
}
$im2 = imagecreatetruecolor($w, $h);
imagealphablending($im2, true);
imagesavealpha($im2, true);
$transparent = imagecolorallocatealpha($im2, 255, 255, 255, 127);
imagefill($im2, 0, 0, $transparent);
imagealphablending($img, true);
imagesavealpha($img, true);
// imagefill($im, 0, 0, $transparent);
imagecopyresampled($im2, $img, ($w - $w2) / 2, ($h - $h2) / 2, 0, 0, $w2, $h2, $w0, $h0);
$img = $im2;
}
Have you tried to use php manual?
For people looking to apply a 'multiply' effect on images like the one in Photoshop (generally b&w ones), you can achieve it with the IMG_FILTER_COLORIZE filter.
<?php
function multiplyColor(&$im, $color = array(255, 0, 0)) {
//get opposite color
$opposite = array(255 - $color[0], 255 - $color[1], 255 - $color[2]);
//now we subtract the opposite color from the image
imagefilter($im, IMG_FILTER_COLORIZE, -$opposite[0], -$opposite[1], -$opposite[2]);
}
?>
If used with png image and alpha must be well and works very well
$filter_r=215;
$filter_g=5;
$filter_b=5;
$alpha=70;
$suffixe="_red";
$path="./img/foto_220_590.png";
if(is_file($path)){
$image=imagecreatefrompng($path);
$new_path=substr($path,0,strlen($path)-4).$suffixe.".png";
echo $imagex = imagesx($image);
echo $imagey = imagesy($image);
for ($x = 0; $x <$imagex; ++$x) {
for ($y = 0; $y <$imagey; ++$y) {
$rgb = imagecolorat($image, $x, $y);
$TabColors=imagecolorsforindex ( $image , $rgb );
$color_r=floor($TabColors['red']*$filter_r/255);
$color_g=floor($TabColors['green']*$filter_g/255);
$color_b=floor($TabColors['blue']*$filter_b/255);
//$newcol = imagecolorallocate($image, $color_r,$color_g,$color_b);
// this new alpha
$newcol = imagecolorallocatealpha($image, $color_r,$color_g,$color_b,$alpha);
imagesetpixel($image, $x, $y, $newcol);
}
}
imagepng($image,$new_path);
I updated #colivier script to be able to myltiply two images, and not just an image with a color:
/**
* Multiply $pathToDst and $pathToSrc to $resultPath
*
* #param string $pathToDst
* #param string $pathToSrc
* #param string $resultPath
*/
function multiply($pathToDst, $pathToSrc, $resultPath) {
switch (pathinfo($pathToDst, PATHINFO_EXTENSION)) {
case "gif" :
$resourceDst = imagecreatefromgif($pathToDst);
break;
case "png" :
$resourceDst = imagecreatefrompng($pathToDst);
break;
default :
$resourceDst = imagecreatefromjpeg($pathToDst);
break;
}
switch (pathinfo($pathToSrc, PATHINFO_EXTENSION)) {
case "gif" :
$resourceSrc = imagecreatefromgif($pathToSrc);
break;
case "png" :
$resourceSrc = imagecreatefrompng($pathToSrc);
break;
default :
$resourceSrc = imagecreatefromjpeg($pathToSrc);
break;
}
for ($x = 0; $x < 400; ++$x) {
for ($y = 0; $y < 400; ++$y) {
$TabColorsFlag = imagecolorsforindex($resourceDst, imagecolorat($resourceDst, $x, $y));
$TabColorsPerso = imagecolorsforindex($resourceSrc, imagecolorat($resourceSrc, $x, $y));
$color_r = floor($TabColorsFlag['red'] * $TabColorsPerso['red'] / 255);
$color_g = floor($TabColorsFlag['green'] * $TabColorsPerso['green'] / 255);
$color_b = floor($TabColorsFlag['blue'] * $TabColorsPerso['blue'] / 255);
imagesetpixel($resourceDst, $x, $y, imagecolorallocate($resourceSrc, $color_r, $color_g, $color_b));
}
}
imagepng($resourceDst, $resultPath, 0);
imagedestroy($resourceDst);
imagedestroy($resourceSrc);
}

Generate random checkerboard image with a variety of colors in PHP

I have the following PHP method that generates new users a profile image when they first sign up, before they upload their own. All it does is just create them a brightly colored square - something to make the interface look a little more interesting when showing a list of users without profile photos.
How could I adapt this method so it created a checkerboard of random colors? Something like this: http://krazydad.com/bestiary/thumbs/random_pixels.jpg
public function generate_random_image($filename, $w = 200, $h = 200, $chosen_color = NULL) {
if(!$chosen_color) {
$color_options = Array("#6f0247", "#FF0569", "#FFF478", "#BAFFC0", "#27DB2D", "#380470", "#9D69D6");
$random = rand(0,sizeof($color_options));
$chosen_color = $color_options[$random];
}
$rgb = self::hex2rgb($chosen_color);
$image = imagecreatetruecolor($w, $h);
for($row = 1; $row <= $h; $row++) {
for($column = 1; $column <= $w; $column++) {
$color = imagecolorallocate ($image, $rgb[0] , $rgb[1], $rgb[2]);
imagesetpixel($image,$column - 1 , $row - 1, $color);
}
$row_count++;
}
$filename = APP_PATH.$filename;
imagepng($image, $filename);
return $chosen_color;
}
How about you just change
$color = imagecolorallocate ($image, $rgb[0] , $rgb[1], $rgb[2]);
to
$color = imagecolorallocate ($image, rand(0,255), rand(0,255), rand(0,255));
Then, each pixel will have it's own colour. Just draw to a small image, then scale by 200% or 300% (or some other arbitrary number) and you'll get nice, big chunky pixels like the image you linked.
While iterating through $rows and $columns you should increase step to desired pixel size and choose another color with each iteration.
example for pixel width = 20x20 :
$pixel = 20;
for($row = 0; $row <= $h / $pixel; $row++) {
for($column = 0; $column <= $w/ $pixel; $column++) {
$rgb = self::hex2rgb($color_options[rand(0,sizeof($color_options))]);
$color = imagecolorallocate ($image, $rgb[0] , $rgb[1], $rgb[2]);
imagefilledrectangle(
$image,
$column*$pixel,
$row*pixel,
$column*$pixel+$pixel,
$row*pixel+$pixel,
$color
);
}
}

Letterbox Image and fill with empty space with another image

I am currently using the GD php library to scale some images letterbox style and fill the resulting empty space with the color black. I need however to fill the empty space using the pattern I have within another image file. Any ideas on how to do this?
This is the code I am using to scale the images:
function resize_image($source_image, $destination_width, $destination_height, $type = 0) {
// $type (1=crop to fit, 2=letterbox)
$source_width = imagesx($source_image);
$source_height = imagesy($source_image);
$source_ratio = $source_width / $source_height;
$destination_ratio = $destination_width / $destination_height;
if ($type == 1) {
// crop to fit
if ($source_ratio > $destination_ratio) {
// source has a wider ratio
$temp_width = (int)($source_height * $destination_ratio);
$temp_height = $source_height;
$source_x = (int)(($source_width - $temp_width) / 2);
$source_y = 0;
} else {
// source has a taller ratio
$temp_width = $source_width;
$temp_height = (int)($source_width / $destination_ratio);
$source_x = 0;
$source_y = (int)(($source_height - $temp_height) / 2);
}
$destination_x = 0;
$destination_y = 0;
$source_width = $temp_width;
$source_height = $temp_height;
$new_destination_width = $destination_width;
$new_destination_height = $destination_height;
} else {
// letterbox
if ($source_ratio < $destination_ratio) {
// source has a taller ratio
$temp_width = (int)($destination_height * $source_ratio);
$temp_height = $destination_height;
$destination_x = (int)(($destination_width - $temp_width) / 2);
$destination_y = 0;
} else {
// source has a wider ratio
$temp_width = $destination_width;
$temp_height = (int)($destination_width / $source_ratio);
$destination_x = 0;
$destination_y = (int)(($destination_height - $temp_height) / 2);
}
$source_x = 0;
$source_y = 0;
$new_destination_width = $temp_width;
$new_destination_height = $temp_height;
}
$destination_image = imagecreatetruecolor($destination_width, $destination_height);
if ($type > 1) {
imagefill($destination_image, 0, 0, imagecolorallocate($destination_image, 0, 0, 0));
}
imagecopyresampled($destination_image, $source_image, $destination_x, $destination_y, $source_x, $source_y, $new_destination_width, $new_destination_height, $source_width, $source_height);
return $destination_image;
}
Thank You
EDIT ------------------
I am now using this code which works perfectly, uses the methods suggested below:
$destination_image = imagecreatetruecolor($destination_width, $destination_height);
if ($type > 1) {
if ($pattern != NULL) {
$pattern = imagecreatefrompng($pattern);
imagesettile($destination_image, $pattern);
imagefill($destination_image, 0, 0, IMG_COLOR_TILED);
} else {
imagefill($destination_image, 0, 0, imagecolorallocate($destination_image, 0, 0, 0));
}
}
imagecopyresampled($destination_image, $source_image, $destination_x, $destination_y, $source_x, $source_y, $new_destination_width, $new_destination_height, $source_width, $source_height);
return $destination_image;
$pattern is a file path to the background image to fill the letter box with!
First prepare the background with imagesettile() to create your tiled canvas to overlay your letter box onto, then copy the letterboxed part of the image into this resource using the source_x/y/w/h parameters of imagecopy() or imagecopyresampled().

How can I replace one color with another in a png 24 alpha transparent image with GD

I have tried:
$index = imagecolorresolve ( $im, 0,0,0 ); // get black
imagecolorset($im, $index, 255, 0, 255); // SET NEW COLOR
This seems to work with png 8 but not 24, and if I do it with 8 it turns out all weird because of the anti-aliasing.
Here is the full test code I'm using. (this is just test code, so be gentle).
function LoadPNG($imgname, $color = false)
{
$im = #imagecreatefrompng($imgname);
imagealphablending($im, false);
if($color) {
$index = imagecolorresolve ( $im, 0,0,0 ); // get black
imagecolorset($im, $index, 255, 0, 255); // SET NEW COLOR
}
imageAlphaBlending($im, true);
imageSaveAlpha($im, true);
return $im;
}
header('Content-Type: image/png');
$img = LoadPNG("head.png", "red");
imagepng($img);
imagedestroy($img);
Based on the solution of inti, i made a script that works:
$imgname = "yourimage.png";
$im = imagecreatefrompng($imgname);
imagealphablending($im, false);
for ($x = imagesx($im); $x--;) {
for ($y = imagesy($im); $y--;) {
$rgb = imagecolorat($im, $x, $y);
$c = imagecolorsforindex($im, $rgb);
if ($c['red'] < 40 && $c['green'] < 40 && $c['blue'] < 40) { // dark colors
// here we use the new color, but the original alpha channel
$colorB = imagecolorallocatealpha($im, 255, 0, 255, $c['alpha']);
imagesetpixel($im, $x, $y, $colorB);
}
}
}
imageAlphaBlending($im, true);
imageSaveAlpha($im, true);
header('Content-Type: image/png');
imagepng($im);
imagedestroy($im);
I'd like a way to optimize it, because it is quite slow
You can try the following:
cycle all points
get the color of that point
if it matches your colorA, set that pixel to the desired colorB
Code:
for ($x=imagesx($im); $x--; ) {
for ($y=imagesy($im); $y--; ) {
$c = imagecolorat($im, $x, $y);
if ($c[0] == 0 && $c[1] == 0 && $c[2] == 0) {
// here we use the new color, but the original alpha channel
$colorB = imagecolorallocatealpha($im, 255, 0, 255, $c[3]);
imagesetpixel($im, $x, $y, $colorB);
}
}
}
Hope this helps!
this function will replace either 1 or all colors for 1 new color, maintaining transparency levels (otherwise borders will probably look awful, if PARTIAL transparency was used to draw borders).
COMPLETE ANSWER TO SIMILAR POST
<?php
function colorizeKeepAplhaChannnel( $inputFilePathIn, $targetRedIn, $targetGreenIn, $targetBlueIn, $outputFilePathIn ) {
$im_src = imagecreatefrompng( $inputFilePathIn );
$im_dst = imagecreatefrompng( $inputFilePathIn );
$width = imagesx($im_src);
$height = imagesy($im_src);
// Note this: FILL IMAGE WITH TRANSPARENT BG
imagefill($im_dst, 0, 0, IMG_COLOR_TRANSPARENT);
imagesavealpha($im_dst,true);
imagealphablending($im_dst, true);
$flagOK = 1;
for( $x=0; $x<$width; $x++ ) {
for( $y=0; $y<$height; $y++ ) {
$rgb = imagecolorat( $im_src, $x, $y );
$colorOldRGB = imagecolorsforindex($im_src, $rgb);
$alpha = $colorOldRGB["alpha"];
$colorNew = imagecolorallocatealpha($im_src, $targetRedIn, $targetGreenIn, $targetBlueIn, $alpha);
$flagFoundColor = true;
// uncomment next 3 lines to substitute only 1 color (in this case, BLACK/greys)
/*
$colorOld = imagecolorallocatealpha($im_src, $colorOldRGB["red"], $colorOldRGB["green"], $colorOldRGB["blue"], 0); // original color WITHOUT alpha channel
$color2Change = imagecolorallocatealpha($im_src, 0, 0, 0, 0); // opaque BLACK - change to desired color
$flagFoundColor = ($color2Change == $colorOld);
*/
if ( false === $colorNew ) {
//echo( "FALSE COLOR:$colorNew alpha:$alpha<br/>" );
$flagOK = 0;
} else if ($flagFoundColor) {
imagesetpixel( $im_dst, $x, $y, $colorNew );
//echo "x:$x y:$y col=$colorNew alpha:$alpha<br/>";
}
}
}
$flagOK2 = imagepng($im_dst, $outputFilePathIn);
if ($flagOK && $flagOK2) {
echo ("<strong>Congratulations, your conversion was successful </strong><br/>new file $outputFilePathIn<br/>");
} else if ($flagOK2 && !$flagOK) {
echo ("<strong>ERROR, your conversion was UNsuccessful</strong><br/>Please verify if your PNG is truecolor<br/>input file $inputFilePathIn<br/>");
} else if (!$flagOK2 && $flagOK) {
$dirNameOutput = dirname($outputFilePathIn)."/";
echo ("<strong>ERROR, your conversion was successful, but could not save file</strong><br/>Please verify that you have PERMISSION to save to directory $dirName <br/>input file $inputFilePathIn<br/>");
} else {
$dirNameOutput = dirname($outputFilePathIn)."/";
echo ("<strong>ERROR, your conversion was UNsuccessful AND could not save file</strong><br/>Please verify if your PNG is truecolor<br/>Please verify that you have PERMISSION to save to directory $dirName <br/>input file $inputFilePathIn<br/>");
}
echo ("TargetName:$outputFilePathIn wid:$width height:$height CONVERTED:|$flagOK| SAVED:|$flagOK2|<br/>");
imagedestroy($im_dst);
imagedestroy($im_src);
}
$targetRed = 255;
$targetGreen = 255;
$targetBlue = 0;
//$inputFileName = 'frameSquareBlack_88x110.png';
$inputFileName = 'testMe.png';
$dirName = "../img/profilePics/";
$nameTemp = basename($inputFileName, ".png");
$outputFileName = $nameTemp."_$targetRed"."_$targetGreen"."_$targetBlue.png";
$inputFilePath = $dirName.$inputFileName;
$outputFilePath = $dirName.$outputFileName;
//echo "inputFileName:$inputFilePath<br>outputName:$outputFilePath<br>";
colorizeKeepAplhaChannnel( $inputFilePath, $targetRed, $targetGreen, $targetBlue, $outputFilePath);
?>
<br/><br/>
Original <br/>
<img src="<?php echo $inputFilePath; ?>">
<br /><br />Colorized<br/>
<img src="<?php echo $outputFilePath; ?>">
<br />
A good way to doing it is using paintOpaqueImage(), which also permit using color tolerance
$targetColor = "#0074AD";
$fill = "#0074AA";
$tolerance = 30000;
$im = new Imagick( "yourimage.png");
if ($im->paintOpaqueImage ( $targetColor , $fill , $tolerance) ){
$im->writeImage("yourimage.png");
}
You can see the tolenrance doc in http://www.imagemagick.org/script/command-line-options.php#fuzz
This function work like a charm :
public function ImageToBlackAndWhite($im) {
for ($x = imagesx($im); $x--;) {
for ($y = imagesy($im); $y--;) {
$rgb = imagecolorat($im, $x, $y);
$r = ($rgb >> 16) & 0xFF;
$g = ($rgb >> 8 ) & 0xFF;
$b = $rgb & 0xFF;
$gray = ($r + $g + $b) / 3;
if ($gray < 0xFF) {
imagesetpixel($im, $x, $y, 0xFFFFFF);
}else
imagesetpixel($im, $x, $y, 0x000000);
}
}
imagefilter($im, IMG_FILTER_NEGATE);
}

Categories