tags:

views:

230

answers:

4

Hello. 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++)
            {
                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;
    }
+3  A: 
  • Image1.Canvas.Pixels[i, j] specifies the color of one pixel.
  • && $000000ff only retains the R(ed) from the RGB value.
Lieven
it returns value from 0 to 255?
loviji
@loviji: result does. Pixels as a whole returns a TColor (RGB value)
Lieven
@Lieven: thanks
loviji
Lieven
Lieven, the order in TColor is the same as the order in Windows's native ColorRef type. http://msdn.microsoft.com/en-us/library/dd183449.aspx Lovij's code gives the same result as calling the API's GetRValue function.
Rob Kennedy
Rob, thank you for the link. Would you also know the rationale why Windows' ColorRef type's hexadecimal form is BGR?
Lieven
Not off-hand, no. Seems like a good question to ask on Stack Overflow, though. ;)
Rob Kennedy
lol. Maybe tomorrow... but it **is** a major pita.
Lieven
+2  A: 

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.

Jonas Elfström
i return ARGB value like this.Bitmap original=new Bitmap(pictureBox1.Image); var result=original.GetPixel(i, j).ToArgb() I think, it is true.thanks
loviji
+4  A: 

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;
Rob Kennedy
+2  A: 

In Delphi, it is meant to get the RED value of a TColor. See some the color constants in the Graphics unit:

(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

Jeroen Pluimers