glReadPixels到UIImage(),黑色图像

时间:2018-04-11 12:25:03

标签: ios swift opengl-es

我尝试拍摄相机vuforia的截图。我用这个代码。它完美适用于iPhone 7(ios 11.3)和iPad Pro(ios 11.2)。但是这个代码不适用于iPad 2(ios 9.3.5),函数返回有效的UIImage,但它是黑色的。

    static public func takeScreenshot() -> UIImage? {
    let xCoord: Int = 0
    let yCoord: Int = 0
    let screen = UIScreen.main.bounds

    let scale = UIScreen.main.scale
    let width = screen.width * scale
    let height = screen.height * scale
    let dataLength: Int = Int(width) * Int(height) * 4
    let pixels: UnsafeMutableRawPointer? = malloc(dataLength * MemoryLayout<GLubyte>.size)
    glPixelStorei(GLenum(GL_PACK_ALIGNMENT), 4)
    glReadPixels(GLint(xCoord), GLint(yCoord), GLsizei(width), GLsizei(height), GLenum(GL_RGBA), GLenum(GL_UNSIGNED_BYTE), pixels)
    guard let pixelData: UnsafePointer = (UnsafeRawPointer(pixels)?.assumingMemoryBound(to: UInt8.self)) else { return nil }
    let cfdata: CFData = CFDataCreate(kCFAllocatorDefault, pixelData, dataLength * MemoryLayout<GLubyte>.size)

    let provider: CGDataProvider! = CGDataProvider(data: cfdata)
    let colorspace = CGColorSpaceCreateDeviceRGB()
    guard let iref = CGImage(width: Int(width),
                                 height: Int(height),
                                 bitsPerComponent: 8,
                                 bitsPerPixel: 32,
                                 bytesPerRow: Int(width)*4,
                                 space: colorspace,
                                 bitmapInfo: CGBitmapInfo.byteOrder32Big,
                                 provider: provider,
                                 decode: nil,
                                 shouldInterpolate: false,
                                 intent: CGColorRenderingIntent.defaultIntent) else { return nil }
    UIGraphicsBeginImageContext(CGSize(width: CGFloat(width), height: CGFloat(height)))
    if let cgcontext = UIGraphicsGetCurrentContext() {
        cgcontext.setBlendMode(CGBlendMode.copy)
        cgcontext.draw(iref, in: CGRect(x: CGFloat(0.0), y: CGFloat(0.0), width: CGFloat(width), height: CGFloat(height)))
        let image: UIImage? = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return image
    }
    return nil
}

更新:我解决了这个问题,需要在opengl线程中运行函数

1 个答案:

答案 0 :(得分:0)

OpenGL ES的格式非常有限,可以接受。有一个很棒的网站,有OpenGL文档http://docs.gl

您对http://docs.gl/es2/glReadPixelshttp://docs.gl/es3/glReadPixels感兴趣。缓冲区格式应为GL_RGBA或GL_BGRA。

也许更好的方法是https://stackoverflow.com/a/9704392/1351828