ブログ用 画像ユーティリティ ⑤ ユーザーコントロール

Published 09 March 09 11:11 AM | hiroyuk 

以下のようにXAMLで記述できるユーザーコントロール VgaImageUC を作成します。

<local:VgaImageUC x:Name="myVgaImage" Grid.Row="1" 
    MouseLeftButtonDown
="UC_MouseLeftButtonDown" 
    MouseMove
="UC_MouseMove" />

このユーザーコントロールの役割は①要件と戦略で説明したように、以下の4つです。

  1. Vgaサイズ画像の作成と表示
  2. モザイク画像の作成と、クリップ表示
  3. 上記2つの画像の合成画像の作成
  4. jpgにエンコードして出力

ユーザーコントロールは UserContrl クラスを継承した具象クラスです(これに対し、カスタムコントロールはControlを継承した具象クラス)。Visual Studio のソリューションエクスプローラーで追加→新しい項目から、以下のダイアログで[ユーザーコントロール(WPF)]を選ぶと、XAMLとコードビハインドのテンプレートを生成してくれます。

image

2つの画像を表示するXAMLを記述します。Mosaique画像はVisibilutyをHiddenにして、ぼかしをかけないRenderOptionであるNearestNeighborにします。

<UserControl x:Class="ImageShrinker.VgaImageUC"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
>
<Border  Name="myPlaceholder" Width="640" Height="480">
  <Canvas Name="myCanvas">
   <Image Canvas.Left="0" Canvas.Top="0" Name="myImage" />
   <Image Canvas.Left="0" Canvas.Top="0" Name="myMosaique"
    Visibility
="Hidden"
    RenderOptions.BitmapScalingMode
="NearestNeighbor" />
  </Canvas>
</Border>
</UserControl>

VgaImageUCユーザーコントロールでは、ファイル名(FileName)とクリップ矩形(ClipRect)が変更されたら、自動的に画像を表示させたいので、この2つのプロパティをDependencyPropertyとして定義します。

public string FileName
{
  get { return (string)GetValue(FileNameProperty); }
  set { SetValue(FileNameProperty, value); }
}

public static DependencyProperty FileNameProperty =
  DependencyProperty.Register("FileName", typeof(string),
 
typeof(VgaImageUC), new FrameworkPropertyMetadata
   
new PropertyChangedCallback(OnFileNameChanged)));

/// <summary>
/// プロパティ変更のコールバック
/// </summary>
private static void OnFileNameChanged(
  DependencyObject obj,
  DependencyPropertyChangedEventArgs args)
{
  VgaImageUC control = (VgaImageUC)obj;
  control.UpdateImage();
}

private readonly int _vgaWidth = 640;
private readonly int _scale = 20;
/// <summary>
/// 画像の更新
/// </summary>
private void UpdateImage()
{
 
BitmapImage bi =
    CreateSmallImage(_vgaWidth, this.FileName);
  myImage.Source = bi;
  myImage.Width = bi.PixelWidth;
  myImage.Height = bi.PixelHeight;

  myMosaique.Source =
CreateSmallImage(_vgaWidth / _scale, this.FileName);
myMosaique.Width = bi.PixelWidth;
myMosaique.Height = bi.PixelHeight;

  myPlaceholder.Width = bi.PixelWidth;
  myPlaceholder.Height = bi.PixelHeight;
}

 

public Rect ClipRect
{
 
get { return (Rect)GetValue(ClipRectProperty); }
  set { SetValue(ClipRectProperty, value); }
}

public static DependencyProperty ClipRectProperty =
  DependencyProperty.Register("ClipRect", typeof(Rect),
    typeof(VgaImageUC), new FrameworkPropertyMetadata( 
     
new PropertyChangedCallback(OnClipRectChanged)));

/// <summary>
/// プロパティ変更のコールバック
/// </summary>
private static void OnClipRectChanged(
  DependencyObject obj,
  DependencyPropertyChangedEventArgs args)
{
  VgaImageUC control = (VgaImageUC)obj;
  control.UpdateRect();
}

/// <summary>
/// モザイククリップ矩形の更新
/// </summary>
private void UpdateRect()
{
 
myMosaique.Clip = new RectangleGeometry(this.ClipRect);
  myMosaique.Visibility = Visibility.Visible;
}

また、ファイル名を引数として受け取るコンストラクタも追加します。App.xaml.csから呼び出すときにこれを使います。

public VgaImageUC(string filename)
{
 
InitializeComponent();
  this.FileName = filename;
}

Comments

No Comments
Anonymous comments are disabled

About hiroyuk

マイクロソフト㈱エバンジェリスト。北海道大学理学部物理学科卒。リアルタイム3Dグラフィックスを専門とし、グラフィックスやシェーダに関する技術文章を執筆・講演。 DirectX SDK日本語ドキュメントの開発に携わるとともに、Windows Presentation Foundation プログラミング(オーム社)、Game Programming Gemsシリーズ、リアルタイム レンダリング第2版(ボーンデジタル)、Texturing & Modeling, A Procedural Approach などを翻訳・監修、XAMLプログラミング(ソフトバンク クリエイティブ)を執筆。趣味は薪割り。

Search

This Blog

DirectX 情報

Silverlight 情報

Windows 情報

WPF 情報

並列コンピューティング情報

著書

Syndication

Page view tracker