/* JAI-Ext - OpenSource Java Advanced Image Extensions Library * http://www.geo-solutions.it/ * Copyright 2014 GeoSolutions * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package it.geosolutions.rendered.viewer; import java.awt.BorderLayout; import java.awt.FlowLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseEvent; import java.awt.event.MouseMotionAdapter; import java.awt.image.DataBuffer; import java.awt.image.RenderedImage; import java.io.File; import java.io.IOException; import javax.imageio.ImageIO; import javax.media.jai.iterator.RandomIter; import javax.media.jai.iterator.RandomIterFactory; import javax.swing.JButton; import javax.swing.JFileChooser; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JToggleButton; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import javax.swing.filechooser.FileFilter; //import com.digitalglobe.util.security.SecurityValidator; /** * Simple rendered image browser, allows to zoom in, out, display tile grid and * view pixel values on mouse over * * @author Andrea Aime * @author Daniele Romagnoli, GeoSolutions SAS * @author Simone Giannecchini, GeoSolutions SAS * */ public class ImageViewer extends JPanel { private ZoomableImageDisplay display; private ImageViewer relatedViewer; private JLabel status; private RandomIter pixelIter; private int[] ipixel; private double[] dpixel; //US9834:SUPPRESSION:Dead Code: Unused Field (Code Quality, Structural):Low:STIGCAT2 private int dataType; private StringBuffer sb = new StringBuffer(); private RenderedImage image; protected File lastDirectory; public ImageViewer(ImageViewer relatedViewer) { this(); this.relatedViewer = relatedViewer; } public ImageViewer() { setLayout(new BorderLayout()); // build the button bar JButton zoomIn = new JButton("Zoom in"); JButton zoomOut = new JButton("Zoom out"); final JToggleButton tileGrid = new JToggleButton("Tile grid"); JButton save = new JButton("Save..."); final JButton showChain = new JButton("Show chain in separate window"); JPanel buttonBar = new JPanel(); buttonBar.setLayout(new FlowLayout(FlowLayout.LEFT)); buttonBar.add(zoomIn); buttonBar.add(zoomOut); buttonBar.add(tileGrid); buttonBar.add(save); buttonBar.add(showChain); // actual image viewer display = new ZoomableImageDisplay(); // display.setBackground(Color.BLACK); tileGrid.setSelected(display.isTileGridVisible()); // the "status bar" status = new JLabel("Move on the image to display pixel values... "); // compose add(buttonBar, BorderLayout.NORTH); add(new JScrollPane(display), BorderLayout.CENTER); add(status, BorderLayout.SOUTH); // events zoomIn.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { display.setScale(display.getScale() * 2.0); if (relatedViewer != null) { relatedViewer.display.setScale(relatedViewer.display.getScale() * 2.0); } } }); zoomOut.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { display.setScale(display.getScale() / 2.0); if (relatedViewer != null) { relatedViewer.display.setScale(relatedViewer.display.getScale() / 2.0); } } }); tileGrid.addChangeListener(new ChangeListener() { public void stateChanged(ChangeEvent e) { display.setTileGridVisible(tileGrid.isSelected()); if (relatedViewer != null) { relatedViewer.display.setTileGridVisible(tileGrid.isSelected()); } } }); save.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent arg0) { // File location = getStartupLocation(); JFileChooser chooser = new JFileChooser(); chooser.setFileFilter(new FileFilter() { @Override public String getDescription() { return "*.png"; } @Override public boolean accept(File file) { return file.isDirectory() || file.getName().toLowerCase().endsWith(".png"); } }); int result = chooser.showSaveDialog(ImageViewer.this); if (result == JFileChooser.APPROVE_OPTION) { File selected = chooser.getSelectedFile(); if (!selected.getName().toLowerCase().endsWith(".png")) { selected = new File(selected.getParentFile(), selected.getName() + ".png"); } lastDirectory = selected.getParentFile(); try { ImageIO.write(image, "PNG", selected); status.setText("File successfully saved"); } catch (IOException e) { status.setText("Failed to save file: " + e.getMessage()); } } } }); showChain.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { RenderedImageBrowser.showChain(image); } }); display.addMouseMotionListener(new MouseMotionAdapter() { @Override public void mouseMoved(MouseEvent e) { if (pixelIter != null) { int x = (int) Math.round(e.getX() / display.getScale()); int y = (int) Math.round(e.getY() / display.getScale()); sb.setLength(0); if ((x < image.getMinX()) || (x >= (image.getMinX() + image.getWidth())) || (y < image.getMinY()) || (y >= (image.getMinY() + image.getHeight()))) { sb.append("Outside of image bounds"); } else { sb.append("Value at "); sb.append(x).append(", ").append(y).append(": ["); if ((dataType == DataBuffer.TYPE_DOUBLE) || (dataType == DataBuffer.TYPE_FLOAT)) { pixelIter.getPixel(x, y, dpixel); for (int i = 0; i < dpixel.length; i++) { sb.append(dpixel[i]); if (i < (dpixel.length - 1)) { sb.append(", "); } } } else { // integer samples pixelIter.getPixel(x, y, ipixel); for (int i = 0; i < ipixel.length; i++) { sb.append(ipixel[i]); if (i < (ipixel.length - 1)) { sb.append(", "); } } } sb.append(']'); } status.setText(sb.toString()); } } }); } // protected File getStartupLocation() // { // if (lastDirectory != null) // { // // REMEDIATION:Path Manipulation:Critical:STIGCAT1 // SecurityValidator.getDirectoryPathValidator().validate( // "PropertyUtil.getFileFromClasspath", lastDirectory.getAbsolutePath(), false); // // return lastDirectory; // } // else // { // // REMEDIATION:Path Manipulation:Critical:STIGCAT1 // return new File(SecurityValidator.getFileNameValidator().validate( // "ImageViewer.getStartupLocation", "/tmp", false)); // } // } public void setImage(RenderedImage image) { this.image = image; if(image == null) { display.setVisible(false); pixelIter = null; } else { display.setImage(image); display.setVisible(true); pixelIter = RandomIterFactory.create(image, null); ipixel = new int[image.getSampleModel().getNumBands()]; dpixel = new double[image.getSampleModel().getNumBands()]; } } public ImageViewer getRelatedViewer() { return relatedViewer; } public void setRelatedViewer(ImageViewer relatedViewer) { this.relatedViewer = relatedViewer; } public void setStatusMessage(String message) { status.setText(message); } }