Ios 目标C:工会的快速转化

Ios 目标C:工会的快速转化,ios,objective-c,swift,Ios,Objective C,Swift,您好,我正在尝试将下面的目标c代码转换为swift,但很难将受支持的联合转换为c,但不能直接转换为swift 我不确定如何转换以下union类型并将其传递给MTLTexture getbytes union { float f[2]; unsigned char bytes[8]; } u; 最后一部分,我想用log语句打印这些浮点值 如果我能为下面的代码片段进行快速转换,那就太好了 id<MTLDevice> device = MTLCreateSystemD

您好,我正在尝试将下面的目标c代码转换为swift,但很难将受支持的联合转换为c,但不能直接转换为swift

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


union {
    float f[2];
    unsigned char bytes[8];
} u;
最后一部分,我想用log语句打印这些浮点值

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


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);

id设备=MTLCreateSystemDefaultDevice();
id队列=[设备队列];
id commandBuffer=[queue commandBuffer];
MTKTextureLoader*textureLoader=[[MTKTextureLoader alloc]initWithDevice:device];
id sourceTexture=[textureLoader newTextureWithCGImage:image.CGImage选项:nil错误:nil];
CGColorSpaceRef srcColorSpace=CGColorSpaceCreateDeviceRGB();
CGColorSpaceRef dstColorSpace=CGColorSpaceCreateDeviceGray();
cgColorConversionInfo=cgColorConversionInfo创建(srcColorSpace,dstColorSpace);
MPSImageConversion*conversion=[[MPSImageConversion alloc]initWithDevice:设备
srcAlpha:MPSAlphaTypeAlphaIsOne
Destapha:MPSAlphaTypeAlphaIsOne
背景颜色:无
conversionInfo:conversionInfo];
MTLTextureDescriptor*grayTextureDescriptor=[MTLTextureDescriptor Texture2dDescriptor WithPixelFormat:MTLPixelFormatR16Unorm
宽度:sourceTexture.width
高度:sourceTexture.height
mipmap:false];
grayTextureDescriptor.usage=MTLTextureUserAgeShaderWrite | MTLTextureUserAgeShaderRead;
id grayTexture=[设备newTextureWithDescriptor:grayTextureDescriptor];
[将编码器转换为commandBuffer:commandBuffer sourceTexture:sourceTexture destinationTexture:grayTexture];
MTLTextureDescriptor*textureDescriptor=[MTLTextureDescriptor Texture2DDescriptor WithPixelFormat:grayTexture.pixelFormat
宽度:sourceTexture.width
高度:sourceTexture.height
mipmap:false];
textureDescriptor.usage=MTLTextureUserAgeShaderWrite | MTLTextureUserAgeShaderRead;
id texture=[设备newTextureWithDescriptor:textureDescriptor];
MPSImageLaplacian*imageKernel=[[MPSImageLaplacian alloc]initWithDevice:device];
[imageKernel encodeToCommandBuffer:commandBuffer sourceTexture:grayTexture destinationTexture:texture];
MPSimageStatisticsMeansandVariance*MeansandVariance=[[MPSimageStatisticsMeansandVariance alloc]initWithDevice:device];
MTLTextureDescriptor*varianceTextureDescriptor=[MTLTextureDescriptor
纹理2DDEScriptorWithPixelFormat:MTLPixelFormatR32Float
宽度:2
身高:1
(二):否;;
varianceTextureDescriptor.usage=MTLTextureReusageShaderWrite;
id varianceTexture=[device newTextureWithDescriptor:varianceTextureDescriptor];
[平均值和方差编码到commandBuffer:commandBuffer源纹理:纹理目标纹理:方差纹理];
[命令缓冲区提交];
[命令缓冲区等待完成];
联合{
浮动f[2];
无符号字符字节[8];
}u;
MTLRegion region=MTLRegionMake2D(0,0,2,1);
[varianceTexture getBytes:u.bytesPerRow:2*4 fromRegion:region mipmapLevel:0];
NSLog(@“平均值:%f”,u.f[0]*255);
NSLog(@“差异:%f”,u.f[1]*255*255);

如果我能得到这个的swift表示,那就太好了。

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

var bytes = [UInt8](repeating: 0, count: 8)
这是长度为8的数组(每个元素中有任意初始值0),您可以将其作为
unsafemtablerawpointer
传递给getBytes:

varianceTexture.getBytes(&bytes, ...)
至于工会,代表它的方式有很多。例如:

var u = ([Float](repeating: 0.0, count: 2), [UInt8](repeating: 0, count: 8))
在这种情况下,你通过它作为

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

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

您可以使用结构,如下所示。并添加扩展以获取日志记录的描述


结构单元{
变量字节:[UInt8]=[0,0,0,0,0,0,0]
变量f:[32]{
设置{
var f=新值
memcpy(&bytes,&f,8)
}
得到{
变量f:[Float32]=[0,0]
var b=字节
memcpy(&f&b,8)
返回数组(f)
}
}
}
扩展u:CustomStringConvertible{
变量说明:字符串{
let ByteString=(bytes.map{“\($0)”})。已加入(分隔符:“”)
return“floats:\(f[0])\(f[1])-字节:\(byteString)”
}
}
var测试=u()
打印(测试)
测试f=[3.14,1.618]
打印(测试)
test.bytes=[19524572 64 160 26 20763]
打印(测试)
日志:


当我将union转换为结构并将其传递给getBytes函数时,我确实得到了错误-无法将结构的值转换为UnsafemtableRawPointerHanks!那么NSlog在这里如何工作呢?不幸的是,您无法使用该黑客,因为swift无法表达相同的意图(在相同的内存空间中保存两条信息)。因此,您必须将
字节
转换为
f
,如下所示:很抱歉,我不懂,请您提供以下示例。我现在使用的并集是这样的
varu=([Float](重复:0.0,计数:2),[UInt8](重复:0,计数:8))
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