I am using the following Imagick function to resize an image. The code runs and resizes the image, but with an error from the server saying "An error occurred while requesting the document from the testing server." And I cannot detect the problem. In the browser it, however, outputs non-human readable characters. In case I try to output the resized/modified image to the browser, there is no problem. I face this problem as I try to save the image to the disk.
Here is my code:
<?php
imagick_resize('running.jpg');
function imagick_resize($image, $width = 460, $height = 300)
{
// define widescreen dimensions
// $width = 460;
// $height = 300;
// load an image
$i = new Imagick($_SERVER['DOCUMENT_ROOT'] . '/alchemyapi/' . $image);
// get the current image dimensions
$geo = $i->getImageGeometry();
// crop the image
if(($geo['width']/$width) < ($geo['height']/$height))
{
$i->cropImage($geo['width'], floor($height*$geo['width']/$width), 0, (($geo['height']-($height*$geo['width']/$width))/2));
}
else
{
$i->cropImage(ceil($width*$geo['height']/$height), $geo['height'], (($geo['width']-($width*$geo['height']/$height))/2), 0);
}
// thumbnail the image
$i->ThumbnailImage($width,$height,true);
// save or show or whatever the image
# $i->setImageFormat('png');
# header("Content-Type: image/png");
# unlink('small_square_img.png');
$i->writeImage($_SERVER['DOCUMENT_ROOT'] . '/alchemyapi/tmp/small_square_img.png');
# file_put_contents('small_square_img.png', $i);
exit($i);
}
?>
The data you are sending to the browser is not a valid image. It is quite likely that you have a Byte-Order-Marker in some of your files before the
You should check for that and fix it if it is occuring, or provide an example of the "non-human readable characters" for people to have a clue of what the problem is.
Related
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.
I have found a code that pull out a thumbnail from a video and its work!
but when I trying to make the php file to print the image with the Content-Type its return an error, when i tried to save it to the server its work fine!
the code:
<?php
function captureVideoPosterImg($movie_file = '')
{
extension_loaded('ffmpeg');
// Instantiates the class ffmpeg_movie so we can get the information you want the video
$movie = new ffmpeg_movie($movie_file);
// Get The duration of the video in seconds
echo $Duration = round($movie->getDuration(), 0);
// Get the number of frames of the video
$TotalFrames = $movie->getFrameCount();
// Get the height in pixels Video
$height = $movie->getFrameHeight();
// Get the width of the video in pixels
$width = $movie->getFrameWidth();
//Receiving the frame from the video and saving
// Need to create a GD image ffmpeg-php to work on it
$image = imagecreatetruecolor($width, $height);
// Create an instance of the frame with the class ffmpeg_frame
$Frame = new ffmpeg_frame($image);
// Choose the frame you want to save as jpeg
$thumbnailOf = (int) round($movie->getFrameCount() / 2.5);
// Receives the frame
$frame = $movie->GetFrame($thumbnailOf);
// Convert to a GD image
$image = $frame->toGDImage();
// Save to disk.
//echo $movie_file.'.jpg';
header('Content-Type: image/jpeg');
imagejpeg($image,null,100);
}
echo captureVideoPosterImg("smovie.mp4");
?>
the file in convert to UTF8 without bom.
thx!
I tried to make a thumbnail of a pdf file which is hosted on another server. My current code is:
<?php
$im = new imagick("http://www.d3publisher.us/Walkthroughs/Naruto_NC_3_DS.pdf");
$im->setImageFormat('jpg');
header('Content-Type: image/jpeg');
echo $im;
?>
The problem is that code is only generating thumbnail for LAST PAGE of the pdf file. How can I make a thumbnail for first page only? I tried to add [0] at the imagick line.
$im = new imagick("http://www.d3publisher.us/Walkthroughs/Naruto_NC_3_DS.pdf[0]");
but it didn't work. It only work for local pdf file, i.e:
$im = new imagick("my-pdf-file.pdf[0]");
Please help me solve this problem.. Thanks..
You'll need to reset the active image to the first page. This can be done with Imagick::setIteratorIndex.
<?php
$im = new imagick("http://www.d3publisher.us/Walkthroughs/Naruto_NC_3_DS.pdf");
$im->setIteratorIndex(0);
$im->setImageFormat('jpg');
header('Content-Type: image/jpeg');
echo $im;
?>
Try...
$im->setImageIndex(0); //this will return 1th page of the pdf file
$im->setImageFormat('jpg');
"This can be done with Imagick::setIteratorIndex. .."
..or not. Simply has no effect . Setting it to one crashes something, setting it to 0 gets the last page..
function make_thumbnail($filename)
{
try
{
$imagick= new Imagick($filename);
}
catch(ImagickException $e)
{
// failed to make a thimbynail. what now?
// load up our trusty truetype font png instead?
$imagick->destroy();
return "0"; // shove any rubbish in the db - it will just say no image available when asked.
}
$imagick->setIteratorIndex(0);// rewind to first page or image of a multi series
$imagick->setImageFormat("png"); // turn it into a png
$imagick = $imagick->flattenImages(); // remove any transparency
$imagick->scaleImage(300,0); //resize...to less than 300px wide
$d = $imagick->getImageGeometry();
$h = $d['height'];
if($h > 300)
$imagick->scaleImage(0,300);
$imagick->setImageCompression(\Imagick::COMPRESSION_UNDEFINED);
$imagick->setImageCompressionQuality(0);
$imagick->setIteratorIndex(0);
$a = $imagick->getImageBlob(); // output as bytestream
$imagick->destroy();
return $a;
}
I have a page while is used only for print, and some of the images on there are uploaded through a script I have. It seems to always reduce the image to 72 dpi, reguardless of what I set imagejpeg() and imagepng() to for quality.
I've used my own personal script and this one on git hub
https://github.com/maxim/smart_resize_image
I was hoping for a little guidance on preserving the dpi at the original 300dpi.
Here is my own personal script
if (!empty($_FILES['image']['name'])) //checking if file upload box contains a value
{
$saveDirectory = 'pics/'; //name of folder to upload to
$tempName = $_FILES['image']['tmp_name']; //getting the temp name on server
$fileName1 = $_FILES['image']['name']; //getting file name on users computer
$count = 1;
do{
$location = $saveDirectory . $_GET['section'] . $count . $fileName1;
$count++;
}while(is_file($location));
if (move_uploaded_file($tempName, $location)) //Moves the temp file on server
{ //to directory with real name
$image = $location;
// Get new sizes
list($width, $height, $type) = getimagesize($image); //gets information about new server image
$framewidth = 932;
$frameheight = 354;
$realwidth = $width; //setting original width and height
$realheight = $height;
// Load
$file1new = imagecreatetruecolor($framewidth, $frameheight); //creates all black image with target w/h
if($type == 2){
$source = imagecreatefromjpeg($image);
imagecopyresampled($file1new, $source , 0, 0, 0, 0, $framewidth, $frameheight, $realwidth, $realheight);
}
elseif($type == 3){
$source = imagecreatefrompng($image);
imagecopyresampled($file1new, $source , 0, 0, 0, 0, $framewidth, $frameheight, $realwidth, $realheight);
}
else{
echo "Wrong file type";
}
if($type == 2){
//creates jpeg image from file1new for file1 (also retains quality)
imagejpeg($file1new, $image,100);
//frees space
imagedestroy($file1new);
}
elseif($type == 3){
//creates png image from file1new for file1 (also retains quality)
imagepng($file1new, $image,10);
//frees space
imagedestroy($file1new);
}
else{
echo "Wrong file type";
}
}
else
{
echo '<h1> There was an error while uploading the file.</h1>';
}
}
}
Edit: Even if dpi isn't the answer, as I see jpgs in specific don't retain that information. I need some way of keeping these images very clear and crisp.
If you generate image and open with a browser, the browser will reduce it to 72dpi before rendering.
If you open with gimp/phptoshop/whatever image editor , it should preserve the same dpi quality.
Though on a screen, there is no difference since your screen is 72 dpi.
Not tested on new browsers, but it was like this in netscape and first firefox versions, I assume it has not changed since.
The function posted by lorezyra (at) lorezyra (dot) com here: http://www.php.net/manual/es/function.imagejpeg.php#85712 might do the trick.
I am new to jQuery but im loving it! ive have a problem i cant get round as of yet.
I am using http://www.zurb.com/playground/ajax_upload
which i have got working using the following upload.php
<?
$time= time();
$uploaddir = 'users/'; //<-- Changed this to my directory for storing images
$uploadfile = $uploaddir.$time.basename($_FILES['userfile']['name']); //<-- IMPORTANT
if (move_uploaded_file($_FILES['userfile']['tmp_name'], $uploadfile)) {
echo $uploaddir.$time.$_FILES['userfile']['name']; // IMPORTANT
#print_r($_FILES);
} else {
// WARNING! DO NOT USE "FALSE" STRING AS A RESPONSE!
// Otherwise onSubmit event will not be fired
echo "error";
}
?>
i have added the time variable to ensure each image is unique. The problem i have is i want to resize and optimise the image on the fly and i am not sure how to do this.
The resize is the most important featuer i require - for example i would like a max width of 300px for the image that is saved even if it was originally 1000px wide. I need to resize proportionaly ( is that a word? :) )
Any help will be great.
Regards
M
To resize images you need libs like GD
The standard function to do this is GD's imagecopyresampled.
In the example is shown one way to resize and keeping the proportion:
//> MAx
$width = 200;
$height = 200;
// Get new dimensions
list($width_orig, $height_orig) = getimagesize($filename);
$ratio_orig = $width_orig/$height_orig;
if ($width/$height > $ratio_orig) {
$width = $height*$ratio_orig;
} else {
$height = $width/$ratio_orig;
}
There is two main image manipulation things in PHP, GD or Imagemagick. Both will be able to do what you need. You will need to configure them on your PHP webserver.