#wp7dev_jp
さて、これまで写真をぼかすことをやってきましたが、今回から別のネタで進めてみます。
今回からトライするのは、レイヤー機能です。Photoshop に搭載しているフォトレタッチの重要な機能で、1つの画像に2つ目の画面をいろいろな効果を付けて合成します。
今回は、まず乗算を実装してみます。
ファイルの追加
プロジェクトに、「Images:フォルダを追加して、そこに以下のファイルをコピーします。
- フォルダ: C:\Program Files (x86)\Microsoft SDKs\Windows Phone\v7.1\Icons\dark
- ファイル1:appbar.folder.rest.png
- ファイル2:appbar.favs.rest.png
コピーしたらファイルのプロパティを以下のように設定。
- ビルドアクション: コンテンツ
- 出力ディレクトリにコピー:新しい場合はコピーする
それから480X480の元画像とマスク用画像を用意しておきます(Source.jpg, Mask.png)
こちらも、Images フォルダにコピーしておきましょう。
XAML
さて、UI を作ります。こんなUIになります。
<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="Photo Effect Sample "Style="{StaticResource PhoneTextNormalStyle}"FontFamily="Segoe WP Bold" /><TextBlock x:Name="PageTitle" Text="Layer Effect"Margin="9,-7,0,0"Style="{StaticResource PhoneTextTitle1Style}"FontFamily="Segoe WP Light" /></StackPanel><!--ContentPanel - 追加コンテンツをここに入力します-->
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0"Height="480"><Image Name="sourceimg2" Stretch="UniformToFill" Height="480"Source="/Layer;component/Images/Mask.png" /><Image Name="sourceimg1" Stretch="UniformToFill" Height="480"Source="/Layer;component/Images/Source.jpg"/><Image Name="resultimg" Stretch="UniformToFill" Height="480" /></Grid></Grid><!--ApplicationBar の使用法を示すサンプル コード-->
<phone:PhoneApplicationPage.ApplicationBar><shell:ApplicationBar IsVisible="True" IsMenuEnabled="True"><shell:ApplicationBarIconButtonIconUri="/Images/appbar.folder.rest.png" Text="画像"x:Name="btnOpenPict" Click="btnOpenPict_Click" /><shell:ApplicationBarIconButtonIconUri="/Images/appbar.favs.rest.png" Text="エフェクト"x:Name="btnEffect" Click="btnEffect_Click" /></shell:ApplicationBar></phone:PhoneApplicationPage.ApplicationBar>
C#
さて、コード側です。といってもぼかし処理と変わりません。
乗算はその名の通り、ピクセル同士の掛け算をします。
式は 結果=元画像xマスク画像 / 255 これを各ポイントのRGBそれぞれに配置します。
元画像に対してマスク画像を掛け算して、結果としてちょっと暗くなります。
private void btnOpenPict_Click(object sender, EventArgs e){PhotoChooserTask task = new PhotoChooserTask();
task.Completed += new EventHandler<PhotoResult>(task_Completed);
task.Show();}void task_Completed(object sender, PhotoResult e){if (e.TaskResult == TaskResult.OK)
{BitmapImage bmp = new BitmapImage();
bmp.SetSource(e.ChosenPhoto);sourceimg1.Source = bmp;}}private void btnEffect_Click(object sender, EventArgs e){WriteableBitmap sourcewp1 = new WriteableBitmap(sourceimg1, null); //元画像用WriteableBitmap sourcewp2 = new WriteableBitmap(sourceimg2, null); //元画像用int wpw = sourcewp1.PixelWidth;
int wph = sourcewp2.PixelHeight;
WriteableBitmap finalwp = new WriteableBitmap(wpw, wph); //最終結果保存用//デバッグ用:時間計開始時間設定
DateTime start = DateTime.Now;for (int pixel = 0; pixel < sourcewp1.Pixels.Length; pixel++){uint color1 = (uint)sourcewp1.Pixels[pixel];uint color2 = (uint)sourcewp2.Pixels[pixel];uint A1 = (color1 >> 24);
uint R1 = ((color1 >> 16) & 0xFF);
uint G1 = ((color1 >> 8) & 0xFF);
uint B1 = ((color1) & 0xFF);
uint A2 = (color2 >> 24);
uint R2 = ((color2 >> 16) & 0xFF);
uint G2 = ((color2 >> 8) & 0xFF);
uint B2 = ((color2) & 0xFF);
uint A = A1;
uint R = 0;
uint G = 0;
uint B = 0;
// 乗算
R = R1 * R2 / 255;G = G1 * G2 / 255;B = B1 * B2 / 255;finalwp.Pixels[pixel] =((int)A << 24) | ((int)R << 16) | ((int)G << 8) | (int)B;}//作成された画像を元画像として表示
resultimg.Source = finalwp;ApplicationTitle.Text = "Photo Effect Sample : " +
(DateTime.Now - start).TotalSeconds.ToString() + " sec";
//処理時間表示
}
さて、実行してみます。 元の画像にマスク画像を乗算した結果です。マスク画像を変えると別の効果も楽しめます。
処理時間も0.1秒かからないのでかなりいいですね。あとは、このフィルタの処理部分を変えていけばいろいろ出来そうです。
関連リンク
- 写真を加工する Part5.1 オーバーレイ
- 写真をぼかす 改め加工する Part 5 レイヤー合成
- 写真をぼかす Part.4.1 マスク画像を使わずに周辺だけをぼかす。
- 写真をぼかす Part.4 マスクを使って周辺だけをぼかす。
- 写真をぼかす Part 3.1 いったん整理
- 写真にぼかしを Part 3 ガウスぼかし
- 写真にぼかしを Part2
- 写真にぼかしを
- 写真をセピアに