스윙 기반 돋보기
본 코드는 JDK6u20 버전에서 디버깅을 통과하여 픽셀에 대한 캡처 처리와 TexturePaint를 이용하여 BufferedImage 대상에 대한 지원
모든 JComponent 구성 요소에 대한 확대경 효과를 제공합니다.
2. 사전 준비 작업
1. 전송된 JComponent 대상을 BufferedImage 대상으로 원본 이미지로 변환하고 아래 코드가 완성됩니다. 관건적인 단계는 BufferedImage 대상에서 자신의 도형 장치 대상을 만드는 것입니다.
orginalImage = new BufferedImage(this.srcComponent.getSize().width,
this.srcComponent.getSize().height, BufferedImage.TYPE_INT_ARGB);
Graphics g = orginalImage.createGraphics();
this.srcComponent.paintAll(g);
2. 소스 BufferedImage 객체에서 모든 픽셀 데이터를 읽습니다. 이것은 다음에 사용됩니다.코드는 다음과 같다.
originalPixels = new int[orginalImage.getWidth()*orginalImage.getHeight()];
orginalImage.getRaster().getDataElements(0,0, orginalImage.getWidth(),
orginalImage.getHeight(), originalPixels)
3. 돋보기 구성 요소를 만들고 사용자 정의 JFrame 대상을 사용하여 테두리를 제거하고 모양을 원형으로 만들어 코드는 다음과 같다.
zoomFrame = new JFrame("MagnifyGlass");
zoomFrame.setUndecorated(true);
Shape shape = new Ellipse2D.Double(0, 0,180, 180); AWTUtilitiesWrapper.
setWindowShape(
zoomFrame,shape);
3: 주요 사고방식과 핵심 코드
1. 원본 이미지에서 마우스의 위치를 포획합니다. 이것은 MouseMotionListener 인터페이스를 완성해야 합니다. 위치를 포획하는 코드는 다음과 같습니다.
double x = e.getPoint().getX();
double y = e.getPoint().getY();
2. 원본 이미지에서 마우스의 위치에 따라 원본 이미지의 픽셀을 캡처합니다. 픽셀의 범위는 축소된 비율에 따라 결정됩니다.
//get garb area rectangle
int grabCols = (int)((double)mySize.width/zoomFactor);
int grabRows = (int)((double)mySize.height/zoomFactor);
3. 소스 이미지 객체의 1차원 픽셀 배열에서 확대할 3D 픽셀 배열을 가져옵니다. 이 구현의 키 중 하나는 다음과 같습니다.
3D 픽셀 배열 객체를 먼저 정의합니다.
int[][][] data = newint[grabRows][grabCols][4];
3D ARGB의 픽셀 배열로 변환하기
//Alpha data
data[row][col][0] = (aRow[col] >> 24) & 0xFF;
//Red data
data[row][col][1] = (aRow[col] >> 16) & 0xFF;
//Green data
data[row][col][2] = (aRow[col] >> 8) & 0xFF;
//Blue data
data[row][col][3]= (aRow[col]) & 0xFF;
4. 호출 방법convertToOneDim()은 캡처된 픽셀을 1차원 배열로 변환하여 작성된 BufferedImage 객체에 배치합니다. 구현 코드는 다음과 같습니다.
grabImage.getRaster().setDataElements( 0, 0,grabWidth, grabHeight, oneDimPixelData );
5. TexturePaint를 이용하여grabImage 대상을 사용하여 돋보기 구성 요소를 채웁니다
TexturePaint tp = new TexturePaint((BufferedImage)grabImage,rect);
g2.setPaint(tp); g2.fill(circle1);
6.screen 좌표를 획득하여 확대경이 마우스를 따라다니는 효과를 실현한다
마우스의 화면 좌표 가져오기
//get screen point
Point offsetPoint = srcComponent.getLocationOnScreen();
e.translatePoint(offsetPoint.x, offsetPoint.y);
screenPoint = e.getPoint();
확대경이 마우스를 따라 움직이는 효과를 실현하려면:
zoomFrame.setLocation(screenPoint);
zoomFrame.setAlwaysOnTop(true);
7. 가장자리 픽셀 확대 문제를 처리하고 빈 부분은 흰색으로 채운다
data[row][col][0] = 0xFF;//alpha
data[row][col][1] = 0xFF;//red
data[row][col][2] = 0xFF;//green
data[row][col][3] = 0xFF;//blue
8. 최종 효과는 다음과 같습니다.
모든 소스 코드와 테스트 프로그램은 다음과 같습니다.
import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Image; import java.awt.Paint; import java.awt.Point; import java.awt.RadialGradientPaint; import java.awt.Rectangle; import java.awt.RenderingHints; import java.awt.Shape; import java.awt.TexturePaint; import java.awt.event.MouseEvent; import java.awt.event.MouseMotionListener; import java.awt.geom.Ellipse2D; import java.awt.image.BufferedImage; import java.awt.image.ColorModel; import javax.swing.JComponent; import javax.swing.JFrame; public class PixelMagnifyGlass extends JComponent implements MouseMotionListener { /** * magnify the image based on pixel data. */ private static final long serialVersionUID = -1632282149543956832L; private double zoomFactor; private JComponent srcComponent; private Point imgPoint; private Point screenPoint; private JFrame zoomFrame; private Dimension mySize; private BufferedImage orginalImage; private int[] originalPixels; public PixelMagnifyGlass(JComponent comp, Dimension size, double zoom) { this.srcComponent = comp; screenPoint = new Point(-1, -1); comp.addMouseMotionListener(this); this.mySize = size; this.zoomFactor = zoom; // convert the JComponent to image orginalImage = new BufferedImage(this.srcComponent.getSize().width, this.srcComponent.getSize().height, BufferedImage.TYPE_INT_ARGB); Graphics g = orginalImage.createGraphics(); this.srcComponent.paintAll(g); g.dispose(); // get all pixel arrays originalPixels = new int[orginalImage.getWidth()*orginalImage.getHeight()]; orginalImage.getRaster().getDataElements( 0, 0, orginalImage.getWidth(), orginalImage.getHeight(), originalPixels); // start the glass component zoomFrame = new JFrame("MagnifyGlass"); zoomFrame.setUndecorated(true); Shape shape = new Ellipse2D.Double(0, 0,mySize.getWidth(), mySize.getHeight()); AWTUtilitiesWrapper.setWindowShape(zoomFrame, shape); } public void paint(Graphics g) { if(imgPoint.x == -1) { g.setColor(Color.BLUE); g.fillRect(0,0, mySize.width, mySize.height); return; } // draw zoom in/out image here Graphics2D g2 = (Graphics2D) g; g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); int grabWidth = (int)((double)mySize.width / zoomFactor); int grabHeight = (int)((double)mySize.height / zoomFactor); int[][][] threeDimPixelData = clipImageToThreeDim(originalPixels, (int)imgPoint.getX(), (int)imgPoint.getY()); int[] oneDimPixelData = convertToOneDim(threeDimPixelData, grabWidth, grabHeight); ColorModel cMD = orginalImage.getColorModel(); BufferedImage grabImage = new BufferedImage(orginalImage.getColorModel(), cMD.createCompatibleWritableRaster(grabWidth, grabHeight), cMD.isAlphaPremultiplied(), null); grabImage.getRaster().setDataElements( 0, 0, grabWidth, grabHeight, oneDimPixelData ); Image scaleImg = grabImage.getScaledInstance(mySize.width, mySize.height, Image.SCALE_FAST); // g2.drawImage(scaleImg, 0,0,null); // add glass edge with black Shape innerCircle = new Ellipse2D.Float(15.5f, 15.5f, mySize.width - 30, mySize.height - 30); Ellipse2D outterCircle = new Ellipse2D.Float(0, 0, mySize.width, mySize.height); Paint gp = new RadialGradientPaint((float)outterCircle.getCenterX(), (float)outterCircle.getCenterY(), (mySize.width)/2, new float[]{0f,0.8f,1f},new Color[]{Color.WHITE,Color.GRAY,Color.BLACK}); g2.setPaint(gp); g2.fill(outterCircle); Rectangle rect = new Rectangle(0,0,scaleImg.getWidth(null), scaleImg.getHeight(null)); TexturePaint tp = new TexturePaint((BufferedImage)grabImage, rect); g2.setPaint(tp); g2.fill(innerCircle); } public Dimension getPreferredSize() { return mySize; } public Dimension getMinimumSize() { return mySize; } public Dimension getMaximumSize() { return mySize; } @Override public void mouseDragged(MouseEvent e) { mouseMoved(e); } public int[][][] clipImageToThreeDim(int[] oneDPix, int startCols, int startRows) { // get garb area rectangle int grabCols = (int)((double)mySize.width / zoomFactor); int grabRows = (int)((double)mySize.height / zoomFactor); int[][][] data = new int[grabRows][grabCols][4]; for (int row = 0; row < grabRows; row++) { int[] aRow = new int[grabCols]; for (int col = 0; col < grabCols; col++) { int element = (row + startRows) * orginalImage.getWidth() + (startCols + col); // image edge detection and assign it as white color. if(element >= oneDPix.length || (startCols + col) >= orginalImage.getWidth()) { aRow[col] = 0; } else { aRow[col] = oneDPix[element]; } } for (int col = 0; col < grabCols; col++) { if(aRow[col] == 0) { // Alpha data data[row][col][0] = 0xFF; // Red data data[row][col][1] = 0xFF; // Green data data[row][col][2] = 0xFF; // Blue data data[row][col][3] = 0xFF; } else { // Alpha data data[row][col][0] = (aRow[col] >> 24) & 0xFF; // Red data data[row][col][1] = (aRow[col] >> 16) & 0xFF; // Green data data[row][col][2] = (aRow[col] >> 8) & 0xFF; // Blue data data[row][col][3] = (aRow[col]) & 0xFF; } } // end for loop on column } return data; } /* The purpose of this method is to convert the data in the 3D array of ints back into
* the 1d array of type int.
* */ public int[] convertToOneDim(int[][][] data, int imgCols, int imgRows) { // Create the 1D array of type int to be populated with pixel data int[] oneDPix = new int[imgCols * imgRows * 4]; // Move the data into the 1D array. Note the // use of the bitwise OR operator and the // bitwise left-shift operators to put the // four 8-bit bytes into each int. for (int row = 0, cnt = 0; row < imgRows; row++) { for (int col = 0; col < imgCols; col++) { oneDPix[cnt] = ((data[row][col][0] << 24) & 0xFF000000) | ((data[row][col][1] << 16) & 0x00FF0000) | ((data[row][col][2] << 8) & 0x0000FF00) | ((data[row][col][3]) & 0x000000FF); cnt++; }// end for loop on col }// end for loop on row return oneDPix; }// end convertToOneDim @Override public void mouseMoved(MouseEvent e) { double x = e.getPoint().getX(); double y = e.getPoint().getY(); // we did not need to handle edge pixel like this again. // if((x + mySize.getWidth()) > this.orginalImage.getWidth()) { // x = x - ((x + mySize.getWidth()) - this.orginalImage.getWidth()); // } // if((y + mySize.getHeight()) > this.orginalImage.getHeight()) { // y = y - ((y + mySize.getHeight()) - this.orginalImage.getHeight()); // } // end comment by gloomy fish on 15-October-2011 imgPoint = new Point((int)x, (int)y); // get screen point Point offsetPoint = srcComponent.getLocationOnScreen(); e.translatePoint(offsetPoint.x, offsetPoint.y); screenPoint = e.getPoint(); repaint(); invokeGlass(); } /** * */ public void invokeGlass() { if(imgPoint.x == -1) { return; } if(zoomFrame.isVisible()) { zoomFrame.getContentPane().remove(this); zoomFrame.getContentPane().add(this); zoomFrame.setLocation(screenPoint); } else { zoomFrame.getContentPane().remove(this); zoomFrame.getContentPane().add(this); zoomFrame.pack(); zoomFrame.setLocation(screenPoint); zoomFrame.setVisible(true); zoomFrame.setAlwaysOnTop(true); } } }
테스트 프로그램:
import java.awt.Dimension; import java.io.File; import javax.swing.ImageIcon; import javax.swing.JFileChooser; import javax.swing.JFrame; import javax.swing.JLabel; public class TestDetachedMagnifyingGlass { public TestDetachedMagnifyingGlass(File f) { ImageIcon i = new ImageIcon(f.getPath()); JLabel label = new JLabel(i); JFrame imageFrame = new JFrame("IMage"); imageFrame.getContentPane().add(label); imageFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); imageFrame.pack(); imageFrame.setVisible(true); new PixelMagnifyGlass(label, new Dimension(180,180),2.0); // mag.invokeGlass(); } public static void main(String[] args) { JFileChooser chooser = new JFileChooser(); chooser.showOpenDialog(null); File f = chooser.getSelectedFile(); new TestDetachedMagnifyingGlass(f); } }
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
[JAVA](Swing) 입력 받고 HTTP 요청 보내기 (GET, POST)문자열 입력받기 메이븐 추가 + jackson 추가 (IntelliJ) HTTP 요청 (HttpURLConnection) Java Swing을 이용해 문자열을 입력 받고 해당 문자열을 HTTP 요청 보내는 과정을 설...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.