3 Stimmen

Fread gibt 0 zurück, liest Pixel aus BMP-Datei

Ich verwende diesen Code, um die Pixel aus einer bmp-Datei zu erhalten. Ich habe bereits die Kopfzeilen und die Palette in den vorherigen Zeilen gelesen, so dass meine FILE * auf den Anfang des Pixel-Arrays zeigt. Es liest die erste Zeile OK, gibt 1000 zurück, was es sollte, aber wenn es versucht, die zweite Zeile von Pixeln zu lesen, gibt es 0 zurück.

Dies ist die Funktion, die die DATEI * empfängt, die Pixelzeilen liest und versucht, sie in einem bmp_type zu speichern. fila_alineada ist die Größe der ausgerichteten Zeilen, dies musste wegen des Paddings geschehen.

bool leer_pixels_8bpp(   FILE *fbmp, bmp_t *imagen,
                            const uint32_t fila_alineada,
                            const bool btopdown ){
int32_t i;
long x, y;
int32_t height, width, contador;
uint8_t *ptmp;

uint8_t bufferfila[fila_alineada];

height = imagen->infoheader.height;
width  = imagen->infoheader.width;
contador  = height;

i = btopdown ? 1 : -1;
y = btopdown ? 0 : ( height - 1 );

for ( ; contador--; y += i ) /* row loop */
{
    /* reading row */
    if ( fread( bufferfila, sizeof( uint8_t ), fila_alineada, fbmp ) != fila_alineada )
    {    /* HERE is the PROBLEM, it reads ok once, but in the second loop it returns 0 */
        fprintf( stderr, "Error reading pixels row.\n" );
        return false;
    }

    ptmp = bufferfila;
        /* saving pixels into bmp_t */
    for ( x = 0L; x < width; x++ )
    {
        imagen->pixels[y][x] = imagen->paleta.colores[ *ptmp++ ];
    }

}

return true;

}

Ich habe es mit verschiedenen bmp's versucht! Das Problem ist hier oder sollte ich erwägen, den gesamten Code zu überprüfen? Hoffe jemand kann mir helfen, danke im Voraus.

2voto

Jason Punkte 30904

Aus Ihrem Code geht hervor, dass Sie nicht lesen, was die width des Bildes ist ... vielmehr lesen Sie einen Betrag von fila_alineada . Sie haben erwähnt, dass fila_alineada war die ausgerichtete Zeilengröße wegen des "Paddings", aber BMP-Dateien sollten am Ende nur so viel Padding haben, dass jede Zeile ein Vielfaches von 4 Bytes ist ... das sollte ein Wert sein, der leicht aus dem BITMAPINFOHEADER berechnet werden kann, indem die tatsächliche Pixelarray-Datengröße durch die Anzahl der Zeilen im Bild geteilt wird. Die Pixelarraydatengröße ist an Offset 0x22 im Header gespeichert. Die Höhe befindet sich, wie Sie sicher schon richtig vermutet haben, an Offset 0x16. Also ist das Argument fila_alineada ist so gut wie überflüssig (d. h., Sie können es entfernen), und Sie berechnen diesen Wert möglicherweise falsch. Ich würde einfach die Informationen in der Kopfzeile verwenden, um die Größe des Puffers zu berechnen, der erforderlich ist, um die Informationen in einer bestimmten Zeile des Bildes zu speichern.

Zweitens, wenn Sie einfach versucht haben, die BITMAPINFOHEADER-Informationen aus der Datei in einen Puffer zu kopieren, der eine repräsentative Header-Struktur darstellt, sollten Sie daran denken, dass der Compiler die Struktur möglicherweise aus Gründen der Byte-Ausrichtung aufgefüllt hat ... aus Sicherheitsgründen sollten Sie daher nicht einfach den gesamten Header aus einer Datei lesen und dann versuchen, die memcpy() um den Puffer in eine BITMAPINFOHEADER-Struktur zu schreiben. Sie sollten die Header-Werte einzeln aus der Datei lesen und diese Werte einzeln in einer Struktur speichern, die den BITMAPINFOHEADER darstellt. Andernfalls, wenn Sie das erstere tun, indem Sie einfach versuchen, die ersten N Bytes der Datei zu lesen und diese in eine Struktur zu kopieren, könnten Sie aufgrund von Byte-Alignment-Problemen damit enden, dass Sie Werte hineinkopieren, die nicht korrekt sind, und daher werden alle Werte, die Sie versuchen, aus dieser Struktur zurückzulesen, nicht die mit Ihrer Bitmap-Datei verbundenen Werte darstellen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X