PHP Doku:: Ausgabe des Bildes im Browser oder als Datei - function.imagejpeg.html

Verlauf / Chronik / History: (1) anzeigen

Sie sind hier:
Doku-StartseitePHP-HandbuchFunktionsreferenzBildverarbeitung und -generierungBildbearbeitung und GDGD- und Image-Funktionenimagejpeg

Ein Service von Reinhard Neidl - Webprogrammierung.

GD- und Image-Funktionen

<<imageistruecolor

imagelayereffect>>

imagejpeg

(PHP 4, PHP 5)

imagejpegAusgabe des Bildes im Browser oder als Datei

Beschreibung

bool imagejpeg ( resource $image [, string $filename [, int $quality ]] )

imagejpeg() erzeugt eine JPEG-Datei aus dem übergebenen image.

Parameter-Liste

image

Eine von den verschiedenen Erzeugungsfunktionen wie imagecreatetruecolor() gelieferte Grafikressource.

filename

Der Pfad der Datei, in die geschrieben werden soll. Wenn dies nicht gesetzt oder NULL ist, so wird die Bilddatei direkt ausgegeben.

Um diesen Parameter zu übergehen, um den Parameter quality anzugeben kann NULL verwendet werden.

quality

quality ist optional und es kann ein Wert zwischen 0 (schlechteste Qualität, kleine Datei) und 100 (beste Qualität, größte Datei) übergeben werden. Der Standardwert ist der standardmäßige IJG-Qualitätswert (ungefähr 75).

Rückgabewerte

Gibt bei Erfolg TRUE zurück. Im Fehlerfall wird FALSE zurückgegeben.

Beispiele

Beispiel #1 Ein Bild ausgeben

<?php
// Erzeut ein leeres Bild und fügt ein wenig Text hinzu
$im imagecreatetruecolor(12020);
$text_color imagecolorallocate($im2331491);
imagestring($im155,  'A Simple Text String'$text_color);

// Die Content-Type-Kopfzeile senden, in diesem Fall image/jpeg
header('Content-type: image/jpeg');

// Das Bild ausgeben
imagejpeg($im);

// Den Speicher freigeben
imagedestroy($im);
?>

Das oben gezeigte Beispiel erzeugt eine ähnliche Ausgabe wie:

Ausgabe des Beispiels: Ein Bild ausgeben

Beispiel #2 Ein Bild speichern

<?php
// Erzeugt ein leeres Bild und fügt ein wenig Text hinzu
$im imagecreatetruecolor(12020);
$text_color imagecolorallocate($im2331491);
imagestring($im155,  'A Simple Text String'$text_color);

// Das Bild als 'simpletext.jpg' speichern
imagejpeg($im'simpletext.jpg');

// Den Speicher freigeben
imagedestroy($im);
?>

Beispiel #3 Das Bild mit 75% Qualität ausgeben

<?php
// Erzeugt ein leeres Bild und fügt ein wenig Text hinzu
$im imagecreatetruecolor(12020);
$text_color imagecolorallocate($im2331491);
imagestring($im155,  'A Simple Text String'$text_color);

// Die Content-Type-Kopfzeile senden, in diesem Fall image/jpeg
header('Content-type: image/jpeg');

// Der Dateiname wird übergangen, indem NULL verwendet wird
// dann wird die Qualität auf 75% gesetzt
imagejpeg($imNULL75);

// Den Speicher freigeben
imagedestroy($im);
?>

Anmerkungen

Hinweis: Die Unterstützung von JPEG steht nur zur Verfügung, wenn PHP mit GD-1.8 oder höher übersetzt wurde.

Hinweis:

Falls Progessive JPEGs ausgegeben werden sollen, so muss Interlacing mittels imageinterlace() eingeschaltet werden.

Siehe auch

  • imagepng() - Ausgabe eines Bildes im Browser oder als Datei im PNG-Format
  • imagegif() - Ausgabe des Bildes im Browser oder als Datei
  • imagewbmp() - Output image to browser or file
  • imageinterlace() - Schaltet die Interlaced-Darstellung eines Bildes an oder aus
  • imagetypes() - Gibt die von der aktuell verwendeten PHP-Version unterstützten Grafik-Formate zurück


71 BenutzerBeiträge:
- Beiträge aktualisieren...
Ray.Paseur sometimes uses Gmail
23.09.2010 0:06
If string $filename is given and it exists, it will be overwritten.
hikmet1023 at hotmail dot com
16.03.2010 17:46
WARNING for those who use utf-8 scripts:
Before going crazy like me for a whole day and digging around configuration files etc.

DIRECT BROWSER OUTPUT using imagejepeg worked only after i have saved my script in ANSI instead of utf-8
someone at anydomain dot com
1.08.2009 22:20
I am using the following function for creating thumbnail(s). it works fine. I just want all the thumbnails a contant height so that they fit in a line. the only problem is that it can only output one image to the browser only. how can it be used to output multiple images.

<?php
function resizeImage($originalImage,$new_height){
   
   
// Get the original geometry and calculate scales
   
list($width, $height) = getimagesize($originalImage);
       
$new_width = round(($width * $new_height) / $height);

   
// Resize the original image
   
$imageResized = imagecreatetruecolor($new_width, $new_height);
   
$imageTmp     = imagecreatefromjpeg ($originalImage);
   
imagecopyresampled($imageResized, $imageTmp, 0, 0, 0, 0, $new_width, $new_height, $width, $height);

   
// Output
   
imagejpeg($imageResized, null, 100);
   
imageDestroy($imageResized);
    return;
}

resizeImage("IMG_0158.JPG",100); //this one shows on the browser
resizeImage("IMG_0159.JPG",100); //this one, and any subsequent ones, do not show up on the browser

?>
Anonymous
31.07.2009 0:16
I wanted a function that could resize an image and store the resulting thumbnail in a variable so I could manually save it. Here is the function. I basically strung together two snippets, one from this website (I think) and one by MrCoder here: http://www.webdeveloper.com/forum/showthread.php?t=188298.

<?php
function resizeToVariable($sourceImage,$newHeight,$newWidth,$destImage)
{
    list(
$width,$height) = getimagesize($image);
   
$img = imagecreatefromjpeg($sourceImage);
   
// create a new temporary image
   
$tmp_img = imagecreatetruecolor($newHeight,$newWidth);
   
// copy and resize old image into new image
   
imagecopyresized( $tmp_img, $img, 0, 0, 0, 0,$newHeight,$newWidth, $width, $height );
   
// use output buffering to capture outputted image stream
   
ob_start();
   
imagejpeg($tmp_img);
   
$i = ob_get_clean();
   
// Save file
   
$fp = fopen ($destImage,'w');
   
fwrite ($fp, $i);
   
fclose ($fp);
}
?>

You can use this for all your image resizing tasks. I for some reason had a problem using imagejpeg to save the image directly.
tomas at dundacek dot cz
8.06.2009 22:31
I had a problem with denied permissions when trying to upload AND resize an image having safe_mode on. This caused that I couldn't create the new file in which I wanted to resampled the image with nor with imagejpeg() nor with touch() and imagejpeg() after it.

Here is my solution, I didn't test, but it's possible, it is biting some memory:

<?php
function resize($image, $target_file) {
 
// $image is the uploaded image
 
list($width, $height) = getimagesize($image['tmp_name']);

 
//setup the new size of the image
 
$ratio = $width/$height;
 
$new_height = 500;
 
$new_width = $new_height * $ratio;

 
//move the file in the new location
 
move_uploaded_file($image['tmp_name'], $target_file);
 
 
// resample the image       
 
$new_image = imagecreatetruecolor($new_width, $new_height);
 
$old_image = imagecreatefromjpeg($target_file);
 
imagecopyresampled($new_image,$old_image,0,0,0,0,$new_width, $new_height, $width, $height);       

 
//output
 
imagejpeg($new_image, $target_file, 100);
}

?>

As you can see, the function moves the uploaded file where you want to save the resampled image (move_uploaded_file is not restricted by safe_mode) and then you can resample the image, because it was created by moving it already.

