bmp文件读取为矩阵

hackerxxw 2008-05-07 12:39:34
请问各位大哥有没有源代码

就是读取一个bmp文件,返回一个矩阵,矩阵里面包含了bmp文件的图像像素信息!

麻烦各位大哥,有代码的贴出来,急需!!
谢谢!!
...全文
446 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
hackerxxw 2008-05-08
  • 打赏
  • 举报
回复
能解释一下分割线下面的代码吗

Emboss_f(FILE *fpi, FILE *fpo) //fpi指向原文件,fpo为修改后的文件
{
int nCounti,nCountj,nCountk,nCountl;
int nRed,nBlue,nGreen;
int nDx=1,nDy=1;
unsigned int nPixel1,nPixel2,nPixel;
fread((char *)&strHead,1,sizeof(strHead),fpi);
fread((char *)&strInfo,1,sizeof(strInfo),fpi);
for(nCounti=0;nCounti<256;nCounti++)
fread((char *)&straPla[nCounti],1,sizeof(RGBQUAD),fpi);
fwrite((char *)&strHead,1,sizeof(strHead),fpo);
fwrite((char*)&strInfo,1,sizeof(strInfo),fpo);
for(nCounti=0;nCounti<256;nCounti++)
fwrite((char *)&straPla[nCounti],1,sizeof(RGBQUAD),fpo);
---------------------------------------------------------------------------------------
for(nCounti=0;nCounti<8;nCounti++)
{
for(nCountj=0;nCountj<64;nCountj++)
fread(&naImage[nCountj][0],1,nWidth,fpi);
for(nCountk=0;nCountk<64-1;nCountk++)
{
for(nCountl=0;nCountl<nWidth-1;nCountl++)
{
nPixel1=(unsigned char)(naImage[nCountk][nCountl]);
nPixel2=(unsigned char)(naImage[nCountk+nDx][nCountl+nDy]);
nRed=fabs(straPla[nPixel1].rgbRed-straPla[nPixel2].rgbRed+128);
nGreen=fabs(straPla[nPixel1].rgbGreen-straPla[nPixel2].rgbGreen+128);
nBlue=fabs(straPla[nPixel1].rgbBlue-straPla[nPixel2].rgbBlue+128);
nPixel=Match_f(nRed,nGreen,nBlue);
naImage[nCountk][nCountl]=nPixel;
}
}
for(nCountl=0;nCountl<nWidth-1;nCountl++)
{
nPixel1=(unsigned char)(naImage[63][nCountl]);
nPixel2=(unsigned char)(naImage[63][nCountl+nDy]);
nRed=fabs(straPla[nPixel1].rgbRed-straPla[nPixel2].rgbRed+128);
nGreen=fabs(straPla[nPixel1].rgbGreen-straPla[nPixel2].rgbGreen+128);
nBlue=fabs(straPla[nPixel1].rgbBlue-straPla[nPixel2].rgbBlue+128);
nPixel=Match_f(nRed,nGreen,nBlue);
naImage[63][nCountl]=nPixel;
}
for(nCountj=0;nCountj<64;nCountj++)
fwrite(&naImage[nCountj][0],1,nWidth,fpo);
}
}


hackerxxw 2008-05-08
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 baihacker 的回复:]
C/C++ code file.read(( char*)&fileheader, sizeof(fileheader));
file.read(( char*)&infoheader, sizeof(infoheader));


真正对你有用的就这两行,这两行足矣
[/Quote]

不错
我也觉得 其实真正的就是操作内存,文件,二进制

但是会得到乱码!
不知道怎么回事??
内核中的洋葱 2008-05-08
  • 打赏
  • 举报
