Creative Communities of the World Forums

The peer to peer support community for media production professionals.

Activity Forums Adobe After Effects Expressions Video to ASCII effect

  • Video to ASCII effect

    Posted by Justin Porter on October 25, 2007 at 11:11 pm

    So i posted on the After Effects forum, and thought maybe it would be more apropriate to post here.

    I’m trying to create an effect where I can take a video and replace it with ASCII characters.

    Kevin Camp came up with this expression which works great, but only renders a single character per text field:

    asciiArray = [” “,”a”,”b”,”c”,”d”,”e”,”f”,”g”,”h”,”i”,”j”]; // enter characters to range from light to dark values
    numCharacters = 10; // enter the total number of ascii characters entered in the array above
    imageMap = thisComp.layer(“Source Image”).sampleImage([position[0], position[1]], [1, 1]);
    a = Math.round(linear(imageMap[0], 0, numCharacters));
    asciiArray[a]

    I tried putting this on a text field and duplicating it in a grid, problem is that it takes a couple thousand layers (all running expressions) to fill the screen area with a sufficient number of ASCII characters and After Effects crashes long before I have enough.

    I also found this page:

    https://www.creative-workflow-hacks.com/2007/08/27/more-fun-with-sampleimage-ascii-animation-in-after-effects/

    which contains an expression that works for one line of text, so I have fewer layers (I only have to duplicate it per the number of lines), but the problem is it doesn’t regulate the width of the text field, so the changing width of the characters change the location of subsequent characters.

    I’m really stuck and I’ve been struggling with this problem for days. Does anyone know how I can achieve this effect?

    Sean Archibald replied 9 years, 7 months ago 9 Members · 36 Replies
  • 36 Replies
  • Dan Ebberts

    October 26, 2007 at 12:14 am

    If your video layer is named “target”, you can apply an expression like this to a text layer:

    density = ” .’`,^:” + ‘”;~-_+<>i!lI?/\|()1{}[]rcvunxzjftLCJUYXZO0Qoahkbdpqwm*WMB8&%$#@’;
    target = thisComp.layer(“target”);
    cols = 80;
    rows = 60;
    w = thisComp.width/cols;
    h = thisComp.height/rows;

    s = “”

    for (var i = 0; i < rows; i++){ for(var j = 0; j < cols; j++){ center = [w/2 + j*w, h/2 + i*h]; sample = target.sampleImage(center,[(w-1)/2,(h-1)/2]); s += density[Math.round(linear(sample[0],0,1,0,density.length - 1))]; } s += "\r"; } s You'll have to fiddle with the font size, tracking, leading, etc. Edit the cols and rows variables to suit your needs Dan

  • Justin Porter

    October 26, 2007 at 12:56 am

    Thanks a lot Dan, I’ll try that one.

  • Kevin Camp

    October 26, 2007 at 4:00 pm

    dan, that is quite impressive in it’s simplicity (at least to a guy with no scripting knowledge).

    in hopes of learning more about scripting…

    [Dan Ebberts] “for (var i = 0; i < rows; i++){"

    var i = 0, sets the initial value of ‘i’ to 0. then compares the value of ‘i’ to the value of rows. and i++ increases the value of ‘i’ until ‘i’ exceeds the value of rows, at which point the ‘loop’ ends (is that correct to call it a loop, or is it like a subroutine).

    [Dan Ebberts] “s = “””

    is this just setting up a variable ‘s’ that initially returns nothing? and it then gets increased (+=) by the value of the density array… until ‘i’ exceeds the value of rows, at which point ‘s’ is nothing again (and the ‘loop’ stops).

    Kevin Camp
    Designer – KCPQ, KMYQ & KRCW

  • Dan Ebberts

    October 26, 2007 at 5:31 pm

    Pretty much. The loop will execute as long as i less than rows. s = “” just establishes s as an empty string. The += appends a new character to the string.

    I just noticed that a back slash character got lost when I pasted the code in. I’ll try it again, this time using the HTML code tag.

    
    
    density = " .'`,^:" + '";~-_+<>i!lI?/\|()1{}[]rcvunxzjftLCJUYXZO0Qoahkbdpqwm*WMB8&%$#@';
    target = thisComp.layer("target");
    cols = 80;
    rows = 60;
    w = thisComp.width/cols;
    h = thisComp.height/rows;
    
    s = ""
    
    for (var i = 0; i < rows; i++){
      for(var j = 0; j < cols; j++){
        center = [w/2 + j*w, h/2 + i*h];
        sample = target.sampleImage(center,[(w-1)/2,(h-1)/2]);
        s += density[Math.round(linear(sample[0],0,1,0,density.length - 1))];
      }
      s += "\r";
    }
    s
    
    

    Dan

  • Patrick Deen

    October 30, 2007 at 11:04 pm

    Dan you make me sick with seemingly easy solutions you come up with!
    I was looking for a way to do this before CS3 after seeing the “black tambourines” video by Beck. I long gave up on the idea that I could figure it out myself.

    The only thing I would like to add is that when you’re experimenting with different video’s it’s more convenient to use the “layer(index)” attribute (just an other handy thing I learned from Dan)

    Setting up the target as “target = thisComp.layer(index -1);”
    Now you can just add the video you want to “ascciisize” to the layer above your scripted text layer.

    To add a little more depth to my ascii video I made a second text layer with bold type and sampled the same video with crunched levels to limit the bold type to the darkest areas. You do need to adjust the letter-spacing to align the bold and normal type. Beware that adding a second scripted layer really shows that this is a processor intense expression.

    asciistuff

  • Justin Porter

    November 5, 2007 at 7:08 pm

    K, finally got a chance to punch this into After Effects.

    I must be doing something wrong though. The result Patrick got is exactly what I’m looking for, so I’m excited to figure out what went wrong and fix it.

    I created a text layer above the “target” video layer, put some dummy text in there and pasted the expression into the Source Text attribute of the text layer.

    When I do this, my dummy text disappears and is replaced by nothing, only a set of fully retracted bounding box handles. Any idea what I could be doing wrong?

    Again, thank you to all of you for your help, there’s no way I could have done this project without you guys helping me out with this script.

  • Justin Porter

    November 6, 2007 at 12:08 am

    I’m trying to deconstruct this expression a little bit so maybe I can troubleshoot it myself.

    Is the backslash that got left out in this statement: ” s += “r”;”, should it be ” s += “/r”;” instead to add a return character to the string?

    Also, does the solitary “s” at the end of the expression put the final string into the text box?

  • Patrick Deen

    November 6, 2007 at 1:30 pm

    You’ve probably set your character size too small if you only see the bounding boxes 😉

    I’ve commented Dan’s expression for you. Hope it helps you to understand it 🙂

    One other thing, you can make your own set of characters ranging from light to dark. I wasn’t really fond of the “@” as the darkest character so I’ve altered the desity string to suit my taste.

    Here’s the commented expression;

    density = ” .’`,^:” + ‘”;~-_+<>i!lI?/|()1{}[]rcvunxzjftLCJUYXZO0Qoahkbdpqwm*WMB8&%$#@’;

    /* “density” is just a string ordered with characters from light to dark (” ” is white and “@” is black).You can access each character from this string as an array. “density[1]” would be “.” since array entries start counting by zero (desity[0] = ” “) */

    target = thisComp.layer(index -1);

    /* the target variable will hold the reference to the layer above the texts layer where you’ve added this expression */

    cols = 80; //number of characters/columns that make up the width of the grid
    rows = 60; //number of characters/rows that make up the height of the grid

    w = thisComp.width/cols;
    // dividing the width by the number of columns gives you the width of each “cell” in the grid

    h = thisComp.height/rows;
    // dividing the height by the number of columns gives you the height of each “cell” in the grid

    s = “” // this declares an empty variable to hold the string that makes up your ascii art

    // Next comes a nested loop that makes it all happen…

    for (var i = 0; i < rows; i++){ // adding the rows /* the value of "i" is zero, repeat this action while "i" is smaller than the number of rows, increment "i" with one after each execution of the embedded script */ //the real nested loop for(var j = 0; j < cols; j++){ // adding the columns to the row /* the value of "j" is zero, repeat this action while "j" is smaller than the number of columns, increment "j" with one after each execution of the script */ center = [w/2 + j*w, h/2 + i*h]; // divide the width/height of the cell in half and add j times the width/height to that value results in the centre-point of each cell sample = target.sampleImage(center,[(w-1)/2,(h-1)/2]); // uses the "center" variable for the position and sets the size of the point to be sampled based on the size of your grid-cells. sample will hold an array of three numbers between 0 and 1 (1=white and 0=black) s += density[Math.round(linear(sample[0],0,1,0,density.length - 1))]; // the variable "s" is incremented with a character from the "desity" string. The expression between the straight brackets uses the first value of the sampled color in the sample variable to produce an integer/rounded number which is used to select the character to add to the string "s" } s += "r"; // After a row is completed this adds a new line to the text until all rows are built. } s // in the end the completed string is echoed by this simple notation and this is what shows up on the text layer.

  • Justin Porter

    November 6, 2007 at 5:20 pm

    thanks Patrick, that’s a great learning tool.

    I’m still having trouble figuring out why my text isn’t showing up though. I had dummy text in the field that when the expression is disabled shows up fine, text size is set to 72px so it seems like it should be showing up. Any other ideas? Where should the text field be placed? would that affect the expression?

  • Patrick Deen

    November 6, 2007 at 5:27 pm

    Copy pasting leads to stupid errors ;-{
    I missed a backslash in my post (among other type errors but this one is crucial)

    s += “\r”; // After a row is completed this adds a new line to the text until all rows are bu

Page 1 of 4

We use anonymous cookies to give you the best experience we can.
Our Privacy policy | GDPR Policy