Amazon S3 Upload PDF and Create Cover Image - php

I have the following bit of code which uploads a PDF to Amazon S3, what I need to do is create an image from the 1st page of the PDF and upload that to s3 as well.
//instantiate the class
$s3 = new S3(awsAccessKey, awsSecretKey);
//check whether a form was submitted
if($_SERVER['REQUEST_METHOD'] == "POST")
{
//retreive post variables
$fileName = $_FILES['file']['name'];
$fileTempName = $_FILES['file']['tmp_name'];
$fileSize = $_FILES['file']['size'];
$extension=end(explode(".", $fileName));
$rand = rand(1,100000000);
$sha1 = sha1($rand);
$md5 = md5($sha1);
$fName = substr($md5, 0, 20);
$finalName = $fName.'.'.$extension;
//create a new bucket
$s3->putBucket("bucket", S3::ACL_PUBLIC_READ);
//move the file
if ($s3->putObjectFile($fileTempName, "bucket", 'publications/'.$finalName, S3::ACL_PUBLIC_READ)) {
$s3file='http://bucket.s3.amazonaws.com/publications/'.$finalName;
$aS3File = 'publications/'.$finalName;
$im = new imagick($s3file[0]);
// convert to jpg
$im->setImageColorspace(255);
$im->setCompression(Imagick::COMPRESSION_JPEG);
$im->setCompressionQuality(75);
$im->setImageFormat('jpeg');
//resize
$im->resizeImage(640, 877, imagick::FILTER_LANCZOS, 1);
//write image on server (line 54)
$s3->putObjectFile("","bucket", 'publications/'.$im->writeImage($fName.'.jpg'), S£::ACL_PUBLIC_READ);
}else{
echo "<strong>Something went wrong while uploading your file... sorry.</strong>";
}
I have replace my actual bucket name with 'bucket' for security, can anyone tell me what I am doing wrong here as I get the following error:
PHP Fatal error: Uncaught exception 'ImagickException' with message
'Unable to read the file: h' in
/var/www/ams/pub-new-issue.php:45\nStack trace:\n#0
/var/www/ams/pub-new-issue.php(45): Imagick->__construct('h')\n#1
{main}\n thrown in /var/www/ams/pub-new-issue.php on line 45,
thanks

$s3file='http://bucket.s3.amazonaws.com/publications/'.$finalName;
$im = new imagick($s3file[0]);
$s3file is a string, but you're accessing an array index in it. As a result, you fetch the first character, h. Use just $s3file in your Imagick instantiation and you should be fine.

Related

how to prevent imagecreatefrom from creating a static gif - PHP

I have a script that sends an image it is saved as a .gif as declared in the movie.php file that will be listed below.
However, as I understand it, it creates an image from the gif making it useless for display because it simply becomes a static image .gif.
Anyway
I wanted to know how I can upload this file and ignore this function (imagecreatefromgif) I tried to change it in several ways and when I remove it I get an error, someone could help me work around this so that the gif will be sent and not be converted to a gif file static. basically I wanted that the way I sent the gif it would only be renamed with function imageGenerateName () but that it would keep all its size and property.
Every help is welcome.
Thanks in advance
.
Movie.php code:
<?php
class Movie {
public function imageGenerateName() {
return bin2hex(random_bytes(60)) . ".gif";
}
}
movie-process.php code
<?php
// Upload img
if(isset($_FILES["image"]) && !empty($_FILES["image"]["tmp_name"])) {
$image = $_FILES["image"];
$imageTypes = ["image/gif"];
$jpgArray = ["image/gif"];
// Check img type
if(in_array($image["type"], $imageTypes)) {
// Check img type
if(in_array($image["type"], $jpgArray)) {
$imageFile = imagecreatefromgif($image["tmp_name"]);
} else {
$imageFile = imagecreatefromgif($image["tmp_name"]);
}
// image name
$imageName = $movie->imageGenerateName();
imagegif($imageFile, "./img/movies/" . $imageName, 100);
$movie->image = $imageName;
}
}
// Upload img
if(isset($_FILES["image"]) && !empty($_FILES["image"]["tmp_name"])) {
$image = $_FILES["image"];
$imageTypes = ["image/gif"];
$jpgArray = ["image/gif"];
// Check img type
if(in_array($image["type"], $imageTypes)) {
// check type is gif
if(in_array($image["type"], $jpgArray)) {
$imageFile = imagecreatefromgif($image["tmp_name"]);
}
// generete img name
$movie = new Movie();
$imageName = $movie->imageGenerateName();
imagegif($imageFile, "./img/movies/" . $imageName, 100);
$movieData->image = $imageName;
}
}
Unfortunately, the imagecreatefromgif function will only read the first image of the gif as the PHP manual says.
I tried before to solve this, but there is no turnaround other than uploading the image without touching it. PHP uses the GD library and this library doesn't have the proper functionality to deal with gif images other than just saving the image with the *.gif extension.
So, this is my suggested solution:
// generete img name
$movie = new Movie();
$imageName = $movie->imageGenerateName();
move_uploaded_file($_FILES["image"]["tmp_name"],"./img/movies/" . $imageName);
$movieData->image = $imageName;
I think since you say you just want to save it as it is, with the same size and its all properties, you can use below code
<?php
$allowed = array('gif');
$filename = $_FILES["image"]['name'];
$ext = pathinfo($filename, PATHINFO_EXTENSION);
if (in_array($ext, $allowed)) {
// generete img name
$movie = new Movie();
$imageName = $movie->imageGenerateName();
$uploadResult = move_uploaded_file($_FILES['image']['tmp_name'], dirname( dirname( __FILE__ ) ).'/img/movies/'. $imageName );
if($uploadResult === true ){
$movie->image = $imageName;
}else{
throw new \Exception('Unable to copy file to the given path');
}
}
Or if you have access to the Imagick lib php extension refer to below link on how to install this php-extension
https://www.php.net/manual/en/imagick.setup.php
then using the functions in that library you can do
<?php
$allowed = array('gif');
$filename = $_FILES["image"]['name'];
$ext = pathinfo($filename, PATHINFO_EXTENSION);
if (in_array($ext, $allowed)) {
$image = new Imagick();
$image->readImage($_FILES["image"]["tmp_name"]);
$image = $image->coalesceImages();
foreach ($image as $frame) {
$frame->cropImage($crop_w, $crop_h, $crop_x, $crop_y);
$frame->thumbnailImage($size_w, $size_h);
$frame->setImagePage($size_w, $size_h, 0, 0);
}
$image = $image->deconstructImages();
$image->writeImages(dirname( dirname( __FILE__ ) ).'/img/movies/'. $imageName, true);
}
?>

Converting Pdf file to images with Imagick and PHP

Program to load pdf image and at the same time convert them to jpg using Imagick.But couldnt convert and load it in Destination directory.
$name = $_FILES['file']['name'];
$fileName = substr($_FILES['file']['tmp_name'], 5).".".$ext;
date_default_timezone_set('UTC');
$fileDate = date('d.m.Y');
$fileSize = $_FILES['file']['size'];
$folder = $_POST['folder'];
$uploadfile1="$media_dir/$fileName";
$imagick = new imagick();
$imagick->readImage($uploadfile1);//line 149
$imagick->setImageFormat('jpg');
foreach($imagick as $i=>$imagick)
{
$imagick->writeImage($uploadfile1. " page ". ($i+1) ." of ". $pages.".jpg");
}
Error
Fatal error: Uncaught ImagickException: unable to open image
`/opt/ama/mediaFiles/phpe765pr.pdf': No such file or directory #
error/blob.c/OpenBlob/2701 in
/home/james/workspace/ama/1.1/userinterface/webfleet/gui/ama/modules/mediaFiles/uploadFile.php:149Stack
trace:#0
/home/james/workspace/ama/1.1/userinterface/webfleet/gui/ama/modules/mediaFiles/uploadFile.php(149):
Imagick->readimage('/opt/gpssi/medi...')#1 {main} thrown in
/home/james/workspace/ama/1.1/userinterface/webfleet/gui/gpssi/modules/mediaFiles/uploadFile.php on line 149
You have a problem with the path of
/opt/ama/mediaFiles/phpe765pr.pdf
Make sure the path exists and the necessary privileges are given to all the folders in the path along the file to read it.

Retrieving external image and saving locally results in distorted image

Stuck on this one. I have this function below that simply takes $ImageSrc which is an external image from anywhere, eg imgur, and then saves it locally (this is not a scraper, I'm allowing people to attach images to their profiles)
public function UploadScreenshot($ImageSrc, $Title, $Description = false) {
$RandomName = substr(md5($Title . time()), 0, 20);
$UploadDir = "/home/vanrust/public_html/Screenshots/";
$file = pathinfo($ImageSrc);
$ext = $file["extension"];
if (!in_array($ext, array('jpg','png','bmp','jpeg'))) return array("error" => "Invalid File Type");
$RandomName = "{$RandomName}.{$ext}";
$image = file_get_contents($ImageSrc);
file_put_contents($UploadDir . $RandomName, $image);
}
The result of the file no matter what is unrecognizable.
The image:
After UploadScreenshot() has retrieved it:
Try to use rename() to move the original file to the new location and rename it.
$file = pathinfo($ImageSrc);
$ext = $file["extension"];
if (!in_array($ext, array('jpg','png','bmp','jpeg'))) return array("error" => "Invalid File Type");
$RandomName = "{$RandomName}.{$ext}";
rename($UploadDir . $RandomName, $ImageSrc);
}
Alternatively, you can use move_uploaded_file() if your $ImageSrc does contain a valid upload file (meaning that it was uploaded via PHP's HTTP POST upload mechanism).
file_put_contents() needs to be used with caution. A single offset (in binary codes) at the beginning or at the end of the file will significantly alter the picture. It requires a validation at the end to compare both files bytes.

Decode image object from binary string in ImageMagick for PHP

I have a script that downloads favicons and turns them in to PNGs.
To handle the conversion, I am using ImageMagick. My current approach involves downloading the data, writing it to a file, converting the file, then deleting the originally downloaded file. Here's what I mean:
$source = 'http://google.com/favicon.ico';
$image = file_get_contents($source);
// I'd like to skip these lines
$favicon = fopen('favicon.ico', 'w');
fwrite($favicon, $image);
fclose($favicon);
$im = new Imagick();
$im->readimage('favicon.ico');
$im = $im->flattenImages();
$im->setImageFormat('png');
$im->writeImage('favicon.png');
unlink('favicon.ico');
This works, but ideally I could do it without writing the $image variable to the file favicon.ico and instead I might just convert the data within the $image variable and then $im->writeImage('favicon.png') on that.
I checked out the method getImageBlob but when I tried that I got this error:
PHP Fatal error: Uncaught exception 'ImagickException' with message 'no decode delegate for this image format `' # error/blob.c/BlobToImage/364' in /home/vagrant/test/test_image.php:73
Stack trace:
#0 /home/vagrant/test/test_image.php(73): Imagick->readimageblob('\x00\x00\x01\x00\x02\x00\x10\x10\x00\x00\x01\x00 \x00h...')
#1 {main}
thrown in /home/vagrant/test/test_image.php on line 73
Any ideas?
You'll need to invoke Imagick::setFormat before reading blob.
<?php
$source = 'http://google.com/favicon.ico';
$image = file_get_contents($source);
$im = new Imagick();
$im->setFormat('ICO');
$im->readImageBlob($image);
$im = $im->flattenImages();
$im->setImageFormat('PNG');
$im->writeImage('favicon.png');
Update
Flattening the .ico image may have negative effects on files containing more than one image. Simplest solution would be to iterate over all the images, and determine which sub-image to use.
$im = new Imagick();
$im->setFormat('ICO');
$im->readImageBlob($image);
for( $idx = 0, $len = $im->getNumberImages(); $idx < $len; $idx++ ) {
// If this is the sub-image you want, do the following, else skip
$im->setImageFormat('png');
$im->setImageIndex($idx);
$im->writeImage(sprintf('favicon_%d.png', $idx));
}

How do I get Image Data from an Image Resource?

I'm working with the Microsoft Azure cloud and need to upload images there. Its class upload methods putBlob() and putBlobData() require either the data itself (not the resource) or the directory string as arguments, none of which is available before the image is actually written to the Blob.
$fp = fopen($tmp_name, 'r');
$data = fread($fp, filesize($tmp_name));
fclose($fp);
//Setup watermark destination
$new_watermarked_image_name = "watermark.jpg";
// Create image resources
$image = imagecreatefromstring($data);
$watermark = imagecreatefrompng('images/watermark_large.png');
$copyright = imagecreatefrompng('images/copyright.png');
// Merge image resource s
$image = overlay_watermark_full_size($image, $watermark);
$image = overlay_watermark_lower_right($image, $copyright);
imagejpeg($image, $new_watermarked_image_name, 100);
//put original image
$AzureStorageBlob->putBlob("uploads", "name", $tmp_name);
//put watermarked image
$AzureStorageBlob->putBlobData("uploads", "name", ?); // ? needs to be data
You need to capture the buffer with ob_start, something like:
ob_start();
imagejpeg($tmp_img);
$i = ob_get_clean();
$i is your image blob
By using latest SDK for PHP you can do this by just passing the image stream:
$image_stream = fopen($tmp_name, 'r');
// Check README.md of how to create $blobRestProxy
$blobRestProxy->createBlockBlob('container_name', 'my_image', $image_stream);
Let me know if you have any further questions

Categories