|
@@ -5,7 +5,10 @@ import { util } from '@kit.ArkTS';
|
|
|
import { photoAccessHelper } from '@kit.MediaLibraryKit';
|
|
import { photoAccessHelper } from '@kit.MediaLibraryKit';
|
|
|
import { image } from '@kit.ImageKit';
|
|
import { image } from '@kit.ImageKit';
|
|
|
import { BusinessError } from '@kit.BasicServicesKit';
|
|
import { BusinessError } from '@kit.BasicServicesKit';
|
|
|
-import { YTLog } from '../../../../Index';
|
|
|
|
|
|
|
+import { ContextHelper, ResultCallBack, YTLog } from '../../../../Index';
|
|
|
|
|
+import { componentSnapshot } from '@kit.ArkUI';
|
|
|
|
|
+import fs from '@ohos.file.fs';
|
|
|
|
|
+
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
* @method cashPhotos 传入需要下载得url数组并下载文件,通过回调函数返回对应cashPaths数组
|
|
* @method cashPhotos 传入需要下载得url数组并下载文件,通过回调函数返回对应cashPaths数组
|
|
@@ -14,19 +17,16 @@ import { YTLog } from '../../../../Index';
|
|
|
* @method saveByShowAssetsCreationDialog 通过ShowAssetsCreationDialog保存文件(弹窗)
|
|
* @method saveByShowAssetsCreationDialog 通过ShowAssetsCreationDialog保存文件(弹窗)
|
|
|
* @method getPhotoFileBuffer 将缓存的图片转化为流
|
|
* @method getPhotoFileBuffer 将缓存的图片转化为流
|
|
|
* @method saveImgToAssets 直接保存图片至相册 需要权限
|
|
* @method saveImgToAssets 直接保存图片至相册 需要权限
|
|
|
|
|
+ * @method saveScreenshotToAlbum 截屏保存图片
|
|
|
|
|
+ * @method manualCompression压缩图片
|
|
|
*/
|
|
*/
|
|
|
export class YTPhotoHelper {
|
|
export class YTPhotoHelper {
|
|
|
private cashPaths: string[] = []
|
|
private cashPaths: string[] = []
|
|
|
private currentIndex: number = 0
|
|
private currentIndex: number = 0
|
|
|
- private readonly context: Context
|
|
|
|
|
-
|
|
|
|
|
- constructor(context: Context) {
|
|
|
|
|
- this.context = context
|
|
|
|
|
- }
|
|
|
|
|
|
|
|
|
|
//传入需要下载得url数组并下载文件,通过回调函数返回对应cashPaths数组
|
|
//传入需要下载得url数组并下载文件,通过回调函数返回对应cashPaths数组
|
|
|
async cashPhotos(urls: string[], finishDownLoad: (cashPaths: string[]) => void, cashPhotoType: string = '.jpg') {
|
|
async cashPhotos(urls: string[], finishDownLoad: (cashPaths: string[]) => void, cashPhotoType: string = '.jpg') {
|
|
|
- let filePath = this.context.cacheDir + '/' + util.generateRandomUUID() + cashPhotoType
|
|
|
|
|
|
|
+ let filePath = ContextHelper.context.cacheDir + '/' + util.generateRandomUUID() + cashPhotoType
|
|
|
// Download the file. If the file already exists, delete the existing one first.
|
|
// Download the file. If the file already exists, delete the existing one first.
|
|
|
try {
|
|
try {
|
|
|
fileIo.accessSync(filePath);
|
|
fileIo.accessSync(filePath);
|
|
@@ -38,7 +38,7 @@ export class YTPhotoHelper {
|
|
|
await axios({
|
|
await axios({
|
|
|
url: urls[this.currentIndex],
|
|
url: urls[this.currentIndex],
|
|
|
method: 'get',
|
|
method: 'get',
|
|
|
- context: getContext(this),
|
|
|
|
|
|
|
+ context: ContextHelper.context,
|
|
|
filePath: filePath,
|
|
filePath: filePath,
|
|
|
onDownloadProgress: (progressEvent: AxiosProgressEvent): void => {
|
|
onDownloadProgress: (progressEvent: AxiosProgressEvent): void => {
|
|
|
YTLog.info("progress: " + progressEvent && progressEvent.loaded && progressEvent.total ?
|
|
YTLog.info("progress: " + progressEvent && progressEvent.loaded && progressEvent.total ?
|
|
@@ -56,7 +56,7 @@ export class YTPhotoHelper {
|
|
|
|
|
|
|
|
//拍照获取图片
|
|
//拍照获取图片
|
|
|
async takePicture() {
|
|
async takePicture() {
|
|
|
- let pathDir = this.context.filesDir;
|
|
|
|
|
|
|
+ let pathDir = ContextHelper.context.filesDir;
|
|
|
let fileName = `${new Date().getTime()}`
|
|
let fileName = `${new Date().getTime()}`
|
|
|
let filePath = pathDir + `/${fileName}.png`
|
|
let filePath = pathDir + `/${fileName}.png`
|
|
|
fileIo.createRandomAccessFileSync(filePath, fileIo.OpenMode.CREATE);
|
|
fileIo.createRandomAccessFileSync(filePath, fileIo.OpenMode.CREATE);
|
|
@@ -67,7 +67,8 @@ export class YTPhotoHelper {
|
|
|
saveUri: uri
|
|
saveUri: uri
|
|
|
};
|
|
};
|
|
|
let result: picker.PickerResult =
|
|
let result: picker.PickerResult =
|
|
|
- await picker.pick(this.context, [picker.PickerMediaType.PHOTO], //(如果需要录像可以添加) picker.PickerMediaType.VIDEO
|
|
|
|
|
|
|
+ await picker.pick(ContextHelper.context, [picker.PickerMediaType.PHOTO],
|
|
|
|
|
+ //(如果需要录像可以添加) picker.PickerMediaType.VIDEO
|
|
|
pickerProfile);
|
|
pickerProfile);
|
|
|
if (!result.resultUri) {
|
|
if (!result.resultUri) {
|
|
|
return Promise.reject('用户未拍照')
|
|
return Promise.reject('用户未拍照')
|
|
@@ -85,7 +86,7 @@ export class YTPhotoHelper {
|
|
|
.then(res => {
|
|
.then(res => {
|
|
|
const photoName = util.generateRandomUUID()
|
|
const photoName = util.generateRandomUUID()
|
|
|
const photoType = '.' + res.photoUris[0].split('.').pop()
|
|
const photoType = '.' + res.photoUris[0].split('.').pop()
|
|
|
- const fullPath = this.context.cacheDir + '/' + photoName + photoType
|
|
|
|
|
|
|
+ const fullPath = ContextHelper.context.cacheDir + '/' + photoName + photoType
|
|
|
const photo = fileIo.openSync(res.photoUris[0])
|
|
const photo = fileIo.openSync(res.photoUris[0])
|
|
|
try {
|
|
try {
|
|
|
fileIo.copyFile(photo.fd, fullPath)
|
|
fileIo.copyFile(photo.fd, fullPath)
|
|
@@ -99,10 +100,48 @@ export class YTPhotoHelper {
|
|
|
})
|
|
})
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ // 保存截图到相册的方法
|
|
|
|
|
+ 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保存文件
|
|
//传入需要保存得cashPaths数组,并通过ShowAssetsCreationDialog保存文件
|
|
|
- async saveByShowAssetsCreationDialog(cashPaths: string[], success?: () => void) {
|
|
|
|
|
- const phAccessHelper = photoAccessHelper.getPhotoAccessHelper(this.context);
|
|
|
|
|
|
|
+ async saveByShowAssetsCreationDialog(
|
|
|
|
|
+ cashPaths: string[],
|
|
|
|
|
+ result?: ResultCallBack<undefined>,
|
|
|
|
|
+ clearCashPaths: boolean = false) {
|
|
|
|
|
+ const phAccessHelper = photoAccessHelper.getPhotoAccessHelper(ContextHelper.context);
|
|
|
const uris = cashPaths.map(item => fileUri.getUriFromPath(item))
|
|
const uris = cashPaths.map(item => fileUri.getUriFromPath(item))
|
|
|
try {
|
|
try {
|
|
|
// 指定待保存照片的创建选项,包括文件后缀和照片类型,标题和照片子类型可选。
|
|
// 指定待保存照片的创建选项,包括文件后缀和照片类型,标题和照片子类型可选。
|
|
@@ -129,9 +168,13 @@ export class YTPhotoHelper {
|
|
|
await fileIo.close(file)
|
|
await fileIo.close(file)
|
|
|
index++
|
|
index++
|
|
|
}
|
|
}
|
|
|
- success?.()
|
|
|
|
|
|
|
+ result?.()
|
|
|
|
|
+ if (clearCashPaths) {
|
|
|
|
|
+ cashPaths.forEach(cashPath => fileIo.unlink(cashPath))
|
|
|
|
|
+ }
|
|
|
} catch (err) {
|
|
} catch (err) {
|
|
|
YTLog.error(err)
|
|
YTLog.error(err)
|
|
|
|
|
+ result?.(undefined, err)
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -160,7 +203,7 @@ export class YTPhotoHelper {
|
|
|
while (index < cashPaths.length) {
|
|
while (index < cashPaths.length) {
|
|
|
//获取当前上下文
|
|
//获取当前上下文
|
|
|
//通过accessHelper模块获取accessHelper对象
|
|
//通过accessHelper模块获取accessHelper对象
|
|
|
- let accessHelper = photoAccessHelper.getPhotoAccessHelper(getContext())
|
|
|
|
|
|
|
+ let accessHelper = photoAccessHelper.getPhotoAccessHelper(ContextHelper.context)
|
|
|
//指定待创建的文件类型、后缀和创建选项,创建图片或视频资源 返回创建的图片和视频的uri
|
|
//指定待创建的文件类型、后缀和创建选项,创建图片或视频资源 返回创建的图片和视频的uri
|
|
|
let uri = await accessHelper.createAsset(photoAccessHelper.PhotoType.IMAGE, 'jpg')
|
|
let uri = await accessHelper.createAsset(photoAccessHelper.PhotoType.IMAGE, 'jpg')
|
|
|
//通过该uri打开图片
|
|
//通过该uri打开图片
|
|
@@ -178,4 +221,24 @@ export class YTPhotoHelper {
|
|
|
YTLog.error(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
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|