分享
 
 
 

BMP位图操作(象素操作)

王朝厨房·作者佚名  2007-01-04
窄屏简体版  字體: |||超大  

下面一段代码对BMP的象素操作非常有用:

void CBmpTryView::OnDraw(CDC* pDC)

{

CBmpTryDoc* pDoc = GetDocument();

ASSERT_VALID(pDoc);

// TODO: add draw code for native data here

CDC memdcX,memdcY;

memdcX.CreateCompatibleDC(pDC);

//map these CDC objects to your window DC

memdcY.CreateCompatibleDC(pDC);

BITMAP bmpX,bmpY;

CBitmap mybmp,bmpClone;

bmpClone.LoadBitmap(IDB_BITMAP2);

//initialize the clone bitmap object(empty image in

//this case) before using

DWORD dwValue,dwValue2;

if(TRUE == mybmp.LoadBitmap(IDB_BITMAP1))

{

mybmp.GetBitmap(&bmpX); //Get bitmap dimensions

//into BITMAP structure.

BYTE* bmpBuffer=(BYTE*)GlobalAlloc(GPTR,

bmpX.bmWidthBytes*bmpX.bmHeight);//allocate memory for image

//byte buffer

dwValue=mybmp.GetBitmapBits(bmpX.bmWidthBytes*bmpX.bmHeight,

bmpBuffer);//Get the bitmap bits

//into a structure

dwValue2 = bmpClone.SetBitmapBits(bmpX.bmWidthBytes*bmpX.bmHeight,

bmpBuffer);//generate image from

//above buffer

bmpClone.GetBitmap(&bmpY);

memdcX.SelectObject(mybmp);//select original bitmap

memdcY.SelectObject(bmpClone);//select clone

//Draw the original bitmap

pDC->BitBlt(10,10,bmpX.bmWidthBytes,bmpX.bmHeight ,&memdcX,

0,0,SRCCOPY);

//Draw the cloned bitmap image

pDC->BitBlt(10,40,bmpX.bmWidthBytes,bmpX.bmHeight ,&memdcY,

0,0,SRCCOPY);

GlobalFree((HGLOBAL)bmpBuffer);//Free memory

}

}

下面是我的3D浏览控件的部分代码:

主要实现把场景内容复制到剪贴板上,格式是CF_BITMAP

void CHoopsView::OnMCopy()

{

if ( !OpenClipboard() )

{

AfxMessageBox( "无法打开剪贴板" );

return;

}

// 删除目前剪贴板的内容

if( !EmptyClipboard() )

{

AfxMessageBox( "无法清除剪贴板" );

return;

}

//CopyBmp2Clipboard() ;

SaveDIB("D:\\1_1.bmp");

// Save2Hsf("D:\\1_1.hsf");

//下面一段程序有问题,关闭程序时有问题

HGLOBAL hStr = ::GlobalAlloc(GMEM_FIXED,11);

LPTSTR lpStr =(LPTSTR) ::GlobalLock(hStr);

sprintf(lpStr,"D:\\1_1.hsf");

::GlobalUnlock(hStr);

if ( ::SetClipboardData( CF_TEXT, hStr ) == NULL )

{

AfxMessageBox( "无法将数据复制到剪贴板当中" );

}

::GlobalFree(hStr);

CloseClipboard();

}

void CHoopsView::OnMPaste()

{

BITMAP bm;

CBitmap *pBmp = new CBitmap();

pBmp->LoadBitmap(IDB_BITMAP1);

pBmp->GetBitmap(&bm);

BYTE* lpBits =

(BYTE*)GlobalAlloc(GPTR, bm.bmWidthBytes*bm.bmHeight);

pBmp->GetBitmapBits(bm.bmWidthBytes*bm.bmHeight,lpBits);

if ( !OpenClipboard() )

{

AfxMessageBox( "无法打开剪贴板" );

return;

}

// 删除目前剪贴板的内容

if( !EmptyClipboard() )

{

AfxMessageBox( "无法清除剪贴板" );

return;

}

if ( ::SetClipboardData( CF_BITMAP, (HBITMAP)(*pBmp) ) == NULL )

{

AfxMessageBox( "无法将数据复制到剪贴板当中" );

}

CloseClipboard();

}

BOOL CHoopsView::SaveDIB(const char * filename)

