我要发帖 回复

版主

29

主题

172

积分

0

专家分

:

私信
发表时间 : 2007-11-15 15:03:57 | 浏览 : 1549    评论 : 4
http://www.52vr.com/bbs/viewthread.php?tid=975中有问vp中如何输出bmp图片?
有很多答案但没有可以直接用的,
1、那段出错的代码如何修改才能正确输出bmp图片?
2、vpMulder这个模块为什么我安装后按F1,在D盘没有看见生成的图片呢?
3、我用
vpMulderSnap* pMulderSnap_myMulderSnap = new vpMulderSnap();
                pMulderSnap_myMulderSnap->setName( "myMulderSnap" );
                pMulderSnap_myMulderSnap->setEnable( true );
                pMulderSnap_myMulderSnap->setSnapedFileDir( "d:/" );
                pMulderSnap_myMulderSnap->setSnapType( vpMulderSnap::Single File );
                pMulderSnap_myMulderSnap->setKeyboard( vpInputKeyboard::SOURCE_BOOLEAN_KEY_F1 );
加入程序中,结果提示 vpMulderSnap::Single File ,找不到定义,我跟进去看,也发现vpMulderSnap.h没有Single File的定义,是不是我下载的版本信息错误?

[ 本帖最后由 pplander 于 2007-11-15 03:16 PM 编辑 ]

最近VR访客

tan_dunming 评论于2007-11-15 22:57:34
屏幕抓屏得到。网上有很多资料,可以参考这个,不一定完整。供参考
#include <glaux.h>
#pragma comment( lib, "glaux.lib")

AUX_RGBImageRec *Image, *tempImage;
HBITMAP hBitmap,hOldBitmap;
HBITMAP CopyScreenToBitmap(LPRECT lpRect) //lpRect 代表选定区域
{
         HDC hScrDC, hMemDC;      
         // 屏幕和内存设备描述表
         // 位图句柄
         int       nX, nY, nX2, nY2;      
         // 选定区域坐标
         int       nWidth, nHeight;      
         // 位图宽度和高度
         int       xScrn, yScrn;         
         // 屏幕分辨率
         // 确保选定区域不为空矩形
         if (IsRectEmpty(lpRect))
          return NULL;
         //为屏幕创建设备描述表
         hScrDC = CreateDC("DISPLAY", NULL, NULL, NULL);
         //为屏幕设备描述表创建兼容的内存设备描述表
         hMemDC = CreateCompatibleDC(hScrDC);
         // 获得选定区域坐标
         nX = lpRect->left;
         nY = lpRect->top;
         nX2 = lpRect->right;
         nY2 = lpRect->bottom;
         // 获得屏幕分辨率
         xScrn = GetDeviceCaps(hScrDC, HORZRES);
         yScrn = GetDeviceCaps(hScrDC, VERTRES);
         //确保选定区域是可见的
         if (nX < 0)
          nX = 0;
         if (nY < 0)
          nY = 0;
         if (nX2 > xScrn)
          nX2 = xScrn;
         if (nY2 > yScrn)
          nY2 = yScrn;
         nWidth = nX2 - nX;
         nHeight = nY2 - nY;
         static bool bInit=false;
         if(!bInit)
         {
                // 创建一个与屏幕设备描述表兼容的位图
                hBitmap=CreateCompatibleBitmap(hScrDC,nWidth,nHeight);
                bInit=true;
         }
         // 把新位图选到内存设备描述表中
         hOldBitmap=(HBITMAP)SelectObject(hMemDC,hBitmap);
         // 把屏幕设备描述表拷贝到内存设备描述表中
         BitBlt(hMemDC,0,0, nWidth,nHeight,hScrDC, nX, nY, SRCCOPY);
         //得到屏幕位图的句柄
         hBitmap=(HBITMAP)SelectObject(hMemDC,hOldBitmap);
         //清除
         DeleteDC(hScrDC);
         DeleteDC(hMemDC);
         // 返回位图句柄
         return hBitmap;
}


