[ Index ] |
PHP Cross Reference of phpwcms V1.4.3 _r380 (23.11.09) |
[Summary view] [Print] [Text view]
1 <?php 2 /****************************************************************************** 3 * 4 * Purpose: This is Image Processor core script. 5 * It contains the Image Processor class 6 * File: ss_image.php 7 * Author: Yuriy Horobey, SmiledSoft.com 8 * Copyright: Yuriy Horobey, SmiledSoft.com 9 * Contact: http://smiledsoft.com/ 10 * 11 * Please do not remove this notice. 12 * 13 * License information: 14 * this version of ss_image.class is a special licenced version for 15 * using inside of phpwcms only. There is no license for forked versions. 16 * It is NOT released under the GPL and it is NOT FREE. 17 * 18 *****************************************************************************/ 19 /* 20 * 2005.02.05 Oliver Georgi 21 * - function set_parameter(JPEG_QUALITY, USE_GD2, USE_COLOR_NAMES) implemented 22 * - $cfg is no longer a global var - and no array anymore 23 * - ss_image.config.php is obsolete with this too 24 * - all $cfg var are $this->var 25 * 26 *****************************************************************************/ 27 28 29 //require_once(dirname(__FILE__)."/ss_image.config.php"); 30 31 class ss_image{ 32 var $img_original; 33 var $img_changed; 34 var $img_original_type; //the format of original image. only has meaning when created from file 35 36 // 2005.02.05 -start- 37 // all "global $cfg" -> "//$global $cfg" 38 // $cfg[] replaced by following "real" var 39 var $cfg_JPEG_QUALITY = 80; 40 var $cfg_USE_GD2 = true; 41 var $cfg_USE_COLOR_NAMES = true; 42 43 var $trans_rgb = array(); //RGB for transparent color for gifs and PNG 44 45 function set_parameter($jpeg_quality=80, $use_gd2=true, $use_color_names=true) { 46 $this->cfg_JPEG_QUALITY = $jpeg_quality; 47 $this->cfg_USE_GD2 = $use_gd2; 48 $this->cfg_USE_COLOR_NAMES = $use_color_names; 49 } 50 51 52 // a simple workaround in case GD Lib has wrong permissions 53 function _tryNullByteFile($where) 54 { 55 if($fp = @fopen($where, "w+b")) { 56 fwrite($fp, ''); 57 fclose($fp); 58 return true; 59 } else { 60 return false; 61 } 62 } 63 64 65 66 function ss_image( 67 $src, //source of the image. Currently can be file or string 68 // use string if your image comes from the database 69 //or is generated by other script 70 $src_kind="f" //"f" -- $src is path to file 71 //"u"--uploaded file, in this case $src is name 72 //of form field <input name='HERE' type='file' ...> 73 //"s" -- $src is a string containing valid image stream 74 //"s64"--$src is base64 encoded 75 ){ 76 //global $_FILES; 77 $this->img_original_type=''; 78 switch(strtoupper(trim($src_kind))){ 79 case "S64": 80 //base 64 encoding -- decode and proceed to create from string 81 $src = base64_decode($src); 82 case "S": 83 //create from string 84 85 $this->img_original = imagecreatefromstring($src); 86 87 break; 88 case "U": 89 $src=$_FILES[$src]['tmp_name']; 90 91 case "F": 92 default: 93 //create from file. this is also the default behaviour 94 $img_info=getimagesize($src); 95 //to prevent divide by zero error in resizing 96 $this->img_original_type=$img_info[2]; 97 switch($img_info[2]){//2nd index contains type information 98 case "1"://GIF supported was canceled since GD1.6 and is inspecting 99 //to be back in middle of 2004 100 $this->img_original = imagecreatefromgif($src); 101 102 break; 103 104 case "2"://JPEG 105 $this->img_original = imagecreatefromjpeg($src); 106 break; 107 108 case "3"://PNG 109 $this->img_original = imagecreatefrompng($src); 110 break; 111 112 case "15"://WBMP 113 $this->img_original = imagecreatefromwbmp($src); 114 break; 115 116 case "16"://XBM 117 $this->img_original = imagecreatefromxbm($src); 118 break; 119 120 default://well format for which we dont have imagecreatefromXX() function 121 //lets try create from GD? most lieklly it will fail, 122 //but what to do? 123 124 $this->img_original = imagecreatefromGD2($src); 125 126 break; 127 128 } 129 break; 130 } 131 if(!$this->img_original) { 132 return null; 133 } else { 134 $transparency_color_index = imagecolortransparent($this->img_original); 135 if($transparency_color_index>-1){ 136 $this->trans_rgb = @imagecolorsforindex($this->img_original,$transparency_color_index); 137 138 } else { 139 $this->trans_rgb = array(); 140 } 141 } 142 } 143 144 145 function output( 146 147 $where="", //specify here file name where to output, or 148 //leave blank to output directly to browser 149 $what="c", // original image or changed imege? 150 //"o"-original "c"-changed 151 $method="" // how to output? 152 //JPG, JPEG, GIF, PNG, XBMP etc, 153 //see get_supported_types() 154 ){ 155 156 $method = strtoupper(trim($method)); 157 if(!$method){ 158 $method=$this->img_original_type; 159 } 160 161 $what = strtoupper(trim($what)); 162 //what to output? original or changed? 163 if($what=="O") { 164 $image = $this->img_original; 165 } else { 166 $image = $this->img_changed; 167 } 168 169 switch($method){ 170 case "1": 171 case "GIF": 172 173 if(!$where){ 174 header("Content-Type: image/gif"); 175 imagegif($image); 176 }else{ 177 if(!imagegif($image, $where)) { 178 $this->_tryNullByteFile($where); 179 imagegif($image, $where); 180 } 181 } 182 break; 183 case "3"://PNG 184 case "PNG": 185 @imagesavealpha($imgage, true); 186 if(!$where){ 187 header("Content-Type: image/png"); 188 imagepng($image, '', 9); 189 } else { 190 if(!imagepng($image, $where, 9)) { 191 $this->_tryNullByteFile($where); 192 imagepng($image, $where, 9); 193 } 194 } 195 break; 196 //Note: WBMP support is only available if PHP was compiled against GD-1.8 or later 197 case "15"://WBMP 198 case "WBMP": 199 if(!$where){ 200 header("Content-Type: image/wbmp"); 201 imagewbmp($image); 202 } else { 203 if(!imagewbmp($image, $where)) { 204 $this->_tryNullByteFile($where); 205 imagewbmp($image, $where); 206 } 207 } 208 break; 209 case "16"://XBM 210 case "XBM": 211 /* 212 Warning {from manual!} 213 This function is currently not documented; only the argument list is available. 214 Note: This function is only available if PHP is compiled with the bundled version of the GD library. 215 216 */ 217 if(!$where){ 218 header("Content-Type: image/xbm"); 219 imagexbm($image); 220 } else { 221 if(!imagexbm($image, $where)) { 222 $this->_tryNullByteFile($where); 223 imagexbm($image, $where); 224 } 225 } 226 break; 227 case "2": 228 case "JPEG": 229 case "JPG": 230 default: 231 if(!$where) { 232 header("Content-Type: image/jpeg"); 233 imagejpeg($image, "", $this->cfg_JPEG_QUALITY); 234 } else { 235 if(!imagejpeg($image, $where, $this->cfg_JPEG_QUALITY)) { 236 $this->_tryNullByteFile($where); 237 imagejpeg($image, $where, $this->cfg_JPEG_QUALITY); 238 } 239 } 240 break; 241 } 242 243 244 } 245 246 247 function get_supported_types(){ 248 $bits = imagetypes(); 249 $res = ""; // variable for result 250 if($bits & IMG_PNG) $res .= "PNG "; 251 if($bits & IMG_GIF) $res .= "GIF "; 252 if($bits & IMG_JPG) $res .= "JPG "; 253 if($bits & IMG_JPEG) $res .= "JPEG "; 254 if($bits & IMG_WBMP) $res .= "WBMP "; 255 if($bits & IMG_XPM) $res .= "XPM "; 256 $res = trim($res); 257 return $res; 258 259 } 260 function commit(){ 261 //copy changed image to original so all next transformation will be 262 // based on already made ones. 263 @imagedestroy($this->img_original); 264 $this->img_original = $this->img_changed; 265 $this->img_changed=NULL; 266 267 } 268 //free memory 269 function destroy(){ 270 @imagedestroy($this->img_original); 271 @imagedestroy($this->img_changed); 272 } 273 274 275 function get_w( $which="o" ){ 276 // return width of: o-original c-changed image 277 return trim(strtoupper($which))=="O" ? imagesx($this->img_original) : imagesx($this->img_changed); 278 } 279 280 function get_h( $which="o" ){ 281 // return height of: o-original c-changed image 282 return trim(strtoupper($which))=="O" ? imagesy($this->img_original) : imagesy($this->img_changed); 283 } 284 285 286 287 //smart imagecreate() function 288 function createimage($width, $height){ 289 290 if($this->trans_rgb) { 291 $image = imagecreate($width,$height); 292 293 $trans_clr=imagecolorallocate($image,$this->trans_rgb['red'],$this->trans_rgb['green'],$this->trans_rgb['blue']); 294 imagefilledrectangle($image,0,0,$width,$height,$trans_clr); 295 imagecolortransparent($image,$trans_clr); 296 } else { 297 $image = $this->cfg_USE_GD2 ? imagecreatetruecolor($width,$height) : imagecreate($width,$height); 298 } 299 return $image; 300 } 301 302 //this will set transparent color to whatewer color is pixel with given x, y 303 function set_transparentcolor($x=0,$y=0){ 304 $color=imagecolorat($this->img_original,$x,$y); 305 return imagecolortransparent($this->img_original,$color); 306 } 307 308 309 function get_color($color, //color in hex form like FF00FF without leading # or anything like that 310 //Just RRGGBB 311 //if use_color_names is true you may specify color by its web standard name 312 $dest="c" // For which image allocate the color? o-original, c-changed 313 //default is C - becaus usually we do something with changed image 314 ){ 315 316 317 318 if($this->cfg_USE_COLOR_NAMES){ 319 //translate color name to RGB hex string 320 require_once(dirname(__FILE__)."/ss_image.colortohex.php"); 321 $color=colortohex($color); 322 } 323 324 // we are not going to check this 325 $r = hexdec("0x".substr($color, 0,2)); 326 $g = hexdec("0x".substr($color, 2,2)); 327 $b = hexdec("0x".substr($color, 4,2)); 328 329 if(strtoupper(trim($dest))=="O") { 330 $img = $this->img_original; 331 } else { 332 $img = $this->img_changed; 333 } 334 $c = imagecolorallocate($img, $r, $g, $b); 335 return $c; 336 337 } 338 339 ############################################################ 340 # 341 # Here are Image Processing functions 342 # They are independant one from each other so you can delete those which 343 # you are not going to use to save space 344 # 345 346 347 #resizer function 348 function set_size( $desired_width, //new width 349 $desired_height, //new height 350 //if one of these parameters is set to * that means that we dont care 351 //about mode and result image will be set to fit other paramter 352 // example if desired_width=="*" and _height="108" -- result image will 353 // be 108 of height no matter which will be the width, W to H ratio 354 // will remain 355 // in strange case when both of them == "*" then we just copy the image 356 357 $mode="-" //how to resize? 358 //"e" or "0" -- exactly to given dimensions, 359 // "0" is here for compatibility with ImageResizer 5.x 360 //in this case geometrical distortions may occure. 361 //"+"- resize to cover rectangle with given W & H 362 //"-"- resize to fit into rectangle with given W & H 363 //in last two cases no geometrical distortions will occure 364 //new in 6.3 365 // "--" -- resize to fit into rectangle, but only if the image is larger than it. 366 //so if image is laready smaller it will not resize 367 // "++" -- resize to cover the rectangle, but only if the image is smaller than it. 368 //if image is already larger than given rectangle by width _and_ height -- no resize. 369 370 ){ 371 372 //prepare parameteres 373 $res = false; 374 $new_img = NULL; 375 $mode=strtoupper(trim($mode)); 376 $desired_width = trim($desired_width); 377 $desired_height = trim($desired_height); 378 379 $org_w = $this->get_w(); 380 $org_h = $this->get_h(); 381 382 383 if( $mode=="--" ){ 384 if (($org_w <= $desired_width ) and ($org_h <= $desired_height ) ){ 385 // image is already smaller than the given region do not resize. 386 387 $desired_width="*"; 388 $desired_height="*"; 389 390 391 } else { 392 $mode ="-"; 393 } 394 395 } 396 397 398 if( $mode=="++" ){ 399 if (($org_w >= $desired_width ) and ($org_h >= $desired_height ) ){ 400 // image is already larger than the given region do not resize. 401 402 $desired_width="*"; 403 $desired_height="*"; 404 405 406 } else { 407 $mode ="+"; 408 } 409 410 } 411 412 413 //calculate new sizes: 414 if($desired_width=="*" and $desired_height=="*"){ 415 //no resizing just copy parameters: 416 $this->img_changed = $this->createimage($this->get_w(), $this->get_h()); 417 return imagecopy($this->img_changed, $this->img_original, 0, 0, 0, 0, $this->get_w(), $this->get_h()); 418 419 } else { 420 421 if(!$org_h) { 422 $org_h=1; // prevent divide by zero 423 } 424 425 $ratio = $org_w / $org_h; 426 427 428 if($desired_width=="*"){ 429 //we dont care what will be new width, image must be of given height 430 //and width should be according to the ration 431 $desired_height = (int)$desired_height; 432 $new_w = $desired_height*$ratio; 433 $new_h = $desired_height; 434 }elseif($desired_height=="*"){ 435 //we dont care what will be new height, image must be of given width 436 //and height should be according to the ration 437 438 $desired_width = (int)$desired_width; 439 $new_w = $desired_width; 440 $new_h = $desired_width/$ratio; 441 }else{ 442 // the desired width and height are given as well as resizing mode 443 // lets calculate new width and height.. 444 $desired_width = (int)$desired_width; 445 $desired_height = (int)$desired_height; 446 if(!$desired_width) $desired_width=1; 447 if(!$desired_height)$desired_height=1; 448 449 switch($mode){ 450 case "0":// compatibility with hft_image 5.x series 451 case "E"://resize to fit exactly 452 $new_w=$desired_width; 453 $new_h=$desired_height; 454 break; 455 case "+"://overlap given region 456 //suppose $new_w will be $desired_width 457 $new_h = $desired_width / $ratio; 458 if($new_h>=$desired_height) $new_w=$desired_width; 459 else{//wrong idea.. right idea was new_h=$desired_height 460 $new_w=$ratio*$desired_height; 461 $new_h=$desired_height; 462 } 463 break; 464 case "-": //fit into given region 465 default: 466 //suppose $new_w will be $desired_width 467 $new_h = $desired_width / $ratio; 468 if($new_h<=$desired_height) $new_w=$desired_width; 469 else{//wrong idea.. right idea was new_h=$desired_height 470 $new_w=$ratio*$desired_height; 471 $new_h=$desired_height; 472 } 473 474 break; 475 } 476 } 477 $new_img = $this->createimage($new_w,$new_h); 478 479 if($this->cfg_USE_GD2){ 480 //use GD2 -- better quality, but not all server have proper installation of it. 481 482 483 $res= imagecopyresampled( 484 485 $new_img, // destination 486 $this->img_original, //source 487 0,0,// destination coords 488 0,0,//source coords 489 $new_w,//new width 490 $new_h,//new height 491 $org_w, 492 $org_h 493 ); 494 495 496 } else { 497 //worse quality but better compatibility 498 499 500 $res = imagecopyresized( 501 $new_img, // destination 502 $this->img_original, //source 503 0,0,// destination coords 504 0,0,//source coords 505 $new_w,//new width 506 $new_h,//new height 507 $org_w, 508 $org_h 509 ); 510 511 } 512 } 513 514 if($res){ 515 $this->img_changed = $new_img; 516 } 517 return $res; 518 519 } 520 521 522 523 524 function rotate( 525 $a, //angle in degrees 0-359,999..99 526 $bkcolor="#FFFFFF" // background color for zone not covered with rotation 527 // in html format 'RRGGBB' -- Hex digits like 'FF0000' - red 528 // 'FFFFFF' -- white etc or use word description like red green white 529 // blue black .. see below 530 ){ 531 532 //process color 533 534 $c=$this->get_color($bkcolor,"o"); 535 536 $this->img_changed = imagerotate($this->img_original, $a, $c); 537 538 } 539 540 541 function gray(){ //this will convert image to B/W 542 @imagedestroy($this->img_changed); 543 544 545 $this->img_changed=$this->createimage($this->get_w(), $this->get_h()); //not true color!! 546 //it won't produce grayscale!! 547 548 //allocate gray scale 549 for ($c = 0; $c < 256; $c++) { 550 ImageColorAllocate($this->img_changed, $c,$c,$c); 551 } 552 553 554 imagecopymerge( $this->img_changed, 555 $this->img_original, 556 0,0,//destination x y 557 0,0,//source x y 558 $this->get_w(), //source sizes 559 $this->get_h(), 560 100//no alpha -- 100% copy 561 ); 562 563 } 564 565 566 567 function watermark( 568 $src, // source of watermark can be file, string, base64 encoded string 569 // see create() 570 $transparency=75, // how visible should be watermark? 0-100 571 //(invisible-fullvisible) 572 573 $x=0, 574 $y=0, //where to place the watermark -- x,y are its top-left corner 575 576 577 $makegray=false, // should watermark be grayed? 578 579 //rare used params: 580 $src_kind="f", // same as in create() 581 582 $desired_w="*",//watermark can be resized 583 $desired_h="*" // values same as in set_Size() 584 585 ){ 586 587 $img_watermark = new ss_image($src, $src_kind); 588 if(trim($desired_w) != "*" or trim($desired_h) !="*" ){ 589 $img_watermark->set_size($desired_w, $desired_h); 590 $img_watermark->commit(); 591 } 592 593 @imagedestroy($this->img_changed); 594 $this->img_changed= $this->createimage($this->get_w(),$this->get_h()); 595 imagecopy($this->img_changed,$this->img_original,0,0,0,0,$this->get_w(),$this->get_h()); 596 597 598 imagealphablending($this->img_changed, true); 599 imagealphablending($img_watermark->img_original, true); 600 601 if($makegray){ 602 $img_watermark->gray(); 603 $img_watermark->commit();//save changes 604 } 605 606 $img_watermark->set_transparentcolor(); 607 608 $res= imagecopymerge( $this->img_changed, 609 $img_watermark->img_original, 610 $x,$y,//destination x y 611 0,0,//source x y 612 $img_watermark->get_w(), //source sizes 613 $img_watermark->get_h(), 614 $transparency 615 ); 616 617 618 619 $img_watermark->destroy(); 620 621 return $res; 622 623 624 625 } 626 627 //crop() will take rectangular part of the image and erase everything outside it. 628 //the rectangle is specified by $x,$y and has sizes $width,$height 629 //if $delprev==true result image will have size $width by $height otherwise the rectangular portion 630 // of the original image will be copied over the existing "changed image" 631 //for example if you have resized the original image -- resized copy is stored in $this->img_changed resource variable 632 // 633 function crop($x, $y, //coordinates of left top corner of the rectangle 634 $width, $height //sizes of the rectangle 635 ){ 636 637 //lets change the height width of the specified crop region if it is out of original image bounds 638 $org_w = $this->get_w(); 639 $org_h = $this->get_h(); 640 641 if($x+$width>$org_w)$width=$org_w-$x; 642 if($y+$height>$org_h)$height=$org_h-$y; 643 644 @ImageDestroy($this->img_changed); 645 $this->img_changed= $this->createimage($width,$height); 646 647 return imagecopy($this->img_changed, $this->img_original, 0,0,$x,$y, $width, $height); 648 649 } 650 651 //write a text over the image 652 function text($text, //what to write? 653 $x=0,$y=0, //where? x,y=upper left corner of the text rectangle 654 $color="000000",//color -- HTML syntax here like FF0000- red, or if "use_color_names" config variable is true 655 //then you can use standard color names like blue, white, etc 656 $font=3,//either number or ttf file name. Number 1-5 are built-in fonts 657 //you can create and load your own font, see PHP manual for this, imageloadfont() will return you 658 //an identifier which you can put here 659 //if you will specify here True Type font file name here we will use it 660 $size=12.0,//TTF font size, only used with TTF fonts 661 $angle=0//angle of writting -0 left to right, 90 bottom to top 180- right to left etc 662 //only used with TTF fonts 663 ){ 664 //prepare changed image 665 @imagedestroy($this->img_changed); 666 $this->img_changed= $this->createimage($this->get_w(),$this->get_h()); 667 668 imagecopy($this->img_changed,$this->img_original,0,0,0,0,$this->get_w(),$this->get_h()); 669 $color=$this->get_color($color); 670 671 //which writting method to use? TTF or standard? 672 if(intval($font)){ 673 $font=(int)$font; 674 return imagestring($this->img_changed,$font,$x,$y,$text,$color); 675 }else{ 676 //this is TTF 677 imagettftext ( $this->img_changed, $size, $angle, $x, $y, $color, $font, $text); 678 } 679 680 } 681 682 function shadow( 683 $dx=8, //ofset by x 684 $dy=8, //ofset by y 685 $transparency=75, // how transparent should be shaddow 0..100 0-grayed mirror of the image 100-invisible, transparent 686 $bkcolor="FFFFFF" // color for background for uncovered zones, if CFG allows you may use word names like white yellow etc 687 ){ 688 689 $this->gray(); 690 $img_gray = $this->img_changed; 691 692 693 $new_w =$this->get_w()+abs($dx); 694 $new_h=$this->get_h()+abs($dy); 695 $this->img_changed= $this->createimage($new_w,$new_h); 696 697 $color= $this->get_color($bkcolor); 698 699 imagefilledrectangle($this->img_changed, 0,0, $new_w,$new_h, $color); 700 701 if($dx<0){ 702 $org_x=-$dx; 703 $shd_x = 0; 704 }else{ 705 $org_x=0; 706 $shd_x = $dx; 707 } 708 if($dy<0){ 709 $org_y=-$dy; 710 $shd_y = 0; 711 }else{ 712 $org_y=0; 713 $shd_y = $dy; 714 } 715 716 imagealphablending($this->img_changed, true); 717 718 719 //the shadow 720 imagecopymerge($this->img_changed,$img_gray,$shd_x,$shd_y,0,0,$this->get_w(),$this->get_h(),$transparency); 721 imagedestroy($img_gray); 722 723 //the original 724 imagecopy($this->img_changed,$this->img_original,$org_x,$org_y,0,0,$this->get_w(),$this->get_h()); 725 726 727 } 728 729 //this function will make image looking sharper. It is especially useful for thumbnails 730 function unsharp($amount=80, $radius=0.5, $threshold=3){ 731 require_once(dirname(__FILE__)."/ss_image.unsharp.php"); 732 return $this->img_changed = UnsharpMask($this->img_original, $amount, $radius, $threshold); 733 } 734 735 736 function mask( 737 $src, // source of watermark can be file, string, base64 encoded string 738 // see create() 739 $transparency=100, // how visible should be mask? 0-100 740 //(invisible-fullvisible) 741 742 $transparent_x=0, 743 $transparent_y=0, //coordinates of pixel which color will be considered to be "transparent" 744 745 746 //rare used params: 747 $src_kind="f" // same as in create() 748 749 ){ 750 751 $img_mask = new ss_image($src, $src_kind); 752 753 @imagedestroy($this->img_changed); 754 $this->img_changed= $this->createimage($this->get_w(),$this->get_h()); 755 imagecopy($this->img_changed,$this->img_original,0,0,0,0,$this->get_w(),$this->get_h()); 756 757 758 imagealphablending($this->img_changed, true); 759 imagealphablending($img_mask->img_original, true); 760 761 762 $img_mask->set_transparentcolor($transparent_x,$transparent_y); 763 764 $res= imagecopymerge( $this->img_changed, 765 $img_mask->img_original, 766 $x,$y,//destination x y 767 0,0,//source x y 768 $img_mask->get_w(), //source sizes 769 $img_mask->get_h(), 770 $transparency 771 ); 772 773 $img_mask->destroy(); 774 775 return $res; 776 777 } 778 779 } 780 781 //class-------------------------------------------------------------------------------------------------------------------- 782 783 ?>
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Wed Dec 30 05:55:15 2009 | Cross-referenced by PHPXref 0.7 |