首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >使用CGPoint从图像中获取像素颜色

使用CGPoint从图像中获取像素颜色
EN

Stack Overflow用户
提问于 2016-01-27 13:41:45
回答 4查看 4.8K关注 0票数 3

在Swift中获取某个像素(由CGPoint指定)的像素颜色时,我遇到了很大的困难。到目前为止,我的代码如下:

代码语言:javascript
复制
@IBOutlet weak var graphImage: UIImageView!

var image : UIImage?

override func viewDidLoad() {
    super.viewDidLoad()
}

func getPixelColor(pos: CGPoint) -> UIColor {
    var pixelData = CGDataProviderCopyData(CGImageGetDataProvider(self.graphImage.image!.CGImage))
    var data : UnsafePointer<UInt8> = CFDataGetBytePtr(pixelData)

    var pixelInfo : Int = ((Int(graphImage.image!.size.width) * Int(pos.y) + Int(pos.x)*4))

    let r = CGFloat(data[pixelInfo]) / CGFloat(255.0)
    let g = CGFloat(data[pixelInfo]+1) / CGFloat(255.0)
    let b = CGFloat(data[pixelInfo]+2) / CGFloat(255.0)
    let a = CGFloat(data[pixelInfo]+3) / CGFloat(255.0)

    return UIColor(red: r, green: g, blue: b, alpha: a)
}

@IBAction func playTapped(sender: AnyObject) {

    getPixelColor(CGPoint(x: 100.0, y: 100.0))

}

在点击play之后,我的应用程序崩溃了,行"let g= CGFloat...“我根本看不到任何错误,尽管我对任何与图像有关的事情都是相当陌生的。我想知道我是否需要使用不同类型的图像,或者我的pixelInfo变量中是否有什么地方出错。顺便说一句,我从How do I get the color of a pixel in a UIImage with Swift?获得了大部分代码。谁能指出可能的问题是什么?任何帮助都将不胜感激!

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2016-01-27 15:18:23

我以前做过类似的事情。我所做的是创建一个名为PixelExtractor的单独类。

代码语言:javascript
复制
class PixelExtractor: NSObject {

  let image: CGImage
  let context: CGContextRef?

  var width: Int {
      get {
          return CGImageGetWidth(image)
      }
  }

  var height: Int {
      get {
          return CGImageGetHeight(image)
      }
  }

  init(img: CGImage) {
      image = img
      context = PixelExtractor.createBitmapContext(img)
  }

  class func createBitmapContext(img: CGImage) -> CGContextRef {

      // Get image width, height
      let pixelsWide = CGImageGetWidth(img)
      let pixelsHigh = CGImageGetHeight(img)

      let bitmapBytesPerRow = pixelsWide * 4
      let bitmapByteCount = bitmapBytesPerRow * Int(pixelsHigh)

      // Use the generic RGB color space.
      let colorSpace = CGColorSpaceCreateDeviceRGB()

      // Allocate memory for image data. This is the destination in memory
      // where any drawing to the bitmap context will be rendered.
      let bitmapData = malloc(bitmapByteCount)
      let bitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.PremultipliedFirst.rawValue)
      let size = CGSizeMake(CGFloat(pixelsWide), CGFloat(pixelsHigh))
      UIGraphicsBeginImageContextWithOptions(size, false, 0.0)
      // create bitmap
      let context = CGBitmapContextCreate(bitmapData, pixelsWide, pixelsHigh, 8,
        bitmapBytesPerRow, colorSpace, bitmapInfo.rawValue)

      // draw the image onto the context
      let rect = CGRect(x: 0, y: 0, width: pixelsWide, height: pixelsHigh)
      CGContextDrawImage(context, rect, img)

      return context!
  }

  func colorAt(x x: Int, y: Int)->UIColor {

      assert(0<=x && x<width)
      assert(0<=y && y<height)

      let uncastedData = CGBitmapContextGetData(context)
      let data = UnsafePointer<UInt8>(uncastedData)

      let offset = 4 * (y * width + x)

      let alpha: UInt8 = data[offset]
      let red: UInt8 = data[offset+1]
      let green: UInt8 = data[offset+2]
      let blue: UInt8 = data[offset+3]

      let color = UIColor(red: CGFloat(red)/255.0, green: CGFloat(green)/255.0, blue: CGFloat(blue)/255.0, alpha: CGFloat(alpha)/255.0)

      return color
  }
}
票数 5
EN

Stack Overflow用户

发布于 2017-01-27 07:23:10

jasonnoahchoi给出了一个很好的答案-如果你在转换到Swift 3.0时遇到了问题,可以尝试使用相同的代码,并进行以下更改:

代码语言:javascript
复制
class PixelExtractor: NSObject {
    
    let image: CGImage
    let context: CGContext?
    
    var width: Int {
        get {
            return image.width
        }
    }
    
