swift - 如何快速正确地从图像中提取数字数组?

标签 swift pixel cgcontext unsafe-pointers

我试图从 UIImage 中快速提取数字数组,但最后我只得到一堆零,根本没有任何有用的信息。

这是我为尝试完成此任务而编写的代码。

var photo = UIImage(named: "myphoto.jpg")!

var withAlpha = true
var bytesPerPixels: Int = withAlpha ? 4 : 3

var width: Int = Int(photo.size.width)
var height: Int = Int(photo.size.height)

var bitsPerComponent: Int = 8
var bytesPerRow = bytesPerPixels * width
var totalPixels = (bytesPerPixels * width) * height

var alignment = MemoryLayout<UInt32>.alignment

var data = UnsafeMutableRawPointer.allocate(byteCount: totalPixels, alignment: alignment )

var bitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.premultipliedFirst.rawValue | CGBitmapInfo.byteOrder32Little.rawValue).rawValue


var colorSpace = CGColorSpaceCreateDeviceRGB()

let ctx = CGContext(data: data, width: width, height: height, bitsPerComponent: bitsPerComponent, bytesPerRow: bytesPerRow, space: colorSpace, bitmapInfo: bitmapInfo)


let bindedPointer: UnsafeMutablePointer<UInt32> = data.bindMemory(to: UInt32.self, capacity: totalPixels)

var pixels = UnsafeMutableBufferPointer.init(start: bindedPointer, count: totalPixels)


for p in pixels{
    print(p, Date())
}

最后我尝试绑定(bind) unsafeMutableRawPointer 来提取值但没有成功, 我在这里可能会缺少什么?

提前谢谢大家。

最佳答案

一些观察:

  • 您需要将图像绘制到上下文中。
  • 我还建议您不要创建必须手动管理的缓冲区,而是传递 nil 并让操作系统为您创建(和管理)该缓冲区。
  • 请注意,totalPixels 应仅为宽度 * 高度
  • 您的代码假定图像的比例1。这并不总是一个有效的假设。我会抓取cgImage并使用它的宽度高度
  • 即使只有三个组件,每个像素仍然需要使用 4 个字节。

因此:

guard 
    let photo = UIImage(named: "myphoto.jpg”),
    let cgImage = photo.cgImage
else { return }

let bytesPerPixels = 4

let width = cgImage.width
let height = cgImage.height

let bitsPerComponent: Int = 8
let bytesPerRow = bytesPerPixels * width
let totalPixels = width * height

let bitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.premultipliedFirst.rawValue | CGBitmapInfo.byteOrder32Little.rawValue).rawValue

let colorSpace = CGColorSpaceCreateDeviceRGB()

guard
    let ctx = CGContext(data: nil, width: width, height: height, bitsPerComponent: bitsPerComponent, bytesPerRow: bytesPerRow, space: colorSpace, bitmapInfo: bitmapInfo),
    let data = ctx.data
else { return }

ctx.draw(cgImage, in: CGRect(x: 0, y: 0, width: width, height: height))

let pointer = data.bindMemory(to: UInt32.self, capacity: totalPixels)

let pixels = UnsafeMutableBufferPointer(start: pointer, count: totalPixels)

for p in pixels {
    print(String(p, radix: 16), Date())
}

关于swift - 如何快速正确地从图像中提取数字数组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57341048/

相关文章:

ios - CIContext + createCGImage + UIImage 崩溃

xamarin.ios - 为什么这个 Core Graphics 绘图代码会生成不同的线宽?

ios - 我可以在 Swift Playground 中加载 Alex Voice吗

android - 有没有办法访问视频的像素?

java - 我如何制作像电视那样的静态屏幕效果?

java - 从内向外在正方形中绘制像素 - Java

objective-c - 如何处理在 Obj C 或 Swift 中返回对象或 nil 的 Core Data 自定义方法

swift - 如何在WKWebview中使按钮刷新页面

ios - 如何从 XMPP 消息存储中删除聊天记录?

iphone - iOS4:如何将 CGContext 转换矩阵设置为绝对数?