回复
/*
This function writes out a 24-bit Windows bitmap file that is readable by Microsoft Paint.
The image data is a 1D array of (r, g, b) triples, where individual (r, g, b) values can
each take on values between 0 and 255, inclusive.

The input to the function is:
char *filename: A string representing the filename that will be written
uint32 width: The width, in pixels, of the bitmap
uint32 height: The height, in pixels, of the bitmap
unsigned char *image: The image data, where each pixel is 3 unsigned chars (r, g, b)

Written by Greg Slabaugh (slabaugh@ece.gatech.edu), 10/19/00
*/
uint32 write24BitBmpFile(char *filename, uint32 width, uint32 height, unsigned char *image)
{
BITMAPINFOHEADER bmpInfoHeader;
BITMAPFILEHEADER bmpFileHeader;
FILE *filep;
uint32 row, column;
uint32 extrabytes, bytesize;
unsigned char *paddedImage = NULL, *paddedImagePtr, *imagePtr;

extrabytes = (4 - (width * 3) % 4) % 4;

/* This is the size of the padded bitmap */
bytesize = (width * 3 + extrabytes) * height;

/* Fill the bitmap file header structure */
bmpFileHeader.bfType = setUint16(BM); /* Bitmap header */
bmpFileHeader.bfSize = setUint32(0); /* This can be 0 for BI_RGB bitmaps */
bmpFileHeader.bfReserved1 = setUint16(0);
bmpFileHeader.bfReserved2 = setUint16(0);
bmpFileHeader.bfOffBits = setUint32(sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER));

/* Fill the bitmap info structure */
bmpInfoHeader.biSize = setUint32(sizeof(BITMAPINFOHEADER));
bmpInfoHeader.biWidth = setUint32(width);
bmpInfoHeader.biHeight = setUint32(height);
bmpInfoHeader.biPlanes = setUint16(1);
bmpInfoHeader.biBitCount = setUint16(24); /* 24 - bit bitmap */
bmpInfoHeader.biCompression = setUint32(BI_RGB);
bmpInfoHeader.biSizeImage = setUint32(bytesize); /* includes padding for 4 byte alignment */
bmpInfoHeader.biXPelsPerMeter = setUint32(0);
bmpInfoHeader.biYPelsPerMeter = setUint32(0);
bmpInfoHeader.biClrUsed = setUint32(0);
bmpInfoHeader.biClrImportant = setUint32(0);


/* Open file */
if ((filep = fopen(filename, "wb")) == NULL) {
printf("Error opening file %s\n", filename);
return BMP_FALSE;
}

/* Write bmp file header */
if (fwrite(&bmpFileHeader, 1, sizeof(BITMAPFILEHEADER), filep) < sizeof(BITMAPFILEHEADER)) {
printf("Error writing bitmap file header\n");
fclose(filep);
return BMP_FALSE;
}

/* Write bmp info header */
if (fwrite(&bmpInfoHeader, 1, sizeof(BITMAPINFOHEADER), filep) < sizeof(BITMAPINFOHEADER)) {
printf("Error writing bitmap info header\n");
fclose(filep);
return BMP_FALSE;
}


/* Allocate memory for some temporary storage */
paddedImage = (unsigned char *)calloc(sizeof(unsigned char), bytesize);
if (paddedImage == NULL) {
printf("Error allocating memory \n");
fclose(filep);
return BMP_FALSE;
}

/* This code does three things. First, it flips the image data upside down, as the .bmp
format requires an upside down image. Second, it pads the image data with extrabytes
number of bytes so that the width in bytes of the image data that is written to the
file is a multiple of 4. Finally, it swaps (r, g, b) for (b, g, r). This is another
quirk of the .bmp file format. */

for (row = 0; row < height; row++) {
imagePtr = image + (height - 1 - row) * width * 3;
paddedImagePtr = paddedImage + row * (width * 3 + extrabytes);
for (column = 0; column < width; column++) {
*paddedImagePtr = *(imagePtr + 2);
*(paddedImagePtr + 1) = *(imagePtr + 1);
*(paddedImagePtr + 2) = *imagePtr;
imagePtr += 3;
paddedImagePtr += 3;
}
}

/* Write bmp data */
if (fwrite(paddedImage, 1, bytesize, filep) < bytesize) {
printf("Error writing bitmap data\n");
free(paddedImage);
fclose(filep);
return BMP_FALSE;
}

/* Close file */
fclose(filep);
free(paddedImage);
return BMP_TRUE;
}


