Bilddaten



  • Hallo,
    ich versuche, in C auf eine Bilddatei zuzugreifen (das scheint auch zu klappen) und den Bildinhalt zu kopieren in eine neue Datei. Leider komme ich damit gar nicht klar. Zum Vorgehen: Ich habe einen Zeiger auf die zu kopierende Datei gelegt und einen auf die Datei, in die kopiert werden soll. Mit dem Befehl "int copy_file" versuche ich den Bildinhalt zu kopieren und weiß nun nicht, mit welcher Funktion ich den Bildinhalt in die neue Datei schreibe (fwrite?)
    Fehlermeldungen erhalte ich keine, die neue Datei ist aber leer.

    @Herrmann: Habe gestern nach Büchern geschaut. Leider eilt es bei mir etwas mit der "Bilddateibearbeitung". Weißt Du, oder sonst wer, ob es speziell zum Thema "Dateiverwaltung" oder "Bildverwaltung" in C Literatur gibt?
    Danke schon mal,
    Rose



  • @Rose, du willst also wie in deinem letzten Beitrag die Daten einer Datei in eine andere kopieren? Richtig? Im letzten Beitrag wurden doch schon komplette Lösungen beschrieben. Was funktioniert mit diesen nicht?



  • Also. wenn ich das, was als Vorschlag auf meinen letzten Beitrag kam, anwende (das mit dem COPY_FILE_BUFSIZE), dann erhalt ich bei der Ausführung immer den Fehler, dass die Anweisung xxx imme auf Speicher yyy verweist und dass deswegen der Befehl read nicht ausgeführt werden kann.
    Da ich, wie Du sicher schon gemerkt hast, ziemlich neu in der Thematik bin, kann ich mit solchen Fehlermeldungen leider auch nix anfangen.
    Hatte halt gedacht, dass es sich bei der Ein- und Ausgabe von Bilddatein ggf. anders verhält als bei reinen Textdateien.
    Gehe ich nach der Fehlermeldung in den Debug-Modus, sagt mir das so direkt auch nichts . . .
    Was also heißt das?
    Danke,
    Rose



  • @Rose,
    ich habe mal eine kleine Funktion geschrieben. Die Funktion kopiert die Daten der Datei mit dem Dateinamen pSrcFn in die Datei pDstFn. Falls du diesbezüglich noch Fragen hast, kannst du dich ja nochmal melden.

    #define COPY_BFSIZE 1024
    ...
    int fcopy( const char *pDstFn, const char *pSrcFn )
    {
      FILE *pSrcFd;
      FILE *pDstFd;
      char cBf[COPY_BFSIZE];
      size_t iRead;
    
      /* Eingabe abpruefen */
      if ( !pDstFn || !pSrcFn )
        return 0;
    
      /* Quelldatei oeffnen */
      pSrcFd = fopen( pSrcFn, "rb" );
      if ( pSrcFd )
      {
        /* Zieldatei oeffnen */
        pDstFd = fopen( pDstFn, "wb" );
        if ( pDstFd )
        { 
          /* Block von Quelldatei in cBf lesen */
          while ( ( iRead = fread( cBf, sizeof( char ), COPY_BFSIZE, pSrcFd ) ) > 0 )
            /* Gelesenen Block in die Zieldatei schreiben */
            fwrite( cBf, sizeof( char ), iRead, pDstFd );      
          /* Dateien schliessen */
          fclose( pSrcFd );
          fclose( pDstFd );
          return 1;
        };  
        /* Quelldatei schliessen */
        fclose( pSrcFd );
      };
    
      return 0;
    };
    


  • Erstmal danke für Deine Hilfe!!!
    Ich habe das natürlich sofort ausprobiert, ärgerlicherweise erhalte ich noch immer diese Fehlermeldung . . .ich vermute, ich habe vergessen, etwas ganz grundlegendes einzubinden, oder das funktioniert mit dem Bildtyp einfach nicht (mit Programm Paint zu Testzwecken erstellt, 256-Farben Bitmap, 268 kB Speicher).
    Hast Du noch Tipps?



  • @Rose,
    poste mal den Code deines Programms. Ohne weitere Information wie Fehlermeldung, usw. kann ich dir leider auch nicht weiterhelfen.



  • @Herrmann, hat doch geklappt, ich habe nur die Zeiger nicht sauber angewandt . . .dann kann das ja auch nix werden!

    Schönen Sonntag abend noch . . .
    Danke,
    Rose



  • Noch als kleine Info Rose, es ist vollkommen egal was in der Datei steht. Wichtig ist nur, dass die Dateien im Binärmodus gelesen/geschrieben.



  • @Herrmann:
    Ich habe noch zwei Fragen bezüglich Deines Quellcodes, bzw. Erweiterungsfragen:

    1. Fragestellung: Ich möchte ein Bild einlesen, eine in einer Bibliothek definierten Funktion mit dem Bild durchführen und diese Ergebnisse in eine Datei schreiben. An welcher Stelle rufe ich die Funktion auf?
      So wie unten funktioniert es leider nicht:

    while ( ( iRead = fread( cBf, sizeof( char ), COPY_BFSIZE, pSrcFd ) ) > 0)

    cmsDoTransform(hTransform,cBf,pDstFd,iRead);

    /* Gelesenen Block in die Zieldatei schreiben */
    fwrite( cBf, sizeof( char ), iRead, pDstFd );

    Die Funktion: cmsDoTransform ist eine extern definierte Funktion, die Bibliothek habe ich eingebunden

    Wenn ich versuche, eine for-Schleife einzubauen, wird es leider auch nix. Hast Du da eine Lösung? Der Fehler ist, dass ich immer eine leere Datei erhalte. Beim Kompilieren und Ausführen erhalte ich sonst keine Meldungen.

    1. Wie lese ich einzelne Zeilen eines Bildes ein??
      Danke schon mal,
      Rose


  • @Rose,
    wenn dein Code wirklich so aussieht, kann es nicht funktionieren.

    ...
    while ( ( iRead = fread( cBf, sizeof( char ), COPY_BFSIZE, pSrcFd ) ) > 0)
    { /* Klammer vergessen */
      cmsDoTransform(hTransform,cBf,pDstFd,iRead);
      fwrite( cBf, sizeof( char ), iRead, pDstFd );
    }; /* und hier genauso */
    ...
    

    Wenn mehr als eine Anweisung in einer Schleife ist, müssen diese in geschweiften Klammern eingeschlossen werden --> siehe C/C++ Buch 🙂

    Der zweite Punkt ist nicht so einfach zu realisieren. Je nachdem was für eine Grafikformat du verwendest, sind die Daten darin anders abgelegt. Weiterhin musst du den Header jeder Grafikdatei beachten. Bitmaps sind warscheinlich am einfachsten. Eine Headerbeschreibung findest du hier:
    http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/bitmaps_7c36.asp



  • Hilfe!!!
    Ich habe die Klammern nun angewandt und es geht trotzdem nicht:
    Ich kopiere Dir jetzt mal den gesamten Code: Die Fehlermeldung erscheint beim Ausführen und besagt, dass Vorgang xxx auf Speicher in yyy weist. Die Anweisung written konnte nicht auf dem Speicher durchgeführt werden.
    Ich bin sicher, Du siehst auf Anhieb, was da falsch ist!!!
    Ich vertiefe mich nun mal in mein C-Buch aus der Bücherei 😉
    1000 Dank schon mal,
    Rose

    #include <stdio.h>
    #include "lcms.h"
    /*#include <stack>
    #include <stdlib.h>
    */

    int main(void)
    {

    #define COPY_BFSIZE 1024

    cmsHPROFILE hInProfile, hOutProfile;
    cmsHTRANSFORM hTransform;

    char cBf[COPY_BFSIZE];
    size_t iRead;

    hInProfile = cmsOpenProfileFromFile("c:\\CIERGB.ICC","r");
    hOutProfile = cmsOpenProfileFromFile("c:\\AppleRGB.ICC","r");

    hTransform = cmsCreateTransform(hInProfile,
    TYPE_BGR_8,
    hOutProfile,
    TYPE_BGR_8,
    INTENT_PERCEPTUAL, 0);

    FILE *pSrcFd;
    const char *pSrcFn="c:\\Düne.bmp";

    FILE *pDstFd;
    const char *pDstFn="c:\\Düne2.bmp";

    /* Eingabe abpruefen */
    if ( !pDstFn || !pSrcFn )
    return 0;

    /* Quelldatei oeffnen */
    pSrcFd = fopen( pSrcFn, "rb" );
    if ( pSrcFd )
    {
    /* Zieldatei oeffnen */
    pDstFd = fopen( pDstFn, "wb" );
    if ( pDstFd )

    {

    /* Block von Quelldatei in cBf lesen */

    while ( ( iRead = fread( cBf, sizeof( char ), COPY_BFSIZE, pSrcFd ) ) > 0)

    {

    cmsDoTransform(hTransform,cBf,pDstFd,iRead);

    /* Gelesenen Block in die Zieldatei schreiben */
    fwrite( cBf, sizeof( char ), iRead, pDstFd );
    };

    /* Dateien schliessen */
    fclose( pSrcFd );
    fclose( pDstFd );
    return 1;
    };
    /* Quelldatei schliessen */
    fclose( pSrcFd );
    };

    return 0;
    };



  • @Rose,
    der Fehler besagt, dass du auf Speicher zugreifst welcher dir nicht gehört. Es wäre super wenn du sagen könntest bei welcher Quellcode-Zeile der Fehler auftritt.
    Ich gehe jetzt mal davon aus, dass du mit einer Entwicklungsumgebung mit Debugger arbeitest. Dann kannst du ja mal deinen Code Zeilenweise-Debuggen um die Stelle des Fehlers zu finden.

    Laufzeitfehler kann man ohne Testen schlecht finden bzw. nachvollziehen.



  • @Herrmann, beim Debuggen erscheint der Fehler in der Zeile

    fwrite( cBf, sizeof( char ), iRead, pDstFd );
    };,

    und zwar, nachdem die Bedingung 3-4 mal durchlaufen wurde. Fehlermeldung lautet: Access-Violation.
    Zur Info: Meine Bitmap-Datei ist 236 kB groß.
    Verstehe ich nicht . . .Du?
    Danke,
    Rose



  • @Rose,
    ich würde jetzt mal darauf tippen, dass die Funktion cmsDoTransform der Übeltäter ist. Kommentier mal den cmsDoTransform-Aufruf aus und mache dann mal einen Testlauf. Sollte es nicht an der Funktion liegen, müssen wir weiter raten 🙂



  • Wenn ich die Funktion "cmsDoTransform" auskommentiere, erhalte ich nicht mehr diese Fehlermeldung, leider wird die Funktion, die cmsDo Trannsform enthält, logischerweise nicht ausgeführt. Ich werde mir die API-Referenz noch mal ansehen, was den diese Funktion für Parameter braucht. Oder fällt Dir auf Anhieb was ein?
    Frage: Du schriebst, ich würde eventl. auf Speicher zugreifen, der mir nicht gehört.Die Fehlermeldung Access Violation deutet ja auch daraufhin. Was meinst Du (und die Fehlermeldung) damit?
    VG+Danke,
    Rose



  • Hallo, ich weiß zwar nicht was die Funktion macht da ich sie in der MSDN nicht finde. Bist du sicher, dass es eine API-Funktion ist? Du kannst aber mal was ausprobieren. Kommentier den Funktionsaufruf wieder ein und schau die die übergebenen Parameter vor und nach diesem Funktionsaufruf an.

    PS: Access Violation:

    /* Dein Programm reserviert damit Speicher für 10 char-Elemente*/
    char cChars[10];
    /* Wenn du nun versuchst auf das 11. Element zuzugreifen, greifst du 
    logischerweise auf Speicher zu, der deinem Programm nicht gehört oder
    zu überschreibst eigene Elemente. */
    cChars[10] = 'x';
    


  • @Herrmann,
    ich probiere zu Studienzwecken aus, in C ein frei verfügbares Color Management System (CMS) zu adressieren und Bilder im Farbmodus zu verändern. Diese CMS beeinhaltet eine API und demnach auch eine API-Referenz, in der ich nachgesehen habe, welche Parameter übergeben werden müssen.
    Werde Deinen Tipp gleich ausprobieren,
    Danke, bis dahin,
    Kerstin


Anmelden zum Antworten