Error[8]: Undefined offset: 5, File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 121
File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 473, decode(

概述我的目标是使用ARKit在真实环境中呈现2D动画角色.动画角色是视频的一部分,在视频的以下快照中显示: 使用代码完全显示视频本身没有任何问题: func view(_ view: ARSKView, nodeFor anchor: ARAnchor) -> SKNode? { guard let urlString = Bundle.main.path(forResource: "reso 我的目标是使用ARKit在真实环境中呈现2D动画角色.动画角色是视频的一部分,在视频的以下快照中显示:

使用代码完全显示视频本身没有任何问题:

func vIEw(_ vIEw: ARSKVIEw,nodeFor anchor: aranchor) -> SKNode? {    guard let urlString = Bundle.main.path(forResource: "resourcename",ofType: "mp4") else { return nil }    let url = URL(fileURLWithPath: urlString)    let asset = AVAsset(url: url)    let item = AVPlayerItem(asset: asset)    let player = AVPlayer(playerItem: item)    let vIDeoNode = SKVIDeoNode(avPlayer: player)    vIDeoNode.size = CGSize(wIDth: 200.0,height: 150.0)    vIDeoNode.anchorPoint = CGPoint(x: 0.5,y: 0.0)    return vIDeoNode}

此代码的结果显示在以下应用程序的屏幕截图中,如预期:

但正如你所看到的,角色的背景并不是很好,所以我需要让它消失,以便创造出实际上站在水平面上的角色的幻觉.
我试图通过对视频产生色度键效果来实现这一点.

>对于那些不熟悉色度键的人来说,这是有时在电视上看到的“绿屏效果”的名称,以使颜色透明.

我对色度键效果的处理方法是创建基于“CIcolorCube”CIFilter的自定义滤镜,然后使用AVVIDeoComposition将滤镜应用于视频.

首先,是创建过滤器的代码:

func RGBtoHSV(r : float,g : float,b : float) -> (h : float,s : float,v : float) {    var h : CGfloat = 0    var s : CGfloat = 0    var v : CGfloat = 0    let col = UIcolor(red: CGfloat(r),green: CGfloat(g),blue: CGfloat(b),Alpha: 1.0)    col.getHue(&h,saturation: &s,brightness: &v,Alpha: nil)    return (float(h),float(s),float(v))}func colorCubeFilterForChromakey(hueAngle: float) -> CIFilter {    let hueRange: float = 20 // degrees size pIE shape that we want to replace    let minHueAngle: float = (hueAngle - hueRange/2.0) / 360    let maxHueAngle: float = (hueAngle + hueRange/2.0) / 360    let size = 64    var cubedata = [float](repeating: 0,count: size * size * size * 4)    var rgb: [float] = [0,0]    var hsv: (h : float,v : float)    var offset = 0    for z in 0 ..< size {        rgb[2] = float(z) / float(size) // blue value        for y in 0 ..< size {            rgb[1] = float(y) / float(size) // green value            for x in 0 ..< size {                rgb[0] = float(x) / float(size) // red value                hsv = RGBtoHSV(r: rgb[0],g: rgb[1],b: rgb[2])                // Todo: Check if hsv.s > 0.5 is really nesseccary                let Alpha: float = (hsv.h > minHueAngle && hsv.h < maxHueAngle && hsv.s > 0.5) ? 0 : 1.0                cubedata[offset] = rgb[0] * Alpha                cubedata[offset + 1] = rgb[1] * Alpha                cubedata[offset + 2] = rgb[2] * Alpha                cubedata[offset + 3] = Alpha                offset += 4            }        }    }    let b = cubedata.withUnsafeBufferPointer { Data(buffer: 
func vIEw(_ vIEw: ARSKVIEw,ofType: "mp4") else { return nil }    let url = URL(fileURLWithPath: urlString)    let asset = AVAsset(url: url)    let filter = colorCubeFilterForChromakey(hueAngle: 38)    let composition = AVVIDeoComposition(asset: asset,applyingCIFiltersWithHandler: { request in        let source = request.sourceImage        filter.setValue(source,forKey: kCIInputimageKey)        let output = filter.outputimage        request.finish(with: output!,context: nil)    })    let item = AVPlayerItem(asset: asset)    item.vIDeoComposition = composition    let player = AVPlayer(playerItem: item)    let vIDeoNode = SKVIDeoNode(avPlayer: player)    vIDeoNode.size = CGSize(wIDth: 200.0,y: 0.0)    return vIDeoNode}
) } let data = b as NSData let colorCube = CIFilter(name: "CIcolorCube",withinputParameters: [ "inputCubedimension": size,"inputCubedata": data ]) return colorCube!}

