Was ist das einfachste RGB-Bildformat?

Lesezeit: 3 Minuten

Nopes Benutzeravatar

Ich arbeite in C an einem Physikexperiment, Youngs Interferenzexperiment und ich habe ein Programm gemacht, das druckt file ein riesiger Haufen Pixel:

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

Wo huewenn ein Wert angegeben wird [0..255]gibt zurück a char * mit 3 Bytes, R,G,B.

Ich möchte einen minimalen Header in meine Bilddatei einfügen, um diese Rohdatei a gültig Bilddatei.

Prägnanter, 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

Sie möchten wahrscheinlich die verwenden PPM-Format was Sie suchen: ein minimaler Header, gefolgt von rohem RGB.

Benutzeravatar von Lassi
Lassi

TARGA (Dateinamenerweiterung .tga) ist möglicherweise das einfachste weithin unterstützte binäre Bilddateiformat, wenn Sie keine Komprimierung und keine seiner Erweiterungen verwenden. Es ist sogar noch einfacher als Windows .bmp Dateien und wird von ImageMagick und vielen Zeichenprogrammen unterstützt. Es war mein bevorzugtes Format, wenn ich nur einige Pixel aus einem Wegwerfprogramm ausgeben musste.

Hier ist ein minimales C-Programm, um ein Bild für die 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)));
}

  • Wann initialisieren Sie die Bytes an den Offsets 0, 1 und 3 bis 11 im tga-Array? Ist es dank des BSS-Linker-Abschnitts oder so etwas garantiert Null?

    – Johan Boule

    8. September 2019 um 1:44 Uhr


  • Gute Frage. Tatsächlich werden globale und statische Variablen garantiert von C mit Null initialisiert. Wenn Sie das Array von bekommen haben malloc() oder es auf dem Stack zuordnen, müssten Sie memset() manuell auf Null setzen (oder verwenden calloc() das macht das von alleine).

    – Lassi

    8. September 2019 um 9:31 Uhr

Benutzeravatar von Ian D. Scott
Ian D. Scott

Die kürzlich erstellt 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

Benutzeravatar von mwfearnley
mwfearnley

Hier ist ein minimales Beispiel, das Ihre Bilddatei mit einem minimalen PPM-Header schreibt. Glücklicherweise konnte ich es mit der genauen for-Schleife, die Sie bereitgestellt haben, zum Laufen bringen:

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

Der Header-Code basiert auf den Spezifikationen unter http://netpbm.sourceforge.net/doc/ppm.html. Für dieses Bild ist der Header nur eine Zeichenfolge von fünfzehn Bytes: "P6 256 256 255\n".

1406930cookie-checkWas ist das einfachste RGB-Bildformat?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy