javascript - 如何使用浏览器端 javascript 将具有编码高度值的 32 位 RGB png 转换为 16 位 png?
问题描述
我正在尝试从 32 位 Rgb 编码的高度值 png 创建一个 16 位高度图 png。
根据mapbox,我可以使用这个公式将它们的 png 像素值解码为以米为单位的高度值。 height = -10000 + ((R * 256 * 256 + G * 256 + B) * 0.1)
我是新了解此类信息的新手,并试图自己弄清楚,但我需要一些帮助。
我找到了这个名为image-js的程序,这个程序的文档在这里。注意我在浏览器中使用它而不是节点。
我认为它有我需要的能力。但是,我真的不确定如何从原始图像中获取数据并使用根据上述公式计算的新高度值创建一个新的 16 位 png。
如果您查看图像下的文档,我可以设置许多属性,例如
bitDepth 并将其设置为 16
getPixelsArray() 这个函数会给我一个像素值数组,格式为 r,g,b。我想我可以通过上面的公式运行每个像素来获得高度。之后如何将这个高度数据转换回 16 位灰度高度图 png?
谢谢!
更新:
感谢 traktor 的建议。我想在我的问题中添加一些信息。
我不一定需要使用 image-js。我的主要目标是从 32 位 RGB 中获得 16 位高度图。所以任何其他浏览器端的 javscript 方法都可以。我也在使用浏览器端 createWritable(); 流将文件写入磁盘。
我有一个从这个不错的模块https://github.com/colkassad/terrain-rgb-height使用的方法,但是我无法让 pngjs 的浏览器端版本正常工作。我认为浏览器端流读取器/写入器和节点读取器/写入器之间存在差异,使其无法正常工作。
谢谢!
解决方案
Image-js
在 GitHub 上查看 package 的源代码,发现options
调用库中使用的对象在源文件中进行了验证,该源文件kind.js
枚举了赋值语句中支持的选项属性:
const { components, alpha, bitDepth, colorModel } = definition;
但是,许多选项默认使用kind
选项属性,其本身默认为“RGBA”。
了解有关选项属性的更多信息允许使用它们(我在代码之外找不到选项文档)。
我会建议
从 32 位编码高度 png 创建一个 Image-js 图像。省略一个
kind
属性以使用 3 个颜色通道和一个 Alpha 通道的默认 32 位 PNG 像素模型。使用 MapBox 转换算法将图像数据(作为图像对象
data
属性中的类型化数组保存)转换为高度值的一维数组。(image.data
) 类型数组的布局似乎与用于ImageData的布局相同使用创建一个新的 image-js 图像
new Image(width, height, decodedHeightArray, {kind="GREY", bitDepth:16})
decodedHeightArray
上一步准备的数组在哪里。
只需将我的代码添加到提供的跟踪器答案中 非常感谢 traktor
这非常有效。对于任何想要代码的人
我正在使用image-js对图像进行编码和解码
let file_handleSixteen = await dir_handle.getFileHandle(sixteen_file_name, {create: true})
let writableSixteen = await file_handleSixteen.createWritable();
async function convert16(arrayBuff) {
let image = await Image.load(arrayBuff);
let width = image.width
let height = image.height
let decodedHeightArray = []
let pixelsArray = image.getPixelsArray()
for (const pixel of pixelsArray) {
let r = pixel[0]
let g = pixel[1]
let b = pixel[2]
let height = getHeightFromRgb(r, g, b);
decodedHeightArray.push(height)
}
let newImage = new Image(width, height, decodedHeightArray, {kind: "GREY", bitDepth: 16})
return newImage.toBlob()
}
function getHeightFromRgb(r, g, b) {
return -10000 + ((r * 256 * 256 + g * 256 + b) * 0.1);
}
const file = await file_handleRgb.getFile();
let imageBuffer = await file.arrayBuffer()
let convertedArray = await convert16(imageBuffer)
await writableSixteen.write(convertedArray)
await writableSixteen.close();
我还使用浏览器流 api 将文件写入磁盘。请注意,文件流 writable.write 仅接受某些值,其中之一是 Blob,这就是为什么在将其传递给 write 方法之前将其转换为 Blob
推荐阅读
- ansible - ansible-galaxy 无法在 gitlab-ci 管道中提取角色
- shell - 在 yaml 中读取和解析文本文件
- mysql - Mysql:从另一列填充和更新列
- java - 无法使用 OpenCSV 写入文件
- sharepoint - 从用户 O365 OneDrive 中删除 AD 安全组
- mysql - 如何将大矩阵输入关系数据库(DB)mysql
- python - python - 如何根据复选框在python中是否选中使单选按钮处于活动状态
- javascript - 测试用例被调用两次导致:未捕获的错误:读取 ECONNRESET 和错误:多次调用 done()
- azure - Azure Dev Ops 多阶段 YAML 管道 - 使用前一阶段状态作为变量
- javascript - 使用javascript根据条件将数组拆分为两个