msdn in Silverlight によると、画像は画像/メディア表示領域 (基本的には高さと幅) でテスト可能です。画像ファイル内の透過/フル アルファ ピクセルは引き続きヒット テスト可能です。私の質問は、Silverlight の画像で不透明なピクセル ヒットのみをテスト可能にする最善の方法は何ですか?
1 に答える
MSDN リファレンスでわかったように、これは通常のヒット テスト機能を使用して行うことはできません。
私が思いついた唯一のアイデアは、画像をWritableBitmapクラスに変換し、 Pixelsプロパティを使用してアルファ チャネル ヒット テストを行うことでした。私は実際にこれを試したことがなく、簡単なことだとは想像できませんが、理論的にはうまくいくはずです。
ピクセルは、ARGB に対応する各整数の 4 バイトを持つ 1 つの大きな int[] です。あらかじめ乗算された 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;
}
すべての MouseMove イベントで WritableBitmap を作成しないなどの最適化を行いたいと思うかもしれませんが、これは機能することを示す概念実証にすぎません。