getNameIndex($i)I am currently using the zip archive function to extract some images, I am looking for a method which gives the filepath of each individual image so I can use getimagesize to get the width and height, below is the method am using to loop through the files.
$chapterZip = new ZipArchive();
if ($chapterZip->open($_FILES['chapterUpload']['tmp_name']))
{
for($i = 0; $i < $chapterZip->numFiles; $i++) {
list($width, $height) = getimagesize(getNameIndex($i));
$imageLocation= "INSERT INTO imageLocation (imageLocation,imageWidth,imageHeight,chapterID) VALUES ('"."Manga/".$_POST['mangaName']."/".$_POST['chapterName']."/".$chapterZip->getNameIndex($i)."',".$width.",".$height.",".$chapterID.")";
getQuery($imageLocation,$l);
}
if($chapterZip->extractTo("Manga/".$_POST['mangaName']."/".$_POST['chapterName']))
{
$errmsg0.="You have successfully uploaded a manga chapter";
$chapterZip->close();
}
}
any help with this would be greatly appreciated !
With PHP's Zip extension's stream wrapper, do not have to manually extract all files:
$size = getimagesize('zip:///path/to/file.zip#path/to/image.jpg');
Related
I want to find out uncompress size of zip file which is stored in aws s3 bucket. How can we find out in php?
In local server i find out using exec('unzip -l filename.zip') in php.
You are uncompressing a zip to find out the size?.. That's a bit overkill..
Here's some code to help you along, loading the zip, iterating through each entry to get the uncompressed size and return it.
$zip = new ZipArchive();
if ($zip->open('myzip.zip')) {
var_dump(getTotalUncompressedSize($zip));
$zip->close();
}
function getTotalUncompressedSize(ZipArchive $zip)
{
$totalSize = 0;
for ($i = 0; $i < $zip->numFiles; $i++) {
$fileStats = $zip->statIndex($i);
$totalSize += $fileStats['size'];
}
return $totalSize;
}
Here is a code what I am using to create image reducer but not getting solution
this code taking an image from my chosen path from the computer and uploading as is it, like same image size and same quality, but I want to reduce image size at the same ratio
<?php
include '../database/db.php';
include "../includes/session.php";
if(isset($_GET["d"]))
{
$output_dir=($_GET['d']);
$directory=($_GET['fp']);
$pid=($_GET['pid']);
$lid=($_GET['lid']);
$subjecta=($_GET['subject']);
}
if(isset($_FILES["myfile"]))
{
$ret = array();
$error =$_FILES["myfile"]["error"];
//You need to handle both cases
//If Any browser does not support serializing of multiple files using FormData()
if(!is_array($_FILES["myfile"]["name"])) //single file
{
$fileName = $_FILES["myfile"]["name"];
move_uploaded_file($_FILES["myfile"]["tmp_name"],$output_dir.$fileName);
$ret[]= $fileName;
$path = "$directory$fileName";
$query = "INSERT INTO table_name (lid,pid,nots,filename)VALUES('$lid','$pid','$path','$fileName')";
$suc= mysql_query($query);
}else{
$fileCount = count($_FILES["myfile"]["name"]);
for($i=0; $i < $fileCount; $i++)
{
$fileName = $_FILES["myfile"]["name"][$i];
move_uploaded_file($_FILES["myfile"]["tmp_name"][$i],$output_dir.$fileName);
$ret[]= $fileName;
$path = "$directory$fileName";
$query = "INSERT INTO table_name (lid,pid,nots,filename)VALUES('$lid','$pid','$path','$fileName')";
$suc= mysql_query($query);
}
}
echo json_encode($ret);
}
?>
we made this code for a single file and multiple files
you should process the uploaded image on your server using something like ImageMagick, you can read more here http://php.net/manual/en/book.imagick.php
you can find some examples of image manipulation here:
http://php.net/manual/en/imagick.examples-1.php
I have the following php function below that's converting a local PDF file into images. In short, I want each PDF page to be converted to a separate image.
The function converts the PDF to an image - but only the last page. I want every page of the PDF to be converted to a image and numbered. Not just the last page of the PDF.
Currently, this function converts the last page of example.pdf to example-0.jpg. Issue I'm sure lies within the for method. What am I missing?
$file_name = 'example.pdf'; // using just for this example, I pull $file_name from another function
function _create_preview_images($file_name) {
// Strip document extension
$file_name = basename($file_name, '.pdf');
// Convert this document
// Each page to single image
$img = new imagick('uploads/'.$file_name.'.pdf');
// Set background color and flatten
// Prevents black background on objects with transparency
$img->setImageBackgroundColor('white');
$img = $img->flattenImages();
// Set image resolution
// Determine num of pages
$img->setResolution(300,300);
$num_pages = $img->getNumberImages();
// Compress Image Quality
$img->setImageCompressionQuality(100);
// Convert PDF pages to images
for($i = 0;$i < $num_pages; $i++) {
// Set iterator postion
$img->setIteratorIndex($i);
// Set image format
$img->setImageFormat('jpeg');
// Write Images to temp 'upload' folder
$img->writeImage('uploads/'.$file_name.'-'.$i.'.jpg');
}
$img->destroy();
}
Seems like most of my code was correct. The issue was, I was using $img->flattenImages(); incorrectly. This merges a sequence of images into one image. Much like how Photoshop flattens all visible layers into an image when exporting a jpg.
I removed the above line and the individual files were written as expected.
/* convert pdf file to list image files */
if($_FILES['file_any']['type']=='application/pdf'){
$file_name = str_replace(substr($url,0,strpos($url,$_FILES['file_any']['name'])),'',$url);
$basename = substr($file_name,0,strpos($file_name,'.'));
$abcd = wp_upload_dir();
$delpath = $abcd['path'];
$savepath = $abcd['url'];
$dirpath = substr($savepath,(strpos($savepath,'/upl')+1));
$file_name = basename($file_name, '.pdf');
$img = new imagick($delpath.'/'.$file_name.'.pdf');
$img->setImageBackgroundColor('white');
$img->setResolution(300,300);
$num_pages = $img->getNumberImages();
$img->setImageCompressionQuality(100);
$imageurl = NULL;
$imagedelurl = NULL;
for($i = 0;$i < $num_pages; $i++) {
$imageurl[]=$savepath.'/'.$basename.'-'.$i.'.jpg';
$imagedelurl[] = $delpath.'/'.$basename.'-'.$i.'.jpg';
// Set iterator postion
$img->setIteratorIndex($i);
// Set image format
$img->setImageFormat('jpeg');
// Write Images to temp 'upload' folder
$img->writeImage($delpath.'/'.$file_name.'-'.$i.'.jpg');
}
$img->destroy();
}
There is a much easier way without the loop, just use $img->writeImages($filename,false); and it will make a file per PDF-page. As you said, if you flatten the image first, it only saves 1 page.
first install
imagemagick
in your system or server
and then create
pdfimage
folder and put pdf file in this folder then run the code and upload it file
<?php
$file_name = $_FILES['pdfupload']['name']; // using just for this example, I pull $file_name from another function
//echo strpos($file_name,'.pdf');
$basename = substr($file_name,0,strpos($file_name,'.'));
//echo $_FILES['pdfupload']['type'];
//if (isset($_POST['submit'])){
if($_FILES['pdfupload']['type']=='application/pdf'){
// Strip document extension
$file_name = basename($file_name, '.pdf');
// Convert this document
// Each page to single image
$img = new imagick('pdfimage/'.$file_name.'.pdf');
// Set background color and flatten
// Prevents black background on objects with transparency
$img->setImageBackgroundColor('white');
//$img = $img->flattenImages();
// Set image resolution
// Determine num of pages
$img->setResolution(300,300);
$num_pages = $img->getNumberImages();
// Compress Image Quality
$img->setImageCompressionQuality(100);
$images = NULL;
// Convert PDF pages to images
for($i = 0;$i < $num_pages; $i++) {
$images[]=$basename.'-'.$i.'.jpg';
// Set iterator postion
$img->setIteratorIndex($i);
// Set image format
$img->setImageFormat('jpeg');
// Write Images to temp 'upload' folder
$img->writeImage('pdfimage/'.$file_name.'-'.$i.'.jpg');
}
echo "<pre>";
print_r($images);
$img->destroy();
}
//}
?>
Is it possible to get image information without loading the actual image with PHP? In my case I want the Height and Width.
I have this code to fetch images from a directory. I echo out the image's url and fetch it with JS.
<?php
$directory = "./images/photos/";
$sub_dirs = glob($directory . "*");
$i = 0;
$len = count($sub_dirs);
foreach($sub_dirs as $sub_dir)
{
$images = glob($sub_dir . '/*.jpg');
$j = 0;
$len_b = count($images);
foreach ($images as $image)
{
if ($j == $len_b - 1) {
echo $image;
} else {
echo $image . "|";
}
$j++;
}
if ($i == $len - 1) {
} else {
echo "|";
}
$i++;
}
?>
getImageSize() is the proper way to get this information in PHP
It does a minimal amount of work based on the type of image. For example, a GIF image's height/width are stored in a header. Very easy to access and read. So this is how the function most likely gets that information from the file. For a JPEG, it has to do a little more work, using the SOFn markers.
The fastest way to access this information would be to maintain a database of file dimensions every time a new one is uploaded.
Given your current situation. I recommend writing a PHP script that takes all of your current image files, gets the size with this function, and then inserts the info into a database for future use.
It depends what you mean by "without loading it".
The built-in getimagesize() does this.
list($w, $h) = getimagesize($filename);
You can programmatically get the image and check the dimensions using Javascript...
var img = new Image();
img.onload = function() {
alert(this.width + 'x' + this.height);
}
img.src = 'http://www.google.com/intl/en_ALL/images/logo.gif';
This can be useful if the image is not a part of the markup ;)
You can store the width'n'height information in a text file, and load it later on.
list($width, $height, $type, $attr) = getimagesize($_FILES["Artwork"]['tmp_name']);
Use this.
I am trying to build a script that retrieves a list of thumbnail images from an external link, much like Facebook does when you share a link and can choose the thumbnail image that is associated with that post.
My script currently works like this:
file_get_contents on the URL
preg_match_all to match any <img src="" in the contents
Works out the full URL to each image and stores it in an array
If there are < 10 images it loops through and uses getimagesize to find width and height
If there are > 10 images it loops through and uses fread and imagecreatefromstring to find width and height (for speed)
Once all width and heights are worked out it loops through and only adds the images to a new array that have a minimum width and height (so only larger images are shown, smaller images are less likely to be descriptive of the URL)
Each image has its new dimensions worked out (scaled down proportionally) and are returned...
<img src="'.$image[0].'" width="'.$image[1].'" height="'.$image[2].'"><br><br>
At the moment this works fine, but there are a number of problems I can potentially have:
SPEED! If the URL has many images on the page it will take considerably longer to process
MEMORY! Using getimagesize or fread & imagecreatefromstring will store the whole image in memory, any large images on the page could eat up the server's memory and kill my script (and server)
One solution I have found is being able to retrieve the image width and height from the header of the image without having to download the whole image, though I have only found some code to do this for JPG's (it would need to support GIF & PNG).
Can anyone make any suggestions to help me with either problem mentioned above, or perhaps you can suggest another way of doing this I am open to ideas... Thanks!
** Edit: Code below:
// Example images array
$images = array('http://blah.com/1.jpg', 'http://blah.com/2.jpg');
// Find the image sizes
$image_sizes = $this->image_sizes($images);
// Find the images that meet the minimum size
for ($i = 0; $i < count($image_sizes); $i++) {
if ($image_sizes[$i][0] >= $min || $image_sizes[$i][1] >= $min) {
// Scale down the original image size
$dimensions = $this->resize_dimensions($scale_width, $scale_height, $image_sizes[$i][0], $image_sizes[$i][1]);
$img[] = array($images[$i], $dimensions['width'], $dimensions['height']);
}
}
// Output the images
foreach ($img as $image) echo '<img src="'.$image[0].'" width="'.$image[1].'" height="'.$image[2].'"><br><br>';
/**
* Retrieves the image sizes
* Uses the getimagesize() function or the filesystem for speed increases
*/
public function image_sizes($images) {
$out = array();
if (count($images) < 10) {
foreach ($images as $image) {
list($width, $height) = #getimagesize($image);
if (is_numeric($width) && is_numeric($height)) {
$out[] = array($width, $height);
}
else {
$out[] = array(0, 0);
}
}
}
else {
foreach ($images as $image) {
$handle = #fopen($image, "rb");
$contents = "";
if ($handle) {
while(true) {
$data = fread($handle, 8192);
if (strlen($data) == 0) break;
$contents .= $data;
}
fclose($handle);
$im = #imagecreatefromstring($contents);
if ($im) {
$out[] = array(imagesx($im), imagesy($im));
}
else {
$out[] = array(0, 0);
}
#imagedestroy($im);
}
else {
$out[] = array(0, 0);
}
}
}
return $out;
}
/**
* Calculates restricted dimensions with a maximum of $goal_width by $goal_height
*/
public function resize_dimensions($goal_width, $goal_height, $width, $height) {
$return = array('width' => $width, 'height' => $height);
// If the ratio > goal ratio and the width > goal width resize down to goal width
if ($width/$height > $goal_width/$goal_height && $width > $goal_width) {
$return['width'] = floor($goal_width);
$return['height'] = floor($goal_width/$width * $height);
}
// Otherwise, if the height > goal, resize down to goal height
else if ($height > $goal_height) {
$return['width'] = floor($goal_height/$height * $width);
$return['height'] = floor($goal_height);
}
return $return;
}
getimagesize reads only header, but imagecreatefromstring reads whole image. Image read by GD, ImageMagick or GraphicsMagic is stored as bitmap so it consumes widthheight(3 or 4) bytes, and there's nothing you can do about it.
The best possible solution for your problem is to make curl multi-request (see http://ru.php.net/manual/en/function.curl-multi-select.php ), and then one by one process recieved images with GD or any other library. And to make memory consumption a bit lower, you can store image files on disk, not in memory.
The only idea that comes to mind for your current approach (which is impressive) is to check the HTML for existing width and height attributes and skip the file read process altogether if they exist.