wps表格插件菜单栏在高分辨率下图片显示模糊
wps插件图标显示模糊问题,目前看下来和图片没关系
1.目前Excel使用OleCreatePictureIndirect直接加载转换IPictureDisp对象返回给excel菜单显示
2.wps直接使用OleCreatePictureIndirect来创建图片显示不出来,wps不兼容png图片,目前采用的方式通过GDI绘制将png先转换成bmp格式的流,在通过OleLoadPicture将流转换成IPictureDisp对象给wps显示。尝试了直接加载bmp格式的图片,看下来效果还是一样
3.研究了国产的图片加载:国产是直接返回一个路径就可以加载,目前看下来直接返回的png格式的图片路径给wps,显示在高分辨率下就会模糊。如果是矢量图.svg格式的图片给wps是可以避免模糊,但是这个在com加载项里面还不知道怎么加载。
具体实现代码如下:
//wps加载透明图片
void LoadTransparentPNG(const WCHAR* pszImagePath, VARIANT* result)
{
GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken = 0;
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
Bitmap bitmap(pszImagePath);
PixelFormat pixelFormat = bitmap.GetPixelFormat();
ColorPalette* pPalette = NULL;
UINT paletteSize = 0;
bitmap.GetPalette(NULL, paletteSize);
if (paletteSize > 0)
{
pPalette = (ColorPalette*)malloc(paletteSize);
bitmap.GetPalette(pPalette, paletteSize);
}
HDC hdcScreen = GetDC(NULL);
HDC hdcMem = CreateCompatibleDC(hdcScreen);
int width = bitmap.GetWidth();
int height = bitmap.GetHeight();
HBITMAP hBitmap = NULL;
BITMAPINFO bmpInfo = { 0 };
bmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmpInfo.bmiHeader.biWidth = width;
bmpInfo.bmiHeader.biHeight = -height;
bmpInfo.bmiHeader.biPlanes = 1;
bmpInfo.bmiHeader.biCompression = BI_RGB;
bmpInfo.bmiHeader.biBitCount = pixelFormat == PixelFormat32bppARGB ? 32 : 24;
bmpInfo.bmiHeader.biSizeImage = width * height * 4;
bmpInfo.bmiHeader.biClrUsed = pPalette ? pPalette->Count : 0;
hBitmap = CreateDIBSection(hdcMem, &bmpInfo, DIB_RGB_COLORS, NULL, NULL, 0);
HBITMAP hOldBitmap = (HBITMAP)SelectObject(hdcMem, hBitmap);
SetGraphicsMode(hdcMem, GM_ADVANCED);
SetMapMode(hdcMem, MM_TEXT);
SetViewportOrgEx(hdcMem, 0, 0, NULL);
SetWindowOrgEx(hdcMem, 0, 0, NULL);
SetStretchBltMode(hdcMem, HALFTONE);
SetBrushOrgEx(hdcMem, 0, 0, NULL);
SetROP2(hdcMem, R2_COPYPEN);
SetGraphicsMode(hdcMem, GM_ADVANCED);
SetArcDirection(hdcMem, AD_COUNTERCLOCKWISE);
SetMiterLimit(hdcMem, 10, NULL);
SetPolyFillMode(hdcMem, WINDING);
SetStretchBltMode(hdcMem, HALFTONE);
SetROP2(hdcMem, R2_COPYPEN);
SetArcDirection(hdcMem, AD_COUNTERCLOCKWISE);
SetMiterLimit(hdcMem, 10, NULL);
SetPolyFillMode(hdcMem, WINDING);
SetStretchBltMode(hdcMem, HALFTONE);
Graphics graphics(hdcMem);
graphics.SetSmoothingMode(SmoothingModeHighQuality);
graphics.SetCompositingMode(CompositingModeSourceOver);
graphics.DrawImage(&bitmap, 0, 0, width, height);
IStream* pStream = NULL;
CreateStreamOnHGlobal(NULL, TRUE, &pStream);
BITMAPFILEHEADER bmpFileHeader = { 0 };
bmpFileHeader.bfType = 0x4D42; // "BM"
bmpFileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
bmpFileHeader.bfSize = bmpFileHeader.bfOffBits + bmpInfo.bmiHeader.biSizeImage;
pStream->Write(&bmpFileHeader, sizeof(BITMAPFILEHEADER), NULL);
pStream->Write(&bmpInfo.bmiHeader, sizeof(BITMAPINFOHEADER), NULL);
BITMAPINFO bmpInfoLocked = bmpInfo;
BYTE* pBits = NULL;
if (GetDIBits(hdcMem, hBitmap, 0, height, NULL, &bmpInfoLocked, DIB_RGB_COLORS))
{
pBits = new BYTE[bmpInfoLocked.bmiHeader.biSizeImage];
if (GetDIBits(hdcMem, hBitmap, 0, height, pBits, &bmpInfoLocked, DIB_RGB_COLORS))
{
pStream->Write(pBits, bmpInfoLocked.bmiHeader.biSizeImage, NULL);
}
}
if (pBits != NULL)
{
delete[] pBits;
}
pStream->Seek({ 0 }, STREAM_SEEK_SET, NULL);
PICTDESC pictDesc = { 0 };
pictDesc.cbSizeofstruct = sizeof(PICTDESC);
pictDesc.picType = PICTYPE_BITMAP;
pictDesc.bmp.hbitmap = hBitmap;
pictDesc.bmp.hpal = NULL;
IPicture* pPicture = NULL;
HRESULT hr = OleLoadPicture(pStream, bmpFileHeader.bfSize, TRUE, IID_IPicture, (void**)&pPicture);
if (pPalette != NULL)
{
free(pPalette);
}
pStream->Release();
SelectObject(hdcMem, hOldBitmap);
DeleteDC(hdcMem);
ReleaseDC(NULL, hdcScreen);
if (pPicture != nullptr)
{
result->vt = VT_UNKNOWN;
pPicture->QueryInterface(IID_IUnknown, (void**)&result->punkVal);
}
GdiplusShutdown(gdiplusToken);
}
excel加载图片逻辑如下
Gdiplus::Bitmap bitmap(fullPath.c_str());
HBITMAP hBitmap;
Gdiplus::Color color(0, 0, 0, 0);
bitmap.GetHBITMAP(color, &hBitmap);
if (hBitmap)
{
PICTDESC pd;
pd.cbSizeofstruct = sizeof(PICTDESC);
pd.picType = PICTYPE_BITMAP;
pd.bmp.hbitmap = hBitmap;
pd.bmp.hpal = NULL;
IPictureDisp * pPictureDisp = NULL;
hr = OleCreatePictureIndirect(&pd, IID_IPictureDisp, TRUE, (void **)&pPictureDisp);
if (SUCCEEDED(hr))
{
result->vt = VT_DISPATCH;
result->pdispVal = pPictureDisp;
}
else
{
DeleteObject(hBitmap);
}
}
在175%显示如图片所示:excel展示正常,但是wps的大图片显示会模糊。是否有解决方案解决这个问题
WPS寻令官 | WPS产品体验官