8

I have a php script to create jpg thumbnail of pdf as follows;

<?php
$file ="test.pdf";
$im = new imagick(realpath($file).'[0]');
$im->setImageFormat("jpg");
$im->resizeImage(200,200,1,0);
// start buffering
ob_start();
$thumbnail = $im->getImageBlob();
$contents =  ob_get_contents();
ob_end_clean();
echo "<img src='data:image/jpg;base64,".base64_encode($thumbnail)."' />";
?>

But the resulting jpg have black background instead of white.. How can I fix this??

hakre
  • 193,403
  • 52
  • 435
  • 836
Alfred
  • 21,058
  • 61
  • 167
  • 249

8 Answers8

26

None of the previously posted answers worked for me however the below did:

$image = new Imagick;

$image->setResolution(300, 300);

$image->readImage("{$originalPath}[0]");

$image->setImageFormat('jpg');

$image->scaleImage(500, 500, true);

$image->setImageAlphaChannel(Imagick::VIRTUALPIXELMETHOD_WHITE);

As I'm using the Laravel framework I then take the converted image and store it using Laravels filesystem.

Storage::put($storePath, $image->getImageBlob());

Update: So I recently changed OS and whereas this previously worked on my Ubuntu machine on my Mac certain images were still coming out black.

I had to change the script to the below:

$image = new Imagick;

$image->setResolution(300, 300);

$image->setBackgroundColor('white');

$image->readImage("{$originalPath}[0]");

$image->setImageFormat('jpg');

$image->scaleImage(500, 500, true);

$image->mergeImageLayers(Imagick::LAYERMETHOD_FLATTEN);

$image->setImageAlphaChannel(Imagick::ALPHACHANNEL_REMOVE);

Seems important to set the background colour before reading in the image. I also flatten any possible layers and remove the alpha channel. I feel like I tried ALPHACHANNEL_REMOVE on my Ubuntu machine and it didn't work so hopefully between these answers readers can find something that works for them.

Luke Vincent
  • 1,266
  • 2
  • 19
  • 35
1

I solved it by;

$im = new imagick(realpath($file).'[0]');
$im->setCompression(Imagick::COMPRESSION_JPEG);
$im->setCompressionQuality(100);
$im->setImageFormat("jpeg");
$im->writeImage("imagename.jpg");
Alfred
  • 21,058
  • 61
  • 167
  • 249
  • `setCompressionQuality` not actualy working in this situation. For change quality use `setImageCompressionQuality` – vatavale Feb 24 '18 at 19:06
1

Simply adding this prevents the JPG to be created with a black background

-alpha off
1

change this code $im->setimageformat("jpg"); to this code $im->setimageformat("png"); if you face a background colour issue.

aronadaal
  • 9,083
  • 1
  • 19
  • 33
Atif Khan
  • 11
  • 1
1

If your version of Imagick is not up to date, the setImageBackgroundColor may be wrong.

Swap the following line

$im->setImageBackgroundColor("red");

to this (Imagick version >= 2.1.0)

$im->setBackgroundColor(new ImagickPixel("red"));

or (Imagick version < 2.1.0)

$im->setBackgroundColor("red");
carlgarner
  • 89
  • 5
  • i made some changes in my question.. have a look.. and your suggestion is not working.. – Alfred May 23 '11 at 16:36
  • @blasteralfred Could you provide access to a copy of your PDF as I believe the issue may be related to that, rather than the code you've now provided above. The updated code works without issue with PDF that I have. – carlgarner May 26 '11 at 10:45
1

Just use flattenImages() right after creating a new imagick():

$im = new Imagick('file.pdf[0]');
$im = $im->flattenImages();

Edit: The flattenImages method has been deprecated & removed. Use

$im = $im->mergeImageLayers( imagick::LAYERMETHOD_FLATTEN );
NIck
  • 71
  • 1
  • 9
0

After endless attempts to append a pdf file with a jpeg image without getting black areas, I found the solution: the function transformImageColorspace

Used in this order works perfectly:

$im = new Imagick();
$im->readImage("file.pdf");

$im->transformImageColorspace(Imagick::COLORSPACE_SRGB);

$im->setImageFormat('jpeg');
$im->writeImage('image.jpg');
Davide
  • 1,635
  • 1
  • 16
  • 29
0

I would like to add to the excellent and helpful answers by saying that a slightly different approach is required if your PDF has multiple pages.

Something I was surprised to discover is that the Imagick class implements Iterable, which means you can run it through a foreach loop and operate on each page in turn (which it turns out is necessary because the layer, colour, and alpha channel changes appear to only take effect on the last page) which will be presented to you as a separate Imagick object:

$im = new Imagick('path/to/file.pdf');
foreach ($im as $c => $page)
{
    // do what you need to do with each page and then...
    $im->writeImage('path/to/image-'.$c.'.jpg');
}
Aaron Mason
  • 310
  • 3
  • 11