diff --git a/CHANGELOG.md b/CHANGELOG.md index 0b62225..fe33e98 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,14 +1,25 @@ -## 2.0.0 -- 包管理工具由npm切换为ohpm -- 适配DevEco Studio: 3.1Beta2(3.1.0.400) -- 适配SDK: API9 Release(3.2.11.9) -- 新增开发者可对图片缓存进行全局配置能力 -- 新增对OpenHarmony图库的Uri数据加载的能力(需要申请图库访问权限和文件读取权限,动态申请图库访问权限) +## 2.0.1 + - 修复若干问题: -​ 1.ImageKnifeOption的loadSrc为undefined,导致的crash问题 +​ 修复ImageKnifeDrawFactory中的setOval和setRect的中心点取值错误,导致部分圆角绘制失效的问题。 -​ 2.ImageKnifeComponent直接绘制GIF图片格式第几帧的时候,无法绘制问题。 +​ 修复因重复下载导致的漏加载的问题。 + +- 新增用例看护已修复的问题 + +## 2.0.0 + +- 包管理工具由npm切换为ohpm。 +- 适配DevEco Studio: 3.1Beta2(3.1.0.400)。 +- 适配SDK: API9 Release(3.2.11.9)。 +- 新增开发者可对图片缓存进行全局配置能力。 +- 新增对OpenHarmony图库的Uri数据加载的能力(需要申请图库访问权限和文件读取权限,动态申请图库访问权限)。 +- 修复若干问题: + +​ ImageKnifeOption的loadSrc为undefined,导致的crash问题。 + +​ ImageKnifeComponent直接绘制GIF图片格式第几帧的时候,无法绘制问题。 ## 1.0.6 @@ -42,11 +53,11 @@ ​ 支持装饰滤波器 ## 1.0.5 -- 自定义组件已支持通用属性和通用事件绑定,因此ImageKnifeComponent将删除相关内容,相关内容由用户自定义实现,提高扩展能力 +- 自定义组件已支持通用属性和通用事件绑定,因此ImageKnifeComponent将删除相关内容,相关内容由用户自定义实现,提高扩展能力。 -- ImageKnifeOption 支持列表绑定 +- ImageKnifeOption 支持列表绑定。 -- ImageKnifeOption +- ImageKnifeOption 。 新增 @@ -60,13 +71,13 @@ - 4.margin 组件外间距 等属性,删除的属性将由通用属性提供支持,可支持在ImageKnifeComponent自定义组件上链式调用 ## 1.0.4 -- 渲染显示部分使用Canvas组件替代Image组件 +- 渲染显示部分使用Canvas组件替代Image组件。 -- 重构渲染封装层ImageKnifeComponent自定义组件 +- 重构渲染封装层ImageKnifeComponent自定义组件。 -- 新增GIF图片解析能力 +- 新增GIF图片解析能力。 -- 新增SVG图片解析能力 +- 新增SVG图片解析能力。 ## 1.0.3 diff --git a/entry/src/main/ets/pages/imageknifeTestCaseIndex.ets b/entry/src/main/ets/pages/imageknifeTestCaseIndex.ets index b01f3a3..0cdad89 100644 --- a/entry/src/main/ets/pages/imageknifeTestCaseIndex.ets +++ b/entry/src/main/ets/pages/imageknifeTestCaseIndex.ets @@ -139,10 +139,10 @@ struct IndexFunctionDemo { console.log("重试Retry") router.pushUrl({ url: "pages/frescoRetryTestCasePage" }); }).margin({ top: 5, left: 3 }) - Button("加载媒体库url") + Button("加载媒体库uri") .onClick(() => { - console.log("加载媒体库url") - router.pushUrl({ url: "pages/dataShareurlLoadPage" }); + console.log("加载媒体库uri") + router.pushUrl({ url: "pages/dataShareUriLoadPage" }); }).margin({ top: 5, left: 3 }) }.width('100%').height(60).backgroundColor(Color.Pink) diff --git a/imageknife/oh-package.json5 b/imageknife/oh-package.json5 index 59bff96..4a5ac13 100644 --- a/imageknife/oh-package.json5 +++ b/imageknife/oh-package.json5 @@ -14,7 +14,7 @@ "main": "index.ets", "repository": "https://gitee.com/openharmony-tpc/ImageKnife", "type": "module", - "version": "2.0.0", + "version": "2.0.1", "dependencies": { "@ohos/disklrucache": "^2.0.0", "@ohos/svg": "^2.0.0", diff --git a/imageknife/src/main/ets/components/cache/FileUtils.ets b/imageknife/src/main/ets/components/cache/FileUtils.ets index 18ffe3c..49c1a49 100644 --- a/imageknife/src/main/ets/components/cache/FileUtils.ets +++ b/imageknife/src/main/ets/components/cache/FileUtils.ets @@ -16,11 +16,10 @@ import fs from '@ohos.file.fs'; export class FileUtils { - base64Str: string= '' - + base64Str: string = '' private static sInstance: FileUtils; - public static getInstance(): FileUtils{ + public static getInstance(): FileUtils { if (!this.sInstance) { this.sInstance = new FileUtils(); } @@ -32,34 +31,55 @@ export class FileUtils { } /** - * 新建文件 - * @param path 文件绝对路径及文件名 - * @return number 文件句柄id - */ - createFile(path: string): number{ + * 新建文件 + * @param path 文件绝对路径及文件名 + * @return number 文件句柄id + */ + createFile(path: string): number { return fs.openSync(path, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE).fd } /** - * 删除文件 - * @param path 文件绝对路径及文件名 - */ - deleteFile(path: string):void { + * 删除文件 + * @param path 文件绝对路径及文件名 + */ + deleteFile(path: string): void { try { let fileExist = fs.accessSync(path); - if(fileExist) { + if (fileExist) { fs.unlinkSync(path); } - }catch (err){ - console.log("FileUtils deleteFile Method has error, err msg="+err.message + " err code="+err.code); + } catch (err) { + console.log("FileUtils deleteFile Method has error, err msg=" + err.message + " err code=" + err.code); } } + /** + * 异步删除文件 + * @param path 文件绝对路径及文件名 + */ + deleteFileAsync(path: string): Promise { + return new Promise((resolve,reject)=>{ + fs.access(path).then(fileExist =>{ + if (fileExist) { + fs.unlink(path).then(()=>{ + resolve(); + }).catch(err=>{ + reject(err) + }) + } + }).catch(err=>{ + reject(err); + }) + }) + } + + /** * 同步删除文件目录 必须保证文件夹里面没有文件 * @param path 待删除目录的绝对路径 */ - deleteFolderSync(path: string):void { + deleteFolderSync(path: string): void { if (this.existFolder(path)) { fs.rmdirSync(path); } @@ -87,7 +107,7 @@ export class FileUtils { /** * 清空已有文件数据 */ - clearFile(path: string):number { + clearFile(path: string): number { return fs.openSync(path, fs.OpenMode.TRUNC).fd } @@ -113,7 +133,7 @@ export class FileUtils { try { let fd = fs.openSync(path, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE).fd let stat = fs.statSync(path) - console.info("FileUtils - writeData size = " + stat.size +" path="+path); + console.info("FileUtils - writeData size = " + stat.size + " path=" + path); fs.writeSync(fd, content, { offset: stat.size }) fs.closeSync(fd) } catch (e) { @@ -124,7 +144,7 @@ export class FileUtils { /** * 判断path文件是否存在 */ - exist(path: string): boolean{ + exist(path: string): boolean { try { let stat = fs.statSync(path) return stat.isFile() @@ -148,7 +168,7 @@ export class FileUtils { /** * 获取path的文件大小 */ - getFileSize(path: string): number{ + getFileSize(path: string): number { try { let stat = fs.statSync(path) return stat.size @@ -159,22 +179,49 @@ export class FileUtils { } /** - * 读取路径path的文件 + * 同步读取路径path的文件 */ readFilePic(path: string): ArrayBuffer { try { let stat = fs.statSync(path) - let fd = fs.openSync(path, fs.OpenMode.READ_WRITE).fd; + let fd = fs.openSync(path, fs.OpenMode.READ_ONLY).fd; let length = stat.size let buf = new ArrayBuffer(length); fs.readSync(fd, buf) fs.closeSync(fd) return buf } catch (e) { - console.log("FileUtils - readFilePic " + e) + console.log("FileUtils - readFilePicSync " + e) return new ArrayBuffer(0) } } + /** + * 异步读取路径path的文件 + */ + readFilePicAsync(path: string): Promise { + return new Promise((resolve,reject)=>{ + fs.open(path, fs.OpenMode.READ_ONLY).then((file) => { + let stat = fs.statSync(path) + let fd = file.fd; + let length = stat.size; + let buf = new ArrayBuffer(length); + fs.read(fd,buf).then((readLen)=>{ + // 关闭文件 + fs.closeSync(file); + resolve(buf); + }).catch(err=>{ + reject(err); + }) + }).catch(err=>{ + reject(err); + }) + + + }) + + } + + /** @@ -231,7 +278,7 @@ export class FileUtils { * 判断文件夹是否存在 * @param 文件夹绝对路径 */ - existFolder(path: string): boolean{ + existFolder(path: string): boolean { try { let stat = fs.statSync(path) return stat.isDirectory() @@ -243,9 +290,9 @@ export class FileUtils { /** * 如果文件夹不存在则创建一个文件夹 然后在其中创建文件 并且将数据写入进文件 - * @param folder 文件夹绝对路径 - * @param file 文件绝对路径 - * @param content 文件内容数据 + * @param folder 文件夹绝对路径 + * @param file 文件绝对路径 + * @param content 文件内容数据 */ createFileProcess(folder: string, file: string, content: ArrayBuffer | string) { //创建文件夹 @@ -260,7 +307,7 @@ export class FileUtils { * string 转 Uint8Array * @param str 输入String */ - stringToUint8Array(str): Uint8Array{ + stringToUint8Array(str): Uint8Array { var arr = []; for (var i = 0, j = str.length; i < j; ++i) { arr.push(str.charCodeAt(i)); @@ -271,7 +318,7 @@ export class FileUtils { /** * int 转 byte[] - * @param n 输入int + * @param n 输入int */ intTobytes2(n) { var bytes = []; @@ -285,7 +332,6 @@ export class FileUtils { uint8ArrayToBuffer(array: Uint8Array): ArrayBuffer { return array.buffer.slice(array.byteOffset, array.byteLength + array.byteOffset) } - } export interface AsyncCallback { diff --git a/imageknife/src/main/ets/components/imageknife/networkmanage/DownloadClient.ets b/imageknife/src/main/ets/components/imageknife/networkmanage/DownloadClient.ets index 9d2e7ae..04a6762 100644 --- a/imageknife/src/main/ets/components/imageknife/networkmanage/DownloadClient.ets +++ b/imageknife/src/main/ets/components/imageknife/networkmanage/DownloadClient.ets @@ -32,7 +32,7 @@ export class DownloadClient implements IDataFetch { .filesDir) || request.loadSrc.startsWith(globalThis.ImageKnife.getImageKnifeContext().cacheDir)) { // 本地沙盒 this.localFileClient.loadData(request, onCompleteFunction, onErrorFunction) - } else if (request.loadSrc.startsWith('datashare://')) { + } else if (request.loadSrc.startsWith('datashare://') || request.loadSrc.startsWith('file://')) { this.dataShareFileClient.loadData(request, onCompleteFunction, onErrorFunction) } else { // 网络下载 diff --git a/imageknife/src/main/ets/components/imageknife/networkmanage/LoadDataShareFileClient.ets b/imageknife/src/main/ets/components/imageknife/networkmanage/LoadDataShareFileClient.ets index 686de8d..0e69f6f 100644 --- a/imageknife/src/main/ets/components/imageknife/networkmanage/LoadDataShareFileClient.ets +++ b/imageknife/src/main/ets/components/imageknife/networkmanage/LoadDataShareFileClient.ets @@ -21,16 +21,19 @@ export class LoadDataShareFileClient implements IDataFetch { loadData(request: RequestOption, onComplete: (img: ArrayBuffer) => void, onError: (err: string) => void) { if (typeof request.loadSrc == 'string') { fs.open(request.loadSrc, fs.OpenMode.READ_ONLY).then((file) => { - let stat = fs.statSync(file.fd); - let buf = new ArrayBuffer(stat.size); - fs.read(file.fd, buf).then((readLen) => { - onComplete(buf); - fs.close(file.fd); + fs.stat(file.fd).then(stat =>{ + let buf = new ArrayBuffer(stat.size); + fs.read(file.fd, buf).then((readLen) => { + onComplete(buf); + fs.close(file.fd); + }).catch(err => { + onError('LoadDataShareFileClient fs.read err happend uri=' + request.loadSrc + " err.msg=" + err?.message + " err.code=" + err?.code) + }) }).catch(err => { - onError('LoadDataShareFileClient fs.read err happend uri=' + request.loadSrc + " err.msg=" + err.message + " err.code=" + err.code) + onError('LoadDataShareFileClient fs.stat err happend uri=' + request.loadSrc + " err.msg=" + err?.message + " err.code=" + err?.code) }) }).catch(err => { - onError('LoadDataShareFileClient fs.open err happend uri=' + request.loadSrc + " err.msg=" + err.message + " err.code=" + err.code) + onError('LoadDataShareFileClient fs.open err happend uri=' + request.loadSrc + " err.msg=" + err?.message + " err.code=" + err?.code) }) } } diff --git a/imageknife/src/main/ets/components/imageknife/networkmanage/LoadLocalFileClient.ets b/imageknife/src/main/ets/components/imageknife/networkmanage/LoadLocalFileClient.ets index cf59a9c..23f7030 100644 --- a/imageknife/src/main/ets/components/imageknife/networkmanage/LoadLocalFileClient.ets +++ b/imageknife/src/main/ets/components/imageknife/networkmanage/LoadLocalFileClient.ets @@ -20,12 +20,16 @@ import { FileUtils } from '../../cache/FileUtils' export class LoadLocalFileClient implements IDataFetch { loadData(request: RequestOption, onComplete: (img: ArrayBuffer) => void, onError: (err: string) => void) { if (typeof request.loadSrc == 'string') { - let fileBuffer = FileUtils.getInstance().readFilePic(request.loadSrc) - if (fileBuffer == null || fileBuffer.byteLength <= 0) { - onError('LoadLocalFileClient loadLocalFileData The File Does Not Exist!Check The File!') - } else { - onComplete(fileBuffer); - } + FileUtils.getInstance().readFilePicAsync(request.loadSrc).then(fileBuffer=>{ + if (fileBuffer == null || fileBuffer.byteLength <= 0) { + onError('LoadLocalFileClient loadLocalFileData The File Does Not Exist!Check The File!') + } else { + onComplete(fileBuffer); + } + }).catch(err=>{ + onError('LoadLocalFileClient loadLocalFileData Error Msg ='+err?.message) + }) + } } } \ No newline at end of file diff --git a/imageknife/src/main/ets/components/imageknife/networkmanage/NetworkDownloadClient.ets b/imageknife/src/main/ets/components/imageknife/networkmanage/NetworkDownloadClient.ets index 1b3716d..9886cea 100644 --- a/imageknife/src/main/ets/components/imageknife/networkmanage/NetworkDownloadClient.ets +++ b/imageknife/src/main/ets/components/imageknife/networkmanage/NetworkDownloadClient.ets @@ -18,6 +18,7 @@ import { RequestOption } from '../RequestOption' import { SparkMD5 } from '../../3rd_party/sparkmd5/spark-md5' import { FileUtils } from '../../cache/FileUtils' import loadRequest from '@ohos.request'; +import { LogUtil } from '../utils/LogUtil' // 数据加载器 export class NetworkDownloadClient implements IDataFetch { @@ -28,6 +29,8 @@ export class NetworkDownloadClient implements IDataFetch { if (!FileUtils.getInstance().existFolder(downloadFolder)) { FileUtils.getInstance().createFolder(downloadFolder) } + + // 理论上来讲不会进入这里来删除文件,但是如果存在文件,则需要同步删除保证后续文件下载没问题。 if (FileUtils.getInstance().exist(allpath)) { FileUtils.getInstance().deleteFile(allpath) } @@ -55,9 +58,17 @@ export class NetworkDownloadClient implements IDataFetch { loadTask.on('complete', () => { let downloadPath = allpath; request.downloadFilePath = downloadPath; - let arraybuffer = FileUtils.getInstance().readFilePic(downloadPath) - onComplete(arraybuffer); - FileUtils.getInstance().deleteFile(downloadPath); + FileUtils.getInstance().readFilePicAsync(downloadPath).then(arraybuffer=>{ + onComplete(arraybuffer); + FileUtils.getInstance().deleteFileAsync(downloadPath).then(()=>{ + LogUtil.log('文件名:'+downloadPath+" 文件删除成功!") + }).catch(err=>{ + LogUtil.log('文件名:'+downloadPath+" 文件删除失败!") + }); + }).catch(err=>{ + onError('NetworkDownloadClient Read File Async Error Msg='+ err?.message) + }) + loadTask.off('complete', () => {