Image to characters (ASCII-Art)

Image to characters
these are the characters used" -~=+*^<a#$%0ß@"


image


                        - = + =         
                      * # # # # # ~     
                    ^ # * -   ~ < # ~   
                  ~ # +   = * -   a <   
                  ^ a   + # a #   + #   
                  a ^   a ^ - #   + #   
      = * * -     < ^   a ^       a <   
  - a # a # # +   ^ #   + # ^ * a # ~   
  < # ~     ^ # - ~ # +   + a # < ~     
~ # =   ^ =   # +   # # +               
+ #   + a ~   # + - # # # # ^ +         
= #   = # ^ a #   = # # # < a # # =     
- # +   * a < -   a # +       - < # =   
  ^ # =       - < # ~   + < ^ ~   < #   
    ^ # a ^ < # # ~   ^ # < a # - ~ # ~ 
      ~ ^ < < +     ~ # =     # *   # + 
                    + #   * ^ # = - # = 
                    = # - - < *   + # - 
                      # < -     = # ^   
                      ~ # # a a # <     
                          + ^ * ~    
Code
PImage source;
int s = 30,w,h;
char chr[] = (" -~=+*^<a#$%0ß@").toCharArray(); //char chr[] = (" °.-~=+*^>a#$%0ß@").toCharArray();
boolean invert = false;
void setup() {
  size(640, 600);
  w = width/s;
  h = height/s;
  source = loadImage("data/source.png");
  textSize(s);
}
void draw() {
  background(255);
  image(source,0,0);
  noStroke();
  for (int i = 0; i < w; i++) {
    for (int j = 0; j < h; j++) {
      float val = getAvg(get(i*s,j*s,s,s));
      fill(val);
      rect(i*s, j*s, s, s);
      char replace = (( (invert)? (chr[floor(map(val,255,0,0,chr.length-0.01))]) : (chr[floor(map(val,0,255,0,chr.length-0.01))])));
      print(replace+" ");
    }
    println();
  }
  noLoop();
}
float getValue(char input) {
  PGraphics temp = createGraphics(s, s);
  temp.beginDraw();
  temp.background(0);
  temp.textSize(s);
  temp.textAlign(3, 3);
  temp.fill(0);
  temp.text(input, s*0.5, s*0.5);
  temp.endDraw();
  return getAvg(temp);
}
float getAvg(PImage input) {
  input.filter(GRAY);
  float sum = 0, imgW = input.width, imgH = input.height;
  for (int i = 0; i < imgW; i++) for (int j = 0; j < imgH; j++) sum += red(input.get(i, j));
  float avg = sum/(imgW*imgH);
  return (avg);
}

Instructions - create a “source.png” inside of the sketches data folder to use.

4 Likes

:open_mouth: Really nice!

I have an idea in my bucket list to do something like this, but in video and with color, but just by looking at this code :tired_face: I still have a lot to learn.

1 Like

Don’t worry, the program I wrote for this is needlessly complicated. I made it like that to make it easier to output. You could start doing it with images and getting frames of images from it and after that just get the colors from the pixels. I am sure you could do it soon, but the best way to progress is with taking a step at the time. After all, “Even with the smallest step forwards, you are still making a difference”

Try to replicate this program with your own skills. After that, try to make it usable with colors. After that create a program that reads all of the frames out of the movie, put them through ascii-isation function and save it on the computer. When you are done, put the whole thing into the processing movie maker, which will return a .mov file, that you can put into a video editor software and transform it to .mp4

the thing is that you would need to display the ascii image on the canvas to acheive colors. It is a bit troublesome, but if you can do the previous steps, you can do it easily. Good luck!

I remember messing around with the ASCII webcam example, and trying to make it work in a grid, but ending nowhere, but I will use your code as reference when I try again, but before I have a few ideas I want to work first. If I run into trouble in the future regarding this topic I may come ask for help.

Thanks for your code!

What does the question mark in “(invert)?” do?

Hi!

((invert)? a : b) is a useful thing.
The actual structure of it is:
((boolean)? valueIfTRUE : valueIfFALSE)
it is useful if you have a lot of conditions and don’t want to keep using if() else(). valueIf----- can only be a value. You cannot do something like ((random(100)>50)? doThis() : doThat())

I hope this short “guide” will be of help in any way in your coding.

That made it clear for me! :slight_smile:

1 Like

is there a way to get the ascii art out of the console and to portrait as a picture if you run the code? cause atm the picture is shown as pixels instead of the ascii characters and the characters only show in the console

replace this with text(replace, i*scale, j * scale) and define variable scale as width/w. this should do the trick. However, I haven’t seen the code in 15 months, so it may be a bit different. Good luck

1 Like