我在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;
}
你知道什么是错的吗?
答案 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);
}