# Conflicts:
#	library/src/main/ets/components/imageknife/utils/ParseImageUtil.ets
#	library/src/main/ets/components/imageknife/utils/gif/GIFParseImpl.ets
This commit is contained in:
zhoulisheng 2023-12-13 10:38:34 +08:00
commit 628f066200
135 changed files with 92 additions and 165 deletions

View File

@ -3,7 +3,7 @@
"bundleName": "com.openharmony.imageknife", "bundleName": "com.openharmony.imageknife",
"vendor": "example", "vendor": "example",
"versionCode": 1000000, "versionCode": 1000000,
"versionName": "2.1.1-rc.4", "versionName": "2.1.1-rc.5",
"icon": "$media:app_icon", "icon": "$media:app_icon",
"label": "$string:app_name", "label": "$string:app_name",
"distributedNotificationEnabled": true "distributedNotificationEnabled": true

View File

@ -2,7 +2,12 @@
- .jpg .png .gif解码功能使用taskpool实现 - .jpg .png .gif解码功能使用taskpool实现
- 修复了内存缓存张数设置为1时gif图片消失的问题 - 修复了内存缓存张数设置为1时gif图片消失的问题
- 新增内存缓存策略,新增缓存张数,缓存大小设置接口 - 新增内存缓存策略,新增缓存张数,缓存大小设置接口
- 磁盘存缓存setAsync改成同步
- 部分release释放放在异步
- requestInStream的回调改成异步
- 修复tasktool出现crash问题
- imageKnife依赖更名为library
- 解决外部定时器失效的问题
## 2.1.1-rc.4 ## 2.1.1-rc.4

View File

@ -10,7 +10,7 @@
<filteritem type="filename" name="hvigorw" desc="hvigorw配置文件DevEco Studio自动生成不手动修改"/> <filteritem type="filename" name="hvigorw" desc="hvigorw配置文件DevEco Studio自动生成不手动修改"/>
<filteritem type="filename" name="hvigorw.bat" desc="hvigorw配置文件DevEco Studio自动生成不手动修改"/> <filteritem type="filename" name="hvigorw.bat" desc="hvigorw配置文件DevEco Studio自动生成不手动修改"/>
<filteritem type="filename" name="hvigor-wrapper.js" desc="hvigorw配置文件DevEco Studio自动生成不手动修改"/> <filteritem type="filename" name="hvigor-wrapper.js" desc="hvigorw配置文件DevEco Studio自动生成不手动修改"/>
<filteritem type="filepath" name="imageknife/src/main/ets/components/3rd_party/.*" desc="第三方开源软件源码,不修改版权头,以防有修改版权风险"/> <filteritem type="filepath" name="library/src/main/ets/components/3rd_party/.*" desc="第三方开源软件源码,不修改版权头,以防有修改版权风险"/>
</filefilter> </filefilter>
<filefilter name="defaultPolicyFilter" desc="Filters for compatibilitylicense header policies"> <filefilter name="defaultPolicyFilter" desc="Filters for compatibilitylicense header policies">
<filteritem type="filename" name="hvigorfile.*" desc="hvigor配置文件DevEco Studio自动生成不手动修改"/> <filteritem type="filename" name="hvigorfile.*" desc="hvigor配置文件DevEco Studio自动生成不手动修改"/>
@ -20,7 +20,7 @@
<filteritem type="filename" name="hvigorw" desc="hvigorw配置文件DevEco Studio自动生成不手动修改"/> <filteritem type="filename" name="hvigorw" desc="hvigorw配置文件DevEco Studio自动生成不手动修改"/>
<filteritem type="filename" name="hvigorw.bat" desc="hvigorw配置文件DevEco Studio自动生成不手动修改"/> <filteritem type="filename" name="hvigorw.bat" desc="hvigorw配置文件DevEco Studio自动生成不手动修改"/>
<filteritem type="filename" name="hvigor-wrapper.js" desc="hvigorw配置文件DevEco Studio自动生成不手动修改"/> <filteritem type="filename" name="hvigor-wrapper.js" desc="hvigorw配置文件DevEco Studio自动生成不手动修改"/>
<filteritem type="filepath" name="imageknife/src/main/ets/components/3rd_party/.*" desc="第三方开源软件源码,不修改版权头,以防有修改版权风险"/> <filteritem type="filepath" name="library/src/main/ets/components/3rd_party/.*" desc="第三方开源软件源码,不修改版权头,以防有修改版权风险"/>
</filefilter> </filefilter>
<filefilter name="binaryFileTypePolicyFilter" desc="Filters for binary file policies"> <filefilter name="binaryFileTypePolicyFilter" desc="Filters for binary file policies">
<filteritem type="filename" name="*.dpg" desc="dpg图片格式文件,用于展示示例"/> <filteritem type="filename" name="*.dpg" desc="dpg图片格式文件,用于展示示例"/>
@ -34,7 +34,7 @@
<filteritem type="filename" name="*.json5" desc="hvigor配置文件"/> <filteritem type="filename" name="*.json5" desc="hvigor配置文件"/>
</filefilter> </filefilter>
<filefilter name="defaultFilter" desc="Files not to check"> <filefilter name="defaultFilter" desc="Files not to check">
<filteritem type="filepath" name="imageknife/src/main/ets/components/3rd_party/.*" desc="第三方开源软件源码,不修改版权头,以防有修改版权风险"/> <filteritem type="filepath" name="library/src/main/ets/components/3rd_party/.*" desc="第三方开源软件源码,不修改版权头,以防有修改版权风险"/>
</filefilter> </filefilter>
</filefilterlist> </filefilterlist>
</oatconfig> </oatconfig>

