簡介
Nokia Imaging SDK 1.0 中新提供的 ChromaKey 濾鏡是一個神奇的濾鏡,它的基本原理就是把
一個指定范圍值內的顏色變為透明或半透明,比如下面的 demo 演示的,看上去第一張照片的兩個人物的
拍攝地點由屋子里變成了沙灘:

原理是用 ChromaKey 濾鏡把第一張圖片的背景色去除,然后用 Blend 濾鏡,與第二張圖片進行融合,顯示結果就是
第三張圖片。
由此可以預見,使用這個濾鏡,如果背景素材豐富的話,可以提供各種有趣的效果。在其它場景的應用交互中,這個濾鏡也是
大有作為的。
步驟:
1)首先在 VS 中新建一個名為 ChromaKeyFilterSample 的解決方案,並且通過 NuGet 添加 Imaging SDK 類庫,
具體參照上一篇文章。
2)在工程的根目錄下面添加兩張圖片,作為下面的處理過程的素材:
圖片一:

圖片二:

3)在 MainPage 的 xaml 頁面,添加 三個 Image 控件,分別顯示 兩張原圖和 結果:
<Image x:Name="pic1" HorizontalAlignment="Left" Height="192" Stretch="Fill" Margin="10,25,0,0" VerticalAlignment="Top" Width="202"/> <Image x:Name="pic2" HorizontalAlignment="Left" Height="192" Stretch="Fill" Margin="236,25,0,0" VerticalAlignment="Top" Width="200"/> <Image x:Name="imgResult" HorizontalAlignment="Left" Height="450" Margin="10,280,0,0" VerticalAlignment="Top" Width="450"/>
4)在頁面的 Loaded 事件中,分別顯示兩張原圖:
// 存儲兩張原圖片的流 Stream stream_pic_1; Stream stream_pic_2; async void MainPage_Loaded(object sender, RoutedEventArgs e) { // 獲取 xap 包中的 圖片 stream_pic_1 = App.GetResourceStream(new Uri("pic_1.jpg", UriKind.Relative)).Stream; stream_pic_2 = App.GetResourceStream(new Uri("pic_2.jpg", UriKind.Relative)).Stream; BitmapImage bitmap_1 = new BitmapImage(); bitmap_1.SetSource(stream_pic_1); pic1.Source = bitmap_1; BitmapImage bitmap_2 = new BitmapImage(); bitmap_2.SetSource(stream_pic_2); pic2.Source = bitmap_2; }
顯示效果:

