Have a look at
http://www.codeproject.com/cs/media/Image_Processing_Lab.asp
To create a grayscale image from a 256-color image, he creates
a new 8-bit image of the same size as the original, sets the Palette
values of the new image to 0,0,0 1,1,1 2,2,2 ... 255,255,255,
then proceeds to set the pixel data of the new image by calculating
the intensities of the original image.
It would have been much faster had he just modified the palette
entries of the original image.
I made another test (create a new Windows application project):
---snip---
Private _bm As Bitmap
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load
Test2()
End Sub
Private Sub Test2()
Dim lena8 As New Bitmap("d:\lena8.bmp")
SetGrayscalePalette(lena8)
_bm = lena8
lena8.Save("d:\lena8-gray.bmp",
System.Drawing.Imaging.ImageFormat.Bmp)
End Sub
Public Shared Sub SetGrayscalePalette(ByVal image As Bitmap)
If (image.PixelFormat <> PixelFormat.Format8bppIndexed) Then
Throw New ArgumentException
End If
Dim palette As ColorPalette = image.Palette
Dim i As Integer
For i = 0 To &H100 - 1
'palette.Entries(i) = Color.FromArgb(i, i, i)
Dim original As Color = palette.Entries(i)
Dim gray As Integer = CType((original.G * 4 + original.R *
2 + original.B) / 7, Integer)
palette.Entries(i) = Color.FromArgb(gray, gray, gray)
Next i
image.Palette = palette
End Sub
Private Sub Form1_Paint(ByVal sender As Object, ByVal e As
System.Windows.Forms.PaintEventArgs) Handles Me.Paint
If _bm Is Nothing Then
Exit Sub
End If
e.Graphics.DrawImage(_bm, 0, 0, _bm.Width, _bm.Height)
End Sub
---snip---
(Yes, I know that (G*4+R*2+B)/7 is simplistic and incorrect)
You will notice that the palette entries actually have changed when
the image is painted on the form, but the saved copy retains the
original colors.
If we were to paint the image from the code above onto a 24-bit
bitmap and save it, we get a nice grayscale image, albeit 24-bit:
---snip---
Dim dst As New Bitmap(lena8.Width, lena8.Height,
PixelFormat.Format24bppRgb)
Dim g As Graphics = Graphics.FromImage(dst)
g.DrawImage(lena8, 0, 0, dst.Width, dst.Height)
g.Dispose()
dst.Save("d:\dst.bmp", ImageFormat.Bmp)
---snip---
(it is not possible to create a Graphics object from an indexed
image).
I have not spent any time digging into why the original palette
is used when saving an indexed image, but as I mentioned in the
other post, I use an imaging library myself (LeadTools).
Perhaps the link at the top might give you a few ideas of how
to go about this in an entirely different way.
Regards,
Joergen Bech