如何从位图获取RGB代码

时间:2015-03-26 15:10:07

标签: c# windows-phone writeablebitmap

为了解决这个问题,我对C#,XAML和Windows手机都很陌生。到目前为止,我已经设法通过图库/相机将照片放入应用程序并将其转换为灰度。但我的目标是从像素中获取rgb值并将其作为文本显示在图像下。如何更改灰度代码而不是修改图像以显示rgb代码?谢谢!

async void GrayScale(Image lpictureBox)
{

    WriteableBitmap modifiedImage = lpictureBox.Source as WriteableBitmap;
    if (modifiedImage == null)
    {
        BitmapSource bs = lpictureBox.Source as BitmapSource;
        modifiedImage = new WriteableBitmap(bs.PixelWidth, bs.PixelHeight);
    }
    int r = 0, a = 0, i = 0;
    int h = modifiedImage.PixelHeight;
    int w = modifiedImage.PixelWidth;
    Stream stream = modifiedImage.PixelBuffer.AsStream();
    byte[] StreamBuffer = new byte[stream.Length];
    stream.Seek(0, 0);
    await stream.ReadAsync(StreamBuffer, 0, StreamBuffer.Length);
    for (i = 0; i < StreamBuffer.Length - 4; i = i + 4)
    {
        var a1 = StreamBuffer[i + 3];
        var r1 = StreamBuffer[i + 2];
        var g1 = StreamBuffer[i + 1];
        var b1 = StreamBuffer[i + 0];
        a = 0xff;
        r = (byte)((0.299 * r1) + (0.587 * g1) + (0.114 * b1));
        StreamBuffer[i + 3] = (byte)a;  // alpha​
        StreamBuffer[i + 2] = (byte)(r > 255 ? 255 : (r < 0 ? 0 : r));  //red​
        StreamBuffer[i + 1] = (byte)(r > 255 ? 255 : (r < 0 ? 0 : r));  //green​
        StreamBuffer[i + 0] = (byte)(r > 255 ? 255 : (r < 0 ? 0 : r));  //blue​
    }
    stream.Seek(0, 0);
    stream.Write(StreamBuffer, 0, StreamBuffer.Length);
    modifiedImage.Invalidate();
    lpictureBox.Source = modifiedImage;
}

2 个答案:

答案 0 :(得分:0)

有很多方法可以完成您所要求的内容,包括仅使用CoderDennis提到的the third-party extensions library评论者。

但是,如果我理解您的问题和Windows Phone实施(MSDN文档的详细信息,例如像素格式和步幅),那么您发布的代码非常接近您所需要的代码。 ,位图的两个重要属性,用于了解何时检索特定像素数据)。基于上述库中的代码,Windows Phone位图始终为每像素32位,并且总是具有等于位图宽度的步幅。

另请注意,如果您要经常检索像素信息,那么每次要检索像素信息时,都可能需要重新读取整个位图。相反,您希望每次都缓存字节缓冲区以供重用。

因此,考虑到这一点,这里是您的原始代码,重新安排并扩展以完成您所要求的内容:

class BitmapData
{
    private readonly byte[] _buffer;
    private readonly int _stride;

    private BitmapData(byte[] buffer, int stride)
    {
        _buffer = buffer;
        _stride = stride;
    }

    public Color GetPixel(int x, int y)
    {
        Color color = new Color();

        // Convert from pixel to byte offsets
        int pixelOffset = y * _stride * 4 + x * 4;

        // Retrieve pixel data
        color.A = _buffer[pixelOffset + 3];
        color.R = _buffer[pixelOffset + 2];
        color.G = _buffer[pixelOffset + 1];
        color.B = _buffer[pixelOffset + 0];

        return color;
    }

    public static async Task<BitmapData> Create(BitmapSource source)
    {
        WriteableBitmap dataSource = source as WriteableBitmap;

        if (dataSource == null)
        {
            // NOTE: in your original code, this is all the initialization you
            // did when the input isn't already a WriteableBitmap object.
            // Wouldn't it make more sense to copy the source bitmap
            // to your new WriteableBitmap object? Otherwise, you won't have
            // the pixel data from the source!
            dataSource = new WriteableBitmap(source.PixelWidth, source.PixelHeight);
        }

        Stream stream = dataSource.PixelBuffer.AsStream();
        byte[] buffer = new byte[stream.Length];
        stream.Seek(0, 0);
        await stream.ReadAsync(buffer, 0, buffer.Length);

        return new BitmapData(buffer, dataSource.PixelWidth);
    }
}

您可以这样创建:

BitmapData bitmapData = await BitmapData.Create(lpictureBox.Source);

您需要将该对象保存在某处的某个字段中,以便稍后当您需要像素信息时,您可以获取它:

Color pixelColor = bitmapData.GetPixel(x, y);

答案 1 :(得分:-1)

如果您需要知道位图上特定像素的RGB代码,可以使用Bitmap.GetPixel()方法。

以下是Bitmap.GetPixel() on MSDN

的链接

编辑: 也许&#39; WritableBitmapEx&#39;是你需要的。

他们的描述:

  

WriteableBitmapEx库是WriteableBitmap的扩展方法的集合。 WriteableBitmap类可用于Windows Phone,WPF,WinRT Windows Store XAML和Silverlight,并允许直接操作位图,并可通过直接绘制到位图来生成快速程序图像。 WriteableBitmap API非常简约,并且只有用于此类操作的原始像素阵列。 WriteableBitmapEx试图通过扩展方法来补偿它,这些方法像内置方法一样易于使用,并提供类似GDI +的功能。

这为.GetPixel()类提供了.GetPixeli()WritableBitmap

相关问题