от delphi до C # Image1.Canvas.Pixels

2

В Delphi написанный код:

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

что это значит? И если возможно, пожалуйста, скажите, как я могу сделать такую ​​же операцию в С#?

Отредактировано: Я не знаю, где проблема: я использую тот же алгоритм, но результат не эквивалентен или тот же .i думаю, что я не понимаю код delphi true!

Код 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;

Код С#:

    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 :)
  • 3
    Код Delphi добавляет значение к целому числу в порядке BGR. Код C # добавляет значение к целому числу в порядке RGB. Это может объяснить, почему вы не получаете изображения с похожим на них шумом. Что еще более важно, вы создаете новый класс Random с использованием одного и того же начального числа каждый раз. Вы должны перейти 255 к Next , а не к Random .
Показать ещё 1 комментарий
Теги:

4 ответа

4
Лучший ответ

Нижний байт Значение Delphi TColor - это красный компонент. Если у вас есть System.Drawing.Bitmap, то то, что вы хотите, это следующее, которое использует Color, обладающая свойством для красной компоненты. Нет необходимости в каких-либо бит-трюках.

result = original.GetPixel(i, j).R;
3
  • Image1.Canvas.Pixels[i, j] указывает цвет одного пикселя.
  • && $000000ff сохраняет только R (ed) из значения RGB.
  • 0
    это возвращает значение от 0 до 255?
  • 0
    @loviji: результат есть. Пиксели в целом возвращают TColor (значение RGB)
Показать ещё 5 комментариев
2

В Delphi он предназначен для получения значения RED TColor. См. Некоторые цветовые константы в Графический блок:

(Более крупный список можно найти здесь).

Эти цвета имеют то же значение, что и родной ColorRef тип, используемый Windows, который имеет порядок в BGR (синий/зеленый/красный), или цвет системы (см. ниже). Обратите внимание, что .NET использует другой тип System.Drawing.Color: порядок - RGB (красный/зеленый/синий) и никаких системных цветов вообще.

Ваш код не будет работать для всех значений TColor, поскольку TColor может содержать два типа цветов:

  • прямое значение RGB
  • значение цвета системы, которое преобразуется графической системой Windows в значение RGB, определенное пользователем

Чтобы сделать сопоставление для всех возможных значений, вы должны использовать функцию ColorToRGB в графическом модуле (она преобразует системные цвета в правильные значения RGB).

В вашем конкретном случае это, вероятно, работает, потому что пиксели Canvas не могут содержать системные цвета, а только значения RGB.

Но: вы не должны использовать жестко закодированные литералы, такие как $000000FF, потому что трудно угадать их смысл.

Чтобы получить правильные значения красного/зеленого/синего, вы должны комбинировать функцию ColorToRGB с этими функциями в блоке Windows:

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;

Эта страница имеет хорошую ссылку на использование цвета в Delphi.

- Йерун

2

Пиксельные данные почти всегда ARGB в пространстве .NET. Учитывая, что у вас есть такие пиксельные координаты в массиве, вы могли:

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

& выполняет побитовое и. Первый FF должен содержать альфа-канал без изменений.

  • 0
    я возвращаю значение ARGB вот так. Bitmap original = new Bitmap (pictureBox1.Image); var result = original.GetPixel (i, j) .ToArgb () & 0xFFFF0000; Я думаю, это правда. Спасибо

Ещё вопросы

Сообщество Overcoder
Наверх
Меню