/*
This function writes out a grayscale image as a 8-bit Windows bitmap file that is readable by Microsoft Paint.
It creates a palette and then calls write8BitBmpFile to output the bitmap file.

The input to the function is:
char *filename: A string representing the filename that will be written
uint32 width: The width, in pixels, of the bitmap
uint32 height: The height, in pixels, of the bitmap
unsigned char *image: The image data, where the value indicates a color between 0 (black) and 255 (white)

Written by Greg Slabaugh (slabaugh@ece.gatech.edu), 10/19/00
*/
uint32 writeGrayScaleDataToBmpFile(char *filename, uint32 width, uint32 height, unsigned char *image)
{
RGBQUAD palette[256];
uint32 i;
uint32 numPaletteEntries = 256;

/* Create the palette - each pixel is an index into the palette */
for (i = 0; i < numPaletteEntries; i++) {
palette[i].rgbRed = i;
palette[i].rgbGreen = i;
palette[i].rgbBlue = i;
palette[i].rgbReserved = 0;
}

return write8BitBmpFile(filename, width, height, image, numPaletteEntries, palette);

}


#define imageWidth 7
#define imageHeight 7
#define DEBUG 2
int main()
{

unsigned char imageData8Bit[imageWidth * imageHeight];
unsigned char imageData24Bit[imageWidth * imageHeight * 3];
RGBQUAD palette[4];
uint32 i;


if (DEBUG == 0) {
printf("Testing grayscale code\n");
for (i = 0; i < imageWidth * imageHeight; i++)
imageData8Bit[i] = 0;

imageData8Bit[0] = 255;
imageData8Bit[1] = 100;
imageData8Bit[imageWidth] = 100;
imageData8Bit[imageWidth * imageHeight - 1] = 255;
writeGrayScaleDataToBmpFile("test0.bmp", imageWidth, imageHeight, imageData8Bit);

} else if (DEBUG == 1) {
printf("Testing 8-bit code\n");

palette[0].rgbRed = 0;
palette[0].rgbGreen = 0;
palette[0].rgbBlue = 0;
palette[0].rgbReserved = 0;

palette[1].rgbRed = 255;
palette[1].rgbGreen = 0;
palette[1].rgbBlue = 0;
palette[1].rgbReserved = 0;

palette[2].rgbRed = 0;
palette[2].rgbGreen = 255;
palette[2].rgbBlue = 0;
palette[2].rgbReserved = 0;

palette[3].rgbRed = 0;
palette[3].rgbGreen = 0;
palette[3].rgbBlue = 255;
palette[3].rgbReserved = 0;

for (i = 0; i < imageWidth * imageHeight; i++)
imageData8Bit[i] = 0;

imageData8Bit[0] = 1;
imageData8Bit[1] = 2;
imageData8Bit[imageWidth] = 3;
imageData8Bit[imageWidth * imageHeight - 1] = 1;

write8BitBmpFile("test1.bmp", imageWidth, imageHeight, imageData8Bit, 4, palette);

} else {
printf("Testing 24-bit code\n");

for (i = 0; i < imageWidth * imageHeight * 3; i++)
imageData24Bit[i] = 0;

imageData24Bit[0] = 255;
imageData24Bit[4] = 255;
imageData24Bit[imageWidth * 3 + 2] = 255;
imageData24Bit[imageWidth * imageHeight * 3 - 3] = 255;

write24BitBmpFile("test2.bmp", imageWidth, imageHeight, imageData24Bit);

}

return BMP_TRUE;
}
内核中的洋葱 2008-05-08
  • 打赏
  • 举报
回复
以前涉及到bmp,当时从网上down了一个源代码。挺好的。
具体网址忘记了。但代码还有。贴出来。
/* This is a Unix port of the bitmap.c code that writes .bmp files to disk.
It also runs on Win32, and should be easy to get to run on other platforms.
Please visit my web page, http://www.ece.gatech.edu/~slabaugh and click on
"c" and "Writing Windows Bitmaps" for a further explanation. This code
has been tested and works on HP-UX 11.00 using the cc compiler. To compile,
just type "cc -Ae bitmapUnix.c" at the command prompt.

If your system is big endian (HP-UX 11.00 is big endian), set the define
below to 1. If it is little endian, set it to 0. The Windows .bmp format
is little endian, so if you're running this code on a big endian system
it will be necessary to swap bytes to write out a little endian file.

Thanks to Robin Pitrat for testing on the Linux platform.

Greg Slabaugh, 11/05/01
*/
#define BMP_BIG_ENDIAN 1


