Создание эскизов картинок на PHP

Класс позволяет получить из большого изображения его уменьшенную копию - эскиз.

##############################################
# Muhammad Sohail Khan    09 August 2006
# Updated        02 Actober 2007
# sohail_meet@hotmail.com
# mr_sohail_khan@yahoo.com
##############################################

class ConvertBMP2GDClass {

function ConvertBMP2GD($src, $dest = false) {
  if(!($src_f = fopen($src, "rb"))) {
    trigger_error("Can't open $src", E_WARNING);
    return false;
  }
  if(!($dest_f = fopen($dest, "wb"))) {
    trigger_error("Can't open $dest", E_WARNING);
    return false;
  }
  $header = unpack("vtype/Vsize/v2reserved/Voffset", fread($src_f, 14));
  $info =unpack("Vsize/Vwidth/Vheight/vplanes/vbits/Vcompression/Vimagesize/Vxres/Vyres/Vncolor/Vimportant", fread($src_f, 40));
  extract($info);
  extract($header);

  if($type != 0x4D42) { // signature "BM"
    return false;
  }
  $palette_size = $offset - 54;
  $ncolor = $palette_size / 4;
  $gd_header = "";
  // true-color vs. palette
  $gd_header .= ($palette_size == 0) ? "\xFF\xFE" : "\xFF\xFF";
  $gd_header .= pack("n2", $width, $height);
  $gd_header .= ($palette_size == 0) ? "\x01" : "\x00";
  if($palette_size) {
  $gd_header .= pack("n", $ncolor);
  }
  // no transparency
  $gd_header .= "\xFF\xFF\xFF\xFF";

  fwrite($dest_f, $gd_header);

  if($palette_size) {
    $palette = fread($src_f, $palette_size);
    $gd_palette = "";
    $j = 0;
    while($j < $palette_size) {
      $b = $palette{$j++};
      $g = $palette{$j++};
      $r = $palette{$j++};
      $a = $palette{$j++};
      $gd_palette .= "$r$g$b$a";
    }
    $gd_palette .= str_repeat("\x00\x00\x00\x00", 256 - $ncolor);
    fwrite($dest_f, $gd_palette);
  }

  $scan_line_size = (($bits * $width) + 7) >> 3;
  $scan_line_align = ($scan_line_size & 0x03) ? 4 - ($scan_line_size & 0x03): 0;

  if($bits == 24) {
    $j = 0;
    $k = 1;
    $m = 2;
    $function = 'return "';
  while($j < $scan_line_size) {
    $function .= "\\0\{\$s\{$m}}\{\$s\{$k}}\{\$s\{$j}}";
    $j += 3;
    $k += 3;
    $m += 3;
  }
    $function .= '";';
  }
  else if($bits == 32) {
    $function = 'return "';
    $j = 0;
    $k = 1;
    $m = 2;
    $n = 3;
  while($j < $scan_line_size) {
    $function .= "\\0\{\$s\{$m}}\{\$s\{$k}}\{\$s\{$j}}";
    $j += 4;
    $k += 4;
    $m += 4;
    $n += 4;
  }
  $function .= '";';
  }else if($bits == 8) {
    $function = 'return $s;';
  }else if($bits == 4) {
    $j = 0;
    $function = '';
  while($j < $scan_line_size) {
    $function .= "\$b=ord(\$s\{$j});";
    $function .= "\$a[]=chr(\$b>>4);";
    $function .= "\$a[]=chr(\$b&0x0F);";
    $j++;
  }
    $function .= "return substr(implode(\$a), 0, \$width);";
  }else if($bits == 1) {
  $j = 0;
  $function = '';
  while($j < $scan_line_size) {
    $function .= "\$b=ord(\$s\{$j});";
    $function .= "\$a[]=chr((int)((\$b&0x80)!=0));";
    $function .= "\$a[]=chr((int)((\$b&0x40)!=0));";
    $function .= "\$a[]=chr((int)((\$b&0x20)!=0));";
    $function .= "\$a[]=chr((int)((\$b&0x10)!=0));";
    $function .= "\$a[]=chr((int)((\$b&0x08)!=0));";
    $function .= "\$a[]=chr((int)((\$b&0x04)!=0));";
    $function .= "\$a[]=chr((int)((\$b&0x02)!=0));";
    $function .= "\$a[]=chr((int)((\$b&0x01)!=0));\n";
    $j++;
  }
  $function .= "return substr(implode(\$a), 0, \$width);";
  }

  $f = create_function('$s, $width', $function);

  for($i = 0, $l = $height - 1; $i < $height; $i++, $l--) {
      // BMP stores scan lines starting from bottom
      fseek($src_f, $offset + (($scan_line_size + $scan_line_align) * $l));
      $scan_line = fread($src_f, $scan_line_size);
      $gd_scan_line = $f($scan_line, $width);
      fwrite($dest_f, $gd_scan_line);
      }
  fclose($src_f);
  fclose($dest_f);
  return true;
  }

