F#懒惰像素读数

时间:2011-01-06 11:36:13

标签: f# pixel lazy-evaluation

我想将图像像素延迟加载到3维整数数组中。 例如,它看起来像这样:

   for i=0 to Width 
     for j=0 to Height
       let point=image.GetPixel(i,j)
       pixels.[0,i,j] <- point.R
       pixels.[1,i,j] <- point.G
       pixels.[2,i,j] <- point.B

如何以懒惰的方式制作?

3 个答案:

答案 0 :(得分:5)

答案 1 :(得分:2)

懒惰是什么意思?

数组不是延迟数据类型,这意味着如果要使用数组,则需要在初始化期间加载所有像素。如果我们使用的是单维数组,那么另一种方法是使用惰性的seq<_>(但您只能按顺序访问元素)。对于多维数组,没有像seq<_>这样的东西,所以你需要使用别的东西。

可能最接近的选择是使用三维延迟值数组(Lazy<int>[,,])。这是一组访问像素的延迟thunks,仅在您实际读取该位置的值时才会计算。你可以像这样初始化它:

for i=0 to Width 
  for j=0 to Height 
    let point = lazy image.GetPixel(i,j) 
    pixels.[0,i,j] <- lazy point.Value.R 
    pixels.[1,i,j] <- lazy point.Value.G 
    pixels.[2,i,j] <- lazy point.Value.B

该代码段会创建一个惰性值,用于读取像素(point),然后创建三个惰性值以获取各个颜色分量。访问颜色分量时,将评估point值(通过访问Value)。

其余代码的唯一区别在于,您需要调用Value(例如pixels.[0,10,10].Value来获取像素的实际颜色分量。

您可以定义更复杂的数据结构(例如您自己的支持索引的类型并且是懒惰的),但我认为惰性值数组应该是一个很好的起点。

答案 2 :(得分:2)

正如其他评论所提到的那样,您可以在3D数组中使用延迟像素加载但这只会使GetPixel操作变得懒惰而不是3D数组的内存分配,因为在调用create方法时已经分配了数组Array3D。

如果你想使内存分配以及GetPixel延迟,那么你可以使用如下代码所示的序列:

let getPixels (bmp:Bitmap) =
  seq {
        for i = 0 to bmp.Height-1 do
            yield seq {
                            for j = 0 to bmp.Width-1 do
                                let pixel = bmp.GetPixel(j,i)
                                yield (pixel.R,pixel.G,pixel.B)
                       }
  }