C # печать значения пикселя - PullRequest
3 голосов
/ 19 декабря 2011

У меня 8-битное растровое цветное изображение.когда я делаю

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

, я получаю

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

, мне нужно получить только 8-битное значение.не 24-битные отдельные значения для R, G, B, A.

Ответы [ 4 ]

5 голосов
/ 19 декабря 2011

Нет способа сделать это, используя класс Bitmap напрямую. Однако вы можете использовать метод LockBits для прямого доступа к пикселям.

Использование небезопасного кода: (не забудьте сначала включить небезопасный код в вашем проекте)

public static unsafe Byte GetIndexedPixel(Bitmap b, Int32 x, Int32 y)
{
    if (b.PixelFormat != PixelFormat.Format8bppIndexed) throw new ArgumentException("Image is not in 8 bit per pixel indexed format!");
    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));
    BitmapData data = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadOnly, b.PixelFormat);
    try
    {
        Byte* scan0 = (Byte*)data.Scan0;
        return scan0[x + y * data.Stride];
    }
    finally
    {
        if (data != null) b.UnlockBits(data);
    }
}

Безопасная альтернатива, использующая Marshal.Copy:

public static Byte GetIndexedPixel(Bitmap b, Int32 x, Int32 y)
{
    if (b.PixelFormat != PixelFormat.Format8bppIndexed) throw new ArgumentException("Image is not in 8 bit per pixel indexed format!");
    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));
    BitmapData data = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadOnly, b.PixelFormat);
    try
    {
        Byte[] pixel = new Byte[1];
        Marshal.Copy(new IntPtr(data.Scan0.ToInt64() + x + y * data.Stride), pixel, 0, 1);
        return pixel[0];
    }
    finally
    {
        if (data != null) b.UnlockBits(data);
    }
}
1 голос
/ 19 декабря 2011

Методы в классе Bitmap не позволяют напрямую получить индекс палитры.

Вы можете получить палитру для изображения, используя свойство Palette, и найти там цвет, но это немного обходной путь.

Чтобы получить индекс палитры напрямую, вы должны использовать метод LockBits для прямого доступа к данным изображения. Вам придется либо использовать маршаллинг для копирования данных в массив, либо использовать указатели в небезопасном режиме для доступа к нему.


Свойство A в значении Color является альфа-компонентом. Может иметь значение от 0 до 255, где 0 - полностью прозрачный, а 255 - полностью прозрачный.

0 голосов
/ 09 января 2014

Если вы не хотите использовать LockBits, вы можете сделать это:

Предупреждение : Этот метод работает только в том случае, если палитра не имеет дублированных значений и не измениласьдругим потоком после установки pixelRGB.

/// <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 голосов
/ 19 декабря 2011

В действительности вы хотите указать значения R, G и B, которые являются 8-битными значениями растровых изображений соответствующих Red, Green и Blue компонентов цвета.

A - это Alfa компонент, значение прозрачности цвета.Если вас это не волнует, просто не показывайте это в строковом выводе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...