如何在 Qt 6 中将 CGImageRef 转换为 QPixmap?

问题描述 投票:0回答:2

在 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 了,所以这没有帮助。

我该如何进行此转换?

c++ macos qt core-graphics
2个回答
1
投票

事实证明,

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
非常简单。


-1
投票

我面临着和你同样的问题,并且正在尝试做同样的事情。 您的解决方案对我有用,但与旧的 Qt5 QtmacExtra 方法相比,它确实会产生模糊的图标。

您也经历过这样的事情吗?您知道解决办法吗?

© www.soinside.com 2019 - 2024. All rights reserved.