Java Tutorial/2D Graphics/Clip

Материал из Java эксперт
Перейти к: навигация, поиск

A clipping area can also be created from a text string.

/*
 * @(#)ClipImage.java 1.2 98/07/09
 *
 * Copyright (c) 1998 Sun Microsystems, Inc. All Rights Reserved.
 *
 * Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
 * modify and redistribute this software in source and binary code form,
 * provided that i) this copyright notice and license appear on all copies of
 * the software; and ii) Licensee does not utilize the software in a manner
 * which is disparaging to Sun.
 *
 * This software is provided "AS IS," without a warranty of any kind. ALL
 * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
 * IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
 * NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
 * LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
 * OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
 * LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
 * INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
 * CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
 * OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGES.
 *
 * This software is not designed or intended for use in on-line control of
 * aircraft, air traffic, aircraft navigation or aircraft communications; or in
 * the design, construction, operation or maintenance of any nuclear
 * facility. Licensee represents and warrants that it will not use or
 * redistribute the Software for such purposes.
 */
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.font.FontRenderContext;
import java.awt.font.TextLayout;
import java.awt.geom.AffineTransform;
import java.net.URL;
import javax.swing.ImageIcon;
import javax.swing.JApplet;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Starry extends JApplet {
  public void init() {
    Image starry = new ImageIcon("yourFile.gif").getImage();
    StarPanel starPanel = new StarPanel(starry);
    getContentPane().add(starPanel, BorderLayout.CENTER);
  }
  protected URL getURL(String filename) {
    URL codeBase = this.getCodeBase();
    URL url = null;
    try {
      url = new URL(codeBase, filename);
    } catch (java.net.MalformedURLException e) {
      System.out.println("Couldn"t create image: " + "badly specified URL");
      return null;
    }
    return url;
  }
  public static void main(String[] args) {
    Image starry = new ImageIcon("yourFile.gif").getImage();
    StarPanel starPanel = new StarPanel(starry);
    JFrame f = new JFrame("Starry");
    f.addWindowListener(new WindowAdapter() {
      public void windowClosing(WindowEvent e) {
        System.exit(0);
      }
    });
    f.getContentPane().add(starPanel, BorderLayout.CENTER);
    f.setSize(new Dimension(550, 200));
    f.setVisible(true);
  }
}
class StarPanel extends JPanel {
  Image img;
  int w, h;
  public StarPanel(Image img) {
    this.img = img;
  }
  public void paintComponent(Graphics g) {
    super.paintComponent(g);
    setBackground(Color.white);
    w = getSize().width;
    h = getSize().height;
    Graphics2D g2;
    g2 = (Graphics2D) g;
    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    g2.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
    FontRenderContext frc = g2.getFontRenderContext();
    Font f = new Font("Helvetica", 1, w / 10);
    String s = new String("The Starry Night");
    TextLayout textTl = new TextLayout(s, f, frc);
    AffineTransform transform = new AffineTransform();
    Shape outline = textTl.getOutline(null);
    Rectangle r = outline.getBounds();
    transform = g2.getTransform();
    transform.translate(w / 2 - (r.width / 2), h / 2 + (r.height / 2));
    g2.transform(transform);
    g2.setColor(Color.blue);
    g2.draw(outline);
    g2.setClip(outline);
    g2.drawImage(img, r.x, r.y, r.width, r.height, this);
  }
}





Animate a clipping path to reveal different portions of an image

/*
 *
 * Copyright (c) 1998 Sun Microsystems, Inc. All Rights Reserved.
 *
 * Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
 * modify and redistribute this software in source and binary code form,
 * provided that i) this copyright notice and license appear on all copies of
 * the software; and ii) Licensee does not utilize the software in a manner
 * which is disparaging to Sun.
 *
 * This software is provided "AS IS," without a warranty of any kind. ALL
 * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
 * IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
 * NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
 * LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
 * OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
 * LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
 * INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
 * CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
 * OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGES.
 *
 * This software is not designed or intended for use in on-line control of
 * aircraft, air traffic, aircraft navigation or aircraft communications; or in
 * the design, construction, operation or maintenance of any nuclear
 * facility. Licensee represents and warrants that it will not use or
 * redistribute the Software for such purposes.
 */
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.RenderingHints;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.awt.geom.AffineTransform;
import java.awt.geom.Arc2D;
import java.awt.geom.Ellipse2D;
import java.awt.geom.GeneralPath;
import java.awt.geom.Rectangle2D;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
import java.net.URL;
import javax.swing.ImageIcon;
import javax.swing.JApplet;
import javax.swing.JFrame;
/**
 * Animated clipping of an image & shapes with alpha.
 */
public class ClipImage extends JApplet implements Runnable {
  private Image img;
  private final double OINC[] = { 5.0, 3.0 };
  private final double SINC[] = { 5.0, 5.0 };
  private double x, y;
  private double ix = OINC[0];
  private double iy = OINC[1];
  private double iw = SINC[0];
  private double ih = SINC[1];
  private double ew, eh; // ellipse width & height
  private GeneralPath p = new GeneralPath();
  private AffineTransform at = new AffineTransform();
  private BasicStroke bs = new BasicStroke(20.0f);
  private Arc2D arc = new Arc2D.Float();
  private Ellipse2D ellipse = new Ellipse2D.Float();
  private RoundRectangle2D roundRect = new RoundRectangle2D.Float();
  private Rectangle2D rect = new Rectangle2D.Float();
  private Color redBlend = new Color(255, 0, 0, 120);
  private Color greenBlend = new Color(0, 255, 0, 120);
  private Thread thread;
  private BufferedImage offImg;
  private int w, h;
  private boolean newBufferedImage;
  public void init() {
    setBackground(Color.white);
    img = new ImageIcon("yourFile.gif").getImage();
  }
  public void drawDemo(Graphics2D g2) {
    if (newBufferedImage) {
      x = Math.random() * w;
      y = Math.random() * h;
      ew = (Math.random() * w) / 2;
      eh = (Math.random() * h) / 2;
    }
    x += ix;
    y += iy;
    ew += iw;
    eh += ih;
    if (ew > w / 2) {
      ew = w / 2;
      iw = Math.random() * -w / 16 - 1;
    }
    if (ew < w / 8) {
      ew = w / 8;
      iw = Math.random() * w / 16 + 1;
    }
    if (eh > h / 2) {
      eh = h / 2;
      ih = Math.random() * -h / 16 - 1;
    }
    if (eh < h / 8) {
      eh = h / 8;
      ih = Math.random() * h / 16 + 1;
    }
    if ((x + ew) > w) {
      x = (w - ew) - 1;
      ix = Math.random() * -w / 32 - 1;
    }
    if (x < 0) {
      x = 2;
      ix = Math.random() * w / 32 + 1;
    }
    if ((y + eh) > h) {
      y = (h - eh) - 2;
      iy = Math.random() * -h / 32 - 1;
    }
    if (y < 0) {
      y = 2;
      iy = Math.random() * h / 32 + 1;
    }
    ellipse.setFrame(x, y, ew, eh);
    g2.setClip(ellipse);
    rect.setRect(x + 5, y + 5, ew - 10, eh - 10);
    g2.clip(rect);
    g2.drawImage(img, 0, 0, w, h, this);
    p.reset();
    p.moveTo(-w / 2.0f, -h / 8.0f);
    p.lineTo(+w / 2.0f, -h / 8.0f);
    p.lineTo(-w / 4.0f, +h / 2.0f);
    p.lineTo(+0.0f, -h / 2.0f);
    p.lineTo(+w / 4.0f, +h / 2.0f);
    p.closePath();
    at.setToIdentity();
    at.translate(w * .5f, h * .5f);
    g2.transform(at);
    g2.setStroke(bs);
    g2.setPaint(redBlend);
    g2.draw(p);
    at.setToIdentity();
    g2.setTransform(at);
    g2.setPaint(greenBlend);
    for (int yy = 0; yy < h; yy += 50) {
      for (int xx = 0, i = 0; xx < w; i++, xx += 50) {
        switch (i) {
        case 0:
          arc.setArc(xx, yy, 25, 25, 45, 270, Arc2D.PIE);
          g2.fill(arc);
          break;
        case 1:
          ellipse.setFrame(xx, yy, 25, 25);
          g2.fill(ellipse);
          break;
        case 2:
          roundRect.setRoundRect(xx, yy, 25, 25, 4, 4);
          g2.fill(roundRect);
          break;
        case 3:
          rect.setRect(xx, yy, 25, 25);
          g2.fill(rect);
          i = -1;
        }
      }
    }
  }
  public Graphics2D createDemoGraphics2D(Graphics g) {
    Graphics2D g2 = null;
    if (offImg == null || offImg.getWidth() != w || offImg.getHeight() != h) {
      offImg = (BufferedImage) createImage(w, h);
      newBufferedImage = true;
    }
    if (offImg != null) {
      g2 = offImg.createGraphics();
      g2.setBackground(getBackground());
    }
    // .. set attributes ..
    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    g2.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
    // .. clear canvas ..
    g2.clearRect(0, 0, w, h);
    return g2;
  }
  public void paint(Graphics g) {
    w = getWidth();
    h = getHeight();
    if (w <= 0 || h <= 0)
      return;
    Graphics2D g2 = createDemoGraphics2D(g);
    drawDemo(g2);
    g2.dispose();
    if (offImg != null && isShowing()) {
      g.drawImage(offImg, 0, 0, this);
    }
    newBufferedImage = false;
  }
  public void start() {
    thread = new Thread(this);
    thread.start();
  }
  public synchronized void stop() {
    thread = null;
  }
  public void run() {
    Thread me = Thread.currentThread();
    while (thread == me && isShowing()) {
      Graphics g = getGraphics();
      paint(g);
      g.dispose();
      thread.yield();
    }
    thread = null;
  }
  protected URL getURL(String filename) {
    URL codeBase = this.getCodeBase();
    URL url = null;
    try {
      url = new URL(codeBase, filename);
    } catch (java.net.MalformedURLException e) {
      System.out.println("Couldn"t create image: " + "badly specified URL");
      return null;
    }
    return url;
  }
  public static void main(String s[]) {
    final ClipImage demo = new ClipImage();
    WindowListener l = new WindowAdapter() {
      public void windowClosing(WindowEvent e) {
        System.exit(0);
      }
      public void windowDeiconified(WindowEvent e) {
        demo.start();
      }
      public void windowIconified(WindowEvent e) {
        demo.stop();
      }
    };
    JFrame f = new JFrame("Java 2D Demo - ClipImage");
    f.addWindowListener(l);
    f.getContentPane().add("Center", demo);
    f.setSize(new Dimension(400, 300));
    f.show();
    demo.start();
  }
}





Clip between Rectangle and Ellipse2D

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.geom.Ellipse2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class ClipBetweenRectangleEllipse2D extends JFrame {
  public ClipBetweenRectangleEllipse2D() {
    getContentPane().add(new DrawingCanvas());
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setSize(500, 500);
    setVisible(true);
  }
  public static void main(String arg[]) {
    new ClipBetweenRectangleEllipse2D();
  }
}
class DrawingCanvas extends JPanel {
  DrawingCanvas() {
    setSize(300, 300);
    setBackground(Color.white);
  }
  public void paint(Graphics g) {
    Graphics2D g2D = (Graphics2D) g;
    Graphics2D g2 = (Graphics2D) g;
    int w = getSize().width;
    int h = getSize().height;
    Ellipse2D e = new Ellipse2D.Float(w / 4.0f, h / 4.0f, w / 2.0f, h / 2.0f);
    g2.setClip(e);
    g2.setColor(Color.red);
    g2.fillRect(0, 0, w, h);
    Rectangle r = new Rectangle(w/2, h/2, w/2, h/2);
    g2.clip(r);
    g2.setColor(Color.green);
    g2.fillRect(0, 0, w, h);
  }
}





Clip Demo

import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Ellipse2D;
public class MainClass extends Frame {
  public static void main(String[] args) {
    (new MainClass()).setVisible(true);
  }
  public MainClass() {
    setSize(250, 250);
  }
  public void paint(Graphics g) {
    Graphics2D g2d = (Graphics2D) g;
    Ellipse2D e = new Ellipse2D.Float(10, 10, 200, 200);
    g2d.clip(e);
    g2d.fillRect(40, 60, 500, 500);
  }
}





Clipping is restricting of drawing to a certain area.

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Ellipse2D;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
public class Clipping extends JPanel implements ActionListener {
  int x = 8, y = 8, radius = 90;
  Timer timer;
  Image image = new ImageIcon("yourImage.png").getImage();
  double delta[] = { 3, 3 };
  public Clipping() {
    timer = new Timer(15, this);
    timer.start();
  }
  public void paint(Graphics g) {
    Graphics2D g2d = (Graphics2D) g;
    g2d.setClip(new Ellipse2D.Double(x, y, radius, radius));
    g2d.drawImage(image, 5, 5, null);
  }
  public static void main(String[] args) {
    JFrame frame = new JFrame();
    frame.add(new Clipping());
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setSize(400, 400);
    frame.setVisible(true);
  }
  public void actionPerformed(ActionEvent e) {
    int w = 400;
    int h = 400;
    if (x < 0) {
      delta[0] = Math.random() % 4 + 5;
    } else if (x > w - radius) {
      delta[0] = -(Math.random() % 4 + 5);
    }
    if (y < 0) {
      delta[1] = Math.random() % 4 + 5;
    } else if (y > h - radius) {
      delta[1] = -(Math.random() % 4 + 5);
    }
    x += delta[0];
    y += delta[1];
    repaint();
  }
}





Setting the Clipping Area with a Shape

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Shape;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JFrame;
public class BasicDraw {
  public static void main(String[] args) {
    new BasicDraw();
  }
  BasicDraw() {
    JFrame frame = new JFrame();
    frame.add(new MyComponent());
    frame.setSize(300, 300);
    frame.setVisible(true);
  }
}
class MyComponent extends JComponent {
  public void paint(Graphics g) {
    Graphics2D g2d = (Graphics2D) g;
    Shape shape = new java.awt.geom.Ellipse2D.Float(20, 20, 200,200);
    g2d.setClip(shape);
    int x = 0;
    int y = 0;
    g2d.drawImage(new ImageIcon("a.png").getImage(), x, y, this);
  }
}