I'm going to set image perspective. I have image of laptop with blank polygon
Another image needs to be pulled on a blank area. Like this:
So, I have this code for dynamical distortion:
$controlPoints = array( 0, 0,
0, 0,
0, $im->getImageHeight(),
0, $im->getImageHeight(),
$im->getImageWidth(), 0,
$im->getImageWidth(), 0,
$im->getImageWidth(), $im->getImageHeight(),
$im->getImageWidth(), $im->getImageHeight());
/* Perform the distortion */
$im->distortImage(Imagick::DISTORTION_PERSPECTIVE, $controlPoints, true);
How can I set $controlPoints array? I can't just set 4 coordinates to each corner of image? Unfortunately, documention for imageick::distort image is poor.
Problem is solved by using another distortion method:
$im->cropImage( 125, 121, $center_x, $center_y );
$controlPoints = array(
0,0, 35,20, # top left
190,0, 150,30, # top right
0,205, -16,105, # bottom right
176,135, 115,105 # bottum left
);
/* Perform the distortion */
$im->distortImage(Imagick::DISTORTION_BILINEAR, $controlPoints, true);
The control points should be pairs of 4, as many as you need but at least 3 pairs.
The meaning of control points is
source_x, source_y, destination_x, destination_y
So it basically tells where should points from the source image go in the destination image.
In your case you will need 4 pairs, one for each corner of the rectangle:
$controlPoints = array(
0, 0, <destination_x>, <destination_y>,
0, $im->getImageHeight(), <destination_x>, <destination_y>,
$im->getImageWidth(), 0, <destination_x>, <destination_y>,
$im->getImageWidth(), $im->getImageHeight(), <destination_x>, <destination_y>
);
Obviously, you will have to figure out each destination coordinate and replace in the array above.
Related
I am using gd lib to merge several images, but I'm having problems with the transparency. First I merge several images which each have a transparent background (works fine). Then I want to put another picture on top which consists of three parts: one part that I want to keep, a transparent part where the images below should show and one part in a color (e.g. green #00ff00) which is supposed to become transparent as well after merging. The images are pixel images, so I only want #0f0 to become transparent, none other color.
Here is an image of the result of the code.
The first picture shows the merged images ("circle" & "cloud").
The second picture shows the "hat" which is put on top of the merged images.
The third picture shows the result I want to achieve.
The fourth picture is what I actually get.
Whatever I do, I can't seem to find the solution. I'd be grateful for your help!
header("Content-type: image/png");
$img = imagecreatetruecolor(200, 200);
//make an image with transparent background
$transparency = imagecolorallocatealpha($img, 0, 0, 0, 127);
imagefill($img, 0, 0, $transparency);
imagesavealpha($img, true);
$circle = imagecreatefrompng("testcircle.png"); //black circle
$cloud = imagecreatefrompng("testcloud.png"); //brown cloud
$hat = imagecreatefrompng("testhat.png"); //blue hat with green area
imagecopy($img, $circle, 0, 0, 0, 0, 200, 200);
imagealphablending($img,true);
imagecopy($img, $cloud, 0, 0, 0, 0, 200, 200);
imagealphablending($img,true);
$green = imagecolorallocate($hat, 0, 255, 0);
imagecolortransparent($hat, $green);
imagecopy($img, $hat, 0, 0, 0, 0, 200, 200);
imagealphablending($img,true);
/* //With this the green area just keeps being green as in the second picture
$green = imagecolorallocate($img, 0, 255, 0);
imagecolortransparent($img, $green);
imagecopy($img, $hat, 0, 0, 0, 0, 200, 200);
imagealphablending($img,true);
*/
imagepng($img);
imagedestroy($img);
After searching for a long time, I've found the solution for my problem. I hope it will help if someone has the same question as me in future.
$green = imagecolorallocate($img, 0, 255, 0);
imagecopy($img, $hat, 0, 0, 0, 0, 200, 200);
imagecolortransparent($img, $green);
imagefill($img,0,0,imagecolorallocatealpha($img, 0, 0, 0, 127)); //this line does the trick
First of all I define green as a color. Then I copy the "hat" onto the picture and make the color transparent. Then comes the trick about filling the picture and that makes the green area transparent again.
(I found the solution in a german forum).
I noticed that this code only makes the first green area transparent though. If there are two seperated areas (or even more), (at least) one will stay green. So while this is a solution that works for me, there might be one out there that is even better.
I would like to create a script which is generating an image with one fix background image but display a randomly selected sentence on the image from a list which is previously given in the script.
So far I have a base and I've tried many variations for the random text, but none of them worked until this time.
Here is the script itself:
<?php
header('Content-type: image/png');
$text = 'The text which will be displayed';
$background_path = 'assets/bg_image.jpg';
$image = imagecreatetruecolor(1280, 720);
$background = imagecreatefromjpeg($background_path);
$color = imagecolorallocate($image, 255, 255, 255);
$title_sizes = imagettfbbox(24, 0, 'assets/roboto-medium.ttf', $text);
$title_height = $title_sizes[3];
$title_width = $title_sizes[4];
imagecopy($image, $background, 0, 0, 0, 0, 1280, 720);
imagettftext($image, 24, 0, (640 - $title_width / 2), (360 - $title_height / 2), $color, 'assets/roboto-medium.ttf', $text);
imagepng($image);
imagedestroy($image);
imagedestroy($background);
?>
So the thing is that the line "$text" allows only one sentence to be displayed. I would like to have multiple lines (various sentences) instead which will be displayed on the given background image randomly upon refresh.
Can you please help me to solve this problem?
Thank you very much in advance!
Regards,
Adam
I want get the exact "gray level" of a given image in PHP. I can't understand why I always get [0, 0, 0] as RGB array using imagecolorsforindex. This is my code:
// load
$img = imagecreatefromjpeg("images/white.jpeg");
// to grayscale
imagefilter($img, IMG_FILTER_GRAYSCALE);
// just 1 pixel that describe the whole image
$grayLevel = resize_image($img, 1, 1);
$gray = imagecolorat($grayLevel, 1, 1);
$readble = imagecolorsforindex($grayLevel, $gray);
print_r($readble);
I first load my image (it's a completely white image, so every pixel should be [255, 255, 255] according to this) and then transform it in grayscale. I resize the image to only one pixel that describe the entire image and I get the RGB array. The array is [0, 0, 0].
I can't understand why I always get [0, 0, 0] with images in grayscale, with color. It the 1-pixel technique wrong?
Many thanks
PS: the resize_image works, I've tested it, anyway this is the code: https://pastebin.com/HNDzKq5E
The first pixel in the image exists at (0, 0), not (1, 1). Try changing
$gray = imagecolorat($grayLevel, 1, 1);
to
$gray = imagecolorat($grayLevel, 0, 0);
its working perfect, until i try to use a font for text.
This is my code.. The 3er line commented now is the one that works fine... but in this example im trying to replace this line with imagettftext.. not lucky.
Whats my error?
$newImage = imagecreatefromjpeg( "orsil_secure.jpg" );
$txtColor = imagecolorallocate($newImage, 0, 0, 0);
//imagestring($newImage, 5, 10, 27, $ranStr, $txtColor);
imagettftext($newImage, 5, 10, 27, $txtColor, $font_path, $ranStr);
header( "Content-type: image/jpeg" );
imagejpeg($newImage);
Oh yes in the previous lines is the route to the font here:
// random number
$ranStr = md5(microtime());
$ranStr = substr($ranStr, 0, 6);
// Set Path to Font File
$font_path = 'captcha.TTF';
It looks like you have the wrong parameters in your call to imagettftext.
Presumably, the 5 corresponds to the font used in imagestring, but has no place in imagettftext. You also need to specify the size and angle.
For example:
imagettftext($newImage, 12, 45, 10, 27, $txtColor, $font_path, $ranStr);
^^ ^^
|| ||
|| ------ angle
----------- size
In this example:
size=12px or 12pt, depending on whether you're using GD1 or GD2
angle = 45°
Obviously, you'll want to use your own values here.
If it still isn't working, then it's likely that the path to your font file is wrong. Check to see if it's in the same folder as the PHP script.
I think you are missing a parameter in your imagettftext.
If you look at http://php.net/manual/en/function.imagettftext.php it has size, angle, x and y.
You are missing one of the 4 (im guessing the angle).
So it needs to be something like:
imagettftext($newImage, 5, 0, 10, 27, $txtColor, $font_path, $ranStr);
Where 0 is for angle.
Hay, I'm using this code to generate an image and fill it with a gray colour.
$canvas = imagecreatetruecolor(100, 100);
$gray = imagecolorallocate($canvas, 0xEE, 0xEE, 0xEE);
imagefill($canvas, 0, 0, $gray);
imagegif($canvas);
This works fine, but if i change the canvas size to a 'long' image, it fails to fill.
$canvas = imagecreatetruecolor(1, 100);
Is this a common bug? Or do i need some other option? How do i fill the whole canvas?
Looks like a bug. I confirm the same behavior. It fills only top 2 pixels, if you specify the width to be 1. The similar for 2 or 3. 4 seems like a magic value - it begins to work there.
On the other hand this bug doesn't seem to appear if you use a 1px-high image, i.e. I tried this and it worked as expected:
$canvas = imagecreatetruecolor(100, 1);
$red = imagecolorallocate($canvas, 0xEE, 0, 0);
imagefill($canvas, 0, 0, $red);
imagegif($canvas, "output.png");
So this might be a kind of a workaround.