经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » ASP.net » 查看文章
uwp 用win2d获取图片主调颜色
来源:cnblogs  作者:吃饭/睡觉  时间:2018/9/25 20:40:19  对本文有异议

win10在设置颜色里有个从“背景图片中选取一种主题颜色”的选项,还有在很多内容展示软件中都使用了这样的功能。

      现在我们需要在 nuget 引用 win2d.uwp 和 Toolkit.uwp 两个库。

     首先将一个图片流转换成 win2d 的 CanvasBitmap 对象,然后通过 CanvasBitmap 的 GetPixelColors 方法获取到图片的全部颜色数组。

  1. /// <summary>
  2. /// 通过stream获取主题色
  3. /// </summary>
  4. /// <param name="uri"></param>
  5. /// <returns></returns>
  6. public async Task<Color> GetPaletteImage(IRandomAccessStream stream)
  7. {
  8.  
  9. //实例化资源
  10. var bimap = await CanvasBitmap.LoadAsync(device , stream);

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

  1. }

  在拿到整个颜色数组后我们需要计算出 平均亮度,平均饱和度,和平均色相

  1. foreach (var item in colors)
  2. {
  3. //将 rgb 转换成 hsv 对象
  4. HsvColor hsv = Microsoft.Toolkit.Uwp.Helpers.ColorHelper.ToHsv(item);
  5. //先将黑色和白色剔除掉
  6. if (hsv.V < 0.3 || hsv.S < 0.2)
  7. {
  8. continue;
  9. }
  10. //找出最大饱和度
  11. maxS = hsv.S > maxS ? hsv.S : maxS;
  12. //找出最大亮度度
  13. maxV = hsv.V > maxV ? hsv.V : maxV;
  14. //找出最大色相
  15. maxH = hsv.H > maxH ? hsv.H : maxH;
  16. //色相总和
  17. sumHue += hsv.H;
  18. //亮度总和
  19. sumS += hsv.S;
  20. //饱和度总和
  21. sumV += hsv.V;
  22. count++;
  23. notBlackWhite.Add(item);
  24. }

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

  1.  

//计算各个值,用来做判断用
double h = Math.Max(maxAvgV, avgV);
double s = Math.Min(maxAvgS, avgS);
double hue = Math.Min(maxAvgH, avgH);

  1.  

  已经将需要做判断的值求出来后,我们将 剔除了白色和黑色的 数据在做一遍计算,符合条件的颜色相加在一起 再 将总和除以符合条件的数量。

  1. foreach (var item in notBlackWhite)
  2. {
  3. HsvColor hsv = Microsoft.Toolkit.Uwp.Helpers.ColorHelper.ToHsv(item);
  4. //颜色大于平均色相 并且 饱和度大于平局饱和度 并且 亮度大于平局亮度 的符合条件 进行相加
  5. if (hsv.H >= hue + 10 && hsv.V >= h && hsv.S >= s)
  6. {
  7. R += item.R;
  8. G += item.G;
  9. B += item.B;
  10. count++;
  11. }
  12. }

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

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

  1.  

 右边为图片的主题颜色,可以看到这张图片的大部分颜色为黑色,而当我们看到这张图片的时候我们的注意力就却会被蓝色吸引住,我们在计算中并不是找到出现最多次的颜色为主题颜色,而是亮度和饱和度最为突出的作为主题色。

 

