I found this nice code :
https://phpimagick.com/Tutorial/backgroundMasking
But I get the same picture without checkerboard. Something is wrong in my config or in the code ?
My best working code is :
$BackgroundColor = "rgb(255, 255, 255)";
$img = new Imagick();
$img->readImage('xxxxx.jpg');
$img->setImageFormat('png');
$fuzz = Imagick::getQuantum() * 0.1; // 10%
$img->transparentPaintImage($BackgroundColor,0,$fuzz,false);
$img->writeImage('xxxx.png');
But without blur and mask :(
Any idea ?
maybe there is a better way but just remove this line works for me :)
$mask->setImageAlphaChannel(\Imagick::ALPHACHANNEL_DEACTIVATE);
Related
It's driving me insane.. Just searched for hours to find a solution. But nothing really found. So hopefully anyone can help me.
I'm trying to create an customized image on the fly. I use this to create the images: https://github.com/Treinetic/ImageArtist
Everything works fine except the font. This is the snippet from the class:
$im = new \Imagick();
$background = new \ImagickPixel('none');
$im->setBackgroundColor($background);
$im->setFont($font->getPath());
$im->setPointSize($writer->getSize() * (0.75));
$im->setGravity(\Imagick::GRAVITY_EAST); //later we will have to change this
$width = $writer->getWidth();
$height = $writer->getHeight();
$text = $writer->getText();
$margin = $writer->getMargin();
$im->newPseudoImage($width, $height, "pango:" . $text );
$clut = new \Imagick();
$clut->newImage(2, 2, new \ImagickPixel($color->toString()));
$im->clutImage($clut);
$clut->destroy();
$im->setImageFormat("png");
$image = imagecreatefromstring($im->getImageBlob());
$template = $this->imageHelper->createTransparentTemplate($width+ (2*$margin),$height+ (2 *$margin));
$img = new Image($template);
$text = new Image($image);
imagedestroy($image);
imagedestroy($template);
return $img->merge($text,$margin,$margin);
The $font-getPath(); looks correct and echo /var/www/vhosts/example.com/dev-test/ImageArtist/src/lib/AssetManager/../../resources/Fonts/Gotham-Light.ttf
This is the full code
use Treinetic\ImageArtist\lib\PolygonShape;
use Treinetic\ImageArtist\lib\Text\TextBox;
use Treinetic\ImageArtist\lib\Text\Color;
use Treinetic\ImageArtist\lib\Text\Font;
use Treinetic\ImageArtist\lib\Overlays\Overlay;
use Treinetic\ImageArtist\lib\Image;
require('../vendor/autoload.php');
$main_image = new Image("ranks/main-image.png");
$textBox = new TextBox(720,40);
$textBox->setColor(new Color(0,0,0, 125));
$textBox->setFont(Font::getFont('./Gotham-Light.ttf'));
$textBox->setSize(42);
$textBox->setMargin(0);
$textBox->setText($_GET["name"]);
$main_image->setTextBox($textBox, 40, 620);
$main_image->save("./newImage.png",IMAGETYPE_PNG);
But the font specified is not used by Imagick. If i try to create an image from den command line via
convert -font /var/www/vhosts/example.com/dev-test/ImageArtist/src/lib/AssetManager/../../resources/Fonts/Gotham-Light.ttf -pointsize 72 label:Test test.gif
And... The Font is used on command line created image :/ The font file is reachable and readable via php but not used via Imagick ....
Does anyone has an idea why php imagick can't use my font but convert -font can?
The script is running on PHP-FPM 7.0.23 on an dedicated root server with nginx as an RPS.
Hope you can help me out.. It really drives me crazy :)
Thanks
Stanlay
SOLVED
Found out that $im->newPseudoImage($width, $height, "pango:" . $text ); cause the issue. Switching to $im->newPseudoImage($width, $height, "caption:" . $text ); and everything works fine.
I installed Yii and Imagine with composer and tried to use imagine.
the issue is when i try to use this code from the imagine website introduction i got an error 500 :
Argument 2 passed to Imagine\Gd\Imagine::create() must be an instance of Imagine\Image\Color, instance of Imagine\Image\Palette\Color\RGB given
code:
use Imagine\Image\Box;
$imagine = new Imagine\Gd\Imagine();
$palette = new Imagine\Image\Palette\RGB();
$size = new Box(400, 300);
$color = $palette->color('#000', 100);
$image = $imagine->create($size, $color);
$image->save('images/test.png');
when i edit this line :
$image = $imagine->create($size, $color);
with
$image = $imagine->create($size);
the picture is created white so i guess Imagine is working
Did i miss something ? Do i have to change something in the config or something else ?
Any idea will be much appreciated
Thanks
Trying to take a rectangular photo, crop it into a square region, and then mask it into a circular with a transparent background.
//$dims is an array with the width, height, x, y of the region in the rectangular image (whose path on disk is $tempfile)
$circle = new \Imagick();
$circle->newImage($dims['w'], $dims['h'], 'none');
$circle->setimageformat('png');
$circle->setimagematte(true);
$draw = new \ImagickDraw();
$draw->setfillcolor('#ffffff');
$draw->circle($dims['w']/2, $dims['h']/2, $dims['w']/2, $dims['w']);
$circle->drawimage($draw);
$imagick = new \Imagick();
$imagick->readImage($tempfile);
$imagick->setImageFormat( "png" );
$imagick->setimagematte(true);
$imagick->cropimage($dims['w'], $dims['h'], $dims['x'], $dims['y']);
$imagick->compositeimage($circle, \Imagick::COMPOSITE_DSTIN, 0, 0);
$imagick->writeImage($tempfile);
$imagick->destroy();
The result is the rectangular image, uncropped and without being circularized. What am I doing wrong?
Example image:
Example input for $dims = {"x":253,"y":0,"x2":438.5,"y2":185.5,"w":185.5,"h":185.5}
Rough expected output:
Image i'm getting looks roughly like the input image.
For those with an older version of Imagick (setimagematte does not exist in version lower than 6.2.9), I came up with an easy solution. The thing here is to copy opacity from the mask to the original image.
Original Image:
Mask:
Result:
The code:
$base = new Imagick('original.jpg');
$mask = new Imagick('mask.png');
$base->compositeImage($mask, Imagick::COMPOSITE_COPYOPACITY, 0, 0);
$base->writeImage('result.png');
You could use an Imagick black circle as mask but I though it wasn't perfect so I used my own.
Of course you will certainly have to resize / crop your images but that's another story.
Hope this helps.
J.
This works for me:
<?php
//$dims is an array with the width, height, x, y of the region in the rectangular image (whose path on disk is $tempfile)
$tempfile = 'VDSlU.jpg';
$outfile = 'blah.png';
$circle = new Imagick();
$circle->newImage(185.5, 185.5, 'none');
$circle->setimageformat('png');
$circle->setimagematte(true);
$draw = new ImagickDraw();
$draw->setfillcolor('#ffffff');
$draw->circle(185.5/2, 185.5/2, 185.5/2, 185.5);
$circle->drawimage($draw);
$imagick = new Imagick();
$imagick->readImage($tempfile);
$imagick->setImageFormat( "png" );
$imagick->setimagematte(true);
$imagick->cropimage(185.5, 185.5, 253, 0);
$imagick->compositeimage($circle, Imagick::COMPOSITE_DSTIN, 0, 0);
$imagick->writeImage($outfile);
$imagick->destroy();
?>
<img src="blah.png">
I always try to keep the code simple until I get it working and then add all the variables etc. That could be the problem or there could be a problem with your version of Imagick.
It's namespaced
Still do not know what it means! - I am getting a bit behind with php as I do not use it very much these days.
There's also another workaround that I suggest here :
// create an imagick object of your image
$image = new \Imagick('/absolute/path/to/your/image');
// crop square your image from its center (100px witdh/height in my example)
$image->cropThumbnailImage(100, 100);
// then round the corners (0.5x the width and height)
$image->roundCorners(50, 50);
// force the png format for transparency
$image->setImageFormat("png");
// write the new image
$image->writeImage('/absolute/path/to/your/new/image');
// done!
Many thanks to all previous answers and contributors that lead me to this code!
Feel free to test/comment my solution!
I stumbled upon this as I was searching for a similar solution for Ruby on Rails, notice that this Stackoverflow question uses vignette instead which seems to be a much simpler way to solve the problem.
I used vignette to solve my problem with rounded images in Ruby on Rails using Dragonfly.
I need to take an image and move it upwards 1 px in certain situations for my code, but with what GD function would I use to do that? I couldn't find another question that asked this, so I asked it. But the middle of the picture is a number and the background is transparent, and the height and width is almost always different
Here's an example. The key part is imagecopymerge() function. play with it's 0,0,1,0 values.
<?php
$src = imagecreatefromgif($img);
list($w,$h) = getimagesize($img);
$sprite = imagecreatetruecolor($w,$h);
$trans = imagecolortransparent($sprite);
imagealphablending($sprite, false);
imagesavealpha($sprite, true);
imagepalettecopy($sprite,$src);
imagefill($sprite,0,0,imagecolortransparent($src));
imagecolortransparent($sprite,imagecolortransparent($src));
imagecopy($sprite,$src,0,0,1,0,$w,$h);
imagegif($sprite,$img);
imagedestroy($sprite);
imagedestroy($src);
?>
I really cannot find a way to successfully do it.. I've searched google for this and it either has black shades around the images or all the images don't overlap. Could you please help?
I am alright at PHP; I'd give myself a 2/5.. I would really appreciate if someone would be willing to help me out.
I'm looking for a simple api that goes something like:
$color=$_GET['color'];
$face=$_GET['face'];
$hat=$_GET['hat'];
echo '<img src="avatar.php?color=$color&face=$face&hat=$hat">';
Thanks for any help in advance. I can understand php from my knowledge of other languages, too, so don't be afraid to talk technical with me; but not too technical.
there are so many comments on this answer so I'm posting this as an answer.
Got it working on my pc.
use svens code :
$images = array( $_GET['color'], $_GET['face'], $_GET['hat'] );
// Allocate new image
$img = imagecreatetruecolor(58, 75);
// Make alpha channels work
imagealphablending($img, true);
imagesavealpha($img, true);
foreach($images as $fn) {
// Load image
$cur = imagecreatefrompng($fn);
imagealphablending($cur, true);
imagesavealpha($cur, true);
// Copy over image
imagecopy($img, $cur, 0, 0, 0, 0, 58, 75);
// Free memory
imagedestroy($cur);
}
header('Content-Type: image/png'); // Comment out this line to see PHP errors
imagepng($img);
?>
I renamed your images like this so its easier :
smile : a.png
headset : b.png
blue : c.png
Turns out the problem is with the layering it. Putting one behind the other
after you rename the images, use this url -- it will work(works on my pc).
YOUR_FILE.php?hat=b.png&color=c.png&face=a.png
This will still give you a black background. I am not sure if you have the exact same code as above in your file on the server - because I played around with the image order on your link and it does not help. Try copy-pasting this exact same code on a different file and then trying. Play around with the order and check the results.
Here's some code to get you started. However you should note that image processing with gd and alpha channels is voodoo.
<?php
$images = array( $_GET['color'], $_GET['face'], $_GET['hat'] );
// Allocate new image
$img = imagecreatetruecolor(58, 75);
// Make alpha channels work
imagealphablending($img, true);
imagesavealpha($img, true);
foreach($images as $fn) {
// Load image
$cur = imagecreatefrompng($fn);
imagealphablending($cur, true);
imagesavealpha($cur, true);
// Copy over image
imagecopy($img, $cur, 0, 0, 0, 0, 58, 75);
// Free memory
imagedestroy($cur);
}
header('Content-Type: image/png'); // Comment out this line to see PHP errors
imagepng($img);
?>
What you still have to do now is checking the return values (look up the image* functions in the manual) to make sure it doesn't fail silently.
I can't really promise it's going to work with the alpha channels.. If not you'll probably have to go through the comments to the imagecopymerge() or imagecopy() on php.net and see if I missed something.