PHP imagick get all images from tiff - php

I am trying to load a tiff file and count the number or images and then then dispaly each image as a PNG thumbnail.
The count part is ok it counts 6 which is the correct number of pages in that tif, the code then lists 6 of the same image which is the the first page of the tiff. Cant workout if there is a problem with my loop or I am simply not using the imagick functions correctly.
Can anyone help
<?php
$image2 = new Imagick('http://mysite.org.uk/tiftest/2.tif');
/* Create the object */
$image = new Imagick('http://mysite.org.uk/tiftest/2.tif');
$count = $image->getNumberImages();
echo "<h3 style=\"font: bold 12pt Arial\">Total Number of Images Extracted ".
"from the TIF : ".$image->getNumberImages()."</h3>";
for ($x = 1;$x <= $image->getNumberImages();$x++) {
$image->pingImage( $image2 );
$image->readImageFile( $image2 );
$image->setImageFormat( 'png' );
$image->thumbnailImage(100, 0);
echo "<img id='" . $x . "' src='data:image/png;base64,".base64_encode($image)."' />"; } ?>

You will have to move to the previous image using $image->previousImage()
Iterate over the number of images backwards and move to the previous image to get all of them, might also be able to use while ($image->hasPreviousImage()) {} construct
Oh, and dont use readImageFile, you already have the image in-memory.

I sussed it !!
Here is the code to get all the sepearte pages out of the tif and display them as PNG's :
<?php
/* Create the object */
$image = new Imagick('http://mysite.o.uk/tiftest/1.tif');
$count = $image->getNumberImages();
echo "<h3 style=\"font: bold 12pt Arial\">Total Number of Images Extracted ".
"from the TIF : ".$image->getNumberImages()."</h3>";
$x =0;
foreach ( $image as $image ) {
$x++;
$image->setImageFormat( 'png' );
$image->thumbnailImage(150, 120);
echo "<img id='" . $x . "' src='data:image/png;base64,".base64_encode($image)."' />";
}
?>
However now I need to know how to display them as true PNG's without using base63 encoding, any ideas ???

Related

PHP trying to understand how to generate thumbnail from directory

