jjzjj

Swift:对给定属性进行操作

coder 2023-09-10 原文

我有一个以 RGBA 形式表示位图图像的结构。该结构具有每个颜色 channel (红色、蓝色和绿色)的属性。

我正在尝试构建一个调整特定颜色级别的图像过滤器。这个版本工作正常,但显然 pixel.COLOR 属性是硬编码的。

func boostColor(inputColor: String) -> UIImage {
    let avgColor = "avg" + inputColor
   // let color = inputColor.lowercaseString // plan to use this to set the property
    for y in 0..<self.inputRGBA.height {
        for x in 0..<self.inputRGBA.width {
            let index = y *  self.inputRGBA.width + x
            var pixel = self.inputRGBA.pixels[index]
            // see how far this pixel's chosen color varies from the average
            let colorDiff = Int(pixel.red) - Int(self.pixelColorAverages[avgColor]!)
            // if less than average red,
            if(colorDiff>0){
                pixel.red = UInt8( max(0,min(255,Int(self.pixelColorAverages[avgColor]!) + colorDiff*100 ) ) )
                // write the adjusted pixel back to the image object
                self.inputRGBA.pixels[index] = pixel
            }
        }
    }
    // write the filtered RGBA image to a UIImage
    return self.inputRGBA.toUIImage()!
}

这个循环的函数接受一个字符串值“red”、“blue”或“green”。我想做的是替换

的实例
pixel.red

pixel.[ONE OF THE INPUT COLORS]

谢谢! (这是一个学术 Playground 项目。我意识到我可能正在通过构建滤色器来重新发明轮子。我感兴趣的不是滤色器本身,而是如何在 Swift 中解决这个属性问题。 ) 这是结构:

public struct Pixel {
public var value: UInt32

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

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

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

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

最佳答案

通过 reflecting 可以实现键值编码,但它非常不快速。在您的情况下,这也是一个坏主意,因为有更强大和有用的替代方案。

我会选择 OptionSetType,因为只有固定数量的可能性 (RGBA)。 enum 也可以,但是 OptionSetType 具有作为“集合”的额外好处。因此,您可以选择以非常方便的方式更改 RGB 而不是 A。

interesting read on OptionSetType


这是一个枚举,用于存储OptionSetType 的原始值。可以单独使用。

public enum RGBAColor : Int, CustomStringConvertible {
    case Red = 1, Green = 2, Blue = 4, Alpha = 8

    public var description : String { // if you still want to have a String value for each color
        var shift = 0
        while (rawValue >> shift != 1) { shift++ }
        return ["Red","Green","Blue","Alpha"][shift]
    }
}

这是OptionSetType。我创建了这些结构的片段,并在需要时复制/粘贴/修改它们。无需重新发明轮子,因为它始终是相同的模式。

public struct RGBAColors : OptionSetType, CustomStringConvertible {

    public  let rawValue : Int
    public  init(rawValue:Int) { self.rawValue = rawValue}
    private init(_ color:RGBAColor) { self.rawValue = color.rawValue }

    static let Red  = RGBAColors(RGBAColor.Red)
    static let Green  = RGBAColors(RGBAColor.Green)
    static let Blue = RGBAColors(RGBAColor.Blue)
    static let Alpha = RGBAColors(RGBAColor.Alpha)

    public var description : String {
        var result = ""
        var shift = 0

        while let currentcolor = RGBAColor(rawValue: 1 << shift++){
            if self.contains(RGBAColors(currentcolor)){
                result += (result.characters.count == 0) ? "\(currentcolor)" : ",\(currentcolor)"
            }
        }

        return "[\(result)]"
    }
}

现在您可以向 Pixel 结构添加一个函数,该函数将根据 enum case 返回颜色值。您还可以选择将 OptionSetType 直接传递给此函数。

public struct Pixel {

    ...

    public func getValueForColor(color:RGBAColor) -> UInt8 {
        switch color {
        case .Red : return self.red
        case .Green : return self.green
        case .Blue : return self.blue
        case .Alpha : return self.alpha
        }
    }
}

这只是一个控制流函数。您现在可以根据需要更改的颜色执行不同的操作。 (或对所有人都适用) 这也是选择 OptionSetType 的唯一原因,如果您不需要它,只需选择 enum。由于 OptionSetType 建立在 enum 之上,您可以随时添加它。

func someFuncWithOptions(colors:RGBAColors) {

    if colors.contains(.Red) {
        someFunc(.Red)
    }
    if colors.contains(.Blue) {
        someFunc(.Blue)
    }
    if colors.contains(.Green) {
        someFunc(.Green)
    }
    if colors.contains(.Alpha) {
        someFunc(.Alpha)
    }
}

这将是您的实际功能

func someFunc(color:RGBAColor) {
    // do something with pixel.getValueForColor(color)
    print(color)
}

这将暴露给您代码的其他部分。所以所有这些的实际使用将非常简单。只需输入 .SomeColor

最好的是,如果您将所有这些都更改为 CMYK,编译器会警告您。键值编码永远不会产生警告,它只会崩溃。

因为它是一个“集合”而不是每个定义的一种颜色,所以您传递了一组选项。 [.option1,.option2,...] 或者您什么都不传递 []

someFuncWithOptions([.Red]) // red
someFuncWithOptions([.Green,.Red]) // red green

您还可以将方便的集合添加到 OptionSetType。这将是一组所有 RGB 颜色,但没有 Alpha channel 。

static let RGB : RGBAColors = [.Red,.Green,.Blue]

someFuncWithOptions([.RGB]) // red blue green

关于Swift:对给定属性进行操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34359914/

有关Swift:对给定属性进行操作的更多相关文章

