HDC在MSDN中的全称为:The handle of device context。通常,我们都是用来做相应的显示操作。
    
    熟悉WIN32的朋友对于其应该不会陌生,经常采用GetDC,GetWindowDC等等来获取其句柄。而用得最多的,可能就是BeginPaint,如:

  1. case WM_PAINT:
  2. HDC hdc = BeginPaint(hWnd,&ps);
  3. ...
  4. EndPaint(hdc,&ps);
  5. break;
  1. case WM_PAINT:      HDC hdc = BeginPaint(hWnd,&ps);     ...     EndPaint(hdc,&ps);      break;

使用起来非常简单,但如果想将其内容保存为普通的图像文档,可就没那么容易。确切地说,在只知道HDC句柄的情况下,我们是无法保存其内容的;但我们可以剑走偏锋,将HDC的内容写到一个缓存中,然后我们再保存该缓存的内容即可。
   
   听起来很简单,却又像很复杂,不是么?没关系,我们现在一步一步来。
   
   
   首先,我们需要一个HDC的句柄。如同前面所说,你可以有多种方法,比如GetDC,GetWindowDC,甚至是CreateDC。反正呢,你用什么方法我不管,我只要有一个HDC的句柄就好了。
   
   有了HDC的句柄,接下来我们所需要做的是,知道这HDC的大小,也就是宽度和长度。这个不难,我们只要简单地调用GetDeviceCaps,然后参数给予HORZRES或VERTRES即可:

  1. int iWidth = GetDeviceCaps(hdc,HORZRES);
  2. int iHeight = GetDeviceCaps(hdc,VERTRES);
  1. int iWidth = GetDeviceCaps(hdc,HORZRES);    int iHeight = GetDeviceCaps(hdc,VERTRES);

为什么要知道大小呢?因为我们要用它来创建缓存。而这缓存,说白了,其实就是一个BMP格式的数据结构而已。
    
    为了创建这个关键的缓存,我们必须调用CreateDIBSection函数,而该函数形参又用到BITMAPINFOHEADER,所以我们的一切,就先从填充该结构体开始。
    
    该结构体定义如下:

  1. typedef struct tagBITMAPINFO
  2. {
  3. BITMAPINFOHEADER bmiHeader;
  4. RGBQUAD bmiColors[1];
  5. } BITMAPINFO;
  1. typedef struct tagBITMAPINFO    {       BITMAPINFOHEADER bmiHeader;       RGBQUAD bmiColors[1];     } BITMAPINFO;

结构体里面还有一个BITMAPINFOHEADER,其定义如下:

  1. typedef struct tagBITMAPINFOHEADER
  2. {
  3. DWORD biSize;
  4. LONG biWidth;
  5. LONG biHeight;
  6. WORD biPlanes;
  7. WORD biBitCount
  8. DWORD biCompression;
  9. DWORD biSizeImage;
  10. LONG biXPelsPerMeter;
  11. LONG biYPelsPerMeter;
  12. DWORD biClrUsed;
  13. DWORD biClrImportant;
  14. } BITMAPINFOHEADER;
  1. typedef struct tagBITMAPINFOHEADER     {       DWORD biSize;       LONG biWidth;       LONG biHeight;       WORD biPlanes;       WORD biBitCount       DWORD biCompression;       DWORD biSizeImage;       LONG biXPelsPerMeter;       LONG biYPelsPerMeter;       DWORD biClrUsed;       DWORD biClrImportant;     } BITMAPINFOHEADER;

这么多变量,是不是有点头晕?大可不必紧张,其实我们只需要填充其中几个,其它统统置为0即可:

  1. BITMAPINFO bmpInfo = {0};
  2. bmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
  3. bmpInfo.bmiHeader.biWidth = iWidth;
  4. bmpInfo.bmiHeader.biHeight = iHeight;
  5. bmpInfo.bmiHeader.biPlanes = 1;
  6. bmpInfo.bmiHeader.biBitCount = 24;
  1. BITMAPINFO bmpInfo = {0};    bmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);    bmpInfo.bmiHeader.biWidth = iWidth;    bmpInfo.bmiHeader.biHeight = iHeight;    bmpInfo.bmiHeader.biPlanes = 1;    bmpInfo.bmiHeader.biBitCount = 24;

