| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293 |
- #include "CBitmapHelper.h"
- #include "../pch/pch.h"
- CBitmapHelper::CBitmapHelper()
- {
- }
- CBitmapHelper::~CBitmapHelper()
- {
- }
- int CBitmapHelper::SaveBitmapToFile(HBITMAP hBitmap, LPCWSTR lpFileName) //hBitmap 为刚才的屏幕位图句柄
- {
- //lpFileName 为位图文件名
- WORD wBitCount; //位图中每个像素所占字节数
- //定义调色板大小,位图中像素字节大小,位图文件大小,写入文件字节数
- DWORD dwPaletteSize = 0, dwBmBitsSize, dwDIBSize, dwWritten;
- BITMAP Bitmap; //位图属性结构
- BITMAPFILEHEADER bmfHdr; //位图文件头结构
- BITMAPINFOHEADER bi; //位图信息头结构
- HANDLE fh; //定义文件,分配内存句柄,调色板句柄
- LPSTR lpbk, lpmem;
- wBitCount = 32;
- //设置位图信息头结构
- 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;
- //创建位图文件
- 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) + dwBmBitsSize;
- bmfHdr.bfSize = dwDIBSize;
- bmfHdr.bfReserved1 = 0;
- bmfHdr.bfReserved2 = 0;
- bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER);
- //写入位图文件头
- WriteFile(fh, (LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER), &dwWritten, NULL);
- //写入位图信息头
- WriteFile(fh, (LPSTR)&bi, sizeof(BITMAPINFOHEADER), &dwWritten, NULL);
- //获取位图阵列
- lpmem = new char[dwBmBitsSize];
- lpbk = (LPSTR) new char[dwBmBitsSize];
- GetBitmapBits(hBitmap, dwBmBitsSize, lpmem);//正向的内存图象数据
- //转化为倒向数据(仅在bmHeight为正时需要)
- for(int i = 0; i < Bitmap.bmHeight; i++)
- {
- memcpy(lpbk + Bitmap.bmWidth * i * 4, lpmem + Bitmap.bmWidth * (Bitmap.bmHeight - i - 1) * 4, Bitmap.bmWidth * 4);
- }
- //写位图数据
- WriteFile(fh, lpbk, dwBmBitsSize, &dwWritten, NULL);
- //清除
- delete[]lpbk;
- delete[]lpmem;
- CloseHandle(fh);
- return TRUE;
- }
- HBITMAP CBitmapHelper::Scale(HBITMAP srcBitmap, int MaxWidth, int MaxHeight)
- {
- BITMAP Bitmap;
- GetObject(srcBitmap, sizeof(BITMAP), (LPSTR)&Bitmap);
- int srcWidth = Bitmap.bmWidth;
- int srcHeight = Bitmap.bmHeight;
- double scaleX = (double)srcWidth / MaxWidth;
- double scaleY = (double)srcHeight / MaxHeight;
- double realScale;
- if(scaleX > scaleY)
- {
- realScale = scaleX;
- }
- else
- {
- realScale = scaleY;
- }
- int newWidth = (int)(srcWidth / realScale);
- int newHeight = (int)(srcHeight / realScale);
- HDC hSrcDC = ::CreateCompatibleDC(NULL);
- SelectObject(hSrcDC, srcBitmap);
- HDC hMemDC = CreateCompatibleDC(hSrcDC);
- //创建一个与屏幕设备描述表兼容的位图
- HBITMAP hNewBitmap = CreateCompatibleBitmap(hSrcDC, newWidth, newHeight);
- //把新位图选到内存设备描述表中
- HBITMAP hOldBitmap = (HBITMAP)SelectObject(hMemDC, hNewBitmap);
- ::StretchBlt(hMemDC, 0, 0, newWidth, newHeight, hSrcDC, 0, 0, srcWidth, srcHeight, SRCCOPY);
- hNewBitmap = (HBITMAP)SelectObject(hMemDC, hOldBitmap);
- return hNewBitmap;
- }
- HBITMAP CBitmapHelper::CopyScreenToBitmap(LPRECT lpRect) //lpRect 代表选定区域
- {
- HDC hScrDC, hMemDC; //屏幕和内存设备描述表
- HBITMAP hBitmap, hOldBitmap;//位图句柄
- int nX, nY, nX2, nY2; //选定区域坐标
- int nWidth, nHeight; //位图宽度和高度
- int xScrn, yScrn; //屏幕宽度和高度
- //确保选定区域不为空矩形
- if(IsRectEmpty(lpRect))
- {
- return NULL;
- }
- //为屏幕创建设备描述表
- hScrDC = CreateDC(L"DISPLAY", NULL, NULL, NULL);
- //为屏幕设备描述表创建兼容的内存设备描述表
- hMemDC = CreateCompatibleDC(hScrDC); //或者::CreateCompatibleDC(NULL)
- //获得选定区域坐标
- 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;
- //创建一个与屏幕设备描述表兼容的位图
- hBitmap = CreateCompatibleBitmap(hScrDC, nWidth, nHeight);
- //把新位图选到内存设备描述表中
- 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; //返回位图句柄
- }
- bool CBitmapHelper::OcrRect(tesseract::TessBaseAPI& tess, LPRECT lpRect, std::string& result)
- {
- HDC hScrDC, hMemDC; //屏幕和内存设备描述表
- HBITMAP hBitmap, hOldBitmap;//位图句柄
- int nX, nY, nX2, nY2; //选定区域坐标
- int nWidth, nHeight; //位图宽度和高度
- int xScrn, yScrn; //屏幕宽度和高度
- //确保选定区域不为空矩形
- if(IsRectEmpty(lpRect))
- {
- return false;
- }
- //为屏幕创建设备描述表
- hScrDC = CreateDC(L"DISPLAY", NULL, NULL, NULL);
- //为屏幕设备描述表创建兼容的内存设备描述表
- hMemDC = CreateCompatibleDC(hScrDC); //或者::CreateCompatibleDC(NULL)
- //获得选定区域坐标
- 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;
- //创建一个与屏幕设备描述表兼容的位图
- hBitmap = CreateCompatibleBitmap(hScrDC, nWidth, nHeight);
- //把新位图选到内存设备描述表中
- hOldBitmap = (HBITMAP)SelectObject(hMemDC, hBitmap);
- BITMAP bm;
- GetObject(hBitmap, sizeof(BITMAP), &bm);
- BITMAPINFOHEADER bi = { 0 };
- bi.biSize = sizeof(BITMAPINFOHEADER);
- bi.biWidth = bm.bmWidth;
- bi.biHeight = bm.bmHeight;
- bi.biPlanes = bm.bmPlanes;
- bi.biBitCount = bm.bmBitsPixel;
- bi.biCompression = BI_RGB;
- bi.biSizeImage = bm.bmHeight * bm.bmWidthBytes;
- //把屏幕设备描述表拷贝到内存设备描述表中
- BitBlt(hMemDC, 0, 0, nWidth, nHeight, hScrDC, nX, nY, SRCCOPY);
- char* lpmem = new char[bi.biSizeImage];
- //正向的内存图象数据
- GetBitmapBits(hBitmap, bi.biSizeImage, lpmem);
- //清除
- DeleteDC(hScrDC);
- DeleteDC(hMemDC);
- //开始测试ocr
- tess.SetImage((const unsigned char*)lpmem, bm.bmWidth, bm.bmHeight, 4, bm.bmWidthBytes);
- tess.Recognize(0);
- result = tess.GetUTF8Text();
- delete[] lpmem;
- tess.Clear();
- return true;
- }
|