public static Bitmap Convert8bppTo16bpp( 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
int sourceBasePtr = (int) sourceData.Scan0.ToPointer( );
int newBasePtr = (int) 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;
}