C 在.bmp中隐藏文本
我用C语言编写了这个函数,将文本放入bmp图像中。我试着让它只改变红色中最不重要的像素。但是,当我打开编辑过的图像时,蓝色变了。数据来自“stb_image.c”库C 在.bmp中隐藏文本,c,bmp,steganography,C,Bmp,Steganography,我用C语言编写了这个函数,将文本放入bmp图像中。我试着让它只改变红色中最不重要的像素。但是,当我打开编辑过的图像时,蓝色变了。数据来自“stb_image.c”库 int-txt\u-bmp(字符*tekst,整数x,整数y,无符号字符*数据){ int i,j,k,l=0; 无符号字符t,p=0; 对于(i=0;i=(7-j); 如果(p==0) 数据[l]&=p; 数据[l]|=p; k*=2; l+=3; } } 返回0; } 你知道怎么回事吗?当使用双RGB模式(正常的未压缩D
int-txt\u-bmp(字符*tekst,整数x,整数y,无符号字符*数据){
int i,j,k,l=0;
无符号字符t,p=0;
对于(i=0;i>=(7-j);
如果(p==0)
数据[l]&=p;
数据[l]|=p;
k*=2;
l+=3;
}
}
返回0;
}
你知道怎么回事吗?当使用
双RGB
模式(正常的未压缩DIB)时,24位DIB中每个三元组的顺序将是蓝、绿、红
(即最低有效字节是蓝色分量)
通过使用BI_位字段
模式并根据您自己的偏好指定通道掩码,可以切换组件,但据我所知,BI_位字段
模式对24位DIB无效
因此,如果要在红色组件中存储某些内容,应使用每个三元组的最高有效字节。这里,这将创建一个未压缩的位图。 经过一点修改,我已经让它创建了一个256x256 rgb的图像并保存到SD卡上,该图像位于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);
}
//2008年9月22日
//晚上10:37
//Enhzflep
#包括//用于文件I/O
#包括
#ifndef字
#定义单词unsigned short
#恩迪夫
#伊夫德沃德
#定义DWORD无符号长
#恩迪夫
#ifndef字节
#定义字节无符号字符
#恩迪夫
#伊芬德夫朗
#定义长
#恩迪夫
#定义BI_RGB 0
#pragma包(推送,2)
typedef结构tagBITMAPFILEHEADER{
字型;
德沃德尺寸;
保留字1;
保留字2;
德沃德;
}BITMAPFILEHEADER,*LPBITMAPFILEHEADER,*PBITMAPFILEHEADER;
#布拉格语包(流行语)
typedef结构TagBitMapInfo标头{
德沃德·比西泽;
长双宽;
长双峰高度;
单词双平面;
单词双比特计数;
德沃德双压缩;
德沃德·比西泽迈格;
长双峰渗透计;
长双渗透计;
德沃德·比克尔鲁斯;
德沃德·比克勒;
}BitMapInfo头,*LPBitMapInfo头,*PBITMapInfo头;
typedef结构标记rgbquad{
字节rgbBlue;
字节rgbGreen;
字节RGR;
字节rgb;
}RGBQUAD,*LPRGBQUAD;
typedef结构tagBITMAPINFO{
位图信息头;
RGBguad颜色[1];
}BITMAPINFO、*LPBITMAPINFO、*PBITMAPINFO;
bool writeBmp24(整数宽度、整数高度、字符*文件名、字符*数据)
{
BITMAPINFO-myBmpInfo;
无符号长myInfoSize;
BITMAPFILEHEADER myBmpFileHeader;
文件*输出文件;
//不同的bmp文件类型使用不同的头
//这是一个24位位图
myInfoSize=sizeof(BitMapInfo标头);
//魔术签名
myBmpFileHeader.bfType=0x4D42;//“BM”
//保留数据-必须为零
myBmpFileHeader.bfReserved1=0;
myBmpFileHeader.bfserved2=0;
//偏移到像素数据的文件中
myBmpFileHeader.bfOffBits=sizeof(BITMAPFILEHEADER)+myInfoSize;
//总文件大小
myBmpFileHeader.bfSize=sizeof(BITMAPFILEHEADER)
+sizeof(BitMapInfo标头)
+myInfoSize
+宽*高*3;
//此标头的大小(字节)
myBmpInfo.bmiHeader.biSize=sizeof(myBmpInfo.bmiHeader);
//像素数据的大小(以字节为单位)
myBmpInfo.bmiHeader.biSizeImage=宽度*高度*3;
//图像尺寸
myBmpInfo.bmiHeader.biWidth=宽度;
myBmpInfo.bmiHeader.biHeight=高度;
//每米像素数(用于帮助为输出设备选择最佳图像)
myBmpInfo.bmiHeader.biXPelsPerMeter=2835;
myBmpInfo.bmiHeader.biYPelsPerMeter=2835;
//仅1像素平面。查找X模式(90年代早期了解更多关于平面概念的信息)
myBmpInfo.bmiHeader.biPlanes=1;
//每像素位数
myBmpInfo.bmiHeader.biBitCount=24;
//压缩型
myBmpInfo.bmiHeader.biCompression=BI_RGB;
//仅用于带有托盘的图像
myBmpInfo.bmiHeader.biClrImportant=0;
myBmpInfo.bmiHeader.biclrued=0;
如果(!(outputFile=fopen(文件名,“wb”))
返回false;
if(fwrite(&myBmpFileHeader,sizeof(BITMAPFILEHEADER),1,outputFile)!=1)
后藤博罗尔;
if(fwrite(&myBmpInfo,myInfoSize,1,outputFile)!=1)
后藤博罗尔;
if(写入(数据,3,宽度*高度,输出文件)!=宽度*高度)
后藤博罗尔;
if(fclose(outputFile))
返回false;
返回true;
bmperor:
fclose(输出文件);
返回false;
}
int main()
{
整数宽度=128;
整数高度=128;
字符*像素数据;//[96*96*3];///100x100像素*24位/像素
char*dest;//指向数据的指针
int x,y;//cur像素
字符曲线;
pixelData=(char*)calloc(3,宽度*高度);
dest=pixelData;//获取原始像素数据在mem中的位置
对于(y=0;yPerhaps,您假定页眉的大小错误?对于bmp图像,每行的长度是4的倍数(用空字节填充)。图像加载器的返回值是一个指向像素数据的“unsigned char*”。像素数据由*x像素的*y扫描线组成,每个像素由N个交错的8位组件组成;指向的第一个像素是图像中最左上角。图像扫描线之间或像素之间没有填充。我强制3个像素components…//包含N个组件的输出映像具有
// 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);
}