2011-12-19 69 views
3

我有一个8位位图彩色图像。当我做了C#打印像素值

Color pixelcolor = b.GetPixel(j,i);  
Console.Write(pixelcolor.ToString() + " "); 

我得到

Color [A=255, R=255, G=255, B=255] 

我需要只有8位值。 R,G,B,A不是24位分离值。

+0

是像8位索引或非索引? – 2011-12-19 08:51:15

+0

@ErnodeWeerd我老实说从未遇到过非索引8bpp格式。这意味着每个颜色分量只有2或3位,这对于存储有意义的颜色信息来说太小了。 – Nyerguds 2018-01-10 08:36:28

+0

@Nyerguds - 没有遇到它并不意味着根据规格是不可能的。单色或四色图像根本不是那么遥远。 – 2018-01-10 11:07:56

回答

4

直接使用Bitmap类没有办法做到这一点。在项目第一Remeber到enable unsafe code:但是,您可以使用LockBits方法直接使用unsafe代码,这样访问像素:

注意

private static unsafe byte GetIndexedPixel(Bitmap b, int x, int y) 
{ 
    if (x < 0 || x >= b.Width) throw new ArgumentOutOfRangeException("x", string.Format("x should be in 0-{0}", b.Width)); 
    if (y < 0 || y >= b.Height) throw new ArgumentOutOfRangeException("y", string.Format("y should be in 0-{0}", b.Height)); 
    var data = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadOnly, PixelFormat.Indexed); 
    try 
    { 
     var scan0 = (byte*) data.Scan0; 
     return scan0[x + y*data.Stride]; 
    } 
    finally 
    { 
     if (data != null) b.UnlockBits(data); 
    } 
} 
+0

您可以通过使用'Marshal.Copy'来避免不安全的字节。 – Nyerguds 2018-01-09 11:56:06

+1

是的,但烦人不得不复制整个缓冲区来查询一个像素。但是通常大部分(如果不是所有的像素都被读取),所以在这种情况下,Marshal.Copy是一个很好的选择。 – vidstige 2018-01-09 15:54:34

+1

是啊...使用此代码的原因与普通的'GetPixel'有相同的常见问题:在可能有数千甚至上万个像素的图像上循环遍历所有内容时,必须锁定和解锁每个像素,是臭名昭着的缓慢,而只是检查一个字节数组的内容是闪电般的。 – Nyerguds 2018-01-10 08:40:05

-1

你想要的值实际上RGB,分别对应RedGreen和颜色的Blue成分的8位位值。

A是一个Alfa coponent,颜色的透明度值。如果你不关心它,只是不要在字符串输出中显示它。

+0

@downvoter:谨慎解释? – Tigran 2011-12-19 10:00:15

+1

这不是如何索引位图工作... – vidstige 2016-06-20 06:20:07

1

Bitmap类中的方法不让您直接获取调色板索引。

您可以使用Palette属性获取图像的调色板,并在那里查找颜色,但这是一种解决方法。

要直接获取调色板索引,您可以使用LockBits方法直接访问图像数据。您将不得不使用编组将数据复制到数组中,或者使用不安全模式下的指针来访问它。


ColorA属性是阿尔法分量。它可以具有0到255的值,其中0完全透明,255完全固体。

0

如果你不想使用LockBits,你可以这样做:

/// <summary> 
/// Gets the pixel value in bytes. Uses Bitmap GetPixel method. 
/// </summary> 
/// <param name="bmp">Bitmap</param> 
/// <param name="location">Pixel location</param> 
/// <returns>Pixel value</returns> 
public static byte Get8bppImagePixel(Bitmap bmp, Point location) 
{ 
    Color pixelRGB = bmp.GetPixel(location.X, location.Y); 
    int pixel8bpp = Array.IndexOf(bmp.Palette.Entries, pixelRGB); 
    return (byte)pixel8bpp; 
} 
+0

这是不可靠的,如果调色板有重复。 – Nyerguds 2018-01-09 11:56:41