uwp 用win2d獲取圖片主調顏色


win10在設置顏色里有個從“背景圖片中選取一種主題顏色”的選項,還有在很多內容展示軟件中都使用了這樣的功能。

      現在我們需要在 nuget 引用 win2d.uwp 和 Toolkit.uwp 兩個庫。

     首先將一個圖片流轉換成 win2d 的 CanvasBitmap 對象,然后通過 CanvasBitmap 的 GetPixelColors 方法獲取到圖片的全部顏色數組。

 /// <summary>
        /// 通過stream獲取主題色
        /// </summary>
        /// <param name="uri"></param>
        /// <returns></returns>
        public async Task<Color> GetPaletteImage(IRandomAccessStream stream)
        {
           
              

            //實例化資源
           var  bimap = await CanvasBitmap.LoadAsync(device , stream);

      //取色
      Color[] colors = bimap.GetPixelColors();
      return await GetThemeColor(colors);

            
        }

  在拿到整個顏色數組后我們需要計算出 平均亮度,平均飽和度,和平均色相

foreach (var item in colors)
                {
                    //將 rgb 轉換成 hsv 對象
                    HsvColor hsv = Microsoft.Toolkit.Uwp.Helpers.ColorHelper.ToHsv(item);

                    //先將黑色和白色剔除掉
                    if (hsv.V < 0.3 || hsv.S < 0.2)
                    {
                        continue;
                    }
                    //找出最大飽和度
                    maxS = hsv.S > maxS ? hsv.S : maxS;
                    //找出最大亮度度
                    maxV = hsv.V > maxV ? hsv.V : maxV;
                    //找出最大色相
                    maxH = hsv.H > maxH ? hsv.H : maxH;
                    //色相總和
                    sumHue += hsv.H;
                    //亮度總和
                    sumS += hsv.S;
                    //飽和度總和
                    sumV += hsv.V;
                    count++;
                    notBlackWhite.Add(item);

                }

double avgV = sumV / count;
double avgS = sumS / count;
double maxAvgV = maxV / 2;
double maxAvgS = maxS / 2;
double maxAvgH = maxH / 2;

 
         

//計算各個值,用來做判斷用
double h = Math.Max(maxAvgV, avgV);
double s = Math.Min(maxAvgS, avgS);
double hue = Math.Min(maxAvgH, avgH);

 

  已經將需要做判斷的值求出來后,我們將 剔除了白色和黑色的 數據在做一遍計算,符合條件的顏色相加在一起 再 將總和除以符合條件的數量。

 foreach (var item in notBlackWhite)
                {
                    HsvColor hsv = Microsoft.Toolkit.Uwp.Helpers.ColorHelper.ToHsv(item);
                    //顏色大於平均色相 並且 飽和度大於平局飽和度 並且 亮度大於平局亮度 的符合條件 進行相加
                    if (hsv.H >= hue + 10 && hsv.V >= h && hsv.S >= s)
                    {
                        R += item.R;
                        G += item.G;
                        B += item.B;
                        count++;
                    }
                }

          double r = R / count;
          double g = G / count;
          double b = B / count;

          color = Color.FromArgb(255, (byte)r, (byte)g, (byte)b);

 

 右邊為圖片的主題顏色,可以看到這張圖片的大部分顏色為黑色,而當我們看到這張圖片的時候我們的注意力就卻會被藍色吸引住,我們在計算中並不是找到出現最多次的顏色為主題顏色,而是亮度和飽和度最為突出的作為主題色。

 

全部代碼:

using Microsoft.Graphics.Canvas;
using Microsoft.Toolkit.Uwp;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Windows.Storage.Streams;
using Windows.UI;

namespace uwp_播放器.Data
{
    public  class ImageThemeBrush
    {
        CanvasDevice device = new CanvasDevice();
      

        /// <summary>
        /// 通過Uri獲取主題色
        /// </summary>
        /// <param name="uri"></param>
        /// <returns></returns>
        public async Task<Color> GetPaletteImage(Uri uri)
        {
            //實例化資源
          var   bimap = await CanvasBitmap.LoadAsync(device, uri);

            //取色
            Color[] colors = bimap.GetPixelColors();
            return await GetThemeColor(colors);
        }



        /// <summary>
        /// 通過stream獲取主題色
        /// </summary>
        /// <param name="uri"></param>
        /// <returns></returns>
        public async Task<Color> GetPaletteImage(IRandomAccessStream stream)
        {
           
              

            //實例化資源
           var  bimap = await CanvasBitmap.LoadAsync(device , stream);

            //取色
            Color[] colors = bimap.GetPixelColors();
            return await GetThemeColor(colors);
            
        }

        

      
        #region Methon:方法


       


        private async Task<Color> GetThemeColor(Color[] colors)
        {
            Color color = new Color();

            await Task.Run(() =>
            {
                //飽和度 黑色多
                double sumS = 0;
                //明亮度 白色多
                double sumV = 0;
                double sumHue = 0;
                //顏色中最大亮度
                double maxV = 0;
                //顏色中最大飽和度
                double maxS = 0;
                //顏色中最大色相
                double maxH = 0;
                double count = 0;
                List<Color> notBlackWhite = new List<Color>();
                foreach (var item in colors)
                {
                    //將 rgb 轉換成 hsv 對象
                    HsvColor hsv = Microsoft.Toolkit.Uwp.Helpers.ColorHelper.ToHsv(item);

                    //先將黑色和白色剔除掉
                    if (hsv.V < 0.3 || hsv.S < 0.2)
                    {
                        continue;
                    }
                    //找出最大飽和度
                    maxS = hsv.S > maxS ? hsv.S : maxS;
                    //找出最大亮度度
                    maxV = hsv.V > maxV ? hsv.V : maxV;
                    //找出最大色相
                    maxH = hsv.H > maxH ? hsv.H : maxH;
                    //色相總和
                    sumHue += hsv.H;
                    //亮度總和
                    sumS += hsv.S;
                    //飽和度總和
                    sumV += hsv.V;
                    count++;
                    notBlackWhite.Add(item);

                }


                double avgH = sumHue / count;
                double avgV = sumV / count;
                double avgS = sumS / count;
                double maxAvgV = maxV / 2;
                double maxAvgS = maxS / 2;
                double maxAvgH = maxH / 2;

                //計算各個值,用來做判斷用
                double h = Math.Max(maxAvgV, avgV);
                double s = Math.Min(maxAvgS, avgS);
                double hue = Math.Min(maxAvgH, avgH);

                //aveS = aveS ;
                double R = 0;
                double G = 0;
                double B = 0;
                count = 0;


                foreach (var item in notBlackWhite)
                {
                    HsvColor hsv = Microsoft.Toolkit.Uwp.Helpers.ColorHelper.ToHsv(item);
                    //顏色大於平均色相 並且 飽和度大於平局飽和度 並且 亮度大於平局亮度 的符合條件 進行相加
                    if (hsv.H >= hue + 10 && hsv.V >= h && hsv.S >= s)
                    {
                        R += item.R;
                        G += item.G;
                        B += item.B;
                        count++;
                    }
                }

                double r = R / count;
                double g = G / count;
                double b = B / count;



                color = Color.FromArgb(255, (byte)r, (byte)g, (byte)b);

               

            });


            colors = null;

            return color;
        }
        #endregion
    }
}

 


免責聲明!

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



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