0

I've got a perl program that grabs a screenshot as a png and inserts it into a variable:

my $png_data = $s->chrome->render_content(format => 'png');

Currently, I save the $png_data straight to a disk and then crop the resulting file with Imagemagick. Then I load the file back into a variable which I write to the database as a BLOB.

This is obviously wasteful.

Rather than saving it to disk, and then reading it back off disk, I'd just like to crop it while in memory and then save to the database.

How can I accomplish this?

* UPDATE * Here is the solution I ended up going with, which took a bit of time to find and noodle out as I'm not very familiar with Imagemagick:

use Image::Magick;
# screenshot grabbed with WWW::Mechanize::Chrome;
# returned value of $png_data is a "blob" which can be saved in db or to file
my $png_data    = $s->chrome->render_content(format => 'png');

# create object to process image
my $img         = Image::Magick->new(magick=>'png');

# BlobToImage functions converts data to image that IM can process
$img->BlobToImage($png_data);

# do some processing of image
my $x = $img->Crop(geometry => "1028x5000+370+880");
print "$x" if "$x";

# now, the tricky part is saving the image by writing the $img back into a Perl string like this:
open (my $fh, '>', \$png_data) || die 'Could not write to string';
$img->Write(filename => $fh, quality => 100, depth => 4);
close $fh;

# The Write() method basically converts it back to a blob. Then you can store the $png_data string into the database in a BLOB column.

# NOTE: I'm not 100% sure if last line worked as I decided to save the image to a file. It seemed to work as I didn't get any errors but I did not verify that the data was actually in the database. But some variation of that last line should work if that one doesn't.
StevieD
  • 6,925
  • 2
  • 25
  • 45
  • Find an image-manipulation module for Perl that can handle PNG images (I believe there's a Perl binding for the ImageMagick library). Install it. Read the documentation to learn how to use it to crop the image in memory. Write the code. What's your question? – Jim Garrison Jun 19 '18 at 04:58
  • The question is the one you didn't answer: What's a good way to accomplish this? Looking for suggestions on easy-to-use modules. – StevieD Jun 19 '18 at 05:16
  • THAT is off-topic according to the rules here. You are expected to do your own research. Please visit the [help] and read [ask] to learn how to use this site effectively. Also, I ***DID*** tell you ***exactly*** where to look. Did you bother to Google "Perl ImageMagick"? – Jim Garrison Jun 19 '18 at 05:17
  • 1
    See also [cropping an image with GD](https://stackoverflow.com/questions/17978193/crop-image-using-gd-library). ImageMagick is powerful, but it's a beast to work with. BTW I don't think asking for recommendations on which library to use for such a task should be off-topic, but indeed it is. – reinierpost Jun 19 '18 at 14:59

1 Answers1

1

Sorry I mistook the Perl dollar signs for PHP, but the interface and functions will be pretty similar and hopefully you can adapt.


You need readImageBlob(). The first chunk of code synthesizes a blob and the second chunk crops it and saves to disk:

<?php

    // Synthesize blob by creating a radial gradient
    $image = new \Imagick();
    $image->newPseudoImage(300, 300, "radial-gradient:red-blue");
    $image->setImageFormat("png");
    $blob=$image->getImageBlob();

    // Now crop the blob
    $imgFromBlob=new \Imagick();
    $imgFromBlob->readImageBlob($blob);
    $imgFromBlob->cropImage(150,150,150,150);
    $imgFromBlob->writeImage("result.png");

?>

Before cropping:

enter image description here

After:

enter image description here

Mark Setchell
  • 191,897
  • 31
  • 273
  • 432
  • Yes, I finally figured out how to do it very similarly with BlobToImage(). Took a long time to figure out. The docs are very scarce and it's confusing for someone that doesn't use ImageMagick much. – StevieD Jun 19 '18 at 14:49
  • Glad you worked it out. Feel free to add an answer showing your Perl code and accept your own answer - it will help other folk who also find the ImageMagick Perl docs difficult to understand and I am not worried about "losing" the points. – Mark Setchell Jun 19 '18 at 15:00
  • Yup, will do. Just got to clean it up a little. I actually decided to save the data in a file system, but still made use of the BlobToImage() call. – StevieD Jun 19 '18 at 18:21