Having installed the PEAR GraphViz package I'm trying to follow the second answer on this page to create a JPEG of a graph. As test code, I have the following:
<?php
require_once 'Image/GraphViz.php';
$graph = new Image_GraphViz();
$graph->addNode('A');
$img = $graph->fetch('jpeg', 'dot');
print "IMG: " . $img;
I've also tried it using the $graph->image('jpeg', 'dot'); method. Both ways, it returns an empty string. When I change the format to something like SVG, it works, which makes me think that certain image generation libraries just aren't installed. But I have the regular (commandline) Graphviz tools installed and they generate images fine. What do I need to install to make this work so PHP can generate images itself?
Related
We have a project where we merge different pdfs to create a catalog.
Right now it's running on myokyawhtun/pdfmerger, which runs fine, but it does not keep links set in acrobat.
We have tried different libraries we found (pure PHP, we cannot install or call applications from the command line via shell-exec or similar on this webspace, so no gs), even if we just import the pdf-files via fpdi and resave them, the hyperlinks get lost.
Is there any (pure PHP) library out there which can retain links inside the files? Or are there some special settings that we missed?
We have tried:
setasign/fpdi
iio/libmergepdf
jurosh/pdf-merge
Example code for the current lib (myokyawhtun/pdfmerger):
require('vendor/myokyawhtun/pdfmerger/tcpdf/tcpdf.php');
require('vendor/myokyawhtun/pdfmerger/tcpdf/tcpdi.php');
require('vendor/myokyawhtun/pdfmerger/PDFMerger.php');
$pdf = new \PDFMerger\PDFMerger;
foreach($sourcePdfs as $file)
{
$pdf->addPDF($pdfDir.'/source/'.$file);
}
$pdf->merge('download', 'Download.pdf');
All the mentioned libraries use FPDI under the hood, which simply does not support content outside of a pages content stream, such as links or any other annotation type.
We (author of FPDI) also offer non-free products which work on another level and which allow you keep all annotations including links and also forms when you concatenate the documents. This is possible with the SetaPDF-Merger component:
$merger = new SetaPDF_Merger();
foreach($sourcePdfs as $file) {
$merger->addFile($pdfDir . '/source/' . $file);
}
$merger->merge();
$document = $merger->getDocument();
$document->setWriter(new SetaPDF_Core_Writer_Http('Download.pdf'));
$document->save()->finish();
I installed composer require spatie/image-optimizer, but when I run the example below the I had two problems:
1- The class could not be found by calling it by using (use). So I solved it by using include.
2- After solving the first problem, the code works fine but the resultant image is the same image with no optimization.
include 'Spatie/Imageoptimizer/src/OptimizerChainFactory.php';
require __DIR__.'/autoload.php';
$pathToImage = "D:/xampp/htdocs/images/vendor/uploads/2.png";
//use Spatie\ImageOptimizer\OptimizerChainFactory;
// Get the image and store the original size
$image = $pathToImage;
$originalSize = filesize($image);
// Optimize updates the existing image
$optimizerChain = OptimizerChainFactory::create();
$optimizerChain->optimize($image);
// Clear stat cache to get the optimized size
clearstatcache();
// Check the optimized size
$optimizedSize = filesize($image);
$percentChange = (1 - $optimizedSize / $originalSize) * 100;
echo sprintf("The image is now %.2f%% smaller\n", $percentChange);
exit(0);
Could you please suggest me any solutions!
I found the cause of the problem, which is the jpg and Optipng tools are not installed in the windows. Is there any way to install the tools in windows and link them to the plugin.
Is there a way in PHP given a video file (.mov, .mp4) to generate a thumbnail image preview?
Solution #1 (Older) (not recommended)
Firstly install ffmpeg-php project (http://ffmpeg-php.sourceforge.net/)
And then you can use of this simple code:
<?php
$frame = 10;
$movie = 'test.mp4';
$thumbnail = 'thumbnail.png';
$mov = new ffmpeg_movie($movie);
$frame = $mov->getFrame($frame);
if ($frame) {
$gd_image = $frame->toGDImage();
if ($gd_image) {
imagepng($gd_image, $thumbnail);
imagedestroy($gd_image);
echo '<img src="'.$thumbnail.'">';
}
}
?>
Description: This project use binary extension .so file, It's very old and last update was for 2008. So, maybe don't works with newer version of FFMpeg or PHP.
Solution #2 (Update 2018) (recommended)
Firstly install PHP-FFMpeg project (https://github.com/PHP-FFMpeg/PHP-FFMpeg)
(just run for install: composer require php-ffmpeg/php-ffmpeg)
And then you can use of this simple code:
<?php
require 'vendor/autoload.php';
$sec = 10;
$movie = 'test.mp4';
$thumbnail = 'thumbnail.png';
$ffmpeg = FFMpeg\FFMpeg::create();
$video = $ffmpeg->open($movie);
$frame = $video->frame(FFMpeg\Coordinate\TimeCode::fromSeconds($sec));
$frame->save($thumbnail);
echo '<img src="'.$thumbnail.'">';
Description: It's newer and more modern project and works with latest version of FFMpeg and PHP. Note that it's required to proc_open() PHP function.
Two ways come to mind:
Using a command-line tool like the popular ffmpeg, however you will almost always need an own server (or a very nice server administrator / hosting company) to get that
Using the "screenshoot" plugin for the LongTail Video player that allows the creation of manual screenshots that are then sent to a server-side script.
I recommend php-ffmpeg library.
Extracting image
You can extract a frame at any timecode using the
FFMpeg\Media\Video::frame method.
This code returns a FFMpeg\Media\Frame instance corresponding to the
second 42. You can pass any FFMpeg\Coordinate\TimeCode as argument,
see dedicated documentation below for more information.
$frame = $video->frame(FFMpeg\Coordinate\TimeCode::fromSeconds(42));
$frame->save('image.jpg');
If you want to extract multiple images from the video, you can use the following filter:
$video
->filters()
->extractMultipleFrames(FFMpeg\Filters\Video\ExtractMultipleFramesFilter::FRAMERATE_EVERY_10SEC, '/path/to/destination/folder/')
->synchronize();
$video
->save(new FFMpeg\Format\Video\X264(), '/path/to/new/file');
By default, this will save the frames as jpg images.
You are able to override this using setFrameFileType to save the frames in another format:
$frameFileType = 'jpg'; // either 'jpg', 'jpeg' or 'png'
$filter = new ExtractMultipleFramesFilter($frameRate, $destinationFolder);
$filter->setFrameFileType($frameFileType);
$video->addFilter($filter);
Is there a way in PHP given a video file (.mov, .mp4) to generate a thumbnail image preview?
Solution #1 (Older) (not recommended)
Firstly install ffmpeg-php project (http://ffmpeg-php.sourceforge.net/)
And then you can use of this simple code:
<?php
$frame = 10;
$movie = 'test.mp4';
$thumbnail = 'thumbnail.png';
$mov = new ffmpeg_movie($movie);
$frame = $mov->getFrame($frame);
if ($frame) {
$gd_image = $frame->toGDImage();
if ($gd_image) {
imagepng($gd_image, $thumbnail);
imagedestroy($gd_image);
echo '<img src="'.$thumbnail.'">';
}
}
?>
Description: This project use binary extension .so file, It's very old and last update was for 2008. So, maybe don't works with newer version of FFMpeg or PHP.
Solution #2 (Update 2018) (recommended)
Firstly install PHP-FFMpeg project (https://github.com/PHP-FFMpeg/PHP-FFMpeg)
(just run for install: composer require php-ffmpeg/php-ffmpeg)
And then you can use of this simple code:
<?php
require 'vendor/autoload.php';
$sec = 10;
$movie = 'test.mp4';
$thumbnail = 'thumbnail.png';
$ffmpeg = FFMpeg\FFMpeg::create();
$video = $ffmpeg->open($movie);
$frame = $video->frame(FFMpeg\Coordinate\TimeCode::fromSeconds($sec));
$frame->save($thumbnail);
echo '<img src="'.$thumbnail.'">';
Description: It's newer and more modern project and works with latest version of FFMpeg and PHP. Note that it's required to proc_open() PHP function.
Two ways come to mind:
Using a command-line tool like the popular ffmpeg, however you will almost always need an own server (or a very nice server administrator / hosting company) to get that
Using the "screenshoot" plugin for the LongTail Video player that allows the creation of manual screenshots that are then sent to a server-side script.
I recommend php-ffmpeg library.
Extracting image
You can extract a frame at any timecode using the
FFMpeg\Media\Video::frame method.
This code returns a FFMpeg\Media\Frame instance corresponding to the
second 42. You can pass any FFMpeg\Coordinate\TimeCode as argument,
see dedicated documentation below for more information.
$frame = $video->frame(FFMpeg\Coordinate\TimeCode::fromSeconds(42));
$frame->save('image.jpg');
If you want to extract multiple images from the video, you can use the following filter:
$video
->filters()
->extractMultipleFrames(FFMpeg\Filters\Video\ExtractMultipleFramesFilter::FRAMERATE_EVERY_10SEC, '/path/to/destination/folder/')
->synchronize();
$video
->save(new FFMpeg\Format\Video\X264(), '/path/to/new/file');
By default, this will save the frames as jpg images.
You are able to override this using setFrameFileType to save the frames in another format:
$frameFileType = 'jpg'; // either 'jpg', 'jpeg' or 'png'
$filter = new ExtractMultipleFramesFilter($frameRate, $destinationFolder);
$filter->setFrameFileType($frameFileType);
$video->addFilter($filter);
Currently i can create PDF files from images in Imagick with this function
$im->setImageFormat("pdf");
$im->writeImage("file.pdf");
And it's possible to fetch multiple pages with imagick like this
$im = new imagick("file.pdf[0]");
$im2 = new imagick("file.pdf[1]");
But is it possible to save two image objects to two pages?
(example of what i am thinking, its not possible like this)
$im->setImageFormat("pdf");
$im->writeImage("file.pdf[0]");
$im2->setImageFormat("pdf");
$im2->writeImage("file.pdf[1]");
I know this is long past due, but this result came up when I was trying to do the same thing. Here is how you create a multi-page PDF file in PHP and Imagick.
$images = array(
'page_1.png',
'page_2.png'
);
$pdf = new Imagick($images);
$pdf->setImageFormat('pdf');
if (!$pdf->writeImages('combined.pdf', true)) {
die('Could not write!');
}
Accepted answer wasn't working for me, as a result, it always generated one page pdf (last image from constructor), to make this work I had to get file descriptor first, like this:
$images = array(
'img1.png', 'img2.png'
);
$fp = fopen('combined.pdf', 'w');
$pdf = new Imagick($images);
$pdf->resetiterator();
$pdf->setimageformat('pdf');
$pdf->writeimagesfile($fp);
fclose($fp);
Is this working?
$im->setImageFormat("pdf");
$im->writeImage("file1.pdf");
$im2->setImageFormat("pdf");
$im2->writeImage("file2.pdf");
exec("convert file*.pdf all.pdf");
CAM::PDF is a pure-Perl solution for low-level PDF manipulation like this. You can either use the appendpdf.pl command-line tool, or do it programmatically like this:
use CAM::PDF;
my $doc1 = CAM::PDF->new('file1.pdf');
my $doc2 = CAM::PDF->new('file2.pdf');
$doc1->appendPDF($doc2);
$doc1->cleanoutput('out.pdf');
If you can figure out how to make ImageMagick write to a string instead of to a file (I'm not an ImageMagick expert...) then you save some performance overhead by keeping it all in Perl.
(I'm the author of CAM::PDF. It's free software: GPL+Artistic dual-licensed).
I do not know php or this Imagick library, but if calling an external program is acceptable I can recommend the program pdfjoin to merge pdf files.
It does have an dependency to pdflatex, so if this is something you intend to run on a server you might have to install extra latex stuff, but the end result from pdfjoin is very good, so I think it will be worth it.