Hello everyone.
Recently I got interested in ASCII art, I could see that there was an example created by Ben Fry in the Processing library.
My problem is that I want to use this code but with an imported video and not a live video from my webcam.
I tried to modify the code as below but I still have this message that appears “ArrayIndexOutOfBoundsException: 0”
Could someone help me to find a solution? I put the code that i modified below, maybe it can help !
Thanks !
/**
- ASCII Video
- by Ben Fry.
- Text characters have been used to represent images since the earliest computers.
- This sketch is a simple homage that re-interprets live video as ASCII text.
- See the keyPressed function for more options, like changing the font size.
*/
import processing.video.*;
Movie movie;
boolean cheatScreen;
// All ASCII characters, sorted according to their visual density
String letterOrder =
" .`-_':,;^=+/"|)\<>)iv%xclrs{*}I?!][1taeo7zjLu" +
“nT#JCwfy325Fp6mqSghVd4EgXPGZbYkOA&8U$@KHDBWNMR0Q”;
char letters;
float bright;
char chars;
PFont font;
float fontSize = 1.5;
void setup() {
size(800, 800);
// This the default video input, see the GettingStartedCapture
// example if it creates an error
movie = new Movie(this, “001.mp4”);
movie.loop();
int count = movie.width * movie.height;
//println(count);
font = loadFont(“UniversLTStd-Light-48.vlw”);
// for the 256 levels of brightness, distribute the letters across
// the an array of 256 elements to use for the lookup
letters = new char[256];
for (int i = 0; i < 256; i++) {
int index = int(map(i, 0, 256, 0, letterOrder.length()));
letters[i] = letterOrder.charAt(index);
}
// current characters for each position in the video
chars = new char[count];
// current brightness for each point
bright = new float[count];
for (int i = 0; i < count; i++) {
// set each brightness at the midpoint to start
bright[i] = 128;
}
}
void movieEvent(Movie m) {
m.read();
}
void draw() {
background(255);
//image(movie, 0, 0, width, height);
pushMatrix();
float hgap = width / float(movie.width);
float vgap = height / float(movie.height);
scale(max(hgap, vgap) * fontSize);
textFont(font, fontSize);
int index = 0;
movie.loadPixels();
for (int y = 1; y < movie.height; y++) {
// Move down for next line
translate(0, 1.0 / fontSize);
pushMatrix();
for (int x = 0; x < movie.width; x++) {
int pixelColor = movie.pixels[index];
// Faster method of calculating r, g, b than red(), green(), blue()
int r = (pixelColor >> 16) & 0xff;
int g = (pixelColor >> 8) & 0xff;
int b = pixelColor & 0xff;
// Another option would be to properly calculate brightness as luminance:
// luminance = 0.3*red + 0.59*green + 0.11*blue
// Or you could instead red + green + blue, and make the the values[] array
// 256*3 elements long instead of just 256.
int pixelBright = max(r, g, b);
// The 0.1 value is used to damp the changes so that letters flicker less
float diff = pixelBright - bright[index];
bright[index] += diff * 0.1;
fill(pixelColor);
int num = int(bright[index]);
text(letters[num], 0, 0);
// Move to the next pixel
index++;
// Move over for next character
translate(1.0 / fontSize, 0);
}
popMatrix();
}
popMatrix();
if (cheatScreen) {
//image(video, 0, height - video.height);
// set() is faster than image() when drawing untransformed images
set(0, height - movie.height, movie);
}
}
/**
- Handle key presses:
- ‘c’ toggles the cheat screen that shows the original image in the corner
- ‘g’ grabs an image and saves the frame to a tiff image
- ‘f’ and ‘F’ increase and decrease the font size
*/
void keyPressed() {
switch (key) {
case ‘g’: saveFrame(); break;
case ‘c’: cheatScreen = !cheatScreen; break;
case ‘f’: fontSize *= 1.1; break;
case ‘F’: fontSize *= 0.9; break;
}
}