i am using php imagick to create a image and than convert to pdf. using php imagick. i coded this:
$image = new Imagick();
$height = 800; //height of the page;
$image->newImage(794, $height, "#f5f5f5");
$image->setImageFormat("jpg");
$card = new Imagick('card.jpg'); ; //get single card
$l_align = 190; //left alignment
for($i=0; $i < 4; $i++) //for creating multiple cards on a page
{
$image->compositeImage($card, Imagick::COMPOSITE_DEFAULT,10, ($l_align*$i)+10);
$image->compositeImage($card, Imagick::COMPOSITE_DEFAULT, 390, ($l_align*$i)+10);
}
$image->setResolution(72, 72);
$image->resetIterator();
$combined = $image->appendImages(true);
$image->setImageFormat("pdf");
$combined->writeImages( 'card.pdf', true );
header("Content-Type: application/pdf");
header('Content-Disposition: attachment; filename="card.pdf"');
echo file_get_contents('card.pdf');
and get something like this
in pdf format . Now i want to page break after every 6 cards print in pdf . i am using imagick . please help me. thanks in advance.
You are using the wrong function for adding images as new pages. You should be using addImage which adds the new image as a separate page, rather than append which just tacks them onto the bottom of the current image.
An example of this working is:
$combined = null;
$images = [
'../../../images/Source1.jpg',
'../../../images/Source2.png',
];
foreach ($images as $image) {
if ($combined == null) {
$combined = new Imagick(realpath($image));
}
else {
$card = new Imagick(realpath($image)); ; //get single card
$combined->addImage($card);
}
}
$combined->setImageFormat("pdf");
$combined->writeImages( './card.pdf', true );
btw there is weird stuff going on in your code example - you're only even attempting to add one image, and what is 'resetIterator' doing in there?
Related
I am Using Imagick to Convert PDF to Images
Uploading PDF to Laravel
public function uploadPdf( Request $request )
{
$model = new Attachment();
if ( $request->hasFile('pdf_file_from_request') ) {
Storage::deleteDirectory('3pagerpdf/pdf');
$pdf = $request->file('pdf_file_from_request');
$fileName = time() . '.' . $pdf->getClientOriginalName();
Storage::putFileAs('3pagerpdf/pdf', $pdf, $fileName);
$model->pdf_file_name_in_datebase = $fileName;
$model->save();
flash()->addSuccess('Pdf Added');
return back();
}
}
Converting that PDF to Images
public function convertpdftoimages()
{
$model = Attachment::first();
set_time_limit(300);
// Get the PDF file from the storage folder
$pdfPath = storage_path('app/3pagerpdf/pdf/'.$model->pdf_file_name_in_datebase);
// Create an Imagick object
$imagick = new Imagick();
// Set the resolution and output format
$imagick->setResolution(300, 300);
$imagick->setFormat('jpeg');
// Read the PDF file into the Imagick object
$imagick->readImage($pdfPath);
// Convert each page of the PDF to an image
foreach ( $imagick as $page ) {
$page->writeImage(public_path("/temp_images/page{$page->getImageIndex()}.jpg"));
}
flash()->addSuccess('Convertion Successfull');
return back();
}
Adding bar code to those images
public function add_bar_code_to_images2()
{
$files = File::files('temp_images');
foreach ( $files as $file ) {
// Generate a barcode image for the file
$barcodeGenerator = new BarcodeGeneratorPNG();
$data = '';
for ($i = 0; $i < 10; $i++) {
$data .= rand(0, 9);
}
$barcodeString = $barcodeGenerator->getBarcode($data, $barcodeGenerator::TYPE_CODE_128);
// Create an image resource from the barcode string
$barcodeImage = imagecreatefromstring($barcodeString);
// Load the original image
$originalImage = imagecreatefromjpeg($file->getPathname());
// Merge the barcode image with the original image
imagecopy($originalImage, $barcodeImage, imagesx($originalImage) - imagesx($barcodeImage) - 10, 10, 0, 0, imagesx($barcodeImage), imagesy($barcodeImage));
// Save the modified image to a new path
imagejpeg($originalImage, 'modified_images/' . $file->getFilename());
}
flash()->addSuccess('Bar Code Added Succesfuully');
return back();
}
Converting those images Back to pdf
public function convertimagestopdf( )
{
// Create a new Imagick object
$imagick = new Imagick();
// Set the resolution of the PDF
$imagick->setResolution(300, 300);
// Iterate over the images in the "modified_images" directory
foreach (glob("modified_images/*.jpg") as $image) {
// Read the image file
$imagick->readImage($image);
}
// Set the format of the PDF to "application/pdf"
$imagick->setImageFormat('pdf');
// Save the PDF to a file
$imagick->writeImages('modified_pdf/document.pdf', true);
flash()->addSuccess('pdf compileed');
return back();
}
What I want is
I want to add bar code to every single page of a pdf but I dont want to use imagick extenstion it needs to be installed on a system to make it work .
I tried the above code
it is taking too long to execute for small pdf's that code it fine but for the pdf with 60 pages and above it starts to give me time out error
Note I am not generating this pdf
the pdf will be uploaded by random user of my application and it will be already a pdf I just need to add barcode to every single page of the pdf .
I will take any alternative solution
in which i dont have to install any application on my computer
like ghostscript
i m Wana Delete One page from PDF By imagemagick , How can this be done? this my code this return just one page in pdf ? what the problem ?
$image = new \Imagick(__DIR__.'/test.pdf');
$pageNumber = $image->count();
$page = true;
$imgs = [];
for($i=0 ; $i<$pageNumber ; $i++){
$image->readImage(__DIR__.'/test.pdf['.$i.']');
if($i === 2 && $page == true){
$image->removeImage();
$page = false;
continue;
}
// $imgs[] = __DIR__.'images'.$i.'.jpg';
}
$image->setImageFormat("pdf");
$image->writeImage('images.pdf');
file_put_contents(__DIR__.'images'.$i.'.pdf',$image);
Assuming that the original pdf is having 5 pages (known as fivepage.pdf), then you may use the following steps to remove page 3 from it and generate a new pdf known as combined.pdf
use Imagick to open the pdf
determine the number of pages
loop over each page of this pdf
save the pages into separate , temporary jpeg files
push the jpeg files (except page 3, $i==2) into array
use the array to generate the "combined.pdf"
delete all the temp jpeg files
So the code is:
<?php
$file="./fivepage.pdf";
$im = new Imagick($file);
$resultimages = array();
$noOfPagesInPDF = $im->getNumberImages();
// loop over all the pdf pages
for ($i = 0; $i < $noOfPagesInPDF; $i++) {
$url = $file.'['.$i.']';
$image = new Imagick();
// $image->setResolution(300,300);
// use the above line if you want higher resolution
$image->readimage($url);
$image->setImageFormat("jpg");
$image->writeImage("./temp_".($i+1).'.jpg');
// include all pages except page 3 ($i==2)
if ($i!=2) {
array_push($resultimages, "./temp_".($i+1).'.jpg');
}
}
// generate the resulting pdf (omitting page 3)
$pdf = new Imagick($resultimages);
$pdf->setImageFormat('pdf');
$pdf->writeImages('combined.pdf', true);
// clear temp images
for ($i = 0; $i < $noOfPagesInPDF; $i++) {
unlink("./temp_".($i+1).'.jpg');
}
echo "pdf without page 3 saved";
?>
I am trying to integrate two small Imagick codes into one. The first code splits a sentence into words, then them into images. The second code appends these images, making a whole image-based sentence. In the first code, I save individual word-based-images in a directory, which is then fetched by the second code using PHP's globe function. Now, I do not want to write images in the directory, instead I supply them to the second code in run-time and append. I need an idea how to do that. I am thinking about Clone() function, building an image index, but I am not sure about that and I need your feedback.
// First Code
$text = "Some sample senetnces";
$words = explode(' ', $text);
$imageout = new \Imagick();
foreach ($words as $no => $word)
{
$draw = new \ImagickDraw();
# $draw->setStrokeColor($strokeColor);
$draw->setFillColor('black');
# $draw->setStrokeWidth(2);
$draw->setFontSize(36);
$draw->setFont(DOCROOT . "/Congenial-Bold.ttf");
$draw->annotation(50, 50, $word);
$imagick = new \Imagick();
$imagick->newImage(500, 300, 'DeepSkyBlue');
$imagick->setImageFormat("png");
$imagick->drawImage($draw);
$imagick->trimImage(0);
$imagick->setImageBackgroundColor('DeepSkyBlue');
$imagick->spliceImage(10, 0, $imagick->getImageWidth(), $imagick->getImageHeight());
$imagick->writeImage(DOCROOT . '/tem634/fonts-' . $no . '.png');
# $images[] = $imagick->Clone();
}
// Second Code
$images = glob( DOCROOT . "/tem634/*.png");
$canvas = new Imagick();
foreach ($images as $image) {
$im = new Imagick($image);
$canvas->addImage($im);
}
// append the images into one
$canvas->resetIterator();
$combined = $canvas->appendImages(false);
$combined->setImageformat("png");
$combined->writeImage(DOCROOT . '/append.png');
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
This one might be a little confusing. I'm using AMCharts with rails. Amcharts comes with a PHP script to export images called "export.php"
I'm trying to figure out how to take the code in export.php and put it into a controller.
Here is the code:
<?php
// amcharts.com export to image utility
// set image type (gif/png/jpeg)
$imgtype = 'jpeg';
// set image quality (from 0 to 100, not applicable to gif)
$imgquality = 100;
// get data from $_POST or $_GET ?
$data = &$_POST;
// get image dimensions
$width = (int) $data['width'];
$height = (int) $data['height'];
// create image object
$img = imagecreatetruecolor($width, $height);
// populate image with pixels
for ($y = 0; $y < $height; $y++) {
// innitialize
$x = 0;
// get row data
$row = explode(',', $data['r'.$y]);
// place row pixels
$cnt = sizeof($row);
for ($r = 0; $r < $cnt; $r++) {
// get pixel(s) data
$pixel = explode(':', $row[$r]);
// get color
$pixel[0] = str_pad($pixel[0], 6, '0', STR_PAD_LEFT);
$cr = hexdec(substr($pixel[0], 0, 2));
$cg = hexdec(substr($pixel[0], 2, 2));
$cb = hexdec(substr($pixel[0], 4, 2));
// allocate color
$color = imagecolorallocate($img, $cr, $cg, $cb);
// place repeating pixels
$repeat = isset($pixel[1]) ? (int) $pixel[1] : 1;
for ($c = 0; $c < $repeat; $c++) {
// place pixel
imagesetpixel($img, $x, $y, $color);
// iterate column
$x++;
}
}
}
// set proper content type
header('Content-type: image/'.$imgtype);
header('Content-Disposition: attachment; filename="chart.'.$imgtype.'"');
// stream image
$function = 'image'.$imgtype;
if ($imgtype == 'gif') {
$function($img);
}
else {
$function($img, null, $imgquality);
}
// destroy
imagedestroy($img);
?>
There are some versions in existence in a thread I found here: http://www.amcharts.com/forum/viewtopic.php?id=341
But I have a feeling the PHP code above has changed since then - because neither implementation worked for me.
What this code more or less dose is grabs the informations, that were sent to the script (POST).
The informations include the height and width of the picture and the RGB values of every pixel. The script draws every pixel and sends the images at the end to the client.
You can use Rmagick's method to draw a pixel. This will give you the same result.
The incomming post data looks like this:
height = number -> cast to int
width = number -> cast to int
// first row with a repeating part of R:G:B,R:G:B,... (n = width)
r0 = 255:0:0,150:120:0,77:88:99,...
r1 = ...
.
.
r100 = ... -> the row count is the height - 1
Actually, I found a discussion about speeding up pixel by pixel drawing.
So apparently I was running into other errors which made me think the already existing code didnt work. However, the code on the thread I linked to in the original question does in fact work!