From 660490aec623818cbee2f3ad152df9b5b42728ec Mon Sep 17 00:00:00 2001 From: madixin Date: Wed, 10 Apr 2024 10:11:41 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B93.x=E7=89=88=E6=9C=ACdemo?= =?UTF-8?q?=E9=A6=96=E9=A1=B5+readme=E8=A1=A5=E5=85=853.x=E5=B7=AE?= =?UTF-8?q?=E5=BC=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: madixin --- CHANGELOG.md | 40 +++++- README.md | 33 +++-- entry/src/main/ets/pages/Index.ets | 54 ++++---- ...hotoShowPage.ets => ManyPhotoShowPage.ets} | 0 entry/src/main/ets/pages/User.ets | 83 ++++++++++++ entry/src/main/ets/pages/UserPage.ets | 119 ++++++++++++++++++ .../resources/base/profile/main_pages.json | 3 +- 7 files changed, 293 insertions(+), 39 deletions(-) rename entry/src/main/ets/pages/{manyPhotoShowPage.ets => ManyPhotoShowPage.ets} (100%) create mode 100644 entry/src/main/ets/pages/User.ets create mode 100644 entry/src/main/ets/pages/UserPage.ets diff --git a/CHANGELOG.md b/CHANGELOG.md index c6274d3..2243169 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,17 +1,47 @@ ## 3.0.0-rc.0 使用Image组件替换Canvas组件渲染,并重构大部分的实现逻辑,提升渲染性能 缺失特性 -- gif/webp动图显示与控制 -- 支持自定义key的实现 +- 不支持drawLifeCycle接口,通过canvas自会图片 +- mainScaleType,border等参数,新版本与系统Image保持一致 +- gif/webp动图播放与控制 +- signature自定义key的实现 - 支持进行图片变换: 支持图像像素源图片变换效果。 -- 使用IDrawLifeCycle自绘Canvas +- 抗锯齿相关参数 较2.x版本增强点: -- 使用Image组件渲染,提升渲染性能 +- 使用Image组件代替Canvas组件渲染 +- 重构Dispatch分发逻辑,支持控制并发请求数,支持请求排队队列的优先级 - 支持通过initMemoryCache自定义策略内存缓存策略和大小。 - 支持option自定义实现图片获取/网络下载 - 继承Image的能力,支持option传入border,设置边框,圆角 - 继承Image的能力,支持option传入objectFit设置图片缩放 -- 并发请求数量,支持请求排队队列的优先级 + +## 2.1.2-rc.12 +- 新增gif播放次数功能 +- 新增磁盘预加载返回文件路径接口prefetchToDiskCache +- 新增跳过网络判断缓存或者磁盘中是否存在图片接口isUrlExist +- 删除多余操作磁盘记录读写 +- 清除定时器改为Gif图时清除 +- uuid改为util.generateRandomUUID() + +## 2.1.2-rc.11 +- 修复设置磁盘容量最大值出现闪退 +- 修复概率出现jscrash问题 +- 修复进度条问题 +- 修复单帧gif图片加载失败 +- removeRunning删除running队列log设置开关 +- ImageKnife新增图片宽高自适应功能 +- 修复onlyRetrieveFromCache属性(仅磁盘和内存获取资源)失效 +- 修改拼写错误 +- 新增多线程优先级 +- 修复复用场景下图片闪动以及概率错位 +- 获取组件宽高改为使用CanvasRenderingContext2D对象获取宽高,并修复改变字体大小导致部分图片消失 +- 修复获取不到磁盘缓存文件问题 +- 修复获取不到网络请求错误回调问题 + +## 2.1.2-rc.10 +- 修复部分gif图片识别成静态图 +- 修复同一张图片发送多次请求 +- 复用场景缓存到树aboutToRecycle清理定时器 ## 2.1.2-rc.9 - 使用taskpool实现多线程加载图片资源 diff --git a/README.md b/README.md index 4219c6e..df55c6e 100644 --- a/README.md +++ b/README.md @@ -12,22 +12,31 @@ - 支持option自定义实现图片获取/网络下载 - 支持监听网络下载回调进度 - 继承Image的能力,支持option传入border,设置边框,圆角 -- 继承Image的能力,支持option传入objectFit设置图片缩放 +- 继承Image的能力,支持option传入objectFit设置图片缩放,包括objectFit为auto时根据图片自适应高度 - 支持通过设置transform缩放图片 - 并发请求数量,支持请求排队队列的优先级 +- 支持生命周期已销毁的图片,不再发起请求 待实现特性 - gif/webp动图显示与控制 - 内存降采样优化,节约内存的占用 -- 支持自定义图片加载和请求并发数量 -- 支持声明周期已销毁的图片,不再发起请求 +- 支持自定义图片加载 - 支持自定义图片解码 - 支持自定义key的实现 - 支持进行图片变换: 支持图像像素源图片变换效果。 -待确认arkui的能力 -- 精确获取开发者给组件设置的宽和高 -- 动图的显示与控制 +注意:3.x版本相对2.x版本做了重大的重构,主要体现在: +- 使用Image组件代替Canvas组件渲染 +- 重构Dispatch分发逻辑,支持控制并发请求数,支持请求排队队列的优先级 +- 支持通过initMemoryCache自定义策略内存缓存策略和大小。 +- 支持option自定义实现图片获取/网络下载 +因此API及能力上,目前有部分差异,主要体现在: +- 不支持drawLifeCycle接口,通过canvas自会图片 +- mainScaleType,border等参数,新版本与系统Image保持一致 +- gif/webp动图播放与控制 +- signature自定义key的实现 +- 支持进行图片变换: 支持图像像素源图片变换效果。 +- 抗锯齿相关参数 ## 下载安装 ``` @@ -39,7 +48,7 @@ ohpm install @ohos/imageknife ``` ImageKnifeComponent({ ImageKnifeOption: { - src: $r("app.media.app_icon"), + loadSrc: $r("app.media.app_icon"), placeholderSrc: $r("app.media.loading"), errorholderSrc: $r("app.media.app_icon"), objectFit: ImageFit.Auto @@ -51,7 +60,7 @@ ImageKnifeComponent({ ``` ImageKnifeComponent({ ImageKnifeOption: { - src: this.localFile, + loadSrc: this.localFile, placeholderSrc: $r("app.media.loading"), errorholderSrc: $r("app.media.app_icon"), objectFit: ImageFit.Auto @@ -63,7 +72,7 @@ ImageKnifeComponent({ ``` ImageKnifeComponent({ ImageKnifeOption: { - src:"https://www.openharmony.cn/_nuxt/img/logo.dcf95b3.png", + loadSrc:"https://www.openharmony.cn/_nuxt/img/logo.dcf95b3.png", placeholderSrc: $r("app.media.loading"), errorholderSrc: $r("app.media.app_icon"), objectFit: ImageFit.Auto @@ -75,7 +84,7 @@ ImageKnifeComponent({ ``` ImageKnifeComponent({ ImageKnifeOption: { - src: "https://file.atomgit.com/uploads/user/1704857786989_8994.jpeg", + loadSrc: "https://file.atomgit.com/uploads/user/1704857786989_8994.jpeg", placeholderSrc: $r("app.media.loading"), errorholderSrc: $r("app.media.app_icon"), objectFit: ImageFit.Auto, @@ -96,7 +105,7 @@ async function custom(context: Context, src: string | PixelMap | Resource): Prom ``` ImageKnifeComponent({ ImageKnifeOption: { - src:"https://www.openharmony.cn/_nuxt/img/logo.dcf95b3.png", + loadSrc:"https://www.openharmony.cn/_nuxt/img/logo.dcf95b3.png", progressListener:(progress:number)=>{console.info("ImageKinfe:: call back progress = " + progress)} } }).width(100).height(100) @@ -105,7 +114,7 @@ ImageKnifeComponent({ ``` ImageKnifeComponent({ ImageKnifeOption: { - src: $r("app.media.rabbit"), + loadSrc: $r("app.media.rabbit"), border: {radius:50} } }).width(100).height(100) diff --git a/entry/src/main/ets/pages/Index.ets b/entry/src/main/ets/pages/Index.ets index c6d5bf6..af510e8 100644 --- a/entry/src/main/ets/pages/Index.ets +++ b/entry/src/main/ets/pages/Index.ets @@ -12,39 +12,51 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { ImageKnifeComponent, ImageKnifeOption } from "@ohos/imageknife" - +import router from '@system.router'; @Entry @Component struct Index { - localFile: string = getContext(this).filesDir + "/icon.png" - @State ImageKnifeOption: ImageKnifeOption = { - loadSrc: $r("app.media.rabbit"), - // src:"https://www.openharmony.cn/_nuxt/img/logo.dcf95b3.png", - // src: this.localFile, - placeholderSrc: $r("app.media.loading"), - errorholderSrc: $r("app.media.app_icon"), - objectFit: ImageFit.Contain, - border: { radius: 50 } - } + aboutToAppear(): void { - // 拷贝本地文件 - // let icon: Uint8Array = getContext(this).resourceManager.getMediaContentSync($r("app.media.startIcon")); - // let file = fs.openSync(this.localFile, fs.OpenMode.CREATE | fs.OpenMode.READ_WRITE); - // fs.writeSync(file.fd, icon.buffer); - // fs.fsyncSync(file.fd); - // fs.closeSync(file); + } build() { Column() { - ImageKnifeComponent({ ImageKnifeOption: this.ImageKnifeOption }).height(200).width(200) + Button("单个图片使用").onClick(()=>{ + router.push({ + uri: 'pages/SingleImage', + + }); + }) + Button("多图 + Foreach").margin({top:10}).onClick(()=>{ + router.push({ + uri: 'pages/ManyPhotoShowPage', + + }); + }) + Button("多图 + reuse + LazyForeach").margin({top:10}).onClick(()=>{ + router.push({ + uri: 'pages/UserPage', + + }); + }) + Button("长图").margin({top:10}).onClick(()=>{ + router.push({ + uri: 'pages/LongImagePage', + + }); + }) + Button("缩放").margin({top:10}).onClick(()=>{ + router.push({ + uri: 'pages/TransformPage', + + }); + }) - // Image($r('app.media.rabbit')).objectFit(ImageFit.Contain).height(200).width(200) - // .border({radius:50}) } .width('100%') diff --git a/entry/src/main/ets/pages/manyPhotoShowPage.ets b/entry/src/main/ets/pages/ManyPhotoShowPage.ets similarity index 100% rename from entry/src/main/ets/pages/manyPhotoShowPage.ets rename to entry/src/main/ets/pages/ManyPhotoShowPage.ets diff --git a/entry/src/main/ets/pages/User.ets b/entry/src/main/ets/pages/User.ets new file mode 100644 index 0000000..e58319b --- /dev/null +++ b/entry/src/main/ets/pages/User.ets @@ -0,0 +1,83 @@ +import { ImageKnifeComponent, ImageKnifeOption } from '@ohos/imageknife' + +// const logger = new imUtils.logger.IMLogger('Avatar') + +class MyImageOption extends ImageKnifeOption { + account?: string +} + +@Component +export struct UserAvatar { + @Prop @Watch('userInfoUpdate') userInfo: string = "" + // @Prop userInfo: string = "" + imgSize: number = 100 + radius: number = 12 + borderSize: number = 0 + imgSizes: number = 1 + @State ImageKnifeOption: ImageKnifeOption = new ImageKnifeOption() + @StorageProp('WeLink_Mob_fontSize_multiple') @Watch('updateImgSize') WeLink_Mob_fontSize_multiple: number = 0 + scaleable: boolean = true; + @State calcImgSize: number = 100 + + aboutToAppear(): void { + this.userInfoUpdate() + this.setImageSize() + } + + setImageSize() { + if (!this.scaleable) { + this.calcImgSize = this.imgSize + } else if (this.WeLink_Mob_fontSize_multiple < 0.9) { + this.calcImgSize = this.imgSize * 0.9 + } else if (this.WeLink_Mob_fontSize_multiple > 1.6) { + this.calcImgSize = this.imgSize * 1.6 + } else { + this.calcImgSize = this.imgSize * this.WeLink_Mob_fontSize_multiple + } + } + + updateImgSize() { + this.setImageSize() + } + + aboutToReuse(param: ESObject) { + this.userInfoUpdate() + } + + userInfoUpdate() { + // if (uri === 'userInfo' && this.imageKnifeOption.account !== this.userInfo.contactId) return; + // // logger.info(`userInfoUpdate uri=${uri} oldAcc=${this.imageKnifeOption.loadSrc} nowAcc=${this.userInfo.externalHeadUrl}`) + // if (this.userInfo.externalHeadUrl === this.imageKnifeOption.loadSrc && this.userInfo.infoUpdateTime.getTime() + // .toString() === this.imageKnifeOption?.signature?.getKey()) return; + this.ImageKnifeOption = { + //TODO:写死loadSRC,场景:变更组件大小,所有图片不显示 + loadSrc: this.userInfo, + placeholderSrc: $r('app.media.icon'), + border: { radius:20,width:5,color:$r('app.color.start_window_background') }, + objectFit:ImageFit.Contain + // signature: new ObjectKey(this.userInfo.infoUpdateTime.getTime().toString()) + } + } + + build() { + Row() { + // Image(this.imageKnifeOption.loadSrc) + + ImageKnifeComponent({ ImageKnifeOption: this.ImageKnifeOption }) + .borderRadius(this.radius) + .clip(true) + .width(this.calcImgSize) + .height(this.calcImgSize) + .backgroundColor(Color.Pink) + + + + // Image(this.userInfo) + // Text((this.imageKnifeOption.loadSrc as string).split('/')[8]) + // .position({ x: 0, y: 0 }) + // .zIndex(9) + // .fontSize(12) + // .fontColor('#ff0000') + } + } +} \ No newline at end of file diff --git a/entry/src/main/ets/pages/UserPage.ets b/entry/src/main/ets/pages/UserPage.ets new file mode 100644 index 0000000..b2bedeb --- /dev/null +++ b/entry/src/main/ets/pages/UserPage.ets @@ -0,0 +1,119 @@ +import { UserAvatar } from './User' + +class CommonDataSource implements IDataSource { + private dataArray: T[] = [] + private listeners: DataChangeListener[] = [] + + constructor(element: []) { + this.dataArray = element + } + + public getData(index: number) { + return this.dataArray[index] + } + + public totalCount(): number { + return this.dataArray.length + } + + public addData(index: number, data: T[]): void { + this.dataArray = this.dataArray.concat(data) + this.notifyDataAdd(index) + } + + unregisterDataChangeListener(listener: DataChangeListener): void { + const pos = this.listeners.indexOf(listener); + if (pos >= 0) { + this.listeners.splice(pos, 1); + } + } + + registerDataChangeListener(listener: DataChangeListener): void { + if (this.listeners.indexOf(listener) < 0) { + this.listeners.push(listener) + } + } + + notifyDataAdd(index: number): void { + this.listeners.forEach((listener: DataChangeListener) => { + listener.onDataAdd(index) + }) + } +} +@Entry +@Component +struct Index { + @State hotCommendList:CommonDataSource = new CommonDataSource([]) + private data:string[] = [ + "http://e.hiphotos.baidu.com/image/pic/item/a1ec08fa513d2697e542494057fbb2fb4316d81e.jpg", + "http://c.hiphotos.baidu.com/image/pic/item/30adcbef76094b36de8a2fe5a1cc7cd98d109d99.jpg", + "http://h.hiphotos.baidu.com/image/pic/item/7c1ed21b0ef41bd5f2c2a9e953da81cb39db3d1d.jpg", + "http://g.hiphotos.baidu.com/image/pic/item/55e736d12f2eb938d5277fd5d0628535e5dd6f4a.jpg", + "http://e.hiphotos.baidu.com/image/pic/item/4e4a20a4462309f7e41f5cfe760e0cf3d6cad6ee.jpg", + "http://b.hiphotos.baidu.com/image/pic/item/9d82d158ccbf6c81b94575cfb93eb13533fa40a2.jpg", + "http://e.hiphotos.baidu.com/image/pic/item/4bed2e738bd4b31c1badd5a685d6277f9e2ff81e.jpg", + "http://g.hiphotos.baidu.com/image/pic/item/0d338744ebf81a4c87a3add4d52a6059252da61e.jpg", + "http://a.hiphotos.baidu.com/image/pic/item/f2deb48f8c5494ee5080c8142ff5e0fe99257e19.jpg", + "http://f.hiphotos.baidu.com/image/pic/item/4034970a304e251f503521f5a586c9177e3e53f9.jpg", + "http://b.hiphotos.baidu.com/image/pic/item/279759ee3d6d55fbb3586c0168224f4a20a4dd7e.jpg", + "http://img2.xkhouse.com/bbs/hfhouse/data/attachment/forum/corebbs/2009-11/2009113011534566298.jpg", + "http://a.hiphotos.baidu.com/image/pic/item/e824b899a9014c087eb617650e7b02087af4f464.jpg", + "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", + "https://hbimg.huabanimg.com/cc6af25f8d782d3cf3122bef4e61571378271145735e9-vEVggB", + 'https://img-blog.csdnimg.cn/20191215043500229.png', + 'https://img-blog.csdn.net/20140514114029140', + 'https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp', + ] + aboutToAppear(): void { + this.hotCommendList.addData(this.hotCommendList.totalCount(),this.data) + AppStorage.set("WeLink_Mob_fontSize_multiple",1) + } + + build() { + Column() { + Button("bigger").onClick(()=>{ + AppStorage.set("WeLink_Mob_fontSize_multiple",1.6) + }) + Button("small").onClick(()=>{ + AppStorage.set("WeLink_Mob_fontSize_multiple",0.8) + }) + List(){ + LazyForEach(this.hotCommendList,(item:string)=>{ + ListItem(){ + ReuseImage({ + userInfo:item + }).width("100%").height("100%").backgroundColor(Color.Yellow) + }.width(200).height(200).margin({bottom:5}) + }) + } + // .cachedCount(20) + .width("100%") + .height("100%") + .backgroundColor(0xFAEEE0) + }.width('100%').height("100%") + } +} + + +@Reusable +@Component +struct ReuseImage { + @State userInfo:string = "" + aboutToReuse(params: ESObject): void { + this.userInfo = params.userInfo + } + + build() { + Column(){ + UserAvatar({ + userInfo:this.userInfo + }) + }.width("100%").height("100%") + } +} \ No newline at end of file diff --git a/entry/src/main/resources/base/profile/main_pages.json b/entry/src/main/resources/base/profile/main_pages.json index e87dd6a..a927122 100644 --- a/entry/src/main/resources/base/profile/main_pages.json +++ b/entry/src/main/resources/base/profile/main_pages.json @@ -5,6 +5,7 @@ "pages/SingleImage", "pages/ManyPhotoShowPage", "pages/LongImagePage", - "pages/TransformPage" + "pages/TransformPage", + "pages/UserPage" ] } \ No newline at end of file