C # - сделать черный пиксель изображения прозрачным - PullRequest
0 голосов
/ 06 октября 2018

У меня большая проблема.

У меня есть код для сравнения 2 пикселей изображения.Это ищет первые пиксели изображения в пределах второго пикселя изображения.

 private bool FindBitmap12(Bitmap bmpNeedle, Bitmap bmpHaystack, out Point location)
    {
        if (bmpNeedle == null || bmpHaystack == null)
        {
            location = new Point();
            return false;
        }
        for (int outerX = 0; outerX < bmpHaystack.Width - bmpNeedle.Width; outerX++)
        {
            for (int outerY = 0; outerY < bmpHaystack.Height - bmpNeedle.Height; outerY++)
            {
                for (int innerX = 0; innerX < bmpNeedle.Width; innerX++)
                {
                    for (int innerY = 0; innerY < bmpNeedle.Height; innerY++)
                    {
                        Color cNeedle = bmpNeedle.GetPixel(innerX, innerY);
                        Color cHaystack = bmpHaystack.GetPixel(innerX + outerX, innerY + outerY);
                        if (cNeedle.R != cHaystack.R || cNeedle.G != cHaystack.G || cNeedle.B != cHaystack.B)
                        {
                            goto notFound;
                        }
                    }
                }
                location = new Point(outerX, outerY);
                return true;
            notFound:
                continue;
            }
        }
        location = Point.Empty;
        return false;
    }

Код выше работает отлично.

Проблема в том, что теперь мне нужно сравнить изображение с черными пикселями наэто изображение, которое не имеет черных пикселей.Так что получается, что приведенный выше код возвращает то, что картинки разные.

Итак, я подумал: эй, давайте сделаем эти черные пиксели прозрачными!

Я сделал этот код:

Rectangle mouseNewRect = new Rectangle(new Point(x - 125, y - 125), new Size(250, 250));
Bitmap myBitmap2 = new Bitmap(mouseNewRect.Width, mouseNewRect.Height);
Bitmap myBitmap3 = new Bitmap("Images\\xd1.png");
myBitmap3.MakeTransparent(Color.Black);
Graphics g = Graphics.FromImage(myBitmap2);
g.CopyFromScreen(mouseNewRect.Left, mouseNewRect.Top, 0, 0, myBitmap2.Size, CopyPixelOperation.SourceCopy);

myBitmap2 == большая картинка;

myBitmap3 == картинка с черными пикселями, которые будут сравниваться в myBitmap2.

Итак, как вы видите, я создал черные пиксели myBitmap3прозрачный, поэтому, когда myBitmap3 сравнивается с myBitmap2, результат должен быть следующим: эй, мы нашли пиксели myBitmap3 внутри myBitmap2!

Я не знаю, почему, но даже делая черные пиксели прозрачными, результат:

bool sucess2 = FindBitmap12(myBitmap3, myBitmap2, out location);

== false.Поэтому я делаю черные пиксели прозрачными, но почему-то sucess2 == false.

Я пытался удалить черные пиксели на https://pixlr.com,, оставляя «пустое» пространство в этих черных пикселях, но также и результатsucess2 == false.

Некоторые1 имеют представление о том, как удалить эти черные пиксели myBitmap3?

Спасибо.

РЕДАКТИРОВАТЬ: в этой части:

Color cNeedle = bmpNeedle.GetPixel(innerX, innerY);
Color cHaystack = bmpHaystack.GetPixel(innerX + outerX, innerY + outerY);
if (cNeedle.R != cHaystack.R || cNeedle.G != cHaystack.G || cNeedle.B != cHaystack.B)
                        {
                            goto notFound;
                        }

Может быть, я могу сделать "Если", что если найду черный пиксель, проигнорирую его и продолжу поиск, так как этот черный пиксель не существует?

1 Ответ

0 голосов
/ 06 октября 2018

Не углубляясь в API Я предполагаю, что метод MakeTransparent не изменяет значения RGB пикселя.Это просто устанавливает где-то в палитре и информации, что этот конкретный цвет не должен быть нарисован на экране.Вот почему, когда вы сравниваете значения RGB, они все те же.

Я не проверял и не проверял свой ответ, но я бы предположил, что некоторое время работал с изображениями.

ЕслиЯ прав, самый простой подход - сравнивать пиксель, только если он не помечен как прозрачный цвет в палитре.

ОБНОВЛЕНИЕ

Там неткажется, простой способ проверки системной палитры.См. https://docs.microsoft.com/en-us/windows/desktop/gdi/system-palette

Вместо этого: не могли бы вы попытаться сравнить альфа-компонент пикселя?Если вы установили альфа-значение пикселя (через pixlr / gimp / photoshop) прозрачным, оно должно иметь значение 0. Таким образом, ваш код будет:

Color cNeedle = bmpNeedle.GetPixel(innerX, innerY);
Color cHaystack = bmpHaystack.GetPixel(innerX + outerX, innerY + outerY);

bool isDifferentRGB = cNeedle.R != cHaystack.R || cNeedle.G != cHaystack.G || cNeedle.B != cHaystack.B;
bool isTransparent = cNeedle.A == 0;

if (isDifferentRGB && !isTransparent)
{
     goto notFound;
}
...