Transform Bitmap object into jagged array of RGB tuple values I've been working on this module with the assistance of codereview, and based on the responses and my own research, this is my project so far. The goal behind the code is that it starts with a .NET bitmap object, extracts the byte array of image data from the bitmap, then transforms it into an array of arrays or matrix. 

The idea behind putting the bitmap data into the matrix is that I want to be able to use a simple representation of a coordinate, like Array[10][20], to get the RGB value for the pixel located at the (10, 20) coordinate. Rather than using a proper 2D array, I'm choosing to use an array of arrays, or "jagged" array, for speed concerns.

Your assistance with sanity, style, F# conventions, and any other problems you spot is appreciated in helping further refine this algorithm. 

open System
open System.Drawing
open System.Drawing.Imaging
open System.Runtime.InteropServices


module ImageSearch = 
    let LoadBitmapIntoArray (pBitmap:Bitmap) =
        let tBitmapData = pBitmap.LockBits( Rectangle(Point.Empty, pBitmap.Size), 
                                            ImageLockMode.ReadOnly, 
                                            PixelFormat.Format24bppRgb )  

        let tImageArrayLength = Math.Abs(tBitmapData.Stride) * pBitmap.Height
        let tImageDataArray = Array.zeroCreate&lt;byte&gt; tImageArrayLength

        Marshal.Copy(tImageDataArray, 0, tBitmapData.Scan0, tImageArrayLength)
        pBitmap.UnlockBits(tBitmapData)

        pBitmap.Width, tImageDataArray

    let Transform2D ( (pArrayWidth:int), (pArray:byte[]) ) = 
        let tHeight = pArray.Length / ( pArrayWidth * 3 ) // 3 bytes per RGB

        let tImageArray = [|
            for tHeightIndex in [ 0 .. tHeight - 1] do
                let tStart  = tHeightIndex * pArrayWidth
                let tFinish = tStart + pArrayWidth - 1 
                yield [|    
                    for tWidthIndex in [tStart .. 3 .. tFinish] do
                        yield ( pArray.[tWidthIndex]
                              , pArray.[tWidthIndex + 1] 
                              , pArray.[tWidthIndex + 2] )
                |]
        |]

        tImageArray

    let SearchBitmap (pSmallBitmap:Bitmap) (pLargeBitmap:Bitmap) = 

        let tSmallArray = Transform2D &lt;| LoadBitmapIntoArray pSmallBitmap 
        let tLargeArray = Transform2D &lt;| LoadBitmapIntoArray pLargeBitmap

        let mutable tMatchFound = false
By convention, F# function names are camelCase, for example transform2D instead of Transform2D.



Hungarian notation is dead and buried. For example, use bitmap instead of pBitmap.



If ImageSearch is a top-level module, declarations do not have to be indented.



Your for...in expressions can be written without brackets. For example, instead of


for tHeightIndex in [ 0 .. tHeight - 1] do



write

for heightIndex in 0 .. height - 1 do


Similarly, instead of


for tWidthIndex in [tStart .. 3 .. tFinish] do



write

for widthIndex in start .. 3 .. finish do


This is not just a style issue, the different versions actually compile to different IL.



The final expression of a function is its return value, so instead of


let tHeight = ...
let tImageArray = [| ... |]
tImageArray



you can write

let height = ...
[| ... |]





In type annotations, it's conventional to have a space on either side of the :, for example instead of


let Transform2D ( (pArrayWidth:int), (pArray:byte[]) ) = 



write

let transform2D (width : int, array : byte[]) =




I can't actually back up this last point. MSDN and FSharp.Core don't seem to stick to one style, even in the same function


let isProperSuperset (x:Set&lt;'T&gt;) (y: Set&lt;'T&gt;) = SetTree.psubset x.Comparer y.Tree x.Tree