Quickest way to add false colour to image

Mike Milne 6 Reputation points
2022-01-09T20:17:26.257+00:00

I’m adding false colour to an animated sequence of black and white images by mapping the pixels according to luminance value to an RGB lookup table. The sample image shows an original image, the lookup values, and the coloured image. This is easy to do to a single image in Photoshop, but I have thousands of images to process, so I’d rather to write a program to process the images directly.

I’m assuming Lockbits is the way to go to get each pixel’s value, but what’s the most efficient way to write out the RGB values into a new image? I’m not asking for actual code – just a general pointer to the best approach!
163673-siren-1.jpg

Developer technologies | VB
{count} votes

1 answer

Sort by: Most helpful
  1. Mike Milne 6 Reputation points
    2022-01-10T13:59:51.863+00:00

    I think I've answered myself on this one - I hadn't realised that the Lockbits method allowed me to modify the image before unlocking, so I think that's the best method. If it works I'll post the code for anyone that might have the same question.

    [Edit:] OK. here's the subroutine for reading and modifying an image with Lockbits. The original image is black & white, so I use the green channel to get luminance. LUT() is the look-up table - an array of colors (0-255). (Derived this from the MS Bitmap Class documentation).

    Private Sub Read_and_Write_Image(ByRef bmp As Bitmap,byref LUT() as color)
            ' Lock the bitmap's bits.  
            Dim rect As New Rectangle(0, 0, bmp.Width, bmp.Height)
            Dim bmpData As System.Drawing.Imaging.BitmapData = bmp.LockBits(rect,
            Drawing.Imaging.ImageLockMode.ReadWrite, bmp.PixelFormat)
            Dim tmpG As Integer
    
            ' Get the address of the first line.
            Dim ptr As IntPtr = bmpData.Scan0
    
            ' Declare an array to hold the bytes of the bitmap.
            ' This code is specific to a bitmap with 24 bits per pixels.
            Dim bytes As Integer = Math.Abs(bmpData.Stride) * bmp.Height
            Dim rgbValues(bytes - 1) As Byte
            dummy = 1
            ' Copy the RGB values into the array.
            System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes)
    
            For counter As Integer = 0 To rgbValues.Length - 1 Step 3 
                tmpG = CInt(rgbValues(counter))
                rgbValues(counter) = LUT(tmpG).B
                rgbValues(counter + 1) = LUT(tmpG).G
                rgbValues(counter + 2) = LUT(tmpG).R
            Next
    
            ' Copy the RGB values back to the bitmap
            System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, ptr, bytes)
    
            ImgBox.Image = bmp
            ' Unlock the bits.
            bmp.UnlockBits(bmpData)
    
        End Sub
    
    1 person found this answer helpful.
    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.