下面一段代码对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; } 
|