Share Pastebin
Guest
Public paste!

saka

By: a guest | Mar 18th, 2010 | Syntax: PHP | Size: 5.22 KB | Hits: 54 | Expires: Never
Copy text to clipboard
  1. <?php
  2.  
  3.  
  4. $im = open_image("test.png");
  5.  
  6. /*
  7. // this failed miserably...
  8. $trans = imagecolorallocatealpha($im,200,200,200,127);
  9. $rotated = imagerotate($im, 30, $trans);
  10. */
  11.  
  12. // this is a triumph!
  13. imagerotatealpha($im, 30);
  14.  
  15. header('Content-type: image/png');
  16. imagepng($im);
  17.  
  18.  
  19.  
  20. // imagerotatealpha($im,$angle) takes the image specified by $im and rotates it $angle degrees counter-clockwise, with unfilled areas alpha transparent
  21. // returns a two-element array with the width and height of the resulting image
  22. function imagerotatealpha(&$im, $angle, $upscale=3) {
  23.         $simple = ($angle % 90 == 0)?true:false; // don't want to upscale for simple rotations
  24.         $angle = deg2rad($angle);
  25.         $w = imagesx($im);
  26.         $h = imagesy($im);
  27.        
  28.         if ($upscale > 1 and !$simple) {
  29.                 // create upscale for sampling
  30.                 $im_upscaled = imagecreatetruecolor($w*$upscale,$h*$upscale);
  31.                 imagealphablending($im_upscaled, false);
  32.                 imagesavealpha($im_upscaled, true);
  33.                 $trans = imagecolorallocatealpha($im_upscaled,255,255,255,127); // white, fully transparent
  34.                 imagefill($im_upscaled, 0, 0, $trans);
  35.                
  36.                 imagecopyresampled($im_upscaled, $im, 0, 0, 0, 0, $upscale*$w, $upscale*$h, $w, $h);
  37.                
  38.                 imagedestroy($im); $im = $im_upscaled;
  39.                 $w *= $upscale; $h *= $upscale;
  40.         }
  41.  
  42.         $rw = round( $w*abs(cos($angle))+abs($h*sin($angle)) );
  43.         $rh = round( $w*abs(sin($angle))+abs($h*cos($angle)) );
  44.         $cx = ($w-1)/2;
  45.         $cy = ($h-1)/2;
  46.         $rcx = ($rw-1)/2;
  47.         $rcy = ($rh-1)/2;
  48.  
  49.         // new image to hold rotated version
  50.         $rotated = imagecreatetruecolor($rw,$rh);
  51.         imagealphablending($rotated,false);
  52.         imagesavealpha($rotated,true);
  53.         $trans = imagecolorallocatealpha($rotated,255,255,255,127); // white, fully transparent
  54.         imagefill($rotated, 0, 0, $trans);
  55.        
  56.         // sample the original at the point where the new image would be if rotated the other direction (avoids gaps)
  57.         for($y=0; $y < $rh; $y++) {
  58.                 for($x=0; $x < $rw; $x++) {
  59.                         $rx = $cx+($x-$rcx)*cos($angle)-($y-$rcy)*sin($angle);
  60.                         $ry = $cy+($x-$rcx)*sin($angle)+($y-$rcy)*cos($angle);
  61.                         // if inside bounds of original image, then copy
  62.                         if($rx<$w and $rx>=0 and $ry<$h and $ry>=0)
  63.                                 imagecopy($rotated,$im,$x,$y,$rx,$ry,1,1); // imagecopy floors the values
  64.                 }
  65.         }
  66.        
  67.         // discard old image
  68.         imagedestroy($im);
  69.         $im = $rotated;
  70.        
  71.         if ($upscale > 1 and !$simple) {
  72.                 // now let's downscale our rotated image back to normal
  73.                 $final_w = round($rw/$upscale);
  74.                 $final_h = round($rh/$upscale);
  75.                 $im_final = imagecreatetruecolor($final_w, $final_h);
  76.                 imagealphablending($im_final, false);
  77.                 imagesavealpha($im_final, true);
  78.                 $trans = imagecolorallocatealpha($im_final,255,255,255,127); // white, fully transparent
  79.                 imagefill($im_final, 0, 0, $trans);
  80.                
  81.                 imagecopyresampled($im_final, $im, 0, 0, 0, 0, $final_w, $final_h, $rw, $rh);
  82.                 // discard rotated upscale
  83.                 imagedestroy($im);
  84.                 $im = $im_final;
  85.                 $rw = $final_w; $rh = $final_h;
  86.         }
  87.        
  88.         return array($rw, $rh);
  89. }
  90.  
  91.  
  92. /*
  93. //this is a copy of above without the upscale, so it's easier to understand:
  94.  
  95. // imagerotatealpha($im,$angle) takes the image specified by $im and rotates it $angle degrees counter-clockwise, with unfilled areas alpha transparent
  96. function imagerotatealpha(&$im, $angle) {
  97.         $angle = deg2rad($angle);
  98.         $w = imagesx($im);
  99.         $h = imagesy($im);
  100.         $rw = round( $w*abs(cos($angle))+abs($h*sin($angle)) );
  101.         $rh = round( $w*abs(sin($angle))+abs($h*cos($angle)) );
  102.         $cx = ($w-1)/2;
  103.         $cy = ($h-1)/2;
  104.         $rcx = ($rw-1)/2;
  105.         $rcy = ($rh-1)/2;
  106.  
  107.         $rotated = imagecreatetruecolor($rw,$rh);
  108.         imagealphablending($rotated,false);
  109.         imagesavealpha($rotated,true);
  110.         $trans = imagecolorallocatealpha($rotated,255,255,255,127); // white, fully transparent
  111.         imagefill($rotated, 0, 0, $trans);
  112.        
  113.         // sample the original at the point where the new image would be if rotated the other direction (avoids gaps)
  114.         for($y=0; $y < $rh; $y++) {
  115.                 for($x=0; $x < $rw; $x++) {
  116.                         $rx = $cx+($x-$rcx)*cos($angle)-($y-$rcy)*sin($angle);
  117.                         $ry = $cy+($x-$rcx)*sin($angle)+($y-$rcy)*cos($angle);
  118.                         // if not outside bounds of original image, then copy
  119.                         if($rx<$w and $rx>=0 and $ry<$h and $ry>=0)
  120.                                 imagecopy($rotated,$im,$x,$y,$rx,$ry,1,1); // imagecopy floors the values
  121.                 }
  122.         }
  123.        
  124.         imagedestroy($im);
  125.         $im = $rotated;
  126.        
  127.         return array($rw,$rh);
  128. }
  129. */
  130.  
  131. // overlay_image($overlaypath,$x,$y) opens the image at $imagepath and overlays it onto $sigimage at position ($x, $y)
  132. // most image types should work, but 24-bit/true color PNG is recommended if you need transparency
  133. function overlay_image($overlaypath,$x=0,$y=0) {
  134.         global $sigimage;
  135.         $overlay = open_image($overlaypath); // open any image
  136.         imagecopy($sigimage, $overlay, $x, $y, 0, 0, imagesx($overlay), imagesy($overlay)); // overlay onto our base image
  137.         @imagedestroy($overlay); // clean up memory, since we don't need the overlay image anymore
  138. }
  139.  
  140. // open_image($path) will load an image into memory so we can work with it, and return an error if we fail
  141. function open_image($path) {
  142.         if (!is_string($path)) return $path; // XXX assume binary data is a gd image already
  143.         $image = @imagecreatefromstring(file_get_contents($path));
  144.         if (!$image) die("could not open image ($path) make sure it exists");
  145.         imagealphablending($image,true); imagesavealpha($image,true); // preserve transparency
  146.         return $image;
  147. }
  148.  
  149. ?>