然后通过修改函数func视图(_ vIEw:ARSKVIEw,nodeFor anchor:aranchor)将视频应用于视频的代码 – > SKNode?我之前写的:

let playerLayer = AVPlayerLayer(player: player)playerLayer.bounds = vIEw.boundsplayerLayer.position = vIEw.centerplayerLayer.pixelBufferAttributes = [(kCVPixelBufferPixelFormatTypeKey as String): kCVPixelFormatType_32BGRA]vIEw.layer.addSublayer(playerLayer)

如果像素颜色与背景的色调范围匹配,则代码应该将视频的每个帧的所有像素替换为Alpha = 0.0.
但是我没有获得透明像素,而是将这些像素设置为黑色,如下图所示:

现在,虽然这不是想要的效果,但它并不让我感到惊讶,因为我知道这是iOS用Alpha通道显示视频的方式.
但这是真正的问题 – 当在AVPlayer中显示普通视频时,可以选择将AVPlayerLayer添加到视图中,并将pixelBufferAttributes设置为它,让玩家层知道我们使用透明像素缓冲区,就像这样:

func vIEw(_ vIEw: ARSKVIEw,nodeFor anchor: aranchor) -> SKNode? {    // Create and configure a node for the anchor added to the vIEw's session.    let bialikVIDeoNode = vIDeoNodeWith(resourcename: "Tsina_05",ofType: "mp4")    bialikVIDeoNode.size = CGSize(wIDth: kDiZengofVIDeoWIDth,height: kDiZengofVIDeoHeight)    bialikVIDeoNode.anchorPoint = CGPoint(x: 0.5,y: 0.0)    // Make the vIDeo background transparent using an SKEffectNode,since chroma-key doesn't work on vIDeo    let effectNode = SKEffectNode()    effectNode.addChild(bialikVIDeoNode)    effectNode.filter = colorCubeFilterForChromakey(hueAngle: 120)    return effectNode}

这段代码为我们提供了一个透明背景(GOOD!)但固定大小和位置(不好……)的视频,如您在此屏幕截图中所示:

我想达到相同的效果,但是在SKVIDeoNode上,而不是在AVPlayerLayer上.但是,我找不到任何方法将pixelBufferAttributes设置为SKVIDeoNode,并且设置播放器层无法实现ARKit的预期效果,因为它已固定在位.

我的问题是否有任何解决方案,或者是否有其他技术可以达到相同的预期效果?

解决方法 解决方案非常简单!
所有需要做的是将视频添加为SKEffectNode的子节点,并将过滤器应用于SKEffectNode而不是视频本身(不需要AVVIDeoComposition).
这是我使用的代码: [+++]

这是根据需要的结果:

总结

以上是内存溢出为你收集整理的ios – ARKit/SpriteKit – 将pixelBufferAttributes设置为SKVideoNode或在视频中制作透明像素(色度键效果)另一种方式全部内容,希望文章能够帮你解决ios – ARKit/SpriteKit – 将pixelBufferAttributes设置为SKVideoNode或在视频中制作透明像素(色度键效果)另一种方式所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

)
File: /www/wwwroot/outofmemory.cn/tmp/route_read.php, Line: 126, InsideLink()
File: /www/wwwroot/outofmemory.cn/tmp/index.inc.php, Line: 166, include(/www/wwwroot/outofmemory.cn/tmp/route_read.php)
File: /www/wwwroot/outofmemory.cn/index.php, Line: 30, include(/www/wwwroot/outofmemory.cn/tmp/index.inc.php)
ios – ARKitSpriteKit – 将pixelBufferAttributes设置为SKVideoNode或在视频中制作透明像素(色度键效果)另一种方式_app_内存溢出

ios – ARKitSpriteKit – 将pixelBufferAttributes设置为SKVideoNode或在视频中制作透明像素(色度键效果)另一种方式

ios – ARKitSpriteKit – 将pixelBufferAttributes设置为SKVideoNode或在视频中制作透明像素(色度键效果)另一种方式,第1张

概述我的目标是使用ARKit在真实环境中呈现2D动画角色.动画角色是视频的一部分,在视频的以下快照中显示: 使用代码完全显示视频本身没有任何问题: func view(_ view: ARSKView, nodeFor anchor: ARAnchor) -> SKNode? { guard let urlString = Bundle.main.path(forResource: "reso 我的目标是使用ARKit在真实环境中呈现2D动画角色.动画角色是视频的一部分,在视频的以下快照中显示:

使用代码完全显示视频本身没有任何问题:

func vIEw(_ vIEw: ARSKVIEw,nodeFor anchor: aranchor) -> SKNode? {    guard let urlString = Bundle.main.path(forResource: "resourcename",ofType: "mp4") else { return nil }    let url = URL(fileURLWithPath: urlString)    let asset = AVAsset(url: url)    let item = AVPlayerItem(asset: asset)    let player = AVPlayer(playerItem: item)    let vIDeoNode = SKVIDeoNode(avPlayer: player)    vIDeoNode.size = CGSize(wIDth: 200.0,height: 150.0)    vIDeoNode.anchorPoint = CGPoint(x: 0.5,y: 0.0)    return vIDeoNode}

此代码的结果显示在以下应用程序的屏幕截图中,如预期:

但正如你所看到的,角色的背景并不是很好,所以我需要让它消失,以便创造出实际上站在水平面上的角色的幻觉.
我试图通过对视频产生色度键效果来实现这一点.

>对于那些不熟悉色度键的人来说,这是有时在电视上看到的“绿屏效果”的名称,以使颜色透明.

我对色度键效果的处理方法是创建基于“CIcolorCube”CIFilter的自定义滤镜,然后使用AVVIDeoComposition将滤镜应用于视频.

首先,是创建过滤器的代码:

func RGBtoHSV(r : float,g : float,b : float) -> (h : float,s : float,v : float) {    var h : CGfloat = 0    var s : CGfloat = 0    var v : CGfloat = 0    let col = UIcolor(red: CGfloat(r),green: CGfloat(g),blue: CGfloat(b),Alpha: 1.0)    col.getHue(&h,saturation: &s,brightness: &v,Alpha: nil)    return (float(h),float(s),float(v))}func colorCubeFilterForChromakey(hueAngle: float) -> CIFilter {    let hueRange: float = 20 // degrees size pIE shape that we want to replace    let minHueAngle: float = (hueAngle - hueRange/2.0) / 360    let maxHueAngle: float = (hueAngle + hueRange/2.0) / 360    let size = 64    var cubedata = [float](repeating: 0,count: size * size * size * 4)    var rgb: [float] = [0,0]    var hsv: (h : float,v : float)    var offset = 0    for z in 0 ..< size {        rgb[2] = float(z) / float(size) // blue value        for y in 0 ..< size {            rgb[1] = float(y) / float(size) // green value            for x in 0 ..< size {                rgb[0] = float(x) / float(size) // red value                hsv = RGBtoHSV(r: rgb[0],g: rgb[1],b: rgb[2])                // Todo: Check if hsv.s > 0.5 is really nesseccary                let Alpha: float = (hsv.h > minHueAngle && hsv.h < maxHueAngle && hsv.s > 0.5) ? 0 : 1.0                cubedata[offset] = rgb[0] * Alpha                cubedata[offset + 1] = rgb[1] * Alpha                cubedata[offset + 2] = rgb[2] * Alpha                cubedata[offset + 3] = Alpha                offset += 4            }        }    }    let b = cubedata.withUnsafeBufferPointer { Data(buffer: 
func vIEw(_ vIEw: ARSKVIEw,ofType: "mp4") else { return nil }    let url = URL(fileURLWithPath: urlString)    let asset = AVAsset(url: url)    let filter = colorCubeFilterForChromakey(hueAngle: 38)    let composition = AVVIDeoComposition(asset: asset,applyingCIFiltersWithHandler: { request in        let source = request.sourceImage        filter.setValue(source,forKey: kCIInputimageKey)        let output = filter.outputimage        request.finish(with: output!,context: nil)    })    let item = AVPlayerItem(asset: asset)    item.vIDeoComposition = composition    let player = AVPlayer(playerItem: item)    let vIDeoNode = SKVIDeoNode(avPlayer: player)    vIDeoNode.size = CGSize(wIDth: 200.0,y: 0.0)    return vIDeoNode}
) } let data = b as NSData let colorCube = CIFilter(name: "CIcolorCube",withinputParameters: [ "inputCubedimension": size,"inputCubedata": data ]) return colorCube!}

