JavaScript将画布转换为PGM
我正在尝试将JavaScript中的画布转换为pgm。 转换文件并下载到桌面后,它具有pgm扩展名,但当我用编辑器打开它时,它被编码为png。 我认为,如果JavaScript没有识别出您想要转换为的扩展,它会在默认情况下将其转换为png。 所以JavaScript可以转换成png、jpeg等格式,但不能转换成pgm 我的问题是,是否可以使用JavaScript将画布转换为pgm,如果没有,是否有任何可用的插件或Js库可以这样做JavaScript将画布转换为PGM,javascript,image,canvas,image-conversion,pgm,Javascript,Image,Canvas,Image Conversion,Pgm,我正在尝试将JavaScript中的画布转换为pgm。 转换文件并下载到桌面后,它具有pgm扩展名,但当我用编辑器打开它时,它被编码为png。 我认为,如果JavaScript没有识别出您想要转换为的扩展,它会在默认情况下将其转换为png。 所以JavaScript可以转换成png、jpeg等格式,但不能转换成pgm 我的问题是,是否可以使用JavaScript将画布转换为pgm,如果没有,是否有任何可用的插件或Js库可以这样做 function image_download() { c
function image_download() {
canvas = $('#canvas').get(0);
var image = new Image();
image.src = canvas.toDataURL("image/pgm");
var download = document.createElement('a');
download.href = image.src;
download.download = 'map.pgm';
download.click();
}
PGM编写器
要将画布另存为PGM,我只需查看文件格式的详细信息,并使用该信息创建一个函数,将画布转换为PGM bin
转化
该文件有一个描述文件和内容的头,然后是一个8位或16位值的二进制数组
因此,从标题开始,将其创建为字符串
const CR = "\n";
var header = "P5" // required
header += CR; // add whitespace char
header += canvas.width;
header += CR; // add whitespace char
header += canvas.height;
header += CR; // add whitespace char
标题不完整,但我们需要获得像素值的最大值,以便转换图像并找到最大值
因此,通过2D上下文获取像素数据
var imgData = ctx.getImageData(0,0,ctx.canvas.width,ctx.height);
对于所需的数据,您有几个选项。该格式为某些值指定对数刻度,为其他值指定线性刻度。如果维护gamma很重要的话,我将把它留给您来查找转换。(请注意,仅当您计划广播或保留光照值(如天文图像)时才需要)
有一个实用程序可以将线性函数转换为BT.709伽马函数。参见链接文档
我添加了一些简单的格式。两个为16位,最大值为3*255
如果要从jpeg编码的图像进行转换,最好先将像素RGB转换为HSL并仅将L保存为8位值,从而从图像中提取亮度,这将阻止jpeg劣质色调和饱和度数据影响结果(jpeg具有近乎无损的灰度数据)
如果您是从最初存储为jpeg(jpg)的图像中保存图像,则应使用此格式
format = formats.jpegLumPreserve;
感性的
因为总有一些聪明啊。。。需要兜售感知亮度转换的人,我也会补充,因为他们通常会弄错。因为我认为转换是一个古老的笑话,转换是基于2/7/1规则,在对数空间中完成的
formats.perceptual = {
convert (r, g, b) { bin[j++] = Math.sqrt(r * r * 0.2 + g * g * 0.7 + b * b * 0.1) | 0},
dataStore (w, h) { return new Uint8Array(w * h) },
}
这是基于成年人感知红色、绿色和蓝色三种原色的平均能力,并将灰色(亮度)结果与感知的颜色亮度匹配。我根本不知道这种格式,我相信大多数浏览器都不提供对其进行本机编码的选项,但是,从中,将您从中获得的
[rgba]
位图数组转换为PGM和PPM并不难。谢谢,您的回答帮助我找到了解决此问题的好方法,但方法不同。(对我迟来的答复表示抱歉)我认为这个回答掩盖了一些关键问题。根据我的理解,你的画布将是sRBG。有许多灰度公式可以应用,具体取决于您是否已将它们转换为线性(--Title:Color to grayscale:该方法在图像识别中是否重要?)。PGM要求709非线性伽马压缩合法,但该标准承认许多变体(es:线性rgb灰度)。
formats.jpegLumPreserve = {
convert (r, g, b) { bin[j++] = rgb2hsl(r + g + b).l},
dataStore (w, h) { return new Uint8Array(w * h) },
}
format = formats.jpegLumPreserve;
formats.perceptual = {
convert (r, g, b) { bin[j++] = Math.sqrt(r * r * 0.2 + g * g * 0.7 + b * b * 0.1) | 0},
dataStore (w, h) { return new Uint8Array(w * h) },
}