如何解码从Assimp到CGImage的原始PNG数据?

问题描述:

我使用的是Assimp,当使用嵌入纹理的FBX时,Assimp在以下struct aiTexture's pcData slot中提供嵌入的纹理数据。为pcData文档说:如何解码从Assimp到CGImage的原始PNG数据?

适当的解码器(如的libjpeg,libpng的,D3DX,魔鬼)需要 加载论文纹理。 aiTexture :: mWidth指定大小,以字节为纹理数据的 ,aiTexture :: PCDATA是一个指针,指向 原始图像数据

我明白pcData将具有标头为png,块等和libPNG可以给我用其他规格(宽度,高度等)返回实际图像数据。

什么是原生iOS/macOS API来做到这一点,而不是使用libPNG 例如:CGImageCreateWithPNGDataProvidersource属性描述为a data provider supplying PNG encoded data。我试着用这样的代码,但这是行不通的:

    CGDataProviderRef dataProvider = NULL; 
       dataProvider = CGDataProviderCreateWithData(NULL, 
                  (const void*)texture->pcData, 
                  texture->mWidth, 
                  rgbReleaseRampData); 
        if(dataProvider) { 
         NSLog(@" ********* Created image data provider "); 
        } 

        // fails at this line    
        CGImageRef imageRef = CGImageCreateWithPNGDataProvider(dataProvider, 
              NULL,false, kCGRenderingIntentDefault); 

那么,至少对于iOS/macOS;它似乎是assimp库的问题。

下,如果没有完美的修复,工作原理:

加入uint_8texture.h保持原始图像数据:

uint8_t *rawImageData; 

FBXConverter.cpp然后重新诠释pcData这样:

out_tex->pcData = reinterpret_cast< aiTexel * >(const_cast<Video&>(video 
).RelinquishContent()); 
out_tex->rawImageData = reinterpret_cast< uint8_t * >(out_tex->pcData); 

修复了上述问题。在不重新解释pcData的情况下,在iOS/macOS中,获取内存缓冲区的无效内存地址。

通过上述修正,生成图像对象只需要以下条件:

const struct aiTexture *aiTexture = aiScene->mTextures[index]; 
NSData *imageData = [NSData dataWithBytes:aiTexture->pcData 
            length:aiTexture->mWidth]; 
self.imageDataProvider = 
    CGDataProviderCreateWithCFData((CFDataRef)imageData); 
NSString* format = [NSString stringWithUTF8String:aiTexture->achFormatHint]; 
if([format isEqualToString:@"png"]) { 
    DLog(@" Created png embedded texture "); 
    self.image = CGImageCreateWithPNGDataProvider(
     self.imageDataProvider, NULL, true, kCGRenderingIntentDefault); 
} 
if([format isEqualToString:@"jpg"]) { 
    DLog(@" Created jpg embedded texture"); 
    self.image = CGImageCreateWithJPEGDataProvider(
     self.imageDataProvider, NULL, true, kCGRenderingIntentDefault); 
} 

The GH Issue.