2016-03-21 122 views
2

我在我的UWP c#項目中有一個圖像,那是一個帶有白色前景的透明png。我現在想把這個PN​​G圖像的白色變成另一種顏色(如藍色)。UWP透明png顏色疊加

示例(注意,彩色圖像沒有透明背景,這是由於我使用的圖像處理軟件不合適,並且演示了白色的變化,背景在最終結果中應該是透明的)。

bubble1 bubble2

我記得,這是團結可能的,現在我想現在在UWP-應用程序做到這一點。我想過使用Lumia ImagingSDK或者Composition API,但不知道,用這兩種方法做熱門。

+1

當然,可以改變色調並對位圖進行圖像處理,但是您需要怎麼做?爲什麼不預先生成所需的所有色彩?一個可能的答案是在這個線程:http://stackoverflow.com/questions/14364716/faster-algorithm-to-change-hue-saturation-lightness-in-a-bitmap其中與色調播放 - 但我會認真考慮需要,並根據預先加載所需顏色的速度來衡量它。 –

+0

你爲什麼不預先生成你需要的所有色彩?'我想要相同的圖像,但顏色不同。考慮到包裝尺寸和成本,我認爲改變顏色的方法可能適合這一點。所以,我明白你的意思:你的方法會從ARGB轉換到HSV/HSL色彩空間,並手動進行顏色處理?我希望,已經有一些MS API實現了功能。 – user3079834

+0

打開Photoshop並生成所需的所有變體 - 然後您可以將它們預加載到您的應用中,並且具有比以編程方式更改色調更快的應用程序。但是,這是一個考慮因素,您可能需要更少的內存使用量或更高的性能。我不知道你正在建立的應用程序,在這種情況下,改變色調是一種快速和整潔的方式來達到:) –

回答

4

您可以這樣做的方法是使用合成效果系統。

先決條件

  1. 定位至少建立10586(該組合物是API這之前的實驗)。
  2. 雖然沒有嚴格要求,但對Visual層有基本的瞭解並不會造成傷害。我寫了一篇博客文章,介紹了這個主題here
  3. 添加Win2D nuget包。

此外,您可以看一下我寫的here,這是一個在XAML應用程序中使用Composition API啓動和運行的快速方法。它也使用效果進行演示。不僅如此,還包括使用Composition API(使用我寫的包)加載圖像。

Gettings開始

你會想要做的非常相似的要點的東西,但不是定義InvertEffect,你要定義既CompositeEffectColorSourceEffect。這將做的是拍攝一張圖像並將其用作「蒙版」,然後用一種顏色替換圖像中的白色。您需要定義的效果是這樣的:

IGraphicsEffect graphicsEffect = new CompositeEffect 
{ 
    Mode = Microsoft.Graphics.Canvas.CanvasComposite.DestinationIn, 
    Sources = 
    { 
     new ColorSourceEffect 
     { 
      Name = "colorSource", 
      Color = Color.FromArgb(255, 255, 255, 255) 
     }, 
     new CompositionEffectSourceParameter("mask") 
    } 
}; 

下一個步驟是創建一個效果工廠:

var effectFactory = compositor.CreateEffectFactory(graphicsEffect, new string[] { "colorSource.Color" }); 

第二個參數,而不是必需的,也可能是你在這種情況下,想要的東西。通過設置此參數,您可以在編輯效果後更改屬性,從而允許您手動設置該屬性並創建每個新效果畫筆或在效果畫筆上爲該屬性設置動畫效果。我們將手動設置它。使用您的新效果工廠創建一個新的效果畫筆。請注意,這個工廠可以創造出許多新的效果畫筆與你上面使用的定義:

var effectBrush = effectFactory.CreateBrush(); 

但是,首先你需要申請你的形象面具。您可以使用我編寫的名爲CompositionImageLoader的庫將圖像加載到曲面中。你也可以在nuget上下載它。用圖像創建表面後,創建一個CompositionSurfaceBrush並將其應用於效果。

var imageLoader = ImageLoaderFactory.CreateImageLoader(compositor); 

var surface = imageLoader.LoadImageFromUri(new Uri("ms-appx:///Assets/Images/HAvng.png")); 
var brush = compositor.CreateSurfaceBrush(surface); 

effectBrush.SetSourceParameter("mask", brush); 

請注意,你應該讓你的ImageLoader的地方,因爲在創造一個又一遍的將是昂貴的。剩下要做的就是將效果刷應用於視覺效果並設置顏色:

visual.Brush = effectBrush; 

effectBrush.Properties.InsertColor("colorSource.Color", Colors.Red); 

然後你就完成了!請注意,如果您想在此之後更改顏色,則只需使用新顏色調用與上述方法相同的InsertColor方法即可。

最終產品

在我的測試代碼,該方法是這樣的:

var compositor = ElementCompositionPreview.GetElementVisual(this).Compositor; 
var visual = compositor.CreateSpriteVisual(); 

visual.Size = new Vector2(83, 86); 
visual.Offset = new Vector3(50, 50, 0); 

_imageLoader = ImageLoaderFactory.CreateImageLoader(compositor); 

var surface = _imageLoader.LoadImageFromUri(new Uri("ms-appx:///Assets/Images/HAvng.png")); 
var brush = compositor.CreateSurfaceBrush(surface); 

IGraphicsEffect graphicsEffect = new CompositeEffect 
{ 
    Mode = Microsoft.Graphics.Canvas.CanvasComposite.DestinationIn, 
    Sources = 
    { 
     new ColorSourceEffect 
     { 
      Name = "colorSource", 
      Color = Color.FromArgb(255, 255, 255, 255) 
     }, 
     new CompositionEffectSourceParameter("mask") 
    } 
}; 

_effectFactory = compositor.CreateEffectFactory(graphicsEffect, new string[] { "colorSource.Color" }); 
var effectBrush = _effectFactory.CreateBrush(); 

effectBrush.SetSourceParameter("mask", brush); 

visual.Brush = effectBrush; 

effectBrush.Properties.InsertColor("colorSource.Color", Colors.Red); 

ElementCompositionPreview.SetElementChildVisual(this, visual); 

注意,在這個例子中,視覺附於this,這是我的MainPage。您可以將其附加到任何XAML元素。如果您希望看到一個自定義控件的示例,您可以在創建XAML標記中定義該自定義控件,然後在調整控件大小時調整視覺大小,則可以找到該控件的here

要查看更多與組成相關的東西,請進入我們的GitHub page!如果您有任何關於API的問題,我們很樂意爲您提供幫助。

+0

這很好,謝謝。而不是'this',我正在使用圖像。該代碼創建了一個很好的紅色,之前它是透明的白色,就像我想要的那樣。我設置了'visual.Offset = new Vector3(0,0,0);'現在有兩個問題:1.如何在舊的(原始)'Image'之前放置新元素**?使用當前代碼,新圖片將顯示在舊圖片的後面。 2.如何替換舊的(原始)'Image'? – user3079834

+0

@robmikh,是否已將此類效果添加到Composition示例應用程序?是否有一些更新的參考代碼,我們可以看看如何使用Composition進行顏色替換?這段代碼稍顯過時,特別是使用ImageLoaderFactory。而且就像OP所說的那樣,這將很適合直接應用於Image控件。 – Maximus