提问人:Sameer Trivedi 提问时间:11/18/2023 更新时间:11/18/2023 访问量:11
如何使用 react-native 将图像张量转换为 PNG?
How to convert an Image tensor to PNG using react-native?
问:
我使用 react-native-tfjs 运行神经网络,它给了我一个 RGB 图像张量作为输出之一。如何将其保存为 PNG 图像?
到目前为止,我尝试了什么:
- 尝试使用该函数,但这不起作用,因为绘制或保存它需要 html5 canvas 元素。
tf.browser.toPixels
- 搜索了 EncodePng 实现,不幸的是 react-native 没有类似的实现。
tf.node.encodePng
- 一堆其他事情,比如尝试将缓冲区转换为 base64,但都没有运气。
以下是我发现有效的 Jpeg 编码实现:
import * as tf from "@tensorflow/tfjs";
import * as jpeg from "jpeg-js";
async function tensorToImageUrl(imageTensor) {
const [height, width] = imageTensor.shape;
const buffer = await imageTensor.toInt().data();
const frameData = new Uint8Array(width * height * 4);
let offset = 0;
for (let i = 0; i < frameData.length; i += 4) {
frameData[i] = buffer[offset];
frameData[i + 1] = buffer[offset + 1];
frameData[i + 2] = buffer[offset + 2];
frameData[i + 3] = 0xff;
offset += 3;
}
const rawImageData = {
data: frameData,
width,
height,
};
const jpegImageData = jpeg.encode(rawImageData, 100);
const base64Encoding = tf.util.decodeString(jpegImageData.data, "base64");
return base64Encoding;
}
我必须有一个无损图像才能进一步检索和处理,所以我不能使用,我试图为png寻找类似的库,但其中很多都已经过时或缺乏文档,如果有人可以帮助我实现该功能,但对于PNG,这将对我的项目非常有帮助。jpeg-js
tensorToImageUrl
答:
0赞
Sameer Trivedi
11/18/2023
#1
好的,所以我设法让它工作,希望它能在未来帮助某人和其他类似的未解决的问题。我使用了 Jimp 图像处理库,它是纯用纯 JS 编写的,可以在 Node 和浏览器中工作,但有一个技巧可以让它在 react-native/react 中工作。
import * as tf from "@tensorflow/tfjs";
import * as _Jimp from "jimp";
const Jimp = typeof self !== "undefined" ? self.Jimp || _Jimp : _Jimp; // The hack
async function encodePng(imageTensor) {
const [height, width] = imageTensor.shape;
const buffer = await imageTensor.toInt().data();
const frameData = new Uint8Array(width * height * 4);
let offset = 0;
for (let i = 0; i < frameData.length; i += 4) {
frameData[i] = buffer[offset];
frameData[i + 1] = buffer[offset + 1];
frameData[i + 2] = buffer[offset + 2];
frameData[i + 3] = 0xff; // Buffer has to be Uint8Array in RGBA raw data because Jimp expects the format, we stuff dummy alpha values here.
offset += 3;
}
const rawImageData = {
data: frameData,
width,
height,
};
var base64Data = "";
try {
const image = await Jimp.read(rawImageData);
console.log(image);
base64Data = await image.getBase64Async(Jimp.MIME_PNG); // JIMP support Jpeg, BMP, PNG etc. so you can modify this however you like.
} catch (e) {
console.log(e);
}
if (base64Data === "") console.log("operation unsucessful");
return base64Data;
}
评论