1

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.

Andrew Morton
  • 21,016
  • 8
  • 48
  • 69
Dakaa
  • 179
  • 8
  • 3
    @downvoters Please explain yourselves. The OP is a SO beginner who is attempting to consolidate a stream of questions. If the problem is that commentary should be text in the question, not comments in the code, please be explicit. I've thrown a +1 I wouldnt normally throw in into the mix as such downvotes without explanation are just a bad idea IMO – Ruben Bartelink Apr 07 '14 at 01:32
  • Maybe I've asked too many questions or not thinking hard enough. I'll mark this question as solved 2 days later since I've already worked out the answer. – Dakaa Apr 07 '14 at 02:15
  • 1
    [There are lots of subtle and not so subtle ways in which your questions can be improved](https://msmvps.com/blogs/jon_skeet/archive/2010/08/29/writing-the-perfect-question.aspx). NB It's best if you have 3 or 4 questions that are all sufficiently different to keep them separate. In your specific case, it probably was time for a summary post like this. It is important for each question (esp such a summary) to remain readable from top to bottom with having to follow links to other questions to get the gist of it. You'll learn all this over time - esp if others comment along with downvotes! – Ruben Bartelink Apr 07 '14 at 02:30
  • 1
    OK, I see upvotes which is great and shows you're alive and listening. But my upvote will become a downvote unless the question is actually improved. As it is - it needs work and you should delete it if you consider yourself not to have the time to change it into something that other people can actually read and understand. – Ruben Bartelink Apr 07 '14 at 09:26
  • I think you should avoid interop/marshaling if at all possible. You should be able to do this using an API built into the .NET class library. See for instance https://stackoverflow.com/a/14337202/5652483 – Scott Hutchinson Dec 13 '20 at 18:00
  • More possibilities at https://stackoverflow.com/questions/21555394/how-to-create-bitmap-from-byte-array – Scott Hutchinson Dec 13 '20 at 18:07

1 Answers1

-1

Figured it out, you do the following:

// this is the first copy operation in your lock/unlock
{
.
.
.
System.Runtime.InteropServices.Marshal.Copy(ptr,values,0,bytes)
.
.
.
}
// you have to do lock/unlock again, this time with your modified byte array, copy again, rearrange the parameter this way
{
.
.
.
System.Runtime.InteropServices.Marshal.Copy(values,0,ptr,bytes)
.
.
.
}
// then save the bitmap with new directory/filename
Dakaa
  • 179
  • 8
  • 2
    This is pretty impossible to read - simply doing line breaks for the reader would help a lot, and not sure what the braces achieve given this is F# and you're not trying to get across any scoping/lifetime in pseudocode concept (or are you?). (Ditto the question - there better be a good reason if people have to go clicking scroll bars) – Ruben Bartelink Apr 07 '14 at 03:36