【问题标题】:Resizing (downscaled) NSImage slightly changes RGB values. How do I preserve the original RGB values?调整(缩小) NSImage 的大小会稍微改变 RGB 值。如何保留原始 RGB 值?
【发布时间】:2017-05-12 03:32:30
【问题描述】:

我正在处理一个需要来自 NSImage 的原始 RGB 值的项目。将完全红色的图像 (PNG Image) (RGB: 255,0,0) 缩小到 200X200 的大小时,我得到的 RGB 值略有不同 (RGB: 251, 0, 7)。调整大小代码和像素提取代码如下。我有两个问题。使用下面的代码调整 NSImage 的大小时,这是预期的行为吗?是否可以保留图像的原始RGB值(缩小之前存在的RGB值)?

调整代码(credit):

open func resizeImage(image:NSImage, newSize:NSSize) -> NSImage{

    let rep = NSBitmapImageRep(bitmapDataPlanes: nil, pixelsWide: Int(newSize.width), pixelsHigh: Int(newSize.height), bitsPerSample: 8, samplesPerPixel: 4, hasAlpha: true, isPlanar: false, colorSpaceName: NSCalibratedRGBColorSpace, bytesPerRow: 0, bitsPerPixel: 0)

    rep?.size = newSize

    NSGraphicsContext.saveGraphicsState()
    let bitmap = NSGraphicsContext.init(bitmapImageRep: rep!)
    NSGraphicsContext.setCurrent(bitmap)
    image.draw(in: NSMakeRect(0, 0, newSize.width, newSize.height), from: NSMakeRect(0, 0, image.size.width, image.size.height), operation: .sourceOver, fraction: CGFloat(1))

    let newImage = NSImage(size: newSize)
    newImage.addRepresentation(rep!)
    return newImage

}

我用来从 NSImage 中提取 RGB 值的代码如下:

RGB提取码(credit)

extension NSImage {

    func pixelData() -> [Pixel] {
        var bmp = self.representations[0] as! NSBitmapImageRep
        var data: UnsafeMutablePointer<UInt8> = bmp.bitmapData!
        var r, g, b, a: UInt8
        var pixels: [Pixel] = []

        NSLog("%d", bmp.pixelsHigh)
        NSLog("%d", bmp.pixelsWide)
        for var row in 0..<bmp.pixelsHigh {
            for var col in 0..<bmp.pixelsWide {
                r = data.pointee
                data = data.advanced(by: 1)
                g = data.pointee
                data =  data.advanced(by: 1)
                b = data.pointee
                data =  data.advanced(by: 1)
                a = data.pointee
                data =  data.advanced(by: 1)
                pixels.append(Pixel(r: r, g: g, b: b, a: a))
            }
        }

        return pixels
    }
}

class Pixel {

    var r: Float!
    var g: Float!
    var b: Float!

    init(r: UInt8, g: UInt8, b: UInt8, a: UInt8) {
        self.r = Float(r)
        self.g = Float(g)
        self.b = Float(b)
    }

}

【问题讨论】:

  • 您正在使用NSCalibratedRGBColorSpace 创建您的位图图像代表。原始图像代表的colorSpaceName 是什么?当通过它们各自的颜色空间进行解释时,不同的像素值可能代表相同的颜色(尽可能接近)。
  • @KenThomases 从原始图像的 NSBitMapRep 打印颜色空间给我:sRGB IEC61966-2.1 颜色空间
  • 如果你在调用中使用colorSpaceName的值来创建位图图像代表会发生什么?
  • 好的,我想我解决了您第一条评论中提示的问题。将颜色空间更改为 NSDeviceRGBColorSpace 现在给了我正确的值。 :)
  • 调整后图像的色彩空间为:通用 RGB 色彩空间。显然有区别。非常感谢您的帮助@KenThomases

标签: ios swift cocoa image-processing


【解决方案1】:

感谢@KenThomases,问题已得到解决。当调整 NSImage 的大小时,我将 NSBitmapImageRep 对象的颜色空间设置为NSCalibratedRGBColorSpace。缩小比例之前的原始 NSImage 与缩小比例的图像具有不同的色彩空间名称。色彩空间的简单改变产生了正确的结果。 NSCalibratedRGBColorSpace 已更改为 NSDeviceRGBColorSpace

【讨论】:

    猜你喜欢
    • 2020-10-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-11
    • 1970-01-01
    • 2011-07-28
    • 1970-01-01
    • 2015-01-25
    相关资源
    最近更新 更多