2016-06-01 118 views
3

我的用例是用戶在他們的手機上拍攝了他們自己的照片,並將其上傳到圖像託管服務作爲JPEG。其他用途可以下載該圖像,然後該圖像被映射到用於遊戲的金屬質感。UIImage作爲PNG下載到MTLTexture

我的問題是,如果我下載該圖像並將其顯示在UIImageView中,它看起來是正確的,但是當我下載圖像並將其轉換爲金屬紋理時,它會被鏡像並順時針旋轉90度。我知道獲取鏡像的圖像是由於金屬具有不同的座標系,但我不瞭解旋轉問題。當我打印已傳入我的函數的圖像的細節時,它具有與正確顯示的UIImageView相同的方向細節,因此我不知道問題出在哪裏。附加是我的功能,給我我的MTLTexture。

- (id<MTLTexture>) createTextureFromImage:(UIImage*) image device:(id<MTLDevice>) device 
{ 
    image =[UIImage imageWithCGImage:[image CGImage] 
        scale:[image scale] 
        orientation: UIImageOrientationLeft]; 

    NSLog(@"orientation and size and stuff %ld %f %f", (long)image.imageOrientation, image.size.width, image.size.height); 

    CGImageRef imageRef = image.CGImage; 

    size_t width = self.view.frame.size.width; 
    size_t height = self.view.frame.size.height; 

    size_t bitsPerComponent = CGImageGetBitsPerComponent(imageRef); 
    size_t bitsPerPixel = CGImageGetBitsPerPixel(imageRef); 

    CGColorSpaceRef colorSpace = CGImageGetColorSpace(imageRef); 

    CGImageAlphaInfo alphaInfo = CGImageGetAlphaInfo(imageRef); 

    // NSLog(@"%@ %u", colorSpace, alphaInfo); 

    CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault | alphaInfo; 
    // NSLog(@"bitmap info %u", bitmapInfo); 


    CGContextRef context = CGBitmapContextCreate(NULL, width, height, bitsPerComponent, (bitsPerPixel/8) * width, colorSpace, bitmapInfo); 

    if(!context) 
    { 
    NSLog(@"Failed to load image, probably an unsupported texture type"); 
    return nil; 
    } 




    CGContextDrawImage(context, CGRectMake(0, 0, width, height), image.CGImage); 


    MTLPixelFormat format = MTLPixelFormatRGBA8Unorm; 

    MTLTextureDescriptor *texDesc = [MTLTextureDescriptor texture2DDescriptorWithPixelFormat:format 
                        width:width 
                        height:height 
                       mipmapped:NO]; 
    id<MTLTexture> texture = [device newTextureWithDescriptor:texDesc]; 

    [texture replaceRegion:MTLRegionMake2D(0, 0, width, height) 
      mipmapLevel:0 
       withBytes:CGBitmapContextGetData(context) 
      bytesPerRow:4 * width]; 

    return texture; 
} 

回答

5

Metal座標是相反的。但是,你現在有一個更簡單的加載與紋理方式MTKTextureLoader

import MetalKit 

let textureLoader = MTKTextureLoader(device: device) 
let texture: MTLTexture = textureLoader.newTextureWithContentsOfURL(filePath, options: nil) 

這會爲你創建一個新的texture使用位於filePath圖像相應的座標。如果你不想使用NSURL,你也有newTextureWithDatanewTextureWithCGImage選項。

+0

Hollllly廢話!非常感謝你做的這些。你能指點我的文件的方向,還是你知道的地方? – crashlog

+1

肯定的事情。這裏是[文檔](https://developer.apple.com/library/ios/documentation/MetalKit/Reference/MTKFrameworkReference/index.html)和一些[示例代碼](https://developer.apple.com/庫文件/ ios/samplecode/MetalKitEssentials/Introduction/Intro.html)用於MetalKit紋理加載器。 – Marius