Convert RGB image to RGB 16-bit and 8-bit

我的未来我决定 提交于 2019-12-13 05:08:00

问题


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;
}


来源:https://stackoverflow.com/questions/32991171/convert-rgb-image-to-rgb-16-bit-and-8-bit

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!