Index: includes/image.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/image.inc,v
retrieving revision 1.40
diff -u -r1.40 image.inc
--- includes/image.inc	16 Jul 2010 02:39:38 -0000	1.40
+++ includes/image.inc	7 Dec 2010 14:12:45 -0000
@@ -166,6 +166,17 @@
  * @see image_crop()
  */
 function image_scale_and_crop(stdClass $image, $width, $height) {
+
+  //recalculate if the units are percent
+  if(substr($width,-1)=="%"){
+    $width=str_replace("%","",$width);
+    $width=round($image->info['width']*$width/100);
+  }
+  if(substr($height,-1)=="%"){
+    $height=str_replace("%","",$height);
+    $height=round($image->info['height']*$height/100);
+  }
+
   $scale = max($width / $image->info['width'], $height / $image->info['height']);
   $x = ($image->info['width'] * $scale - $width) / 2;
   $y = ($image->info['height'] * $scale - $height) / 2;
@@ -201,7 +212,17 @@
  */
 function image_scale(stdClass $image, $width = NULL, $height = NULL, $upscale = FALSE) {
   $aspect = $image->info['height'] / $image->info['width'];
-
+  
+  //recalculate if the units are percent
+  if(substr($width,-1)=="%"){
+    $width=str_replace("%","",$width);
+    $width=round($image->info['width']*$width/100);
+  }
+  if(substr($height,-1)=="%"){
+    $height=str_replace("%","",$height);
+    $height=round($image->info['height']*$height/100);
+  }
+  
   if ($upscale) {
     // Set width/height according to aspect ratio if either is empty.
     $width = !empty($width) ? $width : $height / $aspect;
@@ -245,6 +266,18 @@
  * @see image_gd_resize()
  */
 function image_resize(stdClass $image, $width, $height) {
+  
+  //recalculate if the units are percent
+  if(substr($width,-1)=="%"){
+    $width=str_replace("%","",$width);
+    $width=round($image->info['width']*$width/100);
+  }
+  if(substr($height,-1)=="%"){
+    $height=str_replace("%","",$height);
+    $height=round($image->info['height']*$height/100);
+  }
+  
+
   $width = (int) round($width);
   $height = (int) round($height);
 
@@ -298,6 +331,17 @@
  */
 function image_crop(stdClass $image, $x, $y, $width, $height) {
   $aspect = $image->info['height'] / $image->info['width'];
+  
+  //recalculate if the units are percent
+  if(substr($width,-1)=="%"){
+    $width=str_replace("%","",$width);
+    $width=round($image->info['width']*$width/100);
+  }
+  if(substr($height,-1)=="%"){
+    $height=str_replace("%","",$height);
+    $height=round($image->info['height']*$height/100);
+  }
+
   if (empty($height)) $height = $width / $aspect;
   if (empty($width)) $width = $height * $aspect;
 
Index: modules/image/image.admin.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/image/image.admin.inc,v
retrieving revision 1.28
diff -u -r1.28 image.admin.inc
--- modules/image/image.admin.inc	21 Nov 2010 07:24:53 -0000	1.28
+++ modules/image/image.admin.inc	7 Dec 2010 13:05:48 -0000
@@ -473,6 +473,21 @@
   }
 }
 
+
+/**
+ * Element validate handler to ensure a percent or pixel value.
+ *
+ * 
+ */
+function image_effect_scale_units_validate($element, &$form_state) {
+  $last_char=substr($element['#value'],strlen($element['#value'])-1);
+  if($last_char=="%"){
+    $element['#value']=rtrim($element['#value'],'%');
+  }
+  image_effect_integer_validate($element, $form_state);
+}
+
+
 /**
  * Element validate handler to ensure a hexadecimal color value.
  */
@@ -510,22 +525,25 @@
     '#type' => 'textfield',
     '#title' => t('Width'),
     '#default_value' => isset($data['width']) ? $data['width'] : '',
-    '#field_suffix' => ' ' . t('pixels'),
+    '#description' => ' ' . t('Enter a width in pixels or as a percentage. i.e. 500 or 80%'),
     '#required' => TRUE,
     '#size' => 10,
-    '#element_validate' => array('image_effect_integer_validate'),
+    '#element_validate' => array('image_effect_scale_units_validate'),
     '#allow_negative' => FALSE,
   );
+  
+  
   $form['height'] = array(
     '#type' => 'textfield',
     '#title' => t('Height'),
     '#default_value' => isset($data['height']) ? $data['height'] : '',
-    '#field_suffix' => ' ' . t('pixels'),
+    '#description' => ' ' . t('Enter a height in pixels or as a percentage. i.e. 500 or 80%.'),
     '#required' => TRUE,
     '#size' => 10,
-    '#element_validate' => array('image_effect_integer_validate'),
+    '#element_validate' => array('image_effect_scale_units_validate'),
     '#allow_negative' => FALSE,
   );
+  
   return $form;
 }
 
@@ -858,11 +876,17 @@
 function theme_image_resize_summary($variables) {
   $data = $variables['data'];
 
+  substr($data['width'],-1)=="%" ? $data_width_unit="%" : $data_width_unit="px";
+  $data['width']=str_replace("%","",$data['width']);
+  
+  substr($data['height'],-1)=="%" ? $data_height_unit="%" : $data_height_unit="px";
+  $data['height']=str_replace("%","",$data['height']);
+
   if ($data['width'] && $data['height']) {
-    return check_plain($data['width']) . 'x' . check_plain($data['height']);
+    return check_plain($data['width']).$data_width_unit . ' &times; ' . check_plain($data['height']).$data_height_unit;
   }
   else {
-    return ($data['width']) ? t('width @width', array('@width' => $data['width'])) : t('height @height', array('@height' => $data['height']));
+    return ($data['width']) ? t('width @width', array('@width' => $data['width'].$data_width_unit)) : t('height @height', array('@height' => $data['height'].$data_height_unit));
   }
 }
 

