HarmonyOS 鸿蒙Next应用需要保存图片到相册
HarmonyOS 鸿蒙Next应用需要保存图片到相册
应用需要保存图片到相册,怎么保存?
可以参考如下代码
import { webview } from '@kit.ArkWeb';
import { CommonConstant as Const } from '../common/Constant';
import { BusinessError, request } from '@kit.BasicServicesKit'
import { photoAccessHelper } from '@kit.MediaLibraryKit';
import { fileIo as fs, fileUri, ReadOptions, WriteOptions } from '@kit.CoreFileKit';
import { buffer } from '@kit.ArkTS'
const context = getContext(this);
class SaveImageResultVo {
errorCode: number = 0
}
let writeBufferToFile = (dirPath: string, fileName: string, buf: ArrayBuffer) => {
if (!fs.accessSync(dirPath)) {
// 如果文件夹不存在,则先创建文件夹
fs.mkdirSync(dirPath)
}
let file = fs.openSync(`${dirPath}/${fileName}`, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE)
fs.writeSync(file.fd, buf)
fs.closeSync(file)
}
let saveImageToApplication = async (image: string, dirPath: string, fileName: string): Promise<SaveImageResultVo> => {
return new Promise(async (resolve: Function, reject: Function) => {
if (!fs.accessSync(dirPath)) {
fs.mkdirSync(dirPath)
}
if (image.startsWith('http')) {
// 如果是网络图片,则下载图片
try {
request
.downloadFile(context, { url: image, filePath: `${dirPath}/${fileName}` })
.then((downloadTask) => {
console.debug(`image => 保存图片到应用沙盒`)
downloadTask
.on('complete', () => {
// 图片下载完成
console.log('图片下载完成')
let vo = new SaveImageResultVo
vo.errorCode = 0
resolve(vo)
})
downloadTask
.on('fail', (err: number) => {
console.log('fail')
let vo = new SaveImageResultVo
vo.errorCode = err
resolve(vo)
})
})
.catch((error: BusinessError) => {
reject(error)
})
} catch (err) {
reject(err)
}
} else {
// base64图片
let content = image
if (image.startsWith('data:')) {
// 如果是data:,则截取,后的数据
content = image.split(',')[1]
}
try {
const decodeBuff = buffer.from(content, 'base64').buffer
writeBufferToFile(dirPath, fileName, decodeBuff)
let vo = new SaveImageResultVo
vo.errorCode = 0
resolve(vo)
} catch (err) {
reject(err)
}
}
})
}
let copyFileContentTo = (srcFilePath: string, destFilePath: string) => {
let srcFile = fs.openSync(srcFilePath, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE)
let destFile = fs.openSync(destFilePath, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE)
// 读取源文件内容并写入至目的文件
let bufSize = 4096;
let readSize = 0;
let buf = new ArrayBuffer(bufSize);
let readOptions: ReadOptions = {
offset: readSize,
length: bufSize
};
let readLen = fs.readSync(srcFile.fd, buf, readOptions);
while (readLen > 0) {
readSize += readLen;
let writeOptions: WriteOptions = {
length: readLen
};
fs.writeSync(destFile.fd, buf, writeOptions);
readOptions.offset = readSize;
readLen = fs.readSync(srcFile.fd, buf, readOptions);
}
// 关闭文件
fs.closeSync(srcFile);
fs.closeSync(destFile);
}
let saveImageToAlbum = async (path: string, title?: string, extension?: string): Promise<boolean> => {
return new Promise(async (resolve: Function, reject: Function) => {
try {
let phAccessHelper = photoAccessHelper.getPhotoAccessHelper(context)
let srcFileUri: Array<string> = [fileUri.getUriFromPath(path)]
console.debug(`图片 uri is : ${JSON.stringify(srcFileUri)}`)
let photoCreationConfigs: Array<photoAccessHelper.PhotoCreationConfig> = [
{
title: '保存图片',
fileNameExtension: extension ? extension : 'jpg',
photoType: photoAccessHelper.PhotoType.IMAGE,
subtype: photoAccessHelper.PhotoSubtype.DEFAULT
}
]
let desFileUris: Array<string> = await phAccessHelper.showAssetsCreationDialog(srcFileUri, photoCreationConfigs)
console.debug(`目标图片 uri is : ${JSON.stringify(desFileUris)}`)
if (desFileUris.length > 0) {
for (let index = 0; index < desFileUris.length; index++) {
copyFileContentTo(srcFileUri[index], desFileUris[index])
}
resolve(true)
} else {
resolve(false)
}
} catch (err) {
reject(err)
}
})
}
class LinkClass {
async messageFromHtml(value: string) {
let dirPath = context.cacheDir
let fileName = 'temp2.jpg'
if (fs.accessSync(`${dirPath}/${fileName}`)) {
fs.rmdirSync(`${dirPath}/${fileName}`)
}
try {
let result: SaveImageResultVo = await saveImageToApplication(value, dirPath, fileName)
if (0 == result.errorCode) {
// 图片保存成功
console.debug(`image => 保存图片到应用沙盒成功`)
saveImageToAlbum(`${dirPath}/${fileName}`)
.then((result) => {
if (result) {
console.debug(`image => 保存图片到相册成功`)
} else {
console.debug(`image => 用户拒绝授权`)
}
})
.catch((error: BusinessError) => {
console.error('image => 保存图片到相册异常:')
})
}
} catch (err) {
console.error(err, 'image => 保存图片到应用沙盒异常:')
}
}
}
@Entry
@Component
struct WebPage {
webController: webview.WebviewController = new webview.WebviewController();
@State linkObj: LinkClass = new LinkClass();
build() {
Stack({ alignContent: Alignment.TopStart }) {
Row() {
Column() {
// Web component loading H5.
Web({ src: $rawfile('local/index.html'), controller: this.webController })
.zoomAccess(false)
.width(Const.WEB_CONSTANT_WIDTH)
.aspectRatio(1)
.margin({
left: Const.WEB_CONSTANT_MARGIN_LEFT, right: Const.WEB_CONSTANT_MARGIN_RIGHT,
top: Const.WEB_CONSTANT_MARGIN_TOP
})
.javaScriptProxy({
object: this.linkObj,
name: 'linkObj',
methodList: ['messageFromHtml'],
controller: this.webController
})
}
.width('100%')
.width('100%')
}
}
.backgroundColor('#F1F3F5')
}
}
更多关于HarmonyOS 鸿蒙Next应用需要保存图片到相册的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
如何保存图片到相册
可以使用安全控件中的保存控件,免去权限申请和权限请求等环节,获得临时授权,保存对应图片。参考代码如下:
import { photoAccessHelper } from '@kit.MediaLibraryKit';
import { fileIo } from '@kit.CoreFileKit';
import { common } from '@kit.AbilityKit';
import { promptAction } from '@kit.ArkUI';
import { BusinessError } from '@kit.BasicServicesKit';
async function savePhotoToGallery(context: common.UIAbilityContext) {
let helper = photoAccessHelper.getPhotoAccessHelper(context);
try {
// onClick触发后10秒内通过createAsset接口创建图片文件,10秒后createAsset权限收回。
let uri = await helper.createAsset(photoAccessHelper.PhotoType.IMAGE, ‘jpg’);
// 使用uri打开文件,可以持续写入内容,写入过程不受时间限制
let file = await fileIo.open(uri, fileIo.OpenMode.READ_WRITE | fileIo.OpenMode.CREATE);
// $r(‘app.media.startIcon’)需要替换为开发者所需的图像资源文件
context.resourceManager.getMediaContent($r(‘app.media.startIcon’).id, 0)
.then(async value => {
let media = value.buffer;
// 写到媒体库文件中
await fileIo.write(file.fd, media);
await fileIo.close(file.fd);
promptAction.showToast({ message: ‘已保存至相册!’ });
});
}
catch (error) {
const err: BusinessError = error as BusinessError;
console.error(Failed to save photo. Code is <span class="hljs-subst">${err.code}</span>, message is <span class="hljs-subst">${err.message}</span>
);
}
}
@Entry
@Component
struct Index {
build() {
Row() {
Column({ space: 10 }) {
// $r(‘app.media.startIcon’)需要替换为开发者所需的图像资源文件
Image($r(‘app.media.startIcon’))
.height(400)
.width(‘100%’)
<span class="hljs-title class_">SaveButton</span>().<span class="hljs-title function_">onClick</span>(<span class="hljs-keyword">async</span> (<span class="hljs-attr">event</span>: <span class="hljs-title class_">ClickEvent</span>, <span class="hljs-attr">result</span>: <span class="hljs-title class_">SaveButtonOnClickResult</span>) => {
<span class="hljs-keyword">if</span> (result === <span class="hljs-title class_">SaveButtonOnClickResult</span>.<span class="hljs-property">SUCCESS</span>) {
<span class="hljs-keyword">const</span> <span class="hljs-attr">context</span>: common.<span class="hljs-property">UIAbilityContext</span> = <span class="hljs-title function_">getContext</span>(<span class="hljs-variable language_">this</span>) <span class="hljs-keyword">as</span> common.<span class="hljs-property">UIAbilityContext</span>;
<span class="hljs-comment">// 免去权限申请和权限请求等环节,获得临时授权,保存对应图片</span>
<span class="hljs-title function_">savePhotoToGallery</span>(context);
} <span class="hljs-keyword">else</span> {
promptAction.<span class="hljs-title function_">showToast</span>({ <span class="hljs-attr">message</span>: <span class="hljs-string">'设置权限失败!'</span> })
}
})
}
.<span class="hljs-title function_">width</span>(<span class="hljs-string">'100%'</span>)
}
.<span class="hljs-title function_">height</span>(<span class="hljs-string">'100%'</span>)
.<span class="hljs-title function_">backgroundColor</span>(<span class="hljs-number">0xF1F3F5</span>)
}
}
在HarmonyOS 鸿蒙Next应用中保存图片到相册,可以使用系统提供的MediaStore API。以下是实现这一功能的基本步骤:
-
获取图片文件:首先,确保你已经有了需要保存的图片文件,可以是Bitmap对象或图片路径。
-
构建MediaStore.Images.Media.ContentValues:为图片构建合适的ContentValues对象,包括标题、描述、MIME类型、日期等信息。例如,
ContentValues values = new ContentValues(); values.put(MediaStore.Images.Media.DISPLAY_NAME, "image.jpg"); values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
-
插入MediaStore:使用ContentResolver将ContentValues插入到MediaStore中,这将返回图片的URI。
Uri uri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
-
写入图片数据:通过OutputStream将图片数据写入到上述URI指向的位置。
try (OutputStream outputStream = getContentResolver().openOutputStream(uri)) { bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream); }
-
通知媒体存储:通常系统会自动通知,但在某些情况下,你可能需要手动通知媒体存储更新。
如果问题依旧没法解决请联系官网客服,官网地址是:https://www.itying.com/category-93-b0.html