I have a set of 10 jpegs.
I need to generate 1 SINGLE PDF of these 10 images using PDF.
(1 page = 1 jpeg)
Final result must be a PDF.
Can imagemagick php extension help me with that ?
Yes, it can. Sample code:
<?php
$files = array(realpath('t1.jpg'), realpath('t2.jpg'));
$image = new Imagick($files);
$image->setImageFormat('pdf');
$image->writeImages(__DIR__ . '/file.pdf', true);
The second parameter of Imagick::writeImages() controls if the resulting output is joined into one file.
Footnote: At least on windows, Imagick needs to be used with absolute paths.
convert -density 150 -size 1239x1754 xc:white -density 150 *test.jpg -gravity center -composite test.pdf
Related
I'm trying to convert the first page of PDF documents to a JPEG using Imagick and PHP. As long as the colorspace of the PDF is SRGB, conversion succeeds and the resulting images have correct colors. However, if the PDF has a CMYK colorspace, after conversion, the image colors are off (much brighter or darker).
I'm currently using the following software:
PHP 7.4.3
ImageMagick 6.9.10-23 Q16 x86_64 20190101 (deb package)
Ghostscript 9.50 (2019-10-15)
I'm working on WSL2 on Windows 10.
My test PDF can be found here.
Because I was not happy with the resulting conversions, I firstly tried to see if it is possible to do a successful conversion using Imagick cli. After lots of trial and error, I found that the following command yielded the best result:
convert -density 300 -colorspace srgb input.pdf[0] -layers flatten -strip output.jpg
Result:
I then rewrote the command to PHP:
$input = 'input.pdf';
$output = 'output.pdf';
$image = new Imagick();
$image->setResolution(300, 300);
$image->readImage("{$input}[0]");
$image->transformImageColorspace(Imagick::COLORSPACE_SRGB);
$image = $image->mergeImageLayers(Imagick::LAYERMETHOD_FLATTEN);
$image->setImageFormat('jpeg');
$image->stripImage();
$image->writeImage($output);
$image->destroy();
Result:
The result of the PHP code is not the same as the result of the CLI version and the original PDF. The result is the same as if I would run te following CLI command:
convert -density 300 input.pdf[0] -colorspace srgb -layers flatten -strip output.jpg
The command looks almost the same, however the transforming of the color space happens later.
My question is: what step do I miss in my PHP code to achieve the same result as the command
convert -density 300 -colorspace srgb input.pdf[0] -layers flatten -strip output.jpg
Additional information:
I also tried using color profiles to do the colorspace transformations. Instead of
$image->transformImageColorspace(Imagick::COLORSPACE_SRGB);
I used
$cmyk = file_get_contents('USWebCoatedSWOP.icc');
$rgb = file_get_contents('sRGB_v4_ICC_preference.icc');
$image->profileImage('icc', $cmyk);
$image->profileImage('icc', $rgb);
Besides these two profiles, I also tried combinations of other CMYK (CoatedFOGRA39, JapanColor2001Coated...) and SRGB (AdobeRGB1998, AppleRGB, sRGB_v4_ICC_preference_displayclass...) profiles.
However, I couldn't find a profile combination that came close to the result of the CLI output and the original PDF file.
Thanks to #fmw42, I was able to fix my issue. To fix it, set the color space using setColorSpace() before reading in the pdf.
$input = 'input.pdf';
$output = 'output.pdf';
$image = new Imagick();
$image->setResolution(300, 300);
$image->setColorSpace(Imagick::COLORSPACE_SRGB); // Add this line
$image->readImage("{$input}[0]");
// $image->transformImageColorspace(Imagick::COLORSPACE_SRGB); // You don't need this line
$image = $image->mergeImageLayers(Imagick::LAYERMETHOD_FLATTEN);
$image->setImageFormat('jpeg');
$image->stripImage();
$image->writeImage($output);
$image->destroy();
I want use OCR. But the images can't read perfectly, so i'm converting image to delete noise background, Original Images.
then, i'm run this command :
convert -colorspace gray -modulate 120 -contrast-stretch 10%x80% -modulate 140 -gaussian-blur 1 -contrast-stretch 5%x50% +repage -negate -gaussian-blur 4 -negate -modulate 130 original.jpeg clean.jpeg
Images Result
The problem is, how to convert above command to php?
Well, i'm very confusing using imagick in php.
mycode (this what i know) :
$image = new Imagick('captcha.png');
$image->modulateImage(450, 0, 500);
$image->writeImage("output.jpg");
Result from PHP Imagick : HERE
I know, it's diffrent configuration number, but result not to far.
Any suggestions how?
==== answare (thank you fmw42)
$image = new Imagick('captcha.png');
$image->thresholdimage(0.1 * \Imagick::getQuantum(), 134217727);
$image->shaveImage(2, 1);
$image->writeImage("output.jpg");
To remove the black border and threshold your image in ImageMagick, do
Input:
convert img.png -shave 1x1 -threshold 0 result.png
Because the 8 and 7 touch, I would be surprised if OCR worked.
For Imagick, see
https://www.php.net/manual/en/imagick.thresholdimage.php
https://www.php.net/manual/en/imagick.shaveimage.php
I'm working with imagemagick to convert images from .tiff to .jpeg and make its thumbanils. The converstion from .tiff into .jpeg is OK but the problem comes when I want use imagemagick to move to other folders with others resolutions and creating its thumbnails. Imagemagick says that image in $path.$destinationPath.$ref.".jpeg" is too big but that image doesn't exist...
-Here it is my code:
exec("/usr/bin/convert ".$tiffPath.$ref.".tiff ".$CommonPath.$sourcePath.$ref.".jpeg");
// Ok until here
if (!file_exists($CommonPath.$destinationPath.$ref.".jpeg"))
{
$executa = "/usr/bin/convert -size 800x800 ".$CommonPath.$sourcePath.$ref.".jpeg -thumbnail 800x800 ".$path.$destinationPath.$ref.".jpeg";
exec($executa);
}
Imagemagick returns the following:
convert: unable to open image $CommonPath.$destinationPath.$ref.".jpeg": File is too big # error/blob.c/OpenBlob/2589.
Thanks in advance!
Your second ImageMagick command is malformed. You have:
$executa = "/usr/bin/convert -size 800x800 ".$CommonPath.$sourcePath.$ref.".jpeg -thumbnail 800x800 ".$path.$destinationPath.$ref.".jpeg";
The -size 800x800 is for creating a new image via xc: or canvas:. It may be confusing the command line to think you have two input images. It is certainly not needed. Try removing it, such as
$executa = "/usr/bin/convert ".$CommonPath.$sourcePath.$ref.".jpeg -thumbnail 800x800 ".$path.$destinationPath.$ref.".jpeg";
I have the following method to generate a thumbnail. It takes any dimensions and converts it to a 600 x 450 image, centered.
private function generateThumbnail ($ext, $name) {
if ($ext === ".png"){
exec('convert -define png:size=1200x900 '.$this->file.' -thumbnail 600x450^ -gravity center -extent 600x450 '.$name);
exec("optipng -o2 -q " . $name);
} else {
exec('convert -define jpeg:size=1200x900 '.$this->file.' -thumbnail 600x450^ -gravity center -extent 600x450 '.$name);
$img = new Imagick($name);
$img->setImageCompression(Imagick::COMPRESSION_JPEG);
$img->setImageCompressionQuality(97);
$img->stripImage();
$img->writeImage($name);
$img->destroy();
}
}
The problem arises when generating a thumbnail from a GIF. It doesn't generate an image from the first frame. One GIF just had a blank image (transparent), another had strange colors/quality.
How do I generate a thumbnail the first frame of a GIF, centered?
You could probably do them with the API but I do not use it as it is limited. But it looks like you still need to use the command line for the optipng program anyway so I would have carried on with the command line.
Anyway back to your problem; how do you know the first frames of the gif are not a transparent image or a strange image?
As #Mark Setchell said you should be able to specify a specific frame with input.gif[0] and I would try that with a different number and see what you get.
I am not an animation use but you should be able to see the gif frames with -coalesce. Anthony has some examples on his site: http://www.imagemagick.org/Usage/anim_basics/#coalesce
This should give you an idea of the frames in the gif:
montage script_k.gif -coalesce \
-tile x1 -frame 4 -geometry '+2+2' \
-background none -bordercolor none coalesce_k_montage.gif
You can see how you gif file is made and perhaps go for the second or third frame rather than the first.
Fill Area Flag ('^' flag) is support IM v6.3.8-3But my client's production server has version ImageMagick 6.2.8
Right now in my local server i use this command to generate thumbnail and it works fine:
convert image.jpg -resize "280x210^" -gravity Center -crop "280x210+0+0" thumbnail.jpg
Since my client's production server doesn't support '^' flag how can i generate a thumbnail without using it? (or maybe calculating it manually in PHP or BASH)
Should i use -extent, does it stretch the image?
I also read this and im not sure if ^ flag is for not letting the image stretch because thats what i want, generate a thumbnail without stretching it.
Note: i dont have root access on the server. Im using PHP and BASH to run the commands.
EDIT:
I also don't want any other background colors while resizing and croping.
try
convert image.jpg -background black -resize 280
-gravity center -crop 280x210+0+0 -extent 280x210 image.c.jpg
I found a solution
This is the PHP function i used:
function imgconvert($in,$out,$size){
$size_arr=explode('x',$size);
$resize=( ($size_arr[0]/$size_arr[1]) > 1.775 ? $size_arr[0].'x':'x'.$size_arr[1]);
system("convert \"$in\" -resize $resize -gravity Center -crop \"$size+0+0\" \"$out\"");
}
It seems that if width/height is larger than 1.775 i should use widthX as resize value and if else than i should use Xheight .