【问题标题】:What is the simplest RGB image format?最简单的 RGB 图像格式是什么?
【发布时间】:2013-05-14 05:33:14
【问题描述】:

我正在使用 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 个字节 R、G、B 的 char *。

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

更简洁,切换自:

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

【问题讨论】:

    标签: c image raster


    【解决方案1】:

    这是一个使用最小 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"。

    【讨论】:

      【解决方案2】:

      最近创建的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
      

      【讨论】:

        【解决方案3】:

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

        【讨论】:

        • 什么时候初始化tga数组中偏移量0、1、3到11的字节?由于 BSS 链接器部分或其他原因,它是否保证为零?
        • 好问题。事实上,全局变量和静态变量保证被 C 初始化为零。如果您从malloc() 获取数组或在堆栈上分配它,您必须手动将memset() 归零(或使用calloc()它自己做的)。
        【解决方案4】:

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-09-07
          • 2022-10-30
          • 1970-01-01
          • 1970-01-01
          • 2011-11-25
          • 2019-01-29
          • 2013-08-18
          • 1970-01-01
          相关资源
          最近更新 更多