In php using Imagick, I'm able to convert one pdf page into a jpg image at once. But I need to convert all pages of my pdf into jpg files in separate folder.
below my code
<?php
for($i=0;$i<=20;$i++){
$pdf_file = 'book.pdf';
$save_to = 'pages/tw'.$i.'.jpg';
$img = new imagick();
$img->setResolution(200,200);
$img->readImage("{$pdf_file}[$i]");
$img->scaleImage(800,0);
$img->setImageFormat('jpg');
$img = $img->flattenImages();
$img->writeImages($save_to, false);
$img->destroy();
}
?>
Above code produces results up-to 10 pages. Then it terminated by execution time of 30 secs. I cant manage php.ini because I'm using hosting with another company.
$mypdf = escapeshellarg( "mysafepdf.pdf" );
$newjpg = escapeshellarg( "output.jpg" );
$result = 0;
exec("convert -density 600 {$mypdf} {$newjpg} -colorspace RGB -resample 300", null, $result);
$ result will be 0 if the conversion works
-density = dpi
I hope this will help you!
PS.: This is only for one image, but you can adapt at it for your $i.
Related
I have a big pdf file that about >100mb.
I want to save that pdf page by page converting to jpg.
My php script works well but image quality sucks even quailty set to 100. Jpg output max width set to 1024.
Each file size about 2.5mb. I have searched for this problem but i get everytime about command line solutions. I must use php.
$file = 'e-magazine/1/ebook.pdf';
if($file === null && !file_exists($file)) {
throw new \Exception('FILE NOT EXISTS');
}
$nop = new \Imagick($file);
for($i = 0; $i <= $nop->getnumberimages(); $i++) {
$image_file = 'e-magazine/1/'.($i+1).'.jpg';
$im = new \Imagick();
$im->readimage($file.'['.$i.']');
$im->setImageCompressionQuality(100);
$im->setimageformat('jpeg');
$im->resizeImage(1024, 0, \Imagick::FILTER_CATROM, 1);
$im->writeimage($image_file);
$tm = new \Imagick();
$tm->readimage($image_file);
$tm->setImageCompressionQuality(60);
$tm->setimageformat('jpeg');
$tm->resizeImage(200, 0, \Imagick::FILTER_CATROM, 1);
$tm->writeimage('e-magazine/1/thumbnails/'.($i+1).'_thumb.jpg');
}
What can i do to correct file quality?
PDFs are vector, rather than bitmap, based so you need to set the density before reading the file in order to tell ImageMagick what sort of size you are going to need then it can rasterize accordingly on input. Try the following PRIOR to reading the image:
$im->setResolution(288,288);
Then try reducing that value, say to 144, and comparing the quality till you have enough quality. It is a tradeoff of quality versus processing time and memory demand. The higher the number the higher the quality but the longer and the more memory.
My full solution to this with compensation for PNG transparency alpha channels
$im = new imagick();
$im->setResolution(300, 300);
$im->readimage($pdf_path.'_0.pdf[0]');
$im->setImageResolution(300, 300);
$im->setImageBackgroundColor('#ffffff');
$im = $im->flattenImages();
$im->setImageFormat('jpeg');
$im->setImageCompression(imagick::COMPRESSION_JPEG);
$im->setImageCompressionQuality(100);
$im->resizeImage(1200, 0, imagick::FILTER_LANCZOS, 1);
I have a simple watermark script which works well, but it seems adobe sRGB images lose color quality.
Running a watermark command via shell/imagemagick works great - no color quality lost.
Using imagick, however, dulls the color.
Here is the series of commands I use:
$image = new Imagick();
$image->readImage($this->source_path);
$watermark = new Imagick();
$watermark->readImage($this->watermark_path);
// how big are the images?
$iWidth = $image->getImageWidth();
$iHeight = $image->getImageHeight();
$wWidth = $watermark->getImageWidth();
$wHeight = $watermark->getImageHeight();
// calculate the position
$x = ( $iWidth - $wWidth ) / 2;
$y = ( $iHeight - $wHeight ) / 2;
//we have to make the transparency go to white, or it will become an awefull black color in jpeg version
$white = new Imagick();
$white->newImage($image->getImageWidth(), $image->getImageHeight(), "white");
if ($image->getImageColorspace() == Imagick::COLORSPACE_SRGB) {
$watermark->setColorspace(imagick::COLORSPACE_RGB);
$white->setColorspace(imagick::COLORSPACE_RGB);
}
$white->compositeimage($image, Imagick::COMPOSITE_OVER, 0, 0);
//now apply watermark
$white->compositeImage($watermark, imagick::COMPOSITE_OVER, $x, $y);
//save
$white->writeImage($this->destination);
//save memory
$image->destroy();
$white->destroy();
I made a half-educated assumption that if I convert the other two elements (the white background, and the png overlay) to sRGB, nothing would be lost. I did that with this segment here:
if ($image->getImageColorspace() == Imagick::COLORSPACE_SRGB) {
$watermark->setColorspace(imagick::COLORSPACE_RGB);
$white->setColorspace(imagick::COLORSPACE_RGB);
}
...Still no shrimp Lieutenant Dan...
Is there any possible way around this issue? Ideally I'd like to use the shell commands, but I'd like to perfect the imagick version for those who do not have shell access in their environments.
I found the solution here: http://www.php.net/manual/ru/imagick.compositeimage.php (was like a scavenger hunt!)
The solution as stated in above link:
You might need to set the colorspace the same when composing two
images over each other
<?php
//Creating two Imagick object
$first = new Imagick('first.jpg');
$second = new Imagick('second.jpg');
// Set the colorspace to the same value
$first->setImageColorspace($second->getImageColorspace() );
//Second image is put on top of the first
$first->compositeImage($second, $second->getImageCompose(), 5, 5);
//new image is saved as final.jpg
$first->writeImage('final.jpg');
?>
In my web hosting, I can't use shell, so is there any alternative for this command?
system("convert $src +dither -layers optimize -depth 16 -colors 32 $dest");
I want to compress gif files, so I need to preserve animation.
P.S:
Of course, that I first tried to do it by my own. But without success. So i wrote this question.
Example:
$im = new Imagick("first.gif");
$im->optimizeImageLayers();
$im->writeImages("phpmodul.gif", true);
system("convert first.gif -layers optimize shell.gif");
first.gif - 649 kB
phpmodul.gif - 647 kB
shell.gif - 347 kB
Any help?
P.P.S:
I solved this. My solution.
$animation = new Imagick("$file");
foreach ($animation as $frame) {
$frame->quantizeImage(32, imagick::COLORSPACE_RGB, 16, FALSE, TRUE);
}
$animation = $animation->optimizeImageLayers();
$animation->writeImages("$file", true);
I have been working on converting PDFs to JPGs, for this I have installed imagick and GhostScript. I have been using exec() in my php code to make the conversion. Now my problem is that if the source of the input pdf is a conversion from doc->pdf, then the image quality is grainy when zoomed. On the other hand I need to keep the image size below 500kb, so I cannot use
density more than 200.
Is there a way to add any sort of filter before saving the images, so that the jpg quality is improved.
Here is my sample code:
$inputFileName = 'test.pdf';
$outputFileName = 'converted.jpg';
$sourceFile = escapeshellarg( $inputFileName );
$outputFile = escapeshellarg( $outputFileName );
$exe = "convert -density 200 -colorspace RGB {$sourceFile } {$outputFile }";
$null = "0";
echo exec( $exe, $null, $result );
Any help would be appreciated!
Thanks
Why not increasing the density and decreasing the quality? For example:
$exe = "convert -density 600 -quality 70 -colorspace RGB {$sourceFile } {$outputFile }";
Well how could I change the before image to the after image by using imagemagick?
Is it the -skew command or the -distort, and how can I use it preferably in typo3 and php?
Any help is appreciated!
Using Imagemagick with php and the command line:
// Working on the original image size of 400 x 300
$cmd = "before.jpg -matte -virtual-pixel transparent".
" +distort Perspective \"0,0 0,0 400,0 400,22 400,300 400,320 0,300 0,300 \" ";
exec("convert $cmd perspective.png");
Note:
1/ This is for later versions of Imagemagick - the perspective operator has change.
2/ You need to use +distort not -distort as the image is larger than the initial image boundrys.
Examples of Imagemagick with php usage on my site http://www.rubblewebs.co.uk/imagemagick/operator.php
I think what you're looking for is the Imagick::shearImage function. This creates a checkerboard square and distorts it into a parallelogram (save this as a PHP file and open in your browser to see):
<?php
$im = new Imagick();
$im->newPseudoImage(300, 300, "pattern:checkerboard");
$im->setImageFormat('png');
$im->shearImage("transparent", 0, 10);
header("Content-Type: image/png");
echo $im;
?>
Within a larger script, to shear an image named myimg.png and save it as myimg-sheared.png, you can use:
$im = new Imagick("myimg.png");
$im->shearImage("transparent", 0, 10);
$im->writeImage("myimg_sheared.png");
If shearImage isn't versatile enough, you can try the Imagick::DISTORTION_PERSPECTIVE method via the Imagick::distortImage function.
Perspective distortion should give you what you want. Example:
convert original.png -matte -virtual-pixel white +distort Perspective '0,0,0,0 0,100,0,100 100,100,90,110 100,0,90,5' distorted.png
In TYPO3 you could apply it by (ab)using the SCALE object of the GIFBUILDER. Example:
temp.example = IMAGE
temp.example {
file = GIFBUILDER
file {
format = jpg
quality = 100
maxWidth = 9999
maxHeight = 9999
XY = [10.w],[10.h]
10 = IMAGE
10.file = fileadmin/original.png
20 = SCALE
20 {
params = -matte -virtual-pixel white +distort Perspective '0,0,0,0 0,100,0,100 100,100,90,110 100,0,90,5'
}
}
}