Note: the directory where you want to save the file must have permissions set to 0777.
viciousVelo
6.04.2009 16:49
for those who get the message "permission denied" or "unable to access": it looks like a problem with your writepermissions to this folder. no matter if you use windows- or linuxserver, be sure the correct user has the permission to write to the correct folder.
francesco@essensys
26.03.2009 14:23
I didn't find any example like this on the Web, so I mixed pieces together.. hope this will save time to other people!

Here's a complete solution to READ any image (gif jpg png) from the FILESYSTEM, SCALE it to a max width/height, SAVE the scaled image to a BLOB field keeping the original image type. Quite tricky..

<?php

function scaleImageFileToBlob($file) {

   
$source_pic = $file;
   
$max_width = 200;
   
$max_height = 200;

    list(
$width, $height, $image_type) = getimagesize($file);

    switch (
$image_type)
    {
        case
1: $src = imagecreatefromgif($file); break;
        case
2: $src = imagecreatefromjpeg($file);  break;
        case
3: $src = imagecreatefrompng($file); break;
        default: return
'';  break;
    }

   
$x_ratio = $max_width / $width;
   
$y_ratio = $max_height / $height;

    if( (
$width <= $max_width) && ($height <= $max_height) ){
       
$tn_width = $width;
       
$tn_height = $height;
        }elseif ((
$x_ratio * $height) < $max_height){
           
$tn_height = ceil($x_ratio * $height);
           
$tn_width = $max_width;
        }else{
           
$tn_width = ceil($y_ratio * $width);
           
$tn_height = $max_height;
    }

   
$tmp = imagecreatetruecolor($tn_width,$tn_height);

   
/* Check if this image is PNG or GIF, then set if Transparent*/
   
if(($image_type == 1) OR ($image_type==3))
    {
       
imagealphablending($tmp, false);
       
imagesavealpha($tmp,true);
       
$transparent = imagecolorallocatealpha($tmp, 255, 255, 255, 127);
       
imagefilledrectangle($tmp, 0, 0, $tn_width, $tn_height, $transparent);
    }
   
imagecopyresampled($tmp,$src,0,0,0,0,$tn_width, $tn_height,$width,$height);

   
/*
     * imageXXX() only has two options, save as a file, or send to the browser.
     * It does not provide you the oppurtunity to manipulate the final GIF/JPG/PNG file stream
     * So I start the output buffering, use imageXXX() to output the data stream to the browser,
     * get the contents of the stream, and use clean to silently discard the buffered contents.
     */
   
ob_start();

    switch (
$image_type)
    {
        case
1: imagegif($tmp); break;
        case
2: imagejpeg($tmp, NULL, 100);  break; // best quality
       
case 3: imagepng($tmp, NULL, 0); break; // no compression
       
default: echo ''; break;
    }

   
$final_image = ob_get_contents();

   
ob_end_clean();

    return
$final_image;
}

?>

So, let's suppose you have a form where a user can upload an image, and you have to scale it and save it into your database.

<?php
   
   
[..] // the user has clicked the Submit button..
   
    // Check if the user entered an image
   
if ($_FILES['imagefile']['name'] != '') {
       
$image = scaleImageFileToBlob($_FILES['imagefile']['tmp_name']);

        if (
$image == '') {
            echo
'Image type not supported';
        } else {
           
$image_type = $_FILES['imagefile']['type'];
           
$image = addslashes($image);
           
           
$query  = "UPDATE yourtable SET image_type='$image_type', image='$image' WHERE ...";
           
$result = mysql_query($query);
            if (
$result) {
               echo
'Image scaled and uploaded';
             } else {
               echo
'Error running the query';
             }
        }
    }

?>
soapergem at gmail dot com
6.11.2008 22:48
I came here looking for something similar to the getJPEGresolution function, but noticed the drawbacks that were pointed out in the last post. So, after drawing on some other code examples on the web, I put together the following function which should always properly return the correct values. (But remember that you still need to have the EXIF extension installed with your instance of PHP for this to work!)

<?php

function jpeg_dpi($filename)
{
    if (
exif_imagetype($filename) != IMAGETYPE_JPEG ) {
        return
false;
    } else {
       
$exif = exif_read_data($filename, 'IFD0');
    }
   
   
$x = $y = 0;
    if ( isset(
$exif['XResolution']) && isset($exif['YResolution']) ) {
       
$x = intval(preg_replace('@^(\\d+)/(\\d+)$@e', '$1/$2', $exif['XResolution']));
       
$y = intval(preg_replace('@^(\\d+)/(\\d+)$@e', '$1/$2', $exif['YResolution']));
    }
   
    if ( !
$x && !$y && $fp = fopen($filename, 'r') ) {
       
$string = fread($fp, 20);
       
fclose($fp);
       
       
$data = bin2hex(substr($string, 14, 4));
       
$x = hexdec(substr($data, 0, 4));
       
$y = hexdec(substr($data, 4, 4));
    }
   
    if (
$x || $y ) {
        return array(
$x, $y);
    }
   
    return
false;
}

?>

This function returns an array with the x-resolution, y-resolution when they can be determined, otherwise FALSE.
ahows at noggin dot com dot au
22.10.2008 7:36
Regarding the code below, it only grabs the last byte of the DPI information in JFIF-mode. I was wondering why my 300-DPI file was being reported as 44. 300 - 256 = 44 of course.
lorezyra (at) lorezyra (dot) com
13.09.2008 16:57
I noticed through testing that my previous function would not always return the data requested... this is due to the fact that some cameras and software dont correctly write the DPI info in the JFIF header... So, my 2nd solution is to read the exif info (if available) and output the first non-zero value as the DPI...

<?PHP
function getJPEGresolution($filename){
    if(
exif_imagetype( $filename)!= IMAGETYPE_JPEG) return(false);
   
$outRez=array();
   
// Read the file
   
$exif = exif_read_data($filename, 'IFD0');
   
   
ob_start(); // start a new output buffer
   
$image   = file_get_contents($filename);
   
   
// grab DPI information from the JPG header
   
$outRez["xDPI"] = (int)(ord($image[15])>0? ord($image[15]) : $exif['XResolution'] );
   
$outRez["yDPI"] = (int)(ord($image[17])>0? ord($image[17]) : $exif['YResolution'] );
   
ob_end_clean(); // stop this output buffer

    //correct output if header doesn't contain dpi info:: use exif info instead
   
$outRez["xDPI"] = ($outRez["xDPI"]>0? $outRez["xDPI"] : $exif['THUMBNAIL']['XResolution'] );
   
$outRez["yDPI"] = ($outRez["yDPI"]>0? $outRez["yDPI"] : $exif['THUMBNAIL']['YResolution'] );
   
   
//double check values; make sure it's just a number and not "72/1" ...
   
if(!is_numeric($outRez["xDPI"])) $outRez["xDPI"] = (int)substr($outRez["xDPI"], 0, strpos($outRez["xDPI"],"/",1));
    if(!
is_numeric($outRez["yDPI"])) $outRez["yDPI"] = (int)substr($outRez["yDPI"], 0, strpos($outRez["yDPI"],"/",1));

   
//xDPI and yDPI should equal in value... but we output both anyway...
   
return($outRez);
}
//end function getJPEGresolution
?>
lorezyra (at) lorezyra (dot) com
13.09.2008 15:50
For those looking to grab the resolution of a JPEG image without using GD nor ImageMagic... I wrote this simple function.

Too bad GD doesn't have this very simple function for us to use...

<?php
function getJPEGresolution($filename){
   
$outRez=array();
   
// Read the file
   
ob_start(); // start a new output buffer
   
$image   = file_get_contents($filename);
   
   
// grab DPI information from the JPG header
   
$outRez["xDPI"] = ord($image[15]);
   
$outRez["yDPI"] = ord($image[17]);
   
ob_end_clean(); // stop this output buffer

    //xDPI and yDPI should equal in value... but we output both anyway...
   
return($outRez);
}
//end function getJPEGresolution
?>
stefan at colulus dot com
30.05.2008 20:16
I worked out a script that allows the transfer of alphanumeric data to be placed on an image. The HTML feature is img src and the php feature is imagettftext. This simple code will increment from 1 to 3 on images.

code:

<?php
//ImageCall.php -- This script will call a script to produce the image.
for($next = 1;$next < 4; $next++){
print
"Image $next:<br>";
print
"<img src = 'Image.php?\$text=$next'>";
print
"<br><br>";
}
?>

