Portable Pixmaps und Ein- und Ausgabe von Bildern

Transcrição

Portable Pixmaps und Ein- und Ausgabe von Bildern
Das im letzten Kapitel beschriebene C-Programm erlaubt eine Berechnung von Geodäten in der Nähe rotierender
schwarzer Löcher. Nächstes Ziel war nun die Simulation optischer Effekte welche auftreten, wenn ein hinter dem
schwarzen Loch liegendes Objekt beobachtet wird. Das Programm musste also um die Ein- und Ausgabe von
Bildern erweitert werden. Dies gelang durch Verwendung des Portable Pixmap (.ppm) Dateiformats.
Portable Pixmaps und Ein- und Ausgabe von Bildern
Portable Pixmap Bilddateien können Ascii-codiert werden, sind sehr einfach aufgebaut und daher ideal für die
Verarbeitung innerhalb des Programms ohne zusätzliche Bibliotheken. Dies soll folgendes Beispiel demonstrieren:
P3
# HEADER
2 2
255
0
0
0
255
255
255
0
0
0
0
128
0
Abb. 1: Inhalt einer Ascii-codierten Portable Pixmap Datei und zugehöriges Bild
Der Typkennzeichnung P3 und dem Header folgen Höhe und Breite des Bildes (2 × 2 px). Die nächste Angabe
ist jener Wert, der dem maximalen Farbanteil entspricht. Es folgen die Farbwerte in der Reihenfolge RotGrün-Blau zunächst aller Pixel der ersten Zeile beginnend bei Spalte 1, dann alle Pixel der 2. Zeile usw. Das
Bildverarbeitungsprogramm GIMP ist in der Lage, alle gängigen Bildformate in das Portable Pixmap Format zu
konvertieren. Nun soll gezeigt werden, wie das Programm dieses Format verarbeitet. Alle zur Bildverarbeitung
benötigten Funktionen wurden in der Datei picture.c implementiert:
/***************************************PICTURE.C****************************************/
#include "stdio.h"
#include <stdlib.h>
#include "picture.h"
int ***loadpic(char filename[],int *width, int *height, int *cmax) {
Die Funktion loadpic liest die Portable Pixmap Datei mit dem Namen filename[] ein. Sie gibt ein dreidimensionales Array zurück, wobei beispielsweise der Eintrag loadpic[0][1][2] dem Blau-Anteil (3. Index) des
Pixels [Zeile 1 (1. Index), Spalte 2 (2. Index)] entspricht. In die Zeigervariablen werden die Bildinformationen
Höhe, Breite und maximaler Farbwert geschrieben.
char trash;
int i,j,k;
int ***pixels;
FILE* image;
/*
/*
/*
/*
/*
Speicher fuer unnoetige Header-Infos */
Schleifenvariablen */
Pixelarray */
Bild-Datei */
Bild-Datei oeffnen */
image = fopen(filename,"r");
trash=’a’;
/* Einlesen der Headerzeile */
while (trash!=’\n’) { fscanf(image,"%c",&trash); }
trash=’a’;
while (trash!=’\n’) { fscanf(image,"%c",&trash); }
/* Hoehe und Breite einlesen */
fscanf(image,"%d %d\n",width,height);
fscanf(image,"%d\n",cmax);
/* Maximalen Farbwert einlesen */
/* Passendes Array anlegen */
1
/* Zeilen */
pixels = (int ***)malloc((*height) * sizeof(int**));
if (pixels==NULL) { printf("Speicherfehler"); *height=0;}
for (i=0;i<(*height);i++) {
/* Spalten */
pixels[i] = (int **)malloc((*width) * sizeof(int*));
if (pixels[i]==NULL) { printf("Speicherfehler"); break; }
}
for (i=0;i<(*height);i++) {
/* 3 Werte pro Pixel */
for (j=0;j<(*width);j++) {
pixels[i][j] = (int *)malloc(3*sizeof(int));
if (pixels[i][j]==NULL) { printf("Speicherfehler"); break; }
}
}
/* Werte aus PPM-Datei in Array einlesen */
for (i=0;i<(*height);i++) {
for (j=0;j<(*width);j++) {
for (k=0;k<3;k++) {
fscanf(image,"%d\n",&pixels[i][j][k]);
}
}
}
return pixels;
/* Rueckgabe des Bild-Arrays */
}
void setpixel(int ***pixels,int x, int y, int r, int g, int b) {
Die Funktion setpixel setzt den Pixel in [Zeile y+1, Spalte x+1] im Bildarray pixels auf den Farbwert (r,g,b).
pixels[y][x][0] = r;
pixels[y][x][1] = g;
pixels[y][x][2] = b; }
void getpixel(int ***pixels,int x, int y, int *r, int *g, int *b) {
Die Funktion getpixel liest den Farbwert (r,g,b) des Pixels in [Zeile y+1, Spalte x+1] im Bildarray pixels in
die Zeigervariablen ein.
*r = pixels[y][x][0];
*g = pixels[y][x][1];
*b = pixels[y][x][2]; }
void writepic(char filename[], int ***pixels, int width, int height, int cmax) {
Die Funktion writepic schreibt die im Bildarray pixels gespeicherten Farbinformationen in eine Portable
Pixmap Datei mit dem Namen filename[].
int i,j,k;
/* Schleifenvariablen */
FILE* image;
/* Bilddatei oeffnen */
image = fopen(filename,"wb");
fprintf(image,"P3\n");
/* Header schreiben */
fprintf(image,"# CREATOR: WRITEPIC IN PICTURE.H\n");
/* Breite, Hoehe und max. Farbwert schreiben */
fprintf(image,"%d %d\n",width,height);
fprintf(image,"%d\n",cmax);
for (i=0;i<height;i++) {
/* Werte aus Array schreiben */
for (j=0;j<width;j++) {
for (k=0;k<3;k++) {
fprintf(image,"%d\n",pixels[i][j][k]);
}
}
}
fclose(image);
/* Datei schliessen */
}
/****************************************************************************************/
2