The first component of the 3D array is the colour component. So at index 1,78,218 is the value of the blue component of the pixel at 78,218.
Like this:
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)
Since the images is copied, it doesn't make a difference if you mess with it before or after unlocking the image. The locking is there to make sure nobody changes the image while you do the actual copying.
The
values
array is a flattening of a 2D array into a flat array. The 2D-index.[x,y]
is atstride * y + x * pixelSize
. The RGB components then have a byte each. This explains why this finds the i'th color component at x,y:values.[stride * y + x * pixelSize + i] |> int
To add 50 to every pixel, its easier to use the original 3D array. Suppose you have an image myImage
:
pixels (myImage) |> Array3D.map ((+) 50)
The type of this is Array3D<Color>
, not Image
. If you need the an Image
, you'll need to construct that, somehow, from the Array3D
you now have.