然后通过修改函数func视图(_ vIEw:ARSKVIEw,nodeFor anchor:aranchor)将视频应用于视频的代码 – > SKNode?我之前写的:

let playerLayer = AVPlayerLayer(player: player)playerLayer.bounds = vIEw.boundsplayerLayer.position = vIEw.centerplayerLayer.pixelBufferAttributes = [(kCVPixelBufferPixelFormatTypeKey as String): kCVPixelFormatType_32BGRA]vIEw.layer.addSublayer(playerLayer)

如果像素颜色与背景的色调范围匹配,则代码应该将视频的每个帧的所有像素替换为Alpha = 0.0.
但是我没有获得透明像素,而是将这些像素设置为黑色,如下图所示:

现在,虽然这不是想要的效果,但它并不让我感到惊讶,因为我知道这是iOS用Alpha通道显示视频的方式.
但这是真正的问题 – 当在AVPlayer中显示普通视频时,可以选择将AVPlayerLayer添加到视图中,并将pixelBufferAttributes设置为它,让玩家层知道我们使用透明像素缓冲区,就像这样:

func vIEw(_ vIEw: ARSKVIEw,nodeFor anchor: aranchor) -> SKNode? {    // Create and configure a node for the anchor added to the vIEw's session.    let bialikVIDeoNode = vIDeoNodeWith(resourcename: "Tsina_05",ofType: "mp4")    bialikVIDeoNode.size = CGSize(wIDth: kDiZengofVIDeoWIDth,height: kDiZengofVIDeoHeight)    bialikVIDeoNode.anchorPoint = CGPoint(x: 0.5,y: 0.0)    // Make the vIDeo background transparent using an SKEffectNode,since chroma-key doesn't work on vIDeo    let effectNode = SKEffectNode()    effectNode.addChild(bialikVIDeoNode)    effectNode.filter = colorCubeFilterForChromakey(hueAngle: 120)    return effectNode}

这段代码为我们提供了一个透明背景(GOOD!)但固定大小和位置(不好……)的视频,如您在此屏幕截图中所示:

我想达到相同的效果,但是在SKVIDeoNode上,而不是在AVPlayerLayer上.但是,我找不到任何方法将pixelBufferAttributes设置为SKVIDeoNode,并且设置播放器层无法实现ARKit的预期效果,因为它已固定在位.

我的问题是否有任何解决方案,或者是否有其他技术可以达到相同的预期效果?

解决方法 解决方案非常简单!
所有需要做的是将视频添加为SKEffectNode的子节点,并将过滤器应用于SKEffectNode而不是视频本身(不需要AVVIDeoComposition).
这是我使用的代码:

这是根据需要的结果:

总结

以上是内存溢出为你收集整理的ios – ARKit/SpriteKit – 将pixelBufferAttributes设置为SKVideoNode或在视频中制作透明像素(色度键效果)另一种方式全部内容,希望文章能够帮你解决ios – ARKit/SpriteKit – 将pixelBufferAttributes设置为SKVideoNode或在视频中制作透明像素(色度键效果)另一种方式所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/1099592.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-28
下一篇 2022-05-28

发表评论

登录后才能评论

评论列表(0条)

保存