В соответствии с msdn в Silverlight изображения можно тестировать по их областям отображения изображения / мультимедиа, в основном по их высоте и ширине. Прозрачные / полные альфа-пиксели в файле изображения по-прежнему можно проверить. Теперь мой вопрос: как лучше всего проверить попадание только непрозрачных пикселей в изображения в Silverlight?
Каков наилучший способ проверки только непрозрачных пикселей на изображениях в Silverlight?
Ответы (1)
Это невозможно при использовании обычной возможности проверки попаданий, как вы узнали из ссылки MSDN.
Единственная идея, которая у меня была, заключалась в том, чтобы преобразовать ваш образ в WritableBitmap и используйте класс Pixels для тестирования попадания в альфа-канал. Я на самом деле не пробовал это, и я не могу представить, что это тривиально, но в теории это должно работать.
Пиксели представляют собой один большой int[] с 4 байтами каждого целого числа, соответствующего ARGB. Он использует предварительно умноженный формат ARGB32, поэтому, если есть какая-либо альфа-прозрачность, кроме полных 255, другие значения RGB масштабируются соответствующим образом. Я предполагаю, что вы хотите, чтобы все НЕ полная альфа-версия считалась "попаданием", чтобы вы могли просто проверить альфа-байт, чтобы увидеть, равен ли он 255.
Вы можете получить доступ к пикселю строки/столбца, который вы хотите проверить, по индексу массива следующим образом:
int pixel = myBitmap.Pixels[row * myBitmap.PixelWidth + col];
Ознакомьтесь с этим сообщением еще несколько идей.
ИЗМЕНИТЬ:
Я собрал быстрый тест, он работает и довольно прост:
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, но это всего лишь доказательство концепции, показывающее, что это работает.