I have a problem making the imagecopy function work in PHP.
I don't even know where to start debugging; images is a new fruit for me.
Portion where I have problem:
imagecopy($png, $bgr, 0, 0, 0, 0, 0, 0, $width, $height);
imagecopy($png, $bgr, 0, 0, 0, 0, 0, 0, imagesx($pbuble), imagesy($pbuble));
Full code (my plan is first to copy on top of $png <- $bgr <- $pbuble):
<?php
//Check for correct GET variables
if (is_numeric($_GET['max']) AND is_numeric($_GET['val'])) {
$max = $_GET['max'];
$val = $_GET['val'];
} else {return false;}
//Create empty placeholder
$png = imagecreate(380, 37);
$black = imagecolorallocate($png, 0, 0, 0);
imagecolortransparent($png, $black);
//Create background image with transparency
$bgr = imagecreatefrompng("progress-bgr.png");
imageAlphaBlending($bgr, true);
imageSaveAlpha($bgr, true);
//Calculate width of progress bar atm
$width = imagesx($bgr);
$height = imagesy($bgr);
$pb_width = $val * $width / $max;
//Percentage buble
$pbuble = imagecreatefrompng("percentage-bubble.png");
imageAlphaBlending($pbuble, true);
imageSaveAlpha($pbuble, true);
$perct = $val * 100 / $max;
$txt = $perct . "%";
$txt_color = imagecolorallocate($pbuble, 255, 255, 255);
$font = "dejavusans-webfont.ttf";
$font_size = 7;
$bbox = imagettfbbox($font_size, 0, $font, $txt);
$x = $bbox[0] + (imagesx($pbuble) / 2) - ($bbox[4] / 2);
//$y = $bbox[1] + (imagesy($pbuble) / 2) - ($bbox[5] / 2);
imagettftext($pbuble, $font_size, 0, $x, 14, $txt_color, $font, $txt);
//
imagecopy($png, $bgr, 0, 0, 0, 0, 0, 0, $width, $height);
imagecopy($png, $bgr, 0, 0, 0, 0, 0, 0, imagesx($pbuble), imagesy($pbuble));
//Output image
header("Content-type: image/png");
imagepng($png);
//
imagedestroy($png);
imagedestroy($bgr);
imagedestroy($pbuble);
?>
Stupid me :)
imagecopy($png, $bgr, 0, 0, 0, 0, 0, 0, $width, $height);
has two extra parameters.
should be:
imagecopy($png, $bgr, 0, 0, 0, 0, $width, $height);
Related
I'm trying to write a small program to create cartoon eye's and output them to a folder (PHP CLI) and I'm running into trouble with the expected output. I have two functions that copy sections from an image, one for rotating while preserving the original size and one to get a small section for styling needs. When the functions are used in the order of rotatePreserve() then partialEye() the addcolorallocate in partialEye always becomes transparent. I've tried various colors, all end up with the same result. I've searched and read, but I don't understand why this is happening?
I've tried outputting the image halfway through and createimagefrompng with the same results, I'm failing to understand why the color isn't added correctly. If you run the code, you'll see that the output testing along the way works unless rotatePreserve is called before the partialEye function.
Please help me understand what going wrong here.
Thanks
// Setup Variables
$fixed_x = 512;
$fixed_y = 512;
$output_dir = './output';
$output_filename = 'eye_test.png';
// Output info
echo "\e[1;30;40mBeginning Eye Creator......\n";
echo "Image Size: $fixed_x x $fixed_y \n";
// Functions
function partialEye ($img, $cut, $x, $y, $brow) {
//New image, same size, get bottom part of Eye (Optionally add eye lid )
$part_eye = imagecreate($x, $y);
imagealphablending($part_eye, true);
$transparent = imagecolorallocatealpha($part_eye , 0, 0, 0, 127);
imagefill($part_eye, 0, 0, $transparent);
imagecopy($part_eye, $img, 0, $cut, 0, $cut, $x, $y-$cut);
$blk = imagecolorallocate($part_eye, 0,0,0);
if ($brow === 1) {
//If ran after the rotate// draws in transparent??
imagefilledellipse($part_eye, 256-15, $cut, 256, 15, $blk);
} elseif ($brow === 2) {
imagefilledellipse($part_eye, 256+15, $cut, 256, 15, $blk);
}
return $part_eye;
imagedestroy($part_eye);
}
function rotatePreserve($img, $orig_x, $orig_y, $deg) {
$width_before = $orig_x;
$height_before = $orig_y;
$rotateImgTransparency = imagecolorallocatealpha($img , 1, 1, 1, 127);
$img = imagerotate($img, $deg, $rotateImgTransparency);
//but imagerotate scales, so we clip to the original size
$img2 = imagecreatetruecolor($orig_x, $orig_y);
imagealphablending($img2, false);
imagesavealpha($img2, true);
$rotateImg2Transparency = imagecolorallocatealpha($img2 , 0, 0, 0, 127);
imagefill($img2, 0, 0, $rotateImg2Transparency);
$new_width = imagesx($img); // where dimensions are
$new_height = imagesy($img);// the scaled ones (by imagerotate)
imagecopyresampled(
$img2, $img,
0, 0,
($new_width-$orig_x)/2,
($new_height-$orig_y)/2,
$orig_x,
$orig_y,
$orig_x,
$orig_y
);
return $img2;
imagedestroy($img);
imagedestroy($img2);
}
//New Image
$new_image = imagecreatetruecolor($fixed_x, $fixed_y);
imagealphablending($new_image, false);
//Colors for $new_image
$white_color = imagecolorallocate($new_image, 255, 255, 255 );
$blk_color = imagecolorallocate($new_image, 0,0,0);
$pngTransparency = imagecolorallocatealpha($new_image , 0, 0, 0, 127);
$rand_R = rand(0,255);
$rand_G = rand(0,255);
$rand_B = rand(0,255);
$iris_color = imagecolorallocate($new_image, $rand_R,$rand_G,$rand_B);
imagefill($new_image, 0, 0, $pngTransparency);
$size = 256;
$draw_x = $fixed_x/2;
$draw_y = $fixed_y/2;
imagefilledarc($new_image, $draw_x, $draw_y, $size, $size, 0, 360, $blk_color, IMG_ARC_PIE);
imagefilledarc($new_image, $draw_x, $draw_y, $size-20, $size-20, 0, 360, $white_color, IMG_ARC_PIE);
imagefilledarc($new_image, $draw_x, $draw_y, $size-100, $size-100, 0, 360, $iris_color, IMG_ARC_PIE);
imagefilledarc($new_image, $draw_x, $draw_y, $size-170, $size-170, 0, 360, $blk_color, IMG_ARC_PIE);
imagefilledellipse($new_image, $draw_x, $draw_y-50, $size-180, $size-220, $white_color);
imagefilledellipse($new_image, $draw_x, $draw_y+50, $size-200, $size-225, $white_color);
// Cut top part of Eye off
$partial_eye = partialEye($new_image, 192, $fixed_x, $fixed_y, 0);
// Cut top part of eye and add lid
$left_eye_add_lid_eye = partialEye($new_image, 192, $fixed_x, $fixed_y, 1);
// Rotate and Preserve Size
$left_eye = rotatePreserve($left_eye_add_lid_eye, $fixed_x, $fixed_y, -13);
imagesavealpha($left_eye, true);
imagepng($left_eye, $output_dir.'/left_eye.png', 0, 9);
$first_rotate = rotatePreserve($new_image, $fixed_x, $fixed_y, 26);
// FAILS!!
$right_eye_add_lid_eye = partialEye($first_rotate, 192, $fixed_x, $fixed_y, 2);
//Testing shows the fail with any color choice becoming transparent
imagesavealpha($right_eye_add_lid_eye, true);
imagepng($right_eye_add_lid_eye, $output_dir.'/'.$output_filename, 0, 9);
// Then rotate and flip for final position this would finish the right eye in the correct position
// this would give the expected result if the "eye lid" wasn't transparent
// $right_eye_add_lid_eye = rotatePreserve($right_eye_add_lid_eye, $fixed_x, $fixed_y, -13);
// imageflip($right_eye_add_lid_eye, IMG_FLIP_HORIZONTAL);
// imagesavealpha($right_eye_add_lid_eye, true);
// imagepng($right_eye_add_lid_eye, $output_dir.'/right_eye.png', 0, 9);
results
I'm trying to add a border with rounded corners to an image, and I've gotten the outside corners working fine, but I'm having some issues with the inside ones.
The current method produces the output on the right, and I expected it to look like the left hand side.
private function addInnerRoundCorners($radius, $borderColour, $borderWidth){
$radius = max(array(5, $radius));
$quality = ($radius <= 5 ? 5 : 10);
$newWidth = $this->getOverlayWidth() * $quality;
$newHeight = $this->getOverlayHeight() * $quality;
$tmpImage = imagecreatetruecolor($newWidth, $newHeight);
$transparency = imagecolorallocatealpha($tmpImage, 0, 0, 0, 127);
imagefill($tmpImage, 0, 0, $transparency);
imagecopyresampled($tmpImage, $this->getImage(), 0, 0, 0, 0, $newWidth, $newHeight, $this->getOverlayWidth(), $this->getOverlayHeight());
imagealphablending($tmpImage, false);
imagesavealpha($tmpImage, true);
$newBorderWidth = $borderWidth * $quality;
$newRadius = $radius * $quality;
// Top Left
$corner = $this->getInnerCornerShape(0, $newRadius, $borderColour);
imagecopymerge($tmpImage, $corner, $newBorderWidth, $newBorderWidth, 0, 0, $newRadius, $newRadius, 100);
// Top Right
$corner = $this->getInnerCornerShape(270, $newRadius, $borderColour);
imagecopy($tmpImage, $corner, $newWidth - $newBorderWidth - $newRadius, $newBorderWidth, 0, 0, $newRadius, $newRadius);
// Bottom Left
$corner = $this->getInnerCornerShape(90, $newRadius, $borderColour);
imagecopyresampled($tmpImage, $corner, $newBorderWidth, $newHeight - $newBorderWidth - $newRadius, 0, 0, $newRadius, $newRadius, $newRadius, $newRadius);
// Bottom Right
$corner = $this->getInnerCornerShape(180, $newRadius, $borderColour);
imagecopyresampled($tmpImage, $corner, $newWidth - $newBorderWidth - $newRadius, $newHeight - $newBorderWidth - $newRadius, 0, 0, $newRadius, $newRadius, $newRadius, $newRadius);
imagecopyresampled($this->getImage(), $tmpImage, 0, 0, 0, 0, $this->getOverlayWidth(), $this->getOverlayHeight(), $newWidth, $newHeight);
}
/**
*
*/
private $innerCornerImage = null;
private function getInnerCornerShape($angle = 0, $width, $colour){
$trans = null;
if($this->innerCornerImage == null){
$width2 = 250;
$height = 250;
$image = imagecreatetruecolor($width2, $height);
$trans = imagecolorallocatealpha($image, 68, 68, 68, 127);
imagealphablending($image, false);
imagesavealpha($image, true);
imagefill($image, 0, 0, $trans);
imagearc($image, $width2, $height, $width2 * 2 + 1, $height * 2 + 1, 0, 0, $colour);
imagefilltoborder($image, 1, 1, $colour, $colour);
// Image will be a square, so use width for height too.
$newImage = imagecreatetruecolor($width, $width);
imagealphablending($newImage, false);
imagesavealpha($newImage, true);
imagefill($newImage, 0, 0, $trans);
imagecopyresampled($newImage, $image, 0, 0, 0, 0, $width, $width, $width2, $height);
$this->innerCornerImage = $newImage;
} else {
$trans = imagecolorallocatealpha($this->innerCornerImage, 0, 0, 0, 127);
}
$image = imagerotate($this->innerCornerImage, $angle, $trans);
return $image;
}
It creates a inner corner shape, then just rotates it around. It has a fully transparent background, but as you can see it doesn't merge correctly.
Anyone got any ideas how I can make them merge correctly?
Again, below is the expected result (left). versus the current result (right).
I have this script, which makes an image and posts it on another image:
<?php
$img=imagecreatetruecolor(150,20);
imagealphablending($img,false);
$col=imagecolorallocatealpha($img,255,255,255,127);
$black = imagecolorallocate($img, 0, 0, 0);
imagecolortransparent($img, $black);
imagefilledrectangle($img,0,0,180,20,$col);
imagealphablending($img,true);
$font='../ttf/0001.ttf';
$color = imagecolorallocate($img, 0, 0, 0);
imagettftext($img,11,0,5,14,$color,$font,'Text goes here');
imagealphablending($img,false);
imagesavealpha($img,true);
imagejpeg($img, '../custom_images/test.jpg');
// Create image instances
$dest = imagecreatefromjpeg('../custom_images/121536.jpg');
$src = imagecreatefromjpeg('../custom_images/test.jpg');
$width = imagesx($src);
$height = imagesy($src);
imageantialias($src, true);
$color = imagecolorallocatealpha($src, 0, 0, 0, 127);
$rotated = imagerotate($src, 0, $color);
imagesavealpha($rotated, true);
$trans_colour = imagecolorallocatealpha($rotated, 0, 0, 0, 127);
imagefill($rotated, 0, 0, $trans_colour);
imagepng($rotated, 'shahid.png');
$new_img = imagecreatefrompng('shahid.png');
$width = imagesx($new_img);
$height = imagesy($new_img);
// imagecopymerge($dest, $new_img, 50, 50, 0, 0, $width+60, $height+60, 100);
imagecopymerge_alpha($dest, $new_img, 0, 20, 0, 0, $width, $height, 100);
// Output and free from memory
header('Content-Type: image/png');
imagepng($dest);
imagedestroy($dest);
imagedestroy($src);
?>
2 things:
Background is not transparent
I want the Width and Height to be automatic, so if the text is short, the image is it to.
What do I fault?
Here's the problem the text overlayed over the image and gradient has some weird pixilation around the text, but I can't work out why.
-->
Here's the code:
<?php
function hex2rgb($hex) {
$rgb[0] = hexdec(substr($hex, 0, 2));
$rgb[1] = hexdec(substr($hex, 2, 2));
$rgb[2] = hexdec(substr($hex, 4, 2));
return $rgb;
}
$sourceImage = imagecreatefromstring(file_get_contents("source.jpg"));
$imagePadding = 10;
$height = imagesy($sourceImage);
$width = imagesx($sourceImage);
$baseImage = imagecreatetruecolor($width, $height);
$backgroundColor = imagecolorallocate($baseImage, 0, 0, 0);
imagefill($baseImage, 0, 0, $backgroundColor);
imagecopyresampled($baseImage, $sourceImage, 0, 0, 0, 0, $width, $height, $width, $height);
//==== GRADIENT ====//
// Modified from: http://stackoverflow.com/questions/14684622/blend-transparent-gradient-with-an-image-using-php-gd-library
$gradientCanvas = imagecreatetruecolor($width, $height);
$transColor = imagecolorallocatealpha($gradientCanvas, 0, 0, 0, 127);
imagefill($gradientCanvas, 0, 0, $transColor);
$color = hex2rgb("000000");
$start = -40;
$stop = 120;
$range = $stop - $start;
for ($y = 0; $y < $height; ++$y) {
$alpha = $y <= $start ? 0 : round(min(($y - $start) / $range, 1) * 127);
$newColor = imagecolorallocatealpha($gradientCanvas, $color[0], $color[1], $color[2], $alpha);
imageline($gradientCanvas, 0, $y, $width, $y, $newColor);
}
imagecopyresampled($baseImage, $gradientCanvas, 0, 0, 0, 0, $width, $height, $width, $height);
//==== TEXT ====//
putenv('GDFONTPATH=.');
$font = "HelveticaNeueBold.ttf";
$white = imagecolorallocate($baseImage, 255, 255, 255);
imagettftext($baseImage, 14, 0, $imagePadding, $imagePadding + 16, $white, $font, "Foobar");
header('Content-Type: image/jpeg');
imagejpeg($baseImage);
imagedestroy($baseImage);
imagedestroy($sourceImage);
?>
The default quality of imagejpeg http://php.net/manual/en/function.imagejpeg.php is ~75, you will want to set this to 100
imagejpeg($baseImage, null, 100);
The main reason - you are using JPG as output and input image. Editing JPG images often causes the image distortions. Try to use a PNG image as a source.
Or try set the "quality" parameter of imagejpeg() to 100
I want to align the watermark of an image to the right side.
This is what I have so far but its aligned to the left...
// Add Watermark featuring Website Name
$home_url = home_url();
$search = array('http://','https://');
$site_name = str_ireplace($search, '', $home_url);
$watermark = imagecreatetruecolor($width, $height+15);
// Determine color of watermark's background
if (is_array($Meme_Generator_Data) &&
array_key_exists('watermark_background',$Meme_Generator_Data) &&
strlen($Meme_Generator_Data['watermark_background']) == 7)
{
$wm_bg = $this->convert_color(substr($Meme_Generator_Data['watermark_background'], 1));
$bg_color = imagecolorallocate($watermark, $wm_bg[0], $wm_bg[1], $wm_bg[2]);
imagefill($watermark, 0, 0, $bg_color);
}
// Determine color of watermark's text
if (is_array($Meme_Generator_Data) &&
array_key_exists('watermark_text',$Meme_Generator_Data) &&
strlen($Meme_Generator_Data['watermark_text']) == 7)
{
$wm_text = $this->convert_color(substr($Meme_Generator_Data['watermark_text'], 1));
$text_color = imagecolorallocate($watermark, $wm_text[0], $wm_text[1], $wm_text[2]);
} else {
$text_color = imagecolorallocate($watermark, 255, 255, 255);
}
imagestring($watermark, 5, 5, $height, $site_name, $text_color);
imagecopy($watermark, $img, 0, 0, 0, 0, $width, $height);
$img = $watermark;
Replace
imagecopy($watermark, $img, 0, 0, 0, 0, $width, $height);
with
imagecopy($watermark, $img, imagesx($img) - $width, 0, 0, 0, $width, $height);