Noz*_*zim 0 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
Run Code Online (Sandbox Code Playgroud)
如何以懒惰的方式制作?
什么是缓慢的呼吁GetPixel
.如果你只想根据需要调用它,你可以使用这样的东西:
open System.Drawing
let lazyPixels (image:Bitmap) =
let Width = image.Width
let Height = image.Height
let pixels : Lazy<byte>[,,] = Array3D.zeroCreate 3 Width Height
for i = 0 to Width-1 do
for j = 0 to Height-1 do
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
pixels
Run Code Online (Sandbox Code Playgroud)
GetPixel
每个像素最多调用一次,然后重用其他组件.
解决此问题的另一种方法是对整个图像进行批量加载.这比GetPixel
一遍又一遍地调用要快得多.
open System.Drawing
open System.Drawing.Imaging
let pixels (image:Bitmap) =
let Width = image.Width
let Height = image.Height
let rect = new Rectangle(0,0,Width,Height)
// Lock the image for access
let data = image.LockBits(rect, ImageLockMode.ReadOnly, image.PixelFormat)
// Copy the data
let ptr = data.Scan0
let stride = data.Stride
let bytes = stride * data.Height
let values : byte[] = Array.zeroCreate bytes
System.Runtime.InteropServices.Marshal.Copy(ptr,values,0,bytes)
// Unlock the image
image.UnlockBits(data)
let pixelSize = 4 // <-- calculate this from the PixelFormat
// Create and return a 3D-array with the copied data
Array3D.init 3 Width Height (fun i x y ->
values.[stride * y + x * pixelSize + i])
Run Code Online (Sandbox Code Playgroud)
(从C#样本中采用Bitmap.LockBits
)