在 Qt 5 中,使用其
CGImageRef
模块和 QPixmap
函数将 QtMacExtras
转换为 QtMac::fromCGImageRef
很容易。
在 Qt 6 中,
QtMacExtras
已被删除。那里的大多数功能都有显式替换,除了 QtMac::fromCGImageRef
之外,它“由于缺乏已知的 API 客户端”而被删除。
事实证明我是该 API 的客户,只是不为人所知。尽管如此,现在我需要在 Qt 6 中将
CGImageRef
转换为 QPixmap
。
我查看了 Qt 5.15.2 中
QtMac::fromCGImageRef
的源代码,这让我找到了一个名为 qt_mac_toQImage
的 Qt 内部函数。然而,它使用了大量我在 Qt 5 中无法访问的内部函数和类,更不用说 Qt 6 了,所以这没有帮助。
我该如何进行此转换?
事实证明,
qt_mac_toQImage
的 Qt 5.15 实现中使用的许多私有 Qt 内容适用于尝试对 QImage 进行 CoreGraphics 渲染之外的情况。一旦我把所有这些部分拿出来并简化,将 CGImageRef 转换为 QImage 或 QPixmap 的方法就相当简单了:
CGBitmapInfo CGBitmapInfoForQImage(const QImage &image)
{
CGBitmapInfo bitmapInfo = kCGImageAlphaNone;
switch (image.format()) {
case QImage::Format_ARGB32:
bitmapInfo = kCGImageAlphaFirst | kCGBitmapByteOrder32Host;
break;
case QImage::Format_RGB32:
bitmapInfo = kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Host;
break;
case QImage::Format_RGBA8888_Premultiplied:
bitmapInfo = kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big;
break;
case QImage::Format_RGBA8888:
bitmapInfo = kCGImageAlphaLast | kCGBitmapByteOrder32Big;
break;
case QImage::Format_RGBX8888:
bitmapInfo = kCGImageAlphaNoneSkipLast | kCGBitmapByteOrder32Big;
break;
case QImage::Format_ARGB32_Premultiplied:
bitmapInfo = kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host;
break;
default:
break;
}
return bitmapInfo;
}
QImage CGImageToQImage(CGImageRef cgImage)
{
const size_t width = CGImageGetWidth(cgImage);
const size_t height = CGImageGetHeight(cgImage);
QImage image(width, height, QImage::Format_ARGB32_Premultiplied);
image.fill(Qt::transparent);
CGColorSpaceRef colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceSRGB);
CGContextRef context = CGBitmapContextCreate((void *)image.bits(), image.width(), image.height(), 8,
image.bytesPerLine(), colorSpace, CGBitmapInfoForQImage(image));
// Scale the context so that painting happens in device-independent pixels
const qreal devicePixelRatio = image.devicePixelRatio();
CGContextScaleCTM(context, devicePixelRatio, devicePixelRatio);
CGRect rect = CGRectMake(0, 0, width, height);
CGContextDrawImage(context, rect, cgImage);
CFRelease(colorSpace);
CFRelease(context);
return image;
}
将
CGImageRef
转换为 QImage
后,使用 QPixmap
将其转换为 QPixmap::convertFromImage
非常简单。
我面临着和你同样的问题,并且正在尝试做同样的事情。 您的解决方案对我有用,但与旧的 Qt5 QtmacExtra 方法相比,它确实会产生模糊的图标。
您也经历过这样的事情吗?您知道解决办法吗?