자바에서의그래픽 그래픽스, 이미지 514760-1 2019 년봄학기 6/4/2019 박경신 자바그래픽의두가지방법 간단한그래픽 // (1) 프레임생성하기 public class BasicPaint { JFrame f = new JFrame(" 그래픽기초프로그램 "); f.setdefaultcloseoperation(jframe.exit_on_close); f.setsize(300, 200); f.setvisible(true);
간단한그래픽 JFrame 을생성하고여기에 JPanel 을추가한후에 JPanel 위에그림을그려보자. // (2) Jframe 을생성하고여기에 Jpanel 을추가한후 Jpanel 위에그림을그린다. public class BasicPaint { JFrame f = new JFrame(" 그래픽기초프로그램 "); f.setdefaultcloseoperation(jframe.exit_on_close); f.add(new MyPanel()); f.setsize(300, 200); f.setvisible(true); class MyPanel extends JPanel { public MyPanel() {... 간단한그래픽 컴포넌트에무언가를그리려면 paintcomponent() 메소드를중복정의한다. paintcomponent() 메소드는컴포넌트가화면에그려질때호출된다. class MyPanel extends Jpanel { public void paintcomponent(graphics g) { super.paintcomponent(g); // 여기에그림을그리는코드를넣는다. 간단한그래픽 그래픽좌표계는 x+ 오른쪽, y+ 아래쪽으로갈수록증가한다. 간단한그래픽 사각형을그리려면 Graphics 객체가가지고있는 drawrect() 을호출하면된다. g.drawrect(50, 50, 50, 50); g.drawoval(200, 50, 50, 50);
전체소스 기초도형그리기 public class BasicPaint { JFrame f = new JFrame(" 그래픽기초프로그램 "); f.setdefaultcloseoperation(jframe.exit_on_close); f.add(new MyPanel()); f.setsize(300, 200); f.setvisible(true); class MyPanel extends JPanel { public MyPanel() { setborder(borderfactory.createlineborder(color.black)); protected void paintcomponent(graphics g) { super.paintcomponent(g); g.drawrect(50, 50, 50, 50); g.drawoval(200, 50, 50, 50); 직선그리기 사각형그리기 width height
drawroundrect() 타원그리기 시작점 (x, y) 과넓이 (width) 와높이 (height) 호그리기 : 얼굴그리기 import javax.swing.*; import java.awt.event.*; import java.awt.*; class MyPanel extends JPanel { public void paintcomponent(graphics g) { super.paintcomponent(g); g.setcolor(color.yellow); g.filloval(20, 30, 200, 200); g.setcolor(color.black); // 왼쪽눈을그린다. g.drawarc(60, 80, 50, 50, 180, -180); // 오른쪽눈을그린다. g.drawarc(150, 80, 50, 50, 180, -180); // 입을그린다. g.drawarc(70, 130, 100, 70, 180, 180);
: 얼굴그리기 public class SnowManFace extends JFrame { public SnowManFace() { setsize(280, 300); setdefaultcloseoperation(jframe.exit_on_close); settitle(" 눈사람얼굴 "); setvisible(true); add(new MyPanel()); : 프랙탈로나무그리기 프랙탈 (fractal) 은자기유사성을가지는기하학적구조를프랙털구조를말한다. SnowManFace s=new SnowManFace(); 프랙탈트리를그리는알고리즘 1 나무줄기를그린다. 2 줄기의끝에서특정한각도로 2개의가지를그린다. 3 동일한과정을가지의끝에서반복한다. 충분한가지가생성될때까지이과정을반복한다. : 프랙탈로나무그리기 import java.awt.color; import java.awt.graphics; import javax.swing.jframe; public class DrawTreeFrame extends JFrame { public DrawTreeFrame() { setsize(800, 700); setdefaultcloseoperation(exit_on_close); setvisible(true); private void drawtree(graphics g, int x1, int y1, double angle, int depth) { if (depth == 0) return; int x2 = x1 + (int) (Math.cos(Math.toRadians(angle)) * depth * 10.0); int y2 = y1 + (int) (Math.sin(Math.toRadians(angle)) * depth * 10.0); g.drawline(x1, y1, x2, y2); drawtree(g, x2, y2, angle - 20, depth -1); drawtree(g, x2, y2, angle + 20, depth -1);
: 프랙탈로나무그리기 @Override public void paint(graphics g) { g.setcolor(color.black); drawtree(g, 400, 600, -90, 10); new DrawTreeFrame(); 색상 java.awt 패키지의일부인 Color 클래스를사용 빛의 3원색인 Red 성분, Green 성분, Blue 성분이얼마나함유되어있는지를 0에서 255까지의수를사용하여나타낸다. 색상 색상설정 클래스변수이름 색상 RGB 값 Color.black black (0,0,0) Color.blue blue (0,0,255) Color.cyan cyan (0,255,255) Color.gray gray (128,128,128) Color.darkGray dark gray (64,64,64) Color.lightGray light gray (192,192,192) Color.green green (0,255,0) Color.magenta magenta (255,0,255) 마젠타색상을얻는방법 1 Color c = Color.magenta; 2 Color c = new Color (255,0,255); Color 는알파값 (alpha) 을가질수있다. 알파값이란색상의투명도를나타낸다. E.g. Color c = new Color (255, 0, 0, 128); Color.orange orange (255,200,0) Color.pink pink (255,175,175) Color.red red (255,0,0) Color.white white (255,255,255) Color.yellow yellow (255,255,0)
컴포넌트색상설정메소드 생성자설명컴포넌트객체에서배경색을설정한 setbackground(color c) 다. setcolor(color c) 전경색을설정한다. Color getcolor() 현재의전경색을반환한다. import javax.swing.*; import java.awt.event.*; import java.awt.*; class MyPanel extends JPanel implements ActionListener { JButton button; Color color = new Color(0, 0, 0); public MyPanel() { setlayout(new BorderLayout()); button = new JButton(" 색상변경 "); button.addactionlistener(this); add(button, BorderLayout.SOUTH); public void paintcomponent(graphics g) { super.paintcomponent(g); g.setcolor(color); g.fillrect(10, 10, 210, 220); 실행결과 public void actionperformed(actionevent e) { color = new Color((int) (Math.random()*255.0), (int) (Math.random()*255.0),(int) (Math.random()*255.0)); repaintcomponent(); public class ColorTest extends JFrame { public ColorTest() { setsize(240, 300); setdefaultcloseoperation(jframe.exit_on_close); settitle("color Test"); setvisible(true); JPanel panel = new MyPanel(); add(panel); ColorTest s = new ColorTest();
색상선택기 import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.event.*; import javax.swing.colorchooser.*; public class ColorChooserTest extends JFrame implements ChangeListener { protected JColorChooser color; public ColorChooserTest() { settitle(" 색상선택기테스트 "); setdefaultcloseoperation(jframe.exit_on_close); color = new JColorChooser(); // 생성자호출 color.getselectionmodel().addchangelistener(this); // 리스너등록 color.setborder(borderfactory.createtitledborder(" 색상선택 ")); 문자열출력과폰트 JPanel panel = new JPanel(); panel.add(color); add(panel); pack(); this.setvisible(true); public void statechanged(changeevent e) { Color newcolor = color.getcolor(); new ColorChooserTest(); 문자열출력방법 // (x, y) 위치에문자열을출력하려면 g.drawstring("hello World!", x, y); 폰트를지정하기위해서는 Font 클래스를사용 Font 객체는폰트이름 (Courier, Helvetica,..) 과스타일 (plain, bold, italic,...), 크기 (12 포인트,...) 의 3 가지속성 // plain 형식이고크기는 10 포인트 Font font = new Font("Courier", Font.PLAIN, 10);
폰트의종류 폰트의지정 논리적인폰트 설명 "Serif" 삐침 (serif) 를갖는가변폭글꼴, 대표적으로 TimesRoman이있다. "SansSerif" 삐침 (serif) 를갖지않는가변폭글꼴, 대표적으로 Helvetica가있다. "Monospaced" 고정폭을가지는글꼴, 대표적으로 Courier가있다. "Dialog" 대화상자에서텍스트출력을위하여사용되는글꼴 "DialogInput" 대화상자에서텍스트입력을위하여사용되는글꼴 public void paint(graphics g) { Font f = new Font("Serif", Font.BOLD Font.ITALIC, 12); g.setfont(f);... JLabel mylabel = new JLabel(" 폰트색상 ); Font f = new Font("Dialog", Font.ITALIC, 10); mylabel.setfont(f); // 1 class MyPanel extends JPanel { Font f1, f2, f3, f4, f5; public MyPanel() { f1 = new Font("Serif", Font.PLAIN, 20); f2 = new Font("San Serif", Font.BOLD, 20); f3 = new Font("Monospaced", Font.ITALIC, 20); f4 = new Font("Dialog", Font.BOLD Font.ITALIC, 20); f5 = new Font("DialogInput", Font.BOLD, 20); public void paintcomponent(graphics g) { super.paintcomponent(g); g.setfont(f1); g.drawstring("serif 20 points PLAIN", 10, 50); g.setfont(f2); g.drawstring("sanserif 20 points BOLD", 10, 70); g.setfont(f3); g.drawstring("monospaced 20 points ITALIC", 10, 90); g.setfont(f4); g.drawstring("dialog 20 points BOLD + ITALIC", 10, 110); g.setfont(f5); g.drawstring("dialoginput 20 points BOLD", 10, 130); public class FontTest extends JFrame { public FontTest() { setsize(500, 200); setdefaultcloseoperation(jframe.exit_on_close); settitle("font Test"); setvisible(true); JPanel panel = new MyPanel(); add(panel); FontTest s = new FontTest();
이미지출력 자바는 GIF, PNG JPEG 타입의이미지를화면에그릴수있다. // 소스를입력하고 Ctrl+Shift+O 를눌러서필요한파일을포함한다. public class LoadImageApp extends JPanel { BufferedImage img; BufferedImage img = null; try { img = ImageIO.read(new File("strawberry.jpg")); catch (IOException e) { public void paint(graphics g) { g.drawimage(img, 0, 0, null); public LoadImageApp() { try { img = ImageIO.read(new File("dog.png")); catch (IOException e) { 실행결과 public Dimension getpreferredsize() { if (img == null) { return new Dimension(100, 100); else { return new Dimension(img.getWidth(null), img.getheight(null)); JFrame f = new JFrame(" 이미지표시 "); f.add(new LoadImageApp()); f.pack(); f.setvisible(true); f.setdefaultcloseoperation(jframe.exit_on_close);
: 이미지나누어서그리기 drawimage() 메소드 drawimage() 를이용하여이미지를그릴때, 일부만그릴수있고또크기를변경할수있다. 이러한기능을이용하여서이미지를 16 조각으로나누어서그리는프로그램을작성하여보자. public class MyImageFrame extends JFrame implements ActionListener { private int pieces = 4; private int totalpieces = pieces * pieces; private int[] piecenumber; private BufferedImage img; public MyImageFrame() { settitle("image Draw Test"); try { img = ImageIO.read(new File("hubble.jpg")); catch (IOException e) { System.out.println(e.getMessage()); System.exit(0); void divide() { Random rand = new Random(); int ri; for (int i = 0; i < totalpieces; i++) { ri = rand.nextint(totalpieces); int tmp = piecenumber[i]; piecenumber[i] = piecenumber[ri]; piecenumber[ri] = tmp; piecenumber = new int[totalpieces]; for (int i = 0; i < totalpieces; i++) { piecenumber[i] = i; add(new MyPanel(), BorderLayout.CENTER); JButton button = new JButton("DIVIDE"); button.addactionlistener(this); add(button, BorderLayout.SOUTH); setsize(img.getwidth(null), img.getheight(null)); setvisible(true); class MyPanel extends JPanel { public void paintcomponent(graphics g) { super.paintcomponent(g); int piecewidth = img.getwidth(null) / pieces; int pieceheight = img.getheight(null) / pieces;
영상처리 for (int x = 0; x < pieces; x++) { int sx = x * piecewidth; for (int y = 0; y < pieces; y++) { int sy = y * pieceheight; int number = piecenumber[x * pieces + y]; int dx = (number / pieces) * piecewidth; int dy = (number % pieces) * pieceheight; g.drawimage(img, dx, dy, dx + piecewidth, dy + pieceheight, sx, sy, sx + piecewidth, sy + pieceheight, null); new MyImageFrame(); public void actionperformed(actionevent e) { divide(); repaint(); 영상처리 (image processing) 은이미지를읽어서여러가지처리를하는학문분야이다. 예를들어서화질이나쁜이미지의화질을향상시키는것도영상처리의일종이다. public class GrayScaleImage extends JFrame { BufferedImage image; int width; int height; public GrayScaleImage() { try { File input = new File("Lenna.png"); image = ImageIO.read(input); width = image.getwidth(); height = image.getheight(); Color(image.getRGB(r, c)); for (int r = 0; r < height; r++) { for (int c = 0; c < width; c++) { Color color = new avg, avg); newcolor.getrgb()); int red = (int) (color.getred()); int green = (int) (color.getgreen()); int blue = (int) (color.getblue()); int avg = (red + green + blue) / 3; Color newcolor = new Color(avg, image.setrgb(r, c, File ouptut = new File("output.png"); ImageIO.write(image, "png", ouptut); add(new MyPanel()); pack(); setvisible(true); catch (Exception e) { System.out.println(" 이미지읽기실패!");
Java 2D class MyPanel extends JPanel { public void paintcomponent(graphics g) { g.drawimage(image, 0, 0, null); public Dimension getpreferredsize() { if (image == null) { return new Dimension(100, 100); else { return new Dimension(image.getWidth(null), image.getheight(null)); 광범위한그래픽객체를그릴수있다. 도형의내부를그라디언트 (gradient) 나무늬로채울수있다. 이미지를그릴수있고필터링연산을적용할수있다. 그래픽객체들의충돌을감지할수있는메커니즘을제공한다. static public void main(string args[]) throws Exception { GrayScaleImage obj = new GrayScaleImage(); Java 2D 를이용한그리기 Java 2D 를이용한그리기 public void paintcomponent(graphics g) { Graphics2D g2 = (Graphics2D) g; g2.drawline(100, 100, 300, 300); g2.drawrect(10, 10, 100, 100);...
사각형그리기 Shape r1 = new Rectangle2D.Float(10, 10, 50, 60); g2.draw(r1); 타원그리기 // 타원객체를생성하고타원을그린다. g2.draw(new Ellipse2D.Double(x, y, rectwidth, rectheight)); 원호생성 Shape arc1 = new Arc2D.Float(10, 10, 90, 90, 90, 60, Arc2D.OPEN); import java.util.*; import javax.swing.*; import java.awt.event.*; import java.awt.*; import java.awt.geom.*; public class MoreShapes extends JFrame { public MoreShapes() { setsize(600, 130); settitle("java 2D Shapes"); setdefaultcloseoperation(jframe.exit_on_close); JPanel panel = new MyPanel(); add(panel); setvisible(true); new MoreShapes();
class MyPanel extends JPanel { ArrayList<Shape> shapearray = new ArrayList<Shape>(); public MyPanel() { Shape s; // 사각형 s = new Rectangle2D.Float(10, 10, 70, 80); shapearray.add(s); // 둥근사각형 s = new RoundRectangle2D.Float(110, 10, 70, 80, 20, 20); shapearray.add(s); // 타원 s = new Ellipse2D.Float(210, 10, 80, 80); shapearray.add(s); // 원호 : Arc2D.OPEN s = new Arc2D.Float(310, 10, 80, 80, 90, 90, Arc2D.OPEN); shapearray.add(s); // 원호 Arc2D.CHORD s = new Arc2D.Float(410, 10, 80, 80, 0, 180, Arc2D.CHORD); shapearray.add(s); // 원호 Arc2D.PIE s = new Arc2D.Float(510, 10, 80, 80, 45, 90, Arc2D.PIE); shapearray.add(s); public void paintcomponent(graphics g) { super.paintcomponent(g); Graphics2D g2 = (Graphics2D) g; // 앤티에일리어싱을설정한다. g2.setrenderinghint(renderinghints.key_antialiasing, RenderingHints.VALUE_ANTIALIAS_ON); g2.setcolor(color.black); g2.setstroke(new BasicStroke(3)); for (Shape s : shapearray) g2.draw(s); 도형채우기 단일색으로채우기 g2.setcolor(color.blue); g2.fill(ellipse); 투명하게채우기 g2.setcomposite(alphacomposite.getinstance(alphacomposite.src_over, 0.50F)); 그라디언트로채우기 GradientPaint gp = new GradientPaint(0, 0, Color.WHITE, 0, 100, Color.RED);
실행결과 class MyComponent extends JComponent { public void paint(graphics g) { Graphics2D g2 = (Graphics2D) g; g2.setrenderinghint(renderinghints.key_antialiasing, RenderingHints.VALUE_ANTIALIAS_ON); g2.setstroke(new BasicStroke(3)); GradientPaint gp = new GradientPaint(0, 10, Color.WHITE, 0, 70, Color.RED); // 사각형 g2.setpaint(color.red); g2.fill(new Rectangle2D.Float(10, 10, 70, 80)); // 둥근사각형 g2.setpaint(gp); g2.fill(new RoundRectangle2D.Float(110, 10, 70, 80, 20, 20));... : 간단한애니메이션 class MyPanel extends JPanel implements ActionListener { private final int WIDTH = 500; private final int HEIGHT = 300; private final int START_X = 0; private final int START_Y = 250; private BufferedImage image; private Timer timer; private int x, y; public MyPanel() { setbackground(color.black); setpreferredsize(new Dimension(WIDTH, HEIGHT)); setdoublebuffered(true); File input = new File("ship.jpg"); try { image = ImageIO.read(input); catch (IOException e) { e.printstacktrace();
x = START_X; y = START_Y; timer = new Timer(20, this); timer.start(); @Override public void paintcomponent(graphics g) { super.paintcomponent(g); g.drawimage(image, x, y, this); @Override public void actionperformed(actionevent e) { x += 1; y -= 1; if (x > WIDTH) { x = START_X; y = START_Y; repaint(); public class MyFrame extends JFrame { public MyFrame() { add(new MyPanel()); settitle(" 애니메이션테스트 "); setdefaultcloseoperation(jframe.exit_on_close); setsize(500, 300); setvisible(true); new MyFrame();