我正在尝试模拟 色调效果开放 XML。它的作用是通过改变色调来改变图像中像素的色调。它需要 2 个参数:1)hue
(以度为单位)和 2)amt
(数量,百分比)。我遇到的问题是#2。规范规定:
色调:将效果颜色值朝或远离色调移动
指定金额。
- amt(数量)- 指定颜色值移动的量。
- 色调(色调)- 指定要着色的色调。
不管 XML 构造如何,我都可以模拟 amt
为 100% 的值。例如,如果我想要蓝色(色调:240°),我可以创建这个(有色)。下面是一个示例:
原始和有色(色调 = 240,数量 = 100%)。
这只需将色调设置为 240,保持饱和度和亮度相同并转换为 RGB 和写入每个像素。
但这是我无法实现的:
Hue=240 (蓝色),Amount = 30%,<分别为强>50%和80%
同样,Amount
的规范表示指定颜色值移动的程度 。我在这里尝试了各种方法来使其正常工作,但似乎无法(hue=hue*amount
、originalhue * amount + Hue
等。 )
更多示例:色调=120(绿色),金额 = 30%、50%<分别为 /strong>、80% 和 100%。我能得到的100%。
以下是上图中单个像素的一些值列表:
像素 159, 116 - 蓝色图片
Hue Amount R G B | H S L
Original 244 196 10 | 48 0.92 0.5
Blue 240 30% 237 30 45 | 356 0.85 0.52
Blue 240 50% 245 9 156 | 323 0.93 0.5
Blue 240 80% 140 12 244 | 273 0.91 0.5
Blue 240 100% 12 12 244 | 240 0.91 0.5
像素 159, 116 - 绿色图片
Hue Amount R G B | H S L
Original 244 196 10 | 48 0.92 0.5
Green 120 30% 211 237 30 | 68 0.85 0.52
Green 120 50% 159 237 30 | 83 0.85 0.52
Green 120 80% 81 237 29 | 105 0.85 0.52
Green 120 100% 29 237 29 | 120 0.85 0.52
所以,问题是:有人知道这应该如何工作吗?
注意:这不重复:
I'm trying emulate the Tint Effect of Open XML. What it does is change the hue of pixels in an image by shifting the hue. It takes 2 parameters: 1) the hue
(in degrees) and 2) the amt
(the amount, a percentage). It is #2 that I'm having issues with. The spec states:
Tint: Shifts effect color values either towards or away from hue by the
specified amount.
- amt (Amount) - Specifies by how much the color value is shifted.
- hue (Hue) - Specifies the hue towards which to tint.
Never minding the XML construction, I can emulate values that have an amt
of 100%. So for example, if I want Blue (hue: 240°), I can create this (the Tinted one). Here's an example:
Original and Tinted (hue = 240, Amount = 100%).
This is achieved simply by setting the hue to 240, keeping saturation and luminance the same and converting to RGB and writing each pixel.
Here's what I can't achieve though:
Hue=240 (blue), Amount = 30%, 50% and 80%, respectively
Again, the spec for Amount
says Specifies by how much the color value is shifted. I've tried all sorts of ways here to get this to work, but can't seem to (hue=hue*amount
, originalhue * amount + hue
, etc.)
More examples: Hue=120 (green), Amount = 30%, 50%, 80% and 100%, respectively. The 100% one I can get.
Here are some value lists of a single pixel in the pictures above:
Pixel 159, 116 - Blue Pictures
Hue Amount R G B | H S L
Original 244 196 10 | 48 0.92 0.5
Blue 240 30% 237 30 45 | 356 0.85 0.52
Blue 240 50% 245 9 156 | 323 0.93 0.5
Blue 240 80% 140 12 244 | 273 0.91 0.5
Blue 240 100% 12 12 244 | 240 0.91 0.5
Pixel 159, 116 - Green Pictures
Hue Amount R G B | H S L
Original 244 196 10 | 48 0.92 0.5
Green 120 30% 211 237 30 | 68 0.85 0.52
Green 120 50% 159 237 30 | 83 0.85 0.52
Green 120 80% 81 237 29 | 105 0.85 0.52
Green 120 100% 29 237 29 | 120 0.85 0.52
So, the question is: Does anyone know how this should work?
Note: This is not a duplicate of:
发布评论
评论(2)
我非常确定您的问题是由您插值角度的方式引起的。这是一个插值函数(用 python 编写),应该可以解决这个问题。它基于 xna 论坛主题最短 2D 角度插值。
现在,
interpolate(originalHue,hue,amount)
应该会产生所需的结果。编辑:据我了解,您的目标是将原始色调向特定目标色调旋转一定的给定量。我相信您已经熟悉这一点,但为了便于说明,这里有一个色轮。
(来源:sapdesignguild.org)
问题是混合(或插值)两个角度并不简单,因此像
hue = ((hue - OriginalHue) * amount) + OriginalHue
这样的代码将不起作用。由于 360° 环绕,您可以通过多种方式从一个角度转到另一个角度。要从 0° 到 60°,您可以逆时针旋转 60°、逆时针旋转 420°、顺时针旋转 300° 等。通常,最短的角度就是所需的角度。例如,让我们考虑企鹅脖子:如果您的原始色调是 30°(橙色),目标是 240°(蓝色)并且数量是 50%,您将得到以下结果:
我的猜测是第二个结果是您正在寻找的那个,但我可能是错的,并且错误可能完全在其他地方......
I am quite certain that your problem results from the way you are interpolating angles. Here's an interpolation function (written in python) that should do the trick. It is based on a suggestion from the xna forums thread Shortest 2D Angle Interpolation.
Now,
interpolate(originalHue,hue,amount)
should produce the desired result.Edit: It is my understanding that your goal is to rotate the original hue towards a certain target hue by some given amount. I'm sure you're already familiar with this, but for the sake of illustration, here's a color wheel.
(source: sapdesignguild.org)
The problem is that mixing (or interpolating) two angles is not trivial, so code like
hue = ((hue - originalHue) * amount) + originalHue
will not work. There is an infinite number of ways you can go from one angle to another because of the wraparound at 360°. To get from 0° to 60° you could rotate 60° counter-clockwise, 420° counter-clockwise, 300° clockwise etc. Usually the shortest angle is the desired one.For example, lets consider the penguin necks: if your original hue is 30° (orange), your target is 240° (blue) and the amount is 50%, you would get the following results:
My guess is that the second result is the one you are looking for, but I may be wrong and the error could be somewhere else entirely...
您应该查看 TintParams在 GDI+ 中(尽管不是 .NET 的一部分)——这可能正是您正在寻找的。
You should take a look at TintParams in GDI+ (not part of .NET though) - this may be just what you're looking for.