2

我在 C 中创建了这个函数来将文本放入 bmp 图像中。我试图让它只改变红色的最不重要的像素。但是当我打开编辑后的图像时,蓝色会改变。数据来自“stb_image.c”库。

int txt_bmp(char *tekst, int x, int y, unsigned char *data){
    int i, j, k, l = 0;
    unsigned char t,p = 0;
    for (i = 0; i < strlen(tekst); i++){    
        for (j = 0; j < 8; j++){
            t = 0x80;
            k = 1;
            p = tekst[i] & (t/k);
            p >>= (7-j);
            if (p == 0)
               data[l] &= p;
            data[l] |= p;
            k *= 2;
            l += 3;
        }
    }   
    return 0;
}

你知道有什么问题吗?

4

2 回答 2

1

当使用该BI_RGB模式(普通的未压缩DIB)时,24 位DIB 中每个三元组的顺序将是blue, green, red(即最低有效字节是蓝色分量)。

可以通过使用BI_BITFIELDS模式并根据自己的喜好指定通道掩码来切换组件,但BI_BITFIELDS据我所知,该模式对 24 位 DIB 无效。

所以如果你想在红色组件中存储一些东西,你应该使用每个三元组的最高有效字节。

于 2013-05-11T11:10:11.117 回答
0

在这里,这将创建一个未压缩的位图。稍加修改后,我已经在 arduino 上创建了一个 256x256 rgb 图像并将其保存到 SD 卡,内存为 2kb。(仅像素数据192kb)

目前,对代码进行了注释,使其成为单色图像 - 仅限 R 通道。查看第 155 到 157 行。

// 22nd September 2008
// 10:37pm
// Enhzflep


#include <stdio.h>              // for file I/O
#include <stdlib.h>

#ifndef WORD
 #define WORD unsigned short
#endif

#ifndef DWORD
    #define DWORD unsigned long
#endif

#ifndef BYTE
    #define BYTE unsigned char
#endif

#ifndef LONG
    #define LONG long
#endif

#define BI_RGB 0

#pragma pack(push,2)
typedef struct tagBITMAPFILEHEADER {
    WORD    bfType;
    DWORD   bfSize;
    WORD    bfReserved1;
    WORD    bfReserved2;
    DWORD   bfOffBits;
} BITMAPFILEHEADER,*LPBITMAPFILEHEADER,*PBITMAPFILEHEADER;
#pragma pack(pop)

typedef struct tagBITMAPINFOHEADER{
    DWORD   biSize;
    LONG    biWidth;
    LONG    biHeight;
    WORD    biPlanes;
    WORD    biBitCount;
    DWORD   biCompression;
    DWORD   biSizeImage;
    LONG    biXPelsPerMeter;
    LONG    biYPelsPerMeter;
    DWORD   biClrUsed;
    DWORD   biClrImportant;
} BITMAPINFOHEADER,*LPBITMAPINFOHEADER,*PBITMAPINFOHEADER;
typedef struct tagRGBQUAD {
    BYTE    rgbBlue;
    BYTE    rgbGreen;
    BYTE    rgbRed;
    BYTE    rgbReserved;
} RGBQUAD,*LPRGBQUAD;
typedef struct tagBITMAPINFO {
    BITMAPINFOHEADER bmiHeader;
    RGBQUAD bmiColors[1];
} BITMAPINFO,*LPBITMAPINFO,*PBITMAPINFO;


bool writeBmp24(int width, int height, char *filename, char *data)
{
    BITMAPINFO myBmpInfo;
    unsigned long myInfoSize;
    BITMAPFILEHEADER myBmpFileHeader;
    FILE *outputFile;

    // different bmp file types use different headers
    // this is the one for 24 bit bitmaps
    myInfoSize = sizeof(BITMAPINFOHEADER);

    // magic signature
    myBmpFileHeader.bfType = 0x4D42; // 'BM'

    // reserved data - must be zero
    myBmpFileHeader.bfReserved1 = 0;
    myBmpFileHeader.bfReserved2 = 0;

    // offset into file of the pixel data
    myBmpFileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + myInfoSize;

    // total file size
    myBmpFileHeader.bfSize = sizeof(BITMAPFILEHEADER)
                         + sizeof(BITMAPINFOHEADER)
                         + myInfoSize
                         + width*height*3;

    // size in bytes of this header
    myBmpInfo.bmiHeader.biSize = sizeof(myBmpInfo.bmiHeader);

    // size in bytes of the pixel data
    myBmpInfo.bmiHeader.biSizeImage = width*height*3;

    // image dimensions
    myBmpInfo.bmiHeader.biWidth = width;
    myBmpInfo.bmiHeader.biHeight = height;

    // pixels per meter (used to help select best image for output device)
    myBmpInfo.bmiHeader.biXPelsPerMeter = 2835;
    myBmpInfo.bmiHeader.biYPelsPerMeter = 2835;

    // only 1 pixel plane. Look up X-Mode (early 90s for more info on the concept of planes)
    myBmpInfo.bmiHeader.biPlanes = 1;

    // bits per pixel
    myBmpInfo.bmiHeader.biBitCount = 24;

    // compression type
    myBmpInfo.bmiHeader.biCompression = BI_RGB;

    // only used for images with a pallette
    myBmpInfo.bmiHeader.biClrImportant = 0;
    myBmpInfo.bmiHeader.biClrUsed = 0;


    if (!(outputFile = fopen(filename, "wb")))
        return false;

    if ( fwrite(&myBmpFileHeader, sizeof(BITMAPFILEHEADER), 1, outputFile) != 1)
        goto BmpError;

    if (fwrite(&myBmpInfo, myInfoSize, 1, outputFile) != 1)
        goto BmpError;

    if (fwrite(data, 3, width*height, outputFile) != width*height)
        goto BmpError;

    if (fclose(outputFile))
        return false;

    return true;

BmpError:
           fclose(outputFile);
           return false;
}

int main()
{
    int width = 128;
    int height = 128;

    char *pixelData;//[96*96*3];       //100x100 pixels * 24 bits/pixel
    char *dest;                                  // pointer to data
    int x, y;                                        // cur pixel
    char curVal;

    pixelData = (char*)calloc(3, width * height );
    dest = pixelData;                         // get locatio in mem of raw pixel data
    for (y=0; y<height; y++)           // for all rows of the image
        for (x=0; x<width; x++)       // loop through each pixel
        {
            curVal = x^y;
            dest[0] = 0;//curVal;       // b
            dest[1] = 0;//curVal;       // g
            dest[2] = curVal;           // r
            dest += 3;                            // point to next pixel;
        }

    writeBmp24(width, height, "enhzflep.bmp", pixelData);
    free(pixelData);
}
于 2013-05-11T12:08:52.253 回答