Skip to content

Instantly share code, notes, and snippets.

@taiypeo
Created December 19, 2016 00:17
Show Gist options
  • Save taiypeo/0843e5f9e126ebdc42c5b50954ef914b to your computer and use it in GitHub Desktop.
Save taiypeo/0843e5f9e126ebdc42c5b50954ef914b to your computer and use it in GitHub Desktop.
A basic app that converts .png images to ASCII art
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <iostream>
#include <stdexcept>
#include <vector>
#include "lodepng/lodepng.h" // you have to have lodepng in this folder to compile
bool open_input(std::string filename, std::vector<unsigned char> &img, unsigned int &width,
unsigned int &height);
std::string transform_to_ascii(std::vector<unsigned char> &img, unsigned int width,
unsigned int height);
bool write_output(std::string filename, std::string img);
int main(int argc, char *argv[])
{
if (argc != 3)
{
std::cerr << "Usage: png2ascii input output" << std::endl;
return EXIT_FAILURE;
}
#define INPUT_FILE argv[1]
#define OUTPUT_FILE argv[2]
std::vector<unsigned char> img;
unsigned int width, height;
if (!open_input(INPUT_FILE, img, width, height))
return EXIT_FAILURE;
std::string ascii_img = transform_to_ascii(img, width, height);
if (!write_output(OUTPUT_FILE, ascii_img))
return EXIT_FAILURE;
return EXIT_SUCCESS;
}
bool open_input(std::string filename, std::vector<unsigned char> &img, unsigned int &width,
unsigned int &height)
{
unsigned int err = lodepng::decode(img, width, height, filename);
if (err)
{
std::cerr << "ERROR: " << "lodepng decoder error " << err << ": "
<< lodepng_error_text(err) << std::endl;
return false;
}
return true;
}
std::string transform_to_ascii(std::vector<unsigned char> &img, unsigned int width,
unsigned int height)
{
const char symbols[] = "@%#*+=-:. ";
const int sym_count = strlen(symbols);
std::string result = "";
for (size_t i = 0; i < img.size(); i += 4)
{
float luminance = (0.2126 * img[i] + 0.7152 * img[i + 1] +
0.0722 * img[i + 2]) / 255;
result += symbols[(img[i + 3] ? (size_t) (luminance * (sym_count - 1)) : sym_count - 1)];
if ((result.size() % (width + 1) == width) &&
(result.size() != (width + 1) * height - 1))
{
result += '\n';
}
}
return result;
}
bool write_output(std::string filename, std::string img)
{
std::ofstream file(filename);
if (!file.is_open())
{
std::cerr << "ERROR: Could not write to output file" << std::endl;
return false;
}
file << img;
file.close();
return true;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment