我有一个以 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/
很好奇,就使用rubyonrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提
在控制台中反复尝试之后,我想到了这种方法,可以按发生日期对类似activerecord的(Mongoid)对象进行分组。我不确定这是完成此任务的最佳方法,但它确实有效。有没有人有更好的建议,或者这是一个很好的方法?#eventsisanarrayofactiverecord-likeobjectsthatincludeatimeattributeevents.map{|event|#converteventsarrayintoanarrayofhasheswiththedayofthemonthandtheevent{:number=>event.time.day,:event=>ev
我希望我的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
我正在编写一个包含C扩展的gem。通常当我写一个gem时,我会遵循TDD的过程,我会写一个失败的规范,然后处理代码直到它通过,等等......在“ext/mygem/mygem.c”中我的C扩展和在gemspec的“扩展”中配置的有效extconf.rb,如何运行我的规范并仍然加载我的C扩展?当我更改C代码时,我需要采取哪些步骤来重新编译代码?这可能是个愚蠢的问题,但是从我的gem的开发源代码树中输入“bundleinstall”不会构建任何native扩展。当我手动运行rubyext/mygem/extconf.rb时,我确实得到了一个Makefile(在整个项目的根目录中),然后当
我有一个包含模块的模型。我想在模块中覆盖模型的访问器方法。例如:classBlah这显然行不通。有什么想法可以实现吗? 最佳答案 您的代码看起来是正确的。我们正在毫无困难地使用这个确切的模式。如果我没记错的话,Rails使用#method_missing作为属性setter,因此您的模块将优先,阻止ActiveRecord的setter。如果您正在使用ActiveSupport::Concern(参见thisblogpost),那么您的实例方法需要进入一个特殊的模块:classBlah
我有一个具有一些属性的模型: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
这是一道面试题,我没有答对,但还是很好奇怎么解。你有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][
我有这个html标记:我想得到这个:我如何使用Nokogiri做到这一点? 最佳答案 require'nokogiri'doc=Nokogiri::HTML('')您可以通过xpath删除所有属性:doc.xpath('//@*').remove或者,如果您需要做一些更复杂的事情,有时使用以下方法遍历所有元素会更容易:doc.traversedo|node|node.keys.eachdo|attribute|node.deleteattributeendend 关于ruby-Nokog
对于Rails模型,是否可以/建议让一个类的成员不持久保存到数据库中?我想将用户最后选择的类型存储在session变量中。由于我无法从我的模型中设置session变量,我想将值存储在一个“虚拟”类成员中,该成员只是将值传递回Controller。你能有这样的类(class)成员吗? 最佳答案 将非持久属性添加到Rails模型就像任何其他Ruby类一样:classUser扩展解释:在Ruby中,所有实例变量都是私有(private)的,不需要在赋值前定义。attr_accessor创建一个setter和getter方法:classUs
我已经构建了一些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