Overlaying colour on a JPEG with PHP/GD? - php

I have a collection of black and white JPEG's stored on my server. These images are symbol based, where the symbol is a collection of black lines on a white background.
I am trying to use GD to replace the black colour with another colour on the fly based on a variable passed. Currently, I am:
Getting the JPEG as: $image = imagecreatefromjpeg($imgURL),
Converting a HEX code (#FF0000, say) to RGB through PHP,
And then feeding these variables to:
private function colourize_image($image, $colour, $contrast = 0) {
if (!$image) { return false; }
imagealphablending($image, true);
imagesavealpha($image, true);
# Convert hex colour into RGB values
$r = hexdec('0x' . $colour{0} . $colour{1});
$g = hexdec('0x' . $colour{2} . $colour{3});
$b = hexdec('0x' . $colour{4} . $colour{5});
imagefilter($image, IMG_FILTER_COLORIZE, $r, $g, $b);
imagefilter($image, IMG_FILTER_CONTRAST, $contrast);
# Return the GD image object
return $image;
}
For some reason, the function doesn't work at all (it won't overlay a new colour).
Can anyone advise as to where I am going wrong?
Many thanks.

If the color is the only problem, then you could try this:
<php>
//SNIP
$color = preg_replace('/^#/','',$color); //Get rid of "#" if it's there
$r = hexdec("0x{$color[0]}{$color[1]}");
$g = hexdec("0x{$color[2]}{$color[3]}");
$b = hexdec("0x{$color[4]}{$color[5]}");
//SNIP
</php>

You can use the imageistruecolor function to find out whether the JPEG you've just loaded is true colour or palette-based. If it's not true colour, you can create a new true color image of the same width and height, and copy the old image over:
$width = imagesx($jpeg);
$height = imagesy($jpeg);
$image = imagecreatetruecolor($width, $height);
imagecopy($jpeg, $image, 0, 0, 0, 0, $width, $height);
You should then be able to apply the new colours.

Related

Merge JPEG and PNG with transparent Background to one Image PHP

i have the following script for coping a JPEG and a PNG to an existing PNG called base.png. Within the function "transparent_background" i replace the white background with transparency. This function is the problem. Standlone the function is working with output directly in the browser. please see the comment out "//imagepng($img);". but if i return the $img out of the function its still a jpeg i think, thats why it isnt transparent. The second function is just for resize.
<?php
function transparent_background($img)
{
$img = imagecreatefromjpeg($img); //or whatever loading function you need
$colors= array("255","255","255");
$remove = imagecolorallocate($img, $colors[0], $colors[1], $colors[2]);
imagecolortransparent($img, $remove);
//imagepng($img);
return $img;
imagedestroy($img);
}
function resize($img, $w){
$img = imagecreatefromjpeg($img);
$ratio = imagesx($img)/imagesy($img);
if( $ratio > 1) {
$width = $w;
$height = $w/$ratio;
}
else {
$width = $w*$ratio;
$height = $w;
}
$dst = imagecreatetruecolor($width,$height);
imagecopyresampled($dst,$img,0,0,0,0,$width,$height,imagesx($img),imagesy($img));
return $dst;
imagedestroy($dst);
imagedestroy($img);
}
$h="https://images-eu.ssl-images-amazon.com/images/I/415zYwg2-TL.jpg";
$base = imagecreatefrompng("base.png");
$logo = imagecreatefrompng("fs_logo_line.png");
$pos1=resize($h,"730");
$pos1=transparent_background($h);
imagecopy($base,$pos1,0, 5, 0, 0, imagesx($pos1),imagesy($pos1));
imagecopy($base,$logo,0, 1136, 0,0,imagesx($logo),imagesy($logo));
imagepng($base);
?>
I think the problem is, that i get a jpeg back from the transparent_background function and thats why the image in $pos1 is not transparent. Any ideas how i can solve that? I have tried with ob_start & ob_get_contents but this also didn't work.
You can merge the two images together using the PHP GD2 library.
Example:
<?php
# If you don't know the type of image you are using as your originals.
$image = imagecreatefromstring(file_get_contents($your_original_image));
$frame = imagecreatefromstring(file_get_contents($your_frame_image));
# If you know your originals are of type PNG.
$image = imagecreatefrompng($your_original_image);
$frame = imagecreatefrompng($your_frame_image);
imagecopymerge($image, $frame, 0, 0, 0, 0, 50, 50, 100);
# Save the image to a file
imagepng($image, '/path/to/save/image.png');
# Output straight to the browser.
imagepng($image);
?>
Add imagealphablending($frame,true); before imagecopymerge() if you want to keep PNG frame transparancy over the image.

Image background color not fully removed in PHP [duplicate]

