菜鳥學ffmpeg音視訊技術之6 mac截圖
阿新 • • 發佈:2021-01-09
前面介紹了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;
}