- 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:
在上面的例子中有一个非常小的矩阵。它有 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。
这将使图像的 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
同时缩放 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 易患上癔症……不妨入群互助
👇👇👇
公众号:ArtxCode
网友评论