|
Core Java Technologies Tech Tips¿¡ ¿À½Å ¿©·¯ºÐÀ» ȯ¿µÇÕ´Ï´Ù. Java 2 Platform,
Standard Edition (J2SE)¿¡ ±â¹ÝÇÑ core Java technologies ¿Í APIsÀÇ
»ç¿ë¿¡ °üÇÑ ÃֽŠÁ¤º¸¸¦ ¾ò¾î °¡½Ã±â ¹Ù¶ø´Ï´Ù. ÀÌ ±Û¿¡¼´Â Java 2 SDK, Standard Edition,
v 1.4¸¦ »ç¿ëÇÕ´Ï´Ù.
À̹ø È£¿¡¼´Â,
CONVOLVEOP¸¦ ÀÌ¿ëÇØ¼ µðÁöÅÐ À̹ÌÁö¿¡ È¿°úÁÖ±â
HTTPURLCONNECTION¸¦ »ç¿ëÇÏ¿© À¥ ÆäÀÌÁö ¾×¼¼½ºÇϱâ
À» ´Ù·ç°Ô µË´Ï´Ù.
ÀúÀÚ Daniel H. Steinberg
CONVOLVEOP¸¦ ÀÌ¿ëÇØ¼ µðÁöÅÐ À̹ÌÁö¿¡ È¿°úÁÖ±â
µðÁöÅÐ Ä«¸Þ¶ó·Î ÂïÀº À̹ÌÁö¿Í ½ÇÁ¦ Âï°í ½Í¾ú´ø À̹ÌÁö°¡ ´Ù¸¥ °æ¿ì°¡ ²Ï ÀÖ´Ù. ¿¹¸¦ µé¾î, ¹øÁü È¿°ú³ª ¼±¸íÇÑ È¿°ú, ȤÀº À̹ÌÁö¸¦ ¹à°Ô ¸¸µé°Å³ª ÅæÀ» ³·Ãß´Â µîÀÇ È¿°ú¸¦ ³Ö°í ½ÍÀ» ¼ö ÀÖ´Ù. java.awt.imageÆÐŰÁö´Â µðÁöÅÐ À̹ÌÁö¿¡ ÀÌ¿Í °°Àº º¯È¸¦ ÁÙ ¼ö ÀÖ´Â À¯Æ¿¸®Æ¼¸¦ Æ÷ÇÔÇÑ´Ù. ÀÌ·¯ÇÑ À¯Æ¿¸®Æ¼¸¦ »ç¿ëÇϸé, ÇÏÀÌ ¿£µå »ó¿ë À̹Ì¡ ÆÐŰÁö(high-end commercial imaging packages)°¡ Á¦°øÇÏ´Â µ¿ÀÏÇÑ È¿°ú¸¦ ÁÙ ¼ö ÀÖ´Ù.
ÀÌ ±Û¿¡¼´Â µðÁöÅÐ À̹ÌÁö¿¡ ÀÌ·¯ÇÑ È¿°ú¸¦ ÁÖ±â À§Çؼ java.awt.image ÆÐŰÁö ³»ÀÇ ConvolveOpŬ·¡½º¸¦ »ç¿ëÇÑ´Ù. ConvolveOp´Â ¼Ò½º·ÎºÎÅÍ ¸ñÀû¿¡ À̸£´Â convolution¸¦ ±¸ÇöÇÑ´Ù. . ¿©±â¼ convolutionÀº °¢°¢ÀÇ Çȼ¿À» º»·¡ Çȼ¿°ú ±× ÁÖº¯ Çȼ¿ÀÇ Á¶ÇÕÀ¸·Î ´ëüÇÏ´Â µ¿ÀÛÀ¸·Î »ý°¢ÇØ º¼ ¼ö ÀÖ°Ú´Ù. float ¹è¿À» ÀÌ¿ëÇØ¼ À§¿¡¼ ¼³¸íÇÑ ¹Ù¿Í °°ÀÌ º»·¡ À̹ÌÁöÀÇ Çȼ¿À» Á¶ÀýÇÏ¿© ÀÌ¿¡ ÀûÀýÇÑ È¿°ú¸¦ ÁÙ ¼ö°¡ ÀÖ´Ù. ¿©±â¼ float¹è¿ÀÇ °¢°¢ÀÇ ¿ä¼ÒµéÀº º»·¡ À̹ÌÁö Çȼ¿¿¡ °öÇØÁö´Â ¼öµéÀÌ´Ù. ÀÌ float ¹è¿·ÎºÎÅÍ convolution¿¡¼ °¡Àå ÇÙ½ÉÀÌ µÇ´Â °è¼ö¹è¿(°öÇØÁö´Â ¹è¿)ÀÇ ÀνºÅϽº¸¦ »ý¼ºÇϰí À̸¦ ÀÌ¿ëÇØ¼ convolutionÀ» ½ÇÇàÇÑ´Ù.
¿¹¸¦ µé¾î, ´ÙÀ½°ú °°Àº 3*3 ¹è¿(À̰ÍÀÌ ¹Ù·Î float ¹è¿ÀÌ´Ù.)ÀÌ ÀÖ´Ù¸é a b c
d e f
g h i
°á°ú convolution´Â ´ÙÀ½ °¢ »çÇ×ÀÇ ÇÕÀ¸·Î °¡¿îµ¥ Çȼ¿À» ´ëüÇÑ´Ù.
- a¿Í º»·¡ À̹ÌÁöÀÇ Á᫐ Çȼ¿¿¡¼ ¿ÞÂÊ À§ÀÇ Çȼ¿°ªÀÇ °ö
- b¿Í º»·¡ À̹ÌÁöÀÇ Á᫐ Çȼ¿ÀÇ ¸Ó¸®À§ÀÇ Çȼ¿°ªÀÇ °ö
- c¿Í º»·¡ À̹ÌÁöÀÇ Á᫐ Çȼ¿¿¡¼ ¿À¸¥ÂÊ À§ÀÇ Çȼ¿°ªÀÇ °ö
- ±âŸ
¹Ù²Ù¾î ¸»ÇÏÀÚ¸é, °è¼ö¹è¿¿¡¼ ÇØ´ç Æ÷Áö¼ÇÀÇ °ªÀ» Çȼ¿°ª¿¡ °öÇϰí À̸¦ ÇÕÄ£´Ù. ¹è¿ÀÇ ¿£Æ®¸® ÇÕ°è°¡ 1À̶ó¸é, °á°ú À̹ÌÁö´Â º»·¡ À̹ÌÁö¿Í µ¿ÀÏÇÑ ´ÙÀ̳ª¹Í ¹üÀ§(range)¸¦ °®À» °ÍÀÌ´Ù.
Á» ´õ ±¸Ã¼ÀûÀÎ ¿¹¸¦ º¸ÀÚ. ´ÙÀ½ 3*3 ¹è¿À» »ìÆìº¸ÀÚ. 0 0.2 0
0.2 0.2 0.2
0 0.2 0
ÀÌ·¯ÇÑ ¹è¿Àº °¢ Çȼ¿°ªµéÀ» ±× °ªÀÇ ÀüÈÄÁ¿ìÀÇ °ªµéÀ» Æò±ÕÇÑ °ªÀ¸·Î ´ëüÇÏ´Â °Í°ú °°´Ù. ÀÌ´Â »çÁøÀ» ¾à°£ ¹øÁö°Ô ÇÏ´Â È¿°ú°¡ ÀÖ´Ù.
±×·¸´Ù¸é ´ÙÀ½ 3*3¹è¿À» º¸ÀÚ. À̰ÍÀº ÀÏÄ¡¿¬»ê(identity operation)¿¡ ÇØ´çÇÑ´Ù. À̸¦ convolutionÀÇ ÇÑ ºÎºÐÀ¸·Î Àû¿ëÇÏ¸é º¯ÇÏ´Â °ÍÀº ¾Æ¹«°Íµµ ¾ø´Ù. Áï, ÀÌ´Â °¢°¢ÀÇ Çȼ¿À» ±×°ÍÀÇ ÀÌÀü °ªÀ¸·Î ´ëüÇÑ´Ù´Â °ÍÀÌ´Ù. 0 0 0
0 1 0
0 0 0
ÀÌÀü ¹è¿ÀÇ 1ÀÌ 2·Î ´ëüµÇ¸é °á°ú À̹ÌÁö´Â ´õ ¹à¾ÆÁö°í ¾à°£ »öÀÌ ¹Ù·£ µí º¸ÀδÙ. 1À» 0.5·Î ´ëüÇϸé À̹ÌÁö´Â ´õ ¾îµÎ¿öÁø´Ù.
3*3 ¹è¿¸¸ Ưº°È÷ ÀÌ¿Í °°Àº µ¿ÀÛÀ» ±¸ÇöÇÏ´Â °ÍÀº ¾Æ´Ï´Ù. Á߽ɿ¡ ´ëÇØ ´ëĪÀÌ¸é¼ Á᫐ Çȼ¿¿¡ ÀÇÇØ Á¿ìµÇ´Â convolutionÀ» ½ÇÇàÇϰíÀÚ ÇÑ´Ù¸é, Ȧ¼ö·Î ±¸¼ºµÈ Á¤¹æÇü ¹è¿ÀÌ ÇÊ¿äÇÏ´Ù. 5*5, 7*7 °ú °°Àº Ȧ¼öÇü ¹è¿Àº 3*3 ¹è¿°ú µ¿ÀÏÇÏ°Ô ÀÛµ¿ÇÑ´Ù. ½ÉÁö¾î´Â 1*1¹è¿À» »ç¿ëÇØµµ »ó°ü¾ø´Ù. ¿¹¸¦ µé¾î¼, ´ÙÀ½ ¸Þ¼Òµå¿¡¼¿Í °°ÀÌ ´ÜÀÏ ¿ä¼Ò¸¦ °®´Â float ¹è¿À» »ý¼ºÇϰí ÀÌ ¿ä¼Ò·ÎºÎÅÍ »õ·Î¿î 1*1 Kernel °´Ã¼¸¦ »ý¼ºÇÑ ÈÄ À̸¦ ConvolveOp »ý¼ºÀÚ·Î ³Ñ±ä´Ù. ¸¶Áö¸·À¸·Î º¯°æµÈ À̹ÌÁö¸¦ ¾ò¾î³»±â À§ÇØ BufferedImageOp¸¦ º»·¡ BufferedImage¿¡ Àû¿ëÇÑ´Ù. private void setBrightnessFactor(float multiple) {
float[] brightKernel = {multiple};
BufferedImageOp bright
= new ConvolveOp(new Kernel(1, 1, brightKernel));
convolvedImage
= bright.filter(originalImage, null);
repaint();
}
ÀÌ ¸Þ¼Òµå´Â 2°¡Áö Á¡À» °Á¶Çϰí ÀÖ´Ù. Çϳª´Â À̹ÌÁö°¡ ¹Ù²ð ¶§¸¶´Ù ±×°ÍÀ» »õ·Î ±×¸®±â À§ÇØ paintComponent() ¸Þ¼Òµå¸¦ ¿À¹ö¶óÀ̵åÇØ¾ß ÇÑ´Ù´Â °ÍÀÌ´Ù. public void paintComponent(Graphics g) {
g.drawImage(convolvedImage, 0, 0, this);
}
µÎ¹øÂ°´Â ÀÌ·¯ÇÑ È¿°ú¸¦ Àû¿ëÇÒ ¼ö ÀÖ´Â BufferedImage ¸¦ ¸ÕÀú »ý¼ºÇØ¾ß ÇÑ´Ù´Â °ÍÀÌ´Ù. ÀÌ °æ¿ì¿¡ test.jpg¸¦ ÀÐ°í ±×°÷À¸·ÎºÎÅÍ Image¸¦ »ý¼ºÇÑ´Ù. ±×¸®°í´Â ¿øº» À̹ÌÁö¿Í °°Àº Å©±â·Î BufferedImageÀ» »ý¼ºÇÑ´Ù. ¸¶Áö¸· ´Ü°è·Î, BufferedImage ¿¡ ±× À̹ÌÁö¸¦ ±×·Á³Ö¾î¾ß ÇÑ´Ù. Image image = new ImageIcon("test.jpg").getImage();
originalImage
= new BufferedImage(image.getWidth(null),
image.getHeight(null),
BufferedImage.TYPE_INT_RGB);
Graphics g = originalImage.createGraphics();
g.drawImage(image, 0, 0, null);
g.dispose();
1Â÷¿ø °è¼ö¹è¿À» ÀÌ¿ëÇÏ´Â ´ë½Å¿¡, setBrightnessFactorÀÇ ´ÙÀ½ ¹öÀüÀ» ÅëÇØ 3*3 °è¼ö¹è¿À» ÀÌ¿ëÇÒ ¼ö ÀÖ´Ù. private void setBrightnessFactor(float multiple) {
float[] brightKernel = {0, 0, 0,
0, multiple, 0,
0, 0, 0};
BufferedImageOp bright
= new ConvolveOp(new Kernel(3, 3, brightKernel));
convolvedImage
= bright.filter(originalImage, null);
repaint();
}
À̹ÌÁöÀÇ ºä¾î¸¦ »ý¼ºÇÏ´Â BrightnessChangerÇÁ·Î±×·¥À» º¸ÀÚ. ÀÌ ºä¾î´Â »ç¿ëµÇ´Â ¹è¼öÀÇ °ªÀ» º¯°æÇؼ ¹à±â¸¦ Á¶ÀýÇÒ ¶§ ¾²´Â ½½¶óÀÌ´õ¸¦ Æ÷ÇÔÇÑ´Ù. Å×½ºÆ® À̹ÌÁö°¡ ÇÊ¿äÇÒ °ÍÀÌ´Ù. ÀÌ ¶§, À̹ÌÁöÀÇ À̸§Àº test.jpg·Î ÇÏÀÚ. ÀÌ À̹ÌÁö´Â BrightnessChanger ÇÁ·Î±×·¥À» ½ÇÇàÇÏ´Â µð·ºÅ丮¿¡ À§Ä¡ÇØ ÀÖ¾î¾ß ÇÑ´Ù. Å×½ºÆ® À̹ÌÁö·Î »ç¿ëÇÒ ¼ö ÀÖ´Â Àç¹Ì³ ±×¸²À» ´Ù¿î·Îµå ¹ÞÀÚ. import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.ImageIcon;
import javax.swing.JSlider;
import javax.swing.event.ChangeListener;
import javax.swing.event.ChangeEvent;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.BorderLayout;
import java.awt.image.Kernel;
import java.awt.image.ConvolveOp;
import java.awt.image.BufferedImageOp;
import java.awt.image.BufferedImage;
public class BrightnessChanger extends JPanel {
private BufferedImage originalImage;
private BufferedImage convolvedImage;
private JSlider slide = new JSlider(1,50,10);
BrightnessChanger() {
createBufferedImages();
setUpJFrame();
}
private void createBufferedImages() {
Image image
= new ImageIcon("test.jpg").getImage();
originalImage
= new BufferedImage(image.getWidth(null),
image.getHeight(null),
BufferedImage.TYPE_INT_RGB);
convolvedImage
= new BufferedImage(image.getWidth(null),
image.getHeight(null),
BufferedImage.TYPE_INT_RGB);
Graphics g = originalImage.createGraphics();
g.drawImage(image, 0, 0, null);
g.dispose();
setBrightnessFactor(1);
}
private void setUpJFrame() {
JFrame myFrame = new JFrame("Image Brightness");
myFrame.setSize(convolvedImage.getWidth(),
convolvedImage.getHeight());
myFrame.getContentPane().setLayout(
new BorderLayout());
myFrame.getContentPane().add(
this, BorderLayout.CENTER);
slide.addChangeListener(
new BrightnessListener());
myFrame.getContentPane().add(
slide,BorderLayout.SOUTH);
myFrame.setDefaultCloseOperation(
JFrame.EXIT_ON_CLOSE);
myFrame.setVisible(true);
}
private void setBrightnessFactor(float multiple) {
float[] brightKernel = {multiple};
BufferedImageOp bright
= new ConvolveOp(
new Kernel(1, 1, brightKernel));
bright.filter(originalImage, convolvedImage);
repaint();
}
public void paintComponent(Graphics g) {
g.drawImage(convolvedImage, 0, 0, this);
}
class BrightnessListener implements ChangeListener{
public void stateChanged(
ChangeEvent changeEvent) {
setBrightnessFactor(
(float)(slide.getValue())/10);
}
}
public static void main(String[] args) {
new BrightnessChanger();
}
}
BrightnessChanger¿¹Á¦´Â convolution¸¦ ¼Ò°³ÇÏ´Â °ÍÀÌ ¸ñÀûÀ̱⠶§¹®¿¡ À̹ÌÁöÀÇ ¹à±â¸¦ Á¶Á¤ÇÒ ¶§ ÃßõÇÒ¸¸ÇÑ ¹æ¹ýÀº ¾Æ´Ï´Ù. ÀÌÈÄ Å×Å©ÆÁ¿¡¼ »ö°ú ¹à±â¸¦ Á¶Á¤ÇÏ´Â ¹æ¹ý¿¡ ´ëÇØ¼ ´Ù·ç°Ô µÉ °ÍÀÌ´Ù.
convolutionÀÇ °è¼ö¹è¿À» À§ÇÑ Á¤¹æÇü/Ȧ¼öÇü ¹è¿ÀÇ ÀÌ¿ë ¿Ü¿¡´Â ´ëºÎºÐÀÇ °æ¿ì¿¡ ´ëĪ ¹è¿À» »ç¿ëÇØ¾ß ÇÑ´Ù. ´ÙÀ½ ¿¹Á¦´Â ÀÌÇÏÀÇ 3°³ ÄÄÆ÷³ÍÆ®¸¦ ÀÌ¿ëÇØ¼ ±¸¼ºÇÑ 3*3 ¹è¿À» ÀÌ¿ëÇϰí ÀÖ´Ù. 0 0 0 0 1 0 1 0 1
IDENTITY 0 1 0 EDGE 1 0 1 CORNER 0 0 0
0 0 0 0 1 0 1 0 1
°á°ú ¹è¿Àº ÀÌ·¯ÇÑ ±¸¼º ¿ä¼Ò(building block)ÀÇ ¿¬¼ÓÀûÀÎ Á¶ÇÕÀ¸·Î ¸¸µé¾îÁø´Ù. ¿£Æ®¸®ÀÇ ÇÕÀÌ 0ÀÌ ¾Æ´Ñ ÀÌ»ó, »ç¿ëÀÚ´Â ÀÌ °è¼ö¹è¿À» ¿ä¼ÒÀÇ ÇÕÀ¸·Î ³ª´©¾î »ç¿ëÇÏ°Ô µÈ´Ù. ±×·± ½ÄÀ¸·Î À̹ÌÁöÀÇ ¿øº»°ú °°Àº ÈÖµµÀÇ À̹ÌÁö¸¦ ¸¸µé ¼ö ÀÖ´Ù. ¿¹¸¦ µé¾î, EDGE ¿Í IDENTITY¸¦ ´õÇϸé, ´ÙÀ½°ú °°´Ù. 0 1 0
1 1 1
0 1 0
¿£Æ®¸®ÀÇ ÇÕÀº 5ÀÌ´Ù. ÀÌÁ¦ °¢°¢ÀÇ ¿£Æ®¸®¸¦ 5·Î ³ª´²¼ '¹øÁüÈ¿°ú'¸¦ ÁÖ´Â ¹è¿À» ¸¸µç´Ù. 0 0.2 0
.2 0.2 0.2
0 0.2 0
3*3 Çü½Ä ¹è¿ÀÇ ¹è¼ö¸¦ À§ÇÑ ÆÄ¶ó¹ÌÅͷκÎÅÍ ÀÌ·¯ÇÑ °è¼ö¹è¿À» »ý¼ºÇϱâ À§ÇØ Äڵ带 ¸¸µéÀÚ. private Kernel getKernel(
int corner, int edge, int identity) {
float[] kernel = new float[9];
int sum = corner * 4 + edge * 4 + identity;
if (sum == 0) sum = 1;
for (int i = 0; i < 9; i++) {
kernel[i] = (corner * CORNER[i]
+ edge * EDGE[i]
+ identity * IDENTITY[i]) / sum;
}
return new Kernel(3, 3, kernel);
}
°è¼ö¹è¿À» ¸¸µé¾ú´Ù¸é ÀÌÀü°ú °°Àº ¹æ¹ýÀ¸·Î convolutionÀ» ½ÇÇàÇÏÀÚ. void convolveImage(Kernel kernel) {
BufferedImageOp convolve
= new ConvolveOp(kernel);
buffImage = convolve.filter(buffImage, null);
repaint();
}
ÀÌÁ¦ Å×½ºÆ® ÇÁ·Î±×·¥ÀÎ Convolve¸¦ ½ÇÇàÇØ º¸ÀÚ. Convolve¸¦ ½ÇÇàÇÒ ¶§ 3°³ÀÇ Ä¿¸Çµå ¶óÀÎ ÆÄ¶ó¹ÌÅ͸¦ ÀÔ·ÂÇØ¾ß ÇÑ´Ù. À̵éÀº °¢°¢ CORNER, EDGE, IDENTITY ÀÇ ¹è¼ö¿¡ ÇØ´çÇÏ´Â int°ªÀÌ´Ù. °¡·É ´ÙÀ½°ú °°ÀÌ ÀÔ·ÂÇϸé, java Convolve 1 0 0
¾î´À Á¤µµ ¹øÁü È¿°ú°¡ »ý±ä À̹ÌÁö¸¦ º¼ ¼ö ÀÖ´Ù. ´Ù½Ã Çѹø, À̹ÌÁöÀÇ À̸§Àº test.jpg·Î ÇÑ´Ù. import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.image.BufferedImage;
import java.awt.image.BufferedImageOp;
import java.awt.image.ConvolveOp;
import java.awt.image.Kernel;
import java.awt.Image;
import java.awt.Graphics;
public class Convolve extends JPanel {
private BufferedImage buffImage;
private final float[] IDENTITY = {0, 0, 0,
0, 1, 0,
0, 0, 0};
private final float[] EDGE = {0, 1, 0,
1, 0, 1,
0, 1, 0};
private final float[] CORNER = {1, 0, 1,
0, 0, 0,
1, 0, 1};
Convolve(int corner, int edge, int identity) {
createBufferedImages();
setUpJFrame();
convolveImage(getKernel(corner, edge, identity));
}
private void createBufferedImages() {
Image image
= new ImageIcon("test.jpg").getImage();
buffImage
= new BufferedImage(image.getWidth(null),
image.getHeight(null),
BufferedImage.TYPE_INT_RGB);
Graphics g = buffImage.createGraphics();
g.drawImage(image, 0, 0, null);
g.dispose();
}
private void setUpJFrame() {
JFrame myFrame = new JFrame("Image Brightness");
myFrame.setSize(buffImage.getWidth(),
buffImage.getHeight());
myFrame.getContentPane().add(this);
myFrame.setDefaultCloseOperation(
JFrame.EXIT_ON_CLOSE);
myFrame.setVisible(true);
}
void convolveImage(Kernel kernel) {
BufferedImageOp convolve
= new ConvolveOp(kernel);
buffImage = convolve.filter(buffImage, null);
repaint();
}
private Kernel getKernel(
int corner, int edge, int identity) {
float[] kernel = new float[9];
int sum = corner * 4 + edge * 4 + identity;
if (sum == 0) sum = 1;
for (int i = 0; i < 9; i++) {
kernel[i] = (corner * CORNER[i]
+ edge * EDGE[i]
+ identity * IDENTITY[i]) / sum;
}
return new Kernel(3, 3, kernel);
}
public void paintComponent(Graphics g) {
g.drawImage(buffImage, 0, 0, this);
}
public static void main(String[] args) {
if (args.length != 3) {
System.out.println("Usage: java Convolve" +
" corner edge identity");
System.out.println("where corner, edge, " +
"and identity are ints");
System.exit(0);
}
int corner = Integer.parseInt(args[0]);
int edge = Integer.parseInt(args[1]);
int identity = Integer.parseInt(args[2]);
new Convolve(corner, edge, identity);
}
}
Ä¿¸Çµå ¶óÀÎ ÆÄ¶ó¹ÌÅÍ¿¡ ´Ù¸¥ °ªÀ» ÀÔ·ÂÇØº¸ÀÚ. -1 -1 8¸¦ ÀÔ·ÂÇÏ¸é °´Ã¼ÀÇ ¸ð¼¸®°¡ °Á¶µÈ °ÍÀ» º¼ ¼ö ÀÖ´Ù. ÀÌ´Â ÇÕÀÌ 0À¸·Î °è»ê µÇÁö ¾Ê´Â´Ù. ¾Æ´Ï¸é ¿øº»À» º¸´Ù ¶Ñ·ÇÇÏ°Ô º¸±â À§ÇØ 0 -1 5À» ÀÔ·ÂÇØº¸ÀÚ. »ç¿ëÀÚ´Â ÀÌ ¿¹Á¦¸¦ 5*5³ª ±× ÀÌ»óÀÇ ¹è¿·Î ½±°Ô È®ÀåÇØ º¼ ¼ö ÀÖ´Ù. ConvoleOpÀÇ »ç¿ë¿¡ ÀÖ¾î Á» ´õ ÀÚ¼¼ÇÑ Á¤º¸¸¦ ¿øÇϸé Java 2D API ÇÁ·Î±×·¡¸Ó °¡À̵åÀÇ 5Àå "Imaging"À» Âü°íÇϱ⠹ٶõ´Ù.
HTTPURLCONNECTION¸¦ »ç¿ëÇÏ¿© À¥ ÆäÀÌÁö ¾×¼¼½ºÇϱâ
ÀÌ ±ÛÀº HttpURLConnection °ú ÀÌÀÇ ¼ºêŬ·¡½ºÀÎ HttpsURLConnection À» »ç¿ëÇÏ¿© º¸¾È À¥ ÆäÀÌÁö¿¡ ¾×¼¼½ºÇÏ´Â ¹æ¹ýÀ» º¸¿©ÁØ´Ù. ¶ÇÇÑ ºñº¸¾È ÆäÀÌÁö(non-secure page)¿¡¼ º¸¾È ÆäÀÌÁö(secure one)·ÎÀÇ ¸®´ÙÀÌ·ºÆ®¸¦ ½±°Ô ÇÒ ¼ö ÀÖ´Â ¹æ¹ýµµ º¼ ¼ö ÀÖ´Ù. HTTP ¿Í HTTPS¿¡ °üÇÑ Á¤º¸´Â HTTP 1.1 RFC
2616°ú HTTPS RFC 2818¸¦ Âü°íÇϱ⠹ٶõ´Ù.
ù¹øÂ° ¿¹·Î, ÁÖ¾îÁø URL¿¡ Á¢¼ÓÇϱâ À§ÇØ ´ÙÀ½ WebPageReader ÇÁ·Î±×·¥ÀÇ HttpURLConnection ¸¦ ÀÌ¿ëÇØ º¸ÀÚ. ±×¸®°í ÆäÀÌÁöÀÇ ³»¿ëÀ» ½ºÅÄ´Ùµå ¾Æ¿ô(standard out)¿¡ Ãâ·ÂÇÏÀÚ. import java.net.URL;
import java.net.MalformedURLException;
import java.net.URLConnection;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class WebPageReader {
private static URLConnection connection;
private static void connect( String urlString ) {
try {
URL url = new URL(urlString);
connection = url.openConnection();
} catch (MalformedURLException e){
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
private static void readContents() {
BufferedReader in = null;
try {
in = new BufferedReader(
new InputStreamReader(
connection.getInputStream()));
String inputLine;
while (
(inputLine = in.readLine()) != null) {
System.out.println(inputLine);
}
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
if (args.length != 1) {
System.err.println("usage: java WebPageReader "
+ "<url>");
System.exit(0);
}
connect(args[0]);
readContents();
}
}
¸¸¾à ÇöÀçÀÇ À§Ä¡°¡ ¹æÈº® µÚ¶ó¸é, ´ÙÀ½°ú °°ÀÌ ¼³Á¤µÈ proxyHost°ú proxyPort º¯¼öµéÀÌ ÇÊ¿äÇÏ´Ù. http.proxyHost=webcache
http.proxyPort=8080
https.proxyHost=webcache
https.proxyPort=8080
Ä¿¸Çµå ¶óÀο¡ -DÇ÷¡±×¸¦ ÀÌ¿ëÇØ¼ °ªÀ» Á÷Á¢ ÀÔ·ÂÇϰųª ÇÁ·Î±×·¥ »ó¿¡¼ System.setProperty()¸¦ È£ÃâÇÔÀ¸·Î½á º¯¼ö¸¦ ±¸ÇÒ ¼öÀÖ´Ù. WebPageReader ¸¦ ÄÄÆÄÀÏÇÑ ÈÄ¿¡ ÀÌÇÏ¿Í °°Àº Ä¿¸Çµå·Î Core Java Technologies Tech Tips Ȩ ÆäÀÌÁöÀÇ ³»¿ëÀ» ¿°ÅÇØ º¼ ¼ö ÀÖ´Ù. java WebPageReader
http://java.sun.com/developer/JDCTechTips/
URLConnection´Â Ãß»ó Ŭ·¡½ºÀÌ´Ù. URLŬ·¡½ºÀÇ openConnection() ¸Þ¼Òµå´Â ÁöÁ¤µÈ URLÀ» ÀÐÀ» ¼ö ÀÖµµ·Ï ÀûÀýÇÏ°í ±¸Ã¼ÀûÀÎ ¼ºêŬ·¡½º¸¦ ¸®ÅÏÇÑ´Ù. http³ª https URLÀ» ÀÔ·ÂÇϸé ÀÌ´Â HttpURLConnection³ª HttpsURLConnectionÀÇ ¼ºêŬ·¡½º°¡ µÉ °ÍÀÌ´Ù. ¸¸¾à ´ÙÀ½À» openConnection()¸¦ È£ÃâÇÏ´Â ¶óÀο¡ Ãß°¡Çϸé,
System.out.println(connection.getClass());
HttpURLConnectionÀÇ ¼û°ÜÁø ±¸Çö Ŭ·¡½ºÀÇ ÀνºÅϽº¸¦ ¸®ÅÏÇÏ´Â Ä¿³Ø¼Ç(connection)À» º¸°Ô µÈ´Ù. ¿¹¸¦ µé¸é, ´ÙÀ½°ú °°´Ù.
class sun.net.www.protocol.http.HttpURLConnection
ÀÌ¿Í À¯»çÇÏ°Ô º¸¾È ÆäÀÌÁö¸¦ Àбâ À§ÇØ µ¿ÀÏÇÑ WebPageReaderÄڵ带 »ç¿ëÇÒ ¼ö°¡ ÀÖ´Ù. java WebPageReader https://today.dev.java.net
ÈÄÀÚÀÇ °æ¿ì, Ä¿³Ø¼ÇÀº HttpsURLConnectionÀÇ ¼ºêŬ·¡½ºÀÎ HttpURLConnectionŸÀÔÀ̶ó´Â °ÍÀ» ¾Ë¾Æ¾ß ÇÑ´Ù. º¸´Ù ¸íÈ®ÇÏ°Ô ¸»ÇÏÀÚ¸é ´ÙÀ½°ú °°Àº ¼û¾îÀÖ´Â ±¸Çö Ŭ·¡½º°¡ ÀÖ´Ù´Â °ÍÀ» ÀνÄÇÒ ¼ö ÀÖ¾î¾ß ÇÑ´Ù.
class sun.net.www.protocol.https.HttpsURLConnectionImpl
ÀϹÝÀûÀ¸·Î ºê¶ó¿ìÀú¿¡ URLÀ» ÀÔ·ÂÇÒ ¶§, À̵¿ÇϰíÀÚÇÏ´Â ÆäÀÌÁö°¡ º¸¾È ÆäÀÌÁöÀÎÁö ¾Æ´ÑÁö´Â ¾Ë ¼ö°¡ ¾ø´Ù. ´Ù½Ã ¸»Çϸé, today.dev.java.net ÆäÀÌÁö¸¦ º¸±â À§Çؼ´Â http://today.dev.java.net¸¦ ÀÔ·ÂÇÑ´Ù. ÇÊ¿äÇÏ´Ù¸é ºê¶ó¿ìÀú°¡ ¸®´ÙÀÌ·ºÆ®ÇÒ °ÍÀÌ°í »ç¿ëÀÚ¸¦ https://today.dev.java.net·Î ¿¬°áÇϱâ À§ÇØ ÀûÀýÇÑ ½ÅÈ£º¯°æÀ» ¼öÇàÇÑ´Ù. WebPageReaderÇÁ·Î±×·¥ÀÌ ¿äûµÈ ¸®´ÙÀÌ·º¼ÇÀ» ¼öÇàÇÏ´ÂÁö¸¦ »ìÆìº¸ÀÚ. java WebPageReader http://today.dev.java.net
¿øÇÏ´Â ÆäÀÌÁö·Î ¸®´ÙÀÌ·ºÆ®µÇ´Â ´ë½Å¿¡ ´ÙÀ½°ú °°Àº ¸Þ½ÃÁö¸¦ º¸°Ô µÈ´Ù. <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<HTML><HEAD>
<TITLE>301 Moved Permanently</TITLE>
</HEAD><BODY>
<H1>Moved Permanently</H1>
The document has moved
<A HREF="https://today.dev.java.net/">here</A>.<P>
<HR>
<ADDRESS>
Apache/1.3.26 Server at today.dev.java.net Port 80
</ADDRESS>
</BODY></HTML>
ÀÌ Á¤º¸·ÎºÎÅÍ ¹«¾ð°¡¸¦ Àо´Â °ÍÀº ¾î·ÆÁö¸¸ ¹®Á¦´Â ¸®´ÙÀÌ·º¼Ç¿¡ °üÇÑ °ÍÀÌ ¾Æ´Ï´Ù. URL http://linux.java.netÀ¸·Î ÇÁ·Î±×·¥À» ½ÇÇàÇϸé, ÇÁ·Î±×·¥Àº http://community.java.net/linuxÀ¸·Î ÀûÀýÈ÷ À̸¦ ¸®´ÙÀÌ·ºÆ®ÇÏ°í »ç¿ëÀÚ´Â ¿øÇÏ´Â ÄÁÅÙÃ÷¸¦ º¼ ¼ö°¡ ÀÖ´Ù. ¾î¶² ÀÏÀÌ ÀϾ´ÂÁö¸¦ ÀÚ¼¼È÷ »ìÆìº¸·Á¸é HttpURLConnection¸¦ ¸í½ÃÀûÀ¸·Î ÀÌ¿ëÇØ¾ß ÇÑ´Ù. ½ºÅÄ´Ùµå ¾Æ¿ô¿¡ À¥ ÆäÀÌÁöÀÇ ÄÁÅÙÃ÷¸¦ Ãâ·ÂÇÏ´Â Äڵ带 »èÁ¦Çؼ ÀÏÀ» °£´ÜÈ÷ ÇØº¸ÀÚ. RedirectingReaderÇÁ·Î±×·¥ÀÌ´Ù. import java.net.URL;
import java.net.MalformedURLException;
import java.net.HttpURLConnection;
import java.io.IOException;
public class RedirectingReader {
private static HttpURLConnection connection;
private static void connect( String urlString ) {
try {
URL url = new URL(urlString);
connection
= (HttpURLConnection)url.openConnection();
System.out.println(connection.getURL());
System.out.println(
connection.getResponseCode() +
" " + connection.getResponseMessage());
System.out.println(connection.getURL());
} catch (MalformedURLException e){
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
if (args.length != 1) {
System.err.println(
"usage: java WebPageReader "
+ "<url>");
System.exit(0);
}
connect(args[0]);
}
}
´ÙÀ½°ú °°ÀÌ ¸®´ÙÀÌ·ºÆ®ÇÏ´Â URLÀ» ÀÔ·ÂÇÏ¿© RedirectingReader ¸¦ ÄÄÆÄÀÏÇÏ°í ½ÇÇàÇØ º¸ÀÚ. java RedirectingReader http://linux.java.net/
´ÙÀ½°ú °°Àº Ãâ·Â°ªÀ» º¸°Ô µÉ °ÍÀÌ´Ù. http://linux.java.net/
200 OK
http://community.java.net/linux/
ù¹øÂ° ¶óÀÎÀÌ À绡¸® ³ªÅ¸³´Ù. String°ªÀ¸·Î URLÀ» »ý¼ºÇϰí HttpURLConnection°´Ã¼¸¦ ½ÇÇàÇÏÀÚ. ±×·¯¸é http://linux.java.net¸¦ ¿äûÇÏ´Â µ¿¾È¿¡ Àá±ñÀÇ ¸ØÃãÀÌ »ý±ä´Ù.
ÆäÀÌÁö°¡ ¸®´ÙÀÌ·ºÆ®µÇ´Â ÀÌ ½Ã°£µ¿¾È ¹Þ°Ô µÇ´Â ÀÀ´ä ÄÚµå¿Í ¸Þ½ÃÁö´Â ¸®´ÙÀÌ·ºÆ®µÈ ÆäÀÌÁö·ÎºÎÅÍ ¿Â °ÍÀÌ´Ù. ÀÌ ¸®´ÙÀÌ·ºÆ®µÈ ÆäÀÌÁö´Â Ãâ·Â°ªÀÇ 3¹øÂ° ¶óÀο¡ ¿°ÅµÈ´Ù.
URL url = new
URL(urlString);¾Æ·¡ÀÇ ¶óÀÎÀ» Ãß°¡Çؼ ¸®´ÙÀÌ·º¼ÇÀ» Çã¿ëÇÏÁö ¾Ê¾ÒÀ» ¶§ ¹ß»ýÇÏ´Â Çö»óÀ» º¸ÀÚ.
HttpURLConnection.setFollowRedirects(false);
Ãâ·Â°ªÀº ´ÙÀ½°ú °°´Ù. http://linux.java.net/
302 Found
http://linux.java.net/
ÀÌ´Â 302 ¿¡·¯°¡ ¹ß»ýÇß´Ù´Â °ÍÀ» ³ªÅ¸³½´Ù. °ð ¸®´ÙÀÌ·ºÆ®µÇÁö ¾Ê°í URLÀÌ ±×´ë·Î À¯ÁöµÇ¾ú´Ù´Â °ÍÀÌ´Ù. À̸¦ ó¸®Çϱâ Àü¿¡, Á» Àü¿¡ Ãß°¡Çß´ø ¶óÀÎÀ» Áö¿ì°í ¸®´ÙÀÌ·º¼ÇÀÌ ´Ù½Ã ÀÛµ¿ÇÏ´ÂÁö¸¦ È®ÀÎÇϱâ À§ÇØ RedirectingReader ÇÁ·Î±×·¥À» ½ÇÇà½ÃÄѺ¸ÀÚ. RedirectingReader¸¦ ´Ù½Ã Çѹø ½ÇÇà½Ã۰í, http://today.dev.java.net ¸¦ ÀÔ·ÂÇÏÀÚ. ´ÙÀ½°ú °°Àº Ãâ·Â°ªÀ» º¸°Ô µÈ´Ù. http://today.dev.java.net
301 Moved Permanently
http://today.dev.java.net
À§´Â ÀÌ ÇÁ·Î±×·¥ÀÌ "Moved Permanently" ¿¡·¯¸¦ ó¸®ÇÒ ¼ö ¾ø¾î¼ ¸®´ÙÀÌ·ºÆ® Çß´Ù´Â °ÍÀ» ¸»ÇÑ´Ù. À̰ÍÀÌ ¹Ù·Î ¿øÇß´ø µðÆúÆ® ¼Ó¼ºÀÌ´Ù. º¸¾È¹®Á¦ ¶§¹®¿¡ http °ú https°£¿¡´Â ¸®´ÙÀÌ·ºÆ®ÇÒ ¼ö ¾ø´Ù. ¾îµð·Î ¸®´ÙÀÌ·ºÆ®ÇÒ °ÍÀ̳ÄÇÏ´Â Á¤º¸´Â ÀÌ ÀÀ´äÀÇ Çì´õ ºÎºÐ¿¡ ÀÖ´Ù. ÀÌÀüÀÇ ¿äû¿¡ ´ëÇÑ Àüü ÀÀ´ä Çì´õ´Â ´ÙÀ½°ú °°´Ù. HTTP/1.1 301 Moved Permanently
Date: Tue, 03 Feb 2004 01:38:43 GMT
Server: Apache/1.3.26 (Unix) mod_ssl/2.8.10
OpenSSL/0.9.6b
mod_jk/1.2.1
Location: https://today.dev.java.net/
Content-type: text/html; charset=iso-8859-1
HttpURLConnection ³»ÀÇ getResponseCode() °ú getResponseMessage() ¸Þ¼Òµå°¡ ÀÌ ÀÀ´äÀÇ Ã¹¹øÂ° ¶óÀο¡ Æ÷ÇÔµÈ Á¤º¸¸¦ ¸®ÅÏÇÏ´Â °ÍÀ» º» ÀûÀÌ ÀÖÀ» °ÍÀÌ´Ù. ȤÀº getHeaderField() ¸Þ¼Òµå¸¦ ÀÌ¿ëÇØ¼ Çì´õ ÇʵåÀÇ À̸§¿¡ ½ºÆ®¸µ°ªÀ» ³Ö¾îÁ־ µÈ´Ù. °¡·É, getHeaderField("Location")´Â https://today.dev.java.net/°ªÀ» ¸®ÅÏÇÑ´Ù.
ÀÌ ±ÛÀÇ ½ÃÀۺκп¡¼ ¾ð±ÞÇß´ø HTTP 1.1 °ú HTTPS RFCs¿¡¼ ¿äû°ú ÀÀ´ä Çì´õÀÇ Æ÷¸Ë¿¡ °üÇØ ÀÚ¼¼È÷ »ìÆì º¼ ¼ö ÀÖ´Ù. 300 ·¹º§ ÀÀ´ä¿¡¼, "Location:"´Â ¸®´ÙÀÌ·º¼ÇÀ» À§ÇÑ À§Ä¡°ªÀ» Á¦°øÇؾ߸¸ ÇÑ´Ù. 301³ª 302 ¿¡·¯¸¦ ¹ß»ýÇÏ´ÂÁö¸¦ È®ÀÎÇϱâ À§ÇØ ´ÙÀ½ »çÇ×À» Ãß°¡ÇÏÀÚ. private static boolean mustRedirect(int code){
if (code == HttpURLConnection.HTTP_MOVED_PERM ||
code == HttpURLConnection.HTTP_MOVED_TEMP) {
System.out.println("Received error " + code +
", trying secure redirect");
return true;
} else return false;
}
¸®´ÙÀÌ·ºÆ®°¡ ÀÚµ¿ÀûÀ¸·Î 󸮵ÇÁö ¾Ê´Â´Ù¸é »ç¿ëÀÚ´Â 301 ³ª 302 ÀÀ´ä Äڵ常À» ¹Þ°Ô µÈ´Ù´Â °ÍÀ» ±â¾ïÇÏÀÚ. Áö±Ý±îÁö À̰ÍÀº ¸®´ÙÀÌ·ºÆ®°¡ HttpURLConnection°¡ ¾Æ´Ñ HttpsURLConnection°¡ ÇÊ¿äÇÏ´Ù´Â °ÍÀ» ÀǹÌÇß´Ù. "Location:" Çʵ忡 Á¦°øµÈ Á¤º¸¸¦ µû¸£ÀÚ. ´ÙÀ½°ú °°ÀÌ »õ·Î¿î Á¤º¸¸¦ ÀÌ¿ëÇØ¼ url °ª°ú Ä¿³Ø¼ÇÀ» Àç¼³Á¤ÇÏÀÚ. url = new URL("https://"+ url.getHost()
+ url.getFile());
connection
= (HttpsURLConnection)url.openConnection();
¸¶Áö¸·À¸·Î, À¥ ¸®´õ¸¦ ¹Þ±â À§ÇØ À§ÀÇ ¸ðµç »çÇ×À» ¸ðÀ¸°í ÇÊ¿äÇÒ ¶§ º¸¾È ÆäÀÌÁö·Î ¸®´ÙÀÌ·ºÆ®µÉ ¼ö ÀÖµµ·Ï ÇÏÀÚ. import javax.net.ssl.HttpsURLConnection;
import java.net.URL;
import java.net.MalformedURLException;
import java.net.HttpURLConnection;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class RedirectingReader {
private static HttpURLConnection connection;
private static URL url;
private static void connect(String urlString) {
try {
url = new URL(urlString);
connection
= (HttpURLConnection) url.openConnection();
int code = connection.getResponseCode();
if (mustRedirect(code))
secureRedirect(
connection.getHeaderField("Location"));
readContents();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
private static boolean mustRedirect(int code) {
if (code == HttpURLConnection.HTTP_MOVED_PERM ||
code == HttpURLConnection.HTTP_MOVED_TEMP) {
return true;
} else
return false;
}
private static void secureRedirect(String location)
throws IOException {
System.out.println(location);
url = new URL(location);
connection
= (HttpsURLConnection) url.openConnection();
}
private static void readContents() {
BufferedReader in = null;
try {
in = new BufferedReader(
new InputStreamReader(
connection.getInputStream()));
String inputLine;
while ((inputLine = in.readLine()) != null) {
System.out.println(inputLine);
}
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
if (args.length != 1) {
System.err.println("usage: java WebPageReader "
+ "<url>");
System.exit(0);
}
connect(args[0]);
}
}
¾÷µ¥ÀÌÆ®µÈ RedirectingReader ¸¦ ÄÄÆÄÀÏÇÏ°í µ¿ÀÛÀÌ Á¦´ë·Î ÀÌ·ç¾îÁö´ÂÁö È®ÀÎÇϱâ À§ÇØ ¸î °³ÀÇ ´Ù¸¥ ÀԷ°ªÀ» ³Ö¾î ½ÇÇàÇØº¸ÀÚ. ¿¹¸¦ µé¸é http://today.dev.java.net ¿Í http://linux.java.net¸¦ ³Ö¾îº¸ÀÚ. ¸®´ÙÀÌ·ºÆ®µÇÁö ¾Ê´Â º¸¾ÈÆäÀÌÁö¿Í ºñº¸¾È ÆäÀÌÁö¸¦ ÀÔ·ÂÇØ¼ RedirectingReader¸¦ ½ÇÇàÇØµµ µ¿ÀÛÀÌ ÀûÀýÇÏ°Ô ÀÌ·ç¾îÁ®¾ß ÇÑ´Ù. ÀÌÁ¦ ´Ù½Ã µÚ·Î µ¹¾Æ°¡¼ ÃÖÃÊ WebReader ÇÁ·Î±×·¥¿¡ ¸ðµç println() ¸Þ¼Òµå¸¦ Á¦°ÅÇϰí readContents()¸¦ Ãß°¡ÇÒ ¼ö ÀÖ´Ù.
º» ¸ÞÀÏÀº ¼ö½ÅÀ» µ¿ÀÇÇÑ È¸¿ø´Ô¿¡°Ô¸¸ ¹ß¼ÛµË´Ï´Ù. °ü·Ã¹®ÀÇ : SunKorea@sun.com
º» ¸ÞÀÏÀÇ ¼ö½ÅÀ» °ÅºÎÇϽ÷Á¸é ¼ö½Å°ÅºÎ¸¦
Ŭ¸¯ÇØ ÁÖ¼¼¿ä.
Copyright 2004 Sun Korea, Inc. All rights reserved.
|