- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
这里我有一个 MTKView 并在摄像头源上实时运行一个简单的 CIFilter。这很好用。
在旧设备的自拍相机上,例如 iPhone 5、iPad Air,提要绘制在较小的区域。 更新:发现发生这种情况时,馈送到 MTKView 的 CMSampleBuffer 尺寸较小。我想每次更新中的纹理都需要按比例放大?
import UIKit
import MetalPerformanceShaders
import MetalKit
import AVFoundation
final class MetalObject: NSObject, MTKViewDelegate {
private var metalBufferView : MTKView?
private var metalDevice = MTLCreateSystemDefaultDevice()
private var metalCommandQueue : MTLCommandQueue!
private var metalSourceTexture : MTLTexture?
private var context : CIContext?
private var filter : CIFilter?
init(with frame: CGRect, filterType: Int, scaledUp: Bool) {
super.init()
self.metalCommandQueue = self.metalDevice!.makeCommandQueue()
self.metalBufferView = MTKView(frame: frame, device: self.metalDevice)
self.metalBufferView!.framebufferOnly = false
self.metalBufferView!.isPaused = true
self.metalBufferView!.contentScaleFactor = UIScreen.main.nativeScale
self.metalBufferView!.delegate = self
self.context = CIContext()
}
final func update (sampleBuffer: CMSampleBuffer) {
var textureCache : CVMetalTextureCache?
CVMetalTextureCacheCreate(kCFAllocatorDefault, nil, self.metalDevice!, nil, &textureCache)
var cameraTexture: CVMetalTexture?
guard
let cameraTextureCache = textureCache,
let pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) else {
return
}
let cameraTextureWidth = CVPixelBufferGetWidthOfPlane(pixelBuffer, 0)
let cameraTextureHeight = CVPixelBufferGetHeightOfPlane(pixelBuffer, 0)
CVMetalTextureCacheCreateTextureFromImage(kCFAllocatorDefault,
cameraTextureCache,
pixelBuffer,
nil,
MTLPixelFormat.bgra8Unorm,
cameraTextureWidth,
cameraTextureHeight,
0,
&cameraTexture)
if let cameraTexture = cameraTexture,
let metalTexture = CVMetalTextureGetTexture(cameraTexture) {
self.metalSourceTexture = metalTexture
self.metalBufferView!.draw()
}
}
//MARK: - Metal View Delegate
final func draw(in view: MTKView) {
guard let currentDrawable = self.metalBufferView!.currentDrawable,
let sourceTexture = self.metalSourceTexture
else { return }
let commandBuffer = self.metalCommandQueue!.makeCommandBuffer()
var inputImage = CIImage(mtlTexture: sourceTexture)!.applyingOrientation(self.orientationNumber)
if self.showFilter {
self.filter!.setValue(inputImage, forKey: kCIInputImageKey)
inputImage = filter!.outputImage!
}
self.context!.render(inputImage, to: currentDrawable.texture, commandBuffer: commandBuffer, bounds: inputImage.extent, colorSpace: self.colorSpace!)
commandBuffer.present(currentDrawable)
commandBuffer.commit()
}
final func mtkView(_ view: MTKView, drawableSizeWillChange size: CGSize) {
}
}
最佳答案
看起来旧设备上前置(自拍)摄像头的分辨率较低,因此如果您想让视频使用全宽或全高,则需要按比例放大视频。由于您已经在使用 CIContext 和 Metal,您可以简单地指示渲染调用将图像绘制到您喜欢的任何矩形。
在您的draw
方法中,您执行
self.context!.render(inputImage,
to: currentDrawable.texture,
commandBuffer: commandBuffer,
bounds: inputImage.extent,
colorSpace: self.colorSpace!)
bounds
参数是将在其中呈现图像的目标 矩形。当前,您正在使用图像范围,这意味着图像不会被缩放。
要放大视频,请改用显示矩形。您可以简单地使用您的 metalBufferView.bounds
因为这将是您的显示 View 的大小。你最终会得到
self.context!.render(inputImage,
to: currentDrawable.texture,
commandBuffer: commandBuffer,
bounds: self.metalBufferView.bounds,
colorSpace: self.colorSpace!)
如果图像和 View 具有不同的纵横比(宽度/高度是纵横比),那么您必须计算正确的尺寸以保持图像的纵横比。为此,您最终会得到如下代码:
CGRect dest = self.metalBufferView.bounds;
CGSize imageSize = inputImage.extent.size;
CGSize viewSize = dest.size;
double imageAspect = imageSize.width / imageSize.height;
double viewAspect = viewSize.width / viewSize.height;
if (imageAspect > viewAspect) {
// the image is wider than the view, adjust height
dest.size.height = 1/imageAspect * dest.size.width;
} else {
// the image is taller than the view, adjust the width
dest.size.width = imageAspect * dest.size.height;
// center the tall image
dest.origin.x = (viewSize.width - dest.size.width) / 2;
}
希望这有用,如果有任何问题或澄清会有所帮助,请告诉我。
关于ios - Metal View (MTKView) 绘图尺寸问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50416342/
我在由窗口 Controller 管理的窗口中有一个 MTKView。当我第一次实例化窗口 Controller 和窗口时,MTKView 调用我的委托(delegate)的两个调用,并以首选速率调用
我想在 Mac 应用程序上使用 MTKView。初始化 MTKView 后,它显示红色而不是预期的清晰颜色我的笔记本电脑是 macOS Catalina 10.15.2 的 MacBook Pro,它
我有一个 Metal 片段着色器,它返回一些带有 alpha channel 的透明颜色,我想在 MTKView 下显示一个 UIView,但我得到的背景结果只有黑色和“错误噪声”。 MTLRende
我有一个简单的 macOS 应用程序,它有一个 MTKView——它只是窗口内的一个 MTKView。片段着色器总是这样做: return float4(1, 0, 0, 0.01) 这是带有 1%
我知道在 SceneKit 中,您可以在 SKView 的一侧启用横幅查看实时帧速率和其他有用的调试信息。但是 MTKView 呢? ?我似乎没有找到这样的属性来启用,或者我如何查询当前的帧速率。 (
我正在使用 MTKView 来绘制 Metal 内容。它的配置如下: mtkView = MTKView(frame: self.view.frame, device: device)
我已经成功地创建了一个应用程序来接收实时的 h264 编码视频流,然后使用 Video Toolbox 和 AVSampleBufferDisplayLayer 解码并显示视频。这按预期工作,但我希望
我得到了什么 我正在关注 Apple 示例代码 AVCamPhotoFilter 在 MTKView 上显示相机画面。 我想做什么 除了上面的MTKView,我还需要显示第二个MTKView。但是,第
我是 Metal 的新手,但正在努力遵循 Apple 的 AVCamFilter示例项目。该项目演示了如何使用 MTKView 作为 AVCaptureSession 的预览。 我一直未能弄清楚如何让
我正在尝试实现一个 Metal 支持的绘图应用程序,其中通过沿路径重复冲压纹理正方形在 MTKView 上绘制笔触。我遇到的问题是,虽然每个画笔图章都正确显示了纹理的不透明度,但重叠的方 block
我正在尝试使用 MTKView 进行多重采样。我有一个带有委托(delegate)的 MTKView。我将 View 的 sampleCount 属性设置为 4。我创建了一个将 rasterSampl
众所周知,更新 AppKit 中的用户界面或 UIKit需要在主线程上进行。在展示 drawable 时,Metal 是否有相同的要求? ? 在一个层托管 NSView我一直在玩,我注意到我可以调用[
我有一个项目,用户可以在其中拍摄视频,然后为他们添加滤镜或更改亮度和对比度等基本设置。为此,我使用 BBMetalImage ,它基本上返回 MTKView 中的视频(在项目中命名为 BBMetalV
我正在尝试实现一个 Metal 支持的绘图应用程序,其中通过沿着路径重复冲压纹理方 block 来在 MTKView 上绘制笔触。我在绘制笔触时在顶点级别改变图章的颜色/透明度,这样我就可以模拟墨水效
我正在将 CIImage 渲染到 MTKView 并且图像小于可绘制对象。 let centered = image.transformed(by: CGAffineTransform(transla
我在我的 UIKit 应用程序中使用 MTKViews 来选择 UI 元素。我有一个中央 Metal Controller ,它做的事情有点像这样: public class MetalView: M
这里我有一个 MTKView 并在摄像头源上实时运行一个简单的 CIFilter。这很好用。 问题 在旧设备的自拍相机上,例如 iPhone 5、iPad Air,提要绘制在较小的区域。 更新:发现发
这可能更像是一个通用的图形编程问题,但目前这是在 macOS 上使用 Apple 的 Metal 框架的上下文中。 在 NSView mouseDown 中,只需调用以下命令即可轻松获取鼠标按下事件发
从 MTKView 捕获帧的最有效方法是什么?如果可能的话,我想实时保存帧中的 .mov 文件。是否可以渲染成 AVPlayer 帧或其他东西? 目前正在使用此代码绘制(基于@warrenm Perf
如果我将窗口大小调整为小于 Metal View ,我可以看到滚动条一秒钟,但我无法单击它们,它们也保持可见。你知道我该如何改变这种行为吗?我希望只要窗口小于 Metal View ,滚动条就可见且可
我是一名优秀的程序员,十分优秀!