{

char temp[MVO_BUFFER_SIZE];

char cwidth[MVO_BUFFER_SIZE], cheight[MVO_BUFFER_SIZE];

HC_Open_Segment_By_Key(m_pHView->GetViewKey());

HC_Show_Device_Info(".", "pixels", temp);

HC_Close_Segment();

HC_Parse_String(temp, ",", 0, cwidth);

int width = atoi(cwidth);

HC_Parse_String(temp, ",", 1, cheight);

int height = atoi(cheight);

HOutputHandlerOptions local_options;

HOutputHandlerOptions * options = &local_options;

options->m_Width = width;

options->m_Height = height;

CFile file;

CFileException fe;

if (!file.Open(filename, CFile::modeCreate |

CFile::modeWrite ,&fe))

{

fe.ReportError();

fe.Delete();

return false;

}

HPoint m_WindowColor,m_WindowColorBottom;

m_pHView->GetWindowColor(m_WindowColor,m_WindowColorBottom);

char hsra_options[MVO_BUFFER_SIZE];

char hlr_options[MVO_BUFFER_SIZE];

char current_hsra[MVO_BUFFER_SIZE];

/* first find out the relevant options associated with the view */

HC_Open_Segment_By_Key(m_pHView->GetViewKey());

{

HC_Show_One_Net_Rendering_Optio("hidden surface removal algorithm", current_hsra);

HRenderMode rndrmode = m_pHView->GetRenderMode();

if (rndrmode == HRenderHiddenLine || rndrmode == HRenderHiddenLineFast)

{

HC_Show_One_Net_Rendering_Optio("hidden line removal options", hlr_options);

sprintf(hsra_options, "hsra = hidden line, hidden line removal options = (%s)", hlr_options);

}

else

{

sprintf(hsra_options, "hsra = szb, technology = software frame buffer");

}

}

HC_Close_Segment();

char image_segment[MVO_SEGMENT_PATHNAME_BUFFER];

char driver_segment[MVO_SEGMENT_PATHNAME_BUFFER];

sprintf(image_segment,"?driver/null/hbaseview_%p", (void*)this);

sprintf(driver_segment,"?driver/image/hbaseview_%p", (void*)this);

// prepare image for rendering

HC_Open_Segment(image_segment);

HPixelRGB *image = new HPixelRGB[options->m_Width * options->m_Height];

HC_KEY image_key = HC_KInsert_Image (0.0, 0.0, 0.0, "rgb", options->m_Width, options->m_Height, image);

HC_Close_Segment ();

// prepare data to render

HC_Open_Segment(driver_segment);

//HC_Set_Rendering_Options("attribute lock = (color = (window))");

//HC_Set_Color_By_Value("windows", "RGB", m_WindowColor.x, m_WindowColor.y, m_WindowColor.z);

HC_Set_Window_Frame("off");

HC_Set_Rendering_Options(hsra_options);

char buffer[MVO_BUFFER_SIZE];

sprintf (buffer, "use window id = %s%p, subscreen = (-1, 1, -1, 1)", H_EXTRA_POINTER_FORMAT, (void*)image_key);

HC_Set_Driver_Options (buffer);

HC_Set_Driver_Options ("isolated, no gamma correction");

char color[MVO_BUFFER_SIZE];

HCLOCALE(sprintf(color, "windows=(r=%f g=%f b=%f), window contrast = (r=%f g=%f b=%f)", m_WindowColor.x, m_WindowColor.y, m_WindowColor.z, m_WindowColorBottom.x, m_WindowColorBottom.y, m_WindowColorBottom.z));

HC_Set_Color(color);

HC_Set_Window_Pattern("Down");

//ss if (GetAxisMode() != AxisOff)

//ss HC_Include_Segment_By_Key(GetAxisTriadKey());

HC_Include_Segment_By_Key (m_pHView->GetSceneKey());

HC_Close_Segment ();

HC_Update_One_Display(driver_segment);

BITMAPFILEHEADER bmfHdr;

bmfHdr.bfType=0x4d42;

int sizeHdr=sizeof(BITMAPINFOHEADER);

LPBITMAPINFOHEADER lpBI=( LPBITMAPINFOHEADER)::GlobalAlloc(LMEM_FIXED,sizeHdr);

if(!lpBI)

{

AfxMessageBox("内存申请失败,请稍后再试");

}

BYTE *pDib;

BYTE *pDib2;

long lPixelCount = options->m_Width*options->m_Height;

long lByteCount = lPixelCount*3;

pDib=(BYTE*)::GlobalAlloc(LMEM_FIXED,lByteCount);

HPixelRGB *pPixel = (HPixelRGB*)pDib;

// pPixel = new HPixelRGB[lPixelCount];

if(!pDib)

{

AfxMessageBox("内存申请失败,请稍后再试");

return false;

}

HC_Show_Partial_Image (image_key, 0, 0, options->m_Width , options->m_Height, pPixel) ;

HC_Delete_Segment(driver_segment);

HC_Delete_Segment(image_segment);

delete[] image;

lpBI->biSize=(LONG)sizeof(BITMAPINFOHEADER);

lpBI->biWidth=(LONG)options->m_Width;

lpBI->biHeight=(LONG)options->m_Height;

lpBI->biPlanes=1;

lpBI->biBitCount=24;

lpBI->biCompression=BI_RGB;

lpBI->biSizeImage=0;

lpBI->biXPelsPerMeter=0;

lpBI->biYPelsPerMeter=0;

lpBI->biClrUsed=0;

lpBI->biClrImportant=0;

long rows = options->m_Height;

long cols = options->m_Width;

pDib2=(BYTE*)::GlobalAlloc(LMEM_FIXED,(lByteCount/4+1)*4); //DWORD对齐的

if(!pDib2)

{

AfxMessageBox("内存申请失败,请稍后再试");

return false;

}

for(int j=0;j<rows;j++)

for(int i=0;i<cols;i++)

{

//pDib2[i+j*cols]=pDib[options->m_Width*(options->m_Height-1-j)*3+ll];

pDib2[i*3+j*cols*3] = pPixel[cols*(rows-1-j)+i].b;

pDib2[i*3+j*cols*3+1] = pPixel[cols*(rows-1-j)+i].g;

pDib2[i*3+j*cols*3+2] = pPixel[cols*(rows-1-j)+i].r;

}

// delete pPixel;

bmfHdr.bfSize=(DWORD) (sizeof(BITMAPFILEHEADER) +

sizeHdr + (lByteCount/4+1)*4);

bmfHdr.bfReserved1=bmfHdr.bfReserved2=0;

bmfHdr.bfOffBits=sizeof(BITMAPFILEHEADER)+sizeHdr;

//CBitmap* pBmp = new CBitmap();

CBitmap bmp;

CBitmap* pBmp = &bmp;

//pBmp->CreateBitmapIndirect(&bm);

//pBmp->CreateBitmap(image_width,image_height,24,image_buffer);

CClientDC cdc(this);

struct RGBX

{

BYTE r;

BYTE g;

BYTE b;

BYTE x;

};

RGBX* pData = new RGBX[width*height];

//RGBX* pData = (RGBX*)::GlobalAlloc(GMEM_FIXED,width*height*4);

for(int i=0;i<height;i++)//行数

for(int j=0;j<width;j++)//列数

{

pData[i*width+j].b = pPixel[i*width+j].r;

pData[i*width+j].g = pPixel[i*width+j].g;

pData[i*width+j].r = pPixel[i*width+j].b;

pData[i*width+j].x = 0;

}

pBmp->CreateCompatibleBitmap(&cdc,width,height);

pBmp->SetBitmapBits(width*height*4,(void*)pData);

if ( ::SetClipboardData( CF_BITMAP, (HBITMAP)(*pBmp) ) == NULL )

{

AfxMessageBox( "无法将数据复制到剪贴板当中" );

}

::GlobalFree(pDib);

delete pData;

// delete pBmp;

try

{

file.Write((LPVOID)&bmfHdr,sizeof(BITMAPFILEHEADER));

file.Write((LPVOID)lpBI,sizeHdr);

file.WriteHuge((LPVOID)pDib2,(lByteCount/4+1)*4);

// file.WriteHuge((LPVOID)pDib,lByteCount);

}

catch(CException*Fe)

{

Fe->ReportError();

Fe->Delete();

return false;

}

//::GlobalFree(pDib);

::GlobalFree(lpBI);

::GlobalFree(pDib2);

file.Close();

return true;

}

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有