3 ms·
Simple formats are PPM / Netpbm; they’re ASCII text with an identifier line (“P1” for mono, “P2” for grayscale or “P3” for colour), a width and height in pixels
by jodrellblank 4y ago
Simple formats are PPM / Netpbm; they’re ASCII text with an identifier line (“P1” for mono, “P2” for grayscale or “P3” for colour), a width and height in pixels (e.g. 320 200), then a stream of numbers for pixel values. Line breaks optional. Almost any language that can count and print can make them, your can write them from APL if you want
As ASCII they can pass through email and UUNET and clipboards without BASE64 or equivalent. With flexible line breaks they can even be laid out so the monochrome ones look like the image they describe in a text editor.
See the examples at
https://en.wikipedia.org/wiki/Netpbm# https://en.wikipedia.org/wiki/Netpbm#
- st_goliath 4y agoThe Netbpm format is amazing if you quickly want to try something out and need to generate an image of some sorts. The P6 binary format is even simpler, you write the header followed by a raw pixel data blob, e.g.: fprintf(stdout, "P6\n%d %d\n255\n", WIDTH, HEIGHT); fwrite(image, 1, WIDTH * HEIGHT * 3, stdout); Yes, I know, this obviously misses error handling, etc... The snippet is from a simple Mandelbrot renderer I cobbled together for a school exam exercise many moons ago: https://gist.github.com/AgentD/86445daed5fb21def3699b8122ea2b65 https://gist.github.com/AgentD/86445daed5fb21def3699b8122ea2... The simplicity of the format nicely limits the image output to the last 2 lines here.
- a_e_k 4y agoI use this all the time. I love that it's simple enough that I can type something like those two lines off the top of my head at this point. And as an alternative to that fwrite(), another common pattern that I use is: for (int y = 0; y < HEIGHT; ++y) for (int x = 0; x < WIDTH; ++x) { // ... compute r, g, and b one pixel at a time printf("%c%c%c", r, g, b); } I also find ImageMagick very convenient for working with the format when my program writes a PPM to stdout: ./myprog | convert - foo.png or: ./myprog | display -
- greggman3 4y agoI don't consider ASCII simple because it needs to be parsed (more than a binary format). As sample example, a binary format could be as simple as struct Header { uint32 width; uint32 height; } struct Image { Header header; uint8* data; } Image* readIMG(const char* filename) { int fd = open(filename, ...) Image* image = new Image(); read(fd, &image->header, sizeof(image->header)); size_t size = image->header.width * image->header.height * 4; image->data = malloc(size); read(fd, image->data, size); close(fd); return image; } Yea I know, that's not a complete example, endian issues, error checking. Reading a PPM file is only simple if you already have something to read buffered strings and parse numbers etc... And it's slow and large, especially for todays files.