[UWP]使用Writeable​Bitmap创建HSV色轮

雪夜
发布: 2025-08-30 08:14:02
原创
1041人浏览过
  1. HSV的定义

hsv是一种将rgb颜色模型中的点转换到圆柱坐标系中的表示方法,这种表示方法旨在比rgb基于笛卡尔坐标系的几何结构更直观。hsv即色相、饱和度、明度(英文:hue, saturation, value),也被称为hsb,其中b代表brightness。

色相(H)是颜色的基本属性,即通常所说的颜色名称,如红色、黄色等,值域为0-360。红色对应0度,绿色对应120度,蓝色对应240度。饱和度(S)表示颜色的纯度,数值越高,颜色越纯,数值越低,颜色越接近灰色,取值范围为0-100%。明度(V)表示颜色的亮度,数值越低越接近黑色,取值范围同样为0-100%。

[UWP]使用Writeable​Bitmap创建HSV色轮

1.2 HSV与RGB

HSV在数学上定义为RGB空间中颜色的R、G、B坐标的变换。

[UWP]使用Writeable​Bitmap创建HSV色轮

1.2.1 从RGB到HSV的转换

(r, g, b)分别表示颜色的红、绿、蓝坐标,它们的值为0到1之间的实数。设max为r、g、b中的最大值,min为这些值中的最小值:

[UWP]使用Writeable​Bitmap创建HSV色轮[UWP]使用Writeable​Bitmap创建HSV色轮

1.2.2 从HSV到RGB的转换

给定HSV中的(h, s, v)值定义的一个颜色,h表示色相,s和v分别表示饱和度和明度,值域为0到1之间。在RGB空间中对应的(r, g, b)三原色可以计算为(R、G、B的值域为0到1之间):

[UWP]使用Writeable​Bitmap创建HSV色轮

对于每个颜色向量(r, g, b):

[UWP]使用Writeable​Bitmap创建HSV色轮

1.3 HSV的应用

HSV模型通常用于计算机图形应用中。在需要用户选择颜色应用于特定图形元素的各种应用场景中,常使用HSV色轮。

[UWP]使用Writeable​Bitmap创建HSV色轮

由于HSV对用户来说是一种直观的颜色模型,因此常用于调整图片。下图为Paint.Net中调整图片的示例:

[UWP]使用Writeable​Bitmap创建HSV色轮[UWP]使用Writeable​Bitmap创建HSV色轮

AI角色脑洞生成器
AI角色脑洞生成器

一键打造完整角色设定,轻松创造专属小说漫画游戏角色背景故事

AI角色脑洞生成器 176
查看详情 AI角色脑洞生成器

下图为UWPCommunityToolkit中通过Saturation调整图片的示例:

[UWP]使用Writeable​Bitmap创建HSV色轮

1.4 HSV与色轮

许多设计方面的书籍介绍了使用色轮为UI配色,由于篇幅限制,这里不详细讨论,具体可参考以下链接:网页设计中如何配色

  1. WriteableBitmap

WriteableBitmap提供了一种可写入并可更新的BitmapSource。也就是说,你可以动态更改图像,然后重新呈现更新后的图像。使用WinRTXamlToolkit可以轻松实现这一操作,代码如下:

var diameter = 100;
var source = new WriteableBitmap(diameter, diameter);
var pixels = source.PixelBuffer.GetPixels();
for (var i = 0; i < pixels.Length; i++) {
    pixels[i] = 255 << 24; // 白色
}
source.SetSource(pixels);
登录后复制

上面的代码将一个尺寸为100x100的WriteableBitmap的所有像素设为白色,然后设置为图片的Source。在这里,像素数据的格式为

