【问题标题】:Issue with value types and init’s值类型和 init 的问题
【发布时间】:2020-02-16 12:28:54
【问题描述】:

我正在关注 old tutorial 设置数据结构以查看图像中的 RGBA 值。在大多数情况下,我已经解决了所有数据不足的问题,但我遇到了一个看起来超级简单的问题,我只是对 swift 比较陌生,所以事实证明它有点困难。

import UIKit

public struct RGBAPixel {
    public init(rawVal : UInt32) {
        raw = rawVal
    }
    public var raw: UInt32
    public var red: UInt8 {
        get { return UInt8(raw & 0xFF) }
        set { raw = UInt32(newValue) | (raw & 0xFFFFFF00) }
    }
    public var green: UInt8 {
        get { return UInt8( (raw & 0xFF00) >> 8) }
        set { raw = (UInt32(newValue) << 8) | (raw & 0xFFFF00FF) }
    }
    public var blue: UInt8 {
        get { return UInt8( (raw & 0xFF0000) >> 16) }
        set { raw = (UInt32(newValue) << 16) | (raw & 0xFF00FFFF) }
    }
    public var alpha: UInt8 {
        get { return UInt8( (raw & 0xFF000000) >> 24) }
        set { raw = (UInt32(newValue) << 24) | (raw & 0x00FFFFFF) }
    }
}

let image = UIImage(named: "crossSection.jpg")

let height = Int((image?.size.height)!)
let width = Int((image?.size.width)!)
let bitsPerComponent = Int(8)
let bytesPerRow = 4 * width
let colorSpace = CGColorSpaceCreateDeviceRGB()
let rawData = UnsafeMutablePointer<UInt32>.allocate(capacity: width * height)
let bitmapInfo: UInt32 = CGBitmapInfo.byteOrder32Big.rawValue | CGImageAlphaInfo.premultipliedLast.rawValue
let CGPointZero = CGPoint(x: 0,y: 0)
let rect = CGRect(origin: CGPointZero, size: (image?.size)!)

let imageContext = CGContext(data: rawData, width: width, height: height, bitsPerComponent: bitsPerComponent, bytesPerRow: bytesPerRow, space: colorSpace, bitmapInfo: bitmapInfo)

imageContext?.draw(image!.cgImage!, in:rect)

let pixels = UnsafeMutableBufferPointer<UInt32>(start: rawData, count: width * height)

///*
for var y in 0 ..< height {
    for var x in 0 ..< width {
        var p = pixels[x+y*width] = RGBAPixel(rawVal: 0)
        p.red = 255
        pixels[x+y*width] = p


    }
}
//*/

let outContext = CGContext(data: pixels.baseAddress, width: width, height: height, bitsPerComponent: bitsPerComponent, bytesPerRow: bytesPerRow, space: colorSpace, bitmapInfo: bitmapInfo)

let outImage = UIImage(cgImage: outContext!.makeImage()!)

有两个问题点。首先是靠近底部的问题,当放入 swift 时,它会给出错误“无法将‘RGBAPixel’类型的值分配给‘UInt32’类型”。我很好地关注了video,并查找了我似乎找不到的任何错误。似乎这个问题不是来自更新的问题,所以我很困惑。 我研究了结构和初始化,代码的编写方式似乎很有意义。 init 允许通过 RGBAPixel 传入数据类型 UInt32。同样,非常新,所以请纠正我哪里我错了。谢谢

【问题讨论】:

  • 我想你想要p.raw而不是p
  • @Paulw11 你在说pixels[x+y*width] = p这行吗?这对问题没有影响。问题行是var p = pixels[x+y*width] = RGBAPixel(rawVal: 0) 这应该把所有的像素都变黑了。
  • 那么最后你也需要.raw。 pixels 被声明为持有 UInt32,因此您不能将 RGBAPixel 分配给它,正如编译器告诉您的那样。
  • 事实上,这条线没有多大意义。之后的代码将p 视为a。 RGBAPixel 但它将是 UInt32
  • 太棒了!将 .raw 添加到行尾使其工作!你有什么想法可以访问说红色值吗?