一切从最简单做起,对于BMP而言,最简单的自然是24位位图,这就是为什么biPlanes和biBitCount分别设置为1和24的原因。
    
    填充完BITMAPINFO结构,我们还是不能马上调用CreateDIBSection,因为形参中还有一个HDC。虽然我们可以直接采用已知的HDC句柄,但接下来还要将创建的HBITMAP和HDC相连接,所以我们还是先创建一个缓存DC:

  1. HDC hdcMem = CreateCompatibleDC(hdc);
  1. HDC hdcMem = CreateCompatibleDC(hdc);

一切准备就绪之后,就调用CreateDIBSection吧:

  1. BYTE *pData = NULL;
  2. hBmp = CreateDIBSection(hdcMem,&bmpInfo,DIB_RGB_COLORS,reinterpret_cast<VOID **>(&pData),NULL,0);
  1. BYTE *pData = NULL;    hBmp = CreateDIBSection(hdcMem,&bmpInfo,DIB_RGB_COLORS,reinterpret_cast<VOID **>(&pData),NULL,0);

pData是分配的一个内存空间,将来用来存储HDC的内容,只不过现在一切都是空的。如果你将这数据保存出来,你会发现一团漆黑。
    
    将HBITMAP和HDC结合:

  1. hOldObj = SelectObject(hdcMem, hBmp);
  1. hOldObj = SelectObject(hdcMem, hBmp);

至此为止,我们前期工作已经准备就绪,我们只需要将HDC的内容用BitBlt绘制到缓存中即可:

  1. BitBlt(hdcMem,
  2. 0,
  3. 0,
  4. iWidth,
  5. iHeight,
  6. hdc,
  7. 0,
  8. 0,
  9. SRCCOPY);
  1. BitBlt(hdcMem,           0,           0,           iWidth,           iHeight,           hdc,           0,           0,           SRCCOPY);

这里其实还有一个小技巧,如果你是想绘制HDC的某个区域,你只需要用StretchBlt替代即可:

  1. StretchBlt(hdcMem,
  2. 0,
  3. 0,
  4. iWidth,
  5. iHeight,
  6. hdc,
  7. rcDC.left,
  8. rcDC.top,
  9. rcDC.right - rcDC.left + 1,
  10. rcDC.bottom - rcDC.top + 1,
  11. SRCCOPY);
  1. StretchBlt(hdcMem,                0,                0,                iWidth,                iHeight,                hdc,                rcDC.left,                rcDC.top,                rcDC.right - rcDC.left + 1,                rcDC.bottom - rcDC.top + 1,                SRCCOPY);

喜欢追究问题的你,也许会发现,在调用该函数之后,pData所指向的内存缓冲区已经改变。是的,没错,这些改变的数据就是我们所需要的。接下来我们所需要做的仅仅是,将这数据按BMP文件的格式,保存下来即可。
    
    BMP文件格式其实很简单,最开始是文件头信息,然后是图片信息,接下来是数据。我们只需要按照这格式,顺序将数据写入即可。
    
    文件头信息和图片信息,微软已经为我们定义好了相应的结构体:
    
    BMP信息:

  1. typedef struct tagBITMAPINFOHEADER
  2. {
  3. DWORD biSize;
  4. LONG biWidth;
  5. LONG biHeight;
  6. WORD biPlanes;
  7. WORD biBitCount
  8. DWORD biCompression;
  9. DWORD biSizeImage;
  10. LONG biXPelsPerMeter;
  11. LONG biYPelsPerMeter;
  12. DWORD biClrUsed;
  13. DWORD biClrImportant;
  14. } BITMAPINFOHEADER;
  1. typedef struct tagBITMAPINFOHEADER     {       DWORD biSize;       LONG biWidth;       LONG biHeight;       WORD biPlanes;       WORD biBitCount       DWORD biCompression;       DWORD biSizeImage;       LONG biXPelsPerMeter;       LONG biYPelsPerMeter;       DWORD biClrUsed;       DWORD biClrImportant;     } BITMAPINFOHEADER;