BitmapPixelFormat.Bgra8
登录后复制
,即用四个Byte分别表示颜色的BGRA(通常颜色表示为ARGB,如#FFFF0000即Alpha:255,Red:255,Green:0,Blue:0)。

还可以将WriteableBitmap保存为文件,同样使用WinRTXamlToolkit实现:

await source.SaveAsync(KnownFolders.PicturesLibrary, "Wheel.png");
登录后复制
  1. 使用WriteableBitmap创建HSV色轮

前面介绍了HSV色轮,也介绍了如何使用WriteableBitmap,那么用WriteableBitmap实现一个HSV色轮是一件很简单的事,只需要计算每个像素点距离中心点的角度(Hue)和距离(Saturation)得出HsvColor,再转换成ArgbColor填入WriteableBitmap就实现了。具体代码如下:

var diameter = width = height = 200;
var radius = diameter / 2;
var source = new WriteableBitmap(diameter, diameter);
var pixels = source.PixelBuffer.GetPixels();
<p>for (var y = 0; y < height; y++) {
for (var x = 0; x < width; x++) {
var i = y <em> width + x;
if (Math.Sqrt((x - radius) </em> (x - radius) + (y - radius) <em> (y - radius)) > radius) {
pixels.Bytes[i </em> 4] = 0;
pixels.Bytes[i <em> 4 + 1] = 0;
pixels.Bytes[i </em> 4 + 2] = 0;
pixels.Bytes[i <em> 4 + 3] = 0;
} else {
var distanceOfX = x - radius;
var distanceOfY = y - radius;
var theta = Math.Atan2(distanceOfY, distanceOfX);
if (theta < 0) theta += 2 </em> Math.PI;
var hue = theta <em> 180 / Math.PI;
var saturation = Math.Sqrt(distanceOfX </em> distanceOfX + distanceOfY <em> distanceOfY) / radius;
var value = 1;
var color = ColorHelper.FromHsv(hue, saturation, value);
pixels.Bytes[i </em> 4] = color.B;
pixels.Bytes[i <em> 4 + 1] = color.G;
pixels.Bytes[i </em> 4 + 2] = color.R;
pixels.Bytes[i * 4 + 3] = 255;
}
}
}
source.SetSource(pixels);
登录后复制

[UWP]使用Writeable​Bitmap创建HSV色轮

有一个小问题,即使不仔细看也能看到圆形的边缘锯齿很严重。当然可以在上面的代码里加入高斯模糊的算法处理这些锯齿,但毕竟这篇文章不打算讨论到这么深入。可以简单地使用WriteableBitmapEx对整个WriteableBitmap进行高斯模糊:

source.Convolute(WriteableBitmapExtensions.KernelGaussianBlur5x5);
登录后复制

这样看起来就好很多了。

[UWP]使用Writeable​Bitmap创建HSV色轮

  1. HSV转RGB的陷阱

上面的代码中RGB和HSV互换使用了UWPCommunityToolkit中的ColorHelper,ColorHelper的介绍是这样的:

但这里有一个陷阱。以下代码将一个RGB color转换成HSV color,再转换回RGB color,看起来没什么问题:

var color = Color.FromArgb(255, 255, 20, 200);
var hsv = ColorHelper.ToHsv(color);
Debug.WriteLine(string.Format("H:{0}  S:{1}  V:{2}", hsv.H, hsv.S, hsv.V));
color = ColorHelper.FromHsv(hsv.H, hsv.S, hsv.V);
Debug.WriteLine(string.Format("R:{0}  G:{1}  B:{2}", color.R, color.G, color.B));
登录后复制

但是看输出就能发现转回来的RGB color改变了:

H:314.042553191489  S:0.92156862745098  V:1
R:255  G:19  B:199
登录后复制

造成这个问题的原因在于RGB能表示的颜色范围有限,只是256 256 256=16777216种颜色。而HSV如果使用int值,只能表示360 100 100=3600000种颜色,如果用double则几乎有无数种组合,这样两种颜色模型间就不匹配了。这种情况下只能折衷一下限制HSV的精度了,改成下面的代码能解决上面的问题:

color = ColorHelper.FromHsv(Math.Round(hsv.H), Math.Round(hsv.S, 2), Math.Round(hsv.V, 2));
登录后复制
  1. 参考文献
  • HSL and HSV - Wikipedia
  • WriteableBitmap Class
  1. 源码
  • HsvColorWheel for UWP

以上就是[UWP]使用Writeable​Bitmap创建HSV色轮的详细内容,更多请关注php中文网其它相关文章!

相关标签:
最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号