誰得かわからないけど書く。ちょうど画像処理関係をいじっていることもあって、簡単に実装可能な「セピア調変換 - 酢ろぐ!」をネイティブ(C++/Cx)で書いて、マネージ(C#)で画像の読み込みとImageコントロールへの設定を実装してみようかと思います。
-アプリ側はC#で実装 -C++/Cxでライブラリを作成 -アプリ側からbyte配列でピクセルデータを渡して、ネイティブでセピア調の処理をさせる -ネイティブからアプリに画像を渡して、Imageコントロールで表示
**プロジェクトの作成
C#でメトロアプリを作成します。アプリの実装はひとまずおいて、ネイティブの画像処理のコードを書きます。
**ネイティブ側の実装
ソリューションエクスプローラーを右クリックして、新しいプロジェクトを追加する。「Windows Runtime Component」を探そう。
NativeTestClass.hでメソッドを定義する。
|cpp|
pragma once
namespace WindowsRuntimeComponent1
{
public ref class NativeTestClass sealed
{
public:
NativeTestClass();
void sepia(int width, int height, const Platform::Array
NativeTestClass.cppでメソッドを実装する。
|cpp| // Class1.cpp
include "pch.h"
include "NativeTestClass.h"
using namespace WindowsRuntimeComponent1; using namespace Platform;
NativeTestClass::NativeTestClass() { }
void NativeTestClass::sepia(int width, int height, const Platform::Array
uint8 b = srcBytes[index + 0];
uint8 g = srcBytes[index + 1];
uint8 r = srcBytes[index + 2];
uint8 a = srcBytes[index + 3];
// 単純平均法で輝度を求める
double y = (double)(r + g + b) / 3;
// 輝度に対して指定の比率を掛けてセピア調に変換する
uint8 db = y * 0.4;
uint8 dg = y * 0.7;
uint8 dr = y;
dstBytes[index + 0] = db;
dstBytes[index + 1] = dg;
dstBytes[index + 2] = dr;
dstBytes[index + 3] = a;
}
} ||<
**アプリ側の実装
画像処理のためにStorageFileとWriteableBitmapを使いやすくするライブラリをMITライセンスで公開しています。
以下のサンプルコードで標準APIにないメソッドがあれったら、俺俺ライブラリを使っていると思ってください。画面は超簡単に、ButtonコントロールとImageコントロールが並んでいるだけ。
|xml|
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
<Button Content="Button" HorizontalAlignment="Left" Margin="53,57,0,0" VerticalAlignment="Top" Height="174" Width="325" Click="Button_Click_1"/>
<Image x:Name="effectImage" HorizontalAlignment="Left" Height="560" Margin="432,57,0,0" VerticalAlignment="Top" Width="859"/>
</Grid>
||<
ボタンを押したら処理開始です。
|cs| using System; using System.Runtime.InteropServices.WindowsRuntime; using Softbuild.Media; using Windows.Storage; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; using WindowsRuntimeComponent1;
namespace NativeCodeSample
{
///
private async void Button_Click_1(object sender, RoutedEventArgs e)
{
// 俺俺ライブラリを使って、WriteableBitmapオブジェクトを生成する
var file = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///Assets/Logo.png"));
var bitmap = await WriteableBitmapExtensions.FromStreamAsync(await file.OpenReadAsync());
var w = bitmap.PixelWidth;
var h = bitmap.PixelHeight;
// 元画像と出力画像用のバッファの生成
var srcBytes = bitmap.PixelBuffer.ToArray();
var dstBytes = new byte[srcBytes.Length];
// C++/Cxのライブラリで画像処理をしてみる
var nativeLibrary = new NativeTestClass();
nativeLibrary.sepia(w, h, srcBytes, dstBytes);
// Imageコントロールにセピア調化した画像を表示する
effectImage.Source = WriteableBitmapExtensions.FromArray(w, h, dstBytes);
}
}
} ||<
アプリ側の実装はこれで終わり。ネイティブ側のクラスを特に意識することなく使えているのが分かります。
ってことでできたー!