Convert an Image to 8-bit grayscale

P

platinumhimani

-> How to convert any image(8,16,24,32 or 64-bit) to 8-bit grayscale

-> i have tried to convert a 24-bit image to grayscale using setpixel
and getpixel functions, in vb.net
but i am unable to save that image in grayscale format.How do i do
that.It still saves in true color format.
-> i used picturebox1.image.save() method

-> i tried to convert an 8-bit image into grayscale but was unable to
do it.
 
G

Guest

Make a new memory bitmap with the pixel format set to grey scale. Then read
the coloured pixels one by one, average the red, green and blue value and
make that number the greyscale intensity and write it to the corresponding
pixel location of the memory bitmap. Then save the memory bitmap.
 
P

platinumhimani

well
can we set the pixel format to grayscale..for as i know framework
supports just the Format16bppGrayscale..which also doesn't work
properly and my image is an 8-bit image
<--Help-->
 
P

platinumhimani

hey,
I just found the following code in one of the other threads
Public Sub convert()


Dim g As Graphics
Dim ImageToConvert As Image = New Bitmap(m_Image)
Dim ImageAttributes As ImageAttributes = New ImageAttributes()
Dim width As Integer = ImageToConvert.Width
Dim height As Integer = ImageToConvert.Height
Dim GrayShear()() As Single = New Single()() _
{New Single(4) {0.5, 0.5, 0.5, 0, 0}, _
New Single(4) {0.5, 0.5, 0.5, 0, 0}, _
New Single(4) {0.5, 0.5, 0.5, 0, 0}, _
New Single(4) {0, 0, 0, 1, 0}, _
New Single(4) {0, 0, 0, 0, 1}}


Dim colMatrix As ColorMatrix = New ColorMatrix(GrayShear)


ImageAttributes.SetColorMatrix(colMatrix, ColorMatrixFlag.Default, _
ColorAdjustType.Bitmap)


g = Graphics.FromImage(ImageToConvert)


g.DrawImage(ImageToConvert, _
New Rectangle(0, 0, width, height), 0, 0, _
width, height, GraphicsUnit.Pixel, ImageAttributes)


m_Image = ImageToConvert
g.Dispose()


End Sub


'and it works
 
P

Peter Duniho

hey,
I just found the following code in one of the other threads
Public Sub convert()

It's funny how this code keeps getting around. Makes one wonder when
Microsoft will just go ahead and put the damn functionality into .NET. It's
silly for it to not be built-in.

Of course, one might question why you are posting Visual Basic code to a C#
newsgroup, but I think we can all get the meaning of the code easily enough,
even if it's not the right language. :)

Anyway, when I had the same question, I used Google to find the answer.
Except that Google turned up a few variations, all based on the same code.
Only problem was that each variation had subtle problems with it.

At least the version you found has an array of the correct dimensions. All
of the versions I found actually had an array with the wrong number of
elements in some rows.

In any case, the one thing wrong with the version you just found is that it
doesn't actually map the colors in a perceptually correct way. A better
version of the array would be (still in VB, natch):
Dim GrayShear()() As Single = New Single()() _
{New Single(4) {0.3, 0.3, 0.3, 0, 0}, _
New Single(4) {0.59, 0.59, 0.59, 0, 0}, _
New Single(4) {0.11, 0.11, 0.11, 0, 0}, _
New Single(4) {0, 0, 0, 1, 0}, _
New Single(4) {0, 0, 0, 0, 1}}

Hope that helps...

Pete
 
P

platinumhimani

hey,
thanks for the new matrix.It helped..
But i have a new issue now..m unable to save this image in grayscale
format..
when i check the file properties...using the follwing method

---------------------------------
Public Sub modInfo(ByVal infile As String)
Try
Dim oreg As RegistryKey
Dim ffile As New FileInfo(infile)
Dim instrm As New FileStream(infile, FileMode.Open)
Dim img As Image = Image.FromStream(instrm)
Dim pos As Integer = 0