  function imagecreatefrombmp($filename) {
  // use a memory stream instead of a temp file
  // where possible
  if(function_exists('stream_wrapper_register')&& stream_wrapper_register("mem", "MemoryStream")) {
    $tmp_name = "mem://GD_TMP_FILE";
    $del_tmp = false;
  }else {
    $tmp_name = tempnam("/tmp", "GD");
    $del_tmp = true;
  }
  if($this ->ConvertBMP2GD($filename, $tmp_name)) {
    $img = imagecreatefromgd($tmp_name);
    if($del_tmp) {
    unlink($tmp_name);
  }
  return $img;
  } return false;
  }
}
class MemoryStream {
  var $position;
  var $varname;
  var $buffer;
  
  function stream_open($path, $mode, $options, &$opened_path)
    {$url = parse_url($path);
     $this->varname = $url["host"];
     $this->position = 0;
     $this->buffer = @$GLOBALS[$this->varname];
     return true;
    }
  
  function stream_close()
    {$GLOBALS[$this->varname] = $this->buffer;}
  
  function stream_read($count)
    {$ret = substr($this->buffer, $this->position, $count);
     $this->position += strlen($ret);
     return $ret;
    }
  
  function stream_write($data)
    {$this->buffer .= $data;
     $this->position += strlen($data);
     return strlen($data);
    }
  
  function stream_tell()
    { return $this->position; }
  
  function stream_eof()
    { return $this->position >= strlen($this->buffer); }
  
  function stream_stat()
    { return array( 'size' => strlen($this->buffer) ); }
}
// Thumbnail of JPG,GIF,PNG,WBMP and BMP image
class thumbnail {
  var $img;

  function thumbnail($imgfile)
  {
    //detect image format
    $this->img["format"]=preg_replace("/.*\.(.*)$/","\\1",$imgfile);
    $this->img["format"]=strtoupper($this->img["format"]);
    if (strtoupper($this->img["format"])=="JPG" || strtoupper($this->img["format"])=="JPEG") {
      //JPEG
      $this->img["format"]="JPEG";
      $this->img["src"] = imagecreatefromjpeg($imgfile);
    
    } elseif ($this->img["format"]=="PNG") {
      //PNG
      $this->img["format"]="PNG";
      $this->img["src"] = @ImageCreateFromPNG ($imgfile);
    } elseif ($this->img["format"]=="GIF") {
      //GIF
      $this->img["format"]="GIF";
      $this->img["src"] = @ImageCreateFromGIF ($imgfile);
    } elseif ($this->img["format"]=="WBMP") {
      //WBMP
      $this->img["format"]="WBMP";
      $this->img["src"] = @ImageCreateFromWBMP ($imgfile);
    } else {
    return 0;
    }
    $this->img["src_width"] = imagesx($this->img["src"]);
    $this->img["src_height"] = imagesy($this->img["src"]);
    
  }
/*$save => containa a path where the thumbnail will be stored ex. sohail/a.png
 $w => width of thumbnail  
 $h => height of thumbnail
*/
  function saveImage($save="",$w,$h)
  {
      $old_x=imageSX($save);
      $old_y=imageSY($save);
      if ($old_x > $old_y) {
        $thumb_w=$w;
        $thumb_h=$old_y*($h/$old_x);
      }
      if ($old_x < $old_y) {
        $thumb_w=$old_x*($w/$old_y);
        $thumb_h=$h;
      }
      if ($old_x == $old_y) {
        $thumb_w=$w;
        $thumb_h=$h;
      }
    
    $this->img["dest_width"] = $thumb_w ;
    $this->img["dest_height"] = $thumb_h ;
    
    /* change ImageCreateTrueColor to ImageCreate if your GD not supported ImageCreateTrueColor function*/
    $this->img["des"] = imagecreatetruecolor($this->img["dest_width"],
                             $this->img["dest_height"]) ;
    
    @imagecopyresized($this->img["des"], $this->img["src"], 0, 0, 0, 0, 
            $this->img["dest_width"], $this->img["dest_height"], 
            $this->img["src_width"], $this->img["src_height"]);

    if ($this->img["format"]=="JPG" || $this->img["format"]=="JPEG") {
      //JPEG
      

      
      @imagejpeg($this->img["des"],"$save",75);
    } elseif ($this->img["format"]=="PNG") {
      //PNG
      @imagepng($this->img["des"],"$save");
    } elseif ($this->img["format"]=="GIF") {
      //GIF
      @imagegif($this->img["des"],"$save");
    } elseif ($this->img["format"]=="WBMP") {
      //WBMP
      @imagewbmp($this->img["des"],"$save");
    }
  }
}

//End of thumbnail

// Usage
// for BMP file first it converts into JPEG and then make the thumbnail

/*
  If you hgave image file other then BMP then dont use the conversion process..
  directoly pass the image to the following function

  $thumb = new thumbnail("test3.jpg");
  $thumb -> saveImage("test4.jpg","100","100")
*/

/*
To user BMP file use these functions. 
first pass the bmp file to --- imagecreatefrombmp("untitled3.bmp");

Example
$objBmpToJpg = new ConvertBMP2GDClass();
$img = $objBmpToJpg -> imagecreatefrombmp("untitled3.bmp");
imagejpeg($img,"test3.jpg");
*/
//Calling Thumbnail for JPEG , GIF , PNG files
$thumb = new thumbnail("test3.jpg");
$thumb -> saveImage("test4.jpg","400","400")

.