    var height: Int {
        get {
            return image.height
        }
    }
    
    init(img: CGImage) {
        image = img
        context = PixelExtractor.createBitmapContext(cgImage: img)
    }
    
    class func createBitmapContext(cgImage: CGImage) -> CGContext {
        
        // Get image width, height
        let pixelsWide = cgImage.width
        let pixelsHigh = cgImage.height
        
        let bitmapBytesPerRow = pixelsWide * 4
        let bitmapByteCount = bitmapBytesPerRow * Int(pixelsHigh)
        
        // Use the generic RGB color space.
        let colorSpace = CGColorSpaceCreateDeviceRGB()
        
        // Allocate memory for image data. This is the destination in memory
        // where any drawing to the bitmap context will be rendered.
        let bitmapData = malloc(bitmapByteCount)
        let bitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.premultipliedFirst.rawValue)
        let size = CGSize(width: pixelsWide, height: pixelsHigh)
        UIGraphicsBeginImageContextWithOptions(size, false, 0.0)
        // create bitmap
        let context = CGContext(data: bitmapData, width: pixelsWide, height: pixelsHigh, bitsPerComponent: 8,
                                bytesPerRow: bitmapBytesPerRow, space: colorSpace, bitmapInfo: bitmapInfo.rawValue)
        
        // draw the image onto the context
        let rect = CGRect(x: 0, y: 0, width: pixelsWide, height: pixelsHigh)
        context?.draw(cgImage, in: rect)
        
        return context!
    }
    
    private func colorAt(x: Int, y: Int) -> UIColor {
        
        assert(0<=x && x<width)
        assert(0<=y && y<height)
        
        let data = context!.data!
        
        let offset = 4 * (y * width + x)
        
        let alpha = CGFloat(data.load(fromByteOffset: offset, as: UInt8.self)) / 255.0
        let red = CGFloat(data.load(fromByteOffset: offset + 1, as: UInt8.self)) / 255.0
        let green = CGFloat(data.load(fromByteOffset: offset + 2, as: UInt8.self)) / 255.0
        let blue = CGFloat(data.load(fromByteOffset: offset + 3, as: UInt8.self)) / 255.0
        
        let color = UIColor(red: red, green: green, blue: blue, alpha: alpha)
        
        return color
    }
}
票数 6
EN

Stack Overflow用户

发布于 2019-05-15 03:36:13

jasonnoahchoi答案的Swift 5版本

代码语言:javascript
复制
class PixelExtractor: NSObject {

    let image: CGImage
    let context: CGContext?

    var width: Int {
        get {
            return image.width
        }
    }

    var height: Int {
        get {
            return image.height
        }
    }

    init(img: CGImage) {
        image = img
        context = PixelExtractor.createBitmapContext(img: img)
    }

    class func createBitmapContext(img: CGImage) -> CGContext {

        // Get image width, height
        let pixelsWide = img.width
        let pixelsHigh = img.height

        let bitmapBytesPerRow = pixelsWide * 4
        let bitmapByteCount = bitmapBytesPerRow * Int(pixelsHigh)

        // Use the generic RGB color space.
        let colorSpace = CGColorSpaceCreateDeviceRGB()

        // Allocate memory for image data. This is the destination in memory
        // where any drawing to the bitmap context will be rendered.
        let bitmapData = malloc(bitmapByteCount)
        let bitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.premultipliedFirst.rawValue)
        let size = CGSize(width: CGFloat(pixelsWide), height: CGFloat(pixelsHigh))
        UIGraphicsBeginImageContextWithOptions(size, false, 0.0)
        // create bitmap
        let context = CGContext(data: bitmapData,
                                width: pixelsWide,
                                height: pixelsHigh,
                                bitsPerComponent: 8,
                                bytesPerRow: bitmapBytesPerRow,
                                space: colorSpace,
                                bitmapInfo: bitmapInfo.rawValue)

        // draw the image onto the context
        let rect = CGRect(x: 0, y: 0, width: pixelsWide, height: pixelsHigh)

        context?.draw(img, in: rect)

        return context!
    }

    func colorAt(x: Int, y: Int)->UIColor {

        assert(0<=x && x<width)
        assert(0<=y && y<height)

        guard let pixelBuffer = context?.data else { return .white }
        let data = pixelBuffer.bindMemory(to: UInt8.self, capacity: width * height)

        let offset = 4 * (y * width + x)

        let alpha: UInt8 = data[offset]
        let red: UInt8 = data[offset+1]
        let green: UInt8 = data[offset+2]
        let blue: UInt8 = data[offset+3]

        let color = UIColor(red: CGFloat(red)/255.0, green: CGFloat(green)/255.0, blue: CGFloat(blue)/255.0, alpha: CGFloat(alpha)/255.0)

        return color
    }
}
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35029672

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档