【问题标题】:Image color bug?图像颜色错误?
【发布时间】:2018-08-23 10:25:38
【问题描述】:

我想使用我在下面添加的代码在 UIImage 上生成这个很酷的东西。 但似乎有一个与颜色有关的疯狂错误

所以我希望我的函数用给定的 RGB 值在图像上画线(在我的例子中是 r:76, g:255, b:0 以获得这种绿色外观),因为它的颜色:

但我使用的代码只是将图像着色为洋红色而不是绿色

请看我的代码:

func colorImage(image: UIImage) -> UIImage {
    let color = RGBA32(red: 76, green: 255, blue: 0, alpha: 255)
    let img: CGImage = image.cgImage!
    let context = CGContext(data: nil, width: img.width, height: img.height, bitsPerComponent: 8, bytesPerRow: 4 * img.width, space: CGColorSpaceCreateDeviceRGB(), bitmapInfo: CGImageAlphaInfo.premultipliedLast.rawValue)!
    context.draw(img, in: CGRect(x: 0, y: 0, width: img.width, height: img.height))
    let binaryData = context.data!.bindMemory(to: RGBA32.self, capacity: img.width * img.height)
    for y in stride(from: 0, through: img.height, by: 10) {
        for x in 0..<img.width {
            let pixel = (y*img.width) + x
            binaryData[pixel] = color
        }
    }
    let output = context.makeImage()!
    return UIImage(cgImage: output, scale: image.scale, orientation: image.imageOrientation)
}

struct RGBA32: Equatable {
    private var color: UInt32
    init(red: UInt8, green: UInt8, blue: UInt8, alpha: UInt8) {
        let red   = UInt32(red)
        let green = UInt32(green)
        let blue  = UInt32(blue)
        let alpha = UInt32(alpha)
        color = (red << 24) | (green << 16) | (blue << 8) | (alpha << 0)
    }
    static func ==(lhs: RGBA32, rhs: RGBA32) -> Bool {
        return lhs.color == rhs.color
    }
}

Tbh 我完全不知道为什么会出现这个问题 - 所以任何如何解决这个问题的帮助将不胜感激。谢谢:)

【问题讨论】:

  • 你不觉得显示的颜色看起来像 r:255,g:0,b:255,a:76。你知道 iOS 在 little-endian CPU 上运行吗?
  • 为每个像素分配一个struct而不是struct中包含的UInt32值似乎真的很奇怪。也许我错过了什么。
  • 您愿意分享一些关于您的想法的代码吗? @rmaddy
  • 无需处理像素,只需将原始图像绘制到图像图形上下文中,在其上绘制线条,然后提取结果图像。完成。
  • 所以上面的代码只是一个示例 sn-p - 我绝对意识到“通过操纵它的像素在 UIView 上画线”是完全错误的方式但是在我的 (未共享) 代码的“操纵像素”的其他部分出现了这个颜色问题 - 这就是我问你们并添加一个简单示例以在显而易见的方式:) @matt

标签: ios swift image colors


【解决方案1】:

RGBA 是一个令人困惑的词。不清楚 R 是 32 位数据中的最高有效字节还是 4 字节内存区域中的第一个字节。

但是有了你的bitmapInfo: CGImageAlphaInfo.premultipliedLast.rawValue, R 位居第一,G、B 和 Alpha 最后。

UInt32 的小端表示中,R 表示最低有效字节。

试试这个版本的RGBA

struct RGBA32: Equatable {
    private var color: (red: UInt8, green: UInt8, blue: UInt8, alpha: UInt8)
    init(red: UInt8, green: UInt8, blue: UInt8, alpha: UInt8) {
        color = (red: red, green: green, blue: blue, alpha: alpha)
    }
    static func ==(lhs: RGBA32, rhs: RGBA32) -> Bool {
        return lhs.color == rhs.color
    }
}

(Swift 结构或元组的内存分配没有明确定义,但上面的代码按预期工作。)

【讨论】:

  • 如果最初的问题是由于字节排序引起的,那么它可能是一个仍然依赖特定字节排序的糟糕解决方案。有一些适当的函数可以帮助您处理主机字节顺序,因此代码可以在真实的 iOS 设备和模拟器上运行。
  • @rmaddy,你好像弄错了什么。使用 OP 的 CGContext 设置,R、G、B、A 4 个颜色分量按指定排序,与字节序无关。
  • 我知道上下文需要特定顺序的字节。问题在于struct 中数据的内存布局。如果不是字节顺序问题,那么为什么 OP 的原始代码有问题?除非我弄错了(我当然可能是这样),否则这个答案还取决于结构元组中 4 个值的内部存储器排序。这个答案是否已经在真机和模拟器上测试过?
  • @rmaddy,是的,这是内存布局的问题,但不是主机字节顺序或字节序的问题。 OP 的原始代码依赖于字节顺序且顺序错误。我的答案取决于内存布局,但与字节序无关。实际设备?自己试试。 (不过,目前 iOS、实际设备和模拟器都是 little-endian。)
猜你喜欢
  • 1970-01-01
  • 2015-06-01
  • 1970-01-01
  • 2012-12-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-07
  • 2018-08-21
  • 2012-10-28
相关资源
最近更新 更多