View File

@ -428,7 +428,7 @@ DevEco Studio 4.04.0.3.700--SDK:API10 4.0.10.15
## 目录结构 ## 目录结构
``` ```
/imageknife/src/ /library/src/
- main/ets/components - main/ets/components
- cache # 缓存相关内容 - cache # 缓存相关内容
- diskstrategy # 缓存策略 - diskstrategy # 缓存策略

View File

@ -31,8 +31,8 @@
] ]
}, },
{ {
"name": "imageknife", "name": "library",
"srcPath": "./imageknife" "srcPath": "./library"
}, },
{ {
"name": "gpu_transform", "name": "gpu_transform",

View File

@ -4,13 +4,10 @@
"name": "entry", "name": "entry",
"description": "example description", "description": "example description",
"repository": {}, "repository": {},
"version": "2.1.1-rc.4", "version": "2.1.1-rc.5",
"dependencies": { "dependencies": {
// 如果测试entry的demo需要开启以下2个依赖, 然后点击entry勾选 Edit Configurations->点击Deploy Multi Hap->勾选Deploy Multi Hap Packages
// 然后点击module栏目 把library也勾选上,这样就可以在HSP场景下测试Entry里面的HSP场景
"@ohos/libraryimageknife": "file:../sharedlibrary", "@ohos/libraryimageknife": "file:../sharedlibrary",
"@ohos/disklrucache": "^2.0.2-rc.0", "@ohos/disklrucache": "^2.0.2-rc.0",
// 下面这个依赖是为了跑XTS用例的需要跑XTS时,需要注释上面2个依赖单独使用imageknife依赖 "@ohos/imageknife": "file:../library"
"@ohos/imageknife": "file:../imageknife"
} }
} }

View File

