- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我的 CVPixelBuffer 以 kCVPixelFormatType_32BGRA 的形式出现,我正在尝试以 BGR 格式获取没有 Alpha channel 的帧数据。这是我尝试做的(作为 扩展 CVPixelBuffer
)
func bgrData(byteCount: Int) -> Data? {
CVPixelBufferLockBaseAddress(self, .readOnly)
defer { CVPixelBufferUnlockBaseAddress(self, .readOnly) }
guard let sourceData = CVPixelBufferGetBaseAddress(self) else {
return nil
}
let width = CVPixelBufferGetWidth(self)
let height = CVPixelBufferGetHeight(self)
let sourceBytesPerRow = CVPixelBufferGetBytesPerRow(self)
let destinationBytesPerRow = 3 * width
// Assign input image to `sourceBuffer` to convert it.
var sourceBuffer = vImage_Buffer(
data: sourceData,
height: vImagePixelCount(height),
width: vImagePixelCount(width),
rowBytes: sourceBytesPerRow
)
// Make `destinationBuffer` and `destinationData` for its data to be assigned.
guard let destinationData = malloc(height * destinationBytesPerRow) else {
os_log("Error: out of memory", type: .error)
return nil
}
defer { free(destinationData) }
var destinationBuffer = vImage_Buffer(
data: destinationData,
height: vImagePixelCount(height),
width: vImagePixelCount(width),
rowBytes: destinationBytesPerRow)
// Return `Data` with bgr image.
return imageByteData = Data(
bytes: sourceBuffer.data, count: destinationBuffer.rowBytes * height)
}
但是得到的buffer好像不对。实现这一目标的最佳方法是什么?提前致谢
最佳答案
由于您有权访问您的 CVPixelBuffer,您可以直接使用 Accelerate 框架为您进行转换。
我不会检查此代码中的任何错误、try/catch 语句、无守卫等。您需要确保代码已防错。
让我们首先定义我们的 BGRA 颜色格式。因为我们有 4 个 channel ,所以每个像素需要 32 位。我们还定义我们的 alpha channel 是最后一位。
var bgraSourceFormat = vImage_CGImageFormat(
bitsPerComponent: 8,
bitsPerPixel: 32,
colorSpace: Unmanaged.passRetained(CGColorSpaceCreateDeviceRGB()),
bitmapInfo: CGBitmapInfo(rawValue: CGImageAlphaInfo.last.rawValue),
version: 0,
decode: nil,
renderingIntent: .defaultIntent
)
现在我们可以定义 BGR 格式了。我们需要 3 个 channel ,因此每个像素 24 位就足够了。我们还定义此格式将没有 alpha channel 。
var bgrDestinationFormat = vImage_CGImageFormat(
bitsPerComponent: 8,
bitsPerPixel: 24,
colorSpace: nil,
bitmapInfo: CGBitmapInfo(rawValue: CGImageAlphaInfo.none.rawValue),
version: 0,
decode: nil,
renderingIntent: .defaultIntent
)
并创建转换器...
let bgraToRgbConverter = vImageConverter_CreateWithCGImageFormat(
&bgraSourceFormat,
&bgrDestinationFormat,
nil,
vImage_Flags(kvImagePrintDiagnosticsToConsole),
nil
)
let converter = bgraToRgbConverter!.takeRetainedValue()
现在我们需要从我们现有的像素数据创建一个读取缓冲区,以及一个用于复制我们需要的内容的写入缓冲区。要从 CVPixelBuffer 创建一个读取缓冲区,我们可以这样做:
var bgraBuffer = vImage_Buffer()
let imageFormat = vImageCVImageFormat_CreateWithCVPixelBuffer(cvPixelBuffer).takeRetainedValue()
vImageCVImageFormat_SetColorSpace(imageFormat, CGColorSpaceCreateDeviceRGB())
vImageBuffer_InitWithCVPixelBuffer(
&bgraBuffer,
&bgraSourceFormat,
cvPixelBuffer,
imageFormat,
nil,
vImage_Flags(kvImageNoFlags)
)
并创建空的写入缓冲区...
var bgrBuffer = vImage_Buffer()
vImageBuffer_Init(
&bgrBuffer,
bgraBuffer.height,
bgraBuffer.width,
bgrDestinationFormat.bitsPerPixel,
vImage_Flags(kvImageNoFlags)
)
我们准备好了......让我们告诉加速框架从一种格式转换为另一种格式
vImageConvert_AnyToAny(
converter,
&bgraBuffer,
&bgrBuffer,
nil,
vImage_Flags(kvImagePrintDiagnosticsToConsole)
)
仅此而已。您的 BGRA 现在已作为 vImage_Buffer
转换为 BGR。我们可以通过直接读取像素数据来检查我们是否完成了我们想要的。首先,我们需要访问数据:
let bgraData = bgraBuffer.data!.assumingMemoryBound(to: UInt8.self)
let bgrData = bgrBuffer.data!.assumingMemoryBound(to: UInt8.self)
现在,我们可以打印第一个和第二个像素
print(bgraData[0], bgraData[1], bgraData[2], bgraData[3])
print(bgrData[0], bgrData[1], bgrData[2])
print(bgraData[4], bgraData[5], bgraData[6], bgraData[7])
print(bgrData[3], bgrData[4], bgrData[5])
这是我在 playgrounds 中用于测试的 png 图像中看到的输出:
249 244 234 255
249 244 234
251 242 233 255
251 242 233
如您所见,像素是在没有 alpha channel 的情况下复制的。如果您要使用任何循环,请小心您的 for 循环,因为我们现在有 3 个 channel 。
如果您正在开发一款游戏并在每一帧都这样做,请尝试让您的对象保持事件状态。加速格式定义,写入缓冲区和转换器不会因相同的图像大小和格式而改变,因此它们可以创建一次并保存在内存中以备将来使用。
看起来您正在返回一个数据对象。您可以将 UnsafeMutablePointer
构造转换为您需要的任何内容。
或者您也可以使用加速器的 vImageBuffer_CopyToCVPixelBuffer
方法将 vImage_Buffer
转换回 CVPixelBuffer(如果需要)。 vImage_Buffer
有很多转换器,总有一款适合你。检查this link有关如何使用复制到像素缓冲区方法的更多信息。 This link有一个很好的用法示例。
编辑:您的 CVPixelBuffer 可能会被填充。
由于硬件要求,您的图像可能有一个填充以确保缓冲区宽度和高度是 16 的倍数。这也会导致在您的 vImage_Buffer
结构中进行填充。如果你需要循环,但只需要访问/更新单个像素,你可以使用 Accelerate 的函数来提高速度。检查这个link了解可能的方法,页面末尾有很好的示例。
要完整读取数据,可以这样写:
var bgrData = bgrBuffer.data!.assumingMemoryBound(to: UInt8.self)
print(bgrBuffer.width, bgrBuffer.height, bgrBuffer.rowBytes)
for _ in 0 ..< Int(bgrBuffer.height) {
for x in 0 ..< Int(bgrBuffer.width) {
let b = (bgrData + x * 3 + 0).pointee
let g = (bgrData + x * 3 + 1).pointee
let r = (bgrData + x * 3 + 2).pointee
print(b, g, r)
}
bgrData = bgrData.advanced(by: bgrBuffer.rowBytes)
}
这将确保您正在读取全宽像素,但在末尾传递填充。
关于ios - 如何从 CVPixelBuffer 中删除 alpha channel 并在 Swift 中获取其数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63243981/
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 这个问题似乎不是关于 a specific programming problem, a softwar
我不知道我问的是否可行。 我有一个带有 Color.BLACK 的 Paint 和 0.2f 的 alpha 和两个对象: 它们都使用相同的Paint。我还测试了 2 个不同的 Paint 对象,仅更
Alpha Vantage API 不提供纳斯达克指数的报价(不再?)。我感兴趣的所有其他 indizes 似乎都很有魅力。 例如,调用以下 URL(隐藏 API key )将提供 S&P 的报价(符
问:有没有办法使用默认管道正确混合 Alpha 分量? 问题:我正在将半透明表面绘制到纹理中,然后我想将该纹理传输到主框架后台缓冲区中。通常,当您使用直接的 Alpha 混合来实现透明度或抗锯齿时,会
如果我有一个底层颜色和一个 alpha 值 (C&A),并且想在屏幕上创建一个自定义 C&A,那么确定必须将什么 C&A 作为底层添加到底层之上的层的函数是什么? 编辑: 我想复制 photoshop
我想知道它们之间的区别: 给我的 UIView 分配一个颜色 <1 alpha vs 为它指定一个不透明的颜色,但给 UIView 一个 <1 的 alpha 值。 在屏幕截图上,我制作了两个 UIV
我在 OSX 10.9.4 上试图转换这个 python 正则表达式 p = "(2024 (?:(?:(?:[a-z|.]+ ?)+)) 93)"到 Unix 正则表达式以提高 grep 的速度。
我为 4 张图像制作了这个脚本,第一张图像是 alpha,但从第二张开始什么都没有显示 这是ffmpeg的代码确实有错误,但我没有。不明白:[swscaler @ 0x7fef79845e00] 使用
我正在尝试将文本绘制到具有特定 Alpha 级别的 Canvas 上,并剪辑文本并使用其自己的 Alpha 级别绘制背景颜色: ctx.globalCompositeOperation = '...'
我需要实现Lasso和Ridge回归,并通过交叉验证的方式计算超参数。我找到了执行此操作的代码,但我不太理解它。 lassocv = LassoCV(alphas=None, cv=15, max_i
我得到我的位图,将它用作着色器平铺模式。 除了要绘制的形状轮廓外,PNG 大部分是 alpha。 除了它画出轮廓,但被黑色包围,不是透明的(alpha)。 pnt.reset(); i
我正在开发一个带有 tableViewController 的应用程序。我想在我的表格 View 单元格下方添加背景图片。我想让表格 View 单元格透明,以便我的整个表格 View 可以具有自定义背
如图所示,我有 2 个具有 0.5 alpha 和 1 alpha 的按钮。我想将第一张图片中标题的 alpha 更改为 1,这可能吗? 到目前为止,我尝试了这些都不起作用: button.title
我正在尝试生成一个 python 正则表达式来表示词法分析器的标识符。我的做法是: ([a-zA-Z]([a-zA-Z]|\d)*) 当我使用它时: regex = re.compile("\s*([
我正在尝试删除所有非数字字符的字符串,并且我已阅读 Why isn't isnumeric working? ,或者我必须有一个 unicode 字符串。然而,自从 is.alnum()和is.alp
来自 hadoop 网站上的发布页面: “This release, like previous releases in hadoop-2.x series is still considered a
真的没有与 setAlpha(int) 对应的 XML 属性吗? 如果没有,有什么替代方案? 最佳答案 它比其他响应更容易。有一个 xml 值 alpha 采用 double 值。 android:a
我正在three.js 中构建一个“ Papercut ”世界。我所有的模型都是简单的“平面”,我使用带有 Alpha channel 的 PNG 对它们进行纹理处理,以将平面修剪成更令人愉悦的形状。
我想知道 Graphics2D.setComposite(..., alpha) 之间是否真的有区别和 Graphics2D.setColor(new Color(..., alpha))在 Java
我需要在两个图像之间进行转换 - 两个图像都是隐藏下面的 Sprite 的蒙版。每个面具的一部分是白色的,一部分是透明的。我需要两个图像的总 alpha 每次都为 1,这样蒙版看起来会平滑地改变其形状
我是一名优秀的程序员,十分优秀!