Dateien in Tiff



  • Hallo,

    nachdem mein Code fertig ist, möchte ich noch einen Schritt einbauen.

    Ich möchte ein Bild in tif ausgeben. Dazu habe ich die libtiff Bib eingebunden und er gibt mir auch ein Bild aus. Leider noch nicht korrekt.

    Hier der Code

    void Sin2Tif(double data[], int tif_num)
    {
    int i;
    	int rows = 500, columns = 256;
    
    	TIFF* tif = TIFFOpen(
    			"1.tif", "w");
    	TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, columns);
    	TIFFSetField(tif, TIFFTAG_IMAGELENGTH, rows);
    	TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 1);
    	TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 64);
    	TIFFSetField(tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
    	for (i = 0; i < rows; i++) {
    		TIFFWriteScanline(tif, &data[i * columns], i, 0);
    	}
    	TIFFClose(tif);
    }
    

    Das Problem was besteht ist, dass mein Bild BSPW. 256*500 Pixel groß ist. Es sind aber alles double Werte also 64 Bit.
    Das Bild wird erstellt, aber öffnen geht so einfach nicht. Ich muss mit IMAGEJ das Bild als RAW importieren und dann auswählen "64-bit Real" und "Little-endian byte order". Dann bekomme ich das perfekte Bild angezeigt.
    Leider bringt mir das nicht viel, da ich die tif direkt weiterverarbeiten will und nicht mit imagej bearbeiten möchte.

    Habt ihr da einen Tipp für mich?



  • Hi,

    TIFFwriteScanline erwartet einen Zeiger auf unsigned char. Bekommst Du keinen Compilerfeher oder wenigestens eine Warnung?

    mfg Martin



  • Kann die Lib Pixeldaten als double exportieren?

    Ich würde die Doubles in jeweils nen 8-Bit Int umwandeln. Scheint das zu sein, was sie erwartet (Integer, zumindest).



  • Fehler kommt keiner nein ...

    EDIT:
    Umwandlung habe ich gemacht, aber da verliere ich ja Bildinformationen oder wie meinst du das mit dem umwandeln?



  • Pinockel schrieb:

    Fehler kommt keiner nein ...

    EDIT:
    Umwandlung habe ich gemacht, aber da verliere ich ja Bildinformationen oder wie meinst du das mit dem umwandeln?

    Versuchs mal mit 32-Bit ints.



  • Ich kenne mich mit TIFF nicht aus, jedoch gehe ich einfach mal so davon aus, da ich es nirgendwo sehe, dass du das Format (Gleitkommazahl) neben der Größe in Bits auch festlegen musst. Außer das ist der Standard.



  • EinGast schrieb:

    Ich kenne mich mit TIFF nicht aus, jedoch gehe ich einfach mal so davon aus, da ich es nirgendwo sehe, dass du das Format (Gleitkommazahl) neben der Größe in Bits auch festlegen musst. Außer das ist der Standard.

    Ich habe zwar nur uralte Quellen der TIFFLIB aber da ist das nicht der Standard. Möglicherweise hilft es tatsächlich den Typ zu setzen:

    TIFFSetField(tif, TIFFTAG_DATATYPE, DATATYPE_IEEEFP);
    

    mfg Martin



  • Hey Danke für eure Antworten. Ich habe viel probiert, aber wirklich zu einer Lösung komme ich nicht.

    Wenn ich die double Werte in int umwandle, dann bekomme ich ein Bild was nicht so aussieht wie es soll, da wie ich vermute, Informationen fehlen.

    Wenn ich

    TIFFSetField(tif, TIFFTAG_DATATYPE, DATATYPE_IEEEFP);
    

    eintrage, dann wirft es mir den Fehler

    ‘DATATYPE_IEEEFP’ undeclared (first use in this function)
    


  • Pinockel schrieb:

    Wenn ich die double Werte in int umwandle, dann bekomme ich ein Bild was nicht so aussieht wie es soll, da wie ich vermute, Informationen fehlen.

    In welchen Zahlenbreichen liegen die Doubles? Ich rate mal 0.0 - 1.0.
    Wie konvertierst du?
    Auf was setzt du TIFFTAG_SAMPLESPERPIXEL und TIFFTAG_BITSPERSAMPLE?



  • a) Wertebereich ist ungefähr -2 bis 2. Halt irgendwo dazwischen.

    b) So würde ich die Tags setzen, wenn ich mit double arbeite.

    TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 1);
    TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 64);
    

    c)
    Konvertieren wollte ich eigentlich so. Bzw das wäre mein Funktionscode

    void Tiffy(double data[], int tif_num) {
    	int i;
    	int rows = 500, columns = 256;
    	int32_t Test[rows*columns];
    
    	for (i=0; i<256*500; i++)
    		Test[i] = data[i];
    
    	TIFF* tif = TIFFOpen(
    			"1.tif", "w");
    	TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, columns);
    	TIFFSetField(tif, TIFFTAG_IMAGELENGTH, rows);
    	TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 1);
    	TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 32);
    	for (i = 0; i < rows; i++) {
    		TIFFWriteScanline(tif, &Test[i * columns], i, 0);
    	}
    	TIFFClose(tif);
    
    }
    


  • Pinockel schrieb:

    Hey Danke für eure Antworten. Ich habe viel probiert, aber wirklich zu einer Lösung komme ich nicht.

    Wenn ich die double Werte in int umwandle, dann bekomme ich ein Bild was nicht so aussieht wie es soll, da wie ich vermute, Informationen fehlen.

    Wenn ich

    TIFFSetField(tif, TIFFTAG_DATATYPE, DATATYPE_IEEEFP);
    

    eintrage, dann wirft es mir den Fehler

    ‘DATATYPE_IEEEFP’ undeclared (first use in this function)
    

    Oh, diese Konstante gibt es in meinen Quellen:

    #define	TIFFTAG_DATATYPE		32996U	/* how to interpret data */
    #define	    DATATYPE_VOID		0	/* untyped data */
    #define	    DATATYPE_INT		1	/* signed integer data */
    #define	    DATATYPE_UINT		2	/* unsigned integer data */
    #define	    DATATYPE_IEEEFP		3	/* IEEE floating point data */
    

    Die sind allerdings von 1991:

    /* $Header: /usr/people/sam/tiff/libtiff/RCS/tiff.h,v 1.28 91/07/26 10:06:22 sam Exp $ */
    

    Sollte wohl mal ein Update einspielen 🙄

    mfg Martin



  • Kannst du zu der verwendeten Bibliothek verlinken (Version auch angeben)? Ich tippe immer noch darauf, dass du das Format angeben musst. mgaecklers Code ist eben uralt oder für eine andere Bibliothek.

    Oder du versuchst selbstständig es herauszufinden.



  • http://www.libtiff.org/

    Diese wollte ich verwenden, aber an sich ist mir das egal, solange das Ergebnis stimmt 🙂



  • Also, bei Version 4.0.3 ist in tiff.h ab Zeile 305 dies zu finden:

    #define	TIFFTAG_SAMPLEFORMAT		339	/* !data sample format */
    #define	    SAMPLEFORMAT_UINT		1	/* !unsigned integer data */
    #define	    SAMPLEFORMAT_INT		2	/* !signed integer data */
    #define	    SAMPLEFORMAT_IEEEFP		3	/* !IEEE floating point data */
    #define	    SAMPLEFORMAT_VOID		4	/* !untyped data */
    #define	    SAMPLEFORMAT_COMPLEXINT	5	/* !complex signed int */
    #define	    SAMPLEFORMAT_COMPLEXIEEEFP	6	/* !complex ieee floating */
    


  • Hab es mal so gebaut

    TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, columns);
    	TIFFSetField(tif, TIFFTAG_IMAGELENGTH, rows);
    	TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 1);
    	TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 64);
    	TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_IEEEFP);
    

    Beim öffnen sagt mir ImageJ immer noch das 64 Bit nicht unterstützt wird.

    Gehe ich auf Import>RAW und gehe an

    "64-Bit Real" & "little endian byte order" kommt das richtige Bild.
    Ohne "little endian byte order" bekomme ich nur ein schwarzes Bild.



  • Pinockel schrieb:

    Hab es mal so gebaut

    TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, columns);
    	TIFFSetField(tif, TIFFTAG_IMAGELENGTH, rows);
    	TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 1);
    	TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 64);
    	TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_IEEEFP);
    

    Beim öffnen sagt mir ImageJ immer noch das 64 Bit nicht unterstützt wird.

    Gehe ich auf Import>RAW und gehe an

    "64-Bit Real" & "little endian byte order" kommt das richtige Bild.
    Ohne "little endian byte order" bekomme ich nur ein schwarzes Bild.

    Dann wirst Du wohl nicht darum herumkommen ImageJ ein 32-Bit Format zu geben.

    mfg Martin



  • Ich würds mal mit unsigned int versuchen (SAMPLEFORMAT_UINT, 32bps).
    libttf wird dann wohl die Daten im Bereich von 0 bis UINT_MAX erwarten.

    ~Edit: Habe gerade gemerkt, dass dies das C-Forum ist.~



  • mgaeckler schrieb:

    Pinockel schrieb:

    Hab es mal so gebaut

    TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, columns);
    	TIFFSetField(tif, TIFFTAG_IMAGELENGTH, rows);
    	TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 1);
    	TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 64);
    	TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_IEEEFP);
    

    Beim öffnen sagt mir ImageJ immer noch das 64 Bit nicht unterstützt wird.

    Gehe ich auf Import>RAW und gehe an

    "64-Bit Real" & "little endian byte order" kommt das richtige Bild.
    Ohne "little endian byte order" bekomme ich nur ein schwarzes Bild.

    Dann wirst Du wohl nicht darum herumkommen ImageJ ein 32-Bit Format zu geben.

    mfg Martin

    Wenn ich die Datei öffne wie oben beschrieben, dann erstellt er mir auch eine 32 Bit Datei. Deswegen denke ich, dass die Option "little endian byte order" wichtig ist.
    Also 32 Bit und irgendwie diese little endian byte order einrichten. Danach dann das Bild schreiben.

    Hat dafür jemand eine Idee?



  • Pinockel schrieb:

    Wenn ich die Datei öffne wie oben beschrieben, dann erstellt er mir auch eine 32 Bit Datei. Deswegen denke ich, dass die Option "little endian byte order" wichtig ist.
    Also 32 Bit und irgendwie diese little endian byte order einrichten. Danach dann das Bild schreiben.

    Hat dafür jemand eine Idee?

    Die TIFFLIB (zumindest meine) schreibt die TIFF-Datei im nativen Format des Prozessors. Da mußt Du Dich nicht darum kümmern. ImageJ sollte das dann entsprechend an Hand des Magics auswerten. Wenn nicht, wirf ImageJ weg. Ich kann mir aber nicht vorstellen, daß die das nicht korrekt auswertet, da es ja kaum noch Systeme ohne little endian gibt. 😉

    mfg Martin

    😉 Meine Nikons benutzen Big Endian beim Speichern der RAW Dateien.


Anmelden zum Antworten