diff --git a/common/source/java/ch/systemsx/cisd/common/image/IntensityRescaling.java b/common/source/java/ch/systemsx/cisd/common/image/IntensityRescaling.java
index 09f63db9c9ec87b3d2957b478c91985ff98b7d0a..12636c3dce9499c57d1179cc1fe722b922fa5adc 100644
--- a/common/source/java/ch/systemsx/cisd/common/image/IntensityRescaling.java
+++ b/common/source/java/ch/systemsx/cisd/common/image/IntensityRescaling.java
@@ -18,6 +18,7 @@ package ch.systemsx.cisd.common.image;
 
 import java.awt.image.BufferedImage;
 import java.awt.image.WritableRaster;
+import java.util.EnumSet;
 
 /**
  * Methods for performing an intensity rescaling to 8bits for gray-scale images with a color-depth
@@ -31,6 +32,31 @@ public class IntensityRescaling
     /** The largest number a unsigned short can store. */
     private final static int MAX_USHORT = (1 << 16) - 1;
 
+    public static enum Channel
+    {
+        RED(0, 16), GREEN(1, 8), BLUE(2, 0);
+        
+        private int band;
+
+        private int shift;
+
+        private Channel(int band, int shift)
+        {
+            this.band = band;
+            this.shift = shift;
+        }
+
+        public int getShift()
+        {
+            return shift;
+        }
+
+        public int getBand()
+        {
+            return band;
+        }
+    }
+
     /**
      * The levels in a distribution of pixel values for a given symmetric quantile value.
      */
@@ -156,6 +182,39 @@ public class IntensityRescaling
         return image.getColorModel().getColorSpace().getNumComponents() > 1;
     }
 
+    /** @return Used rgb channels in an image. Returns empty set if image type not RGB */
+    public static EnumSet<Channel> getUsedRgbChannels(BufferedImage image)
+    {
+        EnumSet<Channel> channels = EnumSet.noneOf(Channel.class);
+
+        if (image.getType() != BufferedImage.TYPE_INT_RGB
+                && image.getType() != BufferedImage.TYPE_INT_ARGB)
+        {
+            return channels;
+        }
+
+        for (int i = 0; i < image.getHeight(); i++)
+        {
+            for (int j = 0; j < image.getWidth(); j++)
+            {
+                int rgb = image.getRGB(i, j);
+                if (((rgb >> 16) & 0xff) > 0)
+                {
+                    channels.add(Channel.RED);
+                }
+                if (((rgb >> 8) & 0xff) > 0)
+                {
+                    channels.add(Channel.GREEN);
+                }
+                if ((rgb & 0xff) > 0)
+                {
+                    channels.add(Channel.BLUE);
+                }
+            }
+        }
+        return channels;
+    }
+
     /**
      * Performs an intensity rescaling on a gray-scale image by shifting all intensities so that
      * only significant bits are kept. A bit position is considered significant if only a small
@@ -369,6 +428,37 @@ public class IntensityRescaling
         return rescaleIntensityLevelTo8Bits(new GrayscalePixels(image), levels);
     }
 
+    public static BufferedImage rescaleIntensityLevelTo8Bits(BufferedImage image, Levels levels,
+            Channel channel)
+    {
+        final int width = image.getWidth();
+        final int height = image.getHeight();
+        final BufferedImage rescaledImage =
+                new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
+        WritableRaster rescaledRaster = rescaledImage.getRaster();
+
+        final float dynamicRange = 255f / (levels.maxLevel - levels.minLevel);
+
+        for (int y = 0; y < height; ++y)
+        {
+            for (int x = 0; x < width; ++x)
+            {
+                int originalIntensity = (image.getRGB(x, y) >> channel.getShift()) & 0xff;
+
+                // cut all intensities above the white point
+                int intensity = Math.min(levels.maxLevel, originalIntensity);
+                // cut all intensities below the black point and move the origin to 0
+                intensity = Math.max(0, intensity - levels.minLevel);
+                // normalize to [0, 1] and rescale to 8 bits
+                intensity = (int) (0.5 + (intensity * dynamicRange));
+
+                rescaledRaster
+                        .setSample(x, y, channel.getBand(), intensity);
+            }
+        }
+        return rescaledImage;
+    }
+
     /**
      * See {@link #rescaleIntensityLevelTo8Bits}.
      */
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/dto/api/transformations/IntensityRangeImageTransformerFactory.java b/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/dto/api/transformations/IntensityRangeImageTransformerFactory.java
index abae0a567e4596951435e42cf330d206290e1547..1d582ade1cab70b629641fb35e9bc9e7ba92f1d6 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/dto/api/transformations/IntensityRangeImageTransformerFactory.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/dto/api/transformations/IntensityRangeImageTransformerFactory.java
@@ -17,13 +17,13 @@
 package ch.systemsx.cisd.openbis.dss.etl.dto.api.transformations;
 
 import java.awt.image.BufferedImage;
+import java.util.EnumSet;
 
-
+import ch.systemsx.cisd.base.annotation.JsonObject;
 import ch.systemsx.cisd.base.image.IImageTransformer;
 import ch.systemsx.cisd.base.image.IImageTransformerFactory;
-
-import ch.systemsx.cisd.base.annotation.JsonObject;
 import ch.systemsx.cisd.common.image.IntensityRescaling;
+import ch.systemsx.cisd.common.image.IntensityRescaling.Channel;
 import ch.systemsx.cisd.common.image.IntensityRescaling.Levels;
 
 /**
@@ -71,7 +71,16 @@ public class IntensityRangeImageTransformerFactory implements IImageTransformerF
                 {
                     if (IntensityRescaling.isNotGrayscale(image))
                     {
-                        return image;
+                        EnumSet<Channel> channels = IntensityRescaling.getUsedRgbChannels(image);
+                        if (channels.size() != 1)
+                        {
+                            return image;
+                        } else
+                        {
+                            Levels levels = new Levels(blackPointIntensity, whitePointIntensity);
+                            return IntensityRescaling.rescaleIntensityLevelTo8Bits(image, levels,
+                                    channels.iterator().next());
+                        }
                     }
                     Levels levels = new Levels(blackPointIntensity, whitePointIntensity);
                     return IntensityRescaling.rescaleIntensityLevelTo8Bits(image, levels);