harmonyOS next开发,如何实现一张图实现自动切割9宫图保存?
首先需要在 module.json5 中添加读写图片的权限:
{
"module": {
"requestPermissions": [
{
"name": "ohos.permission.READ_MEDIA",
"reason": "需要读取图片"
},
{
"name": "ohos.permission.WRITE_MEDIA",
"reason": "需要保存图片"
}
]
}
}
然后使用以下代码实现图片切割和保存功能:
import fs from '@ohos.file.fs';
import image from '@ohos.multimedia.image';
import { common } from '@kit.AbilityKit';
import promptAction from '@kit.ArkUI';
// 定义拼图组件接口
interface PuzzlePiece {
// 拼图块的像素地图
pixelMap: image.PixelMap;
// 原始图片中的索引位置
originalIndex: number;
}
// 使用装饰器定义页面组件
@Entry
@Component
struct ImageCutPage {
// 状态变量:选中图片的URI
@State imgUri: string = '';
// 状态变量:存储拼图块的数组
@State puzzlePieces: Array<PuzzlePiece> = [];
// 弹出图片选择器方法
async openPicker() {
try {
// 设置图片选择器选项
const photoSelectOptions = new picker.PhotoSelectOptions();
// 限制只能选择一张图片
photoSelectOptions.MIMEType = picker.PhotoViewMIMETypes.IMAGE_TYPE;
photoSelectOptions.maxSelectNumber = 1;
// 创建并实例化图片选择器
const photoViewPicker = new picker.PhotoViewPicker();
// 选择图片并获取图片URI
let uris: picker.PhotoSelectResult = await photoViewPicker.select(photoSelectOptions);
if (!uris || uris.photoUris.length === 0) return;
// 获取选中图片的第一张URI
let uri: string = uris.photoUris[0];
// 更新状态变量:设置显示图片的URI
this.imgUri = uri;
// 图片更改时触发的方法
this.imgChange();
} catch (e) {
console.error('openPicker', JSON.stringify(e));
}
}
// 图片更改处理方法
async imgChange() {
try {
// 创建图片源对象
const imageSource: image.ImageSource = image.createImageSource(this.imgUri);
// 图片解码选项
let decodingOptions: image.DecodingOptions = {
editable: true,
desiredPixelFormat: 3,
};
// 创建像素地图
let mPixelMap: image.PixelMap = await imageSource.createPixelMap(decodingOptions);
// 获取图片信息
let mImageInfo: image.ImageInfo = await mPixelMap.getImageInfo();
// 计算每个拼图块的大小
const cropSize: image.Size = {
width: mImageInfo.size.width / 3,
height: mImageInfo.size.height / 3,
};
// 清空已有拼图块数据
this.puzzlePieces.splice(0);
// 遍历图片生成9个拼图块
let count = 0;
for (let row = 0; row < 3; row++) {
for (let col = 0; col < 3; col++) {
// 创建基于原图的新图片源
const imageSource = image.createImageSource(this.imgUri);
// 创建新像素地图
let mPixelMap = await imageSource.createPixelMap(decodingOptions);
// 计算裁剪区域
const cropRect: image.Region = {
x: col * cropSize.width,
y: row * cropSize.height,
size: cropSize,
};
// 裁剪像素地图
await mPixelMap.crop(cropRect);
// 创建并添加拼图块至数组
const piece: PuzzlePiece = {
pixelMap: mPixelMap,
originalIndex: count++,
};
this.puzzlePieces.push(piece);
// 保存裁剪后的图片
this.saveCutImage(mPixelMap, count);
}
}
} catch (e) {
console.error('imgChange', JSON.stringify(e));
}
}
// 保存裁剪后的图片
async saveCutImage(pixelMap: image.PixelMap, index: number) {
try {
const imagePackerApi: image.ImagePacker = image.createImagePacker();
const packOpts: image.PackingOption = { format: 'image/jpeg', quality: 80 };
const buffer: ArrayBuffer = await imagePackerApi.packing(pixelMap, packOpts);
let context = getContext(this) as common.UIAbilityContext;
let newUrl = context.filesDir + '/cutImage' + index + '.jpg';
let file: fs.File = fs.openSync(newUrl, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
await fs.writeSync(file.fd, buffer);
fs.closeSync(file);
// 如果需要将图片保存到图库,可以使用PhotoAccessHelper模块
/* if (this.phAccessHelper === null) {
return;
}
let options: photoAccessHelper.CreateOptions = {
title: new Date().getTime().toString()
};
let photoUri: string = await this.phAccessHelper.createAsset(photoAccessHelper.PhotoType.IMAGE, 'jpg', options);
let file: fileIo.File = fileIo.openSync(photoUri, fileIo.OpenMode.READ_WRITE | fileIo.OpenMode.CREATE);
await fileIo.write(file.fd, buffer);
fileIo.closeSync(file); */
} catch (err) {
console.error(err)
}
}
// 构建UI界面
build() {
Column() {
// 添加选择图片按钮,点击后调用打开图片选择器方法
Button('选择图片→').onClick(() => {
this.openPicker();
});
// 如果有拼图块,则显示游戏区
if (this.puzzlePieces.length > 0) {
Text('切割后的九宫格图片↓');
// 游戏区域采用网格布局
Grid() {
// 遍历所有拼图块并创建网格项
ForEach(this.puzzlePieces, (item: PuzzlePiece, index: number) => {
GridItem() {
// 显示拼图块图像
Image(item.pixelMap)
.width('100lpx')
.height('100lpx')
.margin('5lpx');
}
}) // End of ForEach
} // End of Grid
.backgroundColor("#fafafa"); // 设置网格背景色
}
} // End of Column
.width('100%'); // 设置列宽度为100%
}
}
1 回答1.1k 阅读✓ 已解决
1 回答1.4k 阅读
1 回答1.2k 阅读
1 回答1.2k 阅读
1 回答1.2k 阅读
1 回答1k 阅读
1 回答1k 阅读
在HarmonyOS Next中,你可以使用图像处理API来实现将一张图片自动切割为九宫图并保存的功能。以下是实现步骤和示例代码:
实现方案
注意事项
权限申请:确保你的应用有文件读写权限,在module.json5中添加:
性能考虑:大图片处理可能会消耗较多内存,建议:
先对图片进行适当压缩
在后台线程进行处理
添加进度提示
输出格式:可以根据需要调整输出格式(JPEG/PNG)和质量
错误处理:实际应用中应添加更完善的错误处理和用户反馈