- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试将 JavaScript 中的 Canvas 转换为 pgm。在我转换文件并将其下载到我的 table 面后,它具有 pgm 扩展名,但是当我用编辑器打开它时,它被编码为 png。我认为如果 JavaScript 无法识别您要转换为的扩展名,它会默认将其转换为 png。所以 JavaScript 可以转换为 png、jpeg 等,但不能转换为 pgm?
我的问题是是否可以使用 JavaScript 将 canvas 转换为 pgm,如果没有,是否有任何可用的插件或 Js 库可以这样做。
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();
}
最佳答案
为了将 Canvas 保存为 PGM,我刚去了 http://netpbm.sourceforge.net/doc/pgm.html其中详细说明了文件格式,并使用该信息创建了一个将 Canvas 转换为 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
header 不完整,但我们需要获取像素值的最大值,以便转换图像并找到最大值。
因此通过 2D 上下文获取像素数据。
var imgData = ctx.getImageData(0,0,ctx.canvas.width,ctx.height);
关于您想要的数据,您有多种选择。该格式为某些值指定对数标度,为其他值指定线性标度。如果保持 Gamma 很重要,我会留给你找到转换。 (请注意,仅当您计划广播或保存光值(例如天文图像)时才需要)
有一个实用程序可以将线性 Gamma 函数转换为 BT.709 Gamma 函数。查看链接文档
我添加了一些简单的格式。两个为16位,最大值为3*255。
如果您从 jpeg 编码图像转换,最好通过首先将像素 RGB 转换为 HSL 并仅将 L 保存为 8 位值来从图像中提取亮度,这将阻止 jpeg 质量差的色调和饱和度数据影响结果(jpeg 具有近乎无损的灰度数据)
const formats = {
mean : {
convert (r, g, b) { bin[j++] = ((r + g + b) / 3 ) | 0 },
dataStore (w, h) { return new Uint8Array(w * h) },
},
summed : {
convert (r, g, b) { bin[j++] = r + g + b },
dataStore (w, h) { return new Uint16Array(w * h) },
},
meanLog : {
convert (r, g, b) { bin[j++] = Math.sqrt((r * r + g * g + b * b)/ 3) | 0 },
dataStore (w, h) { return new Uint8Array(w * h) },
},
summedLog : {
convert (r, g, b) { bin[j++] = Math.sqrt(r * r + g * g + b * b) | 0 },
dataStore (w, h) { return new Uint16Array(w * h) },
}
}
var imgData = ctx.getImageData(0,0,ctx.canvas.width,ctx.canvas.height);
var format = formats.mean;
var bin = format.dataStore(canvas.width, canvas.height);
var r,g,b,summed,mean,summedLog,meanLog;
var i = 0;
var j = 0;
var max = 0;
var d = imgData.data; // shorthand var to pixel data
while(i < d.length){
format.convert(d[i++],d[i++],d[i++]);
max = Math.max(bin[j-1],max);
i++; // skip alpha
}
header += max; // max value.
header += CR; // add whitespace char
// We have all that is needed to create the file so first convert
// header string to ascII
var fileBin = new Uint8Array(header.length + bin.length);
for(i = 0; i < header.length; i++){
fileBin[i] = header.charCodeAt(i) & 0b01111111; // strip of top bit just in case superstitious coder reads this
}
fileBin.set(new Uint8Array(bin.buffer),header.length); // add the pixel data
// fileBin is the 8bit bin of the PGM file
// Note transparent pixels are black.
// Note I do not check for all black. Format doc indicates that a max val in the head of zero is illegal. What that means you will have to find out.
就是这样。您可以将其转换为 Base64 编码,或者按原样保存
请注意,在此答案之前我从未使用过或听说过这种图像格式,上面的代码是对答案顶部链接的文档的快速解释。如果它有效,我不知道,因为我没有任何东西可以测试它。该代码没有语法和运行时错误。
它更像是展示如何为特定格式创建二进制文件的指南
我想我还会添加一种格式来处理 JPEG 图像,它只需要一个良好的 RGB 到 HSL 函数。
// NOTE to prevent data loss the out put of lum has been
// scaled from the normal 0-100 to 0-255 for the example PGM image format
// If you use this function to get HSL values compatible with HSL CSS
// colours change the multipliers from 255 to 100. Commented with [*1]
function rgb2hsl(r,g,b){ // integers in the range 0-255
var minC, maxC, dif, h, l, s;
h = l = s = 0;
r /= 255; // normalize channels
g /= 255;
b /= 255;
min = Math.min(r, g, b);
max = Math.max(r, g, b);
if(min === max){ // [*1] no colour so early exit
return {
h, s,
l : Math.floor(min * 255), // this normally is 0-100
}
}
dif = max - min;
l = (max + min) / 2;
if (l > 0.5) { s = dif / (2 - max - min) }
else { s = dif / (max + min) }
if (max === r) {
if (g < b) { h = (g - b) / dif + 6.0 }
else { h = (g - b) / dif }
} else if(max === g) { h = (b - r) / dif + 2.0 }
else {h = (r - g) / dif + 4.0 }
h = Math.floor(h * 60);
s = Math.floor(s * 100);
l = Math.floor(l * 255); // [*1] this normally is 0-100
return {h, s, l};
},
然后将以下内容添加到格式对象
formats.jpegLumPreserve = {
convert (r, g, b) { bin[j++] = rgb2hsl(r + g + b).l},
dataStore (w, h) { return new Uint8Array(w * h) },
}
如果您从最初存储为 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) },
}
这是基于成年人感知红色、绿色和蓝色 3 种原色并将灰色(亮度)结果与感知颜色亮度相匹配的平均能力。
关于JavaScript 将 Canvas 转换为 PGM,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44260008/
我正在尝试将一个字符串逐个字符地复制到另一个字符串中。目的不是复制整个字符串,而是复制其中的一部分(我稍后会为此做一些条件......) 但我不知道如何使用迭代器。 你能帮帮我吗? std::stri
我想将 void 指针转换为结构引用。 结构的最小示例: #include "Interface.h" class Foo { public: Foo() : mAddress((uint
这有点烦人:我有一个 div,它从窗口的左上角开始过渡,即使它位于文档的其他任何位置。我试过 usign -webkit-transform-origin 但没有成功,也许我用错了。有人可以帮助我吗?
假设,如果将 CSS3 转换/转换/动画分配给 DOM 元素,我是否可以检测到该过程的状态? 我想这样做的原因是因为我正在寻找类似过渡链的东西,例如,在前一个过渡之后运行一个过渡。 最佳答案 我在 h
最近我遇到了“不稳定”屏幕,这很可能是由 CSS 转换引起的。事实上,它只发生在 Chrome 浏览器 上(可能还有 Safari,因为一些人也报告了它)。知道如何让它看起来光滑吗?此外,您可能会注意
我正在开发一个简单的 slider ,它使用 CSS 过渡来为幻灯片设置动画。我用一些基本样式和一些 javascript 创建了一支笔 here .注意:由于 Codepen 使用 Prefixfr
我正在使用以下代码返回 IList: public IList FindCodesByCountry(string country) { var query =
如何设计像这样的操作: 计算 转化 翻译 例如:从“EUR”转换为“CNY”金额“100”。 这是 /convert?from=EUR&to=CNY&amount=100 RESTful 吗? 最佳答
我使用 jquery 组合了一个图像滚动器,如下所示 function rotateImages(whichHolder, start) { var images = $('#' +which
如何使用 CSS (-moz-transform) 更改一个如下所示的 div: 最佳答案 你可以看看Mozilla Developer Center .甚至还有例子。 但是,在我看来,您的具体示例不
我需要帮助我正在尝试在选中和未选中的汉堡菜单上实现动画。我能够为菜单设置动画,但我不知道如何在转换为 0 时为左菜单动画设置动画 &__menu { transform: translateX(
我正在为字典格式之间的转换而苦苦挣扎:我正在尝试将下面的项目数组转换为下面的结果数组。本质上是通过在项目第一个元素中查找重复项,然后仅在第一个参数不同时才将文件添加到结果集中。 var items:[
如果我有两个定义相同的结构,那么在它们之间进行转换的最佳方式是什么? struct A { int i; float f; }; struct B { int i; float f; }; void
我编写了一个 javascript 代码,可以将视口(viewport)从一个链接滑动到另一个链接。基本上一切正常,你怎么能在那里看到http://jsfiddle.net/DruwJ/8/ 我现在的
我需要将文件上传到 meteor ,对其进行一些图像处理(必要时进行图像转换,从图像生成缩略图),然后将其存储在外部图像存储服务器(s3)中。这应该尽可能快。 您对 nodejs 图像处理库有什么建议
刚开始接触KDB+,有一些问题很难从Q for Mortals中得到。 说,这里 http://code.kx.com/wiki/JB:QforMortals2/casting_and_enumera
我在这里的一个项目中使用 JSF 1.2 和 IceFaces 1.8。 我有一个页面,它基本上是一大堆浮点数字段的大编辑网格。这是通过 inputText 实现的页面上的字段指向具有原始值的值对象
ScnMatrix4 是一个 4x4 矩阵。我的问题是什么矩阵行对应于位置(ScnVector3),旋转(ScnVector4),比例(ScnVector3)。第 4 行是空的吗? 编辑: 我玩弄了
恐怕我是 Scala 新手: 我正在尝试根据一些简单的逻辑将 Map 转换为新 Map: val postVals = Map("test" -> "testing1", "test2" -> "te
输入: This is sample 1 This is sample 2 输出: ~COLOR~[Green]This is sample 1~COLOR~[Red]This is sam
我是一名优秀的程序员,十分优秀!