在我的算法中,我需要创建信息输出。我必须在bmp文件中编写布尔矩阵。 它必须是单色图像,如果此元素上的矩阵为真,则像素为白色。 主要问题是bmp头和如何写这个。在没有其他库的情况下在纯C/C++中编写BMP图像
回答
没有使用任何其他库,你可以看看BMP file format。我已经在过去实现了它,并且可以在没有太多工作的情况下完成。
位图文件结构
每个位图文件含有 位图文件头,一个 位图信息头,颜色 表,并且字节的阵列 定义位图比特。该文件有 以下格式:
BITMAPFILEHEADER bmfh;
BITMAPINFOHEADER bmih;
RGBQUAD aColors [];
BYTE aBitmapBits [];
...查看文件格式的详细信息
谢谢。这似乎太好描述。 – 2010-04-16 16:21:29
如果你的处理器不是x86处理器,记得把所有东西都写出来。 – 2010-04-16 16:21:40
我有x86谢谢。 – 2010-04-16 16:25:39
注意,线由下往上,而不是周围的其他方式保存。
此外,扫描线必须具有四倍的字节长度的倍数,您应该在行的末尾插入填充字节以确保这一点。
我没有看到你写的东西。 – 2010-04-16 16:22:23
别担心,你会一旦实际尝试实现这一点。 – 2010-04-16 16:32:24
@Ben,因为大多数真实世界的图像已经是4倍的倍数,所以很容易错过测试中的四倍数要求。 – 2011-09-14 21:12:55
看看这是否适合你... 在这段代码中,我有3个二维数组,叫做红色,绿色和蓝色。每一个都是大小[宽度] [高度],每个元素对应一个像素 - 我希望这是有道理的!
FILE *f;
unsigned char *img = NULL;
int filesize = 54 + 3*w*h; //w is your image width, h is image height, both int
img = (unsigned char *)malloc(3*w*h);
memset(img,0,3*w*h);
for(int i=0; i<w; i++)
{
for(int j=0; j<h; j++)
{
x=i; y=(h-1)-j;
r = red[i][j]*255;
g = green[i][j]*255;
b = blue[i][j]*255;
if (r > 255) r=255;
if (g > 255) g=255;
if (b > 255) b=255;
img[(x+y*w)*3+2] = (unsigned char)(r);
img[(x+y*w)*3+1] = (unsigned char)(g);
img[(x+y*w)*3+0] = (unsigned char)(b);
}
}
unsigned char bmpfileheader[14] = {'B','M', 0,0,0,0, 0,0, 0,0, 54,0,0,0};
unsigned char bmpinfoheader[40] = {40,0,0,0, 0,0,0,0, 0,0,0,0, 1,0, 24,0};
unsigned char bmppad[3] = {0,0,0};
bmpfileheader[ 2] = (unsigned char)(filesize );
bmpfileheader[ 3] = (unsigned char)(filesize>> 8);
bmpfileheader[ 4] = (unsigned char)(filesize>>16);
bmpfileheader[ 5] = (unsigned char)(filesize>>24);
bmpinfoheader[ 4] = (unsigned char)( w );
bmpinfoheader[ 5] = (unsigned char)( w>> 8);
bmpinfoheader[ 6] = (unsigned char)( w>>16);
bmpinfoheader[ 7] = (unsigned char)( w>>24);
bmpinfoheader[ 8] = (unsigned char)( h );
bmpinfoheader[ 9] = (unsigned char)( h>> 8);
bmpinfoheader[10] = (unsigned char)( h>>16);
bmpinfoheader[11] = (unsigned char)( h>>24);
f = fopen("img.bmp","wb");
fwrite(bmpfileheader,1,14,f);
fwrite(bmpinfoheader,1,40,f);
for(int i=0; i<h; i++)
{
fwrite(img+(w*(h-i-1)*3),3,w,f);
fwrite(bmppad,1,(4-(w*3)%4)%4,f);
}
free(img);
fclose(f);
嗯,评论不会伤害。 – 2011-09-14 19:12:54
确实如此,但整个代码是自我解释的。它的工作原理。把它放在'main()'函数内部并初始化所有变量。并做了! ;) – sinner 2012-06-15 18:01:08
任何人都可以告诉代码中的'yres'吗? – 2013-01-17 13:25:04
这是一个适用于我的代码的C++变体。注意我必须改变大小计算来考虑行填充。
// mimeType = "image/bmp";
unsigned char file[14] = {
'B','M', // magic
0,0,0,0, // size in bytes
0,0, // app data
0,0, // app data
40+14,0,0,0 // start of data offset
};
unsigned char info[40] = {
40,0,0,0, // info hd size
0,0,0,0, // width
0,0,0,0, // heigth
1,0, // number color planes
24,0, // bits per pixel
0,0,0,0, // compression is none
0,0,0,0, // image bits size
0x13,0x0B,0,0, // horz resoluition in pixel/m
0x13,0x0B,0,0, // vert resolutions (0x03C3 = 96 dpi, 0x0B13 = 72 dpi)
0,0,0,0, // #colors in pallete
0,0,0,0, // #important colors
};
int w=waterfallWidth;
int h=waterfallHeight;
int padSize = (4-(w*3)%4)%4;
int sizeData = w*h*3 + h*padSize;
int sizeAll = sizeData + sizeof(file) + sizeof(info);
file[ 2] = (unsigned char)(sizeAll );
file[ 3] = (unsigned char)(sizeAll>> 8);
file[ 4] = (unsigned char)(sizeAll>>16);
file[ 5] = (unsigned char)(sizeAll>>24);
info[ 4] = (unsigned char)(w );
info[ 5] = (unsigned char)(w>> 8);
info[ 6] = (unsigned char)(w>>16);
info[ 7] = (unsigned char)(w>>24);
info[ 8] = (unsigned char)(h );
info[ 9] = (unsigned char)(h>> 8);
info[10] = (unsigned char)(h>>16);
info[11] = (unsigned char)(h>>24);
info[20] = (unsigned char)(sizeData );
info[21] = (unsigned char)(sizeData>> 8);
info[22] = (unsigned char)(sizeData>>16);
info[23] = (unsigned char)(sizeData>>24);
stream.write((char*)file, sizeof(file));
stream.write((char*)info, sizeof(info));
unsigned char pad[3] = {0,0,0};
for (int y=0; y<h; y++)
{
for (int x=0; x<w; x++)
{
long red = lround(255.0 * waterfall[x][y]);
if (red < 0) red=0;
if (red > 255) red=255;
long green = red;
long blue = red;
unsigned char pixel[3];
pixel[0] = blue;
pixel[1] = green;
pixel[2] = red;
stream.write((char*)pixel, 3);
}
stream.write((char*)pad, padSize);
}
如果使用上述C++函数在图像中间切换了奇怪的颜色,请务必以二进制模式打开流出: imgFile.open(filename, std::ios_base::out | std::ios_base::binary);
否则,Windows将不需要的字符插入文件中间! (撞了在这个问题上我的头几个小时)
参阅相关的问题在这里:Why does ofstream insert a 0x0D byte before 0x0A?
这是最好的低水平例如我知道,通过Evercat写的。从 https://en.wikipedia.org/wiki/User:Evercat/Buddhabrot.c
void drawbmp (char * filename) {
unsigned int headers[13];
FILE * outfile;
int extrabytes;
int paddedsize;
int x; int y; int n;
int red, green, blue;
extrabytes = 4 - ((WIDTH * 3) % 4); // How many bytes of padding to add to each
// horizontal line - the size of which must
// be a multiple of 4 bytes.
if (extrabytes == 4)
extrabytes = 0;
paddedsize = ((WIDTH * 3) + extrabytes) * HEIGHT;
// Headers...
// Note that the "BM" identifier in bytes 0 and 1 is NOT included in these "headers".
headers[0] = paddedsize + 54; // bfSize (whole file size)
headers[1] = 0; // bfReserved (both)
headers[2] = 54; // bfOffbits
headers[3] = 40; // biSize
headers[4] = WIDTH; // biWidth
headers[5] = HEIGHT; // biHeight
// Would have biPlanes and biBitCount in position 6, but they're shorts.
// It's easier to write them out separately (see below) than pretend
// they're a single int, especially with endian issues...
headers[7] = 0; // biCompression
headers[8] = paddedsize; // biSizeImage
headers[9] = 0; // biXPelsPerMeter
headers[10] = 0; // biYPelsPerMeter
headers[11] = 0; // biClrUsed
headers[12] = 0; // biClrImportant
outfile = fopen(filename, "wb");
//
// Headers begin...
// When printing ints and shorts, we write out 1 character at a time to avoid endian issues.
//
fprintf(outfile, "BM");
for (n = 0; n <= 5; n++)
{
fprintf(outfile, "%c", headers[n] & 0x000000FF);
fprintf(outfile, "%c", (headers[n] & 0x0000FF00) >> 8);
fprintf(outfile, "%c", (headers[n] & 0x00FF0000) >> 16);
fprintf(outfile, "%c", (headers[n] & (unsigned int) 0xFF000000) >> 24);
}
// These next 4 characters are for the biPlanes and biBitCount fields.
fprintf(outfile, "%c", 1);
fprintf(outfile, "%c", 0);
fprintf(outfile, "%c", 24);
fprintf(outfile, "%c", 0);
for (n = 7; n <= 12; n++)
{
fprintf(outfile, "%c", headers[n] & 0x000000FF);
fprintf(outfile, "%c", (headers[n] & 0x0000FF00) >> 8);
fprintf(outfile, "%c", (headers[n] & 0x00FF0000) >> 16);
fprintf(outfile, "%c", (headers[n] & (unsigned int) 0xFF000000) >> 24);
}
//
// Headers done, now write the data...
//
for (y = HEIGHT - 1; y >= 0; y--) // BMP image format is written from bottom to top...
{
for (x = 0; x <= WIDTH - 1; x++)
{
red = reduce(redcount[x][y] + COLOUR_OFFSET) * red_multiplier;
green = reduce(greencount[x][y] + COLOUR_OFFSET) * green_multiplier;
blue = reduce(bluecount[x][y] + COLOUR_OFFSET) * blue_multiplier;
if (red > 255) red = 255; if (red < 0) red = 0;
if (green > 255) green = 255; if (green < 0) green = 0;
if (blue > 255) blue = 255; if (blue < 0) blue = 0;
// Also, it's written in (b,g,r) format...
fprintf(outfile, "%c", blue);
fprintf(outfile, "%c", green);
fprintf(outfile, "%c", red);
}
if (extrabytes) // See above - BMP lines must be of lengths divisible by 4.
{
for (n = 1; n <= extrabytes; n++)
{
fprintf(outfile, "%c", 0);
}
}
}
fclose(outfile);
return;
}
drawbmp(filename);
只有链接回答不好,你应该提供一些关于答案的信息。 – 2015-08-15 17:48:02
@kevstev不要编辑,是一个可行的解决方案。如果你想适应这个程序在这个线程的新答案中发布一个新版本 – 2017-01-25 14:57:50
复制我主编拉尔夫的HTP代码,以便它会编译(海合会,运行Ubuntu 16.04 LTS)。这只是一个初始化变量的问题。
int w = 100; /* Put here what ever width you want */
int h = 100; /* Put here what ever height you want */
int red[w][h];
int green[w][h];
int blue[w][h];
FILE *f;
unsigned char *img = NULL;
int filesize = 54 + 3*w*h; //w is your image width, h is image height, both int
if(img)
free(img);
img = (unsigned char *)malloc(3*w*h);
memset(img,0,sizeof(img));
int x;
int y;
int r;
int g;
int b;
for(int i=0; i<w; i++)
{
for(int j=0; j<h; j++)
{
x=i; y=(h-1)-j;
r = red[i][j]*255;
g = green[i][j]*255;
b = blue[i][j]*255;
if (r > 255) r=255;
if (g > 255) g=255;
if (b > 255) b=255;
img[(x+y*w)*3+2] = (unsigned char)(r);
img[(x+y*w)*3+1] = (unsigned char)(g);
img[(x+y*w)*3+0] = (unsigned char)(b);
}
}
unsigned char bmpfileheader[14] = {'B','M', 0,0,0,0, 0,0, 0,0, 54,0,0,0};
unsigned char bmpinfoheader[40] = {40,0,0,0, 0,0,0,0, 0,0,0,0, 1,0, 24,0};
unsigned char bmppad[3] = {0,0,0};
bmpfileheader[ 2] = (unsigned char)(filesize );
bmpfileheader[ 3] = (unsigned char)(filesize>> 8);
bmpfileheader[ 4] = (unsigned char)(filesize>>16);
bmpfileheader[ 5] = (unsigned char)(filesize>>24);
bmpinfoheader[ 4] = (unsigned char)( w );
bmpinfoheader[ 5] = (unsigned char)( w>> 8);
bmpinfoheader[ 6] = (unsigned char)( w>>16);
bmpinfoheader[ 7] = (unsigned char)( w>>24);
bmpinfoheader[ 8] = (unsigned char)( h );
bmpinfoheader[ 9] = (unsigned char)( h>> 8);
bmpinfoheader[10] = (unsigned char)( h>>16);
bmpinfoheader[11] = (unsigned char)( h>>24);
f = fopen("img.bmp","wb");
fwrite(bmpfileheader,1,14,f);
fwrite(bmpinfoheader,1,40,f);
for(int i=0; i<h; i++)
{
fwrite(img+(w*(h-i-1)*3),3,w,f);
fwrite(bmppad,1,(4-(w*3)%4)%4,f);
}
fclose(f);
清洁C代码为位图(BMP)图像生成
生成图像:
的代码不使用其他任何库比stdio.h中。因此,代码可以很容易地与C系列的其他语言结合使用,如C++,C#,Java。
#include <stdio.h>
const int bytesPerPixel = 3; /// red, green, blue
const int fileHeaderSize = 14;
const int infoHeaderSize = 40;
void generateBitmapImage(unsigned char *image, int height, int width, char* imageFileName);
unsigned char* createBitmapFileHeader(int height, int width);
unsigned char* createBitmapInfoHeader(int height, int width);
int main(){
int height = 541;
int width = 800;
unsigned char image[height][width][bytesPerPixel];
char* imageFileName = "bitmapImage.bmp";
int i, j;
for(i=0; i<height; i++){
for(j=0; j<width; j++){
image[i][j][2] = (unsigned char)((double)i/height*255); ///red
image[i][j][1] = (unsigned char)((double)j/width*255); ///green
image[i][j][0] = (unsigned char)(((double)i+j)/(height+width)*255); ///blue
}
}
generateBitmapImage((unsigned char *)image, height, width, imageFileName);
}
void generateBitmapImage(unsigned char *image, int height, int width, char* imageFileName){
unsigned char* fileHeader = createBitmapFileHeader(height, width);
unsigned char* infoHeader = createBitmapInfoHeader(height, width);
unsigned char padding[3] = {0, 0, 0};
int paddingSize = (4-(width*bytesPerPixel)%4)%4;
FILE* imageFile = fopen(imageFileName, "wb");
fwrite(fileHeader, 1, fileHeaderSize, imageFile);
fwrite(infoHeader, 1, infoHeaderSize, imageFile);
int i;
for(i=0; i<height; i++){
fwrite(image+(i*width*bytesPerPixel), bytesPerPixel, width, imageFile);
fwrite(padding, 1, paddingSize, imageFile);
}
fclose(imageFile);
}
unsigned char* createBitmapFileHeader(int height, int width){
int fileSize = fileHeaderSize + infoHeaderSize + bytesPerPixel*height*width;
static unsigned char fileHeader[] = {
0,0, /// signature
0,0,0,0, /// image file size in bytes
0,0,0,0, /// reserved
0,0,0,0, /// start of pixel array
};
fileHeader[ 0] = (unsigned char)('B');
fileHeader[ 1] = (unsigned char)('M');
fileHeader[ 2] = (unsigned char)(fileSize );
fileHeader[ 3] = (unsigned char)(fileSize>> 8);
fileHeader[ 4] = (unsigned char)(fileSize>>16);
fileHeader[ 5] = (unsigned char)(fileSize>>24);
fileHeader[10] = (unsigned char)(fileHeaderSize + infoHeaderSize);
return fileHeader;
}
unsigned char* createBitmapInfoHeader(int height, int width){
static unsigned char infoHeader[] = {
0,0,0,0, /// header size
0,0,0,0, /// image width
0,0,0,0, /// image height
0,0, /// number of color planes
0,0, /// bits per pixel
0,0,0,0, /// compression
0,0,0,0, /// image size
0,0,0,0, /// horizontal resolution
0,0,0,0, /// vertical resolution
0,0,0,0, /// colors in color table
0,0,0,0, /// important color count
};
infoHeader[ 0] = (unsigned char)(infoHeaderSize);
infoHeader[ 4] = (unsigned char)(width );
infoHeader[ 5] = (unsigned char)(width>> 8);
infoHeader[ 6] = (unsigned char)(width>>16);
infoHeader[ 7] = (unsigned char)(width>>24);
infoHeader[ 8] = (unsigned char)(height );
infoHeader[ 9] = (unsigned char)(height>> 8);
infoHeader[10] = (unsigned char)(height>>16);
infoHeader[11] = (unsigned char)(height>>24);
infoHeader[12] = (unsigned char)(1);
infoHeader[14] = (unsigned char)(bytesPerPixel*8);
return infoHeader;
}
- 1. 如何在不阻碍其他情况下下载图像?
- 2. 在没有蒙版的情况下在PHP中裁剪图像
- 3. 在没有getImage()的情况下在Applet中加载图像?
- 4. 在没有UNION的情况下以其他形式重写SQL查询
- 5. 如何在没有js的情况下编写designMode ='on'
- 6. 在没有任何api的情况下在jquery上传图像
- 7. 在没有编译的情况下测试我的android库
- 8. 在Spark中,如何在没有RDD的情况下在Hadoop上编写文件?
- 9. 在没有UIScrollView的情况下调整图像的大小
- 10. 在没有OutOfMemoryError的情况下加载较大的图像
- 11. 在没有拉伸的情况下适合div内的图像
- 12. SAXParseException在一种情况下,但没有在其他情况下,当使用相同的XML
- 13. 如何在没有实际发送到cc的人的情况下在php
- 14. 如何在没有装饰的情况下显示图像
- 15. 如何在没有Bg图像的情况下滚动Unity ScrollView?
- 16. 在没有AWT的情况下使用Java加载图像
- 17. 在可可没有图像的情况下保存Webarchive
- 18. 如何在没有故事板的情况下旋转图像?
- 19. 如何在没有URL的情况下隐藏图像控件?
- 20. 如何在没有任何外部视图组件的情况下编写portlet
- 21. 在没有IDE的情况下在C++中手动编写Windows GUI
- 22. 如何在没有根文件夹的情况下在Laravel中编写路线
- 23. 有没有像Python的ctype for PHP的东西?在不需要编写扩展的情况下访问库?
- 24. 如何在没有图库的情况下使用ImageSwitcher
- 25. 在没有fenv.h的情况下在cygwin中编译redisql
- 26. 在没有ORM的情况下在Python中使用数据库
- 27. 如何在没有真正演员的情况下编写用例情景?
- 28. 在没有运行时库的情况下在Linux下编译C++
- 29. jQuery:预加载一组图像,但只有在没有其他加载的情况下
- 30. 在不显示其他图库功能的情况下在图库中显示图片
您可以检查http://qdbmp.sourceforge.net/实现细节:)。 – Marco 2013-12-10 14:28:26
也许用于访问者谷歌搜索类似的概念是我几乎相关的问题和答案在这里:http://stackoverflow.com/questions/17918978/plot-an-array-into-bitmap-in-cc-for-thermal-printer – 2013-12-28 08:46:27