使用混合模式重新创建 HSV 颜色

2024-04-09

我正在开发一个应用程序,该应用程序创建的图像的色调、饱和度和值根据不同的参数而变化。出于性能原因,单独渲染色调、饱和度和明度组件,然后使用 Photoshop 风格的混合模式(正片叠底、叠加、滤色、色调等)将它们合成在一起是有意义的。

我已经知道如何对 RGB 图像执行此操作:将每个通道拆分为自己的红色、绿色或蓝色图像,其值范围从透明到该通道的颜色。将它们叠加在黑色之上,并将其混合模式设置为屏幕,嘿,很快,你就得到了彩色图像:

我该如何处理由 HSV 值定义的图像?我的应用程序经常更改其中一个通道而不更改其他两个通道,如果我可以在 GPU 上合成现有图像,而不是每次发生变化时都渲染一个全新的图像,那么我的渲染速度将会加快。

Here’s an example: an image generated with separate H, S, and V channels

在此示例中,色调围绕圆周从 0° 到 360° 变化,饱和度从中心到边缘从 0% 到 100% 变化,亮度 (V) 围绕圆周从 0% 到 100% 变化。这是我的应用程序创建的典型图像类型。是否可以使用常见混合模式的组合来单独创建这些通道并以数学上完美的方式组合它们?


我的应用程序经常更改其中一个通道而不更改其他两个通道,如果我可以在 GPU 上合成现有图像,而不是每次发生变化时都渲染一个全新的图像,那么我的渲染速度将会加快。 [OP,@ZevEisenberg]

关于速度和 GPU,我只想抛出转换函数 http://www.cs.rit.edu/%7Encs/color/t_convert.html进入片段着色器(e.g. https://stackoverflow.com/questions/15095909/from-rgb-to-hsv-in-opengl-glsl)。这将读取存储在纹理或三个不同纹理中的 HSV,对每个像素进行转换并输出 RGB。好,易于。我看不出不更改其他图层有什么好处,因为 H、S 或 V 都会影响所有 RGB 通道。也许存储中间 RGB 结果,例如hue=hsv2rgb(H,1,1),并更新为final=(hue*S+1-S)*V,缓存色调到RGB,但我认为这不值得。

无论如何,每种混合模式都有一个简单的公式,您可以将它们串在一起以用于涉及一组过于复杂的中间纹理的 HSV,但它会much速度较慢主要是因为不必要的临时存储和内存带宽。更不用说,尝试将公式重写为混合函数听起来相当具有挑战性,对于分支、除法、fract、夹紧、绝对值等...

我对将图像分割为其 HSV 组件并使用 Photoshop 中的混合模式重新创建原始图像的解决方案非常感兴趣。 [赏金,@phisch]

至于Photoshop……我不是很有钱。所以在 gimp 中,有Colours -> Components -> Compose/Decompose它会为你做这件事。如果 Photoshop 中不存在这种情况,我会感到有点惊讶,但也有点不存在。如果没有的话,也许有 Photoshop 脚本/插件可以做到这一点?但你确实说blending。您的问题可能会得到更好的关注https://graphicdesign.stackexchange.com/ https://graphicdesign.stackexchange.com/。下面,我已经给出了所涉及的复杂性的想法,但我怀疑 Photoshop 是否真的可以做到这一点。可能有一些方法可以解决 0 到 1 之外的像素值,但是这样您可能会遇到精度问题,这是不应该这样做的。


不管怎样,挑战就是挑战,尽管不切实际。以下内容仅供娱乐。

