読み込んだ画像に落書きをし、PictureHUBに保存する

2011年11月28日(月)
PROJECT KySS

書き出されるXAMLコードはリスト1のようになります。

リスト1 書き出されたXAMLコード(MainPage.xaml)

(1)<InkPresenter>要素の子要素として<Image>要素を配置しています。
(2)RadioButton1~4までのGroupNameプロパティには全てmyColorと指定しています。myColorは任意の名称で構いません。
<phone:PhoneApplicationPage 
  x:Class="WP71_InkPresenter.MainPage"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
  xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
  xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
  xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="768"
  FontFamily="{StaticResource PhoneFontFamilyNormal}"
  FontSize="{StaticResource PhoneFontSizeNormal}"
  Foreground="{StaticResource PhoneForegroundBrush}"
  SupportedOrientations="Portrait" Orientation="Portrait"
  shell:SystemTray.IsVisible="True" Language="ja-JP">

  <!--LayoutRoot は、全てのページ コンテンツが配置されるルート グリッドです-->
  <Grid x:Name="LayoutRoot" Background="Transparent">
    <Grid.RowDefinitions>
      <RowDefinition Height="Auto"/>
      <RowDefinition Height="*"/>
    </Grid.RowDefinitions>
 
    <!--TitlePanel は、アプリケーション名とページ タイトルを格納します-->
    <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
      <TextBlock x:Name="ApplicationTitle" Text="らくがき" Style="{StaticResource PhoneTextNormalStyle}"/>
    </StackPanel>
 
    <!--ContentPanel - 追加コンテンツをここに入力します-->
    <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
      <InkPresenter Height="334" HorizontalAlignment="Left" Margin="28,100,0,0" Name="InkPresenter1" VerticalAlignment="Top" Width="402"> ■(1)
        <Image Canvas.Left="5" Canvas.Top="6" Height="328" Name="Image1" Stretch="Uniform" Width="391" /> ■(1)
      </InkPresenter>
      <Button Content="画像読み込み" Height="73" HorizontalAlignment="Left" Margin="28,21,0,0" Name="readImageButton" VerticalAlignment="Top" Width="402" />
      <RadioButton Content="赤" Height="75" Margin="28,453,321,0" Name="RadioButton1" VerticalAlignment="Top" Foreground="Red" GroupName="myColor" IsChecked="True" /> ■(2)
      <RadioButton Content="青" Foreground="Blue" GroupName="myColor" Height="75" Margin="141,453,208,0" Name="RadioButton2" VerticalAlignment="Top" /> ■(2)
      <RadioButton Content="緑" Foreground="Green" GroupName="myColor" Height="75" Margin="233,453,0,0" Name="RadioButton3" VerticalAlignment="Top" HorizontalAlignment="Left" Width="107" /> ■(2)
      <RadioButton Content="黄" Foreground="Yellow" GroupName="myColor" Height="75" Margin="323,453,26,0" Name="RadioButton4" VerticalAlignment="Top" /> ■(2)
      <Button Content="らくがきクリア" Height="74" HorizontalAlignment="Left" Margin="28,511,0,0" Name="clearButton" VerticalAlignment="Top" Width="402" />
      <Button Content="保存" Height="78" HorizontalAlignment="Left" Margin="28,580,0,0" Name="saveButton" VerticalAlignment="Top" Width="402" IsEnabled="False" />
    </Grid>
  </Grid>
  
  <!--ApplicationBar の使用法を示すサンプル コード-->
 ~コード略~
</phone:PhoneApplicationPage>

次に、MainPage.xamlを展開して表示される、MainPage.xaml.vbをダブルクリックしてリスト2のコードを記述します。

ロジックコードを記述する

リスト2 (MainPage.xaml.vb)

Option Strict On

ランチャーやチューザーに関するクラスの含まれる、Microsoft.Phone.Tasks名前空間をインポートします。
Imports Microsoft.Phone.Tasks

