/* *------------------------------------------------------------------------------ * Copyright (C) 2006-2015 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 org.openmicroscopy.shoola.agents.imviewer.browser; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics2D; import java.awt.Rectangle; import java.awt.image.BufferedImage; import java.awt.image.DataBuffer; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Map; import javax.swing.Icon; import org.apache.commons.collections.CollectionUtils; import org.openmicroscopy.shoola.agents.imviewer.IconManager; import org.openmicroscopy.shoola.agents.imviewer.ImViewerAgent; import org.openmicroscopy.shoola.agents.imviewer.actions.UnitBarSizeAction; import org.openmicroscopy.shoola.agents.imviewer.actions.ZoomAction; import org.openmicroscopy.shoola.agents.imviewer.actions.ZoomCmd; import org.openmicroscopy.shoola.agents.imviewer.actions.ZoomGridAction; import org.openmicroscopy.shoola.agents.imviewer.util.ImagePaintingFactory; import org.openmicroscopy.shoola.agents.imviewer.view.ImViewer; import org.openmicroscopy.shoola.agents.imviewer.view.ImViewerFactory; import org.openmicroscopy.shoola.agents.imviewer.view.ViewerPreferences; import ome.model.units.BigResult; import omero.log.LogMessage; import org.openmicroscopy.shoola.env.LookupNames; import omero.model.Length; import omero.model.LengthI; import omero.model.enums.UnitsLength; import org.openmicroscopy.shoola.env.rnd.data.Region; import org.openmicroscopy.shoola.env.rnd.data.Tile; import org.openmicroscopy.shoola.env.ui.UserNotifier; import org.openmicroscopy.shoola.util.image.geom.Factory; import org.openmicroscopy.shoola.util.ui.UIUtilities; import omero.gateway.model.ChannelData; /** * The Model component in the <code>Browser</code> MVC triad. * * @author Jean-Marie Burel      * <a href="mailto:j.burel@dundee.ac.uk">j.burel@dundee.ac.uk</a> * @author Andrea Falconi      * <a href="mailto:a.falconi@dundee.ac.uk">a.falconi@dundee.ac.uk</a> * @author Donald MacDonald      * <a href="mailto:donald@lifesci.dundee.ac.uk">donald@lifesci.dundee.ac.uk</a> * @version 3.0 * @since OME2.2 */ class BrowserModel { /** The text above the combined image. */ private static final String COMBINED = "Merged"; /** Channel prefix. */ private static final String PREFIX = ""; /** Gap between the images. */ static final int GAP = 0;//2; /** Reference to the component that embeds this model. */ private Browser component; /** The original image. */ private BufferedImage renderedImage; /** * The image painted on screen. * This image may have been transformed i.e. zoomed, sharpened etc. */ private BufferedImage displayedImage; /** The projected image. */ private BufferedImage projectedImage; /** The projected image. */ private BufferedImage displayedProjectedImage; /** A smaller version (default 50%) of the original image. */ private BufferedImage combinedImage; /** The zoom factor. */ private double zoomFactor; /** Reference to the {@link ImViewer}. */ private ImViewer parent; /** * Flag to indicate if the unit bar is painted or not on top of the * displayed image. This option will be always set to <code>false</code> * if no value in microns see #7057. */ private boolean unitBar; /** The length of the unit bar */ private Length unitBarLength; /** The default color of the unit bar. */ private Color unitBarColor; /** The background color of the canvas. */ private Color backgroundColor; /** Collection of images composing the grid. */ private List<BufferedImage> originalGridImages; /** Collection of retrieved images composing the grid. */ private List<BufferedImage> gridImages; /** Collection of images composing the grid. */ private List<SplitImage> splitImages; /** The magnification factor used to render the annotate image. */ private double ratio; /** The magnification factor used to render the grid image. */ private double gridRatio; /** Flag indicating to initialize {@link #ratio} and {@link #unitBar}. */ private boolean init; /** Flag if interpolation should be used for upscaling images */ private boolean interpolationServerProperty = false; /** * Returns <code>true</code> if the active channels are mapped * to <code>Red</code>, <code>Green</code> or <code>Blue</code>, * <code>false</code> only and exclusively, if the number of active * channels is 0 or greater than 3. * * @param channels The collection of channels to handle. * @return See above. */ private boolean isImageMappedRGB(List channels) { return parent.isMappedImageRGB(channels); } /** * Handles the exception thrown if any while creating the images for the * split view. * * @param e The exception to handle. */ private void handleGridImageCreationException(Exception e) { UserNotifier un = ImViewerAgent.getRegistry().getUserNotifier(); un.notifyInfo("Split View", "Unable to create the images for the view"); LogMessage msg = new LogMessage(); msg.print("Grid Images creation"); msg.print(e); ImViewerAgent.getRegistry().getLogger().error(this, msg); gridImages.clear(); } /** * Creates the images composing the grid when the color model * is <code>GreyScale</code>. */ private void createGridImagesForGreyScale() { int maxC = parent.getMaxC(); List l = parent.getActiveChannelsInGrid(); int n = l.size(); clearList(gridImages); if (combinedImage != null) combinedImage.flush(); switch (n) { case 0: for (int i = 0; i < maxC; i++) gridImages.add(null); combinedImage = null; break; case 1: case 2: case 3: if (isImageMappedRGB(l)) { BufferedImage image = parent.getCombinedGridImage(); if (image == null) { for (int i = 0; i < maxC; i++) gridImages.add(null); break; } combinedImage = Factory.magnifyImage(gridRatio, image); int w = combinedImage.getWidth(); int h = combinedImage.getHeight(); DataBuffer buf = combinedImage.getRaster().getDataBuffer(); List<ChannelData> list = parent.getSortedChannelData(); Iterator<ChannelData> i = list.iterator(); int index; while (i.hasNext()) { index = i.next().getIndex(); if (l.contains(index)) { if (parent.isChannelRed(index)) { gridImages.add( Factory.createBandImage(buf, w, h, Factory.RED_MASK, Factory.RED_MASK, Factory.RED_MASK)); } else if (parent.isChannelGreen(index)) { gridImages.add( Factory.createBandImage(buf, w, h, Factory.GREEN_MASK, Factory.GREEN_MASK, Factory.GREEN_MASK)); } else if (parent.isChannelBlue(index)) { gridImages.add( Factory.createBandImage(buf, w, h, Factory.BLUE_MASK, Factory.BLUE_MASK, Factory.BLUE_MASK)); } } else { gridImages.add(null); } } } else { retrieveGridImagesForGreyScale(l); } break; default: retrieveGridImagesForGreyScale(l); } } /** * Retrieves the images composing the grid when the color model * is <code>GreyScale</code> and when the channels are not mapped to * red, green or blue i.e. a channel mapped to yellow. * * @param channels Collection of active channels in the grid. */ private void retrieveGridImagesForGreyScale(List channels) { List<BufferedImage> images = parent.getGridImages(); if (images != null) { int last = images.size()-1; combinedImage = Factory.magnifyImage(gridRatio, images.get(last)); images.remove(last); Iterator<BufferedImage> i = images.iterator(); boolean b = originalGridImages.size() == 0 && !isImageMappedRGB(channels); BufferedImage img; while (i.hasNext()) { img = i.next(); gridImages.add(Factory.magnifyImage(gridRatio, img)); if (b) originalGridImages.add(img); } } } /** * Retrieves the images composing the grid when the color model * is <code>RBG</code> and when the channels are not mapped to * red, green or blue i.e. a channel mapped to yellow. */ private void retrieveGridImages() { List<BufferedImage> images = parent.getGridImages(); if (images != null) { Iterator<BufferedImage> i = images.iterator(); boolean b = originalGridImages.size() == 0; BufferedImage img; while (i.hasNext()) { img = i.next(); gridImages.add(Factory.magnifyImage(img, gridRatio, 0, isInterpolation())); if (b) originalGridImages.add(img); } combinedImage = Factory.magnifyImage(renderedImage, gridRatio, 0, isInterpolation()); } } /** * Clears the list and frees space. * * @param l The list to handle. */ private void clearList(List<BufferedImage> l) { if (l == null) return; Iterator<BufferedImage> k = l.iterator(); BufferedImage img; while (k.hasNext()) { img = k.next(); img = null; } l.clear(); } /** Creates the images composing the grid. */ private void createGridImages() { //if (combinedImage == null) return; if (originalGridImages == null) originalGridImages = new ArrayList<BufferedImage>(); clearList(gridImages); if (ImViewer.GREY_SCALE_MODEL.equals(parent.getColorModel())) { createGridImagesForGreyScale(); return; } List l = parent.getActiveChannels(); int maxC = parent.getMaxC(); switch (l.size()) { case 0: for (int i = 0; i < maxC; i++) gridImages.add(null); break; case 1: case 2: case 3: if (isImageMappedRGB(l) && !parent.isCompressed()) { combinedImage = null; combinedImage = Factory.magnifyImage(gridRatio, renderedImage); int w = combinedImage.getWidth(); int h = combinedImage.getHeight(); DataBuffer buf = combinedImage.getRaster().getDataBuffer(); List<ChannelData> list = parent.getSortedChannelData(); Iterator<ChannelData> i = list.iterator(); int index; while (i.hasNext()) { index = i.next().getIndex(); if (parent.isChannelActive(index)) { if (parent.isChannelRed(index)) { gridImages.add( Factory.createBandImage(buf, w, h, Factory.RED_MASK, Factory.BLANK_MASK, Factory.BLANK_MASK)); } else if (parent.isChannelGreen(index)) { gridImages.add( Factory.createBandImage(buf, w, h, Factory.BLANK_MASK, Factory.GREEN_MASK, Factory.BLANK_MASK)); } else if (parent.isChannelBlue(index)) { gridImages.add( Factory.createBandImage(buf, w, h, Factory.BLANK_MASK, Factory.BLANK_MASK, Factory.BLUE_MASK)); } } else { gridImages.add(null); } } } else { retrieveGridImages(); } break; default: retrieveGridImages(); } } /** * Calculates the length of the unit bar. * * @param ratio The ratio to multiple the value by. * @return The unit bar length in pixels */ private double getBarSizeInPx(double ratio) { if(unitBarLength == null) return 1; try { double v = unitBarLength.getValue() / (new LengthI(getPixelsSizeX(), unitBarLength.getUnit())) .getValue(); v *= ratio; return v; } catch (BigResult e) { } return 1; } /** * Creates a new instance. * * @param parent The parent of this component. * Mustn't be <code>null</code>. * @param imageID The id of the image. * @param pref The preferences for the viewer. */ BrowserModel(ImViewer parent, ViewerPreferences pref) { if (parent == null) throw new IllegalArgumentException("No parent."); //unloaded image data this.parent = parent; unitBar = false; ratio = ZoomGridAction.DEFAULT_ZOOM_FACTOR; gridRatio = ZoomGridAction.DEFAULT_ZOOM_FACTOR; init = true; unitBarColor = ImagePaintingFactory.UNIT_BAR_COLOR; backgroundColor = ImagePaintingFactory.DEFAULT_BACKGROUND; gridImages = new ArrayList<BufferedImage>(); zoomFactor = ZoomAction.DEFAULT_ZOOM_FACTOR; if (pref != null) { if (pref.getBackgroundColor() != null) backgroundColor = pref.getBackgroundColor(); if (pref.getScaleBarColor() != null) unitBarColor = pref.getScaleBarColor(); if (pref.isFieldSelected(ViewerPreferences.ZOOM_FACTOR)) zoomFactor = ZoomAction.getZoomFactor(pref.getZoomIndex()); } this.interpolationServerProperty = Boolean .parseBoolean((String) ImViewerAgent.getRegistry().lookup( LookupNames.INTERPOLATE)); } /** * Called by the <code>Browser</code> after creation to allow this * object to store a back reference to the embedding component. * * @param component The embedding component. */ void initialize(Browser component) { this.component = component; } /** * Returns <code>true</code> if the rendered image has been set, * <code>false</code> otherwise. * * @return See above. */ boolean hasImage() { return (renderedImage != null); } /** * Sets the rendered image. * * @param image The image to set. */ void setRenderedImage(BufferedImage image) { renderedImage = null; displayedImage = null; combinedImage = null; clearList(gridImages); renderedImage = image; if (renderedImage != null) { if (init) { int imageWidth = image.getWidth(); if (imageWidth < ImViewer.MINIMUM_SIZE) { ratio = 1; gridRatio = 1; setUnitBar(false); } if (imageWidth*ratio > ImViewer.MAXIMUM_SIZE) ratio = (double) ImViewer.MAXIMUM_SIZE/imageWidth; init = false; } } } /** Sets the images composing the grid. */ void setGridImages() { if (gridImages.size() != 0) return; clearList(originalGridImages); try { createGridImages(); } catch (Exception e) { handleGridImageCreationException(e); } } /** * Returns the image to paint on screen. This image is a transformed * version of the rendered image. We apply several transformations to the * {@link #renderedImage} e.g. zooming. * * @return See above. */ BufferedImage getDisplayedImage() { if (displayedImage == null && isBigImage()) { BufferedImage bi = new BufferedImage(getTiledImageSizeX(), getTiledImageSizeY(), BufferedImage.TYPE_INT_RGB); //build it from the tiles. // Create a graphics which can be used to draw into the buffered image Graphics2D g2D = bi.createGraphics(); ImagePaintingFactory.setGraphicRenderingSettings(g2D, isInterpolation()); Map<Integer, Tile> tiles = getTiles(); //Check the size of the tiles int rows = getRows(); int columns = getColumns(); Tile tile; int index; Object img; Region region; for (int i = 0; i < rows; i++) { for (int j = 0; j < columns; j++) { index = i*columns+j; tile = tiles.get(index); region = tile.getRegion(); img = tile.getImage(); if (img != null) { g2D.drawImage((BufferedImage) img, region.getX(), region.getY(), null); } } } g2D.dispose(); return bi; } return displayedImage; } /** * Returns the image to paint on screen. This image is a transformed * version of the projected image. We apply several transformations to the * {@link #projectedImage} e.g. zooming. * * @return See above. */ BufferedImage getDisplayedProjectedImage() { return displayedProjectedImage; } /** * Returns the rendered image. * * @return See above. */ BufferedImage getRenderedImage() { return renderedImage; } /** * Sets the zoom factor. * * @param factor See above. */ void setZoomFactor(double factor) { zoomFactor = factor; } /** * Returns the zoom factor. * * @return See above. */ double getZoomFactor() { return zoomFactor; } /** * Returns the title of the {@link Browser}. * * @return See above. */ String getTitle() { return ImViewer.TITLE_VIEW_INDEX; } /** * Returns the icon of the {@link Browser}. * * @return See above. */ Icon getIcon() { IconManager icons = IconManager.getInstance(); return icons.getIcon(IconManager.VIEWER); } /** * Creates the {@link #displayedImage}. The method should be invoked * after the {@link #setRenderedImage(BufferedImage)} method. */ void createDisplayedImage() { if (renderedImage == null) return; displayedImage = null; if (zoomFactor != ZoomAction.DEFAULT_ZOOM_FACTOR) { BufferedImage img = null; try { img = Factory.magnifyImage(renderedImage, zoomFactor, 0, isInterpolation()); renderedImage.flush(); } catch (Throwable e) { UserNotifier un = ImViewerAgent.getRegistry().getUserNotifier(); un.notifyInfo("Magnification", "An error occurred while magnifying the image."); } if (img != null) displayedImage = img; } else displayedImage = renderedImage; } /** * Creates the {@link #displayedImage}. The method should be invoked * after the {@link #setRenderedImage(BufferedImage)} method. */ void createDisplayedProjectedImage() { if (projectedImage == null) return; if (displayedProjectedImage != null) displayedProjectedImage.flush(); if (zoomFactor != ZoomAction.DEFAULT_ZOOM_FACTOR) { BufferedImage img = null; try { img = Factory.magnifyImage(projectedImage, zoomFactor, 0, isInterpolation()); } catch (Throwable e) { UserNotifier un = ImViewerAgent.getRegistry().getUserNotifier(); un.notifyInfo("Magnification", "An error occurred while magnifying the image."); } if (img != null) displayedProjectedImage = img; } else displayedProjectedImage = projectedImage; } /** * Returns the number of z-sections. * * @return See above. */ int getMaxZ() { return parent.getMaxZ(); } /** * Returns the number of timepoints. * * @return See above. */ int getMaxT() { return parent.getRealT(); } /** * The size of a pixel along the X-axis. * * @return See above. */ Length getPixelsSizeX() { return parent.getPixelsSizeX(); } /** * Returns <code>true</code> if the unit bar is painted on top of * the displayed image, <code>false</code> otherwise. * * @return See above. */ boolean isUnitBar() { return unitBar; } /** * Sets the value of the flag controlling if the unit bar is painted or not. * * @param unitBar Pass <code>true</code> to paint the unit bar, * <code>false</code> otherwise. */ void setUnitBar(boolean unitBar) { if (unitBar) { int unitBarLenghtValue = UnitBarSizeAction.getDefaultValue(); // Guess the unit to use by assuming a 100px wide scalebar Length tmp = new LengthI(getPixelsSizeX().getValue() * 100, getPixelsSizeX().getUnit()); tmp = UIUtilities.transformSize(tmp); this.unitBarLength = new LengthI(unitBarLenghtValue, tmp.getUnit()); } this.unitBar = unitBar; } /** * Sets the size of the unit bar. * * @param size * The size of the unit bar. * @param unit The unit */ void setUnitBarSize(double size, UnitsLength unit) { if (unitBarLength != null) { try { LengthI tmp = new LengthI(size, unit); tmp = new LengthI(tmp, unitBarLength.getUnit()); unitBarLength.setValue(tmp.getValue()); } catch (BigResult e) { } } else { unitBarLength = new LengthI(size, unit); } } /** * Returns the unit used to determine the size of the unit bar. The unit * depends on the size stored. The unit of reference in the OME model is in * microns, but this is a transformed unit. * * @return See above. */ double getUnitInRefUnits() { return unitBarLength != null ? unitBarLength.getValue() : 1; } /** * Returns the original (non-scaled) length of the unit bar in pixels * * @return See above. */ double getOriginalUnitBarSize() { return getBarSizeInPx(1); } /** * Returns the length of the unit bar in pixels * * @return See above. */ double getUnitBarSize() { return getBarSizeInPx(zoomFactor); } /** * Returns the length of the unit bar (in pixels) for an image composing the grid. * * @return See above. */ double getGridBarSize() { return getBarSizeInPx(gridRatio); } /** * Returns the unit bar value. * * @return See above. */ String getUnitBarValue() { return UIUtilities.twoDecimalPlaces(unitBarLength.getValue()); } /** * Returns the unit of the scalebar * @return See above. */ String getUnitBarUnit() { return LengthI.lookupSymbol(unitBarLength.getUnit()); } /** * Returns the color of the unit bar. * * @return See above. */ Color getUnitBarColor() { return unitBarColor; } /** * Sets the color of the unit bar. * * @param c The color to set. */ void setUnitBarColor(Color c) { unitBarColor = c; } /** * Returns the background color of the canvas. * * @return See above. */ Color getBackgroundColor() { return backgroundColor; } /** * Set the background color of the canvas. * * @param c The color to set. */ void setBackgroundColor(Color c) { backgroundColor = c; } /** * Returns the title of the <code>Grid View</code>. * * @return See above. */ String getGridViewTitle() { return ImViewer.TITLE_GRID_INDEX; } /** * Returns the icon of the <code>Grid View</code>. * * @return See above. */ Icon getGridViewIcon() { IconManager icons = IconManager.getInstance(); return icons.getIcon(IconManager.GRIDVIEW); } /** * Returns the title of the <code>Grid View</code>. * * @return See above. */ String getProjectionViewTitle() { return ImViewer.TITLE_PROJECTION_INDEX; } /** * Returns the icon of the <code>Annotator</code>. * * @return See above. */ Icon getProjectionViewIcon() { IconManager icons = IconManager.getInstance(); return icons.getIcon(IconManager.PROJECTION); } /** * Returns the icon of the <code>Annotator</code>. * * @return See above. */ Icon getAnnotatorIcon() { IconManager icons = IconManager.getInstance(); return icons.getIcon(IconManager.ANNOTATION); } /** * Sets the selected XY-plane. A new plane is then rendered. * * @param z The selected z-section. * @param t The selected timepoint. */ void setSelectedXYPlane(int z, int t) { parent.setSelectedXYPlane(z, t); } /** * Returns the real timepoint. * * @return See above. */ int getRealSelectedT() { return parent.getRealSelectedT(); } /** * Returns the default timepoint. * * @return See above. */ int getDefaultT() { return parent.getDefaultT(); } /** * Returns the default z-section. * * @return See above. */ int getDefaultZ() { return parent.getDefaultZ(); } /** * Returns the number of pixels along the X-axis. * * @return See above. */ int getMaxX() { return parent.getMaxX(); } /** * Returns the number of pixels along the Y-axis. * * @return See above. */ int getMaxY() { return parent.getMaxY(); } /** * Returns the size of a pixel along the Y-axis. * * @return See above. */ Length getPixelsSizeY() { return parent.getPixelsSizeY(); } /** * Returns the size of a pixel along the Y-axis. * * @return See above. */ Length getPixelsSizeZ() { return parent.getPixelsSizeZ(); } Length getUnitBarLength() { return unitBarLength; } /** * Returns the number of column for the grid. * * @return See above. */ int getGridColumn() { return 2; } /** * Returns the number of row for the grid. * * @return See above. */ int getGridRow() { int n = parent.getMaxC(); if (n == 1) return 1; if (n == 2 || n == 3) return 2; int row = n/2; if (n%2 != 0) row += 1; return row; } /** * Returns the size of the grid. * * @return See above. */ Dimension getGridSize() { int w = (int) (getMaxX()*gridRatio); int h = (int) (getMaxY()*gridRatio); int n = parent.getMaxC(); int row = 0; int col = 0; if (n == 1) { row = 1; col = 2; } else if (n == 2 || n == 3) { row = 2; col = 2; } else { col = 3; row = n/2; if (n%2 != 0) row += 1; } return new Dimension(col*w+(col-1)*GAP, row*h+(row-1)*GAP); } /** * Returns <code>true</code> if there is no images retrieved for the * grid view, <code>false</code> otherwise. * * @return See above. */ boolean hasNoGridImages() { return gridImages.size() == 0; } /** * Returns a collection of images composing the grid. * * @return See above. */ List<SplitImage> getSplitImages() { if (splitImages == null) splitImages = new ArrayList<SplitImage>(); else splitImages.clear(); String n; splitImages = new ArrayList<SplitImage>(); List<ChannelData> list = parent.getSortedChannelData(); Iterator<ChannelData> i = list.iterator(); ChannelData channel; int j = 0; int size = gridImages.size(); while (i.hasNext()) { channel = i.next(); n = PREFIX+channel.getChannelLabeling(); if (j >= size) splitImages.add(new SplitImage(null, n)); else splitImages.add(new SplitImage(gridImages.get(j), n)); j++; } splitImages.add(new SplitImage(combinedImage, COMBINED)); return splitImages; } /** * Returns the index of the selected pane. * * @return See above. */ int getSelectedIndex() { return parent.getSelectedIndex(); } /** * Returns <code>true</code> if the textual information is painted on * top of the grid image, <code>false</code> otherwise. * * @return See above. */ boolean isTextVisible() { return parent.isTextVisible(); } /** * Returns the magnification factor used to render the annotate image. * * @return See above. */ double getRatio() { return ratio; } /** * Returns the magnification factor used to render a grid image. * * @return See above. */ double getGridRatio() { return gridRatio; } /** * Sets the ratio of the grid image. * * @param gridRatio The value to set. */ void setGridRatio(double gridRatio) { //if (ratio == 1) return; //We don't want to be too small. double max = ZoomGridAction.MAX_ZOOM_FACTOR; if (gridRatio > max) return; this.gridRatio = gridRatio; if (CollectionUtils.isEmpty(originalGridImages)) { try { createGridImages(); } catch (Exception e) { handleGridImageCreationException(e); } return; } int n = originalGridImages.size(); clearList(gridImages); int maxC = parent.getMaxC(); switch (n) { case 0: for (int i = 0; i < maxC; i++) gridImages.add(null); break; case 1: case 2: case 3: //TODO: Review that code. if (isImageMappedRGB(parent.getActiveChannels())) { try { createGridImages(); } catch (Exception e) { handleGridImageCreationException(e); } } else { combinedImage = null; combinedImage = Factory.magnifyImage(gridRatio, renderedImage); Iterator<BufferedImage> i = originalGridImages.iterator(); while (i.hasNext()) { gridImages.add(Factory.magnifyImage(gridRatio, i.next())); } } break; default: combinedImage = null; combinedImage = Factory.magnifyImage(gridRatio, renderedImage); Iterator<BufferedImage> i = originalGridImages.iterator(); while (i.hasNext()) { gridImages.add(Factory.magnifyImage(gridRatio, i.next())); } } } /** * Returns the combined image, displayed in the grid view. * * @return See above. */ BufferedImage getCombinedImage() { return combinedImage; } /** * Returns the number of the channels. * * @return See above. */ int getMaxC() { return parent.getMaxC(); } /** * Zooms in and out the image depending on the passed parameter. * * @param increase Pass <code>true</code> to zoom in, <code>false</code> * to zoom out. */ void zoom(boolean increase) { int index = ZoomCmd.ZOOM_IN; if (!increase) index = ZoomCmd.ZOOM_OUT; ZoomCmd cmd = new ZoomCmd(parent, index); cmd.execute(); } /** * Returns the projected image if any. * * @return See above. */ BufferedImage getProjectedImage() { return projectedImage; } /** * Returns the projected image if any. * * @param projectedImage The projected image. */ void setProjectedImage(BufferedImage projectedImage) { if (this.projectedImage != null) this.projectedImage.flush(); this.projectedImage = projectedImage; } /** Builds a projected image to preview. */ void projectionPreview() { parent.renderXYPlane(); } /** * Returns the parent model. * * @return See above. */ ImViewer getParentModel() { return parent; } /** Clears the grid images when the color model changes. */ void clearGridImages() { clearList(gridImages); } /** * Returns <code>true</code> if the rendered image is an RGB image, * <code>false</code> otherwise. * * @return See above. */ boolean isRenderedImageRGB() { return isImageMappedRGB(parent.getActiveChannels()); } /** * Returns <code>true</code> if the color model is RGB, * <code>false</code> otherwise. * * @return See above. */ boolean isModelRGB() { return !ImViewer.GREY_SCALE_MODEL.equals(parent.getColorModel()); } /** * Returns the list of grid images for openGL. * * @return See above. */ List<GridImage> getGridImages() { List<GridImage> list = new ArrayList<GridImage>(); List<ChannelData> l = parent.getSortedChannelData(); Iterator<ChannelData> i = l.iterator(); int index; GridImage image; //boolean[] rgb; ChannelData data; String label; while (i.hasNext()) { data = i.next(); index = data.getIndex(); label = data.getChannelLabeling(); if (parent.isChannelActive(index)) { image = new GridImage(index, true, label); } else { image = new GridImage(index, false, label); } list.add(image); } return list; } /** * Returns the number of rows, default is <code>1</code>. * * @return See above. */ int getRows() { return parent.getRows(); } /** * Returns the number of columns, default is <code>1</code>. * * @return See above. */ int getColumns() { return parent.getColumns(); } /** * Returns the tiles to display. * * @return See above. */ Map<Integer, Tile> getTiles() { return parent.getTiles(); } /** * Returns <code>true</code> if it is a big image, <code>false</code> * otherwise. * * @return See above. */ boolean isBigImage() { return parent.isBigImage(); } /** * Loads the tiles. * * @param r The selected rectangle. */ void loadTiles(Rectangle r) { parent.loadTiles(r); } /** * Returns the size of the tiled image along the X-axis i.e. * the size of a tile along the X-axis multiplied by the number of columns. * * @return See above. */ int getTiledImageSizeX() { return parent.getTiledImageSizeX(); } /** * Returns the size of the tiled image along the Y-axis i.e. * the size of a tile along the Y-axis multiplied by the number of rows. * * @return See above. */ int getTiledImageSizeY() { return parent.getTiledImageSizeY(); } /** Removes references to images.*/ void discard() { combinedImage = null; displayedImage = null; displayedProjectedImage = null; projectedImage = null; renderedImage = null; clearList(gridImages); clearList(originalGridImages); System.gc();//force garbage collection } /** * Returns if interpolation is enabled or not. * If a value has been set by the user, this value is used; otherwise * the server side default will be used; if there wasn't set one either, * <code>false</code> will be returned. * * @return See above. */ boolean isInterpolation() { if (ImViewerFactory.isInterpolation() != null) return ImViewerFactory.isInterpolation(); else return interpolationServerProperty; } /** * En-/Disables interpolation; value will be stored in user * preferences * * @param interpolation */ void setInterpolation(boolean interpolation) { ImViewerFactory.setInterpolation(interpolation); } }