Quantcast
Viewing all articles
Browse latest Browse all 35736

写真をぼかす 改め加工する Part 5 レイヤー合成

#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 フォルダにコピーしておきましょう。

Image may be NSFW.
Clik here to view.
image
Image may be NSFW.
Clik here to view.
image

XAML

さて、UI を作ります。こんなUIになります。

Image may be NSFW.
Clik here to view.
image

<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:ApplicationBarIconButton 
        IconUri="/Images/appbar.folder.rest.png" Text="画像"
        x:Name="btnOpenPict" Click="btnOpenPict_Click" />
    <shell:ApplicationBarIconButton 
        IconUri="/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";
    //処理時間表示
}

さて、実行してみます。 元の画像にマスク画像を乗算した結果です。マスク画像を変えると別の効果も楽しめます。

Image may be NSFW.
Clik here to view.
image
Image may be NSFW.
Clik here to view.
image

処理時間も0.1秒かからないのでかなりいいですね。あとは、このフィルタの処理部分を変えていけばいろいろ出来そうです。

関連リンク

Image may be NSFW.
Clik here to view.

Viewing all articles
Browse latest Browse all 35736

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>