2010-01-22 104 views
2

在Delphi編寫的代碼:從德爾福C#Image1.Canvas.Pixels

result = (Image1.Canvas.Pixels[i, j] and $000000ff); 

它是什麼意思呢? 如果可能,請說我怎麼能在C#中執行相同的操作?

編輯: 我不知道在哪裏的問題:我使用相同的算法,但結果並不等同或相同 。我覺得我不明白Delphi代碼真!

Delphi代碼:

procedure TForm1.Button1Click(Sender: TObject); 
var 
i,j:byte; 
noise_mass: array [0..255,0..255] of byte; 
BN,BST:real; 
mu:real; 
begin 
mu:=0.75; 
Randomize; 
for i:=0 to 255 do 
begin 
for j:=0 to 255 do 
begin 
    noise_mass[i,j]:=Random(255); 
    BN:=BN+sqr(noise_mass[i,j]); 
    BST:=BST+sqr(image1.Canvas.Pixels[i,j] and $000000ff); 
end; 
end; 
for i:=0 to 255 do 
begin 
for j:=0 to 255 do 
begin 
image1.Canvas.Pixels[i,j]:=image1.Canvas.Pixels[i,j]+round(mu*noise_mass[i,j]*BST/BN); 
end; 
end; 
end; 

C#代碼:

private Bitmap MakeNoise(Bitmap original) 
    { 
     double mu = 0.5; 

     Bitmap newBitmap = new Bitmap(256, 256); 
     double BN = 0, BST = 0; 
     byte[,] noise_mass = new byte[256, 256]; 

     for (int i = 0; i <= 255; i++) 
     { 
      for (int j = 0; j <= 255; j++) 
      { 
       noise_mass[i, j] = (byte)(new System.Random(255)).Next(); 
       BN = BN + Math.Pow(noise_mass[i, j], 2); 
       BST = BST + Math.Pow(original.GetPixel(i, j).R, 2); 

      } 
     } 
     for (int i = 0; i <= 255; i++) 
     { 
      for (int j = 0; j <= 255; j++) 
      { 
       int r = original.GetPixel(i, j).ToArgb() + (int)Math.Round(mu * noise_mass[i, j] * BST/BN); 
       Color c = Color.FromArgb(r); 
       newBitmap.SetPixel(i, j, c); 
      } 
     } 
     return newBitmap; 
    } 
+0

我的水平是在Delphi :) – loviji 2010-01-22 08:38:16

+3

的Delphi代碼是增加一個值,以在BGR順序的整數零。 C#代碼正在以RGB順序向整數添加一個值。這可以解釋爲什麼你沒有得到應用了類似外觀噪聲的圖像。但更重要的是,你每構建一個使用**相同種子**的新Random類。你應該將255傳遞給'Next',而不是'Random'。 – 2010-01-22 10:27:05

+0

我固定爲Random random = new Random(); noise_mass [i,j] =(byte)random.Next(0,256); – loviji 2010-01-22 10:41:34

回答

4

Delphi TColor值的低字節是紅色成分。如果你有什麼是System.Drawing.Bitmap,那麼你想要的是以下內容,它利用了Color結構,它具有紅色組件的屬性。沒有必要進行任何點播。

result = original.GetPixel(i, j).R; 
3
  • Image1.Canvas.Pixels[i, j]指定一個像素的顏色。
  • && $000000ff只保留RGB值的R(ed)。
+0

它返回值從0到255? – loviji 2010-01-22 08:39:21

+0

@loviji:結果呢。像素作爲一個整體返回一個TColor(RGB值) – 2010-01-22 08:41:53

+0

@Lieven:謝謝 – loviji 2010-01-22 08:50:05

2

像素數據在.NET空間中幾乎總是ARGB。鑑於你有一個數組,你會這麼PixelData取出:

UInt32 red = pixels[x+y*w] & 0xFFFF0000 

&執行bitwise and。第一個FF在那裏保持alpha通道不變。

+0

我會像這樣返回ARGB值。 Bitmap original = new Bitmap(pictureBox1.Image); var result = original.GetPixel(i,j).ToArgb()&0xFFFF0000; 我認爲,這是事實。 謝謝 – loviji 2010-01-22 09:23:33

2

在德爾福,它意味着得到的RED值爲TColor。 參見在Graphics unit一些顏色常量:

  • clBlack = TColor($ 000000);
  • clRed = TColor($ 0000FF);
  • clLime = TColor($ 00FF00);
  • clBlue = TColor($ FF0000);
  • clWhite = TColor($ FFFFFF);

(可以找到一個更大的列表here)。

這些顏色與Windows使用的本機ColorRef類型具有相同的值,該類型的順序爲BGR(藍色/綠色/紅色)或系統顏色(請參見下文)。 請注意,.NET使用不同的System.Drawing.Color類型:順序是RGB(紅色/綠色/藍色),根本沒有系統顏色。

您的代碼不會爲所有TColor值的工作,作爲一個TColor可以包含兩種顏色:

  • 直接RGB值
  • 這是由Windows圖形系統轉換系統顏色值到用戶定義的RGB值

爲了對所有可能的值進行映射,您必須使用ColorToRGB function in the Graphics unit(它將系統顏色轉換爲RGB值)。

對於您的特定情況,可能適用,因爲Canvas的像素不能包含系統顏色,只能包含RGB值。

但是:你不應該使用像000000FF這樣的硬編碼文字,因爲很難猜測它們的含義。

要獲得有道紅/綠/藍值,你應該在Windows單元這些功能結合ColorToRGB功能:

function GetRValue(rgb: DWORD): Byte; inline; 
function GetGValue(rgb: DWORD): Byte; inline; 
function GetBValue(rgb: DWORD): Byte; inline; 

所以你會得到這樣的函數來獲取在Delphi中的一個普遍方式紅色部分:

function GetRed(Color: TColor): Byte; 
begin 
    Result := GetRValue(ColorToRGB(Color)); 
end; 

This page對德爾福顏色使用一個很好的參考。

--jeroen