Навигация / Прокрутка между изображениями bmp в C - PullRequest
0 голосов
/ 15 января 2019

У меня есть возможность прочитать Bmp заголовок изображения в соответствии со свойствами ниже.

Глубина изображения: 1 Атрибуты изображения: 1

Я хочу прокручивать / перемещаться между черно-белым изображением (Битовая глубина 1). Без закрытия и повторного открытия (изображение bmp).

1) Как и при вводе == f или F, пиксельные данные идут одно за другим прямое направление Y0, Y1, Y2, Y3, Y4, .... Yn

2) Как и при вводе == r или R, пиксельные данные идут один за другим в обратном направлении Y123, Y122, Y121, Y120, Y119, ...... Y0

3) Также я не хочу читать пиксели с начала (при каждом чтении). Я хочу читать между (только по вертикали). Ниже мой код.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct BitMap {
    short     Type;
    long      Size;
    short     Reserve1;
    short     Reserve2;
    long      OffBits;
    long      biSize;
    long      biWidth;
    long      biHeight;
    short     biPlanes;
    short    biBitCount;
    long      biCompression;
    long      biSizeImage;
    long      biXPelsPerMeter;
    long      biYPelsPerMeter;
    long      biClrUsed;
    long      biClrImportant; } Header;

unsigned char DummyValueRead ; unsigned char pixelValue =0 ;

int Horizontal= 0 ,Vertical = 0 ;

long  myPalette[2]; long  HeaderBytes;

unsigned char bPadding ;  long wBytesPerRow ;  unsigned char
bAdditionalBitsPerRow ;  FILE  *BMPFile;  void SendPixelValues();
unsigned char input ;

int main( void ) {
    BMPFile = fopen ("mul.bmp", "r");
    if (BMPFile == NULL)
    {
        printf("Image Not Found !!!!!!");
        return -1;
    }

    fread(&Header.Type,                                    sizeof(Header.Type), 1, BMPFile);
    fread(&Header.Size,                                       sizeof(Header.Size), 1, BMPFile);
    fread(&Header.Reserve1,                           sizeof(Header.Reserve1) , 1, BMPFile);
    fread(&Header.Reserve2,                           sizeof(Header.Reserve2) , 1, BMPFile);
    fread(&Header.OffBits,                                sizeof(Header.OffBits), 1, BMPFile);
    fread(&Header.biSize,                                  sizeof(Header.biSize), 1, BMPFile);
    fread(&Header.biWidth,                             sizeof(Header.biWidth), 1, BMPFile);
    fread(&Header.biHeight,                            sizeof(Header.biHeight) , 1, BMPFile);

    fread(&Header.biPlanes,                           sizeof(Header.biClrUsed),  1, BMPFile);
    fread(&Header.biBitCount,                      sizeof(Header.biBitCount), 1, BMPFile);
    fread(&Header.biCompression,              sizeof(Header.biCompression), 1, BMPFile);
    fread(&Header.biSizeImage,                    sizeof(Header.biSizeImage), 1, BMPFile);
    fread(&Header.biXPelsPerMeter,         sizeof(Header.biXPelsPerMeter), 1, BMPFile);
    fread(&Header.biYPelsPerMeter,         sizeof(Header.biYPelsPerMeter), 1, BMPFile);

    fread(&Header.biClrUsed,                        sizeof(Header.biClrUsed), 1, BMPFile);
    fread(&Header.biClrImportant,             sizeof(Header.biClrImportant),  1, BMPFile);

    fseek(BMPFile,Header.OffBits,SEEK_SET) ;

    printf("\nType:%hd   and Type in  %x\n", Header.Type,Header.Type);
    printf("Size:%ld\n", Header.Size);
    printf("Reserve1:%hd\n", Header.Reserve1);
    printf("Reserve2:%hd\n", Header.Reserve2);
    printf("OffBits:%ld\n", Header.OffBits);
    printf("biSize:%ld\n", Header.biSize);
    printf("Width:                         %ld\n", Header.biWidth);
    printf("Height:                         %ld\n", Header.biHeight);
    printf("biPlanes:%hd\n", Header.biPlanes);
    printf("biBitCount:%hd\n", Header.biBitCount);
    printf("biCompression:%ld\n", Header.biCompression);
    printf("biSizeImage:%ld\n", Header.biSizeImage);
    printf("biXPelsPerMeter:%ld\n", Header.biXPelsPerMeter);
    printf("biYPelsPerMeter:%ld\n", Header.biYPelsPerMeter);
    printf("biClrUsed:%ld\n", Header.biClrUsed);
    printf("biClrImportant:%ld\n\n", Header.biClrImportant);

    wBytesPerRow =Header.biWidth/8;
    bAdditionalBitsPerRow = Header.biWidth    %    8;
    bPadding = (4 - ((wBytesPerRow + (bAdditionalBitsPerRow?1:0)   ) % 4  )   )    %4;
    HeaderBytes = Header.biWidth/8  ;

    for(Vertical = 0 ;    Vertical <  Header.biHeight ;  Vertical ++)
    {
        printf("Sr. No. %d  \n",Vertical) ;
        scanf("%c",&input) ;
        if(input =='r' || input =='R' )          // Reverse Direction
        {
            //   fseek(BMPFile,((4*968) + 3), SEEK_SET );
            SendPixelValues() ;
        }
        if(input =='f' || input =='F' )          // Forward Direction
            SendPixelValues() ;
        printf("\n")  ;

    }
    fclose(BMPFile);

    return 0;
}

