Bildbearbeitung



  • Hallo Community,

    anscheinend sind hier schon mehrere Studienkollegen gewesen.

    Ich hab auch ein Problem mit dem Programm. Meins ist aber bereits die Dateiausgabe.

    Es sieht fast danach aus als wenn ich die Bildpunkte total durcheinander würfel.

    #include <stdio.h>
    #include <stdlib.h>
    
    #define ZEILENBREITE	512
    #define SPALTENBREITE	512
    
    int main()
    {
    
    FILE *dateizeiger;
    FILE *dateiausgeber;
    
    int j,i,k;
    long dateigroesse;
    short *bild_1d;
    short **bild_2d;
    
    // Zeiger auf Datei holen
    dateizeiger=fopen("Herz.IMA","rb");
    
    // Größe der Datei ermitteln
    fseek(dateizeiger, 0 ,SEEK_END);
    dateigroesse=ftell (dateizeiger);
    rewind(dateizeiger);
    
    // Speicher für eindimensionales Array reservieren
    bild_1d = (short*)malloc(dateigroesse*sizeof(char));
    
    //Einlesen des Bildes von der Festplatte in bild_1d im Arbeitsspeicher
    fread(bild_1d,1,dateigroesse,dateizeiger);
    
    // Bauen 2D-Array 
    bild_2d = (short**)malloc(ZEILENBREITE*sizeof(short*));
    for(i=0;i<ZEILENBREITE;i++) {
    	bild_2d[i] = (short*)malloc(SPALTENBREITE*sizeof(short));
    }
    
    // Laufvariable 1D-Array
    k = 0;
    
    // Kopie von bild_1d in bild_2d
    for(i=0;i<ZEILENBREITE;i++) {
    	for(j=0;j<SPALTENBREITE;j++) {
    		bild_2d[i][j] = bild_1d[k]; // *(*(bild_2d+i)+j)
    		k++;
    	}
    
    }
    
    // Ausgabe von bild_2d ins Dateisystem
    
     dateiausgeber = fopen ("Herz.IMA","w");
      if (dateiausgeber!=NULL){
    	fwrite(bild_2d, 1, dateigroesse, dateiausgeber);
    	 //for(i=0;i<(ZEILENBREITE*SPALTENBREITE);i++) {
    		//	 fwrite(bild_2d, 1, dateigroesse/2, dateiausgeber);
    	// }
      }
    
    //Schließen der geöffneten Dateien
    fclose(dateizeiger);
    fclose(dateiausgeber);
    free (bild_1d);
    
    return 0;
    }
    

    Danke, Amux


  • Mod

    Hallo Amux,

    willkommen im Forum. Worum geht es überhaupt? Bitte setz nicht voraus, dass hier jeder jeden Thread gelesen hat. Ich habe keine Ahnung, wovon du redest und kann dir daher nur oberflächlich helfen:

    Stilistische Fehler:
    - sizeof(char) ist per Definition 1
    - malloc zu casten ist in C nicht nötig, du (oder vermutlich dein Lehrer) denkst an C++. Es ist nicht nur unnötig, du verdeckst dadurch auch ein paar mögliche Fehler.
    - Ein bisschen Fehlerprüfung wäre nett, dein Programm schmiert grandios ab, wenn irgendwas mit der Datei nicht stimmt.
    -Du hast Speicherlöcher, da du die Daten des zweiten Bildes nicht freigibst.

    Und da ich anscheinend keine passende Datei habe und keine Ahnung, was das Programm machen soll, komme ich nun nicht weiter. Ich kann dir nur sagen, dass der Debugger mir flüstert, dass deine Lesezugriffe in Zeile 51 über das Feld hinausgehen. Ob das daran liegt, dass ich keine passende Datei habe oder dass dein Programm ein Fehler hat, kann ich nicht sagen.

    Es ist vermutlich auch keine gute Idee, eine Datei nochmals zum Schreiben zu öffnen, während du sie noch zum Lesen offen hast. Weiterhin fällt mir auf, dass du binär liest, aber nicht binär schreibst. Ob gewollt oder versehentlich kann ich wieder nicht beurteilen.

    Und noch ein paar Punkte: Dein Bild hat ja anscheinend feste Spaltenzahl (also in dem Sinne, dass alle Spalten gleich lang sind). Da wäre es besser, ein Array am Stück zu nehmen. Das ist erstens effizienter und vermeidet zweitens Fehler. ⚠ Du machst nämlich einen dicken Fehler beim Rausschreiben, da du ein paar Pointer ausgibst, aber nicht deine Nutzdaten.

    Wenn du die Zeilenlänge, so wie hier, schon im vorhinein kennst, dann kannst du mit einem Zeiger auf ein Array arbeiten ( short (*bild_2d)[ZEILENLAENGE]; ). Wenn die Größe erst zur Laufzeit feststeht, würdest du einfach ein Zeiger auf ein 1D-Array mit Größe Zeilen*Spalten nehmen und dir beim Zugriff auf Element (x,y) den Index (y + x * Zeilenlänge) errechnen. In beiden Fällen kannst du dann einfach alles in einem Rutsch mit write rausschreiben, so wie du es hier fälschlicherweise versuchst (Korrekterweise müsstest du bei dir die Zeilen einzeln ausgeben).



  • Schau doch mal wie du bild_2d angelegt hast.

    Du hast eine Array mit Zeigern auf die Zeilen.
    Die Zeilen können irgendwo im Speicher liegen.

    So ähnlich wie du das bei // Bauen 2D-Array gemacht hast musst du das Bild auch ausgeben.

    Nebenbei musst du den Speicher von bild_2d und allen Zeilen auch einzeln wieder mit free freigeben wenn du den Speicher nicht mehr brauchst.



  • Hallo SeppJ und DirkB,

    danke für eure Antwort!

    Zur Aufgabe:

    Es soll eine IMA Datei(Bild) eingelesen und mit verschiedenen Filtern bearbeitet werden.

    Das Array brauche ich um nachher einfach den Filter in Teilaufgabe 2 und 3 anwenden zukönnen.

    Hier geht es erstmal nur darum die Datei einzulesen und in das Array zu speichern bzw. dann wieder auszugeben.

    Ich werde die Ausgabe jetzt nochmal überarbeiten!

    Danke, Amux





  • Soweit hat alles funktioniert!

    Danke für die Denkanregungen.

    Bis bald, Amux.


Anmelden zum Antworten