位图图像处理

Dak*_*kaa 4 f# f#-interactive f#-3.0

我想使用 LockBits 方法替换 GetPixel 和 SetPixel,所以我遇到了这个F# 延迟像素读取

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)

在代码末尾,它返回一个包含复制数据的 3D 数组。

  1. 那么3D阵列是复制的图像,如何编辑3D阵列的像素,例如更改颜色?像素大小有什么用?为什么将图像存储在 3D 字节数组而不是 2D 中?

  2. 例如,如果我们想使用 2D 数组,并且我想更改指定像素的颜色,我们该怎么做?

  3. 我们是在字节数组外部像素函数中对给定的复制图像进行操作,还是在解锁图像之前在像素函数内部进行操作?

  4. 如果我们不再使用GetPixel或SetPixel呢?如何从复制的图像字节[]中检索像素的颜色?

如果您不明白我的问题,请解释一下我如何使用上面的代码来执行操作,例如给给定图像的每个像素的 R、G、B“添加 50”,而不使用 getPixel、setPixel

Sør*_*ois 5

  1. 3D 数组的第一个分量是颜色分量。因此,索引 1,78,218 处的值是 78,218 处像素的蓝色分量的值。

  2. 像这样:

    Array2D.init Width Height (fun x y -> 
        let color i = values.[stride * y + x * pixelSize + i] |> int
        new Color(color 0, color 1, color 2)
    
    Run Code Online (Sandbox Code Playgroud)
  3. 由于图像是复制的,因此无论您在解锁图像之前还是之后对其进行修改,都不会产生任何影响。锁定是为了确保在您进行实际复制时没有人更改图像。

  4. values数组是将 2D 数组展平为平面数组。2D 索引.[x,y]位于stride * y + x * pixelSize。RGB 分量各有一个字节。这解释了为什么在 x,y 处找到第 i 个颜色分量:

     values.[stride * y + x * pixelSize + i] |> int
    
    Run Code Online (Sandbox Code Playgroud)

要为每个像素添加 50,使用原始 3D 数组更容易。假设您有一张图像myImage

pixels (myImage) |> Array3D.map ((+) 50) 
Run Code Online (Sandbox Code Playgroud)

这个类型是Array3D<Color>, not Image。如果您需要 an Image,您需要以某种方式Array3D您现在拥有的 构建它。