I have a function that turns a normal image into an RGB byte array. Then I wrote a function to turn this byte array back into a normal image. Unfortunately the color components are shifted, i.e. {R=0, G=94, B=255} (blue) becomes {R=255, G=94, B=0} (orange), and so on. I have tried several answers, including this one and this one. I even tried swapping the components, but that doesn't work either. What am I doing wrong?
Edit:
I also attempted swapping the color components as a trial, hoping it would rectify the color issue.
These lines of code are a test project. I want to implement the RGB_Byte_Array_To_Image
function somewhere else later.
Public Class FormMain
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim filePath As String = "C:\Users\...\Pictures\Testbild mit Gimp erstellen\Test, nicht optimiert, nicht progressiv 2.jpg"
Dim rgbByteArray As Byte() = RGB_Byte_Array_From_Image(filePath)
Dim width As Integer
Dim height As Integer
Dim pixelformat As Imaging.PixelFormat
Using image As New Bitmap(filePath)
width = image.Width
height = image.Height
pixelformat = image.PixelFormat
End Using
Using normal_Image As System.Drawing.Bitmap = RGB_Byte_Array_To_Image(rgbByteArray, width, height, pixelformat)
normal_Image.Save("C:\Users\...\Desktop\Test.png", Imaging.ImageFormat.Png)
End Using
End Sub
Private Shared Function RGB_Byte_Array_To_Image(rgbByteArray() As Byte, width As Integer, height As Integer, pixelformat As Imaging.PixelFormat) As Bitmap
Dim b As New Bitmap(width, height, pixelformat)
Dim BoundsRect As New Rectangle(0, 0, width, height)
Dim bmpData As Imaging.BitmapData = b.LockBits(BoundsRect, Imaging.ImageLockMode.WriteOnly, pixelformat)
Dim bytesPerPixel As Integer = Image.GetPixelFormatSize(pixelformat) \ 8
Dim stride As Integer = bmpData.Stride
Dim scan0 As IntPtr = bmpData.Scan0
For y As Integer = 0 To height - 1
Dim rowOffset As Integer = y * stride
Dim sourceOffset As Integer = y * width * bytesPerPixel
For x As Integer = 0 To width - 1
Dim pixelOffset As Integer = x * bytesPerPixel
' Reverse the order of color components (BGR instead of RGB)
Dim blue As Byte = rgbByteArray(sourceOffset + pixelOffset)
Dim green As Byte = rgbByteArray(sourceOffset + pixelOffset + 1)
Dim red As Byte = rgbByteArray(sourceOffset + pixelOffset + 2)
Runtime.InteropServices.Marshal.WriteByte(scan0, rowOffset + pixelOffset, blue)
Runtime.InteropServices.Marshal.WriteByte(scan0, rowOffset + pixelOffset + 1, green)
Runtime.InteropServices.Marshal.WriteByte(scan0, rowOffset + pixelOffset + 2, red)
Next
Next
b.UnlockBits(bmpData)
Return b
End Function
Private Function RGB_Byte_Array_From_Image(filePath As String) As Byte()
Dim imageBytes As Byte()
Using image As New Bitmap(filePath)
imageBytes = (New Byte(image.Width * image.Height * 3 - 1) {})
For y As Integer = 0 To image.Height - 1
For x As Integer = 0 To image.Width - 1
Dim pixelColor As Color = image.GetPixel(x, y)
Dim pixelIndex As Integer = (y * image.Width + x) * 3
imageBytes(pixelIndex) = pixelColor.R
imageBytes(pixelIndex + 1) = pixelColor.G
imageBytes(pixelIndex + 2) = pixelColor.B
Next
Next
End Using
Return imageBytes
End Function
End Class