from delphi to C# Image1.Canvas.Pixels
In delphi written code:
result = (Image1.Canvas.Pixels[i, j] and $000000ff);
what it is mean? And if possible, please, say how can i do same operation in C#?
Edited: I don't know where problem: I use same algorithm, but result is not equivalent or same .i think i don't understand delphi code true!
Delphi code:
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# code:
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++)
{
开发者_StackOverflow中文版 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;
}
The lower byte of a Delphi TColor value is the red component. If what you have is a System.Drawing.Bitmap, then what you want is the following, which takes advantage of the Color structure having a property for the red component. No need for any bit-twiddling.
result = original.GetPixel(i, j).R;
Image1.Canvas.Pixels[i, j]
specifies the color of one pixel.&& $000000ff
only retains the R(ed) from the RGB value.
Pixel data is almost always ARGB in the .NET space. Given you have such pixeldata in an array you could:
UInt32 red = pixels[x+y*w] & 0xFFFF0000
& performs a bitwise and. The first FF is there to keep the alpha channel untouched.
In Delphi, it is meant to get the RED value of a TColor. See some the color constants in the Graphics unit:
- clBlack = TColor($000000);
- clRed = TColor($0000FF);
- clLime = TColor($00FF00);
- clBlue = TColor($FF0000);
- clWhite = TColor($FFFFFF);
(A larger list can be found here).
These colors are the same value as the native ColorRef type used by Windows which has the order in BGR (blue/green/red), or a system color (see below). Note that .NET uses a different System.Drawing.Color type: the order is RGB (red/green/blue) and no system colors at all.
Your code won't work for all TColor values, as a TColor can contain two kinds of colors:
- a direct RGB value
- a system color value which are converted by the Windows graphics system to a user defined RGB value
In order to do the mapping for all possible values you have to use the ColorToRGB function in the Graphics unit (it converts system colors to propery RGB values).
For your particular case, it probably works because the pixels of a Canvas cannot contain system colors, only RGB values.
But: you should not use hard coded literals like $000000FF, because it is hard to guess their meaning.
To get the Red/Green/Blue values in a proper way, you should combine the ColorToRGB function with these functions in the Windows unit:
function GetRValue(rgb: DWORD): Byte; inline;
function GetGValue(rgb: DWORD): Byte; inline;
function GetBValue(rgb: DWORD): Byte; inline;
So you would get a function like this to get the Red portion in a universal way in Delphi:
function GetRed(Color: TColor): Byte;
begin
Result := GetRValue(ColorToRGB(Color));
end;
This page has a good reference on color usage in Delphi.
--jeroen
精彩评论