'file properties
intfilesize = CInt(ffile.Length)
strfullname = ffile.FullName
strtype = ffile.Extension.ToString
ffile = Nothing
oreg = Registry.ClassesRoot.OpenSubKey(strtype)
If oreg Is Nothing Then
strtype = "UnKnown"
Else
strtype = oreg.GetValue("").ToString
oreg = Registry.ClassesRoot.OpenSubKey(strtype)
strtype = oreg.GetValue("", "").ToString
End If
oreg.Close()
'image properties
intwidth = CInt(img.Width)
intheight = CInt(img.Height)
strimgformat = img.PixelFormat.ToString
pos = strimgformat.LastIndexOf("p")
strimgformat = strimgformat.Substring(pos + 1)
strbitsperpixel = Image.GetPixelFormatSize(img.PixelFormat)
intHorRes = img.HorizontalResolution
intVerRes = img.VerticalResolution
instrm.Close()

Catch ex As Exception
MsgBox(ex.Message)
End Try
End Sub
---------------------------------

, then the pixel format comes out to be 32 bit..non-grayscale...It just
doesn't seem to save correctly..The file generated when saved using the
bitmap's save method..doesn't even open in Photo editor..(It shows an
error)

--> My question is how to save this grayscale file in 8 bits.

and i have a new question...
How do i convert a 24-bit image to 8-bit image (no grayscaling) and
vice-versa.....and save it as 24/8 bit..(should save correctly).

< --HELP-->
regards

Himani
 
P

platinumhimani

and sorry for posting vb.net code to CSharp group i culdn't find the
dot net group..
and anyways i just need the logic
Thanks again
 
P

Peter Duniho

[...]
, then the pixel format comes out to be 32 bit..non-grayscale...It just
doesn't seem to save correctly..The file generated when saved using the
bitmap's save method..doesn't even open in Photo editor..(It shows an
error)

--> My question is how to save this grayscale file in 8 bits.

and i have a new question...
How do i convert a 24-bit image to 8-bit image (no grayscaling) and
vice-versa.....and save it as 24/8 bit..(should save correctly).

I don't know the answer to that one. My limited experience with the .NET
bitmap image support is that 8-bit and 16-bit images have little if no real
support. For sure, the "to grayscale" code here only converts colored
pixels to grayscale ones, but the image format remains the same. The image
is still a color format...it just doesn't have any non-grayscale pixels in
it after the conversion.

Whether that has anything to do with the problem you're having with saving
the file, I don't know. I haven't tried to use .NET to save out any image
bitmaps, so I'm not familiar with how well it works (or doesn't :) ).

For what it's worth, the bitmap image formats aren't very complicated. As
long as you didn't want compression, you should be able to write your own
file output code without too much trouble.

Pete
 
L

Lucian Wischik

Peter Duniho said:
I don't know the answer to that one. My limited experience with the .NET
bitmap image support is that 8-bit and 16-bit images have little if no real
support.

I wrote some code to convert a bitmap into a monochrome image. The
code is in C#, but it uses interop to call the native win32 GDI
functions. (so, it's fast!). And it returns a geniune 1bit image,
rather than a 24bit one which happens to use only black and white..
http://www.wischik.com/lu/Programmer/1bpp

You can adapt this to do 8bpp. To do so, I downloaded the code and
modified it as follows:

static uint MAKERGB(int r,int g,int b)
{ return ((uint)(b&255)) | ((uint)((r&255)<<8)) |
((uint)((g&255)<<16));
}

unsafe public struct BITMAPINFO
{ public uint biSize;
public int biWidth, biHeight;
public short biPlanes, biBitCount;
public uint biCompression, biSizeImage;
public int biXPelsPerMeter, biYPelsPerMeter;
public uint biClrUsed, biClrImportant;
public fixed uint cols[256];
}

bmi.biBitCount=8; // ie. 1bpp
bmi.biClrUsed=256;
bmi.biClrImportant=256;
// Now for the RGBQUAD table.
Random r = new Random();
for (int i=0; i<256; i++)
{ bmi.cols = MAKERGB(r.Next(256),r.Next(256),r.Next(128));
}


Note that this is now unsafe. It's unsafe because I embedded a fixed
array inside the BITMAPINFO structure, to store the palette. Can
anyone advise me what's a nice not-unsafe way to do this? Once I know,
I'll update the web page appropriately.
 
M

Michael C

Al said:
Given a 16 bit grey scale raw image file, can this accomodate reading the
file into an array of unsgined short (16 bit data) and then creating the 8
bit bitmap?

Thanks in advance,

Yes, have a look into Bitmap.LockBits function. You can use this to create a
bitmap and populate it with your required data.

Michael
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top