2017-10-12 99 views
0

我有一个数组=字节[512,512]在每个字段中我有一个值从0到255,然后代表灰色(从白色到黑色)每个像素。到现在为止,我用代码创建了一个代码,它为每个数组字段创建一个新的矩形(宽度为1高度1),然后将其放在画布上。这种方法很慢(至少在我的笔记本电脑上)。它通常需要30或40秒。WPF:寻找一种快速的方法来显示RGB到像素阵列(字节)以创建一个图像

如果有人能告诉我如何以其他方式做到这一点,我会非常高兴。 预先感谢您。

private void draw_a_pixel(Rectangle pixel, double top, int widthCounter) 
    { 
     Canvas.SetTop(pixel, Convert.ToInt32(top)); 
     Canvas.SetLeft(pixel, widthCounter); 
     canvas1.Children.Add(pixel); 

    } 

这是我认为需要最多时间的代码部分。

+0

像素阵列被称为图像..!看看'WriteableBitmap'。 – Chris

+0

是的,像素逐像素不会很快......尽管30秒看起来极端。 – zzxyz

+0

嗨克里斯我已经用WriteableBitmap尝试过,但我找不到任何如何生成它或稍后在画布上显示它的好例子。所以我希望如果你能分享一些关于这方面的知识,也许给我写了一个适用于我的案例的示例代码。 – N1no

回答

1

正如Chris所说,你应该使用WriteableBitmap

下面是一些材料开始:

/// <summary> 
/// method that will create a source for your image object, 
/// and fill it with a specified array of pixels 
/// </summary> 
/// <param name="pixels">your array of pixels</param> 
/// <returns>your image object</returns> 
public BitmapSource DrawImage(Int32[,] pixels) 
{ 
    int resX = pixels.GetUpperBound(0) + 1; 
    int resY = pixels.GetUpperBound(1) + 1; 

    WriteableBitmap writableImg = new WriteableBitmap(resX, resY, 96, 96, PixelFormats.Bgr32, null); 

    //lock the buffer 
    writableImg.Lock(); 

    for (int i = 0; i < resX; i++) 
    { 
     for (int j = 0; j < resY; j++) 
     { 
      IntPtr backbuffer = writableImg.BackBuffer; 
      //the buffer is a monodimensionnal array... 
      backbuffer += j * writableImg.BackBufferStride; 
      backbuffer += i * 4; 
      System.Runtime.InteropServices.Marshal.WriteInt32(backbuffer, pixels[i,j]); 
     } 
    } 

    //specify the area to update 
    writableImg.AddDirtyRect(new Int32Rect(0, 0, resX, resY)); 
    //release the buffer and show the image 
    writableImg.Unlock(); 

    return writableImg; 
} 

您的阵列中的每个像素必须是一个Int32。 这里是一个函数,RGB颜色代码转换成的Int32

/// <summary> 
/// Return the specified color code as a Int32 
/// </summary> 
public Int32 GetColor(byte r, byte g, byte b) 
{ 
    return Int32.Parse(Color.FromRgb(r, g, b).ToString().Trim('#'), System.Globalization.NumberStyles.HexNumber); 
} 

填写您的像素阵列你想要的方式。

将您的XAML添加为Image并更新源代码。

<Image x:Name="Chart"/> 

Chart.Source = DrawImage(pixels); 
+0

非常感谢。你的解释是现货,你的代码样本工作100%! – N1no

1

您可以使用如下所示的方法从字节的二维数组创建灰度位图。像素阵列被复制到符合Gray8格式的像素缓冲器中,即灰度与每像素8位。

public static BitmapSource GetBitmap(byte[,] pixels) 
{ 
    var width = pixels.GetUpperBound(0) + 1; 
    var height = pixels.GetUpperBound(1) + 1; 
    var buffer = new byte[width * height]; 

    for (var y = 0; y < height; y++) 
    { 
     for (var x = 0; x < width; x++) 
     { 
      buffer[width * y + x] = pixels[x, y]; 
     } 
    } 

    var bitmap = BitmapSource.Create(
     width, height, 96, 96, PixelFormats.Gray8, null, buffer, width); 
    bitmap.Freeze(); 

    return bitmap; 
} 

如果一个字节实际上代表的是从白到黑,而不是黑到白的范围值,只写

buffer[width * y + x] = (byte)(255 - pixels[x, y]); 

你可能比在XAML

<Image x:Name="image" /> 
有一个图像控制

并将该位图分配给其Source属性:

image.Source = GetBitmap(pixels); 

您还可以得到一个更灵活的用户界面,如果你在后台线程创建位图,像

image.Source = await Task.Run(() => GetBitmap(pixels)); 
相关问题