unsigned int bAdditionalBitsPerRowCount =
        0,bPaddingCount=0; void SendPixelValues() {

    for(Horizontal = 0 ; Horizontal <  HeaderBytes ;  Horizontal++)
    {
        fread(&pixelValue, sizeof(pixelValue), 1, BMPFile);
        printf("0x%x  ",pixelValue)  ;
    }
    if(bAdditionalBitsPerRow > 0)
    {
        fread(&DummyValueRead , sizeof(DummyValueRead ), 1, BMPFile);
        bAdditionalBitsPerRow++;
        printf("bAdditionalBitsPerRowCount %d",bAdditionalBitsPerRowCount);
    }
    for(Horizontal = 0 ;   Horizontal <  bPadding;  Horizontal++)
    {
        fread(&DummyValueRead , sizeof(DummyValueRead ), 1, BMPFile);
        bPaddingCount++;
    }
    printf("bPaddingCount = %d",bPaddingCount) ;
}

image Спасибо Karan

1 Ответ

0 голосов
/ 16 января 2019

1-битный растровый формат имеет 8 байтов для своей палитры, вы должны прочитать эти 8 байтов перед чтением пикселей.

8 байтов упакованы в один байт. Вы должны разделить биты и записать их соответственно. Растровое изображение может иметь отступ по ширине, вы должны рассчитать отступ для входного файла, а также для выходного файла.

Обязательно прочитайте / запишите файл в двоичном формате (это имеет значение в Windows).

Пример:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#pragma pack(push, 1)
struct BITMAPFILEHEADER {
    short bfType;
    int bfSize;
    short bfReserved1;
    short bfReserved2;
    int bfOffBits;
};

struct BITMAPINFOHEADER {
    int biSize;
    int biWidth;
    int biHeight;
    short biPlanes;
    short biBitCount;
    int biCompression;
    int biSizeImage;
    int biXPelsPerMeter;
    int biYPelsPerMeter;
    int biClrUsed;
    int biClrImportant;
};
#pragma pack(pop)

int main(void) 
{
    //set X and Y offset:
    int x0 = 10;
    int y0 = 10;

    if(sizeof(short) != 2 ||
        sizeof(int) != 4 ||
        sizeof(struct BITMAPFILEHEADER) != 14 ||
        sizeof(struct BITMAPINFOHEADER) != 40)
    {
        printf("Error, wrong structure size...");
        return -1;
    }

    FILE *fin = fopen("mul.bmp", "rb");
    FILE *fout = fopen("output.bmp", "wb");
    if(fin == NULL)
    {
        printf("Image Not Found !!!!!!");
        return -1;
    }

    struct BITMAPFILEHEADER header;
    struct BITMAPINFOHEADER info;

    fread(&header, sizeof(header), 1, fin);
    fread(&info, sizeof(info), 1, fin);

    if (info.biBitCount != 1)
    {
        printf("Error, not 1-bit bitmap\n");
        return -1;
    }

    int old_width = info.biWidth;
    int old_height = info.biHeight;
    int bitcount = info.biBitCount;
    int width_in_bytes = ((old_width * bitcount + 31) / 32) * 4;
    char palette[8];
    fread(palette, 1, sizeof(palette), fin);

    int new_width = old_width - x0;
    int new_height = old_height - y0;

    //convert to 24-bit bitmap for output file
    info.biBitCount = 24;
    info.biWidth = new_width;
    info.biHeight = new_height;
    info.biSizeImage = ((info.biHeight * bitcount + 31) / 32) * info.biWidth;
    header.bfSize = 54 + info.biSizeImage;
    header.bfOffBits = 54;

    fwrite(&header, 1, sizeof(header), fout);
    fwrite(&info, 1, sizeof(info), fout);

    char *bytes_read = malloc(width_in_bytes);
    char black[3] = { 0 };
    char white[3] = { 255,255,255 };
    for(int y = 0; y < old_height; y++)
    {
        fread(bytes_read, 1, width_in_bytes, fin);

        int width_index = 0;
        for(int i = 0; i < width_in_bytes; i++)
        {
            //8 pixels are packed in to 1 byte
            //separate the bits, write them as bytes in 24-bit format
            for(int j = 0; j < 8; j++)
            {
                width_index = i * 8 + j;
                if(width_index < x0) continue;
                if(width_index - x0 >= new_width) break;

                int pixel = (bytes_read[i] & (1 << (8 - j)));

                if(pixel)
                    fwrite(white, 1, 3, fout);
                else
                    fwrite(black, 1, 3, fout);
            }
        }

        //add padding to output file
        int m = width_index % 4;
        if(m)
            fwrite(black, 1, m, fout);
    }

    fclose(fin);
    fclose(fout);

    return 0;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...