一个图片问题,呵呵,初学。

djjlove_2008 2010-09-19 10:20:40
刚接触图片,如何把我在“D:\\1.BMP",这个图片的RGB读出来,并存入一个数组中输出。求一代码,C/C++/MFC和API写均可。
...全文
82 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
npuhuxl 2010-09-19
  • 打赏
  • 举报
回复
用MFC的话,用CImage最简单了
djjlove_2008 2010-09-19
  • 打赏
  • 举报
回复
有用MFC的,windows界面的不?
npuhuxl 2010-09-19
  • 打赏
  • 举报
回复

#define IMG_REVERSE

class BMPFile
{
public:
static bool SaveBMP(unsigned char* pBits, int width, int height, int channel, const char *fileName)
{
using std::ifstream;
using std::ofstream;

if(width <= 0 || height <= 0 || NULL == pBits)
return false;
ofstream out(fileName, std::ios::binary);
if(!out) return false;
BITMAPFILEHEADER bfh;
BITMAPINFOHEADER bih;
RGBQUAD quad[256];
DWORD dwPaletteSize = 0;

memset(&bfh, 0, sizeof(bfh));
memset(&bih, 0, sizeof(bih));

if(channel == 1)
{

for(int i = 0; i < 256; ++ i)
{
quad[i].rgbRed = (BYTE)i;
quad[i].rgbGreen = (BYTE)i;
quad[i].rgbBlue = (BYTE)i;
quad[i].rgbReserved = 0;
}
dwPaletteSize = sizeof(quad);
}

bfh.bfType = 0x4D42; // bmp file
bfh.bfOffBits = sizeof(bfh) + sizeof(bih) + dwPaletteSize;

WORD wBitCount = channel * 8;

bih.biSize = sizeof(BITMAPINFOHEADER);
bih.biWidth = width;
bih.biHeight = height;
bih.biPlanes = 1;
bih.biBitCount = wBitCount;

int rowWidth = ((int)(width * wBitCount + 31) >> 5) << 2;
DWORD dwBmBitsSize = DWORD(rowWidth * height);

bfh.bfSize = bfh.bfOffBits + dwBmBitsSize;

int nBytes = width * channel;
int nAdd = rowWidth - nBytes;
std::auto_ptr<char> buf;
if(nAdd)
{
buf.reset(new char[nAdd]);
memset(buf.get(), 0, nAdd);
}

out.write((const char *)&bfh, sizeof(bfh));
out.write((const char *)&bih, sizeof(bih));
if(dwPaletteSize)
out.write((const char *)quad, sizeof(quad));
#ifndef IMG_REVERSE
for(int i = 0; i < height; ++ i)
#else
for(int i = height - 1; i >= 0; -- i)
#endif
{
unsigned char* ptr = pBits + i * nBytes;
out.write((const char *)ptr, nBytes);
if(nAdd)
{
out.write(buf.get(), nAdd);
}
}
out.close();
return true;
}

static bool loadBMP(unsigned char*&pBits, int&width, int&height, const char* fileName)
{
using std::ifstream;
using std::ofstream;
ifstream in(fileName, std::ios::binary);
if(!in) return false;
BITMAPFILEHEADER bfh;
BITMAPINFOHEADER bih;
RGBQUAD quad[256];
DWORD dwPaletteSize = 0;

typedef char* bufType;

in.read((bufType)&bfh, sizeof(bfh));
in.seekg(0, std::ios::end);
if(bfh.bfType != 0x4D42 || bfh.bfSize != in.tellg())
{
in.close();
return false;
}


in.clear();
in.seekg(sizeof(bfh), std::ios_base::beg);
in.read((bufType)&bih, sizeof(bih));
width = bih.biWidth;
height = bih.biHeight;

std::auto_ptr<unsigned char> buf;
DWORD img_size;
if(bih.biSizeImage != 0)
img_size = bih.biSizeImage;
else
{
img_size = bfh.bfSize - bfh.bfOffBits;
}

unsigned char *ptr;
buf.reset(ptr = new unsigned char[(int)img_size+10]);
if(NULL == ptr)
{
in.close();
return false;
}

in.seekg(bfh.bfOffBits, std::ios_base::beg);
in.read((bufType)ptr, img_size);

DWORD nSrcWidth = ((int)(width * bih.biBitCount + 31) >> 5) << 2;
DWORD nSize = width * height * 3;
DWORD nDestWidth;
DWORD nAddSize;

unsigned char *ptrDest;
unsigned char *ptrSrc;
size_t index;

switch(bih.biBitCount)
{
case 4:
in.seekg(bfh.bfOffBits - sizeof(RGBQUAD) * 16, std::ios_base::beg);// read palette information
in.read((bufType)quad, sizeof(RGBQUAD) * 16);

try
{
pBits = new unsigned char[nSize];
}
catch(...)
{
in.close();
return false;
}
ptrDest = pBits;
ptrSrc = buf.get();
index = 0;
nDestWidth = width * 3;
nAddSize = nSrcWidth - (width+1)/2;
#ifndef IMG_REVERSE
for(int y = 0; y < height; ++ y)
#else
for(int y = height - 1; y >= 0; -- y)
#endif
{
ptrSrc = buf.get() + y * nSrcWidth + nAddSize;
for(int x = 0; x < width; ++ x)
{
index = (x&0x01) ? (ptrSrc[x/2] & 0x0F) : (ptrSrc[x/2] >> 4);
*(ptrDest ++) = quad[index].rgbBlue;
*(ptrDest ++) = quad[index].rgbGreen;
*(ptrDest ++) = quad[index].rgbRed;
}
}
break;
case 8:
in.seekg(bfh.bfOffBits - sizeof(RGBQUAD) * 256, std::ios_base::beg);// read palette information
in.read((bufType)quad, sizeof(RGBQUAD) * 256);

try
{
pBits = new unsigned char[nSize];
}
catch(...)
{
in.close();
return false;
}
ptrDest = pBits;
ptrSrc = buf.get();
index = 0;
nDestWidth = width * 3;
nAddSize = nSrcWidth - width;
#ifndef IMG_REVERSE
for(int y = 0; y < height; ++ y)
#else
for(int y = height - 1; y >= 0; -- y)
#endif
{
ptrSrc = buf.get() + y * nSrcWidth + nAddSize;
for(int x = 0; x < width; ++ x)
{
index = ptrSrc[x];
*(ptrDest ++) = quad[index].rgbBlue;
*(ptrDest ++) = quad[index].rgbGreen;
*(ptrDest ++) = quad[index].rgbRed;
}
}
break;
case 24:
nDestWidth = width * 3;
nAddSize = nSrcWidth - nDestWidth;
try
{
pBits = new unsigned char[nSize];
memset(pBits, 0, nSize);
}
catch(...)
{
pBits = NULL;
in.close();
return false;
}
ptrDest = pBits;
#ifdef IMG_REVERSE
for(int y = height - 1; y >= 0; -- y)
#else
for(int y = 0; y < height; ++ y)
#endif
{
memcpy(ptrDest, buf.get() + nSrcWidth * y + nAddSize, nDestWidth);
ptrDest += nDestWidth;
}
break;
}

in.close();
return true;
}
};