#include <stdio.h>
#include <stdlib.h>
#include <memory.h>

/* This pragma is necessary so that the data in the structures is aligned to 2-byte
boundaries. Some different compilers have a different syntax for this line. For
example, if you're using cc on Solaris, the line should be #pragma pack(2).
*/
#pragma pack 2


/* Default data types. Here, uint16 is an unsigned integer that has size 2 bytes (16 bits),
and uint32 is datatype that has size 4 bytes (32 bits). You may need to change these
depending on your compiler. */
#define uint16 unsigned short
#define uint32 unsigned int

#define BI_RGB 0
#define BM 19778
#define BMP_FALSE 0
#define BMP_TRUE 1

typedef struct {
uint16 bfType;
uint32 bfSize;
uint16 bfReserved1;
uint16 bfReserved2;
uint32 bfOffBits;
} BITMAPFILEHEADER;

typedef struct {
uint32 biSize;
uint32 biWidth;
uint32 biHeight;
uint16 biPlanes;
uint16 biBitCount;
uint32 biCompression;
uint32 biSizeImage;
uint32 biXPelsPerMeter;
uint32 biYPelsPerMeter;
uint32 biClrUsed;
uint32 biClrImportant;
} BITMAPINFOHEADER;


typedef struct {
unsigned char rgbBlue;
unsigned char rgbGreen;
unsigned char rgbRed;
unsigned char rgbReserved;
} RGBQUAD;


/* This function is for byte swapping on big endian systems */
uint16 setUint16(uint16 x)
{
if (BMP_BIG_ENDIAN)
return (x & 0x00FF) << 8 | (x & 0xFF00) >> 8;
else
return x;
}

/* This function is for byte swapping on big endian systems */
uint32 setUint32(uint32 x)
{
if (BMP_BIG_ENDIAN)
return (x & 0x000000FF) << 24 | (x & 0x0000FF00) << 8 | (x & 0x00FF0000) >> 8 | (x & 0xFF000000) >> 24;
else
return x;
}

