2017-10-12 106 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)); 
相關問題