簡體   English   中英

如何在 Qt 6 中將 CGImageRef 轉換為 QPixmap?

[英]How to convert a CGImageRef to a QPixmap in Qt 6?

在 Qt 5 中,使用他們的QtMacExtras模塊和QtMac::fromCGImageRef function 可以輕松地將CGImageRef轉換為QPixmap

在Qt 6, QtMacExtras已經被移除。 那里的大多數函數都有明確的替換,除了QtMac::fromCGImageRef被刪除“由於缺少已知的 API 客戶端”。

好吧,事實證明我是那個 API 的客戶,只是不為人所知。 N.netheless,現在我需要在 Qt 6 中將CGImageRef轉換為QPixmap

我查看了 Qt 5.15.2 中QtMac::fromCGImageRef的源代碼,它引導我找到一個名為qt_mac_toQImage 但是,它使用了大量我在 Qt 5 中無法訪問的內部函數和類,更不用說 Qt 6 了,所以這無濟於事。

我怎樣才能go做這個轉換呢?

事實證明,qt_mac_toQImage 的 Qt 5.15 實現中使用的許多私有qt_mac_toQImage內容適用於除了嘗試對 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很簡單。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM