C++: Fehler beim schreiben einer .tiff Datei mit Libtiff?
Hi,
das ist hoffentlich meine letzte Frage zu dem Thema :).
Ich habe ein Array mit allen RGBA-Werten für ein Bild im Byte Format (z.B.: 4282989356).
Nun möchte mit diesem Array eine neue Bilddatei vom Format .tiff schreiben und verwende dafür die Bibliothek libtiff.
Ich verwende folgenden Code:
auto image = new uint32[20976 * 20976];
for (uint32 row = 0; row < height; row++)
{
TIFFWriteScanline(tif, image, row, 0);
}
Ich habe hier noch die Dokumentation für TIFFWriteScanline().
Das Programm schreibt eine neue .tif Datei, die sogar eine Dateigröße hat die ich erwarte. Allerdings sieht die Datei geöffnet leider so aus.
Ich bin mir nicht sicher ob ich mein Array einfach so übergeben kann. TIFFWriteScanline() erwartet eine Variable vom Datentyp tdata_t, was auch immer das sein soll.
Es gibt ein Tutorial, welches den Vorgang etwas anders implementiert. Im Tutorial werden ein image und buf Array deklariert, beide vom Typ char.
char *image=new char [width*height*sampleperpixel];
unsigned char *buf = NULL;
Es wird die benötigte Speicher für eine Zeile festgelegt und für buf initialisiert.
tsize_t linebytes = sampleperpixel * width;
buf =(unsigned char *)_TIFFmalloc(linebytes);
Schließlich wird wie bei mir über jede Zeile iteriert und dabei zunächst die Bilddaten in buf geschrieben und von buf in die .tif Datei.
for (uint32 row = 0; row < h; row++)
{
memcpy(buf, &image[(h-row-1)*linebytes], linebytes);
TIFFWriteScanline(out, buf, row, 0)
}
Wobei ehrlich gesagt im Tutorial image nur deklariert aber nicht initialisiert wird. Wahrscheinlich muss es noch initialisiert werden. Aber kann ich meine RGBA Daten in Byte codes in ein Char array schreiben? Und wieso werden die Daten überhaupt zuerst in den buf geschrieben? Ist das wichtig und ggf. die Erklärung wieso mein Bild so bescheiden aussieht?
Ich bin gefühlt so kurz vorm Ziel was dieses kleine Projekt angeht und würde mich über Hilfen und Tipps sehr freuen :)
1 Antwort
auto image = new uint32[20976 * 20976];
for (uint32 row = 0; row < height; row++)
{
TIFFWriteScanline(tif, image, row, 0);
/* ^^^^^ */
}
Du holst Die Daten für die Zeile immer von der gleichen Adresse, das sollte eher sowas sein:
TIFFWriteScanline(tif, image+(row*20976), row, 0);
Das ist das Einzige, was direkt ins Auge springt.
P.S.: Du dürftest das natürlich auch Indexbasiert als Arrazugriff schreiben, falls das nicht klar sein sollte.
Ich sehe auf Anhieb nicht, warum das Tutorial rückwärts über die Zeiles des Rasters geht, es sei denn, das Format sieht die Anordnung vor, dann passt Du das entsprechend an.
Schau unbedingt nochmal wegen des Pixelformats und der Byteanordnung und der Byteordnung am Host, eventuell steckt da das Problem.
Ehrlich gesagt weiß ich nicht, was du mit Byteanordnung meinst.
Ich habe mir mal die RGB Werte bei Image[9000] ausgeben lassen kurz bevor ich TIFFWriteScanline ausführe. Dafür bietet Libtiff die Funktion TIFFGetR().
std::cout << TIFFGetR(image[9000]) << std::endl;
std::cout << TIFFGetG(image[9000]) << std::endl;
std::cout << TIFFGetB(image[9000]) << std::endl;
for (uint32 row = 0; row < nheight; row++)
{
TIFFWriteScanline(tif,&image[row * nheight], row, 0);
}
Ich bekomme:
54
72
85
Das sind an dieser Position gute Farbwerte die Sinn machen.
Im tatsächlichen Bild bekomme ich an dieser Position die Werte:
255
71
84
Generell habe ich in jeder Spalte einen Pixel mit dem Wert 255 für entweder R,G oder B.
Meine aktuelle Vermutung:
Ich habe die RGB Daten in einem uint32 Array (image). TIFFWriteScanline erwartet einen void*. Deshalb habe ich &image geschrieben. Kann es sein, dass das Programm bei &image nicht die richtigen Werte übergibt und wie würde ich das lösen? Oder bin ich auf dem falschen Weg?
Das sieht mir nach einer Offsetverschiebung aus, Wenn das Bild nicht ausdrücklich Alpha nutzt, wäre der Wert 255 für Alpha bei jedem Pixel (nicht transparent). Wenn der Wert bei Dir gleichmässig über die Farbkanäle wandert, spricht das dafür, daß das Alignment irgendwie nicht zu stimmen scheint.
Danke schonmal für den Hinweis.
Anders als vorher schreibt er schonmal das Bild in die Datei so wie es aussehen soll. Also ich kann z.B. den Fluss erkennen und Bäume. Das ist ein Fortschritt Leider habe ich immernoch diese senkrechten RGB Streifen. Ich muss jetzt mal den Code von vorne bis hinten prüfen