2010-12-12 30 views
4

我設置了一個代碼,用於隨機覆蓋2個不同顏色的位圖,10個顏色中的7個是藍色,10箇中的3個顏色是綠色。然而,當它完成時,它看起來非常隨意,就像決定放幾次7個藍色像素,然後幾次放3個綠色像素,等等。
例子:
alt text 我的代碼是:爲什麼隨機像素顏色在我的C#應用​​程序中不是那麼隨機的?

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Windows.Forms; 

namespace FourEx 
{ 
    public partial class Form1 : Form 
    { 
     public Form1() 
     { 
      InitializeComponent(); 
     } 

     private void Form1_Load(object sender, EventArgs e) 
     { 
      Bitmap bmp = new Bitmap(canvas.Image); 
      System.Drawing.Imaging.BitmapData bmpdata = bmp.LockBits(new Rectangle(0, 0, 800, 600), System.Drawing.Imaging.ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format32bppArgb); 
      unsafe 
      { 
       int tempy = 0; 
       while (tempy < 600) 
       { 
        byte* row = (byte*)bmpdata.Scan0 + (tempy * bmpdata.Stride); 
        for (int x = 0; x <= 800; x++) 
        { 
         Random rand = new Random(); 
         if (rand.Next(1,10) <= 7) 
         { 
          row[x * 4] = 255; 
         } 
         else 
         { 
          row[(x * 4) + 1] = 255; 
         } 
        } 
        tempy++; 
       } 
      } 
      bmp.UnlockBits(bmpdata); 
      canvas.Image = bmp; 
     } 
    } 
} 

如果您需要更多的信息,讓我知道。

+1

正在使用'LockBits'和'unsafe'進行性能優化嗎?看起來你可以使用['Bitmap.SetPixel'](http://msdn.microsoft.com/en-us/library/system.drawing.bitmap.setpixel.aspx)更容易地做到這一點。 – 2010-12-12 05:14:30

+0

@Code Grey:Get/SetPixel的性能對於圖像處理來說真的很差,這是一種非常普遍的方法,可以在像素逐個像素顏色的情況下獲得可接受的大規模圖像生成性能。 – 2010-12-12 05:19:10

+1

@克里斯:我知道。我問是否是出於性能原因,還是因爲他不知道更簡單的選擇。我已經在應用程序中完成了這兩個操作,具體取決於您如何說,「大規模」,我必須要做的圖像操作。如果你只是一次創建一個隨機圖像(就像在你的'Form.Load'事件中一樣),可能沒有必要擠出每一個可能的表現。 – 2010-12-12 05:21:39

回答

11

移動這一行:

Random rand = new Random(); 

到最外面的範圍。如果你快速創建它們,很多會得到相同的時間種子(由於時鐘的精確性),並且會生成相同的「隨機」序列。另外,你只需要一個隨機實例...

private void Form1_Load(object sender, EventArgs e) 
{ 
    Bitmap bmp = new Bitmap(canvas.Image); 
    System.Drawing.Imaging.BitmapData bmpdata = bmp.LockBits(new Rectangle(0, 0, 800, 600), System.Drawing.Imaging.ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format32bppArgb); 

    Random rand = new Random(); 

    unsafe 
    { 
    // .... 
+0

謝謝,我不認爲這會影響它。完美的作品:)。 – GunnarJ 2010-12-12 07:05:45

+0

爲什麼我們(應用程序開發人員)打算隨時創建隨機種子實例?爲什麼不把它移動到標準庫本身的最外層範圍或類似的東西呢?自從我第一次遇到這種模式以來,我一直在想這個問題已經有20年了(我記得在DOS下的QuickBasic中)。爲什麼在C#和其他語言中不存在跨平臺的替代方案,在類Unix操作系統中實際上存在系統全局'/ dev/random'? – Ivan 2017-06-27 20:48:07