為了顯示效果明顯,把 MainPage 頁面的背景色改為了淡藍色 : Background="AliceBlue"
5)繼續在 MainPage_Loaded 頁面中添加處理代碼。在 PhotoShop 中,用拾色器查看 圖片一
的背景色大致為 #6f9c87,然后給圖片一運用 ChromaKeyFilter 濾鏡:
stream_pic_1.Position = 0; stream_pic_2.Position = 0; var filters = new IFilter[] { //6f9c87 new ChromaKeyFilter(Windows.UI.Color.FromArgb(0xff, 0x6f, 0x9c, 0x87), 0.3d),//顏色值 和 顏色范圍 }; WriteableBitmap writeableBitmap = new WriteableBitmap(450, 450); // 給圖片添加濾鏡的管道過程 using (StreamImageSource streamImageSource = new StreamImageSource(stream_pic_1)) using (FilterEffect filterEffect = new FilterEffect(streamImageSource) { Filters = filters }) using (var renderer = new WriteableBitmapRenderer(filterEffect, writeableBitmap, OutputOption.Stretch)) { await renderer.RenderAsync(); imgResult.Source = writeableBitmap; }
具體濾鏡的使用可以參考 鏈接
到這里,運行代碼顯示效果可以看出,圖片一 的背景色去除了,顯示出了頁面的淡白色:

6)這個步驟就是把上一步中,圖片一 的處理結果 和 圖片二進行融合,繼續在 MainPage_Loaded 方法中,
把上面的這行代碼注釋掉:
// imgResult.Source = writeableBitmap;
然后繼續添加 Blend 濾鏡。BlendFilter 的一個屬性就是指定它的 BitmapImageSource 類型的前景圖片,然后
指定兩張圖片的融合方式:
var filtersBlend = new IFilter[] { // 為 writeableBitmap.AsBitmap() 方法添加命名空間 Nokia.InteropServices.WindowsRuntime // writeableBitmap 是上一步的處理結果 new BlendFilter { ForegroundSource = new BitmapImageSource(writeableBitmap.AsBitmap()), BlendFunction = BlendFunction.Normal } }; // 沙灘背景 的流 stream_pic_2.Position = 0; using (StreamImageSource streamImageSource = new StreamImageSource(stream_pic_2)) using (FilterEffect filterEffect = new FilterEffect(streamImageSource) { Filters = filtersBlend }) using (var renderer = new JpegRenderer(filterEffect)) { Windows.Storage.Streams.IBuffer buf = await renderer.RenderAsync(); Stream stream = System.Runtime.InteropServices.WindowsRuntime.WindowsRuntimeBufferExtensions.AsStream(buf); BitmapImage bi = new BitmapImage(); bi.SetSource(stream); imgResult.Source = bi;// 顯示結果 }
運行結果,可以看出,兩張照片已經融合到了一起:
到這里,這個神奇的濾鏡的講解就完成了。
7)因為在 Iamging SDK 中,可以通過 ColorImageSource 類,初始化一個純色背景的圖片源,通過它再跟
第一張圖片進行融合,就可以改變背景的顏色。把 步驟 6) 上面添加 ”沙灘背景“ 的代碼注釋掉,添加下面代碼,
直接把藍色背景換成了耀眼的紅色:
// 純色 using (ColorImageSource colorImageSource = new ColorImageSource(new Windows.Foundation.Size(450, 450), Windows.UI.Color.FromArgb(150, 255, 0, 0))) using (FilterEffect filterEffect = new FilterEffect(colorImageSource) { Filters = filtersBlend }) using (var renderer = new WriteableBitmapRenderer(filterEffect, writeableBitmap, OutputOption.Stretch)) { await renderer.RenderAsync(); imgResult.Source = writeableBitmap; }
其中的,下面這行代碼的意思是初始化一張 450x450 的背景為紅色的半透明的 ImageSource 對象:
ColorImageSource colorImageSource = new ColorImageSource(new Windows.Foundation.Size(450, 450), Windows.UI.Color.FromArgb(150, 255, 0, 0))
運行代碼顯示效果:

8)另外,在 Imaging SDK 中,還提供了一個 RadialGradient 類,用它可以初始化一個漸變色的 ImageSource 對象,
注釋掉 7)中的代碼,用下面的代碼給 圖片一 添加一個紫色的漸變背景色:
// 漸變色 var rad = new RadialGradient(new Windows.Foundation.Point(0.5, 0.9), new EllipseRadius(0.3, 0.3)); rad.Stops = new GradientStop[] { new GradientStop() { Color = Windows.UI.Color.FromArgb(255, 0, 0, 0), Offset = 0 }, //e70aef new GradientStop() { Color = Windows.UI.Color.FromArgb(0xff, 0xe7, 0x0a, 0xef), Offset = 1 } }; using(var gradImageSource = new GradientImageSource(new Windows.Foundation.Size(450, 450), rad)) using (FilterEffect filterEffect = new FilterEffect(gradImageSource) { Filters = filtersBlend }) //using (FilterEffect filterEffect = new FilterEffect(gradImageSource)) using (var renderer = new WriteableBitmapRenderer(filterEffect, writeableBitmap, OutputOption.Stretch)) { await renderer.RenderAsync(); imgResult.Source = writeableBitmap; }
工程運行效果:
源代碼下載:http://pan.baidu.com/s/1sjpsHVR
代碼運行說明:
在運行源代碼時,會出現一個編譯錯誤: Nokia Imaging SDK does not support the AnyCPU target platform.
因為 Nokia Imaging SDK 支持托管代碼和本地代碼,所以在編譯前需要進行設置:
1)在模擬器上運行時:菜單 -> 生成 -> 配置管理器 -> 活動解決方案平台 -> x86 2)在真機上運行時: 菜單 -> 生成 -> 配置管理器 -> 活動解決方案平台 -> ARM