文件头信息:

  1. typedef struct tagBITMAPFILEHEADER
  2. {
  3. WORD bfType;
  4. DWORD bfSize;
  5. WORD bfReserved1;
  6. WORD bfReserved2;
  7. DWORD bfOffBits;
  8. } BITMAPFILEHEADER;
  1. typedef struct tagBITMAPFILEHEADER     {      WORD bfType;       DWORD bfSize;       WORD bfReserved1;       WORD bfReserved2;       DWORD bfOffBits;     } BITMAPFILEHEADER;

我们首先填充这两个结构体数值:

  1. BITMAPINFOHEADER bmInfoHeader = {0};
  2. bmInfoHeader.biSize = sizeof(BITMAPINFOHEADER);
  3. bmInfoHeader.biWidth = iWidth;
  4. bmInfoHeader.biHeight = iHeight;
  5. bmInfoHeader.biPlanes = 1;
  6. bmInfoHeader.biBitCount = 24;
  7. //Bimap file header in order to write bmp file
  8. BITMAPFILEHEADER bmFileHeader = {0};
  9. bmFileHeader.bfType = 0x4d42;  //bmp
  10. bmFileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
  11. bmFileHeader.bfSize = bmFileHeader.bfOffBits + ((bmInfoHeader.biWidth * bmInfoHeader.biHeight) * 3); ///3=(24 / 8)
  1. BITMAPINFOHEADER bmInfoHeader = {0};    bmInfoHeader.biSize = sizeof(BITMAPINFOHEADER);    bmInfoHeader.biWidth = iWidth;    bmInfoHeader.biHeight = iHeight;    bmInfoHeader.biPlanes = 1;    bmInfoHeader.biBitCount = 24;        //Bimap file header in order to write bmp file    BITMAPFILEHEADER bmFileHeader = {0};    bmFileHeader.bfType = 0x4d42;  //bmp      bmFileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);    bmFileHeader.bfSize = bmFileHeader.bfOffBits + ((bmInfoHeader.biWidth * bmInfoHeader.biHeight) * 3); ///3=(24 / 8)