@ -15,15 +15,15 @@
import { ImageKnife, ImageKnifeComponent, ImageKnifeGlobal, ImageKnifeOption } from "@ohos/libraryimageknife" import { ImageKnife, ImageKnifeComponent, ImageKnifeGlobal, ImageKnifeOption } from "@ohos/libraryimageknife"
import worker from '@ohos.worker'; import worker from '@ohos.worker';
let gifUrl = "https://gw.alicdn.com/tfs/TB1E3H5t8Bh1e4jSZFhXXcC9VXa-198-198.gif" let gifUrl = "https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658"
let data: string[] = [ let data: string[] = [
'https://media.giphy.com/media/hVgagDPf1IRFK/giphy.gif', 'https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658',
'https://placehold.co/600x400/000000/FFFFFF/png', 'https://hbimg.huabanimg.com/cc6af25f8d782d3cf3122bef4e61571378271145735e9-vEVggB',
'https://s1.aigei.com/src/img/gif/92/922f58ca46c34b3e9947ddd4dc17ec32.gif?imageMogr2/auto-orient/thumbnail/!282x282r/gravity/Center/crop/282x282/quality/85/&e=1735488000&token=P7S2Xpzfz11vAkASLTkfHN7Fw-oOZBecqeJaxypL:YRYJJynbOC0Z_Nl7HunjuRr4-Vk=', 'https://pic.ibaotu.com/gif/18/17/16/51u888piCtqj.gif!fwpaa70/fw/700',
'https://placehold.co/600x400/000000/orange/png', 'https://img-blog.csdnimg.cn/20191215043500229.png',
'https://s1.aigei.com/src/img/gif/6c/6c907924ef1546d3a593fae3e78b97f6.gif?imageMogr2/auto-orient/thumbnail/!282x282r/gravity/Center/crop/282x282/quality/85/&e=1735488000&token=P7S2Xpzfz11vAkASLTkfHN7Fw-oOZBecqeJaxypL:PozGIimx0mj5m69DQ0Z6qWn7mA0=', 'https://res.vmallres.com/cmscdn/CN/2023-03/7052a601ac3e428c84c9415ad9734735.gif',
'https://placehold.co/600x400/000000/orange/png?text=Hello+World' 'https://img-blog.csdn.net/20140514114029140'
] ]
@Entry @Entry
@ -56,28 +56,6 @@ struct TestManyGifLoadWithPage {
}.width('50%').backgroundColor(Color.Blue) }.width('50%').backgroundColor(Color.Blue)
} }
Row() {
Column() {
Button('use Worker').align(Alignment.Center).fontSize(10).margin(2)
.onClick(() => {
this.workerOption = {
loadSrc: gifUrl,
placeholderSrc: $r('app.media.icon_loading'),
errorholderSrc: $r('app.media.icon_failed')
}
})
ImageKnifeComponent({ imageKnifeOption: this.workerOption })
.width('100%')
.height(100)
.backgroundColor(Color.Blue)
}.width('50%').backgroundColor(Color.Orange)
Column() {
Button('logs').align(Alignment.Center).fontSize(10).margin(2)
Text('logs').width('100%').height(100).backgroundColor(Color.Orange)
}.width('50%').backgroundColor(Color.Blue)
}
Grid() { Grid() {
ForEach(data, (url: string) => { ForEach(data, (url: string) => {
GridItem(){ GridItem(){

View File

@ -60,20 +60,26 @@ class CommonDataSource <T> implements IDataSource {
struct TestManyNetImageLoadWithPage { struct TestManyNetImageLoadWithPage {
@State hotCommendList:CommonDataSource<string> = new CommonDataSource<string>([]) @State hotCommendList:CommonDataSource<string> = new CommonDataSource<string>([])
private data:Array<string> = [ private data:Array<string> = [
'http://s.yingshidq.com.cn/cover/longbms/2023/08/11/2159934215_1248_702.jpeg', "http://e.hiphotos.baidu.com/image/pic/item/a1ec08fa513d2697e542494057fbb2fb4316d81e.jpg",
'http://s.yingshidq.com.cn/imags/poster/2022/08/02/165937334218556809.jpeg', "http://c.hiphotos.baidu.com/image/pic/item/30adcbef76094b36de8a2fe5a1cc7cd98d109d99.jpg",
'http://s.yingshidq.com.cn/cover/longbms/2023/08/10/4350315060_640_360.jpeg', "http://h.hiphotos.baidu.com/image/pic/item/7c1ed21b0ef41bd5f2c2a9e953da81cb39db3d1d.jpg",
'http://s.yingshidq.com.cn/cover/longbms/2023/08/10/3835072893_1248_702.jpeg', "http://g.hiphotos.baidu.com/image/pic/item/55e736d12f2eb938d5277fd5d0628535e5dd6f4a.jpg",
'http://s.yingshidq.com.cn/cover/longbms/2023/08/10/2821936016_1248_702.jpeg', "http://e.hiphotos.baidu.com/image/pic/item/4e4a20a4462309f7e41f5cfe760e0cf3d6cad6ee.jpg",
'http://s.yingshidq.com.cn/cover/longbms/2023/08/11/1311714870_1248_702.jpeg', "http://b.hiphotos.baidu.com/image/pic/item/9d82d158ccbf6c81b94575cfb93eb13533fa40a2.jpg",
'http://s.yingshidq.com.cn/cover/longbms/2023/08/10/4421772097_1248_702.jpeg', "http://e.hiphotos.baidu.com/image/pic/item/4bed2e738bd4b31c1badd5a685d6277f9e2ff81e.jpg",
'http://s.yingshidq.com.cn/cover/longbms/2023/09/05/5898334347_400_225.png', "http://g.hiphotos.baidu.com/image/pic/item/0d338744ebf81a4c87a3add4d52a6059252da61e.jpg",
'http://s.yingshidq.com.cn/imags/poster/2022/12/06/167031399911862707.jpeg', "http://a.hiphotos.baidu.com/image/pic/item/f2deb48f8c5494ee5080c8142ff5e0fe99257e19.jpg",
'http://s.yingshidq.com.cn/cover/longbms/2023/08/11/1405851829_1248_702.jpeg', "http://f.hiphotos.baidu.com/image/pic/item/4034970a304e251f503521f5a586c9177e3e53f9.jpg",
'http://s.yingshidq.com.cn/cover/longbms/2023/08/10/3796501624_1248_702.jpeg', "http://b.hiphotos.baidu.com/image/pic/item/279759ee3d6d55fbb3586c0168224f4a20a4dd7e.jpg",
'http://s.yingshidq.com.cn/cover/longbms/2023/08/10/4202181519_1248_702.jpeg', "http://img2.xkhouse.com/bbs/hfhouse/data/attachment/forum/corebbs/2009-11/2009113011534566298.jpg",
'http://s.yingshidq.com.cn/cover/longbms/2023/08/11/1449894622_1248_702.jpeg', "http://a.hiphotos.baidu.com/image/pic/item/e824b899a9014c087eb617650e7b02087af4f464.jpg",
'http://s.yingshidq.com.cn/cover/longbms/2023/08/10/3756558151_1248_702.jpeg' "http://c.hiphotos.baidu.com/image/pic/item/9c16fdfaaf51f3de1e296fa390eef01f3b29795a.jpg",
"http://d.hiphotos.baidu.com/image/pic/item/b58f8c5494eef01f119945cbe2fe9925bc317d2a.jpg",
"http://h.hiphotos.baidu.com/image/pic/item/902397dda144ad340668b847d4a20cf430ad851e.jpg",
"http://b.hiphotos.baidu.com/image/pic/item/359b033b5bb5c9ea5c0e3c23d139b6003bf3b374.jpg",
"http://a.hiphotos.baidu.com/image/pic/item/8d5494eef01f3a292d2472199d25bc315d607c7c.jpg",
"http://b.hiphotos.baidu.com/image/pic/item/e824b899a9014c08878b2c4c0e7b02087af4f4a3.jpg",
"http://g.hiphotos.baidu.com/image/pic/item/6d81800a19d8bc3e770bd00d868ba61ea9d345f2.jpg",
] ]
aboutToAppear() { aboutToAppear() {
this.hotCommendList.addData(this.hotCommendList.totalCount(),this.data) this.hotCommendList.addData(this.hotCommendList.totalCount(),this.data)

View File

@ -36,7 +36,7 @@ export struct ImageKnifeComponent {
private currentWidth: number = 0 private currentWidth: number = 0
private currentHeight: number = 0 private currentHeight: number = 0
// 定时器id // 定时器id
private gifTimerId: number = 0 private gifTimerId: number = -1
// 完整gif播放时间 // 完整gif播放时间
private gifLoopDuration: number = 0 private gifLoopDuration: number = 0
private startGifLoopTime: number = 0 private startGifLoopTime: number = 0

View File

@ -138,18 +138,24 @@ export class ImageKnifeData {
} }
release() { release() {
let promise = new Promise<void>((resolve) => {
resolve()
})
if (this.isPixelMap()) { if (this.isPixelMap()) {
if (this.drawPixelMap != undefined && this.drawPixelMap.imagePixelMap != undefined) { if (this.drawPixelMap != undefined && this.drawPixelMap.imagePixelMap != undefined) {
this.drawPixelMap.isLruCacheRelease = true; this.drawPixelMap.isLruCacheRelease = true;
if (this.drawPixelMap.isShowOnComponent){ if (this.drawPixelMap.isShowOnComponent) {
return; return;
}else { } else {
this.drawPixelMap.imagePixelMap.release() promise.then(() => {
.then(() => { if (this.drawPixelMap != undefined && this.drawPixelMap.imagePixelMap != undefined) {
if (this.drawPixelMap != undefined && this.drawPixelMap.imagePixelMap != undefined) { this.drawPixelMap.imagePixelMap.release(() => {
this.drawPixelMap.imagePixelMap = undefined; if (this.drawPixelMap != undefined && this.drawPixelMap.imagePixelMap != undefined) {
} this.drawPixelMap.imagePixelMap = undefined
}) }
})
}
})
} }
LogUtil.info("MemoryLruCache removeMemorySize---- end 释放普通图片:") LogUtil.info("MemoryLruCache removeMemorySize---- end 释放普通图片:")
} }
@ -166,7 +172,11 @@ export class ImageKnifeData {
for (let i = 0; i < gifFrames.length; i++) { for (let i = 0; i < gifFrames.length; i++) {
let tempFrame = gifFrames[i]; let tempFrame = gifFrames[i];
if (tempFrame.drawPixelMap != undefined) { if (tempFrame.drawPixelMap != undefined) {
tempFrame.drawPixelMap.release() promise.then(() => {
if (tempFrame.drawPixelMap != undefined) {
tempFrame.drawPixelMap.release()
}
})
} }
} }
LogUtil.info("MemoryLruCache removeMemorySize---- end 释放GIF图片") LogUtil.info("MemoryLruCache removeMemorySize---- end 释放GIF图片")

View File

@ -70,15 +70,14 @@ export class HttpDownloadClient implements IDataFetch {
connectTimeout: 60000, // 可选 默认60000ms connectTimeout: 60000, // 可选 默认60000ms
readTimeout: 0, // 可选, 默认为60000ms readTimeout: 0, // 可选, 默认为60000ms
usingProtocol: http.HttpProtocol.HTTP1_1, // 可选,协议类型默认值由系统自动指定 usingProtocol: http.HttpProtocol.HTTP1_1, // 可选,协议类型默认值由系统自动指定
},
(err: BusinessError, data: number) => {
if (!err && data == 200) {
} else {
onError(`HttpDownloadClient has error, http code = ${data}`)
}
} }
) ).then((data)=>{
if(data == 200) {
} else {
onError(`HttpDownloadClient has error, http code = ${data}`)
}
})
} catch (err) { } catch (err) {
onError('HttpDownloadClient catch err request uuid ='+request.uuid) onError('HttpDownloadClient catch err request uuid ='+request.uuid)
} }

View File

@ -41,8 +41,8 @@ export class DiskCacheProxy implements ICache<string, ArrayBuffer> {
return this.mDiskLruCache.get(key); return this.mDiskLruCache.get(key);
} }
async putValue(key: string, value: ArrayBuffer) { putValue(key: string, value: ArrayBuffer) {
await this.mDiskLruCache.setAsync(key, value) this.mDiskLruCache.set(key, value)
} }
removeValue(key: string): ArrayBuffer{ removeValue(key: string): ArrayBuffer{

View File

@ -466,8 +466,8 @@ export class RequestManager {
// 保存二级磁盘缓存 // 保存二级磁盘缓存
Promise.resolve(source) Promise.resolve(source)
.then(async (arraybuffer: ArrayBuffer)=>{ .then((arraybuffer: ArrayBuffer)=>{
await this.mDiskCacheProxy.putValue(this.options.generateDataKey, arraybuffer) this.mDiskCacheProxy.putValue(this.options.generateDataKey, arraybuffer)
}) })
.catch( (err:BusinessError)=>{ .catch( (err:BusinessError)=>{
LogUtil.log('download file is ='+ImageKnifeData.GIF+'and save diskLruCache error ='+ (err as BusinessError)) LogUtil.log('download file is ='+ImageKnifeData.GIF+'and save diskLruCache error ='+ (err as BusinessError))
@ -480,8 +480,8 @@ export class RequestManager {
// 保存二级磁盘缓存 // 保存二级磁盘缓存
Promise.resolve(source) Promise.resolve(source)
.then(async (arraybuffer: ArrayBuffer)=>{ .then((arraybuffer: ArrayBuffer)=>{
await this.mDiskCacheProxy.putValue(this.options.generateDataKey, arraybuffer) this.mDiskCacheProxy.putValue(this.options.generateDataKey, arraybuffer)
}) })
.catch((err:BusinessError)=>{ .catch((err:BusinessError)=>{
LogUtil.log('download file is ='+ImageKnifeData.SVG+'and save diskLruCache error ='+ (err as BusinessError)) LogUtil.log('download file is ='+ImageKnifeData.SVG+'and save diskLruCache error ='+ (err as BusinessError))
@ -548,8 +548,8 @@ export class RequestManager {
private saveCacheAndDisk(value: PixelMap, filetype:string, onComplete:(value:ImageKnifeData)=>void|PromiseLike<ImageKnifeData>, source:ArrayBuffer) { private saveCacheAndDisk(value: PixelMap, filetype:string, onComplete:(value:ImageKnifeData)=>void|PromiseLike<ImageKnifeData>, source:ArrayBuffer) {
let imageKnifeData = this.createImagePixelMap(ImageKnifeType.PIXELMAP, value); let imageKnifeData = this.createImagePixelMap(ImageKnifeType.PIXELMAP, value);
this.mMemoryCacheProxy.putValue(this.options.generateCacheKey, imageKnifeData); this.mMemoryCacheProxy.putValue(this.options.generateCacheKey, imageKnifeData);
let save2DiskCache = async (arraybuffer:ArrayBuffer) => { let save2DiskCache = (arraybuffer:ArrayBuffer) => {
await this.mDiskCacheProxy.putValue(this.options.generateDataKey, arraybuffer) this.mDiskCacheProxy.putValue(this.options.generateDataKey, arraybuffer)
// 落盘之后需要主动移除当前request并且调用下一个加载 // 落盘之后需要主动移除当前request并且调用下一个加载
let removeCurrentAndSearchNextRun = this.options.removeCurrentAndSearchNext let removeCurrentAndSearchNextRun = this.options.removeCurrentAndSearchNext
removeCurrentAndSearchNextRun(); removeCurrentAndSearchNextRun();

Some files were not shown because too many files have changed in this diff Show More