ascii_art
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revisionNext revisionBoth sides next revision | ||
ascii_art [2023/03/24 11:04] – [Step 0. Choose an image] frchris | ascii_art [2023/03/25 15:37] – [Step 2. Load your image’s pixel data into a 2-dimensional array] frchris | ||
---|---|---|---|
Line 33: | Line 33: | ||
"""" | """" | ||
</ | </ | ||
+ | |||
+ | This Lab is based on one of [[https:// | ||
+ | |||
==== Step 0. Choose an image ==== | ==== Step 0. Choose an image ==== | ||
Choose the first image that you want to convert into ASCII art. It’s good to start with an image around 640x480. | Choose the first image that you want to convert into ASCII art. It’s good to start with an image around 640x480. | ||
+ | <code PickPicture.java> | ||
+ | import java.awt.Color; | ||
+ | import java.awt.Font; | ||
+ | import java.awt.Graphics; | ||
+ | import javax.swing.JFrame; | ||
+ | import javax.swing.JPanel; | ||
+ | import java.awt.image.BufferedImage; | ||
+ | import java.io.File; | ||
+ | import java.io.IOException; | ||
+ | import javax.imageio.ImageIO; | ||
+ | import java.awt.*; | ||
+ | /** | ||
+ | | ||
+ | | ||
+ | | ||
+ | */ | ||
+ | public class PickPicture extends JPanel | ||
+ | { | ||
+ | | ||
+ | private String fileName; | ||
+ | private BufferedImage source; | ||
+ | private Font titleFont, regularFont; | ||
+ | |||
+ | public PickPicture(String fileName) | ||
+ | { | ||
+ | titleFont = new Font(" | ||
+ | regularFont = new Font(" | ||
+ | try | ||
+ | { | ||
+ | // the line that reads the image file | ||
+ | this.fileName = fileName; | ||
+ | this.source = ImageIO.read(new File(fileName)); | ||
+ | System.out.println(fileName + " read "); | ||
+ | System.out.println(source.getWidth() + " by " + source.getHeight()); | ||
+ | |||
+ | } | ||
+ | catch (IOException e) | ||
+ | { | ||
+ | System.out.println(" | ||
+ | "Make sure the file is \n 1. In the project folder,\n " + | ||
+ | "2. The file name is perfect-including capital letters\n " + | ||
+ | "3. The extension is right-like .png or .jpg\n " + e); | ||
+ | } | ||
+ | |||
+ | } | ||
+ | public int getWidth() {return source.getWidth(); | ||
+ | public int getHeight() {return source.getHeight(); | ||
+ | | ||
+ | public void paintComponent(Graphics g){ | ||
+ | super.paintComponent(g); | ||
+ | g.setColor(Color.WHITE); | ||
+ | g.fillRect(0, | ||
+ | g.drawImage(source, | ||
+ | g.setColor(Color.BLACK);// | ||
+ | g.setFont(titleFont); | ||
+ | g.drawString(fileName, | ||
+ | g.setFont(regularFont); | ||
+ | g.drawString ( getWidth() + " by " + getHeight(), | ||
+ | | ||
+ | | ||
+ | } | ||
+ | | ||
+ | public static void main(String[] args) { | ||
+ | PickPicture pic= new PickPicture(" | ||
+ | JFrame window = new JFrame(" | ||
+ | window.setSize(pic.getWidth(), | ||
+ | window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); | ||
+ | window.getContentPane().add(pic); | ||
+ | window.setVisible(true); | ||
+ | |||
+ | } | ||
+ | |||
+ | } | ||
+ | </ | ||
==== Step 1. Read your image and print its height and width in pixels ==== | ==== Step 1. Read your image and print its height and width in pixels ==== | ||
+ | |||
+ | <code Step1.java> | ||
+ | import java.awt.image.BufferedImage; | ||
+ | import java.io.File; | ||
+ | import java.io.IOException; | ||
+ | import javax.imageio.ImageIO; | ||
+ | |||
+ | public class Step1 | ||
+ | { | ||
+ | private BufferedImage image; | ||
+ | private String fileName; | ||
+ | public Step1(String fileName) | ||
+ | { | ||
+ | try | ||
+ | { | ||
+ | this.fileName = fileName; | ||
+ | image = ImageIO.read(new File(fileName)); | ||
+ | System.out.println(fileName + " read "); | ||
+ | | ||
+ | System.out.println(" | ||
+ | // Print the width and height of the image using a BufferedImage method. | ||
+ | |||
+ | } | ||
+ | catch (IOException e) | ||
+ | { | ||
+ | System.out.println(" | ||
+ | } | ||
+ | } | ||
+ | |||
+ | public static void main(String[] args) | ||
+ | { | ||
+ | new Step1(" | ||
+ | } | ||
+ | |||
+ | } | ||
+ | </ | ||
==== Step 2. Load your image’s pixel data into a 2-dimensional array ==== | ==== Step 2. Load your image’s pixel data into a 2-dimensional array ==== | ||
+ | <code Step2.java> | ||
+ | |||
+ | import java.awt.image.BufferedImage; | ||
+ | import java.io.File; | ||
+ | import java.io.IOException; | ||
+ | import javax.imageio.ImageIO; | ||
+ | /** | ||
+ | * Test your Step2 code with this. It reads your 2D array of Color | ||
+ | * and draws it. | ||
+ | * @author Chris Thiel, OFMCap | ||
+ | * @version 25 Mar 2023 | ||
+ | */ | ||
+ | public class Step2 | ||
+ | { | ||
+ | private BufferedImage image; | ||
+ | private String fileName; | ||
+ | private int width, | ||
+ | private int[] rgb; // for 8bit RGB packed in an int array | ||
+ | private Color[][] px; | ||
+ | public Step2(String fileName) | ||
+ | { | ||
+ | try | ||
+ | { | ||
+ | // the line that reads the image file | ||
+ | this.fileName = fileName; | ||
+ | image = ImageIO.read(new File(fileName)); | ||
+ | System.out.println(fileName + " read "); | ||
+ | width = image.getWidth(); | ||
+ | height = image.getHeight(); | ||
+ | System.out.println(" | ||
+ | rgb = image.getRGB(0, | ||
+ | System.out.println(rgb.length); | ||
+ | // rgb is a 1D array, with the rows listed one after the other. | ||
+ | ///to convert to a 2D array use something like this: | ||
+ | // grid (x,y) = rgb[ y*width + x]; | ||
+ | // Make a new 2D array of color name px, and fill it from the 1D rgb array | ||
+ | // for example, px[0][0] = new Color ( rgb[0] ); | ||
+ | | ||
+ | |||
+ | } | ||
+ | catch (IOException e) | ||
+ | { | ||
+ | System.out.println(" | ||
+ | } | ||
+ | } | ||
+ | public Color[][] getPx() { return px;} | ||
+ | public static void main(String[] args) | ||
+ | { | ||
+ | new Step2(" | ||
+ | } | ||
+ | |||
+ | } | ||
+ | </ | ||
+ | You can see what your new 2D Array of Color looks like with {{ :: | ||
+ | |||
==== Step 3. Convert the RGB tuples of your pixels into single brightness numbers | ==== Step 3. Convert the RGB tuples of your pixels into single brightness numbers | ||
+ | |||
+ | Now that you have a 2D Array of '' | ||
+ | - Average: average the R, G and B values - '' | ||
+ | - Lightness: average the maximum and minimum values out of R, G and B - '' | ||
+ | - Luminance: take a weighted average of the R, G and B values to account for human perception - '' | ||
+ | - Luminosity: Take the sqrt root of the weighted squares - '' | ||
+ | - See [[https:// | ||
+ | <code Step3.java> | ||
+ | import java.awt.Color; | ||
+ | import java.awt.Font; | ||
+ | import java.awt.Graphics; | ||
+ | import javax.swing.JFrame; | ||
+ | import javax.swing.JPanel; | ||
+ | import java.awt.*; | ||
+ | /** | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | */ | ||
+ | public class Step3 extends JPanel | ||
+ | { | ||
+ | |||
+ | private String fileName; | ||
+ | private Font titleFont, regularFont; | ||
+ | private Color[][] clr; | ||
+ | private int[][] brightness; | ||
+ | |||
+ | public Step3(String fileName) | ||
+ | { | ||
+ | this.fileName = fileName; | ||
+ | this.clr = new Step2(fileName).getPx(); | ||
+ | titleFont = new Font(" | ||
+ | regularFont = new Font(" | ||
+ | | ||
+ | // Make a 2D int array that same number of rows and columns | ||
+ | // as the Color array | ||
+ | | ||
+ | |||
+ | | ||
+ | | ||
+ | //Fill the brightness array with yout choice of conversion method | ||
+ | // (like Average, Lightness, Luminocity, or your own) | ||
+ | | ||
+ | |||
+ | |||
+ | } | ||
+ | public int average(Color c) | ||
+ | { | ||
+ | // your code here | ||
+ | } | ||
+ | public int luminance(Color c) | ||
+ | { | ||
+ | // your code here | ||
+ | } | ||
+ | public int lightness(Color c) | ||
+ | { | ||
+ | //your code here | ||
+ | } | ||
+ | public int luminosity(Color c){ | ||
+ | // your code here | ||
+ | } | ||
+ | public int getWidth() { | ||
+ | return brightness.length;// | ||
+ | } | ||
+ | |||
+ | public int getHeight() { | ||
+ | return brightness[0].length; | ||
+ | } | ||
+ | |||
+ | public void paintComponent(Graphics g){ | ||
+ | super.paintComponent(g); | ||
+ | g.setColor(Color.WHITE); | ||
+ | g.fillRect(0, | ||
+ | // | ||
+ | for (int y=0; y < getHeight(); | ||
+ | for(int x=0; x < getWidth(); x++) | ||
+ | { | ||
+ | int b = brightness[x][y]; | ||
+ | g.setColor( new Color(b, | ||
+ | g.fillRect( x, y, 1, 1); | ||
+ | } | ||
+ | |||
+ | g.setColor(Color.BLACK);// | ||
+ | g.setFont(titleFont); | ||
+ | g.drawString(fileName, | ||
+ | g.setFont(regularFont); | ||
+ | g.drawString ( getWidth() + " by " + getHeight() + "- Drawn from 2DColor Array", | ||
+ | |||
+ | } | ||
+ | |||
+ | public static void main(String[] args) { | ||
+ | Step3 pic= new Step3(" | ||
+ | JFrame window = new JFrame(" | ||
+ | window.setSize(pic.getWidth(), | ||
+ | window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); | ||
+ | window.getContentPane().add(pic); | ||
+ | window.setVisible(true); | ||
+ | } | ||
+ | |||
+ | } | ||
+ | </ | ||
==== Step 4. Convert brightness numbers to ASCII characters | ==== Step 4. Convert brightness numbers to ASCII characters | ||
+ | You can experiment with different ways to map brightnesses to characters, but a good place to start is the string below. The characters in it are ordered from thinnest to boldest, which means lightest to darkest. | ||
+ | |||
+ | |||
==== Step 5. What if it looks your image looks squashed? ==== | ==== Step 5. What if it looks your image looks squashed? ==== | ||
- | [[https:// | + | [[https:// |
ascii_art.txt · Last modified: 2023/03/27 10:46 by frchris