Index: imageapi_imagemagick.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/imageapi/imageapi_imagemagick.module,v
retrieving revision 1.17.2.5
diff -d -u -r1.17.2.5 imageapi_imagemagick.module
--- imageapi_imagemagick.module	29 May 2009 17:48:32 -0000	1.17.2.5
+++ imageapi_imagemagick.module	18 May 2010 18:22:22 -0000
@@ -127,9 +127,65 @@
     $bgcolor = str_replace('0x', '#', $bgcolor);
   }
   $image->ops[] = '-background '. escapeshellarg($bgcolor) .' -rotate '. (float) $degrees;
+
+  // Need to update the dimensions for later operations in the pipeline
+  // otherwise (eg) rotate then scale is badly wrong.
+  $dimensions = imageapi_imagemagick_calculate_rotated_dimensions($image->info['width'], $image->info['height'], $degrees);
+  $image->info['width'] = $dimensions['width'];
+  $image->info['height'] = $dimensions['height'];
   return TRUE;
 }
 
+/**
+ * Calculate the new dimensions of a rotated image.
+ *
+ * Given the dimensions of a box, and an angle, return the dimensions of a new
+ * containing box.
+ *
+ * @return a named array containing values for width and height.
+ */
+function imageapi_imagemagick_calculate_rotated_dimensions($width, $height, $degrees) {
+  // There may be several maths short cuts, eg matrices,
+  // but doing it the long way like this is clear code and geometry.
+  // Compressing things just made it 'clever' in a bad way.
+  //
+  // @see stackoverflow.com/questions/622140/calculate-bounding-box-coordinates-from-a-rotated-rectangle-picture-inside
+  //
+  $theta = deg2rad($degrees);
+  // Set up a box.
+  $points = array(
+    array(0, 0),
+    array($width, 0),
+    array(0, $height),
+    array($width, $height),
+  );
+  $bounding_box = array(
+    'left'   => 0,
+    'right'  => 0,
+    'top'    => 0,
+    'bottom' => 0,
+  );
+  // Rotate each point in the box
+  foreach ($points as $p => $point) {
+    $x = $point[0];
+    $y = $point[1];
+    $new_x = ($x)*cos($theta)+($y)*sin($theta);
+    $new_y = ($x)*sin($theta)+($y)*cos($theta);
+    // Note the bounds
+    $bounding_box['left'] = min($bounding_box['left'], $new_x);
+    $bounding_box['right'] = max($bounding_box['right'], $new_x);
+    $bounding_box['top'] = min($bounding_box['top'], $new_y);
+    $bounding_box['bottom'] = max($bounding_box['bottom'], $new_y);
+  }
+
+  // And how big is the new box?
+  $dimensions = array(
+    'width' => (int)abs($bounding_box['right'] - $bounding_box['left']),
+    'height' => (int)abs($bounding_box['bottom'] - $bounding_box['top']),
+  );
+  return $dimensions;
+}
+
 function imageapi_imagemagick_image_sharpen(&$image, $radius, $sigma, $amount, $threshold) {
   $unsharp_arg = $radius .'x'. $sigma .'+'. $amount/100 .'+'. $threshold;
   $image->ops[] = '-unsharp '. $unsharp_arg;
