根据 Silverlight 中的 msdn,图像可以在其图像/媒体显示区域(基本上是其高度和宽度)上进行命中测试。图像文件中的透明/完整 Alpha 像素仍然可以命中测试。我现在的问题是,在 Silverlight 中的图像中只有非透明像素命中可测试的最佳方法是什么?
问问题
528 次
1 回答
1
正如您在 MSDN 参考中发现的那样,使用正常的命中测试功能将无法做到这一点。
我唯一的想法是将您的图像转换为WritableBitmap类并使用Pixels属性进行 alpha 通道命中测试。我实际上并没有尝试过这个,我无法想象它是微不足道的,但它应该在理论上有效。
像素是一个大的 int[],每个整数的 4 个字节对应于 ARGB。它使用预乘的 ARGB32 格式,因此如果除了完整的 255 之外还有任何 alpha 透明度,其他 RGB 值也会相应地缩放。我假设您希望任何不是完整的 alpha 都被视为“命中”,因此您可以检查 alpha 字节以查看它是否为 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;
}
您可能希望进行一些优化,例如不在每个 MouseMove 事件上创建 WritableBitmap,但这只是证明它有效的概念证明。
于 2010-10-20T15:32:29.530 回答