Skip to content

Instantly share code, notes, and snippets.

@jmpinit
Created February 11, 2014 02:40
Show Gist options
  • Save jmpinit/8928370 to your computer and use it in GitHub Desktop.
Save jmpinit/8928370 to your computer and use it in GitHub Desktop.
/**
* Written by jmptable for 6.005 problem set 0 artwork problem
* run in [processing](http://processing.org/)
*/
import java.awt.Color;
import java.util.*;
import javax.swing.*;
import java.io.File;
/**
* Colors in the turtle's palette.
* values gotten by dumping RGB values from Colors in PenColor.java.
*/
Color[] colors = new Color[] {
new Color(0,0,0),
new Color(0,0,255),
new Color(0,255,255),
new Color(128,128,128),
new Color(0,255,0),
new Color(255,0,255),
new Color(255,200,0),
new Color(255,175,175),
new Color(255,0,0),
new Color(228,228,0),
};
void setup() {
PImage img = loadImage(choosefile());
img.loadPixels();
loadPixels();
size(img.width, img.height);
/**
* Find colors in palette nearest to originals for each pixel.
*/
int[] turtleColors = new int[img.width*img.height];
for(int y=0; y < img.height; y++) {
for(int x=0; x < img.width; x++) {
int pixel = img.pixels[y*img.width+x];
// calculate amount of difference from available colors
// and find the index of the color with the smallest difference
int smallest = -1;
int smallestIndex = 0;
for(int i=0; i < colors.length; i++) {
int score = int(abs(red(pixel)-colors[i].getRed()) + abs(green(pixel)-colors[i].getGreen()) + abs(blue(pixel)-colors[i].getBlue()));
if(score < smallest || smallest == -1) {
smallest = score;
smallestIndex = i;
}
}
turtleColors[y*img.width+x] = smallestIndex;
}
}
/**
* Draw the converted image for inspection.
*/
for(int i=0; i < turtleColors.length; i++) {
Color c = colors[turtleColors[i]];
img.pixels[i] = color(c.getRed(), c.getGreen(), c.getBlue());
}
img.loadPixels();
image(img, 0, 0);
/**
* Write the compressed image to Java source code file.
*/
printArray(runLengthCompression(turtleColors));
}
int[] runLengthCompression(int[] arr) {
ArrayList<Integer> encoded = new ArrayList<Integer>();
// compress by storing long sequences of the same value as
// value, length
int last = arr[0];
int len = 1;
for(int i=0; i < arr.length; i++) {
int current = arr[i];
if(current != last) {
encoded.add(last); encoded.add(len);
len = 1;
last = current;
} else {
len++;
}
}
encoded.add(last); encoded.add(len);
// generate statically allocated array from compressed data
int[] result = new int[encoded.size()];
for(int i=0; i < result.length; i++) result[i] = encoded.get(i);
return result;
}
/**
* Write an integer array to a Java source file for embedding in a program
*/
void printArray(int[] arr) {
final int lineWidth = 80;
ArrayList<String> lines = new ArrayList<String>();
int i = 0;
int lineIndex = 0;
lines.add("new int[] {");
boolean done = false;
while(!done) {
String line = "";
line += "\t";
int col = 0;
while(col < lineWidth-1 && !done) {
line += arr[i++] + ", ";
done = !(i < arr.length);
col++;
}
if(!done) {
line += arr[i++] + ",";
}
done = !(i < arr.length);
lines.add(line);
lineIndex++;
}
lines.add("};");
saveStrings("picture.java", lines.toArray(new String[1]));
}
/**
* Show a file-chooser dialog to the user to select the image for conversion.
* modified from http://wiki.processing.org/w/Open_Files_through_a_GUI .
*/
String choosefile() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception e) {
e.printStackTrace();
}
// create a file chooser
final JFileChooser fc = new JFileChooser("C:\\Users\\owen\\Pictures");
// in response to a button click:
int returnVal = fc.showOpenDialog(this);
if (returnVal == JFileChooser.APPROVE_OPTION) {
File file = fc.getSelectedFile();
// see if it's an image
if (file.getName().endsWith("jpg") || file.getName().endsWith("png")) {
return file.getPath();
} else {
println("Unsupported filetype.");
exit();
}
} else {
println("Open command cancelled by user.");
exit();
}
return null;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment