<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />下面的 JSL 创建两个位图:彩虹色背景和 Mandelbrot 形状蒙版。两个位图被添加到图形中,并且彩虹在蒙版下移动。它非常快,因为位图仅创建一次,并且操作系统提供对遮罩透明孔的支持。
遮罩中的透明孔是使用 alpha 层创建的,与红色、绿色和蓝色层类似。Alpha 是一个介于 0 和 1 之间的数字,用于确定在先前绘制的像素之上渲染时像素的透明/不透明程度。在此示例中,alpha 为零(透明)或一(不透明)。您可以将位图与中间值混合。
JSL 的内联版本经过调整,用于制作视频的位图。附加文件在运行时看起来可能会更好一些,因为它使用计时器来确定接下来要显示的帧。
克雷格·黑尔斯 - YouTube
https://www.youtube.com/watch?v=NA-O0YbehpQ
// 此示例演示了制作带孔图像的一种方法。
// 大多数图像只使用红色、绿色和蓝色(如背景彩虹)
// 下图)。一些图像添加 Alpha 作为第四个通道来描述
// 不透明或透明。JMP 使用 1 表示不透明。
//
规模= 35; // 整体尺寸
nr = 20 * 规模; // 纵横比
nc = 25 * 比例; // 纵横比
// 像素最初构建在矩阵中,使用 J 函数分配
传输 = J( nr, nc, 0 );
// 使用 mandelbrot 函数填充像素。使用并行分配
// 为了速度而不是嵌套循环。
并行分配(
{nr = N 行( transp ), nr2 = N 行( transp ) / 2,
nc = N 列( transp ), nc3 = N 列( transp ) / 1.3333, limit = 1000},
transp[r, c] = Mandelbrot( limit, 4, // 从 1..limit 返回整数答案
2 * (c - nc3) / Sqrt( nr * nc ), // 将矩阵行、列缩放到感兴趣的空间
2 * (r - nr2) / Sqrt( nr * nc ) ) / limit // 除以极限比例 0..1
);
// 下一行是重要的一行。该图像是使用 4 个数据通道创建的,
// 红色、绿色、蓝色和 Alpha。因为 r、g、b 使用相同的“transp”值
// 图像是灰度的,但由于来自 Mandelbrot() 的数据,你不会看到太多
// 蒙版中的灰色...只有黑色。将 2nd transp 更改为 1-transp 你会看到
// 绿色蒙版。但重要的参数是 transp<.5,它创建了 alpha
// 渠道。transp 是一个由 0 到 1 之间的值组成的矩形矩阵;高价值
// 是曼德尔布罗集合内的平坦区域,低值在外部。转运<.5
// 外部为 true,即 1,内部为 false,即 0。这使得一个矩形阵列
// alpha 为 0 或 1:1 是遮罩,0 是透明。(alpha 可以是小数
// 这将混合位图。这里不使用它。)
transpImage = 新图像( "rgba", {transp, transp, transp, transp < .5} );
// 此示例不使用保存的图像,但您可以像这样使用 png
// 例如,如果您使用 Gimp 打开它,则保存具有透明度。
// 测试: transpimage << saveimage( "\\VBOXSVR\windowsShare\transparent\test.png", "png" );
// 创建一个窗口来保存动画和一个图形框来保存位图。
// 在 JMP 中展示透明位图的最佳选择是在图表中
// 因为其他带有位图的显示框并不真正希望彼此重叠。
新窗口(“透明度”,
gb = Graph Box(framesize( nc + 20, nr + 20 ), // 周围有 10 像素彩虹边框
<<背景颜色(“红色”))); // 在添加第二张图像之前您可能会看到红色
// 将第一张图像插入帧中并获取图像片段的句柄
gb[framebox( 1 )] << addimage( 图像( transpimage ) );
transpSeg = gb[framebox( 1 )] << childseg;
// 定位它;这个“面具”只被定位一次,就在这里
transpSeg << 移动( 50, 50 );
//
//
// 制作第二个没有任何透明度的彩虹图像
背景 = J( nr * 2, nc * 2, 0 ); // 滚动的额外内容。制作一些彩虹像素...
并行分配(
{nr = N 行(背景),nc = N 列(背景)},
背景[r, c] = RGB 颜色( (Sin( r / 70 ) + 1) / 2, (Sin( c / 50 ) + 1) / 2, Sin( (r + c) / 60 ) )
);
// 将像素转换为位图图像,添加到帧中,获取句柄
背景图像 = 新图像(背景);
gb[framebox( 1 )] << addimage( 图像( 背景图像 ) );
背景段 = gb[framebox( 1 )] << childseg;
//
wait(.1);// 确保窗口在循环开始之前打开
//
开始=0; // 利用时间来创建更流畅的动画
帧=0;
while( start < 30, // 运行 30 秒
位置=开始; // 用作 sin 和 cos 的弧度参数...
开始=开始+1/30;
x = 50 + 50 * Sin( 位置 * .39 ); // 使用任意缩放
y = 50 + 50 * Cos( 位置 * .27 ); // 艺术许可
// 好吧,这很笨拙;看来移动方法需要帮助评估......
// EvalExpr 查看其参数并搜索要计算的 Expr。
// EvalExpr 返回一个仍需要计算的表达式
Eval( Eval Expr(backgroundseg << move( Expr( x ), Expr( y ) ) ) );
// gb<<无效;等待(0);动画因等待而变得不完整(允许交互)
gb << 更新窗口; // 这是非常流畅的动画,但不是交互式的
//制作图片:gb << savepicture("\\VBOXSVR\windowsShare\transparent\v\v"||right(char(frame++,9),9,"0")||".png", "png" );
);
//
// 更多想法(未经测试,让我们知道会发生什么):
// 设置图形框的 xscale 和 yscale 以匹配帧大小
// 如果你想以精确的像素工作。
// 尝试使用 0.5 左右的 alpha 值来混合图像。
// 将图中其他要绘制的线段排列在 mask 线段之前;
// 标记段可以通过掩模中的孔出现。电影双筒望远镜。
// 移动掩码而不是数据。
// 具有透明度的多层。使用视差理念的侧滚轴。
// 使用 MouseTrap 拖动蒙版。
// 尝试旋转蒙版,也许还可以使用 MouseTrap,具体取决于单击的距离
// 从掩模的中心开始。