标签: ios swift image-processing


【解决方案1】:

您使用的是&lt;UInt32&gt; 而不是&lt;RGBAPixel&gt;

let rawData = UnsafeMutablePointer<UInt32>.allocate(capacity: width * height)
//Should be:
let rawData = UnsafeMutablePointer<RGBAPixel>.allocate(capacity: width * height)

同理:

let pixels = UnsafeMutableBufferPointer<UInt32>(start: rawData, count: width * height)
// Should be:
let pixels = UnsafeMutableBufferPointer<RGBAPixel>(start: rawData, count: width * height)

试试这个(为了便于阅读,我添加了几行空行)- 使用黑色作为颜色:

import UIKit

struct RGBAPixel {
    var raw: UInt32

    public init(rawVal : UInt32) {
        raw = rawVal
    }

    public var red: UInt8 {
        get { return UInt8(raw & 0xFF) }
        set { raw = UInt32(newValue) | (raw & 0xFFFFFF00) }
    }

    public var green: UInt8 {
        get { return UInt8( (raw & 0xFF00) >> 8) }
        set { raw = (UInt32(newValue) << 8) | (raw & 0xFFFF00FF) }
    }

    public var blue: UInt8 {
        get { return UInt8( (raw & 0xFF0000) >> 16) }
        set { raw = (UInt32(newValue) << 16) | (raw & 0xFF00FFFF) }
    }

    public var alpha: UInt8 {
        get { return UInt8( (raw & 0xFF000000) >> 24) }
        set { raw = (UInt32(newValue) << 24) | (raw & 0x00FFFFFF) }
    }
}

let image = UIImage(named: "crossSection.jpg")

let height = Int((image?.size.height)!)
let width = Int((image?.size.width)!)

let bitsPerComponent = Int(8)
let bytesPerRow = 4 * width

let colorSpace = CGColorSpaceCreateDeviceRGB()

let rawData = UnsafeMutablePointer<RGBAPixel>.allocate(capacity: width * height)

let bitmapInfo: UInt32 = CGBitmapInfo.byteOrder32Big.rawValue | CGImageAlphaInfo.premultipliedLast.rawValue

let CGPointZero = CGPoint(x: 0,y: 0)

let rect = CGRect(origin: CGPointZero, size: (image?.size)!)

let imageContext = CGContext(data: rawData, width: width, height: height, bitsPerComponent: bitsPerComponent, bytesPerRow: bytesPerRow, space: colorSpace, bitmapInfo: bitmapInfo)

imageContext?.draw(image!.cgImage!, in:rect)

let pixels = UnsafeMutableBufferPointer<RGBAPixel>(start: rawData, count: width * height)

///*
for var y in 0 ..< height {
    for var x in 0 ..< width {
        pixels[x+y*width] = RGBAPixel(rawVal: 0xFF000000)
    }
}
//*/

let outContext = CGContext(data: pixels.baseAddress, width: width, height: height, bitsPerComponent: bitsPerComponent, bytesPerRow: bytesPerRow, space: colorSpace, bitmapInfo: bitmapInfo)

let outImage = UIImage(cgImage: outContext!.makeImage()!)

使用颜色:

for var y in 0 ..< height {
    for var x in 0 ..< width {
        var p = RGBAPixel(rawVal: 0xFF000000)
        p.red = 128
        pixels[x+y*width] = p
    }
}

【讨论】:

  • 没错!嗯,非常感谢!我很确定我的一切都和视频一样。非常感谢。
猜你喜欢
  • 1970-01-01
  • 2018-05-17
  • 1970-01-01
  • 1970-01-01
  • 2011-05-28
  • 1970-01-01
  • 1970-01-01
  • 2011-08-25
相关资源
最近更新 更多