0

0

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

雪夜

雪夜

发布时间:2025-08-30 08:14:02

|

1066人浏览过

|

来源于php中文网

原创

  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色轮

Proface Avatarize
Proface Avatarize

一个利用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();

for (var y = 0; y < height; y++) { for (var x = 0; x < width; x++) { var i = y width + x; if (Math.Sqrt((x - radius) (x - radius) + (y - radius) (y - radius)) > radius) { pixels.Bytes[i 4] = 0; pixels.Bytes[i 4 + 1] = 0; pixels.Bytes[i 4 + 2] = 0; pixels.Bytes[i 4 + 3] = 0; } else { var distanceOfX = x - radius; var distanceOfY = y - radius; var theta = Math.Atan2(distanceOfY, distanceOfX); if (theta < 0) theta += 2 Math.PI; var hue = theta 180 / Math.PI; var saturation = Math.Sqrt(distanceOfX distanceOfX + distanceOfY distanceOfY) / radius; var value = 1; var color = ColorHelper.FromHsv(hue, saturation, value); pixels.Bytes[i 4] = color.B; pixels.Bytes[i 4 + 1] = color.G; pixels.Bytes[i 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

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

312

2023.08.02

int占多少字节
int占多少字节

int占4个字节,意味着一个int变量可以存储范围在-2,147,483,648到2,147,483,647之间的整数值,在某些情况下也可能是2个字节或8个字节,int是一种常用的数据类型,用于表示整数,需要根据具体情况选择合适的数据类型,以确保程序的正确性和性能。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

519

2024.08.29

c++怎么把double转成int
c++怎么把double转成int

本专题整合了 c++ double相关教程,阅读专题下面的文章了解更多详细内容。

48

2025.08.29

C++中int的含义
C++中int的含义

本专题整合了C++中int相关内容,阅读专题下面的文章了解更多详细内容。

188

2025.08.29

c++怎么把double转成int
c++怎么把double转成int

本专题整合了 c++ double相关教程,阅读专题下面的文章了解更多详细内容。

48

2025.08.29

C++中int、float和double的区别
C++中int、float和double的区别

本专题整合了c++中int和double的区别,阅读专题下面的文章了解更多详细内容。

94

2025.10.23

class在c语言中的意思
class在c语言中的意思

在C语言中,"class" 是一个关键字,用于定义一个类。想了解更多class的相关内容,可以阅读本专题下面的文章。

455

2024.01.03

python中class的含义
python中class的含义

本专题整合了python中class的相关内容,阅读专题下面的文章了解更多详细内容。

6

2025.12.06

excel制作动态图表教程
excel制作动态图表教程

本专题整合了excel制作动态图表相关教程,阅读专题下面的文章了解更多详细教程。

30

2025.12.29

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PostgreSQL 教程
PostgreSQL 教程

共48课时 | 6.2万人学习

Excel 教程
Excel 教程

共162课时 | 10万人学习

PHP基础入门课程
PHP基础入门课程

共33课时 | 1.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

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