2017-02-19 67 views
0

我想將使用openGL ES在iOS上生成的繪圖保存到使用CGDataProvider和CGImage函數的PNG文件中。我在Objective-C上發現了一些代碼,我轉換爲Swift 3.代碼編譯但在運行時拋出一個錯誤: 致命錯誤:意外發現零,同時展開可選值在此行:在iOS中將openGL ES繪圖保存爲PNG圖像文件Swift 3

let iref: CGImage = CGImage(pngDataProviderSource: provider!, decode: nil, shouldInterpolate: true, intent: CGColorRenderingIntent.defaultIntent)! 

代碼:

let x: Int = 0 
let y: Int = 0 
let dataLength: Int = Int(width) * Int(height) * 4 
let pixels: UnsafeMutableRawPointer? = malloc(dataLength * MemoryLayout<GLubyte>.size) 
glPixelStorei(GL_PACK_ALIGNMENT.ui, 4) 
glReadPixels(GLint(x), GLint(y), GLsizei(width), GLsizei(height), GLenum(GL_RGBA), GL_UNSIGNED_BYTE.ui, pixels) 
let pixelData: UnsafePointer = (UnsafeRawPointer(pixels)?.assumingMemoryBound(to: UInt8.self))! 
let cfdata: CFData = CFDataCreate(kCFAllocatorDefault, pixelData, dataLength * MemoryLayout<GLubyte>.size) 

let provider: CGDataProvider! = CGDataProvider(data: cfdata) 

let iref: CGImage = CGImage(pngDataProviderSource: provider!, decode: nil, shouldInterpolate: true, intent: CGColorRenderingIntent.defaultIntent)! 
UIGraphicsBeginImageContext(CGSize(width: CGFloat(width), height: CGFloat(height))) 
let cgcontext: 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() 

我不能在網上找到了雨燕3.任何幫助,請您在修復此錯誤的幫助。

+1

至少檢查哪一個是零。你使用2力量解包。一個是提供者,另一個是整個CGImage。無論如何嘗試提供者的不同構造函數:CGDataProvider(dataInfo:nil data:cfdata,size:size,releaseData:nil) –

+0

它的整個CGImage變爲零。 我嘗試了你給出的構造函數,但是它失敗並顯示以下錯誤消息: Nil與預期的參數類型「CGDataProviderReleaseDataCallback」不兼容(又名'@convention(c) ') let provider = CGDataProvider(dataInfo:nil data:cfdata,size:size,releaseData:nil) – acn

+1

啊我現在看到了。您正在CGImage上使用構造函數,該構造函數需要原始PNG數據,但您擁有原始RGBA數據。您使用的方法期望(例如)來自PNG圖像文件內容的數據。您將需要使用具有原始RGBA數據的完整構造函數:CGImage(width :, height :, bitsPerComponent :, bitsPerPixel :, bytesPerRow :, space :, bitmapInfo :, provider :, decode :, shouldInterpolate:,intent :) –

回答

0

至於建議的馬蒂奇Oblak,錯誤不見了,代碼工作正常,當我取代在上面這行代碼

let iref: CGImage = CGImage(pngDataProviderSource: provider!, decode: nil, shouldInterpolate: true, intent: CGColorRenderingIntent.defaultIntent)! 

與此

let iref: CGImage? = 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: true, intent: CGColorRenderingIntent.defaultIntent) 

新的工作代碼:

let x: Int = 0 
let y: Int = 0 
let dataLength: Int = Int(width) * Int(height) * 4 
let pixels: UnsafeMutableRawPointer? = malloc(dataLength * MemoryLayout<GLubyte>.size) 
glPixelStorei(GL_PACK_ALIGNMENT.ui, 4) 
glReadPixels(GLint(x), GLint(y), GLsizei(width), GLsizei(height), GLenum(GL_RGBA), GL_UNSIGNED_BYTE.ui, pixels) 
let pixelData: UnsafePointer = (UnsafeRawPointer(pixels)?.assumingMemoryBound(to: UInt8.self))! 
let cfdata: CFData = CFDataCreate(kCFAllocatorDefault, pixelData, dataLength * MemoryLayout<GLubyte>.size) 

let provider: CGDataProvider! = CGDataProvider(data: cfdata) 

let iref: CGImage? = 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: true, intent: CGColorRenderingIntent.defaultIntent) 
UIGraphicsBeginImageContext(CGSize(width: CGFloat(width), height: CGFloat(height))) 
let cgcontext: 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()