【问题标题】:Swift 3: get color of pixel in UIImage (better: UIImageView)Swift 3:获取 UIImage 中像素的颜色(更好:UIImageView)
【发布时间】:2020-12-19 15:38:56
【问题描述】:

我尝试了不同的解决方案(例如this one),但我得到的颜色看起来与真实图像中的颜色有些不同。我猜这是因为图像只有RGB,而不是RGBA。这可能是个问题吗?

相关问题:如果 UIImage 有contentMode = .scaleAspectFill,我是否必须重新计算图像,还是只使用imageView.image

编辑:

我试过这个扩展:

extension CALayer {
    func getPixelColor(point: CGPoint) -> CGColor {
        var pixel: [CUnsignedChar] = [0, 0, 0, 0]

        let colorSpace = CGColorSpaceCreateDeviceRGB()
        let bitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.premultipliedLast.rawValue)

        let context = CGContext(data: &pixel, width: 1, height: 1, bitsPerComponent: 8, bytesPerRow: 4, space: colorSpace, bitmapInfo: bitmapInfo.rawValue)

        context!.translateBy(x: -point.x, y: -point.y)

        self.render(in: context!)

        let red: CGFloat   = CGFloat(pixel[0]) / 255.0
        let green: CGFloat = CGFloat(pixel[1]) / 255.0
        let blue: CGFloat  = CGFloat(pixel[2]) / 255.0
        let alpha: CGFloat = CGFloat(pixel[3]) / 255.0


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

        return color.cgColor
    }
}

但对于某些图像,坐标系似乎是颠倒的,而对于其他图像,我得到的值真的是错误的......我在这里错过了什么?

编辑 2:

我尝试使用这些图片:

https://dl.dropboxusercontent.com/u/119600/gradient.png https://dl.dropboxusercontent.com/u/119600/gradient@2x.png

但我确实得到了错误的值。它们嵌入在 UIImageView 中,但我转换了坐标:

private func convertScreenPointToImage(point: CGPoint) -> CGPoint {
    let widthMultiplier = gradientImage.size.width / UIScreen.main.bounds.width
    let heightMultiplier = gradientImage.size.height / UIScreen.main.bounds.height

    return CGPoint(x: point.x * widthMultiplier, y: point.y * heightMultiplier)
}

这个

在 iPhone 7 模拟器上运行时给我=== Optional((51, 76, 184, 255)),这是不正确的...

【问题讨论】:

    标签: uiimageview uiimage


    【解决方案1】:

    我写这是一个游乐场。我用指针索引图像数据并获取 rgba 值:

    func pixel(in image: UIImage, at point: CGPoint) -> (UInt8, UInt8, UInt8, UInt8)? {
        let width = Int(image.size.width)
        let height = Int(image.size.height)
        let x = Int(point.x)
        let y = Int(point.y)
        guard x < width && y < height else {
            return nil
        }
        guard let cfData:CFData = image.cgImage?.dataProvider?.data, let pointer = CFDataGetBytePtr(cfData) else {
            return nil
        }
        let bytesPerPixel = 4
        let offset = (x + y * width) * bytesPerPixel
        return (pointer[offset], pointer[offset + 1], pointer[offset + 2], pointer[offset + 3])
    }
    
    let image = UIImage(named: "t.png")!
    if let (r,g,b,a) = pixel(in: image, at: CGPoint(x: 1, y:2)) {
        print ("Red: \(r), Green: \(g), Blue: \(b), Alpha: \(a)")
    }
    

    请注意,如果您在作为 UIImageView 属性的 UIImage 上使用它,则像素坐标是原始分辨率下实际图像的像素坐标,而不是缩放后的 UIImageView 的屏幕坐标。它还尝试了 RGB Jpg 和 RGBA PNG,两者都被导入为 32 位 RGBA 图像,因此它适用于两者。

    【讨论】:

    • 我无法让它正常工作,我仍然得到错误的值 :( 请查看我的编辑
    • 代码正确;我刚刚用你的第一张图片检查了它。我打开 Photoshop,切换到吸管工具并打开信息面板。我将鼠标悬停在 x = 120, y = 500 的像素上,photoshop 说 r:175 g: 146 b 232。我在操场上运行代码,得到红色 175,绿色:146,蓝色:232,Alpha:255。您的输入和预期输出是什么?
    • 我得到了不同的值(见我的编辑) - 你如何加载图像?
    • 像在操场上一样加载它 let image = UIImage (named: "gradient.png")!我敢打赌这就是问题所在。您正在从资产目录加载,因此您将获得 @2x 图像。而我直接加载 1X 图像。
    猜你喜欢
    • 2020-05-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多