import java.awt.*;
import java.awt.Image;
import javax.swing.*;
import java.awt.event.*;
import java.io.*;
import javax.swing.border.*;
import javax.imageio.ImageIO;
import java.awt.image.*;
//----------------------------------------------------------
// PixelCraft() - Sets up the GUI for PixelCraft.
// Author - Drew Murphy
// April 14, 2011
//----------------------------------------------------------
public class PixelCraft{
private JTextField fileSelected;
private JTextField blockwidth;
private JLabel image;
private JProgressBar progressBar;
private int progressMax;
private PixelCraft pframe = this;
private JCheckBox red;
private JCheckBox yellow;
private JCheckBox blue;
private JCheckBox green;
private JCheckBox black;
private JCheckBox white;
private JCheckBox brown;
private JCheckBox orange;
private JCheckBox cyan;
private JCheckBox purple;
private JCheckBox gray;
private JCheckBox lightblue;
private JCheckBox pink;
private JCheckBox aquagreen;
private JCheckBox magenta;
private JCheckBox lightgray;
private JCheckBox sand;
private BufferedImage renderedImage; //image returned to PixelFrame
private static Color[][] colorSchematic; //schematic determined from calling ColorAlgorithm
//--------------------------------------------------------------------------------------
public PixelCraft(){
java.net.URL logoURL = PixelCraft.class.getResource("logo.jpg");
java.net.URL iconURL = PixelCraft.class.getResource("icon.png");
JFrame frame = new JFrame ("PixelCraft 0.2 - A Simple Minecraft Picture Converter by Drew Murphy");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(1000,600);
// Get the currently installed look and feel
LookAndFeel lf = UIManager.getLookAndFeel();
// Install a different look and feel; specifically, the Windows look and feel
try {
UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
} catch (InstantiationException e) {
} catch (ClassNotFoundException e) {
} catch (UnsupportedLookAndFeelException e) {
} catch (IllegalAccessException e) {
}
JPanel settings = new JPanel(); //container for chooseFile, updatePanel, and control
JPanel images = new JPanel(); //displays images
JPanel window = new JPanel(); //container for settings and images
JPanel control = new JPanel(); //container for updatePanel and progress
JPanel options = new JPanel(); //container for preferences and banner
JPanel chooseFile = new JPanel();
JPanel updatePanel = new JPanel();
JPanel preferences = new JPanel();
JPanel progress = new JPanel();
JPanel banner = new JPanel();
//--------------
// ChooseFile panel
//--------------
JButton browse = new JButton ("Browse");
browse.setPreferredSize(new Dimension(80,30));
browse.addActionListener(new FileListener());
fileSelected = new JTextField("C:\\", 30);
fileSelected.setBorder(BorderFactory.createLineBorder(Color.black, 1));
fileSelected.setPreferredSize(new Dimension(250,18));
chooseFile.add(fileSelected);
chooseFile.add(browse);
//-------------------
// Preferences panel
//-------------------
preferences.setLayout(new BoxLayout(preferences, BoxLayout.Y_AXIS));
preferences.setPreferredSize(new Dimension(200,400));
preferences.setBackground(Color.white);
preferences.setBorder(BorderFactory.createLineBorder(Color.black,1));
red = new JCheckBox("Red Wool",true);
yellow = new JCheckBox("Yellow Wool",true);
blue = new JCheckBox("Blue Wool",true);
green = new JCheckBox("Green Wool",true);
black = new JCheckBox("Black Wool",true);
white = new JCheckBox("White Wool",true);
brown = new JCheckBox("Brown Wool",true);
orange = new JCheckBox("Orange Wool",true);
cyan = new JCheckBox("Cyan Wool",true);
purple = new JCheckBox("Purple Wool",true);
gray = new JCheckBox("Gray Wool",true);
lightblue = new JCheckBox("Light Blue Wool",true);
pink = new JCheckBox("Pink Wool",true);
aquagreen = new JCheckBox("Aqua Green Wool",true);
magenta = new JCheckBox("Magenta Wool",true);
lightgray = new JCheckBox("Light Gray Wool",true);
sand = new JCheckBox("Sand",false);
red.setBackground(Color.white);
yellow.setBackground(Color.white);
blue.setBackground(Color.white);
green.setBackground(Color.white);
black.setBackground(Color.white);
white.setBackground(Color.white);
brown.setBackground(Color.white);
orange.setBackground(Color.white);
cyan.setBackground(Color.white);
purple.setBackground(Color.white);
gray.setBackground(Color.white);
lightblue.setBackground(Color.white);
pink.setBackground(Color.white);
aquagreen.setBackground(Color.white);
magenta.setBackground(Color.white);
lightgray.setBackground(Color.white);
sand.setBackground(Color.white);
preferences.add(red);
preferences.add(yellow);
preferences.add(blue);
preferences.add(green);
preferences.add(black);
preferences.add(white);
preferences.add(brown);
preferences.add(orange);
preferences.add(cyan);
preferences.add(purple);
preferences.add(gray);
preferences.add(lightblue);
preferences.add(pink);
preferences.add(aquagreen);
preferences.add(magenta);
preferences.add(lightgray);
preferences.add(sand);
preferences.setAlignmentX(Component.CENTER_ALIGNMENT);
//----------------
// Banner
//----------------
ImageIcon logo = new ImageIcon(logoURL);
JLabel bannerLogo = new JLabel();
bannerLogo.setIcon(logo);
banner.add(bannerLogo);
//----------------
// Progress Bar
//----------------
progressBar = new JProgressBar();
progressBar.setValue(0);
progressBar.setStringPainted(true);
progress.add(progressBar);
//-------------
// UpdatePanel
//-------------
JLabel blockdescrip = new JLabel("Width in blocks: ");
blockdescrip.setBorder(BorderFactory.createEmptyBorder(8,8,8,8));
blockdescrip.setPreferredSize(new Dimension(100,25));
blockwidth = new JTextField("64", 4);
blockwidth.setHorizontalAlignment(JTextField.CENTER);
blockwidth.setBorder(BorderFactory.createLineBorder(Color.black,1));
JButton create = new JButton("Create image!");
create.setBackground(Color.cyan);
create.setBorder(BorderFactory.createEmptyBorder(15,15,15,15));
create.setPreferredSize(new Dimension(150,25));
create.addActionListener(new CreateImage());
updatePanel.setLayout(new BoxLayout(updatePanel,BoxLayout.X_AXIS));
updatePanel.add(blockdescrip);
updatePanel.add(Box.createRigidArea(new Dimension(30,0)));
updatePanel.add(blockwidth);
updatePanel.add(Box.createRigidArea(new Dimension(20,0)));
updatePanel.add(create);
//-----------------
// Nested Panels
//-----------------
control.setLayout(new BoxLayout(control,BoxLayout.Y_AXIS));
control.add(Box.createRigidArea(new Dimension(0,70)));
control.add(progress);
control.add(Box.createRigidArea(new Dimension(0,10)));
control.add(updatePanel);
options.setLayout(new BorderLayout());
options.add(banner, BorderLayout.WEST);
options.add(preferences, BorderLayout.EAST);
settings.setLayout(new BoxLayout(settings,BoxLayout.PAGE_AXIS));
settings.add(chooseFile);
settings.add(Box.createRigidArea(new Dimension(0,30)));
settings.add(options);
settings.add(control);
settings.add(Box.createRigidArea(new Dimension(0,10)));
images.setPreferredSize(new Dimension(800,600));
images.setBorder(BorderFactory.createEmptyBorder(8,8,8,8));
image= new JLabel();
images.add(image);
window.setLayout(new BorderLayout());
window.add(settings,BorderLayout.WEST);
window.add(images,BorderLayout.EAST);
frame.add(window);
frame.pack();
frame.setIconImage(Toolkit.getDefaultToolkit().getImage(iconURL));
frame.setVisible(true);
}
//--------------------------------------------------------------------------------------
//---------------
// Main Method
//---------------
public static void main(String[] args) {
PixelCraft frame = new PixelCraft();
}
//--------------------------------------------------------------------------------------
//---------------
// Progress Bar Methods
//---------------
public void updateBar(int newValue) {
progressBar.setValue(newValue);
progressBar.repaint();
}
//--------------------------------------------------------------------------------------
//---------------
// File Selection
//---------------
private class FileListener implements ActionListener{
public void actionPerformed (ActionEvent event) {
JFileChooser choose = new JFileChooser();
int status = choose.showOpenDialog(null);
if (status != JFileChooser.APPROVE_OPTION)
fileSelected.setText("No File Chosen");
else {
File file = choose.getSelectedFile();
fileSelected.setText(file.getAbsolutePath());
}
}
}
//--------------------------------------------------------------------------------------
//--------------------------------------------------------
// Runs the programs main function of pixelating the image
//--------------------------------------------------------
private class CreateImage implements ActionListener{
public void actionPerformed(ActionEvent event) {
String fileName = fileSelected.getText();
Image resizedPicture = Toolkit.getDefaultToolkit().getImage(fileName);
ImageIcon picture = new ImageIcon(fileName);
int numColumns = Integer.parseInt(blockwidth.getText());
boolean checkValues[] = new boolean[17];
checkValues[0] = red.isSelected();
checkValues[1] = yellow.isSelected();
checkValues[2] = blue.isSelected();
checkValues[3] = green.isSelected();
checkValues[4] = black.isSelected();
checkValues[5] = white.isSelected();
checkValues[6] = brown.isSelected();
checkValues[7] = orange.isSelected();
checkValues[8] = cyan.isSelected();
checkValues[9] = purple.isSelected();
checkValues[10] = gray.isSelected();
checkValues[11] = lightblue.isSelected();
checkValues[12] = pink.isSelected();
checkValues[13] = aquagreen.isSelected();
checkValues[14] = magenta.isSelected();
checkValues[15] = lightgray.isSelected();
checkValues[16] = sand.isSelected();
JLabel test = new JLabel();
MediaTracker tracker = new MediaTracker(test);
//--------------------------------------------
// Scale picture to fit on-screen, if necessary.
//--------------------------------------------
if (resizedPicture.getWidth(null) > 800 || resizedPicture.getHeight(null) > 600) {
if (resizedPicture.getWidth(null) > 800) {
float ratio = 800 / (float)resizedPicture.getWidth(null);
double width = 800.0;
float height = (float)resizedPicture.getHeight(null) * ratio;
resizedPicture = resizedPicture.getScaledInstance((int)width,(int)height,Image.SCALE_SMOOTH);
}
if (resizedPicture.getHeight(null) > 600) {
float ratio = 600 / (float)resizedPicture.getHeight(null);
double height = 600.0;
float width = (float)resizedPicture.getWidth(null) * ratio;
resizedPicture = resizedPicture.getScaledInstance((int)width,(int)height,Image.SCALE_SMOOTH);
}
}
float ratio = (float)resizedPicture.getWidth(null) / (float)resizedPicture.getHeight(null);
int numRows = (int)(numColumns/ratio);
progressBar.setMaximum(numColumns*numRows);
progressMax = numColumns*numRows;
//-------------------------------------------------------------------------------------
// Makes sure the image is loaded completely before invoking the ImagePixelate() class
//-------------------------------------------------------------------------------------
tracker.addImage(resizedPicture, 0);
try{
tracker.waitForAll();
} catch (InterruptedException e) {}
//--------------------------------------------------
// ImagePixelate call - Program's main function
//--------------------------------------------------
picture.setImage(resizedPicture);
image.setIcon(picture);
ImagePixelate renderedPicture = new ImagePixelate(resizedPicture, numColumns, checkValues, pframe);
BufferedImage renderedFinal = renderedPicture.getRenderedImage();
picture.setImage(renderedFinal);
image.setIcon(picture);
}
}
//--------------------------------------------------------------------------------------
private class SaveImage implements ActionListener {
public void actionPerformed(ActionEvent event) {
}
}
//--------------------------------------------------------------------------------------
private class ImagePixelate{
public ImagePixelate(Image toRender, int columnNumber, boolean[] checkValues, PixelCraft frame) {
int height = -1;
int width = -1;
Color[] palettePossibilities = {
new Color(182,50,45), //red
new Color(222,207,42), //yellow
new Color(38,50,151), //blue
new Color(53,74,23), //green
new Color(0,0,0), //black
new Color(255,255,255), //white
new Color(81,48,26), //brown
new Color(234,125,51), //orange
new Color(41,121,154), //cyan
new Color(125,48,193), //purple
new Color(68,68,68), //gray
new Color(142,168,223), //lightblue
new Color(219,138,160), //pink
new Color(61,200,49), //aquagreen
new Color(192,76,203), //magenta
new Color(155,162,162), //lightgray
new Color(220,214,180) //sand
};
int booleanIndex = 0;
for (int i= 0; i < checkValues.length; i++) {
if (checkValues[i])
booleanIndex++;
}
Color palette[] = new Color[booleanIndex];
booleanIndex = 0;
for (int i= 0; i < checkValues.length; i++) {
if (checkValues[i]) {
palette[booleanIndex] = palettePossibilities[i];
booleanIndex++;
}
}
//--------------------
// MediaTracker call
//--------------------
JLabel testCase = new JLabel();
MediaTracker tracker = new MediaTracker(testCase);
tracker.addImage(toRender,1);
try{
tracker.waitForAll();
height = toRender.getHeight(null);
width = toRender.getWidth(null);
} catch (InterruptedException e) {}
//------------------------------------------------------------------------------------------
// Determining the size of each block given the user specified width of the image in blocks
//------------------------------------------------------------------------------------------
float ratio = (float) width / (float) height;
int numColumns;
if (columnNumber < 1)
numColumns = 64;
else
numColumns = columnNumber;
float rowCalc = (float) numColumns / ratio;
int numRows = (int) rowCalc;
colorSchematic = new Color[numColumns][numRows];
int blockWidth = width / numColumns;
int blockHeight = blockWidth;
BufferedImage imageToDraw = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics2D g = imageToDraw.createGraphics();
g.drawImage(toRender, 0, 0, null);
g.dispose();
//------------------------------------------------------------------------------------------------
// Get the pixels of each block, and then use the algorithm to determine the closest palette color
//------------------------------------------------------------------------------------------------
int[] pixels = new int[blockWidth*blockHeight];
ColorAlgorithm currentSection;
int progress = 0;
for (int x = 0; x < numColumns; x++) {
for (int y = 0; y < numRows; y++) {
frame.updateBar(progress);
PixelGrabber grabber = new PixelGrabber(imageToDraw, x*blockWidth, y*blockHeight,
blockWidth, blockHeight, pixels, 0, blockWidth);
try {
grabber.grabPixels();
} catch (InterruptedException e) {}
currentSection = new ColorAlgorithm(pixels, palette);
colorSchematic[x][y] = currentSection.getColor();
progress++;
}
}
Crafter buildPicture = new Crafter(colorSchematic, numColumns, numRows, blockWidth);
renderedImage = buildPicture.getImage();
}
public BufferedImage getRenderedImage() {
return renderedImage;
}
}
}