I'm using codeigniter and imagick for convert pdf to png image file.
$im = new imagick();
$im->setResolution ( 110,110);
$im->readImage($target_path);
$num_page = $im->getnumberimages();
for ($i=0; $i < $num_page ; $i++) {
$im->readImage($target_path."[".$i."]");
$im->setImageFormat('png');
$im->writeImage(?);
}
$im->destroy();
I don't know how save this file in codeignietr_folder/assets/pdf-img
I tried ../../assets/test.png and localhost/codeignietr_folder/assets/pdf-img
but it doesn't work!
how could i do it?
You can use $im->writeImage($file); where
$file = getcwd() . '/assets/pdf-img/test.png';
Related
I am currently trying to convert an ICO file to a 16x16 px PNG, using PHP-Imagick. What I've tried so far:
<?php
if (empty(\Imagick::queryFormats("ICO"))) {
throw new \Exception('Unsupported format');
}
$sourceFile = __DIR__ . '/favicon.ico';
$targetFile = __DIR__ . '/favicon.png';
$im = new \Imagick($sourceFile);
$im->writeImages($targetFile, true);
This works partially. The problem is, that an ICO file may contain multiple images, so the code above creates multiple PNG files
favicon-0.png
favicon-1.png
...
for every size. This is okay, but then, I need the possibility to find the one that is close to 16x16 px, scale it down (if needed) and delete all others. For this, I already tried some things and this is where I'm stuck currently:
<?php
if (empty(\Imagick::queryFormats("ICO"))) {
throw new \Exception('Unsupported format');
}
$sourceFile = __DIR__ . '/favicon.ico';
$targetFile = __DIR__ . '/favicon.png';
$im = new \Imagick($sourceFile);
$count = $im->getNumberImages();
if ($count > 1) {
for ($x = 1; $x <= $count; $x++) {
$im->previousImage();
$tmpImageWidth = $im->getImageWidth();
$tmpImageHeight = $im->getImageHeight();
// ???
}
}
$im->writeImages($targetFile, true);
I guess, i would find a working way with some trial and error. But I would like to know, if there's an easier way to achieve this.
TL;DR: I need a simple way to convert an ICO file of any size to a 16x16 px PNG, using PHP-Imagick (using GD isn't an option).
Update:
My (currently working but maybe suboptimal) solution:
<?php
if (empty(\Imagick::queryFormats("ICO"))) {
throw new \Exception('Unsupported format');
}
$sourceFile = __DIR__ . '/favicon.ico';
$targetFile = __DIR__ . '/favicon.png';
$im = new \Imagick($sourceFile);
$count = $im->getNumberImages();
$targetWidth = $targetHeight = 16;
if ($count > 1) {
$images = [];
for ($x = 1; $x <= $count; $x++) {
$im->previousImage();
$images[] = [
'object' => $im,
'size' => $im->getImageWidth() + $im->getImageHeight()
];
}
$minSize = min(array_column($images, 'size'));
$image = array_values(array_filter($images, function($image) use ($minSize) {
return $minSize === $image['size'];
}))[0];
$im = $image['object'];
if ($image['size'] <> $targetWidth + $targetHeight) {
$im->cropThumbnailImage($targetWidth, $targetHeight);
}
}
else {
if ($im->getImageWidth() <> $targetWidth || $im->getImageHeight() <> $targetHeight) {
$im->cropThumbnailImage($targetWidth, $targetHeight);
}
}
$im->writeImage($targetFile);
Updated Answer
On re-reading your question, it seems you actually want to make a PNG file from an ICO file. I have read the Wikipedia entry for ICO files and, as usual, it is a poorly specified complicated mess of closed source Microsoft stuff. I can't tell if they come in some order.. smallest first, or largest first, so I think my recommendation would be to simply iterate through all the images in your ICO file, as you planned, and get the one with the largest number of pixels and resize that to 16x16.
Original Answer
Too much for a comment, maybe not enough for an answer... I don't use PHP Imagick much at alll, but if you use ImageMagick at the command-line in the Terminal, you can set the ICO sizes like this:
magick INPUT -define icon:auto-resize="256,128,96,64,16" output.ico
to say what resolutions you want embedded in the output file. As I said, I don't use PHP, but I believe the equivalent is something like:
$imagick->setOption('icon:auto-resize', "16");
Sorry I can't help better, I am just not set up to use PHP and Imagick, but hopefully you can work it out from here.
My final solution:
<?php
if (empty(\Imagick::queryFormats("ICO"))) {
throw new \Exception('Unsupported format');
}
$sourceFile = __DIR__ . '/favicon.ico';
$targetFile = __DIR__ . '/favicon.png';
$im = new \Imagick($sourceFile);
$count = $im->getNumberImages();
$targetWidth = $targetHeight = 16;
if ($count > 1) {
$images = [];
for ($x = 1; $x <= $count; $x++) {
$im->previousImage();
$images[] = [
'object' => $im,
'size' => $im->getImageWidth() + $im->getImageHeight()
];
}
$minSize = min(array_column($images, 'size'));
$image = array_values(array_filter($images, function($image) use ($minSize) {
return $minSize === $image['size'];
}))[0];
$im = $image['object'];
if ($image['size'] <> $targetWidth + $targetHeight) {
$im->cropThumbnailImage($targetWidth, $targetHeight);
}
}
else {
if ($im->getImageWidth() <> $targetWidth || $im->getImageHeight() <> $targetHeight) {
$im->cropThumbnailImage($targetWidth, $targetHeight);
}
}
$im->writeImage($targetFile);
I'm having a problem when im trying to convert a PDF to images with imagick and PHP (5.5). everything works fine i can create a image for each page in the PDF but i run into the following problems. and have been stuck here for days now.
When i create a image from a PDF file some of them gets a black background even thou i have set setImageBackgroundColor to white
I have tried to set setImageCompressionQuality to get the image in better quality (right not the created image gets pixelated).
also i cannot seem to change the DPI version of the image to a 72 dpi one.
the code is as following:
$file_name = basename($file_name);
$img = new imagick();
$img->readImage($dir.'/'.$file_name);
$img->setImageBackgroundColor('white');
$img->setResolution(72,72);
$img->resampleImage(72,72,imagick::FILTER_LANCZOS,0);
$img->setImageUnits(imagick::RESOLUTION_PIXELSPERINCH);
$img->setImageCompression(imagick::COMPRESSION_JPEG);
$img->setImageCompressionQuality(100);
$img->stripImage();
$num_pages = $img->getNumberImages();
for($i = 0;$i < $num_pages; $i++) {
$img->setIteratorIndex($i);
$img->setImageBackgroundColor('white');
$img->flattenImages();
$img->setImageFormat("jpeg");
$final_name = str_replace(" ", "+", basename(str_replace(".".$file_ext,"", $file_name)));
$final_name = preg_replace("/[^a-zA-Z0-9-+]/", "", $final_name);
$save_to = $pdf_dir."/".str_replace(".".$file_ext,"", $final_name).'-'.$i.'.jpg';
$img->writeImage($save_to);
$file_image = str_replace(dirname(__FILE__)."/../../", "/", $save_to);
$file_images[] = $file_image;
}
$img->destroy();
You had some mistakes in your code.
setResolution needs to be called before loading the PDF
You need to use setBackgroundColor rather than setImageBackgroundColor.
You probably want to set the individual page compression quality, but see below.
So code:
$imagick = new Imagick();
$imagick->setResolution(72, 72);
$imagick->readImage($file_name);
$imagick->setBackgroundColor('white');
$imagick->setImageCompression(imagick::COMPRESSION_JPEG);
$imagick->setImageCompressionQuality(70);
foreach ($imagick as $c => $_page) {
$_page->setBackgroundColor('white');
$_page->setImageCompressionQuality(70);
$_page->setImageFormat('jpg');
$_page->writeImage($file."_background-$c.jpg");
}
btw, the fact that you're using JPEG at 100 quality is disturbing. If that is an image that is going to be sent to a browser, the quality should be lower than 100. If you are using it as an intermediate picture, using PNG as the intermediate format is better as it is lossless and it supports transparency.
That seemed to do the trick, changed to answer a bit as i couldnt get your foreach to work thou, wich made it work as intended:
Thank you for saving me from alot of headache.
$img = new imagick();
$img->setResolution(72, 72);
$img->readImage($dir.'/'.$file_name);
$img->setBackgroundColor('white');
$img->setImageCompression(imagick::COMPRESSION_JPEG);
$img->setImageCompressionQuality(70);
$num_pages = $img->getNumberImages();
for($i = 0;$i < $num_pages; $i++) {
$final_name = str_replace(" ", "+", basename(str_replace(".".$file_ext,"", $file_name)));
$final_name = preg_replace("/[^a-zA-Z0-9-+]/", "", $final_name);
$save_to = $pdf_dir."/".str_replace(".".$file_ext,"", $final_name).'-'.$i.'.jpg';
$img->setIteratorIndex($i);
$img->setBackgroundColor('white');
$img->setImageCompressionQuality(70);
$img->setImageFormat('jpg');
$img->writeImage($save_to);
$file_image = str_replace(dirname(__FILE__)."/../../", "/", $save_to);
$file_images[] = $file_image;
}
I have a problem with my php: when I make conversion PDF to JPG not shown correctly.
This is the original pictures of pdf - > http://s16.postimg.org/ma0jizgt1/text_problem2_fw.png
This is the jpg after converting with imagick - > http://s14.postimg.org/ilhs9tt3l/text_problem_fw.png
Please can you help me ?
Thank you
PHP:
if (move_uploaded_file( $_FILES["files"]["tmp_name"], $uploadUrlPdf . $_FILES["files"]["name"]))
{
$_FILES['files']['name'];
$nr_pag = $_POST['nr_pagini'];
for($i = 0; $i < $nr_pag; $i++)
{
$fn = $uploadUrlSwf.sprintf("%02d", "$i").".jpg";
if (!file_exists($fn))
{
$im = new imagick();
$im->setResolution($dpi,$dpi);
$pdf = $uploadUrlPdf.$_FILES['files']['name']."[$i]";
$im->readimage($pdf);
$im->setImageFormat('jpg');
$im->writeImage($fn);
file_put_contents( $fn, (string)$im );
$im->clear();
$im->destroy();
}
}
}
else
{
echo "error!";
}
Try setting your dpi value higher. If that does not work, try another export format (other than jpg). SVG would be your best bet, because you can scale that while the text and other shapes are still perfect quality. JPG wil not be sharp at a high zoom level if the resolution (dpi) is too low.
This forum entry might help: anti-aliased text when exporting PDF to image
I am trying to convert a multipage PDF File to images by using PHP Image magic extension.The problem is that instead of getting images corresponding to each page of the file, I am getting the last page of pdf as the output image. Here is the code:
$handle = fopen($imagePath, "w");
$img1 = new Imagick();
$img1->setResolution(300,300);
$img1->readImage(path to pdf file);
$img1->setColorspace(imagick::IMGTYPE_GRAYSCALE);
$img1->setCompression(Imagick::COMPRESSION_JPEG);
$img1->setCompressionQuality(80);
$img1->setImageFormat("jpg");
$img1->writeImageFile($handle);
What am I doing wrong?The convert command on commandline with the same parameters works.
Try something like this instead:
$images = new Imagick("test.pdf");
foreach($images as $i=>$image) {
$image->setResolution(300,300);
//etc
$image->writeImage("page".$i.".jpg");
}
Try writeImages function. It creates each page as one image and it gives file names for multiple images like this: yourimagename, yourimagename-1, yourimagename-2.... It increases automatically from 0 to your numberofpagesinPdf-1.
The code looks like this:
$imagick = new Imagick($file_handle);
$imagick->readImage();
$imagick->writeImages($yourImagename.'.jpg', false);
This will work for pdf having multiple pages as well as the single page.
$pdf_file = 'path/to/pdf/file.php';
$image = new imagick();
$image->setResolution(300,300);
$image->readImage($pdf);
$image->setImageFormat('jpg');
// Set all other properties
$pages = $image->getNumberImages();
if ($pages) {
foreach($image as $index => $pdf_image) {
$pdf_image->writeImage('destination/path/' . $index . '-image_file.jpg');
}
} else {
echo 'PDF doesn\'t have any pages';
}
Try something like this if you know number of pages of your pdf:
$images = new Imagick();
foreach ($pages as $p){
$im->readImage($PdfFile."[".$p."]"); //yourfile.pdf[0], yourfile.pdf[1], ...
$im->setCompression(Imagick::COMPRESSION_JPEG);
$im->setCompressionQuality(82);
$im->setImageFormat( "jpg" );
//...
$image_out = "image_".$p.".jpg";
$im->writeImage($image_out);
}
$im->clear();
$im->destroy();
If you dont know number of pages, you could do something like this:
$images = new Imagick();
$im->readImage($PdfFile);
$pages = (int)$im->getNumberImages();
this worked for me
$file = "./path/to/file/name.pdf";
$fileOpened = #fopen($archivo, 'rb');
$images = new Imagick();
$images->readImageFile($fileOpened);
foreach ($images as $i => $image) {
$image->setResolution(300, 300);
$image->setImageFormat("jpg");
$image->setImageCompression(imagick::COMPRESSION_JPEG);
$image->setImageCompressionQuality(90);
$image->setImageUnits(imagick::RESOLUTION_PIXELSPERINCH);
$data_blob = $image->getImageBlob();
$ouput="./path/images/files/page" . $i . ".jpg";
file_put_contents($ouput, $data_blob);
}
#fclose($fileOpened);
I hope I can help you too
I have a 96x96 image and i need to divide it in 36 pieces of 16x16 and i have a script given below works fine on my localhost but not working on my webhost.
function makeTiles($name, $imageFileName, $crop_width, $crop_height)
{
$dir = "/pic";
$slicesDir = "/pic/16X16";
// might be good to check if $slicesDir exists etc if not create it.
$ImgExt = split(".",$imageFileName);
$inputFile = $dir . $imageFileName;
$img = new Imagick($inputFile);
$imgHeight = $img->getImageHeight();
$imgWidth = $img->getImageWidth();
$cropWidthTimes = ceil($imgWidth/$crop_width);
$cropHeightTimes = ceil($imgHeight/$crop_height);
for($i = 0; $i < $cropWidthTimes; $i++)
{
for($j = 0; $j < $cropHeightTimes; $j++)
{
$img = new Imagick($inputFile);
$x = ($i * $crop_width);
$y = ($j * $crop_height);
$img->cropImage($crop_width, $crop_height, $x, $y);
$data = $img->getImageBlob();
$newFileName = $slicesDir . $name . "_" . $x . "_" . $y . ".".$ImgExt[1];
$result = file_put_contents ($newFileName, $data);
}
}
}
Getting fatal error
Fatal error: Class 'Imagick' not found in myfile.php line number
My host saying:
Imagick and image magic both are same unfortunately, we do not have
them as a PHP module we have binaries like ImageMagick binary and
Image magic path is /usr/local/bin. Include this function in your
script and check the website functionality from your end.
I dont know how to fix this error.
If I understand it correctly you will have to invoke the imagick binary from your script using exec():
exec('/usr/local/bin/convert '.$inputFile.' -crop 96x96+ox+oy '.$newFilename);
The ox and oy should be replaced with the correct offset values.
Here is are a couple of links that might help:
How do I use Imagick binaries from php
Imagick - Convert Command-line tool