dingshaofengbinbin 2010-09-19
  • 打赏
  • 举报
回复
帮顶!!!
DontKissBossAss 2010-09-19
  • 打赏
  • 举报
回复
ImageBuffer[0] 是R
ImageBuffer[1] 是B
ImageBuffer[2] 是G
。。。
。。。
。。。 一次类推。注意每行的结束标志。或者00

DontKissBossAss 2010-09-19
  • 打赏
  • 举报
回复
这个是写这玩的,两张bmp合成一个。最简单那种。。。。
DontKissBossAss 2010-09-19
  • 打赏
  • 举报
回复
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <windows.h>
#define MAPSIZE 1280*1024*3

typedef unsigned char BYTE;
typedef BYTE* PBYTE;

size_t GetBufferLenght(PBYTE bt)
{
LPBITMAPFILEHEADER lpbmfh = (LPBITMAPFILEHEADER)bt;

return lpbmfh->bfSize;
}

void SaveBitmaptoFile(char *bmpname, PBYTE bt, size_t size)
{
FILE *out_file = NULL;
out_file = fopen(bmpname,"wb");
if(NULL == out_file)
{
printf("Open FIle Failed!\n");
return;
}

fwrite(bt,sizeof(BYTE),size,out_file);

fclose(out_file);
return;
}

int main()
{
LPBITMAPINFOHEADER pBitmapHeader = NULL;

int nBufLen = 0;
FILE *pFile = NULL;
PBYTE pByte = (PBYTE)malloc(MAPSIZE);

pFile = fopen("c:\\3.bmp", "rb");
if(pFile == NULL)
{
printf("OpenFile Failed\n");
return 0;
}

nBufLen = fread(pByte, 1, MAPSIZE, pFile);
if(nBufLen == 0)
{
printf("fread Failed\n");
return 0;
}
printf("Image Size = %d\n", nBufLen);
fclose(pFile);

pBitmapHeader = (LPBITMAPINFOHEADER)(pByte +sizeof(BITMAPFILEHEADER));
long width = pBitmapHeader->biWidth;
long Heigt = pBitmapHeader->biHeight;

int offsetof = sizeof(BITMAPINFOHEADER);
PBYTE ImageBuffer = pByte + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);

DWORD i;
for(i = 0; i < width * Heigt *3; i+=3)
{
BYTE bt = 0.299 * ImageBuffer[i] + 0.587 * ImageBuffer[i+1] + 0.114 * ImageBuffer[i+2];
ImageBuffer[i] = bt;
ImageBuffer[i+1] = bt;
ImageBuffer[i+2] = bt;
}

SaveBitmaptoFile("C:\\Graybmp.bmp", pByte, GetBufferLenght(pByte));
printf("width:%ld\nHeight: %ld\n", width, Heigt);
printf("%d\n", pBitmapHeader->biSizeImage);

system("PAUSE");
return 0;
}

64,666

社区成员

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

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