/* * Copyright 2017 Laszlo Balazs-Csiki * * This file is part of Pixelitor. Pixelitor is free software: you * can redistribute it and/or modify it under the terms of the GNU * General Public License, version 3 as published by the Free * Software Foundation. * * Pixelitor 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 Pixelitor. If not, see <http://www.gnu.org/licenses/>. */ package pixelitor.gui.utils; import pixelitor.io.FileExtensionUtils; import pixelitor.utils.Messages; import javax.imageio.ImageIO; import javax.swing.*; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Image; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.io.File; import java.io.IOException; import static java.awt.Color.BLACK; import static java.awt.Color.WHITE; /** * Image preview panel for the open file chooser */ public class ImagePreviewPanel extends JPanel implements PropertyChangeListener { private static final int SIZE = 200; private static final int EMPTY_SPACE_AT_LEFT = 5; private Image smallImage; private final Color backgroundColor; private int newImgWidth; private int newImgHeight; private int imgWidth; private int imgHeight; private static final int MSG_STRING_X = 20; private static final int MSG_STRING_Y = 31; public ImagePreviewPanel() { setPreferredSize(new Dimension(SIZE, SIZE)); backgroundColor = getBackground(); } // the property change events form the JFileChooser @Override public void propertyChange(PropertyChangeEvent e) { File file = getFileFromFileChooserEvent(e); if (file == null) { smallImage = null; repaint(); return; } String fileName = file.getAbsolutePath(); if (FileExtensionUtils.hasSupportedInputExt(file)) { createThumbImage(file, fileName); repaint(); } } private void createThumbImage(File file, String fileName) { // we read the whole image and downscale it to a thumb // TODO perhaps it is possible to read a thumb directly // TODO another problem is that ora and pxc files are reported as "Unrecognized" Image bigImage = null; if (fileName.toLowerCase().endsWith(".bmp")) { try { bigImage = ImageIO.read(file); } catch (IOException ex) { Messages.showException(ex); } } else { // TODO: load all with ImageIO and cache // it seems that ImageIcon loads slower but it is cached ImageIcon icon = new ImageIcon(fileName); bigImage = icon.getImage(); } smallImage = scaleImage(bigImage); } private static File getFileFromFileChooserEvent(PropertyChangeEvent e) { File file; String propertyName = e.getPropertyName(); switch (propertyName) { case JFileChooser.DIRECTORY_CHANGED_PROPERTY: file = null; break; case JFileChooser.SELECTED_FILE_CHANGED_PROPERTY: file = (File) e.getNewValue(); break; default: file = null; } return file; } private Image scaleImage(Image img) { if (img == null) { return null; } imgWidth = img.getWidth(null); imgHeight = img.getHeight(null); int availableWidth = getWidth() - EMPTY_SPACE_AT_LEFT; int availableHeight = getHeight(); double heightScale = availableHeight / (double) imgHeight; double widthScale = availableWidth / (double) imgWidth; double scale = Math.min(heightScale, widthScale); newImgWidth = (int) (scale * (double) imgWidth); newImgHeight = (int) (scale * (double) imgHeight); return img.getScaledInstance(newImgWidth, newImgHeight, Image.SCALE_FAST); } @Override public void paintComponent(Graphics g) { g.setColor(backgroundColor); int panelWidth = getWidth(); int panelHeight = getHeight(); g.fillRect(0, 0, panelWidth, panelHeight); if (smallImage != null) { int x = (panelWidth - newImgWidth) / 2 + EMPTY_SPACE_AT_LEFT; int y = (panelHeight - newImgHeight) / 2; g.drawImage(smallImage, x, y, this); boolean doubleDrawMsg = y < MSG_STRING_Y - 10; String msg = "Size: " + imgWidth + " x " + imgHeight + " pixels"; if (imgWidth == -1 || imgHeight == -1) { msg = "Unrecognized!"; doubleDrawMsg = false; } g.setColor(BLACK); g.drawString(msg, MSG_STRING_X, MSG_STRING_Y); if (doubleDrawMsg) { g.setColor(WHITE); g.drawString(msg, MSG_STRING_X - 1, MSG_STRING_Y - 1); } } } }