Jump to content

ImageMagick and Processwire (PHP & API)


creativejay
 Share

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!

Link to comment
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?

Link to comment
Share on other sites

  • 2 weeks later...
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.

Link to comment
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.

Link to comment
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

 

Link to comment
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
Link to comment
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
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...