What I've got so far, learning from
https://web.archive.org/web/20141229164101/http://bobpowell.net/lockingbits.aspx
https://stackoverflow.com/a/4619004/3487239
https://stackoverflow.com/a/22855181/3487239
open System.Drawing
open System.Drawing.Imaging
let cat = new Bitmap("cat.jpg") // original image of cat
let pixels (image:Bitmap) = // BitLocking and Unlocking an Image
    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)
    let pixelSize = 4 // <-- calculate this from the PixelFormat
    
    // All the data has been inserted into byte[] values
    (*
       This block of code is where I go through the byte[] values from above
       to do all sorts of image manipulation eg. changing color of pixels etc
       Which I have completed, just need to save the image.
    *)
    // My Question
    (*
       In here, how to turn the modified byte[] values back to Bitmap before
       unlocking the bits?
    *)
    // Unlock the image
    image.UnlockBits(data)
pixels cat // modified version of the same image
What I've tried so far, (new memory stream to new bitmap, new bitmap constructor then bitmap.save etc...)
https://stackoverflow.com/a/22890620/3487239
https://stackoverflow.com/a/3801289/3487239
The code compiles using above methods, but it creates another copy of the same image instead of the desired result.
 
    