2017-02-19 6 views
0

Я пытаюсь сохранить чертеж, сгенерированный на iOS, используя openGL ES в PNG-файле с использованием функций CGDataProvider и CGImage. Я нашел некоторый код в сети в Objective-C, который я преобразовал в Swift 3. Кодирование компилируется, но не выполняется во время выполнения, вызывая ошибку: Неустранимая ошибка: неожиданно найден нуль при развертывании Необязательное значение в этой строке:Сохранение рисунка OpenGL ES в файл изображения PNG в iOS 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() 

Я не могу найти какой-либо помощи в Интернете для Swift 3. не могли бы вы помочь устранить эту ошибку.

+1

По крайней мере, проверьте, какой из них равен нулю. Вы используете 2 силы разворота. Один с провайдером, а другой - с CGImage. В любом случае попробуйте использовать другой конструктор для провайдера: CGDataProvider (dataInfo: nil data: cfdata, size: size, releaseData: nil) –

+0

Его весь CGImage становится нулевым. Я пробовал созданный вами конструктор, но с этим сообщением об ошибке не получается: Nil несовместим с ожидаемым типом аргумента 'CGDataProviderReleaseDataCallback' (aka '@convention (c) (необязательный , UnsafeRawPointer, Int) ->() ') 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 :, поставщик :, decode :, shouldInterpolate :, intent :) –

ответ

0

Как было предложено Matic 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() 
Смежные вопросы