C++ 怎样把一个BITMAP中的数据读到一个数组里? 50
2个回答
展开全部
MFC 程序里用:
HBITMAP hBmp = CreateDIBitmap( dc.m_hDC,// handle to device context
&bmiHeader, // pointer to BITMAPINFOHEADER
CBM_INIT, // initialization flag
lpDIBBits, // pointer to initialization data
&bmInfo, // pointer to bitmap color-format data
DIB_RGB_COLORS); // color-data usage
bitmap.Attach( hBmp ); // 用这句,就把 BITMAP 读入了 CBitmap bitmap 对象里。
BITMAP 需要很多辅助信息,才能知道里面的数据的意义,所以用 CBitmap对象存放,便于使用。
我的实用程序:
/* =========================================================================*
* LoadBMPImage - Loads a BMP file and creates a bitmap GDI object
* also creates logical palette for it.
* Returns - TRUE for success (check success or not)
* sBMPFile - Full path of the BMP file, (input file name)
* bitmap - The bitmap object to initialize, (bring back img in it)
* pPal - Will hold the logical palette. Can be NULL (bring back)
*==========================================================================*/
BOOL CVPICDoc::LoadBMPImage(LPCTSTR sBMPFile, CBitmap &bitmap, CPalette *pPal)
{
BITMAPFILEHEADER bmfHeader;
// Read file header
CFile file;
if( !file.Open( sBMPFile, CFile::modeRead) ) return FALSE;
if (file.Read((LPSTR)&bmfHeader, sizeof(bmfHeader)) != sizeof(bmfHeader))
return FALSE;
// Check File type should be 'BM'
if (bmfHeader.bfType != ((WORD) ('M' << 8) | 'B'))
return FALSE;
read_bmp_o = bmfHeader.bfOffBits / 8;
// Get length of the remainder of the file and allocate memory
DWORD nPackedDIBLen = file.GetLength() - sizeof(BITMAPFILEHEADER);
HGLOBAL hDIB = ::GlobalAlloc(GMEM_FIXED, nPackedDIBLen);
if (hDIB == 0)
return FALSE;
// Read the remainder of the bitmap file.
// BITMAPINFOHEADER + possible-Color-Table + DIB-bits
if (file.ReadHuge((LPSTR)hDIB, nPackedDIBLen) != nPackedDIBLen )
{
::GlobalFree(hDIB);
return FALSE;
}
BITMAPINFOHEADER &bmiHeader = *(LPBITMAPINFOHEADER)hDIB ;
BITMAPINFO &bmInfo = *(LPBITMAPINFO)hDIB ;
read_bmp_w = bmiHeader.biWidth;
read_bmp_h = bmiHeader.biHeight;
read_bmp_c = bmiHeader.biBitCount;
read_bmp_size = bmiHeader.biSizeImage;
if (read_bmp_size == 0) {
read_bmp_size = ((((read_bmp_w * read_bmp_c) + 31) & ~31) >> 3) * read_bmp_h;
};
read_bmp_l = read_bmp_size / read_bmp_h; // scan line width
// If bmiHeader.biClrUsed is zero we have to infer the number
// of colors from the number of bits used to specify it.
int nColors = bmiHeader.biClrUsed ? bmiHeader.biClrUsed :
1 << bmiHeader.biBitCount;
LPVOID lpDIBBits;
if( bmInfo.bmiHeader.biBitCount > 8 )
lpDIBBits = (LPVOID)((LPDWORD)(bmInfo.bmiColors + bmInfo.bmiHeader.biClrUsed) +
((bmInfo.bmiHeader.biCompression == BI_BITFIELDS) ? 3 : 0));
else
lpDIBBits = (LPVOID)(bmInfo.bmiColors + nColors);
// Create the logical palette
if( pPal != NULL )
{
// Create the palette
if( nColors <= 256 )
{
UINT nSize = sizeof(LOGPALETTE) + (sizeof(PALETTEENTRY) * nColors);
LOGPALETTE *pLP = (LOGPALETTE *) new BYTE[nSize];
pLP->palVersion = 0x300;
pLP->palNumEntries = nColors;
for( int i=0; i < nColors; i++)
{
pLP->palPalEntry[i].peRed = bmInfo.bmiColors[i].rgbRed;
pLP->palPalEntry[i].peGreen = bmInfo.bmiColors[i].rgbGreen;
pLP->palPalEntry[i].peBlue = bmInfo.bmiColors[i].rgbBlue;
pLP->palPalEntry[i].peFlags = 0;
}
pPal->CreatePalette( pLP );
delete[] pLP;
}
}
CClientDC dc(NULL);
CPalette* pOldPalette = NULL;
if( pPal )
{
pOldPalette = dc.SelectPalette( pPal, FALSE );
dc.RealizePalette();
}
HBITMAP hBmp = CreateDIBitmap( dc.m_hDC,// handle to device context
&bmiHeader, // pointer to BITMAPINFOHEADER
CBM_INIT, // initialization flag
lpDIBBits, // pointer to initialization data
&bmInfo, // pointer to bitmap color-format data
DIB_RGB_COLORS); // color-data usage
bitmap.Attach( hBmp );
if( pOldPalette )
dc.SelectPalette( pOldPalette, FALSE );
::GlobalFree(hDIB);
return TRUE;
}
---------------
如果你喜欢 c 程序,喜欢把孤零零的点阵数据放入数组也可以。
这是完整的程序,读入1个 .bmp 文件,允许裁剪出其中的一部分。数据按行读入。buff 存一行数据,你修改一下,改成大数组,就可存放全部数据。但你仍需BITMAPINFO,BITMAPFILEHEADER等数据才有实用价值。完整的程序:
#include <windows.h>
#include <stdio.h>
#include <time.h>
#include <string.h>
#include <stdlib.h>
int DEBUG=0;
unsigned char *buff;
FILE *fin;
FILE *fout;
main(int argc, char *argv[] )
{
char namein[72], nameout[72];
int clip_x0, clip_y0, clip_x1, clip_y1;
int buff_len, buff_len2;
int height, width; /* input bmp */
int height2, width2; /* output bmp */
int color_depth;
int no_off = 0;
int i,j,k,jj;
int delta;
unsigned char *zero, *junk;
BITMAPFILEHEADER *bfh, *bfh2;
BITMAPINFOHEADER *bih, *bih2;
BITMAPINFO *binfo, *binfo2;
bfh = (BITMAPFILEHEADER *) malloc( sizeof(BITMAPFILEHEADER));
bih = (BITMAPINFOHEADER *) malloc( sizeof(BITMAPINFOHEADER));
binfo = (BITMAPINFO *) malloc( sizeof(BITMAPINFO));
bfh2 = (BITMAPFILEHEADER *) malloc( sizeof(BITMAPFILEHEADER));
bih2 = (BITMAPINFOHEADER *) malloc( sizeof(BITMAPINFOHEADER));
binfo2 = (BITMAPINFO *) malloc( sizeof(BITMAPINFO));
junk = (unsigned char *) malloc(sizeof(unsigned char));
zero = (unsigned char *) malloc(sizeof(unsigned char));
zero[0] = 0xff;
clip_x0 = 0; clip_x1 = 99;
clip_y0 = 0; clip_y1 = 99;
if (argc < 2) {
fprintf(stderr,"\007========================================================\n");
fprintf(stderr," Usage: %s -in namein -out nameout -x0 0 -x1 0 -y0 99 -y1 99\n", argv[0]);
fprintf(stderr,"========================================================\n");
exit(-1);
};
strcpy(namein,"BB120.bmp");
strcpy(nameout,"tmp.bmp");
for (i =1; i<argc-1;i++) {
if (strcmp("-in",argv[i]) == 0) strcpy (namein,argv[i+1]);
if (strcmp("-out",argv[i]) == 0) strcpy (nameout,argv[i+1]);
if (strcmp("-x0",argv[i]) == 0) sscanf (argv[i+1],"%d", &clip_x0);
if (strcmp("-x1",argv[i]) == 0) sscanf (argv[i+1],"%d", &clip_x1);
if (strcmp("-y0",argv[i]) == 0) sscanf (argv[i+1],"%d", &clip_y0);
if (strcmp("-y1",argv[i]) == 0) sscanf (argv[i+1],"%d", &clip_y1);
if (strcmp("-debug",argv[i]) == 0) sscanf (argv[i+1],"%d", &DEBUG);
if (strcmp("-no_off",argv[i]) == 0) sscanf (argv[i+1],"%d", &no_off);
} /* end for */
if ( (fin = fopen(namein,"rb" )) == NULL ) {
printf("Cann't open input file: %s\n",namein); exit(1);};
fread(bfh2, sizeof(BITMAPFILEHEADER),1,fin);
fread(binfo2, sizeof(BITMAPINFO),1,fin);
rewind(fin);
fread(bfh, sizeof(BITMAPFILEHEADER),1,fin);
fread(binfo, sizeof(BITMAPINFO),1,fin);
width = binfo->bmiHeader.biWidth;
height = binfo->bmiHeader.biHeight;
color_depth = binfo->bmiHeader.biBitCount;
buff_len = (width * (color_depth / 8 ) / 4 ) * 4;
if (buff_len < width * color_depth / 8 ) buff_len = buff_len + 4;
buff = (unsigned char *) malloc( (buff_len) * sizeof(unsigned char));
if (DEBUG == 1) {printf("buff length = %d\n", buff_len); };
if ( (fout = fopen(nameout,"wb" )) == NULL ) {
printf("Cann't open input file: %s\n",nameout); exit(1);};
/* consider 8 bit image only here */
if (clip_x0 < 0) clip_x0 = 0;
if (clip_x1 >= width ) clip_x1 = width - 1 ;
if (clip_y0 < 0) clip_y0 = 0;
if (clip_y1 >= height) clip_y1 = height - 1 ;
width2 = (clip_x1 - clip_x0) + 1;
height2 = (clip_y1 - clip_y0) + 1;
buff_len2 = (width2 * (color_depth / 8) / 4) * 4;
if (buff_len2 < width2 * (color_depth / 8) ) buff_len2 = buff_len2 + 4;
delta = buff_len2 - width2 * (color_depth / 8);
binfo2->bmiHeader.biWidth = width2;
binfo2->bmiHeader.biHeight = height2;
binfo2->bmiHeader.biSizeImage = width2 * height2;
bfh2->bfSize = sizeof(BITMAPFILEHEADER) + bfh->bfOffBits - sizeof(BITMAPINFO) + buff_len2 * height2 ;
fwrite(bfh2, sizeof(BITMAPFILEHEADER),1,fout);
fwrite(binfo2, sizeof(BITMAPINFO),1,fout);
j = bfh->bfOffBits - sizeof(BITMAPINFO);
if ( color_depth <=16 && no_off == 0)
{
if (j > 0 && j < bfh->bfSize)
{
for (i=0;i < bfh->bfOffBits ;i++){
fread(junk,sizeof(unsigned char), 1, fin);
fwrite(junk,sizeof(unsigned char), 1, fout);
}; };
};
j = (clip_x0) * (color_depth / 8);
k = (width2 )* (color_depth / 8);
jj = 0;
Lab_read: /* try goto instead of for */
fread( &buff[0], sizeof(unsigned char), buff_len, fin);
if (jj < clip_y0 || jj > clip_y1) goto skip;
fwrite(&buff[j],sizeof(unsigned char),k,fout);
if (delta !=0) {
for (i=0;i < delta; i++){
fwrite(&zero[0], sizeof(unsigned char),1, fout);
};
};
skip: jj = jj + 1;
if (jj < height) goto Lab_read;
fclose(fin);
fclose(fout);
printf("\007Output in %s\n",nameout);
}
HBITMAP hBmp = CreateDIBitmap( dc.m_hDC,// handle to device context
&bmiHeader, // pointer to BITMAPINFOHEADER
CBM_INIT, // initialization flag
lpDIBBits, // pointer to initialization data
&bmInfo, // pointer to bitmap color-format data
DIB_RGB_COLORS); // color-data usage
bitmap.Attach( hBmp ); // 用这句,就把 BITMAP 读入了 CBitmap bitmap 对象里。
BITMAP 需要很多辅助信息,才能知道里面的数据的意义,所以用 CBitmap对象存放,便于使用。
我的实用程序:
/* =========================================================================*
* LoadBMPImage - Loads a BMP file and creates a bitmap GDI object
* also creates logical palette for it.
* Returns - TRUE for success (check success or not)
* sBMPFile - Full path of the BMP file, (input file name)
* bitmap - The bitmap object to initialize, (bring back img in it)
* pPal - Will hold the logical palette. Can be NULL (bring back)
*==========================================================================*/
BOOL CVPICDoc::LoadBMPImage(LPCTSTR sBMPFile, CBitmap &bitmap, CPalette *pPal)
{
BITMAPFILEHEADER bmfHeader;
// Read file header
CFile file;
if( !file.Open( sBMPFile, CFile::modeRead) ) return FALSE;
if (file.Read((LPSTR)&bmfHeader, sizeof(bmfHeader)) != sizeof(bmfHeader))
return FALSE;
// Check File type should be 'BM'
if (bmfHeader.bfType != ((WORD) ('M' << 8) | 'B'))
return FALSE;
read_bmp_o = bmfHeader.bfOffBits / 8;
// Get length of the remainder of the file and allocate memory
DWORD nPackedDIBLen = file.GetLength() - sizeof(BITMAPFILEHEADER);
HGLOBAL hDIB = ::GlobalAlloc(GMEM_FIXED, nPackedDIBLen);
if (hDIB == 0)
return FALSE;
// Read the remainder of the bitmap file.
// BITMAPINFOHEADER + possible-Color-Table + DIB-bits
if (file.ReadHuge((LPSTR)hDIB, nPackedDIBLen) != nPackedDIBLen )
{
::GlobalFree(hDIB);
return FALSE;
}
BITMAPINFOHEADER &bmiHeader = *(LPBITMAPINFOHEADER)hDIB ;
BITMAPINFO &bmInfo = *(LPBITMAPINFO)hDIB ;
read_bmp_w = bmiHeader.biWidth;
read_bmp_h = bmiHeader.biHeight;
read_bmp_c = bmiHeader.biBitCount;
read_bmp_size = bmiHeader.biSizeImage;
if (read_bmp_size == 0) {
read_bmp_size = ((((read_bmp_w * read_bmp_c) + 31) & ~31) >> 3) * read_bmp_h;
};
read_bmp_l = read_bmp_size / read_bmp_h; // scan line width
// If bmiHeader.biClrUsed is zero we have to infer the number
// of colors from the number of bits used to specify it.
int nColors = bmiHeader.biClrUsed ? bmiHeader.biClrUsed :
1 << bmiHeader.biBitCount;
LPVOID lpDIBBits;
if( bmInfo.bmiHeader.biBitCount > 8 )
lpDIBBits = (LPVOID)((LPDWORD)(bmInfo.bmiColors + bmInfo.bmiHeader.biClrUsed) +
((bmInfo.bmiHeader.biCompression == BI_BITFIELDS) ? 3 : 0));
else
lpDIBBits = (LPVOID)(bmInfo.bmiColors + nColors);
// Create the logical palette
if( pPal != NULL )
{
// Create the palette
if( nColors <= 256 )
{
UINT nSize = sizeof(LOGPALETTE) + (sizeof(PALETTEENTRY) * nColors);
LOGPALETTE *pLP = (LOGPALETTE *) new BYTE[nSize];
pLP->palVersion = 0x300;
pLP->palNumEntries = nColors;
for( int i=0; i < nColors; i++)
{
pLP->palPalEntry[i].peRed = bmInfo.bmiColors[i].rgbRed;
pLP->palPalEntry[i].peGreen = bmInfo.bmiColors[i].rgbGreen;
pLP->palPalEntry[i].peBlue = bmInfo.bmiColors[i].rgbBlue;
pLP->palPalEntry[i].peFlags = 0;
}
pPal->CreatePalette( pLP );
delete[] pLP;
}
}
CClientDC dc(NULL);
CPalette* pOldPalette = NULL;
if( pPal )
{
pOldPalette = dc.SelectPalette( pPal, FALSE );
dc.RealizePalette();
}
HBITMAP hBmp = CreateDIBitmap( dc.m_hDC,// handle to device context
&bmiHeader, // pointer to BITMAPINFOHEADER
CBM_INIT, // initialization flag
lpDIBBits, // pointer to initialization data
&bmInfo, // pointer to bitmap color-format data
DIB_RGB_COLORS); // color-data usage
bitmap.Attach( hBmp );
if( pOldPalette )
dc.SelectPalette( pOldPalette, FALSE );
::GlobalFree(hDIB);
return TRUE;
}
---------------
如果你喜欢 c 程序,喜欢把孤零零的点阵数据放入数组也可以。
这是完整的程序,读入1个 .bmp 文件,允许裁剪出其中的一部分。数据按行读入。buff 存一行数据,你修改一下,改成大数组,就可存放全部数据。但你仍需BITMAPINFO,BITMAPFILEHEADER等数据才有实用价值。完整的程序:
#include <windows.h>
#include <stdio.h>
#include <time.h>
#include <string.h>
#include <stdlib.h>
int DEBUG=0;
unsigned char *buff;
FILE *fin;
FILE *fout;
main(int argc, char *argv[] )
{
char namein[72], nameout[72];
int clip_x0, clip_y0, clip_x1, clip_y1;
int buff_len, buff_len2;
int height, width; /* input bmp */
int height2, width2; /* output bmp */
int color_depth;
int no_off = 0;
int i,j,k,jj;
int delta;
unsigned char *zero, *junk;
BITMAPFILEHEADER *bfh, *bfh2;
BITMAPINFOHEADER *bih, *bih2;
BITMAPINFO *binfo, *binfo2;
bfh = (BITMAPFILEHEADER *) malloc( sizeof(BITMAPFILEHEADER));
bih = (BITMAPINFOHEADER *) malloc( sizeof(BITMAPINFOHEADER));
binfo = (BITMAPINFO *) malloc( sizeof(BITMAPINFO));
bfh2 = (BITMAPFILEHEADER *) malloc( sizeof(BITMAPFILEHEADER));
bih2 = (BITMAPINFOHEADER *) malloc( sizeof(BITMAPINFOHEADER));
binfo2 = (BITMAPINFO *) malloc( sizeof(BITMAPINFO));
junk = (unsigned char *) malloc(sizeof(unsigned char));
zero = (unsigned char *) malloc(sizeof(unsigned char));
zero[0] = 0xff;
clip_x0 = 0; clip_x1 = 99;
clip_y0 = 0; clip_y1 = 99;
if (argc < 2) {
fprintf(stderr,"\007========================================================\n");
fprintf(stderr," Usage: %s -in namein -out nameout -x0 0 -x1 0 -y0 99 -y1 99\n", argv[0]);
fprintf(stderr,"========================================================\n");
exit(-1);
};
strcpy(namein,"BB120.bmp");
strcpy(nameout,"tmp.bmp");
for (i =1; i<argc-1;i++) {
if (strcmp("-in",argv[i]) == 0) strcpy (namein,argv[i+1]);
if (strcmp("-out",argv[i]) == 0) strcpy (nameout,argv[i+1]);
if (strcmp("-x0",argv[i]) == 0) sscanf (argv[i+1],"%d", &clip_x0);
if (strcmp("-x1",argv[i]) == 0) sscanf (argv[i+1],"%d", &clip_x1);
if (strcmp("-y0",argv[i]) == 0) sscanf (argv[i+1],"%d", &clip_y0);
if (strcmp("-y1",argv[i]) == 0) sscanf (argv[i+1],"%d", &clip_y1);
if (strcmp("-debug",argv[i]) == 0) sscanf (argv[i+1],"%d", &DEBUG);
if (strcmp("-no_off",argv[i]) == 0) sscanf (argv[i+1],"%d", &no_off);
} /* end for */
if ( (fin = fopen(namein,"rb" )) == NULL ) {
printf("Cann't open input file: %s\n",namein); exit(1);};
fread(bfh2, sizeof(BITMAPFILEHEADER),1,fin);
fread(binfo2, sizeof(BITMAPINFO),1,fin);
rewind(fin);
fread(bfh, sizeof(BITMAPFILEHEADER),1,fin);
fread(binfo, sizeof(BITMAPINFO),1,fin);
width = binfo->bmiHeader.biWidth;
height = binfo->bmiHeader.biHeight;
color_depth = binfo->bmiHeader.biBitCount;
buff_len = (width * (color_depth / 8 ) / 4 ) * 4;
if (buff_len < width * color_depth / 8 ) buff_len = buff_len + 4;
buff = (unsigned char *) malloc( (buff_len) * sizeof(unsigned char));
if (DEBUG == 1) {printf("buff length = %d\n", buff_len); };
if ( (fout = fopen(nameout,"wb" )) == NULL ) {
printf("Cann't open input file: %s\n",nameout); exit(1);};
/* consider 8 bit image only here */
if (clip_x0 < 0) clip_x0 = 0;
if (clip_x1 >= width ) clip_x1 = width - 1 ;
if (clip_y0 < 0) clip_y0 = 0;
if (clip_y1 >= height) clip_y1 = height - 1 ;
width2 = (clip_x1 - clip_x0) + 1;
height2 = (clip_y1 - clip_y0) + 1;
buff_len2 = (width2 * (color_depth / 8) / 4) * 4;
if (buff_len2 < width2 * (color_depth / 8) ) buff_len2 = buff_len2 + 4;
delta = buff_len2 - width2 * (color_depth / 8);
binfo2->bmiHeader.biWidth = width2;
binfo2->bmiHeader.biHeight = height2;
binfo2->bmiHeader.biSizeImage = width2 * height2;
bfh2->bfSize = sizeof(BITMAPFILEHEADER) + bfh->bfOffBits - sizeof(BITMAPINFO) + buff_len2 * height2 ;
fwrite(bfh2, sizeof(BITMAPFILEHEADER),1,fout);
fwrite(binfo2, sizeof(BITMAPINFO),1,fout);
j = bfh->bfOffBits - sizeof(BITMAPINFO);
if ( color_depth <=16 && no_off == 0)
{
if (j > 0 && j < bfh->bfSize)
{
for (i=0;i < bfh->bfOffBits ;i++){
fread(junk,sizeof(unsigned char), 1, fin);
fwrite(junk,sizeof(unsigned char), 1, fout);
}; };
};
j = (clip_x0) * (color_depth / 8);
k = (width2 )* (color_depth / 8);
jj = 0;
Lab_read: /* try goto instead of for */
fread( &buff[0], sizeof(unsigned char), buff_len, fin);
if (jj < clip_y0 || jj > clip_y1) goto skip;
fwrite(&buff[j],sizeof(unsigned char),k,fout);
if (delta !=0) {
for (i=0;i < delta; i++){
fwrite(&zero[0], sizeof(unsigned char),1, fout);
};
};
skip: jj = jj + 1;
if (jj < height) goto Lab_read;
fclose(fin);
fclose(fout);
printf("\007Output in %s\n",nameout);
}
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询