- Max/MSP/Jitter 教程 01 - 什么是矩阵?
- Max/MSP/Jitter 教程 02 - Jitter 对象的属性
- Max/MSP/Jitter 教程 03 - 播放 QuickTime 视频
- Max/MSP/Jitter 教程 04 - 创建矩阵
- Max/MSP/Jitter 教程 05 - 矩阵的数学运算
- Max/MSP/Jitter 教程 06 - 控制视频播放
- Max/MSP/Jitter 教程 07 - ARGB 颜色
00 翻译自 Cycling74 的 Max/MSP/Jitter 官方文档:Tutorial 6: Adjust Color Levels
jit.scalebias
本教程进一步讨论了上一章的颜色话题,并介绍专门用于修改矩阵 ARGB 颜色平面的对象:jit.scalebias
。
“scale” 是缩放因子,乘以给定的数值。”bias” 是加上一定的量来偏移某个值。组合乘法和加法,可以实现输入值到输出值的线性映射。
因为 jit.scalebias
修改图像中的 ARGB 颜色信息,所以它只处理 char 数据类型的 4 平面矩阵。(有关 ARGB 颜色和 char 数据的内容,请参阅 教程 7)
用 char 类型数据计算
前一章讲到,char (8位)数据可以表示 0~255 之间的整数值,或 0~1 之间的小数值。比如在教程 4 中,我们用 jit.print
输出 0~255 的整数值。但是很多时候要修改矩阵的 char 值(更改其中一个属性)时,Jitter 对象只接收浮点数属性值。这可能有点费解,让我们来看看本教程的 patch。
打开教程 patch。双击打开中间的 explain_scalebias
查看子 patch:
char 数据的浮点类型演示
在上面的例子中有一个非常小的矩阵。它有 4 个 char 平面,但只有一个单元。这样我们只需要注意矩阵中单个数值的变化。已将平面 2(绿色平面)的值设置为 100。在右侧,把整数值转换为 0~1 之间的小数值:用 100/255,得到 0~1 之间的值 0.392。
jit.scalebias
对象乘上指定的缩放因子,然后再加上偏移因子。jit.scalebias
计算时会把所有值看做浮点数,然后再转换为 char 数据重新存储到矩阵中。
这里用 scale 2.0
和 bias 0.2
消息来设置缩放和偏移因子。缩放因子(乘数)是 2.0,偏移因子(之后添加的偏移)是 0.2。为了了解 jit.scalebias
内部机制,将绿色值看做 0.392 x 2.0 + 0.2
,等于 0.984。jit.iter
对象逐一输出每个单元中每个平面的值(矩阵只有一个单元),(以 char 类型存储在矩阵中)为 251(或是 0~1 范围的 0.984)。
(作为练习,请计算 jit.scalebias
在上面例子中在红色和蓝色平面中产生的值。在原矩阵中这些平面的值为 0,因此结果矩阵中的值将为 0 x 2.0 + 0.2 = 0.2
,在 0~255 的范围内等于 51。因此底部的 jit.pwindow
对象显示的 RGB 值是 51 251 51)
更多例子
如果前一部分的讲解你已经理解得很清楚,可以跳过这部分。如果还是不太清楚 char 数据(特别是 jit.scalebias
)的数学运算是如何工作的,这里还有一些例子。
从左到右逐个点击 preset
对象中的每个预设值。下面我们解释每个预设。
原始矩阵的绿色平面中的值为 255.(相当于 0~1 范围的 1.0)
jit.scalebias
将其乘以 0.5 得到 127.5; 但是将值存储为 char 时,jit.scalebias
会截断小数部分,将值存储为 127。这产生了相当不精确的结果。(0~255 范围的 127 等于 0~1 范围内的 0.498,而不是我们期望的 0.5)但用 8 位 char 数据只能这样了。如果需要更高的精度,char 数据就不适合,需要用 long,float32 或 float64 数据的矩阵,以及
jit.op @op *
和jit.op @op +
对象。原始值为 100,将它加倍(缩放因子 2.0)会得到预期结果 200。这样不会有精度损失。
- 原始值为 100(0.392)。缩放 1.0 倍保持不变,然后加上 -0.2 (也就是减去 0.2)得到结果 49(即 0.192)。
0.392 x 2.0 + 0.2 = 0.984
。在 0~255 的范围内为 251。- 此示例和下一个示例说明当乘法和加法运算的结果超过 8 位字符的容量时会发生什么。
jit.scalebias
会直接裁剪结果为 char 的最大或最小值。这里,0.392 x 4.0 = 1.568(即 100x4 = 400),因此取上限为 255。 - 在另一个方向,0.392 - 0.5 = -0.108,因此结果为 0。
注意,这些误差和裁剪只发生在将结果重新存储为 char 时。在此之前,这些值在内部用浮点数计算,可以保证精度。即使乘法使内部值超出0~1 范围,也不会做裁剪,而且加法运算可以让其回到范围。这里 0.392 x 3.0(= 1.176)- 0.5 = 0.676。存储为 char 时会产生小的误差。0.676 在 0~255 范围内等于 172.38,但是小数部分会被截断并存储为 172(即 0.675)。如果没有变化,比例因子应为 1,偏移量应为 0。
你可以尝试更多的值,直到完全了解 jit.scalebias
以及 8 位 char 数据产生的结果。完成后关闭 [explain_scalebias] 窗口。
调整图像的颜色亮度
现在将 jit.scalebias
应用于彩色图像。在教程 patch 的左上角可以看到熟悉的配置:jit.movie
对象,加载视频的 read
消息,和从 jit.movie
触发 jit_matrix 消息的 metro
对象。在这个 patch 中,jit.scalebias
用乘法和加法来修改矩阵。
加载图片或视频
点击 read chilis.jpg
读取 JPEG 静态图像(而非视频)到 jit.movie
。QuickTime 可以处理各种媒体格式,包括 PICT 或 JPEG 格式的静止图像。jit.movie
将静止图像视为 1 帧长的视频。
jit.movie
的输出将传到 jit.scalebias
处理,然后显示在 jit.pwindow
中(现在先忽略 jit.matrix
对象。我们在本章后面讨论)。可以修改 jit.scalebias
的 scale 和 bias 属性来更改值。
点击开关启动 metro
。拖动 scale $1
消息框上方的数字框,将 scale 属性值增加到 1.25。
增加图像亮度; scale 值越大亮度越大
这将使图像的 4 个平面的所有非零值放大到 1.25 倍(增加 25%)。请注意,乘法会让较大的被乘数增加更多值。例如,如果原始矩阵中某单元格的红色值为 200,它将增加到 250(净增加 50),而同一单元格的蓝色值可能从 30 增加到 37(净增加 7)。
- 尝试将 scale 增加到非常大,如 20。原始矩阵中 13 或更大的值将被增大到最大值 255(甚至非常小的值也会增加到可见水平),产生人为的过度曝光。
- 尝试将 scale 降低到 0~1 之间。这会使图像变暗。scale ≤ 0 会将所有值设置为 0。
- 将 scale 属性恢复为 1。现在尝试调整 bias 属性,为矩阵中所有值添加常量。正值使图像变亮,负值使图像变暗。
以常量提升(或降低)亮度
还可以尝试几种更极端的 scale 和 bias 设置。设置 scale 为 40,bias 为 -20。这会将几乎所有值推到 255 或 0,除白色或黑色之外仅留下少数颜色。尝试设置 scale 为 -1,bias 为 1。高低值会互换,反转颜色。继续降低 scale(比如 -4 或 -8)会产生类似的反转,但只有原始值较低的值才会被正 bias 提升回 0~1 范围。
单独调整平面
你可以用 scale,abias,rscale,rbias 等属性在 jit.scalebias
中单独调整每个平面中的亮度。
将 scale 设置回 1,将 bias 设置回 0。然后提供新的值来独立调整每个颜色平面。
调整每个颜色平面的亮度
这里有一个可以同时调整三个颜色平面缩放比例的控制器,让过程更具交互性。单击或拖动 swatch
对象时,它发送一个表示鼠标所在位置 RGB 颜色值的列表。这些值之前以 0~255 范围表示,现在已经被改为 0.0~1.0 的值(如果需要,inspector 中有一个复选框可选择用旧样式输出)。用 unpack
拆分列表为三个单独的浮点数来改变 jit.scalebias
的 rscale,gscale 和 bscale 属性 。
用 swatch
的值作为 jit.scalebias
的属性
- 拖动
swatch
同时缩放 RGB 三个平面。这会产生 0~1 范围内的缩放值来降低所有亮度,让图像稍微变暗。 - 可以在不同图像上尝试这些操作。读取其他彩色图像如 colorswatch.pict 或 wheel.mov, 并尝试调整颜色亮度。
重新分配矩阵的平面
在上一个教程中,我们使用 jit.unpack
和 jit.pack
来重新组合矩阵的平面。使用 jit.matrix
对象的planemap
属性也可以做到。在这个例子中,用 jit.matrix
传递 jit.movie
的输出来演示如何设置 planemap
属性。
用 jit.matrix
重新分配矩阵的平面
jit.matrix
的 planemap
属性可以映射(分配)输入矩阵的任何平面到输出矩阵的任何平面上。planemap 后面跟的数字表示矩阵中有多少平面(在本例中为 4)。列表中的每个位置代表输出平面(第一个代表输出平面 0,第二个代表平面 1,等等),数字表示分配给它的输入平面。默认情况下,平面值为 0 1 2 3(等),输入矩阵中的每个平面都分配给输出矩阵中的同一平面。可以随意更改这些映射。例如,如果发送消息 planemap 0 3 2 1
给 jit.matrix
,会把输入平面 3 分配给输出平面 1(3 位于输出平面 1 的列表位置),把输入平面 1 输出到平面 3。这样就调换了图像的红色和蓝色平面。
点击
read wheel.mov
消息框并启动metro
显示视频。(设置jit.scalebias
scale 属性为 1,bias 属性为 0,就可以在jit.pwindow
中看到未改变的图像)在 patch 的右下角,单击planemap 0 3 2 1
消息框交换矩阵的红色和蓝色平面。单击消息框planemap 0 1 2 3
恢复正常的平面映射。如果设置所有 RGB 输出平面设置为相同的输入平面,将在三个 RGB 平面中得到相等的值,从而产生灰度图像。单击消息框
planemap 0 1 1 1
查看效果。三个 RGB 平面在列表中的值都是 1,因此原始的红色平面用来输出矩阵的所有 RGB 平面。用一个coll
对象存储所有平面映射的组合,发送到jit.matrix
来更改planemap
属性。双击 patcher
rotatecolorplanes
查看子 patch。里面有一个 1 到 6 的计数器,逐一执行主 patch 中coll
对象中的不同映射。(当它关闭时会发出数字 1 重置为默认平面映射)
点击主 patch
rotatecolorplanes
对象上方的开关,以每秒切换一次设置的速率,逐一执行不同的平面映射。将右输入口上方的数字框更改为较小的值(例如 80),查看快速重新分配平面的闪烁效果。
在下一章节中,你将了解如何使用 jit.hue
以更微妙的方式调整图像色调,以及使用 jit.brcosa
调整颜色的其他方法。
读取和导入图像
在本教程 patch 中,将三种不同类型的图像加载到 jit.movie
中:PICT 和 JPEG 静止图像,以及 QuickTime 视频。在视频对象中读入静止图像看起来有点奇怪,但 QuickTime 确实可以播放多种类型的媒体文件,jit.movie
知道如何读取它们。(jit.movie
还可以读入 AIFF 音频文件,用 start 和 stop 消息播放,用 time 属性跳转到不同的位置等等。当然这时看不到矩阵的任何视觉内容)
如教程 5 所示,用 importmovie
消息加载静止图像到 jit.matrix
中很方便。用这种方式导入 QuickTime 视频,只有一帧存储在 jit.matrix
中。
在这个 patch 中,我们用 jit.movie
加载所有图像。原因一是我们要加载整个视频(不只是视频的一帧)。原因二是想演示 jit.matrix
的 planemap 属性。矩阵有实际输入(左入口传入 jit_matrix 消息)时,planemap
属性才起作用。如果用 importmovie
直接导入图像到 jit.matrix
,planemap
不起作用。
小结
jit.scalebias
用乘法和加法来修改 4 平面 char 矩阵中指定的平面(或所有平面)的值。scale 是矩阵中的每个值要乘上的缩放因子;bias 是乘法之后被加到每个单元的值。scale 和 bias 属性影响矩阵的所有平面。如果想一次只影响一个平面,请使用特定的属性例如 ascale,abias,rscale,rbias 等。
必须用浮点数定义这些属性值。当执行乘法和加法运算时,jit.scalebias
将 char 值视为 0~1 范围内的小数值,使用 floats 执行数学运算,然后将结果转换回 char(0~255 之间的整数)并存储。超出 0~1 范围的结果,在转换回 char 之前截取为 0 或 1。
可以用 jit.matrix
的 planemap
属性重新分配矩阵的平面。planemap
的参数按顺序列出输出平面,列表中的值是要分配给每个输出平面的输入平面。例如,要将输入矩阵的平面 1 分配给输出矩阵的所有四个平面,属性应设置为 planemap 1 1 1 1
。
jit.scalebias
提供了强大的工具来调整 4 平面 char(ARGB 颜色)矩阵中的颜色值。下一章节将介绍更多此类工具。
友情提示:独自折腾 Max 易患上癔症……不妨入群互助
👇👇👇