This is currently what I have. When I include it in my index.php and then call the function on pageload, I get a blank page. So something is wrong here, but I don't know what. I feel like I'm really close though. I just want to create thumbnails of images in a directory, and then show them in HTML as a list of images you can click that trigger lightboxes.
I'm still really shaky in PHP. I'm trying to wrap my head around editing images in a directory.
<?php
function buildThumbGallery(){
$h = opendir('/Recent_Additions/'); //Open the current directory
while (false !== ($curDir = readdir($h))) {
if (!file_exists('/Recent_Additions/thumbs/')) {
$thumbDir = mkdir('/Recent_Additions/thumbs/', 0777, true);
}else{
$thumbDir = '/Recent_Additions/thumbs/';
}
$width = 200;
$height = 200;
foreach ($curDir as $image) {
$filePath = $curDir."/".$image;
$genThumbImg = $image->scaleImage($width, $height, true);
$newThumb = imagejpeg($genThumbImg, $thumbDir, 100);
echo '<li> <a class="fancybox" data-fancybox-group="'.basename($curDir).'" href="'.$filePath.'" title="'.basename($curDir)." ".strpbrk(basename($filePath, ".jpg"), '-').'"><img src="'.$newThumb.'"/>'.basename($curDir).'</a>';
imagedestroy($newThumb);
}echo '</li>';
}
?>
You are doing several things wrong:
You're not closing the while loop.
Readdir already loops through a directory, your foreach is not doing anything.
You are missing quotes in your echo.
You are calling the method scaleImage on a string, I think you meant to call the function imagescale.
You're missing and misunderstanding a lot of stuff, take a look at how to create a thumbnail here: https://stackoverflow.com/a/11376379/4193448
Also see if you can enable PHP errors, getting a blank page while your code is full of errors is not really helping is it?
::EDIT::
With help from #swordbeta, I got my script working properly. Here is the code for future reference:
<?php
function buildThumbGallery(){
$curDir = "./Recent_Additions/";
$thumbsPath = $curDir."thumbs/";
if (!file_exists($thumbsPath)) {
mkdir($thumbsPath, 0777, true);
}
foreach(scandir($curDir) as $image){
if ($image === '.' || $image === '..' || $image === 'thumbs') continue;
if(!file_exists($thumbsPath.basename($image, ".jpg")."_thumb.jpg")){
// Max vert or horiz resolution
$maxsize=200;
// create new Imagick object
$thumb = new Imagick($curDir.$image); //'input_image_filename_and_location'
$thumb->setImageFormat('jpg');
// Resizes to whichever is larger, width or height
if($thumb->getImageHeight() <= $thumb->getImageWidth()){
// Resize image using the lanczos resampling algorithm based on width
$thumb->resizeImage($maxsize,0,Imagick::FILTER_LANCZOS,1);
}else{
// Resize image using the lanczos resampling algorithm based on height
$thumb->resizeImage(0,$maxsize,Imagick::FILTER_LANCZOS,1);
}
// Set to use jpeg compression
$thumb->setImageCompression(Imagick::COMPRESSION_JPEG);
$thumb->setImageCompressionQuality(100);
// Strip out unneeded meta data
$thumb->stripImage();
// Writes resultant image to output directory
$thumb->writeImage($thumbsPath.basename($image, ".jpg")."_thumb.jpg"); //'output_image_filename_and_location'
// Destroys Imagick object, freeing allocated resources in the process
$thumb->destroy();
}else{
echo '<a class="fancybox" data-fancybox-group="'.basename($curDir).'" href="'.$curDir.basename($image, "_thumb.jpg").'" title="Recent Addition - '.basename($image, ".jpg").'"><img src="'.$thumbsPath.basename($image, ".jpg")."_thumb.jpg".'"/></a>';
echo '<figcaption>'.basename($image, ".jpg").'</figcaption>' . "<br/>";
}
}
}
?>
::Original Post::
Ok, after going back and doing some more research and suggestions from #swordbeta, i've got something that works. My only issue now is I can't get the images to show in my index.php. I'll style the output in CSS later, right now I just want to see the thumbnails, and then later build them into lightbox href links:
<?php
function buildThumbGallery(){
$curDir = "./Recent_Additions/";
$thumbsPath = $curDir."/thumbs/";
if (!file_exists($thumbsPath)) {
mkdir($thumbsPath, 0777, true);
}
$width = 200;
foreach(scandir($curDir) as $image){
if ($image === '.' || $image === '..') continue;
if(file_exists($thumbsPath.basename($image)."_thumb.jpg")){
continue;
}else{
// Max vert or horiz resolution
$maxsize=200;
// create new Imagick object
$thumb = new Imagick($curDir.$image); //'input_image_filename_and_location'
// Resizes to whichever is larger, width or height
if($thumb->getImageHeight() <= $thumb->getImageWidth()){
// Resize image using the lanczos resampling algorithm based on width
$thumb->resizeImage($maxsize,0,Imagick::FILTER_LANCZOS,1);
}else{
// Resize image using the lanczos resampling algorithm based on height
$thumb->resizeImage(0,$maxsize,Imagick::FILTER_LANCZOS,1);
}
// Set to use jpeg compression
$thumb->setImageCompression(Imagick::COMPRESSION_JPEG);
$thumb->setImageCompressionQuality(100);
// Strip out unneeded meta data
$thumb->stripImage();
// Writes resultant image to output directory
$thumb->writeImage($thumbsPath.basename($image)."_thumb.jpg"); //'output_image_filename_and_location'
// Destroys Imagick object, freeing allocated resources in the process
$thumb->destroy();
}
} echo '<img src="'.$thumbsPath.basename($image)."_thumb.jpg".'" />' . "<br/>";
}
?>
At the moment, the output from the echo isn't showing anything, but the rest of the script is working properly (i.e. generating thumbnail images in a thumbs directory).
I'm guessing i'm not formatting my echo properly. This script is called in my index.php as <?php buildThumbGallery(); ?> inside a styled <div> tag.

Can I add a resize function to this script?

I am not really good in PHP but the images that will show on the webpage of mine will be the main resolution. I would like to downscale it but I have no clue how.
<?php
$images = glob('*.{gif,png,jpg,jpeg}', GLOB_BRACE); // Formats to look for
$num_of_files = 2; // Number of images to display
foreach ($images as $image) {
$num_of_files--;
if ($num_of_files > -1) // This made me laugh when I wrote it
{
echo "<b>" . $image . "</b><br>"
. "Created on " . date('D, d M y H:i:s', filemtime($image)) . "<br>"
. "<img src='" . $image . "'><br><br>";
} // Display images
else {
break;
}
}
?>
It seems like you just want to resize the image shown in the browser, right? In that case some simple styling would do the trick:
. "<img src='" . $image . "' style='width: 200px'><br><br>";
Change the 200px to whatever width you want, the height will scale proportionally.
You should also have a look on how to use CSS classes.
If you rather want to scale the actual image file (i.e. if it resides on your server), check out ImageMagick.

Resize copied image on upload as thumbnail

I am working on an uploader and slowly getting it working, I am uploading 3 images at once, and setting arrays for each one as keys, with an increment of ++1. I am wanting to resize the image before it gets copied to the thumbnail folder.
I have this code.
Everything works with it.
As you see, I started on getting the file info, but after that I am totally stuck on what to do after to resize the image proportionally with a maximum width of xpx and height to match it without looking distorted.
Any help would be really appreciated. Thank You.
EDIT --- I started working on it myself and wondering if this is the right approach to what i am doing.
<?php
if (isset($_POST['addpart'])) {
$image = $_FILES['images']['tmp_name'];
$name = $_POST['username'];
$i = 0;
foreach ($image as $key) {
$fileData = pathinfo(basename($_FILES["images"]["name"][$i]));
$fileName[] = $name . '_' . uniqid() . '.' . $fileData['extension'];
move_uploaded_file($key, "image/" . end($fileName));
copy("image/" . end($fileName), "image_thumbnail/" . end($fileName));
// START -- THE RESIZER THAT IS BEING WORKED ON
$source = "image_thumb/" . end($fileName);
$dest = "image_thumb/" . end($fileName);
$quality = 100;
$scale = 1 / 2;
$imsize = getimagesize($source);
$x = $scale * $imsize[0];
$y = $scale * $imsize[1];
$im = imagecreatefromjpeg($source);
$newim = imagecreatetruecolor($x, $y);
imagecopyresampled($newim, $im, 0, 0, 0, 0, $x, $y, $imsize[0], $imsize[1]);
imagejpeg($newim, $dest, $quality);
// END -- THE RESIZER THAT IS BEING WORKED ON
$i++;
}
echo 'Uploaded<br>';
echo 'Main Image - ' . $fileName[0] . '<br>';
echo 'Extra Image 1 - ' . $fileName[1] . '<br>';
echo 'Extra Image 2 - ' . $fileName[2] . '<br>';
echo '<hr>';
}
?>
thanks
Use GD library.
Create input image object using imagecreatefromstring() for example: imagecreatefromstring(file_get_contents($_FILES['images']['tmp_name'][$i]))
It's the simplest way.
Another option is to detect file type and use functions like imagecreatefromjpeg (), imagecreatefrompng(), etc.
Create output empty image using imagecreate()
Use imagecopyresampled() or imagecopyresized() to resize image and copy+paste it from input image to output image
Save output image using function like imagejpeg()
Clean memory using imagedestroy()
The built-in image manipulation commands of PHP makes your code difficult to understand and to maintain. I suggest you to use a library which wraps it into a more productive way.
If you use Intervention/image, for example, your code will look like this:
<?php
// target file to manipulate
$filename = $_FILES['images']['tmp_name'];
// create image instance
$img = Image::make($filename);
// resize to width, height
$img->resize(320, 240);
// save it!
$img->save('thumbs/'. uniqid() . '.' . pathinfo($filename, PATHINFO_EXTENSION));
Read the full documentation here: http://image.intervention.io/use/uploads

resize width and compress images on upload php mysql

I have a client that sends me text messages from his iPhone with images for me to upload into his gallery. I'm trying to create a admin system so I can simply take the images from the texts, go to the admin page on my iPhone and upload the images straight to the gallery.
This would save me tons of time in my day to day work schedule.
Using the provided code. How can I add the following functions:
I would like to compress the file size down to a smaller size if possible, similar to the save to web jpg function in Photoshop. (Most images I get are around 1-3 MB. I would like to get them down to around 150-500kb max)
I would like to automatically change the width to 760px, but keep the aspect ratio so the images are not squished. He sends me landscape and portrait images.
Beings they are iPhone images. They have an extension .JPG (all caps) I would like this to change to .jpg (all lower case.) This is not a deal breaker I would just like to know how to do this for future use.
Either one of these functions would be very helpful, but all 3 would be ideal for my situation.
Here is the code I'm working with?
THIS IS THE FINAL CORRECT CODE FOR UPLOADING AND RESIZING IMAGES PROVIDED By #tman
Make sure you have imagick installed in your php.ini file. Check with your hosting provider to install it.
<?php
include($_SERVER['DOCUMENT_ROOT'] . "/connections/dbconnect.php");
for($i=0;$i<count($_FILES["image"]["name"]);$i++){
if($_FILES["image"]["name"][$i] != ''){ // don't insert if file name empty
$dataType = mysql_real_escape_string($_POST["dataType"][$i]);
$title = mysql_real_escape_string($_POST["title"][$i]);
$fileData = pathinfo($_FILES["image"]["name"][$i]);
$fileName = uniqid() . '.' . $fileData['extension'];
$target_path = $_SERVER['DOCUMENT_ROOT'] . "/images/gallery/" . $fileName;
if (move_uploaded_file($_FILES["image"]["tmp_name"][$i], $target_path)){ // The file is in the images/gallery folder.
// Insert record into database by executing the following query:
$sql="INSERT INTO images (data_type, title, file_name) "."VALUES('$dataType','$title','$fileName')";
$retval = mysql_query($sql);
///NEW
$size = getimagesize($target_path);
$width=$size[0];
$height=$size[1];
$newwidth = 760;
$newheight = $height*($newwidth/$width);
$pic = new Imagick($target_path);//specify name
$pic->resizeImage($newwidth,$newhight,Imagick::FILTER_LANCZOS,1);
unlink($target_path);
$pic->writeImage($target_path);
$pic->destroy();
///NEW
echo "The image {$_FILES['image']['name'][$i]} was successfully uploaded and added to the gallery<br />
<a href='index.php'>Add another image</a><br />";
}
else
{
echo "There was an error uploading the file {$_FILES['image']['name'][$i]}, please try again!<br />";
}
}
} // close your foreach
?>
uploader.php Original code. Allows me to upload 4 images at once. WORKS!!!
<?php
include($_SERVER['DOCUMENT_ROOT'] . "/connections/dbconnect.php");
for($i=0;$i<count($_FILES["image"]["name"]);$i++){
if($_FILES["image"]["name"][$i] != ''){ // don't insert if file name empty
$dataType = mysql_real_escape_string($_POST["dataType"][$i]);
$title = mysql_real_escape_string($_POST["title"][$i]);
$fileData = pathinfo($_FILES["image"]["name"][$i]);
$fileName = uniqid() . '.' . $fileData['extension'];
$target_path = $_SERVER['DOCUMENT_ROOT'] . "/images/gallery/" . $fileName;
if (move_uploaded_file($_FILES["image"]["tmp_name"][$i], $target_path)){ // The file is in the images/gallery folder.
// Insert record into database by executing the following query:
$sql="INSERT INTO images (data_type, title, file_name) "."VALUES('$dataType','$title','$fileName')";
$retval = mysql_query($sql);
echo "The image {$_FILES['image']['name'][$i]} was successfully uploaded and added to the gallery<br />
<a href='index.php'>Add another image</a><br />";
}
else
{
echo "There was an error uploading the file {$_FILES['image']['name'][$i]}, please try again!<br />";
}
}
} // close your foreach
?>
FYI, This will allow you to give a unique names to your images, resize the width, but keep the correct aspect ratio and upload multiple file at the same time.
Awesome Stuff!
Like this:
$filelocation='http://help.com/images/help.jpg';
$newfilelocation='http://help.com/images/help1.jpg';
$size = getimagesize($filelocation);
$width=$size[0];//might need to be ['1'] im tired .. :)
$height=$size[1];
// Plz note im not sure of units pixles? & i could have the width and height confused
//just had some knee surgery so im kinda loopy :)
$newwidth = 760;
$newheight = $height*($newwidth/$width)
$pic = new Imagick( $filelocation);//specify name
$pic->resizeImage($newwidth,$newhight,Imagick::FILTER_LANCZOS,1);
//again might have width and heing confused
$pic->writeImage($newfilelocation);//output name
$pic->destroy();
unlink($filelocation);//deletes image
Here is something kind of similar, lets check the size and compress if the image seems that it is too big. I didn't resize it which just requires that you get the dimensions and resize based on desire.
All this is doing is if the file is greater than 250KB compress it to 85% ..
$bytes = filesize($inventory_path.DIRECTORY_SEPARATOR.$this->uploadName);
//$maxSizeInBytes = 26400; //is 250KB? No? compress it.
if ($bytes > 26400) {
$img = new Imagick($inventory_path.DIRECTORY_SEPARATOR.$this->uploadName);
$img->setImageCompression(imagick::COMPRESSION_JPEG);
$img->stripImage();
$img->setImageCompressionQuality(85);
$img->writeImage($inventory_path.DIRECTORY_SEPARATOR.$this->uploadName);
}
OR:
// resize with imagejpeg ($image, $destination, $quality); if greater than byte size KB
// Assume only supported file formats on website are jpg,jpeg,png, and gif. (any others will not be compressed)
$bytes = filesize($inventory_path.DIRECTORY_SEPARATOR.$this->uploadName);
//$maxSizeInBytes = 26400; //is gtr than 250KB? No? compress it.
if ($bytes > 26400) {
$info = getimagesize($inventory_path.DIRECTORY_SEPARATOR.$this->uploadName);
$quality = 85; //(1-100), 85-92 produces 75% quality
if ($info['mime'] == 'image/jpeg') {
$image = imagecreatefromjpeg($inventory_path.DIRECTORY_SEPARATOR.$this->uploadName);
imagejpeg($image,$inventory_path.DIRECTORY_SEPARATOR.$this->uploadName,$quality);
} elseif ($info['mime'] == 'image/gif') {
$image = imagecreatefromgif($inventory_path.DIRECTORY_SEPARATOR.$this->uploadName);
imagejpeg($image,$inventory_path.DIRECTORY_SEPARATOR.$this->uploadName,$quality);
} elseif ($info['mime'] == 'image/png') {
$image = imagecreatefrompng($inventory_path.DIRECTORY_SEPARATOR.$this->uploadName
imagejpeg($image,$inventory_path.DIRECTORY_SEPARATOR.$this->uploadName,$quality);
}
}

Downscale/resize?

How do I resize/downscale the images that gets uploaded with my upload script down to 350x100 if they are over 350x100?
My script:
$allowed_filetypes = array('.png','.PNG');
$filename = $_FILES['strUpload']['name'];
$ext = substr($filename, strpos($filename,'.'), strlen($filename)-1);
if(in_array($ext,$allowed_filetypes))
{
list($width, $height, $type, $attr) = getimagesize($_FILES['strUpload']['tmp_name']);
if ($width > 350 || $height > 100)
{
echo "That file dimensions are not allowed. Only 350x100 is allowed";
exit();
}
if ($_FILES['strUpload']['size'] > 2097152 )
{
echo "ERROR: Large File Size. Only less than 2mb accepted";
exit();
}
$imagename = uniqid('ff') . ".png";
move_uploaded_file ( $_FILES['strUpload']['tmp_name'], $imagename );
print ( "<script type=\"text/javascript\">" );
if(file_exists($imagename) && $_FILES['strUpload']['name'] != '')
{
print ( "self.opener.SetImageFile(\"" . $imagename . "\");" );
echo "\n";
print ( "self.opener.setInputFile(\"" . $imagename . "\");" );
}
echo "\n";
print ( "window.close();" );
echo "\n";
print ( "</script>" );
$open = new dbconnect();
$open->callDB("localhost","pema2201_william","lindberg","pema2201_siggen");
$ip = $_SERVER['REMOTE_ADDR'];
$dattum = date('Y-m-d H:i:s', time());
mysql_query("INSERT INTO piclist (ip,pic,datum) VALUES('$ip','$imagename','$dattum')") or die(mysql_error());
}
else
{
echo "WRONG FILE TYPE ONLY PNG ALLOWED"
}
PHP has several image handling libraries. The GD library has shipped since PHP 4.3 so I suggest using that. Just read the docs to find what you need.
Use imagecopyresized - there's a good example of how to use it on the PHP manual page.
Have a look at this question someone else asked a few days ago.
That not only explains how it's done, but also how it's done in an efficient way. (ImageMagick should be used over the GD library)
Hope that helps.
The general gist is to create a new "canvas" of the desired dimensions for the image to go in.
Take your uploaded image and copy it onto the new canvas giving setting a source width x height (take all of the source image) and destination width x height (use all of the destination canvas), offsets are available to shift the image around a bit if you need to.
Then finally save it where you need it to go, or insert it into a database field, (this will replace your move_uploaded_file call).

Categories