仮想ファイルシステムを作成および使用するための型が含まれている、System.IO.IsolatedStorage名前空間をインポートします。分離ストレージによって、安全なクライアント側のストレージが提供されます。
Imports System.IO.IsolatedStorage

曲、アルバム、再生リスト、およびピクチャを列挙、再生、および表示するためのクラスの含まれる、Microsoft.Xna.Framework.Media名前空間をインポートします。ピクチャへのアクセスを提供するMediaLibrayクラスを使用するため、この名前空間のインポートが必要です。
Imports Microsoft.Xna.Framework.Media

Imports System.Windows.Media.Imaging

インクの操作を行うクラスを提供する、System.Windows.Ink名前空間をインポートします。
Imports System.Windows.Ink

Partial Public Class MainPage
  Inherits PhoneApplicationPage
 
  ' コンストラクター
  Public Sub New()
    InitializeComponent()
  End Sub

単一のインクストローク(インクの一筆)を表す、Strokeクラス用メンバ変数myStrokeを宣言します。
  Dim myStroke As Stroke

[画像読み込み]ボタンがタップされた時の処理

新しいPhotoChooserTaskのインスタンス、photoTaskオブジェクトを生成します。Showメソッドで実行します。 
AddHandlerステートメントで、タスクが完了した時のCompletedイベントハンドラを追加します。Completedイベント内では、完了イベントがTaskResult.OKで、正常に完了した場合は以下の処理を行います。 
chooser での選択の結果は引数で渡されますので、SetSourceメソッドで、渡された画像を BitmapImage オブジェクトに格納します。Image1のSourceプロパティにchooserで選択した画像を格納している、BitmapImageオブジェクトを指定します。[保存]ボタンの使用を可能とします。
完了イベントが正常に完了しなかった場合は、[保存]ボタンは使用不可のままで、処理を抜けます。[画像読み込み]ボタンをタップして、PictureHUBが表示されている場合に、画像を選択しないで、戻るボタン(←)をタップした場合などです。
  Private Sub readImageButton_Click(sender As Object, e As System.Windows.RoutedEventArgs) Handles readImageButton.Click
    Dim photoTask As New PhotoChooserTask
    AddHandler photoTask.Completed, Sub(photoSender As Object, photoArgs As PhotoResult)
                                     If photoArgs.TaskResult = TaskResult.OK Then
                                       Dim bmp As New BitmapImage
                                       bmp.SetSource(photoArgs.ChosenPhoto)
                                       Image1.Source = bmp
                                       saveButton.IsEnabled = True
                                     Else
                                       saveButton.IsEnabled = False  
                                       Exit Sub
                                     End If
                                   End Sub
    photoTask.Show()
  End Sub

[らくがきクリア]ボタンがタップされた時の処理

インクのストロークをクリアします。落書きをクリアします。
  Private Sub clearButton_Click(sender As Object, e As System.Windows.RoutedEventArgs) Handles clearButton.Click
    InkPresenter1.Strokes.Clear()
  End Sub
  • 「読み込んだ画像に落書きをし、PictureHUBに保存する」サンプルプログラム

四国のSOHO。薬師寺国安(VBプログラマ)と、薬師寺聖(デザイナ、エンジニア)によるコラボレーション・ユニット。1997年6月、Dynamic HTMLとDirectAnimationの普及を目的として結成。共同開発やユニット名義での執筆活動を行う。XMLおよび.NETに関する著書や連載多数。最新刊は「Silverlight実践プログラミング」両名とも、Microsoft MVP for Development Platforms - Client App Dev (Oct 2003-Sep 2012)。http://www.PROJECTKySS.NET/

連載バックナンバー

Think ITメルマガ会員登録受付中

Think ITでは、技術情報が詰まったメールマガジン「Think IT Weekly」の配信サービスを提供しています。メルマガ会員登録を済ませれば、メルマガだけでなく、さまざまな限定特典を入手できるようになります。

Think ITメルマガ会員のサービス内容を見る

他にもこの記事が読まれています