I'm a newbie programmer. Is there any algorithm to convert an image to 16-bit or 8-bit? I didn't find it on google, I'am desperate.
可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
回答1:
Changing to 16 bit is the easier one. Assuming that the original image is in image
, you can simply draw it into the result.
Bitmap result = new Bitmap(image.Width, image.Height, PixelFormat.Format16bppRgb565); using (Graphics g = Graphics.FromImage(result)) { g.DrawImage(image, 0, 0, image.Width, image.Height); }
Unfortunately, this does not work for indexed images (images with palette, up to 256 colors). But you can find a solution in my answer here, see the ConvertPixelFormat
method.
回答2:
The only difference between 16 bit rgb and 8 bit rgb is the range, 16 bit has values form 0 to 65536 while 8 bit has values from 0 to 256, hence you should just be able to devide a 16 bit rgb value by 256 using integer division (for simplicity) and that will be it converted. (You need to decide the value in each plane by 256)
回答3:
Convert RGB image to 8-bit
public static Bitmap ConvertFromRGBTo8bit(this Bitmap rgbBmp) { // Copy image to byte Array var BoundsRectSrc = new Rectangle(0, 0, rgbBmp.Width, rgbBmp.Height); BitmapData bmpDataSrc = rgbBmp.LockBits(BoundsRectSrc, ImageLockMode.WriteOnly, rgbBmp.PixelFormat); IntPtr ptrSrc = bmpDataSrc.Scan0; int imgSizeSrc = bmpDataSrc.Stride * rgbBmp.Height; byte[] rgbValues = new byte[imgSizeSrc]; Marshal.Copy(ptrSrc, rgbValues, 0, imgSizeSrc); // Crearte bitmap with 8 index grayscale Bitmap newBmp = new Bitmap(rgbBmp.Width, rgbBmp.Height, PixelFormat.Format8bppIndexed); ColorPalette ncp = newBmp.Palette; for (int i = 0; i < 256; i++) ncp.Entries[i] = Color.FromArgb(255, i, i, i); newBmp.Palette = ncp; var BoundsRectDst = new Rectangle(0, 0, rgbBmp.Width, rgbBmp.Height); BitmapData bmpDataDst = newBmp.LockBits(BoundsRectDst, ImageLockMode.WriteOnly, newBmp.PixelFormat); IntPtr ptrDst = bmpDataDst.Scan0; int imgSizeDst = bmpDataDst.Stride * newBmp.Height; byte[] grayValues = new byte[imgSizeDst]; // Convert image to 8 bit according average pixel if (rgbBmp.PixelFormat == PixelFormat.Format16bppRgb555 || rgbBmp.PixelFormat == PixelFormat.Format16bppRgb565) for (int i = 0, j = 0; i < grayValues.Length; i++, j += 2) grayValues[i] = (byte)((rgbValues[j] + rgbValues[j + 1]) / 2); else if (rgbBmp.PixelFormat == PixelFormat.Format24bppRgb) for (int i = 0, j = 0; i < grayValues.Length; i++, j += 3) grayValues[i] = (byte)((rgbValues[j] + rgbValues[j + 1] + rgbValues[j + 2]) / 3); else if (rgbBmp.PixelFormat == PixelFormat.Format32bppRgb) for (int i = 0, j = 0; i < grayValues.Length; i++, j += 4) grayValues[i] = (byte)((rgbValues[j] + rgbValues[j + 1] + rgbValues[j + 2] + rgbValues[j + 3]) / 4); Marshal.Copy(grayValues, 0, ptrDst, imgSizeDst); newBmp.UnlockBits(bmpDataDst); rgbBmp.UnlockBits(bmpDataSrc); return newBmp; }