Path: blob/master/src/demo/share/jfc/J2Ddemo/java2d/demos/Images/ImageOps.java
41175 views
/*1*2* Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.3*4* Redistribution and use in source and binary forms, with or without5* modification, are permitted provided that the following conditions6* are met:7*8* - Redistributions of source code must retain the above copyright9* notice, this list of conditions and the following disclaimer.10*11* - Redistributions in binary form must reproduce the above copyright12* notice, this list of conditions and the following disclaimer in the13* documentation and/or other materials provided with the distribution.14*15* - Neither the name of Oracle nor the names of its16* contributors may be used to endorse or promote products derived17* from this software without specific prior written permission.18*19* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS20* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,21* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR22* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR23* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,24* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,25* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR26* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF27* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING28* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS29* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.30*/31package java2d.demos.Images;323334import java.awt.BorderLayout;35import java.awt.Color;36import java.awt.Component;37import java.awt.Dimension;38import java.awt.Font;39import java.awt.Graphics2D;40import java.awt.Image;41import java.awt.event.ActionEvent;42import java.awt.event.ActionListener;43import java.awt.geom.AffineTransform;44import java.awt.image.BufferedImage;45import java.awt.image.BufferedImageOp;46import java.awt.image.ByteLookupTable;47import java.awt.image.ConvolveOp;48import java.awt.image.Kernel;49import java.awt.image.LookupOp;50import java.awt.image.RescaleOp;51import java2d.ControlsSurface;52import java2d.CustomControls;53import javax.swing.JComboBox;54import javax.swing.JSlider;55import javax.swing.SwingConstants;56import javax.swing.event.ChangeEvent;57import javax.swing.event.ChangeListener;585960/**61* Images drawn using operators such as ConvolveOp LowPass & Sharpen,62* LookupOp and RescaleOp.63*/64@SuppressWarnings("serial")65public class ImageOps extends ControlsSurface implements ChangeListener {6667protected JSlider slider1, slider2;68private static final String[] imgName = { "bld.jpg", "boat.png" };69private static final BufferedImage[] img = new BufferedImage[imgName.length];70private static final String[] opsName = {71"Threshold", "RescaleOp", "Invert", "Yellow Invert", "3x3 Blur",72"3x3 Sharpen", "3x3 Edge", "5x5 Edge" };73private static final BufferedImageOp[] biop =74new BufferedImageOp[opsName.length];75private static int rescaleFactor = 128;76private static float rescaleOffset = 0;77private static final int low = 100, high = 200;78private int opsIndex, imgIndex;7980static {81thresholdOp(low, high);82int i = 1;83biop[i++] = new RescaleOp(1.0f, 0, null);84byte[] invert = new byte[256];85byte[] ordered = new byte[256];86for (int j = 0; j < 256; j++) {87invert[j] = (byte) (256 - j);88ordered[j] = (byte) j;89}90biop[i++] = new LookupOp(new ByteLookupTable(0, invert), null);91byte[][] yellowInvert = new byte[][] { invert, invert, ordered };92biop[i++] = new LookupOp(new ByteLookupTable(0, yellowInvert), null);93int[][] dim = { { 3, 3 }, { 3, 3 }, { 3, 3 }, { 5, 5 } };94float[][] data = { { 0.1f, 0.1f, 0.1f, // 3x3 blur950.1f, 0.2f, 0.1f,960.1f, 0.1f, 0.1f },97{ -1.0f, -1.0f, -1.0f, // 3x3 sharpen98-1.0f, 9.0f, -1.0f,99-1.0f, -1.0f, -1.0f },100{ 0.f, -1.f, 0.f, // 3x3 edge101-1.f, 5.f, -1.f,1020.f, -1.f, 0.f },103{ -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, // 5x5 edge104-1.0f, -1.0f, -1.0f, -1.0f, -1.0f,105-1.0f, -1.0f, 24.0f, -1.0f, -1.0f,106-1.0f, -1.0f, -1.0f, -1.0f, -1.0f,107-1.0f, -1.0f, -1.0f, -1.0f, -1.0f } };108for (int j = 0; j < data.length; j++, i++) {109biop[i] = new ConvolveOp(new Kernel(dim[j][0], dim[j][1], data[j]));110}111}112113@SuppressWarnings("LeakingThisInConstructor")114public ImageOps() {115setDoubleBuffered(true);116setBackground(Color.white);117for (int i = 0; i < imgName.length; i++) {118Image image = getImage(imgName[i]);119int iw = image.getWidth(this);120int ih = image.getHeight(this);121img[i] = new BufferedImage(iw, ih, BufferedImage.TYPE_INT_RGB);122img[i].createGraphics().drawImage(image, 0, 0, null);123}124slider1 = new JSlider(SwingConstants.VERTICAL, 0, 255, low);125slider1.setPreferredSize(new Dimension(15, 100));126slider1.addChangeListener(this);127slider2 = new JSlider(SwingConstants.VERTICAL, 0, 255, high);128slider2.setPreferredSize(new Dimension(15, 100));129slider2.addChangeListener(this);130setControls(new Component[] { new DemoControls(this), slider1, slider2 });131setConstraints(new String[] {132BorderLayout.NORTH, BorderLayout.WEST, BorderLayout.EAST });133}134135public static void thresholdOp(int low, int high) {136byte[] threshold = new byte[256];137for (int j = 0; j < 256; j++) {138if (j > high) {139threshold[j] = (byte) 255;140} else if (j < low) {141threshold[j] = (byte) 0;142} else {143threshold[j] = (byte) j;144}145}146biop[0] = new LookupOp(new ByteLookupTable(0, threshold), null);147}148149@Override150public void render(int w, int h, Graphics2D g2) {151int iw = img[imgIndex].getWidth(null);152int ih = img[imgIndex].getHeight(null);153AffineTransform oldXform = g2.getTransform();154g2.scale(((double) w) / iw, ((double) h) / ih);155g2.drawImage(img[imgIndex], biop[opsIndex], 0, 0);156g2.setTransform(oldXform);157}158159@Override160public void stateChanged(ChangeEvent e) {161if (e.getSource().equals(slider1)) {162if (opsIndex == 0) {163thresholdOp(slider1.getValue(), high);164} else {165rescaleFactor = slider1.getValue();166biop[1] = new RescaleOp(rescaleFactor / 128.0f, rescaleOffset,167null);168}169} else {170if (opsIndex == 0) {171thresholdOp(low, slider2.getValue());172} else {173rescaleOffset = slider2.getValue();174biop[1] = new RescaleOp(rescaleFactor / 128.0f, rescaleOffset,175null);176}177178}179repaint();180}181182public static void main(String[] s) {183createDemoFrame(new ImageOps());184}185186187static class DemoControls extends CustomControls implements ActionListener {188189ImageOps demo;190JComboBox<String> imgCombo, opsCombo;191Font font = new Font(Font.SERIF, Font.PLAIN, 10);192193@SuppressWarnings("LeakingThisInConstructor")194public DemoControls(ImageOps demo) {195super(demo.name);196this.demo = demo;197add(imgCombo = new JComboBox<>());198imgCombo.setFont(font);199for (String name : ImageOps.imgName) {200imgCombo.addItem(name);201}202imgCombo.addActionListener(this);203add(opsCombo = new JComboBox<>());204opsCombo.setFont(font);205for (String name : ImageOps.opsName) {206opsCombo.addItem(name);207}208opsCombo.addActionListener(this);209}210211@Override212public void actionPerformed(ActionEvent e) {213if (e.getSource().equals(opsCombo)) {214demo.opsIndex = opsCombo.getSelectedIndex();215if (demo.opsIndex == 0) {216demo.slider1.setValue(ImageOps.low);217demo.slider2.setValue(ImageOps.high);218demo.slider1.setEnabled(true);219demo.slider2.setEnabled(true);220} else if (demo.opsIndex == 1) {221demo.slider1.setValue(ImageOps.rescaleFactor);222demo.slider2.setValue((int) ImageOps.rescaleOffset);223demo.slider1.setEnabled(true);224demo.slider2.setEnabled(true);225} else {226demo.slider1.setEnabled(false);227demo.slider2.setEnabled(false);228}229} else if (e.getSource().equals(imgCombo)) {230demo.imgIndex = imgCombo.getSelectedIndex();231}232demo.repaint(10);233}234235@Override236public Dimension getPreferredSize() {237return new Dimension(200, 39);238}239240@Override241@SuppressWarnings("SleepWhileHoldingLock")242public void run() {243try {244Thread.sleep(1111);245} catch (Exception e) {246return;247}248Thread me = Thread.currentThread();249while (thread == me) {250for (int i = 0; i < ImageOps.imgName.length; i++) {251imgCombo.setSelectedIndex(i);252for (int j = 0; j < ImageOps.opsName.length; j++) {253opsCombo.setSelectedIndex(j);254if (j <= 1) {255for (int k = 50; k <= 200; k += 10) {256demo.slider1.setValue(k);257try {258Thread.sleep(200);259} catch (InterruptedException e) {260return;261}262}263}264try {265Thread.sleep(4444);266} catch (InterruptedException e) {267return;268}269}270}271}272thread = null;273}274} // End DemoControls275} // End ImageOps276277278279