1. 程式人生 > 其它 >菜鳥學ffmpeg音視訊技術之6 mac截圖

菜鳥學ffmpeg音視訊技術之6 mac截圖

技術標籤:截圖mac錄製

前面介紹了window 使用gdi抓取螢幕的方法,現在介紹mac系統如何進行螢幕抓取,如果您使用的qt框架,當然可以使用qt更加方便。但是qt有一個bug,mac外界擴充套件屏時,如果擴充套件屏相對位置是左上,左邊,左下截圖是異常的。

這裡介紹使用mac原生api進行截圖:

1.獲取螢幕區域

    NSScreen *screen = [[NSScreen screens] objectAtIndex:screenNumber];
    CGRect mainRect;
    mainRect.origin = screen.frame.origin;
    mainRect.size = screen.frame.size;

screenNumber 為螢幕序號,mac系統自帶的螢幕始終是0,其他的可以通過NSScreen screens來獲取具體資訊。

2.抓圖

CGImageRef imageRef = CGWindowListCreateImage(mainRect, kCGWindowListOptionOnScreenOnly, kCGNullWindowID, kCGWindowImageNominalResolution | kCGWindowImageShouldBeOpaque);

第一個引數是要擷取螢幕的區域,第二個引數固定kCGWindowListOptionOnScreenOnly(截圖),第三個引數是視窗id,因為是截圖直接給NULL.

第四個引數需要注意,kCGWindowImageNominalResolution表示擷取圖片只有螢幕物理大小,如果設定的是

kCGWindowImageBestResolution

將會是高清圖,mac的螢幕一般是視網膜屏,縮放因子是2,所以截出來的圖片大小是kCGWindowImageNominalResolution截出來的2倍。需要進行縮放。

3.獲得RGBA資料

    auto width = CGImageGetWidth(imageRef);
    auto height = CGImageGetHeight(imageRef);

    auto prov = CGImageGetDataProvider(imageRef);
    if (!prov) {
        CGImageRelease(imageRef);
        return QPixmap();
    }
//    auto bytesperrow = CGImageGetBytesPerRow(imageRef);
//    auto bitsperpixel = CGImageGetBitsPerPixel(imageRef);

    auto rawdatas = CGDataProviderCopyData(prov);
    auto buf = CFDataGetBytePtr(rawdatas);
    CFRelease(rawdatas);
buf 中的資料就是RGBA的格式,可以直接給QImage生成一幅圖片顯示或是儲存一幅圖片。

4.完整程式碼

QPixmap MacScreenCaputre::caputreScreen(int screenNumber)
{
    if(screenNumber<0 || screenNumber >= QApplication::screens().count())
        return QPixmap();
    QScreen* screen = QApplication::screens().at(screenNumber);
    if(nullptr == screen)
        return QPixmap();
    QRect  rect = screen->availableGeometry();

    CGRect mainRect;
    mainRect.origin.x = rect.x();
    mainRect.origin.y = rect.y();
    mainRect.size.width = rect.width();
    mainRect.size.height = rect.height();
    CGImageRef imageRef = CGWindowListCreateImage(mainRect, kCGWindowListOptionOnScreenOnly, kCGNullWindowID, kCGWindowImageBestResolution | kCGWindowImageShouldBeOpaque);

    auto width = CGImageGetWidth(imageRef);
    auto height = CGImageGetHeight(imageRef);

    auto prov = CGImageGetDataProvider(imageRef);
    if (!prov) {
        CGImageRelease(imageRef);
        return QPixmap();
    }

    auto rawdatas = CGDataProviderCopyData(prov);
    auto buf = CFDataGetBytePtr(rawdatas);
    QPixmap pixmap = QPixmap::fromImage(QImage(buf, width, height, 
 QImage::Format_RGB32));

    CFRelease(rawdatas);
    return pixmap;
}