c++ 如何在Qt6中将CGImageRef转换为QPixmap?

qxsslcnc  于 2022-12-15  发布在  其他
关注(0)|答案(1)|浏览(217)

在Qt 5中,使用QtMacExtras模块和QtMac::fromCGImageRef函数可以轻松地将CGImageRef转换为QPixmap
在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了,所以这没有帮助。
我该如何着手进行这种转变呢?

9lowa7mx

9lowa7mx1#

事实证明,在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::convertFromImage将其转换为QPixmap就很简单了。

相关问题