Accord.Imaging.Image.Convert16bppTo8bpp C# (CSharp) Method

Convert16bppTo8bpp() public static method

Convert bitmap with 16 bits per plane to a bitmap with 8 bits per plane.

The routine does the next pixel format conversions: Format16bppGrayScale to Format8bppIndexed with grayscale palette; Format48bppRgb to Format24bppRgb; Format64bppArgb to Format32bppArgb; Format64bppPArgb to Format32bppPArgb.

Invalid pixel format of the source image.
public static Convert16bppTo8bpp ( this bimap ) : Bitmap
bimap this Source image to convert.
return System.Drawing.Bitmap
        public static Bitmap Convert16bppTo8bpp(this Bitmap bimap)
        {
            Bitmap newImage = null;
            int layers = 0;

            // get image size
            int width = bimap.Width;
            int height = bimap.Height;

            // create new image depending on source image format
            switch (bimap.PixelFormat)
            {
                case PixelFormat.Format16bppGrayScale:
                    // create new grayscale image
                    newImage = CreateGrayscaleImage(width, height);
                    layers = 1;
                    break;

                case PixelFormat.Format48bppRgb:
                    // create new color 24 bpp image
                    newImage = new Bitmap(width, height, PixelFormat.Format24bppRgb);
                    layers = 3;
                    break;

                case PixelFormat.Format64bppArgb:
                    // create new color 32 bpp image
                    newImage = new Bitmap(width, height, PixelFormat.Format32bppArgb);
                    layers = 4;
                    break;

                case PixelFormat.Format64bppPArgb:
                    // create new color 32 bpp image
                    newImage = new Bitmap(width, height, PixelFormat.Format32bppPArgb);
                    layers = 4;
                    break;

                default:
                    throw new UnsupportedImageFormatException("Invalid pixel format of the source image.");
            }

            // lock both images
            BitmapData sourceData = bimap.LockBits(new Rectangle(0, 0, width, height),
                ImageLockMode.ReadOnly, bimap.PixelFormat);
            BitmapData newData = newImage.LockBits(new Rectangle(0, 0, width, height),
                ImageLockMode.ReadWrite, newImage.PixelFormat);

            unsafe
            {
                // base pointers
                byte* sourceBasePtr = (byte*)sourceData.Scan0.ToPointer();
                byte* newBasePtr = (byte*)newData.Scan0.ToPointer();
                // image strides
                int sourceStride = sourceData.Stride;
                int newStride = newData.Stride;

                for (int y = 0; y < height; y++)
                {
                    ushort* sourcePtr = (ushort*)(sourceBasePtr + y * sourceStride);
                    byte* newPtr = (byte*)(newBasePtr + y * newStride);

                    for (int x = 0, lineSize = width * layers; x < lineSize; x++, sourcePtr++, newPtr++)
                    {
                        *newPtr = (byte)(*sourcePtr >> 8);
                    }
                }
            }

            // unlock both image
            bimap.UnlockBits(sourceData);
            newImage.UnlockBits(newData);

            return newImage;
        }