【问题标题】:how to properly extract the array of numbers from an image in swift?如何快速正确地从图像中提取数字数组?
【发布时间】:2019-08-03 18:22:44
【问题描述】:

我正在尝试快速从 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())
}

最后我尝试绑定 unsafeMutableRawPointer 以提取值但没有成功, 我会在这里遗漏什么?

提前谢谢大家。

【问题讨论】:

  • 与您的问题无关,但为什么要为每个字节打印日期?

标签: swift pixel cgcontext unsafe-pointers


【解决方案1】:

一些观察:

  • 您需要将图像绘制到上下文中。
  • 我还建议不要创建必须手动管理的缓冲区,而是传递nil 并让操作系统为您创建(和管理)该缓冲区。
  • 注意totalPixels 应该只是width * height
  • 您的代码假定图像的scale1。这并不总是一个有效的假设。我会抓住cgImage 并使用它的widthheight
  • 即使您只有三个组件,您仍然需要使用每个像素 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())
}

【讨论】:

    【解决方案2】:

    您需要将图像绘制到上下文中。

    ctx?.draw(photo.cgImage!, in: CGRect(origin: .zero, size: photo.size))
    

    在创建 CGContext 之后添加它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-12-26
      • 1970-01-01
      • 1970-01-01
      • 2016-03-03
      • 2015-03-14
      • 2022-10-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多