Swing을 이용하여 이미지의 일부분을 모자이크 처리하는 프로그램 만들어보기
코드 소개
-
Swing을 이용하여 GUI 화면에 버튼 배열을 만들고, 그 버튼을 이미지로 채운 뒤, 버튼의 역할(버튼 속 이미지를 모자이크 처리)을 구현한 프로그램이다.
코드
-
MosaicButtonMain.java
/**
* Created on Jan 7, 2018
* @author minsu -- hufs.ac.kr, Dept of CES
* Copy Right -- Free for Educational Purpose
*/
package mosaicButton;
import java.awt.EventQueue;
import javax.swing.UIManager;
public class MosaicButtonMain {
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel"); // Apply Nimbus Look-and-Feel
MosaicButtonFrame frame = new MosaicButtonFrame(); // generate frame
frame.setVisible(true); // show frame
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
}
-
MosaicButtonFrame.java
/**
* Created on Jan 7, 2018
* @author minsu -- hufs.ac.kr, Dept of CES
* Copy Right -- Free for Educational Purpose
*/
package mosaicButton;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JButton;
import javax.swing.border.EmptyBorder;
import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.io.IOException;
import javax.imageio.ImageIO;
import java.awt.Image;
import javax.swing.ImageIcon;
import java.awt.image.BufferedImage;
import java.awt.Color;
import java.awt.Graphics2D;
public class MosaicButtonFrame extends JFrame {
private static final long serialVersionUID = 1L; // serialize
private static final int IMAGENUM = 25; // This value must be a square number.
private static final int IMAGENUMSQRT = (int)(Math.sqrt(IMAGENUM));
private static final int SQUARESIDELENGTH = 150; // This value determines button's size.
private static final int MOSAICQUALITY = 5; // This value is aliquot part of 'SQUARESIDELENGTH'.
private static Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
private static final int FRAME_WIDTH = SQUARESIDELENGTH*IMAGENUMSQRT; // Frame's width
private static final int FRAME_HEIGHT = SQUARESIDELENGTH*IMAGENUMSQRT; // Frame's height
MosaicButtonFrame thisClass = this;
BufferedImage originalImage = null;
BufferedImage[][] originalImageData = new BufferedImage[IMAGENUMSQRT][IMAGENUMSQRT]; // original image's array which fills each cell
BufferedImage[][] mosaicImageData = new BufferedImage[MOSAICQUALITY][MOSAICQUALITY]; // mosaic image's array which fills each cell
private static final String IMAGERESOURCE = "/images/image.png"; // image file's path
private boolean[][] isMosaic = new boolean [IMAGENUMSQRT][IMAGENUMSQRT]; // cell's status(mosaic or non-mosaic)
private JPanel contentPane; // including btnPanel
private JPanel btnPanel; // including btnImage
private JButton[][] btnImage = new JButton [IMAGENUMSQRT][IMAGENUMSQRT];
/**
* Create the frame.
*/
public MosaicButtonFrame() {
setTitle("Mosaic-Image Button"); // program's title
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(FRAME_WIDTH, FRAME_HEIGHT); // set frame's size
setResizable(false); // fix frame's size
setLocation((screenSize.width - FRAME_WIDTH) / 2, (screenSize.height - FRAME_HEIGHT) / 2); // program is located center of pc-monitor
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(0, 0, 0, 0));
contentPane.setLayout(new BorderLayout(0, 0));
setContentPane(contentPane);
btnPanel = new JPanel();
contentPane.add(btnPanel, BorderLayout.CENTER);
btnPanel.setLayout(new GridLayout((int)IMAGENUMSQRT, (int)IMAGENUMSQRT, 0, 0));
for(int i=0; i<IMAGENUMSQRT; i++) {
for(int j=0; j<IMAGENUMSQRT; j++) {
int m = i; // actionListener needs final-variable
int n = j; // actionListener needs final-variable
isMosaic[m][n] = false; // initialize cell's status
btnImage[i][j] = new JButton();
JButton btnCell = btnImage[i][j];
btnCell.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
mosaicAction(btnCell, m, n);
}
});
btnPanel.add(btnCell);
}
}
initialize(); // set cell(button)'s icon
}
void initialize() {
try {
originalImage = ImageIO.read(getClass().getResource(IMAGERESOURCE));
}
catch(IOException e) {
e.printStackTrace();
}
int spwidth = originalImage.getWidth()/IMAGENUMSQRT; // sliced picture's width
int spheight = originalImage.getHeight()/IMAGENUMSQRT; // sliced picture's height
int cellWidth = thisClass.getWidth()/IMAGENUMSQRT; // button(cell)'s width
int cellHeight = thisClass.getHeight()/IMAGENUMSQRT; // button(cell)'s height
for(int i=0; i<IMAGENUMSQRT; ++i) { // slicing image
for(int j=0; j<IMAGENUMSQRT; ++j) {
originalImageData[i][j] =
originalImage.getSubimage(j*spwidth, i*spheight, spwidth, spheight);
}
}
for(int i = 0; i < IMAGENUMSQRT; i++) { // set button's image-icon
for(int j = 0; j < IMAGENUMSQRT; j++) {
btnImage[i][j].setIcon(new ImageIcon(originalImageData[i][j]
.getScaledInstance(cellWidth, cellHeight, Image.SCALE_SMOOTH))); // resize image
}
}
}
void mosaicAction(JButton btnCell, int m, int n) {
int cellWidth = FRAME_WIDTH/IMAGENUMSQRT; // button's width
int cellHeight = FRAME_HEIGHT/IMAGENUMSQRT; // button's height
if(isMosaic[m][n]) { // restore original(non-mosaic) image
btnCell.setIcon(new ImageIcon(originalImageData[m][n]
.getScaledInstance(cellWidth, cellHeight, Image.SCALE_SMOOTH))); // resize image
isMosaic[m][n] = false; // set cell's status
}
else { // mosaic image
int pwidth = originalImageData[m][n].getWidth()/MOSAICQUALITY;
int pheight = originalImageData[m][n].getHeight()/MOSAICQUALITY;
int bwidth = cellWidth/MOSAICQUALITY;
int bheight = cellHeight/MOSAICQUALITY;
for(int i=0; i<MOSAICQUALITY; ++i) { // copy original-image into another (BufferedImage)array
for(int j=0; j<MOSAICQUALITY; ++j) {
mosaicImageData[i][j] =
originalImageData[m][n].getSubimage(j*pwidth, i*pheight, pwidth, pheight);
}
}
Color[][] bcol = new Color[MOSAICQUALITY][MOSAICQUALITY];
for(int i=0; i<MOSAICQUALITY; ++i) {
for(int j=0; j<MOSAICQUALITY; ++j) {
bcol[i][j] = getAverageColor(mosaicImageData[i][j]); // get average-color from BufferedImage
mosaicImageData[i][j] = OneColorBufferedImage.getBufferedImage(bwidth, bheight, bcol[i][j]);
}
}
btnCell.setIcon(new ImageIcon(getMergedBufferedImage(mosaicImageData)));
isMosaic[m][n] = true; // set cell's status
}
}
Color getAverageColor(BufferedImage tile){ // get average-color from image
int twidth = tile.getWidth();
int theight = tile.getHeight();
double pixSize = twidth*theight;
double sumRed = 0;
double sumGreen = 0;
double sumBlue = 0;
Color pixColor = null;
for(int i=0; i<theight; ++i) {
for(int j=0; j<twidth; ++j) {
pixColor = new Color(tile.getRGB(i,j));
sumRed += pixColor.getRed();
sumGreen += pixColor.getGreen();
sumBlue += pixColor.getBlue();
}
}
int avgRed = (int)(sumRed/pixSize);
int avgGreen = (int)(sumGreen/pixSize);
int avgBlue = (int)(sumBlue/pixSize);
return new Color(avgRed, avgGreen, avgBlue);
}
BufferedImage getMergedBufferedImage(BufferedImage[][] imageData) { // merge sliced(2D-Array) image
int width = SQUARESIDELENGTH;
int height = SQUARESIDELENGTH;
BufferedImage mergedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics2D graphics = (Graphics2D) mergedImage.getGraphics();
graphics.setBackground(Color.WHITE);
for(int i=0; i<MOSAICQUALITY; i++) {
for(int j=0; j<MOSAICQUALITY; j++) {
graphics.drawImage(imageData[i][j], imageData[i][j].getWidth()*j, imageData[i][j].getHeight()*i, null);
}
}
return mergedImage;
}
}
-
OneColorBufferedImage.java
/**
* Created on Jan 7, 2018
* @author minsu -- hufs.ac.kr, Dept of CES
* Copy Right -- Free for Educational Purpose
*/
package mosaicButton;
import java.awt.Color;
import java.awt.image.BufferedImage;
public class OneColorBufferedImage {
/**
* Create the mosaic image.
*/
static public BufferedImage getBufferedImage (int width, int height, Color color){
BufferedImage result = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); // generate BufferedImage
int[] data = new int[width * height]; // pixel data array
int i = 0;
for(int y = 0; y < height; y++) {
int red = color.getRed();
int green = color.getGreen();
int blue = color.getBlue();
for(int x = 0; x < width; x++) {
data[i++] = (red << 16) | (green << 8) | blue; // calculate each pixel's data
}
}
result.setRGB(0, 0, width, height, data, 0, width); // create mosaic image using pixel data array
return result;
}
}