256色的灰度图像点阵处理后,如何显示出来

yo_quan 2002-10-10 09:39:14
从一个256的灰度图像中读出了数据
然后经过数字图像处理
最后现在想显示出来
试验了CreateBitmap
但是显示为全白
void DisImage_256Gray(IMAGE_DIMENTION imgDimention,BYTE** img,HDC hdc,int dc_Width,int dc_Height,int nMod){
int nWidthInPixels=imgDimention.nWidthInPixel;
int nHeightInPixels=imgDimention.nHeightInPixel;

BYTE* ResultImage=new BYTE[HEIGHT_MAX_PIXELS*WIDTH_MAX_PIXELS];
ZeroMemory(ResultImage,sizeof(BYTE)*HEIGHT_MAX_PIXELS*WIDTH_MAX_PIXELS);

BYTE* Pointer=ResultImage;

//将二维图像数组转换为一维图像数组
int i,j;
int test=nWidthInPixels%2; //看看宽度是否是2的倍数,如不是就需要在最后面补一字节的0即0x00;
int RealWidth=nWidthInPixels;
if(test!=0)
RealWidth++;

for(i=0;i<nHeightInPixels;i++){
CopyMemory(Pointer,img[i],RealWidth*sizeof(BYTE));
Pointer+=RealWidth;
}
HBITMAP hBmp=CreateBitmap(RealWidth,nHeightInPixels,1,8,(void*)ResultImage);
HDC hMem=CreateCompatibleDC(hdc);
SelectObject(hMem,hBmp);
if(nMod==1)
BitBlt(hdc,0,0,dc_Width,dc_Height,hMem,0,0,SRCCOPY);
else
StretchBlt(hdc,0,0,dc_Width,dc_Height,hMem,0,0,RealWidth,nHeightInPixels,SRCCOPY);

DeleteDC(hMem);
DeleteObject(hBmp);
delete[] ResultImage;
}
...全文
327 16 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
jishiping 2002-10-11
  • 打赏
  • 举报
回复
HBITMAP hBmp=CreateDIBSection(hdc,(BITMAPINFO*)buf,DIB_RGB_COLORS,
(void**)&Data, NULL, 0);
并没有转换成RGB啊,还是灰阶的图。你看到没有,
memset(buf, 0, 40+256*4);
pbih = (BITMAPINFOHEADER*)buf;
pbih->biSize = 40;
pbih->biWidth = nWidthInPixels;
pbih->biHeight = nHeightInPixels;
pbih->biPlanes = 1;
pbih->biBitCount = 8;
上面的代码是设置BITMAP的头信息,而下面的代码是设定BITMAP的调色盘
信息。
for(int n=0; n<256; n++)
memset(buf+40+n*4, n, 3);
对于DIB(*.bmp文件)的格式,我太熟了,只是对于你使用的CreateBitmap
的用法,我也不熟。一般我都使用CreateDIBSection,或者直接分配一块
内存,将内存的格式设置成DIB格式(也就是*.bmp文件中除去前面14个字
节后的格式),然后使用SetDIBitsToDevice或者StretchDIBits直接在DC
上画图。
yo_quan 2002-10-11
  • 打赏
  • 举报
回复
jishiping(JSP 季世平)

我看了一下你的代码,实际上是把256位图转为了RGB位图
HBITMAP hBmp=CreateDIBSection(hdc,
(BITMAPINFO*)buf,DIB_RGB_COLORS,
(void**)&Data, NULL, 0);
而没用到调色板
不过到底代码的准确性,我还没去试
而你提到的关于**的问题,我做下面:
char** img=new BYTE*[HEIGHT_MAX_PIXELS];
for(int i=0;i<HEIGHT_MAX_PIXELS;i++){
img[i]=new BYTE[WIDTH_MAX_PIXELS];
}
ddd









yo_quan 2002-10-11
  • 打赏
  • 举报
回复
up
jishiping 2002-10-11
  • 打赏
  • 举报
回复
上面的代码我是经过测试的,如果不行的话,就是你的img[i]的问题了。
yo_quan 2002-10-11
  • 打赏
  • 举报
回复
还是没搞定亚
shally5 2002-10-11
  • 打赏
  • 举报
