From 8629370f576e1aba5d249c1c3fdfd2f4998959a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=98=8E=E6=9C=88=E6=B8=85=E9=A3=8E?= <2928139825@qq.com> Date: Thu, 27 Jul 2023 14:49:31 +0800 Subject: [PATCH] =?UTF-8?q?1.=E4=BF=AE=E5=A4=8DImageKnife=E7=BB=98?= =?UTF-8?q?=E5=88=B6=E9=83=A8=E5=88=86=E5=A4=8D=E6=9D=82gif=E5=9B=BE?= =?UTF-8?q?=E7=89=87=EF=BC=8Cgif=E5=9B=BE=E7=89=87=E9=97=AA=E5=B1=8F?= =?UTF-8?q?=E6=98=BE=E7=A4=BA=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 明月清风 <2928139825@qq.com> --- AppScope/app.json5 | 2 +- CHANGELOG.md | 10 ++ README.md | 2 +- entry/oh-package.json5 | 4 +- imageknife/oh-package.json5 | 2 +- .../ets/components/imageknife/ImageKnife.ets | 2 +- .../imageknife/ImageKnifeComponent.ets | 110 +++++++++--------- .../components/imageknife/RequestOption.ets | 2 +- oh-package.json5 | 2 +- 9 files changed, 73 insertions(+), 63 deletions(-) diff --git a/AppScope/app.json5 b/AppScope/app.json5 index 6e57827..d2dc22d 100644 --- a/AppScope/app.json5 +++ b/AppScope/app.json5 @@ -3,7 +3,7 @@ "bundleName": "com.openharmony.imageknife", "vendor": "example", "versionCode": 1000000, - "versionName": "1.0.0", + "versionName": "2.0.2", "icon": "$media:app_icon", "label": "$string:app_name", "distributedNotificationEnabled": true diff --git a/CHANGELOG.md b/CHANGELOG.md index fe33e98..ecbd17a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,13 @@ +## 2.0.2 + +- 修复若干问题: + +​ 修复ImageKnife绘制部分复杂gif图片,gif图片闪屏显示的问题 + +​ 适配DevEco Studio 版本:4.0 Canary2(4.0.3.312), SDK: API10 (4.0.9.3) + + + ## 2.0.1 - 修复若干问题: diff --git a/README.md b/README.md index dd8899c..df7372f 100644 --- a/README.md +++ b/README.md @@ -452,7 +452,7 @@ request.skipMemoryCache(true) 在下述版本验证通过: -DevEco Studio版本: 4.0Canary1(4.0.3.212), SDK: API10(4.0.8.3) +DevEco Studio 版本:4.0 Canary2(4.0.3.312), SDK: API10 (4.0.9.3) ## 目录结构 diff --git a/entry/oh-package.json5 b/entry/oh-package.json5 index c1075b1..8ee4860 100644 --- a/entry/oh-package.json5 +++ b/entry/oh-package.json5 @@ -1,10 +1,10 @@ { - "license": "ISC", + "license": "Apache License 2.0", "devDependencies": {}, "name": "entry", "description": "example description", "repository": {}, - "version": "1.0.0", + "version": "2.0.2", "dependencies": { "@ohos/imageknife": "file:../imageknife", "@ohos/disklrucache": "^2.0.0" diff --git a/imageknife/oh-package.json5 b/imageknife/oh-package.json5 index 4a5ac13..40311a8 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.1", + "version": "2.0.2", "dependencies": { "@ohos/disklrucache": "^2.0.0", "@ohos/svg": "^2.0.0", diff --git a/imageknife/src/main/ets/components/imageknife/ImageKnife.ets b/imageknife/src/main/ets/components/imageknife/ImageKnife.ets index a8a6ede..c631cef 100644 --- a/imageknife/src/main/ets/components/imageknife/ImageKnife.ets +++ b/imageknife/src/main/ets/components/imageknife/ImageKnife.ets @@ -18,7 +18,7 @@ import { LruCache } from "../cache/LruCache" import {EngineKeyFactories} from "../cache/key/EngineKeyFactories" import {EngineKeyInterface} from "../cache/key/EngineKeyInterface" import {RequestOption} from "../imageknife/RequestOption" -import {AsyncCallback} from "../imageknife/interface/asynccallback" +import {AsyncCallback} from "../imageknife/interface/AsyncCallback" import {PlaceHolderManager} from "../imageknife/holder/PlaceHolderManager" import {RetryHolderManager} from "../imageknife/holder/RetryHolderManager" import {ErrorHolderManager} from "../imageknife/holder/ErrorHolderManager" diff --git a/imageknife/src/main/ets/components/imageknife/ImageKnifeComponent.ets b/imageknife/src/main/ets/components/imageknife/ImageKnifeComponent.ets index 31abc5d..cdff39e 100644 --- a/imageknife/src/main/ets/components/imageknife/ImageKnifeComponent.ets +++ b/imageknife/src/main/ets/components/imageknife/ImageKnifeComponent.ets @@ -25,17 +25,12 @@ import { LogUtil } from '../imageknife/utils/LogUtil' @Component export struct ImageKnifeComponent { @Watch('watchImageKnifeOption') @ObjectLink imageKnifeOption: ImageKnifeOption; - - autoPlay:boolean = true - + autoPlay: boolean = true private settings: RenderingContextSettings = new RenderingContextSettings(true) private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings) private hasDisplayRetryholder = false; - - - private lastWidth:number = 0 - private lastHeight:number = 0 - + private lastWidth: number = 0 + private lastHeight: number = 0 private currentWidth: number = 0 private currentHeight: number = 0 @@ -82,9 +77,10 @@ export struct ImageKnifeComponent { } } - private canvasHasReady:boolean = false; - private firstDrawFlag:boolean = false; - private onReadyNext:()=>void = undefined + private canvasHasReady: boolean = false; + private firstDrawFlag: boolean = false; + private onReadyNext: () => void = undefined + build() { Canvas(this.context) .width('100%') @@ -92,11 +88,11 @@ export struct ImageKnifeComponent { .onAreaChange((oldValue: Area, newValue: Area) => { this.currentWidth = newValue.width as number this.currentHeight = newValue.height as number - if(this.currentWidth <=0 || this.currentHeight <=0 ){ + if (this.currentWidth <= 0 || this.currentHeight <= 0) { // 存在宽或者高为0,此次重回无意义,无需进行request请求 - }else{ + } else { // 前提:宽高值均有效,值>0. 条件1:当前宽高与上一次宽高不同 条件2:当前是第一次绘制 - if( (this.currentHeight != this.lastHeight || this.currentWidth != this.lastWidth) || this.firstDrawFlag){ + if ((this.currentHeight != this.lastHeight || this.currentWidth != this.lastWidth) || this.firstDrawFlag) { this.firstDrawFlag = false; LogUtil.log('ImageKnifeComponent onAreaChange And Next To Execute. Canvas currentWidth =' + this.currentWidth + ' currentHeight=' + this.currentHeight) this.lastWidth = this.currentWidth @@ -107,15 +103,15 @@ export struct ImageKnifeComponent { }) .onReady(() => { this.canvasHasReady = true; - if(this.onReadyNext){ + if (this.onReadyNext) { LogUtil.log('ImageKnifeComponent onReadyNext is running!') this.onReadyNext() this.onReadyNext = undefined; } }) - .onClick((event:ClickEvent) => { + .onClick((event: ClickEvent) => { // 需要将点击事件回传 - if(this.imageKnifeOption.onClick){ + if (this.imageKnifeOption.onClick) { this.imageKnifeOption.onClick(event) } if (this.imageKnifeOption.canRetryClick && this.hasDisplayRetryholder) { @@ -134,13 +130,13 @@ export struct ImageKnifeComponent { * 给firstDrawFlag置为true,保证size即使没有变化也要进入 请求绘制流程 * @param drawFirst 是否是aboutToAppear第一次绘制 */ - whetherWaitSize(drawFirst?:boolean) { - if(this.currentHeight <= 0 || this.currentWidth <= 0){ + whetherWaitSize(drawFirst?: boolean) { + if (this.currentHeight <= 0 || this.currentWidth <= 0) { // 宽或者高没有高度,需要等待canvas组件初始化完成 - if(drawFirst){ + if (drawFirst) { this.firstDrawFlag = true; } - }else{ + } else { LogUtil.log('ImageKnifeComponent whetherWaitSize 宽高有效 直接发送请求') this.imageKnifeExecute() } @@ -157,11 +153,11 @@ export struct ImageKnifeComponent { * 待onReady执行的时候执行 * @param nextFunction 下一个方法 */ - runNextFunction(nextFunction:()=>void){ - if(!this.canvasHasReady){ + runNextFunction(nextFunction: () => void) { + if (!this.canvasHasReady) { // canvas未初始化完成 this.onReadyNext = nextFunction; - }else{ + } else { nextFunction(); } } @@ -170,15 +166,15 @@ export struct ImageKnifeComponent { request.load(this.imageKnifeOption.loadSrc) .addListener((err, data) => { LogUtil.log('ImageKnifeComponent request.load callback') - this.runNextFunction(this.displayMainSource.bind(this,data)); + this.runNextFunction(this.displayMainSource.bind(this, data)); return false; }) - let realSize = { - width: this.currentWidth, - height: this.currentHeight - } - request.setImageViewSize(realSize) + let realSize = { + width: this.currentWidth, + height: this.currentHeight + } + request.setImageViewSize(realSize) } configCacheStrategy(request: RequestOption) { @@ -202,14 +198,14 @@ export struct ImageKnifeComponent { if (this.imageKnifeOption.placeholderSrc) { request.placeholder(this.imageKnifeOption.placeholderSrc, (data) => { LogUtil.log('ImageKnifeComponent request.placeholder callback') - this.runNextFunction(this.displayPlaceholder.bind(this,data)) + this.runNextFunction(this.displayPlaceholder.bind(this, data)) }) } if (this.imageKnifeOption.thumbSizeMultiplier) { request.thumbnail(this.imageKnifeOption.thumbSizeMultiplier, (data) => { LogUtil.log('ImageKnifeComponent request.thumbnail callback') - this.runNextFunction(this.displayThumbSizeMultiplier.bind(this,data)) + this.runNextFunction(this.displayThumbSizeMultiplier.bind(this, data)) }, this.imageKnifeOption.thumbSizeDelay) } if (this.imageKnifeOption.errorholderSrc) { @@ -237,7 +233,7 @@ export struct ImageKnifeComponent { request.addProgressListener((percentValue: number) => { // 如果进度条百分比 未展示大小,展示其动画 LogUtil.log('ImageKnifeComponent request.addProgressListener callback') - this.runNextFunction(this.displayProgress.bind(this,percentValue)) + this.runNextFunction(this.displayProgress.bind(this, percentValue)) }) } @@ -245,17 +241,15 @@ export struct ImageKnifeComponent { request.retryholder(this.imageKnifeOption.retryholderSrc, (data) => { LogUtil.log('ImageKnifeComponent request.retryholder callback') this.hasDisplayRetryholder = true - this.runNextFunction(this.displayRetryholder.bind(this,data)) + this.runNextFunction(this.displayRetryholder.bind(this, data)) }) } } - - - configRenderGpu(request: RequestOption){ - if(this.imageKnifeOption.enableGpu){ + configRenderGpu(request: RequestOption) { + if (this.imageKnifeOption.enableGpu) { request.enableGPU() - }else{ + } else { // 如果enableGpu未设置则不启动GPU渲染 } } @@ -282,11 +276,11 @@ export struct ImageKnifeComponent { displayPlaceholder(data: ImageKnifeData) { if (!this.drawLifeCycleHasConsumed(this.imageKnifeOption.drawLifeCycle, 'displayPlaceholder', this.context, data, this.imageKnifeOption, - this.currentWidth, this.currentHeight, (gifTimeId) => { + this.currentWidth, this.currentHeight, (gifTimeId) => { this.setGifTimeId(gifTimeId) })) { if (!this.drawLifeCycleHasConsumed(globalThis.ImageKnife.getDefaultLifeCycle(), 'displayPlaceholder', this.context, data, this.imageKnifeOption, - this.currentWidth, this.currentHeight, (gifTimeId) => { + this.currentWidth, this.currentHeight, (gifTimeId) => { this.setGifTimeId(gifTimeId) })) { this.defaultLifeCycle.displayPlaceholder(this.context, data, this.imageKnifeOption, this.currentWidth, this.currentHeight, (gifTimeId) => { @@ -300,11 +294,11 @@ export struct ImageKnifeComponent { displayProgress(percent: number) { if (!this.drawLifeCycleHasConsumed(this.imageKnifeOption.drawLifeCycle, 'displayProgress', this.context, percent, this.imageKnifeOption, - this.currentWidth, this.currentHeight, (gifTimeId) => { + this.currentWidth, this.currentHeight, (gifTimeId) => { this.setGifTimeId(gifTimeId) })) { if (!this.drawLifeCycleHasConsumed(globalThis.ImageKnife.getDefaultLifeCycle(), 'displayProgress', this.context, percent, this.imageKnifeOption, - this.currentWidth, this.currentHeight, (gifTimeId) => { + this.currentWidth, this.currentHeight, (gifTimeId) => { this.setGifTimeId(gifTimeId) })) { this.defaultLifeCycle.displayProgress(this.context, percent, this.imageKnifeOption, this.currentWidth, this.currentHeight, (gifTimeId) => { @@ -318,11 +312,11 @@ export struct ImageKnifeComponent { displayThumbSizeMultiplier(data: ImageKnifeData) { if (!this.drawLifeCycleHasConsumed(this.imageKnifeOption.drawLifeCycle, 'displayThumbSizeMultiplier', this.context, data, this.imageKnifeOption, - this.currentWidth, this.currentHeight, (gifTimeId) => { + this.currentWidth, this.currentHeight, (gifTimeId) => { this.setGifTimeId(gifTimeId) })) { if (!this.drawLifeCycleHasConsumed(globalThis.ImageKnife.getDefaultLifeCycle(), 'displayThumbSizeMultiplier', this.context, data, this.imageKnifeOption, - this.currentWidth, this.currentHeight, (gifTimeId) => { + this.currentWidth, this.currentHeight, (gifTimeId) => { this.setGifTimeId(gifTimeId) })) { this.defaultLifeCycle.displayThumbSizeMultiplier(this.context, data, this.imageKnifeOption, this.currentWidth, this.currentHeight, (gifTimeId) => { @@ -334,11 +328,11 @@ export struct ImageKnifeComponent { displayMainSource(data: ImageKnifeData) { if (!this.drawLifeCycleHasConsumed(this.imageKnifeOption.drawLifeCycle, 'displayMainSource', this.context, data, this.imageKnifeOption, - this.currentWidth, this.currentHeight, (gifTimeId) => { + this.currentWidth, this.currentHeight, (gifTimeId) => { this.setGifTimeId(gifTimeId) })) { if (!this.drawLifeCycleHasConsumed(globalThis.ImageKnife.getDefaultLifeCycle(), 'displayMainSource', this.context, data, this.imageKnifeOption, - this.currentWidth, this.currentHeight, (gifTimeId) => { + this.currentWidth, this.currentHeight, (gifTimeId) => { this.setGifTimeId(gifTimeId) })) { this.defaultLifeCycle.displayMainSource(this.context, data, this.imageKnifeOption, this.currentWidth, this.currentHeight, (gifTimeId) => { @@ -352,11 +346,11 @@ export struct ImageKnifeComponent { displayRetryholder(data: ImageKnifeData) { if (!this.drawLifeCycleHasConsumed(this.imageKnifeOption.drawLifeCycle, 'displayRetryholder', this.context, data, this.imageKnifeOption, - this.currentWidth, this.currentHeight, (gifTimeId) => { + this.currentWidth, this.currentHeight, (gifTimeId) => { this.setGifTimeId(gifTimeId) })) { if (!this.drawLifeCycleHasConsumed(globalThis.ImageKnife.getDefaultLifeCycle(), 'displayRetryholder', this.context, data, this.imageKnifeOption, - this.currentWidth, this.currentHeight, (gifTimeId) => { + this.currentWidth, this.currentHeight, (gifTimeId) => { this.setGifTimeId(gifTimeId) })) { this.defaultLifeCycle.displayRetryholder(this.context, data, this.imageKnifeOption, this.currentWidth, this.currentHeight, (gifTimeId) => { @@ -369,11 +363,11 @@ export struct ImageKnifeComponent { displayErrorholder(data: ImageKnifeData) { if (!this.drawLifeCycleHasConsumed(this.imageKnifeOption.drawLifeCycle, 'displayErrorholder', this.context, data, this.imageKnifeOption, - this.currentWidth, this.currentHeight, (gifTimeId) => { + this.currentWidth, this.currentHeight, (gifTimeId) => { this.setGifTimeId(gifTimeId) })) { if (!this.drawLifeCycleHasConsumed(globalThis.ImageKnife.getDefaultLifeCycle(), 'displayErrorholder', this.context, data, this.imageKnifeOption, - this.currentWidth, this.currentHeight, (gifTimeId) => { + this.currentWidth, this.currentHeight, (gifTimeId) => { this.setGifTimeId(gifTimeId) })) { this.defaultLifeCycle.displayErrorholder(this.context, data, this.imageKnifeOption, this.currentWidth, this.currentHeight, (gifTimeId) => { @@ -676,10 +670,17 @@ export struct ImageKnifeComponent { if (index >= 1) { let preFrame = frames[index-1] disposal = preFrame.disposalType + + if (disposal === FrameDisposalType.DISPOSE_RestoreBackground) { + const { width, height, left, top } = preFrame.dims; + context.clearRect(left, top, width, height); + } + } else { + if (disposal === FrameDisposalType.DISPOSE_RestoreBackground) { + context.clearRect(0, 0, compWidth, compHeight) + } } - if (disposal === FrameDisposalType.DISPOSE_RestoreBackground) { - context.clearRect(0, 0, compWidth, compHeight) - } + let scaleType = (typeof this.imageKnifeOption.mainScaleType == 'number') ? this.imageKnifeOption.mainScaleType : ScaleType.FIT_CENTER context.save(); let frameW = frames[0].dims.left + frames[0].dims.width @@ -725,7 +726,6 @@ export enum ScaleType { } - export class ScaleTypeHelper { static drawImageWithScaleType(context: CanvasRenderingContext2D, scaleType: ScaleType, source: PixelMap | ImageBitmap, imageWidth: number, imageHeight: number, compWidth: number, compHeight: number, imageOffsetX: number, imageOffsetY: number) { let scaleW = compWidth / imageWidth diff --git a/imageknife/src/main/ets/components/imageknife/RequestOption.ets b/imageknife/src/main/ets/components/imageknife/RequestOption.ets index cc09074..d130631 100644 --- a/imageknife/src/main/ets/components/imageknife/RequestOption.ets +++ b/imageknife/src/main/ets/components/imageknife/RequestOption.ets @@ -14,7 +14,7 @@ */ import { DiskStrategy } from "../cache/diskstrategy/DiskStrategy" -import type { AsyncCallback } from "../imageknife/interface/asynccallback" +import type { AsyncCallback } from "../imageknife/interface/AsyncCallback" import type { AsyncSuccess } from "../imageknife/interface/AsyncSuccess" import type { IAllCacheInfoCallback } from "../imageknife/interface/IAllCacheInfoCallback" import { AUTOMATIC } from "../cache/diskstrategy/enum/AUTOMATIC" diff --git a/oh-package.json5 b/oh-package.json5 index f6480cc..5c64671 100644 --- a/oh-package.json5 +++ b/oh-package.json5 @@ -6,6 +6,6 @@ "name": "imageknife", "description": "example description", "repository": {}, - "version": "1.0.0", + "version": "2.0.2", "dependencies": {} }