F#懒像素读取 [英] F# lazy pixels reading

查看:96
本文介绍了F#懒像素读取的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想将图像像素延迟加载到3维整数数组中. 例如,以简单的方式看起来像这样:

I want to make a lazy loading of image pixels to the 3 dimensional array of integers. For example in simple way it looks like this:

   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

如何以懒惰的方式制作?

How it can be made in lazy way?

推荐答案

调用GetPixel会很慢.如果您只想根据需要调用它,则可以使用以下内容:

What would be slow is the call to GetPixel. If you want to call it only as needed, you could use something like this:

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

GetPixel将对每个像素最多调用一次,然后再用于其他组件.

GetPixel will be called at most once for every pixel, and then reused for the other components.

解决此问题的另一种方法是对整个图像进行批量加载.这比一遍又一遍地调用GetPixel要快得多.

Another way of approaching this problem would be to do a bulk-load of the entire image. This will be a lot quicker than calling GetPixel over and over again.

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])

(从 查看全文

登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