/* *------------------------------------------------------------------------------ * Copyright (C) 2006-2010 University of Dundee. All rights reserved. * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *------------------------------------------------------------------------------ */ package omero.gateway.util; import java.awt.Color; import java.awt.Point; import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import javax.imageio.ImageIO; import omero.gateway.model.MaskData; import omero.gateway.model.ROIData; import omero.model.RoiI; /** * Uploaded for masks. * * @author Jean-Marie Burel      * <a href="mailto:j.burel@dundee.ac.uk">j.burel@dundee.ac.uk</a> * @author Donald MacDonald      * <a href="mailto:donald@lifesci.dundee.ac.uk">donald@lifesci.dundee.ac.uk</a> * @since OME3.0 */ public class UploadMask { /** The default color. */ private static final int DEFAUL_COLOR = Color.black.getRGB(); /** The ROIComponent. */ private ROIComponent component; /** * Maps the <integer, MaskClass> map to an MaskData object. * * @param map See above. * @param z The z section of the image. * @param t The t point of the image. * @param c The channel of the image. * @return See above. * @throws IOException */ private Map<Integer, MaskData> mapToMaskData(Map<Integer, MaskClass> map, int z, int t, int c) throws IOException { Map<Integer, MaskData> maskDataMap = new HashMap<Integer, MaskData>(); Iterator<Integer> iterator = map.keySet().iterator(); int value; MaskData mask; while (iterator.hasNext()) { value = iterator.next(); mask = map.get(value).asMaskData(z, t, c); maskDataMap.put(value, mask); } return maskDataMap; } /** * Creates a new instance. * * @param imageId The ImageId where the uploaded images are from. */ public UploadMask(long imageId) { component = new ROIComponent(imageId); } /** * Adds a Mask Shape to the appropriate ROIClass, creating one if necessary. * * @param image The Image containing the mask data. * @param z The Z Section of the image. * @param t The Time point of the image. * @throws IOException Thrown if an error occurred while creating the mask. */ public void addImage(byte[] image, int z, int t, int c) throws IOException { Map<Integer, MaskClass> classMap = createMasks(image); Map<Integer, MaskData> maskMap = mapToMaskData(classMap, z, t, c); component.addMasks(maskMap); } /** * Adds a Mask Shape to the appropriate ROIClass, creating one if necessary. * * @param image The Image containing the mask data. * @param z The Z Section of the image. * @param t The Time point of the image. * @throws IOException Thrown if an error occurred while creating the mask. */ public void addArray(int[][] image, int z, int t, int c) throws IOException { Map<Integer, MaskClass> classMap = createMasks(image); Map<Integer, MaskData> maskMap = mapToMaskData(classMap, z, t, c); component.addMasks(maskMap); } /** * Creates Mask Class objects from the bytes stream, This will create a * Mask object for each unique colour value in the image. * * @param bytes The bytes representing the image. * @return A map of <Integer, MaskClass> * @throws IOException Thrown if an error occurred while creating the mask. */ private Map<Integer, MaskClass> createMasks(byte[] bytes) throws IOException { Map<Integer, MaskClass> maskMap = new HashMap<Integer, MaskClass>(); ByteArrayInputStream imageStream = new ByteArrayInputStream(bytes); BufferedImage inputImage = ImageIO.read(imageStream); int value; MaskClass mask; for (int x = 0; x < inputImage.getWidth(); x++) for (int y = 0; y < inputImage.getHeight(); y++) { value = inputImage.getRGB(x, y); if (value == DEFAUL_COLOR) continue; if (!maskMap.containsKey(value)) { mask = new MaskClass(value); maskMap.put(value, mask); } else mask = maskMap.get(value); mask.add(new Point(x, y)); } return maskMap; } /** * Creates Mask Class objects from the bytes stream, This will create a * Mask object for each unique colour value in the image. * * @param bytes The bytes representing the image. * @return A map of <Integer, MaskClass> * @throws IOException Thrown if an error occurred while creating the mask. */ private Map<Integer, MaskClass> createMasks(int[][] data) throws IOException { Map<Integer, MaskClass> maskMap = new HashMap<Integer, MaskClass>(); int value; MaskClass mask; for (int y = 0; y < data.length; y++) for (int x = 0; x < data[y].length; x++) { value = data[x][y]; if (value == DEFAUL_COLOR || value == 0) continue; if (!maskMap.containsKey(value)) { mask = new MaskClass(value); maskMap.put(value, mask); } else mask = maskMap.get(value); mask.add(new Point(x, y)); } return maskMap; } /** * Returns the ROIs created from uploading the images. * * @return See above. */ public List<RoiI> getROI() { List<ROIData> roiList = component.getROI(); List<RoiI> rList = new ArrayList<RoiI>(); for (ROIData roi : roiList) rList.add((RoiI)roi.asIObject()); return rList; } }