I am getting unwanted dashed black border when I rotate an image. I have tried to remove that but I am not finding any success. I am using the following function for image rotation. I try to preserve transparency. I have provided a image as well.
Here is an Image URL: http://s23.postimg.org/hep2pkol7/border.png
function imageRotation ($source, $rotang)
{
imagealphablending($source, false);
imagesavealpha($source, true);
$rotation = imagerotate($source, $rotang, imageColorAllocateAlpha($source, 0, 0, 0, 127));
imagealphablending($rotation, false);
imagesavealpha($rotation, true);
return $rotation;
}
I call the function something like that:
$rotatedImage = imageRotation($image, 10);
Here is the full code
<?php
// Some settings
$text = "Previously blogging";
$fontFace = 'Days.ttf';
$fontSize = 90;
$angle = 0;
$bbox = calculateTextBox($text, $fontFace, $fontSize, $angle);
$image = imagecreatetruecolor($bbox['width'], $bbox['height']);
// Define some colors
$black = imagecolorallocate($image, 0, 0, 0);
$yellow = imagecolorallocate($image, 0xFF, 0xFF, 0xFF);
//Fill the image with background color
imagefill($image, 0, 0, $yellow);
// Draw text
imagettftext($image, $fontSize, $angle, $bbox['left'], $bbox['top'], $black, $fontFace, $text);
$image = imageRotation($image, 20);
$im = imagecreatefromjpeg('weight-loss.jpg');
// Switch antialiasing on for one image
imageantialias($im, true);
$destWidth = imagesx($im);
$destHeight = imagesy($im);
$src_w = imagesx($image);
$src_h = imagesy($image);
$dst_x = ($destWidth - $src_w)/2;
$dst_y = ($destHeight - $src_h)/2;
imagecopy($im, $image, $dst_x, $dst_y, 0, 0, $src_w, $src_h);
header ('Content-Type: image/jpeg');
imagejpeg($im, null, 100);
imagedestroy($im);
imagedestroy($image);
function calculateTextBox($text,$fontFile,$fontSize,$fontAngle)
{
$rect = imagettfbbox($fontSize,$fontAngle,$fontFile,$text);
$minX = min(array($rect[0],$rect[2],$rect[4],$rect[6]));
$maxX = max(array($rect[0],$rect[2],$rect[4],$rect[6]));
$minY = min(array($rect[1],$rect[3],$rect[5],$rect[7]));
$maxY = max(array($rect[1],$rect[3],$rect[5],$rect[7]));
return array(
"left" => abs($minX),
"top" => abs($minY),
"width" => $maxX - $minX,
"height" => $maxY - $minY,
"box" => $rect
);
}
function imageRotation ($source, $rotang)
{
imagealphablending($source, false);
imagesavealpha($source, true);
$rotation = imagerotate($source, $rotang, imageColorAllocateAlpha($source, 0, 0, 0, 127), 0);
imagealphablending($rotation, false);
imagesavealpha($rotation, true);
return $rotation;
}
?>
This is neither a dashed border, nor a border at all actually. This happens because your images are low-resolution, what cause the the rotated borders to "break", because actual pixels don't rotate.
That's what I'm trying to explain:
A line, parallel to the "pixel construction"; one px is three dashes long:
-------------------------------------
It would look smooth.
Rotated line:
---
---
---
---
---
---
---
As you see, due to low resolution, it steps, not smoothly goes down.
If you use the higher resolution, the issue would go away. The visual effect of the "black" border appears because your white image contrasts with the other part of image.
Related
I want to add a color layer over a image in php using gd.
This is the image:
I want to overlay this with this color: #ABD0D2
I made a quick image how it should look at the end.
Keep in mind that the image should still be transparent
So far I have this code:
$img = imagecreatefrompng('image.png');
imagesavealpha($img, true);
imagefill($img, 0, 0, imagecolorallocatealpha($img, 0, 0, 0, 127));
// make overlay with new color???
imagepng($img, 'new.png');
imagedestroy($img);
You can create a new image, filled with your target colour, and then merge the two:
$img = imagecreatefrompng('image.png');
$w = imagesx($img);
$h = imagesy($img);
imagesavealpha($img, true);
$img2 = imagecreatetruecolor($w, $h);
imagefill($img2, 0, 0, imagecolorallocatealpha($img, 0xAB, 0xD0, 0xD2, 64));
imagecopy($img, $img2, 0, 0, 0, 0, $w, $h);
imagepng($img, 'new.png');
imagedestroy($img);
imagedestroy($img2);
Result:
It's not completely clear to me how you want to maintain transparency (as your expected result image isn't transparent) so in the code above I've set the 'mask' colour at 50% opacity.
That worked for me:
$width = 400;
$height = 400;
$image = imagecreatefrompng('img.png');
$blueOverlay = imagecreatetruecolor($width, $height);
imagesavealpha($image, true);
imagealphablending($image, false);
imagesavealpha($blueOverlay, true);
$blue = imagecolorallocatealpha($blueOverlay, 0, 0, 255, ceil(0.22 * 127));
imagefill($blueOverlay, 0, 0, $blue);
imagecopymerge($blueOverlay, $image, 0, 0, 0, 0, $width, $height, 70);
imagepng($blueOverlay, 'imgWithOverlay.png');
imagedestroy($image);
imagedestroy($blueOverlay);
So I'm trying to take two large images (but later I'll be combinging 6 images in total), resize them to the x, y width, height I have taken from photoshop, and combine them into one 460 x 230 sized image.
This is the code I'm using
<?php
$dest = imagecreatefrompng('https://blzgdapipro-a.akamaihd.net/hero/ana/career-portrait.png');
$src = imagecreatefrompng('https://blzgdapipro-a.akamaihd.net/game/rank-icons/season-2/rank-6.png');
imagealphablending($dest, false);
imagesavealpha($dest, true);
imagealphablending($src, false);
imagesavealpha($src, true);
//imagescale($dest, 396, 161.92);
$some = imagecreate(460, 230);
$dest2 = resize($dest, 396, 162);
$src2 = resize($src, 79.19, 79.19);
//imagecopyresized($dest, $dest, 0, 0, 0, 0, 396, 161.92, 1098, 449);
imagecopyresized($src, $src, 10, 10, 0, 0, 79.19, 79.19, 256, 256);
//$img2 = imagecopymerge($dest, $src, 0, 0, 0, 0, 256, 256, 100); //have to play with these numbers for it to work for you, etc.
imagecopymerge($dest2, $src2, 0, 0, 0, 0, 460, 230, 50);
header('Content-Type: image/png');
imagepng($dest, 'merged2.png');
imagepng($dest2);
//file_put_contents('merged.png', $contents);
imagedestroy($dest);
imagedestroy($src);
imagedestroy($some);
imagedestroy($dest2);
imagedestroy($src2);
imagedestroy($img2);
//imagedestroy($then);
function resize($img, $width, $height, $stretch = false)
{
$temp = imagecreatetruecolor($width, $height);
imagealphablending($temp, true);
imagesavealpha($temp, true);
$bg = imagecolorallocatealpha($temp, 0, 0, 0, 0); // Background color
imagefill($temp, 0, 0, $bg);
if ($stretch)
{
imagecopyresampled($temp, img, 0, 0, 0, 0, $width, $height, imagesx($img), imagesy($img));
}
else
{
if (imagesx($img) <= $width && imagesy($img) <= $height)
{
$fwidth = imagesx($img);
$fheight = imagesy($img);
}
else
{
$wscale = $width / imagesx($img);
$hscale = $height / imagesy($img);
$scale = min($wscale, $hscale);
$fwidth = $scale * imagesx($img);
$fheight = $scale * imagesy($img);
}
imagecopyresampled($temp,
$img,
($width - $fwidth) / 2, ($height - $fheight) / 2,
0, 0,
$fwidth, $fheight,
imagesx($img), imagesy($img)
);
}
return $temp;
}
The issue is that the image rendered is very faded
because of this line:
imagecopymerge($dest2, $src2, 0, 0, 0, 0, 460, 230, 50);
If I change the 50, which is the PCT value to 100, it shows one image with a black background (masking the other image), but if I change it to 0, it shows only the other image with a black background (masking the other image)
If the value is either 0 or 100, the image shown is at its full color though. How do I merge these 2 images together while preserving their transparency and vibrancy of color?
Instead of imagecopymerge use imagecopy. You also always need to correctly specify the dimensions of the source image when copying:
$dest = imagecreatefrompng('https://blzgdapipro-a.akamaihd.net/hero/ana/career-portrait.png');
$src = imagecreatefrompng('https://blzgdapipro-a.akamaihd.net/game/rank-icons/season-2/rank-6.png');
$dest2 = resize($dest, 396, 162);
imagedestroy($dest);
$src2 = resize($src, 79, 79); // should be int not float.
imagedestroy($src);
// the last 2 params must match the width/height of the $src2 image.
imagecopy($dest2, $src2, 0, 0, 0, 0, 79, 79);
imagedestroy($src2);
header('Content-Type: image/png');
imagepng($dest2);
imagedestroy($dest2);
You don't need to change the alpha settings on $dest or $src because they aren't being rendered - you render the new image resource created in, and returned by, your resize function. Because of this you do need to slightly change the function:
function resize($img, $width, $height, $stretch = false)
{
$temp = imagecreatetruecolor($width, $height);
imagealphablending($temp, false); // changed to false.
imagesavealpha($temp, true);
...
Edit:
You might be better off simply using the imagescale function instead of using your own resize function:
$dest = imagecreatefrompng('https://blzgdapipro-a.akamaihd.net/hero/ana/career-portrait.png');
$src = imagecreatefrompng('https://blzgdapipro-a.akamaihd.net/game/rank-icons/season-2/rank-6.png');
$dest2 = imagescale($dest, 396);
imagealphablending($dest2, false);
imagesavealpha($dest2, true);
$src2 = imagescale($src, 79);
imagecopy($dest2, $src2, 0, 0, 0, 0, 79, 79);
header('Content-Type: image/png');
imagepng($dest2);
imagedestroy($dest);
imagedestroy($src);
imagedestroy($dest2);
imagedestroy($src2);
Im trying to crop a square image and merge it with a Marker, but i cant get the copped circle image to be transparent.
When is save the circle image as a PNG , it shows it OK with Transparent corners, but when i open it in Photoshop it has a White Color on the corners like the final image below.
here is the code im using:
//SAVED THE CIRCLE PNG IMAGE
$width = 320;
$height = 320;
$img1 = '';
switch($fileExt){
case '.png':
$img1 = ImageCreateFrompng($img= $image_config['new_image']);
break;
case '.jpg':
$img1 = ImageCreateFromjpeg($img= $image_config['new_image']);
break;
case '.gif':
$img1 = ImageCreateFromgif($img= $image_config['new_image']);
break;
}
$x=$width ;
$y=$height;
$img2 = imagecreatetruecolor($x, $y);
$bg = imagecolorallocate($img2, 255, 255, 255);
imagefill($img2, 0, 0, $bg);
$e = imagecolorallocate($img2, 0, 0, 0);
$r = $x <= $y ? $x : $y;
imagefilledellipse ($img2, ($x/2), ($y/2), $r, $r, $e);
imagecolortransparent($img2, $e);
imagecopymerge($img1, $img2, 0, 0, 0, 0, $x, $y, 100);
imagecolortransparent($img1, $bg);
header("Content-type: image/png");
imagepng($img1, './img/deviceImg/pin'.$datetime.'.png');
imagedestroy($img2); // kill mask first
imagedestroy($img1); // kill canvas last
//MERGING IT WITH THE PIN
$width = 320;
$height = 320;
$image_1 = imagecreatefrompng('./img/deviceImg/pin.png');
imagesavealpha($image_1, true);
imagealphablending($image_1, true);
$image_2 = imagecreatefrompng('./img/deviceImg/pin'.$datetime.'.png');
imagesavealpha($image_2, true);
imagealphablending($image_2, true);
imagecopy($image_1, $image_2, 40, 22, 0, 0, $width, $height);
imagepng($image_1, './img/deviceImg/pinASD'.$datetime.'.png');
Transparency is only copied with imagecopymerge(), not imagecopy(). So your penultimate line:
imagecopy($image_1, $image_2, 40, 22, 0, 0, $width, $height);
Should be changed to:
imagecopymerge($image_1, $image_2, 40, 22, 0, 0, $width, $height, 100);
Note the extra parameter (pct) at the end. As per the manual:
The two images will be merged according to pct which can range from 0 to 100. When pct = 0, no action is taken, when 100 this function behaves identically to imagecopy() for pallete images, except for ignoring alpha components, while it implements alpha transparency for true colour images.
I have one problem with PHP create image. What is wrong with my following code?
<?php
$filename = 'play';
$img = "http://www.slcentral.com/ipod-mp3-player/5.JPG";
$image = imagecreatefromjpeg($img);
$cleft = 0;
$ctop = 45;
$canvas = imagecreatetruecolor(480, 270);
imagecopy($canvas, $image, 0, 0, $cleft, $ctop, 480, 360);
$image = $canvas;
$imageWidth = imagesx($image);
$imageHeight = imagesy($image);
// ADD THE PLAY ICON
$play_icon = "f-play.png";
$logoImage = imagecreatefrompng($play_icon);
imagealphablending($logoImage, TRUE);
$logoWidth = imagesx($logoImage);
$logoHeight = imagesy($logoImage);
// CENTER PLAY ICON
$left = round($imageWidth / 2) - round($logoWidth / 2);
$top = round($imageHeight / 2) - round($logoHeight / 2);
// CONVERT TO PNG SO WE CAN GET THAT PLAY BUTTON ON THERE
imagecopy( $image, $logoImage, $left, $top, 0, 0, $logoWidth, $logoHeight);
imagepng( $image, $filename .".png", 9);
// MASHUP FINAL IMAGE AS A JPEG
$input = imagecreatefrompng($filename .".png");
$output = imagecreatetruecolor($imageWidth, $imageHeight);
$white = imagecolorallocate($output, 255, 255, 255);
imagefilledrectangle($output, 0, 0, $imageWidth, $imageHeight, $white);
imagecopy($output, $input, 0, 0, 0, 0, $imageWidth, $imageHeight);
// OUTPUT TO 'i' FOLDER
header("Content-type: image/jpeg");
imagejpeg($output, $filename . ".jpg", 95);
// UNLINK PNG VERSION
#unlink($filename .".png");
die();
?>
Above code is create one image from giving url and add play icon to it. And I want to access to http://coolrss.com/create-img.php it will show image with play icon.
Please help!
Make sure the path has the right permission or you will get:
PHP Warning: imagepng(): Unable to open 'play.png' for writing: Permission denied in /var/www/coolrss/public_html/create-img.php on line 32
Make sure you have installed GD.
Start your code with this header (after the php tag (<?php))
header("Content-Type: image/jpeg");
At the end (last line) add
imagejpeg($output, NULL, 100);
Your code looks like this now:
<?php
header("Content-Type: image/jpeg");
$filename = 'play';
$img = "http://www.slcentral.com/ipod-mp3-player/5.JPG";
$image = imagecreatefromjpeg($img);
$cleft = 0;
$ctop = 45;
$canvas = imagecreatetruecolor(480, 270);
imagecopy($canvas, $image, 0, 0, $cleft, $ctop, 480, 360);
$image = $canvas;
$imageWidth = imagesx($image);
$imageHeight = imagesy($image);
// ADD THE PLAY ICON
$play_icon = "f-play.png";
$logoImage = imagecreatefrompng($play_icon);
imagealphablending($logoImage, TRUE);
$logoWidth = imagesx($logoImage);
$logoHeight = imagesy($logoImage);
// CENTER PLAY ICON
$left = round($imageWidth / 2) - round($logoWidth / 2);
$top = round($imageHeight / 2) - round($logoHeight / 2);
// CONVERT TO PNG SO WE CAN GET THAT PLAY BUTTON ON THERE
imagecopy( $image, $logoImage, $left, $top, 0, 0, $logoWidth, $logoHeight);
imagepng( $image, $filename .".png", 9);
// MASHUP FINAL IMAGE AS A JPEG
$input = imagecreatefrompng($filename .".png");
$output = imagecreatetruecolor($imageWidth, $imageHeight);
$white = imagecolorallocate($output, 255, 255, 255);
imagefilledrectangle($output, 0, 0, $imageWidth, $imageHeight, $white);
imagecopy($output, $input, 0, 0, 0, 0, $imageWidth, $imageHeight);
imagejpeg($output, NULL, 100);
Screenshot - Works for me
So I have an image, and I am writing text and a color box onto the image. It works but it's being added to the image in the top right corner, but I need it in the center of the image. I tried changing the x and y variables, but it only moves the text and not the white box.
Here is code
$image_filepath = './kenshin.jpg';
saveImageWithText("Welcome to Eureka!", $color, $image_filepath);
function saveImageWithText($text, $color, $source_file) {
$public_file_path = '.';
// Copy and resample the imag
list($width, $height) = getimagesize($source_file);
$image_p = imagecreatetruecolor($width, $height);
$image = imagecreatefromjpeg($source_file);
imagecopyresampled($image_p, $image, 0, 0, 0, 0, $width, $height, $width, $height);
// Prepare font size and colors
$text_color = imagecolorallocate($image_p, 0, 0, 0);
$bg_color = imagecolorallocate($image_p, 255, 255, 255);
$font = $public_file_path . '/arial.ttf';
$font_size = 12;
// Set the offset x and y for the text position
$offset_x = 0;
$offset_y = 20;
// Get the size of the text area
$dims = imagettfbbox($font_size, 0, $font, $text);
$text_width = $dims[4] - $dims[6] + $offset_x;
$text_height = $dims[3] - $dims[5] + $offset_y;
// Add text background
imagefilledrectangle($image_p, 0, 0, $text_width, $text_height, $bg_color);
// Add text
imagettftext($image_p, $font_size, 0, $offset_x, $offset_y, $text_color, $font, $text);
// Save the picture
imagejpeg($image_p, $public_file_path . '/output.jpg', 100);
// Clear
imagedestroy($image);
imagedestroy($image_p);
};
Here is output
Try this. It will help you…
<?php
$img = imagecreatefromjpeg("girl-hugging-the-globe.jpg"); // image.jpg is the image on which we are going to write text ,you can replace this iamge name with your
if(!$img) die("Unabe to load image");
$red = imagecolorallocate($img, 255, 0, 0);
$green = imagecolorallocate($img, 0, 255, 0);
$width = 600;// it will store width of image
$height = 100; //it will store height of image
$fontsize = 6; // size of font
$text = "Block Prints Online"; // Define the text
$pos = ( $width - imagefontwidth($fontsize)*STRLEN($text) );// calculate the left position of the text:
imagestring($img, $fontsize, 200, 150, $text, $red);
header('Content-type: image/jpeg');
imagejpeg($img);//it will output a jpeg image
imagedestroy($img);//it will destroy $img*/
?>