全部代码:

  1. using Microsoft.Graphics.Canvas;
  2. using Microsoft.Toolkit.Uwp;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.Threading.Tasks;
  6. using Windows.Storage.Streams;
  7. using Windows.UI;
  8. namespace uwp_播放器.Data
  9. {
  10. public class ImageThemeBrush
  11. {
  12. CanvasDevice device = new CanvasDevice();
  13. /// <summary>
  14. /// 通过Uri获取主题色
  15. /// </summary>
  16. /// <param name="uri"></param>
  17. /// <returns></returns>
  18. public async Task<Color> GetPaletteImage(Uri uri)
  19. {
  20. //实例化资源
  21. var bimap = await CanvasBitmap.LoadAsync(device, uri);
  22. //取色
  23. Color[] colors = bimap.GetPixelColors();
  24. return await GetThemeColor(colors);
  25. }
  26. /// <summary>
  27. /// 通过stream获取主题色
  28. /// </summary>
  29. /// <param name="uri"></param>
  30. /// <returns></returns>
  31. public async Task<Color> GetPaletteImage(IRandomAccessStream stream)
  32. {
  33. //实例化资源
  34. var bimap = await CanvasBitmap.LoadAsync(device , stream);
  35. //取色
  36. Color[] colors = bimap.GetPixelColors();
  37. return await GetThemeColor(colors);
  38. }
  39. #region Methon:方法
  40.  
  41.  
  42.  
  43.  
  44. private async Task<Color> GetThemeColor(Color[] colors)
  45. {
  46. Color color = new Color();
  47. await Task.Run(() =>
  48. {
  49. //饱和度 黑色多
  50. double sumS = 0;
  51. //明亮度 白色多
  52. double sumV = 0;
  53. double sumHue = 0;
  54. //颜色中最大亮度
  55. double maxV = 0;
  56. //颜色中最大饱和度
  57. double maxS = 0;
  58. //颜色中最大色相
  59. double maxH = 0;
  60. double count = 0;
  61. List<Color> notBlackWhite = new List<Color>();
  62. foreach (var item in colors)
  63. {
  64. //将 rgb 转换成 hsv 对象
  65. HsvColor hsv = Microsoft.Toolkit.Uwp.Helpers.ColorHelper.ToHsv(item);
  66. //先将黑色和白色剔除掉
  67. if (hsv.V < 0.3 || hsv.S < 0.2)
  68. {
  69. continue;
  70. }
  71. //找出最大饱和度
  72. maxS = hsv.S > maxS ? hsv.S : maxS;
  73. //找出最大亮度度
  74. maxV = hsv.V > maxV ? hsv.V : maxV;
  75. //找出最大色相
  76. maxH = hsv.H > maxH ? hsv.H : maxH;
  77. //色相总和
  78. sumHue += hsv.H;
  79. //亮度总和
  80. sumS += hsv.S;
  81. //饱和度总和
  82. sumV += hsv.V;
  83. count++;
  84. notBlackWhite.Add(item);
  85. }
  86. double avgH = sumHue / count;
  87. double avgV = sumV / count;
  88. double avgS = sumS / count;
  89. double maxAvgV = maxV / 2;
  90. double maxAvgS = maxS / 2;
  91. double maxAvgH = maxH / 2;
  92. //计算各个值,用来做判断用
  93. double h = Math.Max(maxAvgV, avgV);
  94. double s = Math.Min(maxAvgS, avgS);
  95. double hue = Math.Min(maxAvgH, avgH);
  96. //aveS = aveS ;
  97. double R = 0;
  98. double G = 0;
  99. double B = 0;
  100. count = 0;
  101. foreach (var item in notBlackWhite)
  102. {
  103. HsvColor hsv = Microsoft.Toolkit.Uwp.Helpers.ColorHelper.ToHsv(item);
  104. //颜色大于平均色相 并且 饱和度大于平局饱和度 并且 亮度大于平局亮度 的符合条件 进行相加
  105. if (hsv.H >= hue + 10 && hsv.V >= h && hsv.S >= s)
  106. {
  107. R += item.R;
  108. G += item.G;
  109. B += item.B;
  110. count++;
  111. }
  112. }
  113. double r = R / count;
  114. double g = G / count;
  115. double b = B / count;
  116. color = Color.FromArgb(255, (byte)r, (byte)g, (byte)b);
  117. });
  118. colors = null;
  119. return color;
  120. }
  121. #endregion
  122. }
  123. }

 

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号