使用 ChromaKey 濾鏡進行摳圖


 

 

簡介

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

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM