imagetools.php
changeset 25 5c377ceb0e4c
child 40 bd3372a2afc1
equal deleted inserted replaced
24:d275dc8f4203 25:5c377ceb0e4c
       
     1 <?php
       
     2 
       
     3 /**
       
     4  * Greyhound - real web management for Amarok
       
     5  * Copyright (C) 2008 Dan Fuhry
       
     6  *
       
     7  * This program is Free Software; you can redistribute and/or modify it under the terms of the GNU General Public License
       
     8  * as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
       
     9  *
       
    10  * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
       
    11  * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
       
    12  */
       
    13 
       
    14 /**
       
    15  * Determines an image's filetype based on its signature.
       
    16  * @param string Path to image file
       
    17  * @return string One of gif, png, or jpg, or false if none of these.
       
    18  */
       
    19 
       
    20 function get_image_filetype($filename)
       
    21 {
       
    22   $filecontents = @file_get_contents($filename);
       
    23   if ( empty($filecontents) )
       
    24     return false;
       
    25   
       
    26   if ( substr($filecontents, 0, 8) == "\x89\x50\x4e\x47\x0d\x0a\x1a\x0a" )
       
    27     return 'png';
       
    28   
       
    29   if ( substr($filecontents, 0, 6) == 'GIF87a' || substr($filecontents, 0, 6) == 'GIF89a' )
       
    30     return 'gif';
       
    31   
       
    32   if ( substr($filecontents, 0, 2) == "\xFF\xD8" )
       
    33     return 'jpg';
       
    34   
       
    35   return false;
       
    36 }
       
    37 
       
    38 /**
       
    39  * Scales an image to the specified width and height, and writes the output to the specified
       
    40  * file. Will use ImageMagick if present, but if not will attempt to scale with GD. This will
       
    41  * always scale images proportionally.
       
    42  * 
       
    43  * Ported from Enano CMS (which is also my project)
       
    44  * 
       
    45  * @param string Path to image file
       
    46  * @param string Path to output file
       
    47  * @param int Image width, in pixels
       
    48  * @param int Image height, in pixels
       
    49  * @param bool If true, the output file will be deleted if it exists before it is written
       
    50  * @return bool True on success, false on failure
       
    51  */
       
    52 
       
    53 function scale_image($in_file, $out_file, $width = 225, $height = 225, $unlink = false)
       
    54 {
       
    55   global $db, $session, $paths, $template, $plugins; // Common objects
       
    56   
       
    57   if ( !is_int($width) || !is_int($height) )
       
    58     return false;
       
    59   
       
    60   if ( !file_exists($in_file) )
       
    61     return false;
       
    62   
       
    63   if ( preg_match('/["\'\/\\]/', $in_file) || preg_match('/["\'\/\\]/', $out_file) )
       
    64     return false;
       
    65   
       
    66   if ( file_exists($out_file) && !$unlink )
       
    67     return false;
       
    68   else if ( file_exists($out_file) && $unlink )
       
    69     @unlink($out_file);
       
    70   if ( file_exists($out_file) )
       
    71     // couldn't unlink (delete) the output file
       
    72     return false;
       
    73     
       
    74   $file_ext = substr($in_file, ( strrpos($in_file, '.') + 1));
       
    75   switch($file_ext)
       
    76   {
       
    77     case 'png':
       
    78       $func = 'imagecreatefrompng';
       
    79       break;
       
    80     case 'jpg':
       
    81     case 'jpeg':
       
    82       $func = 'imagecreatefromjpeg';
       
    83       break;
       
    84     case 'gif':
       
    85       $func = 'imagecreatefromgif';
       
    86       break;
       
    87     case 'xpm':
       
    88       $func = 'imagecreatefromxpm';
       
    89       break;
       
    90     default:
       
    91       return false;
       
    92   }
       
    93     
       
    94   // try to find convert in the PATH
       
    95   // FIXME: unix specific (won't work on windows)
       
    96   $path = ( isset($_ENV['PATH']) ) ? $_ENV['PATH'] : ( isset($_SERVER['PATH']) ? $_SERVER['PATH'] : '/usr/local/bin:/usr/bin:/bin' );
       
    97   $path = explode(':', $path);
       
    98   foreach ( $path as $dir )
       
    99   {
       
   100     if ( file_exists("$dir/convert") && is_executable("$dir/convert") )
       
   101     {
       
   102       $magick_path = "$dir/convert";
       
   103     }
       
   104   }
       
   105   
       
   106   $can_use_magick = isset($magick_path);
       
   107   $can_use_gd = (
       
   108       function_exists('getimagesize')         &&
       
   109       function_exists('imagecreatetruecolor') &&
       
   110       function_exists('imagecopyresampled')   &&
       
   111       function_exists($func)
       
   112     );
       
   113   if ( $can_use_magick )
       
   114   {
       
   115     if ( !preg_match('/^([\/A-z0-9_-]+)$/', $magick_path) )
       
   116     {
       
   117       // ImageMagick path seems screwy
       
   118       return false;
       
   119     }
       
   120     $cmdline = "\"$magick_path\" \"$in_file\" -resize \"{$width}x{$height}>\" \"$out_file\"";
       
   121     system($cmdline, $return);
       
   122     if ( !file_exists($out_file) )
       
   123       return false;
       
   124     return true;
       
   125   }
       
   126   else if ( $can_use_gd )
       
   127   {
       
   128     @list($width_orig, $height_orig) = @getimagesize($in_file);
       
   129     if ( !$width_orig || !$height_orig )
       
   130       return false;
       
   131     // calculate new width and height
       
   132     
       
   133     $ratio = $width_orig / $height_orig;
       
   134     if ( $ratio > 1 )
       
   135     {
       
   136       // orig. width is greater that height
       
   137       $new_width = $width;
       
   138       $new_height = round( $width / $ratio );
       
   139     }
       
   140     else if ( $ratio < 1 )
       
   141     {
       
   142       // orig. height is greater than width
       
   143       $new_width = round( $height / $ratio );
       
   144       $new_height = $height;
       
   145     }
       
   146     else if ( $ratio == 1 )
       
   147     {
       
   148       $new_width = $width;
       
   149       $new_height = $width;
       
   150     }
       
   151     if ( $new_width > $width_orig || $new_height > $height_orig )
       
   152     {
       
   153       // Too big for our britches here; set it to only convert the file
       
   154       $new_width = $width_orig;
       
   155       $new_height = $height_orig;
       
   156     }
       
   157     
       
   158     $newimage = @imagecreatetruecolor($new_width, $new_height);
       
   159     if ( !$newimage )
       
   160       return false;
       
   161     $oldimage = @$func($in_file);
       
   162     if ( !$oldimage )
       
   163       return false;
       
   164     
       
   165     // Perform scaling
       
   166     imagecopyresampled($newimage, $oldimage, 0, 0, 0, 0, $new_width, $new_height, $width_orig, $height_orig);
       
   167     
       
   168     // Get output format
       
   169     $out_ext = substr($out_file, ( strrpos($out_file, '.') + 1));
       
   170     switch($out_ext)
       
   171     {
       
   172       case 'png':
       
   173         $outfunc = 'imagepng';
       
   174         break;
       
   175       case 'jpg':
       
   176       case 'jpeg':
       
   177         $outfunc = 'imagejpeg';
       
   178         break;
       
   179       case 'gif':
       
   180         $outfunc = 'imagegif';
       
   181         break;
       
   182       case 'xpm':
       
   183         $outfunc = 'imagexpm';
       
   184         break;
       
   185       default:
       
   186         imagedestroy($newimage);
       
   187         imagedestroy($oldimage);
       
   188         return false;
       
   189     }
       
   190     
       
   191     // Write output
       
   192     $outfunc($newimage, $out_file);
       
   193     
       
   194     // clean up
       
   195     imagedestroy($newimage);
       
   196     imagedestroy($oldimage);
       
   197     
       
   198     // done!
       
   199     return true;
       
   200   }
       
   201   if ( file_exists($out_file) )
       
   202     return true;
       
   203   return false;
       
   204 }
       
   205