<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 函数分配
transp = J( nr, nc, 0 );
// 使用 mandelbrot 函数填充像素。使用并行分配
// 为了速度,而不是嵌套循环。
并行分配(
{nr = N 行( transp ), nr2 = N 行( transp ) / 2,
nc = N Cols( transp ), nc3 = N Cols( 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。因为相同的“transp”值用于 r,g,b
// 图像是灰度图,但由于来自 Mandelbrot() 的数据,你不会看到太多
// 面具中的灰色......只有黑色。将 2nd transp 更改为 1-transp,您会看到
// 绿色遮罩。但重要的参数是 transp<.5,它创建了 alpha
// 渠道。transp 是值介于 0 和 1 之间的矩形矩阵;高价值
// 是 mandelbrot 集内的平坦区域,低值在外面。传输<.5
// 在外部为真或 1,在内部为假或 0。这使得矩形阵列
// 0 或 1 的 alpha:1 是遮罩,0 是透明的。(alpha 可以是小数
// 这将混合位图。这里不使用它。)
transpImage = New Image( "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( image( 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 ) )
);
// 将像素转换为位图图像,添加到框架,获取句柄
backgroundImage = 新图像(背景);
gb[framebox( 1 )] << addimage( image( backgroundImage ) );
backgroundSeg = gb[framebox( 1 )] << childseg;
//
wait(.1);// 确保窗口在循环开始之前打开
//
开始= 0; // 使用时间来创建更流畅的动画
帧=0;
while( start < 30, // 运行 30 秒
位置=开始; // 用作 sin 和 cos 的弧度 arg ...
开始 = 开始 + 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 值来混合图像。
// 将图中其他要绘制的线段安排在遮罩线段之前;
// 标记段可以通过掩码中的孔出现。电影望远镜。
// 移动掩码而不是数据。
// 具有透明度的多层。使用视差想法的侧滚动条。
// 使用 MouseTrap 拖动遮罩。
// 尝试旋转蒙版,也许也可以使用 MouseTrap,具体取决于点击的距离
// 是从面具的中心。