使用 ChromaKey 濾鏡進行摳圖

 

 

簡介html

Nokia Imaging SDK  1.0 中新提供的 ChromaKey 濾鏡是一個神奇的濾鏡,它的基本原理就是把async

一個指定範圍值內的顏色變爲透明或半透明,好比下面的 demo 演示的,看上去第一張照片的兩我的物的spa

拍攝地點由屋子裏變成了沙灘:3d

原理是用 ChromaKey 濾鏡把第一張圖片的背景色去除,而後用 Blend 濾鏡,與第二張圖片進行融合,顯示結果就是code

第三張圖片。orm

 

由此能夠預見,使用這個濾鏡,若是背景素材豐富的話,能夠提供各類有趣的效果。在其它場景的應用交互中,這個濾鏡也是htm

大有做爲的。對象

 

 

步驟:blog

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

更多有關說明請參考: http://developer.nokia.com/Resources/Library/Lumia/#!nokia-imaging-sdk/adding-libraries-to-the-project.html

相關文章
相關標籤/搜索