Jump to content
creativejay

ImageMagick and Processwire (PHP & API)

Recommended Posts

I thought this would be simple. I want to make a composite image from a background I provide and a logo (jpg or png) provided by a user, where the logo is resized and placed (retaining its transparency) on top of the background.

Being completely unfamiliar with the API of Imagick, I can't even get it off the ground. But it seems as though this should be fairly straightforward:

$exhibitors = $users->find("roles=exhibitor, limit=1");
			
			foreach($exhibitors as $getKV) {
				$ex_logo = $getKV->exhibitor_logo->path . $getKV->exhibitor_logo->filename;
				$background = $config->urls->templates . "images/Exhibitor-Graphic-BG-Silver.jpg";
				   $imagick = new \Imagick($background);
				   $imagick2 = new \Imagick($ex_logo);
				   $imagick1->compositeImage($imagick2, $type, 0, 0);
				   $imagick1->setImageFormat('jpg');
				
				   $image->setImageFormat("jpg");
				   header("Content-Type: image/jpg");
				   echo $imagick->getImageBlob();			
				}

However it results in:

Quote

 

ImagickException #435

unable to open image `/site/templates/images/Exhibitor-Graphic-BG-Silver.jpg': No such file or directory @ error/blob.c/OpenBlob/2614

 

I realize not everything I want to do (including the resize) is covered in the script above, but first we need the script to even find the images, and that is failing. The examples I find for Imagick often place their source images in the same directory, which doesn't help me figure out what's wrong with the formatting of my path. 

I have already tried using static strings for $imagick and $imagick2, starting from the server's user directory and starting from the public_html directory, with the same result.

Has anyone used Imagick for composite images, who can see what I'm doing wrong here? 

Is there a better way to go about this?

 

Thanks!

Share this post


Link to post
Share on other sites

Ah, thank you, that corrects the path. Both image variable paths now output starting from the server root.

				if($getKV->exhibitor_logo->width >= $getKV->exhibitor_logo->height) {
					 $logoresize =  $getKV->exhibitor_logo->width(1500);
					} else {
					 $logoresize =  $getKV->exhibitor_logo->height(500);
				}
				$ex_logo = $logoresize->path . $logoresize->filename;
				$background = $config->path('templates') . "images/Exhibitor-Graphic-BG-Silver.jpg";
				$imagick = new \Imagick($background);
				$imagick2 = new \Imagick($ex_logo);
				  
				$imagick->compositeImage($imagick2, \Imagick::COMPOSITE_ATOP, 0, 0);   
				$imagick->setImageFormat('jpg');
									
				header("Content-Type: image/jpg");
				echo $imagick->getImageBlob(); 	

The above seems as though it should work, but the page silently fails (no logs, no content). Is this the bug I've seen people discuss where it times out before the allotted time when there's more than one Imagick thread? Or could something else be causing it?

Share this post


Link to post
Share on other sites

No idea... try this alternative:

$im = new \Imagick(); 
$im->readImageBlob($imageurl);

 

Share this post


Link to post
Share on other sites
On 10/3/2019 at 10:54 AM, Pixrael said:

No idea... try this alternative:


$im = new \Imagick(); 
$im->readImageBlob($imageurl);

 

Thanks. This displays an empty image object (which renders as a small empty square). 😩 

I also tried changing the source images in $ex_logo and $background from path to url but that didn't have a positive effect.

Share this post


Link to post
Share on other sites

It work for me. Try to assign the image path manually to verify that the Imagick is working:

$im->readImageBlob("https://www.domain.com/site/templates/images/image.svg");

If you are able to open the picture in the browser using the path, this should render the picture on the page.

Share this post


Link to post
Share on other sites
1 hour ago, Pixrael said:

It work for me. Try to assign the image path manually to verify that the Imagick is working:


$im->readImageBlob("https://www.domain.com/site/templates/images/image.svg");

If you are able to open the picture in the browser using the path, this should render the picture on the page.

				header("Content-Type: image/jpg");	
				$im = new
				\Imagick(); 
				$im->readImageBlob("https://www.ketocon.org/site/assets/files/1130/ketovangelist-lockup-w-tag_glc-lg.1500x0.png");
				

Still getting a blank square. (doesn't work if I put 'png' for the header, either, or try the other half of the image I'm trying to composite, which is a jpg)

Here's my imagick install (from phpinfo):

548007845_ScreenShot2019-10-14at5_05_49PM.png.0200c92231b0830338e57a0c10666ee5.png

 

Share this post


Link to post
Share on other sites

This is my code fragment that is currently working.. but I save the image to file because my case

// here I load the SVG file
$svg = file_get_contents("https://www.domain.com/site/templates/images/$image.svg");

// here goes code to modify some elements, colors and texts in the svg
....

// here I set the SVG var to Imagick and save to a PNG file ready for download
$im = new \Imagick(); 
$im->readImageBlob($svg); 
$im->setImageFormat("png24");
$im->scaleImage(1024, 1024, true);
$im->writeImage("../downloads/$filename");
$im->clear();
$im->destroy();

$file = "https://www.domain.com/site/downloads/$filename";
echo $file;

I implemented it as a service that is called by AJAX and returns the URL to the generated image.

  • Thanks 1

Share this post


Link to post
Share on other sites

Thank you, Pixrael! That got me to the solution!

 

				$loadLogo = $getKV->exhibitor_logo;
				$logoresize = $loadLogo->pim2Load('ig')->canvas(1600,895,array(0, 0, 0, 0),'c',0)->setOutputFormat("png")->pimSave()->httpUrl;
					
				$exlogo = $logoresize;
				$filename = $getKV->name . "_instagram.png";
				
				$background = "https://domain.com/site/templates/images/Exhibitor-Graphic-BG-Platinum.jpg";
				
				
				$logo =
				file_get_contents("$exlogo");
				$bg =
				file_get_contents("$background");
				
				$im = new \Imagick(); 
				$im->readImageBlob($bg);
				$im2 = new \Imagick();
				$im2->readImageBlob($logo);
				
				$im->compositeImage($im2, \Imagick::COMPOSITE_ATOP, 100, 350);   
				
				
				$im->setImageFormat("png24");
				$im->scaleImage(1024,
				1024, true);
				$im->writeImage("../downloads/$filename");
				$im->clear();
				$im->destroy();
				
				$file =
				"https://domain.com/site/downloads/$filename";
				echo "<img src='$file' alt='$getKV->name' />";

Now I just need to bring in the code to start with a different background graphic based on the order history in Padloper. In THEORY, I'm almost there! 😅

 

Thanks so much for your help!

  • Like 1

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...