繁体   English   中英

联合的目标 C 到 swift 转换

[英]Objective C to swift conversion for unions

Hi I am trying to convert below objective c code into swift but struggling to convert unions which are supported into C but not directly in swift.

我不确定如何转换以下联合类型并将其传递给 MTLTexture getbytes?


union {
    float f[2];
    unsigned char bytes[8];
} u;

最后一部分,我想用 log 语句打印这些浮点值。

如果我能够为下面的代码片段进行 swift 转换,那就太好了。


id<MTLDevice> device = MTLCreateSystemDefaultDevice();
id<MTLCommandQueue> queue = [device newCommandQueue];
id<MTLCommandBuffer> commandBuffer = [queue commandBuffer];

MTKTextureLoader *textureLoader = [[MTKTextureLoader alloc] initWithDevice:device];
id<MTLTexture> sourceTexture = [textureLoader newTextureWithCGImage:image.CGImage options:nil error:nil];


CGColorSpaceRef srcColorSpace = CGColorSpaceCreateDeviceRGB();
CGColorSpaceRef dstColorSpace = CGColorSpaceCreateDeviceGray();
CGColorConversionInfoRef conversionInfo = CGColorConversionInfoCreate(srcColorSpace, dstColorSpace);
MPSImageConversion *conversion = [[MPSImageConversion alloc] initWithDevice:device
                                                                   srcAlpha:MPSAlphaTypeAlphaIsOne
                                                                  destAlpha:MPSAlphaTypeAlphaIsOne
                                                            backgroundColor:nil
                                                             conversionInfo:conversionInfo];
MTLTextureDescriptor *grayTextureDescriptor = [MTLTextureDescriptor texture2DDescriptorWithPixelFormat:MTLPixelFormatR16Unorm
                                                                                                 width:sourceTexture.width
                                                                                                height:sourceTexture.height
                                                                                             mipmapped:false];
grayTextureDescriptor.usage = MTLTextureUsageShaderWrite | MTLTextureUsageShaderRead;
id<MTLTexture> grayTexture = [device newTextureWithDescriptor:grayTextureDescriptor];
[conversion encodeToCommandBuffer:commandBuffer sourceTexture:sourceTexture destinationTexture:grayTexture];


MTLTextureDescriptor *textureDescriptor = [MTLTextureDescriptor texture2DDescriptorWithPixelFormat:grayTexture.pixelFormat
                                                                                             width:sourceTexture.width
                                                                                            height:sourceTexture.height
                                                                                         mipmapped:false];
textureDescriptor.usage = MTLTextureUsageShaderWrite | MTLTextureUsageShaderRead;
id<MTLTexture> texture = [device newTextureWithDescriptor:textureDescriptor];

MPSImageLaplacian *imageKernel = [[MPSImageLaplacian alloc] initWithDevice:device];
[imageKernel encodeToCommandBuffer:commandBuffer sourceTexture:grayTexture destinationTexture:texture];


MPSImageStatisticsMeanAndVariance *meanAndVariance = [[MPSImageStatisticsMeanAndVariance alloc] initWithDevice:device];
MTLTextureDescriptor *varianceTextureDescriptor = [MTLTextureDescriptor
                                                   texture2DDescriptorWithPixelFormat:MTLPixelFormatR32Float
                                                   width:2
                                                   height:1
                                                   mipmapped:NO];
varianceTextureDescriptor.usage = MTLTextureUsageShaderWrite;
id<MTLTexture> varianceTexture = [device newTextureWithDescriptor:varianceTextureDescriptor];
[meanAndVariance encodeToCommandBuffer:commandBuffer sourceTexture:texture destinationTexture:varianceTexture];


[commandBuffer commit];
[commandBuffer waitUntilCompleted];

union {
    float f[2];
    unsigned char bytes[8];
} u;

MTLRegion region = MTLRegionMake2D(0, 0, 2, 1);
[varianceTexture getBytes:u.bytes bytesPerRow:2 * 4 fromRegion:region mipmapLevel: 0];

NSLog(@"mean: %f", u.f[0] * 255);
NSLog(@"variance: %f", u.f[1] * 255 * 255);

如果我为此获得 swift 表示会很棒吗?

您可以使用 Struct 代替,就像这样。 并添加一个扩展来获取日志记录的描述。


struct u {

    var bytes: [UInt8] = [0,0,0,0, 0,0,0,0]

    var f: [Float32] {
        set {
            var f = newValue
            memcpy(&bytes, &f, 8)
        }
        get {
            var f: [Float32] = [0,0]
            var b = bytes
            memcpy(&f, &b, 8)
            return Array(f)
        }
    }
}

extension u: CustomStringConvertible {
    var description: String {
        let bytesString = (bytes.map{ "\($0)"}).joined(separator: " ")
        return "floats : \(f[0]) \(f[1]) - bytes  : \(bytesString)"
    }
}


var test = u()
print(test)
test.f = [3.14, 1.618]
print(test)
test.bytes = [195, 245, 72, 64, 160, 26, 207, 63]
print(test)

日志:

floats : 0.0 0.0 - bytes  : 0 0 0 0 0 0 0 0
floats : 3.14 1.618 - bytes  : 195 245 72 64 160 26 207 63
floats : 3.14 1.618 - bytes  : 195 245 72 64 160 26 207 63

您不需要整个联合来使getBytes工作,那里只使用u.bytes ,可以将其转换为

var bytes = [UInt8](repeating: 0, count: 8)

那是长度为 8 的数组(每个元素中具有任意初始值 0),您将它作为UnsafeMutableRawPointer传递给 getBytes :

varianceTexture.getBytes(&bytes, ...)

至于联合,有很多种表示方式。 例如:

var u = ([Float](repeating: 0.0, count: 2), [UInt8](repeating: 0, count: 8))

在这种情况下,您将其传递为

varianceTexture.getBytes(&u.1, ...)

或者,您可以以类似的方式将其设为 class 或结构。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM