在偶然中发现Qt程序自带的粘贴板无法正常获取OutLook邮箱中邮件里的图片,获取的图片都不是原图(现象:图片丢失了一部分)。
使用Windows API方法成功解决。(库要加 user32.lib,头文件 windows.h)
代码如下:
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152/*! * brief 使用windows api获取粘贴板中的图片(不支持粘贴板复制的本地文件) * param filePath 保存文件路径 */ bool Tool::getWindowsClipboardBmpFile(const QString &filePath) { HWND hWnd = GetDesktopWindow(); // 获取安全窗口句柄 ::OpenClipboard(hWnd); // 打开剪贴板 HANDLE hBitmap = ::GetClipboardData(CF_BITMAP); // 获取剪贴板数据句柄 HDC hDC = ::GetDC(hWnd); // 获取设备环境句柄 HDC hdcMem = CreateCompatibleDC(hDC); // 创建与设备相关的内存环境 SelectObject(hdcMem, hBitmap); // 选择对象 SetMapMode(hdcMem, GetMapMode(hDC)); // 设置映射模式 BITMAP csBitmap; // 得到位图对象 int index = GetObject(hBitmap, sizeof(BITMAP), &csBitmap); if(hBitmap) { unsigned long n_BPP, n_Width, n_Height; if(index) { n_Width = (unsigned long)csBitmap.bmWidth; n_Height = (unsigned long)csBitmap.bmHeight; n_BPP = (unsigned long)csBitmap.bmBitsPixel; long sz = csBitmap.bmWidth*csBitmap.bmHeight*(csBitmap.bmBitsPixel>>3); csBitmap.bmBits = (void *) new BYTE[sz]; GetBitmapBits((HBITMAP)hBitmap, sz, csBitmap.bmBits); qDebug()<< "图片属性为:"<< n_Width<< n_Height<< n_BPP<< csBitmap.bmBits; } else { delete csBitmap.bmBits; csBitmap.bmBits = nullptr; DeleteObject(hBitmap); ::ReleaseDC(hWnd, hDC); // 释放设备环境句柄 DeleteDC(hdcMem); // 删除内存环境 ::CloseClipboard(); // 关闭剪贴板 qDebug()<< "剪贴板缓冲区中的对象无效"; return false; } DWORD *lp_Canvas = new DWORD[ n_Width * n_Height]; if (n_BPP == 32) { for(unsigned long y = 0; y < n_Height; y ++) { for(unsigned long x = 0; x < n_Width; x ++) { RGBQUAD * rgb = ((RGBQUAD *) ((char*)(csBitmap.bmBits) + csBitmap.bmWidthBytes*y + x*sizeof(DWORD))); lp_Canvas[(n_Height - 1 - y)*n_Width + x] = *((DWORD *)rgb); } } } else if(n_BPP == 24) { for(unsigned long y = 0; y < n_Height; y ++) { for(unsigned long x = 0; x < n_Width; x ++) { RGBTRIPLE rgbi = *((RGBTRIPLE *) ((char*)(csBitmap.bmBits) + csBitmap.bmWidthBytes*y + x*3)); RGBQUAD rgbq; rgbq.rgbRed = rgbi.rgbtRed; rgbq.rgbGreen = rgbi.rgbtGreen; rgbq.rgbBlue = rgbi.rgbtBlue; lp_Canvas[(n_Height - 1 - y)*n_Width + x] = *((DWORD *)(&rgbq)); } } } unsigned long n_Bits = 32; FILE *pFile = fopen(filePath.toLatin1().data(), "wb"); if(pFile == nullptr) { delete csBitmap.bmBits; csBitmap.bmBits = nullptr; delete lp_Canvas; lp_Canvas = nullptr; pFile = nullptr; DeleteObject(hBitmap); ::ReleaseDC(hWnd, hDC); // 释放设备环境句柄 DeleteDC(hdcMem); // 删除内存环境 ::CloseClipboard(); // 关闭剪贴板 qDebug()<< "文件打开失败"; return false; } // 保存位图文件头 BITMAPFILEHEADER fileHeader; fileHeader.bfType = 0x4d42; fileHeader.bfSize = 0; fileHeader.bfReserved1 = 0; fileHeader.bfReserved2 = 0; fileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER); fwrite((char*)&fileHeader, sizeof(fileHeader), 1, pFile); // 保存位图信息标题 BITMAPINFOHEADER infoHeader; infoHeader.biSize = sizeof(infoHeader); infoHeader.biWidth = n_Width; infoHeader.biHeight = n_Height; infoHeader.biPlanes = 1; infoHeader.biBitCount = (unsigned short)( n_Bits & 0xffff); infoHeader.biCompression = BI_RGB; infoHeader.biSizeImage = 0; infoHeader.biXPelsPerMeter = 0; infoHeader.biYPelsPerMeter = 0; infoHeader.biClrUsed = 0; infoHeader.biClrImportant = 0; fwrite((char*)&infoHeader, sizeof(infoHeader), 1, pFile); fwrite((char*)lp_Canvas, 1, (n_Bits >> 3) * n_Width*n_Height, pFile); fclose(pFile); delete csBitmap.bmBits; csBitmap.bmBits = nullptr; delete lp_Canvas; lp_Canvas = nullptr; pFile = nullptr; DeleteObject(hBitmap); ::ReleaseDC(hWnd, hDC); // 释放设备环境句柄 DeleteDC(hdcMem); // 删除内存环境 ::CloseClipboard(); // 关闭剪贴板 } else { qDebug()<< "粘贴板的缓冲区中没有BMP任何内容"; DeleteObject(hBitmap); ::ReleaseDC(hWnd, hDC); // 释放设备环境句柄 DeleteDC(hdcMem); // 删除内存环境 ::CloseClipboard(); // 关闭剪贴板 return false; } return true; }
最后
以上就是舒适大碗最近收集整理的关于Qt 粘贴板获取图片不全,使用windows api 获取粘贴板图片的全部内容,更多相关Qt内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复