36831


GLKTextureLoader.textureでnullが帰って来てエラーになります。  
どのようにして取得すれば良いでしょうか?

エラーメッセージ

[code]

    Error Domain=GLKTextureLoaderErrorDomain Code=12 "(null)" UserInfo={GLKTextureLoaderErrorKey=Image decoding failed}
    
[/code]

コード

[code]

    import Cocoa
    import CoreImage
    import GLKit
    
    func toCGImage(image: NSImage) -> CGImage?{
        var imageRect:CGRect = CGRect(x: 0, y: 0, width: image.size.width, height: image.size.height)
        let aCGImage = image.cgImage(forProposedRect: &imageRect, context: nil, hints: nil)
        return aCGImage
    }
    
    let simpleattr: [NSOpenGLPixelFormatAttribute] = [
        NSOpenGLPixelFormatAttribute(NSOpenGLPFADoubleBuffer),
        NSOpenGLPixelFormatAttribute(NSOpenGLPFAAccelerated),
        NSOpenGLPixelFormatAttribute(0)
    ]
    
    let pf = NSOpenGLPixelFormat(attributes: simpleattr)
    
    let image1 = NSImage(byReferencingFile: "/Users/xxx/Pictures/スクリーンショット1.png")!
    let image2 = NSImage(byReferencingFile: "/Users/xxx/Pictures/スクリーンショット2.png")!
    let overlayImage:CIImage = CIImage(cgImage: toCGImage(image: image1)!)
    let backgroundImage:CIImage = CIImage(cgImage: toCGImage(image: image2)!)
    
    let alpha:CGFloat = 0.8
    let rgba:[CGFloat] = [0.0, 0.0, 0.0, alpha]
    let colorMatrix:CIFilter = CIFilter(name: "CIColorMatrix")!
    colorMatrix.setDefaults()
    colorMatrix.setValue(overlayImage, forKey: kCIInputImageKey)
    let vector = CIVector(values: rgba, count: 4)
    colorMatrix.setValue(vector, forKey: "inputAVector")
    
    let composite:CIFilter = CIFilter(name: "CISourceOverCompositing")!
    composite.setDefaults()
    composite.setValue(colorMatrix.outputImage, forKey: kCIInputImageKey)
    composite.setValue(backgroundImage, forKey: kCIInputBackgroundImageKey)
    
    let outputImage:CIImage = composite.outputImage!
    
    let context:CIContext = CIContext.init(options: nil)
    let pixelData = context.createCGImage(outputImage, from: outputImage.extent)!
    
    let glContext:NSOpenGLContext = NSOpenGLContext(format: pf!, share: nil)!
    glContext.makeCurrentContext()
    
    var texture:GLKTextureInfo
    
    do {
        //失敗する。
        texture = try GLKTextureLoader.texture(with: pixelData, options: nil)
    } catch {
        //ここに来る。
        print(error)
        exit(0)
    }
    
[/code]

[![画像](https://i.stack.imgur.com/6Nn6f.png)](https://i.stack.imgur.com/6Nn6f.png)


CC BY-SA 3.0
2017-07-31T16:03:12.000
36828
2017-08-04T04:53:53.550
2017-08-04T04:53:53.550
19110
13017
question
swift macos swift3 opengl
GLKTextureLoader.textureでエラーが発生する


あなたが表示されているエラー情報のなかの`"(null)"`は、エラーオブジェクト`error`内のエラーメッセージを表しており、メソッドからの戻り値ではありません。「nullが帰る」と言う表現は少々誤解を招く可能性がありますね。

* * *

さて、本題ですが、そのエラー情報の中に以下のような記述があります。

> GLKTextureLoaderErrorKey=Image decoding failed

「画像のデコードに失敗した」と言うことですから、与えられた画像フォーマットに何らかの問題があって、画像が正しく読み込めなかったのであろうと考えられます。

そこで[Appleの公式リファレンスで`GLKTextureLoader.texture(with:options:)`](https://developer.apple.com/documentation/glkit/glktextureloader/1488673-texture)を調べると次のような記述があります。

> Table 1 Supported Bitmap Formats
[code]

>     Color Space Pixel format and bitmap information constant
>     Null        8 bpp, 8 bpc, alphaOnly
>     Gray        8 bpp, 8 bpc, none
>     Gray        8 bpp, 8 bpc, alphaOnly
>     RGB         32 bpp, 8 bpc, noneSkipFirst
>     RGB         32 bpp, 8 bpc, premultipliedFirst
>  
[/code]

あなたのコードで`pixelData`のビットマップ情報を表示させると以下のようになりました。

[code]

    print(pixelData.bitmapInfo) //->CGBitmapInfo(rawValue: 1)
    
[/code]

この`rawValue:
1`と言うのは、`CGImageAlphaInfo.premultipliedLast`にあたりますので、サポート対象ではないと言うことになります。

* * *

あなたのコードの中には、ビットマップ形式を指定するような部分が全くありませんので、`CIContext`が適当にフォーマットを選んでしまっている状態ですから、所望のフォーマットを何らかの方法で指定してやればいいでしょう。

この行を、

[code]

    let pixelData = context.createCGImage(outputImage, from: outputImage.extent)!
    
[/code]

こんなふうに書き換えて見てください。

[code]

    let pixelData = context.createCGImage(outputImage, from: outputImage.extent,
                                          format: kCIFormatARGB8,
                                          colorSpace: CGColorSpaceCreateDeviceRGB())!
    
[/code]

`kCIFormatARGB8`と言うのは`A`つまりalphaが最初(First)に来ていることを表しています。

こちらの動作テスト(macOS
10.12.6)では、この修正でエラーがでなくなりました。他の部分まであなたの期待通りに動いているのかどうかはわかりかねますが、お試しください。

* * *

ちなみに`CIContext.init(options:
nil)`と言うのは`CIContext()`とするのとまったく同じですね。また、変数宣言の型指定も付ける付けないを混在させていますが、「Swiftが型推論を間違えない場所では型指定は省略する」に統一してしまえばいいように思うのですが。


CC BY-SA 3.0
2017-07-31T23:42:09.847
36831
2017-07-31T23:42:09.847
13972
36828
answer