什么是最简单的RGB图像格式?

时间:2013-05-19 15:30:13

标签: c image raster

我正在C上进行物理实验,Young's interference experiment我制作了一个程序,可以打印到file一大堆像素:

for (i=0; i < width*width; i++)
{
    fwrite(hue(raster_matrix[i]), 1, 3, file);
}

hue,当给定值[0..255]时,返回一个带有3个字节的char *,R,G,B。

我想在我的图片文件中添加一个最小的标题,以使这个原始文件成为有效的图像文件。

更简洁: 切换自:

offset
0000 : height * width : data } my data, 24bit RGB pixels

offset
0000 : dword : magic        \
     : /* ?? */              \
0012 : dword : height         } Header <--> common image file
0016 : dword : width         /
     : /* ?? */             /
0040 : height * width : data  } my data, 24bit RGB pixels

谢谢。

4 个答案:

答案 0 :(得分:33)

您可能想要使用您正在寻找的PPM format:最小标头后跟原始RGB。

答案 1 :(得分:4)

最近创建的farbfeld格式很少,但没有太多软件支持它(至少到目前为止)。

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

答案 2 :(得分:2)

TARGA(文件扩展名为.tga)可能是最简单的广泛支持的二进制映像文件格式,如果您不使用压缩并且不使用其任何扩展名。它甚至比Windows .bmp文件更简单,并且得到ImageMagick和许多绘图程序的支持。当我只需要从一次性程序中输出一些像素时,它就是我的首选格式。

这是一个用于生成标准输出图像的最小C程序:

#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)));
}

答案 3 :(得分:0)

这是一个最小的示例,该示例使用最小的PPM标头写入图像文件:

#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;
}

我根据http://netpbm.sourceforge.net/doc/ppm.html上的规范编写了标头代码。

我破解了一些设置代码,因此可以合并问题中给出的for循环。 :)