理由
InkCanvas.Background
(画像) に設定する ImageBrush
の Width
, Height
は画像のピクセル数ではなく
画像のピクセル数 * (96F / 画像の水平方向dpi or 垂直方向 dpi)
で計算されるから。これは WPF 自体の仕様。
なので、dpi の値が
- 96f 超ならば背景画像の 幅or高さは小さくなる
- 96f 未満ならば背景画像の 幅or高さは大きくなる
確認した現象
解像度 640x480
だが dpi が異なる 2 枚の画像を用意する。
各々を InkCanvas
へコードビハインドにて背景設定した場合
- 96dpi 画像の場合は InkCanvas 上で縮小されない
- 300dpi 画像の場合は InkCanvas 上で縮小される
96dpi | 300dpi |
---|---|
![]() |
![]() |
再現手順
- VisualStudio 2019
- .NET 4.7.2
(VisualStudio 2012, .NET 4.0 でも再現する)
後出サンプルソースの通り、 InkCanvas.Background
の背景画像は次の流れで設定する。
-
FileStream
で読み込みしたものを、BitmapImage
へ設定 -
ImageBrush
に上記BitmapImage
を設定する-
Stretch.None
で拡大縮小はさせない
-
-
InkCanvas.Background
に上記ImageBrush
を設定する
xaml
<Window x:Class="DpiTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:DpiTest"
mc:Ignorable="d"
WindowStyle="None"
Width="800"
Height="600" >
<Grid Background="LightGray">
<InkCanvas
Name="MainCanvas"
Width="640"
Height="480" />
</Grid>
</Window>
xaml.cs
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.IO;
namespace DpiTest
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.InitializeImage();
}
private void InitializeImage()
{
var bitmapImage = new BitmapImage();
using (var fileStream = new FileStream(@"C:\path\to\image.jpg", FileMode.Open, FileAccess.Read))
{
bitmapImage.BeginInit();
bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
bitmapImage.StreamSource = fileStream;
bitmapImage.EndInit();
}
bitmapImage.Freeze();
var imageBrush = new ImageBrush();
imageBrush.Stretch = Stretch.None;
imageBrush.ImageSource = bitmapImage;
this.MainCanvas.Background = imageBrush;
}
}
}
理由を把握する為に確認・参考したもの
-
ImageSource の親 > BitmapSource.Width
- 原寸のピクセルデータではなく、
GetHeightInternal()
を取得していることを確認できる
- 原寸のピクセルデータではなく、
-
原寸 pixel を変換する処理 その1
- dpi と ピクセルデータを基に、変換処理を実行していることが分かる
-
原寸 pixel を変換する処理 その2
- 変換処理の内容。解説するよりも内容を見てもらったほうが良い