it-swarm.com.de

Was ist das einfachste RGB-Bildformat?

Ich arbeite in C an einem Physikexperiment, Young's Interferenzexperiment und ich habe ein Programm erstellt, das file eine riesige Anzahl von Pixeln druckt:

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

Wobei hue bei Angabe eines Wertes [0..255] einen char * mit 3 Byte, R, G, B, zurückgibt.

Ich möchte eine minimale Kopfzeile in meine Bilddatei einfügen, um aus dieser Rohdatei eine gültige Bilddatei zu machen.

Genauer gesagt: Umschalten von:

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

zu

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

Vielen Dank.

32
Nope

Wahrscheinlich möchten Sie das Format PPM verwenden , nach dem Sie suchen: ein minimaler Header, gefolgt von rohem RGB.

31

Das kürzlich erstellte farbfeld - Format ist ziemlich minimal, obwohl es (zumindest bisher) nicht viel Software unterstützt.

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
4
Ian D. Scott

TARGA (Dateinamenerweiterung .tga) ist möglicherweise das einfachste, weit verbreitete Dateiformat für binäre Bilder, wenn Sie keine Komprimierung und keine der Erweiterungen verwenden. Es ist sogar einfacher als Windows .bmp-Dateien und wird von ImageMagick und vielen Paint-Programmen unterstützt. Es war mein wichtigstes Format, wenn ich nur einige Pixel eines Wegwerfprogramms ausgeben muss.

Hier ist ein minimales C-Programm, um ein Bild zur Standardausgabe zu generieren:

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

Hier ein minimales Beispiel, in dem Ihre Image-Datei mit einem minimalen PPM -Header geschrieben wird:

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

Ich habe den Header-Code basierend auf den Spezifikationen unter http://netpbm.sourceforge.net/doc/ppm.html geschrieben.

Ich habe etwas Setup-Code gehackt, damit ich die in der Frage angegebene for-Schleife einbauen konnte. :)

0
mwfearnley