/*
This function writes out an 8-bit Windows bitmap file that is readable by Microsoft Paint.
The image has an arbitrary palette, consisting of up to 256 unique colors. The image data
consists of values that index into the palette.

The input to the function is:
char *filename: A string representing the filename that will be written
uint32 width: The width, in pixels, of the bitmap
uint32 height: The height, in pixels, of the bitmap
unsigned char *image: The image data, where the value indicates an index into the palette
uint32 numPaletteEntries The number of entries used in the palette
RGBQUAD *palette: The palette

Written by Greg Slabaugh (slabaugh@ece.gatech.edu), 10/19/00
*/
uint32 write8BitBmpFile(char *filename, uint32 width, uint32 height, unsigned char *image, uint32 numPaletteEntries, RGBQUAD *palette)
{
BITMAPINFOHEADER bmpInfoHeader;
BITMAPFILEHEADER bmpFileHeader;
FILE *filep;
uint32 row;
uint32 extrabytes, bytesize;
unsigned char *paddedImage = NULL;

/* The .bmp format requires that the image data is aligned on a 4 byte boundary. For 8 - bit bitmaps,
this means that the width of the bitmap must be a multiple of 4. This code determines
the extra padding needed to meet this requirement. */
extrabytes = (4 - width % 4) % 4;

/* This is the size of the padded bitmap */
bytesize = (width + extrabytes) * height;

/* Fill the bitmap file header structure */
bmpFileHeader.bfType = setUint16(BM); /* Bitmap header */
bmpFileHeader.bfSize = setUint32(0); /* This can be 0 for BI_RGB bitmaps */
bmpFileHeader.bfReserved1 = setUint16(0);
bmpFileHeader.bfReserved2 = setUint16(0);
bmpFileHeader.bfOffBits = setUint32(sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * numPaletteEntries);

/* Fill the bitmap info structure */
bmpInfoHeader.biSize = setUint32(sizeof(BITMAPINFOHEADER));
bmpInfoHeader.biWidth = setUint32(width);
bmpInfoHeader.biHeight = setUint32(height);
bmpInfoHeader.biPlanes = setUint16(1);
bmpInfoHeader.biBitCount = setUint16(8); /* 8 - bit bitmap */
bmpInfoHeader.biCompression = setUint32(BI_RGB);
bmpInfoHeader.biSizeImage = setUint32(bytesize); /* includes padding for 4 byte alignment */
bmpInfoHeader.biXPelsPerMeter = setUint32(0);
bmpInfoHeader.biYPelsPerMeter = setUint32(0);
bmpInfoHeader.biClrUsed = setUint32(numPaletteEntries);
bmpInfoHeader.biClrImportant = setUint32(0);


/* Open file */
if ((filep = fopen(filename, "wb")) == NULL) {
printf("Error opening file %s\n", filename);
return BMP_FALSE;
}

/* Write bmp file header */
if (fwrite(&bmpFileHeader, 1, sizeof(BITMAPFILEHEADER), filep) < sizeof(BITMAPFILEHEADER)) {
printf("Error writing bitmap file header\n");
fclose(filep);
return BMP_FALSE;
}

/* Write bmp info header */
if (fwrite(&bmpInfoHeader, 1, sizeof(BITMAPINFOHEADER), filep) < sizeof(BITMAPINFOHEADER)) {
printf("Error writing bitmap info header\n");
fclose(filep);
return BMP_FALSE;
}

/* Write bmp palette */
if (fwrite(palette, 1, numPaletteEntries * sizeof(RGBQUAD), filep) < numPaletteEntries * sizeof(RGBQUAD)) {
printf("Error writing bitmap palette\n");
fclose(filep);
return BMP_FALSE;
}

/* Allocate memory for some temporary storage */
paddedImage = (unsigned char *)calloc(sizeof(unsigned char), bytesize);
if (paddedImage == NULL) {
printf("Error allocating memory \n");
fclose(filep);
return BMP_FALSE;
}

/* Flip image - bmp format is upside down. Also pad the paddedImage array so that the number
of pixels is aligned on a 4 byte boundary. */
for (row = 0; row < height; row++)
memcpy(&paddedImage[row * (width + extrabytes)], &image[(height - 1 - row) * width], width);

/* Write bmp data */
if (fwrite(paddedImage, 1, bytesize, filep) < bytesize) {
printf("Error writing bitmap data\n");
free(paddedImage);
fclose(filep);
return BMP_FALSE;
}

/* Close file */
fclose(filep);
free(paddedImage);
return BMP_TRUE;
}

baihacker 2008-05-08
  • 打赏
  • 举报
回复
    file.read(( char*)&fileheader, sizeof(fileheader));
file.read(( char*)&infoheader, sizeof(infoheader));

真正对你有用的就这两行,这两行足矣
hackerxxw 2008-05-08
  • 打赏
  • 举报
回复
有其他的代码吗?
hackerxxw 2008-05-08
  • 打赏
  • 举报
回复

Emboss_f(FILE *fpi, FILE *fpo) //fpi指向原文件,fpo为修改后的文件
{
int nCounti,nCountj,nCountk,nCountl;
int nRed,nBlue,nGreen;
int nDx=1,nDy=1;
unsigned int nPixel1,nPixel2,nPixel;
fread((char *)&strHead,1,sizeof(strHead),fpi);
fread((char *)&strInfo,1,sizeof(strInfo),fpi);
for(nCounti=0;nCounti<256;nCounti++)
{
fread((char *)&straPla[nCounti],1,sizeof(RGBQUAD),fpi);
}
//到了这里应该是接触到了fpi文件中的像素数据吧 怎么取呢???

hebin1985 2008-05-07
  • 打赏
  • 举报
回复
你可以自己解码,其实BMP的解码挺简单的.先从文件头读出有关的信息,结构大致如下:

typedef struct { // bmfh
u32 bfSize;
u16 bfReserved1;
u16 bfReserved2;
u32 bfOffBits;
} BITMAPFILEHEADER;

typedef struct { // bmih
u32 biSize;
s32 biWidth;
s32 biHeight;
u16 biPlanes;
u16 biBitCount;
u32 biCompression;
u32 biSizeImage;
s32 biXPelsPerMeter;
s32 biYPelsPerMeter;
u32 biClrUsed;
u32 biClrImportant;
} BITMAPINFOHEADER;
至于每一个数据项都是什么意思,你可以到MSDN上去查.然后后面的可能就是颜色表或者颜色数据了,根据上面的两个结构体可以得到他们的大小.至于读文件中的数据楼主可以自己做了.
独孤过儿 2008-05-07
  • 打赏
  • 举报
回复
毕业设计吧...

去google吧...
con_con 2008-05-07
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 baihacker 的回复:]
C/C++ code#include <iostream>
#include <fstream>
#include "windows.h"
using namespace std;