I want to remove the white background of any image uploaded on the site working on PHP platform. The uploading function is done but messed up with this functionality.
Here is the link I found here:
Remove white background from an image and make it transparent
But this is doing reverse. I want to remove the colored background and make it image with transparent background.
Since you only need single-color transparency, the easiest way is to define white with imagecolortransparent(). Something like this (untested code):
$img = imagecreatefromstring($your_image); //or whatever loading function you need
$white = imagecolorallocate($img, 255, 255, 255);
imagecolortransparent($img, $white);
imagepng($img, $output_file_name);
function transparent_background($filename, $color)
{
$img = imagecreatefrompng('image.png'); //or whatever loading function you need
$colors = explode(',', $color);
$remove = imagecolorallocate($img, $colors[0], $colors[1], $colors[2]);
imagecolortransparent($img, $remove);
imagepng($img, $_SERVER['DOCUMENT_ROOT'].'/'.$filename);
}
transparent_background('logo_100x100.png', '255,255,255');
Try ImageMagick it did the trick for me. You can also control the amount of color that needs to be removed. Just pass image path, bgcolor as an array of RGB, and fuzz in percent. As long as you have ImageMagick installed on your system/hosting. I had my hosting provider install it for me as a module.
I'm using ImageMagick version 6.2.8
Example:
$image = "/path/to/your/image.jpg";
$bgcolor = array("red" => "255", "green" => "255", "blue" => "255");
$fuzz = 9;
remove_image_background($image, $bgcolor, $fuzz);
protected function remove_image_background($image, $bgcolor, $fuzz)
{
$image = shell_exec('convert '.$image.' -fuzz '.$fuzz.'% -transparent "rgb('.$bgcolor['red'].','.$bgcolor['green'].','.$bgcolor['blue'].')" '.$image.'');
return $image;
}
get the index of white color in the image and set it to transparent.
$whiteColorIndex = imagecolorexact($img,255,255,255);
$whiteColor = imagecolorsforindex($img,$whiteColorIndex);
imagecolortransparent($img,$whiteColor);
you can alternatively use imagecolorclosest() if you don't know the exact color.
The function from #geoffs3310 should be the accepted answer here, but note, that the png saved does not contain an alpha channel.
To remove the background and save the new png as a transparent png with alpha the following code works
$_filename='/home/files/IMAGE.png';
$_backgroundColour='0,0,0';
$_img = imagecreatefrompng($_filename);
$_backgroundColours = explode(',', $_backgroundColour);
$_removeColour = imagecolorallocate($_img, (int)$_backgroundColours[0], (int)$_backgroundColours[1], (int)$_backgroundColours[2]);
imagecolortransparent($_img, $_removeColour);
imagesavealpha($_img, true);
$_transColor = imagecolorallocatealpha($_img, 0, 0, 0, 127);
imagefill($_img, 0, 0, $_transColor);
imagepng($_img, $_filename);
Use the php image processing and GD, read the image pixel by pixel
if the RGB components are all 255 (The pixel is white), set the alpha
channel to 255 (transparent). You may have to change the filetype of the image
depending if the uploaded filetype supports an alpha channel.
Version to conversion from URL and return on page:
$img = imagecreatefromjpeg('http://mypage.com/image.jpg');
$remove = imagecolorallocate($img, 255, 255, 255); // Define color rgb to remove
imagecolortransparent($img, $remove);
ob_start();
imagepng($img);
$imgData = ob_get_clean();
imagedestroy($img);
$data_img = 'data:image/png;base64,'.base64_encode($imgData);
echo '<body style="background: #f00;"><img src="'.$data_img.'"></body>';

PHP - How to add a transparent color layer on a image using GD?

Is there anyway to add a transparent color layer on a image using GD?
Here is an example. I am receiving a image looks like on the left-hand side (the image gots a transparent background). If I pass in a color like #ff0000 to the program, I want to add a 50% transparent color layer onto the image, but only to the area that got things on it, the result image will still got a transparent background, looks like on the right-hand side.
example
<?php
$img = 'color.png';
$hex = "#ff0000";
list($width, $height) = getimagesize($img);
list($r, $g, $b) = sscanf($hex, "#%02x%02x%02x");
$img_a = imagecreatefrompng($img);
imagealphablending($img_a, true);
$layer = imagecolorallocatealpha($img_a, $r, $g, $b, 50);
imagefilledrectangle($img_a, 0, 0, $width, $height, $layer);
header('Content-Type: image/png');
imagepng($img_a);
imagedestroy($img_a);
?>

Php IMG_FILTER_GRAYSCALE converting transparent pixels to black

