From f344e0ff6e1631af576439e4f2f207cc18f09cb6 Mon Sep 17 00:00:00 2001
From: anttil <anttil>
Date: Tue, 12 Mar 2013 10:52:54 +0000
Subject: [PATCH] BIS-338 / SP-535 : Apply rescaling transformation also for
 color images that are using only one color component (R, G or B) when using
 optimal rescaling mode

SVN: 28597
---
 ...scaleIntensityImageTransformerFactory.java | 37 +++++++++++++++++--
 .../server/images/ImageChannelsUtils.java     | 14 ++++++-
 2 files changed, 46 insertions(+), 5 deletions(-)

diff --git a/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/dto/api/transformations/AutoRescaleIntensityImageTransformerFactory.java b/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/dto/api/transformations/AutoRescaleIntensityImageTransformerFactory.java
index 97a16508fa1..12569904452 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/dto/api/transformations/AutoRescaleIntensityImageTransformerFactory.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/dto/api/transformations/AutoRescaleIntensityImageTransformerFactory.java
@@ -17,12 +17,14 @@
 package ch.systemsx.cisd.openbis.dss.etl.dto.api.transformations;
 
 import java.awt.image.BufferedImage;
+import java.awt.image.WritableRaster;
+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;
 
 /**
@@ -58,7 +60,19 @@ public class AutoRescaleIntensityImageTransformerFactory implements IImageTransf
                 {
                     if (IntensityRescaling.isNotGrayscale(image))
                     {
-                        return image;
+                        EnumSet<Channel> channels = IntensityRescaling.getUsedRgbChannels(image);
+                        if (channels.size() != 1)
+                        {
+                            return image;
+                        } else
+                        {
+                            Channel channel = channels.iterator().next();
+                            Levels levels =
+                                    IntensityRescaling.computeLevels(toGrayScale(image, channel),
+                                            threshold);
+                            return IntensityRescaling.rescaleIntensityLevelTo8Bits(image, levels,
+                                    channel);
+                        }
                     }
                     Levels levels = IntensityRescaling.computeLevels(image, threshold);
                     return IntensityRescaling.rescaleIntensityLevelTo8Bits(image, levels);
@@ -66,4 +80,21 @@ public class AutoRescaleIntensityImageTransformerFactory implements IImageTransf
             };
     }
 
+    private BufferedImage toGrayScale(BufferedImage image, Channel channel)
+    {
+        BufferedImage gray =
+                new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_BYTE_GRAY);
+        WritableRaster raster = gray.getRaster();
+
+        for (int y = 0; y < image.getHeight(); y++)
+        {
+            for (int x = 0; x < image.getWidth(); x++)
+            {
+                int value = (image.getRGB(x, y) >> channel.getShift()) & 0xff;
+                raster.setPixel(x, y, new int[]
+                    { value });
+            }
+        }
+        return gray;
+    }
 }
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/dss/generic/server/images/ImageChannelsUtils.java b/screening/source/java/ch/systemsx/cisd/openbis/dss/generic/server/images/ImageChannelsUtils.java
index 793d7739a85..ee5fdabf795 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/dss/generic/server/images/ImageChannelsUtils.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/dss/generic/server/images/ImageChannelsUtils.java
@@ -47,6 +47,7 @@ import ch.systemsx.cisd.openbis.dss.etl.IImagingLoaderStrategy;
 import ch.systemsx.cisd.openbis.dss.etl.ImagingLoaderStrategyFactory;
 import ch.systemsx.cisd.openbis.dss.etl.dto.ImageTransfomationFactories;
 import ch.systemsx.cisd.openbis.dss.etl.dto.api.ChannelColorRGB;
+import ch.systemsx.cisd.openbis.dss.etl.dto.api.transformations.AutoRescaleIntensityImageTransformerFactory;
 import ch.systemsx.cisd.openbis.dss.generic.server.ResponseContentStream;
 import ch.systemsx.cisd.openbis.dss.generic.server.images.dto.DatasetAcquiredImagesReference;
 import ch.systemsx.cisd.openbis.dss.generic.server.images.dto.ImageChannelStackReference;
@@ -633,6 +634,7 @@ public class ImageChannelsUtils
                 imageReference.getImageTransfomationFactories();
         // image level transformation is applied always, as it cannot be applied or changed in
         // external image viewer
+
         resultImage = applyImageTransformation(resultImage, transfomations.tryGetForImage());
 
         if (transformationInfo.isApplyNonImageLevelTransformation() == false)
@@ -647,8 +649,9 @@ public class ImageChannelsUtils
         {
             String channelTransformationCode =
                     transformationInfo.tryGetSingleChannelTransformationCode() == null ? transfomations
-                            .tryGetDefaultTransformationCode() : transformationInfo
-                            .tryGetSingleChannelTransformationCode();
+                            .tryGetDefaultTransformationCode()
+                            : transformationInfo
+                                    .tryGetSingleChannelTransformationCode();
 
             if (channelTransformationCode != null
                     && (false == channelTransformationCode.equals(imageReference
@@ -658,6 +661,13 @@ public class ImageChannelsUtils
                         transfomations.tryGetForChannel(transformationInfo
                                 .tryGetSingleChannelTransformationCode());
             }
+
+            if (channelLevelTransformationOrNull == null)
+            {
+                channelLevelTransformationOrNull =
+                        new AutoRescaleIntensityImageTransformerFactory(
+                                ImageUtil.DEFAULT_IMAGE_OPTIMAL_RESCALING_FACTOR);
+            }
         }
 
         return applyImageTransformation(resultImage, channelLevelTransformationOrNull);
-- 
GitLab