我是靠谱客的博主 舒适大碗,最近开发中收集的这篇文章主要介绍Qt 粘贴板获取图片不全,使用windows api 获取粘贴板图片,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

在偶然中发现Qt程序自带的粘贴板无法正常获取OutLook邮箱中邮件里的图片,获取的图片都不是原图(现象:图片丢失了一部分)。

使用Windows API方法成功解决。(库要加 user32.lib,头文件 windows.h)
代码如下:

/*!
* 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 粘贴板获取图片不全,使用windows api 获取粘贴板图片所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(75)

评论列表共有 0 条评论

立即
投稿
返回
顶部