  1. ruby-on-rails - 使用 Ruby on Rails 进行自动化测试 - 最佳实践 - 2

    很好奇,就使用ruby​​onrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提

  2. ruby-on-rails - 按天对 Mongoid 对象进行分组 - 2

    在控制台中反复尝试之后,我想到了这种方法,可以按发生日期对类似activerecord的(Mongoid)对象进行分组。我不确定这是完成此任务的最佳方法,但它确实有效。有没有人有更好的建议,或者这是一个很好的方法?#eventsisanarrayofactiverecord-likeobjectsthatincludeatimeattributeevents.map{|event|#converteventsarrayintoanarrayofhasheswiththedayofthemonthandtheevent{:number=>event.time.day,:event=>ev

  3. ruby-on-rails - 如果为空或不验证数值,则使属性默认为 0 - 2

    我希望我的UserPrice模型的属性在它们为空或不验证数值时默认为0。这些属性是tax_rate、shipping_cost和price。classCreateUserPrices8,:scale=>2t.decimal:tax_rate,:precision=>8,:scale=>2t.decimal:shipping_cost,:precision=>8,:scale=>2endendend起初,我将所有3列的:default=>0放在表格中,但我不想要这样,因为它已经填充了字段,我想使用占位符。这是我的UserPrice模型:classUserPrice回答before_val

  4. ruby - 使用 C 扩展开发 ruby​​gem 时,如何使用 Rspec 在本地进行测试? - 2

    我正在编写一个包含C扩展的gem。通常当我写一个gem时,我会遵循TDD的过程,我会写一个失败的规范,然后处理代码直到它通过,等等......在“ext/mygem/mygem.c”中我的C扩展和在gemspec的“扩展”中配置的有效extconf.rb,如何运行我的规范并仍然加载我的C扩展?当我更改C代码时,我需要采取哪些步骤来重新编译代码?这可能是个愚蠢的问题,但是从我的gem的开发源代码树中输入“bundleinstall”不会构建任何native扩展。当我手动运行rubyext/mygem/extconf.rb时,我确实得到了一个Makefile(在整个项目的根目录中),然后当

  5. ruby-on-rails - 在混合/模块中覆盖模型的属性访问器 - 2

    我有一个包含模块的模型。我想在模块中覆盖模型的访问器方法。例如:classBlah这显然行不通。有什么想法可以实现吗? 最佳答案 您的代码看起来是正确的。我们正在毫无困难地使用这个确切的模式。如果我没记错的话,Rails使用#method_missing作为属性setter,因此您的模块将优先,阻止ActiveRecord的setter。如果您正在使用ActiveSupport::Concern(参见thisblogpost),那么您的实例方法需要进入一个特殊的模块:classBlah

  6. ruby - 多个属性的 update_column 方法 - 2

    我有一个具有一些属性的模型:attr1、attr2和attr3。我需要在不执行回调和验证的情况下更新此属性。我找到了update_column方法,但我想同时更新三个属性。我需要这样的东西:update_columns({attr1:val1,attr2:val2,attr3:val3})代替update_column(attr1,val1)update_column(attr2,val2)update_column(attr3,val3) 最佳答案 您可以使用update_columns(attr1:val1,attr2:val2

  7. ruby - 如何进行排列以有效地定制输出 - 2

    这是一道面试题,我没有答对,但还是很好奇怎么解。你有N个人的大家庭,分别是1,2,3,...,N岁。你想给你的大家庭拍张照片。所有的家庭成员都排成一排。“我是家里的friend,建议家庭成员安排如下:”1岁的家庭成员坐在这一排的最左边。每两个坐在一起的家庭成员的年龄相差不得超过2岁。输入:整数N,1≤N≤55。输出:摄影师可以拍摄的照片数量。示例->输入:4,输出:4符合条件的数组:[1,2,3,4][1,2,4,3][1,3,2,4][1,3,4,2]另一个例子:输入:5输出:6符合条件的数组:[1,2,3,4,5][1,2,3,5,4][1,2,4,3,5][1,2,4,5,3][

  8. ruby - Nokogiri 剥离所有属性 - 2

    我有这个html标记:我想得到这个:我如何使用Nokogiri做到这一点? 最佳答案 require'nokogiri'doc=Nokogiri::HTML('')您可以通过xpath删除所有属性:doc.xpath('//@*').remove或者,如果您需要做一些更复杂的事情,有时使用以下方法遍历所有元素会更容易:doc.traversedo|node|node.keys.eachdo|attribute|node.deleteattributeendend 关于ruby-Nokog

  9. ruby-on-rails - Rails 模型——非持久类成员或属性? - 2

    对于Rails模型,是否可以/建议让一个类的成员不持久保存到数据库中?我想将用户最后选择的类型存储在session变量中。由于我无法从我的模型中设置session变量,我想将值存储在一个“虚拟”类成员中,该成员只是将值传递回Controller。你能有这样的类(class)成员吗? 最佳答案 将非持久属性添加到Rails模型就像任何其他Ruby类一样:classUser扩展解释:在Ruby中,所有实例变量都是私有(private)的,不需要在赋值前定义。attr_accessor创建一个setter和getter方法:classUs

  10. ruby - 即使失败也继续进行多主机测试 - 2

    我已经构建了一些serverspec代码来在多个主机上运行一组测试。问题是当任何测试失败时,测试会在当前主机停止。即使测试失败,我也希望它继续在所有主机上运行。Rakefile:namespace:specdotask:all=>hosts.map{|h|'spec:'+h.split('.')[0]}hosts.eachdo|host|begindesc"Runserverspecto#{host}"RSpec::Core::RakeTask.new(host)do|t|ENV['TARGET_HOST']=hostt.pattern="spec/cfengine3/*_spec.r

随机推荐