接下来的事情,估计大家都轻车熟路了。创建文件,然后写入数据,保存,完毕。

  1. HANDLE hFile = CreateFile(strFile.c_str(),GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
  2. DWORD dwWrite = 0;
  3. WriteFile(hFile,&bmFileHeader,sizeof(BITMAPFILEHEADER),&dwWrite,NULL);
  4. WriteFile(hFile,&bmInfoHeader, sizeof(BITMAPINFOHEADER),&dwWrite,NULL);
  5. WriteFile(hFile,&vtData[0], vtData.size(),&dwWrite,NULL);
  6. CloseHandle(hFile);
  1. HANDLE hFile = CreateFile(strFile.c_str(),GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);    DWORD dwWrite = 0;    WriteFile(hFile,&bmFileHeader,sizeof(BITMAPFILEHEADER),&dwWrite,NULL);    WriteFile(hFile,&bmInfoHeader, sizeof(BITMAPINFOHEADER),&dwWrite,NULL);    WriteFile(hFile,&vtData[0], vtData.size(),&dwWrite,NULL);    CloseHandle(hFile);

文章的最后,是参考源代码:

  1. #ifdef UNICODE
  2. #ifndef TSTRING
  3. #define TSTRING std::wstring
  4. #endif
  5. #else
  6. #ifndef TSTRING
  7. #define TSTRING std::string
  8. #endif
  9. #endif
  10. BOOL WriteBmp(const TSTRING &strFile,const std::vector<BYTE> &vtData,const SIZE &sizeImg);
  11. BOOL WriteBmp(const TSTRING &strFile,HDC hdc);
  12. BOOL WriteBmp(const TSTRING &strFile,HDC hdc,const RECT &rcDC);
  13. BOOL WriteBmp(const TSTRING &strFile,const std::vector<BYTE> &vtData,const SIZE &sizeImg)
  14. {
  15. BITMAPINFOHEADER bmInfoHeader = {0};
  16. bmInfoHeader.biSize = sizeof(BITMAPINFOHEADER);
  17. bmInfoHeader.biWidth = sizeImg.cx;
  18. bmInfoHeader.biHeight = sizeImg.cy;
  19. bmInfoHeader.biPlanes = 1;
  20. bmInfoHeader.biBitCount = 24;
  21. //Bimap file header in order to write bmp file
  22. BITMAPFILEHEADER bmFileHeader = {0};
  23. bmFileHeader.bfType = 0x4d42;  //bmp
  24. bmFileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
  25. bmFileHeader.bfSize = bmFileHeader.bfOffBits + ((bmInfoHeader.biWidth * bmInfoHeader.biHeight) * 3); ///3=(24 / 8)
  26. HANDLE hFile = CreateFile(strFile.c_str(),GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
  27. if(hFile == INVALID_HANDLE_VALUE)
  28. {
  29. return FALSE;
  30. }
  31. DWORD dwWrite = 0;
  32. WriteFile(hFile,&bmFileHeader,sizeof(BITMAPFILEHEADER),&dwWrite,NULL);
  33. WriteFile(hFile,&bmInfoHeader, sizeof(BITMAPINFOHEADER),&dwWrite,NULL);
  34. WriteFile(hFile,&vtData[0], vtData.size(),&dwWrite,NULL);
  35. CloseHandle(hFile);
  36. return TRUE;
  37. }
  38. BOOL WriteBmp(const TSTRING &strFile,HDC hdc)
  39. {
  40. int iWidth = GetDeviceCaps(hdc,HORZRES);
  41. int iHeight = GetDeviceCaps(hdc,VERTRES);
  42. RECT rcDC = {0,0,iWidth,iHeight};
  43. return WriteBmp(strFile,hdc,rcDC);
  44. }
  45. BOOL WriteBmp(const TSTRING &strFile,HDC hdc,const RECT &rcDC)
  46. {
  47. BOOL bRes = FALSE;
  48. BITMAPINFO bmpInfo = {0};
  49. BYTE *pData = NULL;
  50. SIZE sizeImg = {0};
  51. HBITMAP hBmp = NULL;
  52. std::vector<BYTE> vtData;
  53. HGDIOBJ hOldObj = NULL;
  54. HDC hdcMem = NULL;
  55. //Initilaize the bitmap information
  56. bmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
  57. bmpInfo.bmiHeader.biWidth = rcDC.right - rcDC.left;
  58. bmpInfo.bmiHeader.biHeight = rcDC.bottom - rcDC.top;
  59. bmpInfo.bmiHeader.biPlanes = 1;
  60. bmpInfo.bmiHeader.biBitCount = 24;
  61. //Create the compatible DC to get the data
  62. hdcMem = CreateCompatibleDC(hdc);
  63. if(hdcMem == NULL)
  64. {
  65. goto EXIT;
  66. }
  67. //Get the data from the memory DC
  68. hBmp = CreateDIBSection(hdcMem,&bmpInfo,DIB_RGB_COLORS,reinterpret_cast<VOID **>(&pData),NULL,0);
  69. if(hBmp == NULL)
  70. {
  71. goto EXIT;
  72. }
  73. hOldObj = SelectObject(hdcMem, hBmp);
  74. //Draw to the memory DC
  75. sizeImg.cx = bmpInfo.bmiHeader.biWidth;
  76. sizeImg.cy = bmpInfo.bmiHeader.biHeight;
  77. StretchBlt(hdcMem,
  78. 0,
  79. 0,
  80. sizeImg.cx,
  81. sizeImg.cy,
  82. hdc,
  83. rcDC.left,
  84. rcDC.top,
  85. rcDC.right - rcDC.left + 1,
  86. rcDC.bottom - rcDC.top + 1,
  87. SRCCOPY);
  88. vtData.resize(sizeImg.cx * sizeImg.cy * 3);
  89. memcpy(&vtData[0],pData,vtData.size());
  90. bRes = WriteBmp(strFile,vtData,sizeImg);
  91. SelectObject(hdcMem, hOldObj);
  92. EXIT:
  93. if(hBmp != NULL)
  94. {
  95. DeleteObject(hBmp);
  96. }
  97. if(hdcMem != NULL)
  98. {
  99. DeleteDC(hdcMem);
  100. }
  101. return bRes;
  102. }
  1. #ifdef UNICODE#ifndef TSTRING#define TSTRING std::wstring#endif#else#ifndef TSTRING#define TSTRING std::string#endif#endifBOOL WriteBmp(const TSTRING &strFile,const std::vector<BYTE> &vtData,const SIZE &sizeImg);BOOL WriteBmp(const TSTRING &strFile,HDC hdc);BOOL WriteBmp(const TSTRING &strFile,HDC hdc,const RECT &rcDC);BOOL WriteBmp(const TSTRING &strFile,const std::vector<BYTE> &vtData,const SIZE &sizeImg) { BITMAPINFOHEADER bmInfoHeader = {0};bmInfoHeader.biSize = sizeof(BITMAPINFOHEADER);bmInfoHeader.biWidth = sizeImg.cx;bmInfoHeader.biHeight = sizeImg.cy;bmInfoHeader.biPlanes = 1;bmInfoHeader.biBitCount = 24;//Bimap file header in order to write bmp fileBITMAPFILEHEADER bmFileHeader = {0};bmFileHeader.bfType = 0x4d42;  //bmp  bmFileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);bmFileHeader.bfSize = bmFileHeader.bfOffBits + ((bmInfoHeader.biWidth * bmInfoHeader.biHeight) * 3); ///3=(24 / 8)HANDLE hFile = CreateFile(strFile.c_str(),GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);if(hFile == INVALID_HANDLE_VALUE){return FALSE;}DWORD dwWrite = 0;WriteFile(hFile,&bmFileHeader,sizeof(BITMAPFILEHEADER),&dwWrite,NULL);WriteFile(hFile,&bmInfoHeader, sizeof(BITMAPINFOHEADER),&dwWrite,NULL);WriteFile(hFile,&vtData[0], vtData.size(),&dwWrite,NULL);CloseHandle(hFile);return TRUE;} BOOL WriteBmp(const TSTRING &strFile,HDC hdc){int iWidth = GetDeviceCaps(hdc,HORZRES);int iHeight = GetDeviceCaps(hdc,VERTRES);RECT rcDC = {0,0,iWidth,iHeight};return WriteBmp(strFile,hdc,rcDC);}BOOL WriteBmp(const TSTRING &strFile,HDC hdc,const RECT &rcDC){BOOL bRes = FALSE;BITMAPINFO bmpInfo = {0};BYTE *pData = NULL;SIZE sizeImg = {0};HBITMAP hBmp = NULL;std::vector<BYTE> vtData;HGDIOBJ hOldObj = NULL;HDC hdcMem = NULL;//Initilaize the bitmap informationbmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);bmpInfo.bmiHeader.biWidth = rcDC.right - rcDC.left;bmpInfo.bmiHeader.biHeight = rcDC.bottom - rcDC.top;bmpInfo.bmiHeader.biPlanes = 1;bmpInfo.bmiHeader.biBitCount = 24;//Create the compatible DC to get the datahdcMem = CreateCompatibleDC(hdc);if(hdcMem == NULL){goto EXIT;}//Get the data from the memory DChBmp = CreateDIBSection(hdcMem,&bmpInfo,DIB_RGB_COLORS,reinterpret_cast<VOID **>(&pData),NULL,0);if(hBmp == NULL){goto EXIT;}hOldObj = SelectObject(hdcMem, hBmp);//Draw to the memory DCsizeImg.cx = bmpInfo.bmiHeader.biWidth;sizeImg.cy = bmpInfo.bmiHeader.biHeight;StretchBlt(hdcMem,0,0,sizeImg.cx,sizeImg.cy,hdc,rcDC.left,rcDC.top,rcDC.right - rcDC.left + 1,rcDC.bottom - rcDC.top + 1,SRCCOPY);vtData.resize(sizeImg.cx * sizeImg.cy * 3);memcpy(&vtData[0],pData,vtData.size());bRes = WriteBmp(strFile,vtData,sizeImg);SelectObject(hdcMem, hOldObj);EXIT:if(hBmp != NULL){DeleteObject(hBmp);}if(hdcMem != NULL){DeleteDC(hdcMem);}return bRes;}

一共有三个WriteBmp函数,使用上非常简单。
    
    比如,我想保存一个HDC,只需要简单地调用:

  1. HDC hdc = GetDC(NULL);
  2. WriteBmp(TEXT("//NAND//DCSave.bmp"));
  3. ReleaseDC(NULL,hdc);
  1. HDC hdc = GetDC(NULL);    WriteBmp(TEXT("//NAND//DCSave.bmp"));    ReleaseDC(NULL,hdc);

如果想保存HDC的某一个部分,同样也很简单:

  1. HDC hdc = GetDC(NULL);
  2. RECT rcDC = {0,0,100,100};
  3. WriteBmp(TEXT("//NAND//DCSavePart.bmp"),rcDC);
  4. ReleaseDC(NULL,hdc);
  1. HDC hdc = GetDC(NULL);    RECT rcDC = {0,0,100,100};    WriteBmp(TEXT("//NAND//DCSavePart.bmp"),rcDC);    ReleaseDC(NULL,hdc);

这个函数还能做到一个很有意思的功能,就是截取屏幕。对于屏幕来说,也是一个HDC,我们只要获取屏幕的HDC句柄,剩下的就没有什么难度了:

  1. HDC hdc = CreateDC(_T("DISPLAY"), NULL, NULL, NULL);
  2. WriteBmp(TEXT("//NAND//ScreenCapture.BMP"),hdc);
  3. DeleteDC(hdc);

将HDC保存为BMP文件的更多相关文章

  1. [原]将BITMAPINFO保存成bmp文件,以及渲染到设备

    /* class Image { public: Image() = delete; Image(const uint32_t& _w, const uint32_t& _h) :w( ...

  2. 使用ffmpeg将BMP图片编码为x264视频文件,将H264视频保存为BMP图片,yuv视频文件保存为图片的代码

    ffmpeg开源库,实现将bmp格式的图片编码成x264文件,并将编码好的H264文件解码保存为BMP文件. 实现将视频文件yuv格式保存的图片格式的測试,图像格式png,jpg, gif等等測试均O ...

  3. OpenGL(十) 截屏并保存BMP文件

    BMP文件格式 BMP图像又称为Bitmap(位图),是Windows系统中广泛采用的图像格式.BMP文件的数据按照从文件头开始的先后顺序分为四个部分: 我们一般见到的图像以24位图像为主,即R.G. ...

  4. 1.1.0-学习Opencv与MFC混合编程之---全屏截图,保存为BMP图像(并增加快捷键)

    源代码:http://download.csdn.net/detail/nuptboyzhb/3961677 Ø  添加全屏截图菜单项,菜单项的属性如下; Ø  为该菜单项建立类向导. 编辑消息处理函 ...

  5. 【VC++技术杂谈006】截取电脑桌面并将其保存为bmp图片

    本文主要介绍如何截取电脑桌面并将其保存为bmp图片. 1. Bmp图像文件组成 Bmp是Windows操作系统中的标准图像文件格式. Bmp图像文件由四部分组成: (1)位图头文件数据结构,包含Bmp ...

  6. 图像预处理第9步:存为.bmp文件

    //图像预处理第9步:将最终标准化后的字符图像分为单个单个的HDIB保存,并存为.bmp文件 void CChildView::OnImgprcToDibAndSave() { unsigned ch ...

  7. BMP文件解析

    目录 BMP文件简介 BMP文件格式 位图头 位图信息 调色板 位图数据 C语言代码 获取文件大小 获取文件尺寸 获取文件偏移量 读取文件数据示例 一个问题 完整程序 BMP文件简介 BMP(全称Bi ...

  8. 二维码图片以字符串的形式保存DB,已文件流显示页面上

    以下是生成二维码的方法,我只用其中一个方法 这个需要引用ZXing.DLL 链接:https://pan.baidu.com/s/1mCTwHiAm_awtsPcibAotZw 提取码:ufp6 pu ...

  9. [ATL/WTL]_[中级]_[保存CBitmap到文件-保存屏幕内容到文件]

    场景: 1. 在做图片处理时,比方放大后或加特效后须要保存CBitmap(HBITMAP)到文件. 2.截取屏幕内容到文件时. 3.不须要增加第3方库时. 说明: 这段代码部分来自网上.第一次学atl ...

随机推荐

  1. uva 10763 Foreign Exchange(排序比较)

    题目连接:10763 Foreign Exchange 题目大意:给出交换学生的原先国家和所去的国家,交换成功的条件是如果A国给B国一个学生,对应的B国也必须给A国一个学生,否则就是交换失败. 解题思 ...

  2. android UI进阶之用ViewPager实现欢迎引导页面[转]

    ViewPager需要android-support-v4.jar这个包的支持,来自google提供的一个附加包.大家搜下即可. ViewPager主要用来组织一组数据,并且通过左右滑动的方式来展示. ...

  3. XMLHttpRequest对象的使用

    1.首先要创建XMLHttpRequest对象,这个对象是前台与后台进行异步的重要对象,现在的浏览器有很多种,创建 XMLHttpRequest 的方法也不相同,所以为了兼容各种浏览器,在创建XMLH ...

  4. ASP.NET性能监视参数详解

    性能监视器- Performance Monitor 性能监视器是Windows自带的系统资源和性能监视工具. 性能监视器能够量化地提供CPU使用率, 内存分配状况, 异常派发情况, 线程调度频率等信 ...

  5. final, finally, finalize 的区别

    1.final 用于声明属性, 方法和类, 分别表示属性不可变, 方法不可覆盖, 类不可继承.内部类要访问局部变量, 局部变量必须定义成 final 类型, 例如, 一段代码…… 2.finally ...

  6. 5.7.1.3 Global 对象的属性

    Global对象还包含了一些属性,例如,特殊的值undefined.NaN以及Infinity都是Global对象的属性.此外,所有原生引用类型的构造函数,像Object和Function,也都是Gl ...

  7. nrf51 官方PWM库

    地址:https://github.com/NordicSemiconductor/nrf51-pwm-library nrf_pwm_init函数 初始化PWM参数 设置输出pwm的gpio pin ...

  8. mybatis配置方法

    首先导入mybatis-3.1.1.jar包以及Mysql-connector-java-5.1.6-bin.jar包 新建一个数据库 create database mybatis; use myb ...

  9. 射频识别技术漫谈(15)——Mifare1的安全性及7字节序列号M1卡

    Mifare1的安全性主要指卡中数据的安全性,要求卡中的数据不能被非法修改或窃听.数据的安全性主要使用加密技术来保证,加密技术有两个关键因素:加密算法和密钥.现代加密技术的一大特点是加密算法公开,如果 ...

  10. 射频识别技术漫谈(9)——动物标签HDX

    半双工(HDX,Half Duplex)技术是ISO11784/11785中规定的另一种标签与读写器之间的通讯方式.读写器先打开射频场对标签充电以激活标签,然后关闭磁场,标签在读写器磁场关闭的情况下向 ...