任何语言的示例都会有所帮助,但最终我将使用Ruby或JavaScript / CoffeeScript。
我有一个像素值数组。例如,我有一个表示5x5图像像素的数组。
image = [1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5]
图像就像:
1 2 3 4 5
6 7 8 9 0
1 2 3 4 5
6 7 8 9 0
1 2 3 4 5
我已经有了获取行的方法。但我想要一种方法来检索索引的列。
假设我在Ruby中有一个方法:
class Array
def column(index)
...
end
end
我想要以下结果:
image.column(0) #=> [1,6,1,6,1]
image.column(3) #=> [4,9,4,9,4]
编辑:感谢所有提供帮助的人。这就是我的目的:
def column index
output = []
i = 0
while i < @height
output << pixel(index + (i * @width))
i += 1
end
output
end
Pixel是另一种方法,它在给定索引的情况下从RGBA值数组中返回平均值。
这就足够了,我可以放心地假设图像中的每一行/每列都是正确的大小。我还想让这个过程相当简单,因为我可能会把它变成一个使用类型钳位数组的CoffeeScript应用程序(出于性能原因以及canvas数据是Uint8ClampedArray的事实),在这种情况下,输出的值将是Uint8ClampedArray和我将使用索引而不是push,因为Uint8ClampedArray不支持/不支持push / pop / shift / unshift。
答案 0 :(得分:4)
许多其他答案适用于您的问题所指定的正好为5x5的图像,但如果这不是隐含的,我会为此构建一个类,如:
class ImageMap
attr_reader :image
def initialize(image,columns=nil)
@image = image.each_slice(columns ||= Math.sqrt(image.size)).to_a
end
def columns
@image.first.size
end
def rows
@image.size
end
def column(n)
@image.map{|a| a[n]}
end
def row(n)
[@image[n]].concat([nil] * columns).take(columns).flatten
end
def cell(column,row)
column(column)[row]
end
def print
@image.each {|a| puts a.join}
end
end
这将处理所有图像,并允许您也设置预期列的数量。如果没有列期望,那么它会尝试使其成为正方形。
<强>方形强>
image = [1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5]
im = ImageMap.new(image)
im.column(0)
#=> [1, 6, 1, 6, 1]
im.column(3)
#=> [4, 9, 4, 9, 4]
im.row(0)
#=> [1, 2, 3, 4, 5]
im.cell(4,2)
#=> 5
非正方
image = [1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5]
im = ImageMap.new(image,4)
im.column(0)
#=> [1, 5, 9, 3, 7, 1, 5]
im.columns
#=> 4
im.rows
#=> 7
显然,这可以使用一些处理越界值,但你应该能够处理它。不存在的行/列的示例:
im.column(7)
#=> [nil, nil, nil, nil, nil]
im.row(7)
#=> [nil, nil, nil, nil, nil]
im.cell(7,2)
#=> nil
另请注意,如果它不是方形,它仍将起作用,例如。
image = [1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,4] # added a 4
im = ImageMap.new(image)
im.column(0)
#=> [1, 6, 1, 6, 1, 4]
im.column(1)
#=> [2, 7, 2, 7, 2, nil]
im.image
#=> [[1, 2, 3, 4, 5], [6, 7, 8, 9, 0], [1, 2, 3, 4, 5], [6, 7, 8, 9, 0], [1, 2, 3, 4, 5], [4]]
根据OP当前解决方案进行更新 这种方法应该预先形成相同的功能,并且有点像rubyesque
def column index
(0...@height).map { |i| pixel(index + (i * @width)) }
end
答案 1 :(得分:3)
image = [1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5]
def column(image, n, row_length)
(n..image.length).step(row_length).map{|i| image[i]}
end
column(image, 3, 5) # => [4, 9, 4, 9, 4]
答案 2 :(得分:3)
您可以考虑创建一个单独的类,而不是在类Array
中创建新方法。我假设image
的大小是多行的倍数 - 考虑到示例并且我们正在讨论像素 - 但如果丢弃该假设,代码显然可以改变。
感谢@SergioTulentsev和@engineersmnky提出的建议(见评论),我已经实施了。
<强>代码强>
class Array2D
def initialize(arr, ncols)
raise ArgumentError, "ncols must be positive" if ncols < 1
raise ArgumentError,
"arr.size must a multiple of ncols" unless (arr.size % ncols).zero?
@arr = arr
@ncols = ncols
@nrows = arr.size/ncols
end
def [](r,c) @arr[r*@ncols+c] end
def row(r) @arr[r*@ncols, @ncols] end
def rows_at(*indices) indices.map { |i| row(i) } end
def col(c) @nrows.times.map { |r,a| self[r,c] } end
def cols_at(*indices) indices.map { |i,a| col(i) } end
def array() rows_at(*0...@nrows) end
def transpose() cols_at(*0..@ncols) end
alias :to_s :array
end
Array2D.instance_methods(false)
#=> [:[], :row, :rows_at, :col, :cols_at, :array, :transpose, :to_s]
请注意,方法self
中self[r,c]
需要col
。如果没有self
,[1,2]
将返回一个数组。
示例强>
image = [1,2,3,4,5,6,7,8,9,0,11,12,13,14,15,16,17,18,19,10,21,22,23,24,25]
image2D = Array2D.new(image, 5)
image2D.array
#=> [[ 1, 2, 3, 4, 5],
# [ 6, 7, 8, 9, 0],
# [11, 12, 13, 14, 15],
# [16, 17, 18, 19, 10],
# [21, 22, 23, 24, 25]]
image2D[1,3]
#=> 9
image2D.row(1)
#=> [6, 7, 8, 9, 0]
image2D.rows_at(1,3)
#=> [[6, 7, 8, 9, 0], [16, 17, 18, 19, 10]]
image2D.col(1)
#=> [2, 7, 12, 17, 22]
image2D.cols_at(1,3)
#=> [[2, 7, 12, 17, 22],
# [4, 9, 14, 19, 24]]
image2D.transpose
#=> [[1, 6, 11, 16, 21],
# [2, 7, 12, 17, 22],
# [3, 8, 13, 18, 23],
# [4, 9, 14, 19, 24],
# [5, 0, 15, 10, 25]]
答案 3 :(得分:1)
def column(index)
(0...5).map{|i|image[i*5+index]}
end