/* * @(#)ImageTest.java 1.8 96/02/27 * * Copyright (c) 1994-1995 Sun Microsystems, Inc. All Rights Reserved. * * Permission to use, copy, modify, and distribute this software * and its documentation for NON-COMMERCIAL or COMMERCIAL purposes and * without fee is hereby granted. * Please refer to the file http://java.sun.com/copy_trademarks.html * for further important copyright and trademark information and to * http://java.sun.com/licensing.html for further important licensing * information for the Java (tm) Technology. * * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. * * THIS SOFTWARE IS NOT DESIGNED OR INTENDED FOR USE OR RESALE AS ON-LINE * CONTROL EQUIPMENT IN HAZARDOUS ENVIRONMENTS REQUIRING FAIL-SAFE * PERFORMANCE, SUCH AS IN THE OPERATION OF NUCLEAR FACILITIES, AIRCRAFT * NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL, DIRECT LIFE * SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH THE FAILURE OF THE * SOFTWARE COULD LEAD DIRECTLY TO DEATH, PERSONAL INJURY, OR SEVERE * PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH RISK ACTIVITIES"). SUN * SPECIFICALLY DISCLAIMS ANY EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR * HIGH RISK ACTIVITIES. */ import java.awt.*; import java.awt.image.*; import java.awt.event.*; import java.applet.Applet; public class ImageTest extends Applet { public void init() { setLayout(new BorderLayout()); add("Center", new ImagePanel(this)); add("North", new ImageHelp()); setVisible(true); } public String getAppletInfo() { return "A simple image manipulation tool."; } } class ImageHelp extends Panel { public ImageHelp() { setLayout(new GridLayout(5, 1)); add(new Label("Move the images with the mouse, with < > ^ v, or with [L]eft/[R]ight/[U]p/[D]own", Label.CENTER)); add(new Label("Resize the images with +/-", Label.CENTER)); add(new Label("[T]oggle a color filter with the T key", Label.CENTER)); add(new Label("Change the alpha with (Shift)+/-", Label.CENTER)); add(new Label("Rotate the image with (Shift)<> or (Shift)[L]eft/[R]ight", Label.CENTER)); } } class ImagePanel extends Panel { Applet applet; public ImagePanel(Applet app) { applet = app; setLayout(new BorderLayout()); Panel grid = new Panel(); grid.setLayout(new GridLayout(0, 2)); add("Center", grid); grid.add(new ImageCanvas(applet, makeDitherImage(), 0.5)); Image joe = applet.getImage(applet.getDocumentBase(), "../graphics/joe.surf.yellow.small.gif"); grid.add(new ImageCanvas(applet, joe, 1.0)); setBounds(0, 0, 20, 20); } Image makeDitherImage() { int w = 100; int h = 100; int pix[] = new int[w * h]; int index = 0; for (int y = 0; y < h; y++) { int red = (y * 255) / (h - 1); for (int x = 0; x < w; x++) { int blue = (x * 255) / (w - 1); pix[index++] = (255 << 24) | (red << 16) | blue; } } return applet.createImage(new MemoryImageSource(w, h, pix, 0, w)); } } class ImageCanvas extends Canvas implements ImageObserver, KeyListener, MouseListener, MouseMotionListener, FocusListener { double hmult = 0; int xadd = 0; int yadd = 0; int xprev = 0; int yprev = 0; int imgw = -1; int imgh = -1; int xoff = 0; int yoff = 0; int scalew = -1; int scaleh = -1; boolean focus = false; boolean usefilter = false; static final int numalphas = 9; int alpha = numalphas - 1; static final int numrotations = 8; int rotation = 0; ImageFilter colorfilter; ImageFilter alphafilters[] = new ImageFilter[numalphas]; RotateFilter rotfilters[] = new RotateFilter[numrotations]; Image origimage; Image curimage; Applet applet; public ImageCanvas(Applet app, Image img, double mult) { applet = app; origimage = img; hmult = mult; pickImage(); setBounds(0, 0, 100, 100); addMouseListener(this); addMouseMotionListener(this); addKeyListener(this); addFocusListener(this); } //1.1 event handling public void focusGained(FocusEvent e) { focus = true; repaint(); } public void focusLost(FocusEvent e) { focus = false; repaint(); } public void keyPressed(KeyEvent e) { } public void keyTyped(KeyEvent e) { char key = e.getKeyChar(); switch(key) { case 't': case 'T': usefilter = !usefilter; pickImage(); repaint(); e.consume(); break; case '^': case '6': case 'u': case 'U': yadd -= 5; repaint(); e.consume(); break; case 'v': case 'V': case 'd': case 'D': yadd += 5; repaint(); e.consume(); break; case '>': case 'R': rotation--; if (rotation < 0) { rotation = numrotations - 1; } pickImage(); scalew = scaleh = -1; repaint(); e.consume(); break; case '.': case 'r': xadd += 5; repaint(); e.consume(); break; case '<': case 'L': rotation++; if (rotation >= numrotations) { rotation = 0; } pickImage(); scalew = scaleh = -1; repaint(); e.consume(); break; case ',': case 'l': xadd -= 5; repaint(); e.consume(); break; case '+': if (++alpha > numalphas - 1) { alpha = numalphas - 1; } pickImage(); repaint(); e.consume(); break; case '=': hmult *= 1.2; scalew = scaleh = -1; repaint(); e.consume(); break; case '-': hmult /= 1.2; scalew = scaleh = -1; repaint(); e.consume(); break; case '_': if (--alpha < 0) { alpha = 0; } pickImage(); repaint(); e.consume(); break; } } public void keyReleased(KeyEvent e) { } public void mouseClicked(MouseEvent e) { } public void mousePressed(MouseEvent e) { xprev = e.getX(); yprev = e.getY(); e.consume(); } public void mouseReleased(MouseEvent e) { e.consume(); } public void mouseEntered(MouseEvent e) { requestFocus(); e.consume(); } public void mouseExited(MouseEvent e) { } public void mouseDragged(MouseEvent e) { int x = e.getX(); int y = e.getY(); xadd += x - xprev; yadd += y - yprev; xprev = x; yprev = y; repaint(); e.consume(); } public void mouseMoved(MouseEvent e) { } public void paint(Graphics g) { Rectangle r = getBounds(); int hlines = r.height / 10; int vlines = r.width / 10; if (focus) { g.setColor(Color.red); } else { g.setColor(Color.darkGray); } g.drawRect(0, 0, r.width-1, r.height-1); g.drawLine(0, 0, r.width, r.height); g.drawLine(r.width, 0, 0, r.height); g.drawLine(0, r.height / 2, r.width, r.height / 2); g.drawLine(r.width / 2, 0, r.width / 2, r.height); if (imgw < 0) { imgw = curimage.getWidth(this); imgh = curimage.getHeight(this); if (imgw < 0 || imgh < 0) { return; } } if (scalew < 0) { if (rotation == 0) { scalew = imgw; scaleh = imgh; } else { Rectangle rect = new Rectangle(0, 0, imgw, imgh); rotfilters[rotation].transformBBox(rect); xoff = rect.x; yoff = rect.y; scalew = rect.width; scaleh = rect.height; } scalew = (int) (scalew * hmult); scaleh = (int) (scaleh * hmult); xoff = (imgw - scalew) / 2; yoff = (imgh - scaleh) / 2; } if (imgw != scalew || imgh != scaleh) { g.drawImage(curimage, xadd + xoff, yadd + yoff, scalew, scaleh, this); } else { g.drawImage(curimage, xadd + xoff, yadd + yoff, this); } } static final long updateRate = 100; public synchronized boolean imageUpdate(Image img, int infoflags, int x, int y, int w, int h) { if (img != curimage) { return false; } boolean ret = true; boolean dopaint = false; long updatetime = 0; if ((infoflags & WIDTH) != 0) { imgw = w; dopaint = true; } if ((infoflags & HEIGHT) != 0) { imgh = h; dopaint = true; } if ((infoflags & (FRAMEBITS | ALLBITS)) != 0) { dopaint = true; ret = false; } else if ((infoflags & SOMEBITS) != 0) { dopaint = true; updatetime = updateRate; } if ((infoflags & ERROR) != 0) { ret = false; } if (dopaint) { repaint(updatetime); } return ret; } public synchronized Image pickImage() { ImageProducer src = origimage.getSource(); if (alpha != numalphas - 1) { ImageFilter imgf = alphafilters[alpha]; if (imgf == null) { int alphaval = (alpha * 255) / (numalphas - 1); imgf = new AlphaFilter(alphaval); alphafilters[alpha] = imgf; } src = new FilteredImageSource(src, imgf); } if (rotation != 0) { RotateFilter imgf = rotfilters[rotation]; if (imgf == null) { double angle = (2 * Math.PI * rotation) / numrotations; imgf = new RotateFilter(angle); rotfilters[rotation] = imgf; } src = new FilteredImageSource(src, imgf); } if (usefilter) { if (colorfilter == null) { colorfilter = new RedBlueSwapFilter(); } src = new FilteredImageSource(src, colorfilter); } Image choice; if (src == origimage.getSource()) { choice = origimage; } else { choice = applet.createImage(src); } if (curimage != choice) { if (curimage != null && curimage != origimage) { curimage.flush(); } curimage = choice; } return choice; } } class RedBlueSwapFilter extends RGBImageFilter { public RedBlueSwapFilter() { canFilterIndexColorModel = true; } public void setColorModel(ColorModel model) { if (model instanceof DirectColorModel) { DirectColorModel dcm = (DirectColorModel) model; int rm = dcm.getRedMask(); int gm = dcm.getGreenMask(); int bm = dcm.getBlueMask(); int am = dcm.getAlphaMask(); int bits = dcm.getPixelSize(); dcm = new DirectColorModel(bits, bm, gm, rm, am); substituteColorModel(model, dcm); consumer.setColorModel(dcm); } else { super.setColorModel(model); } } public int filterRGB(int x, int y, int rgb) { return ((rgb & 0xff00ff00) | ((rgb & 0xff0000) >> 16) | ((rgb & 0xff) << 16)); } } class AlphaFilter extends RGBImageFilter { ColorModel origmodel; ColorModel newmodel; int alphaval; public AlphaFilter(int alpha) { alphaval = alpha; canFilterIndexColorModel = true; } public int filterRGB(int x, int y, int rgb) { int alpha = (rgb >> 24) & 0xff; alpha = alpha * alphaval / 255; return ((rgb & 0x00ffffff) | (alpha << 24)); } }