在这里,这将创建一个未压缩的位图。稍加修改后,我已经在 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);
}