隐藏.bmp中的文本

时间:2013-05-11 10:17:31

标签: c bmp steganography

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

你知道什么是错的吗?

2 个答案:

答案 0 :(得分:1)

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

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

因此,如果您想在红色组件中存储某些内容,则应使用每个三元组中最重要的字节。

答案 1 :(得分:0)

这里,这将创建一个未压缩的位图。 经过一点修改,我已经创建并在SD卡上创建一个256x256 rgb图像,在arduino上有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);
}