/** * @file EffectsMenu.java * @brief Menu holder for various image effects. * * @section License * * Copyright (C) 2009, 2012 IsmAvatar <IsmAvatar@gmail.com> * Copyright (C) 2009 Serge Humphrey <bob@bobtheblueberry.com> * Copyright (C) 2013 jimn346 <jds9496@gmail.com> * Copyright (C) 2014 Robert B. Colton * * This file is a part of JEIE. * * 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 3 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, see <http://www.gnu.org/licenses/>. **/ package org.jeie; import java.awt.AlphaComposite; import java.awt.Color; import java.awt.Composite; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Image; import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.image.BufferedImage; import java.awt.image.ConvolveOp; import java.awt.image.FilteredImageSource; import java.awt.image.Kernel; import java.awt.image.RescaleOp; import javax.swing.JMenu; import javax.swing.JMenuItem; import javax.swing.KeyStroke; import org.jeie.resources.Resources; public class EffectsMenu extends JMenu implements ActionListener { private static final long serialVersionUID = 1L; public Jeie jeie; public class Blur implements ImageAction { public int amount; public Blur(int amt) { amount = amt; } public void paint(Graphics g) { Canvas c = jeie.canvas; Graphics2D g2 = (Graphics2D) g; // create the blur kernel int numCoords = amount * amount; float blurFactor = 1.0f / numCoords; float[] blurKernel = new float[numCoords]; for (int j = 0; j < numCoords; j++) blurKernel[j] = blurFactor; Kernel k = new Kernel(amount,amount,blurKernel); ConvolveOp blur = new ConvolveOp(k,ConvolveOp.EDGE_NO_OP,null); BufferedImage img = c.getRenderImage(); //Clear the image. g2.setBackground(new Color(0, 0, 0, 0)); g2.clearRect(0,0,img.getWidth(),img.getHeight()); g2.drawImage(img,blur,0,0); } public boolean copiesRaster() { return true; } } public class Value implements ImageAction { public float amount; public Value(float amt) { amount = amt; } public void paint(Graphics g) { Canvas c = jeie.canvas; Graphics2D g2 = (Graphics2D) g; float[] scale = { amount,amount,amount,1.0f }; // keep alpha float[] offsets = { 0.0f,0.0f,0.0f,0.0f }; RescaleOp value = new RescaleOp(scale,offsets,null); BufferedImage img = c.getRenderImage(); //Clear the image. g2.setBackground(new Color(0, 0, 0, 0)); g2.clearRect(0,0,img.getWidth(),img.getHeight()); g2.drawImage(img,value,0,0); } public boolean copiesRaster() { return true; } } public class Invert implements ImageAction { public void paint(Graphics g) { Canvas c = jeie.canvas; Graphics2D g2d = (Graphics2D) g; float[] negFactors = { -1.0f,-1.0f,-1.0f,1.0f }; // keep alpha float[] offsets = { 255f,255f,255f,0.0f }; RescaleOp invert = new RescaleOp(negFactors,offsets,null); BufferedImage img = c.getRenderImage(); //Clear the image. g2d.setBackground(new Color(0, 0, 0, 0)); g2d.clearRect(0,0,img.getWidth(),img.getHeight()); g2d.drawImage(img,invert,0,0); } public boolean copiesRaster() { return true; } } public class Fade implements ImageAction { public Color fadeTo; public float amount; public Fade(Color to, float amt) { fadeTo = to; amount = amt; } public void paint(Graphics g) { Canvas c = jeie.canvas; Graphics2D g2d = (Graphics2D) g; Composite oldComp = g2d.getComposite(); Color oldCol = g2d.getColor(); g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,amount)); g2d.setColor(fadeTo); Dimension d = c.getImageSize(); g2d.fillRect(0,0,d.width,d.height); g2d.setColor(oldCol); g2d.setComposite(oldComp); } public boolean copiesRaster() { return false; } } public class Saturation implements ImageAction { public int amount; public Saturation(int amt) { amount = amt; } public void paint(Graphics g) { Canvas c = jeie.canvas; SaturationFilter filter = new SaturationFilter(amount / 100f); FilteredImageSource filteredSrc = new FilteredImageSource(c.getRenderImage().getSource(), filter); Image image = Toolkit.getDefaultToolkit().createImage(filteredSrc); Graphics2D g2 = (Graphics2D) g; //Clear the image. g2.setBackground(new Color(0, 0, 0, 0)); g2.clearRect(0,0,image.getWidth(null),image.getHeight(null)); g2.drawImage(image, 0, 0, null); } public boolean copiesRaster() { return true; } } public void applyAction(ImageAction act) { Canvas c = jeie.canvas; c.acts.add(act); c.redoActs.clear(); c.redrawCache(); } public EffectsMenu(Jeie jeie) { super(Resources.getString("EffectsMenu.EFFECTS")); this.jeie = jeie; // TODO: Menu Icons add(makeMenuItem("BLUR")); add(makeMenuItem("SATURATION")); add(makeMenuItem("VALUE")); add(makeMenuItem("INVERT")); add(makeMenuItem("FADE")); addSeparator(); JMenuItem colorize = makeMenuItem("COLORIZE"); colorize.setEnabled(false); add(colorize); } public JMenuItem makeMenuItem(String key) { JMenuItem mi = new JMenuItem(Resources.getString("EffectsMenu." + key)); mi.setActionCommand(key); mi.addActionListener(this); mi.setAccelerator(KeyStroke.getKeyStroke(Resources.getKeyboardString("EffectsMenu." + key))); mi.setIcon(Resources.getIconForKey("EffectsMenu." + key)); return mi; } public void actionPerformed(ActionEvent e) { String act = e.getActionCommand(); if (act.equals("BLUR")) { Integer integer = IntegerDialog.getInteger(Resources.getString("EffectsMenu.BLUR_AMOUNT"),1,9,3,3); if (integer != null) applyAction(new Blur(integer)); return; } if (act.equals("SATURATION")) { Integer integer = IntegerDialog.getInteger(Resources.getString("EffectsMenu.SATURATION_AMOUNT"),0,200,100,50); if (integer != null) applyAction(new Saturation(integer)); return; } if (act.equalsIgnoreCase("VALUE")) { Integer integer = IntegerDialog.getInteger(Resources.getString("EffectsMenu.VALUE_AMOUNT"),-10,10,0,5); if (integer != null) applyAction(new Value((integer + 10) / 10.0f)); return; } if (act.equals("INVERT")) { applyAction(new Invert()); return; } if (act.equals("FADE")) { Integer integer = IntegerDialog.getInteger(Resources.getString("EffectsMenu.FADE_AMOUNT"),0,256,128,64); if (integer != null) applyAction(new Fade(Color.BLACK,((float) integer) / 256.0f)); return; } } }