diff --git a/CHANGELOG.md b/CHANGELOG.md index d751c46..6717a1d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ ## 2.1.1-rc.5 - .jpg .png .gif解码功能使用taskpool实现 - 修复了内存缓存张数设置为1时gif图片消失的问题 +- 新增内存缓存策略,新增缓存张数,缓存大小设置接口 diff --git a/README.md b/README.md index eaf9af7..21e1e27 100644 --- a/README.md +++ b/README.md @@ -386,6 +386,39 @@ request.skipMemoryCache(true) +### setLruCacheSize + +setLruCacheSize(size: number,memory:number): void + +设置图片文件缓存的大小上限,size单位为张数,memory单位为字节,提升再次加载同源图片的加载速度,特别是对网络图源会有较明显提升。 +如果不设置则默认为100张,100MB。缓存采用内置的LRU策略。 +size为0则代表不限制缓存张数,memory为0则代表不限制缓存大小。 +建议根据应用实际需求,设置合理缓存上限,数字过大可能导致内存占用过高,可能导致OOM异常。 + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| -------- | -------- | -------- |-------------------------| +| size | number | 是 | 图片文件的缓存张数,单位为张。只支持正整数,0 | +| memory | number | 是 | 图片文件的缓存大小,单位为字节。只支持正数,0 | + +**示例:** +```ts +//EntryAbility.ets +import { InitImageKnife } from '...imageknife' +export default class EntryAbility extends UIAbility { + onWindowStageCreate(windowStage: window.WindowStage) { + InitImageKnife.init(this.context); + let imageKnife: ImageKnife | undefined = ImageKnifeGlobal.getInstance().getImageKnife() + if (imageKnife != undefined) { + //设置全局内存缓存大小张数 + imageKnife.setLruCacheSize(100, 100 * 1204 * 1024) + } + } +} +``` + + ## 约束与限制 在下述版本验证通过: diff --git a/entry/oh-package.json5 b/entry/oh-package.json5 index 7f3ed43..f371f22 100644 --- a/entry/oh-package.json5 +++ b/entry/oh-package.json5 @@ -6,13 +6,8 @@ "repository": {}, "version": "2.1.1-rc.4", "dependencies": { - - // 如果测试entry的demo需要开启以下2个依赖, 然后点击entry勾选 Edit Configurations->点击Deploy Multi Hap->勾选Deploy Multi Hap Packages - // 然后点击module栏目 把library也勾选上,这样就可以在HSP场景下测试Entry里面的HSP场景 "@ohos/libraryimageknife": "file:../library", "@ohos/disklrucache": "^2.0.2-rc.0", - - // 下面这个依赖是为了跑XTS用例的,需要跑XTS时 需要注释上面2个依赖单独使用imageknife依赖 "@ohos/imageknife": "file:../imageknife" } } diff --git a/entry/src/main/ets/entryability/EntryAbility.ets b/entry/src/main/ets/entryability/EntryAbility.ets index 3e816e7..f4c40d5 100644 --- a/entry/src/main/ets/entryability/EntryAbility.ets +++ b/entry/src/main/ets/entryability/EntryAbility.ets @@ -15,40 +15,42 @@ import UIAbility from '@ohos.app.ability.UIAbility'; import hilog from '@ohos.hilog'; import window from '@ohos.window'; -import {InitImageKnife, ImageKnifeGlobal,ImageKnife,ImageKnifeDrawFactory,LogUtil } from '@ohos/libraryimageknife' +import { InitImageKnife, ImageKnifeGlobal, ImageKnife, ImageKnifeDrawFactory, LogUtil } from '@ohos/libraryimageknife' import { CustomEngineKeyImpl } from './CustomEngineKeyImpl' -import abilityAccessCtrl,{Permissions} from '@ohos.abilityAccessCtrl'; +import abilityAccessCtrl, { Permissions } from '@ohos.abilityAccessCtrl'; import { BusinessError } from '@ohos.base' export default class EntryAbility extends UIAbility { - onWindowStageCreate(windowStage: window.WindowStage) { - // Main window is created, set main page for this ability - let list : Array = ['ohos.permission.MEDIA_LOCATION','ohos.permission.READ_MEDIA']; - let permissionRequestResult:Object; - let atManager = abilityAccessCtrl.createAtManager(); - atManager.requestPermissionsFromUser(this.context, list, (err:BusinessError,result:Object)=>{ - if(err){ - console.log("dodo requestPermissionsFromUserError:"+JSON.stringify(err)); - }else{ - permissionRequestResult = result; - console.log("dodo permissionRequestResult:"+JSON.stringify(permissionRequestResult)) - } - }) + onWindowStageCreate(windowStage: window.WindowStage) { + // Main window is created, set main page for this ability + let list: Array = ['ohos.permission.MEDIA_LOCATION', 'ohos.permission.READ_MEDIA']; + let permissionRequestResult: Object; + let atManager = abilityAccessCtrl.createAtManager(); + atManager.requestPermissionsFromUser(this.context, list, (err: BusinessError, result: Object) => { + if (err) { + console.log("dodo requestPermissionsFromUserError:" + JSON.stringify(err)); + } else { + permissionRequestResult = result; + console.log("dodo permissionRequestResult:" + JSON.stringify(permissionRequestResult)) + } + }) - windowStage.loadContent('pages/index', (err:BusinessError, data:void) => { - }); + windowStage.loadContent('pages/index', (err: BusinessError, data: void) => { + }); - InitImageKnife.init(this.context); + InitImageKnife.init(this.context); - let imageKnife:ImageKnife|undefined = ImageKnifeGlobal.getInstance().getImageKnife() - if(imageKnife != undefined) { - // 全局配置网络加载进度条 - imageKnife - .setDefaultLifeCycle(ImageKnifeDrawFactory.createProgressLifeCycle("#10a5ff", 0.5)) - // 全局配置缓存key - imageKnife.setEngineKeyImpl(new CustomEngineKeyImpl()) - } - //开启ImageKnife所有级别日志开关 - LogUtil.mLogLevel = LogUtil.ALL + let imageKnife: ImageKnife | undefined = ImageKnifeGlobal.getInstance().getImageKnife() + if (imageKnife != undefined) { + // 全局配置网络加载进度条 + imageKnife + .setDefaultLifeCycle(ImageKnifeDrawFactory.createProgressLifeCycle("#10a5ff", 0.5)) + // 全局配置缓存key + imageKnife.setEngineKeyImpl(new CustomEngineKeyImpl()) + //设置全局内存缓存大小张数 + imageKnife.setLruCacheSize(100, 100 * 1204 * 1024) } + //开启ImageKnife所有级别日志开关 + LogUtil.mLogLevel = LogUtil.ALL + } } diff --git a/entry/src/main/ets/pages/index.ets b/entry/src/main/ets/pages/index.ets index a4cb9a5..879f5f5 100644 --- a/entry/src/main/ets/pages/index.ets +++ b/entry/src/main/ets/pages/index.ets @@ -79,7 +79,7 @@ struct IndexFunctionDemo { Button("ImageKnife测试目录页面") .onClick(() => { console.log("pages/imageknifeTestCaseIndex 页面跳转") - router.replaceUrl({ url: "pages/imageknifeTestCaseIndex" }); + router.pushUrl({ url: "pages/imageknifeTestCaseIndex" }); }).margin({ top: 15 }) }.width('100%').height(60).backgroundColor(Color.Pink) } diff --git a/imageknife/src/main/ets/components/cache/MemoryLruCache.ets b/imageknife/src/main/ets/components/cache/MemoryLruCache.ets index df78b51..7eeb9f1 100644 --- a/imageknife/src/main/ets/components/cache/MemoryLruCache.ets +++ b/imageknife/src/main/ets/components/cache/MemoryLruCache.ets @@ -14,32 +14,110 @@ */ import { ImageKnife } from '../imageknife/ImageKnife'; import { ImageKnifeData } from '../imageknife/ImageKnifeData'; +import { LogUtil } from '../imageknife/utils/LogUtil'; import { LruCache } from './LruCache'; -export class MemoryLruCache extends LruCache{ - constructor(maxsize:number) { - super(maxsize) +export class MemoryLruCache extends LruCache { + maxMemory: number = 0 + memorySize: number = 0 + + constructor(maxsize: number, maxMemory: number) { + super(maxsize); + this.removeAll(); + this.maxMemory = maxMemory + this.memorySize = 0; + } + + // 添加缓存键值对 + put(key: string, value: ImageKnifeData) { + if (key == null || value == null) { + throw new Error('key or value is invalid '); + } + let pre = this.map.get(key) + if (pre == null ) { + this.size++ + this.addMemorySize(value) + } + this.entryRemoved(key, pre, value); + this.trimToSize(); + } + + // 移除键为key的缓存 + remove(key: string): ImageKnifeData | undefined { + if (key == null) { + throw new Error('key is null,checking the parameter'); + } + let preValue = this.map.get(key) + if (this.map.remove(key)) { + this.size-- + if (preValue != undefined) { + this.removeMemorySize(preValue) + } + } + return preValue + } + + removeAll() { + this.map.clear() + this.size = 0 + this.memorySize = 0; } // 移除较少使用的缓存数据 - trimToSize(tempsize: number) { + trimToSize() { + LogUtil.info("MemoryLruCache maxSize:" + this.maxsize + " maxMemory: " + this.maxMemory) + if (this.maxMemory == 0 || this.maxsize == 0 ){ + return; + } while (true) { - if (tempsize < 0) { - this.map.clear() - this.size = 0 - break - } - if (this.size <= tempsize || this.map.isEmpty()) { + if (this.size <= this.maxsize && this.memorySize <= this.maxMemory || this.map.isEmpty()) { break } let delkey = this.map.getFirstKey() - let data : ImageKnifeData|undefined = this.map.get(delkey) - if(data != undefined){ + let data: ImageKnifeData | undefined = this.map.get(delkey) + this.size-- + if (data != undefined) { + this.removeMemorySize(data) data.release() } this.map.remove(delkey) - this.size-- } } + private removeMemorySize(value: ImageKnifeData): void { + if (value.drawPixelMap != undefined) { + LogUtil.info("MemoryLruCache removeMemorySize---- top drawPixelMap memorySize:" + this.memorySize) + if (value.drawPixelMap.imagePixelMap != undefined) { + this.memorySize -= value.drawPixelMap.imagePixelMap.getPixelBytesNumber(); + } + LogUtil.info("MemoryLruCache removeMemorySize---- end drawPixelMap memorySize:" + this.memorySize) + } + if (value.drawGIFFrame != undefined) { + LogUtil.info("MemoryLruCache removeMemorySize---- top drawGIFFrame memorySize:" + this.memorySize) + if (value.drawGIFFrame != undefined) { + this.memorySize -= value.drawGIFFrame.getGIFFramesBytesNumber(); + } + LogUtil.info("MemoryLruCache removeMemorySize---- end drawGIFFrame memorySize:" + this.memorySize) + } + LogUtil.info("MemoryLruCache removeMemorySize---- end mapSize:" + this.map.size()) + } + + private addMemorySize(value: ImageKnifeData): void { + if (value.drawPixelMap != undefined) { + LogUtil.info("MemoryLruCache addMemorySize---- top drawPixelMap memorySize:" + this.memorySize) + if (value.drawPixelMap.imagePixelMap != undefined) { + this.memorySize += value.drawPixelMap.imagePixelMap.getPixelBytesNumber(); + } + LogUtil.info("MemoryLruCache addMemorySize---- end drawPixelMap memorySize:" + this.memorySize) + } + if (value.drawGIFFrame != undefined) { + LogUtil.info("MemoryLruCache addMemorySize---- top drawGIFFrame memorySize:" + this.memorySize) + if (value.drawGIFFrame != undefined) { + this.memorySize += value.drawGIFFrame.getGIFFramesBytesNumber(); + } + LogUtil.info("MemoryLruCache addMemorySize---- end drawGIFFrame memorySize:" + this.memorySize) + } + LogUtil.info("MemoryLruCache addMemorySize---- end mapSize:" + this.map.size()) + } + } \ No newline at end of file diff --git a/imageknife/src/main/ets/components/imageknife/ImageKnife.ets b/imageknife/src/main/ets/components/imageknife/ImageKnife.ets index c2976c3..3e54d99 100644 --- a/imageknife/src/main/ets/components/imageknife/ImageKnife.ets +++ b/imageknife/src/main/ets/components/imageknife/ImageKnife.ets @@ -78,7 +78,7 @@ export class ImageKnife { this.pausedMaps = new EasyLinkedHashMap(); // 构造方法传入size 为保存文件个数 - this.memoryCache = new MemoryLruCache(100); + this.memoryCache = new MemoryLruCache(100,100*1024*1024); // 创建disk缓存 传入的size 为多少比特 比如20KB 传入20*1024 this.diskMemoryCache = DiskLruCache.create(ImageKnifeGlobal.getInstance().getHapContext()); @@ -174,12 +174,13 @@ export class ImageKnife { return new CompressBuilder(); } - // 替代原来的LruCache - public replaceLruCache(size: number) { + + // 设置缓存张数,缓存大小,单位字节 + public setLruCacheSize(size: number,memory:number) { if (this.memoryCache.map.size() <= 0) { - this.memoryCache = new MemoryLruCache(size); + this.memoryCache = new MemoryLruCache(size,memory); } else { - let newLruCache = new MemoryLruCache(size); + let newLruCache = new MemoryLruCache(size,memory); this.memoryCache.foreachLruCache((value: ImageKnifeData, key: string, map: Object) => { newLruCache.put(key, value); }) diff --git a/imageknife/src/main/ets/components/imageknife/ImageKnifeComponent.ets b/imageknife/src/main/ets/components/imageknife/ImageKnifeComponent.ets index e997ec7..7aa4a26 100644 --- a/imageknife/src/main/ets/components/imageknife/ImageKnifeComponent.ets +++ b/imageknife/src/main/ets/components/imageknife/ImageKnifeComponent.ets @@ -87,6 +87,8 @@ export struct ImageKnifeComponent { private detachFromLayoutGIF :DetachFromLayout|undefined = undefined; + private detachFromLayoutPixelMap :DetachFromLayout|undefined = undefined; + build() { Canvas(this.context) @@ -511,7 +513,6 @@ export struct ImageKnifeComponent { drawMainSource(context: CanvasRenderingContext2D, data: ImageKnifeData, imageKnifeOption: ImageKnifeOption, compWidth: number, compHeight: number, setGifTimeId?: (timeId: number) => void) { LogUtil.log('ImageKnifeComponent default drawMainSource start!') if (data.isPixelMap()) { - data.drawPixelMap?.imagePixelMap?.getImageInfo().then((imageInfo) => { let scaleType = (typeof imageKnifeOption.mainScaleType == 'number') ? imageKnifeOption.mainScaleType : ScaleType.FIT_CENTER LogUtil.log('ImageKnifeComponent imageinfo width =' + imageInfo.size.width + ' height=' + imageInfo.size.height + 'scaleType=' + scaleType) @@ -521,6 +522,10 @@ export struct ImageKnifeComponent { context.restore(); LogUtil.log('ImageKnifeComponent default drawMainSource end!') }) + if (data.drawPixelMap != undefined) { + data.drawPixelMap.isShowOnComponent = true; + this.detachFromLayoutPixelMap = data.drawPixelMap.detachFromLayoutPixelMap; + } } else if (data.isGIFFrame()) { if(data.drawGIFFrame != undefined) { data.drawGIFFrame.isShowOnComponent = true @@ -614,6 +619,9 @@ export struct ImageKnifeComponent { if(this.detachFromLayoutGIF != undefined){ this.detachFromLayoutGIF.detach(); } + if (this.detachFromLayoutPixelMap != undefined) { + this.detachFromLayoutPixelMap.detach(); + } this.resetGifData(); } diff --git a/imageknife/src/main/ets/components/imageknife/ImageKnifeData.ets b/imageknife/src/main/ets/components/imageknife/ImageKnifeData.ets index 575b451..6cd4753 100644 --- a/imageknife/src/main/ets/components/imageknife/ImageKnifeData.ets +++ b/imageknife/src/main/ets/components/imageknife/ImageKnifeData.ets @@ -14,6 +14,8 @@ */ import { GIFFrame } from './utils/gif/GIFFrame' import { DetachFromLayout } from './RequestOption' +import { LogUtil } from './utils/LogUtil' +import { Ellipse2 } from '@ohos/svg/src/main/ets/components/utils/SVGBase' export enum ImageKnifeType { PIXELMAP = 'PixelMap', @@ -24,6 +26,21 @@ export enum ImageKnifeType { export class DrawPixelMap { imagePixelMap: PixelMap | undefined = undefined + isShowOnComponent: boolean = false; //gif是否显示在组件上 true:显示在组件上 false:不显示在组件上 + isLruCacheRelease: boolean = false; //当前lru是否释放gif资源,true的就释放了gif资源 false就是没有释放 + + detachFromLayoutPixelMap: DetachFromLayout = { + detach: () => { + this.isShowOnComponent = false + if (this.isLruCacheRelease) { + let pixelMap = this.imagePixelMap; + if (pixelMap != undefined) { + pixelMap.release(); + } + this.imagePixelMap = undefined; + } + } + } } export class DrawString { @@ -36,13 +53,13 @@ export class DrawResource { export class DrawGIFFrame { imageGIFFrames: GIFFrame[] | undefined = undefined - isShowOnComponent:boolean = false;//gif是否显示在组件上 true:显示在组件上 false:不显示在组件上 - isLruCacheRelease:boolean = false;//当前lru是否释放gif资源,true的就释放了gif资源 false就是没有释放 + isShowOnComponent: boolean = false; //gif是否显示在组件上 true:显示在组件上 false:不显示在组件上 + isLruCacheRelease: boolean = false; //当前lru是否释放gif资源,true的就释放了gif资源 false就是没有释放 - detachFromLayoutGIF :DetachFromLayout = { - detach:()=> { + detachFromLayoutGIF: DetachFromLayout = { + detach: () => { this.isShowOnComponent = false - if(this.isLruCacheRelease) { + if (this.isLruCacheRelease) { let gifFrames = this.imageGIFFrames; if (gifFrames != undefined) { for (let i = 0; i < gifFrames.length; i++) { @@ -56,6 +73,20 @@ export class DrawGIFFrame { } } }; + + getGIFFramesBytesNumber(): number { + let pixelMapBytes: number = 0; + if (this.imageGIFFrames != undefined) { + for (let index = 0; index < this.imageGIFFrames.length; index++) { + let drawPixelMap = this.imageGIFFrames[index].drawPixelMap; + if (drawPixelMap != undefined) { + pixelMapBytes += drawPixelMap.getPixelBytesNumber(); + LogUtil.info("getGIFFramesBytesNumber gif总大小为:" + pixelMapBytes); + } + } + } + return pixelMapBytes; + } } export class ImageKnifeData { @@ -65,9 +96,7 @@ export class ImageKnifeData { static PNG = 'png'; static BMP = 'bmp'; static WEBP = 'webp'; - waitSaveDisk = false; - imageKnifeType: ImageKnifeType | undefined = undefined; drawPixelMap: DrawPixelMap | undefined = undefined; drawGIFFrame: DrawGIFFrame | undefined = undefined; @@ -79,6 +108,7 @@ export class ImageKnifeData { data.imageKnifeType = type; data.drawPixelMap = new DrawPixelMap(); data.drawPixelMap.imagePixelMap = value; + data.drawPixelMap.isShowOnComponent = true; return data; } @@ -87,6 +117,7 @@ export class ImageKnifeData { data.imageKnifeType = type; data.drawGIFFrame = new DrawGIFFrame(); data.drawGIFFrame.imageGIFFrames = value; + data.drawGIFFrame.isShowOnComponent = true; return data; } @@ -106,24 +137,30 @@ export class ImageKnifeData { return ImageKnifeType.RESOURCE == this.imageKnifeType; } - release(){ - if(this.isPixelMap()){ - if(this.drawPixelMap != undefined && this.drawPixelMap.imagePixelMap != undefined){ - this.drawPixelMap.imagePixelMap.release() - .then(()=>{ - if(this.drawPixelMap != undefined && this.drawPixelMap.imagePixelMap !=undefined){ - this.drawPixelMap.imagePixelMap = undefined; - } - }) + release() { + if (this.isPixelMap()) { + if (this.drawPixelMap != undefined && this.drawPixelMap.imagePixelMap != undefined) { + this.drawPixelMap.isLruCacheRelease = true; + if (this.drawPixelMap.isShowOnComponent){ + return; + }else { + this.drawPixelMap.imagePixelMap.release() + .then(() => { + if (this.drawPixelMap != undefined && this.drawPixelMap.imagePixelMap != undefined) { + this.drawPixelMap.imagePixelMap = undefined; + } + }) + } + LogUtil.info("MemoryLruCache removeMemorySize---- end 释放普通图片:") } } - if(this.isGIFFrame()){ + if (this.isGIFFrame()) { if (this.drawGIFFrame != undefined) { this.drawGIFFrame.isLruCacheRelease = true; - if(this.drawGIFFrame.isShowOnComponent){ + if (this.drawGIFFrame.isShowOnComponent) { return; - }else { + } else { let gifFrames = this.drawGIFFrame.imageGIFFrames; if (gifFrames != undefined) { for (let i = 0; i < gifFrames.length; i++) { @@ -132,6 +169,7 @@ export class ImageKnifeData { tempFrame.drawPixelMap.release() } } + LogUtil.info("MemoryLruCache removeMemorySize---- end 释放GIF图片:") this.drawGIFFrame.imageGIFFrames = undefined } this.drawGIFFrame.imageGIFFrames = undefined @@ -139,18 +177,17 @@ export class ImageKnifeData { } } - if(this.isString()){ - if(this.drawString != undefined && this.drawString.imageString!=undefined){ + if (this.isString()) { + if (this.drawString != undefined && this.drawString.imageString != undefined) { this.drawString.imageString = undefined } } - if(this.isResource()){ - if(this.drawResource != undefined && this.drawResource.imageResource != undefined){ + if (this.isResource()) { + if (this.drawResource != undefined && this.drawResource.imageResource != undefined) { this.drawResource.imageResource = undefined } } } - } \ No newline at end of file diff --git a/imageknife/src/main/ets/components/imageknife/utils/ParseImageUtil.ets b/imageknife/src/main/ets/components/imageknife/utils/ParseImageUtil.ets index a4ae4a5..5fc0ea4 100644 --- a/imageknife/src/main/ets/components/imageknife/utils/ParseImageUtil.ets +++ b/imageknife/src/main/ets/components/imageknife/utils/ParseImageUtil.ets @@ -26,12 +26,42 @@ export class ParseImageUtil implements IParseImage { // scale(0,1) parseImageThumbnail(scale: number, imageinfo: ArrayBuffer, onCompleteFunction: (value: PixelMap) => void | PromiseLike, onErrorFunction: (reason?: BusinessError | string) => void) { - taskPoolExecutePixelMap(imageinfo,scale,onCompleteFunction,onErrorFunction); + // taskPoolExecutePixelMap(imageinfo,scale,onCompleteFunction,onErrorFunction); + + let imageSource:image.ImageSource = image.createImageSource(imageinfo); // 步骤一:文件转为pixelMap 然后变换 给Image组件 + imageSource.getImageInfo((err, value) => { + if (err) { + onErrorFunction(err); + return; + } + let hValue = Math.round(value.size.height * scale); + let wValue = Math.round(value.size.width * scale); + let defaultSize:image.Size = { + height: hValue, + width: wValue + }; + + let opts:image.DecodingOptions = { + editable: true, + desiredSize: defaultSize + }; + imageSource.createPixelMap(opts, (err, pixelmap) => { + if (err) { + onErrorFunction(err); + } else { + onCompleteFunction(pixelmap); + } + imageSource.release() + }) + + }) + + } } -// let TAG:string = "ParseImageUtil_TASK" + @Concurrent async function taskParseImage(arrayBuffer: ArrayBuffer,scale: number): Promise { diff --git a/imageknife/src/main/ets/components/imageknife/utils/gif/GIFParseImpl.ets b/imageknife/src/main/ets/components/imageknife/utils/gif/GIFParseImpl.ets index 6846e6f..83cb55e 100644 --- a/imageknife/src/main/ets/components/imageknife/utils/gif/GIFParseImpl.ets +++ b/imageknife/src/main/ets/components/imageknife/utils/gif/GIFParseImpl.ets @@ -35,7 +35,47 @@ export interface gifBackData { export class GIFParseImpl implements IParseGif { parseGifs(imageinfo: ArrayBuffer, callback: (data?: GIFFrame[], err?: BusinessError | string) => void) { - taskPoolExecutePixelMapList(imageinfo,callback); + // taskPoolExecutePixelMapList(imageinfo,callback); + // oh解码流程 + let imageSource = image.createImageSource(imageinfo); + let decodeOpts: image.DecodingOptions = { + sampleSize: 1, + editable: true, + rotate: 0 + } + let data:GIFFrame[] = []; + imageSource.createPixelMapList(decodeOpts).then((pixelList: Array) => { + //sdk的api接口发生变更:从.getDelayTime() 变为.getDelayTimeList() + imageSource.getDelayTimeList().then(delayTimes => { + if (pixelList.length > 0) { + let pixelmap = pixelList[0]; + pixelmap.getImageInfo().then(imageInfo => { + for (let i = 0; i < pixelList.length; i++) { + let frame = new GIFFrame(); + frame.drawPixelMap = pixelList[i]; + frame.dims = { width: imageInfo.size.width, height: imageInfo.size.height, top: 0, left: 0 } + if (i < delayTimes.length) { + frame.delay = delayTimes[i]; + } else { + frame.delay = delayTimes[delayTimes.length - 1] + } + data.push(frame) + } + callback(data,undefined) + imageSource.release(); + }).catch((err: string) => { + imageSource.release(); + callback(undefined,err) + }) + } + }).catch((err: string) => { + imageSource.release(); + callback(undefined,err) + }) + }).catch((err: string) => { + imageSource.release(); + callback(undefined,err) + }) } } @@ -50,8 +90,8 @@ async function taskParseGif(arrayBuffer: ArrayBuffer): Promise { } let pixelList = await imageSource.createPixelMapList(decodeOpts); if (pixelList.length > 0) { - let pixelmap1 = pixelList[0]; - let imageInfo = await pixelmap1.getImageInfo(); + let pixelmap = pixelList[0]; + let imageInfo = await pixelmap.getImageInfo(); let delayTimes = await imageSource.getDelayTimeList(); for (let i = 0; i < pixelList.length; i++) { let frame = new GIFFrame();