UINT width;
UINT height;
UINT size;
unsigned short bitcount;
fstream file;

char* data;

void draw()
{

int i = 0,j = 0;
while(i<width*height) data[i++] = char(255);//白色

int x1 = 100, y1 = 100, x2 = 200, y2 = 200;
int x3 = 125, y3 = 125, x4 = 175, y4 = 175;


[/Quote]
hackerxxw 2008-05-07
  • 打赏
  • 举报
回复
代码还不错!
谢谢
baihacker 2008-05-07
  • 打赏
  • 举报
回复
#include <iostream>
#include <fstream>
#include "windows.h"
using namespace std;

UINT width;
UINT height;
UINT size;
unsigned short bitcount;
fstream file;

char* data;

void draw()
{

int i = 0,j = 0;
while(i<width*height) data[i++] = char(255);//白色

int x1 = 100, y1 = 100, x2 = 200, y2 = 200;
int x3 = 125, y3 = 125, x4 = 175, y4 = 175;

for (i=0;i<width;i++)
{
for (j=0;j<width;j++)
{
if ( j>=x1 && j<=x2 && ( (i>=y1&&i<y3) || (i>y4&& i<=y2) ) )
data[i*width+j] = char(0);
else
if ( i>=y3 && i<=y4 && ( (j>=x1&&j<x3) ||(j>x4&&j<=x2) ) )
data[i*width+j] = char(0);
}
}
}

void main()
{
BITMAPFILEHEADER fileheader;
BITMAPINFOHEADER infoheader;
char filename[255];
cout<<"请输入文件名:"<<endl;
cin>>filename;

file.open(filename, ios::out | ios::in | ios::binary);
if (!file)
{
MessageBox(NULL,"文件打开失败!","警告",0);
return;
}

file.read(( char*)&fileheader, sizeof(fileheader));
file.read(( char*)&infoheader, sizeof(infoheader));

size = fileheader.bfSize;
width = infoheader.biWidth;
if (width%4)
width = width/4*4+4;//储存宽度和实际宽度不一样,修正
height = infoheader.biHeight;

if ((bitcount=infoheader.biBitCount) != 8)
{
MessageBox(NULL,"不支持的位图!","警告",0);
file.close();
return;
}
// char t;
// file.seekg(fileheader.bfOffBits,ios::beg);
// for (int i=0;i<40*width;i++)
// {
// file.read(&t,1);
// cout<<int(t);
// if(!( (i+1)%width)) cout<<endl;
// }

data = new char[width*height];
draw();

file.seekp(fileheader.bfOffBits,ios::beg);
file.write(data, width*height);
file.close();

delete [] data;
}
hackerxxw 2008-05-07
  • 打赏
  • 举报
回复
还有更详细的教程吗?
hackerxxw 2008-05-07
  • 打赏
  • 举报
回复
谢谢支持!
星羽 2008-05-07
  • 打赏
  • 举报
回复
hackerxxw 2008-05-07
  • 打赏
  • 举报
回复
谢谢了

当然如果有完整的代码更好啊

应为这个模块不是我做的,我做的仅仅只是或的矩阵类的处理,

所以如果有完整的程序,我就可以直接调用了

64,639

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