回复
学习。。。。
yo_quan 2002-10-11
  • 打赏
  • 举报
回复
用 jishiping(JSP 季世平) 的方法
可以显示了
至于ddeng(登登)的方法我没去试验,
不过我看,应该可以的.
ddeng 2002-10-11
  • 打赏
  • 举报
回复
难怪慢呢,多写了一层无用的循环,呵呵,今天晕得很~~~
应该是:
void __stdcall DispalyGray256(HDC dc, Byte* img, int Width, int Height) {
Graphics::TBitmap *Bitmap = new Graphics::TBitmap();
if(Bitmap->PixelFormat!=pf8bit) {
Bitmap->PixelFormat = pf8bit;
}
Bitmap->Width = Width;
Bitmap->Height = Height;
LOGPALETTE *PalPalette = (LOGPALETTE *)new char[sizeof(LOGPALETTE)+sizeof(PALETTEENTRY)*256];
PalPalette->palVersion = 0x300;
PalPalette->palNumEntries = 256;
for(int i=0; i<256; i++) {
PalPalette->palPalEntry[i].peRed = (Byte)i;
PalPalette->palPalEntry[i].peGreen = (Byte)i;
PalPalette->palPalEntry[i].peBlue = (Byte)i;
PalPalette->palPalEntry[i].peFlags = PC_RESERVED;
}
Bitmap->Palette = ::CreatePalette(PalPalette);
delete PalPalette;
for(int y=0; y<Height; y++) {
Byte *pPtr = static_cast<Byte *>(Bitmap->ScanLine[y]);
memcpy(pPtr, img+y*Width, Width);
}
::BitBlt(dc, 0, 0, Width, Height, Bitmap->Canvas->Handle, 0, 0, SRCCOPY);
delete Bitmap;
}
yincp 2002-10-11
  • 打赏
  • 举报
回复
关注
ddeng 2002-10-11
  • 打赏
  • 举报
回复
呵呵,实际测试了一下,发现按24位图操作结果显示得更快些,可能是256色位图在BitBlt到屏幕(我们屏幕差不多都是用真彩的吧)时系统要进行转换更慢吧。
//---------------------------------------------------------------------------
void __stdcall DispalyGray24bit(HDC dc, Byte* img, int Width, int Height) {
Graphics::TBitmap *Bitmap = new Graphics::TBitmap();
if(Bitmap->PixelFormat!=pf24bit) {
Bitmap->PixelFormat = pf24bit;
}
Bitmap->Width = Width;
Bitmap->Height = Height;
for(int y=0; y<Height; y++) {
Byte *pPtr = static_cast<Byte *>(Bitmap->ScanLine[y]);
for(int x=0; x<Width*3; x+=3) {
Byte *pPtrSrc = img+y*Width;
pPtr[x] = pPtrSrc[x];
pPtr[x+1] = pPtrSrc[x];
pPtr[x+2] = pPtrSrc[x];
}
}
::BitBlt(dc, 0, 0, Width, Height, Bitmap->Canvas->Handle, 0, 0, SRCCOPY);
delete Bitmap;
}
ddeng 2002-10-11
  • 打赏
  • 举报
回复
或者按24位图像操作就不用处理调色板了,但运行时内存需求大,处理时间长,不过图像不太大时应该感觉不出来的。
ddeng 2002-10-11
  • 打赏
  • 举报
回复
void __stdcall DispalyGray256(HDC dc, Byte* img, int Width, int Height) {
Graphics::TBitmap *Bitmap = new Graphics::TBitmap();
if(Bitmap->PixelFormat!=pf8bit) {
Bitmap->PixelFormat = pf8bit;
}
Bitmap->Width = Width;
Bitmap->Height = Height;
LOGPALETTE *PalPalette = (LOGPALETTE *)new char[sizeof(LOGPALETTE)+sizeof(PALETTEENTRY)*256];
PalPalette->palVersion = 0x300;
PalPalette->palNumEntries = 256;
for(int i=0; i<256; i++) {
PalPalette->palPalEntry[i].peRed = (Byte)i;
PalPalette->palPalEntry[i].peGreen = (Byte)i;
PalPalette->palPalEntry[i].peBlue = (Byte)i;
PalPalette->palPalEntry[i].peFlags = PC_RESERVED;
}
Bitmap->Palette = ::CreatePalette(PalPalette);
delete PalPalette;
for(int y=0; y<Height; y++) {
Byte *pPtr = static_cast<Byte *>(Bitmap->ScanLine[y]);
for(int x=0; x<Width; x++) {
memcpy(pPtr, img+y*Width, Width);
}
}
::BitBlt(dc, 0, 0, Width, Height, Bitmap->Canvas->Handle, 0, 0, SRCCOPY);
delete Bitmap;

}

