3

I'm using ImageMagick's Perl API to create thumbnails. I'm using suggestions on ImageMagick image optimization from this previous SO question:

open my $file, $params->{'openFile'};
my $imageData = do { local $/; <$file> };

if ($params->{'size'} eq "largesized") {
    $thumbnailWidth = 1000;
    $thumbnailHeight = 1000;
}   

$image->BlobToImage($imageData);
$image->SetAttribute('quality' => 80);
$image->SetAttribute('compression' => 'JPEG');
$image->SetAttribute('sampling-factor' => '4:2:0');
$image->SetAttribute('interlace' => 'Plane');
$image->SetAttribute('gaussian-blur' => '0.05');
$image->Thumbnail('geometry' => $thumbnailWidth . "x" . $thumbnailHeight);

my $thumbnailData = $image->ImageToBlob();


open(my $file, '>', $params->{'saveFile'}) or return { 'thumbnailGenerated' => 0, error => "Could not open file '" . $params->{'saveFile'} . "'." };
print $file $thumbnailData;
close $file;

As far as I can tell, this should create a nicely optimized thumbnail. However, while the input image is 3088x2320 and weighs in at 1.6 MB, the resulting thumbnail at 1000x1000 actually is larger at 2.3 MB (which seems positively huge for a JPEG of that size). Note: on the sample out, it is cropped a bit because the JavaScript that uploads the images forces one to select a 1:1 crop by design.

I'm running ImageMagick 6.9.10-68 Q16 x86_64 2021-10-14 (CentOS). The command line equivalent produces a smaller image as expected (84kb):

  convert -thumbnail 1000x1000 -quality 80 -compress JPEG -sampling-factor 4:2:0 -interlace Plane -gaussian-blur 0.05  imageMagickSampleImage.jpg imageMagickSampleImage3.jpg

It makes me wonder if the SetAttribute attributes are not being passed to the Thumbnail function or something. I've found PerlMagick less than perfect at various points and have been wondering if I just need to go with GD instead.

I notice that the thumbnails are still too large (and larger than the command line), but get smaller if I remove all of the "SetAttribute" lines. The output of the 1000x1000 thumbnail goes from 2.4MB to 976KB. That's still over 10x larger than the command line with these same attributes set.

I thought maybe moving some of the attributes directly to the ImageToBlob method would help, but it didn't seem to change the outcome at all. Here's that attempt:

my $thumbnailData = $image->ImageToBlob('quality' => 40, 'compression' => 'JPEG', 'sampling-factor' => '4:2:0', 'interlace' => 'Plane', 'gaussian-blur' => '0.05');
Timothy R. Butler
  • 1,097
  • 7
  • 20
  • 3
    Maybe you can share 1) your input image 2) your **ImageMagick** version 3) your output image 4) the command to actually save it. Thank you. – Mark Setchell Jun 24 '22 at 19:16
  • 1
    What happens if you do the same thing with ImageMagick directly? – brian d foy Jun 25 '22 at 14:15
  • @MarkSetchell I added those details. Thanks! – Timothy R. Butler Jun 25 '22 at 16:41
  • @briandfoy it seems to work better when I run it directly. I found a possible error in my code ("compression" rather than "compress," the command line argument) that I thought might help, but no dice -- it still doesn't work. – Timothy R. Butler Jun 25 '22 at 16:42
  • 1
    Not sure I undertand. Your output JPG comes up as a PNG in my browser. – Mark Setchell Jun 25 '22 at 19:17
  • @MarkSetchell I'm not sure I understand either! That's the verbatim output from the code above. I have no idea why it is outputting as a PNG. I hadn't bothered to check to see what the actual format of the output file was... – Timothy R. Butler Jun 26 '22 at 01:10

1 Answers1

3

The issue apparently is that despite specifying JPEG compression and inputting a JPEG, the ImageToBlob method was outputting a PNG file, as @MarkSetchell observed in the comments above.

A helpful code snippet from Perl Graphics Programming offers the solution. I modified my code accordingly to specifically tell ImageMagick to output a JPEG:

 my $thumbnailData = $image->ImageToBlob(magick => 'jpeg');

The 1000x1000 graphic went from its previously massive size to just 167KB.

Timothy R. Butler
  • 1,097
  • 7
  • 20
  • The only remaining question is _why_ it is converting it to a PNG unless explicitly told not to. I'm not sure this is necessary to answer, although it bugs me. – Timothy R. Butler Jun 26 '22 at 01:22