怎么把图像读到数组??(UP有分)

liushuaiboy 2004-04-06 09:57:15
各位高手怎么把图像读到二维数组??请各位高手说得详细些,我才刚刚起步:)
...全文
81 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
liushuaiboy 2004-04-07
  • 打赏
  • 举报
回复
谢谢各位的帮助,结贴。
liushuaiboy 2004-04-06
  • 打赏
  • 举报
回复
puhuofeie(扑火飞蛾)兄:我的CDib类里好像没有GetDibData()这个函数呀
快乐鹦鹉 2004-04-06
  • 打赏
  • 举报
回复
嗯。只要确定二维的大小,就没有问题了。读到数组没有问题啊。
要读任何形式的图像,那可难了,我想现在好像还没有一个软件可以读任何形式的图像吧???
一般也就读几种常用格式的就可以了。
liushuaiboy 2004-04-06
  • 打赏
  • 举报
回复
还有一个问题,请各位高手指点:如何才能读任何形式的图像那?:(
liushuaiboy 2004-04-06
  • 打赏
  • 举报
回复
谢谢各位高手指点。 happyparrot(快乐鹦鹉)兄,头文件里不是有图像的大小吗?再动态生成二维数组,呵呵,不知道行不行。puhuofeie(扑火飞蛾) 兄,谢谢你的程序,我先试一下,不懂再问。code8238(二进制动物) 兄 ,smallbugworm(虫虫)谢谢你们二位的提议,让我好好研究一下。呵呵
酒红绿叶 2004-04-06
  • 打赏
  • 举报
回复
lpBits /二维!!

把一维读到二维里面就可以了,不过二维动态申请有点问题!

最好用一维!
酒红绿叶 2004-04-06
  • 打赏
  • 举报
回复
CString pFilePath;

CFileDialog filedlg(true,"*.bmp",NULL,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
"256 bmp Files (*.bmp)|*.bmp||",NULL);

if( filedlg.DoModal() != IDOK )
return;

pFilePath = filedlg.GetPathName();

if( pDib )
delete [] pDib;

pDib=new CDib(pFilePath);

if(pDib->IsValid())
{

lSize = pDib->GetSize();
}
else DeleteContents();

if(pDib)
{

lpDIBBits = pDib->GetDibData();

}
这是写在OnFileOpen
这个程序用到了网上比较常用的CDib类,

这里lpDIBBits 就是指向图象数据的一维指针



快乐鹦鹉 2004-04-06
  • 打赏
  • 举报
回复
图像读到二维数组???数组的二个维的大小你想怎样定义呢?
smallbugworm 2004-04-06
  • 打赏
  • 举报
回复
用CImageList试试
code8238 2004-04-06
  • 打赏
  • 举报
回复
需要了解bmp文件的格式,重点研究一下文件头
酒红绿叶 2004-04-06
  • 打赏
  • 举报
回复
//仅对8位,24位图像进行灰度处理,将灰度图存为 8 位,并赋值处理数组。
void CDib::Gray()
{
//分配处理数组内存
if(!m_pDataS)
{
m_pDataS = new double[m_nWidth*m_nHeight];
}

unsigned char bitCount=GetBitCount();
// 灰度映射表
unsigned char bMap[256];
if(bitCount==8)
{

for(int i=0;i<256;i++)
{
bMap[i]=(unsigned char)(0.299*m_pRGBQuad[i].rgbRed+
0.587*m_pRGBQuad[i].rgbGreen+
0.114*m_pRGBQuad[i].rgbBlue+0.5);
m_pRGBQuad[i].rgbRed=i;
m_pRGBQuad[i].rgbGreen=i;
m_pRGBQuad[i].rgbBlue=i;
m_pRGBQuad[i].rgbReserved=0;
}
// 更换每个象素的颜色索引(即按照灰度映射表换成灰度值)
long lw=WIDTHBYTES(m_nWidth*8);
for(long j=0l;j<m_nHeight;j++)
{
for(long i=0l;i<m_nWidth;i++)
{
long jj=j*lw+i;
m_pDibData[jj]=bMap[m_pDibData[jj]];
m_pDataS[j*m_nWidth+i]=(double)bMap[m_pDibData[jj]];
}
}
}
else if(bitCount==24)
{
//计算相应的 8 位图大小
unsigned long dwFileSize = sizeof(BITMAPFILEHEADER) + m_pBitmapInfoHeader->biSize
+ 256 * sizeof(RGBQUAD) + WIDTHBYTES(m_nWidth*8) * m_nHeight;

//写 BITMAPFILEHEADER
BITMAPFILEHEADER bfh;
memcpy(&bfh,m_pBitmapFileHeader,sizeof(BITMAPFILEHEADER));
bfh.bfOffBits = sizeof(BITMAPFILEHEADER) + m_pBitmapInfoHeader->biSize
+ 256 * sizeof(RGBQUAD);
bfh.bfSize = dwFileSize;
m_fileLeng = dwFileSize;
//写 BITMAPINFOHEADER
BITMAPINFOHEADER bih;
memcpy(&bih,m_pBitmapInfoHeader,m_pBitmapInfoHeader->biSize);
bih.biBitCount = 8;
bih.biSizeImage = (unsigned long)WIDTHBYTES(m_nWidth*8) * (unsigned long)m_nHeight;
bih.biClrUsed = 256;

//写 RGBQUAD
RGBQUAD rgbq[256];
for(int i=0;i<256;i++)
{
rgbq[i].rgbRed=i;
rgbq[i].rgbGreen=i;
rgbq[i].rgbBlue=i;
rgbq[i].rgbReserved=0;
}

//写位图数据
unsigned char* pData = new unsigned char[bih.biSizeImage];
long lw=WIDTHBYTES(m_nWidth*24);
for(long j=0l;j<m_nHeight;j++)
{
for(long i=0l;i<m_nWidth;i++)
{
long jj=j*lw;
long ii=3*i;
unsigned char gray = (unsigned char)(0.299*(m_pDibData[jj+ii])+
0.587*(m_pDibData[jj+ii+1])+0.114*(m_pDibData[jj+ii+2])+0.5);
pData[j*m_nWidth+i] = gray;
m_pDataS[j*m_nWidth+i] = gray;
}
}
//重新申请内存文件
m_pFileData = m_memFile.Detach();
ASSERT(m_pFileData = (BYTE *) realloc((void * )m_pFileData,dwFileSize));
m_memFile.Attach(m_pFileData,dwFileSize, GROWBYTES);
m_memFile.Seek(0l,CFile::begin);
m_memFile.Write(&bfh,sizeof(BITMAPFILEHEADER));
m_memFile.Write(&bih,sizeof(BITMAPINFOHEADER));
m_memFile.Write(rgbq,256 * sizeof(RGBQUAD));
m_memFile.Write(pData,bih.biSizeImage);

SetPara();
delete[] pData;
}
}

//返回处理数组头指针
double* CDib::GetPPIData()
{
if(!m_pDataS)
Gray();
return m_pDataS;
}

//全局函数调用完后,必须调用;成员函数调用后,不能调用
void CDib::Done()
{
ASSERT(m_pDataS);
unsigned char bitCount = GetBitCount();
ASSERT( bitCount==8 );
{
long lw=WIDTHBYTES(m_nWidth*8);
for(long j=0l;j<m_nHeight;j++)
{
for(long i=0l;i<m_nWidth;i++)
{
long jj=j*lw+i;
m_pDibData[jj]=(unsigned char)bound(m_pDataS[j*m_nWidth+i]);

}
}
}
}
// 恢复原始位图文件
void CDib::Restore(void)
{
BITMAPFILEHEADER* p=(BITMAPFILEHEADER*)m_pBackup;
if(m_fileLeng == p->bfSize)
{
m_memFile.Seek(0l,CFile::begin);
m_memFile.Write(m_pBackup,m_fileLeng);
} else
{
m_fileLeng = p->bfSize;
m_pFileData = m_memFile.Detach();
ASSERT( m_pFileData = (BYTE*)realloc((void*)m_pFileData,m_fileLeng) );
m_memFile.Attach(m_pFileData,m_fileLeng, GROWBYTES);
m_memFile.Seek(0l,CFile::begin);
m_memFile.Write(m_pBackup,m_fileLeng);

SetPara();
}
if(m_pDataS)
{
delete[] m_pDataS;
m_pDataS = NULL;
}
}

// 扩大位图
void CDib::Enlarge(long width, long height)
{
ASSERT(width>0&&height>0);
ASSERT(GetBitCount() == 8);//只对8位图处理

//原图像的长宽
long lOldWidth = m_nWidth;
long lOldWidthByte = WIDTHBYTES(m_nWidth * 8);
long lOldHeight = m_nHeight;

//需要申请的长宽
long lWidthByte = WIDTHBYTES(width * 8);
unsigned long sizeImage =
(unsigned long)lWidthByte * (unsigned long)height;

unsigned long dwFileSize = sizeof(BITMAPFILEHEADER)
+ m_pBitmapInfoHeader->biSize
+ 256 * sizeof(RGBQUAD) + sizeImage;

//写 BITMAPFILEHEADER
BITMAPFILEHEADER bfh;
memcpy(&bfh,m_pBitmapFileHeader,sizeof(BITMAPFILEHEADER));

bfh.bfSize = dwFileSize;
m_fileLeng = dwFileSize;

this->m_nHeight = height;
this->m_nWidth = width;

//写 BITMAPINFOHEADER
BITMAPINFOHEADER bih;
memcpy(&bih,m_pBitmapInfoHeader,m_pBitmapInfoHeader->biSize);
bih.biWidth = width;
bih.biHeight = height;
bih.biSizeImage = sizeImage;

//写 RGBQUAD
RGBQUAD rgbq[256];
for(int i=0;i<256;i++)
{
rgbq[i].rgbRed=m_pRGBQuad[i].rgbRed;
rgbq[i].rgbGreen=m_pRGBQuad[i].rgbGreen;
rgbq[i].rgbBlue=m_pRGBQuad[i].rgbBlue;
rgbq[i].rgbReserved=0;
}



//写位图数据
unsigned char* pData = new unsigned char[sizeImage];

for(long j=0;j<height;j++)
{

for(long i=0;i<lWidthByte;i++)
{
pData[(height-j-1) * lWidthByte +i] = 255;
}

}

//重新申请内存文件
m_pFileData = m_memFile.Detach();
ASSERT(m_pFileData = (BYTE * )realloc(m_pFileData,dwFileSize));
m_memFile.Attach(m_pFileData,dwFileSize, GROWBYTES);
m_memFile.Seek(0l,CFile::begin);
m_memFile.Write(&bfh,sizeof(BITMAPFILEHEADER));
m_memFile.Write(&bih,sizeof(BITMAPINFOHEADER));
m_memFile.Write(rgbq,256 * sizeof(RGBQUAD));
m_memFile.Write(pData,bih.biSizeImage);

SetPara();

delete[] pData;
if(m_pDataS)
{
delete[] m_pDataS;
m_pDataS = NULL;
}

}
// 设置成员变量
void CDib::SetPara(void)
{
m_pBitmapFileHeader = (BITMAPFILEHEADER*)m_pFileData;
if (m_pBitmapFileHeader->bfType == 0x4d42)
{
AfxGetApp()->BeginWaitCursor();
m_pBitmapInfo = (BITMAPINFO*) (m_pFileData + sizeof(BITMAPFILEHEADER));
m_pBitmapInfoHeader = (BITMAPINFOHEADER*) (m_pFileData + sizeof(BITMAPFILEHEADER));
//宽度和高度
m_nWidth = m_pBitmapInfoHeader->biWidth;
m_nHeight = m_pBitmapInfoHeader->biHeight;
//每像素的颜色位数
m_nBitCount = (unsigned char)m_pBitmapInfoHeader->biBitCount;

//颜色数
m_nTotalColors = GetColorNumber();
if (m_pBitmapInfoHeader->biClrUsed == 0)
m_pBitmapInfoHeader->biClrUsed = m_nTotalColors;

//指向位图颜色索引表项的指针, 如果没有颜色表项, 则该值为NULL
m_pRGBQuad = (RGBQUAD*)(m_pFileData + sizeof(BITMAPFILEHEADER) + m_pBitmapInfoHeader->biSize);

//颜色索引表的大小(字节)
unsigned long dwColorTableSize = m_nTotalColors * sizeof(RGBQUAD);

//指向位图数据的指针
m_pDibData = m_pFileData + sizeof(BITMAPFILEHEADER) + m_pBitmapInfoHeader->biSize + dwColorTableSize;


//如果没有颜色索引表, 则该值为NULL
if (m_pRGBQuad == (RGBQUAD*)m_pDibData) m_pRGBQuad = NULL;

//位图的大小(面积像素单位)
m_pBitmapInfoHeader->biSizeImage = GetSize();

AfxGetApp()->EndWaitCursor();
m_bValid = TRUE;
}
else
{
AfxMessageBox("This is not a bitmap file!");
m_bValid = FALSE;
}

}
酒红绿叶 2004-04-06
  • 打赏
  • 举报
回复
#include "stdafx.h"
#include "Dib.h"


const unsigned int GROWBYTES = 1024;

//IMPLEMENT_DYNAMIC(CDib, CObject)

CDib::CDib()
{
Init();
}

CDib::CDib(const char* pszDibFileName)
{
Init();
LoadFile(pszDibFileName);
}


CDib::~CDib()
{
if(m_pBackup)
delete[] m_pBackup;
m_pBackup = NULL;

if(m_pFileData)
free(m_pFileData);
if(m_pDataS)
delete[] m_pDataS;

m_pDataS = NULL;
m_pRGBQuad = NULL;
m_pBitmapInfo = NULL;
m_pBitmapInfoHeader = NULL;
m_pBitmapFileHeader = NULL;
m_pszFileName = NULL;
m_pDibData = NULL;
}

#ifdef _DEBUG
void CDib::Dump(CDumpContext& dc) const
{
CObject::Dump(dc);
}

void CDib::AssertValid() const
{
CObject::AssertValid();
ASSERT(m_pszFileName != NULL);
// ASSERT(m_hDIB != 0);
}
#endif


void CDib::Init()
{
m_bValid = false;
m_fileLeng = 0;
m_nWidth = 0; //宽度
m_nHeight = 0; //高度
m_nBitCount = 0; //每个像素占有的位数
m_nTotalColors = 0; //颜色总数
m_pDibData = NULL; //位图像素数据
m_pszFileName = NULL;
m_pBitmapFileHeader = NULL;
m_pBitmapInfoHeader = NULL;
m_pBitmapInfo = NULL;
m_pRGBQuad = NULL; //RGBQUAD 表项
m_pDataS = NULL;
m_pFileData = NULL;
m_pBackup = NULL;
}

long CDib::GetWidth() const
{
return m_nWidth;
}

long CDib::GetHeight() const
{
return m_nHeight;
}

//获取数据缓冲区的大小
unsigned long CDib::GetSize()
{
if (m_pBitmapInfoHeader->biSizeImage != 0)
return (m_pBitmapInfoHeader->biSizeImage);
else
return (unsigned long)WIDTHBYTES(m_nWidth*m_nBitCount) * (unsigned long)m_nHeight;
}

unsigned char CDib::GetBitCount() const
{
return m_nBitCount;
}

unsigned int CDib::GetColorNumber() const
{
unsigned int nColors = 0;

if ((m_pBitmapInfoHeader->biClrUsed == 0) &&
(m_pBitmapInfoHeader->biBitCount < 9))
{
switch (m_pBitmapInfoHeader->biBitCount)
{
case 1: nColors = 2; break;
case 4: nColors = 16; break;
case 8: nColors = 256;break;
}
}
else
nColors = (unsigned int) m_pBitmapInfoHeader->biClrUsed;

return nColors;
}

char* CDib::GetFileName() const
{
return m_pszFileName;
}

unsigned char* CDib::GetDibData() const
{
return m_pDibData;
}

RGBQUAD* CDib::GetRGBQuad() const
{
return m_pRGBQuad;
}

BITMAPINFO* CDib::GetBmpInfo() const
{
return m_pBitmapInfo;
}

unsigned long CDib::GetFileLeng()
{
return m_fileLeng;
}

bool CDib::IsValid() const
{
return m_bValid;
}

void CDib::LoadFile(const char* pszDibFileName)
{
ASSERT(pszDibFileName);
//如果存在就释放内存
if(m_pBitmapInfo) //::GlobalFree(m_hDIB);
{
free(m_pFileData);
delete[] m_pBackup;
}
//再次初始化, 用于多次动态重用
Init();
m_pszFileName = (char*)pszDibFileName;

CFile file(pszDibFileName, CFile::modeRead);

//写入内存文件
m_fileLeng = (unsigned long)file.GetLength();
m_pBackup = new unsigned char[m_fileLeng];

unsigned char* pBuf = new unsigned char[m_fileLeng];
file.Read(pBuf,m_fileLeng);

m_pFileData = (BYTE*)malloc(m_fileLeng);

m_memFile.Attach(m_pFileData,m_fileLeng, GROWBYTES);
m_memFile.Write(pBuf,m_fileLeng);

memcpy(m_pBackup,m_pFileData,m_fileLeng);

SetPara();
delete[] pBuf;
}

bool CDib::SaveFile(const char *pszDibFileName)
{

CFile file;
CFileException e;
if(!file.Open(pszDibFileName, CFile::modeCreate|
CFile::modeReadWrite|CFile::shareExclusive,&e))
{
AfxMessageBox("Can't Save File ");
return FALSE;
}

file.Seek(0l,CFile::begin);
file.Write((void *)m_pBitmapFileHeader,sizeof(BITMAPFILEHEADER));
file.Write((void *)m_pBitmapInfoHeader,sizeof(BITMAPINFOHEADER));
file.Write((void *)m_pRGBQuad,256 * sizeof(RGBQUAD));
file.Write((void *)m_pDibData,m_pBitmapInfoHeader->biSizeImage);
file.Flush();

file.Close();
return TRUE;
}


//the return value is the number of scan lines copied.
int CDib::Draw(HDC hdc, int XDest, int YDest, int nDestWidth,
int nDestHeight, int XSrc, int YSrc,
int nSrcWidth, int nSrcHeight,
unsigned int iUsage, unsigned long dwRop
,long RectW,long RectH)
{
XDest = (int) ((RectW-nSrcWidth)/2);
YDest = (int) ((RectH-nSrcHeight)/2);
if (m_pRGBQuad) // Has a color table
{
HPALETTE hPalette = CreateBitmapPalette();
HPALETTE hOldPalette = ::SelectPalette(hdc, hPalette, FALSE);
::RealizePalette(hdc);

int nScanLines = StretchDIBits(hdc,
XDest, YDest, nDestWidth, nDestHeight,
XSrc, YSrc, nSrcWidth, nSrcHeight,
m_pDibData, m_pBitmapInfo, iUsage, dwRop);

::SelectPalette(hdc, hOldPalette, FALSE);
::DeleteObject(hPalette);
return nScanLines;
}
else
return StretchDIBits(hdc,
XDest, YDest, nDestWidth, nDestHeight,
XSrc, YSrc, nSrcWidth, nSrcHeight,
m_pDibData, m_pBitmapInfo, iUsage, dwRop);

}


HPALETTE CDib::CreateBitmapPalette()
{
if((m_pRGBQuad == NULL) || !IsValid())return NULL;
struct
{
WORD palVersion;
WORD palNumEntries;
PALETTEENTRY palPalEntry[256];
} palette = { 0x300, 256 };

LPRGBQUAD pRGBTable = m_pRGBQuad;

for(unsigned int i = 0; i < m_nTotalColors; ++i)
{
palette.palPalEntry[i].peRed = pRGBTable[i].rgbRed;
palette.palPalEntry[i].peGreen = pRGBTable[i].rgbGreen;
palette.palPalEntry[i].peBlue = pRGBTable[i].rgbBlue;
palette.palPalEntry[i].peFlags = 0;
}

HPALETTE hPalette = ::CreatePalette((LPLOGPALETTE)&palette);

return hPalette;

}

九重霄 2004-04-06
  • 打赏
  • 举报
回复
up
kpld8888 2004-04-06
  • 打赏
  • 举报
回复
UP
gloomyfish 2004-04-06
  • 打赏
  • 举报
回复
这种问题你也问~~
Readpixel(BYTE *bpixel,int width,int height)
{
//定义临时变量
int i,j;
//定义一维像素长度
int lenght;
lenght=WIDTHBYTES(width*8);//每一行长度
//定义二维数组
char **temp = new char[][];
for(i=0;i<lenght;i++)
{
for(j=0;j<WIDTHBYTES(width*8);j++)
{
temp[i][j]=*(bpixel+lenght*i+j);
}
}
就这样就ok了
多努力ing!
liushuaiboy 2004-04-06
  • 打赏
  • 举报
回复
smallgenie(浪漫男人)兄,指点一下我吧,别说风凉话了:(
sona 2004-04-06
  • 打赏
  • 举报
回复
坐个便车!!!我也是个笨鸟。
//省略很多的关于显示的代码
CBitmap bitmap;
BITMAP bm;
//.....//
bitmap->GetBitmap(&bm);
int bitmapsize=bm.bmHeight*bm.bmwidthBytes;
BYTE* px=(BYTE*)GlobalAlloc(GPTR,bitmapsize);//声明px数组,可惜是一维的
DWORD dwvalue;
dwvalue=bitmap->GetBitmapBus(bitmapsize,px);
//但是可以这样读
int rgb,x,y;
int PixelBytes=bm.bmBitsPixel/8;
for(y=0;y<bm.bmHeight;y++)
for(x=0;x<bm.bmwidth;x++)
{
rgb=y*bm.bmwidthBytes+x*pixelBytes;
px[rgb+0]...//读取R
px[rgb+1]...//读取G
px[rgb+2]...//读取B
} //bmp图象
我的问题是怎样声明一个数组来存放图象的灰度?
我知道RGB与GRAY之间的关系


smallgenie 2004-04-06
  • 打赏
  • 举报
回复
那个Cdib封的不好,有本事自己写一个来。

19,468

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 图形处理/算法
社区管理员
  • 图形处理/算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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