我将从以下函数开始(来自here https://stackoverflow.com/questions/15095909/from-rgb-to-hsv-in-opengl-glsl)和三个 HSV 纹理...

vec3 hsv2rgb(vec3 c)
{
    vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
    vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
    return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
}

我只知道OpenGL我不确定如果没有浮点纹理或一些扩展混合函数,我将如何做到这一点,所以我正在使用它们。但我只允许使用混合(没有任何着色器)。对于常量,我将使用 (1,1,1)、(1,2/3,1/3)、(3,3,3)、(6,6,6) (1/255,1 /255,1/255)、(255,255,255)、(1/2,1/2,1/2) 和 (0,0,0) 因为我无法让 GL_ZERO 进行缩放GL_DIFFERENCE_NV.

  1. 从色调纹理开始

  2. 使用添加剂混合添加(1,2/3,1/3)

  3. 找到小数部分

    1. 使用减法混合,减去 0.5(这是针对floor()因为我假设 GLrounds转换为 8 位时的颜色。如果没有,请跳过此部分)

    2. 缩小 1/255。这可以通过常规的 alpha 混合来完成,但我已经使用颜色纹理进行了缩放。

    3. 通过非浮点纹理舍入到最接近的 1/255

    4. 缩小 255(回到浮点纹理)

    5. 现在我们有了整数部分。从我们开始的内容中减去这个

  4. 缩放 6

  5. 使用减法混合,取 3

  6. 取该值的绝对值

    我将简单地使用GL_DIFFERENCE_NV为此,但如果没有它,下一步可能会使用两个单独的夹具。因为底片无论如何都会被钳位,所以类似于clamp(p-K.xxx,0,1) + clamp(-p-K.xxx,0,1).

  7. 减1

    enter image description here well, that's hue done

  8. 可以通过传递非浮点纹理来夹紧,但只是要使用GL_MIN

  9. 现在我可以使用 alpha 混合mix(),但饱和度会作为没有 Alpha 通道的黑白图像加载。因为它是混合白色的,所以手工操作实际上更容易......

    按饱和度缩放

  10. add 1

  11. 减去饱和度

    enter image description here and saturation has been applied

  12. 按价值缩放

    enter image description here and there's the image

  13. 咖啡时间(休闲时光

全部完成使用

  • glBlendEquation with GL_FUNC_REVERSE_SUBTRACT, GL_MIN and GL_DIFFERENCE_NV
  • glBlendFunc

这是我的代码...

//const tex init
constTex[0] = makeTex() with 1, 1, 1...
constTex[1] = makeTex() with 1, 2/3, 1/3...
constTex[2] = makeTex() with 3, 3, 3...
constTex[3] = makeTex() with 6, 6, 6...
constTex[4] = makeTex() with 1/255, 1/255, 1/255...
constTex[5] = makeTex() with 255, 255, 255...
constTex[6] = makeTex() with 1/2, 1/2, 1/2...
constTex[7] = makeTex() with 0, 0, 0...

...

fbo[0] = makeFBO() with GL_RGB
fbo[1] = makeFBO() with GL_RGB32F
fbo[2] = makeFBO() with GL_RGB32F

...


hsv[0] = loadTex() hue
hsv[1] = loadTex() value
hsv[2] = loadTex() saturation

...

fbo[1].bind();
glDisable(GL_BLEND);
draw(hsv[0]); //start with hue
glEnable(GL_BLEND);
glBlendEquation(GL_FUNC_ADD);
glBlendFunc(GL_ONE, GL_ONE); //add
draw(constTex[1]); //(1, 2/3, 1/3)
glBlendFunc(GL_ONE, GL_ONE);
fbo[1].unbind();

//compute integer part
fbo[2].bind();
glDisable(GL_BLEND);
draw(*fbo[1].colour[0]); //copy the last bit
glEnable(GL_BLEND);
glBlendEquation(GL_FUNC_REVERSE_SUBTRACT);
glBlendFunc(GL_ONE, GL_ONE); //subtract
draw(constTex[6]); //0.5
glBlendEquation(GL_FUNC_ADD);
glBlendFunc(GL_ZERO, GL_SRC_COLOR); //scale down
draw(constTex[4]); //1/255
fbo[2].unbind();

fbo[0].bind(); //floor to integer
glDisable(GL_BLEND);
draw(*fbo[2].colour[0]);
fbo[0].unbind();

fbo[2].bind(); //scale back up
glDisable(GL_BLEND);
draw(*fbo[0].colour[0]);
glEnable(GL_BLEND);
glBlendEquation(GL_FUNC_ADD);
glBlendFunc(GL_ZERO, GL_SRC_COLOR); //scale up
draw(constTex[5]); //255
fbo[2].unbind();

//take integer part for fractional
fbo[1].bind();
glEnable(GL_BLEND);
glBlendEquation(GL_FUNC_REVERSE_SUBTRACT);
glBlendFunc(GL_ONE, GL_ONE); //subtract
draw(*fbo[2].colour[0]); //integer part
glBlendEquation(GL_FUNC_ADD);
glBlendFunc(GL_ZERO, GL_SRC_COLOR); //scale
draw(constTex[3]); //6
glBlendEquation(GL_FUNC_REVERSE_SUBTRACT);
glBlendFunc(GL_ONE, GL_ONE); //subtract
draw(constTex[2]); //3
glBlendEquation(GL_DIFFERENCE_NV);
glBlendFunc(GL_ZERO, GL_ONE); //take the absolute
draw(constTex[7]); //0
glBlendEquation(GL_FUNC_REVERSE_SUBTRACT);
glBlendFunc(GL_ONE, GL_ONE); //subtract
draw(constTex[0]); //1
glBlendEquation(GL_MIN);
glBlendFunc(GL_ONE, GL_ONE); //clamp (<0 doesn't matter, >1 use min)
draw(constTex[0]); //1
glBlendEquation(GL_FUNC_ADD);
glBlendFunc(GL_ZERO, GL_SRC_COLOR); //scale
draw(hsv[1]); //saturation
glBlendEquation(GL_FUNC_ADD);
glBlendFunc(GL_ONE, GL_ONE); //add
draw(constTex[0]); //1
glBlendEquation(GL_FUNC_REVERSE_SUBTRACT);
glBlendFunc(GL_ONE, GL_ONE); //subtract
draw(hsv[1]); //saturation
glBlendEquation(GL_FUNC_ADD);
glBlendFunc(GL_ZERO, GL_SRC_COLOR); //scale
draw(hsv[2]); //saturation
fbo[1].unbind();

fbo[1].blit(); //check result
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用混合模式重新创建 HSV 颜色 的相关文章

  • Android:连接和彩色阿拉伯字母

    我想显示已连接ANDandroid 视图 webview 或 textview 上的彩色阿拉伯字母 首先 我使用了没有颜色的 TextView 并且阿拉伯语显示正确 当我使用 spannableString 时 彩色字母与单词断开 其次 我
  • 如何在 WPF 中的窗口上绘图(最佳实践)?

    我正在尝试编写一个类似交互式游戏的小型应用程序 我需要有一个Draw方法将在屏幕上绘制 但无法弄清楚如何构造 WPF 的方法 如果这是Winforms 我可以使用 public void Draw Graphics g 但对于一个WPF W
  • 适用于 Littler 或 Rscript 的外部图形设备

    我真的很喜欢 Littler 对于使用 R 编写脚本非常有用 但我不知道如何使用 gnuplot 中的外部图形设备 例如使用 Octave 我能够生成所需的图表 但我必须使用 Sys sleep 并且我不想这样做 因为我想以交互方式自行关闭
  • 使用 WinForms 绘制宽线时出现 OutOfMemoryException

    这个太疯狂了 我只画了几千条线OnPaint处理程序 没有问题 当pen Width lt 1 或者当屏幕上没有很多行时 好的 我画了一张比例尺地图 线宽随地图缩放 当我缩放一些地图时 我得到OutOfMemoryException WHY
  • Zsh 颜色部分制表符补全

    是否可以在Zsh中对部分完成结果的已完成部分进行着色 Fish 默认执行此操作 至少在 Gentoo 中 如下图所示 全尺寸图像 https i stack imgur com KaL1g png https i stack imgur c
  • 在 Mathematica 中创建具有不同颜色边的图形

    我想创建一个图 图论 其中某些边具有与其他边不同的颜色 这将用于突出显示图中从一个顶点到另一个顶点的路径 以下是一些具有不同颜色边缘的示例http demonstrations wolfram com AGraphTheoryInterpr
  • OpenGL 的每个组件 alpha 通道?

    是否可以使用 OpenGL 对每个组件使用一个 alpha 通道 一个用于红色 一个用于绿色 一个用于蓝色 进行混合 如果没有 有哪些可能的解决方法 这不是直接支持的东西 不过 您自己实现起来相当容易 使用 3 通道 alpha 纹理渲染三
  • MATLAB:生成给定三种颜色的颜色图

    我正在尝试在 MATLAB 中生成给定三种颜色 最高值 零值和最低值 的颜色图 我的思维过程是从最高端到中间循环 并将每个步骤存储到一个 3xN 第一列是 R 第二列是 G 第三列是 B 矩阵 所以我正在使用 fade from high
  • 如何使用 OpenCV 找到红色区域? [复制]

    这个问题在这里已经有答案了 我正在尝试编写一个检测红色的程序 然而有时它比平常更暗 所以我不能只使用一个值 检测不同深浅的红色的最佳范围是多少 我目前使用的范围是 128 0 0 255 60 60 但有时它甚至检测不到我放在它前面的红色物
  • PowerShell 中一个命令中的多个前景色

    我想用一个语句输出许多不同的前景色 PS C gt Write Host Red ForegroundColor Red Red 该输出为红色 PS C gt Write Host Blue ForegroundColor Blue Blu
  • 如何随机获得Material Design Color?

    谷歌有他们的颜色 指南 http www google com design spec style color html 那么如何随机接收一个颜色呢 有没有办法指定表中的数字并从表的所有颜色中接收随机颜色 例如getMatColor 100
  • ggplot2 使用 geom_line 手动指定颜色

    我正在尝试绘制下面的图表 并想手动指定颜色 我需要按基因型绘制 因为有多个基因型属于同一个 Bgrnd All 并且我希望它们在绘制的线条中单独出现 但是 我想按 Bgrnd All 对线条进行着色 特别是按照我在 scale fill m
  • 如何创建热图来说明控制发散调色板中心颜色位置的网格差异?

    我有两个人脸 3D 网格 我希望使用热图来说明差异 我想使用红蓝发散色阶 我的数据可以查到here https github com Patricklv How to create heatmap illustraing 3D mesh d
  • opencv 视频上的颜色阈值

    I am thresholding for a color range in an opencv video The goal is to seperate the B mode black and white information on
  • 如何为十六进制颜色字符串创建独立类型?

    我正在尝试在 TypeScript 中创建一个独立类型 可用于将单个有效的十六进制颜色代码表示为完全类型安全的字符串 我的尝试如下 但由于实际上不是独立类型而未能实现 而这正是我希望实现的目标 type HexDigit
  • 如何设置评分栏的星星颜色?

    如何设置评分栏的星星颜色 我想要黄色星星 最简单的方法 android progressTint color color 光滑有光泽
  • 合并空间上接近的路径/线段的算法

    我正在寻找一种用于街道地图制图概括的几何算法 名称 在我的地图数据中 我有许多路径 点的有序列表 由线段连接 这些路径彼此靠近且几乎平行 我如何 1 识别这些 相邻路径 即如何找到比某个阈值更接近的路径 以及 2 将它们合并成一条路径 即如
  • CSS:为表格中选定的行设置颜色

    我需要将以下功能添加到我的表中 当用户单击一行 选择它 时 该行会用颜色标记 FFCF8B 与hover 我试过 newspaper b tbody tr selected td 但它不起作用 newspaper b border coll
  • 如何在ggplot2中使用希腊符号?

    我的类别需要用希腊字母命名 我在用ggplot2 并且它与数据配合得很好 不幸的是 我无法弄清楚如何将这些希腊符号放在 x 轴上 在刻度线处 并使它们出现在图例中 有什么办法可以做到吗 更新 我看了一下link https github c
  • 每个刻度标签都有不同的颜色

    我正在尝试使用 matplotlib python 3 5 创建一个散点图 其中 x 轴上的每个刻度都有不同的颜色 这怎么可能 例如 假设 x 刻度为 Mo Tu We Th Fr Sa Su 现在我希望 Mo 是绿色的 Tu 是蓝色的 等

随机推荐

  • 日期自然语言解析器(.NET)?

    我希望能够让用户使用自然语言 例如 下周五 每个工作日 输入日期 包括重复日期 很像以下的例子http todoist com Help timeInsert http todoist com Help timeInsert I found
  • RecyclerView 中的共享元素转换

    我试图在 RecyclerView 上使用共享元素转换 但它似乎不起作用 这是我使用的适配器的一部分makeSceneTransitionAnimation public void onBindViewHolder final BookVi
  • Safari ITP 2.0 存储访问 API - 在 hasStorageAccess 中嵌套 requestStorageAccess 时出现问题 - 非嵌套工作

    我目前正在尝试实现调用存储访问 API 但在将 requestStorageAccess 的调用嵌套在 hasStorageAccess 中时遇到问题 这是代码的概要 它相当标准 requestStorageAccessAndServe l
  • 如何在 Haml 中撤消 Rails 模板生成?

    我在 Rails 项目中安装了一个新的 gem phrasing 它对多个 Haml gem 具有 gem 依赖性 我需要 gem 它为我的项目添加了一些惊人的功能 并且需要安装依赖项 但是现在当我运行rails generate scaf
  • Slick - 更新完整对象或超过 22 列

    我有一张桌子user permissions其中有 46 个权限列以及id and created date 这个表有对应的UserPermissions class class UserPermission val id Long val
  • C# 中 anagram 函数的实现

    可能的重复 有什么简单的方法可以判断单词列表是否是彼此的字谜 https stackoverflow com questions 522112 what is an easy way to tell if a list of words a
  • SOLR 权限/根据访问权限过滤结果

    例如 我有文档 A B C 用户 1 必须只能看到文档 A B 用户 2 必须只能看到文档 C 是否可以在 SOLR 中执行此操作而不通过元数据进行过滤 如果我使用元数据过滤器 每次访问权限发生变化时 我都必须重新索引 2012 年 2 月
  • Spring 注入 - 访问构造函数中注入的对象

    我有一个资源 Spring bean 它的一些字段是由 Spring 注入的 例如 Repository value appDao public class AppDaoImpl implements AppDao PersistenceC
  • 有没有办法将 __len__ 或 __eq__ 等方法实现为类方法?

    它很容易实现 len self Python 中的方法 以便它处理len inst 像这样的调用 class A object def len self return 7 a A len a gives us 7 您可以定义很多类似的方法
  • 在时尚中排除网站的子文件夹?

    有没有办法使用 Stylish 排除网站的子文件夹 moz document domain www website com 将会影响 website com 的所有页面 问题是 这个网站还托管一个维基 www website com wik
  • 如何在我的网站上显示我的 Instagram feed?

    我有一个网站 可以显示我的 Instagram 动态 以前我用过 Instagram 遵循 API 用户 自我 媒体 最近 这个 API 使用的是我生成的一次访问令牌 并将其作为变量保存在我的代码中 并且很长一段时间 2 3 年 都没有更改
  • 在 Javascript 中将小数金额转换为文本字符串分数?

    我有一个以数字形式返回的值 可以是十进制数 例如 1 15 但是 我需要格式化所有数字在一个范围内到给定的分数 例如 所有大于 0 但小于 0 2 的数字我想返回 1 8 我已经开始将其作为一系列 if else 语句来执行此操作 但我想知
  • DTO 接口

    我目前正在开始开发一个大型 Web 应用程序 主要包含 Angular SPA 和可以访问后端层的 OData WebAPI 我们正处于早期阶段 并已开始实施第一批课程 包括Model dll它位于公共名称空间中 以便所有层都可以访问它 我
  • Prometheus:如何根据 Consul 标签删除目标

    我的 Prometheus 服务器从 Consul 获取其目标列表 或 服务 用 Consul 的行话来说 我只想监视这些目标的子集 这应该可以通过普罗米修斯的正则表达式机制实现 但我无法正确配置 这是怎么做到的 我已经搜索过网络 但没有一
  • 如果原始值与任何when_表达式都不匹配,则返回原始值

    我的 SQL 导出字段上有一行 并且我试图删除字段中返回的空白值 如果它与姓氏中的 AMA 完全匹配 但是 当我使用当前代码导出文件时 姓氏不带 AMA 的名称将被完全删除 Max Orders ShipFirstName CASE Ord
  • 如何在不编写 20 个 if 语句或创建 20 个列表/字典的情况下进行以下比较?

    这个问题与生物学有关 所以对于那些知道氨基酸和密码子是什么的人来说 那就太棒了 对于那些不明白的人 我已尽力表述 以便您能够理解我在说什么 所以我有一个密码子列表 也可以称为3字母字符串 由以下四个字母的组合组成 A G C T 即AAT
  • 如何使用 jQuery 设置输入框的默认值?

    我想更改输入框的默认值 以便在重置表单时保留该值 我有以下代码 它使用 jQuery 设置一个值 但当按下重置时 该值将变为初始值
  • typescript 对 setState 与用户输入进行反应

    在这个打字稿反应 create react app 的基本示例中 我试图通过用户输入更改state name 有人可以向我展示一个工作示例 我没有找到 或更好的示例 文档在哪里 linter 的 第二个 错误是 54 24 错误 TS232
  • 为什么这个 Snowflake 查询不需要 LATERAL 关键字就可以工作?

    我在雪花中有这样的观点 create or replace view foo as select 1 as id foo 2 as sales from values 1 100 2 200 3 300 和这个用户定义的表函数 https
  • 使用混合模式重新创建 HSV 颜色

    我正在开发一个应用程序 该应用程序创建的图像的色调 饱和度和值根据不同的参数而变化 出于性能原因 单独渲染色调 饱和度和明度组件 然后使用 Photoshop 风格的混合模式 正片叠底 叠加 滤色 色调等 将它们合成在一起是有意义的 我已经