Skip to content

Instantly share code, notes, and snippets.

@kritzikratzi
Created September 19, 2012 15:29
Show Gist options
  • Save kritzikratzi/3750270 to your computer and use it in GitHub Desktop.
Save kritzikratzi/3750270 to your computer and use it in GitHub Desktop.
Re-assembling the "click and drag" xkcd comic
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
public class Assembler {
static int N = 48;
static int SIZE = 200;
static int imagesUsed;
public static void main(String[] args) throws IOException {
BufferedImage img = new BufferedImage( SIZE*N*2, SIZE*N*2, BufferedImage.TYPE_INT_ARGB );
int center = SIZE*N;
place( img, "n", "e", center-SIZE, center, 1, -1 );
place( img, "s", "e", center-SIZE, center-SIZE, 1, 1 );
place( img, "n", "w", center, center, -1, -1 );
place( img, "s", "w", center, center-SIZE, -1, 1 );
System.out.println( "writing to disk ..." );
ImageIO.write( img, "png", new File( "giant-" + System.currentTimeMillis() + ".png" ) );
System.out.println( "used " + imagesUsed + " images" );
}
private static void place( BufferedImage dest, String ns, String ew, int startX, int startY, int xInc, int yInc ){
Graphics2D g = dest.createGraphics();
g.setRenderingHint( RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON );
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR );
for( int i = 1; i <= N; i++ ){
for( int j = 1; j <= N; j++ ){
String filename = "images/" + i + ns + j + ew + ".png";
File src = new File( filename );
if( src.exists() && src.length() > 10 ){
System.out.println( "place " + filename );
try {
BufferedImage img = ImageIO.read( src );
System.out.println( (startX+xInc*SIZE*j) + ": " + (startY+yInc*SIZE*i));
g.drawImage( img, startX+xInc*SIZE*j,startY+yInc*SIZE*i, SIZE, SIZE, null );
img.flush();
imagesUsed ++;
}
catch (IOException e) {
e.printStackTrace();
}
}
else{
g.setColor( ns == "n"? Color.white : Color.black );
g.fillRect(startX+xInc*SIZE*j,startY+yInc*SIZE*i, SIZE, SIZE);
}
}
}
}
}
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.URL;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class Downloader {
final static int N = 49;
static int downloadedImages = 0;
public static void main(String[] args) throws InterruptedException {
ThreadPoolExecutor executor = new ThreadPoolExecutor( 10, 10, 10, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>() );
fetch( executor, "n", "e" );
fetch( executor, "s", "e" );
fetch( executor, "n", "w" );
fetch( executor, "s", "w" );
executor.shutdown();
executor.awaitTermination( 1, TimeUnit.DAYS );
System.out.println( "downloaded " + downloadedImages + " new images" );
}
private static void fetch( ThreadPoolExecutor executor, String ns, String ew ){
for( int i = 1; i <= N; i++ ){
for( int j = 1; j <= N; j++ ){
String filename = i + ns + j + ew + ".png";
executor.submit( new Fetcher( filename ) );
}
}
}
static class Fetcher implements Runnable{
private String filename;
public Fetcher( String filename ){
this.filename = filename;
}
public void run(){
File dest = new File( "images/" + filename );
if( dest.exists() ){
System.out.println( "skip " + filename );
}
else{
System.out.println( "fetch " + filename );
try( FileOutputStream fos = new FileOutputStream( dest ) ){
URL website = new URL("http://imgs.xkcd.com/clickdrag/" + filename );
ReadableByteChannel rbc = Channels.newChannel(website.openStream());
fos.getChannel().transferFrom(rbc, 0, 1 << 24);
downloadedImages ++;
}
catch( IOException e ){
System.err.println( "404: " + filename );
try(PrintWriter out = new PrintWriter( dest ) ){
out.close();
}
catch( FileNotFoundException e1){
e1.printStackTrace();
}
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment