Solved

16 bit Grayscale BMP

Posted on 2006-06-16
8
2,813 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
  • 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
Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
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

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

This article describes a simple method to resize a control at runtime.  It includes ready-to-use source code and a complete sample demonstration application.  We'll also talk about C# Extension Methods. Introduction In one of my applications…
This article aims to explain the working of CircularLogArchiver. This tool was designed to solve the buildup of log file in cases where systems do not support circular logging or where circular logging is not enabled
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…
In a recent question (https://www.experts-exchange.com/questions/29004105/Run-AutoHotkey-script-directly-from-Notepad.html) here at Experts Exchange, a member asked how to run an AutoHotkey script (.AHK) directly from Notepad++ (aka NPP). This video…

789 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