int GetBitmapData(HBITMAP hBitmap, unsigned char* pData, LPSTR lpFileName=NULL)
{

        HDC            hDC;         
           //设备描述表
    int            iBits;  
        //当前显示分辨率下每个像素所占字节数
        WORD            wBitCount;   
           //位图中每个像素所占字节数
    //定义调色板大小, 位图中像素字节大小 ,位图文件大小 , 写入文件字节数
        DWORD           dwPaletteSize=0, dwBmBitsSize, dwDIBSize, dwWritten;
        BITMAP          Bitmap;        
        //位图属性结构
        BITMAPFILEHEADER   bmfHdr;        
        //位图文件头结构
    BITMAPINFOHEADER   bi;            
        //位图信息头结构
        LPBITMAPINFOHEADER lpbi;         
        //指向位图信息头结构
    HANDLE          fh, hDib, hPal,hOldPal=NULL;
        //定义文件,分配内存句柄,调色板句柄  

   //计算位图文件每个像素所占字节数
   hDC = CreateDC("DISPLAY",NULL,NULL,NULL);
   iBits = GetDeviceCaps(hDC, BITSPIXEL) * GetDeviceCaps(hDC, PLANES);
   DeleteDC(hDC);
   wBitCount = 24;

   //计算调色板大小
   if (wBitCount <= 8)
      dwPaletteSize = (1 << wBitCount) *sizeof(RGBQUAD);   

   //设置位图信息头结构
   GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&Bitmap);
   bi.biSize            = sizeof(BITMAPINFOHEADER);
   bi.biWidth           = Bitmap.bmWidth;
   bi.biHeight          = Bitmap.bmHeight;
   bi.biPlanes          = 1;
   bi.biBitCount         = wBitCount;
   bi.biCompression      = BI_RGB;
   bi.biSizeImage        = 0;
   bi.biXPelsPerMeter     = 0;
   bi.biYPelsPerMeter     = 0;
   bi.biClrUsed         = 0;
   bi.biClrImportant      = 0;

   dwBmBitsSize = ((Bitmap.bmWidth *
    wBitCount+31)/32)* 4
         *Bitmap.bmHeight ;

   //为位图内容分配内存
   hDib  = GlobalAlloc(GHND,dwBmBitsSize+
        dwPaletteSize+sizeof(BITMAPINFOHEADER));
   lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDib);
   *lpbi = bi;

   // 处理调色板   
   hPal = GetStockObject(DEFAULT_PALETTE);
   if (hPal)
   {
      hDC  = GetDC(NULL);
      hOldPal = SelectPalette(hDC, (HPALETTE)hPal, FALSE);
      RealizePalette(hDC);
   }

   // 获取该调色板下新的像素值
   GetDIBits(hDC, hBitmap, 0, (UINT) Bitmap.bmHeight,
         (LPSTR)lpbi + sizeof(BITMAPINFOHEADER)
    +dwPaletteSize,         (LPBITMAPINFO)lpbi, DIB_RGB_COLORS);

   //恢复调色板   
   if (hOldPal)
   {
      SelectPalette(hDC, (HPALETTE)hOldPal, TRUE);
      RealizePalette(hDC);
      ReleaseDC(NULL, hDC);
   }  
   //unsigned char* data=((unsigned char*) ((LPBITMAPINFO)lpbi) + (WORD) (((LPBITMAPINFO)lpbi)->bmiHeader.biSize));
   if(pData!=NULL)
   {
           unsigned char ch;
           memcpy(pData, (unsigned char*)((LPBITMAPINFO)lpbi) + (WORD) (((LPBITMAPINFO)lpbi)->bmiHeader.biSize), Bitmap.bmWidth*Bitmap.bmHeight*3);
           for(int i=0; i<Bitmap.bmWidth*Bitmap.bmHeight; i++)
           {
                   ch=pData[i*3];
                   pData[i*3]=pData[i*3+2];
                   pData[i*3+2]=ch;
           }
   }
   /*
   //创建位图文件   
   fh = CreateFile(lpFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);
   if (fh == INVALID_HANDLE_VALUE)
      return FALSE;

   // 设置位图文件头
   bmfHdr.bfType = 0x4D42;  // "BM"
   dwDIBSize    = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + dwPaletteSize + dwBmBitsSize;  
   bmfHdr.bfSize = dwDIBSize;
   bmfHdr.bfReserved1 = 0;
   bmfHdr.bfReserved2 = 0;
   bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER) + dwPaletteSize;
  
   // 写入位图文件
   WriteFile(fh, (LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER), &dwWritten, NULL);
   // 写入位图文件其余内容
   WriteFile(fh, (LPSTR)lpbi, dwDIBSize, &dwWritten, NULL);
   CloseHandle(fh);

   tempImage=new AUX_RGBImageRec;
   tempImage->data=((unsigned char*) ((LPBITMAPINFO)lpbi) + (WORD) (((LPBITMAPINFO)lpbi)->bmiHeader.biSize));
   tempImage->sizeX=Bitmap.bmWidth;
   tempImage->sizeY=Bitmap.bmHeight;
   WriteBmp(tempImage->data, tempImage->sizeX, tempImage->sizeY, lpFileName);
*/

   //清除   
   GlobalUnlock(hDib);
   GlobalFree(hDib);
   
   return TRUE;
}

int WriteBmp(unsigned char *image, int xsize, int ysize, char *filename)
{
    unsigned char header[54] = {
      0x42, 0x4d, 0, 0, 0, 0, 0, 0, 0, 0,
        54, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 24, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0
    };
   
    long file_size = (long)xsize * (long)ysize * 3 + 56;
    header[2] = (unsigned char)(file_size &0x000000ff);
    header[3] = (file_size >> 8) & 0x000000ff;
    header[4] = (file_size >> 16) & 0x000000ff;
    header[5] = (file_size >> 24) & 0x000000ff;
   
    long width = xsize;
    header[18] = width & 0x000000ff;
    header[19] = (width >> 8) &0x000000ff;
    header[20] = (width >> 16) &0x000000ff;
    header[21] = (width >> 24) &0x000000ff;
   
    long height = ysize;
    header[22] = height &0x000000ff;
    header[23] = (height >> 8) &0x000000ff;
    header[24] = (height >> 16) &0x000000ff;
    header[25] = (height >> 24) &0x000000ff;
   
    FILE *fp;
    if (!(fp = fopen(filename, "wb")))
      return -1;
      
    fwrite(header, sizeof(unsigned char), 54, fp);
    fwrite(image, sizeof(unsigned char), (size_t)(long)xsize * ysize * 3, fp);

    fclose(fp);
    return 0;
}
pplander 评论于2007-11-19 16:20:12
恩,我去试一试,
不过有没有简单点的方法可以直接获取VP窗口的内容?
tan_dunming 评论于2007-11-19 18:59:53
PrtScrSysRq
追求卓越
muyekey 评论于2007-11-20 21:02:31
好东西,顶

手机版|VR开发网 统计 津ICP备18009691号
网安备12019202000257

GMT+8, 2021-9-23 11:16 AM

返回顶部