在C中的bmp图像之间导航/滚动

时间:2019-01-15 05:44:19

标签: c printf

我能够按照以下属性读取图像的Bmp标头。

图像位深度:1 图片属性:1

我想在黑白图像(位深度1)之间滚动/导航。无需关闭并重新打开它(bmp图像)。

1)就像输入== f或F一样,像素数据一一向前移动 Y0,Y1,Y2,Y3,Y4,.... Yn

2)就像输入== r或R一样,像素数据一一向后移动 Y123,Y122,Y121,Y120,Y119,...... Y0

3)另外,我也不想从开始读取像素(每次读取)。 我想读之间(仅限垂直)。 下面是我的代码。

let hotspotConfig = NEHotspotConfiguration(ssid: SSID, passphrase: "", isWEP: false)

NEHotspotConfigurationManager.shared.apply(hotspotConfig) {[unowned self] (error) in

    if let error = error {
        self.showError(error: error)
    }
    else {
        self.showSuccess()
    }
}

Image 谢谢 卡兰

1 个答案:

答案 0 :(得分:0)

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;
}