I'm trying to show all images within a specified directory.
The following code lists all allowed file names:
function getDirectoryList()
{
// create an array to hold directory list
$results = array();
// create a handler for the directory
$handler = opendir($this->currentDIR);
// open directory and walk through the filenames
while ($file = readdir($handler)) {
// Make sure we get allowed images types
if ($this->allowedFileType($file,$this->allowedImageTypes) )
{
$results[] = $file;
}
}
// tidy up: close the handler
closedir($handler);
// done!
return $results;
}
(...)
$images = getDirectoryList();
foreach($images as $img) {
echo "<li>".$img."</li>";
}
How can I get file size and MIME type?
I read that mime_content_typeis deprecated and I should use finfo_file istead. But I've not been very successfull with this.
Do I have to use /usr/share/misc/magic to get file information? Can't I use GD library?
I've looked at many examples, but they are old and don't work that well.
Any help appreciated.
to get the size and mime type of image its simple,
use function : getimagesize
uses like :
list($width, $height, $type, $attr) = getimagesize("img/myimg.jpg");
Returns an array with 7 elements.
Index 0 and 1 contains respectively the width and the height of the image.
Index 2 is one of the IMAGETYPE_XXX constants indicating the type of the image.
using filesize give the size in bytes
To expand on Haim Evgi's post, use getimagesize() to retrieve the dimensions and the image type in an array. Then, use image_type_to_mime_type() on the image type code to retrieve the MIME:
list ($fileWidth, $fileHeight, $fileType) = getimagesize($filename);
$fileMimeType = image_type_to_mime_type($fileType);
Related
I want download an image from AWS S3 and process it with php. I am using "imagecreatefromjpeg" and "getimagesize" to process my image but it seem that
Storage::disk('s3')->get(imageUrlonS3);
retrieve the image in binary and is giving me errors. This is my code:
function createSlices($imagePath) {
//create transform driver object
$im = imagecreatefromjpeg($imagePath);
$sizeArray = getimagesize($imagePath);
//Set the Image dimensions
$imageWidth = $sizeArray[0];
$imageHeight = $sizeArray[1];
//See how many zoom levels are required for the width and height
$widthLog = ceil(log($imageWidth/256,2));
$heightLog = ceil(log($imageHeight/256,2));
//more code here to slice the image
.
.
.
.
}
// ex: https://s3-us-west-2.amazonaws.com/bucketname/image.jpg
$content = Storage::disk('s3')->get(imageUrlonS3);
createSlices($content);
What am I missing here ?
Thanks
I think you are right in your question what the problem is - the get method returns the source of the image of itself, not the location of the image. When you pass that to createSlices, you're passing the binary data, not its file path. Inside of createSlices you call imagecreatefromjpeg, which expects a file path, not the image itself.
If this indeed the case, you should be able to use createimagefromstring instead of createimagefromjpeg and getimagesizefromstring instead of getimagesize. The functions createimagefromstring and getimagesizefromstring each expects the binary string of the image, which I believe is what you have.
Here's the relevant documentation:
createimagefromstring - http://php.net/manual/en/function.imagecreatefromstring.php
getimagesizefromstring - http://php.net/manual/en/function.getimagesizefromstring.php
Resulting code might look something like this:
function createSlices($imageData) {
$im = imagecreatefromstring($imageData);
$sizeArray = getimagesizefromstring($imageData);
//Everything else can probably be the same
.
.
.
.
}
$contents = Storage::disk('s3')->get($imageUrlOnS3);
createSlices($contents);
Please note I haven't tested this, but I believe from what I can see in your question and what I read in the documentation that this might just do it.
I have an image that is sent from an iPad app to an SQL database. I can retrieve this image and display in a web page using the following php:
$img = base64_encode($row['photoData']);
echo "<img src=\"data:image/jpg;charset=utf8;base64, $img\"/>";
This displays fine. What I want to do now is put this image into a PDF document using FPDF however I am struggling to do this.
This:
$img = base64_encode($row['photoData']);
$pdf->Image($img);
give this error:
FPDF error: Image file has no extension and no type was specified:
So I tried this (although I realise I will then have to look at how to get the size of the image sorted):
$pdf->Image($img, 20, 20, 20, 20 'JPG');
which give me:
FPDF error: Missing or incorrect image file:
What is the correct way to do this?
Or would it be easier to temporarily save the image to the server and then place the saved image into the PDFdoc?
As mentioned in the comments above this is possible by using a stream ("data url") to hand over the image data to the fpdf library without writing physical files to disk:
<?php
// load the 'fpdf' extension
require('fpdf.php');
// just for demonstration purpose, the OP gets the content from a database instead
$h_img = fopen('img.jpg', "rb");
$img = fread($h_img, filesize('img.jpg'));
fclose($h_img);
// prepare a base64 encoded "data url"
$pic = 'data://text/plain;base64,' . base64_encode($img);
// extract dimensions from image
$info = getimagesize($pic);
// create a simple pdf document to prove this is very well possible:
$pdf = new FPDF();
$pdf->AddPage();
$pdf->SetFont('Arial','B',16);
$pdf->Cell(40,10,'Hello Image!');
$pdf->Image($pic, 10, 30, $info[0], $info[1], 'jpg');
$pdf->Output();
If this is a good advice is another question, this is merely meant to prove that this is possible...
According to the Docs FPDF::Image accepts a filename as the first argument, not a binary blob.
If you want to use FPDF specifically, save the image to a temporary file first, and then pass that to FPDF::Image.
To do that, something like this should work:
$tmpFile = tempnam(sys_get_temp_dir(), 'fpdfimg');
if (file_put_contents($tmpFile, $row['photoData'])) {
$fpdf->Image($tmpFile);
// save/display image
unlink($tmpFile);
}
Alternatively, if you want to just serve the image as a PDF (with no other content) you could use Imagick:
$im = new \Imagick();
$im->readImageBlob($row['photoData']);
$im->setImageFormat('pdf');
header('Content-Type: application/pdf');
echo $im;
Since FPDF cannot use base64 data to produce images on the PDF, I would recommend saving the file to the disk permanently as opposed to writing a temp file for every PDF operation.
This will save you a lot of I/O overhead.
Assuming your table has unique photo_id or photo_name to accompany photoData then you can use something like this to create your images and use them in FPDF.
I will also assume you have a last_update and photo_extension column.
<?php
$path = '/path/to/fpdf/images/';
$filename = $row['photo_id'].'.'.$row['photo_extension'];
$filepath = $path.$filename;
// If a physical file is not available then create it
// If the DB data is fresher than the file then make a new file
if(!is_file($filepath) || strtotime($row['last_update']) > filemtime($filepath))
{
$result = file_put_contents($filepath, $row['photoData']);
if($result === FALSE)
{
die(__FILE__.'<br>Error - Line #'.__LINE__.': Could not create '.$filepath);
}
}
$pdf->Image($filepath);
If you plan on updating the photoData which is stored in your DB then you will have to make sure to also have a timestamp column and compare that timestamp against the filemtime($filepath) of the image on your disk.
Another solution for this ;)
Make a new php by copying and pasting this (piece of fpdf's code edited):
require('fpdf.php');
class DATAIMAGE extends FPDF
{
protected function _parsedata($file)
{
// Extract info from a JPEG file
$a = getimagesizefromstring($file);
if(!$a)
$this->Error('Missing or incorrect image file: '.$file);
if($a[2]!=2)
$this->Error('Not a JPEG file: '.$file);
if(!isset($a['channels']) || $a['channels']==3)
$colspace = 'DeviceRGB';
elseif($a['channels']==4)
$colspace = 'DeviceCMYK';
else
$colspace = 'DeviceGray';
$bpc = isset($a['bits']) ? $a['bits'] : 8;
return array('w'=>$a[0], 'h'=>$a[1], 'cs'=>$colspace, 'bpc'=>$bpc, 'f'=>'DCTDecode', 'data'=>$file);
}
}
Then call this php instead of fpdf.php in your main php.
You'll now be able to display an image simply by adding 'data' to the end of the function:
$pdf->Image($mysqlrow["blob"],0,0,40,0,'data');
in my php page I have <input type='file' name='aimage[]' id='aimage' />
and a snippet code to get this file as :
foreach($_FILES["aimage"]["tmp_name"] as $file)
{
/*** get the image info. ***/
if(is_uploaded_file($file) && getimagesize($file) != false){
$size = getimagesize($file);
/*** assign our variables ***/
$type = $size['mime'];
$imgfp = fopen($file, 'rb');
$size = $size[3];
// $name = $file['name'];
$maxsize = 99999999;
/*** check the file is less than the maximum file size ***/
//if($_FILES['aimage']['size'] < $maxsize )
// {
/*** connect to db ***/
$formvars['file'] = fread($imgfp, getimagesize($file));
Although using foreach, I got error as Warning: fread() expects parameter 2 to be long, array given in. what's cause of this error? How can I check only images uploaded to site and other files detected by code?
The error is caused by the second parameter of fread() : getimagesize($file)) which returns an array and not a long. getimagesize returns an array(width, height)
Maybe you want to use filesize($file) instead
From the getimagesize documentation:
Returns an array with up to 7 elements. Not all image types will
include the channels and bits elements.
Index 0 and 1 contains respectively the width and the height of the
image.
Note: Some formats may contain no image or may contain multiple
images. In these cases, getimagesize() might not be able to properly
determine the image size. getimagesize() will return zero for width
and height in these cases. Index 2 is one of the IMAGETYPE_XXX
constants indicating the type of the image.
Index 3 is a text string with the correct height="yyy" width="xxx"
string that can be used directly in an IMG tag.
mime is the correspondant MIME type of the image. This information can
be used to deliver images with the correct HTTP Content-type header:
Example #1 getimagesize() and MIME types
I've seen this somewhere, but can't seem to remember. How can I use getimagesize() to return the file type?
$url = (POST_IMAGESELECTOR);
$path_parts = pathinfo($url);
if ($path_parts !='') {
$extension = $path_parts['extension'];
} else {
$extension = getimagesize($url);
}
Given the documentation, getimagesize return an array of 7 values.
The one you can use are:
Index 2 is one of the IMAGETYPE_XXX constants indicating the type of the image.
And / Or:
mime is the correspondant MIME type of the image. This information can be used to deliver images with the correct HTTP Content-type header
From the manual:
getimagesize Returns an array with 7 elements.
Index 2 is one of the IMAGETYPE_XXX constants indicating the type of
the image.
Take a look at the manual for getimagesize(). Its return value is an array with the third element indicating the image's type.
Just read the documentation:
Returns an array with 7 elements.
...
Index 2 is one of the IMAGETYPE_XXX constants indicating the type of the image.
...
Try this:
$image = getimagesize('/path/to/image.gif') ;
$imagetype = $image['mime'];
echo $imagetype . "<br />";
print_r($image);
I'm trying to embed a IPTC data onto a JPEG image using iptcembed() but am having a bit of trouble.
I have verified it is in the end product:
// Embed the IPTC data
$content = iptcembed($data, $path);
// Verify IPTC data is in the end image
$iptc = iptcparse($content);
var_dump($iptc);
Which returns the tags entered.
However when I save and reload the image the tags are non existant:
// Save the edited image
$im = imagecreatefromstring($content);
imagejpeg($im, 'phplogo-edited.jpg');
imagedestroy($im);
// Get data from the saved image
$image = getimagesize('./phplogo-edited.jpg');
// If APP13/IPTC data exists output it
if(isset($image['APP13']))
{
$iptc = iptcparse($image['APP13']);
print_r($iptc);
}
else
{
// Otherwise tell us what the image *does* contain
// SO: This is what's happening
print_r($image);
}
So why aren't the tags in the saved image?
The PHP source is avaliable here, and the respective outputs are:
Image output
Data output
getimagesize has an optional second parameter Imageinfo which contains the info you need.
From the manual:
This optional parameter allows you to extract some extended information from the image file. Currently, this will return the different JPG APP markers as an associative array. Some programs use these APP markers to embed text information in images. A very common one is to embed ยป IPTC information in the APP13 marker. You can use the iptcparse() function to parse the binary APP13 marker into something readable.
so you could use it like this:
<?php
$size = getimagesize('./phplogo-edited.jpg', $info);
if(isset($info['APP13']))
{
$iptc = iptcparse($info['APP13']);
var_dump($iptc);
}
?>
Hope this helps...