一个测试:
void __fastcall TForm1::Button1Click(TObject *Sender)
{
Byte* img = new Byte[256*256];
for(int i=0; i<256*256; i++) {
img[i] = i%256;
}
DispalyGray256(Canvas->Handle, img, 256, 256);
delete []img;
}
jishiping 2002-10-11
  • 打赏
  • 举报
回复
对于二维指针img, 我不知道调用时的实参是如何定义的。如果实参的定义
是BYTE img[800][800],那么你使用img[i]是错误的。如果你是这样定义的:
BYTE* img[800]; for(int n=0; n<800; n++) img[n] = new BYTE[800];
那么使用img[i]是正确的。这儿我不知道实参是如何定义的,所以我不知道
这儿使用img[i]是否正确。这儿我暂且假设是正确的。对于CreateBitmap的
用法,我也不是很清楚,用下面的方法CreateDIBSection建立BITMAP是可以
了。

void DisImage_256Gray(IMAGE_DIMENTION imgDimention,BYTE** img,HDC hdc,int dc_Width,int dc_Height,int nMod){
{
BYTE *Data;
char buf[40+256*4];
BITMAPINFOHEADER* pbih;

int nWidthInPixels=imgDimention.nWidthInPixel;
int nHeightInPixels=imgDimention.nHeightInPixel;

memset(buf, 0, 40+256*4);
pbih = (BITMAPINFOHEADER*)buf;
pbih->biSize = 40;
pbih->biWidth = nWidthInPixels;
pbih->biHeight = nHeightInPixels;
pbih->biPlanes = 1;
pbih->biBitCount = 8;
for(int n=0; n<256; n++)
memset(buf+40+n*4, n, 3);
HBITMAP hBmp=CreateDIBSection(hdc,
(BITMAPINFO*)buf,DIB_RGB_COLORS,
(void**)&Data, NULL, 0);
int RealWidth = (nWidthInPixels+3)/4*4;
BYTE* Pointer = Data + RealWidth *
nHeightInPixels;
for(int i=0;i<nHeightInPixels;i++){
CopyMemory(Pointer,img[i],nWidthInPixels,
nWidthInPixels);
Pointer -= RealWidth;
}
HDC hMem=CreateCompatibleDC(hdc);
SelectObject(hMem,hBmp);
if(nMod==1)
BitBlt(hdc,0,0,dc_Width,dc_Height,hMem,0,0,SRCCOPY);
else
StretchBlt(hdc,0,0,dc_Width,dc_Height,hMem,0,0,
RealWidth,nHeightInPixels,SRCCOPY);

DeleteDC(hMem); DeleteObject(hBmp);
}
CCLIS 2002-10-10
  • 打赏
  • 举报
回复
设置TBITMAP的PIXELWIDTH,
设置调色板
设置BITMAP头信息。
COPY数据

简单些,就是将256色图的数据以24位图的方式显示。

byte *line = ScanLine[y];
line[x] = line[x+1] = line[x+2] = color;
yo_quan 2002-10-10
  • 打赏
  • 举报
回复
我个人的感觉应该是少了调色板的内容
用CreateBitmap的方法,显示2值图像是没有问题的
这个我是实验了的.
不过,在bcb种,我想用tbitmap应该可以搞定
只不过我想用这个来试试
aawolf 2002-10-10
  • 打赏
  • 举报
回复
CopyMemory(Pointer,img[i],RealWidth*sizeof(BYTE));
个人感觉可能是这里的问题,你最好是保存成文件看看缺了什么。是不是却了Bitmap头?

13,871

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder相关内容讨论区
社区管理员
  • 基础类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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