<?php
//Image.php -- This script creates a square image and places the text on it.

// image size and color
$im = ImageCreate(77,77);
$color1 = ImageColorAllocate($im,0x66,0xCC,0x00);
$color2 = ImageColorAllocate($im,0x33,0x66,0x00);
$color3 = ImageColorAllocate($im,0x00,0x99,0x00);
$color4 = ImageColorAllocate($im,0x3D,0x3D,0x3D);

// image creation
ImageFilledRectangle($im,1,1,76,76,$color1);
ImageFilledpolygon($im, array (76,1,1,76,76,76),3,$color2);
ImageFilledRectangle($im,5,5,72,72,$color3);

// determine numeric center of image
$size = ImageTTFBBox(45,0,'impact',$_GET['$text']);
$X = (77 - (abs($size[2]- $size[0])))/2;
$Y = ((77 - (abs($size[5] - $size[3])))/2 + (abs($size[5] - $size[3])));

//places numeric information on image
ImageTTFText($im,45,0,($X-1),$Y,$color4,'impact',$_GET['$text']);

//returns completed image to calling script
Header('Content-Type: image/png');
Imagejpeg($im);

?>
xavi at lapalomera dot com
21.05.2008 20:11
For those whom needs other dpi image than the GD library, just do the following:

<?php
//Get jpeg image contents
ob_start();
imagejpeg($image, "", 100);
$image = ob_get_contents();
ob_end_clean();

//Or read jpeg image
$image = file_get_contents($file);

//Replace header image info to set DPI as units and the density for X and Y
//First parameter are units for X and Y densities (0x00 No units, 0x01 DPI, 0x02 DPC)
//Second parameter is the X density
//Third parameter is the Y density
$image = substr_replace($image, pack("Cnn", 0x01, 300, 300), 13, 5);

header("Content-type: image/jpeg");
header('Content-Disposition: attachment; filename="'.basename($file).'"');   

echo
$image;
?>
gcc dot programmer at gmail dot com
28.03.2008 6:24
The following was developed using Mac OSX ( Linux ).  The ghostscript call would have to be changed on a Windows box...

In an application I was developing, I needed to create .jpg thumbnails from .pdf uploaded files.  After some research, I found one easy way to accomplish this was ( SIMPLIFIED ):

<?php
     exec
("sw/bin/gs -q -dNOPAUSE -dBATCH -sDEVICE=jpeg
              -sOutputFile=test.jpg theFile.pdf"
);
?>

This of course assumes that ghostscript is installed on the server, you have permissions, yada...

Essentially this calls on ghostscript to do the conversion.

