I am trying to make a preview from pdf that users must to upload. I am using 1and1 hosting server, so I don´t have total control about what to install, and I don´t know how to install ImageMagick. I followed these steps and I was using this code (that is working in a different project using a VPS):
private function preViewPDF($filename)
{
$img_path = './assets/uploads/previews';
$file_name = explode(".", $filename)[0].".jpg";
$dir = './assets/upload/files/';
$img = new Imagick($dir."/".$filename.'[0]');
$img->setImageFormat('jpg');
$img->writeImage($img_path."/".$file_name);
return "previews/".$id.$type."/".$file_name;
}
After try that and get Imagick Class not Found Exception, I am trying to convert using exec command:
Actual code
private function preViewPDF($filename)
{
$file_name = explode(".", $filename)[0].".jpg";
$dir = getcwd().'/assets/uploads/files/';
if(file_exists($dir."/".$filename))
{
exec("convert ".$dir."/".$filename.'[0]'." ".$dir."/".$file_name, $output, $return_var);
var_dump($output);
echo "<br>";
var_dump($return_var);
}
else echo "no file";
echo "<br>".$dir."/".$filename.'[0]'."<br>";
echo "<br>".$file_name."<br>";
}
The var_dump($output); throws an empty array. And the $return_var is 1... general error :(
If I change the value between [] (the number of the page I want to convert) $output throws:
array(3) {
[0]=> string(0) ""
[1]=> string(70) "Requested FirstPage is greater than the number of pages in the file: 1"
[2]=> string(53) " No pages will be processed (FirstPage > LastPage)."
}
So... any ideas what am I doing wrong?? Thank you.
Extra Data
Only two little things more (maybe obvious). The first, if I emulate the order on a SSL connection it works (I get a image from a pdf). And second, permissions are not the reason (I tried to create and write a file -with fopen and fwrite- and it works).
EDIT
First, an explanation about my actual code:
$file_name = explode(".", $filename)[0].".jpg";
This line is because the extension of $filename is .pdf, so I need remove this part and concatenate the right extension .jpg (from hello.pdf I get hello.jpg).
$dir = getcwd().'/assets/uploads/files/';
This is the folder where the pdf is uploaded and the jpg preview must be saved.
if(file_exists($dir."/".$filename))
I put this line, simply because I though that the uploading of the pdf wasn´t finished and this was the reason that doesn´t work.
exec("convert ".$dir."/".$filename.'[0]'." ".$dir."/".$file_name, $output, $return_var);
This is the line where the command convert is executed... but doesn´t work.
Second thing is a new simple code I just tried:
if(file_exists("./DpRPJTmfSArPRuGZrOddLendfbhgHTrydwukMRvOMuSzVMDuBb.pdf"))
{
exec("convert ./DpRPJTmfSArPRuGZrOddLendfbhgHTrydwukMRvOMuSzVMDuBb.pdf[0] ./DpRPJTmfSArPRuGZrOddLendfbhgHTrydwukMRvOMuSzVMDuBb.jpg", $output, $return_var);
var_dump($output);
echo "<br>";
var_dump($return_var);
}
else echo "no hay fichero";
The $output is empty, and the $return_var is 1.
Forget all the dross and start simple with the file in the same folder as the code to see if Imagemagick is working.
convert input.pdf output.jpg
Also you have so many variables etc. in the Imagemagick code it is hard to read it.
I am also confused by your code and I would create the filename and path outside the convert code and you can echo it to ensure it contains what you expect.
This looks wrong:
$filename.'[0]'
I would try:
$filename[0]
I assume your pdf has more than one page?
Edit
Try this code - it has a different way of displaying any errors and allows you to view the contents of your command if you have lots of variables etc.
$error=array();
echo "<pre>";
$cmd = "./DpRPJTmfSArPRuGZrOddLendfbhgHTrydwukMRvOMuSzVMDuBb.pdf[0] ./DpRPJTmfSArPRuGZrOddLendfbhgHTrydwukMRvOMuSzVMDuBb.jpg";
// You can use this line to see what the $cmd ontains when using a lot of variables
echo $cmd;
exec("$cmd 2>&1", $error);
echo "<br>".print_r($error)."<br>";
echo "</pre>";
I make preview with this:
exec('convert -density 300 -trim "'.$file.'" -resize 600 -quality 85 -colorspace RGB -background white "'.$destination.'" &', $output, $return_var);
Where $file is tue original and $destination is the name of image.
With the & at the end, each image will be named image-0.jpg, image-1.jpg..
$return_var == 0 when all is OK
Related
I'm trying to use pngquant with PHP using the following code (source):
<?php
function compress_png($path_to_png_file, $max_quality = 90)
{
if (!file_exists($path_to_png_file)) {
throw new Exception("File does not exist: $path_to_png_file");
}
// guarantee that quality won't be worse than that.
$min_quality = 60;
// '-' makes it use stdout, required to save to $compressed_png_content variable
// '<' makes it read from the given file path
// escapeshellarg() makes this safe to use with any path
// maybe with more memory ?
ini_set("memory_limit", "128M");
// The command should look like: pngquant --quality=60-90 - < "image-original.png"
$comm = "pngquant --quality=$min_quality-$max_quality - < ".escapeshellarg( $path_to_png_file);
$compressed_png_content = shell_exec($comm);
var_dump($compressed_png_content);
if (!$compressed_png_content) {
throw new Exception("Conversion to compressed PNG failed. Is pngquant 1.8+ installed on the server?");
}
return $compressed_png_content;
}
echo compress_png("image-original.png");
The function is supposed to retrieve the output of the shell_exec function. With the output i should be able to create a new png file, however the output of the shell_exec in the browser is corrupt: �PNG.
Note: the execution of the command is succesfully executed in the console without PHP (pngquant --quality=60-90 - < "image-original.png")
If I execute the php code from the console, i get the following message:
error: failed writing image to stdout (16)
I've searched everywhere without any solution, can someone help me or have any idea of what could be causing the problem ?
The php-pngquant wrapper allow you to retrieve the content from the generated image by PNGQuant directly into a variable using the getRawOutput method:
<?php
use ourcodeworld\PNGQuant\PNGQuant;
$instance = new PNGQuant();
$result = $instance
->setImage("/image/to-compress.png")
->setQuality(50,80)
->getRawOutput();
// Result is an array with the following structure
// $result = array(
// 'statusCode' => 0,
// 'tempFile' => "/tmp/example-temporal.png",
// 'imageData' => [String] (use the imagecreatefromstring function to get the binary data)
//)
// Get the binary data of the image
$imageData = imagecreatefromstring($result["imageData"]);
// Save the PNG Image from the raw data into a file or do whatever you want.
imagepng($imageData , '/result_image.png');
Under the hood, the wrapper provides as the output argument in PNGQuant a temporary file, then pngquant will write the compressed image into that file and will retrieve its content in the result array. You can still verify the exit code of PNGQuant with the statusCode index of the result array.
this is my first question ever.
I have a form pdf that i need to fill with php, it works fine with fpdm. When I open the file in chrome or in Architect 4 even the dropdown list are filled but when I open the same file in Adobe Reader, everything is filled except the dropdown list.
Anyone have any thoughts about it ? I think maybe it's a conversion problem between FDF and PDF but i have really no idea on how to solve it.
EDIT :
$fieldsI = array(
/* ---------------- Beneficiaire 1 ----------------*/
'ZA1benefNom1' => $InfosFormateur[0]['nom'],
'ZA1benefPrenom1' => $InfosFormateur[0]['prenom'],
[...]
'ZA4nature1' => 'H ', //strval('H'),
'ZA4montant1' => strval($montant[$InfosFormateur[0]['IdProfil']])
);
$pdf = new FPDM('pdf/das2/form2.pdf');
$pdf->Load($fieldsI, true); // second parameter: true if UTF-8
$pdf->Merge();
I don't know where i can upload the result.
I have an other problem by the way, when I want to merge all my pdf filled, i try many solutions. I have one almost working :
public function combine_pdf($outputName,$fileArray)
{
$merged_pdf = "";
foreach($fileArray as $filename){
$merged_pdf .= " ".$filename;
}
exec("pdftk".$merged_pdf." cat output ".$outputName);
header(sprintf('Location: %s', $outputName));
}
But when i open the pdf generated in Adobe Pdf reader, everything is blank again.
I have found the solution. It's working !
You need pdftk on your server :
public function combine_pdf($outputName,$fileArray, $rep = "download/DAS/")
{
$merged_pdf = "";
foreach($fileArray as $filename){
$merged_pdf .= " ".$filename;
}
exec("pdftk".$merged_pdf." cat output ".$rep."tmpfinal.pdf "); //merge all my filled pdf to 1 pdf
exec("pdftk ".$rep."tmpfinal.pdf generate_fdf output ".$rep."final.fdf"); //generate a clean fdf from this pdf
exec("pdftk ".$rep."tmpfinal.pdf fill_form ".$rep."final.fdf output ".$outputName); // then use the pdf as template filled by the fdf.
header(sprintf('Location: %s', $outputName));
}
I hope it will help someone
I'm currently running into a very odd issue with fpdf. I found a similar question with no answer: not a PNG file in FPDF. I have an image uploaded through a browser to my file server, and then pulled into a fpdf report. When this image is a png, I get the error: "FPDF error: Not a PNG file". I don't get any errors when the uploaded image is a jpg. This issue seemingly appeared overnight a few weeks ago.
Even stranger, it's only happening with new png's being uploaded. There was a png in a report that was generating fine. When I downloaded that png from the system and re-uploaded it, the errors appeared again.
Here are some of the steps I've taken while attempting to troubleshoot the issue:
I've made sure the image is actually a png (through its properties).
Nothing has changed with the way I've been saving the images, but here's the code:
$original = $time."_".$name."_o.".$extension;
$thumbnail = $time."_".$name."_t.".$extension;
include('SimpleImage.php');
$image = new SimpleImage();
$image->load($_FILES['file']['tmp_name']);
$image->save($A_path."images/".$original);
$image->resizeToHeight(200);
$image->save($A_path."images/thumbs/".$thumbnail);
$photo = "images/".$original;
$thumb = "images/thumbs/".$thumbnail;
I've checked to see if their were any changes to the PNG format or FPDF updates, with no luck.
I've converted a jpg that works into a png through gimp.
Converting a png to a jpg through gimp and then uploading the jpg to the system does not generate any errors.
WORKAROUND- I've gone ahead and converted png's to jpg's on save, rather than re-encoding the image. Thanks for the help.
Fixed it by changing the picture format manually to JPG and then repeating the process.
The error message indicates that there is something wrong with the first eight bytes of the file (the "png signature").
Use "od -c | head -1" to inspect the first 16 bytes. Every PNG file
begins with these:
211 P N G \r \n 032 \n \0 \0 \0 \r I H D R
If you prefer, use "xxd file.png | head -1" and expect to see this:
0000000: 8950 4e47 0d0a 1a0a 0000 000d 4948 4452 .PNG........IHDR
These 16 bytes are the PNG signature and the length and name of the first chunk. The first 8 bytes are the format
name, plus newlines (linefeeds) and carriage returns that are designed
to detect various transmission errors. The next 8 bytes are the beginning
of the IHDR chunk, which must be length=13 expressed as a 4-byte integer, and the name="IHDR".
See the PNG specification for details.
Check the depth of the image. FPDF supports 24bit depth (i'm not sure about 32bit depth), neither does it support alpha channel.
I'd try to reencode to png with ImageMagick (or paint.net under windows).
convert input.png -depth 8 +matte output.png
I found a crud solution that works for me but this will take little more space on your host. But you can determine which extension worked and delete the rest However its worth it.
First take the file contents and convert them to base64_encode.
Create an array of the file formats you want the file to be in "png","jpg","jpeg" and decode the base64 image looping through the file extensions. This recreates the image with three file extensions in your folder.
Use the
try{
}catch (Exception $e) {
}
to loop trough and find which image extension works and use it.
Here is my full code
$base64 = base64_encode(file_get_contents("full/domain/path/to/image"));
$f_ex = array('.png', '.jpg', '.jpeg'); //array of extensions to recreate
$path = "path/to/new/images"; //this folder will have there images.
$i = 0;
$end = 3;
while ($i < $end) {
$data = base64_decode($base64); //decode the image file from base64
$filename = "unique_but_memorable_filename(eg invoice id)" . $f_ex[$i]; //$f_ex loops through the file extensions
file_put_contents($path . $filename, $data); //we save our new images to the path above
$i++;
}
Inside your FPDF where your image is set, we loop through the images we recreated and see which one works and stop there
try {
$filename = "remember_unique_but_memorable_filename(eg invoice id)" . $f_ex[0];
$logo = "your domail.com where image was stored" . '/' . $path . $filename;
$pdf->Image($logo, 10, 17, 100, 100);
//Put your code here to delete the other image formats.
} catch (Exception $e) {
try {
$filename = "remember_unique_but_memorable_filename(eg invoice id)" . $f_ex[1];
$logo = "your domail.com where image was stored" . '/' . $path . $filename;
$pdf->Image($logo, 10, 17, 100, 100);
//Put your code here to delete the other image formats.
} catch (Exception $e) {
try {
$filename = "remember_unique_but_memorable_filename(eg invoice id)" . $f_ex[2];
$logo = "your domail.com where image was stored" . '/' . $path . $filename;
$pdf->Image($logo, 10, 17, 100, 100);
//Put your code here to delete the other image formats.
} catch (Exception $e) {
//if all the three formats fail, lets see the error
echo 'Message: ' . $e->getMessage();
}
}
}
I am a beginner to PHP so please forgive any ignorance...
I am using the exec() command as following to get the list of files in my media directory..
<?php // exec.php
$cmd = "dir"; // Windows
exec(escapeshellcmd($cmd), $output, $status);
if ($status) echo "Exec command failed";
else
{
echo "<pre>";
foreach($output as $line) echo "<a href='$line'>$line</a> \n";
}
?>
The problem is it gives the list of files along with the various timestamps of the filenames-
Volume in drive F is Movies
Volume Serial Number is 172B-1DE0
06/17/2011 01:11 AM 6,318 bck.gif
Hence, here it creates clickable link to each line for the output which needless to say does not work.
What I want is that it will only create clickable links for the filenames and not the extra meta information, which the user can then click to launch his native program like this-
video1.mpg
video2.mpg
bck.gif
You're far better off using PHP's directory manipulation functions instead. The scandir() function should be of particular interest to you.
http://uk.php.net/manual/en/book.dir.php
http://uk.php.net/manual/en/function.scandir.php
Don't forget that the scandir listing will include . and .. ao you'll need to remove them from the results set unless you plan to use them for navigation.
There is no need to use exec(); to list files in the directory, PHP has many build in functions for dealing with the file system:
From the readdir() manual page:
<?php
if ($dirHandle = opendir('.')) {
while (false !== ($nodeHandle = readdir($dirHandle ))) {
if ($nodeHandle == '.' || $nodeHandle == '..') {
continue;
}
echo "$nodeHandle \n";
}
closedir($dirHandle);
}
?>
I have ffmpeg installed
safe_mode is off
when i do this: $movie = new ffmpeg_movie('Bear.wmv');
I can use getDuration(), getFilename().... wthout any problems, so it's all seems to be working
exec is working fine, cos when i do: $output = exec('ls -lart'); I get a nice little result.
but when I do this:
exec('ffmpeg -i Bear.wmv outputfile.flv')
nothing happens
if I add: $command_output, $result
the only result i guess is: array { }
I have tried everything I could think of:
exec('ffmpeg -i Bear.wmv outputfile.flv')
exec('ffmpeg.so -i Bear.wmv outputfile.flv')
exec('/usr/lib/php5/20090626/ffmpeg -i Bear.wmv outputfile.flv')
I've tried all sizes and folders and codecs but still don't get anything back
All i wanna do is convert that video, Bear.wmv to an flv file.
I'm very close to crying like a baby and/or jumping out of the window (im only on the first floor but still lol)
so Please help!!??!
FFMPEG is a application wich don't output to STDIO but STDERR, so you can redirect it to standard output:
$cmd = $FFMPEGDIR . " -i somefile.avi 2>&1"; // SEE 2>&1 !!
Extracting size:
exec( $cmd , $info );
echo "<pre>".print_r($info,true)."</pre>";
$resolution = preg_match( '#[ ,\t]([0-9]{3,4}x[0-9]{3,4})[ ,\t]#si' , implode( " " , $info ) , $durmatches );
$rtab = explode( "x" , $durmatches[1] );
$videowidth = $rtab[0];
$videoheight = $rtab[1];
Recently set ffmpeg up for audio stuff... it's a bit of a black art, ffmpeg is notorious for not playing nice (or consistently) - what works (worked) for me might not work for you!
try using: shell_exec()
or:
$command="{$FFMPEG_BINARY} ... rest of your options";
$process=proc_open($command, $descriptors, $pipes);
if (!$process)
{
// failed to exec...
}
else
{
// command ran...
}
my ffmpeg was in... "/usr/bin/ffmpeg" just check you've got right path too.