43

我正在用 C 语言做一个物理实验,Young 的干涉实验,我做了一个程序,可以打印到file一大堆像素:

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

其中hue,当给定一个值 [0..255] 时,返回char *3 个字节的 a,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

4 回答 4

48

您可能想要使用您正在寻找的PPM 格式:一个最小标题,后跟原始 RGB。

于 2013-05-19T15:38:49.750 回答
10

.tga如果您不使用压缩且不使用任何扩展名, TARGA(文件扩展名)可能是最简单且广泛支持的二进制图像文件格式。它甚至比 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)));
}
于 2018-04-04T19:18:23.063 回答
8

最近创建的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
于 2016-03-11T17:38:08.647 回答
4

这是一个使用最小 PPM 标头写入图像文件的最小示例。令人高兴的是,我能够让它与您提供的确切 for 循环一起工作:

#include <math.h> // compile with gcc young.c -lm
#include <stdio.h>
#include <stdlib.h>

#define width 256

int main(){
    int x, y, i; unsigned char raster_matrix[width*width], h[256][3];
    #define WAVE(x,y) sin(sqrt( (x)*(x)+(y)*(y) ) * 30.0 / width)
    #define hue(i) h[i]

    /* Setup nice hue palette */
    for (i = 0; i <= 85; i++){
        h[i][0] = h[i+85][1] = h[i+170][2] = (i <= 42)? 255:    40+(85-i)*5;
        h[i][1] = h[i+85][2] = h[i+170][0] = (i <= 42)? 40+i*5: 255;
        h[i][2] = h[i+85][0] = h[i+170][1] = 40;
    }

    /* Setup Young's Interference image */
    for (i = 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中的规范。对于此图像,标头只是一个 15 个字节的字符串:"P6 256 256 255\n".

于 2019-01-03T14:46:35.793 回答