Computer Science 15-110, Spring 2010
Class Notes: Graphics, Color, and Polygon Methods
Graphics, Color, and Polygon Methods
import java.awt.*;
import javax.swing.*;
class MyGraphics extends JComponent {
public void paint(Graphics page) {
// Place your paint code here!
}
////////////////////////////////////////////// /// END OF YOUR CODE /// /// (you may ignore all the code below!!! /// //////////////////////////////////////////////
public Dimension getPreferredSize() {
int initialWidth = 500;
int initialHeight = 400;
return new Dimension(initialWidth, initialHeight);
}
public static void main(String[] args) {
JComponent jc = newInstance();
JFrame frame = new JFrame(jc.getClass().getName());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel cp = new JPanel();
cp.setLayout(new BorderLayout());
cp.add(jc);
frame.setContentPane(cp);
frame.pack();
frame.setVisible(true);
}
// Returns an instance of this class as a JComponent. This is necessary so
// students can rename this class without changing the "main" method's body.
public static JComponent newInstance() {
StackTraceElement[] trace = null;
try { throw new RuntimeException(); }
catch (Exception e) { trace = e.getStackTrace(); }
try { return (JComponent)Class.forName(trace[0].getClassName()).newInstance(); }
catch (Exception e) { return null; }
}
} public void paint(Graphics page) {
page.setColor(Color.gray);
page.fillRect(50, 100, 150, 200);
page.setColor(Color.black);
page.drawLine(50, 100, 150, 200); // suprised?
}
public void paint(Graphics page) {
for (int i=0; i<10; i++) {
setLineThickness(page, i);
int x = 100 + 20*i;
page.drawLine(x, 50, x, 150);
}
}
//////////////////////////////////////
/// setLineThickness Helper method
//////////////////////////////////////
public static void setLineThickness(Graphics page, int thickness) {
if (thickness < 0) thickness = 0;
((Graphics2D)page).setStroke(new BasicStroke(thickness));
}
Another Example:
public void paint(Graphics page) {
// See how the same line is drawn differently
// with different line thicknesses
page.setColor(Color.blue);
setLineThickness(page, 20);
page.drawLine(50, 50, 50, 250);
page.setColor(Color.yellow);
setLineThickness(page, 5);
page.drawLine(50, 50, 50, 250);
page.setColor(Color.black);
setLineThickness(page, 1);
page.drawLine(50, 50, 50, 250);
}
public void paint(Graphics page) {
page.fillRect(50, 50, 100, 100);
}
public void paint(Graphics page) {
page.drawRect(50, 50, 100, 100);
page.setColor(Color.blue);
setLineThickness(page, 5);
page.drawRect(100, 100, 100, 100);
}
public void paint(Graphics page) {
page.fillRect(50, 50, 50, 150);
page.setColor(Color.green);
page.fillOval(50, 50, 50, 150);
}
public void paint(Graphics page) {
page.fillRect(50, 50, 50, 150);
page.setColor(Color.green);
page.drawOval(50, 50, 50, 150);
}
public void paint(Graphics page) {
int left = 50, top = 50, width = 50, height = 150;
page.fillRect(left, top, width, height);
int arcWidth = 30, arcHeight = 30;
page.setColor(Color.yellow);
page.fillRoundRect(left, top, width, height, arcWidth, arcHeight);
left += 100;
page.setColor(Color.blue);
page.fillRoundRect(left, top, width, height, arcWidth, arcHeight);
}
public void paint(Graphics page) {
int left = 50, top = 50, width = 50, height = 150;
page.fillRect(left, top, width, height);
int arcWidth = 30, arcHeight = 30;
page.setColor(Color.yellow);
page.drawRoundRect(left, top, width, height, arcWidth, arcHeight);
left += 100;
page.setColor(Color.blue);
page.drawRoundRect(left, top, width, height, arcWidth, arcHeight);
}
public void paint(Graphics page) {
int left = 50, top = 100, width = 100, height = 150;
page.fillRect(left, top, width, height);
int startAngle = 45; // in degrees, where 45 always is the top-right corner!
int extentAngle = 90;
page.setColor(Color.yellow);
page.fillArc(left, top, width, height, startAngle, extentAngle);
startAngle = 180;
extentAngle = 135;
page.setColor(Color.red);
page.fillArc(left, top, width, height, startAngle, extentAngle);
}
public void paint(Graphics page) {
int left = 50, top = 100, width = 100, height = 150;
page.fillRect(left, top, width, height);
int startAngle = 45; // in degrees, where 45 always is the top-right corner!
int extentAngle = 90;
page.setColor(Color.yellow);
page.drawArc(left, top, width, height, startAngle, extentAngle);
startAngle = 180;
extentAngle = 135;
page.setColor(Color.red);
page.drawArc(left, top, width, height, startAngle, extentAngle);
}
public void paint(Graphics page) {
page.fillRect(100, 50, 200, 150);
Polygon p = new Polygon();
p.addPoint(100, 50);
p.addPoint(200, 125);
p.addPoint(300, 50);
page.setColor(Color.green);
page.fillPolygon(p);
}
public void paint(Graphics page) {
page.fillRect(100, 50, 200, 150);
Polygon p = new Polygon();
p.addPoint(100, 50);
p.addPoint(200, 125);
p.addPoint(300, 50);
page.setColor(Color.green);
page.drawPolygon(p);
}
public void paint(Graphics page) {
page.drawString("Carpe Diem", 50, 50);
page.setColor(Color.red);
page.drawLine(50, 50, 100, 50); // surprised?
}
public void paint(Graphics page) {
page.setFont(new Font("Monospaced", Font.PLAIN, 16));
page.drawString("Carpe Diem", 50, 50);
page.setColor(Color.red);
page.setFont(new Font("Serif", Font.BOLD, 32));
page.drawString("Carpe Diem", 50, 100);
page.setColor(Color.blue);
page.setFont(new Font("SansSerif", Font.BOLD|Font.ITALIC, 64));
page.drawString("Carpe Diem", 50, 175);
}
public void paint(Graphics page) {
page.setColor(Color.blue);
page.fillRect(50, 50, 400, 100);
page.setFont(new Font("SansSerif", Font.BOLD, 64));
page.setColor(Color.yellow);
drawCenteredString(page, "Carpe Diem", 50, 50, 400, 100);
}
////////////////////////////////////// /// drawCenteredString Helper methods //////////////////////////////////////
public static int getStringWidth(Graphics page, Font f, String s) {
// Find the size of string s in the font of the Graphics context "page"
FontMetrics fm = page.getFontMetrics(f);
java.awt.geom.Rectangle2D rect = fm.getStringBounds(s, page);
return (int)Math.round(rect.getWidth());
}
public static int getStringHeight(Graphics page, Font f, String s) {
// Find the size of string s in the font of the Graphics context "page"
FontMetrics fm = page.getFontMetrics(f);
java.awt.geom.Rectangle2D rect = fm.getStringBounds(s, page);
return (int)Math.round(rect.getHeight());
}
public static int getStringAscent(Graphics page, Font f, String s) {
// Find the size of string s in the font of the Graphics context "page"
FontMetrics fm = page.getFontMetrics(f);
return fm.getAscent();
}
public static void drawCenteredString(Graphics page, String s, int left, int top, int width, int height) {
Font font = page.getFont();
int textWidth = getStringWidth(page,font,s);
int textHeight = getStringHeight(page,font,s);
int textAscent = getStringAscent(page,font,s);
// Center text horizontally and vertically within provided rectangular bounds
int textX = left + (width - textWidth)/2;
int textY = top + (height - textHeight)/2 + textAscent;
page.drawString(s, textX, textY);
}
imports:
import java.awt.*;
import java.awt.image.*;
import javax.imageio.*;
import java.io.*;
import javax.swing.*;
helper methods:
//////////////////////////////////////
/// Image Helper methods
/////////////////////////////////////
// Paint the given image rotated and scaled with a top-left at x,y
public static void drawImage(Graphics page, Image image, int x, int y, double scale, double radians) {
double imageWidth = image.getWidth(null);
double imageHeight = image.getHeight(null);
Dimension newSize = getImageSize(image, scale, radians);
java.awt.geom.AffineTransform transform = new java.awt.geom.AffineTransform();
transform.translate(x+newSize.getWidth()/2,y+newSize.getHeight()/2); // last (not first!)
transform.rotate(radians);
transform.scale(scale,scale);
transform.translate(-imageWidth/2, -imageHeight/2); // first
((Graphics2D)page).drawImage(image,transform,null);
}
// Same as drawImage, only here we position the image by its center
public static void drawCenteredImage(Graphics page, Image image, int cx, int cy, double scale, double radians) {
Dimension newSize = getImageSize(image, scale, radians);
drawImage(page, image, cx - newSize.width/2, cy - newSize.height/2, scale, radians);
}
// get the size of this image after it has been scaled and rotated
public static Dimension getImageSize(Image image, double scale, double radians) {
double imageWidth = image.getWidth(null);
double imageHeight = image.getHeight(null);
java.awt.geom.AffineTransform transform = new java.awt.geom.AffineTransform();
transform.rotate(radians);
transform.scale(scale,scale);
transform.translate(-imageWidth/2, -imageHeight/2); // first
double[] x = { 0, imageWidth, imageWidth , 0 };
double[] y = { 0, 0 , imageHeight, imageHeight };
double minx=0, maxx=0, miny=0, maxy=0;
java.awt.geom.Point2D.Double src = new java.awt.geom.Point2D.Double();
java.awt.geom.Point2D.Double dst = new java.awt.geom.Point2D.Double();
for (int i=0; i<4; i++) {
src.setLocation(x[i],y[i]);
transform.transform(src,dst);
if (i == 0) {
minx = maxx = dst.getX();
miny = maxy = dst.getY();
}
else {
minx = Math.min(dst.getX(),minx);
miny = Math.min(dst.getY(),miny);
maxx = Math.max(dst.getX(),maxx);
maxy = Math.max(dst.getY(),maxy);
}
}
return new Dimension((int)(maxx-minx), (int)(maxy-miny));
}
// Convert a jpg/png/etc file into an awt BufferedImage
public static BufferedImage loadBufferedImage(String filename) {
File file = new File(filename);
if (!file.exists())
throw new RuntimeException("File " + filename + " does not exist");
try { return ImageIO.read(file); }
catch (Exception e) { throw new RuntimeException(e); }
}
// Verify the given the file format is one that is supported.
public static void verifyFileFormatIsSupported(String format) {
String[] legalFormats = ImageIO.getReaderFormatNames();
for (String legalFormat : legalFormats)
if (legalFormat.equals(format))
return;
throw new RuntimeException("Illegal format " + format + " not in " +
java.util.Arrays.toString(legalFormats));
}
// Save the BufferedImage into the given file -- the image type is determined
// by the extension of the file (.jpg, .png, etc)
public static void saveBufferedImage(BufferedImage image, String filename) {
int dotIndex = filename.lastIndexOf('.');
if (dotIndex < 0) throw new RuntimeException("file must end in .jpg, .png, etc");
String format = filename.substring(dotIndex+1);
verifyFileFormatIsSupported(format);
try { ImageIO.write(image, format, new File(filename)); }
catch (Exception e) { throw new RuntimeException(e); }
}
complete file (with imports and helper methods): DrawImages.java public void paint(Graphics page) { // To run this, first save the image sampleImage.jpg to the current directory // get the dimensions of the draw area int width = this.getWidth(); int height = this.getHeight(); // paint the background a pleasing olive green to complement our image page.setColor(new Color(120,120,50)); page.fillRect(0,0,width,height); // center the full-sized, non-rotated image in the window double scale = 1.0; double rotation = 0.0; BufferedImage image = loadBufferedImage("sampleImage.jpg"); drawCenteredImage(page, image, width/2, height/2, scale, rotation); // now draw a version of the image with its left-top at (0,0) and scaled to be smaller scale = 1.0/5.0; drawImage(page, image, 0, 0, scale, rotation); // and draw a 1/5th version in the top-right corner rotated by 45 degrees // This requires that we obtain the size of the rotated image so we // can compute its resulting left-top rotation = Math.toRadians(45); Dimension newSize = getImageSize(image, scale, rotation); int newLeft = width - newSize.width; int newTop = 0; drawImage(page, image, newLeft, newTop, scale, rotation); }
complete file (with imports and helper methods): EditImages.java public static void main(String[] args) { // To run this, first save the image sampleImage.jpg to the current directory BufferedImage image = loadBufferedImage("sampleImage.jpg"); Dimension dim = getImageSize(image, 1, 0); int imageWidth = dim.width; int imageHeight = dim.height; // Change all "nearly-black" pixels to blue! for (int x=0; x<imageWidth; x++) for (int y=0; y<imageHeight; y++) { int rgba = image.getRGB(x,y); int alpha = (rgba >> 24) & 0xff; int red = (rgba >> 16) & 0xff; int green = (rgba >> 8) & 0xff; int blue = (rgba ) & 0xff; if ((red < 30) && (green < 30) && (blue < 30)) { // we have a black pixel, switch to blue red = 0; green = 0; blue = 255; rgba = (alpha << 24) | (red << 16) | (green << 8) | (blue); image.setRGB(x,y,rgba); } } saveBufferedImage(image, "sampleImage1.jpg"); // Get the graphics and paint a semi-transparent oval in the middle Graphics g = image.getGraphics(); g.setColor(new Color(255, 0, 0, 128)); // semi-transparent red g.fillOval(0, imageHeight/2-20, imageWidth, 40); saveBufferedImage(image, "sampleImage3.jpg"); // Make a new image from scratch int width = 400, height = 200; image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); g = image.getGraphics(); g.setColor(Color.yellow); g.fillRect(0,0,width,height); // add some vertical bars g.setColor(Color.blue); for (int x=20; x<width; x+=50) g.fillRect(x,0,10,height); // and a semi-transparent message g.setColor(new Color(255, 0, 0, 128)); // semi-transparent red again g.setFont(new Font("Arial",Font.BOLD,64)); drawCenteredString(g,"Carpe Diem",0,0,width,height); saveBufferedImage(image, "sampleImage4.jpg"); }
public void paint(Graphics page) {
// For a list of colors, see: http://en.wikipedia.org/wiki/List_of_colors
Color amethyst = new Color(153, 102, 204);
page.setColor(amethyst);
page.fillRect(10, 10, 50, 100);
Color cinnabar = new Color(227, 66, 52);
page.setColor(cinnabar);
page.fillRect(30, 30, 50, 50);
}
public void paint(Graphics page) {
// For a list of colors, see: http://en.wikipedia.org/wiki/List_of_colors
Color amethyst = new Color(153, 102, 204);
page.setColor(amethyst);
page.fillRect(10, 10, 50, 100);
Color semiTransparentCinnabar = new Color(227, 66, 52, 128); page.setColor(semiTransparentCinnabar); page.fillRect(30, 30, 50, 50); }
public void paint(Graphics page) {
Color amethyst = new Color(153, 102, 204);
page.setColor(amethyst);
page.fillRect(10, 10, 50, 100);
Color anotherAmethyst = new Color(153, 102, 204);
page.setColor(anotherAmethyst);
page.fillRect(30, 30, 50, 50);
System.out.println(amethyst == anotherAmethyst); // surprised?
System.out.println(amethyst.equals(anotherAmethyst));
}
public void paint(Graphics page) {
Color amethyst = new Color(153, 102, 204);
page.setColor(amethyst);
page.fillRect(10, 10, 50, 100);
Color brighterAmethyst = amethyst.brighter();
page.setColor(brighterAmethyst);
page.fillRect(30, 30, 50, 50);
}
public void paint(Graphics page) {
Color amethyst = new Color(153, 102, 204);
page.setColor(amethyst);
page.fillRect(10, 10, 50, 100);
Color darkerAmethyst = amethyst.darker();
page.setColor(darkerAmethyst);
page.fillRect(30, 30, 50, 50);
}
public void paint(Graphics page) {
Color amethyst = new Color(153, 102, 204);
page.setColor(amethyst);
page.fillRect(10, 10, 50, 100);
Color semiTransparentCinnabar = new Color(227, 66, 52, 128);
page.setColor(semiTransparentCinnabar);
page.fillRect(30, 30, 50, 50);
System.out.println("RGBA values for semiTransparentCinnabar:");
System.out.println(" red = " + semiTransparentCinnabar.getRed());
System.out.println(" green = " + semiTransparentCinnabar.getGreen());
System.out.println(" blue = " + semiTransparentCinnabar.getBlue());
System.out.println(" alpha = " + semiTransparentCinnabar.getAlpha());
}
public void paint(Graphics page) {
page.fillRect(100, 50, 200, 150);
Polygon p = new Polygon();
p.addPoint(100, 50);
p.addPoint(200, 125);
p.addPoint(300, 50);
page.setColor(Color.black);
page.fillPolygon(p);
Rectangle bounds = p.getBounds();
System.out.println("Polygon's bounds: ");
System.out.println(" left = " + (int)bounds.getX());
System.out.println(" top = " + (int)bounds.getY());
System.out.println(" width = " + (int)bounds.getWidth());
System.out.println(" height = " + (int)bounds.getHeight());
}
public void paint(Graphics page) {
page.fillRect(100, 50, 200, 150);
Polygon p = new Polygon();
p.addPoint(100, 50);
p.addPoint(200, 125);
p.addPoint(300, 50);
page.setColor(Color.black);
page.fillPolygon(p);
// This line starts inside the triangle, ends outside the triangle
page.setColor(Color.yellow);
page.drawLine(150, 75, 150, 100);
System.out.println("Polygon contains...");
System.out.println(" (150, 75) = " + p.contains(150, 75));
System.out.println(" (150, 100) = " + p.contains(150, 100));
System.out.println("Polygon's bounds contains...");
Rectangle bounds = p.getBounds();
System.out.println(" (150, 75) = " + bounds.contains(150, 75));
System.out.println(" (150, 100) = " + bounds.contains(150, 100));
}
public void paint(Graphics page) {
page.fillRect(100, 50, 200, 150);
Polygon p = new Polygon();
p.addPoint(100, 50);
p.addPoint(125, 75);
p.addPoint(100, 100);
page.setColor(Color.blue);
page.fillPolygon(p);
p.translate(50, 50);
page.setColor(Color.yellow);
page.fillPolygon(p);
p.translate(50, -75);
page.setColor(Color.red);
page.fillPolygon(p);
}
public void paint(Graphics page) {
Polygon p1 = new Polygon();
p1.addPoint(50, 50);
p1.addPoint(100, 100);
p1.addPoint(50, 150);
page.setColor(Color.blue);
page.fillPolygon(p1);
Polygon p2 = new Polygon();
p2.addPoint(75, 70);
p2.addPoint(125, 120);
p2.addPoint(175, 70);
page.setColor(Color.red);
page.fillPolygon(p2);
Rectangle bounds1 = p1.getBounds();
Rectangle bounds2 = p2.getBounds();
System.out.println("intersection tests for...");
System.out.println(" polygons: " + shapesIntersect(p1, p2));
System.out.println(" polygon bounds: " + shapesIntersect(bounds1, bounds2));
}
////////////////////////////////////// /// shapesIntersect Helper method //////////////////////////////////////
public static boolean shapesIntersect(Shape s1, Shape s2) {
java.awt.geom.Area area = new java.awt.geom.Area(s1);
area.intersect(new java.awt.geom.Area(s2));
return !area.isEmpty();
}
carpe diem - carpe diem - carpe diem - carpe diem - carpe diem - carpe diem - carpe diem - carpe diem - carpe diem