WPFとVB.NETで表示した画像をクリックした場所の色を取得はややこしい(後編)
前回の画像をクリックした場所の色を取得の続き、終わったと思ったら終わってなかった
WPFとVB.NETで表示した画像をクリックした場所の色を取得はややこしい ( ソフトウェア ) - 午後わてんのブログ - Yahoo!ブログのつづき
http://blogs.yahoo.co.jp/gogowaten/13952774.html
画像とWindowsのDpiが違うと画像の上にあるマウスカーソルから取得できる位置は見た目の位置と違うので、画像クリックで色を取得するには一工夫
Dpi、ドットパーインチ、1インチに並んでいるピクセルの数
画像ファイルによってDpiの数値は様々
携帯やデジカメは72Dpiとか
Windowsの標準は96Dpiで表示
スキャナで取り込んだものは600Dpiとかいろいろある
WPFで作ったアプリで普通に表示するとDpiが反映されたサイズで表示される
DpiがいくつなのかJpeg画像ならファイルのプロパティで確認できる
WPFのBitmapImageに画像ファイルを渡してImageのSourceに指定すると
Dpiが考慮された表示になる
96Dpiの画像なら96/96*100=100x100ピクセルの大きさで表示される
72Dpiの画像は96/72*100=133.33333x133.33333…
600Dpiは96/600*100=16x16
そのまま表示される
Dpiが72だと少し引き伸ばされたように表示される
Dpi72、256x192ピクセルの画像を表示した時の
ImageとそのSource(画像)
引き伸ばされて341.3x256で表示されている
画像をクリックするときは表示されているものをクリックするわけだから
341x256の中のどこか1点ってことになる
でも中の画像は256x192なので変換が必要になる
クリックした場所が(x,y)のとき中の画像の位置(nx,ny)は
nx = 画像のDpi/96*x
ny = 画像のDpi/96*y
クリックした場所が100,156なら
72/96*100=75
72/96*156=117
中の画像の75,117になる
別の方法
画像を読み込むときにDpiを96に変更して表示する
これなら見た目通りの位置とサイズになるので変換の必要がなくなる
でもこのDpiを変更ってのが簡単じゃない
BitmapとDpiの数値を渡すとDpi変更したBitmapを返す
'BitmapSourceのDpi変更、対応ピクセルフォーマットはBgra32だけこれで変更できるけどもっといい方法があるはず
Private Function ChangeDpi(b As BitmapSource, Optional x As Double = 96,
Optional y As Double = 96) As CachedBitmap
Dim stride As Integer = b.PixelWidth * 4
Dim pixels(b.PixelHeight * stride - 1) As Byte
b.CopyPixels(pixels, stride, 0)
'BitmapSource.Createから作成したBitmapはCachedBitmapになるみたい
Dim cb As CachedBitmap = BitmapSource.Create(
b.PixelWidth, b.PixelHeight, x, y, PixelFormats.Bgra32, Nothing, pixels, stride)
Return cb
End Function
渡されたBitmapをCopyPixelsメソッドでByte配列にバラバラにして
それを元に新たにBitmapSourceを作って返しているだけ
BitmapSourceのCreateでDpiを指定できるのでそれを利用している
ChangeDpiはBgra32しか対応していないので
読み込んだ画像をBgra32に変換しておく必要がある
これはFormatConvertedBitmapっていう便利なのがあるので
FormatConvertedBitmap(BitmapSource, PixelFormats.Bgra32, Nothing, 0)
これで変換できる
上が座標変換で
下がDpi変換
WPFとVB.NETで画像の中の特定の色を透明にする ( ソフトウェア ) - 午後わてんのブログ - Yahoo!ブログ
https://blogs.yahoo.co.jp/gogowaten/13957183.html
https://blogs.yahoo.co.jp/gogowaten/13957183.html
関連記事
2018年
WPF、dpiの変更とUseLayoutRoundingを指定して画像をくっきり表示 ( ソフトウェア ) - 午後わてんのブログ - Yahoo!ブログ
https://blogs.yahoo.co.jp/gogowaten/15316739.html
https://blogs.yahoo.co.jp/gogowaten/15316739.html