So, then, once the new .jpg is created, it needed to be resized to accomodate the UI.  Though I could easily do it from the command line with "convert", I was having issues using this command from PHP ( it's not my first language ).  I found this thread while groping for a different method, and found an unworkable solution that stimulated me to write the following:

( commented out lines were for debug, but might prove instructional for your own purposes, so I left them in )

[This function takes in a .jpg file to be converted to a thumbnail, the new width you want the thumbnail to be, and the name to which you want the thumbnail saved.  It then creates the thumbnail]

<?php
    
function createImage( $upload, $newWidth, $name )
     {
          if (!
$info = getimagesize($upload) )
               return
false;
         
//echo "width: "  . $info[0] . "<br/>";
          //echo "height: " . $info[1] . "<br/>";

          //create crude aspect ratio:
         
$aspect = $info[0] / $info[1];
         
$newHeight = round( $newWidth/$aspect );
         
//echo "$newHeight <br/>";

         
$src = @imagecreatefromjpeg("$upload");
          if ( !
$src )
               return
false;

         
$tmp = @imagecreatetruecolor( $newWidth, $newHeight );
         
imagecopyresampled( $tmp, $src, 0, 0, 0, 0, $newWidth,
                                        
$newHeight, $info[0], $info[1] );

         
imagejpeg( $tmp, $name, 100 );
         
imagedestroy( $src );
         
imagedestroy( $tmp );
          return
true;
     }

?>

$upload = the path to the file you want to make a thumbnail from.

$newWidth = the width of your thumbnails.

$name = the path ( including name ) of the thumbnail you're creating.

If I have test.jpg in my servers root directory, and I want a thumbnail
with a width of 120 pixels, with the name thumb.jpg also to be saved
in the servers root directory, I'd call this function thus:

<?php
     createImage
("test.jpg", 120, "thumb.jpg");
?>

I hope this makes life easier for somebody.
Anonymous
16.03.2008 19:24
Here is a function to resize an image and maintain aspect ratio. It will resize jpeg, gif or png and could easily be modified to add bmp. The name field is the destination of the file minus the file extension:

<?php
//name= filename minus type
   
function createImage($uploadedfile,$newWidth,$name)
    {
       
// Capture the original size of the uploaded image
       
if(!$info=getimagesize($uploadedfile))
          return
false;
       
        switch (
$info['mime'])
        {
            case
'image/jpeg':
               
$src = imagecreatefromjpeg($uploadedfile);
                break;
            case
'image/gif':
               
$src = imagecreatefromgif($uploadedfile);
                break;
            case
'image/png':
               
$src = imagecreatefrompng($uploadedfile);
                break;
            default:
                return
false;
        }
       
       
//Change the filename to add the filetype
       
$mime=split("image/",$info['mime']);
       
$filename=$name.".".$mime[1];
       
       
$size = getimagesize($uploadedfile);
       
$newHeight=aspect_ratio($size[0],$newWidth,$size[1]);
       
       
$tmp=imagecreatetruecolor($newWidth,$newHeight);
       
       
// this line actually does the image resizing, copying from the original
        // image into the $tmp image
       
imagecopyresampled($tmp,$src,0,0,0,0,$newWidth,$newHeight,$info[0], $info[1]);
       
        switch (
$info['mime'])
        {
            case
'image/jpeg':
               
imagejpeg($tmp,$filename,100); //100 is the quality settings, values range from 0-100.
               
break;
            case
'image/gif':
               
imagegif($tmp,$filename,100); //100 is the quality settings, values range from 0-100.
               
break;
            case
'image/png':
               
imagepng($tmp,$filename); //100 is the quality settings, values range from 0-100.
               
break;
        }
           
       
imagedestroy($src);
       
imagedestroy($tmp); // NOTE: PHP will clean up the temp file it created when the request
        // has completed.
       
return true;
    }

    if(!
createImage($uploadedfile,100, "uploaded_images/imgname"))
    {
      echo
"error";
    }
?>
james [at] bellisinasce.it
21.01.2008 6:20
When using

ImageJpeg ($img, "", $qlty) or any other Image*() command, with direct output to browser, BE ABSOLUTELY CERTAIN that your php file does not contain any \r, \n, or white spaces before the <? and after the ?> signs.

This should always kept in mind, not only for the file you are executing BUT ALSO FOR ALL THE INCLUDES called during the file execution!

I got totally crazy about this, for a whole weekend :(
My php editor did not correctly display a \n sign, as I was locally using a different charset/OS.

example

<?
include ("/usr/www.example.com/inc/function.inc.php");
include (
"/usr/www.example.com/inc/function.common.php");
connect_db0 ();
$admin_cookie = ckadmin_cookie ();
...
$img = file_get_contents ($path.$_GET['src']);
$im = imagecreatefromstring ($img);
header ("Content-Type: image/jpeg");       
imageJPEG ($im);
imageDestroy ($im);   
...

?>

If any of the included files, for any reason, prints an error message (or simply a warning) or has any white spaces/return/new line chars before "<?" or  after the ">?" signs, the result will be a broken image!

Even looking inside the defective image, it will be quite difficult to notice the unwanted characters, especially if you are using something like the windows' notepad... X(

If nothing is found, with the file/php editors, and you are not sure about your charset compatibility, I suggest to try to edit directly the files on the server, if possible, and search for all unwanted chars. ;)
pbijl
20.12.2007 12:37
note that using a different quality besides the default can result in strange cropping when resizing for example.
Michaelsoft
16.10.2007 11:50
I could not find any information on changing the DPI information on a JPG file using the GD lib. Since changing this does not resize or scale the actual image, it is only a header-setting.
The following snipplet will save your $image to $file and set the DPI to 150.

<?php

  imagejpeg
($image, $file, 75);

 
// Change DPI
 
$dpi_x   = 150;
 
$dpi_y   = 150;
 
 
// Read the file
 
$size    = filesize($file);
 
$image   = file_get_contents($file);

 
// Update DPI information in the JPG header
 
$image[13] = chr(1);
 
$image[14] = chr(floor($dpi_x/255));
 
$image[15] = chr(      $dpi_x%255);
 
$image[16] = chr(floor($dpi_y/255));
 
$image[17] = chr(      $dpi_y%255);

 
// Write the new JPG
 
$f = fopen($file, 'w');
 
fwrite($f, $msg, $size);
 
fclose($f);

?>

P.s. not fully tested (yet) but it works for my images ...
Elliott Brueggeman
30.07.2007 18:37
I did an experiment with the image quality parameter of the imagejpeg() function when creating jpegs. I found the optimal image quality with file size is taken into account to be 80 - very close to the default value of 75.

Anything over 80 results in an unnecessary increase in file size without much increase in image quality.

Results and sample pictures: http://www.ebrueggeman.com/article_php_image_optimization.php
write2shadi [at] gmail [dot] com
30.07.2007 15:54
after seeking for 2 days why ImageJpeg() was writing an empty file to the server, it was due to insufficient disk space on my hosting plan.... hope this helps,
Pedja (pedja at supurovic dot net)
26.07.2007 19:59
Here is sample function that creates thumbnail of source JPEG file. Thumbnail wil be in square form (with and height are the same), and original image cropped to fit in.

Parameters:

$p_thumb_file - name of the file (including path) where thumb should be saved to

$p_photo_file - nam of the source JPEG file (including path) thatthumbnail should be created of

$p_max_size - with and height (they will be the same) in pixels for thumbnail image

$p_quality - quality of jpeg thumbnail

<?php

function photoCreateCropThumb ($p_thumb_file, $p_photo_file, $p_max_size, $p_quality = 75) {
 
   
$pic = @imagecreatefromjpeg($p_photo_file);

    if (
$pic) {
       
$thumb = @imagecreatetruecolor ($p_max_size, $p_max_size) or die ("Can't create Image!");
       
$width = imagesx($pic);
       
$height = imagesy($pic);
        if (
$width < $height) {
               
$twidth = $p_max_size;
               
$theight = $twidth * $height / $width;
               
imagecopyresized($thumb, $pic, 0, 0, 0, ($height/2)-($width/2), $twidth, $theight, $width, $height);
        } else {
               
$theight = $p_max_size;
               
$twidth = $theight * $width / $height;
               
imagecopyresized($thumb, $pic, 0, 0, ($width/2)-($height/2), 0, $twidth, $theight, $width, $height);
        }

       
ImageJPEG ($thumb, $p_thumb_file, $p_quality);
    }

}

?>
Ross
27.04.2007 17:58
Just incase its confusing, i forgot to add

        $thumbwidth=70;
        $thumbheight=70;

to the top of the script below!
Ross
27.04.2007 16:53
This is a function that I had developed for a CMS.  The idea is that it runs from an upload form. The user uploads a hi-res image, which is copied to the server, a low res one is created (half the width/height of hi res) and a thumbnail is created.

The image is resized matching the smallest side of the image to the thumbnail size (in this example it is 70px).  The other side is then resized proportionally (which will end up being more than 70px) and cropped and centered so that it too is 70px.

There is a mixture of imagecopyresized and imagecopyresampled, i have chosen the ones that work best in this situation but imagecopyresampled gives a much nicer image.

Hope this helps someone.

        $dest_hires = "../images/artistsphotos/".$imageName."h.jpg";
        $dest_lowres = "../images/artistsphotos/".$imageName."l.jpg";
        $dest_thumbnail = "../images/artistsphotos/".$imageName."i.jpg";

        /*upload full size image to site - if it is hi res we do not want to manipulate it
        want to leave all qualit in tact.*/
        move_uploaded_file($_FILES["fileartimg"]["tmp_name"],"$dest_hires");

        $ims = getimagesize($dest_hires); //now we have dimensions of original image...
   
        /******creating lower res image******/
        $newwidth=ceil($ims[0]/2);//half the width of original file - use ceil() to avoid decimals.
        $newheight=ceil($ims[1]/2);//half the height
   
        $img = imagecreatetruecolor($newwidth,$newheight); //low res img - always use truecolor to prevent any 'wierd' colour effects.
        $org_img = imagecreatefromjpeg($dest_hires); //load in hi res
   
        imagecopyresized($img, $org_img, 0, 0, 0, 0, $newwidth, $newheight, $ims[0], $ims[1]);
        imagejpeg($img,$dest_lowres,80);//save to file low res img.
        imagedestroy($img);
       
        /******creating thumbnail******/
        //see which is bigger, x or y axis, then resize smaller side to 70.
        //$resizewidth is the temporary width of the thumbnail, it is in fact the width when it has been resized
        //using the apect ration and before cropping, at this stage the thumb will not be 70px X 70px
        //unless it is a square. Same applies to height ($resizeheight).
        //$thumbx and $thumby are the positions of the cropping are for thumbnail, these are calculated
        //so that the cropped image is centered.
       
        if ($ims[0]>$ims[1])
        {//then the width is bigger
            $aspectRatio = $ims[1]/70;
   
            $resizewidth=ceil($ims[0]/$aspectRatio);
            $resizeheight=70;
           
            $thumbx=ceil(($resizewidth - $thumbwidth)/2);
            $thumby=0;
        }
        else if ($ims[0]<$ims[1])
        {//then the height is bigger
            $aspectRatio = $ims[0]/70;
   
            $resizewidth=70;
            $resizeheight=ceil($ims[1]/$aspectRatio);
           
            $thumbx=0;
            $thumby=ceil(($resizeheight - $thumbheight)/2);
        }
        else if ($ims[0]==$ims[1])
        {//then we have a perfect square.
            $resizewidth=70;
            $resizeheight=70;
            $thumbx=0;
            $thumby=0;
        }
       
        $img = imagecreatetruecolor($resizewidth,$resizeheight);
        $org_img = imagecreatefromjpeg($dest_lowres);
   
        //this is the almost thumbnail sized image with everything resized to ratio
        imagecopyresampled($img, $org_img, 0, 0, 0, 0, $resizewidth, $resizeheight, $newwidth, $newheight);
        $img2 = imagecreatetruecolor($thumbwidth,$thumbheight);

        //this is the thumbnail image, where the above is cropped.
        imagecopyresized($img2, $img, 0, 0, $thumbx, $thumby, $resizewidth, $resizeheight, $resizewidth, $resizeheight);
        imagejpeg($img2,$dest_thumbnail,100);
        imagedestroy($img);
        imagedestroy($img2);
john at mtslink dot com
5.01.2007 5:07
Just wanted to mention that the create_thumbnail script below fails on uppercase filenames. Many cameras default to IMG_XX.JPG and since strpos is case sensitive it fails.

I changed all the strpos to stripos and it worked wonderfully.
webmaster at jongliertreff dot de
25.08.2006 13:56
Here's another on-the-fly thumbnail creation script.
When I scripted the pictuerviewer on my page, I had all the pictures only in full size and qualit, because I wanted the posibility für visitors to download the pictures.
But as Imagesizes of more than 4 MP are to large for websites, I created thumbnails and the smaller pictures on the fly. But I found out, that the Script needed too much RAM, especially in the thumbnail overview, when I had more then 50 thumbnails to create on the fly at the same time.

So I modified my image creator and my viewer to let them store images, that are created. So only the first visitor has to wait (which is usually me for controlling the uploads und updates), all other visitors get the stored images, which is much faster.

Create different folders. I have a main folder called 'imagesdb' and the tree subfolders full (Full quality images), show (images for the picture viewer) and thumb (for thumbnails in overview).

Store the script for example as image.php and link it like that:

<?PHP
$image_name
= "foo.jpg";
$style = "show";
    
// I've taken the foldernames. It's easier. For the
     //thumbnails replace "show" with "thumb".
$image_name = "imagesdb/$style/$image_name";
if(!
file_exists($image_name))
       
$image_name = "image.php?image_name=$image_name&style=$style";
    
// only if file doesn't exist call the on-the-fly creating file
?>

Now the main script, stored in the file image.php:

<?PHP

$image_name
= $_GET['image_name'];
$style = $_GET['style'];

    
// Now set the maximum sizes to the different styles.
     // You may set additional styles, but remember to
     // create the according subfolders.

switch($style) {
  case
"show":
   
$max_size = 800;
    break;
  case
"thumb":
   
$max_size = 125;
}

$dest_file = "imagesdb/$style/$image_name";
    
// set output file
$image_file = "imagesdb/full/$image_name";
    
// set source file
$size = getimagesize($image_file);
    
// get original size

if($size[0] > $size[1]) {
 
$divisor = $size[0] / $max_size;
}
else {
 
$divisor = $size[1] / $max_size;
}
    
// to get allways pictures of the same size, which ist
     // mostly wanted in imageviewers, look what ist larger:
     // width or height

$new_width = $size[0] / $divisor;
$new_height = $size[1] / $divisor;
    
// set new sizes

settype($new_width, 'integer');
settype($new_height, 'integer');
    
// sizes should be integers

$image_big = imagecreatefromjpeg($image_file);
    
// load original image
$image_small = imagecreatetruecolor($new_width, $new_height);
    
// create new image
imagecopyresampled($image_small, $image_big, 0,0, 0,0, $new_width,$new_height, $size[0],$size[1]);
    
// imageresampled whill result in a much higher quality
     // than imageresized
imagedestroy($image_big);
    
// the original data are no longer used

header("Content-type: image/jpeg");

if(
$style=="show" || $style=="thumb") {
  if(!
file_exists($dest_file))
   
imagejpeg($image_small, $dest_file, 100);
}
    
// if you have set additional sizese put them in the
     // if-arguments, too.
     // if someone calls the image.php directly in the
     // browser with imagenames allready existing, they
     // won't be overwritten

imagejpeg($image_small, '', 100);
imagedestroy($image_small);
    
// finally send image to browser and destroy no longer
     // needed data.

?>

As this website helped me for several times in the past and for creating this script, I hope I can help others with this script saving the time for developing a much more performant solution than an allways-on-the-fly-creating script.
chris dot calo at gmail dot com
24.07.2006 16:30
Thanks to Stuart and Darren for the corrections to the create_thumbnail function.  Another note on that function: imagecreatefromwbmp was incorrectly used.  WBMPs are wireless bitmaps, not windows bitmaps (thanks to clambert at whitecrown), so the thumbnail routine as is will not be able to handle windows bitmaps.  See the notes at http://us2.php.net/manual/en/function.imagecreatefromwbmp.php for tips on working with windows bitmaps.
stuart at purpletoucan dot com
23.07.2006 19:55
Thanks to Chris dot Calo for the thumbnail snippet.  The file type issue is easily resolved by getting the type from the file with getimagesize, and you can handle unsupported types at that stage too.  Thus:

   list($img_width,$img_height, $type) = getimagesize($source_file); // Get the original dimentions
   if ($type != 1 && $type != 2 && $type != 3 && $type != 15) { die("Your file is not a supported format"); }

...and then later check the type again to open the image correctly:

   if ( $type == 1 ) { $img_source = imagecreatefromgif($source_file); }
   else if ( $type == 2 ) { $img_source = imagecreatefromjpeg($source_file); }
   else if ( $type == 3 ) { $img_source = imagecreatefrompng($source_file); }
   else if ( $type == 15 ) { $img_source = imagecreatefromwbmp($source_file); }
Darren Kulp ( kulp at thekulp dot com )
19.07.2006 5:47
With regard to chris.calo's code:

// The following block retrieves the source file.  It assumes the filename extensions match the file's format.
   if ( strpos($source_file,".gif") ) { $img_source = imagecreatefromgif($source_file); }
   if ( (strpos($source_file,".jpg")) || (strpos($source_file,".jpeg")) )
 ... etc.

It assumes more than that, namely that the filename does not contain the strings '.gif', '.jpg', '.jpeg', '.bmp', or '.png' *anywhere* in the string. Some valid files with special filenames could break this; for example, a file named "used.to.be.a.png.file.gif" would cause this script to attempt to load the file as a PNG. Obviously this is a rare case, but the issue could be easily avoided by using "else ifs" (uses less CPU time) or checking that the extension abuts the end of the string or both.

That said, the whole business could be avoided if PHP didn't clutter the namespace with different functions to do the same thing with different image formats. Ick.
chris dot calo at gmail dot com
17.07.2006 23:44
function create_thumbnail( $source_file, $destination_file, $max_dimension)
{
    list($img_width,$img_height) = getimagesize($source_file); // Get the original dimentions
    $aspect_ratio = $img_width / $img_height;
   
    if ( ($img_width > $max_dimension) || ($img_height > $max_dimension) ) // If either dimension is too big...
    {
        if ( $img_width > $img_height ) // For wide images...
        {
            $new_width = $max_dimension;
            $new_height = $new_width / $aspect_ratio;
        }
        elseif ( $img_width < $img_height ) // For tall images...
        {
            $new_height = $max_dimension;
            $new_width = $new_height * $aspect_ratio;
        }
        elseif ( $img_width == $img_height ) // For square images...
        {
            $new_width = $max_dimension;
            $new_height = $max_dimension;
        }
        else { echo "Error reading image size."; return FALSE; }
    }
    else { $new_width = $img_width; $new_height = $img_height; } // If it's already smaller, don't change the size.
   
    // Make sure these are integers.
    $new_width = intval($new_width);
    $new_height = intval($new_height);
   
    $thumbnail = imagecreatetruecolor($new_width,$new_height); // Creates a new image in memory.

    // The following block retrieves the source file.  It assumes the filename extensions match the file's format.
    if ( strpos($source_file,".gif") ) { $img_source = imagecreatefromgif($source_file); }
    if ( (strpos($source_file,".jpg")) || (strpos($source_file,".jpeg")) )
    { $img_source = imagecreatefromjpeg($source_file); }
    if ( strpos($source_file,".bmp") ) { $img_source = imagecreatefromwbmp($source_file); }
    if ( strpos($source_file,".png") ) { $img_source = imagecreatefrompng($source_file); }
   
    // Here we resample and create the new jpeg.
    imagecopyresampled($thumbnail, $img_source, 0, 0, 0, 0, $new_width, $new_height, $img_width, $img_height);
    imagejpeg( $thumbnail, $destination_file, 100 );
   
    // Finally, we destroy the two images in memory.
    imagedestroy($img_source);
    imagedestroy($thumbnail);
}
your [dot] sheepy [at] gmail [dot] com
3.04.2006 10:34
Regarding Carl Gieringer's comment, it is possible to have PHP files in utf-8.  Just make sure the editor does not output BOM, which is unnecessary in utf-8 anyway.

Except for any editors from Microsoft, most programmer's editors that supports utf allows you to surpress BOM.
doobd at doobd dot com
15.02.2006 18:48
in addition to my THUMBNAIL GENERATOR script:

i forgot to say, src path must not be http:// but server path (e.g. for some linux server: src=/home/users/user1/public_html/images/image1.jpg) or relative path, as in example in script (src=test.jpg, src=../test.jpg, src=pictures/test.jpg...)

15.02.2006 16:44
THUMBNAIL GENERATOR

Hope someone will find this usefull... save it to thumb.php and use it for on-the-fly thumbnails generating

e.g.
<img src= "thumb.php?src=pic.jpg&wmax=150&hmax=100&quality=90&bgcol=FF0000"> </img>

<?php
   
// by dooobd@NOSPAM.doobd.com
    //
    // proportional on-the-fly thumb generator from JPG images
    //
    // usage example:
    // <img src= "thumb.php?src=pic.jpg&wmax=150&hmax=100&quality=90&bgcol=FF0000"> </img>
    //
    // parameters:  src = source image
    //              wmax = max width
    //              hmax = max height
    //              quality = JPG quality of generated thumb - optional.
    //                        if not specified, quality=90
    //              bgcol = if specified, allways generates exact wmax x hmax sized thumb,
    //                      with bacground color bgcol and centered source image
    //
    // note: if source image is smaller than desired thumbnail, it will not be resized!

   
header("Content-type: image/jpeg");
   
$source = imagecreatefromjpeg($src);
   
$orig_w=imagesx($source);
   
$orig_h=imagesy($source);
   
    if (
$orig_w>$wmax || $orig_h>$hmax)
    {
       
$thumb_w=$wmax;
       
$thumb_h=$hmax;
        if (
$thumb_w/$orig_w*$orig_h>$thumb_h)
           
$thumb_w=round($thumb_h*$orig_w/$orig_h);
        else
           
$thumb_h=round($thumb_w*$orig_h/$orig_w);
    } else
    {
       
$thumb_w=$orig_w;
       
$thumb_h=$orig_h;
    }
    if (!@
$bgcol)
    {
       
$thumb=imagecreatetruecolor($thumb_w,$thumb_h);
       
imagecopyresampled($thumb,$source,
                          
0,0,0,0,$thumb_w,$thumb_h,$orig_w,$orig_h);
    }
    else
    {
       
$thumb=imagecreatetruecolor($wmax,$hmax);
       
imagefilledrectangle($thumb,0,0,$wmax-1,$hmax-1,intval($bgcol,16));
       
imagecopyresampled($thumb,$source,
                          
round(($wmax-$thumb_w)/2),round(($hmax-$thumb_h)/2),
                          
0,0,$thumb_w,$thumb_h,$orig_w,$orig_h);
    }
    if (!@
$quality) $quality=90;
   
imagejpeg($thumb,"",$quality);
   
imagedestroy($thumb);
?>
valentinp at gmail dot com
7.01.2006 3:41
For all those people getting the

"Warning: imagejpeg(): Unable to access data ..."

I solved it by chmodding the directory you're writing to, to 0777.

NO fopen() needed!

Regards,
Valentin

3.01.2006 14:59
Hi

I had similar problem with safe mode. My solution is:

before imagejpeg(), touch() etc.
write:
ini_set(safe_mode,Off);
and after everything:
ini_set(safe_mode,On);

strange, but it works
Chears2All
aerowinx at hotmail dot de
22.12.2005 12:26
If imagejpeg brings up this warning:

Warning: imagejpeg(): Unable to access data ...

it could be a problem with "Safe Mode". A solution could be to touch the new file before, like:

touch($newfile);
imagejpeg($image_p, $newfile, 100);
Kenneth Keiter
18.12.2005 5:59
So.. after messing around with this beast of a function for hours, I discovered that it DOES NOT preserve the resource it is using the create the image, nor do imagepng() or imagegif(). By this I mean that you can not run two imagejpeg(), imagepng() or imagegif() calls on the same resource. Another possibly undocumented quirk... :-(
I_have at no_email_for_spam dot com
2.11.2005 18:01
The behaviour of not being allowed to write the file is based on a change in latest release, see http://www.php.net/ChangeLog-4.php#4.4.1

- Added missing safe_mode checks for image* functions and cURL.
- ...

Some people (including me) consider this new behaviour as broken, see also http://bugs.php.net/bug.php?id=35060 - please vote for/against the bug if you feel same/different.

Workaround is e.g. a touch($filename); before the imagejpeg($im,$filename);
moron at industrial dot org
2.11.2005 17:12
Please note that there is a bug report open for the currently broken safe_mode behaviour on this function:

http://bugs.php.net/?id=35060

According to the PHP staffer who has responded the docs are wrong (I don't agree but I'm also not their employee). 

The work around is to use touch() (or any other file system function that can do this) to create the file first before using imagejpeg().
mitnick at cc dot lv
2.11.2005 11:26
i had the same problem as tobylewis had

when i tried to call imagejpeg(), width porperly parameters given it displayed
imagejpeg(): Unable to access usr/home/public_html/pic1.jpg

imho if not correctly configured server this function is not allowed to create the file on disk.

the workaround however is if you create the file using some other function, before call imagejpeg(). something like this

<?
$fh
=fopen($file_name_dest,'w');
fclose($fh);
imagejpeg($dest,$file_name_dest, $quality); 
?>
mbailey [at] aethon [dt] co [dt] uk
18.09.2005 22:46
>>Bram Van Dam's

note below is missing "()" from the ob_end_clean call:

ob_end_clean; // stop this output buffer

should read

ob_end_clean(); // stop this output buffer

You can then use this for adding content-length headers (for example flash requires a content length in advance to create loaders)

e.g.

...

ob_start(); // start a new output buffer
   imagejpeg( $newimage, "", 90 );
   $ImageData = ob_get_contents();
   $ImageDataLength = ob_get_length();
ob_end_clean(); // stop this output buffer

header("Content-type: image/jpeg") ;
header("Content-Length: ".$ImageDataLength);
echo $ImageData;

...
(enVide neFelibata) envide at tugamail dot com
28.08.2005 16:32
Every script I was writing was giving me an error.
When writing the following code I was able, as a client, to browse the website and save the images (Save image as...) with IE. Yet with Firefox and family the browser tried to save them as 'script_name.php' instead of 'image_name.jpg'.

<?php
    header
("Content-Type: image/jpeg");
   
imagejpeg($image,'',100); // Output to Browser
?>

After trying to save all the watermarked images or saving the image as 'temp.jpg' before outputing it to user, I've read this topic on BugZilla that advised to add the following header:

<?php
    header
("Content-Type: image/jpeg");
   
header("Content-Disposition: attachment; filename=image_name.jpg"); // THIS ONE
?>

Sorry about the English.
Bram Van Dam
19.08.2005 21:50
If you wish to capture the jpg data into a variable, rather than outputting it or saving it into a file (perhaps so you can put it in a database), you might want to consider output buffering. Something along these lines should work:

<?php
ob_start
(); // start a new output buffer
   
imagejpeg( $newimage, NULL, 100 );
   
$ImageData = ob_get_contents();
ob_end_clean; // stop this output buffer
?>
John Luetke
6.08.2005 2:53
Rewrote the manual example into this function for creating a thumbnail image:

function thumbnail_jpeg ($original, $thumbnail, $width, $height, $quality) {
  list($width_orig, $height_orig) = getimagesize($original);
  if ($width && ($width_orig < $height_orig)) {
    $width = ($height / $height_orig) * $width_orig;
  }
        else {
    $height = ($width / $width_orig) * $height_orig;
  }
  $image_p = imagecreatetruecolor($width, $height);
  $image = imagecreatefromjpeg($originial);
  imagecopyresampled($image_p, $image, 0, 0, 0, 0, $width, $height, $width_orig, $height_orig);
  imagejpeg($image_p, $thumbnail, $quality);
  return;
}
tobylewis at mac dot com
24.06.2005 16:04
After trying to get imagejpeg (and imagegif and imagepng) to save an image to a file for some time, it finally dawned on me that perhaps the function would not automatically create the file named in the second parameter.

I then used fopen to create a file prior to the call to imagejpeg and the image was successfully written to the file.  It did not seem to matter if fclose was called before or after the call to imagejpeg.

I also tried to create a file outside of php and use it as the target for output, but this initially failled because of permissions.  Once I set all write permissions on this also accepted output from imagejpeg.
ghokanso at cs dot ndsu dot edu
8.06.2005 18:54
When displaying an image using imagepng or imagejpeg, you may want/need to call "header("Content-type: image/jpeg")" before the imagepng and imagejpeg functions.
It appears that some servers/browers are striping out the default header so the image is not rendered and appears as raw data.
(Firefox 1.02+ and OSX Safari for example)
wojteksw at go2 dot pl
4.04.2005 0:37
I have changed one line in the script of Kokesh
25-Jun-2004 06:42 listed above, and now it generates better quality thumbnails.
You have to change function imagecopyresized() to imagecopyresampled()
nerdgirl at HATE_SPAMnerdgirl dot dk
27.02.2005 21:31
Here is an example of uploading an image, changing its size (width/height) and saving it to a new file. It uses ftp to upload both the original and the resized image. This is usefull in situations where ftp is your only option.

It took me a while to figure it out, so I hope this will save someone else a lot of time :-)

The following assumes that the image is uploaded from a form with a filefield called 'gfx'. I have left out all error checking to keep it simple, so remember to modify the code, to suit your needs.

<?php
$new_width
= 100;
$new_height = 200;
$tmp_image=imagecreatefromjpeg($_FILES['gfx']['tmp_name']);
$width = imagesx($tmp_image);
$height = imagesy($tmp_image);
$new_image = imagecreatetruecolor($new_width,$new_height);
ImageCopyResized($new_image, $tmp_image,0,0,0,0, $new_width, $new_height, $width, $height);
//Grab new image
ob_start();
ImageJPEG($new_image);
$image_buffer = ob_get_contents();
ob_end_clean();
ImageDestroy($new_image);
//Create temporary file and write to it
$fp = tmpfile();
fwrite($fp, $image_buffer)) {
rewind($fp);
//Upload new image
$conn_id = ftp_connect('ftp.example.tld');
ftp_login($conn_id,'user','pass');
ftp_fput($conn_id,'path/to/new/file.jpg', $fp, FTP_BINARY);
fclose($fp);
?>
r dot duclos at chello dot fr
11.02.2005 15:41
Hy, here is a little code for generate a thumbnail, very good quality. Enjoy it !

<?php

function miniature($pict, $dest_pict){
   
   
$handle = @imagecreatefromjpeg($pict);

   
$x=imagesx($handle);
   
$y=imagesy($handle);
                                                  
        if(
$x > $y){                               
               
$max = $x;                          
               
$min = $y;                          
        }                                         
        if(
$x <= $y){                               
               
$max = $y;                          
               
$min = $x;                          
        }                                        

//$size_in_pixel : Size max of the label in pixel.  The size of the picture being
//proportional to the original, this value define maximum size
//of largest side with dimensions of the picture. Sorry for my english !

//Here $size_in_pixel = 100 for a thumbnail.
       
$size_in_pixel = '100';

       
$rate = $max/$size_in_pixel;
       
$final_x = $x/$rate;
       
$final_y = $y/$rate;

        if(
$final_x > $x) {
               
$final_x = $x;
               
$final_y = $y;
        }

       
$final_x = ceil($final_x);
       
$final_y = ceil($final_y);

       
$black_picture = imageCreatetruecolor($final_x,$final_y);
       
imagefill($black_picture,0,0,imagecolorallocate($black_picture, 255, 255, 255));
       
imagecopyresampled($black_picture, $handle, 0, 0, 0, 0,$final_x, $final_y, $x, $y);

        if(!@
imagejpeg($black_picture,$dest_pict.'/mini_'.$pict, $size_in_pixel))
       
imagestring($black_picture, 1, $final_x-4, $final_y-8, ".", imagecolorallocate($black_picture,0,0,0));
                       
       
//The number is the quality of the result picture
       
imagejpeg($black_picture,'', '100');
       
imagedestroy($handle);
       
imagedestroy($black_picture);
    }
   
$pict = "PICT7024.jpg";
$dest_pict = "D:/Program Files/EasyPHP1-7/www/test";
miniature($pict, $dest_pict);

?>
arjini at gmail dot com
13.09.2004 1:20
Scenario:
    When pointing your browser directly at a script outputting an image, it displays without problem, but when using it in another page via html (i.e. : img src="x.php?yada=yada" ), you get a broken image.

Reason:
    *Any* extra data sent along with the image will cause it to not display on other pages. Extra data may include, whitespace characters (check the begginings and ends of your files), or a call to session_start(), which is what got me.

Summary:
    If you're going to send an image DONT START A SESSION in the script that is outputting the image, and make sure that the PHP delimiters are the first and last things in your file.

10.09.2004 17:40
For best results, use only loss-less file formats (such as PNG) for storing images or image parts that you later intend to output with this function.
arjini at gmail dot com
8.09.2004 3:48
Converting a directory of PNG images into jpegs is as easy as:

<?php
    $d
= dir('./');
    while(
false !== ($e = $d->read())){
        if(
strpos($e,'.png')){
           
$r = imagecreatefrompng('./'.$e);
           
imagejpeg($r,str_replace('.png','.jpg',$e),75);
        }
    }
?>

Don't let anybody convince you otherwise. Put that in the folder that the images are in and run it. I tried for 2 hours to get photoshop to do it, to no avail. PHP to the rescue!
Olav Alexander Mjelde
7.07.2004 14:31
Note to steve:
yes, this is true.. I simply forgot to think about that issue with the clear text to the script..

I think the easiest way to "fix" it, would be to replace the @ in the string with something which cant be used in an email adress..

Then the script would do a replace of excisting of that character..

abc@123.com would then be abc*123.com, which the script would parse back into abc@123.com
Steve
27.06.2004 3:14
Regarding Olav's attempt at avoiding spambots, the code will produce a string of code like requests.php?string=<email_address>, and most spambots will parse that email address right out.  You should either create static php scripts to output specific addresses, or do something like save a temporary file on the server with the address you want, and either pass the filename to the makeimage script or have the script open a specific file to check.  If you put the address anywhere on the page the spambot will parse it out, including a tag like href="mailto:xxx".  That's why people use forms to send email now.
Kokesh
25.06.2004 18:42
Here is the simple, but powerful script for creating thumbnails on the fly.
You can include the script
directly to www page - just put it in <img src= tag.
with width 150pix.
This resizer respects the ASPECT RATIO.
Here is the script:
<?php
// Use it this way: resize.php?pic=imageurl&width=width_in_pixels
// kokesh@kokeshnet.com 2004
   
header("Content-type: image/jpeg");
   
$im     = imagecreatefromjpeg($pic);
   
$orange = imagecolorallocate($im, 220, 210, 60);
   
$px     = (imagesx($im) - 7.5 * strlen($string)) / 2;

   
$old_x=imageSX($im);
   
$old_y=imageSY($im);

   
$new_w=(int)($width);
    if ((
$new_w<=0) or ($new_w>$old_x)) {
     
$new_w=$old_x;
    }

   
$new_h=($old_x*($new_w/$old_x));

    if (
$old_x > $old_y) {
       
$thumb_w=$new_w;
       
$thumb_h=$old_y*($new_h/$old_x);

    }
    if (
$old_x < $old_y) {
       
$thumb_w=$old_x*($new_w/$old_y);
       
$thumb_h=$new_h;
    }
    if (
$old_x == $old_y) {
       
$thumb_w=$new_w;
       
$thumb_h=$new_h;
    }
    
$thumb=ImageCreateTrueColor($thumb_w,$thumb_h);
    
imagecopyresized($thumb,$im,0,0,0,0,$thumb_w,$thumb_h,$old_x,$old_y);

   
imagejpeg($thumb,"",90);
   
imagedestroy($thumb);
?>
rich @ richud dot com
24.06.2004 22:49
'quality' must be a whole number however if a mixed number is given it only uses whole part, e.g. a given value of 90.987 results in 90 being used.
Tom Davis
8.06.2004 12:49
I came across a problem where Internet Explorer refused to cache some dynamically created images. To get round this, send out a Last-Modified header.

Eg:

<?php

header
('Last-Modified: '.gmdate('D, d M Y H:i:s', $timestamp).' GMT');
header('Content-Type: image/jpeg');
imagejpeg($photo);

?>

25.05.2004 20:42
A word of warning when outputting images to the browser...

Make sure there is no extra spaces around the <?php ?> tags, in the file you are editing, and also any included files.

I began to think there was a bug in GD or something, and I checked the file I was working on, but forgot about the includes...

Hours gone..
stick [at] geek [dot] hu
24.05.2004 1:08
Just a note to Olav Alexander Mjelde's code: don't forget to put an
imagedestroy($im);
at the end of it or you can run into memory problems.
jannehonkonen at hotmail dot com
5.05.2004 7:44
I had problem wanting to insert stealth - copyrights into images. I could have done this easily with fopen and such, but I still wanted to use imagejpeg(); and it's quality feature. Well this is one kind of solution what I discovered, and seems to work fine.

--code--
$filename = "http://www.domain.com/something.jpg";
$im = imagecreatefromjpeg($filename);
imagejpeg($im,$ModImg,65);
$ModImg .= "This is the text added after EOF of the jpeg";
echo $ModImg;
--code--

As imagejpeg(); inserts imagedata into $ModImg, it does not show the image, but it seems to send headers in that point, so header(); is not needed before echoing variable. Text is viewable with Hex-editors etc.
Olav Alexander Mjelde
7.04.2004 15:24
Some people have never heard of spambots, searching the net for email adresses.
How do you avoid this?
Some people write emails like: olav-x AT volvo-power.net (mine btw),
but this will confuse "stupid" users.
The optimal sollution is to have an image with your email adress on.

* When using this function,
you have to put it in a non-html php file..
eg. I put it in a makeimage.php file.
so, how do you display it?

In your users.php, put this:

echo "<b>Email:</b>&nbsp;
        <img src=\"/sql/phpPictures/makeimage.php
         ?string={$row['email']}\">";

Below is the makeimage.php (working example)

<?php
header
("Content-type: image/jpg");
if (!isset(
$string))
  { 
   
$string = "Missing data";
  }

$font  = 4;
$width  = ImageFontWidth($font) * strlen($string);
$height = ImageFontHeight($font);
           
$im = @imagecreate ($width,$height);
//white background
$background_color = imagecolorallocate
                
($im, 255, 255, 255);
//black text
$text_color = imagecolorallocate ($im, 0, 0,0);
imagestring ($im, $font, 0, 0$string, $text_color);

imagejpeg ($im);
?>

Enjoy..
php at andy-pearce dot com
19.02.2004 21:42
This might be too obvious, but perhaps worth pointing out. If you want to simply serve images without altering them, it's presumably more efficient to use something like the following:

<?php
   
// Normally $filename would depend on $_GET, etc.
   
$filename = '/photoalbum/images/test.jpg';
   
header('Content-type: image/jpeg');
   
header('Content-transfer-encoding: binary');
   
header('Content-length: '.filesize($filename));
   
readfile($filename);
?>

That way you avoid the overhead of reading and parsing the image, you simply send it directly to the browser.

This is particularly useful if you're using PHP to implement access controls, because it allows you to redirect files from areas of the filesystem browsers can't normally access (although the filename should always come from your script if possible, and not from a URL field, to prevent subverting it with URLs such as image.php?../../../etc/passwd).
gzink at zinkconsulting dot com
1.01.2004 12:17
Don't forget that JPEG compression has artifacts! And they're not all really obvious. The PHP JPEG compression is pretty decent, but it seems to generally:

-Lighten the image overall, by a reasonable amount (never seen this before, but it will drive graphic designers crazy, you might want to darken the image before compressing it)
-Reduce saturation, especially with images with lots of points of different color within a few pixels of each other (this is a documented feature of JPEG)
-Seriously mess with blue colors, which is common to all JPEG but really annoying in some situations with blue and black or other detailed blue parts

You might want to consider using imagepng() and outputting a PNG image instead of a JPEG if any of the above affect you, or your image is not very photo-like. Sometimes I have an algorithm compare JPEG to PNG for an image and send the smaller version to the user.

Also, when using imagepng(), you should use imageinterlace() before it 95% of the time. Interlaced JPEGs load progressively, improving in quality as the image loads, so users on slower connections see the whole image at low quality. All this happens without affecting the file size (actually, sometimes the file size is smaller!) or final quality.

Hope this helps a few people out. It's not all that obvious without lots of playing around.

-Galen
http://zinkconsulting.com/
chris AT NOSPAM sketchdiary DOT com
25.09.2003 1:20
Just a reminder, if you're passing a string of text via GET, you should rawurlencode() or urlencode() them.  Some older browsers (such as Netscape 4.x) have issues regarding spaces in the URL.

NS 4 shows a broken image:
<image src="newimage.php?text=Show me the text!">

Makes all browsers happy:
<image src="newimage.php?text=<? echo urlencode('Show me the text!'); ?>">

Better to be safe than sorry...
irishcybernerd at email dot com
29.05.2003 19:33
Rather than using the temporary file, as described above, you can buffer the output stream. Someone else showed me this, and it seems to work very nicely.

    //Start buffering the output stream
    ob_start();

    // output the image as a file to the output stream
    Imagejpeg($im);
   
    //Read the output buffer
    $buffer = ob_get_contents();

    //clear the buffer
    ob_end_clean();

    //use $buffer as you wish...
jt at tsw dot org dot uk
25.02.2003 4:39
I've just read all this AFTER solving the problem in my own little way. (this is re dumping the image into a string)

Im not actually saving the file to a database, but I'm passing it over XML:RPC so I have the constraint that I cant just dump it to browser, and also its not binary safe.. my solution does not involve ob_start(); which might arguably be the more elgant solution. I didnt see my solution listed, so I thought I aught to post it to add to the wealth of knowledge:

[apologies if this is incorrect, im snipping from a large bit of irrelevent XML:RPC catching stuff]

$tmpfname = tempnam ("/tmp", "FOO");      // Generate the temp file

Imagejpeg($im,$tmpfname);                        // save me image to the file

$temp = fopen($tmpfname,"rb");                  // <- Open the file for reading binary
   
$buffer = fread($temp,filesize($tmpfname));  // get that data into the buffer
fclose($temp);                                            // close the file
unlink($tmpfname);                                     // finished with the file, discard

$out = base64_encode($buffer);                  // encode it (not nessicary if you are using some kind of binary safe function with the info)

and of course on the other end of whatever your doing,

[ some function to get $in ]

header("Content-type: image/jpeg");
$in = base64_decode($buffer);          // get the binary data back
echo $in;

This should work with things like Imagepng

Hope that helps anyone out.
crazyted at crazyted dot com
20.02.2003 6:51
In regards to adding images (or any other binary file) to a database, unless you absolutely *have* to, a MUCH better solution is to simply save the file you create to a directory and update your database with a URL to this file.

When I first started DB development I was hung up with BLOBs and how to make them effectively work with PHP but realized that they can severely impact performance and you also limit what you can do with those files once they're inside the DB.

If you can avoid using BLOBs, and most people can, then by all means just create a look-up table for your file urls and save them to a directory to store the files. File access and scalability will be greatly increased in most cases.
dominik at deobald dot org
26.12.2002 16:27
About dwards's note: If you choose to send an image to the user directly and don't want to have "strange characters", you have to set the mime-type of the result the user is going to receive:

header('Content-Type: image/jpeg');
imagejpeg($img);
dward at outeru dot comewithnospam
20.07.2002 2:57
It took me quite a while to figure out how to output dynamic images along with html with my php scripts.

I may be dim but I'm sure I'm not the only one. So here it is if you need it.

Instead of sending the image directly to the browser, which ends up looking like a bunch of garbage to most users, send an IMG tag with the SRC attribute set to your PHP script that creates the image.

echo '<IMG SRC="makeimg.php?args=YourMakeImgArgs">';
dklein at gmx dot de
11.12.2001 17:52
Looks like any specified resolution settings in a JPEG file get lost when using imageJPEG() function in a script.
I had a high resolution JPEG which i added text to with imagestringup() so my customer can print the emailed JPEG as a filled form, but printing both Graphics from Photoshop revealed that any JPEG created is downsampled to 72 dpi, while width and height is kept.
(72 dpi is the standard web resolution)
Nothing to wonder about, but maybe if you read this you dont need to scratch your head :)
pingling at idea dot net dot pl
23.10.2001 13:27
As the GD 1.8.4 manual says, the quality should be a value in the range 0-95. And this seems to be true - setting it to 100 doesn't change the default quality.
godehardt at hotmail dot com
3.07.2001 21:28
If you call imagecreatefromjpeg and load a jpeg with 75% quality and output it with imagejpeg u can specify the new quality for e.g. 90% and u can increase quality, but output will look like 75% quality picture with the only difference that the new pic is bigger.

So u should check the source quality before u alter output quality. In most cases a quality of 75% is sufficient. For previews i use 50%.

But i make a check if source quality is lower than my personal output quality, i will not chance source quality !

Hope that helps your Webserver and keeps the traffic low :-)



PHP Powered Diese Seite bei php.net
The PHP manual text and comments are covered by the Creative Commons Attribution 3.0 License © the PHP Documentation Group - Impressum - mail("TO:Reinhard Neidl",...)