如何在 Swift iOS 中读取和记录图像的原始像素

Posted

技术标签:

【中文标题】如何在 Swift iOS 中读取和记录图像的原始像素【英文标题】:How to read and log the raw pixels of image in swift iOS 【发布时间】:2016-02-17 16:44:01 【问题描述】:

我需要读取图像的像素值并迭代以在 swift 输出中打印,到目前为止,我已经编写了这个并使用 RGBAImage 类来读取像素。我从CGContextRef 到迭代迷路了。我尝试从 CGImage 编写,将像素数据从目标 C 语言获取到 swift,因为我想在 swift 中工作。

func createRGBAPixel(inImage: CGImageRef) -> CGContextRef 
//Image width, height

let pixelWidth = CGImageGetWidth(inImage)
let pixelHeight = CGImageGetHeight(inImage)

//Declaring number of bytes 

let bytesPerRow = Int(pixelWidth) * 4
let byteCount = bytesPerRow * Int(pixelHeight)

//RGB color space

let colorSpace = CGColorSpaceCreateDeviceRGB()

//Allocating image data

let mapData = malloc(byteCount)
let mapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.PremultipliedFirst.rawValue)

//Create bitmap context

let context = CGBitmapContextCreate(mapData, pixelWidth, pixelHeight, Int(8), Int(bytesPerRow), colorSpace, mapInfo.rawValue)

let pixelImage = CGBitmapContextCreate(pixels, pixelWidth, pixelHeight, bitsPerComponent, bytesPerRow, colorSpace, mapInfo)
let CGContextRef = pixelImage
let CGContextDrawImage(context, CGRectMake(0, 0, pixelWidth, pixelHeight), inImage)

//Iterating and logging
print("Logging pixel counts")
let pixels = calloc(pixelHeight * pixelWidth, sizeof(UInt32))

let myImage = CGImageRef: inImage
let myRGBA = RGBAImage(image: myImage)! //RGBAImage class to read pixels.

var number = 0
var currentPixel:Int32 = 0
currentPixel = pixels * UInt32
for number in 0..<pixelHeight 
  for number in 0..<pixelWidth 
    var color = color * currentPixel
    print((pixel.red + pixel.green + pixel.blue) / 3.0)
    currentPixel++
  

return context!

【问题讨论】:

【参考方案1】:

我为此创建了小班:

class ImagePixelReader 

    enum Component:Int 
        case r = 0
        case g = 1
        case b = 2
        case alpha = 3
    

    struct Color 
        var r:UInt8
        var g:UInt8
        var b:UInt8
        var a:UInt8

        var uiColor:UIColor 
            return UIColor(red:CGFloat(r)/255.0,green:CGFloat(g)/255.0,blue:CGFloat(b)/255.0,alpha:CGFloat(alpha)/255.0)
        

    

    let image:UIImage

    private var data:CFData
    private let pointer:UnsafePointer<UInt8>
    private let scale:Int

    init?(image:UIImage)

        self.image = image
        guard let cfdata = self.image.cgImage?.dataProvider?.data,
              let pointer = CFDataGetBytePtr(cfdata) else 
            return nil
        
        self.scale = Int(image.scale)
        self.data = cfdata
        self.pointer = pointer
    

    func componentAt(_ component:Component,x:Int,y:Int)->UInt8

        assert(CGFloat(x) < image.size.width)
        assert(CGFloat(y) < image.size.height)

        let pixelPosition = (Int(image.size.width) * y * scale + x) * 4 * scale

        return pointer[pixelPosition + component.rawValue]
    

    func colorAt(x:Int,y:Int)->Color

        assert(CGFloat(x) < image.size.width)
        assert(CGFloat(y) < image.size.height)

        let pixelPosition = (Int(image.size.width) * y * scale + x) * 4 * scale

        return Color(r: pointer[pixelPosition + Component.r.rawValue],
                     g: pointer[pixelPosition + Component.g.rawValue],
                     b: pointer[pixelPosition + Component.b.rawValue],
                     a: pointer[pixelPosition + Component.alpha.rawValue])
    

使用方法:

if let reader = ImagePixelReader(image: yourImage) 

   //get alpha or color
   let alpha = reader.componentAt(.alpha, x: 10, y:10)
   let color = reader.colorAt(x:10, y: 10).uiColor

   //getting all the pixels you need

   var values = ""

   //iterate over all pixels
   for x in 0 ..< Int(image.size.width)
     for y in 0 ..< Int(image.size.height)

        let color = reader.colorAt(x: x, y: y)
        values += "[\(x):\(y):\(color)] "

     
     //add new line for every new row
     values += "\n"
   

   print(values)

【讨论】:

以上是关于如何在 Swift iOS 中读取和记录图像的原始像素的主要内容,如果未能解决你的问题,请参考以下文章

iOS - 如何获取时区的原始偏移量?

在 Swift 中捕获原始图像类型

如何在 Xcode 8 和 iOS 10 中使用 AFNetworking 类和 Swift 3 上传图像

如何仅在 Swift 中访问从相机拍摄的图像,就像 iOS 中的画廊一样?

在iOS swift中旋转和混合图像

在 iOS/swift 中上传图像时如何删除裁剪选项