在JSL脚本中嵌入图像时不时出现一个问题,引发了足够多的讨论,我认为这值得写一篇博客文章。这次围绕JMP虚拟水冷却器的讨论主题是在JSL脚本中包含图像的想法。不久前发生了类似的讨论,促使我写了一篇博客文章,名为如何在JMP 9中将图像添加到图形 。但是这一次,最初的问题和随后的讨论特别询问了有关将图像嵌入脚本的问题,以使脚本不依赖于外部图像文件。一个电子邮件线程在星期二开始,在星期三它进入了我的收件箱。到星期五,我仍然看到对该主题的更多回复。我决定在JMP中是否有很多兴趣,当然在整个 JMP 用户社区。
那么,您可以将图像嵌入JSL脚本中,从而不再需要原始图像文件吗?答案当然是是 。(如果不是的话,我就不会写这篇博客文章!)具有讽刺意味的是,关于嵌入图像的整个讨论都在我写我的最后一篇博客文章的同时进行,使用图像为数据添加上下文 。因此,让我们从那个遗漏的地方开始。
在该博客文章中,我使用了JMP数据表来生成双变量图。该图包括显示风速和风向的箭头。然后,我在图中添加了图像。该图像是密歇根湖周围风向发生的区域的地图。如果要保存图形,可以使用小红色三角形(lrt)并选择“脚本”->“将脚本保存到脚本窗口”。这将编写必要的JSL,以重现整个图形。如果这样做,我将看到以下代码。(这只是实际代码的一部分。)
添加图片(
设置Blob(
炭烧面包 (
“ 625799eJM // 9WNs7G2 + 0s6euR1e ... Ix0RcMtzpWCTfj / AXh1fKw =“,
“ base64compressed”
),
“ png”
),
界线(
剩下 (- 90.96 ),
对 (- 84.02 ),
最佳 ( 44.97 ),
底部 ( 39.04 )
)
),
如果你读如何在JMP 9中将图像添加到图形 ,您将识别“添加图像”命令。但是在该示例中,我使用了文件引用,这意味着JSL依赖于外部映像文件。在此示例中,我们使用的是一个斑点 。Blob是一长串字符数据,已使用base64压缩进行了压缩。这是在脚本内部将图像存储为像素数据的最小方法。顺便说一句... 字符串中间的“是”表示为了简洁起见,大部分字符串已被删除。实际的字符串比我在这里显示的要长得多。除了压缩的字符数据外,图像类型也被写入。这样,在读取脚本时,JMP知道如何解释存储在Blob中的字符数据。这样做的好处是,我可以生成所需的图形,然后使用“将脚本保存到脚本窗口”获取JMP来为我生成压缩的字符数据。我不必自己弄清楚该怎么做。真好!
此时,您可能想知道脚本文件现在有多大。好吧,就我而言,没有嵌入图像的脚本为1 KB。图像文件是PNG文件,大小为26 KB。因此,两个文件的总和为27 KB。如果我将图像嵌入脚本文件并将其保存到磁盘,则脚本文件现在为34 KB。因此,包含图像的脚本大于两个单独文件的总和。但是,我不得不承认,我惊讶的是它的体积并不大。PNG文件是压缩像素数据的二进制文件。脚本中嵌入的图像被写为ASCII字符。因此,我希望脚本会更大。我想不同的图像会有不同的结果。换句话说,您的里程可能会有所不同。
现在,我可以与其他人共享我的JSL脚本,当他们在JMP中运行它时,他们将看到我的图形以及图像。而且他们不会在日志中看到错误消息,指出找不到图像文件。
希望您喜欢这个小技巧,并且一如既往,请让我知道您的想法。
约翰·庞特(John Ponte)写道:我在这里展示的技术是经过设计的...约翰·庞特写道:
我在这里展示的技术旨在处理图像,例如JPG或PNG。但是在Mac上,pdf被认为是图像格式。因此,您可以通过使用Open()命令将图像添加到图形中,并将pdf指定为外部图像,从而将pdf转换为blob。请参阅上面的“如何在JMP 9中将图像添加到图形中”以了解如何执行此操作。然后将该脚本保存到脚本窗口,该窗口会将pdf转换为blob。然后,您可以使用blob作为图像源编写自己的脚本来显示图像。一旦有了斑点,就可以摆脱创建的原始图形。这只是使pdf成为斑点的一种方法。那有意义吗?
马克·西普洛隆(mark cipollone)写道:约翰,是否有可能嵌入eithe ...标记西普龙写道:
约翰,
是否可以在某个位置的JMP文件中嵌入PDF或Powerpoint文件?我想做的是嵌入文件,然后允许用户通过表脚本启动/查看文件。这个想法是添加一个“单击此处获取更多信息”表脚本。当用户单击它时,将启动PDF或Powerpoint文件,它将显示JMP文件的更多详细信息。我喜欢嵌入它的想法,因为沿着单独的文件拖动总是很乱。
谢谢Mark Cipollone。
约翰·庞特(John Ponte)写道:嗨,阿米特(Amit),要转换回去,您只需...约翰·庞特写道:
嗨,阿米特,
要转换回去,您只需要知道您的宽度和高度即可。图像具有宽度和高度,但是数据表具有一定数量的行和列。但是列的数量对应于唯一变量的数量,而不是图像的尺寸之一。如果您使用我之前提供的代码,则可以从原始图像知道宽度和高度。如果您仍然没有这些值,但是您知道您是根据上面的代码创建的数据表,则可以在X和Y列中查找最大值,这将为您提供宽度(最大值Y)和高度(最大X)。使用该技术,可以对这两列中的值进行假设,但是我们知道,如果您根据上面的代码创建了数据表,则该假设是正确的。
因此,考虑到这一点,下面是重新创建图像的代码:
//逆向处理-从数据表中重新创建图像
//创建三个矩阵(用于像素颜色)
r2 = J(numRows,numCols);
g2 = J(numRows,numCols);
b2 = J(numRows,numCols);
//保存每个像素的r,g,b值
对于每一行(
r2 [:y,:x] =:R;
g2 [:y,:x] =:G;
b2 [:y,:x] =:B;
);
//保存新图片
img2 = NewImage(“ rgb”,{r2,g2,b2});
img2 << saveImage(“ C:\ JMP \ images \ newImage.png”,png);
注意,我在变量前面使用了“ 2”。您可以像以前一样重用相同的变量,但是我想测试我的代码并确保它能正常工作。如果您重复使用相同的变量,则无需担心宽度和高度或再次创建矩阵。实际上可能有一种更有效的方法来执行此操作,但这是使我无法自拔的解决方案。另外,请注意我将图像另存为PNG。您也可以使用其他格式,例如JPG。
顺便说一句-我的电子邮件是John.Ponte@jmp.com
请享用!
阿米特·博特拉(Amit Bothra)写道:嗨,约翰,谢谢您的答复。我有...阿米特·博特拉写道:
你好,约翰,
谢谢回复。我还有一个要求。如何将表格转换回图像。该表包括以下列:Y,X,R,G,B。
您有可以通过以下方式与您联系的jmp电子邮件吗?
问候,
阿米特
约翰·庞特(John Ponte)写道:嗨,阿米特(Amit),这肯定是可能的,她...约翰·庞特写道:
嗨,阿米特,
这肯定是可能的,这是JSL可以做到的:
//打开/读取图像到JMP
img = NewImage(“ $ SAMPLE_IMAGES \ tile.jpg”);
//获取颜色值作为3个不同的矩阵
{r,g,b} = img << getPixels(“ rgb”);
//获取图像/矩阵的尺寸
numRows = nrow(r);
numCols = ncol(r);
//创建数据表
dt =新表格(“像素数据”,
newColumn(“ Y”,设置值(shape(repeat(1 :: numRows,numCols)`,numCols,numRows))),
newColumn(“ X”,设置值(repeat(1 :: numCols,numRows))),
newColumn(“ R”,设置值(r)),
newColumn(“ G”,设置值(g)),
newColumn(“ B”,设置值(b)),
);
x和y值是图像中的像素位置。r,g和b值是归一化颜色空间(值介于0.0和1.0之间)中每个像素的颜色分量。只需更改第一行以引用您自己的图像,就可以了。尽管您可能还想更改数据表的名称。
如果您还有其他疑问和好运,请告诉我!
约翰
阿米特·博特拉(Amit Bothra)写道:嗨约翰,我想创建一个数据集。阿米特·博特拉写道:
你好,约翰,
我想从具有以下列的图像创建数据集:X,Y,r,b,g,其中X和Y是坐标,R,G和B是颜色。这在JMP中可行吗?
我的想法是在其上运行K均值集群。我的来源是 http://lamages.blogspot.com/2012/12/now-i-see-it-k-means-cluster-analysis.html#more
问候,
阿米特
Zoe Jewell写道:非常整洁!我特别喜欢JM的方式...佐伊·杰威尔(Zoe Jewell) 写道:
井井有条!我特别喜欢JMP可以生成压缩字符数据的方式。