public static Bitmap Convert8bppTo16bpp(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.Format8bppIndexed:
// create new grayscale image
newImage = new Bitmap(width, height, PixelFormat.Format16bppGrayScale);
layers = 1;
break;
case PixelFormat.Format24bppRgb:
// create new color 48 bpp image
newImage = new Bitmap(width, height, PixelFormat.Format48bppRgb);
layers = 3;
break;
case PixelFormat.Format32bppArgb:
// create new color 64 bpp image
newImage = new Bitmap(width, height, PixelFormat.Format64bppArgb);
layers = 4;
break;
case PixelFormat.Format32bppPArgb:
// create new color 64 bpp image
newImage = new Bitmap(width, height, PixelFormat.Format64bppPArgb);
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++)
{
byte* sourcePtr = (byte*)(sourceBasePtr + y * sourceStride);
ushort* newPtr = (ushort*)(newBasePtr + y * newStride);
for (int x = 0, lineSize = width * layers; x < lineSize; x++, sourcePtr++, newPtr++)
{
*newPtr = (ushort)(*sourcePtr << 8);
}
}
}
// unlock both image
bimap.UnlockBits(sourceData);
newImage.UnlockBits(newData);
return newImage;
}
}