Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 转换为纹理时缺少UIImage的透明度_Ios_Swift_Metal_Metalkit - Fatal编程技术网

Ios 转换为纹理时缺少UIImage的透明度

Ios 转换为纹理时缺少UIImage的透明度,ios,swift,metal,metalkit,Ios,Swift,Metal,Metalkit,我将UIImage转换为纹理,然后将该纹理转换为UIImage。透明区域将替换为黑色 我用于将UIImage转换为纹理的函数 func imageToTexture(imageNamed: String, device: MTLDevice) -> MTLTexture { let bytesPerPixel = 4 let bitsPerComponent = 8 var image = UIImage(named: imageNamed)! let

我将UIImage转换为纹理,然后将该纹理转换为UIImage。透明区域将替换为黑色

我用于将UIImage转换为纹理的函数

func imageToTexture(imageNamed: String, device: MTLDevice) -> MTLTexture {
    let bytesPerPixel = 4
    let bitsPerComponent = 8

    var image = UIImage(named: imageNamed)!

    let width = Int(image.size.width)
    let height = Int(image.size.height)

    let bounds = CGRect(x: 0, y: 0, width: CGFloat(width), height: CGFloat(height))
    var rowBytes = width * bytesPerPixel
    var colorSpace = CGColorSpaceCreateDeviceRGB()

    let context = CGContext(data: nil, width: width, height: height, bitsPerComponent: bitsPerComponent, bytesPerRow: rowBytes, space: colorSpace, bitmapInfo: CGBitmapInfo(rawValue: CGImageAlphaInfo.premultipliedLast.rawValue).rawValue)

    context!.clear(bounds)
    context?.translateBy(x: CGFloat(width), y: CGFloat(height))
    //  CGContextTranslateCTM(context!, CGFloat(width), CGFloat(height))
    context?.scaleBy(x: -1.0, y: -1.0)
    //   CGContextScaleCTM(context!, -1.0, -1.0)
    context?.draw(image.cgImage!, in: bounds)
    //  CGContextDrawImage(context, bounds, image.CGImage)

    var texDescriptor = MTLTextureDescriptor.texture2DDescriptor(pixelFormat: .bgra8Unorm , width: width, height: height, mipmapped: true)

    var texture = device.makeTexture(descriptor: texDescriptor)
    texture?.label = imageNamed

    // var pixelsData = CGBitmapContextGetData(context!)
    var pixelsData = context?.data
    var region = MTLRegionMake2D(0, 0, width, height)
    texture?.replace(region: region, mipmapLevel: 0, withBytes: pixelsData!, bytesPerRow: rowBytes)

    makeImage(from: texture!)
    return texture!
}
将纹理转换为图像的函数。将UIImage更改为纹理后,我正在调用将其转换回UIImage。事实并非如此

func makeImage(from texture: MTLTexture) -> UIImage? {
    let width = texture.width
    let height = texture.height
    let bytesPerRow = width * 4

    let data = UnsafeMutableRawPointer.allocate(bytes: bytesPerRow * height, alignedTo: 4)
    defer {
        data.deallocate(bytes: bytesPerRow * height, alignedTo: 4)
    }

    let region = MTLRegionMake2D(0, 0, width, height)
    texture.getBytes(data, bytesPerRow: bytesPerRow, from: region, mipmapLevel: 0)

    var buffer = vImage_Buffer(data: data, height: UInt(height), width: UInt(width), rowBytes: bytesPerRow)

    let map: [UInt8] = [2, 1, 0, 3]
    vImagePermuteChannels_ARGB8888(&buffer, &buffer, map, 0)

    guard let colorSpace = CGColorSpace(name: CGColorSpace.genericRGBLinear) else { return nil }
    guard let context = CGContext(data: data, width: width, height: height, bitsPerComponent: 8, bytesPerRow: bytesPerRow,
                                  space: colorSpace, bitmapInfo: CGImageAlphaInfo.noneSkipLast.rawValue) else { return nil }
    guard let cgImage = context.makeImage() else { return nil }

    let x =  UIImage(cgImage: cgImage)
    return x;
}

此处,输出图像在透明区域为黑色。我不知道我哪里搞砸了。

您正在使用
CGImageAlphaInfo.noneSkipLast
创建位图上下文。您明确告诉它忽略数据中的alpha分量。此外,您可能应该直接从数据创建
CGImage
,而不是通过位图上下文。Ken所说的是最可能的原因。要扩展它,我觉得
imageToTexture
函数很好,请尝试在
makeImage
中使用
CGImageAlphaInfo.premultipledLast
来匹配
imageToTexture
。旁注:如果您只是在进行原型设计,您可能需要考虑使用CoreImage将
UIImage
渲染为
CVPixelBuffer
,将
CVPixelBufferMetalCompatibilityKey
设置为true时从
CVPixelBuffer池
生成的
。您可以使用
CVMetalTextureCacheCreateTextureFromImage()
获取映射绑定到与该像素缓冲区相同内存的
MTLTexture
。“以我的经验来说,这让事情变得更容易了。”肯特·霍马斯说,谢谢