Skip to content

Instantly share code, notes, and snippets.

@davidwhitney
Created April 15, 2020 19:54
Show Gist options
  • Save davidwhitney/194ec56b2d21ac28b0dcbd0657726d84 to your computer and use it in GitHub Desktop.
Save davidwhitney/194ec56b2d21ac28b0dcbd0657726d84 to your computer and use it in GitHub Desktop.
Remote Dojo 2
import { Code } from "./AsciiArt";
describe("Code", async () => {
let sut;
beforeEach(() => {
sut = new Code();
});
it("A single white pixel returns '.'", async () => {
const result = await sut.makeArtFrom("app/white.jpg");
expect(result).toBe(".");
});
it("A single black pixel returns '#'", async () => {
const result = await sut.makeArtFrom("app/black.jpg");
expect(result).toBe("#");
});
it("An image with multiple colours, renders correctly", async () => {
const result = await sut.makeArtFrom("app/blackthenwhite.jpg");
expect(result).toBe("#.");
});
it("An image with multiple colours veritcally, renders correctly", async () => {
const result = await sut.makeArtFrom("app/blackthenwhite2.jpg");
expect(result).toBe("#\r\n.");
});
it("Images no bigger than provided width", async () => {
const result = await sut.makeArtFrom("app/Ducky.png", 100, 100);
const lines = result.split('\r\n');
expect(lines[0].length).toBeLessThanOrEqual(100);
});
it("Images auto-scale missing dimensions in height", async () => {
const result = await sut.makeArtFrom("app/25x50.png", 50);
const lines = result.split('\r\n');
expect(lines[0].length).toBe(50);
expect(lines.length).toBe(100);
});
it("Images auto-scale missing dimensions in width", async () => {
const result = await sut.makeArtFrom("app/25x50.png", null, 100);
const lines = result.split('\r\n');
expect(lines.length).toBe(100);
expect(lines[0].length).toBe(50);
});
it("Can render a duck", async () => {
const result = await sut.makeArtFrom("app/Ducky.png", 50, 50);
console.log(result);
});
});
const Jimp = require("jimp");
export class Code {
public async makeArtFrom(fileName: string, width?: number, height?: number): Promise<string> {
let image = await this.readFile(fileName);
image = this.resizeIfAppropriate(image, width, height);
const output = this.mapToAscii(image);
return output.trim();
}
private mapToAscii(image) {
let output = "";
for (let y = 0; y < image.bitmap.height; y++) {
for (let x = 0; x < image.bitmap.width; x++) {
const rgb = Jimp.intToRGBA(image.getPixelColor(x, y));
const brightness = (rgb.r + rgb.g + rgb.b) / 3;
output += this.selectCharacter(brightness);
}
output += "\r\n";
}
return output;
}
private resizeIfAppropriate(image, width?: number, height?: number) {
if (width || height) {
image.resize(width || Jimp.AUTO, height || Jimp.AUTO);
}
return image;
}
private selectCharacter(brightess: number): string {
if (brightess >= 200) {
return ".";
} else if (brightess >= 180) {
return "o";
} else if (brightess >= 150) {
return "D";
} else if (brightess >= 130) {
return "O";
} else if (brightess >= 120) {
return "@";
} else if (brightess >= 100) {
return "#";
} else if (brightess >= 80) {
return "░";
} else if (brightess >= 50) {
return "█";
}
return '#';
}
private readFile(fileName: string): Promise<any> {
return new Promise((resolve, reject) => {
Jimp.read(fileName, (err, image) => {
if(err) { reject(err); }
resolve(image);
});
});
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment