| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244 |
- import axios, { AxiosProgressEvent } from '@ohos/axios';
- import { fileIo, fileUri } from '@kit.CoreFileKit';
- import { camera, cameraPicker as picker } from '@kit.CameraKit';
- import { util } from '@kit.ArkTS';
- import { photoAccessHelper } from '@kit.MediaLibraryKit';
- import { image } from '@kit.ImageKit';
- import { BusinessError } from '@kit.BasicServicesKit';
- import { ContextHelper, ResultCallBack, YTLog } from '../../../../Index';
- import { componentSnapshot } from '@kit.ArkUI';
- import fs from '@ohos.file.fs';
- /**
- * @method cashPhotos 传入需要下载得url数组并下载文件,通过回调函数返回对应cashPaths数组
- * @method takePicture 拍照获取图片
- * @method selectImage 从相册选择图片
- * @method saveByShowAssetsCreationDialog 通过ShowAssetsCreationDialog保存文件(弹窗)
- * @method getPhotoFileBuffer 将缓存的图片转化为流
- * @method saveImgToAssets 直接保存图片至相册 需要权限
- * @method saveScreenshotToAlbum 截屏保存图片
- * @method manualCompression压缩图片
- */
- export class YTPhotoHelper {
- private cashPaths: string[] = []
- private currentIndex: number = 0
- //传入需要下载得url数组并下载文件,通过回调函数返回对应cashPaths数组
- async cashPhotos(urls: string[], finishDownLoad: (cashPaths: string[]) => void, cashPhotoType: string = '.jpg') {
- let filePath = ContextHelper.context.cacheDir + '/' + util.generateRandomUUID() + cashPhotoType
- // Download the file. If the file already exists, delete the existing one first.
- try {
- fileIo.accessSync(filePath);
- fileIo.unlinkSync(filePath);
- } catch (err) {
- YTLog.error(err)
- }
- await axios({
- url: urls[this.currentIndex],
- method: 'get',
- context: ContextHelper.context,
- filePath: filePath,
- onDownloadProgress: (progressEvent: AxiosProgressEvent): void => {
- YTLog.info("progress: " + progressEvent && progressEvent.loaded && progressEvent.total ?
- Math.ceil(progressEvent.loaded / progressEvent.total * 100) : 0)
- }
- })
- this.currentIndex++
- this.cashPaths.unshift(filePath)
- if (this.currentIndex < urls.length) {
- this.cashPhotos(urls, finishDownLoad, cashPhotoType)
- } else {
- finishDownLoad(this.cashPaths)
- }
- }
- //拍照获取图片
- async takePicture() {
- let pathDir = ContextHelper.context.filesDir;
- let fileName = `${new Date().getTime()}`
- let filePath = pathDir + `/${fileName}.png`
- fileIo.createRandomAccessFileSync(filePath, fileIo.OpenMode.CREATE);
- let uri = fileUri.getUriFromPath(filePath);
- let pickerProfile: picker.PickerProfile = {
- cameraPosition: camera.CameraPosition.CAMERA_POSITION_BACK,
- saveUri: uri
- };
- let result: picker.PickerResult =
- await picker.pick(ContextHelper.context, [picker.PickerMediaType.PHOTO],
- //(如果需要录像可以添加) picker.PickerMediaType.VIDEO
- pickerProfile);
- if (!result.resultUri) {
- return Promise.reject('用户未拍照')
- }
- return filePath
- }
- //从相册选择图片
- selectImage(success: (fullPath: string) => void, maxNumber: number = 1) {
- const option = new photoAccessHelper.PhotoSelectOptions()
- option.MIMEType = photoAccessHelper.PhotoViewMIMETypes.IMAGE_TYPE
- option.maxSelectNumber = maxNumber
- const picker = new photoAccessHelper.PhotoViewPicker()
- picker.select(option)
- .then(res => {
- const photoName = util.generateRandomUUID()
- const photoType = '.' + res.photoUris[0].split('.').pop()
- const fullPath = ContextHelper.context.cacheDir + '/' + photoName + photoType
- const photo = fileIo.openSync(res.photoUris[0])
- try {
- fileIo.copyFile(photo.fd, fullPath)
- .then(() => {
- YTLog.info(fullPath)
- success(fullPath)
- })
- } catch (err) {
- YTLog.error(err)
- }
- })
- }
- // 保存截图到相册的方法
- async saveScreenshotToAlbum(activityId: string, result?: ResultCallBack<undefined>, clearCashPaths: boolean = false) {
- try {
- // 获取组件截图
- const pixelMap = componentSnapshot.getSync(activityId)
- if (!pixelMap) {
- console.error('Failed to get screenshot')
- return
- }
- // 创建临时文件路径
- const tempDir = ContextHelper.context.tempDir
- const filePath = tempDir + '/screenshot_' + util.generateRandomUUID() + '.jpg'
- // 将PixelMap打包为JPEG格式
- const imagePacker = image.createImagePacker()
- const packOptions: image.PackingOption = {
- format: 'image/jpeg',
- quality: 90
- }
- const data = await imagePacker.packing(pixelMap, packOptions)
- // 写入文件
- const file = fs.openSync(filePath, fs.OpenMode.CREATE | fs.OpenMode.READ_WRITE)
- fs.writeSync(file.fd, data)
- fs.closeSync(file)
- this.saveByShowAssetsCreationDialog([filePath], result, clearCashPaths)
- } catch (error) {
- console.error('Error saving screenshot: ' + JSON.stringify(error))
- }
- }
- //传入需要保存得cashPaths数组,并通过ShowAssetsCreationDialog保存文件
- async saveByShowAssetsCreationDialog(
- cashPaths: string[],
- result?: ResultCallBack<undefined>,
- clearCashPaths: boolean = false) {
- const phAccessHelper = photoAccessHelper.getPhotoAccessHelper(ContextHelper.context);
- const uris = cashPaths.map(item => fileUri.getUriFromPath(item))
- try {
- // 指定待保存照片的创建选项,包括文件后缀和照片类型,标题和照片子类型可选。
- const photoCreationConfigs = uris.map(() => {
- const photoCreationConfig: photoAccessHelper.PhotoCreationConfig = {
- fileNameExtension: 'jpg',
- photoType: photoAccessHelper.PhotoType.IMAGE,
- }
- return photoCreationConfig
- })
- // 基于弹窗授权的方式获取媒体库的目标uri。
- let desFileUris: Array<string> =
- await phAccessHelper.showAssetsCreationDialog(uris, photoCreationConfigs);
- let index = 0
- while (index < uris.length) {
- //通过该uri打开图片
- let file = await fileIo.open(desFileUris[index], fileIo.OpenMode.READ_WRITE | fileIo.OpenMode.CREATE)
- //获取流
- const buffer = await this.getPhotoFileBuffer(cashPaths[index])
- //通过流写入相册
- await fileIo.write(file.fd, buffer)
- //关流
- await fileIo.close(file)
- index++
- }
- result?.()
- if (clearCashPaths) {
- cashPaths.forEach(cashPath => fileIo.unlink(cashPath))
- }
- } catch (err) {
- YTLog.error(err)
- result?.(undefined, err)
- }
- }
- //传入图片地址,转化为流
- async getPhotoFileBuffer(filePath: string): Promise<ArrayBuffer> {
- try {
- const imageSource = image.createImageSource(filePath)
- let imagePackerApi = image.createImagePacker();
- let buffer = await imagePackerApi.packing(imageSource, {
- quality: 100,
- format: 'image/jpeg'
- })
- return buffer
- } catch (err) {
- let error: BusinessError = err as BusinessError;
- console.error(`read file failed, errCode:${error.code}, errMessage:${error.message}`);
- return Promise.reject(err)
- }
- }
- //须先申请权限ohos.permission.WRITE_IMAGEVIDEO 保存图片至相册
- async saveImgToAssets(cashPaths: string[]) {
- try {
- let index = 0;
- while (index < cashPaths.length) {
- //获取当前上下文
- //通过accessHelper模块获取accessHelper对象
- let accessHelper = photoAccessHelper.getPhotoAccessHelper(ContextHelper.context)
- //指定待创建的文件类型、后缀和创建选项,创建图片或视频资源 返回创建的图片和视频的uri
- let uri = await accessHelper.createAsset(photoAccessHelper.PhotoType.IMAGE, 'jpg')
- //通过该uri打开图片
- let file = await fileIo.open(uri, fileIo.OpenMode.READ_WRITE | fileIo.OpenMode.CREATE)
- //获取流
- const buffer = await this.getPhotoFileBuffer(cashPaths[index])
- //通过流写入相册
- await fileIo.write(file.fd, buffer)
- //关流
- await fileIo.close(file)
- index++
- }
- } catch (e) {
- YTLog.error(e)
- }
- }
- /**
- * 手动压缩图片
- * @param filePath 图片路径
- * @param result 回调
- * @param quality 压缩质量
- */
- async manualCompression(filePath: string, result: (imagePath: string) => void, quality: number = 20) {
- const imageSourceApi: image.ImageSource = image.createImageSource(filePath);
- const packOpts: image.PackingOption = { format: "image/jpeg", quality };
- const imagePackerApi = image.createImagePacker()
- const buffer = await imagePackerApi.packing(imageSourceApi, packOpts)
- const imagePath = ContextHelper.context.cacheDir + '/' + util.generateRandomUUID() + '.jpeg'
- const file = fileIo.openSync(imagePath, fileIo.OpenMode.CREATE | fileIo.OpenMode.READ_WRITE)
- fileIo.writeSync(file.fd, buffer)
- fileIo.closeSync(file)
- fileIo.unlinkSync(filePath)
- result(imagePath)
- return imagePath
- }
- }
|