Каков наилучший способ проверки только непрозрачных пикселей на изображениях в Silverlight? - PullRequest
2 голосов
/ 20 октября 2010

В соответствии с msdn в Silverlight изображения подвергаются тестированию на удар по областям отображения изображений / мультимедиа, в основном по их высоте и ширине.Прозрачные / полные альфа-пиксели в файле изображения по-прежнему проверяются на удар.Теперь у меня вопрос: как лучше всего проверить непрозрачные пиксельные совпадения на изображениях в Silverlight?

1 Ответ

1 голос
/ 20 октября 2010

Это невозможно сделать при использовании возможности обычного тестирования на попадание, как вы узнали из справочника MSDN.

Единственная идея, которая у меня возникла, заключалась в том, чтобы преобразовать ваше изображение в класс WritableBitmap и использовать свойство Pixels для тестирования совпадений по альфа-каналу. Я на самом деле не пробовал это, и я не могу себе представить, что это тривиально, но это должно сработать в теории.

Пиксели - это одно большое целое [] с 4 байтами каждого целого числа, соответствующего ARGB. Он использует предварительно умноженный формат ARGB32, поэтому, если есть какая-либо альфа-прозрачность, кроме полных 255, другие значения RGB масштабируются соответственно. Я предполагаю, что вы хотите, чтобы что-либо НЕ полная альфа считалось "хитом", поэтому вы можете просто проверить по альфа-байту, чтобы узнать, 255 ли это

Вы получите доступ к пикселю строки / столбца, который хотите проверить, по индексу массива, например так:

int pixel = myBitmap.Pixels[row * myBitmap.PixelWidth + col];

Проверьте этот пост , чтобы узнать больше идей.

EDIT:

Я собрал быстрый тест, он работает, и это довольно просто:

public MainPage()
{
    InitializeComponent();

    this.image = new BitmapImage(new Uri("my_tranny_image.png", UriKind.Relative));
    this.MyImage.Source = image;

    this.LayoutRoot.MouseMove += (sender, e) =>
    {
        bool isHit = ImageHitTest(image, e.GetPosition(this.MyImage));
        this.Result.Text = string.Format("Hit Test Result: {0}", isHit);
    };
}

bool ImageHitTest(BitmapSource image, Point point)
{
    var writableBitmap = new WriteableBitmap(image);

    // check bounds
    if (point.X < 0.0 || point.X > writableBitmap.PixelWidth - 1 ||
        point.Y < 0.0 || point.Y > writableBitmap.PixelHeight - 1)
        return false;

    int row = (int)Math.Floor(point.Y);
    int col = (int)Math.Floor(point.X);

    int pixel = writableBitmap.Pixels[row * writableBitmap.PixelWidth + col];
    byte[] pixelBytes = BitConverter.GetBytes(pixel);

    if (pixelBytes[0] != 0x00)
        return true;
    else
        return false;
}

Возможно, вы захотите провести некоторые оптимизации, например не создавать WritableBitmap для каждого события MouseMove, но это всего лишь подтверждение концепции, показывающей, что оно работает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...