TransWikia.com

How to save an image resource

Drupal Answers Asked by kosher on November 13, 2021

I have brought an image in from an API and cropped it using imagecrop in a custom module. I now have an image resource. But I cannot figure out how to turn the resource into a file I can save in Drupal or just save the resource directly as a file through Drupal. I have tried variations of file_get_contents and file_save_data. Any help would be appreciated.

When I use the following:

$cropped_image = imagecrop($image_resource, $rect);
$final_file = file_save_data($cropped_image);
$type = array('type' => $content_type);
$node = Drupal::entityTypeManager()
  ->getStorage('node')
  ->create($type);
$node->field_image = array(
  'target_id' => $image_file->id(),
);
$node->save();

I get the error "Call to a member function id() on bool in" on the $node->field_image line. That has made me think that the resource is not getting saved into a file with file_save_data() (obviously, not exactly sure what is happening).

When I included a file_get_contents($cropped_image) and then process that through file_save_data (as I do when I bring in an image from a URL), I end up with an error that the system is unable to handle the request in nothing in the recent log messages.

I have tried various other methods as well with no joy.

One Answer

I may have had the code correct at some time yesterday, but I was running out of memory on my localhost. I ended up rewriting some of the code and - once I realized I was having memory issues - moved everything onto the server, where it all worked like a charm. Sorry for asking the question. And, thanks, Simon, for provoking me to question everything anew with your comment.

Here is my final code;

            $cropped_image = imagecrop($precrop_resource, $rect);
            imagedestroy($precrop_resource);

            $file_path = Drupal::service('file_system')->realpath('public://');
            imagejpeg($cropped_image, $file_path . '/temp-image.jpg');

            // load the image
            $cropped_data = file_get_contents($file_path . '/temp-image.jpg');
            $cropped_file = file_save_data($cropped_data);
            unset($cropped_data);

Then I added the image to the node object and saved the node.

EDIT:

I eventually realized a couple issues with the above code. First, it was not just my memory on the localhost; processing 10MB+ jpegs would exhaust the memory on the server as well because the GD2 image tools process everything in uncompressed format. Second, the files were saving without .jpg on their filenames, so using them could be a problem.

So, I ended up using the ImageMagick to process things and added another variable to the file_save_data function call.

Here is my new and improved final code:

            // crop the image
            $precropped_image = new Imagick($precrop_file->getFileUri());           
            $precropped_image->cropImage($rect['width'], $rect['height'], $rect['x'], $rect['y']);
            $precropped_image->writeImage($file_path . '/temp-image.jpg');

            // save the cropped image in the Drupal DB
            $cropped_data = file_get_contents($file_path . '/temp-image.jpg');
            $cropped_file = file_save_data($cropped_data, 'public://' . $image_title . '-og.jpg');

Answered by kosher on November 13, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP