What is the simplest RGB image format?

Deadly 提交于 2019-11-28 20:08:05

You probably want to use the PPM format which is what you're looking for: a minimal header followed by raw RGB.

Ian D. Scott

The recently created farbfeld format is quite minimal, though there is not much software supporting it (at least so far).

Bytes                  │ Description
8                      │ "farbfeld" magic value
4                      │ 32-Bit BE unsigned integer (width)
4                      │ 32-Bit BE unsigned integer (height)
(2+2+2+2)*width*height │ 4*16-Bit BE unsigned integers [RGBA] / pixel, row-major

TARGA (file name extension .tga) may be the simplest widely supported binary image file format if you don't use compression and don't use any of its extensions. It's even simpler than Windows .bmp files and is supported by ImageMagick and many paint programs. It has been my go-to format when I just need to output some pixels from a throwaway program.

Here's a minimal C program to generate an image to standard output:

#include <stdio.h>
#include <string.h>

enum { width = 550, height = 400 };

int main(void) {
  static unsigned char pixels[width * height * 3];
  static unsigned char tga[18];
  unsigned char *p;
  size_t x, y;

  p = pixels;
  for (y = 0; y < height; y++) {
    for (x = 0; x < width; x++) {
      *p++ = 255 * ((float)y / height);
      *p++ = 255 * ((float)x / width);
      *p++ = 255 * ((float)y / height);
    }
  }
  tga[2] = 2;
  tga[12] = 255 & width;
  tga[13] = 255 & (width >> 8);
  tga[14] = 255 & height;
  tga[15] = 255 & (height >> 8);
  tga[16] = 24;
  tga[17] = 32;
  return !((1 == fwrite(tga, sizeof(tga), 1, stdout)) &&
           (1 == fwrite(pixels, sizeof(pixels), 1, stdout)));
}

Here's a minimal example that writes your image file with a minimal PPM header:

#include <stdio.h>
#include <stdlib.h>

#include <math.h> // compile with gcc -lm
#define WAVE(x,y) sin(sqrt( (x)*(x)+(y)*(y) ) / 3.0)

int main(){
    /* Setup code */
    #define width 256
    unsigned char raster_matrix[width*width];
    unsigned char a[3];
    #define hue(c) (a[0] = c, a[1] = 128, a[2] = 255-c, a)

    int x, y, i = 0;
    for (y = 0; y < width; y++) for (x = 0; x < width; x++)
        raster_matrix[i++] = 128 + 64*(WAVE(x,y) + WAVE(x,width-y));


    /* Open PPM File */
    FILE *file = fopen("young.ppm", "wb"); if (!file) return -1;

    /* Write PPM Header */
    fprintf(file, "P6 %d %d %d\n", width, width, 255); /* width, height, maxval */

    /* Write Image Data */
    for (i=0; i < width*width; i++)
        fwrite(hue(raster_matrix[i]), 1, 3, file);

    /* Close PPM File */
    fclose(file);

    /* All done */
    return 0;
}

I wrote the header code based on the specs at http://netpbm.sourceforge.net/doc/ppm.html.

I hacked in some setup code so I could incorporate the for loop given in the question. :)

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!