I am trying to get my PNGs converted into grayscale and it almost works properly with this code:
$image = imagecreatefromstring(file_get_contents($this->image_dest."".$this->file_name));
imagefilter($image, IMG_FILTER_GRAYSCALE);
imagepng($image, $this->image_dest."".$this->file_name);
The problem is, when the image has some transparency, the transparent pixels are being rendered as black. I see there are others who have had the same question in part of their question, but it was never answered about this issue specifically.
I hope someone can help out with this!
If it helps, I was previously using this snippet to convert to greyscale, but it has the same problem with the transparent pixels in pngs being converted to black and I am not sure
how to detect the transparency and convert it using the imagecolorat function.
//Creates the 256 color palette
for ($c=0;$c<256;$c++){
$palette[$c] = imagecolorallocate($new,$c,$c,$c);
}
//Creates yiq function
function yiq($r,$g,$b){
return (($r*0.299)+($g*0.587)+($b*0.114));
}
//Reads the origonal colors pixel by pixel
for ($y=0;$y<$h;$y++) {
for ($x=0;$x<$w;$x++) {
$rgb = imagecolorat($new,$x,$y);
$r = ($rgb >> 16) & 0xFF;
$g = ($rgb >> 8) & 0xFF;
$b = $rgb & 0xFF;
//This is where we actually use yiq to modify our rbg values, and then convert them to our grayscale palette
$gs = yiq($r,$g,$b);
imagesetpixel($new,$x,$y,$palette[$gs]);
}
}
Okay, this was mostly borrowed.. Don't quite remember where, but it should work:
//$im is your image with the transparent background
$width = imagesx($im);
$height = imagesy($im);
//Make your white background to overlay the original image on ($im)
$bg = imagecreatetruecolor($width, $height);
$white = imagecolorallocate($bg, 255, 255, 255);
//Fill it with white
imagefill($bg, 0, 0, $white);
//Merge the two together
imagecopyresampled($bg, $im, 0, 0, 0, 0, $width, $height, $width, $height);
//Convert to gray-scale
imagefilter($bg, IMG_FILTER_GRAYSCALE);
Hope that helps!

Remove Image background with php and save transparent png

I want to remove the white background of any image uploaded on the site working on PHP platform. The uploading function is done but messed up with this functionality.
Here is the link I found here:
Remove white background from an image and make it transparent
But this is doing reverse. I want to remove the colored background and make it image with transparent background.
Since you only need single-color transparency, the easiest way is to define white with imagecolortransparent(). Something like this (untested code):
$img = imagecreatefromstring($your_image); //or whatever loading function you need
$white = imagecolorallocate($img, 255, 255, 255);
imagecolortransparent($img, $white);
imagepng($img, $output_file_name);
function transparent_background($filename, $color)
{
$img = imagecreatefrompng('image.png'); //or whatever loading function you need
$colors = explode(',', $color);
$remove = imagecolorallocate($img, $colors[0], $colors[1], $colors[2]);
imagecolortransparent($img, $remove);
imagepng($img, $_SERVER['DOCUMENT_ROOT'].'/'.$filename);
}
transparent_background('logo_100x100.png', '255,255,255');
Try ImageMagick it did the trick for me. You can also control the amount of color that needs to be removed. Just pass image path, bgcolor as an array of RGB, and fuzz in percent. As long as you have ImageMagick installed on your system/hosting. I had my hosting provider install it for me as a module.
I'm using ImageMagick version 6.2.8
Example:
$image = "/path/to/your/image.jpg";
$bgcolor = array("red" => "255", "green" => "255", "blue" => "255");
$fuzz = 9;
remove_image_background($image, $bgcolor, $fuzz);
protected function remove_image_background($image, $bgcolor, $fuzz)
{
$image = shell_exec('convert '.$image.' -fuzz '.$fuzz.'% -transparent "rgb('.$bgcolor['red'].','.$bgcolor['green'].','.$bgcolor['blue'].')" '.$image.'');
return $image;
}
get the index of white color in the image and set it to transparent.
$whiteColorIndex = imagecolorexact($img,255,255,255);
$whiteColor = imagecolorsforindex($img,$whiteColorIndex);
imagecolortransparent($img,$whiteColor);
you can alternatively use imagecolorclosest() if you don't know the exact color.
The function from #geoffs3310 should be the accepted answer here, but note, that the png saved does not contain an alpha channel.
To remove the background and save the new png as a transparent png with alpha the following code works
$_filename='/home/files/IMAGE.png';
$_backgroundColour='0,0,0';
$_img = imagecreatefrompng($_filename);
$_backgroundColours = explode(',', $_backgroundColour);
$_removeColour = imagecolorallocate($_img, (int)$_backgroundColours[0], (int)$_backgroundColours[1], (int)$_backgroundColours[2]);
imagecolortransparent($_img, $_removeColour);
imagesavealpha($_img, true);
$_transColor = imagecolorallocatealpha($_img, 0, 0, 0, 127);
imagefill($_img, 0, 0, $_transColor);
imagepng($_img, $_filename);
Use the php image processing and GD, read the image pixel by pixel
if the RGB components are all 255 (The pixel is white), set the alpha
channel to 255 (transparent). You may have to change the filetype of the image
depending if the uploaded filetype supports an alpha channel.
Version to conversion from URL and return on page:
$img = imagecreatefromjpeg('http://mypage.com/image.jpg');
$remove = imagecolorallocate($img, 255, 255, 255); // Define color rgb to remove
imagecolortransparent($img, $remove);
ob_start();
imagepng($img);
$imgData = ob_get_clean();
imagedestroy($img);
$data_img = 'data:image/png;base64,'.base64_encode($imgData);
echo '<body style="background: #f00;"><img src="'.$data_img.'"></body>';

Categories