Solved

16 bit Grayscale BMP

Posted on 2006-06-16
8
2,946 Views
Last Modified: 2012-05-05
Hi
I have an 16 bit short array data of 3712x3712 sized.
I want to create a grayscale image file probably bmp format.
Here is my code:
It did not worked. Because .net does not support 16 bit grayscale images.
Is there a way to create a 16 bit grayscale image by c#.

public static unsafe Bitmap BytesToBmp(byte[] bmpBytes,int width,int height)
        {
            Size imageSize=new Size(width,height);  
            Bitmap bmp = new Bitmap(imageSize.Width, imageSize.Height);

            BitmapData bData = bmp.LockBits(new Rectangle(new Point(), bmp.Size),
                ImageLockMode.WriteOnly,
                PixelFormat.Format16bppGrayScale);

            // Copy the bytes to the bitmap object
            Marshal.Copy(bmpBytes, 0, bData.Scan0, bmpBytes.Length);
            bmp.UnlockBits(bData);
            return bmp;
        }  
0
Comment
Question by:obeser
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4
  • 3
8 Comments
 
LVL 2

Expert Comment

by:Naishal
ID: 16919333
what's the error?
0
 
LVL 48

Expert Comment

by:AlexFM
ID: 16919386
Windows doesn't support 16 bpp grayscale images. If you want to keep such image in a file, use binary raw file. To draw 16 bpp image, convert it to 8 bpp grayscale image.
0
 

Author Comment

by:obeser
ID: 16925914
How can i convert 16 bpp imageto 8 bpp grayscale image?
If i can achieve this i will solve my problem.
I am aware that "Windows doesn't support 16 bpp grayscale images".
cheers
Ozgur
0
Salesforce Has Never Been Easier

Improve and reinforce salesforce training & adoption using WalkMe's digital adoption platform. Start saving on costly employee training by creating fast intuitive Walk-Thrus for Salesforce. Claim your Free Account Now

 
LVL 48

Expert Comment

by:AlexFM
ID: 16925949
You need to convert every 16 bits pixel to 8 bit. Bitmap shown in 8 bits looses resolution, but there is nothing to do.
Simplest way to convert 16 to 8 is to get high byte of every pixel.
You can improve conversion is real dynamic pixel range is less than 0 - 2^16 - 1. For example, pixels in 16 bpp bitmap are in the range 1000 - 5000. In this case you need to map interval 1000 - 5000 to 0 - 255 using simple math.
Using high byte of every pixel is the same as mapping 0 - 2^16-1 to 0-255.

Having array of bytes you can copy it to bitmap and show on the screen. Your code is not 100% correct, I can post you code which converts byte[] to grayscale bitmap.
0
 

Author Comment

by:obeser
ID: 16926016
would you please send a code that take 16 bit array data and draw it as 8bpp grayscale bitmap.
0
 
LVL 48

Accepted Solution

by:
AlexFM earned 500 total points
ID: 16926062
       Bitmap BytesToBmp(ushort[] bmpBytes,int width,int height)
        {
              Byte[] bytes = new byte[width*height];

              // Convert 16 bbis array to 8 bits using simple algorithm
              for ( int i = 0; i < width*height; i++ )
              {
                    bytes[i] = (Byte) (bmpBytes[i] >> 8);
              }

              return BitsToBitmapMonochrome(butes, width, height);
        }


        // Create monochrome bitmap from Byte array
        Bitmap BitsToBitmapMonochrome(Byte[] bytes, int width, int height)
        {
            if (bytes.GetLength(0) < width * height)
            {
                return null;
            }

            Bitmap bmp = new Bitmap(width, height, PixelFormat.Format8bppIndexed);
            int i;

            bmp.Palette = GetGrayScalePalette();
           
            BitmapData data = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height),
                ImageLockMode.WriteOnly, bmp.PixelFormat);

            if (data.Stride == width)
            {
                Marshal.Copy(bytes, 0, data.Scan0, width * height);
            }
            else
            {
                for (i = 0; i < bmp.Height; i++)
                {
                    IntPtr p = new IntPtr(data.Scan0.ToInt32() + data.Stride * i);
                    Marshal.Copy(bytes, i * bmp.Width, p, bmp.Width);
                }
            }

            bmp.UnlockBits(data);

            return bmp;
        }

        ColorPalette GetGrayScalePalette()
        {
            Bitmap bmp = new Bitmap(1, 1, PixelFormat.Format8bppIndexed);

            ColorPalette monoPalette = bmp.Palette;

            Color[] entries = monoPalette.Entries;

            for ( int i = 0; i < 256; i++ )
            {
                entries[i] = Color.FromArgb(i, i, i);
            }

            return monoPalette;
        }
0
 

Author Comment

by:obeser
ID: 16926117
thanks i will try it today and return to you. It seems ok.
here the simple algorithm you used should be replaced by a histogram equalization  algorithm.
Because the simple algo. you used produce not saturated images. Do you aware of it?
0
 
LVL 48

Expert Comment

by:AlexFM
ID: 16926130
Sure, algorithm part is yours. I posted simplest way, you need to use the way which is best for your case. Having some experience in image processing, I know that there is no universal solution for all imaging tasks.
0

Featured Post

PeopleSoft Has Never Been Easier

PeopleSoft Adoption Made Smooth & Simple!

On-The-Job Training Is made Intuitive & Easy With WalkMe's On-Screen Guidance Tool.  Claim Your Free WalkMe Account Now

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

We all know that functional code is the leg that any good program stands on when it comes right down to it, however, if your program lacks a good user interface your product may not have the appeal needed to keep your customers happy. This issue can…
Performance in games development is paramount: every microsecond counts to be able to do everything in less than 33ms (aiming at 16ms). C# foreach statement is one of the worst performance killers, and here I explain why.
Finds all prime numbers in a range requested and places them in a public primes() array. I've demostrated a template size of 30 (2 * 3 * 5) but larger templates can be built such 210  (2 * 3 * 5 * 7) or 2310  (2 * 3 * 5 * 7 * 11). The larger templa…
Attackers love to prey on accounts that have privileges. Reducing privileged accounts and protecting privileged accounts therefore is paramount. Users, groups, and service accounts need to be protected to help protect the entire Active Directory …

738 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question