HarmonyOS 鸿蒙Next 拉起相册后选中的照片jpeg格式如何转换成nv21数据
HarmonyOS 鸿蒙Next 拉起相册后选中的照片jpeg格式如何转换成nv21数据
// 拉起相册,选择图片
let PhotoSelectOptions = new photoAccessHelper.PhotoSelectOptions();
PhotoSelectOptions.MIMEType = photoAccessHelper.PhotoViewMIMETypes.IMAGE_TYPE;
PhotoSelectOptions.maxSelectNumber = 1;
let photoPicker = new photoAccessHelper.PhotoViewPicker();
let photoSelectResult: photoAccessHelper.PhotoSelectResult = await photoPicker.select(PhotoSelectOptions);
let albumPath = photoSelectResult.photoUris[0];
通过convertPixelFormat转换了一下像素格式,但是打印出来readBuffer每个字节都是0,如何能把读到的这张jpeg转换成nv21数据,并保存到应用沙箱/本地相册呢?
更多关于HarmonyOS 鸿蒙Next 拉起相册后选中的照片jpeg格式如何转换成nv21数据的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
楼主你的demo感觉有点问题,这边基于你的demo修改了下,可以参考注释内容
async convert() {
// 拉起相册,选择图片
try {
// 1. 拉起相册,选择图片
let PhotoSelectOptions = new photoAccessHelper.PhotoSelectOptions();
PhotoSelectOptions.MIMEType = photoAccessHelper.PhotoViewMIMETypes.IMAGE_TYPE;
PhotoSelectOptions.maxSelectNumber = 1; // 选择一张图片
let photoPicker = new photoAccessHelper.PhotoViewPicker();
let photoSelectResult: photoAccessHelper.PhotoSelectResult = await photoPicker.select(PhotoSelectOptions);
if (!photoSelectResult || photoSelectResult.photoUris.length === 0) {
console.error("No image selected");
return;
}
let url = photoSelectResult.photoUris[0]; // 获取选中图片的URI
// 2. 读取图片为buffer
const file = fs.openSync(url, fs.OpenMode.READ_ONLY);
const photoSize = fs.statSync(file.fd).size;
let buffer = new ArrayBuffer(photoSize);
fs.readSync(file.fd, buffer);
fs.closeSync(file);
// 3. 创建ImageSource并生成PixelMap
const imageSource = image.createImageSource(buffer);
const pixelMap = await imageSource.createPixelMap();
// 4. 转换为NV21格式
let targetPixelFormat = image.PixelMapFormat.NV21;
await pixelMap.convertPixelFormat(targetPixelFormat);
// 5. 读取转换后的像素数据
const imageInfo = await pixelMap.getImageInfo();
const readBuffer = new ArrayBuffer(imageInfo.size.width * imageInfo.size.height * 3 / 2); // NV21格式的大小
await pixelMap.readPixelsToBuffer(readBuffer);
// 6. 将NV21数据保存到沙箱
const sandboxDir = getContext().filesDir; // 沙箱目录
const filePath = `${sandboxDir}/image_nv21.bin`; // 保存路径
let file1 = fs.openSync(filePath, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
fs.writeSync(file1.fd, readBuffer);
console.log("NV21 image saved to:", filePath);
} catch (error) {
console.error("Error occurred:", error);
}
}
aboutToAppear(): void {
this.convert()
}
沙箱文件
更多关于HarmonyOS 鸿蒙Next 拉起相册后选中的照片jpeg格式如何转换成nv21数据的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
谢谢,我试了可以成功保存nv21,我想问下用media文件夹里面的图去生成PixelMap是不是同样的方式?目前图片又保存失败了let media = await this.context.resourceManager.getMediaContent($r(‘app.media.faces’).id); // 3. 创建ImageSource并生成PixelMap const imageSource = image.createImageSource(media.buffer); const pixelMap = await imageSource.createPixelMap();
在HarmonyOS鸿蒙Next系统中,将拉起相册后选中的JPEG格式照片转换成NV21数据,可以通过以下步骤实现:
-
读取JPEG数据: 使用系统API读取选中的JPEG照片,获取其字节数组。
-
解码JPEG数据: 利用BitmapFactory类将JPEG字节数组解码成Bitmap对象。
-
创建NV21缓冲区: 根据Bitmap的宽度和高度,计算NV21数据所需的缓冲区大小,并创建相应的byte数组。
-
转换Bitmap到NV21: 遍历Bitmap的像素数据,按照NV21的格式(YUV420SP)填充缓冲区。注意,NV21格式中,Y分量在前,UV分量交错在后。
-
处理边缘情况: 对于Bitmap的宽高不是16的倍数的情况,需要进行适当填充或裁剪,以保证NV21数据的正确性。
具体代码实现如下(伪代码):
Bitmap bitmap = BitmapFactory.decodeByteArray(jpegData, 0, jpegData.length);
int width = bitmap.getWidth();
int height = bitmap.getHeight();
byte[] nv21Data = new byte[width * height * 3 / 2];
// 填充nv21Data...
// 此处省略具体转换逻辑,需按NV21格式手动填充
// 返回nv21Data
注意:上述代码省略了具体的转换逻辑,需根据NV21格式手动实现。
如果问题依旧没法解决请联系官网客服,官网地址是:https://www.itying.com/category-93-b0.html