Estoy tratando de crear un png de mapa de altura de 16 bits a partir de un png de valor de altura codificado en Rgb de 32 bits.
De acuerdo con mapbox , puedo decodificar sus valores de píxeles png a valores de altura en metros con esta fórmula. height = -10000 + ((R * 256 * 256 + G * 256 + B) * 0.1)
Soy nuevo en la comprensión de este tipo de información y he tratado de resolverlo yo mismo, pero necesito ayuda.
Encontré este programa llamado image-js , los documentos para este programa están aquí . Tenga en cuenta que estoy usando esto en el navegador, no con node.
Creo que tiene las habilidades que necesito. Sin embargo, realmente no estoy seguro de cómo obtener los datos de la imagen original y crear un nuevo png de 16 bits con los nuevos valores de altura calculados a partir de la fórmula anterior.
Si mira en los documentos debajo de la imagen, puedo establecer muchas propiedades, como
bitDepth y ajústelo a 16
getPixelsArray() esta función me dará una matriz de valores de píxeles en forma de r,g,b. Creo que luego puedo ejecutar cada píxel a través de la fórmula anterior para obtener la altura. Después de eso, ¿cómo convierto estos datos de altura en un png de mapa de altura en escala de grises de 16 bits?
¡Gracias!
Imágenes de ejemplo. Valor de altura codificado Rgb de 32 bits png 
Mapa de altura de 16 bits png. Tienes que hacer zoom para ver los cambios en la imagen. 
Actualizar:
Gracias a traktor por la sugerencia. Quería agregar algo de información a mi pregunta.
No necesariamente necesito usar image-js. Mi objetivo principal es obtener un mapa de altura de 16 bits a partir de un RGB de 32 bits. Por lo tanto, cualquier otro método javscript del lado del navegador estaría bien. También estoy usando el lado del navegador createWritable(); flujo para escribir el archivo en el disco.
Tengo un método utilizado desde este módulo agradable https://github.com/colkassad/terrain-rgb-height , sin embargo, no puedo hacer que la versión del lado del navegador de pngjs funcione correctamente. Creo que hay una diferencia entre los lectores/escritores de flujo lateral del navegador y los lectores/escritores de nodos que hacen que no funcione.
¡Gracias!
Revisar el código fuente del paquete Image-js en GitHub revela que el objeto de options utilizado en las llamadas a la biblioteca se verifica en el archivo fuente kind.js , que enumera las propiedades de las opciones admitidas en la instrucción de asignación:
const { components, alpha, bitDepth, colorModel } = definition; Sin embargo, muchas opciones están predeterminadas usando la propiedad de opción kind , que a su vez es "RGBA".
Saber más sobre las propiedades de las opciones permite usarlas (no pude encontrar documentación de opciones fuera del código).
Yo sugeriría
Cree una imagen Image-js a partir del png de altura codificada de 32 bits. Omita una propiedad kind para usar el modelo de píxeles PNG de 32 bits predeterminado de 3 canales de color más un canal alfa.
Convierta los datos de la imagen (mantenidos como una matriz escrita en la propiedad de data del objeto de la imagen) en una matriz unidimensional de valores de altura utilizando el algoritmo de conversión de MapBox. El diseño de la matriz escrita ( image.data ) parece ser el mismo que el utilizado para ImageData
Cree una nueva imagen image-js usando
new Image(width, height, decodedHeightArray, {kind="GREY", bitDepth:16}) donde decodedHeightArray es la matriz preparada en el paso anterior.
Solo agregué mi código a la respuesta proporcionada por el rastreador. Muchas gracias, traktor.
Esto funcionó perfectamente. Para quien quiera el código
estoy usando image-js para codificar y decodificar la imagen
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();También estoy usando la API de flujos del navegador para escribir el archivo en el disco. Tenga en cuenta que los flujos de archivos writable.write solo aceptan ciertos valores, uno de ellos es un blob, es por eso que lo convirtió a blob antes de pasarlo al método de escritura.