Compare commits

...

307 Commits

Author SHA1 Message Date
landwind bc55de9e2e Modify the README file
Signed-off-by: landwind <mamingshuai1@huawei.com>
2025-04-28 10:56:30 +08:00
openharmony_ci c1426cd35a
!463 项目配置文件新增设备类型,样例设置混淆
Merge pull request !463 from zgf/master
2025-02-20 03:00:15 +00:00
zgf adb78853af 项目配置文件新增设备类型,样例设置混淆
Signed-off-by: zgf <zenggaofeng2@h-partners.com>
2025-02-19 17:39:29 +08:00
openharmony_ci 9e387602f6
!461 支持图片携带的EXIF元数据作为显示方向
Merge pull request !461 from yang/master
2025-02-19 09:24:27 +00:00
yang 115118e238 支持图片携带的EXIF元数据作为显示方向
Signed-off-by: yang <yangweiping7@h-partners.com>
2025-02-19 14:46:37 +08:00
openharmony_ci acb45a66bc
!460 修改版本号3.2.2-rc.0
Merge pull request !460 from zgf/master
2025-02-18 07:51:13 +00:00
zgf 25b7899746 修改版本号3.2.2-rc.0
Signed-off-by: zgf <zenggaofeng2@h-partners.com>
2025-02-18 15:03:11 +08:00
openharmony_ci e41fce46bf
!459 增加ImageKnifeComponent组件销毁网络请求中断
Merge pull request !459 from zgf/master
2025-02-18 03:56:03 +00:00
zgf 8601f87865 增加ImageKnifeComponent组件销毁网络请求中断
Signed-off-by: zgf <zenggaofeng2@h-partners.com>
2025-02-13 16:15:49 +08:00
openharmony_ci 933cc284ec
!458 优化ImageKnifeLoader类的getImageArrayBuffer方法
Merge pull request !458 from 刘海康/master
2025-02-07 09:12:11 +00:00
openharmony_ci fbf4cc88bd
!456 增加图片下载失败各种错误信息样例
Merge pull request !456 from zgf/master
2025-02-07 02:48:13 +00:00
liuhaikang a21a8f025f 优化ImageKnifeLoader类的getImageArrayBuffer方法
Signed-off-by: liuhaikang <liuhaikang1@h-partners.com>
2025-02-06 20:09:06 +08:00
zgf 996fc5c909
增加图片下载失败各种错误信息样例
增加图片下载失败各种错误信息样例

Signed-off-by: zgf <zenggaofeng2@h-partners.com>
2025-02-06 08:16:36 +00:00
zgf 677ea73337 增加图片下载失败各种错误信息样例
Signed-off-by: zgf <zenggaofeng2@h-partners.com>
2025-02-06 15:56:37 +08:00
openharmony_ci 5c22496b96
!455 发布正式版本3.2.1
Merge pull request !455 from 刘海康/master
2025-01-23 03:38:42 +00:00
liuhaikang 425aa3a5bc 发布正式版本3.2.1
Signed-off-by: liuhaikang <liuhaikang1@h-partners.com>
2025-01-23 11:04:36 +08:00
openharmony_ci 226d9939be
!454 判断loadSrc传入pixelmap类型处增加保护
Merge pull request !454 from zgf/master
2025-01-21 08:04:35 +00:00
zgf 2c7473f422 判断loadSrc传入pixelmap类型处增加保护
Signed-off-by: zgf <zenggaofeng2@h-partners.com>
2025-01-21 15:25:12 +08:00
openharmony_ci 17e3787cfa
!453 优化文件缓存初始化效率
Merge pull request !453 from 刘海康/master
2025-01-21 02:29:39 +00:00
liuhaikang 915eded1ab 优化文件缓存初始化效率
Signed-off-by: liuhaikang <liuhaikang1@h-partners.com>
2025-01-20 15:34:07 +08:00
openharmony_ci a1e8e0b15f
!452 修复自定义矩形裁剪异常、清除文件缓存接口导致文件缓存失效
Merge pull request !452 from zgf/master
2025-01-13 07:40:45 +00:00
zgf 1615da7b7c 修复自定义矩形裁剪异常、清除文件缓存接口导致文件缓存失效
Signed-off-by: zgf <zenggaofeng2@h-partners.com>
2025-01-13 14:49:46 +08:00
madixin 3378d36046 优化ImageFit.Auto的demo,使用滚动条调整宽度,体现高度的自适应
Signed-off-by: madixin <42690727@qq.com>
2025-01-12 11:57:05 +08:00
openharmony_ci f709bd3f01
!450 修改版本号和OAT配置
Merge pull request !450 from zgf/master
2025-01-03 06:02:22 +00:00
zgf a844860bae 修改版本号和OAT配置
Signed-off-by: zgf <zenggaofeng2@h-partners.com>
2025-01-03 12:07:39 +08:00
zgf 60ec83850a 删除重复debug日志(showpixelmap)
Signed-off-by: zgf <zenggaofeng2@h-partners.com>
2025-01-02 07:36:20 +00:00
openharmony_ci 9939c748a8
!448 修改样例resource泄露、heic格式补充、降采样优化、增加解码和文件读取debug日志
Merge pull request !448 from zgf/master
2025-01-02 02:23:11 +00:00
zgf 1efe55db1e 修改样例resource泄露、heic格式补充、降采样优化、增加解码和文件读取debug日志
Signed-off-by: zgf <zenggaofeng2@h-partners.com>
2025-01-02 10:15:25 +08:00
openharmony_ci 990a9a363f
!446 修正decodeEndTime记录错误
Merge pull request !446 from Madi/master
2024-12-24 03:05:09 +00:00
madixin 618320843f 1.修正decodeEndTime记录错误
2.内存缓存记录图片buffersize
3.测试加载回调demo里展示图片来源于网络,文件缓存,还是内存缓存。 去除renderTime的记录
4.调整动图的测试页面,不涉及逻辑修改

Signed-off-by: madixin <madixin@huawei.com>
2024-12-24 10:40:17 +08:00
openharmony_ci db56763a50
!445 扩大内存和文件缓存的限制和默认值
Merge pull request !445 from Madi/master
2024-12-23 02:48:35 +00:00
madixin 2f2e562aed 扩大内存和文件缓存的限制和默认值
Signed-off-by: madixin <madixin@huawei.com>
2024-12-21 18:25:32 +08:00
zgf fc6668cb0d 高度自适应方案修改、成功回调返回httpCode以及修复错误码httpCode无数据
Signed-off-by: zgf <zenggaofeng2@h-partners.com>
2024-12-19 17:04:22 +08:00
openharmony_ci ba48f233a7
!443 增加页面展示和测试local本地图片的显示
Merge pull request !443 from Madi/master
2024-12-16 03:58:54 +00:00
madixin 549d9edf48 1.增加页面展示和测试local本地图片的显示,目前发现rawfile下的文件无法显示
2.httpRequestOption --》 HttpRequestOption

Signed-off-by: madixin <madixin@huawei.com>
2024-12-14 17:22:05 +08:00
openharmony_ci db78e56e9a
!442 增加日志开关和网络请求超时参数
Merge pull request !442 from zgf/master
2024-12-09 02:56:01 +00:00
zgf 68672e1dc7 增加日志开关和网络请求超时参数
Signed-off-by: zgf <zenggaofeng2@h-partners.com>
2024-12-09 10:43:33 +08:00
zgf 6719e8ab19 修改网络请求readTimeout和日志修改
Signed-off-by: zgf <zenggaofeng2@h-partners.com>
2024-12-05 19:35:18 +08:00
zgf 7b025a7415 错误日志和回调增加信息
Signed-off-by: zgf <zenggaofeng2@h-partners.com>
2024-12-04 06:44:32 +00:00
openharmony_ci 912c23f34b
!439 调整closeSync方法,紧接着writeSync,readSync,防止打开的文件没有正确关闭
Merge pull request !439 from Madi/master
2024-12-03 10:43:13 +00:00
madixin 5f548d1090 调整closeSync方法,紧接着writeSync,readSync,防止打开的文件没有正确关闭
Signed-off-by: madixin <madixin@huawei.com>
2024-12-03 17:21:18 +08:00
madixin 303ff79be1 更新issue bug的模版版本和PR模版
Signed-off-by: madixin <madixin@huawei.com>
2024-12-01 19:58:19 +08:00
openharmony_ci 51e4675957
!437 增加仓库默认issue模板,填写正确imageknife版本
Merge pull request !437 from Madi/master
2024-11-30 13:02:57 +00:00
madixin 47edcfed3e 提交imageknife issue模版,选定版本
Signed-off-by: madixin <madixin@huawei.com>
2024-11-30 20:37:36 +08:00
zgf e475dcd30a 修改ImageKnifeComponent组件pixel Map初始值以及修复多张错误图不显示
Signed-off-by: zgf <zenggaofeng2@h-partners.com>
2024-11-29 18:26:46 +08:00
openharmony_ci e98984c56a
!435 主图和错误图并发加载时,以及主图加载失败后立即加载错误图,可能会导致短时间内并发数超过maxRequests,及时减少并发
Merge pull request !435 from Madi/master
2024-11-27 11:32:27 +00:00
madixin fba280904e 主图和错误图并发加载时,以及主图加载失败后立即加载错误图,可能会导致短时间内并发数超过maxRequests,故在dispatchNextJob减少响应的并发
Signed-off-by: madixin <madixin@huawei.com>
2024-11-27 15:39:04 +08:00
Madixin 8aebc58a53 更新默认OpenHarmony工程
Signed-off-by: Madixin <madixin@huawei.com>
2024-11-27 06:00:00 +00:00
openharmony_ci 9ff70d9c78
!433 ImageFit.Auto 组件宽度更改后自动支持自适应高度
Merge pull request !433 from Madi/master
2024-11-27 01:13:11 +00:00
madixin e29c659e89 1. ImageFit.Auto 组件宽度更改后自动支持自适应高度,并补充样例。
2.修复onLoadStart会调用2次的bug

Signed-off-by: madixin <madixin@huawei.com>
2024-11-25 17:45:55 +08:00
openharmony_ci 83b42f36b0
!432 完善日志,补充组件id信息
Merge pull request !432 from Madi/master
2024-11-25 02:40:14 +00:00
madixin 74bc24d61d 完善日志,补充组件id信息
Signed-off-by: madixin <madixin@huawei.com>
2024-11-25 09:54:50 +08:00
zgf dac7731794 支持ico格式图片、修复错误回调无法执行reload和新增降采样默认值
Signed-off-by: zgf <zenggaofeng2@h-partners.com>
2024-11-22 16:51:22 +08:00
zgf 1ae2ce8d92 ImageKnifeAnimatorComponent补充圆角功能
Signed-off-by: zgf <zenggaofeng2@h-partners.com>
2024-11-15 15:37:10 +08:00
openharmony_ci 65c39faf8a
!429 taskpool执行异常时,回调onLoadFailed
Merge pull request !429 from Madi/master
2024-11-15 06:03:32 +00:00
madixin 328257bb96 1.taskpool执行异常时,回调onLoadFailed
2.调整imageKnifeData为public作用域,以及命名

Signed-off-by: madixin <madixin@huawei.com>
2024-11-15 12:17:52 +08:00
openharmony_ci a45fb6af7d
!428 完善错误日志的打印
Merge pull request !428 from Madi/master
2024-11-15 03:03:58 +00:00
madixin 5296bf7a1d 1.完善错误日志
2.修复部分imagesource没有release的问题

Signed-off-by: madixin <madixin@huawei.com>
2024-11-15 10:05:23 +08:00
openharmony_ci 30c327747b
!427 修复无法解析其他module的Resource格式图片
Merge pull request !427 from zgf/master
2024-11-12 09:44:47 +00:00
zgf 73bc96e524 修复无法解析其他module的Resource格式图片
Signed-off-by: zgf <zenggaofeng2@h-partners.com>
2024-11-12 17:05:05 +08:00
openharmony_ci 32da743bcc
!426 判断和处理imageSource.getImageInfo为空的场景,返回错误信息
Merge pull request !426 from Madi/master
2024-11-12 01:45:34 +00:00
madixin 630b0df448 判断和处理imageSource.getImageInfo为空的场景,返回错误信息
Signed-off-by: madixin <madixin@huawei.com>
2024-11-10 08:06:57 +08:00
zgf f552f57713 修改CHANGELOG版本号
Signed-off-by: zgf <zenggaofeng2@h-partners.com>
2024-11-08 15:12:39 +08:00
openharmony_ci 3dd622e4e2
!424 3.x分支代码合并master分支
Merge pull request !424 from zgf/master
2024-11-08 06:10:07 +00:00
zgf 3423f4cd5d 3.x分支代码合并到master分支
Signed-off-by: zgf <zenggaofeng2@h-partners.com>
2024-11-08 11:02:58 +08:00
zgf 0e0f1a96c2 Merge remote-tracking branch 'origin/3.x'
# Conflicts:
#	CHANGELOG.md
#	README.md
#	README_zh.md
#	entry/src/main/ets/common/CustomEngineKeyImpl.ets
#	entry/src/main/ets/pages/DownSamplePage.ets
#	entry/src/main/ets/pages/ImageAnimatorPage.ets
#	entry/src/main/ets/pages/Index.ets
#	entry/src/main/ets/pages/LoadStatePage.ets
#	entry/src/main/ets/pages/ObjectFitPage.ets
#	entry/src/main/ets/pages/SingleImage.ets
#	entry/src/main/ets/pages/TestCacheDataPage.ets
#	entry/src/main/ets/pages/TestChangeColorPage.ets
#	entry/src/main/ets/pages/TestLoadCancelListenerPage.ets
#	entry/src/main/ets/pages/TestSetCustomImagePage.ets
#	entry/src/main/ets/pages/TestTaskResourcePage.ets
#	entry/src/main/ets/pages/TestWriteCacheStage.ets
#	entry/src/main/ets/pages/UserPage.ets
#	entry/src/main/resources/base/element/string.json
#	entry/src/main/resources/base/profile/main_pages.json
#	entry/src/main/resources/zh_CN/element/string.json
#	entry/src/ohosTest/ets/test/List.test.ets
#	entry/src/ohosTest/ets/test/SamplingTest.test.ets
#	entry/src/ohosTest/ets/test/imageFormatAndSize.test.ets
#	library/oh-package.json5
#	library/src/main/ets/ImageKnife.ets
#	library/src/main/ets/ImageKnifeDispatcher.ets
#	library/src/main/ets/ImageKnifeLoader.ets
#	library/src/main/ets/components/ImageKnifeAnimatorComponent.ets
#	library/src/main/ets/components/ImageKnifeComponent.ets
#	library/src/main/ets/downsampling/BaseDownsampling.ets
#	library/src/main/ets/downsampling/DownsampleStartegy.ets
#	library/src/main/ets/downsampling/Downsampler.ets
#	library/src/main/ets/key/DefaultEngineKey.ets
#	library/src/main/ets/model/ImageKnifeData.ets
#	library/src/main/ets/model/ImageKnifeOption.ets
#	library/src/main/ets/model/ImageKnifeRequest.ets
#	sharedlibrary/src/main/ets/pages/Index.ets
2024-11-06 18:40:38 +08:00
madixin 8adc342444 补充:解决单个图片解码后内存占用超过内存缓存最大值,导致无法显示图片的问题
Signed-off-by: madixin <madixin@huawei.com>
2024-11-06 16:52:09 +08:00
madixin 95ffcb9e74 解决单个图片解码后内存占用超过内存缓存最大值,导致无法显示图片的问题
Signed-off-by: madixin <madixin@huawei.com>
2024-11-06 15:50:15 +08:00
zgf b0661e83ac 3.x分支新增降采样功能
Signed-off-by: zgf <zenggaofeng2@h-partners.com>
2024-11-04 16:18:47 +08:00
zgf 04e2d430f2 修改CHANGELOG版本号
Signed-off-by: zgf <zenggaofeng2@h-partners.com>
2024-11-01 16:38:49 +08:00
jinzhao 80ba246aeb 删除对constructor的修改
Signed-off-by: jinzhao <jinzhao@kaihong.com>
2024-11-01 07:44:21 +00:00
jinzhao c75bb9226a 新增https自定义证书功能
Signed-off-by: jinzhao <jinzhao@kaihong.com>
2024-11-01 07:44:21 +00:00
tyBrave 1153390393 保持英文README不变
Signed-off-by: tyBrave <tianyong21@h-partners.com>
2024-10-29 16:42:32 +08:00
tyBrave 7210d5060b 更新README文件
Signed-off-by: tyBrave <tianyong21@h-partners.com>
2024-10-29 16:23:38 +08:00
tyBrave 1c7bedc6d5 同步3.x分支代码
Signed-off-by: tyBrave <tianyong21@h-partners.com>
2024-10-29 07:31:35 +00:00
tyBrave 5f2e80400a 更改针对接口回调信息需求的审核意见
Signed-off-by: tyBrave <tianyong21@h-partners.com>
2024-10-29 15:17:47 +08:00
zgf fd0394a80a 排队队列改为Queue、showPixelMap回调改为同步
Signed-off-by: zgf <zenggaofeng2@h-partners.com>
2024-10-28 14:39:40 +08:00
tyBrave c5a861f4fe 更改接口回调信息的README
Signed-off-by: tyBrave <tianyong21@h-partners.com>
2024-10-25 22:51:18 +08:00
tyBrave b57194cf4c 新增接口回调信息功能
Signed-off-by: tyBrave <tianyong21@h-partners.com>
2024-10-25 22:48:53 +08:00
tyBrave 1a2326c691 新增图片加载回调信息demo及其xts
Signed-off-by: tyBrave <tianyong21@h-partners.com>
2024-10-25 22:47:25 +08:00
madixin 9c0b4ebace 1.修复并发相同请求,只收到第一个onLoadStart的bug
2.判断是否要排队的条件,修改为大于等于maxRequests

Signed-off-by: madixin <madixin@huawei.com>
2024-10-25 17:17:44 +08:00
zgf 8d4442157c 子线程网络请求和自定义网络改为异步请求、复用场景清空组件内容
Signed-off-by: zgf <zenggaofeng2@h-partners.com>
2024-10-25 09:02:32 +00:00
zgf a34e20acfa 子线程网络请求和自定义网络改为异步请求、复用场景清空组件内容
Signed-off-by: zgf <zenggaofeng2@h-partners.com>
2024-10-25 17:01:18 +08:00
zgf 8dd224e7e6 修改CHANGELOG3.0.3正式版本
Signed-off-by: zgf <zenggaofeng2@h-partners.com>
2024-10-24 17:48:47 +08:00
openharmony_ci a7fa5de2de
!405 ImageKnife降采样适配3.x
Merge pull request !405 from 田双明/master
2024-10-23 01:53:00 +00:00
田双明 346c704193
update entry/src/main/ets/pages/Index.ets.
Signed-off-by: 田双明 <tianshuangming@h-partners.com>
2024-10-23 01:12:36 +00:00
田双明 e857a41129 Merge branch 'master' of gitee.com:openharmony-tpc/ImageKnife into master
Signed-off-by: 田双明 <tianshuangming@h-partners.com>
2024-10-22 10:43:49 +00:00
tyBrave 7f51e9164e 新增onLoadCancel接口回调的demo
Signed-off-by: tyBrave <tianyong21@h-partners.com>
2024-10-21 14:30:33 +08:00
tyBrave 41be71bb73 新增从缓存中获取图片的格式大小等的xts
Signed-off-by: tyBrave <tianyong21@h-partners.com>
2024-10-21 14:29:46 +08:00
tyBrave 08b36b7803 新增图片颜色变化demo
Signed-off-by: tyBrave <tianyong21@h-partners.com>
2024-10-21 14:28:53 +08:00
openharmony_ci da4c159d44
!404 增加onLoadCancel回调的demo、增加设置图片颜色变换demo、增加从缓存获取图片格式大小的xts等
Merge pull request !404 from tyBrave/master
2024-10-21 01:28:42 +00:00
tsm 29e0df8d2b 降采样功demo文字国际化
Signed-off-by: tsm <tianshuangming@h-partners.com>
2024-10-18 18:16:42 +08:00
tsm 5fa004afc0 降采样功能
Signed-off-by: tsm <tianshuangming@h-partners.com>
2024-10-18 15:31:38 +08:00
tyBrave d82d85ea19 去掉多余的日志信息
Signed-off-by: tyBrave <tianyong21@h-partners.com>

TestCacheDataPage 文件添加版权头

Signed-off-by: tyBrave <tianyong21@h-partners.com>

资源国际化

Signed-off-by: tyBrave <tianyong21@h-partners.com>

add TIPS text dec

Signed-off-by: tyBrave <tianyong21@h-partners.com>

update code because of checkcode

Signed-off-by: tyBrave <tianyong21@h-partners.com>

update code because of use image url

Signed-off-by: tyBrave <tianyong21@h-partners.com>
2024-10-17 17:39:50 +08:00
tyBrave 8e55d336f9 修改获取缓存中的图片格式大小的单元测试
Signed-off-by: tyBrave <tianyong21@h-partners.com>
2024-10-16 17:17:02 +08:00
tyBrave e31c592ee4 修改onLoadCancel回调demo及其缓存中获取图片的格式大小信息
Signed-off-by: tyBrave <tianyong21@h-partners.com>
2024-10-16 15:56:42 +08:00
tyBrave 1027fc0304 add xts test get size and format in image of callback
Signed-off-by: tyBrave <tianyong21@h-partners.com>
2024-10-16 10:57:36 +08:00
tyBrave ec651e91df add test cancel callback demo
Signed-off-by: tyBrave <tianyong21@h-partners.com>
2024-10-16 10:56:06 +08:00
tyBrave 7b9da8d9fa add change color of image in lib
Signed-off-by: tyBrave <tianyong21@h-partners.com>
2024-10-16 10:40:22 +08:00
tyBrave 2a81312ed5 add get cache data
Signed-off-by: tyBrave <tianyong21@h-partners.com>
2024-10-12 09:57:11 +08:00
zgf cde07275c3 自定义网络方法增加请求头参数
Signed-off-by: zgf <zenggaofeng2@h-partners.com>
2024-10-11 17:52:32 +08:00
zgf 43dd3c528c 样例国际化
Signed-off-by: zgf <zenggaofeng2@h-partners.com>
2024-10-10 16:51:11 +08:00
zgf 4383fa3659 新增preload预加载和cancel取消加载接口,添加prefetch配合preload接口样例
Signed-off-by: zgf <zenggaofeng2@h-partners.com>
2024-10-10 11:34:57 +08:00
openharmony_ci 78770a430c
!398 中文图片链接替换
Merge pull request !398 from zgf/master
2024-10-10 01:24:31 +00:00
zgf 2201fec90c 中文图片链接替换
Signed-off-by: zgf <zenggaofeng2@h-partners.com>
2024-10-09 15:36:07 +08:00
zgf aa2cd9c1bf 新增reload加载接口和网络恢复重新加载样例
Signed-off-by: zgf <zenggaofeng2@h-partners.com>
2024-10-09 15:35:06 +08:00
zgf 1787fffea7 3.x分支xts引入文件报错修改
Signed-off-by: zgf <zenggaofeng2@h-partners.com>
2024-09-30 17:10:07 +08:00
zgf 8e773e929a 3.x分支修改CHANGELOG版本号
Signed-off-by: zgf <zenggaofeng2@h-partners.com>
2024-09-30 16:18:59 +08:00
zgf a3ed45a468 3.x分支更新3.1.0版本代码,并且删除适配componentV2装饰器提交
Signed-off-by: zgf <zenggaofeng2@h-partners.com>
2024-09-30 15:28:02 +08:00
zgf ccd4455b83
!392 修改版本号3.0.2-rc.1
Merge pull request !392 from zgf/3.x
2024-09-29 08:30:37 +00:00
zgf 2fc1f4c776 修改版本号3.0.2-rc.1
Signed-off-by: zgf <zenggaofeng2@h-partners.com>
2024-09-29 16:14:21 +08:00
zgf 6dcf2840b3 FileUtil.readFile接口和file格式图片同步关闭fd
Signed-off-by: zgf <zenggaofeng2@h-partners.com>
2024-09-27 09:58:27 +08:00
openharmony_ci f7cef581b1
!388 适配国际化
Merge pull request !388 from hexagon1337/master
2024-09-25 03:40:24 +00:00
hexagon1337 ddb8fc89be 修改README_zh屏蔽词
Signed-off-by: hexagon1337 <liuyaoming3@h-partners.com>
2024-09-25 11:03:44 +08:00
hexagon1337 858e28c3a2 补充imagetransformation和removecache页面的国际化
Signed-off-by: hexagon1337 <liuyaoming3@h-partners.com>
2024-09-25 10:34:33 +08:00
hexagon1337 565938c98a 补充imagetransformation和removecache页面的国际化
Signed-off-by: hexagon1337 <liuyaoming3@h-partners.com>
2024-09-23 12:14:04 +08:00
hexagon1337 f1008e869e 适配国际化
Signed-off-by: hexagon1337 <liuyaoming3@h-partners.com>
2024-09-21 18:19:06 +08:00
openharmony_ci afde885ae1
!385 调整内部包的结构
Merge pull request !385 from Madi/master
2024-09-06 09:04:17 +00:00
Madixin 9f98c174f2 调整内部包的结构
Signed-off-by: Madixin <madixin@huawei.com>
2024-09-06 16:39:42 +08:00
openharmony_ci b491bc8dae
!384 重构代码:抽取ImageKnifeDispatcher子线程requestJob相关代码到ImageKnifeLoader中,降低函数复杂度
Merge pull request !384 from Madi/master
2024-09-06 08:19:22 +00:00
Madixin 6cbe5eadc5 重构代码:抽取ImageKnifeDispatcher子线程requestJob相关代码到ImageKnifeLoader中,降低函数复杂度
Signed-off-by: Madixin <madixin@huawei.com>
2024-09-06 15:15:35 +08:00
zgf 0dd26b9e75 Revert "降采样"
Signed-off-by: zgf <zenggaofeng2@h-partners.com>
2024-09-06 11:05:46 +08:00
openharmony_ci 233b24032e
!382 修改网络请求超时设置
Merge pull request !382 from zgf/master
2024-09-05 10:35:52 +00:00
zgf d78ba39efe 修改网络请求超时设置
Signed-off-by: zgf <zenggaofeng2@h-partners.com>
2024-09-05 18:08:43 +08:00
zgf dcdc17f51f 修改网络请求超时设置
Signed-off-by: zgf <zenggaofeng2@h-partners.com>
2024-09-05 18:04:21 +08:00
openharmony_ci 483803a302
!380 修改file格式图片同步close和PixelMap默认不可编辑
Merge pull request !380 from zgf/master
2024-09-02 08:38:03 +00:00
zgf 2cbce5790b 修改file格式图片同步close和PixelMap默认不可编辑
Signed-off-by: zgf <zenggaofeng2@h-partners.com>
2024-09-02 15:58:32 +08:00
openharmony_ci f9e83786a8
!379 imageKnife降采样
Merge pull request !379 from 田双明/master
2024-09-02 07:43:33 +00:00
tsm f415bb7aa1 降采样
Signed-off-by: tsm <tianshuangming@h-partners.com>
2024-09-02 11:44:53 +08:00
openharmony_ci 55fcfe6021
!375 ImageknifeComponents代码整理
Merge pull request !375 from Madi/master
2024-08-30 06:26:33 +00:00
Madixin 587d35f085 优化整理imageknifecomponent代码
Signed-off-by: Madixin <madixin@huawei.com>
2024-08-30 11:56:11 +08:00
openharmony_ci b3114dd47b
!371 新增Task任务报错10200006样例
Merge pull request !371 from zgf/master
2024-08-28 09:26:58 +00:00
zgf 0c8a777c82 新增Task任务报错10200006样例
Signed-off-by: zgf <zenggaofeng2@h-partners.com>
2024-08-28 17:00:43 +08:00
zgf ddbff75a7d 新增Task任务报错10200006样例
Signed-off-by: zgf <zenggaofeng2@h-partners.com>
2024-08-28 16:27:47 +08:00
zgf 2911708267 子线程本地Resource参数类型转换成number
Signed-off-by: zgf <zenggaofeng2@h-partners.com>
2024-08-27 11:30:08 +00:00
zgf 7252a2fe05 子线程本地Resource参数类型转换成number
Signed-off-by: zgf <zenggaofeng2@h-partners.com>
2024-08-27 16:48:48 +08:00
Madixin 47c178fe1f 修改使用hilog记录日志,默认打开debug级别的日志,增加可维侧性
Signed-off-by: Madixin <madixin@huawei.com>
2024-08-27 16:37:47 +08:00
openharmony_ci 6612dea1d5
!368 修改webp图片区分动静图和错误图加载完未发起排队队列中的请求
Merge pull request !368 from zgf/master
2024-08-23 09:45:04 +00:00
zgf fae5b3c7fd 修改webp图片区分动静图和错误图加载完未发起排队队列中的请求
Signed-off-by: zgf <zenggaofeng2@h-partners.com>
2024-08-23 17:28:50 +08:00
Madi ad18fe60b2
!366 修复宽高不等svg图片显示有毛边
Merge pull request !366 from zgf/master
2024-08-19 03:47:42 +00:00
zgf 906337cc62 修复宽高不等svg图片显示有毛边
Signed-off-by: zgf <zenggaofeng2@h-partners.com>
2024-08-19 11:01:32 +08:00
openharmony_ci fa59e2b9ac
!365 修改README待实现特性
Merge pull request !365 from zgf/master
2024-08-15 06:56:52 +00:00
zgf bebbc865f7 修改README待实现特性
Signed-off-by: zgf <zenggaofeng2@h-partners.com>
2024-08-15 14:44:38 +08:00
zgf 48b425109a 控制动图组件新增事件和文件缓存数量最大值修改
Signed-off-by: zgf <zenggaofeng2@h-partners.com>
2024-08-14 17:29:58 +08:00
openharmony_ci bea89c5c77
!361 新增动画显示首帧和第一帧样例
Merge pull request !361 from zgf/master
2024-08-14 08:18:04 +00:00
zgf 4898145979 新增动画显示首帧和第一帧样例
Signed-off-by: zgf <zenggaofeng2@h-partners.com>
2024-08-09 16:07:33 +08:00
openharmony_ci dd0c64fb91
!359 修复xts报错:ImageKnifeOption用法变更
Merge pull request !359 from zgf/master
2024-08-07 10:18:13 +00:00
zgf 5c1b0578b6 修复xts报错:ImageKnifeOption用法变更
Signed-off-by: zgf <zenggaofeng2@h-partners.com>
2024-08-07 18:05:26 +08:00
zgf cdfb4fafa9 修复xts报错:ImageKnifeOption用法变更
Signed-off-by: zgf <zenggaofeng2@h-partners.com>
2024-08-07 17:42:07 +08:00
openharmony_ci 370cc03b96
!357 适配ComponentV2装饰器
Merge pull request !357 from zgf/master
2024-08-06 07:29:26 +00:00
zgf 1b05a2aa2d ComponentV2装饰器适配
Signed-off-by: zgf <zenggaofeng2@h-partners.com>
2024-08-06 11:37:43 +08:00
zgf d7a14b8833 修复webp静态图无法设置图形变换
Signed-off-by: zgf <zenggaofeng2@h-partners.com>
2024-08-05 10:07:37 +08:00
zgf 69f951b290 修复动图控制组件初始值失效、网络请求成功code以及文件缓存可选初始化
Signed-off-by: zgf <zenggaofeng2@h-partners.com>
2024-08-02 16:25:41 +08:00
wangyingjun01 f497f32c48 ImageKnife3.x分支合并到master分支
Signed-off-by: wangyingjun01 <wangyingjun5@h-partners.com>
2024-07-31 11:41:01 +08:00
wangyingjun01 7fac49e442 ImageKnife3.x分支合并到master分支
Signed-off-by: wangyingjun01 <wangyingjun5@h-partners.com>
2024-07-31 11:23:37 +08:00
wangyingjun01 45b1fbc591 ImageKnife3.x分支合并到master分支
Signed-off-by: wangyingjun01 <wangyingjun5@h-partners.com>
2024-07-31 11:06:41 +08:00
wangyingjun01 7d39ff5129 Merge remote-tracking branch 'origin/3.x'
# Conflicts:
#	CHANGELOG.md
#	OAT.xml
#	README.md
#	build-profile.json5
#	entry/oh-package.json5
#	entry/src/main/ets/entryability/EntryAbility.ets
#	entry/src/main/ets/pages/UserPage.ets
#	entry/src/main/ets/pages/dataShareUriLoadPage.ets
#	entry/src/main/ets/pages/imageknifeTestCaseIndex.ets
#	entry/src/main/ets/pages/index.ets
#	entry/src/main/ets/pages/testImageKnifeHttpRequestHeader.ets
#	entry/src/main/ets/pages/testImageKnifeOptionChangedPage5.ets
#	entry/src/main/ets/pages/testManyNetImageLoadWithPage2.ets
#	entry/src/main/module.json5
#	entry/src/main/resources/base/element/string.json
#	entry/src/main/resources/base/profile/main_pages.json
#	entry/src/ohosTest/ets/test/DefaultJobQueueTest.test.ets
#	entry/src/ohosTest/ets/test/List.test.ets
#	entry/src/ohosTest/ets/test/diskLruCache.test.ets
#	entry/src/ohosTest/ets/test/imageknife.test.ets
#	entry/src/ohosTest/ets/test/requestoption.test.ets
#	entry/src/ohosTest/module.json5
#	gpu_transform/CHANGELOG.md
#	gpu_transform/oh-package.json5
#	library/index.ets
#	library/oh-package.json5
#	library/src/main/ets/SendableData.ets
#	library/src/main/ets/components/cache/DiskCacheEntry.ets
#	library/src/main/ets/components/cache/DiskLruCache.ets
#	library/src/main/ets/components/cache/FileUtils.ets
#	library/src/main/ets/components/cache/LruCache.ets
#	library/src/main/ets/components/imageknife/ImageKnife.ets
#	library/src/main/ets/components/imageknife/ImageKnifeComponent.ets
#	library/src/main/ets/components/imageknife/ImageKnifeData.ets
#	library/src/main/ets/components/imageknife/ImageKnifeDrawFactory.ets
#	library/src/main/ets/components/imageknife/ImageKnifeOption.ets
#	library/src/main/ets/components/imageknife/RequestOption.ets
#	library/src/main/ets/components/imageknife/TaskParams.ets
#	library/src/main/ets/components/imageknife/constants/Constants.ets
#	library/src/main/ets/components/imageknife/holder/ErrorHolderManager.ets
#	library/src/main/ets/components/imageknife/holder/PlaceHolderManager.ets
#	library/src/main/ets/components/imageknife/holder/RetryHolderManager.ets
#	library/src/main/ets/components/imageknife/interface/IParseImage.ets
#	library/src/main/ets/components/imageknife/networkmanage/DownloadClient.ets
#	library/src/main/ets/components/imageknife/networkmanage/HttpDownloadClient.ets
#	library/src/main/ets/components/imageknife/networkmanage/IDataFetch.ets
#	library/src/main/ets/components/imageknife/networkmanage/LoadDataShareFileClient.ets
#	library/src/main/ets/components/imageknife/networkmanage/LoadLocalFileClient.ets
#	library/src/main/ets/components/imageknife/networkmanage/NetworkDownloadClient.ets
#	library/src/main/ets/components/imageknife/requestmanage/MemoryCacheProxy.ets
#	library/src/main/ets/components/imageknife/requestmanage/RequestManager.ets
#	library/src/main/ets/components/imageknife/resourcemanage/ParseResClientBase64.ets
#	library/src/main/ets/components/imageknife/transform/TransformUtils.ets
#	library/src/main/ets/components/imageknife/utils/ParseImageUtil.ets
#	library/src/main/ets/components/imageknife/utils/gif/GIFFrame.ts
#	library/src/main/ets/components/imageknife/utils/gif/GIFParseImpl.ets
#	library/src/main/ets/components/imageknife/utils/gif/IParseGif.ets
#	library/src/main/ets/components/imageknife/utils/svg/SVGParseImpl.ets
#	library/src/main/ets/downsampling/BaseDownsampling.ets
#	library/src/main/ets/downsampling/DownsampleStartegy.ets
#	library/src/main/ets/downsampling/Downsampler.ets
#	library/src/main/ets/networkmanage/CustomDataFetchClient.ets
#	library/src/main/ets/networkmanage/DataFetchResult.ets
#	library/src/main/ets/networkmanage/RequestData.ets
#	library/src/main/ets/utils/CalculatePixelUtils.ets
#	library/src/main/ets/utils/DefaultJobQueue.ets
#	library/src/main/ets/utils/IJobQueue.ets
#	library/src/main/ets/utils/MResource.ets
#	library/src/main/ets/utils/base/AsyncLock.ts
#	oh-package.json5
#	sharedlibrary/src/main/ets/Index.ets
#	sharedlibrary/src/main/ets/pages/Index.ets
#	sharedlibrary/src/test/List.test.ets
2024-07-31 11:02:46 +08:00
zgf 4872cc64f7 修复错误图显示以及heic格式匹配
Signed-off-by: zgf <zenggaofeng2@h-partners.com>
2024-07-29 11:27:22 +08:00
zgf a792587c93 修复自定义下载失败无失败回调以及新增全局自定义下载接口
Signed-off-by: zgf <zenggaofeng2@h-partners.com>
2024-07-26 15:17:13 +08:00
zgf 44b3ca48ef 修复自定义下载失败无失败回调以及新增全局自定义下载接口
Signed-off-by: zgf <zenggaofeng2@h-partners.com>
2024-07-26 15:15:47 +08:00
openharmony_ci 8f41c6d13e
!345 去除READ_IMAGEVIDEO和WRITE_IMAGEVIDEO权限以及修复部分heif图无法解码
Merge pull request !345 from zgf/master
2024-07-24 02:36:16 +00:00
zgf 7101a26267 去除READ_IMAGEVIDEO和WRITE_IMAGEVIDEO权限以及修复部分heif图无法解码
Signed-off-by: zgf <zenggaofeng2@h-partners.com>
2024-07-24 10:01:12 +08:00
zgf 1dee5f345b 去除READ_IMAGEVIDEO和WRITE_IMAGEVIDEO权限以及修复部分heif图无法解码
Signed-off-by: zgf <zenggaofeng2@h-partners.com>
2024-07-23 16:34:16 +08:00
zgf 19e1ba9528 去除READ_IMAGEVIDEO和WRITE_IMAGEVIDEO权限
Signed-off-by: zgf <zenggaofeng2@h-partners.com>
2024-07-23 16:30:43 +08:00
zgf d2bd8f75fc 修改下采样和hsp本地图样例
Signed-off-by: zgf <zenggaofeng2@h-partners.com>
2024-07-22 14:41:15 +08:00
zgf e22c1184f4 新增ImageKnifeAnimatorComponent控制动图组件及修复部分heif无法解码
Signed-off-by: zgf <zenggaofeng2@h-partners.com>
2024-07-22 14:36:55 +08:00
openharmony_ci 659d28dd37
!340 加载优先级Priority类型改为taskpool.Priority类型
Merge pull request !340 from zgf/master
2024-07-18 06:18:40 +00:00
zgf 7930c50f11 文件缓存设置最大缓存数量改为无上限
Signed-off-by: zgf <zenggaofeng2@h-partners.com>
2024-07-18 10:59:03 +08:00
zgf 136c3e509a 加载优先级Priority类型改为taskpool.Priority类型
Signed-off-by: zgf <zenggaofeng2@h-partners.com>
2024-07-18 10:55:44 +08:00
zgf a1f80ce93f 自定义下载改为仅支持主图和修改requestInSteam配置、新增ColorFilter属性
Signed-off-by: zgf <zenggaofeng2@h-partners.com>
2024-07-12 16:04:52 +08:00
zgf 7ecc9faf9f 添加测试多张相同内容不同链接图片样例
Signed-off-by: zgf <zenggaofeng2@h-partners.com>
2024-07-04 14:53:14 +08:00
chongtiantian e48600fe7f 修改uuid的生成方式,使用资源loadSrc,宽高以及转换效果的拼接字符串作为入参,修复同资源图形转换错乱的问题。
Signed-off-by: chongtiantian <chongtiantian1@h-partners.com>
2024-07-01 16:07:57 +08:00
chongtiantian 414e335a3a 修复图形变换的闪退问题
Signed-off-by: chongtiantian <chongtiantian1@h-partners.com>
2024-06-27 17:17:32 +08:00
zgf db1ccdc604 修复file://格式图片无法显示以及媒体展示图片样例改用photoAccessHelper接口获取本地图片资源
Signed-off-by: zgf <zenggaofeng2@h-partners.com>
2024-06-27 06:44:44 +00:00
openharmony_ci c51e0eca77
!318 X86模拟器配置
Merge pull request !318 from yaofangyong/master
2024-06-27 06:34:28 +00:00
madixin 54f6673d35 修复前一次提交的文件路径判断错误
Signed-off-by: madixin <madixin@huawei.com>
2024-06-27 12:28:42 +08:00
zgf e8cd4cf95e 媒体url样例改用photoAccessHelper接口获取本地图片资源
Signed-off-by: zgf <zenggaofeng2@h-partners.com>
2024-06-27 02:45:29 +00:00
madixin 3fa2d61b6e 1.补充Imageknife相关public接口
2.支持文件路径支持设置非context.cacheDir的路径

Signed-off-by: madixin <madixin@huawei.com>
2024-06-27 09:42:57 +08:00
madixin 2c54685897 1.补充销毁时cancel事件的发出
2.补充对应readme文档

Signed-off-by: madixin <madixin@huawei.com>
2024-06-26 09:35:33 +08:00
yaofangyong d873733517 x86
Signed-off-by: yaofangyong <2385605052@qq.com>
2024-06-25 19:34:37 +08:00
Madi daf15f5be1
!316 修复Resource类型以及onLoadListener回调和onComplete回调
Merge pull request !316 from zgf/3.x
2024-06-25 08:55:59 +00:00
zgf 7f8009bda9 修复Resource类型以及onLoadListener回调和onComplete回调
Signed-off-by: zgf <zenggaofeng2@h-partners.com>
2024-06-25 16:53:22 +08:00
Madi 9565bd6522
!314 占位图从内存获取提前到判断队列前面以及样例增加版权头
Merge pull request !314 from zgf/3.x
2024-06-20 10:53:28 +00:00
zgf 57b33c1123 占位图从内存获取提前到判断队列前面以及样例增加版权头
Signed-off-by: zgf <zenggaofeng2@h-partners.com>
2024-06-20 18:39:18 +08:00
Madi a3026e13e8
!312 修改xts用例setCache和getMapCache
Merge pull request !312 from zgf/master
2024-06-19 13:58:26 +00:00
zgf 334b042086 修改xts用例setCache和getMapCache
Signed-off-by: zgf <zenggaofeng2@h-partners.com>
2024-06-19 21:49:08 +08:00
Madi 7c0fc08d9d
!311 增加gif图duration的默认值,以及默认播放次数
Merge pull request !311 from zgf/master
2024-06-19 11:37:42 +00:00
zgf f171b64e95 增加gif图duration的默认值,以及默认播放次数
Signed-off-by: zgf <zenggaofeng2@h-partners.com>
2024-06-19 19:24:51 +08:00
zgf 549658e321 修改CHANGELOG
Signed-off-by: zgf <zenggaofeng2@h-partners.com>
2024-06-19 19:00:09 +08:00
zgf 47a3933ddc 样例引入依赖改为libraryimageknife
Signed-off-by: zgf <zenggaofeng2@h-partners.com>
2024-06-19 10:29:54 +08:00
Madi d42caf8188
!307 svg解码修改,预加载接口修复,文件缓存目录配置
Merge pull request !307 from zgf/3.x
2024-06-14 09:11:31 +00:00
zgf 0aafb99028 svg解码修改,预加载接口修复,文件缓存目录配置
Signed-off-by: zgf <zenggaofeng2@h-partners.com>
2024-06-14 16:43:16 +08:00
zgf 150b75fe8c svg解码修改,预加载接口修复,文件缓存目录配置
Signed-off-by: zgf <zenggaofeng2@h-partners.com>
2024-06-14 16:41:25 +08:00
zgf 7b4f496150 1.修复复用场景下从内存获取图片后又清空了画布导致图片不显示,
2.svg解码单位改为px
3.获取组件宽高改用onSizeChange
4.修复复用占位图不显示

Signed-off-by: zgf <zenggaofeng2@h-partners.com>
2024-06-14 15:03:00 +08:00
Madi d4a87f0c5e
!304 修复多线程图片加载出现空白问题
Merge pull request !304 from baofeng/master
2024-06-13 06:20:16 +00:00
baofeng f7ce1945b8 修复多线程图片加载出现空白问题
Signed-off-by: baofeng <baofeng6@h-partners.com>
2024-06-12 18:37:14 +08:00
openharmony_ci ee980fe094
!302 imageKnife降采样案例修改
Merge pull request !302 from 田双明/master
2024-06-11 08:20:16 +00:00
tsm fe80ce7a34 降采样案例修改
Signed-off-by: tsm <2418639820@qq.com>
2024-06-11 15:19:54 +08:00
Madi 5d73ee0b11
!301 修改门禁编译问题 修改点如下:修改src/main/cpp/util/DebugLog.h文件中hilog的大小写
Merge pull request !301 from sunao/3.x
2024-06-07 11:09:08 +00:00
sunao aa94d9c508 修改门禁编译问题 修改点如下:修改src/main/cpp/util/DebugLog.h文件中hilog的大小写
Signed-off-by: sunao <sunao19@h-partners.com>
2024-06-07 18:04:37 +08:00
sunao d6e3ebc253 修改门禁编译问题 修改点如下:修改src/main/cpp/boundscheck/CMakeLists.txt文件中的内容,修改src/main/cpp/util/DebugLog.h文件中hilog的大小写
Signed-off-by: sunao <sunao19@h-partners.com>
2024-06-07 17:18:10 +08:00
madixin 9fbea8f624 1.完善readme对于syncLoad的描述
2.回调时,对相同key的请求,都需要分别判断是否已经destroy了。

Signed-off-by: madixin <madixin@huawei.com>
2024-06-07 08:55:09 +08:00
zgf 134c687efc 修复头像超过设备高度图片闪动问题-消息列表底部头像闪动问题
Signed-off-by: zgf <zenggaofeng2@h-partners.com>
2024-06-06 20:45:34 +08:00
zgf 77b016fde9 新增媒体图片file://格式
Signed-off-by: zgf <zenggaofeng2@h-partners.com>
2024-06-06 15:17:45 +08:00
zgf a3314d003a 新增svg图片解码
Signed-off-by: zgf <zenggaofeng2@h-partners.com>
2024-06-05 14:57:26 +08:00
zgf 9ee162c69a 修复成功回调获取不到宽高
Signed-off-by: zgf <zenggaofeng2@h-partners.com>
2024-06-04 15:16:25 +08:00
openharmony_ci 804049b36b
!292 修复preLoad接口失效
Merge pull request !292 from zgf/master
2024-06-03 07:52:15 +00:00
zgf bafd1a568f 修复preLoad接口失效
Signed-off-by: zgf <zenggaofeng2@h-partners.com>
2024-06-03 15:02:43 +08:00
zhang_hanyong 2fee05b569 图片裁剪成圆形时裁剪不平滑问题修复
Signed-off-by: zhang_hanyong <zhang_hanyong@h-partners.com>
2024-06-03 11:47:58 +08:00
zgf b2a7fb47f8 修改package.json版本
Signed-off-by: zgf <zenggaofeng2@h-partners.com>
2024-05-31 10:21:15 +08:00
zgf 8d39586c67 文件缓存初始化增加默认值、预加载接口新增返回加载错误信息、加载队列从队列从Queue改为Stack以及fileType新增heic格式
Signed-off-by: zgf <zenggaofeng2@h-partners.com>
2024-05-30 08:29:50 +00:00
zgf 945e842e69 文件缓存初始化增加默认值、预加载接口新增返回加载错误信息、加载队列从队列从Queue改为Stack以及fileType新增heic格式
Signed-off-by: zgf <zenggaofeng2@h-partners.com>
2024-05-30 16:27:27 +08:00
madixin 36875b0534 支持全局配置是否在子线程请求加载图片,默认在子线程
Signed-off-by: madixin <madixin@huawei.com>
2024-05-30 15:27:55 +08:00
zhang_hanyong 52e5d1f5bf 支持多种组合变换
Signed-off-by: zhang_hanyong <zhang_hanyong@h-partners.com>
2024-05-29 06:16:40 +00:00
openharmony_ci f7bb2f1999
!287 ImageKnife提供图片加载成功/失败的事件README补充
Merge pull request !287 from 任伟x/master
2024-05-27 09:31:50 +00:00
任伟x b777d40426 ImageKnife提供图片加载成功失败的事件README补充
Signed-off-by: 任伟x <renwei79@h-partners.com>
2024-05-27 16:58:59 +08:00
任伟x 27094f0db9 ImageKnife提供图片加载成功失败的事件README补充
Signed-off-by: 任伟x <renwei79@h-partners.com>
2024-05-27 16:24:19 +08:00
zgf 2b5d0d3f0c 修改内存缓存xts样例
Signed-off-by: zgf <zenggaofeng2@h-partners.com>
2024-05-27 14:56:57 +08:00
张欢 374b5c0cc3 修改packjson
Signed-off-by: 张欢 <zhanghuan165@h-partners.com>
2024-05-24 17:14:55 +08:00
openharmony_ci 0d27e7a8cc
!281 修改readme文档
Merge pull request !281 from zhanghuan633/master
2024-05-24 08:43:48 +00:00
张欢 ce8b3cbb7a 修改readme文档
Signed-off-by: 张欢 <zhanghuan165@h-partners.com>
2024-05-24 16:19:49 +08:00
zgf 094eb4d1f4 优化文件缓存和内存释放以及成功回调新增宽高参数
Signed-off-by: zgf <zenggaofeng2@h-partners.com>
2024-05-24 15:03:43 +08:00
zgf 08399f557e 优化文件缓存和内存释放以及成功回调新增宽高参数
Signed-off-by: zgf <zenggaofeng2@h-partners.com>
2024-05-24 06:47:25 +00:00
zgf 980c8e8767 优化文件缓存和内存释放以及成功回调新增宽高参数
Signed-off-by: zgf <zenggaofeng2@h-partners.com>
2024-05-24 14:45:00 +08:00
zgf 2549d7a8c8 加载图片流程添加日志
Signed-off-by: zgf <zenggaofeng2@h-partners.com>
2024-05-24 14:43:09 +08:00
openharmony_ci 668bf251fd
!276 ImageKnife提供清理缓存能力
Merge pull request !276 from 任伟x/master
2024-05-23 06:56:58 +00:00
任伟x ee6e0acef6 ImageKnife提供清理缓存能力
Signed-off-by: 任伟x <renwei79@h-partners.com>
2024-05-22 17:28:30 +08:00
openharmony_ci 3ecc586559
!268 ImageKnife支持多种组合变换
Merge pull request !268 from zhanghanyong/master
2024-05-22 09:02:14 +00:00
zhang_hanyong 1e94a03d5b 支持多种组合变换
Signed-off-by: zhang_hanyong <zhang_hanyong@h-partners.com>
2024-05-21 11:02:53 +08:00
任伟x 8c15816eee ImageKnife提供清理缓存能力
Signed-off-by: 任伟x <renwei79@h-partners.com>
2024-05-21 10:39:11 +08:00
张欢 6d43923279 修复懒加载在多次点击出现卡死的问题
Signed-off-by: 张欢 <zhanghuan165@h-partners.com>
2024-05-20 15:25:19 +08:00
任伟x caebb3ed8d ImageKnife提供图片加载成功失败的事件单元测试修改
Signed-off-by: 任伟x <renwei79@h-partners.com>
2024-05-20 01:43:26 +00:00
madixin d354a52975 补充await
Signed-off-by: madixin <madixin@huawei.com>
2024-05-18 09:45:42 +08:00
madixin 7acce8276a 图片加载事件增加请求开始的回调,以及修复有缓存时,没有回调的bug
Signed-off-by: madixin <madixin@huawei.com>
2024-05-17 09:00:53 +08:00
明月清风 f26f96fd2f 更新说明:
1、修复可视化代码逻辑

Signed-off-by: 明月清风 <qiufeihu1@h-partners.com>
2024-05-16 17:09:50 +08:00
openharmony_ci 83e76dcc08
!260 ImageKnife提供图片加载成功/失败的事件
Merge pull request !260 from 任伟x/master
2024-05-16 02:15:01 +00:00
任伟x 275ee6bc0a ImageKnife提供图片加载成功失败的事件
Signed-off-by: 任伟x <renwei79@h-partners.com>
2024-05-15 16:55:29 +08:00
Madi c0b3d6855e
!257 ImageKnife提供图片加载成功/失败的事件
Merge pull request !257 from 任伟x/3.x
2024-05-11 07:08:08 +00:00
任伟x cbc4dd3783 ImageKnife提供图片加载成功/失败的事件
Signed-off-by: 任伟x <renwei79@h-partners.com>
2024-05-11 14:46:25 +08:00
zgf 39f97e0a41 修复错误图绘制完后变成占位图
Signed-off-by: zgf <zenggaofeng2@h-partners.com>
2024-05-11 10:01:09 +08:00
zgf 8d00a54a4f 补充写入缓存策略样例
Signed-off-by: zgf <zenggaofeng2@h-partners.com>
2024-05-10 10:38:24 +08:00
openharmony_ci b74f6e68ec
!253 更新版本信息
Merge pull request !253 from 田双明/master
2024-05-10 01:18:28 +00:00
sijainguo 2731a7f8cc 版本信息修改
Signed-off-by: sijainguo <sijianguo5@h-partners.com>
2024-05-09 11:27:55 +08:00
zgf f350c32b2e 网络请求减少拼接操作,修复网络加载速度慢
Signed-off-by: zgf <zenggaofeng2@h-partners.com>
2024-05-09 09:54:16 +08:00
madixin 0cd3d8b370 placeholderSrc,errorholderSrc 支持传入string,请求网路
Signed-off-by: madixin <madixin@huawei.com>
2024-05-09 08:39:40 +08:00
明月清风 dc96ec43b4 更新说明:
- 补充单个图片测试demo

Signed-off-by: 明月清风 <qiufeihu1@h-partners.com>
2024-05-08 18:14:09 +08:00
明月清风 7030f5f55a 更新说明:
- 支持hsp多包图片资源
- 新增putCache写入缓存接口
- 修复入参为pixelMap图片不显示问题

Signed-off-by: 明月清风 <qiufeihu1@h-partners.com>
2024-05-08 17:45:08 +08:00
openharmony_ci 8fbc60f907
!202 使用安全函数memset_s替代memset,memcpy_s替代memcpy
Merge pull request !202 from 刘海康/master
2024-05-08 00:35:51 +00:00
madixin dd24720c00 1.补充option参数:placeholderObjectFit,errorholderObjectFit分别支持占位图填充效果和错误图填充效果
2.合并读写缓存策略CacheStrategy

Signed-off-by: madixin <madixin@huawei.com>
2024-05-07 15:31:54 +08:00
openharmony_ci 937f448fb7
!247 imageKnife降采样
Merge pull request !247 from 田双明/master
2024-05-07 03:48:56 +00:00
tsm d6a3f2df0e imageKnife 下采样
Signed-off-by: tsm <2418639820@qq.com>
2024-05-07 11:01:14 +08:00
madixin 8b4ba78d56 补充设置并发数量调整为8,减少下发taskpool请求数量,从而减少丢帧
Signed-off-by: madixin <madixin@huawei.com>
2024-05-06 20:02:33 +08:00
openharmony_ci 49502f1143
!240 修改header图的存储标志位
Merge pull request !240 from taxuexunji/master
2024-05-06 03:02:10 +00:00
2206069183@qq.com 4f549b2f81 修改header图的存储标志位
Signed-off-by: 2206069183@qq.com <2206069183@qq.com>
2024-05-06 10:32:19 +08:00
madixin 400ba85a5d Merge branch '3.x' of gitee.com:openharmony-tpc/ImageKnife into 3.x 2024-05-05 16:37:03 +08:00
madixin 4c0ee994a9 将请求默认并行从64调整到8,减少对taskpool execute内存消耗
Signed-off-by: madixin <madixin@huawei.com>
2024-05-05 16:36:23 +08:00
openharmony_ci a27ca5b4c7
!234 ImageKnife组件修改配置字段srcEntrance替换为srcEntry
Merge pull request !234 from xiagengwen/master
2024-05-05 02:38:12 +00:00
Madi 96e61758ad
!236 3.x样例拼音检查修改
Merge pull request !236 from zgf/3.x
2024-05-04 10:54:59 +00:00
Madi ac409d4ac9
!237 修复通过磁盘链接加载图片无法显示
Merge pull request !237 from zgf/master
2024-05-04 10:35:13 +00:00
Madi 98145712fa
!235 修复占位图、错误图、重试图从内存获取之后进入子线程导致内存泄露
Merge pull request !235 from zgf/master
2024-05-04 10:34:42 +00:00
zgf 08ba6360c7 修复通过磁盘链接加载图片无法显示
Signed-off-by: zgf <zenggaofeng2@h-partners.com>
2024-05-04 17:53:55 +08:00
zgf 902f49a6e2 样例拼音检查修改
Signed-off-by: zgf <zenggaofeng2@h-partners.com>
2024-05-04 17:11:40 +08:00
zgf a6bbe8341a 修复占位图、错误图、重试图从内存获取之后进入子线程导致内存泄露
Signed-off-by: zgf <zenggaofeng2@h-partners.com>
2024-05-04 17:09:21 +08:00
xiagengwen ceb5fe7010 ImageKnife组件修改配置字段srcEntrance替换为srcEntry
Signed-off-by: xiagengwen <xiagengwen1@h-partners.com>
2024-05-04 15:22:45 +08:00
madixin 0e2245b5f6 修改3.0.0-rc.2版本号
Signed-off-by: madixin <madixin@huawei.com>
2024-05-04 10:51:09 +08:00
madixin b99e97d811 1.抽取interface到data类
2.实现缓存未完成初始化时,子线程不写文件

Signed-off-by: madixin <madixin@huawei.com>
2024-05-04 09:16:57 +08:00
madixin 91634663dc 1.修改memorykey生成
2.文件缓存key由子线程生成,返回到主线程管理

Signed-off-by: madixin <madixin@huawei.com>
2024-05-03 20:57:16 +08:00
madixin 33ba458600 1.修改imageknifeOpion为小写
2.writeCacheStrategy为memory时,子线程不写文件
3.文件缓存未初始化时,不写缓存

Signed-off-by: madixin <madixin@huawei.com>
2024-05-03 15:06:58 +08:00
madixin 00f5e81571 1.属性改为小写imageKnifeOption
2.支持使用一个或多个图片变换,如模糊,高亮等

Signed-off-by: madixin <madixin@huawei.com>
2024-05-03 14:10:54 +08:00
madixin be0f5ff8ef 完善3.x README.md,使用5.0 API12
Signed-off-by: madixin <madixin@huawei.com>
2024-05-02 10:14:23 +08:00
zgf e8f081523b 补充文件缓存预加载接口preLoadCache、getCacheImage,请求头,以及ImageKnifeOption属性isCacheable、onlyRetrieveFromCache,请求头
Signed-off-by: zgf <zenggaofeng2@h-partners.com>
2024-04-30 17:31:46 +08:00
zgf 915c9275b3 补充文件缓存预加载接口preLoadCache、getCacheImage,请求头,以及ImageKnifeOption属性写入缓存策略、onlyRetrieveFromCache,请求头
Signed-off-by: zgf <zenggaofeng2@h-partners.com>
2024-04-30 16:30:58 +08:00
zgf 219164b278 补充文件缓存预加载接口preLoadCache、isUrlExist,请求头,以及ImageKnifeOption属性isCacheable、onlyRetrieveFromCache,请求头
Signed-off-by: zgf <zenggaofeng2@h-partners.com>
2024-04-30 12:01:32 +08:00
openharmony_ci 4ee4760aed
!229 ImageKnife控制可视化区域图片
Merge pull request !229 from 17792399693/master
2024-04-30 02:50:06 +00:00
明月清风 34cb7e64ea 更新说明:
1、规范化代码

Signed-off-by: 明月清风 <qiufeihu1@h-partners.com>
2024-04-30 10:06:48 +08:00
chongtiantian f54b5045c7 ImageKnife控制可视化区域图片
Signed-off-by: chongtiantian <chongtiantian1@h-partners.com>
2024-04-29 17:58:07 +08:00
明月清风 e65ee6bb81 更新说明:
1、新增自定义key能力

Signed-off-by: 明月清风 <qiufeihu1@h-partners.com>
2024-04-29 15:06:14 +08:00
openharmony_ci d5faaf74d2
!226 ImageKnife支持heic图片修改demo
Merge pull request !226 from taxuexunji/master
2024-04-29 06:59:54 +00:00
2206069183@qq.com 240a2658a7 修改heic图片展示demo
Signed-off-by: 2206069183@qq.com <2206069183@qq.com>
2024-04-29 10:19:22 +08:00
openharmony_ci bb57dc0f51
!223 【ImageKnife】加载图片支持自定义网络栈补充XTS用例以及优化按钮重复点击问题
Merge pull request !223 from zhanghanyong/master
2024-04-29 01:41:40 +00:00
madixin 225754b15d 1.dispatch队列时,只下发progress状态的请求
2.filecache trim时,在主线程中不读取文件,减少主线程逻辑开销

Signed-off-by: madixin <madixin@huawei.com>
2024-04-29 09:31:23 +08:00
zhang_hanyong b185bf1f18 ImageKnife加载图片支持自定义网络栈补充XTS用例以及优化按钮重复点击问题
Signed-off-by: zhang_hanyong <zhang_hanyong@h-partners.com>
2024-04-28 18:12:06 +08:00
liuhaikang 46b75226cf 使用安全函数memset_s替代memset,memcpy_s替代memcpy
Signed-off-by: liuhaikang <liuhaikang@huawei-partners.com>
2024-04-28 10:21:54 +08:00
openharmony_ci 97a5ca1ec2
!221 新增自定义key获取已缓存的图片单元测试
Merge pull request !221 from 任伟x/master
2024-04-25 02:10:08 +00:00
任伟x 68257fb666 Merge branch 'master' of gitee.com:openharmony-tpc/ImageKnife into master
Signed-off-by: 任伟x <renwei79@h-partners.com>
2024-04-24 08:17:28 +00:00
任伟x 06ab9131ed ImageKnife支持根据自定义key获取已缓存的图片-新增xts
Signed-off-by: 任伟x <renwei79@h-partners.com>
2024-04-24 16:05:48 +08:00
openharmony_ci befcd414ac
!219 ImageKnife控制重要图片请求加载优先级
Merge pull request !219 from 17792399693/master
2024-04-24 06:20:29 +00:00
chongtiantian 87f3dab4fa ImageKnife控制重要图片请求加载优先级
Signed-off-by: chongtiantian <chongtiantian1@h-partners.com>
2024-04-24 10:05:23 +08:00
openharmony_ci 32b29801bd
!217 适配复用场景触发懒加载onDataReloaded
Merge pull request !217 from zgf/master
2024-04-24 01:48:21 +00:00
zenggaofeng 9bc31bb138 适配复用场景触发懒加载onDataReloaded
Signed-off-by: zenggaofeng <zenggaofeng2@h-partners.com>
2024-04-23 20:32:37 +08:00
zenggaofeng d152713556 aboutToRecycle生命周期将请求生命周期销毁
Signed-off-by: zenggaofeng <zenggaofeng2@h-partners.com>
2024-04-23 20:06:22 +08:00
madixin 5d21da6dac 优化主线程文件缓存里的读取文件操作,减少主线程耗时
Signed-off-by: madixin <madixin@huawei.com>
2024-04-23 19:32:45 +08:00
chenchen2019710 ec861fb89f 修改ImageKnife跳过网络,点击默认,图片没有传入宽高,无显示bug
Signed-off-by: chenchen2019710 <1173940354@qq.com>
2024-04-23 17:48:45 +08:00
openharmony_ci 5fdc066846
!215 【ImageKnife】加载图片支持自定义网络栈和图片加载组件
Merge pull request !215 from zhanghanyong/master
2024-04-23 08:26:42 +00:00
zhang_hanyong 9ff235a856 ImageKnife加载图片支持自定义网络栈和图片加载组件
Signed-off-by: zhang_hanyong <zhang_hanyong@h-partners.com>
2024-04-23 16:00:20 +08:00
openharmony_ci 906bfe55f1
!211 ImageKnife支持根据自定义key获取已缓存的图片
Merge pull request !211 from 任伟x/master
2024-04-23 03:45:27 +00:00
任伟x 6ae9982ec6 ImageKnife支持根据自定义key获取已缓存的图片
Signed-off-by: 任伟x <renwei79@h-partners.com>
2024-04-23 10:37:44 +08:00
zenggaofeng 883357a8b0 优化getRequest方法中获取context和generateMemoryKey方法
Signed-off-by: zenggaofeng <zenggaofeng2@h-partners.com>
2024-04-20 10:16:10 +08:00
Madi f07c401dc2
!201 generateKey方法减少sparkMD5和stringify操作
Merge pull request !201 from zgf/3.x
2024-04-18 10:31:35 +00:00
zenggaofeng 709c51b532 generateKey方法减少sparkMD5和stringify操作
Signed-off-by: zenggaofeng <zenggaofeng2@h-partners.com>
2024-04-18 18:19:26 +08:00
zenggaofeng 2a66bdbbba LogUtil日志默认改为关闭OFF
Signed-off-by: zenggaofeng <zenggaofeng2@h-partners.com>
2024-04-18 01:58:00 +00:00
张欢 9fd6963a8e 修复发送消息时最近的两条消息头像闪动的问题
Signed-off-by: 张欢 <zhanghuan165@h-partners.com>
2024-04-15 15:24:29 +08:00
madixin dec741e7f7 更新changelog和readme
Signed-off-by: madixin <madixin@huawei.com>
2024-04-10 10:17:45 +08:00
madixin 660490aec6 修改3.x版本demo首页+readme补充3.x差异
Signed-off-by: madixin <madixin@huawei.com>
2024-04-10 10:11:41 +08:00
madixin 46b12bf7c2 1.修复新版本图片错位显示问题:通过watchoption变化后发起请求
2.修复展位图错误图,没有从缓存拿取的问题
3.修复请求超过并发数,放队列后仍然直接下发请求的问题

Signed-off-by: madixin <madixin@huawei.com>
2024-04-08 12:01:37 +08:00
longfeng 07dc0b0ca4 支持x86编译
Signed-off-by: longfeng <longfeng20@huawei.com>
2024-04-02 03:03:09 +00:00
madixin ae7a8a864f ## 3.0.0-rc.0
使用Image组件替换Canvas组件渲染,并重构大部分的实现逻辑,提升渲染性能

Signed-off-by: madixin <madixin@huawei.com>
2024-03-31 15:55:44 +08:00
439 changed files with 15155 additions and 27429 deletions

View File

@ -0,0 +1,13 @@
### 该问题是怎么引起的?
### 重现步骤
### 报错信息

View File

@ -0,0 +1,47 @@
name: 缺陷反馈|Bug
description: 当您发现了一个缺陷,需要向社区反馈时,请使用此模板。
title: "[Bug]: "
labels: ["bug"]
body:
- type: markdown
attributes:
value: |
感谢对OpenHarmony社区的支持与关注欢迎反馈缺陷。
- type: textarea
attributes:
label: 发生了什么问题?
description: 提供尽可能多的信息描述产生了什么问题。
placeholder: ""
validations:
required: true
- type: textarea
attributes:
label: 期望行为是什么?
description: 描述期望的行为应该是什么样子的。
placeholder: ""
validations:
required: true
- type: textarea
attributes:
label: 如何复现该缺陷
description: 提供尽可能多的信息描述如何复现该缺陷。
validations:
required: true
- type: textarea
attributes:
label: 其他补充信息
description: 补充下其他您认为需要提供的信息。
validations:
required: false
- type: checkboxes
attributes:
label: 版本或分支信息
description: 在哪些版本、分支存在该缺陷的?
options:
- label: master
- label: Release 3.2
- label: Release 3.1
- label: Release 3.0
- label: Release 2.x
validations:
required: true

View File

@ -0,0 +1 @@
blank_issues_enabled: false

View File

@ -0,0 +1,21 @@
name: 新需求|Feature
description: 您需要反馈或实现一个新需求时,使用此模板。
title: "[新需求]: "
labels: ["enhancement"]
body:
- type: markdown
attributes:
value: |
感谢提出新需求。
- type: textarea
attributes:
label: 新需求提供了什么功能?
description: 请描述下新需求的功能是什么,解决了什么问题
validations:
required: true
- type: textarea
attributes:
label: 该需求带来的价值、应用场景?
description: 请描述下该需求的价值,应用场景等。
validations:
required: false

View File

@ -0,0 +1,15 @@
name: 问题咨询|Question
description: 如果您对OpenHarmony社区有疑问欢迎反馈咨询。
title: "[问题咨询]: "
labels: ["question"]
body:
- type: markdown
attributes:
value: |
感谢提出问题,我们将安排人答复!
- type: textarea
attributes:
label: 问题描述
description: 请描述下您的问题
validations:
required: true

View File

@ -0,0 +1,72 @@
name: 安全问题|Security Issue
description: 当您发现安全问题时,使用此模板反馈。
title: "[安全问题]: "
labels: ["SIG_Security"]
body:
- type: markdown
attributes:
value: |
感谢对OpenHarmony社区的支持与关注欢迎反馈安全问题。
- type: input
attributes:
label: 漏洞编号:
description: 请描述下漏洞编号。
placeholder: ""
validations:
required: false
- type: input
attributes:
label: 漏洞归属组件
description: 请描述下漏洞归属组件。
placeholder: ""
validations:
required: false
- type: input
attributes:
label: 漏洞归属版本
description: 请描述下漏洞归属版本。
placeholder: ""
validations:
required: false
- type: input
attributes:
label: CVSS V3.0分值
description: 请描述下CVSS V3.0分值。
placeholder: ""
validations:
required: false
- type: textarea
attributes:
label: 漏洞简述
description: 请提供下漏洞的描述信息。
placeholder: ""
validations:
required: true
- type: textarea
attributes:
label: 影响性分析说明
description: 请描述下该漏洞的影响。
placeholder: ""
validations:
required: false
- type: textarea
attributes:
label: 原理分析
description: 请分析下该漏洞的原理。
placeholder: ""
validations:
required: false
- type: input
attributes:
label: 受影响版本
description: 请描述下该漏洞的影响版本。
placeholder: ""
validations:
required: false
- type: textarea
attributes:
label: 规避方案或消减措施
description: 请描述下该漏洞的规避方案或消减措施。
placeholder: ""
validations:
required: false

View File

@ -0,0 +1,8 @@
### 一、修改说明
### 二、变更内容
### 三、测试建议

7
.gitignore vendored
View File

@ -1,10 +1,11 @@
/node_modules
/oh_modules
/local.properties
/.idea
**/build
/oh_modules/
/.hvigor/
/oh-package-lock.json5
/.hvigor
.cxx
/.clangd
/.clang-format
/.clang-tidy
**/.test

3
.gitmodules vendored Normal file
View File

@ -0,0 +1,3 @@
[submodule "gpu_transform/src/main/cpp/boundscheck/third_party_bounds_checking_function"]
path = gpu_transform/src/main/cpp/boundscheck/third_party_bounds_checking_function
url = https://gitee.com/openharmony/third_party_bounds_checking_function.git

View File

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.6 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@ -1,7 +1,247 @@
## 2.1.2-rc.13
- 修改ImageKnife跳过网络从内存中获取图片 cacheType参数未使用bug
- 新增WEBP图片解析能力。
- 新增gif图片支持暂停播放功能
## 3.2.2-rc.1
- Support EXIF metadata carried by images as display orientation
## 3.2.2-rc.0
- Add ImageKnifeComponent to destroy network request interruption
- Code refactoring during the download of image resources stage
## 3.2.1
- Release official version
## 3.2.1-rc.0
- Fix bug: CropTransformation is used to crop the original image
- Fix bug: After calling the clear all file cache interfaces, the file cache becomes invalid
- Optimize the efficiency of file cache initialization.
- Add protection at the location where loadSrc is passed in the pixelmap type
## 3.2.0
- When successfully requesting the network, return the httpcode as well
- Fix bug: Network error code httpCode returns no data
- Modify implementation of ImageFit.Auto: do not modify image height
- Modify memory cache limit and file cache limit
- Fix record decodeEndTime in imageKinfaData
- Add image buffersize in memory cache
- Optimize the magic number of heif format image files
- Fix bug: The width and height of the downsampling component are inconsistent with the image resolution unit
## 3.2.0-rc.6
- Support LogUtil to turn off log
- Support set network request readTimeout and connectTimeout through ImageKnifeOption
## 3.2.0-rc.5
- Enhance: ImageFit.Auto support adaptive height after component width change
- Fix bug: call onLoadStart 2 times(import from 3.2.0-rc.0)
- Change the initial value of the PixelMap component of ImageKnife to ImageContent EMPTY
- Clear memory cache, cancel pixel map release
- Loading process log modification
- Change the network request readTimeout to 30s
## 3.2.0-rc.4
- Support ICO format images
- Fix bug: call reload problem in onLoadFailed
- Provide default downsampling strategy to prevent slow loading for large images
## 3.2.0-rc.3
- Fix bug: PixelMap size exceeds the maximum value of memory cache and is not cached
- Dealing with exception scenarios where imageSource.getImageInfo return undefined
- Fix inability to parse Resource format images of other modules
- Improve the error logs
- Fix callback onLoadFailed when taskpool exception occurs
- ImageKnife AnimatorComponent component adds rounded corner function
## 3.2.0-rc.2
- Added callback information for image loading
- Added the interface for obtaining the upper limit and size of the current cache and the number of images corresponding to the current cache
- HTTPS custom certificate verification
- Add downsampling function to reduces memory cache consumption
## 3.2.0-rc.1
- Change the queue from Stack to Queue
- ShowPixelMap callback PixelMap assigns value to Image component to synchronize
## 3.2.0-rc.0
- Rollback the old version V1 decorator. V2 decorator will be provided in version 4.x
- The sub-thread network request is changed to asynchronous, thereby increasing the number of concurrent sub-thread network requests
- Set the concurrency through the setMaxRequests interface under the ImageKnife class
- aboutToRecycle life cycle clear image content
- Fixed bug for receive only the first onLoadStart for concurrent identical requests
- Modify the condition for determining whether to queue to be greater than or equal to maxRequests
## 3.1.1-rc.1
- Photo reduction sampling
## 3.1.1-rc.0
- 重构代码抽取ImageKnifeDispatcher子线程requestJob相关代码到ImageKnifeLoader中降低函数复杂度
## 3.1.0
- 部分静态webp图片有delay属性导致识别成动图,改用getFrameCount识别
- 修复加载错误图后未去请求排队队列中的请求
- 子线程本地Resource参数类型转换成number
- 修改使用hilog记录日志默认打开debug级别的日志
- file格式图片fd同步close
- 解码pixelMap默认不可编辑图形变化可编辑
- 修改网络请求超时设置
## 3.1.0-rc.2
- 修复宽高不等svg图片显示有毛边
## 3.1.0-rc.1
- ImageKnifeAnimatorComponent新增开始、结束、暂停的回调事件
- 文件缓存数量负数和超过INT最大值时默认为INT最大值
## 3.1.0-rc.0
- ComponentV2装饰器适配
- imageKnifeOption={...}用法改为new ImageKnifeOption({...})
- animatorOption={...}用法改为new AnimatorOption({...})
## 3.0.3
- Released version 3.0.3
## 3.0.3-rc.0
- Custom network method to add request header parameters
## 3.0.2
- Added new image reloading interface reload
- Added return request preload interface preload
- Added cancel request interface cancel
## 3.0.2-rc.2
- ImageKnifeAnimatorComponent新增开始、结束、暂停的回调事件
- 文件缓存数量负数和超过INT最大值时默认为INT最大值
- 修复宽高不等svg图片显示有毛边
- 部分静态webp图片有delay属性导致识别成动图,改用getFrameCount识别
- 修复加载错误图后未去请求排队队列中的请求
- 子线程本地Resource参数类型转换成number
- 修改使用hilog记录日志默认打开debug级别的日志
- 解码pixelMap默认不可编辑图形变化可编辑
- 修改网络请求超时设置
- 重构代码抽取ImageKnifeDispatcher子线程requestJob相关代码到ImageKnifeLoader中降低函数复杂度
## 3.0.2-rc.1
- release打包关闭混淆
## 3.0.2-rc.0
- FileUtil.readFile接口和file格式图片同步关闭fd
## 3.0.1
- 修复animatorOption属性设置初始化值失效
- 网络请求code为206、204时返回arraybuffer
- ImageKnifeComponent显示非必要文件缓存初始化
- 修复webp静态图无法设置图形变换
## 3.0.1-rc.2
- 修复自定义下载失败无失败回调
- 增加全局配置自定义下载接口
- 修复主图相同,错误图不同导致只显示一个错误图
- heic格式图片文件魔数从第五位开始匹配
## 3.0.1-rc.1
- 新增ImageKnifeAnimatorComponent控制动图组件
- 修复部分heif图无法解码
## 3.0.1-rc.0
- 文件缓存设置最大缓存数量改为无限制
## 3.0.0
- 修复图形变换的闪退问题
- 自定义下载customGetImage改为仅主图支持
- 修改网络请求requestInStream配置优先返回arraybuffer
- 新增ColorFilter属性
## 3.0.0-rc.9
- 修复Resource类型$r(变量无法)加载
- 成功回调增加图片格式
- Image组件增加onComplete回调
- 修复404链接无返回错误信息
- onLoadListener增加请求取消回调
## 3.0.0-rc.8
- svg解码单位改为px
- 修复预加载接口preLoadCache传ImageKnifeOption失效
- 文件缓存初始化接口新增目录参数
- 占位图从内存获取提前到判断队列前面
- 图片改为不可拖拽
- 修复getCacheImage默认内存获取后不返回数据
- 成功回调返回GIF图宽高
## 3.0.0-rc.7
- 修复成功回调获取不到宽高
- 新增svg图片解码
- 新增媒体图片file://格式
- 修复头像超过设备高度图片闪动问题-消息列表底部头像闪动问题
## 3.0.0-rc.6
- 支持多种组合变换
- 支持全局配置是否在子线程请求加载图片,默认在子线程
- 文件缓存初始化增加默认值
- 预加载接口新增返回加载错误信息
- 加载队列改为使用堆Stack
- fileType图片格式新增heic格式
## 3.0.0-rc.5
- 图片加载事件增加请求开始的回调,以及修复有缓存时没有回调的bug
- 修复对已销毁组件不再下发请求的逻辑
- 加载图片流程添加日志
- 子线程写入文件缓存获取buffer优化
- 成功回调增加返回图片分辨率宽高
- 内存缓存时将pixelMap进行release释放
- 提供清理缓存能力
## 3.0.0-rc.4
- 支持hsp多包图片资源
- 新增putCache写入缓存接口
- 修复入参为pixelMap图片不显示问题
- 网络请求减少拼接操作,修复网络加载速度慢
- 提供图片加载成功/失败的事件
## 3.0.0-rc.3
- 将请求默认并行从64调整到8减少对taskpool execute内存消耗
- 补充option参数placeholderObjectFiterrorholderObjectFit分别支持占位图填充效果和错误图填充效果
## 3.0.0-rc.2
- 新增支持使用一个或多个图片变换,如模糊,高亮等
## 3.0.0-rc.1
- 新增从内存或文件缓存获取图片数据接口getCacheImage
- 新增图片预加载preLoadCache并返回文件缓存路径
- ImageKnifeOption新增writeCacheStrategy存入策略(只存入内存或文件缓存)
- ImageKnifeOption新增onlyRetrieveFromCache仅用缓存加载
- 新增单个和全局请求头
- 补齐自定key特性
- 获取组件宽高改用onSizeChange 需要API12
## 3.0.0-rc.0
- 使用Image组件替换Canvas组件渲染并重构大部分的实现逻辑提升渲染性能
较2.x版本增强点
- 使用Image组件代替Canvas组件渲染
- 重构Dispatch分发逻辑支持控制并发请求数支持请求排队队列的优先级
- 支持通过initMemoryCache自定义策略内存缓存策略和大小。
- 支持option自定义实现图片获取/网络下载
- 继承Image的能力支持option传入border设置边框圆角
- 继承Image的能力支持option传入objectFit设置图片缩放
- 修复发送消息时最近的两条消息头像闪动的问题
缺失特性
- 不支持drawLifeCycle接口通过canvas自会图片
- mainScaleTypeborder等参数新版本与系统Image保持一致
- gif/webp动图播放与控制
- signature自定义key的实现
- 支持进行图片变换: 支持图像像素源图片变换效果。
- 抗锯齿相关参数
## 2.2.0-rc.2
- ImageKnife支持heic图片修改demo按钮控制组件是否展示
- ImageKnife控制可视化区域图片
## 2.2.0-rc.1
- 修改ImageKnife跳过网络,点击默认,图片没有传入宽高,无显示bug
- ImageKnife支持根据自定义key获取已缓存的图片
- ImageKnife加载图片支持自定义网络栈和图片加载组件
- 适配复用场景触发懒加载onDataReloaded
- ImageKnife控制重要图片请求加载优先级
## 2.2.0-rc.0
- 修复自定义DataFetch接口实现不生效问题
- 修改磁盘缓存到子线程
- 更新SDK到API12
@ -10,6 +250,11 @@
- imageKnife支持heic测试demo独立页面展示
- drawLifeCycle支持gif图
## 2.1.2
- 修改ImageKnife跳过网络从内存中获取图片 cacheType参数未使用bug
- 新增WEBP图片解析能力。
- 新增gif图片支持暂停播放功能
## 2.1.2-rc.12
- 新增gif播放次数功能
- 新增磁盘预加载返回文件路径接口prefetchToDiskCache

10
OAT.xml
View File

@ -27,7 +27,8 @@
<filteritem type="filename" name="hvigorw" 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="filepath" name="library/src/main/ets/components/3rd_party/.*" desc="第三方开源软件源码,不修改版权头,以防有修改版权风险"/>
<filteritem type="filename" name=".gitmodules" desc="git配置文件不添加版权头"/>
<filteritem type="filepath" name="library/src/main/ets/3rd_party/.*" desc="第三方开源软件源码,不修改版权头,以防有修改版权风险"/>
</filefilter>
<filefilter name="defaultPolicyFilter" desc="Filters for compatibilitylicense header policies">
<filteritem type="filename" name="hvigorfile.*" desc="hvigor配置文件DevEco Studio自动生成不手动修改"/>
@ -37,7 +38,8 @@
<filteritem type="filename" name="hvigorw" 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="filepath" name="library/src/main/ets/components/3rd_party/.*" desc="第三方开源软件源码,不修改版权头,以防有修改版权风险"/>
<filteritem type="filename" name=".gitmodules" desc="git配置文件不添加版权头"/>
<filteritem type="filepath" name="library/src/main/ets/3rd_party/.*" desc="第三方开源软件源码,不修改版权头,以防有修改版权风险"/>
</filefilter>
<filefilter name="binaryFileTypePolicyFilter" desc="Filters for binary file policies">
<filteritem type="filename" name="*.dpg" desc="dpg图片格式文件,用于展示示例"/>
@ -48,11 +50,11 @@
<filteritem type="filename" name="*.gif" desc="gif图片格式文件,用于展示示例"/>
<filteritem type="filename" name="*.jpg" desc="jpg图片格式文件,用于展示示例"/>
<filteritem type="filename" name="*.jpeg" desc="jpeg图片格式文件,用于展示示例"/>
<filteritem type="filename" name="*.json5" desc="hvigor配置文件"/>
<filteritem type="filename" name="*.heic" desc="heic图片格式文件,用于展示示例"/>
<filteritem type="filename" name="*.json5" desc="hvigor配置文件"/>
</filefilter>
<filefilter name="defaultFilter" desc="Files not to check">
<filteritem type="filepath" name="library/src/main/ets/components/3rd_party/.*" desc="第三方开源软件源码,不修改版权头,以防有修改版权风险"/>
<filteritem type="filepath" name="library/src/main/ets/3rd_party/.*" desc="第三方开源软件源码,不修改版权头,以防有修改版权风险"/>
</filefilter>
</filefilterlist>
</oatconfig>

913
README.md
View File

@ -1,606 +1,389 @@
## 🚨 **重要提示 | IMPORTANT**
>
> **⚠️ 此代码仓已归档。新地址请访问 [ImageKnife](https://gitcode.com/openharmony-tpc/ImageKnife)。| ⚠️ This repository has been archived. For the new address, please visit [ImageKnife](https://gitcode.com/openharmony-tpc/ImageKnife).**
>
---
>
# ImageKnife
**专门为OpenHarmony打造的一款图像加载缓存库致力于更高效、更轻便、更简单。**
ImageKnife is a specially crafted image loading and caching library for OpenHarmony, optimized for efficiency, lightness, and simplicity.
## 简介
## Introduction
本项目基于开源库 [Glide](https://github.com/bumptech/glide) 进行OpenHarmony的自研版本
This project is a self-developed version for OpenHarmony, inspired by the open-source [Glide](https://github.com/bumptech/glide) library. It sports the following features:
- 支持内存缓存使用LRUCache算法对图片数据进行内存缓存。
- 支持磁盘缓存,对于下载图片会保存一份至磁盘当中。
- 支持进行图片变换: 支持图像像素源图片变换效果。
- 支持用户配置参数使用:(
例如:配置是否开启一级内存缓存,配置磁盘缓存策略,配置仅使用缓存加载数据,配置图片变换效果,配置占位图,配置加载失败占位图等)。
- 推荐使用ImageKnifeComponent组件配合ImageKnifeOption参数来实现功能。
- 支持用户自定义配置实现能力参考ImageKnifeComponent组件中对于入参ImageKnifeOption的处理。
- Customizable memory cache strategy with adjustable cache size (default LRU)
- Disk L2 cache for downloaded images
- Custom implementation for image acquisition and network downloading
- Listening for progress of network downloads through callbacks
- Image options for borders and rounded corners
- Image scaling with **objectFit**, including auto-adapting height
- Image scaling through transformation
- Concurrent request management with priority queuing
- No requests made for images whose lifecycle has been destroyed
- Custom cache keys
- Custom HTTP request headers
- **writeCacheStrategy** for controlling cache storage (memory or file)
- Preloading images with **preLoadCache**
- Loading images exclusively from cache with **onlyRetrieveFromCache**
- Support for image transformations such as blurring and highlighting
<img src="screenshot/gif1.gif" width="50%"/>
Planned features:
## 下载安装
- Memory downsampling optimization to save memory usage
- Support for custom image decoding
Note: The 3.x version has been significantly restructured from the 2.x version, mainly in the following aspects:
- Use of the **Image** component instead of the **Canvas** component for rendering
- Refactored dispatch logic to control the number of concurrent requests and support priority in request queuing
- Support for custom memory cache strategies and sizes through **initMemoryCache**
- Support for custom implementation of image acquisition/network downloading through options
Therefore, there are some differences in APIs and capabilities, which mainly include the following:
- The **drawLifeCycle** API is not supported; images are drawn manually through the canvas.
- In the new version, parameters such as **mainScaleType** and **border** are consistent with the system **Image** component.
- GIF/WebP animation playback and control (implemented by **ImageAnimator**).
- Anti-aliasing related parameters.
## How to Install
```
ohpm install @ohos/imageknife
// If file caching is required, initialize the file cache in advance.
await ImageKnife.getInstance().initFileCache(context, 256, 256 * 1024 * 1024)
```
## 使用说明
## How to Use
### 1.依赖配置
在entry\src\main\ets\entryability\EntryAbility.ts中做如下配置初始化全局ImageKnife实例
#### 1. Displaying a Local Resource Image
```typescript
import UIAbility from '@ohos.app.ability.UIAbility';
import window from '@ohos.window';
import { ImageKnife } from '@ohos/imageknife'
export default class EntryAbility extends UIAbility {
onWindowStageCreate(windowStage: window.WindowStage) {
windowStage.loadContent('pages/Index', (err, data) => {
});
// 初始化全局ImageKnife
ImageKnife.with(this.context);
// 后续访问ImageKnife请通过:ImageKnifeGlobal.getInstance().getImageKnife()方式
```
ImageKnifeComponent({
ImageKnifeOption:{
loadSrc: $r("app.media.app_icon"),
placeholderSrc: $r("app.media.loading"),
errorholderSrc: $r("app.media.app_icon"),
objectFit: ImageFit.Auto
}
}
}).width(100).height(100)
```
### 2.加载普通图片
#### 2. Displaying a File from Local Context Files
接下来我们来写个简单实例看看:
```extendtypescript
import { ImageKnifeComponent, ImageKnifeOption } from '@ohos/imageknife'
@Entry
@Component
struct Index {
@State message: string = 'Hello World'
@State option: ImageKnifeOption = {
loadSrc: $r('app.media.icon')
```
ImageKnifeComponent({
ImageKnifeOption: {
loadSrc: this.localFile,
placeholderSrc: $r("app.media.loading"),
errorholderSrc: $r("app.media.app_icon"),
objectFit: ImageFit.Auto
}
}).width(100).height(100)
```
build() {
Row() {
Column() {
Text(this.message)
.fontSize(50)
.fontWeight(FontWeight.Bold)
ImageKnifeComponent({ imageKnifeOption: this.option })
.width(300)
.height(300)
}.width('100%')
}.height('100%')
#### 3. Displaying a Network Image
```
ImageKnifeComponent({
ImageKnifeOption: {
loadSrc:"https://www.openharmony.cn/_nuxt/img/logo.dcf95b3.png",
placeholderSrc: $r("app.media.loading"),
errorholderSrc: $r("app.media.app_icon"),
objectFit: ImageFit.Auto
}
}
}).width(100).height(100)
```
非常简单仅需定义一个ImageKnifeOption数据对象然后在你需要的UI位置加入ImageKnifeComponent自定义组件就可以加载出一张图像了。
### 3.加载SVG图片
加载svg其实和普通流程没有区别,只要将 `loadSrc: $r('app.media.jpgSample'),` `改成一张 loadSrc: $r('app.media.svgSample'),`
svg类型图片即可。
### 4.加载GIF图片
加载GIF其实和普通流程也没有区别只要将 `loadSrc: $r('app.media.jpgSample'),` `改成一张 loadSrc: $r('app.media.gifSample'),`
GIF图片即可。
#### 4.1加载GIF图片
更改ImageKnifeOption对象的autoPlay可选autoPlay = true为开始播放autoPlay = false为暂停播放
### 5.自定义Key
因为通常改变标识符比较困难或者根本不可能所以ImageKnife也提供了 签名 API 来混合(你可以控制的)额外数据到你的缓存键中。
签名(signature)适用于媒体内容,也适用于你可以自行维护的一些版本元数据。
将签名传入加载请求
```extendtypescript
imageKnifeOption = {
loadSrc: 'https://aahyhy.oss-cn-beijing.aliyuncs.com/blue.jpg',
signature: new ObjectKey(new Date().getTime().toString())
}
```
详细样例请参考SignatureTestPage文件
代码示例
### 6.自定义请求头规格
设置全局header并且设置request的header时当key不同时全局和request并行当key相同时request的header覆盖全局的header
## 进阶使用
如果简单的加载一张图像无法满足需求我们可以看看ImageKnifeOption这个类提供了哪些扩展能力。
### ImageKnifeOption参数列表
| 参数名称 | 入参内容 | 功能简介 |
| ---------------------------- |----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------|
| loadSrc | string\ | PixelMap\ |Resource | 图片数据源 |
| mainScaleType | ScaleType | 设置主图展示样式(可选) |
| strategy | DiskStrategy | 设置磁盘缓存策略(可选) |
| dontAnimateFlag | boolean | gif加载展示一帧可选 |
| placeholderSrc | PixelMap\ | Resource | 占位图数据源 |
| placeholderScaleType | ScaleType | 设置占位图展示样式(可选) |
| errorholderSrc | PixelMap\ | Resource | 错误占位图数据源 |
| errorholderSrcScaleType | ScaleType | 设置失败占位图展示样式(可选) |
| retryholderSrc | PixelMap\ | Resource | 重试占位图数据源 |
| retryholderScaleType | ScaleType | 设置重试占位图展示样式(可选) |
| thumbSizeMultiplier | number 范围(0,1] | 设置缩略图占比(可选) |
| thumbSizeDelay | number | 设置缩略图展示时间(可选) |
| thumbSizeMultiplierScaleType | ScaleType | 设置缩略图展示样式(可选) |
| displayProgress | boolean | 设置是否展示下载进度条(可选) |
| canRetryClick | boolean | 设置重试图层是否点击重试(可选) |
| onlyRetrieveFromCache | boolean | 仅使用缓存加载数据(可选) |
| isCacheable | boolean | 是否开启一级内存缓存(可选) |
| gif | {<br/> // 返回一周期动画gif消耗的时间<br/> loopFinish?: (loopTime?) => void<br/> // gif播放速率相关<br/> speedFactory?: number<br/> // 直接展示gif第几帧数据<br/> seekTo?: number<br/> playTimes?: number<br/> } | GIF播放控制能力可选 |
| transformation | BaseTransform<PixelMap> | 单个变换(可选) |
| transformations | Array<BaseTransform<PixelMap>> | 多个变换,目前仅支持单个变换(可选) |
| allCacheInfoCallback | IAllCacheInfoCallback | 输出缓存相关内容和信息(可选) |
| signature | ObjectKey | 自定key可选 |
| **drawLifeCycle** | **IDrawLifeCycle** | **用户自定义实现绘制方案(可选)** |
| imageSmoothingEnabled | boolean | 抗锯齿是否开启属性配置设置为false时imageSmoothingQuality失效 |
| imageSmoothingQuality | AntiAliasing | 抗锯齿属性配置 |
| autoPlay | boolean | GIF播放暂停控制可选 |
其他参数只需要在ImageKnifeOption对象上按需添加即可。
这里我们着重讲一下**自定义实现绘制方案**。为了增强绘制扩展能力目前ImageKnifeComponent使用了Canvas的渲染能力作为基础。在此之上为了抽象组件绘制表达。我将图像的状态使用了
**IDrawLifeCycle绘制生命周期进行表达**
大致流程 展示占位图->展示网络加载进度->展示缩略图->展示主图->展示重试图层->展示失败占位图
<img src="screenshot/png1.png" width="100%"/>
ImageKnifeComponent内部责任链实现。 用户参数设置->全局参数设置->自定义组件内部设置
采用责任链的好处是,用户可以通过自定义绘制,重新绘制图层。如果不想绘制也可以通过预制回调获取绘制流程信息。
<img src="screenshot/png2.png" width="70%"/>
### 场景1:默认的展示不满足需求,需要加个圆角效果。
代码如下:
```typescript
import { ImageKnifeComponent } from '@ohos/imageknife'
import { ImageKnifeOption } from '@ohos/imageknife'
import { ImageKnifeDrawFactory } from '@ohos/imageknife'
@Entry
@Component
struct Index {
@State imageKnifeOption1: ImageKnifeOption = {
// 加载一张本地的jpg资源必选
loadSrc: $r('app.media.jpgSample'),
// 占位图使用本地资源icon_loading可选
placeholderSrc: $r('app.media.icon_loading'),
// 失败占位图使用本地资源icon_failed可选
errorholderSrc: $r('app.media.icon_failed'),
// 绘制圆角30边框5边框"#ff00ff".用户自定义绘制(可选)
drawLifeCycle:ImageKnifeDrawFactory.createRoundLifeCycle(5,"#ff00ff",30)
};
build(){
Scroll() {
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
ImageKnifeComponent({ imageKnifeOption: this.imageKnifeOption1 })
.width(300)
.height(300)
}
}
.width('100%')
.height('100%')
}
}
```
`ImageKnifeDrawFactory.createRoundLifeCycle(5,"#ff00ff",30)`
我们深入查看源码可以发现实际上是对IDrawLifeCycle接口的部分实现这里我介绍一下IDrawLifeCycle。
*
*IDrawLifeCycle的返回值代表事件是否被消费如果被消费接下来组件内部就不会处理如果没被消费就会传递到下一个使用者。目前消费流程用户自定义->
全局配置定义->组件内部默认定义)**
所以我们在当数据是一张PixelMap的时候目前jpg png bmp webp
svg返回的都是PixelMapgif返回GIFFrame数组我们返回了true。消费了事件代表这个绘制流程用户自定义完成。
<img src="screenshot/gif2.gif" width="50%"/>
由于IDrawLifeCycle实现较为冗长我们封装了ImageKnifeDrawFactory工厂提供了网络下载百分比效果、圆角、椭圆添加边框等能力。下面我们就再看看使用工厂封装之后的场景代码。
### 场景2: 网络下载百分比效果展示
当进行加载网络图片时,可能需要展示网络下载百分比动画。但是默认的动画又不能满足需求,这个时候我们就需要自定义网络下载百分比效果。代码如下:
```typescript
import UIAbility from '@ohos.app.ability.UIAbility';
import window from '@ohos.window';
import { ImageKnifeGlobal,ImageKnife,ImageKnifeDrawFactory,LogUtil } from '@ohos/imageknife'
import abilityAccessCtrl,{Permissions} from '@ohos.abilityAccessCtrl';
export default class EntryAbility extends UIAbility {
onWindowStageCreate(windowStage: window.WindowStage) {
//.. 删除不必要代码
windowStage.loadContent('pages/index', (err, data) => {
});
// 初始化ImageKnifeGlobal和ImageKnife
ImageKnife.with(this.context);
// 全局配置网络加载进度条 使用ImageKnifeGlobal.getInstance().getImageKnife()访问ImageKnife
ImageKnifeGlobal.getInstance().getImageKnife().setDefaultLifeCycle(ImageKnifeDrawFactory.createProgressLifeCycle("#10a5ff", 0.5))
}
}
```
这里大家可能会问为什么会将这个IDrawLifeCycle放在AbilityStage里面实现
这是因为网络下载百分比进度很多时候都是全局通用如果有需要全局配置的自定义展示方案。推荐在AbilityStage里面往ImageKnife的setDefaultLifeCycle函数中注入即可将ImageKnifeComponent中的默认绘制方案替换。
在这里我们实现的效果如下图所示。
<img src="screenshot/gif3.gif" width="50%"/>
## 高级用法
以上简单使用和进阶使用都是经过一层自定义组件封装之后形成的RequestOption封装成了ImageKnifeOption,绘制部分封装成了自定义组件ImageKnifeComponent。
如果用户其实并不关心绘制部分或者说想用自己的通用方案对自定义组件ImageKnifeComponent重构都是可以的。
下面我们会着重指导用户如何复用图片加载逻辑重构自定义组件ImageKnifeComponent。
首先我们先看看RequestOption构建的内容,如下所示:
### 数据加载
#### RequestOption构建:
请查阅下文接口内容:[RequestOption接口方法](#requestoption用户配置参数)
了解了RequestOption的参数内容后我们可以参考ImageKnifeComponent组件代码进行分析。
**从`imageKnifeExecute()`函数入口首先我们需要构建一个RequestOption对象`let request = new RequestOption()`,
接下来就是按需配置request对象的内容最后使用 `ImageKnifeGlobal.getInstance().getImageKnife()?.call(request)`发送request执行任务即可。**
是不是很简单,而其实最重要的内容是就是: **按需配置request对象的内容** 为了更好理解,我举例说明一下:
#### 场景一: 简单加载一张图片
#### 4. Downloading an Image with Custom Options
```
let request = new RequestOption();
// (必传)
request.load("图片url")
// (可选 整个request监听回调)
.addListener({callback:(err:BusinessError|string, data:ImageKnifeData) => {
// data 是ImageKnifeData对象
if(data.isPixelMap()){
// 这样就获取到了目标PixelMap
let pixelmap = data.drawPixleMap.imagePixelMap;
}
return false;
})
let compSize:Size = {
width: this.currentWidth,
height:this.currentHeight
}
// (必传)这里setImageViewSize函数必传组件大小因为涉及到图片变换效果都需要适配图像源和组件大小
request.setImageViewSize(compSize)
// 最后使用ImageKnife的call函数调用request即可
let imageKnife:ImageKnife|undefined = ImageKnifeGlobal.getInstance().getImageKnife();
if(imageKnife != undefined){
imageKnife.call(request)
ImageKnifeComponent({
ImageKnifeOption: {
loadSrc: "https://file.atomgit.com/uploads/user/1704857786989_8994.jpeg",
placeholderSrc: $r("app.media.loading"),
errorholderSrc: $r("app.media.app_icon"),
objectFit: ImageFit.Auto,
customGetImage: custom
}
}).width(100).height(100)
```
**其他场景,可以按需加载**
比如我需要配置 **占位图** 只需要 在request对象创建好之后,调用 **placeholder** 函数即可
```
request.placeholder(this.imageKnifeOption.placeholderSrc, (data) => {
console.log('request.placeholder callback')
this.displayPlaceholder(data)
})
```
再比如 我对缓存配置有要求,我要禁用内存缓存,调用 **skipMemoryCache** 函数即可
```
request.skipMemoryCache(true)
```
这里只是简单介绍部分使用,更多的内容请参考 **按需加载** 原则并且可以参考ImageKnifeComponent源码或者根据文档自行探索实现。
## 接口说明
### RequestOption用户配置参数
| 方法名 | 入参 | 接口描述 |
| ------------------------------------------------------------ | ------------------------------------------------------------ | -------------------------------------------------------- |
| load(src: string \| PixelMap \|Resource) | src:string\|PixelMap\|Resource | 用户加载图片源 |
| setImageViewSize(imageSize: { width: number, height: number }) | imageSize:{width: number, height: number } | 传入显示图片组件的大小,变换的时候需要作为参考 |
| diskCacheStrategy(strategy: DiskStrategy) | strategy:DiskStrategy | 配置磁盘缓存策略 NONE SOURCE RESULT ALL AUTOMATIC |
| placeholder(src: PixelMap\|Resource, func?: AsyncSuccess<ImageKnifeData>) | src: PixelMap\|Resource, func?: AsyncSuccess<ImageKnifeData> | 占位图占位图回调数据ImageKnifeData |
| errorholder(src: PixelMap\|Resource, func?: AsyncSuccess<ImageKnifeData>) | src: PixelMap\|Resource, func?: AsyncSuccess<ImageKnifeData> | 错误占位图错误占位图回调数据ImageKnifeData |
| retryholder(src: PixelMap\|Resource, func?: AsyncSuccess<ImageKnifeData>) | src: PixelMap\|Resource, func?: AsyncSuccess<ImageKnifeData> | 重试占位图重试占位图回调数据ImageKnifeData |
| addListener(func: AsyncCallback<ImageKnifeData>) | func: AsyncCallback<ImageKnifeData> | 配置整个监听回调,数据正常加载返回,加载失败返回错误信息 |
| thumbnail(sizeMultiplier:number, func?: AsyncSuccess<ImageKnifeData>) | sizeMultiplier:number, func?: AsyncSuccess<ImageKnifeData> | 设置缩略图比例,缩略图返回后,加载并展示缩略图 |
| addProgressListener(func?: AsyncSuccess<number>) | func?: AsyncSuccess<number> | 设置网络下载百分比监听,返回数据加载百分比数值 |
| addAllCacheInfoCallback(func: IAllCacheInfoCallback) | func: IAllCacheInfoCallback | 设置获取所有缓存信息监听 |
| skipMemoryCache(skip: boolean) | skip: boolean | 配置是否跳过内存缓存 |
| retrieveDataFromCache(flag: boolean) | flag: boolean | 配置仅从缓存中加载数据 |
| signature | ObjectKey | 自定义key |
同时支持[图片变换相关](#图片变换相关)接口。
### ImageKnife 启动器/门面类
| 方法名 | 入参 | 接口描述 |
| ------------------------------- | ---------------------- | ---------------------------------- |
| call(request: RequestOption) | request: RequestOption | 根据用户配置参数具体执行加载流程 |
| preload(request: RequestOption) | request: RequestOption | 根据用户配置参数具体执行预加载流程 |
| pauseRequests() | | 全局暂停请求 |
| resumeRequests() | | 全局恢复暂停 |
| isUrlExist(url, cacheType, size)| url, CacheType, Size | 判断图片是否在 缓存和磁盘中存在,如果入参是缓存,需要传入值图片大小,参数 CacheType, Size可选|
### 缓存策略相关
| 使用方法 | 类型 | 策略描述 |
|--------------------------------------------|-----------|----------------------|
| request.diskCacheStrategy(new ALL()) | ALL | 表示既缓存原始图片,也缓存转换过后的图片 |
| request.diskCacheStrategy(new AUTOMATIC()) | AUTOMATIC | 表示尝试对本地和远程图片使用适合的策略 |
| request.diskCacheStrategy(new DATA()) | DATA | 表示只缓存原始图片 |
| request.diskCacheStrategy(new NONE()) | NONE | 表示不缓存任何内容 |
| request.diskCacheStrategy(new RESOURCE()) | RESOURCE | 表示只缓存转换过后的图片 |
### AntiAliasing类型展示效果
| 使用方法 | 类型 | 策略描述 |
|-------------------------|--------|-------------|
| AntiAliasing.FIT_HIGH | String | 图像抗锯齿设置为高画质 |
| AntiAliasing.FIT_MEDIUM | String | 图像抗锯齿设置为中画质 |
| AntiAliasing.FIT_LOW | String | 图像抗锯齿设置为低画质 |
### CacheType类型展示效果
| 使用方法 | 类型 | 策略描述 |
|-------------------------|-----|-----------------------------------|
| CacheType.Default| int | 默认值,先从内存获取,无值则从磁盘获取 |
| CacheType.Cache| int | 缓存 |
| CacheType.Disk | int | 磁盘 |
### ScaleType类型展示效果
| 使用方法 | 类型 | 策略描述 |
|-------------------------|-----|-----------------------------------|
| ScaleType.FIT_START | int | 图像位于用户设置组件左上角显示,图像会缩放至全部展示 |
| ScaleType.FIT_END | int | 图像位于用户设置组件右下角显示,图像会缩放至全部展示 |
| ScaleType.FIT_CENTER | int | 图像位于用户设置组件居中,图像会缩放至全部展示 |
| ScaleType.CENTER | int | 图像居中展示,不缩放 |
| ScaleType.CENTER_CROP | int | 图像的宽高长度,短的部分缩放至组件大小,超出的全部裁剪 |
| ScaleType.FIT_XY | int | 图像拉伸至组件大小 |
| ScaleType.CENTER_INSIDE | int | 如果图像大于组件则执行FIT_CENTER,小于组件则CENTER |
| ScaleType.NONE | int | 如果不想适配,直接展示原图大小 |
| ScaleType.AUTO_HEIGHT | int | 设置宽的时候,图片高度自适应 |
| ScaleType.AUTO_WIDTH | int | 设置高的时候,图片宽度自适应 |
| ScaleType.AUTO | int | 没有设置宽和高,图片按照自身宽高显示 |
### 图片变换相关
| 使用方法 | 类型 | 相关描述 |
|--------------------------------|------------------------------------|--------------------------------|
| request.centerCrop() | CenterCrop | 可以根据图片文件目标显示大小进行对应centerCrop |
| request.centerInside() | CenterInside | 可以根据图片文件目标显示大小进行对应centerInside |
| request.fitCenter() | FitCenter | 可以根据图片文件目标显示大小进行对应fitCenter |
| request.blur() | BlurTransformation | 模糊处理(图片分辨率较大建议传递第二个参数将图片进行缩小) |
| request.brightnessFilter() | BrightnessFilterTransformation | 亮度滤波器 |
| request.contrastFilter() | ContrastFilterTransformation | 对比度滤波器 |
| request.cropCircle() | CropCircleTransformation | 圆形剪裁显示 |
| request.cropCircleWithBorder() | CropCircleWithBorderTransformation | 圆环展示 |
| request.cropSquare() | CropSquareTransformation | 正方形剪裁 |
| request.crop() | CropTransformation | 自定义矩形剪裁 |
| request.grayscale() | GrayscaleTransformation | 灰度级转换 |
| request.invertFilter() | InvertFilterTransformation | 反转滤波器 |
| request.pixelationFilter() | PixelationFilterTransformation | 像素化滤波器 |
| request.rotateImage() | RotateImageTransformation | 图片旋转 |
| request.roundedCorners() | RoundedCornersTransformation | 圆角剪裁 |
| request.sepiaFilter() | SepiaFilterTransformation | 乌墨色滤波器 |
| request.sketchFilter() | SketchFilterTransformation | 素描滤波器 |
| request.mask() | MaskTransformation | 遮罩 |
| request.swirlFilter() | SwirlFilterTransformation | 扭曲滤波器 |
| request.kuwaharaFilter() | KuwaharaFilterTransform | 桑原滤波器 |
| request.toonFilter() | ToonFilterTransform | 动画滤波器 |
| request.vignetteFilter() | VignetteFilterTransform | 装饰滤波器 |
<img src="screenshot/gif4.gif" width="50%"/>
### 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)
}
}
// Custom implementation of the image acquisition method, such as custom network download。
@Concurrent
async function custom(context: Context, src: string | PixelMap | Resource): Promise<ArrayBuffer | undefined> {
console.info("ImageKnife:: custom download: " + src)
// Example of hardcoding to read from a local file. You can also request a network image.
return context.resourceManager.getMediaContentSync($r("app.media.bb").id).buffer as ArrayBuffer
}
```
## 约束与限制
在下述版本验证通过:
DevEco Studio 4.14.1.3.520--SDK:API11 4.1.0.63
DevEco Studio 4.14.1.3.418--SDK:API11 4.1.0.56
DevEco Studio 4.14.1.3.322--SDK:API11 4.1.0.36
DevEco Studio 4.04.0.3.700--SDK:API10 4.0.10.15
HSP场景适配:
在使用ImageKnifeComponent进行加载图片时, 提供的ImageKnifeOption配置类新增了可选参数context, 在HSP场景下需要传入正确的context, 才能保证三方库后续正确获取Resource资源。
在使用RquestOption进行加载图片时, 提供的RquestOption配置类新增了接口`setModuleContext(moduleCtx:common.UIAbilityContext)`, 在HSP场景下需要传入正确的context, 才能保证三方库后续正确获取Resource资源。
非HSP场景不影响原功能, ImageKnifeOption配置类新增的可选参数context可以不传, RquestOption配置类新增的接口可以不调用。
注意:
基于性能优化的原因2.1.2-rc.13及以后版本引用了API12 Sendable接口至此以后的版本只支持API12。
## 目录结构
#### 5. Listening for Network Download Progress
```
/library/src/
- main/ets/components
- cache # 缓存相关内容
- diskstrategy # 缓存策略
- key # 缓存key生成策略
- Base64.ets # Base64算法
- CustomMap.ets # 自定义Map封装
- DiskCacheEntry.ets # 磁盘缓存entry
- DiskLruCache.ets # 磁盘LRU缓存策略
- FileReader.ets # 文件读取相关
- FileUtils.ets # 文件工具类
- LruCache.ets # 内存LRU缓存策略
- Md5.ets # MD5算法
- imageknife # imageknife主要内容
- compress # 压缩相关
- constants # 常量相关
- entry # 部分数据结构
- holder # 占位图相关解析
- interface # 接口相关
- networkmanage # 网络相关
- pngj # pngj相关
- requestmanage # imageknife请求相关
- resourcemanage # 本地资源解析相关
- transform # 图片变换相关
- utils # 工具类相关
- ImageKnife.ets # imageknife门面app持久化类
- ImageKnifeData.ets # 数据封装
- ImageKnifeComponent.ets # 自定义控件封装
- ImageKnifeDrawFactory.ets # IDrawLifeCycle用户自定义实现
- ImageKnifeOption.ets # 用户传参数封装
- RequestOption.ets # 用户设置参数封装
/entry/src/
- main/ets
- entryability
- CustomEngineKeyImpl.ets
- EntryAbility.ts
- pages # 测试page页面列表
- basicTestFeatureAbilityPage.ets # 测试列表加载
- basicTestFileIOPage.ets # 测试fileio
- basicTestMediaImage.ets # 测试媒体image
- basicTestResourceManagerPage.ets # 测试本地资源解析
- compressPage.ets # 压缩页面
- cropImagePage2.ets # 手势裁剪页面
- frescoImageTestCasePage.ets # 测试属性动画组件切换
- frescoRetryTestCasePage.ets # 测试ImageKnifeComponent加载失败重试
- svgTestCasePage.ets # 测试svg解析页面
- imageknifeTestCaseIndex.ets # 测试用例页面入口
- index.ets # 程序入口页面
- loadNetworkTestCasePage.ets # 网络加载测试
- loadResourceTestCasePage.ets # 本地加载测试
- showErrorholderTestCasePage.ets # 加载失败占位图测试
- SignatureTestPage.ets # 自定义key测试
- storageTestDiskLruCache.ets # 磁盘缓存测试
- storageTestLruCache.ets # 内存缓存测试
- testAllCacheInfoPage.ets # 所有缓存信息获取测试
- testImageKnifeAutoHeightPage.ets # 图片高度自适应测试
- testImageKnifeAutoWidthPage.ets # 图片宽度自适应测试
- testImageKnifeAutoPage.ets # 图片宽高自适应测试
- testImageKnifeOptionChangedPage.ets # 数据切换测试
- testImageKnifeOptionChangedPage2.ets # 数据切换测试,部分变换
- testImageKnifeOptionChangedPage3.ets # 数据切换测试,组件动画
- testImageKnifeOptionChangedPage4.ets # 数据切换测试,内容动画
- testImageKnifeOptionChangedPage5.ets # 数据切换测试,ImageKnifeDrawFactory封装圆角圆环边框等
- testPreloadPage.ets # 预加载测试
- transformPixelMapPage.ets # 所有类型变换测试
- testSingleFrameGifPage.ets # 单帧gif加载测试
- TestStopPlayingGifPage # gif播放暂停测试
- OptionTestPage.ets # 图片缓存测试
- testManyGifLoadWithPage # 测试gif加载页面
- testImageKnifeCache # 测试图片是否在缓存或者磁盘中
-workers
- upngWorkerTestCase.ets # png子线程解析
- upngWorkerDepend.ts # png子线程解析具体执行
ImageKnifeComponent({
ImageKnifeOption: {
loadSrc:"https://www.openharmony.cn/_nuxt/img/logo.dcf95b3.png",
progressListener:(progress:number)=>{console.info("ImageKinfe:: call back progress = " + progress)}
}
}).width(100).height(100)
```
## 贡献代码
#### 6. Setting Border Options
使用过程中发现任何问题都可以提 [issue](https://gitee.com/openharmony-tpc/ImageKnife/issues)
给我们,当然,我们也非常欢迎你给我们发 [PR](https://gitee.com/openharmony-tpc/ImageKnife/issues) 。
```
ImageKnifeComponent({ ImageKnifeOption:
{
loadSrc: $r("app.media.rabbit"),
border: {radius:50}
}
}).width(100).height(100)
```
## 开源协议
#### 7. Setting Image Transformation Options
本项目基于 [Apache License 2.0](https://gitee.com/openharmony-tpc/ImageKnife/blob/master/LICENSE) ,请自由的享受和参与开源。
```
ImageKnifeComponent({ ImageKnifeOption:
{
loadSrc: $r("app.media.rabbit"),
border: {radius:50},
transformation: new BlurTransformation(3)
}
}).width(100).height(100)
```
Multiple combined transformation usages:
## 遗留问题
```
let transformations: collections.Array<PixelMapTransformation> = new collections.Array<PixelMapTransformation>();
transformations.push(new BlurTransformation(5));
transformations.push(new BrightnessTransformation(0.2));
ImageKnifeComponent({
imageKnifeOption: {
loadSrc: $r('app.media.pngSample'),
placeholderSrc: $r("app.media.loading"),
errorholderSrc: $r("app.media.app_icon"),
objectFit: ImageFit.Contain,
border: { radius: { topLeft: 50, bottomRight: 50 } }, // Rounded corner settings
transformation: transformations.length > 0 ? new MultiTransTransformation(transformations) : undefined // Graphic transformation group
}
}).width(300)
.height(300)
.rotate ({angle: 90}) // Rotate by 90 degrees.
.contrast(12) // Contrast filter
```
Other transformation-related properties can be stacked to achieve combined transformation effects.
1.目前只支持一种图片变换效果。
Example of circular cropping transformation:
2.目前svg和gif动图不支持变换效果。
```
ImageKnifeComponent({ ImageKnifeOption:
{
loadSrc: $r('app.media.pngSample'),
objectFit: ImageFit.Cover,
border: { radius: 150 }
}
}).width(300)
.height(300)
```
## 补充说明
### SVG标签说明
使用版本为(SVG)1.1,当前支持的标签列表有:
- a
- circla
- clipPath
- defs
- ellipse
- feBlend
- feColorMatrix
- feComposite
- feDiffuseLighting
- feDisplacementMap
- feDistantLight
- feFlood
- feGaussianBlur
- feImage
- feMorphology
- feOffset
- fePointLight
- feSpecularLighting
- feSpotLight
- feTurbulence
- filter
- g
- image
- line
- linearGradient
- mask
- path
- pattern
- polygon
- polyline
- radialGradient
- rect
- stop
- svg
- text
- textPath
- tspan
- use
Example of Circular cropping with border transformation:
```
ImageKnifeComponent({ ImageKnifeOption:
{
loadSrc: $r('app.media.pngSample'),
objectFit: ImageFit.Cover,
border: { radius: 150, color: Color.Red, width: 5 }
}
}).width(300)
.height(300)
```
Example of contrast filtering transformation:
```
ImageKnifeComponent({
imageKnifeOption: {
loadSrc: $r('app.media.pngSample')
}
}).width(300)
.height(300)
.contrast(12)
```
Example of rotation transformation:
```
ImageKnifeComponent({
imageKnifeOption:({
loadSrc: $r('app.media.pngSample')
}
}).width(300)
.height(300)
.rotate({angle:90})
.backgroundColor(Color.Pink)
```
#### 8. Listening for Image Loading Success and Failure
```
ImageKnifeComponent({ ImageKnifeOption:
{
loadSrc: $r("app.media.rabbit"),
onLoadListener:{
onLoadStart:()=>{
this.starTime = new Date().getTime()
console.info("Load start: ");
},
onLoadFailed: (err) => {
console.error("Load Failed Reason: " + err + " cost " + (new Date().getTime() - this.starTime) + " milliseconds");
},
onLoadSuccess: (data, imageData) => {
console.info("Load Successful: cost " + (new Date().getTime() - this.starTime) + " milliseconds");
return data;
},
onLoadCancel(err){
console.info(err)
}
}
}
}).width(100).height(100)
```
#### 9. Use of syncLoad
**syncLoad** sets whether to load the image synchronously. By default, the image is loaded asynchronously. When loading a small image, you are advised to set **syncLoad** to **true** so that the image loading can be quickly completed on the main thread.
```
ImageKnifeComponent({
imageKnifeOption:{
loadSrc:$r("app.media.pngSample"),
placeholderSrc:$r("app.media.loading")
},syncLoad:true
})
```
#### 10. Use of ImageKnifeAnimatorComponent
```
ImageKnifeAnimatorComponent({
imageKnifeOption:{
loadSrc:"https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658",
placeholderSrc:$r('app.media.loading'),
errorholderSrc:$r('app.media.failed')
},animatorOption:this.animatorOption
}).width(300).height(300).backgroundColor(Color.Orange).margin({top:30})
```
#### Reuse Scenario
Clear the component content in the **aboutToRecycle** lifecycle and trigger image loading through watch observeration.
## Available APIs
### ImageKnife
| Component | Parameter | Description |
| --------------------------- | -------------------------------- | ------------ |
| ImageKnifeComponent | ImageKnifeOption | Image display component.|
| ImageKnifeAnimatorComponent | ImageKnifeOption, AnimatorOption| Animated image control component.|
### AnimatorOption
| Parameter | Type | Description |
| ---------- | --------------- | ---------------------------------------- |
| state | AnimationStatus | Playback status. Optional. |
| iterations | number | Number of playback times. Optional. |
| reverse | boolean | Playback order. Optional. |
| onStart | ()=>void | Triggered when the animation starts. Optional. |
| onFinish | ()=>void | Triggered when the animation finishes or stops. Optional.|
| onPause | ()=>void | Triggered when the animation pauses. Optional. |
| onCancel | ()=>void | Triggered when the animation is canceled, that is, when it is reset to its initial state. Optional. |
| onRepeat | ()=>void | Triggered when the animation repeats. Optional. |
### ImageKnifeOption
| Parameter | Type | Description |
| --------------------- | ----------------------------------------------------- | ------------------------------ |
| loadSrc | string, PixelMap, Resource | Main image. |
| placeholderSrc | PixelMap, Resource | Placeholder image. Optional. |
| errorholderSrc | PixelMap, Resource | Error image. Optional. |
| objectFit | ImageFit | How the main image is resized to fit its container. Optional. |
| placeholderObjectFit | ImageFit | How the placeholder image is resized to fit its container. Optional. |
| errorholderObjectFit | ImageFit | How the error image is resized to fit its container. Optional. |
| writeCacheStrategy | CacheStrategyType | Cache writing strategy. Optional. |
| onlyRetrieveFromCache | boolean | Whether to skip network and local requests. Optional.|
| customGetImage | (context: Context, src: string | Custom image download. Optional. |
| border | BorderOptions | Border corner. Optional. |
| priority | taskpool.Priority | Load priority. Optional. |
| context | common.UIAbilityContext | Context. Optional. |
| progressListener | (progress: number)=>void | Progress. Optional. |
| signature | String | Custom cache signature. Optional. |
| headerOption | Array\<HeaderOptions> | Request headers. Optional. |
| transformation | PixelMapTransformation | Image transformation. Optional. |
| drawingColorFilter | ColorFilter | Drawing color filter. Optional. |
| onComplete | (event:EventImage \| undefined)=>void | Callback for image loading completion. Optional. |
| onLoadListener | onLoadStart:()=>void,onLoadSuccess:(data:string\|Pixelmap)=>void | Callback for image loading events. Optional. |
### ImageKnife
| Parameter | Type | Description |
| ----------------- | ------------------------------------------------------------ | -------------------------- |
| initMemoryCache | newMemoryCache: IMemoryCache | Initializes a custom memory cache strategy. |
| initFileCache | context: Context, size: number, memory: number | Initializes the file cache size and quantity |
| preLoadCache | loadSrc: string I ImageKnifeOption | Preloads and returns the file cache path. |
| getCacheImage | loadSrc: string, cacheType: CacheStrategy = CacheStrategy.Default, signature?: string) | Obtains resources from memory or file cache.|
| addHeader | key: string, value: Object | Adds a global HTTP request header. |
| setHeaderOptions | Array<HeaderOptions> | Sets global HTTP request headers. |
| deleteHeader | key: string | Deletes a global HTTP request header. |
| setCustomGetImage | customGetImage?: (context: Context, src: string | PixelMap |
| setEngineKeyImpl | IEngineKey | Sets a global cache key generation strategy. |
| putCacheImage | url: string, pixelMap: PixelMap, cacheType: CacheStrategy = CacheStrategy.Default, signature?: string | Writes to the memory disk cache. |
| removeMemoryCache | url: string | Removes an entry from the memory cache. |
| removeFileCache | url: string | Removes an entry from the file cache. |
### Graphics tRansformation Types (GPUImage Dependency Required)
| Type | Description |
| ------------------------ | ----------------------------- |
| BlurTransformation | Blurs the image. |
| BrightnessTransformation | Applies a brightness filter. |
| CropSquareTransformation | Crops the image to a square. |
| CropTransformation | Crops the image to a custom rectangle. |
| GrayScaleTransformation | Applies a grayscale filter. |
| InvertTransformation | Applies an inversion filter. |
| KuwaharaTransformation | Applies a Kuwahara filter (requires **GPUImage**). |
| MaskTransformation | Applies a mask. |
| PixelationTransformation | Applies a pixelation filter (requires **GPUImage**).|
| SepiaTransformation | Applies a sepia filter (requires **GPUImage**).|
| SketchTransformation | Applies a sketch filter (requires **GPUIImage**). |
| SwirlTransformation | Applies a swirl filter (requires **GPUImage**). |
| ToonTransformation | Applies a cartoon filter (requires **GPUImage**). |
| VignetterTransformation | Applies a vignette filter (requires **GPUImage**). |
## Downloading and Installing the GPUImage Dependency
Method 1: In the **Terminal** window, run the following command to install the third-party HAR. DevEco Studio will automatically add the HAR as a dependency to the **oh-package.json5** file of the project.
```
ohpm install @ohos/gpu_transform
```
Method 2: Set the third-party HAR as a dependency in the **oh-package.json5** file of the project. The following is a configuration example:
```
"dependencies": {
"@ohos/gpu_transform": "^1.0.2"
}
```
## Constraints
This project has been verified in the following version:
DevEco Studio: NEXT Beta1-5.0.3.806, SDK: API12 Release(5.0.0.66)
## About obfuscation
- Code obfuscation, please see[Code Obfuscation](https://docs.openharmony.cn/pages/v5.0/zh-cn/application-dev/arkts-utils/source-obfuscation.md)
- If you want the imageknife library not to be obfuscated during code obfuscation, you need to add corresponding exclusion rules in the obfuscation rule configuration file obfuscation-rules.txt
```
-keep
./oh_modules/@ohos/imageknife
```
## How to Contribute
If you find any problem during the use, submit an [Issue](https://gitee.com/openharmony-tpc/ImageKnife/issues) or a [PR](https://gitee.com/openharmony-tpc/ImageKnife/issues) to us.
## License
This project is licensed under [Apache License 2.0](https://gitee.com/openharmony-tpc/ImageKnife/blob/master/LICENSE).
## Known Issues
- The **ImageFit** attribute cannot be set for the **ImageKnifeAnimator** component.
- The **border** attribute of the **ImageKnifeAnimator** component cannot make the image rounded corners.

485
README_zh.md Normal file
View File

@ -0,0 +1,485 @@
## 🚨 **重要提示 | IMPORTANT**
>
> **⚠️ 此代码仓已归档。新地址请访问 [ImageKnife](https://gitcode.com/openharmony-tpc/ImageKnife)。| ⚠️ This repository has been archived. For the new address, please visit [ImageKnife](https://gitcode.com/openharmony-tpc/ImageKnife).**
>
---
>
# ImageKnife
**专门为OpenHarmony打造的一款图像加载缓存库致力于更高效、更轻便、更简单。**
## 简介
本项目参考开源库 [Glide](https://github.com/bumptech/glide) 进行OpenHarmony的自研版本
- 支持自定义内存缓存策略,支持设置内存缓存的大小(默认LRU策略)。
- 支持磁盘二级缓存,对于下载图片会保存一份至磁盘当中。
- 支持自定义实现图片获取/网络下载
- 支持监听网络下载回调进度
- 继承Image的能力支持option传入border设置边框圆角
- 继承Image的能力支持option传入objectFit设置图片缩放包括objectFit为auto时根据图片自适应高度
- 支持通过设置transform缩放图片
- 并发请求数量,支持请求排队队列的优先级
- 支持生命周期已销毁的图片,不再发起请求
- 自定义缓存key
- 自定义http网络请求头
- 支持writeCacheStrategy控制缓存的存入策略(只存入内存或文件缓存)
- 支持preLoadCache预加载图片
- 支持onlyRetrieveFromCache仅用缓存加载
- 支持使用一个或多个图片变换,如模糊,高亮等
待实现特性
- 内存降采样优化,节约内存的占用
- 支持自定义图片解码
注意3.x版本相对2.x版本做了重大的重构主要体现在
- 使用Image组件代替Canvas组件渲染
- 重构Dispatch分发逻辑支持控制并发请求数支持请求排队队列的优先级
- 支持通过initMemoryCache自定义策略内存缓存策略和大小
- 支持option自定义实现图片获取/网络下载
因此API及能力上目前有部分差异主要体现在
- 不支持drawLifeCycle接口通过canvas自会图片
- mainScaleTypeborder等参数新版本与系统Image保持一致
- gif/webp动图播放与控制(ImageAnimator实现)
- 抗锯齿相关参数
## 下载安装
```
ohpm install @ohos/imageknife
// 如果需要用文件缓存,需要提前初始化文件缓存
await ImageKnife.getInstance().initFileCache(context, 256, 256 * 1024 * 1024)
```
## 使用说明
#### 1.显示本地资源图片
```
ImageKnifeComponent({
ImageKnifeOption: {
loadSrc: $r("app.media.app_icon"),
placeholderSrc: $r("app.media.loading"),
errorholderSrc: $r("app.media.app_icon"),
objectFit: ImageFit.Auto
}
}).width(100).height(100)
```
#### 2.显示本地context files下文件
```
ImageKnifeComponent({
ImageKnifeOption: {
loadSrc: this.localFile,
placeholderSrc: $r("app.media.loading"),
errorholderSrc: $r("app.media.app_icon"),
objectFit: ImageFit.Auto
}
}).width(100).height(100)
```
#### 3.显示网络图片
```
ImageKnifeComponent({
ImageKnifeOption: {
loadSrc:"https://www.openharmony.cn/_nuxt/img/logo.dcf95b3.png",
placeholderSrc: $r("app.media.loading"),
errorholderSrc: $r("app.media.app_icon"),
objectFit: ImageFit.Auto
}
}).width(100).height(100)
```
#### 4.自定义下载图片
```
ImageKnifeComponent({
ImageKnifeOption: {
loadSrc: "https://file.atomgit.com/uploads/user/1704857786989_8994.jpeg",
placeholderSrc: $r("app.media.loading"),
errorholderSrc: $r("app.media.app_icon"),
objectFit: ImageFit.Auto,
customGetImage: custom
}
}).width(100).height(100)
// 自定义实现图片获取方法,如自定义网络下载
@Concurrent
async function custom(context: Context, src: string | PixelMap | Resource): Promise<ArrayBuffer | undefined> {
console.info("ImageKnife:: custom download" + src)
// 举例写死从本地文件读取,也可以自己请求网络图片
return context.resourceManager.getMediaContentSync($r("app.media.bb").id).buffer as ArrayBuffer
}
```
#### 5.监听网络下载进度
```
ImageKnifeComponent({
ImageKnifeOption: {
loadSrc:"https://www.openharmony.cn/_nuxt/img/logo.dcf95b3.png",
progressListener:(progress:number)=>{console.info("ImageKinfe:: call back progress = " + progress)}
}
}).width(100).height(100)
```
#### 6.支持option传入border设置边框圆角
```
ImageKnifeComponent({ ImageKnifeOption:
{
loadSrc: $r("app.media.rabbit"),
border: {radius:50}
}
}).width(100).height(100)
```
#### 7.支持option图片变换
```
ImageKnifeComponent({ ImageKnifeOption:
{
loadSrc: $r("app.media.rabbit"),
border: {radius:50},
transformation: new BlurTransformation(3)
}
}).width(100).height(100)
```
多种组合变换用法
```
let transformations: collections.Array<PixelMapTransformation> = new collections.Array<PixelMapTransformation>();
transformations.push(new BlurTransformation(5));
transformations.push(new BrightnessTransformation(0.2));
ImageKnifeComponent({
imageKnifeOption: {
loadSrc: $r('app.media.pngSample'),
placeholderSrc: $r("app.media.loading"),
errorholderSrc: $r("app.media.app_icon"),
objectFit: ImageFit.Contain,
border: { radius: { topLeft: 50, bottomRight: 50 } }, // 圆角设置
transformation: transformations.length > 0 ? new MultiTransTransformation(transformations) : undefined // 图形变换组
}
}).width(300)
.height(300)
.rotate({ angle: 90 }) // 旋转90度
.contrast(12) // 对比度滤波器
```
其它变换相关属性,可叠加实现组合变换效果
圆形裁剪变换示例
```
ImageKnifeComponent({ ImageKnifeOption:
{
loadSrc: $r('app.media.pngSample'),
objectFit: ImageFit.Cover,
border: { radius: 150 }
}
}).width(300)
.height(300)
```
圆形裁剪带边框变换示例
```
ImageKnifeComponent({ ImageKnifeOption:
{
loadSrc: $r('app.media.pngSample'),
objectFit: ImageFit.Cover,
border: { radius: 150, color: Color.Red, width: 5 }
}
}).width(300)
.height(300)
```
对比度滤波变换示例
```
ImageKnifeComponent({
imageKnifeOption: {
loadSrc: $r('app.media.pngSample')
}
}).width(300)
.height(300)
.contrast(12)
```
旋转变换示例
```
ImageKnifeComponent({
imageKnifeOption: {
loadSrc: $r('app.media.pngSample')
}
}).width(300)
.height(300)
.rotate({angle:90})
.backgroundColor(Color.Pink)
```
#### 8.监听图片加载成功与失败
```
ImageKnifeComponent({ ImageKnifeOption:
{
loadSrc: $r("app.media.rabbit"),
onLoadListener:{
onLoadStart:()=>{
this.starTime = new Date().getTime()
console.info("Load start: ");
},
onLoadFailed: (err) => {
console.error("Load Failed Reason: " + err + " cost " + (new Date().getTime() - this.starTime) + " milliseconds");
},
onLoadSuccess: (data, imageData) => {
console.info("Load Successful: cost " + (new Date().getTime() - this.starTime) + " milliseconds");
return data;
},
onLoadCancel(err){
console.info(err)
}
}
}
}).width(100).height(100)
```
#### 9.ImageKnifeComponent - syncLoad
设置是否同步加载图片默认是异步加载。建议加载尺寸较小的Resource图片时将syncLoad设为true因为耗时较短在主线程上执行即可
```
ImageKnifeComponent({
imageKnifeOption:{
loadSrc:$r("app.media.pngSample"),
placeholderSrc:$r("app.media.loading")
},syncLoad:true
})
```
#### 10.ImageKnifeAnimatorComponent 示例
```
ImageKnifeAnimatorComponent({
imageKnifeOption: {
loadSrc:"https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658",
placeholderSrc:$r('app.media.loading'),
errorholderSrc:$r('app.media.failed')
},animatorOption:this.animatorOption
}).width(300).height(300).backgroundColor(Color.Orange).margin({top:30})
```
#### 11.加载图片回调信息数据 示例
```
ImageKnifeComponent({ ImageKnifeOption: = {
loadSrc: $r('app.media.pngSample'),
objectFit: ImageFit.Contain,
onLoadListener: {
onLoadStart: (req) => {
let startCallBackData = JSON.stringify(req?.imageKnifeData);
},
onLoadFailed: (res, req) => {
let failedBackData = res + ";" + JSON.stringify(req?.imageKnifeData);
},
onLoadSuccess: (data, imageData, req) => {
let successBackData = JSON.stringify(req?.imageKnifeData);
},
onLoadCancel: (res, req) => {
let cancelBackData = res + ";" + JSON.stringify(req?.imageKnifeData);
}
},
border: { radius: 50 },
onComplete: (event) => {
if (event && event.loadingStatus == 0) {
let render_success = JSON.stringify(Date.now())
}
}
}
}).width(100).height(100)
```
#### 12.图片降采样 示例
```
ImageKnifeComponent({
imageKnifeOption:{
loadSrc:$r("app.media.pngSample"),
placeholderSrc:$r('app.media.loading'),
errorholderSrc:$r('app.media.failed'),
downsampleOf: DownsampleStrategy.NONE
}
}).width(300).height(300)
```
#### 13.rcp自定义网络请求
```
ImageKnifeComponent({
loadSrc:"http//xx.xx",
customGetImage:custom
})
// 自定义下载方法
@Concurrent
async function custom(context: Context, src: string | PixelMap | Resource,headers?: Record<string,Object>): Promise<ArrayBuffer | undefined> {
return new Promise((resolve,reject)=>{
if (typeof src == "string") {
let session = GetSession.session
let req = new rcp.Request(src,"GET");
session.fetch(req).then((response)=>{
if(response.statusCode == 200) {
let buffer = response.body
resolve(buffer)
} else {
reject("rcp code:"+response.statusCode)
}
}).catch((err:BusinessError)=>{
reject("error rcp src:"+src+",err:"+JSON.stringify(err))
})
}
})
}
```
#### 复用场景
在aboutToRecycle生命周期清空组件内容通过watch监听触发图片的加载。
## 接口说明
### ImageKnife组件
| 组件名称 | 入参内容 | 功能简介 |
|-----------------------------|---------------------------------|--------|
| ImageKnifeComponent | ImageKnifeOption | 图片显示组件 |
| ImageKnifeAnimatorComponent | ImageKnifeOption、AnimatorOption | 动图控制组件 |
### AnimatorOption参数列表
| 参数名称 | 入参内容 | 功能简介 |
|------------|-----------------|----------|
| state | AnimationStatus | 播放状态(可选) |
| iterations | number | 播放次数(可选) |
| reverse | boolean | 播放顺序(可选) |
| onStart | ()=>void | 动画开始播放时触发(可选) |
| onFinish | ()=>void | 动画播放完成时或者停止播放时触发(可选) |
| onPause | ()=>void | 动画暂停播放时触发(可选) |
| onCancel | ()=>void | 动画返回最初状态时触发(可选) |
| onRepeat | ()=>void | 动画重复播放时触发(可选) |
### ImageKnifeOption参数列表
| 参数名称 | 入参内容 | 功能简介 |
|-----------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------|
| loadSrc | string、PixelMap、Resource | 主图展示 |
| placeholderSrc | PixelMap、Resource | 占位图图展示(可选) |
| errorholderSrc | PixelMap、Resource | 错误图展示(可选) |
| objectFit | ImageFit | 主图填充效果(可选) |
| placeholderObjectFit | ImageFit | 占位图填充效果(可选) |
| errorholderObjectFit | ImageFit | 错误图填充效果(可选) |
| writeCacheStrategy | CacheStrategyType | 写入缓存策略(可选) |
| onlyRetrieveFromCache | boolean | 是否跳过网络和本地请求(可选) |
| customGetImage | customGetImage?:(context: Context, src: string、PixelMap、Resource ,headers?: Record<string, Object>) => Promise<ArrayBufferundefined> | 自定义下载图片(可选) | | Resource | 错误占位图数据源 |
| border | BorderOptions | 边框圆角(可选) |
| priority | taskpool.Priority | 加载优先级(可选) |
| context | common.UIAbilityContext | 上下文(可选) |
| progressListener | (progress: number)=>void | 进度(可选) |
| signature | String | 自定义缓存关键字(可选) |
| headerOption | Array<HeaderOptions> | 设置请求头(可选) |
| transformation | PixelMapTransformation | 图片变换(可选) |
| drawingColorFilter | ColorFilter、drawing.ColorFilter | 颜色滤镜效果(可选) |
| onComplete | (event:EventImage、undefined) => void | 图片成功回调事件(可选) |
| onLoadListener | onLoadStart?: (req?: ImageKnifeRequest) => void,onLoadSuccess?: (data: string \| PixelMap \| undefined, imageData: ImageKnifeData, req?: ImageKnifeRequest) => void,onLoadFailed?: (err: string, req?: ImageKnifeRequest) => void,onLoadCancel?: (res: string, req?: ImageKnifeRequest) => void | 监听图片加载成功与失败 |
| downsampleOf | DownsampleStrategy | 降采样(可选) |
| httpOption | HttpRequestOption | 网络请求配置(可选) |
### 降采样类型
| 类型 | 相关描述 |
|------------------------|-------------------|
| NONE | 不进行降采样 |
| AT_MOST | 请求尺寸大于实际尺寸不进行放大 |
| FIT_CENTER_MEMORY | 两边自适应内存优先 |
| FIT_CENTER_QUALITY | 两边自适应质量优先 |
| CENTER_INSIDE_MEMORY | 宽高缩放比最大的比例,进行缩放适配内存优先 |
| CENTER_INSIDE_QUALITY | 宽高缩放比最大的比例,进行缩放适配质量优先 |
| AT_LEAST | 根据宽高的最小的比例,进行适配 |
### ImageKnife接口
| 参数名称 | 入参内容 | 功能简介 |
|-------------------|---------------------------------------------------------------------------------------------------------------------------------------|------------------|
| initMemoryCache | newMemoryCache: IMemoryCache | 自定义内存缓存策略 |
| initFileCache | context: Context, size: number, memory: number | 初始化文件缓存数量和大小 |
| reload | request: ImageKnifeRequest | 图片重新加载 |
| preLoad | loadSrc: string I ImageKnifeOption | 预加载返回图片请求request |
| cancel | request: ImageKnifeRequest | 取消图片请求 |
| preLoadCache | loadSrc: string I ImageKnifeOption | 预加载并返回文件缓存路径 |
| getCacheImage | loadSrc: string, cacheType: CacheStrategy = CacheStrategy.Default, signature?: string) | 从内存或文件缓存中获取资源 |
| addHeader | key: string, value: Object | 全局添加http请求头 |
| setHeaderOptions | Array<HeaderOptions> | 全局设置http请求头 |
| deleteHeader | key: string | 全局删除http请求头 |
| setCustomGetImage | customGetImage?: (context: Context, src: string、PixelMap、Resource ,headers?: Record<string, Object>) => Promise<ArrayBufferundefined>| 全局设置自定义下载 |
| setEngineKeyImpl | IEngineKey | 全局配置缓存key生成策略 |
| putCacheImage | url: string, pixelMap: PixelMap, cacheType: CacheStrategy = CacheStrategy.Default, signature?: string | 写入内存磁盘缓存 |
| removeMemoryCache | url: string、ImageKnifeOption | 清理指定内存缓存 |
| removeFileCache | url: string、ImageKnifeOption | 清理指定磁盘缓存 |
| getCacheLimitSize | cacheType?: CacheStrategy | 获取指定缓存的上限大小 |
| getCurrentCacheNum | cacheType?: CacheStrategy | 获取指定缓存的当前缓存图片个数 |
| getCurrentCacheSize | cacheType?: CacheStrategy | 获取指定缓存的当前大小 |
| getCurrentCacheSize | cacheType?: CacheStrategy | 获取指定缓存的当前大小 |
### 回调接口说明
| 回调接口 | 回调字段 | 回调描述 |
|----------------|-------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| onLoadStart | req: ImageKnifeRequest | req返回字段中包含了图片请求的信息如图片的url及其组件的宽高同时ImageKnifeRequest包含了ImageKnifeData其中包含此次请求的开始及其检查内存缓存的时间点 |
| onLoadSuccess | data: string、PixelMap、undefined, imageData: ImageKnifeData, req?: ImageKnifeRequest | data:加载成功的结果数据imageData图片的存入缓存中的信息 req图片请求的信息同时其中的ImageKnifeData包含此次请求中图片的原始大小、图片的解码大小、格式、图片帧、请求结束时间、磁盘检查时间、网络请求开始结束、图片解码开始结束等时间点 |
| onLoadFailed | err: string, req?: ImageKnifeRequest | err:错误信息描述req图片请求的信息同时其中的ImageKnifeData包含此次请求错误信息ErrorInfoTimeInfoErrorInfo其中包含了错误阶段、错误码及其网络请求的错误码TimeInfo中包含请求结束时间、磁盘检查时间、网络请求开始结束、图片解码开始结束等时间点 |
| onLoadCancel | reason: string, req?: ImageKnifeRequest | reason:取消回调原因req图片请求的信息同时其中的ImageKnifeData包含此次请求错误信息ErrorInfoTimeInfoErrorInfo其中包含了错误阶段、错误码及其网络请求的错误码TimeInfo中包含请求结束时间、磁盘检查时间、网络请求开始结束、图片解码开始结束及其请求取消等时间点 |
### 图形变换类型需要为GPUImage添加依赖项
| 类型 | 相关描述 |
| ---------------------------------- | ----------------------------- |
| BlurTransformation | 模糊处理 |
| BrightnessTransformation | 亮度滤波器 |
| CropSquareTransformation | 正方形剪裁 |
| CropTransformation | 自定义矩形剪裁 |
| GrayScaleTransformation | 灰度级滤波器 |
| InvertTransformation | 反转滤波器 |
| KuwaharaTransformation | 桑原滤波器使用GPUIImage |
| MaskTransformation | 遮罩 |
| PixelationTransformation | 像素化滤波器使用GPUIImage |
| SepiaTransformation | 乌墨色滤波器使用GPUIImage |
| SketchTransformation | 素描滤波器使用GPUIImage |
| SwirlTransformation | 扭曲滤波器使用GPUIImage |
| ToonTransformation | 动画滤波器使用GPUIImage |
| VignetterTransformation | 装饰滤波器使用GPUIImage |
## 下载安装GPUImage依赖
方法一在Terminal窗口中执行如下命令安装三方包DevEco Studio会自动在工程的oh-package.json5中自动添加三方包依赖。
```
ohpm install @ohos/gpu_transform
```
方法二: 在工程的oh-package.json5中设置三方包依赖配置示例如下
```
"dependencies": {
"@ohos/gpu_transform": "^1.0.2"
}
```
## 约束与限制
在下述版本验证通过:
DevEco Studio: NEXT Beta1-5.0.3.806, SDK: API12 Release(5.0.0.66)
## 关于混淆
- 代码混淆,请查看[代码混淆简介](https://docs.openharmony.cn/pages/v5.0/zh-cn/application-dev/arkts-utils/source-obfuscation.md)
- 如果希望imageknife库在代码混淆过程中不会被混淆需要在混淆规则配置文件obfuscation-rules.txt中添加相应的排除规则
```
-keep
./oh_modules/@ohos/imageknife
```
## 贡献代码
使用过程中发现任何问题都可以提 [issue](https://gitee.com/openharmony-tpc/ImageKnife/issues)
,当然,也非常欢迎发 [PR](https://gitee.com/openharmony-tpc/ImageKnife/pulls) 共建。
## 开源协议
本项目基于 [Apache License 2.0](https://gitee.com/openharmony-tpc/ImageKnife/blob/master/LICENSE) ,请自由的享受和参与开源。
## 遗留问题
- ImageKnifeAnimator组件无法设置ImageFit属性

View File

@ -1,16 +1,20 @@
{
"app": {
"signingConfigs": [
],
"products": [
{
"name": "default",
"signingConfig": "default",
"compileSdkVersion": 12,
"compatibleSdkVersion": 12
"compatibleSdkVersion": 12,
"runtimeOS": "OpenHarmony"
}
],
"buildModeSet": [
{
"name": "debug"
"name": "debug",
},
{
"name": "release"
@ -49,18 +53,6 @@
]
}
]
},
{
"name": "sharedlibrary2",
"srcPath": "./sharedlibrary2",
"targets": [
{
"name": "default",
"applyToProducts": [
"default"
]
}
]
}
]
}

5
entry/.gitignore vendored
View File

@ -1,5 +1,6 @@
/node_modules
/oh_modules
/.preview
/build
/oh_modules/
/oh-package-lock.json5
/.cxx
/.test

View File

@ -1,15 +1,28 @@
{
"apiType": 'stageMode',
"apiType": "stageMode",
"buildOption": {
"sourceOption": {
"workers": [
"./src/main/ets/workers/upngWorkerTestCase.ets"
]
"arkOptions": {
// "apPath": "./modules.ap" /* Profile used for profile-guided optimization (PGO), a compiler optimization technique to improve app runtime performance. */
}
},
"buildOptionSet": [
{
"name": "release",
"arkOptions": {
"obfuscation": {
"ruleOptions": {
"enable": true,
"files": [
"./obfuscation-rules.txt"
]
}
}
}
},
],
"targets": [
{
"name": "default",
"name": "default"
},
{
"name": "ohosTest",

View File

@ -1,2 +0,0 @@
// Script for compiling build behavior. It is built in the build plug-in and cannot be modified currently.
module.exports = require('@ohos/hvigor-ohos-plugin').hapTasks

6
entry/hvigorfile.ts Normal file
View File

@ -0,0 +1,6 @@
import { hapTasks } from '@ohos/hvigor-ohos-plugin';
export default {
system: hapTasks, /* Built-in plugin of Hvigor. It cannot be modified. */
plugins:[] /* Custom plugin to extend the functionality of Hvigor. */
}

View File

@ -0,0 +1,21 @@
# Define project specific obfuscation rules here.
# You can include the obfuscation configuration files in the current module's build-profile.json5.
#
# For more details, see
# https://gitee.com/openharmony/arkcompiler_ets_frontend/blob/master/arkguard/README.md
# Obfuscation options:
# -disable-obfuscation: disable all obfuscations
# -enable-property-obfuscation: obfuscate the property names
# -enable-toplevel-obfuscation: obfuscate the names in the global scope
# -compact: remove unnecessary blank spaces and all line feeds
# -remove-log: remove all console.* statements
# -print-namecache: print the name cache that contains the mapping from the old names to new names
# -apply-namecache: reuse the given cache file
# Keep options:
# -keep-property-name: specifies property names that you want to keep
# -keep-global-name: specifies names that you want to keep in the global scope
-keep
./oh_modules/@ohos/imageknife

View File

@ -1,14 +1,13 @@
{
"license": "Apache License 2.0",
"devDependencies": {},
"name": "entry",
"description": "example description",
"repository": {},
"version": "2.1.2-rc.12",
"version": "1.0.0",
"description": "Please describe the basic information.",
"main": "",
"author": "",
"license": "",
"dependencies": {
"@ohos/libraryimageknife": "file:../sharedlibrary",
"@ohos/sharedlibrary2": "file:../sharedlibrary2",
"@ohos/disklrucache": "^2.0.2-rc.0",
"@ohos/imageknife": "file:../library"
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Huawei Device Co., Ltd.
* Copyright (C) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
@ -7,13 +7,11 @@
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* distributed under the License is distributed on an 'AS IS' BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export class Material{
material_id: string ='';
thumbnail: string = '';
name: string ='';
export default class Constants {
static readonly TAG: string = "MyImageKnifeTest: "
}

View File

@ -0,0 +1,65 @@
/*
* Copyright (C) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { IEngineKey, ImageKnifeOption, PixelMapTransformation,SparkMD5 ,ImageKnifeRequestSource,
DownsampleStrategy} from '@ohos/libraryimageknife';
//全局自定义key demo
@Sendable
export class CustomEngineKeyImpl implements IEngineKey {
// 生成内存缓存key
generateMemoryKey(loadSrc: string | PixelMap | Resource, requestSource: ImageKnifeRequestSource,
imageKnifeOption: ImageKnifeOption,isAnimator?: boolean, width?: number, height?: number): string {
let key = ""
if(imageKnifeOption.signature == "aaa" && typeof loadSrc == "string") {
let num = loadSrc.indexOf("?")
let src = loadSrc.substring(0,num)
key = "loadSrc=" + src
} else {
key = (isAnimator == true ? "Animator=" : "loadSrc==") + (typeof loadSrc == "string" ? loadSrc : JSON.stringify(loadSrc)) + ";"
}
if (requestSource === ImageKnifeRequestSource.SRC) {
if (imageKnifeOption.signature !== undefined && imageKnifeOption.signature !== "") {
key += "signature=" + imageKnifeOption.signature + ";"
}
if (imageKnifeOption.transformation) {
key += "transformation=" + this.getTransformation(imageKnifeOption.transformation) + ";"
}
if ((imageKnifeOption.downsampleOf !== DownsampleStrategy.NONE && imageKnifeOption.downsampleOf !== undefined)) {
key += "downsampleOf" + imageKnifeOption.downsampleOf + "width=" + width + "height=" + height
}
}
return key
}
// 生成文件缓存key
generateFileKey(loadSrc: string | PixelMap | Resource, signature?: string,isAnimator?: boolean): string {
let src = ""
if(signature == "aaa" && typeof loadSrc == "string") {
let num = loadSrc.indexOf("?")
let key = loadSrc.substring(0,num)
src = "loadSrc=" + key
} else {
src = (isAnimator == true ? "Animator=" : "loadSrc==") + (typeof loadSrc == "string" ? loadSrc : JSON.stringify(loadSrc)) + ";"
}
if (signature !== undefined && signature !== "") {
src += "signature=" + signature + ";"
}
return SparkMD5.hashBinary(src)
}
private getTransformation(transformation: PixelMapTransformation): string {
return transformation.getName()
}
}

View File

@ -1,13 +1,13 @@
/*
* Copyright (C) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* distributed under the License is distributed on an 'AS IS' BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
@ -20,7 +20,7 @@ export class GlobalContext {
private static instance: GlobalContext;
private _objects = new Map<string, Object>();
public static getInstance(): GlobalContext {
public static getContext(): GlobalContext {
if (!GlobalContext.instance) {
GlobalContext.instance = new GlobalContext();
}

View File

@ -1,76 +0,0 @@
/*
* Copyright (C) 2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { EngineKeyFactories, EngineKeyInterface, RequestOption } from '@ohos/libraryimageknife'
import { ObjectKey } from '@ohos/libraryimageknife';
export class CustomEngineKeyImpl implements EngineKeyInterface {
redefineUrl: (loadSrc: string) => string;
addOtherInfo: string = "Version=1.0.0;"
constructor() {
this.redefineUrl = this.urlNeedClearToken;
}
// request只读
generateMemoryCacheKey(loadSrc: string, size: string, transformed: string, dontAnimate: boolean, signature: ObjectKey): string {
return EngineKeyFactories.createMemoryCacheKey(loadSrc, size, transformed, dontAnimate, signature, this.redefineUrl, this.addOtherInfo);
}
generateTransformedDiskCacheKey(loadSrc: string, size: string, transformed: string, dontAnimate: boolean, signature: ObjectKey): string {
return EngineKeyFactories.createTransformedDiskCacheKey(loadSrc, size, transformed, dontAnimate, signature, this.redefineUrl, this.addOtherInfo);
}
generateOriginalDiskCacheKey(loadSrc: string, signature: ObjectKey): string {
return EngineKeyFactories.createOriginalDiskCacheKey(loadSrc, signature, this.redefineUrl, this.addOtherInfo);
}
// 需求场景: 请求图片可能 请求中存在token需要清除 可以把输入的url清除token后作为key的一部分这样token发生变化也能命中缓存。
urlNeedClearToken = (url: string) => {
if (this.isHttpRequest(url)) {
return this.clearToken(url)
} else {
return url;
}
}
isHttpRequest(loadSrc: string) {
if (typeof loadSrc == "string" && loadSrc.toLowerCase().startsWith("http")) {
return true;
}
return false;
}
// 清除url里面中携带的token
clearToken(url: string): string {
let retUrl = url.replace(this.findTokenParam(url), "")
return retUrl;
}
// 网络图片加载 可能因为Token问题导致缓存失效
findTokenParam(url: string): string {
let tokenParam = "";
let tokenKeyIndex = url.indexOf("?token=") >= 0 ? url.indexOf("?token=") : url.indexOf("&token=");
if (tokenKeyIndex != -1) {
let nextAndIndex = url.indexOf("&", tokenKeyIndex + 1);
if (nextAndIndex != -1) {
tokenParam = url.substring(tokenKeyIndex + 1, nextAndIndex + 1);
} else {
tokenParam = url.substring(tokenKeyIndex);
}
}
return tokenParam;
}
}

View File

@ -1,59 +1,80 @@
/*
* Copyright (C) 2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* Copyright (C) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* distributed under the License is distributed on an 'AS IS' BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import UIAbility from '@ohos.app.ability.UIAbility';
import AbilityConstant from '@ohos.app.ability.AbilityConstant';
import hilog from '@ohos.hilog';
import UIAbility from '@ohos.app.ability.UIAbility';
import Want from '@ohos.app.ability.Want';
import window from '@ohos.window';
import { InitImageKnife, ImageKnifeGlobal, ImageKnife, ImageKnifeDrawFactory, LogUtil } from '@ohos/libraryimageknife'
import { CustomEngineKeyImpl } from './CustomEngineKeyImpl'
import { ImageKnife, InitImageKnife } from '@ohos/libraryimageknife';
import { CustomEngineKeyImpl } from '../common/CustomEngineKeyImpl';
import abilityAccessCtrl, { Permissions } from '@ohos.abilityAccessCtrl';
import { BusinessError } from '@ohos.base'
export default class EntryAbility extends UIAbility {
onWindowStageCreate(windowStage: window.WindowStage) {
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate');
}
onDestroy(): void {
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onDestroy');
}
async onWindowStageCreate(windowStage: window.WindowStage): Promise<void> {
// Main window is created, set main page for this ability
let list: Array<Permissions> = ['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) {
// let list: Array<Permissions> = ['ohos.permission.READ_IMAGEVIDEO', 'ohos.permission.WRITE_IMAGEVIDEO'];
// let permissionRequestResult: Object;
// let atManager = abilityAccessCtrl.createAtManager();
// atManager.requestPermissionsFromUser(this.context, list, (err: BusinessError, result: Object) => {
// if (err) {
//
// } else {
// permissionRequestResult = result;
//
// }
// })
} else {
permissionRequestResult = result;
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate');
// 初始化ImageKnife的文件缓存
await InitImageKnife.init(this.context)
ImageKnife.getInstance().setEngineKeyImpl(new CustomEngineKeyImpl())
// 全局配置请求头
ImageKnife.getInstance().addHeader('refer', "http://1.94.37.200:7070/AntiTheftChain/downloadImage");
ImageKnife.getInstance().deleteHeader('refer');
windowStage.loadContent('pages/Index', (err, data) => {
if (err.code) {
hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? '');
return;
}
})
windowStage.loadContent('pages/index', (err: BusinessError, data: void) => {
hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. Data: %{public}s', JSON.stringify(data) ?? '');
});
}
InitImageKnife.init(this.context);
onWindowStageDestroy(): void {
// Main window is destroyed, release UI related resources
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageDestroy');
}
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.addHeader('refer', "http://1.94.37.200:7070/AntiTheftChain/downloadImage");
imageKnife.deleteHeader('refer');
}
// 开启ImageKnife所有级别日志开关
LogUtil.mLogLevel = LogUtil.ALL
onForeground(): void {
// Ability has brought to foreground
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onForeground');
}
onBackground(): void {
// Ability has back to background
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onBackground');
}
}

View File

@ -0,0 +1,58 @@
/*
* Copyright (C) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an 'AS IS' BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { ImageKnifeComponent } from '@ohos/libraryimageknife';
import { display } from '@kit.ArkUI';
@Entry
@Component
struct AutoImageFit {
@State imageWidth: number = 200;
private maxWidth: number = px2vp(display.getDefaultDisplaySync().width);
build() {
Column() {
this.Slider()
Column() {
Text('Image')
Image('https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/56/v3/8MdhfSsCSMKj4sA6okUWrg/5uBx56tLTUO3RYQl-E5JiQ.jpg')
.width('100%')
.objectFit(ImageFit.Auto)
Text('ImageKnife')
ImageKnifeComponent({
imageKnifeOption: {
loadSrc: 'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/56/v3/8MdhfSsCSMKj4sA6okUWrg/5uBx56tLTUO3RYQl-E5JiQ.jpg',
objectFit: ImageFit.Auto,
}
}).width('100%')
}.width(this.imageWidth).border({ width: 1 })
}
}
@Builder
Slider() {
Slider({
value: this.imageWidth,
min: 100,
max: this.maxWidth,
style: SliderStyle.OutSet
})
.blockColor(Color.White)
.width('100%')
.onChange((value: number) => {
this.imageWidth = value;
})
}
}

View File

@ -1,104 +0,0 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {
ImageKnifeComponent,
ImageKnifeOption,
RotateImageTransformation,
RoundedCornersTransformation
} from '@ohos/libraryimageknife'
@Entry
@Component
struct CacheRuleChangedPage {
@State progresshint: string = "输出加载百分比回调信息"
@State imageKnifeOption1: ImageKnifeOption =
{
loadSrc: "https://thirdwx.qlogo.cn/mmopen/vi_32/DYAIOgq83ericA1Mv66TwicuYOtbDMBcUhv1aa9RJBeAn9uURfcZD0AUGrJebAn1g2AjN0vb2E1XTET7fTuLBNmA/132",
placeholderSrc: $r('app.media.icon_loading'),
errorholderSrc: $r('app.media.icon_failed'),
displayProgress: true
};
@State ImageKnifeOption: ImageKnifeOption =
{
loadSrc: "https://hbimg.huabanimg.com/0ef60041445edcfd6b38d20e19024b2cd9281dcc3525a4-Vy8fYO_fw658/format/webp",
placeholderSrc: $r('app.media.icon_loading'),
errorholderSrc: $r('app.media.icon_failed'),
displayProgress: true
};
@State imageKnifeOption3: ImageKnifeOption =
{
loadSrc: "https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp",
placeholderSrc: $r('app.media.icon_loading'),
errorholderSrc: $r('app.media.icon_failed'),
displayProgress: true
};
@State imageKnifeOption4: ImageKnifeOption =
{
loadSrc: "https://hbimg.huabanimg.com/cc6af25f8d782d3cf3122bef4e61571378271145735e9-vEVggB",
placeholderSrc: $r('app.media.icon_loading'),
errorholderSrc: $r('app.media.icon_failed'),
displayProgress: true,
};
@State imageKnifeOption5: ImageKnifeOption =
{
loadSrc: "https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp?mama=sdafsfasdfsdfsdaf&baba=sdfsafsafsd",
placeholderSrc: $r('app.media.icon_loading'),
errorholderSrc: $r('app.media.icon_failed'),
displayProgress: true,
};
build() {
Scroll() {
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Text('下图默认加载网络图片不带?token=').margin({ top: 20 })
Button('点击加载网络图片?token=').margin({ top: 5 }).onClick(() => {
this.imageKnifeOption4 = {
loadSrc: "https://hbimg.huabanimg.com/cc6af25f8d782d3cf3122bef4e61571378271145735e9-vEVggB?token=fsdafsfsafsafsdaf111111",
placeholderSrc: $r('app.media.icon_loading'),
errorholderSrc: $r('app.media.icon_failed'),
displayProgress: true,
}
})
ImageKnifeComponent({ imageKnifeOption: this.imageKnifeOption4 })
.width(300)
.height(300)
Text('下图默认加载网络图片不带&token=').margin({ top: 20 })
Button('点击加载网络图片&token=').margin({ top: 5 }).onClick(() => {
this.imageKnifeOption5 = {
loadSrc: "https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp?mama=sdafsfasdfsdfsdaf&token=fsdafsfsafsafsdaf111111&baba=sdfsafsafsd",
placeholderSrc: $r('app.media.icon_loading'),
errorholderSrc: $r('app.media.icon_failed'),
displayProgress: true,
}
})
ImageKnifeComponent({ imageKnifeOption: this.imageKnifeOption5 })
.width(300)
.height(300)
}
}
.width('100%')
.height('100%')
}
}

View File

@ -0,0 +1,220 @@
/*
* Copyright (C) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an 'AS IS' BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { DownsampleStrategy, ImageKnifeOption, } from '@ohos/imageknife';
import { ImageKnifeComponent } from '@ohos/libraryimageknife';
import { image } from '@kit.ImageKit';
import { BusinessError } from '@kit.BasicServicesKit';
import { Downsampler } from '@ohos/imageknife/src/main/ets/downsampling/Downsampler';
import { FileTypeUtil } from '@ohos/imageknife/src/main/ets/utils/FileTypeUtil';
@Entry
@Component
struct DownSamplePage {
@State imageKnifeOption: ImageKnifeOption = {
loadSrc: $r('app.media.startIcon'),
placeholderSrc: $r('app.media.loading'),
errorholderSrc: $r('app.media.app_icon'),
objectFit: ImageFit.Contain
}
isBrightness: boolean = false
@State beforeSampling: number = 0
@State afterSampling: number = 0
@State SamplingList: SamplingType[] = [
new SamplingType(7, 'AT_LEAST'),
new SamplingType(1, 'AT_MOST'),
new SamplingType(2, 'FIT_CENTER_MEMORY'),
new SamplingType(4, 'FIT_CENTER_QUALITY'),
new SamplingType(5, 'CENTER_INSIDE_MEMORY'),
new SamplingType(6, 'CENTER_INSIDE_QUALITY'),
new SamplingType(0, 'NONE'),
]
@State checked: boolean = false
updateImageKnifeOption(value: string) {
if (value === 'NONE') {
this.imageKnifeOption = {
loadSrc: $r('app.media.pngSample'),
placeholderSrc: $r('app.media.loading'),
errorholderSrc: $r('app.media.app_icon'),
objectFit: ImageFit.Contain,
downsampleOf: DownsampleStrategy.NONE
}
this.originalPixMap($r('app.media.pngSample'))
this.afterSamplingFunc($r('app.media.pngSample'))
} else if (value === 'AT_MOST') {
this.imageKnifeOption = {
loadSrc: $r('app.media.pngSample'),
placeholderSrc: $r('app.media.loading'),
errorholderSrc: $r('app.media.app_icon'),
objectFit: ImageFit.Contain,
downsampleOf: DownsampleStrategy.AT_MOST
}
this.originalPixMap($r('app.media.pngSample'))
this.afterSamplingFunc($r('app.media.pngSample'))
} else if (value === 'FIT_CENTER_MEMORY') {
this.imageKnifeOption = {
loadSrc: $r('app.media.pngSample'),
placeholderSrc: $r('app.media.loading'),
errorholderSrc: $r('app.media.app_icon'),
objectFit: ImageFit.Contain,
downsampleOf: DownsampleStrategy.FIT_CENTER_MEMORY
}
this.originalPixMap($r('app.media.pngSample'))
this.afterSamplingFunc($r('app.media.pngSample'))
} else if (value === 'FIT_CENTER_QUALITY') {
this.imageKnifeOption = {
loadSrc: $r('app.media.pngSample'),
placeholderSrc: $r('app.media.loading'),
errorholderSrc: $r('app.media.app_icon'),
objectFit: ImageFit.Contain,
downsampleOf: DownsampleStrategy.FIT_CENTER_QUALITY
}
this.originalPixMap($r('app.media.pngSample'))
this.afterSamplingFunc($r('app.media.pngSample'))
} else if (value === 'CENTER_INSIDE_MEMORY') {
this.imageKnifeOption = {
loadSrc: $r('app.media.pngSample'),
placeholderSrc: $r('app.media.loading'),
errorholderSrc: $r('app.media.app_icon'),
objectFit: ImageFit.Contain,
downsampleOf: DownsampleStrategy.CENTER_INSIDE_MEMORY
}
this.originalPixMap($r('app.media.pngSample'))
this.afterSamplingFunc($r('app.media.pngSample'))
} else if (value === 'CENTER_INSIDE_QUALITY') {
this.imageKnifeOption = {
loadSrc: $r('app.media.pngSample'),
placeholderSrc: $r('app.media.loading'),
errorholderSrc: $r('app.media.app_icon'),
objectFit: ImageFit.Contain,
downsampleOf: DownsampleStrategy.CENTER_INSIDE_QUALITY
}
this.originalPixMap($r('app.media.pngSample'))
this.afterSamplingFunc($r('app.media.pngSample'))
} else {
this.imageKnifeOption = {
loadSrc: $r('app.media.pngSample'),
placeholderSrc: $r('app.media.loading'),
errorholderSrc: $r('app.media.app_icon'),
objectFit: ImageFit.Contain,
downsampleOf: DownsampleStrategy.AT_LEAST
}
this.originalPixMap($r('app.media.pngSample'))
this.afterSamplingFunc($r('app.media.pngSample'))
}
}
async afterSamplingFunc(imgs: Resource) {
let img: Uint8Array = await getContext(this).resourceManager.getMediaContent(imgs);
let imageSource: image.ImageSource = image.createImageSource(img.buffer.slice(0));
let fileTypeUtil = new FileTypeUtil();
let typeValue = fileTypeUtil.getFileType(img.buffer.slice(0)) as string;
let decodingOptions: image.DecodingOptions = {
editable: true,
desiredPixelFormat: 3,
}
let imageInfo = await imageSource.getImageInfo()
if (this.imageKnifeOption.downsampleOf !== DownsampleStrategy.NONE && this.imageKnifeOption.downsampleOf != undefined ) {
let reqSize =
new Downsampler().calculateScaling(typeValue, imageInfo.size.width, imageInfo.size.height, 300,
300, this.imageKnifeOption.downsampleOf)
decodingOptions = {
editable: true,
desiredSize: {
width: reqSize.width,
height: reqSize.height
}
}
}
// 创建pixelMap
imageSource.createPixelMap(decodingOptions).then((pixelMap: image.PixelMap) => {
imageSource.release()
this.afterSampling = pixelMap.getPixelBytesNumber()
pixelMap.release()
}).catch((err: BusinessError) => {
imageSource.release()
console.error('Failed to create PixelMap')
});
}
async originalPixMap(imgs: Resource,) {
let img: Uint8Array = await getContext(this).resourceManager.getMediaContent(imgs);
let imageSource: image.ImageSource = image.createImageSource(img.buffer.slice(0));
let decodingOptions: image.DecodingOptions = {
editable: true,
desiredPixelFormat: 3,
}
// 创建pixelMap
imageSource.createPixelMap(decodingOptions).then((pixelMap: image.PixelMap) => {
imageSource.release()
this.beforeSampling = pixelMap.getPixelBytesNumber()
pixelMap.release()
}).catch((err: BusinessError) => {
imageSource.release()
console.error('Failed to create PixelMap')
});
}
getResourceString(res:Resource){
return getContext().resourceManager.getStringSync(res.id)
}
build() {
Scroll() {
Column() {
ForEach(this.SamplingList, (item: SamplingType, index) => {
Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
Radio({ value: item.value + 'radio', group: 'radioGroup' })
.height(50)
.width(50)
.checked(this.checked)
.onClick(() => {
this.updateImageKnifeOption(item.value)
})
Text(this.getResourceString($r('app.string.Sampling_pecification'))+ item.value).fontSize(20)
}
}, (item: SamplingType) => JSON.stringify(item))
Column() {
Text(`${this.getResourceString($r('app.string.Unreal_samples'))}${this.beforeSampling}`).fontSize(20)
Text(`${ this.getResourceString($r('app.string.After_the_sampling'))}${this.afterSampling}`).fontSize(20)
}
ImageKnifeComponent({
imageKnifeOption: this.imageKnifeOption
})
.height(px2vp(300))
.width(px2vp(300))
.borderWidth(1)
.borderColor(Color.Pink)
}
}
.height('100%')
.width('100%')
}
}
class SamplingType {
key: number
value: string
constructor(key: number, value: string) {
this.key = key
this.value = value
}
}

View File

@ -0,0 +1,93 @@
/*
* Copyright (C) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an 'AS IS' BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { ImageKnifeComponent } from '@ohos/libraryimageknife'
@Entry
@Component
struct ErrorMessageDownload {
@State httpCode: string = ''
@State httpError: string = ''
@State storageError: string = ''
@State fileError: string = ''
@State notPic: string = ''
build() {
Column() {
Text(this.httpCode)
ImageKnifeComponent({
imageKnifeOption:{
loadSrc:'https://gitee.com/openharmony-tpc/ImageKnife/issues/1111111',
errorholderSrc:$r('app.media.failed'),
onLoadListener:{
onLoadFailed:(err)=>{
this.httpCode = err
}
}
}
}).width(100).height(100).margin({bottom:10})
Text(this.httpError)
ImageKnifeComponent({
imageKnifeOption:{
loadSrc:'https://xx.xx.xx',
errorholderSrc:$r('app.media.failed'),
onLoadListener:{
onLoadFailed:(err)=>{
this.httpError = err
}
}
}
}).width(100).height(100).margin({bottom:10})
Text(this.storageError)
ImageKnifeComponent({
imageKnifeOption:{
loadSrc:'/data/storage/el2/base/haps/entry/cache/a/b',
errorholderSrc:$r('app.media.failed'),
onLoadListener:{
onLoadFailed:(err)=>{
this.storageError = err
}
}
}
}).width(100).height(100).margin({bottom:10})
Text(this.fileError)
ImageKnifeComponent({
imageKnifeOption:{
loadSrc:'file://xx.xx.xx',
errorholderSrc:$r('app.media.failed'),
onLoadListener:{
onLoadFailed:(err)=>{
this.fileError = err
}
}
}
}).width(100).height(100).margin({bottom:10})
Text(this.notPic)
ImageKnifeComponent({
imageKnifeOption:{
loadSrc:'xx.xx.xx',
errorholderSrc:$r('app.media.failed'),
onLoadListener:{
onLoadFailed:(err)=>{
this.notPic = err
}
}
}
}).width(100).height(100).margin({bottom:10})
}
}
}

View File

@ -0,0 +1,102 @@
/*
* Copyright (C) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an 'AS IS' BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { AnimatorOption, ImageKnifeAnimatorComponent, ImageKnifeOption } from '@ohos/libraryimageknife'
@Entry
@Component
struct ImageAnimatorPage {
@State animatorOption: AnimatorOption = {
state: AnimationStatus.Running,
iterations: -1,
onFinish: () => {
console.log('ImageKnifeAnimatorComponent animatorOption onFinish')
},
onStart: () => {
console.log('ImageKnifeAnimatorComponent animatorOption onStart')
},
onPause: () => {
console.log('ImageKnifeAnimatorComponent animatorOption onPause')
},
onCancel: () => {
console.log('ImageKnifeAnimatorComponent animatorOption onCancel')
},
onRepeat: () => {
console.log('ImageKnifeAnimatorComponent animatorOption onRepeat')
}
}
@State animatorOptionFirstFrame: AnimatorOption = {
state: AnimationStatus.Initial
}
@State animatorOptionLastFrame: AnimatorOption = {
state: AnimationStatus.Initial,
reverse: true
}
@State imageKnifeOption: ImageKnifeOption = {
loadSrc: 'https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658',
placeholderSrc: $r('app.media.loading'),
errorholderSrc: $r('app.media.failed')
}
build() {
Column() {
Row() {
Button($r('app.string.Play')).onClick(() => {
this.animatorOption.state = AnimationStatus.Running
})
Button($r('app.string.Pause')).onClick(() => {
this.animatorOption.state = AnimationStatus.Paused
})
Button($r('app.string.Stop')).onClick(() => {
this.animatorOption.state = AnimationStatus.Stopped
})
}
Row() {
Button($r('app.string.Infinite_loop')).onClick(() => {
this.animatorOption.iterations = -1
})
Button($r('app.string.Play_once')).onClick(() => {
this.animatorOption.iterations = 1
})
Button($r('app.string.Play_twice')).onClick(() => {
this.animatorOption.iterations = 2
})
}
ImageKnifeAnimatorComponent({
imageKnifeOption: this.imageKnifeOption,
animatorOption: this.animatorOption
}).width(300).height(300).backgroundColor(Color.Orange).margin({ top: 30 })
Row({ space: 10 }) {
Column() {
Text($r('app.string.Display_the_first_frame')).fontSize(20)
ImageKnifeAnimatorComponent({
imageKnifeOption: this.imageKnifeOption,
animatorOption: this.animatorOptionFirstFrame
}).width(120).height(120).backgroundColor(Color.Orange)
}
Column() {
Text($r('app.string.Display_the_last_frame')).fontSize(20)
ImageKnifeAnimatorComponent({
imageKnifeOption: this.imageKnifeOption,
animatorOption: this.animatorOptionLastFrame
}).width(120).height(120).backgroundColor(Color.Orange)
}
}.margin({ top: 50 }).padding(10)
}.width('100%').height('100%')
}
}

View File

@ -0,0 +1,99 @@
/*
* Copyright (C) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an 'AS IS' BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { connection } from '@kit.NetworkKit'
import { List } from '@kit.ArkTS'
import { ImageKnifeRequest,ImageKnife,ImageKnifeComponent } from '@ohos/libraryimageknife'
@Entry
@Component
struct ImageKnifeReload {
@State index: number = 0
aboutToAppear(): void {
NetWatchState.init()
}
build() {
Column() {
ImageKnifeComponent({
imageKnifeOption:{
loadSrc:'https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp',
placeholderSrc:$r('app.media.loading'),
errorholderSrc:$r('app.media.failed'),
onLoadListener:{
onLoadFailed(err,request){
NetWatchState.requestList.add(request)
}
}
}
}).width(200).height(200)
ImageKnifeComponent({
imageKnifeOption:{
loadSrc:'https://img-blog.csdn.net/20140514114029140',
placeholderSrc:$r('app.media.loading'),
errorholderSrc:$r('app.media.failed'),
onLoadListener:{
onLoadFailed(err,request){
NetWatchState.requestList.add(request)
}
}
}
}).width(200).height(200).margin({top:10})
Text("重试5次" + this.index)
ImageKnifeComponent({
imageKnifeOption:{
loadSrc:'https://img-blog.csdn.net/20140514114029140',
placeholderSrc:$r('app.media.loading'),
errorholderSrc:$r('app.media.failed'),
onLoadListener:{
onLoadFailed:(err,request) => {
this.index++
if(request != undefined && this.index < 5) {
ImageKnife.getInstance().reload(request)
}
}
}
}
}).width(200).height(200).margin({top:10})
}.width('100%')
.height('100%')
}
}
class NetWatchState {
public static netConnection: connection.NetConnection | undefined = undefined
public static requestList: List<ImageKnifeRequest> = new List()
static init() {
NetWatchState.netConnection = connection.createNetConnection()
// 注册订阅事件
NetWatchState.netConnection.register(()=>{
})
// 订阅网络能力变化事件。调用register后才能接收到此事件通知
NetWatchState.netConnection.on('netCapabilitiesChange',(data:connection.NetCapabilityInfo)=>{
if(NetWatchState.requestList.length > 0 && data.netHandle.netId >= 100) {
NetWatchState.requestList.forEach((request)=>{
ImageKnife.getInstance().reload(request)
NetWatchState.requestList.remove(request)
})
}
})
}
static cancel(){
if(NetWatchState.netConnection != undefined) {
// 取消订阅
NetWatchState.netConnection.unregister(()=>{})
}
}
}

View File

@ -0,0 +1,432 @@
/*
* Copyright (C) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an 'AS IS' BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {
BlurTransformation,
BrightnessTransformation,
CropSquareTransformation,
CropTransformation,
GrayScaleTransformation,
ImageKnifeComponent,
ImageKnifeOption,
InvertTransformation,
KuwaharaTransformation,
MaskTransformation,
MultiTransTransformation,
PixelationTransformation,
PixelMapTransformation,
SepiaTransformation,
SketchTransformation,
SwirlTransformation,
ToonTransformation,
VignetterTransformation
} from '@ohos/libraryimageknife';
import { collections } from '@kit.ArkTS'
@Entry
@Component
struct ImageTransformation {
@State imageKnifeOption: ImageKnifeOption = {
loadSrc: $r('app.media.pngSample'),
placeholderSrc: $r('app.media.loading'),
errorholderSrc: $r('app.media.app_icon'),
objectFit: ImageFit.Contain
}
@State isRound: boolean = false;
@State isContrast: boolean = false;
@State isRotate: boolean = false;
isBlur: boolean = false
isBrightness: boolean = false
isGrayScale: boolean = false;
isInvert: boolean = false;
isToon: boolean = false;
isCropCircle: boolean = false;
isCropCircleWithBorder: boolean = false;
isKuwahara: boolean = false;
isPixelation: boolean = false;
isSketch: boolean = false;
isSwirl: boolean = false;
isVignetter: boolean = false;
isCropSquare: boolean = false;
isCropTop: boolean = false;
isCropCenter: boolean = false;
isCropBottom: boolean = false;
isMask: boolean = false;
isSepia: boolean = false;
build() {
Scroll() {
Column() {
Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
Checkbox({ name: 'checkbox1', group: 'checkboxGroup' })
.selectedColor(0x39a2db)
.shape(CheckBoxShape.ROUNDED_SQUARE)
.onChange((value: boolean) => {
this.isBlur = value;
this.updateImageKnifeOption();
})
.width(30)
.height(30)
Text($r('app.string.Blur_effect')).fontSize(20)
}
Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
Checkbox({ name: 'checkbox2', group: 'checkboxGroup' })
.selectedColor(0x39a2db)
.shape(CheckBoxShape.ROUNDED_SQUARE)
.onChange((value: boolean) => {
this.isBrightness = value;
this.updateImageKnifeOption();
})
.width(30)
.height(30)
Text($r('app.string.Highlighting_effect')).fontSize(20)
}
Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
Checkbox({ name: 'checkbox3', group: 'checkboxGroup' })
.selectedColor(0x39a2db)
.shape(CheckBoxShape.ROUNDED_SQUARE)
.onChange((value: boolean) => {
this.isGrayScale = value;
this.updateImageKnifeOption();
})
.width(30)
.height(30)
Text($r('app.string.Ashing_effect')).fontSize(20)
}
Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
Checkbox({ name: 'checkbox4', group: 'checkboxGroup' })
.selectedColor(0x39a2db)
.shape(CheckBoxShape.ROUNDED_SQUARE)
.onChange((value: boolean) => {
this.isInvert = value;
this.updateImageKnifeOption();
})
.width(30)
.height(30)
Text($r('app.string.Inverse_effect')).fontSize(20)
}
Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
Checkbox({ name: 'checkbox5', group: 'checkboxGroup' })
.selectedColor(0x39a2db)
.shape(CheckBoxShape.ROUNDED_SQUARE)
.onChange((value: boolean) => {
this.isToon = value;
this.updateImageKnifeOption();
})
.width(30)
.height(30)
Text($r('app.string.Animation_filter_effect')).fontSize(20)
}
Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
Checkbox({ name: 'checkbox6', group: 'checkboxGroup' })
.selectedColor(0x39a2db)
.shape(CheckBoxShape.ROUNDED_SQUARE)
.onChange((value: boolean) => {
this.isCropCircle = value;
this.updateImageKnifeOption();
})
.width(30)
.height(30)
Text($r('app.string.Crop_circular_effect')).fontSize(20)
}
Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
Checkbox({ name: 'checkbox7', group: 'checkboxGroup' })
.selectedColor(0x39a2db)
.shape(CheckBoxShape.ROUNDED_SQUARE)
.onChange((value: boolean) => {
this.isCropCircleWithBorder = value;
this.updateImageKnifeOption();
})
.width(30)
.height(30)
Text($r('app.string.Crop_circular_with_border_effect')).fontSize(20)
}
Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
Checkbox({ name: 'checkbox8', group: 'checkboxGroup' })
.selectedColor(0x39a2db)
.shape(CheckBoxShape.ROUNDED_SQUARE)
.onChange((value: boolean) => {
this.isContrast = value;
})
.width(30)
.height(30)
Text($r('app.string.Contrast_effect')).fontSize(20)
}
Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
Checkbox({ name: 'checkbox9', group: 'checkboxGroup' })
.selectedColor(0x39a2db)
.shape(CheckBoxShape.ROUNDED_SQUARE)
.onChange((value: boolean) => {
this.isSepia = value;
this.updateImageKnifeOption();
})
.width(30)
.height(30)
Text($r('app.string.Black_ink_filtering_effect')).fontSize(20)
}
Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
Checkbox({ name: 'checkbox10', group: 'checkboxGroup' })
.selectedColor(0x39a2db)
.shape(CheckBoxShape.ROUNDED_SQUARE)
.onChange((value: boolean) => {
this.isRotate = value;
})
.width(30)
.height(30)
Text($r('app.string.Rotate')).fontSize(20)
}
Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
Checkbox({ name: 'checkbox11', group: 'checkboxGroup' })
.selectedColor(0x39a2db)
.shape(CheckBoxShape.ROUNDED_SQUARE)
.onChange((value: boolean) => {
this.isRound = value;
this.updateImageKnifeOption();
})
.width(30)
.height(30)
Text($r('app.string.Corners')).fontSize(20)
}
Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
Checkbox({ name: 'checkbox12', group: 'checkboxGroup' })
.selectedColor(0x39a2db)
.shape(CheckBoxShape.ROUNDED_SQUARE)
.onChange((value: boolean) => {
this.isKuwahara = value;
this.updateImageKnifeOption();
})
.width(30)
.height(30)
Text($r('app.string.Kuwahara_Filter_effect')).fontSize(20)
}
Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
Checkbox({ name: 'checkbox13', group: 'checkboxGroup' })
.selectedColor(0x39a2db)
.shape(CheckBoxShape.ROUNDED_SQUARE)
.onChange((value: boolean) => {
this.isPixelation = value;
this.updateImageKnifeOption();
})
.width(30)
.height(30)
Text($r('app.string.Pixelated_Filter_effect')).fontSize(20)
}
Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
Checkbox({ name: 'checkbox14', group: 'checkboxGroup' })
.selectedColor(0x39a2db)
.shape(CheckBoxShape.ROUNDED_SQUARE)
.onChange((value: boolean) => {
this.isSketch = value;
this.updateImageKnifeOption();
})
.width(30)
.height(30)
Text($r('app.string.Sketch_Filter_effect')).fontSize(20)
}
Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
Checkbox({ name: 'checkbox15', group: 'checkboxGroup' })
.selectedColor(0x39a2db)
.shape(CheckBoxShape.ROUNDED_SQUARE)
.onChange((value: boolean) => {
this.isSwirl = value;
this.updateImageKnifeOption();
})
.width(30)
.height(30)
Text($r('app.string.Distortion_Filter_effect')).fontSize(20)
}
Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
Checkbox({ name: 'checkbox16', group: 'checkboxGroup' })
.selectedColor(0x39a2db)
.shape(CheckBoxShape.ROUNDED_SQUARE)
.onChange((value: boolean) => {
this.isVignetter = value;
this.updateImageKnifeOption();
})
.width(30)
.height(30)
Text($r('app.string.Decorative_Filter_effect')).fontSize(20)
}
Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
Checkbox({ name: 'checkbox17', group: 'checkboxGroup' })
.selectedColor(0x39a2db)
.shape(CheckBoxShape.ROUNDED_SQUARE)
.onChange((value: boolean) => {
this.isCropSquare = value;
this.updateImageKnifeOption();
})
.width(30)
.height(30)
Text($r('app.string.Square_cutting_effect')).fontSize(20)
}
Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
Checkbox({ name: 'checkbox18', group: 'checkboxGroup' })
.selectedColor(0x39a2db)
.shape(CheckBoxShape.ROUNDED_SQUARE)
.onChange((value: boolean) => {
this.isCropTop = value;
this.updateImageKnifeOption();
})
.width(30)
.height(30)
Text($r('app.string.Top_cutting_effect')).fontSize(20)
}
Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
Checkbox({ name: 'checkbox19', group: 'checkboxGroup' })
.selectedColor(0x39a2db)
.shape(CheckBoxShape.ROUNDED_SQUARE)
.onChange((value: boolean) => {
this.isCropCenter = value;
this.updateImageKnifeOption();
})
.width(30)
.height(30)
Text($r('app.string.Middle_cutting_effect')).fontSize(20)
}
Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
Checkbox({ name: 'checkbox20', group: 'checkboxGroup' })
.selectedColor(0x39a2db)
.shape(CheckBoxShape.ROUNDED_SQUARE)
.onChange((value: boolean) => {
this.isCropBottom = value;
this.updateImageKnifeOption();
})
.width(30)
.height(30)
Text($r('app.string.Bottom_cutting_effect')).fontSize(20)
}
Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
Checkbox({ name: 'checkbox21', group: 'checkboxGroup' })
.selectedColor(0x39a2db)
.shape(CheckBoxShape.ROUNDED_SQUARE)
.onChange((value: boolean) => {
this.isMask = value;
this.updateImageKnifeOption();
})
.width(30)
.height(30)
Text($r('app.string.Mask_effect')).fontSize(20)
}
if (this.isContrast) {
ImageKnifeComponent({
imageKnifeOption: this.imageKnifeOption
})
.width(300)
.height(300)
.rotate({ angle: this.isRotate ? 90 : 0 })
.contrast(12)
.backgroundColor(Color.Pink)
} else {
ImageKnifeComponent({
imageKnifeOption: this.imageKnifeOption
}).width(300)
.height(300)
.rotate({ angle: this.isRotate ? 90 : 0 })
.backgroundColor(Color.Pink)
}
}
}
.height('100%')
.width('100%')
}
updateImageKnifeOption() {
let transformations: collections.Array<PixelMapTransformation> = new collections.Array<PixelMapTransformation>()
if (this.isBlur) {
transformations.push(new BlurTransformation(5));
}
if (this.isBrightness) {
transformations.push(new BrightnessTransformation(0.2));
}
if (this.isGrayScale) {
transformations.push(new GrayScaleTransformation());
}
if (this.isInvert) {
transformations.push(new InvertTransformation());
}
if (this.isToon) {
transformations.push(new ToonTransformation(0.3, 10.0));
}
if (this.isKuwahara) {
transformations.push(new KuwaharaTransformation(10));
}
if (this.isPixelation) {
transformations.push(new PixelationTransformation(5.0));
}
if (this.isSketch) {
transformations.push(new SketchTransformation());
}
if (this.isSwirl) {
transformations.push(new SwirlTransformation(200, 1.0, [0.5, 0.5]));
}
if (this.isVignetter) {
transformations.push(new VignetterTransformation([0.5, 0.5], [0.0, 0.0, 0.0], [0.3, 0.75]));
}
if (this.isCropSquare) {
transformations.push(new CropSquareTransformation());
}
if (this.isCropTop) {
transformations.push(new CropTransformation(100, 100, 0));
}
if (this.isCropCenter) {
transformations.push(new CropTransformation(100, 100, 1));
}
if (this.isCropBottom) {
transformations.push(new CropTransformation(100, 100, 2));
}
if (this.isSepia) {
transformations.push(new SepiaTransformation());
}
if (this.isMask) {
transformations.push(new MaskTransformation($r('app.media.mask_starfish')));
}
this.imageKnifeOption = {
loadSrc: $r('app.media.pngSample'),
placeholderSrc: $r('app.media.loading'),
errorholderSrc: $r('app.media.app_icon'),
objectFit: ImageFit.Contain,
border: { radius: this.isRound ? { topLeft: 50, bottomRight: 50 } : 0 },
transformation: transformations.length > 0 ? new MultiTransTransformation(transformations) : undefined
}
if (this.isCropCircle) {
this.imageKnifeOption.objectFit = ImageFit.Cover;
this.imageKnifeOption.border = { radius: 150 };
}
if (this.isCropCircleWithBorder) {
this.imageKnifeOption.objectFit = ImageFit.Cover;
this.imageKnifeOption.border = { radius: 150, color: Color.Red, width: 5 };
}
}
}

View File

@ -0,0 +1,236 @@
/*
* Copyright (C) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an 'AS IS' BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import router from '@system.router';
@Entry
@Component
struct Index {
getResourceString(res:Resource){
return getContext().resourceManager.getStringSync(res.id)
}
aboutToAppear(): void {
}
build() {
Scroll(){
Column() {
Button($r('app.string.Test_ImageAnimator')).onClick(()=>{
router.push({
uri: 'pages/ImageAnimatorPage',
});
})
Button($r('app.string.Network_reload')).margin({top:10}).onClick(()=>{
router.push({
uri: 'pages/ImageKnifeReload',
});
})
Button($r('app.string.preloading_prefetch')).margin({top:10}).onClick(()=>{
router.push({
uri: 'pages/PrefetchAndCacheCount',
});
})
Button($r('app.string.request_concurrency')).margin({top:10}).onClick(()=>{
router.push({
uri: 'pages/SetMaxRequestPage',
});
})
Button($r('app.string.Single_CallBack')).margin({top:10}).onClick(()=>{
router.push({
uri: 'pages/SingleImageCallBack',
});
})
Button($r('app.string.Multiple_CallBack')).margin({top:10}).onClick(()=>{
router.push({
uri: 'pages/MultipleImageCallBack',
});
})
Button($r('app.string.Test_multiple_images')).margin({top:10}).onClick(()=>{
router.push({
uri: 'pages/TestCommonImage',
});
})
Button($r('app.string.Test_Task_error')).margin({top:10}).onClick(()=>{
router.push({
uri: 'pages/TestTaskResourcePage',
});
})
Button($r('app.string.Test_HSP')).margin({top:10}).onClick(()=>{
router.push({
uri: 'pages/TestHspPreLoadImage',
});
})
Button($r('app.string.Test_SingleImage')).margin({top:10}).onClick(()=>{
router.push({
uri: 'pages/SingleImage',
});
})
Button($r('app.string.Test_LocalImageShow')).margin({top:10}).onClick(()=>{
router.push({
uri: 'pages/LocalImage',
});
})
Button($r('app.string.Error_Message')).margin({top:10}).onClick(()=>{
router.push({
uri: 'pages/ErrorMessageDownload',
});
})
Button($r('app.string.Test_custom_download')).margin({top:10}).onClick(()=>{
router.push({
uri: 'pages/TestSetCustomImagePage',
});
})
Button(this.getResourceString($r('app.string.Multiple_images')) + ' + reuse + LazyForeach').margin({top:10}).onClick(()=>{
router.push({
uri: 'pages/UserPage',
});
})
Button($r('app.string.Image_Downsampling_Functionality')).margin({top:10}).onClick(()=>{
router.push({
uri: 'pages/DownSamplePage',
});
})
Button($r('app.string.Display_long_image')).margin({top:10}).onClick(()=>{
router.push({
uri: 'pages/LongImagePage',
});
})
Button($r('app.string.Auto_ImageFit')).margin({top:10}).onClick(()=>{
router.push({
uri: 'pages/AutoImageFit',
});
})
Button($r('app.string.Image_scaling')).margin({top:10}).onClick(()=>{
router.push({
uri: 'pages/TransformPage',
});
})
Button(this.getResourceString($r('app.string.Message_list')) + ' + List').margin({top:10}).onClick(()=>{
router.push({
uri: 'pages/TestImageFlash',
});
})
Button($r('app.string.Custom_cache_key')).margin({top:10}).onClick(()=>{
router.push({
uri: 'pages/SignatureTestPage',
});
})
Button($r('app.string.Preloading_images_to_cache')).margin({top:10}).onClick(()=>{
router.push({
uri: 'pages/TestPrefetchToFileCache',
});
})
Button($r('app.string.Retrieve_image_display_from_cache')).margin({top:10}).onClick(()=>{
router.push({
uri: 'pages/TestIsUrlExist',
});
})
Button($r('app.string.Test_single_request_header')).margin({top:10}).onClick(()=>{
router.push({
uri: 'pages/TestHeader',
});
})
Button($r('app.string.Test_write_cache_strategy')).margin({top:10}).onClick(()=>{
router.push({
uri: 'pages/TestWriteCacheStage',
});
})
Button($r('app.string.Image_Transformation')).margin({top:10}).onClick(()=>{
router.push({
uri: 'pages/ImageTransformation',
});
})
Button($r('app.string.Different_ObjectFit')).margin({top:10}).onClick(()=>{
router.push({
uri: 'pages/ObjectFitPage',
});
})
Button($r('app.string.Test_image_loading_success_or_failure_events')).margin({top:10}).onClick(()=>{
router.push({
uri: 'pages/LoadStatePage',
})
})
Button($r('app.string.Test_removing_image_cache_interface')).margin({top:10}).onClick(()=>{
router.push({
uri: 'pages/TestRemoveCache',
});
})
Button($r('app.string.Test_error_image_display')).margin({top:10}).onClick(()=>{
router.push({
uri: 'pages/TestErrorHolderPage',
});
})
Button($r('app.string.Test_media_URL')).margin({top:10}).onClick(()=>{
router.push({
uri: 'pages/dataShareUriLoadPage',
});
})
Button($r('app.string.test_cache_btn')).margin({ top: 10 }).onClick(() => {
router.push({
uri: 'pages/TestCacheDataPage',
});
})
Button($r('app.string.test_change_color_btn')).margin({ top: 10 }).onClick(() => {
router.push({
uri: 'pages/TestChangeColorPage',
});
})
Button($r('app.string.test_cancel_callback_btn')).margin({ top: 10 }).onClick(() => {
router.push({
uri: 'pages/TestLoadCancelListenerPage',
});
})
Button($r('app.string.test_callback')).margin({ top: 10 }).onClick(() => {
router.push({
uri: 'pages/TestImageKnifeCallbackPage',
});
})
Button($r('app.string.test_exif')).margin({ top: 10 }).onClick(() => {
router.push({
uri: 'pages/TestImageExif',
});
})
}
} .width('100%')
.height('100%')
}
}

View File

@ -0,0 +1,51 @@
/*
* Copyright (C) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an 'AS IS' BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { InfoItem } from './model/DataSourcePrefetching';
import { PageViewModel } from './model/PageViewModel';
import { ImageKnifeComponent, ImageKnifeOption } from '@ohos/libraryimageknife';
import { CommonDataSource } from './model/CommonDataSource';
@Entry
@Component
export struct LazyForEachCache {
@State hotCommendList:CommonDataSource<InfoItem> = new CommonDataSource<InfoItem>([])
aboutToAppear(): void {
this.hotCommendList.addData(this.hotCommendList.totalCount(),PageViewModel.getItems())
}
build() {
Column() {
List({ space: 16 }) {
LazyForEach(this.hotCommendList, (item: InfoItem,index) => {
ListItem() {
Column({ space: 12 }) {
ImageKnifeComponent({
imageKnifeOption:{
loadSrc: item.albumUrl,
placeholderSrc:$r('app.media.loading')
}
}).width(100).height(100)
Text(`${index}`)
}.border({ width: 5 , color: '#000000'})
}
})
}
.cachedCount(5)
.width('100%')
.height('100%')
.margin({ left: 10, right: 10 })
.layoutWeight(1)
}
}
}

View File

@ -0,0 +1,51 @@
/*
* Copyright (C) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an 'AS IS' BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { InfoItem } from './model/DataSourcePrefetching';
import { PageViewModel } from './model/PageViewModel';
import { ImageKnifeComponent, ImageKnifeOption } from '@ohos/libraryimageknife';
import { CommonDataSource } from './model/CommonDataSource';
@Entry
@Component
export struct LazyForEachCount {
@State hotCommendList:CommonDataSource<InfoItem> = new CommonDataSource<InfoItem>([])
aboutToAppear(): void {
this.hotCommendList.addData(this.hotCommendList.totalCount(),PageViewModel.getItems())
}
build() {
Column() {
List({ space: 16 }) {
LazyForEach(this.hotCommendList, (item: InfoItem,index) => {
ListItem() {
Column({ space: 12 }) {
ImageKnifeComponent({
imageKnifeOption:{
loadSrc: item.albumUrl,
placeholderSrc:$r('app.media.loading')
}
}).width(100).height(100)
Text(`${index}`)
}.border({ width: 5 , color: '#000000'})
}
})
}
.cachedCount(30)
.width('100%')
.height('100%')
.margin({ left: 10, right: 10 })
.layoutWeight(1)
}
}
}

View File

@ -0,0 +1,42 @@
/*
* Copyright (C) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an 'AS IS' BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { ImageKnifeComponent, ImageKnifeOption } from '@ohos/libraryimageknife';
@Entry
@Component
struct ListPage {
private data: string[] = []
@State ImageKnifeOption: ImageKnifeOption = { loadSrc: $r('app.media.startIcon')}
aboutToAppear(): void {
for (let i = 0; i < 1000; i++) {
this.data.push(i.toString())
}
}
build() {
Row() {
List({ space: 10 }) {
ForEach(this.data, (item: string) => {
ImageKnifeComponent({ imageKnifeOption: this.ImageKnifeOption }).height(200).width(200)
}, (item: string) => item)
}
.width('100%')
}
.height('100%')
}
}

View File

@ -0,0 +1,116 @@
/*
* Copyright (C) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an 'AS IS' BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { ImageKnifeComponent, ImageKnifeOption } from '@ohos/libraryimageknife'
import matrix4 from '@ohos.matrix4'
@Entry
@Component
struct LoadStatePage {
starTime:number = new Date().getTime()
@State ImageKnifeOption: ImageKnifeOption = {
loadSrc: $r('app.media.rabbit'),
placeholderSrc: $r('app.media.loading'),
errorholderSrc: $r('app.media.app_icon'),
objectFit: ImageFit.Contain,
onLoadListener: {
onLoadFailed: (err) => {
console.error('Load Failed Reason: ' + err);
},
onLoadSuccess: (data) => {
return data;
},
},
border: { radius: 50 }
}
@State imageKnifeOption1: ImageKnifeOption = {
loadSrc: $r('app.media.startIcon')
}
@State message: string = ''
@State currentWidth: number = 200
@State currentHeight: number = 200
@State typeValue: string = ''
build() {
Column() {
Text($r('app.string.TIPS'))
.margin({ top: 20 })
Row() {
Button($r('app.string.Test_failure_success'))
.onClick(() => {
this.ImageKnifeOption = {
loadSrc: 'https://www.openharmony.cn/_nuxt/img/logo.dcf95b3.png',
placeholderSrc: $r('app.media.loading'),
errorholderSrc: $r('app.media.app_icon'),
objectFit: ImageFit.Contain,
onLoadListener: {
onLoadStart:()=>{
this.starTime = new Date().getTime()
console.info('Load start: ');
},
onLoadFailed: (err) => {
console.error('Load Failed Reason: ' + err + ' cost ' + (new Date().getTime() - this.starTime) + ' milliseconds');
},
onLoadSuccess: (data,imageData) => {
console.info('Load Successful: cost ' + (new Date().getTime() - this.starTime) + ' milliseconds');
this.currentWidth = imageData.imageWidth!
this.currentHeight = imageData.imageHeight!
this.typeValue = imageData.type!
return data;
},
},
border: { radius: 50 },
onComplete:(event)=>{
console.error('Load onComplete width:'+event?.width , ' height:'+event?.height , ' componentWidth:'+event?.componentWidth,' componentHeight:' + event?.componentHeight);
}
}
})
}
.margin({ top: 20 })
Text($r('app.string.image_format',this.typeValue))
Text($r('app.string.image_width',this.currentWidth))
Text($r('app.string.image_height',this.currentHeight))
ImageKnifeComponent({ imageKnifeOption: this.ImageKnifeOption }).height(this.currentHeight).width(this.currentWidth)
.margin({ top: 20 })
Button($r('app.string.Custom_download_failed')).onClick(()=>{
this.imageKnifeOption1 = {
loadSrc: 'abc',
placeholderSrc:$r('app.media.loading'),
errorholderSrc:$r('app.media.failed'),
customGetImage:custom,
onLoadListener: {
onLoadFailed:(err)=>{
this.message = 'err:' + err
}
}
}
}).margin({ top: 20 })
Text(this.message).fontSize(20).margin({ top: 20 })
ImageKnifeComponent({ imageKnifeOption: this.imageKnifeOption1 }).height(this.currentHeight).width(this.currentWidth)
.margin({ top: 20 })
}
.width('100%')
.height('100%')
}
}
// 自定义下载方法
@Concurrent
async function custom(context: Context, src: string | PixelMap | Resource,headers?: Record<string,Object>): Promise<ArrayBuffer | undefined> {
console.info('ImageKnife:: custom download' + src)
// 举例写死从本地文件读取,也可以自己请求网络图片
return undefined
}

View File

@ -0,0 +1,78 @@
/*
* Copyright (C) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an 'AS IS' BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { ImageKnifeComponent } from '@ohos/libraryimageknife';
import fs from '@ohos.file.fs';
@Entry
@Component
struct LocalImage {
scroller: Scroller = new Scroller;
localFile: string = getContext(this).filesDir + '/icon.png'
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() {
Scroll(this.scroller) {
Column() {
Text($r('app.string.local_r_file'))
.fontSize(30)
.fontWeight(FontWeight.Bold)
ImageKnifeComponent({
imageKnifeOption: {
loadSrc: $r('app.media.startIcon'),
objectFit: ImageFit.Contain
}
}).width(100).height(100)
Text($r('app.string.local_rawfile'))
.fontSize(30)
.fontWeight(FontWeight.Bold)
ImageKnifeComponent({
imageKnifeOption: {
loadSrc: $rawfile('image/startIcon.png'),
objectFit: ImageFit.Contain
}
}).width(100).height(100)
Text($r('app.string.Under_context_file'))
.fontSize(30)
.fontWeight(FontWeight.Bold)
ImageKnifeComponent({
imageKnifeOption: {
loadSrc: this.localFile,
objectFit: ImageFit.Contain
}
}).width(100).height(100)
Text($r('app.string.local_other_module'))
.fontSize(30)
.fontWeight(FontWeight.Bold)
ImageKnifeComponent({
imageKnifeOption: {
loadSrc: $r('[sharedlibrary].media.startIcon'),
objectFit: ImageFit.Contain
}
}).width(100).height(100)
}
.width('100%')
}
.height('100%')
}
}

View File

@ -0,0 +1,43 @@
/*
* Copyright (C) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an 'AS IS' BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { ImageKnifeComponent } from '@ohos/libraryimageknife'
@Entry
@Component
struct LongImagePage {
build() {
Scroll() {
// Image('https://wx2.sinaimg.cn/mw690/006HyQKGgy1hnqp08dw09j30u04twu0x.jpg').objectFit(ImageFit.Auto).height(300)
// Image($r('app.media.aaa')).objectFit(ImageFit.Auto).width(200)
ImageKnifeComponent({
imageKnifeOption: {
loadSrc:'https://wx2.sinaimg.cn/mw690/006HyQKGgy1hnqp08dw09j30u04twu0x.jpg',
//src:$r('app.media.aaa'),
placeholderSrc: $r('app.media.loading'),
errorholderSrc: $r('app.media.failed'),
httpOption: {
connectTimeout: 60000,
readTimeout: 60000
},
objectFit: ImageFit.Auto
}
})
}
.height('100%') .width('100%')
}
}

View File

@ -0,0 +1,55 @@
/*
* Copyright (C) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an 'AS IS' BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { ImageKnifeComponent,ImageKnife } from '@ohos/libraryimageknife';
import { CommonDataSource } from './model/CommonDataSource';
@Entry
@Component
struct MaxRequest1 {
@State hotCommendList:CommonDataSource<string> = new CommonDataSource<string>([])
private data: Array<string> = []
aboutToAppear(): void {
ImageKnife.getInstance().setMaxRequests(8)
for (let index = 0; index < 200; index++) {
this.data.push(`https://img-blog.csdn.net/20140514114029140?${index}`)
}
this.hotCommendList.addData(this.hotCommendList.totalCount(),this.data)
}
build() {
Column() {
WaterFlow() {
LazyForEach(this.hotCommendList,(item: string)=>{
FlowItem() {
Column(){
ImageKnifeComponent({
imageKnifeOption: {
loadSrc: item,
placeholderSrc: $r('app.media.loading'),
errorholderSrc: $r('app.media.failed'),
}
}).width('50%').height(160)
}
}.height(200)
.backgroundColor('#95efd2')
},(item: string) => item)
}.columnsTemplate('1fr 1fr')
.cachedCount(8)
.columnsGap(10)
.rowsGap(5)
.backgroundColor(0xFAEEE0)
.width('100%').height('100%')
}
}
}

View File

@ -0,0 +1,55 @@
/*
* Copyright (C) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an 'AS IS' BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { ImageKnifeComponent,ImageKnife } from '@ohos/libraryimageknife';
import { CommonDataSource } from './model/CommonDataSource';
@Entry
@Component
struct MaxRequest2 {
@State hotCommendList:CommonDataSource<string> = new CommonDataSource<string>([])
private data: Array<string> = []
aboutToAppear(): void {
ImageKnife.getInstance().setMaxRequests(20)
for (let index = 200; index < 400; index++) {
this.data.push(`https://img-blog.csdn.net/20140514114029140?${index}`)
}
this.hotCommendList.addData(this.hotCommendList.totalCount(),this.data)
}
build() {
Column() {
WaterFlow() {
LazyForEach(this.hotCommendList,(item: string)=>{
FlowItem() {
Column(){
ImageKnifeComponent({
imageKnifeOption: {
loadSrc: item,
placeholderSrc: $r('app.media.loading'),
errorholderSrc: $r('app.media.failed'),
}
}).width('50%').height(160)
}
}.height(200)
.backgroundColor('#95efd2')
},(item: string) => item)
}.columnsTemplate('1fr 1fr')
.cachedCount(20)
.columnsGap(10)
.rowsGap(5)
.backgroundColor(0xFAEEE0)
.width('100%').height('100%')
}
}
}

View File

@ -0,0 +1,55 @@
/*
* Copyright (C) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an 'AS IS' BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { ImageKnifeComponent,ImageKnife } from '@ohos/libraryimageknife';
import { CommonDataSource } from './model/CommonDataSource';
@Entry
@Component
struct MaxRequest3 {
@State hotCommendList:CommonDataSource<string> = new CommonDataSource<string>([])
private data: Array<string> = []
aboutToAppear(): void {
ImageKnife.getInstance().setMaxRequests(32)
for (let index = 400; index < 600; index++) {
this.data.push(`https://img-blog.csdn.net/20140514114029140?${index}`)
}
this.hotCommendList.addData(this.hotCommendList.totalCount(),this.data)
}
build() {
Column() {
WaterFlow() {
LazyForEach(this.hotCommendList,(item: string)=>{
FlowItem() {
Column(){
ImageKnifeComponent({
imageKnifeOption: {
loadSrc: item,
placeholderSrc: $r('app.media.loading'),
errorholderSrc: $r('app.media.failed'),
}
}).width('50%').height(160)
}
}.height(200)
.backgroundColor('#95efd2')
},(item: string) => item)
}.columnsTemplate('1fr 1fr')
.cachedCount(40)
.columnsGap(10)
.rowsGap(5)
.backgroundColor(0xFAEEE0)
.width('100%').height('100%')
}
}
}

View File

@ -0,0 +1,151 @@
/*
* Copyright (C) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an 'AS IS' BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { ImageKnifeComponent,ImageKnifeOption } from '@ohos/libraryimageknife';
import { CommonDataSource } from './model/CommonDataSource'
@Entry
@Component
struct MultipleImageCallBack {
@State hotCommendList: CommonDataSource<string> = new CommonDataSource<string>([])
@State componentIndex: number = 0
@State startIndex: number = 0
@State successIndex: number = 0
@State failIndex: number = 0
@State cancelJobIndex: number = 0
@State cancelLoadIndex: number = 0
@State memoryIndex: number = 0
@State fileCacheIndex: number = 0
@State netIndex: number = 0
@State checkText: string = ''
private data: Array<string> = []
aboutToAppear(): void {
for (let index = 0; index < 100; index++) {
this.data.push(`https://img-blog.csdn.net/20140514114029140?${index}`)
}
this.hotCommendList.addData(this.hotCommendList.totalCount(), this.data)
}
build() {
Column() {
Row() {
Column() {
Text('图片总数:' + this.componentIndex)
Text('开始回调:' + this.startIndex)
Text('成功回调:' + this.successIndex)
Text('失败回调:' + this.failIndex)
Text('队列取消回调:' + this.cancelJobIndex)
Text('加载取消回调:' + this.cancelLoadIndex)
Text('内存数量:' + this.memoryIndex)
Text('文件数量:' + this.fileCacheIndex)
Text('网络数量:' + this.netIndex)
}.width('50%')
Column() {
Button('check')
.onClick(()=>{
this.checkText = ''
if (this.componentIndex !== this.startIndex + this.cancelJobIndex) {
this.checkText = this.checkText + '图片总数!=开始+队列取消,'
}
if(this.startIndex !== this.successIndex + this.failIndex + this.cancelLoadIndex) {
this.checkText = this.checkText + '开始回调!=成功+失败+加载取消,'
}
if(this.successIndex !== this.memoryIndex + this.fileCacheIndex + this.netIndex) {
this.checkText = this.checkText + '成功回调!=内存+文件+网络,'
}
if(this.componentIndex !== this.successIndex + this.failIndex + this.cancelJobIndex + this.cancelLoadIndex) {
this.checkText = this.checkText + '图片总数!=成功+失败+加载取消+队列取消,'
}
if(this.checkText == '') {
this.checkText = 'check正确'
}
})
Text(this.checkText)
}.width('50%')
}.width('100%')
Column() {
WaterFlow() {
LazyForEach(this.hotCommendList, (item: string,index: number) => {
FlowItem() {
Column() {
Text(index + '')
ImageComponent({
imageKnifeOption: {
loadSrc: item,
placeholderSrc: $r('app.media.loading'),
errorholderSrc: $r('app.media.failed'),
onLoadListener: {
onLoadStart:()=>{
this.startIndex++
console.log('image load multiple loadStart:' + this.startIndex)
},
onLoadSuccess:(pixelmap,imageData,request)=>{
this.successIndex++
let memory = request?.imageKnifeData?.timeInfo?.memoryCheckEndTime ? 1 : 0
let fileCache = request?.imageKnifeData?.timeInfo?.diskCheckEndTime ? 1 : 0
let net = request?.imageKnifeData?.timeInfo?.netRequestEndTime ? 1 : 0
memory = memory - fileCache
fileCache = fileCache - net
this.memoryIndex = this.memoryIndex + memory
this.fileCacheIndex = this.fileCacheIndex + fileCache
this.netIndex = this.netIndex + net
console.log('image load multiple loadSuccess:' + this.successIndex)
},
onLoadFailed:()=>{
this.failIndex++
console.log('image load multiple loadFail:' + this.failIndex)
},
onLoadCancel:(message,request)=>{
let flag = request?.imageKnifeData?.timeInfo?.netRequestStartTime ? true : false
if (flag) {
this.cancelLoadIndex++
} else {
this.cancelJobIndex++
}
console.log('image load multiple cancelJobIndex:' + this.cancelJobIndex,'cancelLoadIndex' + this.cancelLoadIndex)
}
}
},index:this.componentIndex
}).width('50%').height(160)
}
}.height(200)
.backgroundColor('#95efd2')
}, (item: string) => item)
}
.cachedCount(0)
.columnsTemplate('1fr 1fr')
.columnsGap(10)
.rowsGap(5)
.backgroundColor(0xFAEEE0)
.width('100%')
}
.height('80%')
}.width('100%')
.height('100%')
}
}
@Component
struct ImageComponent {
@State imageKnifeOption: ImageKnifeOption = new ImageKnifeOption()
@Link index: number
aboutToAppear(): void {
this.index++
}
build() {
ImageKnifeComponent({
imageKnifeOption: this.imageKnifeOption
})
}
}

View File

@ -0,0 +1,71 @@
/*
* Copyright (C) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an 'AS IS' BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { ImageKnife, ImageKnifeComponent, ImageKnifeOption } from '@ohos/libraryimageknife'
@Entry
@Component
struct ObjectFitPage {
@State imageKnifeOption: ImageKnifeOption = {
loadSrc: $r('app.media.app_icon'),
placeholderSrc: $r('app.media.loading'),
errorholderSrc: $r('app.media.app_icon'),
objectFit: ImageFit.Fill
}
build() {
Column() {
Button($r('app.string.Main_image_Fill')).onClick(()=>{
this.imageKnifeOption = {
loadSrc: $r('app.media.app_icon'),
placeholderSrc: $r('app.media.loading'),
errorholderSrc: $r('app.media.app_icon'),
objectFit: ImageFit.Fill
}
})
Button($r('app.string.Maintain_proportion_filling')).margin({top:10}).onClick(async () => {
ImageKnife.getInstance().removeAllMemoryCache()
await ImageKnife.getInstance().removeAllFileCache()
this.imageKnifeOption = {
loadSrc: 'https://wx2.sinaimg.cn/mw690/006HyQKGgy1hnqp08dw09j30u04twu0x.jpg',
placeholderSrc: $r('app.media.app_icon'),
errorholderSrc: $r('app.media.app_icon'),
objectFit: ImageFit.Fill,
placeholderObjectFit: ImageFit.Contain
}
})
Button($r('app.string.Error_graph_None')).margin({top:10}).onClick(() => {
this.imageKnifeOption = {
loadSrc: 'http://xxxxx',
placeholderSrc: $r('app.media.loading'),
errorholderSrc: $r('app.media.app_icon'),
objectFit: ImageFit.Fill,
errorholderObjectFit: ImageFit.None
}
})
ImageKnifeComponent({
imageKnifeOption: this.imageKnifeOption
}).width(300).height(200).border({width:1}).margin({top:50})
}
.height('100%')
.width('100%')
}
}

View File

@ -1,79 +0,0 @@
/*
* Copyright (C) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { ImageKnifeComponent, ImageKnifeOption,NONE,DiskStrategy } from '@ohos/libraryimageknife'
@Entry
@Component
struct OptionTestPage {
@State imageKnifeOption1: ImageKnifeOption =
{
loadSrc: $r('app.media.icon'),
placeholderSrc: $r('app.media.icon_loading'),
errorholderSrc: $r('app.media.icon_failed'),
};
@State imageKnifeOption2: ImageKnifeOption =
{
loadSrc: $r('app.media.icon'),
placeholderSrc: $r('app.media.icon_loading'),
errorholderSrc: $r('app.media.icon_failed')
};
build() {
Scroll() {
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Text("示例加载图片不进行缓存").fontSize(15)
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Button("加载")
.onClick(() => {
let setting:DiskStrategy = new NONE();
this.imageKnifeOption1 = {
loadSrc: 'https://img-blog.csdn.net/20140514114029140',
placeholderSrc: $r('app.media.icon_loading'),
errorholderSrc: $r('app.media.icon_failed'),
onlyRetrieveFromCache: false,
isCacheable: false,
strategy: setting
}
}).margin({ top: 5, left: 3 })
ImageKnifeComponent({ imageKnifeOption: this.imageKnifeOption1 }).width(300).height(300)
}.width('100%').backgroundColor(Color.Pink)
Text("示例:加载图片进行缓存").fontSize(15)
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Button("加载")
.onClick(() => {
let setting2:DiskStrategy = new NONE();
this.imageKnifeOption2 = {
loadSrc: 'https://img-blog.csdn.net/20140514114029140',
placeholderSrc: $r('app.media.icon_loading'),
errorholderSrc: $r('app.media.icon_failed'),
onlyRetrieveFromCache: true,
isCacheable: true,
strategy: setting2
}
}).margin({ top: 5, left: 3 })
ImageKnifeComponent({ imageKnifeOption: this.imageKnifeOption2 }).width(300).height(300)
}.width('100%').backgroundColor(Color.Pink)
}
}.width('100%')
.height('100%')
}
}

View File

@ -0,0 +1,39 @@
/*
* Copyright (C) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an 'AS IS' BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { router } from '@kit.ArkUI'
@Entry
@Component
struct PrefetchAndCacheCount {
build() {
Column() {
Button('cacheCount == 5')
.onClick(()=>{
router.pushUrl({url:'pages/LazyForEachCache'})
})
Button('cacheCount == 30')
.margin({top:10})
.onClick(()=>{
router.pushUrl({url:'pages/LazyForEachCount'})
})
Button('prefetch + preload')
.margin({top:10})
.onClick(()=>{
router.pushUrl({url:'pages/PrefetchAndPreload'})
})
}.width('100%')
.height('100%')
}
}

View File

@ -0,0 +1,56 @@
/*
* Copyright (C) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an 'AS IS' BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { BasicPrefetcher } from '@kit.ArkUI';
import DataSourcePrefetchingImageKnife, { InfoItem } from './model/DataSourcePrefetching';
import { PageViewModel } from './model/PageViewModel';
import { ImageKnifeComponent, ImageKnifeOption } from '@ohos/libraryimageknife';
@Entry
@Component
export struct PrefetchAndPreload {
// 创建DataSourcePrefetchingImageKnife对象具备任务预取、取消能力的数据源
private readonly dataSource = new DataSourcePrefetchingImageKnife(PageViewModel.getItems());
// 创建BasicPrefetcher对象默认的动态预取算法实现
private readonly prefetcher = new BasicPrefetcher(this.dataSource);
build() {
Column() {
List({ space: 16 }) {
LazyForEach(this.dataSource, (item: InfoItem,index:number) => {
ListItem() {
Column({ space: 12 }) {
ImageKnifeComponent({
imageKnifeOption:{
loadSrc: item.albumUrl,
placeholderSrc:$r('app.media.loading')
}
}).width(100).height(100)
Text(`${index}`)
}.border({ width: 5 , color: '#000000'})
}
.reuseId('imageKnife')
})
}
.cachedCount(5)
.onScrollIndex((start: number, end: number) => {
// 列表滚动触发visibleAreaChanged实时更新预取范围触发调用prefetch、cancel接口
this.prefetcher.visibleAreaChanged(start, end)
})
.width('100%')
.height('100%')
.margin({ left: 10, right: 10 })
.layoutWeight(1)
}
}
}

View File

@ -1,109 +0,0 @@
/*
* Copyright (C) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import image from '@ohos.multimedia.image'
import {
ImageKnifeData,
RequestOption,
Size,
ImageKnife,
ImageKnifeGlobal,
ImageKnifeComponent,
ObjectKey
} from '@ohos/libraryimageknife'
import { BusinessError } from '@ohos.base'
const TAG = "TEST-"
let timeId = -1
@Entry
@Component
struct RequestOptionLoadImage {
@State pixelMap: PixelMap | undefined = undefined
load(src: string | image.PixelMap | Resource) {
clearTimeout(timeId)
let request = new RequestOption()
//*requestOption调用*
request.addHeader('refer', 'http://1.94.37.200:7070/AntiTheftChain/downloadImage');
//通过时间戳去清除缓存
request.signature = new ObjectKey(new Date().getTime().toString())
request.load(src)
.addListener({ callback: (err: BusinessError | string, data: ImageKnifeData) => {
if (data.isPixelMap()) {
if (data.drawPixelMap) {
let pixelmap = data.drawPixelMap.imagePixelMap
if (pixelmap) {
this.pixelMap = pixelmap
}
}
}
if (data.isGIFFrame()) {
let index: number = 0
if (data.drawGIFFrame) {
if (data.drawGIFFrame.imageGIFFrames) {
let renderGif = () => {
if (data.drawGIFFrame) {
if (data.drawGIFFrame.imageGIFFrames) {
let pixelmap = data.drawGIFFrame.imageGIFFrames[index].drawPixelMap
let delay = data.drawGIFFrame.imageGIFFrames[index].delay
if (pixelmap) {
this.pixelMap = pixelmap
}
index++;
if (index == data.drawGIFFrame.imageGIFFrames.length - 1) {
index = 0
}
timeId = setTimeout(renderGif, data!.drawGIFFrame!.imageGIFFrames![index].delay)
}
}
}
renderGif()
}
}
}
if (err) {
console.log(TAG + "error:" + JSON.stringify(err));
}
return false
}
})
let compSize: Size = {
width: 300,
height: 300
}
request.setImageViewSize(compSize)
let imageknife: ImageKnife | undefined = ImageKnifeGlobal.getInstance().getImageKnife()
if (imageknife != undefined) {
imageknife.call(request)
}
}
build() {
Scroll() {
Column() {
Text("RequestOption加载图片").fontSize(25)
Button("加载网络gif").onClick(() => {
this.load("https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658")
})
Button("加载静态图").onClick(() => {
this.load($r('app.media.pngSample'))
})
ImageKnifeComponent({ imageKnifeOption: {
loadSrc: this.pixelMap as image.PixelMap
} }).width(300).height(300).borderWidth(3)
}
}
}
}

View File

@ -0,0 +1,37 @@
/*
* Copyright (C) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an 'AS IS' BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { router } from '@kit.ArkUI'
@Entry
@Component
struct SetMaxRequestPage {
build() {
Column() {
Button('maxRequest = 8')
.onClick(()=>{
router.pushUrl({url:'pages/MaxRequest1'})
})
Button('maxRequest = 20')
.onClick(()=>{
router.pushUrl({url:'pages/MaxRequest2'})
}).margin({top:20})
Button('maxRequest = 32')
.onClick(()=>{
router.pushUrl({url:'pages/MaxRequest2'})
}).margin({top:20})
}.width('100%')
.height('100%')
}
}

View File

@ -1,20 +1,19 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* Copyright (C) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* distributed under the License is distributed on an 'AS IS' BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { ImageKnifeComponent, ImageKnifeOption } from '@ohos/libraryimageknife';
import { ImageKnifeComponent, ImageKnifeOption, NONE, DiskStrategy } from '@ohos/libraryimageknife'
import { ObjectKey } from '@ohos/libraryimageknife';
@Entry
@Component
@ -22,43 +21,39 @@ struct SignatureTestPage {
@State imageKnifeOption1: ImageKnifeOption =
{
loadSrc: $r('app.media.icon'),
placeholderSrc: $r('app.media.icon_loading'),
errorholderSrc: $r('app.media.icon_failed'),
placeholderSrc:$r('app.media.loading'),
};
@State imageKnifeOption2: ImageKnifeOption =
{
loadSrc: $r('app.media.icon'),
placeholderSrc: $r('app.media.icon_loading'),
errorholderSrc: $r('app.media.icon_failed')
placeholderSrc:$r('app.media.loading'),
};
build() {
Scroll() {
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Text("Signature固定为 1").fontSize(15)
Text($r('app.string.The_key_fixed_1')).fontSize(15)
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Button("加载")
Button($r('app.string.Load'))
.onClick(() => {
this.imageKnifeOption1 = {
loadSrc: 'https://img-blog.csdn.net/20140514114029140',
placeholderSrc: $r('app.media.icon_loading'),
errorholderSrc: $r('app.media.icon_failed'),
signature: new ObjectKey("1")
placeholderSrc:$r('app.media.loading'),
signature: '1'
}
}).margin({ top: 5, left: 3 })
ImageKnifeComponent({ imageKnifeOption: this.imageKnifeOption1 }).width(300).height(300)
}.width('100%').backgroundColor(Color.Pink)
Text("设置Signature每次为时间戳").fontSize(15)
Text($r('app.string.The_key_changes_timestamp')).fontSize(15)
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Button("加载")
Button($r('app.string.Load'))
.onClick(() => {
this.imageKnifeOption2 = {
loadSrc: 'https://img-blog.csdn.net/20140514114029140',
placeholderSrc: $r('app.media.icon_loading'),
errorholderSrc: $r('app.media.icon_failed'),
signature: new ObjectKey(new Date().getTime().toString())
placeholderSrc:$r('app.media.loading'),
signature: new Date().getTime().toString()
}
}).margin({ top: 5, left: 3 })
ImageKnifeComponent({ imageKnifeOption: this.imageKnifeOption2 }).width(300).height(300)
@ -71,7 +66,7 @@ struct SignatureTestPage {
}
aboutToAppear() {
console.log("唯一标识页面:" + new ObjectKey(new Date().getTime().toString()).getKey())
console.log('唯一标识页面:' + new Date().getTime().toString())
}
}

View File

@ -0,0 +1,149 @@
/*
* Copyright (C) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an 'AS IS' BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { ImageKnifeComponent,BlurTransformation } from '@ohos/libraryimageknife';
import fs from '@ohos.file.fs';
import image from '@ohos.multimedia.image';
import { common2D, drawing } from '@kit.ArkGraphics2D';
@Entry
@Component
struct SingleImage {
resource: string = 'app.media.svgSample'
scroller: Scroller = new Scroller;
localFile: string = getContext(this).filesDir + '/icon.png'
@State pixelMap:PixelMap | undefined = undefined;
@State DrawingColorFilter: ColorFilter | undefined = undefined
private color: common2D.Color = { alpha: 255, red: 255, green: 0, blue: 0 };
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);
this.changePic(getContext().resourceManager.getMediaContentSync( $r('app.media.aaa'))
.buffer as ArrayBuffer);
}
build() {
Scroll(this.scroller) {
Column() {
Text($r('app.string.Local_SVG'))
.fontSize(30)
.fontWeight(FontWeight.Bold)
ImageKnifeComponent({
imageKnifeOption: {
loadSrc: $r(this.resource),
placeholderSrc: $r('app.media.loading'),
errorholderSrc: $r('app.media.failed'),
objectFit: ImageFit.Contain
}
}).width(100).height(100)
.onClick(()=>{
this.DrawingColorFilter = drawing.ColorFilter.createBlendModeColorFilter(this.color, drawing.BlendMode.SRC_IN);
})
ImageKnifeComponent({
imageKnifeOption: {
loadSrc: $r('[sharedlibrary].media.pngSample'),
placeholderSrc: $r('app.media.loading'),
errorholderSrc: $r('app.media.failed'),
objectFit: ImageFit.Contain
}
}).width(100).height(100)
Text($r('app.string.Under_context_file'))
.fontSize(30)
.fontWeight(FontWeight.Bold)
ImageKnifeComponent({
imageKnifeOption: {
loadSrc: this.localFile,
placeholderSrc: $r('app.media.loading'),
errorholderSrc: $r('app.media.failed'),
objectFit: ImageFit.Contain
}
}).width(100).height(100)
Text($r('app.string.Network_images'))
.fontSize(30)
.fontWeight(FontWeight.Bold)
ImageKnifeComponent({
imageKnifeOption: {
loadSrc:'https://www.openharmony.cn/_nuxt/img/logo.dcf95b3.png',
placeholderSrc: $r('app.media.loading'),
errorholderSrc: $r('app.media.failed'),
objectFit: ImageFit.Contain,
progressListener:(progress:number)=>{console.info('ImageKnife:: call back progress = ' + progress)},
// 通过https协议进行连接时默认使用系统预设CA证书。若希望使用自定义证书进行https连接则需要将自定义证书上传至应用沙箱目录中并在caPath中指定该证书所在的应用沙箱路径
// caPath: '/data/storage/el1/bundle/ca.pem',
}
}).width(100).height(100)
Text($r('app.string.Custom_network_download'))
.fontSize(30)
.fontWeight(FontWeight.Bold)
ImageKnifeComponent({
imageKnifeOption: {
loadSrc: 'https://file.atomgit.com/uploads/user/1704857786989_8994.jpeg',
placeholderSrc: $r('app.media.loading'),
errorholderSrc: $r('app.media.failed'),
objectFit: ImageFit.Contain,
headerOption:[{
key:'refer',
value:'xx.xx.xx.xx'
}],
customGetImage: custom,
transformation: new BlurTransformation(10)
}
}).width(100).height(100)
Text($r('app.string.PixelMap_loads_images'))
.fontSize(30)
.fontWeight(FontWeight.Bold)
ImageKnifeComponent({
imageKnifeOption: {
loadSrc: this.pixelMap!,
placeholderSrc: $r('app.media.loading'),
errorholderSrc: $r('app.media.failed'),
objectFit: ImageFit.Contain,
}
}).width(100).height(100)
}
.width('100%')
}
.height('100%')
}
changePic(buffer: ArrayBuffer){
let imageSource: image.ImageSource = image.createImageSource(buffer);
if (imageSource) {
let decodingOptions: image.DecodingOptions = {
editable: true,
}
imageSource.createPixelMap(decodingOptions,(err,pixelMap)=>{
imageSource.release()
this.pixelMap = pixelMap;
})
}
}
}
// 自定义下载方法
@Concurrent
async function custom(context: Context, src: string | PixelMap | Resource,headers?: Record<string,Object>): Promise<ArrayBuffer | undefined> {
let refer = headers!['refer'] as string
console.info('ImageKnife:: custom download' + src,'refer:'+refer)
// 举例写死从本地文件读取,也可以自己请求网络图片
let buffer = context.resourceManager.getMediaContentSync($r('app.media.startIcon').id).buffer as ArrayBuffer
return buffer
}

View File

@ -0,0 +1,126 @@
/*
* Copyright (C) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an 'AS IS' BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { ImageKnifeComponent,ImageKnifeOption } from '@ohos/libraryimageknife';
import { CommonDataSource } from './model/CommonDataSource'
@Entry
@Component
struct SingleImageCallBack {
@State hotCommendList: CommonDataSource<string> = new CommonDataSource<string>([])
@State componentIndex: number = 0
@State startIndex: number = 0
@State successIndex: number = 0
@State failIndex: number = 0
@State cancelJobIndex: number = 0
@State cancelLoadIndex: number = 0
@State memoryIndex: number = 0
@State fileCacheIndex: number = 0
@State netIndex: number = 0
@State checkText: string = ''
build() {
Column() {
Row() {
Column() {
Text('图片总数:' + this.componentIndex)
Text('开始回调:' + this.startIndex)
Text('成功回调:' + this.successIndex)
Text('失败回调:' + this.failIndex)
Text('队列取消回调:' + this.cancelJobIndex)
Text('加载取消回调:' + this.cancelLoadIndex)
Text('内存数量:' + this.memoryIndex)
Text('文件数量:' + this.fileCacheIndex)
Text('网络数量:' + this.netIndex)
}.width('50%')
Column() {
Button('check')
.onClick(()=>{
this.checkText = ''
if (this.componentIndex !== this.startIndex + this.cancelJobIndex) {
this.checkText = this.checkText + '图片总数!=开始+队列取消,'
}
if(this.startIndex !== this.successIndex + this.failIndex + this.cancelLoadIndex) {
this.checkText = this.checkText + '开始回调!=成功+失败+加载取消,'
}
if(this.successIndex !== this.memoryIndex + this.fileCacheIndex + this.netIndex) {
this.checkText = this.checkText + '成功回调!=内存+文件+网络,'
}
if(this.componentIndex !== this.successIndex + this.failIndex + this.cancelJobIndex + this.cancelLoadIndex) {
this.checkText = this.checkText + '图片总数!=成功+失败+加载取消+队列取消,'
}
if(this.checkText == '') {
this.checkText = 'check正确'
}
})
Text(this.checkText)
}.width('50%')
}.width('100%')
Column() {
ImageComponent({
imageKnifeOption: {
loadSrc: 'https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp',
placeholderSrc: $r('app.media.loading'),
errorholderSrc: $r('app.media.failed'),
onLoadListener: {
onLoadStart: () => {
this.startIndex++
console.log('image load multiple loadStart:' + this.startIndex)
},
onLoadSuccess: (pixelmap, imageData, request) => {
this.successIndex++
let memory = request?.imageKnifeData?.timeInfo?.memoryCheckEndTime ? 1 : 0
let fileCache = request?.imageKnifeData?.timeInfo?.diskCheckEndTime ? 1 : 0
let net = request?.imageKnifeData?.timeInfo?.netRequestEndTime ? 1 : 0
memory = memory - fileCache
fileCache = fileCache - net
this.memoryIndex = this.memoryIndex + memory
this.fileCacheIndex = this.fileCacheIndex + fileCache
this.netIndex = this.netIndex + net
console.log('image load multiple loadSuccess:' + this.successIndex)
},
onLoadFailed: () => {
this.failIndex++
console.log('image load multiple loadFail:' + this.failIndex)
},
onLoadCancel: (message,request) => {
let flag = request?.imageKnifeData?.type ? true : false
if (flag) {
this.cancelLoadIndex++
} else {
this.cancelJobIndex++
}
console.log('image load multiple cancelJobIndex:' + this.cancelJobIndex,'cancelLoadIndex' + this.cancelLoadIndex)
}
}
},index:this.componentIndex
}).width(300).height(300)
}
.height('80%')
}.width('100%')
.height('100%')
}
}
@Component
struct ImageComponent {
@State imageKnifeOption: ImageKnifeOption = new ImageKnifeOption()
@Link index: number
aboutToAppear(): void {
this.index++
}
build() {
ImageKnifeComponent({
imageKnifeOption: this.imageKnifeOption
})
}
}

View File

@ -0,0 +1,140 @@
/*
* Copyright (C) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an 'AS IS' BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { ImageKnife, CacheStrategy, ImageKnifeComponent, ImageKnifeOption } from '@ohos/libraryimageknife';
@Entry
@Component
struct TestCacheDataPage {
@State cacheUpLimit: number = 0;
@State currentNum: number = 0;
@State currentSize: number = 0;
@State currentWidth: number = 200
@State currentHeight: number = 200
@State markersLimitText: string = getContext(this).resourceManager.getStringSync($r('app.string.memory'))
@State markersNumText: string = getContext(this).resourceManager.getStringSync($r('app.string.memory'))
@State markersSizeText: string = getContext(this).resourceManager.getStringSync($r('app.string.memory'))
@State ImageKnifeOption: ImageKnifeOption = {
loadSrc: '',
objectFit: ImageFit.Contain,
onLoadListener: {
onLoadFailed: (err) => {
console.error('Load Failed Reason: ' + err);
},
onLoadSuccess: (data) => {
return data;
},
},
border: { radius: 50 }
}
aboutToAppear(): void {
ImageKnife.getInstance().initFileCache(getContext(this), 256, 256 * 1024 * 1024, 'ImageKnifeCache1')
}
build() {
Column() {
ImageKnifeComponent(
{ imageKnifeOption: this.ImageKnifeOption })
.height(this.currentHeight)
.width(this.currentWidth)
.margin({ top: 10 })
Button($r('app.string.load_memory'))
.onClick(() => {
this.ImageKnifeOption = {
loadSrc: 'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/3e/v3/LqRoLI-PRSu9Nqa8KdJ-pQ/dSqskBpSR9eraAMn7NBdqA.jpg',
objectFit: ImageFit.Contain,
writeCacheStrategy: CacheStrategy.Memory,
border: { radius: 50 },
}
})
Button($r('app.string.load_disk'))
.onClick(() => {
this.ImageKnifeOption = {
loadSrc: 'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/56/v3/8MdhfSsCSMKj4sA6okUWrg/5uBx56tLTUO3RYQl-E5JiQ.jpg',
objectFit: ImageFit.Contain,
writeCacheStrategy: CacheStrategy.File,
border: { radius: 50 },
}
})
Text($r('app.string.cur_cache_limit', this.markersLimitText, this.cacheUpLimit))
.fontSize(20)
.margin({ bottom: 8 });
Text($r('app.string.cur_cache_image_num', this.markersNumText, this.currentNum))
.fontSize(20)
.margin({ bottom: 8 });
Text($r('app.string.cur_cache_size', this.markersSizeText, this.currentSize)).fontSize(20).margin({ bottom: 20 });
Button($r('app.string.get_cur_memory_limit')).onClick(() => {
let result = ImageKnife.getInstance().getCacheLimitSize(CacheStrategy.Memory);
this.markersLimitText = getContext(this).resourceManager.getStringSync($r('app.string.memory'))
if (result) {
this.cacheUpLimit = result / (1024 * 1024);
} else {
this.cacheUpLimit = 0;
}
}).margin({ bottom: 8 });
Button($r('app.string.get_img_number_of_cache')).onClick(() => {
let result = ImageKnife.getInstance().getCurrentCacheNum(CacheStrategy.Memory);
this.markersNumText = getContext(this).resourceManager.getStringSync($r('app.string.memory'))
if (result) {
this.currentNum = result;
} else {
this.currentNum = 0;
}
}).margin({ bottom: 8 });
Button($r('app.string.get_cur_memory_size')).onClick(() => {
let result = ImageKnife.getInstance().getCurrentCacheSize(CacheStrategy.Memory);
this.markersSizeText = getContext(this).resourceManager.getStringSync($r('app.string.memory'))
if (result) {
this.currentSize = result / (1024 * 1024);
} else {
this.currentSize = 0;
}
}).margin({ bottom: 8 });
Button($r('app.string.get_cur_disk_limit')).onClick(() => {
let result = ImageKnife.getInstance().getCacheLimitSize(CacheStrategy.File);
this.markersLimitText = getContext(this).resourceManager.getStringSync($r('app.string.disk'))
if (result) {
this.cacheUpLimit = result / (1024 * 1024);
} else {
this.cacheUpLimit = 0;
}
}).margin({ bottom: 8 });
Button($r('app.string.get_img_number_of_disk')).onClick(() => {
let result = ImageKnife.getInstance().getCurrentCacheNum(CacheStrategy.File);
this.markersNumText = getContext(this).resourceManager.getStringSync($r('app.string.disk'))
if (result) {
this.currentNum = result;
} else {
this.currentNum = 0;
}
}).margin({ bottom: 8 });
Button($r('app.string.get_cur_disk_size')).onClick(() => {
let result = ImageKnife.getInstance().getCurrentCacheSize(CacheStrategy.File);
this.markersSizeText = getContext(this).resourceManager.getStringSync($r('app.string.disk'))
if (result) {
this.currentSize = result / (1024 * 1024);
} else {
this.currentSize = 0;
}
}).margin({ bottom: 8 });
}
.height('100%').width('100%').margin({ top: 50 })
}
}

View File

@ -0,0 +1,112 @@
/*
* Copyright (C) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an 'AS IS' BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { drawing, common2D } from '@kit.ArkGraphics2D';
import { ImageKnifeComponent, ImageKnifeOption } from '@ohos/imageknife';
@Entry
@Component
struct TestChangeColorPage {
private imageOne: Resource = $r('app.media.ic_test_change_color_png');
private imageTwo: Resource = $r('app.media.ic_test_change_color_png');
@State src: Resource = this.imageOne
@State src2: Resource = this.imageTwo
@State color: common2D.Color = {
alpha: 255,
red: 255,
green: 1,
blue: 1
};
@State DrawingColorFilterFirst: ColorFilter | undefined = undefined
build() {
Column() {
Text($r('app.string.select_color_btn')).margin({ top: 20 })
Row() {
Button($r('app.string.red')).backgroundColor(Color.Red).margin(5).onClick(() => {
this.color = {
alpha: 255,
red: 255,
green: 1,
blue: 1
};
})
Button($r('app.string.yellow')).backgroundColor(Color.Yellow).margin(5).onClick(() => {
this.color = {
alpha: 255,
red: 255,
green: 255,
blue: 1
};
})
Button($r('app.string.green')).backgroundColor(Color.Green).margin(5).onClick(() => {
this.color = {
alpha: 255,
red: 1,
green: 255,
blue: 1
};
})
Button($r('app.string.blue')).backgroundColor(Color.Blue).margin(5).onClick(() => {
this.color = {
alpha: 255,
red: 1,
green: 1,
blue: 255
};
})
}
.width('100%')
.height(50)
.justifyContent(FlexAlign.Center)
Text($r('app.string.master_image')).margin({ top: 20 })
ImageKnifeComponent({
imageKnifeOption: {
loadSrc: this.src
}
}).width(110).height(110)
Text($r('app.string.click_img_to_change_color')).margin({ top: 30 })
ImageKnifeComponent({
imageKnifeOption: {
loadSrc: this.src,
drawingColorFilter: this.DrawingColorFilterFirst
}
})
.onClick(() => {
this.DrawingColorFilterFirst =
drawing.ColorFilter.createBlendModeColorFilter(this.color, drawing.BlendMode.SRC_IN);
}).width(110).height(110)
Text($r('app.string.test_non_svg_color')).margin({ top: 30 })
ImageKnifeComponent({
imageKnifeOption: {
loadSrc: $r('app.media.ic_test_change_color_png'),
drawingColorFilter: drawing.ColorFilter.createBlendModeColorFilter(this.color, drawing.BlendMode.SRC_IN)
}
}).width(110).height(110)
Text($r('app.string.test_svg_color')).margin({ top: 30 })
ImageKnifeComponent({
imageKnifeOption: {
loadSrc: $r('app.media.ic_test_change_color_svg'),
drawingColorFilter: drawing.ColorFilter.createBlendModeColorFilter(this.color, drawing.BlendMode.SRC_IN)
}
}).width(110).height(110)
}.width('100%').height('100%')
}
}

View File

@ -0,0 +1,52 @@
/*
* Copyright (C) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an 'AS IS' BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { ImageKnifeComponent } from '@ohos/libraryimageknife';
@Entry
@Component
struct TestCommonImage {
private data: Array<string> = []
aboutToAppear(): void {
for (let index = 0; index < 30; index++) {
this.data.push(`https://img-blog.csdn.net/20140514114029140?${index}`)
}
}
build() {
Column() {
WaterFlow() {
ForEach(this.data,(item: string)=>{
FlowItem() {
Column(){
ImageKnifeComponent({
imageKnifeOption: {
loadSrc: item,
placeholderSrc: $r('app.media.loading'),
errorholderSrc: $r('app.media.failed'),
objectFit: ImageFit.Contain,
signature: 'aaa'
}
}).width('50%').height(200)
}
}.height(200)
.backgroundColor('#95efd2')
},(item: string) => item)
}.columnsTemplate('1fr 1fr')
.columnsGap(10)
.rowsGap(5)
.backgroundColor(0xFAEEE0)
.width('100%').height('100%')
}
}
}

View File

@ -0,0 +1,47 @@
/*
* Copyright (C) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an 'AS IS' BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { ImageKnifeComponent } from '@ohos/libraryimageknife'
@Entry
@Component
struct TestErrorHolderPage {
build() {
Column() {
Text('ImageKnifeComponent1').fontSize(20)
ImageKnifeComponent({
imageKnifeOption: {
loadSrc: 'abc',
errorholderSrc:$r('app.media.failed')
}
}).width(200).height(200)
Text('ImageKnifeComponent2').fontSize(20)
ImageKnifeComponent({
imageKnifeOption: {
loadSrc: 'abc',
errorholderSrc:$r('app.media.startIcon')
}
}).width(200).height(200)
Text('ImageKnifeComponent2').fontSize(20)
ImageKnifeComponent({
imageKnifeOption: {
loadSrc: 'abc',
errorholderSrc:$r('app.media.mask_starfish')
}
}).width(200).height(200)
}
.height('100%') .width('100%')
}
}

View File

@ -0,0 +1,39 @@
/*
* Copyright (C) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an 'AS IS' BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { ImageKnifeComponent,ImageKnifeOption } from '@ohos/libraryimageknife'
@Entry
@Component
struct TestPrefetchToFileCachePage {
@State imageKnifeOption: ImageKnifeOption = {
loadSrc:'https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658',
placeholderSrc:$r('app.media.loading'),
headerOption:[
{
key:'abc',
value:'单个'
}
]
}
build() {
Column() {
ImageKnifeComponent({
imageKnifeOption: this.imageKnifeOption
}).width(300).height(300)
}
.height('100%') .width('100%')
}
}

View File

@ -1,29 +1,25 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* Copyright (C) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* distributed under the License is distributed on an 'AS IS' BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
@Sendable
export class ObjectKey{
import { IndexComponent } from '@ohos/libraryimageknife'
private objectKey: string;
constructor(objectKey: string) {
this.objectKey = objectKey;
@Entry
@Component
struct TestHspPreLoadImage {
build() {
Column() {
IndexComponent()
}.width('100%').height('100%')
}
getKey(): string{
return this.objectKey;
}
}

View File

@ -0,0 +1,92 @@
/*
* Copyright (C) 2025 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an 'AS IS' BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { ImageKnifeComponent } from '@ohos/libraryimageknife';
import fs from '@ohos.file.fs';
@Entry
@Component
struct LocalImage {
scroller: Scroller = new Scroller;
build() {
Scroll(this.scroller) {
Column() {
Column() {
Text($r('app.string.base_image'))
.fontSize(20)
.fontWeight(FontWeight.Bold)
Row() {
Image($rawfile('rotate/rotate.jpg')).width(100).height(100).margin({ right: 10 })
ImageKnifeComponent({
imageKnifeOption: {
loadSrc: $rawfile('rotate/rotate.jpg'),
objectFit: ImageFit.Contain
}
}).width(100).height(100)
}
}
.margin({ bottom: 20 })
Column() {
Text($r('app.string.rotate_mirror'))
.fontSize(20)
.fontWeight(FontWeight.Bold)
Row() {
Image($rawfile('rotate/rotate_mirror.jpg')).width(100).height(100).margin({ right: 10 })
ImageKnifeComponent({
imageKnifeOption: {
loadSrc: $rawfile('rotate/rotate_mirror.jpg'),
objectFit: ImageFit.Contain
}
}).width(100).height(100)
}
}.margin({ bottom: 20 })
Column() {
Text($r('app.string.rotate_rotate90'))
.fontSize(20)
.fontWeight(FontWeight.Bold)
Row() {
Image($rawfile('rotate/rotate_rotate90.jpg')).width(100).height(100).margin({ right: 10 })
ImageKnifeComponent({
imageKnifeOption: {
loadSrc: $rawfile('rotate/rotate_rotate90.jpg'),
objectFit: ImageFit.Contain
}
}).width(100).height(100)
}
}.margin({ bottom: 20 })
Column() {
Text($r('app.string.rotate_mirror_rotate270'))
.fontSize(20)
.fontWeight(FontWeight.Bold)
Row() {
Image($rawfile('rotate/rotate_mirror_rotate270.jpg')).width(100).height(100).margin({ right: 10 })
ImageKnifeComponent({
imageKnifeOption: {
loadSrc: $rawfile('rotate/rotate_mirror_rotate270.jpg'),
objectFit: ImageFit.Contain
}
}).width(100).height(100)
}
}
}
.width('100%')
}
.height('100%')
}
}

View File

@ -0,0 +1,137 @@
/*
* Copyright (C) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an 'AS IS' BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { ImageKnifeComponent } from '@ohos/libraryimageknife'
@Observed
export class MsgModel {
id: string
cId: string
body: string
status: number
constructor(id: string, body: string, cId?: string) {
this.id = id
this.body = body
this.status = -1
this.cId = cId || ''
}
}
@Reusable
@Component
export struct MsgItem {
count: number = 0
private data: Array<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',
]
build(){
if (this.count % 2 == 0 && this.count <6){
ImageKnifeComponent({
imageKnifeOption:{
loadSrc:$r('app.media.startIcon'),
placeholderSrc:$r('app.media.loading')
},syncLoad:true
})
}else if (this.count > 6 && this.count - 6 < this.data.length){
ImageKnifeComponent({
imageKnifeOption:{
loadSrc:this.data[this.count - 6],
placeholderSrc:$r('app.media.loading')
},syncLoad:true
})
}else {
ImageKnifeComponent({
imageKnifeOption:{
loadSrc:$r('app.media.pngSample'),
placeholderSrc:$r('app.media.loading')
},syncLoad:true
})
}
}
}
@Entry
@Component
struct ImageTestPage {
count : number = 0
rCount: number = 0
scroller: Scroller = new Scroller()
@State list: MsgModel[] = []
@State imageSize: number =100
handAdd(){
this.count++
const msgItem = new MsgModel('add_id'+this.count, 'addBody'+this.count,'cId'+ this.count)
this.list.push(msgItem)
setTimeout(()=> {
msgItem.status = 1
},3000)
this.scroller.scrollEdge(Edge.Bottom)
}
build(){
Column(){
Row(){
Button('addItem').onClick(()=> {
this.handAdd()
})
Button('remove').onClick(()=> {
this.list.splice(0,1)
})
}
Row(){
Text($r('app.string.Click_on_add'))
.onClick(()=> {
this.imageSize = this.imageSize + 50
})
.width('50%').backgroundColor(0x88ff0000).textAlign(TextAlign.Center).height(50)
Text($r('app.string.Click_on_reduce'))
.onClick(()=> {
this.imageSize = Math.max(this.imageSize - 50, 0)
})
.width('50%').backgroundColor(0x88ff0000).textAlign(TextAlign.Center).height(50)
}.height(50).width('100%')
List({space: 20, scroller: this.scroller }) {
ForEach(this.list, (item: MsgModel)=> {
ListItem(){
MsgItem({count : this.count}).width(this.imageSize).height(this.imageSize);
}
},(item:MsgModel)=> item.id)
}.width('100%').height('auto').layoutWeight(1)
}
.width('100%')
.height('100%')
}
}

View File

@ -0,0 +1,387 @@
/*
* Copyright (C) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an 'AS IS' BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { ImageKnifeComponent, ImageKnifeData, ImageKnifeOption, ImageKnifeRequest } from '@ohos/libraryimageknife';
import { router } from '@kit.ArkUI';
@Entry
@Component
struct TestImageKnifeCallbackPage {
@State imageKnifeOption: ImageKnifeOption = {
loadSrc: '',
objectFit: ImageFit.Contain,
border: { radius: 50 }
};
@State currentWidth: number = 200
@State currentHeight: number = 200
@State url: string | undefined = ''
@State imageType: string | undefined = ''
@State imageWidth: number | undefined = 0
@State imageHeight: number | undefined = 0
@State imageSize: number | undefined = 0
@State componentWidth: number | undefined = 0
@State componentHeight: number | undefined = 0
@State frameNum: number | undefined = 0
@State decodeSize: string | undefined = ''
@State errMsg: string | undefined = ''
@State errPhase: string | undefined = ''
@State errCode: number | undefined = 0
@State httpCode: number | undefined = 0
@State reqStartTime: string | undefined = ''
@State reqEndTime: string | undefined = ''
@State reqCancelTime: string | undefined = ''
@State memoryStartTime: string | undefined = ''
@State memoryEndTime: string | undefined = ''
@State diskStartTime: string | undefined = ''
@State diskEndTime: string | undefined = ''
@State netStartTime: string | undefined = ''
@State netEndTime: string | undefined = ''
@State decodeStartTime: string | undefined = ''
@State decodeEndTime: string | undefined = ''
@State showChild: boolean = true;
@State requestFrom: string = '';
build() {
Column() {
Text($r('app.string.img_url', this.url)).fontSize(14)
Text($r('app.string.img_format', this.imageType)).fontSize(14)
Text($r('app.string.img_master_size', this.imageWidth, this.imageHeight, this.imageSize)).fontSize(14)
Text($r('app.string.componentWH', this.componentWidth, this.componentHeight)).fontSize(14)
Text($r('app.string.img_frame', this.frameNum)).fontSize(14)
Text($r('app.string.img_content_size', this.decodeSize)).fontSize(14)
Text($r('app.string.err_msg', this.errMsg)).fontSize(14)
Text($r('app.string.err_phase', this.errPhase)).fontSize(14)
Text($r('app.string.err_code', this.errCode)).fontSize(14)
Text($r('app.string.http_code', this.httpCode)).fontSize(14)
Text($r('app.string.req_start_time', this.reqStartTime)).fontSize(14)
Text($r('app.string.req_end_time', this.reqEndTime)).fontSize(14)
Text($r('app.string.req_cancel_time', this.reqCancelTime)).fontSize(14)
Text($r('app.string.memory_start_time', this.memoryStartTime)).fontSize(14)
Text($r('app.string.memory_end_time', this.memoryEndTime)).fontSize(14)
Text($r('app.string.disk_start_time', this.diskStartTime)).fontSize(14)
Text($r('app.string.disk_end_time', this.diskEndTime)).fontSize(14)
Text($r('app.string.net_start_time', this.netStartTime)).fontSize(14)
Text($r('app.string.net_end_time', this.netEndTime)).fontSize(14)
Text($r('app.string.decode_start_time', this.decodeStartTime)).fontSize(14)
Text($r('app.string.decode_end_time', this.decodeEndTime)).fontSize(14)
Text($r('app.string.request_data_from', this.requestFrom)).fontSize(14)
Scroll() {
Column() {
Row() {
Button($r('app.string.Network_images'))
.fontSize(13)
.onClick(() => {
this.destroy();
this.imageKnifeOption = {
loadSrc: 'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/10/v3/qaEzwkU0QeKb1yehnP2Xig/q7fxAlgMQKup-HUBayRLGQ.jpg',
objectFit: ImageFit.Contain,
onLoadListener: {
onLoadStart: (data) => {
this.analyzeStartCallBackData(data);
},
onLoadFailed: (res, req) => {
this.analyzeFailedBackData(res, req?.imageKnifeData);
},
onLoadSuccess: (data, imageData, req) => {
this.analyzeSuccessCallBackData(req?.imageKnifeData);
},
onLoadCancel: (res, req) => {
this.analyzeFailedBackData(res, req?.imageKnifeData);
}
},
border: { radius: 50 },
}
})
Button($r('app.string.gif'))
.fontSize(13)
.onClick(() => {
this.destroy();
this.imageKnifeOption = {
loadSrc: 'https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658',
objectFit: ImageFit.Contain,
onLoadListener: {
onLoadStart: (data) => {
this.analyzeStartCallBackData(data);
},
onLoadFailed: (res, req) => {
this.analyzeFailedBackData(res, req?.imageKnifeData);
},
onLoadSuccess: (data, imageData, req) => {
this.analyzeSuccessCallBackData(req?.imageKnifeData);
},
onLoadCancel: (res, req) => {
this.analyzeFailedBackData(res, req?.imageKnifeData);
}
},
border: { radius: 50 },
}
})
Button($r('app.string.local_pic'))
.fontSize(13)
.onClick(() => {
this.destroy();
this.imageKnifeOption = {
loadSrc: $r('app.media.pngSample'),
objectFit: ImageFit.Contain,
onLoadListener: {
onLoadStart: (data) => {
this.analyzeStartCallBackData(data);
},
onLoadFailed: (res, req) => {
this.analyzeFailedBackData(res, req?.imageKnifeData);
},
onLoadSuccess: (data, imageData, req) => {
this.analyzeSuccessCallBackData(req?.imageKnifeData);
},
onLoadCancel: (res, req) => {
this.analyzeFailedBackData(res, req?.imageKnifeData);
}
},
border: { radius: 50 },
}
})
}
Row() {
Button($r('app.string.net_load_failed'))
.fontSize(13)
.onClick(() => {
this.destroy();
this.imageKnifeOption = {
loadSrc: 'https://img-blog.csdn.net/20140514114039140',
objectFit: ImageFit.Contain,
onLoadListener: {
onLoadStart: (data) => {
this.analyzeStartCallBackData(data);
},
onLoadFailed: (res, req) => {
this.analyzeFailedBackData(res, req?.imageKnifeData);
},
onLoadSuccess: (data, imageData, req) => {
this.analyzeSuccessCallBackData(req?.imageKnifeData);
},
onLoadCancel: (res, req) => {
this.analyzeFailedBackData(res, req?.imageKnifeData);
}
},
border: { radius: 50 },
}
})
Button($r('app.string.local_load_failed'))
.fontSize(13)
.onClick(() => {
this.destroy();
this.imageKnifeOption = {
loadSrc: 'app.media.xxx',
objectFit: ImageFit.Contain,
onLoadListener: {
onLoadStart: (data) => {
this.analyzeStartCallBackData(data);
},
onLoadFailed: (res, req) => {
this.analyzeFailedBackData(res, req?.imageKnifeData);
},
onLoadSuccess: (data, imageData, req) => {
this.analyzeSuccessCallBackData(req?.imageKnifeData);
},
onLoadCancel: (res, req) => {
this.analyzeFailedBackData(res, req?.imageKnifeData);
}
},
border: { radius: 50 },
}
})
Button($r('app.string.share_load_failed'))
.fontSize(13)
.onClick(() => {
this.destroy();
this.imageKnifeOption = {
loadSrc: 'datashare://ssas',
objectFit: ImageFit.Contain,
onLoadListener: {
onLoadStart: (data) => {
this.analyzeStartCallBackData(data);
},
onLoadFailed: (res, req) => {
this.analyzeFailedBackData(res, req?.imageKnifeData);
},
onLoadSuccess: (data, imageData, req) => {
this.analyzeSuccessCallBackData(req?.imageKnifeData);
},
onLoadCancel: (res, req) => {
this.analyzeFailedBackData(res, req?.imageKnifeData);
}
},
border: { radius: 50 },
}
})
}
Button($r('app.string.test_cancel_callback_btn'))
.fontSize(13)
.onClick(() => {
this.destroy();
this.imageKnifeOption = {
loadSrc: 'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/bf/v3/lSjrRwFcS-ez6jp1ALSQFg/0n7R7XinSPyrYLqDu_1dfw.jpg',
objectFit: ImageFit.Contain,
onLoadListener: {
onLoadStart: (data) => {
this.showChild = false;
this.analyzeStartCallBackData(data);
},
onLoadFailed: (res, req) => {
this.analyzeFailedBackData(res, req?.imageKnifeData);
},
onLoadSuccess: (data, imageData, req) => {
this.analyzeSuccessCallBackData(req?.imageKnifeData);
},
onLoadCancel: (res, req) => {
this.analyzeFailedBackData(res, req?.imageKnifeData);
}
},
border: { radius: 50 },
}
})
Button($r('app.string.list_pic'))
.fontSize(13)
.onClick(() => {
router.push({
url: 'pages/TestListImageKnifeCallbackPage',
});
})
if (this.showChild) {
ImageKnifeComponent(
{ imageKnifeOption: this.imageKnifeOption })
.height(this.currentHeight)
.width(this.currentWidth)
.margin({ top: 20, bottom: 20 })
}
}
.width('100%')
}
}.alignItems(HorizontalAlign.Start)
}
formatDate(time: number | undefined) {
if (!time) {
return;
}
let date = new Date(time);
const year = date.getFullYear().toString()
let month = (date.getMonth() + 1).toString()
let day = date.getDate().toString()
let hour = date.getHours().toString()
let min = date.getMinutes().toString()
let seconds = date.getSeconds().toString()
let mill = date.getMilliseconds();
return `${year}-${month}-${day} ${hour}:${min}:${seconds}:${mill}`
}
analyzeStartCallBackData(req: ImageKnifeRequest | undefined) {
let data = req?.imageKnifeData;
if (data) {
if (typeof req?.imageKnifeOption.loadSrc == 'string') {
this.url = req?.imageKnifeOption.loadSrc;
}
this.componentWidth = req?.componentWidth;
this.componentHeight = req?.componentHeight;
this.reqStartTime = this.formatDate(data.timeInfo?.requestStartTime);
this.memoryStartTime = this.formatDate(data.timeInfo?.memoryCheckStartTime);
this.memoryEndTime = this.formatDate(data.timeInfo?.memoryCheckEndTime);
this.requestFrom = '';
}
}
analyzeSuccessCallBackData(data: ImageKnifeData | undefined) {
if (data) {
this.imageWidth = data.imageWidth;
this.imageHeight = data.imageHeight;
this.imageSize = data.bufSize;
this.frameNum = data.frameCount;
this.httpCode = data.httpCode
this.decodeSize = JSON.stringify(data.decodeImages);
this.imageType = data.type;
this.reqEndTime = this.formatDate(data.timeInfo?.requestEndTime);
this.diskStartTime = this.formatDate(data.timeInfo?.diskCheckStartTime);
this.diskEndTime = this.formatDate(data.timeInfo?.diskCheckEndTime);
this.netStartTime = this.formatDate(data.timeInfo?.netRequestStartTime);
this.netEndTime = this.formatDate(data.timeInfo?.netRequestEndTime);
this.decodeStartTime = this.formatDate(data.timeInfo?.diskCheckStartTime);
this.decodeEndTime = this.formatDate(data.timeInfo?.diskCheckEndTime);
if (data.timeInfo?.netRequestEndTime !== undefined) {
this.requestFrom = 'Http request';
} else if (data.timeInfo?.diskCheckEndTime !== undefined) {
this.requestFrom = 'File Cache';
} else {
this.requestFrom = 'Memory Cache';
}
}
}
analyzeFailedBackData(res: string, data: ImageKnifeData | undefined) {
if (data) {
this.errMsg = res;
this.errPhase = data.errorInfo?.phase;
this.errCode = data.errorInfo?.code;
this.httpCode = data.httpCode;
this.reqEndTime = this.formatDate(data.timeInfo?.requestEndTime);
this.diskStartTime = this.formatDate(data.timeInfo?.diskCheckStartTime);
this.diskEndTime = this.formatDate(data.timeInfo?.diskCheckEndTime);
this.netStartTime = this.formatDate(data.timeInfo?.netRequestStartTime);
this.netEndTime = this.formatDate(data.timeInfo?.netRequestEndTime);
this.decodeStartTime = this.formatDate(data.timeInfo?.diskCheckStartTime);
this.decodeEndTime = this.formatDate(data.timeInfo?.diskCheckEndTime);
this.reqCancelTime = this.formatDate(data.timeInfo?.requestCancelTime)
this.requestFrom = '';
}
}
destroy() {
this.currentWidth = 200
this.currentHeight = 200
this.url = ''
this.imageType = ''
this.imageWidth = 0
this.imageHeight = 0
this.imageSize = 0
this.componentWidth = 0
this.componentHeight = 0
this.frameNum = 0
this.decodeSize = ''
this.errMsg = ''
this.errPhase = ''
this.errCode = 0
this.httpCode = 0
this.reqStartTime = ''
this.reqEndTime = ''
this.reqCancelTime = ''
this.memoryStartTime = ''
this.memoryEndTime = ''
this.diskStartTime = ''
this.diskEndTime = ''
this.netStartTime = ''
this.netEndTime = ''
this.decodeStartTime = ''
this.decodeEndTime = ''
this.showChild = true;
}
}

View File

@ -0,0 +1,86 @@
/*
* Copyright (C) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an 'AS IS' BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { ImageKnifeComponent, ImageKnife, ImageKnifeOption, CacheStrategy } from '@ohos/libraryimageknife'
@Entry
@Component
struct TestIsUrlExist {
@State imageKnifeOption: ImageKnifeOption = {
loadSrc: $r('app.media.startIcon'),
placeholderSrc: $r('app.media.loading'),
errorholderSrc:$r('app.media.failed')
}
@State source: PixelMap | string | Resource = $r('app.media.startIcon')
@State source1: PixelMap | string | Resource = $r('app.media.startIcon')
build() {
Column() {
Flex() {
Button($r('app.string.Preloading_GIF')).onClick(() => {
this.imageKnifeOption.loadSrc =
'https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658'
})
Button($r('app.string.Retrieve_GIF_from_memory')).onClick(() => {
ImageKnife.getInstance()
.getCacheImage('https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658',
CacheStrategy.Memory)
.then((data) => {
this.source = data !== undefined ? data.source : $r('app.media.startIcon')
})
})
Button($r('app.string.Retrieve_GIF_from_disk')).onClick(() => {
ImageKnife.getInstance()
.getCacheImage('https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658',
CacheStrategy.File)
.then((data) => {
this.source1 = data !== undefined ? data.source : $r('app.media.startIcon')
})
})
}
Flex() {
Button($r('app.string.Preloading_static_images')).onClick(() => {
this.imageKnifeOption.loadSrc =
'https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp'
})
Button($r('app.string.Retrieve_images_from_memory')).onClick(() => {
ImageKnife.getInstance()
.getCacheImage('https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp',
CacheStrategy.Memory)
.then((data) => {
this.source = data!.source
})
})
Button($r('app.string.Retrieve_images_from_disk')).onClick(() => {
ImageKnife.getInstance()
.getCacheImage('https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp',
CacheStrategy.File)
.then((data) => {
this.source1 = data!.source
})
})
}.margin({ top: 10 })
ImageKnifeComponent({
imageKnifeOption: this.imageKnifeOption
}).width(200).height(200).margin({ top: 10 })
Image(this.source).margin({ top: 10 })
.width(200).height(200)
Image(this.source1).margin({ top: 10 })
.width(200).height(200)
}
.height('100%').width('100%')
}
}

View File

@ -0,0 +1,103 @@
/*
* Copyright (C) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an 'AS IS' BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { ImageKnifeComponent} from '@ohos/libraryimageknife';
class ArrayElement {
public src: string = '';
public w: number = 0;
public h: number = 0;
}
@Entry
@Component
struct TestListImageKnifeCallbackPage {
private wid: number = 200;
private hig: number = 200;
private dataArray: ESObject[] = [
'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/56/v3/8MdhfSsCSMKj4sA6okUWrg/5uBx56tLTUO3RYQl-E5JiQ.jpg',
'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/56/v3/8MdhfSsCSMKj4sA6okUWrg/5uBx56tLTUO3RYQl-E5JiQ.jpg',
'https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658',
'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/78/v3/qQJpAtRGQe2e_VhbGHDgIw/b3zlit99S6GybD3XdNwqJw.jpg',
'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/55/v3/5DZ2LLqYSsK85-shqgLveQ/7ZXcyCWNTvOzQP5FFLBGkg.jpg',
'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/3e/v3/LqRoLI-PRSu9Nqa8KdJ-pQ/dSqskBpSR9eraAMn7NBdqA.jpg',
'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/25/v3/jgB2ekkTRX-3yTYZalnANQ/xff_x9cbSPqb7fbNwgJa7A.jpg',
'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/fb/v3/alXwXLHKSyCAIWt_ydgD2g/BCCuu25TREOitQxM7eYOEw.jpg',
'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/63/v3/qbe6NZkCQyGcITvdWoZBgg/Y-5U1z3GT_yaK8CBD3jkwg.jpg',
'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/16/v3/fm2tO4TsRH6mv_D_nSSd5w/FscLpLwQQ-KuV7oaprFK2Q.jpg',
'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/89/v3/UAUvtPHqRD-GWWANsEC57Q/zcRJCQebQ322Aby4jzmwmQ.jpg',
'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/30/v3/tUUzzx73R4yp8G--lMhuWQ/EBbcu_dLTT-Jj68XAh6mtA.jpg',
'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/76/v3/EyF6z4FISpCHhae38eEexw/OtyAiu-zSSevNQYvUdtVmA.jpg',
'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/37/v3/12rH1yiEQmK9wlOOcy5avQ/RzBXiEBRRqOC7LRkwNj6VA.jpg',
'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/9a/v3/TpRN4AIzRoyUXIqWdKoE0g/ShOnD_tfS46HDbpSWhbCkQ.jpg',
'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/03/v3/H3X17s8eTdS2w56JgbB5jQ/a45sT-j8Sbe8sSQXTzeYvQ.jpg',
'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/10/v3/qaEzwkU0QeKb1yehnP2Xig/q7fxAlgMQKup-HUBayRLGQ.jpg',
'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/96/v3/rMJJoAflTDSWa1z2pHs2wg/8dOqD0GlQBOCL5AvQok9FQ.jpg',
'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/ed/v3/KMO4D6D2QGuVOCLX4AhOFA/ef51xAaLQuK7BsnuD9abog.jpg',
'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/d9/v3/FSZH0aTdSqWxeAaxoPvi0g/RqxPxUCXQFiTMBfKTF9kkw.jpg',
'https://hbimg.huabanimg.com/cc6af25f8d782d3cf3122bef4e61571378271145735e9-vEVggB',
'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/bf/v3/lSjrRwFcS-ez6jp1ALSQFg/0n7R7XinSPyrYLqDu_1dfw.jpg',
'https://img-blog.csdn.net/20140514114029140',
'https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp',
$r('app.media.pngSample'),
$r('app.media.rabbit')
]
private data: Array<ArrayElement> = [];
aboutToAppear(): void {
for (let i = 0; i < this.dataArray.length; i++) {
let element: ArrayElement = {
src: this.dataArray[i],
w: this.wid -(i*5),
h: this.hig -(i*5)
}
this.data.push(element);
}
}
build() {
List({ space: 3 }) {
ForEach(this.data, (item: ArrayElement) => {
ListItem() {
ImageKnifeComponent({
imageKnifeOption:
{
loadSrc: item.src,
objectFit: ImageFit.Contain,
onLoadListener: {
onLoadStart: (data) => {
console.log('listCache start:{ url:' + data?.imageKnifeOption.loadSrc +
',componentWidth:' + data?.componentWidth +
',componentHeight:' + data?.componentHeight +
'},' + JSON.stringify(data?.imageKnifeData))
},
onLoadFailed: (res, req) => {
console.log('listCache onLoadFailed:res:' + res + ';' + JSON.stringify(req?.imageKnifeData))
},
onLoadSuccess: (data, imageData,req) => {
console.log('listCache onLoadSuccess:' + JSON.stringify(req?.imageKnifeData))
},
onLoadCancel: (res, req) => {
console.log('listCache onLoadCancel:res:' + res + ';' + JSON.stringify(req?.imageKnifeData))
}
},
border: { radius: 50 },
}
}).height(item.w).width(item.h)
}.width('100%')
}, (item: ArrayElement,index) => (item.src+index))
}.width('100%').height('100%')
}
}

View File

@ -0,0 +1,101 @@
/*
* Copyright (C) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an 'AS IS' BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { ImageKnife, ImageKnifeComponent, ImageKnifeOption } from '@ohos/libraryimageknife';
@Entry
@Component
struct TestLoadCancelListenerPage {
@State currentWidth: number = 200
@State currentHeight: number = 200
@State showChild: boolean = true;
@State text: string = '';
@State ImageKnifeOption: ImageKnifeOption = {
loadSrc: '',
objectFit: ImageFit.Contain,
border: { radius: 50 }
};
build() {
Column() {
Text($r('app.string.onLoadCancel_reason', this.text)).margin(20).fontSize(15)
Button($r('app.string.rm_component_of_net'))
.margin(20)
.onClick(() => {
this.clearCache();
this.ImageKnifeOption = {
loadSrc: 'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/76/v3/EyF6z4FISpCHhae38eEexw/OtyAiu-zSSevNQYvUdtVmA.jpg',
objectFit: ImageFit.Contain,
onLoadListener: {
onLoadStart: () => {
this.showChild = false;
},
onLoadCancel: (res) => {
this.text = res
console.log('TestLoadCancelListenerPage----onLoadCancel> url:' + res)
}
},
border: { radius: 50 }
}
})
Button($r('app.string.component_display'))
.margin(20).onClick(() => {
this.text = '';
this.showChild = true;
this.ImageKnifeOption = {
loadSrc: '',
objectFit: ImageFit.Contain,
border: { radius: 50 }
}
})
Button($r('app.string.rm_component_of_local'))
.margin(20)
.onClick(() => {
this.clearCache();
this.ImageKnifeOption = {
loadSrc: $r('app.media.loading'),
objectFit: ImageFit.Contain,
onLoadListener: {
onLoadStart: () => {
this.showChild = false;
},
onLoadCancel: (res) => {
this.text = res
console.log('TestLoadCancelListenerPage----onLoadCancel> url:' + res)
}
},
border: { radius: 50 }
}
})
if (this.showChild) {
ImageKnifeComponent(
{ imageKnifeOption: this.ImageKnifeOption })
.height(150)
.width(150)
.backgroundColor(Color.Orange)
.margin({ top: 20 })
}
}
.height('100%')
.width('100%')
}
clearCache(){
ImageKnife.getInstance().removeAllMemoryCache();
}
}

View File

@ -0,0 +1,50 @@
/*
* Copyright (C) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an 'AS IS' BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { ImageKnifeComponent,ImageKnife,ImageKnifeOption } from '@ohos/libraryimageknife'
@Entry
@Component
struct TestPrefetchToFileCachePage {
@State imageKnifeOption: ImageKnifeOption = {
loadSrc:$r('app.media.startIcon'),
placeholderSrc:$r('app.media.loading'),
errorholderSrc:$r('app.media.failed')
}
async preload(url:string) {
let fileCachePath = await ImageKnife.getInstance().preLoadCache(url)
console.log('preload-fileCachePath=='+ fileCachePath)
}
async preload1(url:string) {
let fileCachePath = await ImageKnife.getInstance().preLoadCache({ loadSrc: url })
console.log('preload-fileCachePath1=='+ fileCachePath)
}
build() {
Column() {
Button($r('app.string.Preloading_images_to_file_cache_using_URL')).margin({top:10}).onClick(async ()=>{
await this.preload('https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658')
})
Button($r('app.string.Preloading_images_to_file_cache_using_option')).margin({top:10}).onClick(async ()=>{
await this.preload1('https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658')
})
Button($r('app.string.Load_image_offline_after_preloading')).margin({top:10}).onClick(()=>{
this.imageKnifeOption.loadSrc = 'https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658'
})
ImageKnifeComponent({
imageKnifeOption: this.imageKnifeOption
}).width(300).height(300).margin({top:30})
}
.height('100%') .width('100%')
}
}

View File

@ -0,0 +1,126 @@
/*
* Copyright (C) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an 'AS IS' BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { ImageKnifeComponent, ImageKnife, ImageKnifeOption, CacheStrategy } from '@ohos/libraryimageknife'
@Entry
@Component
struct TestRemoveCache {
@State imageKnifeOption: ImageKnifeOption = {
loadSrc: $r('app.media.startIcon'),
placeholderSrc: $r('app.media.loading'),
errorholderSrc:$r('app.media.failed')
}
@State source: PixelMap | string | Resource = $r('app.media.startIcon');
@State source1: PixelMap | string | Resource = $r('app.media.startIcon');
@State url: string = '';
build() {
Column() {
Flex() {
Button($r('app.string.Preloading_GIF')).onClick(() => {
this.imageKnifeOption.loadSrc = 'https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658';
this.url = 'https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658';
})
.margin({left:10})
Button($r('app.string.Retrieve_GIF_from_memory')).onClick(() => {
ImageKnife.getInstance()
.getCacheImage('https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658',
CacheStrategy.Memory)
.then((data) => {
this.source = data !== undefined ? data.source : $r('app.media.startIcon');
})
})
.margin({left:10})
Button($r('app.string.Retrieve_GIF_from_disk')).onClick(() => {
ImageKnife.getInstance()
.getCacheImage('https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658',
CacheStrategy.File)
.then((data) => {
this.source1 = data !== undefined ? data.source : $r('app.media.startIcon');
})
})
.margin({left:10})
}
Flex() {
Button($r('app.string.Preloading_static_images')).onClick(() => {
this.imageKnifeOption.loadSrc = 'https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp';
this.url = 'https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp';
})
.margin({left:10})
Button($r('app.string.Retrieve_images_from_memory')).onClick(() => {
ImageKnife.getInstance()
.getCacheImage('https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp',
CacheStrategy.Memory)
.then((data) => {
this.source = data!.source;
})
})
.margin({left:10})
Button($r('app.string.Retrieve_images_from_disk')).onClick(() => {
ImageKnife.getInstance()
.getCacheImage('https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp',
CacheStrategy.File)
.then((data) => {
this.source1 = data!.source;
})
})
.margin({left:10})
}.margin({ top: 10 })
Flex() {
Button($r('app.string.Delete_all_caches')).onClick(() => {
ImageKnife.getInstance()
.removeAllMemoryCache()
ImageKnife.getInstance()
.removeAllFileCache()
})
.margin({left:5})
Button($r('app.string.Delete_all_memory_caches')).onClick(() => {
ImageKnife.getInstance()
.removeAllMemoryCache()
})
.margin({left:5})
Button($r('app.string.Delete_all_file_caches')).onClick(() => {
ImageKnife.getInstance()
.removeAllFileCache()
})
.margin({left:5})
}.margin({ top: 10 })
Flex() {
Button($r('app.string.Delete_all_custom_memory_caches')).onClick(() => {
ImageKnife.getInstance()
.removeMemoryCache(this.url)
})
.margin({left:20})
Button($r('app.string.Delete_all_custom_file_caches')).onClick(() => {
ImageKnife.getInstance()
.removeFileCache(this.url)
})
.margin({left:20})
}.margin({ top: 10 })
ImageKnifeComponent({
imageKnifeOption: this.imageKnifeOption
}).width(200).height(200).margin({ top: 10 })
Image(this.source).margin({ top: 10 })
.width(200).height(200)
Image(this.source1).margin({ top: 10 })
.width(200).height(200)
}
.height('100%').width('100%')
}
}

View File

@ -0,0 +1,68 @@
/*
* Copyright (C) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an 'AS IS' BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { ImageKnifeComponent, ImageKnife, ImageKnifeOption } from '@ohos/libraryimageknife'
@Entry
@Component
struct TestSetCustomImagePage {
@State imageKnifeOption: ImageKnifeOption = {
loadSrc: $r('app.media.startIcon'),
placeholderSrc: $r('app.media.loading')
}
aboutToAppear(): void {
ImageKnife.getInstance().setCustomGetImage(custom)
}
aboutToDisappear(): void {
ImageKnife.getInstance().setCustomGetImage()
}
getResourceString(res:Resource){
return getContext().resourceManager.getStringSync(res.id)
}
build() {
Column() {
Button(this.getResourceString($r('app.string.Custom_network_download')) + ' a').onClick(()=>{
this.imageKnifeOption ={
loadSrc: 'aaa',
placeholderSrc: $r('app.media.loading')
}
})
Button(this.getResourceString($r('app.string.Custom_network_download')) + ' b').onClick(()=>{
this.imageKnifeOption = {
loadSrc: 'bbb',
placeholderSrc: $r('app.media.loading')
}
})
Button(this.getResourceString($r('app.string.Custom_network_download')) + ' c').onClick(()=>{
this.imageKnifeOption = {
loadSrc: 'ccc',
placeholderSrc: $r('app.media.loading')
}
})
ImageKnifeComponent({
imageKnifeOption: this.imageKnifeOption
}).width(300)
.height(300)
}
.width('100%')
.height('100%')
}
}
@Concurrent
async function custom(context: Context, src: string | PixelMap | Resource,headers?: Record<string,Object>): Promise<ArrayBuffer | undefined> {
console.info('ImageKnife:: custom download' + src)
// 举例写死从本地文件读取,也可以自己请求网络图片
let buffer = context.resourceManager.getMediaContentSync($r('app.media.pngSample').id).buffer as ArrayBuffer
return buffer
}

View File

@ -0,0 +1,79 @@
/*
* Copyright (C) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an 'AS IS' BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { ImageKnifeComponent, ImageKnifeOption } from '@ohos/libraryimageknife'
@ComponentV2
export struct ZuImage {
@Param @Require src: PixelMap | ResourceStr | string | undefined
@Param @Require placeholderSrc: PixelMap | ResourceStr | string | undefined
@Local errorholderSrc: PixelMap | ResourceStr | string | undefined
build() {
if (this.src) {
//当前版本存在bug
ImageKnifeComponent({
imageKnifeOption: {
loadSrc: this.src,
placeholderSrc: this.placeholderSrc,
errorholderSrc: this.errorholderSrc ?? this.placeholderSrc,
objectFit: ImageFit.Cover
}
})
} else {
Image(this.placeholderSrc)
.objectFit(ImageFit.Cover)
}
}
}
@Entry
@ComponentV2
struct TestTaskResourcePage {
@Local stateMenus: Array<string> = [
'https://hbimg.huabanimg.com/cc6af25f8d782d3cf3122bef4e61571378271145735e9-vEVggB',
'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/bf/v3/lSjrRwFcS-ez6jp1ALSQFg/0n7R7XinSPyrYLqDu_1dfw.jpg',
'https://img-blog.csdn.net/20140514114029140',
'https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp',
]
@Builder
_buildItem(item: string) {
Column({ space: 8 }) {
ZuImage({
src: item,
placeholderSrc: $r('app.media.loading')
}).width(44)
.height(44)
}
}
build() {
Grid() {
ForEach(this.stateMenus, (item: string) => {
GridItem() {
this._buildItem(item)
}
})
}.width('100%')
.columnsTemplate('1fr 1fr 1fr 1fr 1fr')
.rowsGap(24)
.padding({
top: 24,
bottom: 24,
left: 24,
right: 24
})
}
}

View File

@ -0,0 +1,74 @@
/*
* Copyright (C) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an 'AS IS' BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { ImageKnifeComponent,CacheStrategy,ImageKnifeOption } from '@ohos/libraryimageknife'
@Entry
@Component
struct TestWriteCacheStage {
@State imageKnifeOption1: ImageKnifeOption = {
loadSrc:$r('app.media.startIcon'),
placeholderSrc:$r('app.media.loading'),
errorholderSrc:$r('app.media.failed')
}
@State imageKnifeOption2: ImageKnifeOption = {
loadSrc:$r('app.media.startIcon'),
placeholderSrc:$r('app.media.loading'),
errorholderSrc:$r('app.media.failed')
}
@State imageKnifeOption3: ImageKnifeOption = {
loadSrc:$r('app.media.startIcon'),
placeholderSrc:$r('app.media.loading'),
errorholderSrc:$r('app.media.failed')
}
build() {
Column() {
Button($r('app.string.Write_memory_and_file')).margin({top:10}).onClick(async ()=>{
this.imageKnifeOption1 = {
loadSrc:'https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp',
placeholderSrc:$r('app.media.loading'),
errorholderSrc:$r('app.media.failed'),
writeCacheStrategy:CacheStrategy.Default
}
})
ImageKnifeComponent({
imageKnifeOption: this.imageKnifeOption1
}).width(200).height(200).margin({top:10})
Button($r('app.string.Write_memory')).margin({top:10}).onClick(async ()=>{
this.imageKnifeOption2 = {
loadSrc:'https://hbimg.huabanimg.com/cc6af25f8d782d3cf3122bef4e61571378271145735e9-vEVggB',
placeholderSrc:$r('app.media.loading'),
errorholderSrc:$r('app.media.failed'),
writeCacheStrategy:CacheStrategy.Memory
}
})
ImageKnifeComponent({
imageKnifeOption: this.imageKnifeOption2
}).width(200).height(200).margin({top:10})
Button($r('app.string.Write_file')).margin({top:10}).onClick(async ()=>{
this.imageKnifeOption3 = {
loadSrc:'https://img-blog.csdn.net/20140514114029140',
placeholderSrc:$r('app.media.loading'),
errorholderSrc:$r('app.media.failed'),
writeCacheStrategy:CacheStrategy.File
}
})
ImageKnifeComponent({
imageKnifeOption: this.imageKnifeOption3
}).width(200).height(200).margin({top:10})
}
.height('100%') .width('100%')
}
}

View File

@ -0,0 +1,51 @@
/*
* Copyright (C) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an 'AS IS' BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { ImageKnifeComponent, ImageKnifeOption } from '@ohos/libraryimageknife'
import matrix4 from '@ohos.matrix4'
@Entry
@Component
struct TransformPage {
private custom_scale:number = 1
@State matrix1:object = matrix4.identity().scale({ x: 1, y: 1 })
@State ImageKnifeOption: ImageKnifeOption = {
loadSrc: $r('app.media.rabbit'),
placeholderSrc: $r('app.media.loading'),
errorholderSrc: $r('app.media.app_icon'),
objectFit: ImageFit.Contain,
border: { radius: 50 }
}
build() {
Column() {
ImageKnifeComponent({ imageKnifeOption: this.ImageKnifeOption }).height(200).width(200)
.transform(this.matrix1)
// Image($r('app.media.rabbit')).objectFit(ImageFit.Contain).height(200).width(200).transform(this.matrix1)
Button($r('app.string.Enlarge')).onClick(()=>{
this.custom_scale = this.custom_scale * 2
this.matrix1 = matrix4.identity().scale({ x: this.custom_scale, y: this.custom_scale })
})
Button($r('app.string.Reduce')).onClick(()=>{
this.custom_scale = this.custom_scale / 2
this.matrix1 = matrix4.identity().scale({ x: this.custom_scale, y: this.custom_scale })
})
}
.width('100%')
.height('100%')
}
}

View File

@ -0,0 +1,98 @@
/*
* Copyright (C) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an 'AS IS' BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { ImageKnifeComponent, ImageKnifeOption } from '@ohos/libraryimageknife'
// 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
scalable: boolean = true;
@State calcImgSize: number = 100
aboutToAppear(): void {
this.userInfoUpdate()
this.setImageSize()
}
setImageSize() {
if (!this.scalable) {
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.loading'),
errorholderSrc: $r('app.media.failed'),
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')
}
}
}

View File

@ -0,0 +1,94 @@
/*
* Copyright (C) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an 'AS IS' BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { CommonDataSource } from './model/CommonDataSource'
import { UserAvatar } from './User'
@Entry
@Component
struct Index {
@State hotCommendList:CommonDataSource<string> = new CommonDataSource<string>([])
private data:string[] = [
'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/56/v3/8MdhfSsCSMKj4sA6okUWrg/5uBx56tLTUO3RYQl-E5JiQ.jpg',
'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/e2/v3/4zI1Xm_3STmV30aZXWRrKw/6aN7WodDRUiBApgffiLPCg.jpg',
'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/42/v3/2dSQCqERTP2TTPyssOMEbQ/zL1ebnKKQ_ilqTDcwCAkOw.jpg',
'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/78/v3/qQJpAtRGQe2e_VhbGHDgIw/b3zlit99S6GybD3XdNwqJw.jpg',
'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/55/v3/5DZ2LLqYSsK85-shqgLveQ/7ZXcyCWNTvOzQP5FFLBGkg.jpg',
'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/3e/v3/LqRoLI-PRSu9Nqa8KdJ-pQ/dSqskBpSR9eraAMn7NBdqA.jpg',
'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/25/v3/jgB2ekkTRX-3yTYZalnANQ/xff_x9cbSPqb7fbNwgJa7A.jpg',
'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/fb/v3/alXwXLHKSyCAIWt_ydgD2g/BCCuu25TREOitQxM7eYOEw.jpg',
'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/63/v3/qbe6NZkCQyGcITvdWoZBgg/Y-5U1z3GT_yaK8CBD3jkwg.jpg',
'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/16/v3/fm2tO4TsRH6mv_D_nSSd5w/FscLpLwQQ-KuV7oaprFK2Q.jpg',
'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/89/v3/UAUvtPHqRD-GWWANsEC57Q/zcRJCQebQ322Aby4jzmwmQ.jpg',
'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/30/v3/tUUzzx73R4yp8G--lMhuWQ/EBbcu_dLTT-Jj68XAh6mtA.jpg',
'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/76/v3/EyF6z4FISpCHhae38eEexw/OtyAiu-zSSevNQYvUdtVmA.jpg',
'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/37/v3/12rH1yiEQmK9wlOOcy5avQ/RzBXiEBRRqOC7LRkwNj6VA.jpg',
'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/9a/v3/TpRN4AIzRoyUXIqWdKoE0g/ShOnD_tfS46HDbpSWhbCkQ.jpg',
'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/03/v3/H3X17s8eTdS2w56JgbB5jQ/a45sT-j8Sbe8sSQXTzeYvQ.jpg',
'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/10/v3/qaEzwkU0QeKb1yehnP2Xig/q7fxAlgMQKup-HUBayRLGQ.jpg',
'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/96/v3/rMJJoAflTDSWa1z2pHs2wg/8dOqD0GlQBOCL5AvQok9FQ.jpg',
'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/ed/v3/KMO4D6D2QGuVOCLX4AhOFA/ef51xAaLQuK7BsnuD9abog.jpg',
'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/d9/v3/FSZH0aTdSqWxeAaxoPvi0g/RqxPxUCXQFiTMBfKTF9kkw.jpg',
'https://hbimg.huabanimg.com/cc6af25f8d782d3cf3122bef4e61571378271145735e9-vEVggB',
'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/bf/v3/lSjrRwFcS-ez6jp1ALSQFg/0n7R7XinSPyrYLqDu_1dfw.jpg',
'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%')
}
}

View File

@ -1,82 +0,0 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {ImageKnifeOption,ImageKnifeComponent} from '@ohos/libraryimageknife'
@Entry
@Component
struct BasicTestFeatureAbilityPage {
@Watch("watchPathChange") @State filePath: string = "查看featureAbility路径";
watchPathChange() {
console.log("watchPathChange")
}
urls: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",
]
@State options:Array<ImageKnifeOption> = new Array
aboutToAppear(){
this.options = this.urls.map<ImageKnifeOption>((url:string)=>{
return {
loadSrc:url
}
})
console.log('this.options length ='+this.options.length)
}
build() {
Stack({ alignContent: Alignment.TopStart }) {
Column() {
List({ space: 20, initialIndex: 0 }) {
ForEach(this.options, (item:ImageKnifeOption) => {
ListItem() {
ImageKnifeComponent({imageKnifeOption:item}).width(300).height(300)
}
}, (item:ImageKnifeOption )=> item.loadSrc as string)
}
.listDirection(Axis.Vertical) // 排列方向
.divider({ strokeWidth: 2, color: 0xFFFFFF, startMargin: 20, endMargin: 20 }) // 每行之间的分界线
.edgeEffect(EdgeEffect.None) // 滑动到边缘无效果
.chainAnimation(false) // 联动特效关闭
.onScrollIndex((firstIndex: number, lastIndex: number) => {
console.info('first' + firstIndex)
console.info('last' + lastIndex)
})
}.width('100%')
}.width('100%').height('100%').backgroundColor(0xDCDCDC).padding({ top: 5 })
}
}

View File

@ -1,161 +0,0 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an 'AS IS' BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { FileUtils, ImageKnifeGlobal} from '@ohos/libraryimageknife'
import resourceManager from '@ohos.resourceManager';
import { BusinessError } from '@ohos.base'
import common from '@ohos.app.ability.common';
@Entry
@Component
struct basicTestFileIOPage {
@State filePath: string = '查看featureAbility路径';
appFilePath = '';
appCachePath = '';
@State imageHint: string = '文字提醒1'
@State imageHint2: string = '文字提醒2'
@State imageFile: string = ''
@State imageRes: Resource = $r('app.media.pngSample')
@State imagePixelMap?: PixelMap = undefined
@State normalPixelMap: boolean = false;
@State normalResource: boolean = false;
watchPathChange() {
console.log('watchPathChange');
}
build() {
Scroll() {
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Text(this.filePath).fontSize(20)
Button('featureAbility.getContext().getFilesDir()')
.margin({ top: 10 })
.onClick(() => {
let data:string = (ImageKnifeGlobal.getInstance().getHapContext() as common.UIAbilityContext).filesDir as string;
console.log('ImageKnife filesPath = ' + data)
this.filePath = data
this.appFilePath = data;
})
Button('featureAbility.getContext().getCacheDir()')
.margin({ top: 10 })
.onClick(() => {
let data:string = (ImageKnifeGlobal.getInstance().getHapContext() as common.UIAbilityContext).cacheDir as string;
console.log('ImageKnife cachesPath = ' + data)
this.filePath = data
this.appFilePath = data;
})
Text(this.imageHint)
Button('files目录创建Folder1和Folder2 验证statSync mkdirSync')
.margin({ top: 10 })
.onClick(() => {
if(this.appFilePath == '' || this.appFilePath == null){
this.imageHint = 'appFilePath未取到值,请按顺序从上往下,从左往右依次测试'
return
}
console.log('files目录创建Folder1和Folder2 验证statSync mkdirSync')
try {
FileUtils.getInstance()
.createFolder(this.appFilePath + '/Folder1');
FileUtils.getInstance()
.createFolder(this.appFilePath + '/Folder2');
} catch (e) {
console.log('appFilePath未取到值,请按顺序从上往下,从左往右依次测试"'+JSON.stringify(e));
}
})
Button('将media资源存入Folder1 验证writeSync mkdirSync createStreamSync')
.margin({ top: 10 })
.onClick(() => {
console.log('将media资源存入Folder1 验证writeSync mkdirSync createStreamSync')
if(this.appFilePath == '' || this.appFilePath == null){
this.appFilePath = 'appFilePath未取到值,请按顺序从上往下,从左往右依次测试'
return
}
((ImageKnifeGlobal.getInstance().getHapContext() as common.UIAbilityContext).resourceManager as resourceManager.ResourceManager)
.getMediaContent($r('app.media.gifSample').id)
.then(data => {
console.log('result.getMedia')
console.log('basicTestFileIOPage - 本地加载资源 解析后数据data length= ' + data.byteLength)
let arrayBuffer = this.typedArrayToBuffer(data);
FileUtils.getInstance().writeFile(this.appFilePath + '/Folder1/jpgSample.gif', arrayBuffer)
this.imageFile = 'file://' + this.appFilePath + '/Folder1/jpgSample.gif'
console.log('Folder1 imaeFile =' + this.imageFile)
})
.catch((err:BusinessError) => {
console.log('basicTestFileIOPage - 本地加载资源err' + JSON.stringify(err as BusinessError));
})
})
Text(this.imageHint2)
Button('copy:Folder1至Folder2 验证copyFileSync')
.margin({ top: 10 })
.onClick(() => {
console.log('copy:Folder1至Folder2 验证copyFileSync')
if(this.appFilePath == '' || this.appFilePath == null){
this.imageHint2 = 'appFilePath未取到值,请按顺序从上往下,从左往右依次测试'
return
}
try {
let filePath1 = this.appFilePath + '/Folder1/jpgSample.gif';
let filePath2 = this.appFilePath + '/Folder2/jpgSample.gif';
FileUtils.getInstance().createFolder(this.appFilePath + '/Folder1')
FileUtils.getInstance().createFolder(this.appFilePath + '/Folder2')
FileUtils.getInstance().copyFile(filePath1, filePath2);
this.imageFile = 'file://' + this.appFilePath + '/Folder2/jpgSample.gif'
console.log('Folder2 imaeFile =' + this.imageFile)
} catch (e) {
console.log('appFilePath未取到值,请按顺序从上往下,从左往右依次测试:'+JSON.stringify(e))
}
})
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Button('显示空PixelMap')
.margin({ left: 10 })
.onClick(() => {
this.normalPixelMap = true;
this.normalResource = false;
})
Button('显示RES')
.margin({ left: 10 })
.onClick(() => {
this.normalPixelMap = false;
this.normalResource = true;
})
Button('显示String')
.margin({ left: 10 })
.onClick(() => {
this.normalPixelMap = false;
this.normalResource = false;
})
}
Image(this.normalPixelMap ? this.imagePixelMap : (this.normalResource ? this.imageRes : this.imageFile))
.width(200)
.height(200)
.backgroundColor(Color.Pink)
}
.width('100%')
.height('100%')
}
}
typedArrayToBuffer(array: Uint8Array): ArrayBuffer {
return array.buffer.slice(array.byteOffset, array.byteLength + array.byteOffset)
}
}

View File

@ -1,129 +0,0 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an 'AS IS' BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import featureAbility from '@ohos.ability.featureAbility';
import { FileUtils } from '@ohos/libraryimageknife'
import { FileTypeUtil } from '@ohos/libraryimageknife'
import resourceManager from '@ohos.resourceManager';
import { Base64 } from '@ohos/libraryimageknife'
import { ParseImageUtil } from '@ohos/libraryimageknife'
import { ImageKnifeGlobal } from '@ohos/libraryimageknife'
import { BusinessError } from '@ohos.base'
import common from '@ohos.app.ability.common';
@Entry
@Component
struct BasicTestMediaImage {
@State imagePixelMap?: PixelMap = undefined;
build() {
Scroll() {
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Flex({ direction: FlexDirection.Row }) {
Button('本地资源jpg')
.onClick(() => {
((ImageKnifeGlobal.getInstance().getHapContext() as common.UIAbilityContext).resourceManager as resourceManager.ResourceManager)
.getMediaContent($r('app.media.jpgSample').id)
.then(data => {
let arrayBuffer = this.typedArrayToBuffer(data);
let parseImageUtil = new ParseImageUtil();
parseImageUtil.parseImage(arrayBuffer, (pxielmap) => {
this.imagePixelMap = pxielmap;
}, (err:BusinessError|string|undefined) => {
})
})
.catch((err:BusinessError) => {
console.log('basicTestMediaImage - 本地加载资源err' + JSON.stringify(err));
})
}).margin({ left: 15 }).backgroundColor(Color.Blue)
Button('本地资源png')
.onClick(() => {
((ImageKnifeGlobal.getInstance().getHapContext() as common.UIAbilityContext).resourceManager as resourceManager.ResourceManager)
.getMediaContent($r('app.media.pngSample').id)
.then(data => {
let arrayBuffer = this.typedArrayToBuffer(data);
let parseImageUtil = new ParseImageUtil();
parseImageUtil.parseImage(arrayBuffer, (pxielmap) => {
this.imagePixelMap = pxielmap;
},(err:BusinessError|string|undefined) => {
})
})
.catch((err:BusinessError) => {
console.log('basicTestMediaImage - 本地加载资源err' + JSON.stringify(err));
})
}).margin({ left: 15 }).backgroundColor(Color.Blue)
Button('本地资源bmp')
.onClick(() => {
((ImageKnifeGlobal.getInstance().getHapContext() as common.UIAbilityContext).resourceManager as resourceManager.ResourceManager)
.getMediaContent($r('app.media.bmpSample').id)
.then(data => {
let arrayBuffer = this.typedArrayToBuffer(data);
let parseImageUtil = new ParseImageUtil();
parseImageUtil.parseImage(arrayBuffer, (pxielmap) => {
this.imagePixelMap = pxielmap;
}, (err:BusinessError|string|undefined) => {
})
})
.catch((err:BusinessError) => {
console.log('basicTestMediaImage - 本地加载资源err' + JSON.stringify(err));
})
}).margin({ left: 15 }).backgroundColor(Color.Blue)
Button('本地资源webp')
.onClick(() => {
((ImageKnifeGlobal.getInstance().getHapContext() as common.UIAbilityContext).resourceManager as resourceManager.ResourceManager)
.getMediaContent($r('app.media.jpgSample').id)
.then(data => {
let arrayBuffer = this.typedArrayToBuffer(data);
let parseImageUtil = new ParseImageUtil();
parseImageUtil.parseImage(arrayBuffer, (pxielmap) => {
this.imagePixelMap = pxielmap;
}, (err:BusinessError|string|undefined) => {
})
})
.catch((err:BusinessError) => {
console.log('basicTestMediaImage - 本地加载资源err' + JSON.stringify(err));
})
}).margin({ left: 15 }).backgroundColor(Color.Blue)
Button('本地资源gif')
.onClick(() => {
((ImageKnifeGlobal.getInstance().getHapContext() as common.UIAbilityContext).resourceManager as resourceManager.ResourceManager)
.getMediaContent($r('app.media.gifSample').id)
.then(data => {
let arrayBuffer = this.typedArrayToBuffer(data);
let parseImageUtil = new ParseImageUtil();
parseImageUtil.parseImage(arrayBuffer, (pxielmap) => {
this.imagePixelMap = pxielmap;
}, (err:BusinessError|string|undefined) => {
})
})
.catch((err:BusinessError) => {
console.log('basicTestMediaImage - 本地加载资源err' + JSON.stringify(err));
})
}).margin({ left: 15 }).backgroundColor(Color.Blue)
}
.margin({ top: 15 })
Image(this.imagePixelMap)
.width(300)
.height(300)
.backgroundColor(Color.Pink)
}
}
.width('100%')
.height('100%')
}
typedArrayToBuffer(array: Uint8Array): ArrayBuffer {
return array.buffer.slice(array.byteOffset, array.byteLength + array.byteOffset)
}
}

View File

@ -1,86 +0,0 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an 'AS IS' BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import featureAbility from '@ohos.ability.featureAbility';
import {FileUtils} from '@ohos/libraryimageknife'
import {FileTypeUtil} from '@ohos/libraryimageknife'
import resourceManager from '@ohos.resourceManager';
import {Base64} from '@ohos/libraryimageknife'
import {ImageKnifeGlobal} from '@ohos/libraryimageknife'
import { BusinessError } from '@ohos.base'
import common from '@ohos.app.ability.common';
@Entry
@Component
struct BasicTestResourceManagerPage {
@State fileTypeStr: string = '解析后图片类型';
build() {
Scroll() {
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Text(this.fileTypeStr).fontSize(20)
.width(300).height(200).backgroundColor(Color.Pink)
Button('getMedia解析一张jpg图片')
.margin({ top: 10 })
.onClick(() => {
((ImageKnifeGlobal.getInstance().getHapContext() as common.UIAbilityContext).resourceManager as resourceManager.ResourceManager)
.getMediaContent($r('app.media.jpgSample')
.id)
.then(data => {
console.log('basicTestFileIOPage - 本地加载资源 解析后数据data = ' + data)
let arrayBuffer = this.typedArrayToBuffer(data);
let filetypeUtil = new FileTypeUtil();
let fileType = filetypeUtil.getFileType(arrayBuffer);
if(fileType != null) {
this.fileTypeStr = fileType;
}
})
.catch((err:BusinessError) => {
console.log('basicTestFileIOPage - 本地加载资源err' + JSON.stringify(err));
})
})
Button('getMediaBase64解析一张png图片')
.margin({ top: 10 })
.onClick(() => {
((ImageKnifeGlobal.getInstance().getHapContext() as common.UIAbilityContext).resourceManager as resourceManager.ResourceManager)
.getMediaContentBase64($r('app.media.pngSample')
.id)
.then(data => {
console.log('ParseResClientBase64 - 本地加载资源 解析后数据data')
let matchReg = ';base64,';
let firstIndex = data.indexOf(matchReg);
data = data.substring(firstIndex + matchReg.length, data.length)
console.log('ParseResClientBase64 - 本地加载资源 解析后数据剔除非必要数据后data= ' + data)
let arrayBuffer = Base64.getInstance()
.decode(data);
let filetypeUtil = new FileTypeUtil();
let fileType = filetypeUtil.getFileType(arrayBuffer);
if(fileType != null) {
this.fileTypeStr = fileType;
}
})
.catch((err:BusinessError) => {
console.log('basicTestFileIOPage - 本地加载资源err' + JSON.stringify(err));
})
})
}
}
.width('100%')
.height('100%')
}
typedArrayToBuffer(array: Uint8Array): ArrayBuffer {
return array.buffer.slice(array.byteOffset, array.byteLength + array.byteOffset)
}
}

View File

@ -1,152 +0,0 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {ImageKnife} from '@ohos/libraryimageknife'
import {OnRenameListener} from '@ohos/libraryimageknife'
import {OnCompressListener} from '@ohos/libraryimageknife'
import {ImageKnifeGlobal} from '@ohos/libraryimageknife'
@Entry
@Component
struct CompressPage {
@State mRPixelMap?: PixelMap = undefined;
@State mFPixelMap?: PixelMap = undefined;
@State mResultText: string= "压缩回调结果"
@State mResultPath: string= "压缩路径:"
@State mAsyncPath: string= ""
@State mAsyncPathHint: string= ""
build() {
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center }) {
Column() {
Column() {
Text("Resource image compress").fontColor(Color.Gray).fontSize(16);
Button() {
Text("同步压缩").fontSize(13).fontColor(Color.White)
}
.height(35)
.width(120)
.margin({ top: 10 })
.onClick(() => {
this.compressAsyncRecource();
});
Scroll(){
Text(this.mAsyncPathHint).fontSize(13)
}
.height(55)
.width(350)
Image(this.mAsyncPath)
.width(200)
.height(200)
.margin({ top: 10 })
.backgroundColor(Color.Pink)
Button() {
Text($r("app.string.resource_image_compress")).fontSize(13).fontColor(Color.White)
}
.height(35)
.width(120)
.margin({ top: 10 })
.onClick(() => {
this.cropressRecource();
});
Image(this.mRPixelMap == undefined?'': this.mRPixelMap!)
.width(200)
.height(200)
.margin({ top: 10 })
Text(this.mResultText).fontColor(Color.Gray).fontSize(16);
Text(this.mResultPath).fontColor(Color.Gray).fontSize(16);
}.margin({ top: 10 });
Column() {
Text("file image compress").fontColor(Color.Gray).fontSize(16);
Button() {
Text($r("app.string.file_image_compress")).fontSize(13).fontColor(Color.White)
}
.height(35)
.width(120)
.margin({ top: 10 })
.onClick(() => {
});
Image(this.mFPixelMap == undefined ?'':this.mFPixelMap!)
.width(200)
.height(200)
.margin({ top: 10 });
}.margin({ top: 10 }).visibility(Visibility.Hidden);
}.margin({ bottom: 30 });
}.width('100%').height('100%');
}
private compressAsyncRecource() {
let data = new Array<Resource>();
data.push($r('app.media.jpgSample'))
let imageKnife:ImageKnife|undefined = ImageKnifeGlobal.getInstance().getImageKnife()
if(imageKnife!=undefined) {
imageKnife
.compressBuilder()
.load(data)
.ignoreBy(100)
.get()
.then((path: string) => {
this.mAsyncPathHint = path;
this.mAsyncPath = 'file://' + path;
});
}
console.info("asasd start compress end")
}
private cropressRecource() {
let data = new Array<Resource>();
data.push($r('app.media.jpgSample'))
let rename: OnRenameListener = {
reName() {
return "test_1.jpg";
}
}
let listener: OnCompressListener = {
start:()=>{
this.mResultText = "start"
console.info("asasd start")
},
onSuccess:(p: PixelMap | null | undefined, path: string)=> {
if(p!=null && p!=undefined) {
let pack = p;
this.mRPixelMap = pack as PixelMap;
console.info("asasd success path:" + this.mRPixelMap)
this.mResultText = "success";
this.mResultPath = path;
}
},
onError:(s: string)=>{
console.info("asasd onError:" + s)
this.mResultText = "fail";
}
}
console.info("asasd start compress")
let imageKnife:ImageKnife|undefined = ImageKnifeGlobal.getInstance().getImageKnife()
if(imageKnife != undefined) {
imageKnife
.compressBuilder()
.load(data)
.ignoreBy(100)
.setRenameListener(rename)
.setCompressListener(listener)
.launch();
}
console.info("asasd start compress end")
}
}

View File

@ -1,107 +0,0 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an 'AS IS' BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { CropImage } from '@ohos/libraryimageknife'
import { CropOptions } from '@ohos/libraryimageknife'
import { Crop } from '@ohos/libraryimageknife'
import { RecourseProvider } from '@ohos/libraryimageknife'
import { PixelMapCrop,Options } from '@ohos/libraryimageknife'
import { CropCallback } from '@ohos/libraryimageknife'
import { FileUtils } from '@ohos/libraryimageknife'
import { ImageKnifeGlobal } from '@ohos/libraryimageknife'
import { BusinessError } from '@ohos.base'
import resourceManager from '@ohos.resourceManager';
import common from '@ohos.app.ability.common'
@Entry
@Component
export struct CropImagePage2 {
@State options1: Options = new Options();
@State cropTap: boolean = false;
@State width1: number = 0;
@State height1: number = 0;
@State _rotate: number = 0;
@State _scale: number = 1;
private _resource: Resource = $r('app.media.bmpSample');
private settings: RenderingContextSettings = new RenderingContextSettings(true)
private canvasContext: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings)
build() {
Scroll() {
Column() {
Button('点击解析图片')
.onClick(() => {
((ImageKnifeGlobal.getInstance().getHapContext() as common.UIAbilityContext).resourceManager as resourceManager.ResourceManager)
.getMediaContent($r('app.media.bmpSample').id)
.then((data:Uint8Array) => {
let arrayBuffer = FileUtils.getInstance().uint8ArrayToBuffer(data);
let optionx = new Options();
optionx.setWidth(800)
.setHeight(800)
.setCropFunction((err:BusinessError|string, pixelmap:PixelMap|null, sx:number, sy:number) => {
console.log('PMC setCropFunction callback')
if (err) {
console.error('PMC crop err =' + err)
} else {
this.width1 = sx * px2vp(1);
this.height1 = sy * px2vp(1);
if(pixelmap != null) {
this.canvasContext.drawImage(pixelmap, 0, 0, this.width1, this.height1)
}
}
})
optionx.loadBuffer(arrayBuffer, () => {
this.options1 = optionx;
})
})
})
PixelMapCrop({ options: $options1, cropTap: this.cropTap })
Button('点击裁剪图片')
.onClick(() => {
this.cropTap = !this.cropTap;
})
Canvas(this.canvasContext)
.width(this.width1)
.height(this.height1)
.rotate({
z: 1,
centerX: this.width1 / 2,
centerY: this.height1 / 2,
angle: this._rotate
})
.scale({ x: this._scale, y: this._scale, z: 1.0 })
.gesture(GestureGroup(GestureMode.Parallel,
RotationGesture({ fingers: 2 }).onActionUpdate((event?: GestureEvent) => {
if(event != undefined) {
this._rotate = event.angle;
}
}), PinchGesture({ fingers: 2 }).onActionUpdate((event?: GestureEvent) => {
if(event != undefined) {
this._scale = event.scale;
}
})))
}
.backgroundColor(Color.Brown)
.width('100%')
}
}
}

View File

@ -1,19 +1,20 @@
/*
* Copyright (C) 2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* Copyright (C) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* distributed under the License is distributed on an 'AS IS' BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import mediaLibrary from '@ohos.multimedia.mediaLibrary';
import { ImageKnifeComponent, ImageKnifeOption, } from '@ohos/libraryimageknife'
import { ImageKnifeComponent, ImageKnifeOption } from '@ohos/libraryimageknife'
import { dataSharePredicates } from '@kit.ArkData';
import { photoAccessHelper } from '@kit.MediaLibraryKit';
@Entry
@ -23,67 +24,29 @@ struct DataShareUriLoadPage {
{
loadSrc: $r('app.media.icon'),
placeholderSrc: $r('app.media.icon_loading'),
errorholderSrc: $r('app.media.icon_failed')
placeholderSrc: $r('app.media.loading'),
errorholderSrc: $r('app.media.failed')
};
build() {
Scroll() {
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Text("获取媒体图库的uri用ImageKnife展示").fontSize(15)
Text($r('app.string.Retrieve_media_gallery')).fontSize(15)
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Button("点击加载Uri并展示")
.onClick(() => {
// 获取mediaLibrary实例后续用到此实例均采用此处获取的实例
const context = getContext(this);
let media = mediaLibrary.getMediaLibrary(context);
let imageType = mediaLibrary.MediaType.IMAGE;
// 创建文件获取选项此处参数为获取image类型的文件资源
let imagesFetchOp:mediaLibrary.MediaFetchOptions = {
selections: mediaLibrary.FileKey.MEDIA_TYPE + '= ?',
selectionArgs: [imageType.toString()],
};
// 获取文件资源使用callback方式返回异步结果
media.getFileAssets(imagesFetchOp, (error, fetchFileResult) => {
// 判断获取的文件资源的检索结果集是否为undefined若为undefined则接口调用失败
if (fetchFileResult == undefined) {
console.log('get fetchFileResult failed with error: ' + error);
return;
}
// 获取文件检索结果集中的总数
const count = fetchFileResult.getCount();
// 判断结果集中的数量是否小于0小于0时表示接口调用失败
if (count < 0) {
console.log('get count from fetchFileResult failed, count: ' + count);
return;
}
// 判断结果集中的数量是否等于0等于0时表示接口调用成功但是检索结果集为空请检查文件获取选项参数配置是否有误和设备中是否存在相应文件
if (count == 0) {
console.log('The count of fetchFileResult is zero');
return;
}
console.log('Get fetchFileResult successfully, count: ' + count);
// 获取文件检索结果集中的第一个资源使用callback方式返回异步结果
fetchFileResult.getFirstObject((error, fileAsset) => {
// 检查获取的第一个资源是否为undefined若为undefined则接口调用失败
if (fileAsset == undefined) {
console.log('get first object failed with error: ' + error);
return;
}
console.log("fileAsset id=" + fileAsset.id + " fileAsset uri=" + fileAsset.uri + " fileAsset displayName=" + fileAsset.displayName)
// 加载图库第一张图片的uri
this.imageKnifeOption1 = {
loadSrc: fileAsset.uri,
placeholderSrc: $r('app.media.icon_loading'),
errorholderSrc: $r('app.media.icon_failed')
}
// 释放FetchFileResult实例并使其失效。无法调用其他方法
fetchFileResult.close();
});
});
Button($r('app.string.Click_load_Uri'))
.onClick(async () => {
let photoSelectOptions = new photoAccessHelper.PhotoSelectOptions();
photoSelectOptions.MIMEType = photoAccessHelper.PhotoViewMIMETypes.IMAGE_TYPE;
photoSelectOptions.maxSelectNumber = 1;
let uris: Array<string> = [];
let photoViewPicker = new photoAccessHelper.PhotoViewPicker();
let photoSelectResult: photoAccessHelper.PhotoSelectResult = await photoViewPicker.select(photoSelectOptions);
uris = photoSelectResult.photoUris;
this.imageKnifeOption1 = {
loadSrc: uris[0],
placeholderSrc:$r('app.media.loading')
}
}).margin({ top: 5, left: 3 })
ImageKnifeComponent({ imageKnifeOption: this.imageKnifeOption1 }).width(300).height(300)
}.width('100%').backgroundColor(Color.Pink)

View File

@ -1,98 +0,0 @@
/*
* Copyright (C) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import router from '@system.router';
import {
ImageKnifeComponent,
ImageKnifeOption,
ImageKnifeDrawFactory,
ScaleType
} from '@ohos/libraryimageknife'
@Entry
@Component
struct DrawFactoryTestPage {
types:Array<ScaleType> = [ScaleType.FIT_START,ScaleType.FIT_END,ScaleType.FIT_CENTER,ScaleType.CENTER,ScaleType.CENTER_CROP,ScaleType.FIT_XY,ScaleType.CENTER_INSIDE,ScaleType.NONE]
@State msg:string = `当前ScaleType${this.types[0]}`
@State imageKnifeOption1: ImageKnifeOption =
{
loadSrc:"https://xximg1.meitudata.com/2LqS1vmqv0.png!thumb-w321-webp75",
mainScaleType: this.types[0],
placeholderSrc: $r('app.media.icon_loading'),
errorholderSrc: $r('app.media.icon_failed'),
drawLifeCycle:ImageKnifeDrawFactory.createOvalLifeCycle(15,'#ff000000')
}
@State imageKnifeOption2: ImageKnifeOption =
{
loadSrc:"https://xximg1.meitudata.com/2LqS1vmqv0.png!thumb-w321-webp75",
mainScaleType: this.types[0],
placeholderSrc: $r('app.media.icon_loading'),
errorholderSrc: $r('app.media.icon_failed'),
drawLifeCycle:ImageKnifeDrawFactory.createRoundLifeCycle(10,'#ff000000',30)
}
count:number = 0;
build() {
Scroll() {
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Text("用例看护DrawFactory").fontSize(15)
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Button(this.msg)
.onClick(() => {
this.count++;
let index= this.count % this.types.length;
this.msg = `当前ScaleType${this.types[index]}`
this.imageKnifeOption1 = {
loadSrc:"https://xximg1.meitudata.com/2LqS1vmqv0.png!thumb-w321-webp75",
mainScaleType: this.types[index],
placeholderSrc: $r('app.media.icon_loading'),
errorholderSrc: $r('app.media.icon_failed'),
drawLifeCycle:ImageKnifeDrawFactory.createOvalLifeCycle(15,'#ff000000')
}
this.imageKnifeOption2 = {
loadSrc:"https://xximg1.meitudata.com/2LqS1vmqv0.png!thumb-w321-webp75",
mainScaleType: this.types[index],
placeholderSrc: $r('app.media.icon_loading'),
errorholderSrc: $r('app.media.icon_failed'),
drawLifeCycle:ImageKnifeDrawFactory.createRoundLifeCycle(10,'#ff000000',30)
}
}).margin({ top: 15, bottom:15 })
ImageKnifeComponent({ imageKnifeOption: this.imageKnifeOption1 }).width('100%').height(300).backgroundColor(Color.Orange)
ImageKnifeComponent({ imageKnifeOption: this.imageKnifeOption2 }).width('100%').height(300).backgroundColor(Color.Orange)
.margin({ top: 15, bottom:15 })
}
.width('100%').height('100%').backgroundColor(Color.Pink)
}.width('100%')
}
.width('100%')
.height('100%')
}
}

View File

@ -1,78 +0,0 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {ImageKnifeComponent} from '@ohos/libraryimageknife'
import {ImageKnifeOption} from '@ohos/libraryimageknife'
import {RotateImageTransformation} from '@ohos/libraryimageknife'
import {RoundedCornersTransformation} from '@ohos/libraryimageknife'
@Entry
@Component
struct FrescoImageTestCasePage {
@State imageKnifeOption1: ImageKnifeOption =
{
loadSrc: "https://thirdwx.qlogo.cn/mmopen/vi_32/DYAIOgq83ericA1Mv66TwicuYOtbDMBcUhv1aa9RJBeAn9uURfcZD0AUGrJebAn1g2AjN0vb2E1XTET7fTuLBNmA/132",
placeholderSrc: $r('app.media.icon_loading'),
errorholderSrc: $r('app.media.icon_failed'),
retryholderSrc: $r('app.media.icon_retry'),
displayProgress: true,
canRetryClick:true
};
@State ImageKnifeOption: ImageKnifeOption =
{
loadSrc: "https://hbimg.huabanimg.com/0ef60041445edcfd6b38d20e19024b2cd9281dcc3525a4-Vy8fYO_fw658/format/webp",
placeholderSrc: $r('app.media.icon_loading'),
errorholderSrc: $r('app.media.icon_failed'),
retryholderSrc: $r('app.media.icon_retry'),
displayProgress: true,
canRetryClick:true
};
@State imageKnifeOption3: ImageKnifeOption =
{
loadSrc: "https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp",
placeholderSrc: $r('app.media.icon_loading'),
errorholderSrc: $r('app.media.icon_failed'),
retryholderSrc: $r('app.media.icon_retry'),
displayProgress: true,
canRetryClick:true
};
@State imageKnifeOption4: ImageKnifeOption =
{
loadSrc: "https://hbimg.huabanimg.com/testRetryxxxx",
placeholderSrc: $r('app.media.icon_loading'),
errorholderSrc: $r('app.media.icon_failed'),
retryholderSrc: $r('app.media.icon_retry'),
displayProgress: true,
canRetryClick:true
};
build() {
Scroll() {
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
// ImageKnifeComponent({ imageKnifeOption: this.imageKnifeOption1 })
// ImageKnifeComponent({ imageKnifeOption: this.imageKnifeOption })
// ImageKnifeComponent({ imageKnifeOption: this.imageKnifeOption3 })
ImageKnifeComponent({ imageKnifeOption: this.imageKnifeOption4 })
.width(300)
.height(300)
}
}
.width('100%')
.height('100%')
}
}

View File

@ -1,69 +0,0 @@
/*
* Copyright (C) 2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { ImageKnifeComponent, ImageKnifeOption, FileUtils,ImageKnifeGlobal } from '@ohos/libraryimageknife'
import common from '@ohos.app.ability.common'
@Entry
@Component
struct Index {
@State imageOption1:ImageKnifeOption = {
loadSrc: $r('app.media.icon'),
}
@State imageOption2:ImageKnifeOption = {
loadSrc: $r('app.media.icon'),
}
@State imageOption3:ImageKnifeOption = {
loadSrc: $r('app.media.icon'),
}
build() {
Scroll() {
Column() {
Button('点击加载网络图片').onClick(()=>{
this.imageOption2 = {
loadSrc: 'https://hbimg.huabanimg.com/cc6af25f8d782d3cf3122bef4e61571378271145735e9-vEVggB',
}
})
ImageKnifeComponent({imageKnifeOption:this.imageOption2}).width(300).height(300).backgroundColor(Color.Pink)
Button('点击加载本地文件').onClick(()=>{
let ctx:Object|undefined = ImageKnifeGlobal.getInstance().getHapContext();
if(ctx != undefined){
let path = (ctx as common.UIAbilityContext).filesDir+"/set.jpeg";
FileUtils.getInstance().readFilePicAsync(path).then(buffer=>{
this.imageOption3 = {
loadSrc: path
}
})
}
})
ImageKnifeComponent({imageKnifeOption:this.imageOption3}).width(300).height(300).backgroundColor(Color.Pink)
}.width('100%')
}
.width('100%')
.height('100%')
}
}

View File

@ -1,411 +0,0 @@
/*
* Copyright (C) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import router from '@ohos.router';
@Entry
@Component
struct IndexFunctionDemo {
@State hint1: string = '启用网络模拟加载替换网络加载'
build() {
Scroll() {
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Text("OHOS基础接口测试列表").fontSize(15)
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Button("测试元能力")
.onClick(() => {
console.log("测试List列表")
router.pushUrl({ url: "pages/basicTestFeatureAbilityPage" });
}).margin({ top: 5, left: 3 })
Button("测试文件")
.onClick(() => {
console.log("测试文件子系统")
router.pushUrl({ url: "pages/basicTestFileIOPage" });
}).margin({ top: 5, left: 3 })
Button("优先级加载")
.onClick(() => {
console.log("优先级加载")
router.pushUrl({ url: "pages/testPriorityComponent" });
}).margin({ top: 5, left: 3 })
}.width('100%').height(60).backgroundColor(Color.Pink)
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Button("测试全球化")
.onClick(() => {
console.log("测试全球化子系统")
router.pushUrl({ url: "pages/basicTestResourceManagerPage" });
}).margin({ top: 5, left: 3 })
Button("测试媒体")
.onClick(() => {
console.log("测试媒体子系统")
router.pushUrl({ url: "pages/basicTestMediaImage" });
}).margin({ top: 5, left: 3 })
}.width('100%').height(60).backgroundColor(Color.Pink)
Text("测试图片切换功能点").fontSize(15)
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Button("测试图片切换")
.onClick(() => {
console.log("测试ImageKnifeComponent所有图片切换")
router.pushUrl({ url: "pages/testImageKnifeOptionChangedPage" });
}).margin({ top: 5, left: 3 })
Button("测试图片高度自适应")
.onClick(() => {
console.log("测试ImageKnifeComponent图片高度自适应")
router.pushUrl({ url: "pages/testImageKnifeAutoHeightPage" });
}).margin({ top: 5, left: 3 })
Button("测试gif播放次数")
.onClick(() => {
router.pushUrl({ url: "pages/testGifPlayTimesPage" });
}).margin({ top: 15 })
}.width('100%').height(60).backgroundColor(Color.Pink)
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Button("测试图片宽度自适应")
.onClick(() => {
console.log("测试ImageKnifeComponent图片宽度自适应")
router.pushUrl({ url: "pages/testImageKnifeAutoWidthPage" });
}).margin({ top: 5, left: 3 })
Button("测试图片宽高自适应")
.onClick(() => {
console.log("测试ImageKnifeComponent图片宽高自适应")
router.pushUrl({ url: "pages/testImageKnifeAutoPage" });
}).margin({ top: 5, left: 3 })
}.width('100%').height(60).backgroundColor(Color.Pink)
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Button("测试thumbnail")
.onClick(() => {
console.log("测试ImageKnifeComponent thumbnail")
router.pushUrl({ url: "pages/testImageKnifeOptionChangedPage2" });
}).margin({ top: 5, left: 3 })
Button("测试RequestOption加载图片")
.onClick(() => {
console.log("测试RequestOption加载图片")
router.pushUrl({ url: "pages/RequestOptionLoadImage" });
}).margin({ top: 5, left: 3 })
}.width('100%').height(60).backgroundColor(Color.Pink)
Text("测试缓存功能点").fontSize(15)
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Button("测试内存缓存LRU")
.onClick(() => {
console.log("测试一级内存缓存")
router.pushUrl({ url: "pages/storageTestLruCache" });
}).margin({ top: 5, left: 3 })
Button("测试所有缓存信息输出")
.onClick(() => {
console.log("pages/testAllCacheInfoPage 页面跳转")
router.pushUrl({ url: "pages/testAllCacheInfoPage" });
}).margin({ top: 5, left: 3 })
}.width('100%')
.height(60).backgroundColor(Color.Pink)
Text("测试复用场景").fontSize(15)
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Button("懒加载复用列表")
.onClick(() => {
console.log("测试一级内存缓存")
router.pushUrl({ url: "pages/testReusePhotoPage" });
}).margin({ top: 5, left: 3 })
}.width('100%')
.height(60).backgroundColor(Color.Pink)
Text("测试占位图 失败占位图 功能点").fontSize(15)
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Button("测试失败占位图")
.onClick(() => {
console.log("测试失败占位图")
router.pushUrl({ url: "pages/showErrorholderTestCasePage" });
}).margin({ top: 5, left: 3 })
}.width('100%').height(60).backgroundColor(Color.Pink)
Text("测试预加载 gif静态动态切换功能点").fontSize(15)
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Button("测试预加载")
.onClick(() => {
console.log("测试预加载")
router.pushUrl({ url: "pages/testPreloadPage" });
}).margin({ top: 5, left: 3 })
Button("测试磁盘预加载返回string")
.onClick(() => {
console.log("测试预加载测试磁盘预加载返回string")
router.pushUrl({ url: "pages/testDiskPreLoadPage" });
}).margin({ top: 5, left: 3 })
}.width('100%').height(60).backgroundColor(Color.Pink)
Text("测试图片变换 图片压缩 功能点").fontSize(15)
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Button("测试图片变换")
.onClick(() => {
console.log("测试图片变换")
router.pushUrl({ url: "pages/transformPixelMapPage" });
}).margin({ top: 5, left: 3 })
Button("测试图片压缩")
.onClick(() => {
console.log("测试图片压缩")
router.pushUrl({ url: "pages/compressPage" });
}).margin({ top: 5, left: 3 })
}.width('100%').height(60).backgroundColor(Color.Pink)
Text("测试缓存规则和重试").fontSize(15)
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Button("更改缓存规则")
.onClick(() => {
console.log("更改缓存规则")
router.pushUrl({ url: "pages/CacheRuleChangedPage" });
}).margin({ top: 5, left: 3 })
Button("重试Retry")
.onClick(() => {
console.log("重试Retry")
router.pushUrl({ url: "pages/frescoRetryTestCasePage" });
}).margin({ top: 5, left: 3 })
Button("加载媒体库uri")
.onClick(() => {
console.log("加载媒体库uri")
router.pushUrl({ url: "pages/dataShareUriLoadPage" });
}).margin({ top: 5, left: 3 })
}.width('100%').height(60).backgroundColor(Color.Pink)
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Button("测试Option缓存是否生效")
.onClick(() => {
console.log("测试Option缓存是否生效")
router.pushUrl({ url: "pages/OptionTestPage" });
}).margin({ top: 5, left: 3 })
Button("测试Signature自定义缓存")
.onClick(() => {
console.log("测试Signature自定义缓存")
router.pushUrl({ url: "pages/SignatureTestPage" });
}).margin({ top: 5, left: 3 })
}.width('100%').height(60).backgroundColor(Color.Pink)
Text("测试pngj和裁剪").fontSize(15)
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Button("测试pngj")
.onClick(() => {
console.log("测试pngj")
router.pushUrl({ url: "pages/pngjTestCasePage" });
}).margin({ top: 5, left: 3 })
Button("图片裁剪")
.onClick(() => {
console.log("图片裁剪")
router.pushUrl({ url: "pages/cropImagePage2" });
}).margin({ top: 5, left: 3 })
}.width('100%').height(60).backgroundColor(Color.Pink)
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Button("测试svg")
.onClick(() => {
console.log("pages/svgTestCasePage 页面跳转")
router.pushUrl({ url: "pages/svgTestCasePage" });
}).margin({ top: 15 })
Button("测试gif已转移,不再使用worker")
.onClick(() => {
}).margin({ top: 15 })
}.width('100%').height(60).backgroundColor(Color.Pink)
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Button("组件显式动画")
.onClick(() => {
console.log("pages/testImageKnifeOptionChangedPage3 页面跳转")
router.pushUrl({ url: "pages/testImageKnifeOptionChangedPage3" });
}).margin({ top: 15 })
Button("组件内容动画")
.onClick(() => {
console.log("pages/testImageKnifeOptionChangedPage4 页面跳转")
router.pushUrl({ url: "pages/testImageKnifeOptionChangedPage4" });
}).margin({ top: 15 })
Button("自定义圆角椭圆")
.onClick(() => {
console.log("pages/testImageKnifeOptionChangedPage5 页面跳转")
router.pushUrl({ url: "pages/testImageKnifeOptionChangedPage5" });
}).margin({ top: 15 })
}.width('100%').height(60).backgroundColor(Color.Pink)
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Button("大量照片")
.onClick(() => {
console.log("pages/manyPhotoShowPage 页面跳转")
router.pushUrl({ url: "pages/manyPhotoShowPage" });
}).margin({ top: 15 })
Button("部分url测试")
.onClick(() => {
console.log("pages/tempUrlTestPage 页面跳转")
router.pushUrl({ url: "pages/tempUrlTestPage" });
}).margin({ top: 15 })
Button("测试drawFactory")
.onClick(() => {
console.log("pages/drawFactoryTestPage 页面跳转")
router.pushUrl({ url: "pages/drawFactoryTestPage" });
}).margin({ top: 15 })
}.width('100%').height(60).backgroundColor(Color.Pink)
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Button("图片暂停和恢复")
.onClick(() => {
console.log("pages/photosPausedResumedPage 页面跳转")
router.pushUrl({ url: "pages/photosPausedResumedPage" });
}).margin({ top: 15 })
Button("List滑动暂停和恢复")
.onClick(() => {
console.log("pages/photosPausedResumedPage2 页面跳转")
router.pushUrl({ url: "pages/photosPausedResumedPage2" });
}).margin({ top: 15 })
}.width('100%').height(60).backgroundColor(Color.Pink)
Text("单帧gif测试").fontSize(15)
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Button("单帧gif测试")
.onClick(() => {
router.pushUrl({ url: "pages/testSingleFrameGifPage" });
}).margin({ top: 5, left: 3 })
Button("webp测试")
.onClick(() => {
router.pushUrl({ url: "pages/webpImageTestPage" });
}).margin({ top: 5, left: 3 })
}.width('100%').height(60).backgroundColor(Color.Pink)
Text("worker测试").fontSize(15)
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Button("gif加载测试已转移,worker不再使用")
.onClick(() => {
}).margin({ top: 5, left: 3 })
}.width('100%').height(60).backgroundColor(Color.Pink)
Text("HSP相关测试").fontSize(15)
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Button("进入HSP的library共享包")
.onClick(() => {
router.pushUrl({ url: '@bundle:com.openharmony.imageknife/sharedlibrary/ets/pages/Index' })
.then(() => {
console.log('push page suceess')
})
}).margin({ top: 15 })
Button("hsp加载后缓存情况,先点左侧按钮")
.onClick(() => {
console.log("pages/hspCacheTestPage 页面跳转")
router.pushUrl({ url: "pages/hspCacheTestPage" });
}).margin({ top: 15 })
Button("不同的hsp资源加载")
.onClick(() => {
console.log("pages/multiHspTestPage 页面跳转")
router.pushUrl({ url: "pages/multiHspTestPage" });
})
}.width('100%').height(60).backgroundColor(Color.Pink)
Text("测试图片加载稳定").fontSize(15)
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Button("测试多张网络图片加载速度")
.onClick(() => {
router.pushUrl({ url: "pages/testManyNetImageLoadWithPage" });
}).margin({ top: 5, left: 3 })
Button("多线程加载大量网络图片加载速度")
.onClick(() => {
router.pushUrl({ url: "pages/testManyNetImageLoadWithPage2" });
}).margin({ top: 5, left: 3 })
Button("测试多张gif加载位置")
.onClick(() => {
router.pushUrl({ url: "pages/testManyGifLoadWithPage" });
}).margin({ top: 5, left: 3 })
}.width('100%').height(60).backgroundColor(Color.Pink)
Text('测试图片抗锯齿').fontSize(15)
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Button('测试图片抗锯齿')
.onClick(() => {
router.pushUrl({ url: 'pages/testImageAntiAliasingWithPage' });
}).margin({ top: 5, left: 3 })
Button('共享转场缩放')
.onClick(() => {
router.pushUrl({ url: 'pages/testImageKnifeRouter1' });
}).margin({ top: 5, left: 3 })
}.width('100%').height(60).backgroundColor(Color.Pink)
Text('测试图片header属性').fontSize(15)
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Button('图片header属性设置')
.onClick(() => {
router.pushUrl({ url: 'pages/testImageKnifeHttpRequestHeader' });
}).margin({ top: 5, left: 3 })
Button('测试自定义DataFetch属性')
.onClick(() => {
router.pushUrl({ url: 'pages/testImageKnifeDataFetch' });
}).margin({ top: 5, left: 3 })
Button('全局header和request的header')
.onClick(() => {
router.pushUrl({ url: 'pages/testImageKnifeHttpRequestHeader1' });
}).margin({ top: 5, left: 3 })
}.width('100%').height(60).backgroundColor(Color.Pink)
Text('测试图片缓存内存').fontSize(15)
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Button('测试图片缓存内存')
.onClick(() => {
router.pushUrl({ url: 'pages/testImageKnifeCache' });
}).margin({ top: 5, left: 3 })
}.width('100%').height(60).backgroundColor(Color.Pink)
Text('测试gif暂停播放属性').fontSize(15)
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Button('测试gif暂停播放属性')
.onClick(() => {
router.pushUrl({ url: 'pages/testStopPlayingGifPage' });
}).margin({ top: 5, left: 3 })
}.width('100%').height(60).backgroundColor(Color.Pink)
Text('测试heic图片加载').fontSize(15)
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Button('测试heic')
.onClick(() => {
router.pushUrl({ url: 'pages/testImageKnifeHeic' });
}).margin({ top: 5, left: 3 })
}.width('100%').height(60).backgroundColor(Color.Pink)
}
}
.width('100%')
.height('100%')
}
aboutToAppear() {
}
onBackPress() {
}
}

View File

@ -1,102 +0,0 @@
/*
* Copyright (C) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import router from '@ohos.router';
import {
ImageKnifeComponent,
ImageKnifeOption,
ImageKnifeGlobal,
ImageKnife,
HeaderOptions
} from '@ohos/libraryimageknife'
import { ObjectKey } from '@ohos/libraryimageknife';
@Entry
@Component
struct IndexFunctionDemo {
@State headerOptions1: HeaderOptions = {
key: "refer",
value: "http://1.94.37.200:7070/AntiTheftChain/downloadImage"
};
@State imageKnifeOption1: ImageKnifeOption =
{
loadSrc: $r('app.media.icon'),
placeholderSrc: $r('app.media.icon_loading'),
errorholderSrc: $r('app.media.icon_failed'),
headerOption: [this.headerOptions1]
};
@State imageKnifeOption2: ImageKnifeOption =
{
loadSrc: $r('app.media.icon'),
placeholderSrc: $r('app.media.icon_loading'),
errorholderSrc: $r('app.media.icon_failed'),
headerOption: [this.headerOptions1]
};
build() {
Scroll() {
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Text("简单示例1加载一张本地png图片").fontSize(15)
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Button("加载PNG")
.onClick(() => {
this.imageKnifeOption1 = {
loadSrc: $r('app.media.pngSample'),
placeholderSrc: $r('app.media.icon_loading'),
errorholderSrc: $r('app.media.icon_failed'),
signature: new ObjectKey('ccccccc')
}
}).margin({ top: 5, left: 3 })
ImageKnifeComponent({ imageKnifeOption: this.imageKnifeOption1 }).width(300).height(300)
}.width('100%').backgroundColor(Color.Pink)
Text("简单示例2加载一张网络gif图片").fontSize(15)
Text("gif解析在子线程,请在页面构建后创建worker,注入imageknife").fontSize(15)
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Button("加载GIF")
.onClick(() => {
this.imageKnifeOption2 = {
loadSrc: 'https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658',
placeholderSrc: $r('app.media.icon_loading'),
errorholderSrc: $r('app.media.icon_failed'),
displayProgress:true,
}
}).margin({ top: 5, left: 3 })
ImageKnifeComponent({ imageKnifeOption: this.imageKnifeOption2 }).width(300).height(300)
}.width('100%').backgroundColor(Color.Pink)
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Button("ImageKnife测试目录页面")
.onClick(() => {
console.log("pages/imageknifeTestCaseIndex 页面跳转")
router.pushUrl({ url: "pages/imageknifeTestCaseIndex" });
}).margin({ top: 15 })
}.width('100%').height(60).backgroundColor(Color.Pink)
}
}
.width('100%')
.height('100%')
}
aboutToAppear() {
}
aboutToDisappear(){
}
onBackPress() {
}
}

View File

@ -1,74 +0,0 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an 'AS IS' BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {ImageKnifeComponent, ScaleType} from '@ohos/libraryimageknife'
import {ImageKnifeOption} from '@ohos/libraryimageknife'
import {ImageKnifeGlobal} from '@ohos/libraryimageknife'
import {RotateImageTransformation} from '@ohos/libraryimageknife'
import {Material} from './model/Material'
import {TestDataSource} from './model/TestDataSource'
import {DiskLruCache} from '@ohos/disklrucache'
import ArkWorker from '@ohos.worker'
import Prompt from '@system.prompt'
@Entry
@Component
struct ManyPhotoShowPage {
private data: TestDataSource = new TestDataSource();
private elementScroller: Scroller = new Scroller()
build() {
Column() {
List({ space: 20, scroller: this.elementScroller }) {
LazyForEach(this.data, (item: Material, index) => {
ListItem() {
Column() {
Stack({ alignContent: Alignment.BottomEnd }) {
// 滤镜图片
ImageKnifeComponent({ imageKnifeOption: {
loadSrc: item.thumbnail,
mainScaleType: ScaleType.FIT_XY,
} })
}
.width(56).height(56)
//滤镜标题
Text(item.name)
.fontSize(10)
.maxLines(1)
.fontColor(Color.White)
.textAlign(TextAlign.Center)
.layoutWeight(1)
.width('100%')
.backgroundColor(Color.Orange)
}
.width(56)
.height(72)
.clip(true)
.borderRadius(4)
}
}, (item: Material) => item.material_id)
}
.listDirection(Axis.Horizontal)
.width('100%')
.height(72)
}
}
}

View File

@ -1,70 +0,0 @@
/*
* Copyright (C) 2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export class BasicDataSource<T> implements IDataSource {
private listeners: DataChangeListener[] = [];
public totalCount(): number {
return 0;
}
public getData(index: number):T | undefined {
return undefined;
}
registerDataChangeListener(listener: DataChangeListener): void {
if (this.listeners.indexOf(listener) < 0) {
console.info('add listener');
this.listeners.push(listener);
}
}
unregisterDataChangeListener(listener: DataChangeListener): void {
const pos = this.listeners.indexOf(listener);
if (pos >= 0) {
console.info('remove listener');
this.listeners.splice(pos, 1);
}
}
notifyDataReload(): void {
this.listeners.forEach(listener => {
listener.onDataReloaded();
})
}
notifyDataAdd(index: number): void {
this.listeners.forEach(listener => {
listener.onDataAdd(index);
})
}
notifyDataChange(index: number): void {
this.listeners.forEach(listener => {
listener.onDataChange(index);
})
}
notifyDataDelete(index: number): void {
this.listeners.forEach(listener => {
listener.onDataDelete(index);
})
}
notifyDataMove(from: number, to: number): void {
this.listeners.forEach(listener => {
listener.onDataMove(from, to);
})
}
}

View File

@ -0,0 +1,55 @@
/*
* Copyright (C) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an 'AS IS' BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export class CommonDataSource <T> 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)
})
}
}

View File

@ -0,0 +1,93 @@
/*
* Copyright (C) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an 'AS IS' BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {ImageKnife, ImageKnifeRequest} from '@ohos/libraryimageknife'
import { IDataSourcePrefetching } from '@kit.ArkUI';
import { HashMap } from '@kit.ArkTS';
const IMADE_UNAVAILABLE = $r('app.media.failed')
export interface InfoItem {
albumUrl: string | Resource
}
export default class DataSourcePrefetchingImageKnife implements IDataSourcePrefetching {
private dataArray: Array<InfoItem>
private readonly requestList: HashMap<number,ImageKnifeRequest> = new HashMap()
private listeners: DataChangeListener[] = [];
constructor(dataArray: Array<InfoItem>) {
this.dataArray = dataArray;
}
public getData(index: number) {
return this.dataArray[index]
}
public totalCount(): number {
return this.dataArray.length
}
public addData(index: number, data: InfoItem[]): 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)
})
}
async prefetch(index: number): Promise<void> {
let item = this.dataArray[index]
if (typeof item.albumUrl == 'string') {
// 图片预加载
let request = ImageKnife.getInstance().preload({
loadSrc:item.albumUrl,
onLoadListener:{
onLoadSuccess:()=>{
// 预加载成功,删除成功请求
this.requestList.remove(index)
},
onLoadFailed:()=>{
// 移除失败请求
this.requestList.remove(index)
}
}
})
this.requestList.set(index,request)
}
}
// 取消请求处理
cancel(index: number) {
if(this.requestList.hasKey(index)) {
// 返回MAP对象指定元素
const request = this.requestList.get(index)
// 取消请求
ImageKnife.getInstance().cancel(request)
// 移除被取消的请求对象
this.requestList.remove(index)
}
}
}

View File

@ -0,0 +1,146 @@
/*
* Copyright (C) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an 'AS IS' BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { InfoItem } from './DataSourcePrefetching'
export class PageViewModel {
private static dataArray: Array<InfoItem> = [
{
albumUrl: 'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/56/v3/8MdhfSsCSMKj4sA6okUWrg/5uBx56tLTUO3RYQl-E5JiQ.jpg'
},
{
albumUrl: 'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/e2/v3/4zI1Xm_3STmV30aZXWRrKw/6aN7WodDRUiBApgffiLPCg.jpg'
},
{
albumUrl: 'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/42/v3/2dSQCqERTP2TTPyssOMEbQ/zL1ebnKKQ_ilqTDcwCAkOw.jpg'
},
{
albumUrl: 'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/78/v3/qQJpAtRGQe2e_VhbGHDgIw/b3zlit99S6GybD3XdNwqJw.jpg'
},
{
albumUrl: 'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/55/v3/5DZ2LLqYSsK85-shqgLveQ/7ZXcyCWNTvOzQP5FFLBGkg.jpg'
},
{
albumUrl: 'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/3e/v3/LqRoLI-PRSu9Nqa8KdJ-pQ/dSqskBpSR9eraAMn7NBdqA.jpg'
},
{
albumUrl: 'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/25/v3/jgB2ekkTRX-3yTYZalnANQ/xff_x9cbSPqb7fbNwgJa7A.jpg'
},
{
albumUrl: 'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/fb/v3/alXwXLHKSyCAIWt_ydgD2g/BCCuu25TREOitQxM7eYOEw.jpg'
},
{
albumUrl: 'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/63/v3/qbe6NZkCQyGcITvdWoZBgg/Y-5U1z3GT_yaK8CBD3jkwg.jpg'
},
{
albumUrl: 'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/16/v3/fm2tO4TsRH6mv_D_nSSd5w/FscLpLwQQ-KuV7oaprFK2Q.jpg'
},
{
albumUrl: 'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/89/v3/UAUvtPHqRD-GWWANsEC57Q/zcRJCQebQ322Aby4jzmwmQ.jpg'
},
{
albumUrl: 'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/30/v3/tUUzzx73R4yp8G--lMhuWQ/EBbcu_dLTT-Jj68XAh6mtA.jpg'
},
{
albumUrl: 'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/76/v3/EyF6z4FISpCHhae38eEexw/OtyAiu-zSSevNQYvUdtVmA.jpg'
},
{
albumUrl: 'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/37/v3/12rH1yiEQmK9wlOOcy5avQ/RzBXiEBRRqOC7LRkwNj6VA.jpg'
},
{
albumUrl: 'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/9a/v3/TpRN4AIzRoyUXIqWdKoE0g/ShOnD_tfS46HDbpSWhbCkQ.jpg'
},
{
albumUrl: 'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/03/v3/H3X17s8eTdS2w56JgbB5jQ/a45sT-j8Sbe8sSQXTzeYvQ.jpg'
},
{
albumUrl: 'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/10/v3/qaEzwkU0QeKb1yehnP2Xig/q7fxAlgMQKup-HUBayRLGQ.jpg'
},
{
albumUrl: 'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/96/v3/rMJJoAflTDSWa1z2pHs2wg/8dOqD0GlQBOCL5AvQok9FQ.jpg'
},
{
albumUrl: 'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/ed/v3/KMO4D6D2QGuVOCLX4AhOFA/ef51xAaLQuK7BsnuD9abog.jpg'
},
{
albumUrl: 'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/d9/v3/FSZH0aTdSqWxeAaxoPvi0g/RqxPxUCXQFiTMBfKTF9kkw.jpg'
},
{
albumUrl: 'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/bf/v3/lSjrRwFcS-ez6jp1ALSQFg/0n7R7XinSPyrYLqDu_1dfw.jpg'
},
{
albumUrl: 'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/8a/v3/ZKzYV5BJTuCk5hCE0y_xNA/8JT95OQnSZSd6_xQQUONhQ.jpg'
},
{
albumUrl: 'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/1/v3/sTXb_I7URBKjdMyLDYa19w/qpcwa_FNQmi3-EzjbGsJ8A.jpg'
},
{
albumUrl: 'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/e5/v3/m7wFvw_eQIuDV0Mk0IKi8g/gJU4migzTHKYk5KrgdZbBw.jpg'
},
{
albumUrl: 'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/3f/v3/k_UWbB5_RGW7JemQZ0OQdw/_DUdmaZRQyG-Oyvkb663Bw.jpg'
},
{
albumUrl: 'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/39/v3/rFRN7G_VSo-p4mBjTZtkRw/gBwTI-ieSIqSsSmLNBEcgw.jpg'
},
{
albumUrl: 'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/04/v3/6K8BPYKVQFOr7KCuAG9nog/qKd3pZlrQy2M-feB3ycVPA.jpg'
},
{
albumUrl: 'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/7d/v3/f0GQFzm1T6eduVeMUhO3Wg/-4cvzIJiRCegjIno3ofIbQ.jpg'
},
{
albumUrl: 'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/e4/v3/C0xxsSeySxW-2iYR5OEbpQ/f1GlaD3zTeKPX8Vd-M1oVQ.jpg'
},
{
albumUrl: 'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/c2/v3/32LCyXN4TuWKWcdf9gAwWw/ej14_BCJQNCaWOKoI9aZAw.jpg'
},
{
albumUrl: 'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/fd/v3/LyYJMdMmQNaC5GyBYEZ5Pw/uFLiovypRSagKyIS-UJPVw.jpg'
},
{
albumUrl: 'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/15/v3/MHM9KaWGTgubn6M8-B_6nw/1YO9JyYhTHSBWsoiqYkGZw.jpg'
},
{
albumUrl: 'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/4c/v3/UdYfbv1_QYqn_ulDHp89OA/VkjexMluTqGO3yt3gPK1DA.jpg'
},
{
albumUrl: 'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/e8/v3/N8blT_7qSK-tRtahIyov7g/M_kjGEEmSzOlTc47Zrfozg.jpg'
},
{
albumUrl: 'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/28/v3/VS_h3m4YRrSgbgxnqE3vtQ/h-2Q1Qy2SSGEuXM36-Rq_w.jpg'
},
{
albumUrl: 'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/2e/v3/R-BaM5ToRNGq5rwtNTcnww/Q2e01VHiR2y9KtFaZmpmNQ.jpg'
},
{
albumUrl: 'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/88/v3/3djkAJKKTdC539XqMdstSg/wHO7DxvXQS2xbt2Y_-4BNg.jpg'
},
{
albumUrl: 'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/fb/v3/guw4eiggR3uWjscFTxITYg/TzRB35iPTdCztrZUUaNuFg.jpg'
},
{
albumUrl: 'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/93/v3/UvSh_f1LT66i0-3hvsYN_A/eYnE3Z8YT5Sk7F-vS2ZmCQ.jpg'
},
{
albumUrl: 'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/5/v3/tv8Vqf9hQrKpozGeZWg2mw/VEICB-bmQYi0Iv6TGADbhw.jpg'
},
{
albumUrl: 'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/30/v3/4v1Ot5BRR6OFVQ9MGn9Xxg/xrPgRn0LS1ep-r7ewIuwiw.jpg'
},
]
static getItems() {
return PageViewModel.dataArray
}
}

View File

@ -1,590 +0,0 @@
/*
* Copyright (C) 2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {BasicDataSource} from './BasicDataSource'
import { Material } from './Material';
export class TestDataSource extends BasicDataSource<Material> {
private dataArray: Material[] = [
{name:"测试CBC",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/R9aT7lpEEVxawo4.jpeg!thumb-w321-webp75",material_id:"5060118818"},
{name:"通用天空1像素测试",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/1V6c63lKLGPlKVo.png!thumb-w321-webp75",material_id:"506009997"},
{name:"像素测试+bin",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/2NxCo49xAB1L96K.jpeg!thumb-w321-webp75",material_id:"506009998"},
{name:"像素测试",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/P6gH3pWBGw7L6dD.jpeg!thumb-w321-webp75",material_id:"506009999"},
{name:"名称一",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/MKosgAWo5VKpo9Z.jpeg!thumb-w321-webp75",material_id:"50600999"},
{name:"质感",thumbnail:"https://xximg1.meitudata.com/XepUPNP4WP.png!thumb-w321-webp75",material_id:"20076061608"},
{name:"抠图批量拼图",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/pA2S9lvNpMY4X3N.jpeg!thumb-w321-webp75",material_id:"506002368"},
{name:"修改测试",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/69MiA9VxKdkzjWR.png!thumb-w321-webp75",material_id:"50600229"},
{name:"兰桂坊-艺术",thumbnail:"https://material-center-pre.meitudata.com/material/image/6228901fd8ddd6350.jpeg!thumb-w321-webp75",material_id:"50639415"},
{name:"有门槛的我",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/P98i3gdgDw3Rmx5.png!thumb-w321-webp75",material_id:"506093422"},
{name:"222嗯嗯1",thumbnail:"https://stage.meitudata.com/public/creator/ed70a3c696c8e7b.jpg!thumb-w321-webp75",material_id:"50693244"},
{name:"滤镜流程11",thumbnail:"https://material-center-pre.meitudata.com/material/image/6194a57b5b9ef7678.jpg!thumb-w321-webp75",material_id:"506017292"},
{name:"hsxTest11.8",thumbnail:"https://material-center-pre.meitudata.com/material/image/6189f29b48f165954.jpg!thumb-w321-webp75",material_id:"506530963"},
{name:"旧-美食手绘1",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/0lZCW9BrDgMroLL.jpeg!thumb-w321-webp75",material_id:"5060002001"},
{name:"Forest",thumbnail:"https://xximg1.meitudata.com/V2jTkoYa96.jpeg!thumb-w321-webp75",material_id:"20106191835"},
{name:"春樱",thumbnail:"https://xximg1.meitudata.com/k5DIOxgJpN.jpeg!thumb-w321-webp75",material_id:"20076291634"},
{name:"GT G",thumbnail:"http://xximg2.meitudata.com/Z9DCJpkB2l.jpeg!thumb-w321-webp75",material_id:"20085081215"},
{name:"测",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/zwdte8R2e5KMMmm.jpeg!thumb-w321-webp75",material_id:"506000000"},
{name:"五一鱼块",thumbnail:"https://xximg1.meitudata.com/mlahyxNxjN.jpeg!thumb-w321-webp75",material_id:"20076292056"},
{name:"青空",thumbnail:"https://xximg1.meitudata.com/8OkUwBympV.jpeg!thumb-w321-webp75",material_id:"20106311844"},
{name:"质感",thumbnail:"https://xximg1.meitudata.com/9nzUydyWeB.png!thumb-w321-webp75",material_id:"20076061589"},
{name:"测试CBC",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/R9aT7lpEEVxawo4.jpeg!thumb-w321-webp75",material_id:"5060118818"},
{name:"像素天空抠图测试",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/Ymju0r3deAl7xoJ.jpeg!thumb-w321-webp75",material_id:"506005680"},
{name:"像素滤镜测试",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/8zPcB0y4vdreG1d.jpeg!thumb-w321-webp75",material_id:"506019998"},
{name:"通用天空1像素测试",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/1V6c63lKLGPlKVo.png!thumb-w321-webp75",material_id:"506009997"},
{name:"人像风格化",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/VYwIWp0E52v5vaE.jpeg!thumb-w321-webp75",material_id:"50600288888"},
{name:"像素+边框测试",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/Z9dtor442OY76KV.jpeg!thumb-w321-webp75",material_id:"506005678"},
{name:"像素测试+bin",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/2NxCo49xAB1L96K.jpeg!thumb-w321-webp75",material_id:"506009998"},
{name:"像素测试",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/P6gH3pWBGw7L6dD.jpeg!thumb-w321-webp75",material_id:"506009999"},
{name:"兰桂坊-艺术",thumbnail:"https://material-center-pre.meitudata.com/material/image/6228901fd8ddd6350.jpeg!thumb-w321-webp75",material_id:"50639415"},
{name:"藤黄",thumbnail:"https://xximg1.meitudata.com/KnJSa8X496.jpeg!thumb-w321-webp75",material_id:"20076281728"},
{name:"梅幸茶",thumbnail:"https://xximg1.meitudata.com/GYGcPokEQ3.jpeg!thumb-w321-webp75",material_id:"20076281771"},
{name:"五一鱼块",thumbnail:"https://xximg1.meitudata.com/mlahyxNxjN.jpeg!thumb-w321-webp75",material_id:"20076292056"},
{name:"12.妆容滤镜层级控制",thumbnail:"https://xxtool-release.zone1.meitudata.com/deRP83dkdlR4.png!thumb-w321-webp75",material_id:"200720002017"},
{name:"12.妆容滤镜层级控制1",thumbnail:"https://xxtool-release.zone1.meitudata.com/rPJ1vKjJY6jz.png!thumb-w321-webp75",material_id:"200720002018"},
{name:"13.3D打光",thumbnail:"https://xxtool-release.zone1.meitudata.com/z8K3P249ZmVW.png!thumb-w321-webp75",material_id:"200720002020"},
{name:"14.新bling效果",thumbnail:"https://xxtool-release.zone1.meitudata.com/e4xlVkl0BzMy.png!thumb-w321-webp75",material_id:"200720003001"},
{name:"美食手绘效果2",thumbnail:"https://xxtool-release.zone1.meitudata.com/B6MleZrWeMvj.jpg!thumb-w321-webp75",material_id:"200720002002"},
{name:"16.美食手绘效果",thumbnail:"https://xxtool-release.zone1.meitudata.com/xEke61aRK6dg.jpg!thumb-w321-webp75",material_id:"200720002003"},
{name:"17.素材无人脸规则",thumbnail:"https://xxtool-release.zone1.meitudata.com/B6MleZ1ae5Ry.jpg!thumb-w321-webp75",material_id:"200720002010"},
{name:"18.径向色散效果",thumbnail:"https://xxtool-release.zone1.meitudata.com/EyvzkoPgakDL.jpg!thumb-w321-webp75",material_id:"200720002012"},
{name:"胶片滤镜2",thumbnail:"https://xxtool-release.zone1.meitudata.com/3zVRo1E16vZG.png!thumb-w321-webp75",material_id:"200720002008"},
{name:"20.胶片滤镜",thumbnail:"https://xxtool-release.zone1.meitudata.com/3zVRo1EdvZ0W.jpg!thumb-w321-webp75",material_id:"200720002009"},
{name:"21.虚化滤镜",thumbnail:"https://xxtool-release.zone1.meitudata.com/1mLMv1kd2BLZ.jpg!thumb-w321-webp75",material_id:"200720002011"},
{name:"22.天空分割滤镜",thumbnail:"https://xxtool-release.zone1.meitudata.com/8NXRMzE019aB.jpg!thumb-w321-webp75",material_id:"200720002006"},
{name:"23.妆容滤镜",thumbnail:"https://xxtool-release.zone1.meitudata.com/0XDRo7xdPkVx.jpg!thumb-w321-webp75",material_id:"200720002007"},
{name:"1.随机滤镜",thumbnail:"https://xxtool-release.zone1.meitudata.com/V06dg1RJ8pDr.jpg!thumb-w321-webp75",material_id:"200720001004"},
{name:"15.实时取色效果",thumbnail:"https://xxtool-release.zone1.meitudata.com/2p5Ro1VDZvxR.png!thumb-w321-webp75",material_id:"200720001001"},
{name:"10.不带妆容",thumbnail:"https://xxtool-release.zone1.meitudata.com/8NXRMz5oypN7.jpeg!thumb-w321-webp75",material_id:"200720002030"},
{name:"16.美食手绘效果1",thumbnail:"https://xxtool-release.zone1.meitudata.com/1mLMWyxNVMAe.jpg!thumb-w321-webp75",material_id:"506088836"},
{name:"素材多比例滤镜",thumbnail:"https://xxtool-release.zone1.meitudata.com/7d8RoA7DXYB9.jpg!thumb-w321-webp75",material_id:"200720002013"},
{name:"安德森粉",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/OXOHRLBqVppoxEY.png!thumb-w321-webp75",material_id:"20079982224"},
{name:"安德森黄",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/bBZcY8dnYDqZE5v.png!thumb-w321-webp75",material_id:"20079982225"},
{name:"安德森冷",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/x5NF1JLYvqGENkj.png!thumb-w321-webp75",material_id:"20079982226"},
{name:"安德森暖青",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/KeVUpByXzRp0oPK.png!thumb-w321-webp75",material_id:"20079982227"},
{name:"高光+100",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/PB2cdnDGN0nqb8q.png!thumb-w321-webp75",material_id:"20079981113"},
{name:"高光-100",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/XepU5b6OZKW90Yv.png!thumb-w321-webp75",material_id:"20079981114"},
{name:"阴影+100",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/KeVUp1oQD6W8xg5.png!thumb-w321-webp75",material_id:"20079981115"},
{name:"阴影-100",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/GPWcJeyweKZR69d.png!thumb-w321-webp75",material_id:"20079981116"},
{name:"cg无素材",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/LEasj5wg0o10JzO.png!thumb-w321-webp75",material_id:"20079981112"},
{name:"会员电影胶片",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/8QzFJLZVqLlvj8v.png!thumb-w321-webp75",material_id:"20079982254"},
{name:"秋1",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/KeVUpByPLRGkgYj.jpeg!thumb-w321-webp75",material_id:"20079982230"},
{name:"秋2",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/6kQUqeG39YJlEo1.jpeg!thumb-w321-webp75",material_id:"20079982231"},
{name:"秋3",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/KeVUpByPvxBLldg.jpeg!thumb-w321-webp75",material_id:"20079982232"},
{name:"秋4",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/3YDh1Dl6xY30nqD.jpeg!thumb-w321-webp75",material_id:"20079982233"},
{name:"秋5",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/9nzUG9DeeGmn94G.jpeg!thumb-w321-webp75",material_id:"20079982234"},
{name:"秋6",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/YkpUjYwlPanLVNg.jpeg!thumb-w321-webp75",material_id:"20079982235"},
{name:"秋7",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/OXOHRLB3YBPbD0o.jpeg!thumb-w321-webp75",material_id:"20079982236"},
{name:"秋8",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/dWZS0X3P2LjqJ5x.jpeg!thumb-w321-webp75",material_id:"20079982240"},
{name:"自然灰2",thumbnail:"https://xximg1.meitudata.com/OXOH0zayv2.png!thumb-w321-webp75",material_id:"20079981854"},
{name:"自然灰1",thumbnail:"https://xximg1.meitudata.com/mbeUyRpobN.png!thumb-w321-webp75",material_id:"20079981853"},
{name:"色散",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/3YDhOe5eO9.png!thumb-w321-webp75",material_id:"20079981726"},
{name:"毕业季",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/4VQt9N8Pjo.png!thumb-w321-webp75",material_id:"20079981254"},
{name:"一键美颜质感",thumbnail:"https://xximg1.meitudata.com/x5NFQPRBWG.png!thumb-w321-webp75",material_id:"20079982147"},
{name:"相框吸色",thumbnail:"https://xximg1.meitudata.com/2zmU1vvaPD.png!thumb-w321-webp75",material_id:"20079982037"},
{name:"美化吸色灰度限制",thumbnail:"https://xximg1.meitudata.com/EPBcLQoodX.png!thumb-w321-webp75",material_id:"20079980037"},
{name:"相机吸色测试",thumbnail:"https://xximg1.meitudata.com/p0LTZqZ2Wm.jpeg!thumb-w321-webp75",material_id:"20079981873"},
{name:"吸色测试2",thumbnail:"https://xximg1.meitudata.com/9nzUyoDvEQ.png!thumb-w321-webp75",material_id:"20079981874"},
{name:"吸色灰度限制0.5",thumbnail:"https://xximg1.meitudata.com/9nzUyYZ5LZ.png!thumb-w321-webp75",material_id:"20079981029"},
{name:"foodie锐化",thumbnail:"https://xximg1.meitudata.com/oJWHn2klo6.png!thumb-w321-webp75",material_id:"20079982000"},
{name:"自然风光",thumbnail:"https://xximg1.meitudata.com/N8eUq1aDk1.jpeg!thumb-w321-webp75",material_id:"20079982003"},
{name:"室内",thumbnail:"https://xximg1.meitudata.com/LEasJPl8mE.jpeg!thumb-w321-webp75",material_id:"20079982004"},
{name:"室外",thumbnail:"https://xximg1.meitudata.com/g5eFOyEePx.jpeg!thumb-w321-webp75",material_id:"20079982005"},
{name:"老人",thumbnail:"https://xximg1.meitudata.com/vgzUl2EGV5.jpeg!thumb-w321-webp75",material_id:"20079982006"},
{name:"街道复用",thumbnail:"https://xximg1.meitudata.com/QEasmNjL8x.jpeg!thumb-w321-webp75",material_id:"20079981781"},
{name:"大师1",thumbnail:"https://xximg1.meitudata.com/wgNU30boQ4.png!thumb-w321-webp75",material_id:"20079981962"},
{name:"大师2",thumbnail:"https://xximg1.meitudata.com/YkpU1yPmPa.png!thumb-w321-webp75",material_id:"20079981963"},
{name:"大师3",thumbnail:"https://xximg1.meitudata.com/qRdTJOZYn8.png!thumb-w321-webp75",material_id:"20079981964"},
{name:"大师4",thumbnail:"https://xximg1.meitudata.com/LEasJoKld4.png!thumb-w321-webp75",material_id:"20079981965"},
{name:"大师5",thumbnail:"https://xximg1.meitudata.com/KeVUaQnzez.png!thumb-w321-webp75",material_id:"20079981966"},
{name:"大师6",thumbnail:"https://xximg1.meitudata.com/BNGiP6vklD.png!thumb-w321-webp75",material_id:"20079981967"},
{name:"大师7",thumbnail:"https://xximg1.meitudata.com/wgNU30boLG.png!thumb-w321-webp75",material_id:"20079981968"},
{name:"大师8",thumbnail:"https://xximg1.meitudata.com/j4Gce54yGg.png!thumb-w321-webp75",material_id:"20079981969"},
{name:"大师9",thumbnail:"https://xximg1.meitudata.com/g5eFO8dEYO.png!thumb-w321-webp75",material_id:"20079981970"},
{name:"模糊相机测试",thumbnail:"https://xximg1.meitudata.com/wgNU3GgL0p.png!thumb-w321-webp75",material_id:"20079982016"},
{name:"",thumbnail:"https://xximg1.meitudata.com/g5eFOoOWnK.png!thumb-w321-webp75",material_id:"20079981872"},
{name:"复古",thumbnail:"https://xximg1.meitudata.com/x5NFQGlPeD.png!thumb-w321-webp75",material_id:"20079982026"},
{name:"夜景抠图",thumbnail:"https://xximg1.meitudata.com/qRdTJOxoK4.png!thumb-w321-webp75",material_id:"20079981936"},
{name:"我爱中国",thumbnail:"https://xximg1.meitudata.com/3YDhOJgLgp.png!thumb-w321-webp75",material_id:"20079981422"},
{name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/oJQiW3WX68vDyaW.jpeg!thumb-w321-webp75",material_id:"20079992271"},
{name:"桃子奶油",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/lk0HjR5ealbk2Ze.jpeg!thumb-w321-webp75",material_id:"20079992275"},
{name:"橘粉奶油",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/5JOi8ZVNnqE8w8g.jpeg!thumb-w321-webp75",material_id:"20079990090"},
{name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/DyOHJnqNb5o8LQg.jpeg!thumb-w321-webp75",material_id:"20079992277"},
{name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/y59IlX8wQXoNGEK.jpeg!thumb-w321-webp75",material_id:"20079992276"},
{name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/dWku02V3BpYDylY.jpeg!thumb-w321-webp75",material_id:"20079990081"},
{name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/p0GcOvOamLXoD3Z.jpeg!thumb-w321-webp75",material_id:"20079992273"},
{name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/6kOHqmQ3qjPoYQa.jpeg!thumb-w321-webp75",material_id:"20079992266"},
{name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/RwXHJpZKvlQK2GJ.jpeg!thumb-w321-webp75",material_id:"20079992267"},
{name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/2zVHE2XGb3d0xgv.jpeg!thumb-w321-webp75",material_id:"20079990045"},
{name:"炫光",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/dWku0XJZxGgDLO9.jpeg!thumb-w321-webp75",material_id:"20079992229"},
{name:"CG3",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/JdXHB6LLY8agV8O.jpeg!thumb-w321-webp75",material_id:"20079992238"},
{name:"CG测试2",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/j4QUVv66nq0P55z.jpeg!thumb-w321-webp75",material_id:"20079991111"},
{name:"国庆挂历2",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/YkVHj0oP36pmOL1.jpeg!thumb-w321-webp75",material_id:"20079999999"},
{name:"美化国庆挂历",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/g5yIKQJdqK1aBlQ.jpeg!thumb-w321-webp75",material_id:"20079998888"},
{name:"在逃公主",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/N8RHzY8o4oKQqEJ.jpeg!thumb-w321-webp75",material_id:"20079992200"},
{name:"2020美颜默认",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/qR1tRvwgl5mmZDp.jpeg!thumb-w321-webp75",material_id:"20079990088"},
{name:"复古画册",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/zq9HXROgvWQpXJp.jpeg!thumb-w321-webp75",material_id:"20079990080"},
{name:"美食1",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/PBXUkeGKl4.jpeg!thumb-w321-webp75",material_id:"20079990060"},
{name:"美食改",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/8QYIwP5P0x.jpeg!thumb-w321-webp75",material_id:"20079990059"},
{name:"细细闪",thumbnail:"https://xximg1.meitudata.com/XeVHPQGmWg.jpeg!thumb-w321-webp75",material_id:"20079991001"},
{name:"细细闪2",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/qR1tRvRVBLmGaQK.jpeg!thumb-w321-webp75",material_id:"20079990069"},
{name:"新闪闪1",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/aOWsGzGNdEOkngB.jpeg!thumb-w321-webp75",material_id:"20079990068"},
{name:"新闪闪3-2",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/qR1tRvbq9BkKZZv.jpeg!thumb-w321-webp75",material_id:"20079990078"},
{name:"新闪闪5",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/j4QUVwNX4q6LV80.jpeg!thumb-w321-webp75",material_id:"20079990077"},
{name:"天空闪-橙",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/wgRHvqkwVNgzaQO.jpeg!thumb-w321-webp75",material_id:"20079990073"},
{name:"新说3",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/6kOHRdweoL.jpeg!thumb-w321-webp75",material_id:"20079990057"},
{name:"新说2",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/QEXSmQ3JNP.jpeg!thumb-w321-webp75",material_id:"20079990056"},
{name:"新说",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/nBqUo2nYVw.jpeg!thumb-w321-webp75",material_id:"20079990055"},
{name:"少女胶片颗粒",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/EPdUL929P1.jpeg!thumb-w321-webp75",material_id:"20079990053"},
{name:"折纸3",thumbnail:"https://xximg1.meitudata.com/j4QUeqxb8N.jpeg!thumb-w321-webp75",material_id:"20079990021"},
{name:"折纸滤镜",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/dWkuagV42R.jpeg!thumb-w321-webp75",material_id:"20079990050"},
{name:"温柔纹理2",thumbnail:"https://xximg1.meitudata.com/5JOiDgbOjz.jpeg!thumb-w321-webp75",material_id:"20079990003"},
{name:"温柔纹理",thumbnail:"https://xximg1.meitudata.com/mbZHy9Kyd4.jpeg!thumb-w321-webp75",material_id:"20079990024"},
{name:"油画新说1",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/dWkuaga464.jpeg!thumb-w321-webp75",material_id:"20079990054"},
{name:"油画新说2",thumbnail:"https://xximg1.meitudata.com/V2jTkpeb8e.jpeg!thumb-w321-webp75",material_id:"20079990001"},
{name:"油画新说3",thumbnail:"https://xximg1.meitudata.com/8QYIw15O85.jpeg!thumb-w321-webp75",material_id:"20079991994"},
{name:"珍珠2",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/zq9H5VqpGo.jpeg!thumb-w321-webp75",material_id:"20079990043"},
{name:"珍珠",thumbnail:"https://xximg1.meitudata.com/dWkua4m2NL.jpeg!thumb-w321-webp75",material_id:"20079991002"},
{name:"爱心月亮",thumbnail:"https://xximg1.meitudata.com/LEKSJEmG9L.png!thumb-w321-webp75",material_id:"20079990041"},
{name:"星星月亮",thumbnail:"https://xximg1.meitudata.com/3YVfOV8JWX.jpeg!thumb-w321-webp75",material_id:"20079990040"},
{name:"钢笔淡彩",thumbnail:"https://xximg1.meitudata.com/6kOHRlg2E8.jpeg!thumb-w321-webp75",material_id:"20079990039"},
{name:"拯救废片2",thumbnail:"https://xximg1.meitudata.com/KeEHax9bao.jpeg!thumb-w321-webp75",material_id:"20079990038"},
{name:"书本感",thumbnail:"https://xximg1.meitudata.com/WYBfmxXLVz.jpeg!thumb-w321-webp75",material_id:"20079990036"},
{name:"拯救废片1",thumbnail:"https://xximg1.meitudata.com/dWkuaGDnaG.jpeg!thumb-w321-webp75",material_id:"20079990037"},
{name:"夏日4",thumbnail:"https://xximg1.meitudata.com/j4QUeglDGW.jpeg!thumb-w321-webp75",material_id:"20079990035"},
{name:"夏日2",thumbnail:"https://xximg1.meitudata.com/zq9H5obmPq.jpeg!thumb-w321-webp75",material_id:"20079990034"},
{name:"夏日3",thumbnail:"https://xximg1.meitudata.com/lk0Hk4z4JE.jpeg!thumb-w321-webp75",material_id:"20079990033"},
{name:"春日柔光",thumbnail:"https://xximg1.meitudata.com/oJQinkgLpN.jpeg!thumb-w321-webp75",material_id:"20079992020"},
{name:"春日日系",thumbnail:"https://xximg1.meitudata.com/JdXHWgQ588.jpeg!thumb-w321-webp75",material_id:"20079990022"},
{name:"2020情人节2",thumbnail:"https://xximg1.meitudata.com/p0GcZg6o2m.jpeg!thumb-w321-webp75",material_id:"20079990017"},
{name:"11",thumbnail:"https://xximg1.meitudata.com/j4QUeR0ylz.jpeg!thumb-w321-webp75",material_id:"20079990014"},
{name:"锐化+颗粒",thumbnail:"https://xximg1.meitudata.com/nBqUoWm5Eq.jpeg!thumb-w321-webp75",material_id:"20079990015"},
{name:"22",thumbnail:"https://xximg1.meitudata.com/EPdULoXbK8.jpeg!thumb-w321-webp75",material_id:"20079990004"},
{name:"2019圣诞2",thumbnail:"https://xximg1.meitudata.com/aOWsL0gy9L.jpeg!thumb-w321-webp75",material_id:"20079990008"},
{name:"bling裸妆",thumbnail:"https://xximg1.meitudata.com/Z3Vspe2qwl.jpeg!thumb-w321-webp75",material_id:"20079991976"},
{name:"水雾",thumbnail:"https://xximg1.meitudata.com/eqOHv8b9Jy.jpeg!thumb-w321-webp75",material_id:"20079990009"},
{name:"泫雅柔光2",thumbnail:"https://xximg1.meitudata.com/1zVH1X80BW.jpeg!thumb-w321-webp75",material_id:"20079990000"},
{name:"无辜妆",thumbnail:"https://xximg1.meitudata.com/8QYIw5OwzQ.jpeg!thumb-w321-webp75",material_id:"20079990020"},
{name:"2023",thumbnail:"https://xximg1.meitudata.com/WYBfmyJ4jO.jpeg!thumb-w321-webp75",material_id:"20079992023"},
{name:"风格妆22",thumbnail:"https://xximg1.meitudata.com/y59IbNv8ek.jpeg!thumb-w321-webp75",material_id:"20079990013"},
{name:"吸色测试",thumbnail:"https://xximg1.meitudata.com/g5yIOn36zo.jpeg!thumb-w321-webp75",material_id:"20079991234"},
{name:"爱国",thumbnail:"https://xximg1.meitudata.com/nBqUonb8dG.jpeg!thumb-w321-webp75",material_id:"20079991919"},
{name:"春樱改良",thumbnail:"https://xximg1.meitudata.com/2zVH1mYp8m.jpeg!thumb-w321-webp75",material_id:"20079991858"},
{name:"爱心阴影",thumbnail:"https://xximg1.meitudata.com/8QYIw59nPj.jpeg!thumb-w321-webp75",material_id:"20079991935"},
{name:"无辜妆2",thumbnail:"https://xximg1.meitudata.com/LEKSJPXj2E.jpeg!thumb-w321-webp75",material_id:"20079990006"},
{name:"1993",thumbnail:"https://xximg1.meitudata.com/vgyHlz3kOv.jpeg!thumb-w321-webp75",material_id:"20079991993"},
{name:"皮肤质感3",thumbnail:"https://xximg1.meitudata.com/LEKSJooQb8.jpeg!thumb-w321-webp75",material_id:"20079991113"},
{name:"皮肤质感2",thumbnail:"https://xximg1.meitudata.com/p0GcZPPXNW.jpeg!thumb-w321-webp75",material_id:"20079991112"},
{name:"皮肤质感",thumbnail:"https://xximg1.meitudata.com/WYBfmDvxQK.jpeg!thumb-w321-webp75",material_id:"20079991884"},
{name:"万圣2",thumbnail:"https://xximg1.meitudata.com/dWkuap6DpQ.jpeg!thumb-w321-webp75",material_id:"20079991866"},
{name:"闪闪压缩2",thumbnail:"https://xximg1.meitudata.com/BNPTP2XB6X.jpeg!thumb-w321-webp75",material_id:"20079990030"},
{name:"闪闪压缩",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/oJQiWKQQE3VWLKR.jpeg!thumb-w321-webp75",material_id:"20079990076"},
{name:"复古画册加纸纹",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/QEXSyJENWDbBkna.jpeg!thumb-w321-webp75",material_id:"20079990079"},
{name:"新闪闪2",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/KeEHpDpzvPgVOqY.jpeg!thumb-w321-webp75",material_id:"20079990067"},
{name:"新闪闪4",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/mbZHO5dyaXPe91g.jpeg!thumb-w321-webp75",material_id:"20079990072"},
{name:"天空闪",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/bBLUYpzJY518dqa.jpeg!thumb-w321-webp75",material_id:"20079990070"},
{name:"美食3改",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/RwXHmlPzDO.jpeg!thumb-w321-webp75",material_id:"20079990058"},
{name:"质感胶片颗粒",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/1zVH1pkp0o.jpeg!thumb-w321-webp75",material_id:"20079990052"},
{name:"雀斑",thumbnail:"https://xximg1.meitudata.com/bBLUvke8mb.jpeg!thumb-w321-webp75",material_id:"20079991000"},
{name:"春日柔光1",thumbnail:"https://xximg1.meitudata.com/KeEHa9ZGYO.jpeg!thumb-w321-webp75",material_id:"20079990031"},
{name:"灰调2",thumbnail:"https://xximg1.meitudata.com/JdXHW51qgp.jpeg!thumb-w321-webp75",material_id:"20079990002"},
{name:"移轴虚化2",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/WYBf3WkazQXvlwl.jpeg!thumb-w321-webp75",material_id:"506000008"},
{name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/6kOHqmdRWjl4BEm.jpeg!thumb-w321-webp75",material_id:"50600006"},
{name:"微光",thumbnail:"https://xximg1.meitudata.com/KeEHa4wl8p.jpeg!thumb-w321-webp75",material_id:"20076251574"},
{name:"微光",thumbnail:"https://xximg1.meitudata.com/eqZUvNY3YL.png!thumb-w321-webp75",material_id:"20076251567"},
{name:"微光",thumbnail:"https://xximg1.meitudata.com/BNPTPoVbeV.jpeg!thumb-w321-webp75",material_id:"20076251575"},
{name:"微光",thumbnail:"https://xximg1.meitudata.com/bBZcvmqk8z.png!thumb-w321-webp75",material_id:"20076251568"},
{name:"微光",thumbnail:"https://xximg1.meitudata.com/g5yIOPJmZn.jpeg!thumb-w321-webp75",material_id:"20076251573"},
{name:"微光",thumbnail:"https://xximg1.meitudata.com/5JeHDVNROj.png!thumb-w321-webp75",material_id:"20076251569"},
{name:"微光",thumbnail:"https://xximg1.meitudata.com/wgNU3PJVzR.png!thumb-w321-webp75",material_id:"20076251577"},
{name:"17.素材无人脸规则",thumbnail:"https://xxtool-release.zone1.meitudata.com/owv1PzKKkaEz.jpg!thumb-w321-webp75",material_id:"506088832"},
{name:"22.天空分割滤镜",thumbnail:"https://xxtool-release.zone1.meitudata.com/laM7B2WRZRve.jpg!thumb-w321-webp75",material_id:"506088818"},
{name:"11.柔发效果支持",thumbnail:"https://xxtool-release.zone1.meitudata.com/L24ZJRgYjyw5.png!thumb-w321-webp75",material_id:"506088812"},
{name:"13.3D打光",thumbnail:"https://xxtool-release.zone1.meitudata.com/owv1PzXYWoxL.png!thumb-w321-webp75",material_id:"506088810"},
{name:"仅日本10.不带妆容",thumbnail:"https://xxtool-release.zone1.meitudata.com/y1B45rOXGkBW.jpeg!thumb-w321-webp75",material_id:"506088811"},
{name:"12.妆容滤镜层级控制1",thumbnail:"https://xxtool-release.zone1.meitudata.com/e4xlJA94A6Mp.png!thumb-w321-webp75",material_id:"506088831"},
{name:"6.强制曝光滤镜",thumbnail:"https://xxtool-release.zone1.meitudata.com/kOo1k0DW9drL.jpg!thumb-w321-webp75",material_id:"506088835"},
{name:"5.男生、女生滤镜",thumbnail:"https://xxtool-release.zone1.meitudata.com/OmB4J1oagj0M.jpg!thumb-w321-webp75",material_id:"506088815"},
{name:"4.带有动效滤镜",thumbnail:"https://xxtool-release.zone1.meitudata.com/V06dJl3051WA.jpg!thumb-w321-webp75",material_id:"506088823"},
{name:"12.妆容滤镜层级控制",thumbnail:"https://xxtool-release.zone1.meitudata.com/kOo1k0Nva6LL.png!thumb-w321-webp75",material_id:"506088816"},
{name:"3.妆容滤镜",thumbnail:"https://xxtool-release.zone1.meitudata.com/OmB4J13jO5Dg.jpg!thumb-w321-webp75",material_id:"506088822"},
{name:"2.bling滤镜",thumbnail:"https://xxtool-release.zone1.meitudata.com/e4xlJA9WZJoy.jpg!thumb-w321-webp75",material_id:"506088834"},
{name:"1.随机滤镜",thumbnail:"https://xxtool-release.zone1.meitudata.com/GYZza015D1LE.jpg!thumb-w321-webp75",material_id:"506088824"},
{name:"19.素材多比例滤镜",thumbnail:"https://xxtool-release.zone1.meitudata.com/B6MlzDxYm10N.jpg!thumb-w321-webp75",material_id:"506088821"},
{name:"16.美食手绘效果",thumbnail:"https://xxtool-release.zone1.meitudata.com/4JpRm4Em6Y7J.jpg!thumb-w321-webp75",material_id:"506088833"},
{name:"16.美食手绘效果2",thumbnail:"https://xxtool-release.zone1.meitudata.com/3zVRNe69zMKM.jpg!thumb-w321-webp75",material_id:"506088829"},
{name:"23.妆容滤镜",thumbnail:"https://xxtool-release.zone1.meitudata.com/L24ZJRgjNYWe.jpg!thumb-w321-webp75",material_id:"506088814"},
{name:"18.径向色散效果",thumbnail:"https://xxtool-release.zone1.meitudata.com/y1B45rOEZeMP.jpg!thumb-w321-webp75",material_id:"506088813"},
{name:"14.新bling效果",thumbnail:"https://xxtool-release.zone1.meitudata.com/y1B45rp8Ky7z.png!thumb-w321-webp75",material_id:"506088837"},
{name:"绵绵",thumbnail:"https://xximg1.meitudata.com/EPdUL42bLj.jpeg!thumb-w321-webp75",material_id:"20076412020"},
{name:"清澈",thumbnail:"https://xximg1.meitudata.com/nBqUo6pveO.jpeg!thumb-w321-webp75",material_id:"20076412057"},
{name:"阴雨",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/N3OFzPJbwBgXG6z.jpeg!thumb-w321-webp75",material_id:"506002342"},
{name:"ar胶片",thumbnail:"https://xximg1.meitudata.com/lkjUk85p5G.png!thumb-w321-webp75",material_id:"20108891781"},
{name:"INS",thumbnail:"https://xximg1.meitudata.com/bBLUv93q2O.jpeg!thumb-w321-webp75",material_id:"20108890012"},
{name:"高级灰",thumbnail:"https://xximg1.meitudata.com/jzOIeJz1mK.png!thumb-w321-webp75",material_id:"20108891777"},
{name:"夜景2",thumbnail:"https://xximg1.meitudata.com/1zVH1nl3nL.jpeg!thumb-w321-webp75",material_id:"20108890014"},
{name:"藕色颗粒",thumbnail:"https://xximg1.meitudata.com/V2jTkoQgO6.jpeg!thumb-w321-webp75",material_id:"20108890015"},
{name:"胶片1",thumbnail:"https://xximg1.meitudata.com/KnJSa8gWE4.png!thumb-w321-webp75",material_id:"20108891783"},
{name:"fuji",thumbnail:"https://xximg1.meitudata.com/qR1tJbvd5d.jpeg!thumb-w321-webp75",material_id:"20108890010"},
{name:"咸咸测试",thumbnail:"https://xximg1.meitudata.com/EPdULqxXOR.jpeg!thumb-w321-webp75",material_id:"20108899999"},
{name:"古风藕色",thumbnail:"https://xximg1.meitudata.com/JdXHWjK4o9.jpeg!thumb-w321-webp75",material_id:"20108891775"},
{name:"natural1",thumbnail:"https://xximg1.meitudata.com/zq9H5ekDQv.jpeg!thumb-w321-webp75",material_id:"20108891682"},
{name:"受伤妆",thumbnail:"https://xximg1.meitudata.com/nBqUoEKnoD.jpeg!thumb-w321-webp75",material_id:"20108891787"},
{name:"natural2",thumbnail:"https://xximg1.meitudata.com/j4QUedKlNv.jpeg!thumb-w321-webp75",material_id:"20108891848"},
{name:"描边2",thumbnail:"https://xximg1.meitudata.com/4VOC9QOZRd.jpeg!thumb-w321-webp75",material_id:"20108891835"},
{name:"natural3",thumbnail:"https://xximg1.meitudata.com/9nOHy6gJOb.jpeg!thumb-w321-webp75",material_id:"20108890019"},
{name:"宝丽来1",thumbnail:"https://xximg1.meitudata.com/JdXHW5qp88.jpeg!thumb-w321-webp75",material_id:"20108891840"},
{name:"日系复古",thumbnail:"https://xximg1.meitudata.com/6zZIRWym8L.png!thumb-w321-webp75",material_id:"20108891846"},
{name:"暗调测试",thumbnail:"https://xximg1.meitudata.com/YkVH1pNvLW.jpeg!thumb-w321-webp75",material_id:"20108897777"},
{name:"宝丽来2",thumbnail:"https://xximg1.meitudata.com/6kOHRWaqeJ.jpeg!thumb-w321-webp75",material_id:"20108891841"},
{name:"海外柔光",thumbnail:"https://xximg1.meitudata.com/p0GcZyqa5z.jpeg!thumb-w321-webp75",material_id:"20108891801"},
{name:"绯红",thumbnail:"https://xximg1.meitudata.com/wgNU340lGP.png!thumb-w321-webp75",material_id:"20108891770"},
{name:"霜色",thumbnail:"https://xximg1.meitudata.com/lkjUkL6GXp.png!thumb-w321-webp75",material_id:"20108891769"},
{name:"梅幸茶",thumbnail:"https://xximg1.meitudata.com/GPWcPEw1Wj.png!thumb-w321-webp75",material_id:"20108891771"},
{name:"水墨",thumbnail:"https://xximg1.meitudata.com/9nzUyjane8.png!thumb-w321-webp75",material_id:"20108891772"},
{name:"1780",thumbnail:"https://xximg1.meitudata.com/vgyHlJoLg3.jpeg!thumb-w321-webp75",material_id:"20108891780"},
{name:"描边3",thumbnail:"https://xximg1.meitudata.com/nBqUoz0g3y.jpeg!thumb-w321-webp75",material_id:"20108891837"},
{name:"描边4",thumbnail:"https://xximg1.meitudata.com/1zVH1XvE4z.jpeg!thumb-w321-webp75",material_id:"20108891838"},
{name:"描边1",thumbnail:"https://xximg1.meitudata.com/WYBfmdWOoQ.jpeg!thumb-w321-webp75",material_id:"20108891834"},
{name:"青空",thumbnail:"https://xximg1.meitudata.com/8OkUwBympV.jpeg!thumb-w321-webp75",material_id:"20106311844"},
{name:"暮霭",thumbnail:"https://xximg1.meitudata.com/9QktyzB0nW.jpeg!thumb-w321-webp75",material_id:"20106311843"},
{name:"糖果",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/qp4IReJkzbEZD41.jpeg!thumb-w321-webp75",material_id:"506002348"},
{name:"苏打",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/nplIo2XOm6.jpeg!thumb-w321-webp75",material_id:"20096442168"},
{name:"淡奶油",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/PVQIkeOx5L.jpeg!thumb-w321-webp75",material_id:"20096442169"},
{name:"温柔",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/N8RHqBW392.jpeg!thumb-w321-webp75",material_id:"20096442166"},
{name:"珠光",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/nBqUo2X8lP.jpeg!thumb-w321-webp75",material_id:"20096442165"},
{name:"丝绸",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/BNPTPWpNRL.jpeg!thumb-w321-webp75",material_id:"20096442167"},
{name:"黑白",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/OXOHRJnJ5vOXBpY.jpeg!thumb-w321-webp75",material_id:"20096081095"},
{name:"暗房",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/eqZU6dBdw3EY3d1.jpeg!thumb-w321-webp75",material_id:"506002307"},
{name:"低反差",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/4VQtnwmwpBL5wDN.jpeg!thumb-w321-webp75",material_id:"506002309"},
{name:"森山",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/1zXUmEWE4DWbQW2.jpeg!thumb-w321-webp75",material_id:"506002313"},
{name:"Instant",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/qRdTR9w9ygLqdeb.jpeg!thumb-w321-webp75",material_id:"506002310"},
{name:"范戴克",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/BNGiqXNXZkljKlb.jpeg!thumb-w321-webp75",material_id:"506002312"},
{name:"圣诞",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/PVQIdno4bnlEEOq.jpeg!thumb-w321-webp75",material_id:"20076452266"},
{name:"小梦境",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/2zVHEkJKPj3q5nz.jpeg!thumb-w321-webp75",material_id:"20076452193"},
{name:"在逃公主",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/lk0HjoJRKlq9E0Z.jpeg!thumb-w321-webp75",material_id:"20076452200"},
{name:"璀璨",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/DyOHJWjXJGk6Ojl.jpeg!thumb-w321-webp75",material_id:"20076452189"},
{name:"星河",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/LEKSjB8pREZExxZ.jpeg!thumb-w321-webp75",material_id:"20076452180"},
{name:"星河II",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/g5yIKQq99XvKZQP.jpeg!thumb-w321-webp75",material_id:"20076452181"},
{name:"星河III",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/oJQiWKVVJNXe3PB.jpeg!thumb-w321-webp75",material_id:"20076452184"},
{name:"年味",thumbnail:"https://xximg1.meitudata.com/EVvILvqjRQ.jpeg!thumb-w321-webp75",material_id:"20076352017"},
{name:"白日梦 ",thumbnail:"https://xximg1.meitudata.com/vgyHlzq34j.jpeg!thumb-w321-webp75",material_id:"20076351989"},
{name:"白桃",thumbnail:"https://xximg1.meitudata.com/g5eFOnEgJj.png!thumb-w321-webp75",material_id:"20076351888"},
{name:"Norge",thumbnail:"https://xximg1.meitudata.com/9nOHylkdjn.jpeg!thumb-w321-webp75",material_id:"2007635584"},
{name:"冬至",thumbnail:"https://xximg1.meitudata.com/zqOU5K9Q5m.png!thumb-w321-webp75",material_id:"20076351887"},
{name:"红杉",thumbnail:"https://xximg1.meitudata.com/QEasmkjv09.png!thumb-w321-webp75",material_id:"20076351981"},
{name:"暖暖 ",thumbnail:"https://xximg1.meitudata.com/y59Ib9kQZw.jpeg!thumb-w321-webp75",material_id:"20076351988"},
{name:"神仙奶油光",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/XRLI50zwLEBpQ19.jpeg!thumb-w321-webp75",material_id:"20096472176"},
{name:"神仙奶油光Ⅱ",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/PVQIdB3VbL63GQN.jpeg!thumb-w321-webp75",material_id:"20096472177"},
{name:"法式油画",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/99ETGwRbEnKn9qd.jpeg!thumb-w321-webp75",material_id:"20096472178"},
{name:"法式油画Ⅱ",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/wkQsvqJNVn9GaaP.jpeg!thumb-w321-webp75",material_id:"20096472179"},
{name:"曼哈顿大桥",thumbnail:"https://xximg1.meitudata.com/bBLUvjadBB.jpeg!thumb-w321-webp75",material_id:"20106301861"},
{name:"维多利亚港",thumbnail:"https://xximg1.meitudata.com/wgRH3jVEDg.jpeg!thumb-w321-webp75",material_id:"20106301862"},
{name:"新宿",thumbnail:"https://xximg1.meitudata.com/x5eIQyn1bp.jpeg!thumb-w321-webp75",material_id:"20106301935"},
{name:"那不勒斯",thumbnail:"https://xximg1.meitudata.com/zqOU5LPDwe.png!thumb-w321-webp75",material_id:"20106301936"},
{name:"赛博朋克",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/ykGslXOBVOZ1wZm.jpeg!thumb-w321-webp75",material_id:"20106302217"},
{name:"盐系",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/29gtLmJEWLAadDk.jpeg!thumb-w321-webp75",material_id:"20096522258"},
{name:"29",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/wOXiNM4O8Jxyv7E.jpeg!thumb-w321-webp75",material_id:"506030029"},
{name:"28",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/jkEIPyplzRPYXmP.jpeg!thumb-w321-webp75",material_id:"506030028"},
{name:"27",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/JgpCWo3NL2G81JZ.jpeg!thumb-w321-webp75",material_id:"506030027"},
{name:"26",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/DpWhZ42RzkXpDgW.jpeg!thumb-w321-webp75",material_id:"5060230026"},
{name:"25",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/Ng9CWAVaM342ERY.jpeg!thumb-w321-webp75",material_id:"506030025"},
{name:"24",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/3MLhOxa9x2m49Rp.jpeg!thumb-w321-webp75",material_id:"506030024"},
{name:"23",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/Ng9CWAVy999Ea27.jpeg!thumb-w321-webp75",material_id:"506030023"},
{name:"22",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/mjkuw39egW2Lv9V.jpeg!thumb-w321-webp75",material_id:"506030022"},
{name:"21",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/9L1IrA1E6l7799X.jpeg!thumb-w321-webp75",material_id:"506030021"},
{name:"20",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/rOwi0AkzJo210E5.jpeg!thumb-w321-webp75",material_id:"506030020"},
{name:"19",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/ed7IAoW6mr4OVwl.jpeg!thumb-w321-webp75",material_id:"506030019"},
{name:"18",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/3MLhOx2A2R5GJom.jpeg!thumb-w321-webp75",material_id:"506030018"},
{name:"17",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/DpWhZ4mE9OZYEv2.jpeg!thumb-w321-webp75",material_id:"506030017"},
{name:"16",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/lK4H8LpVG7o8ZWo.jpeg!thumb-w321-webp75",material_id:"506030016"},
{name:"15",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/JgpCWoverVMGlGE.jpeg!thumb-w321-webp75",material_id:"506030015"},
{name:"14",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/rOwi0Akmj2Wrg8e.jpeg!thumb-w321-webp75",material_id:"506030014"},
{name:"13",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/ZWdUX61ERRREYx7.jpeg!thumb-w321-webp75",material_id:"506030013"},
{name:"12",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/Ng9CWAdDvZDZWN0.jpeg!thumb-w321-webp75",material_id:"506030012"},
{name:"10",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/5O0iJdZB9VKpZYK.jpeg!thumb-w321-webp75",material_id:"506030006"},
{name:"9",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/AY4T4jpeo29dAJY.jpeg!thumb-w321-webp75",material_id:"506030005"},
{name:"8",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/EZNHdk171m9Z1Zp.jpeg!thumb-w321-webp75",material_id:"506030004"},
{name:"7",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/ed7IAorRPGr2DV1.jpeg!thumb-w321-webp75",material_id:"506030003"},
{name:"测试红点6",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/wOXiNMwZDXGyaOW.jpeg!thumb-w321-webp75",material_id:"506030002"},
{name:"测试红点5",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/9L1IrAz4yYjKLOp.jpeg!thumb-w321-webp75",material_id:"506030001"},
{name:"测试红点4",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/EZNHdk1owgyDp9Z.jpeg!thumb-w321-webp75",material_id:"5060238998"},
{name:"测试红点3",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/3MLhOxDGxyVLwmV.jpeg!thumb-w321-webp75",material_id:"5060238997"},
{name:"测试红点2",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/jkEIPyVeNwvW4X8.jpeg!thumb-w321-webp75",material_id:"5060238996"},
{name:"测试红点",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/3MLhOxDGZNlxerJ.jpeg!thumb-w321-webp75",material_id:"5060238995"},
{name:"123",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/8LxIzOLaGM06Ekx.jpeg!thumb-w321-webp75",material_id:"5060238991"},
{name:"小草3",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/09mIW9BGz4DdNPK.jpeg!thumb-w321-webp75",material_id:"5060238990"},
{name:"小草2",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/wOXiNMPBxwoymBv.jpeg!thumb-w321-webp75",material_id:"5060238989"},
{name:"小草",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/rOwi0AO9BdZzzkv.jpeg!thumb-w321-webp75",material_id:"5060238988"},
{name:"星星1",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/71zSrY2veyMDEaE.jpeg!thumb-w321-webp75",material_id:"506010255"},
{name:"小树1",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/4AVSv70z5YzveBy.jpeg!thumb-w321-webp75",material_id:"506010256"},
{name:"小花4",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/G5wUz1B4zNpRE0P.jpeg!thumb-w321-webp75",material_id:"506010254"},
{name:"31",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/Kg2CJr4d5PKRP4p.jpeg!thumb-w321-webp75",material_id:"506030031"},
{name:"西西里",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/yNmTl3VBD1Nz5yE.jpeg!thumb-w321-webp75",material_id:"506002337"},
{name:"尼斯",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/5JeH8E3e6Vvq8YY.jpeg!thumb-w321-webp75",material_id:"506002331"},
{name:"布达佩斯",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/lkjUjRxbeV2moG0.jpeg!thumb-w321-webp75",material_id:"20096082224"},
{name:"月升",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/qRdTRadQlQanwQa.jpeg!thumb-w321-webp75",material_id:"20096082225"},
{name:"聚会",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/5JeH8ZOg14O3Jq6.jpeg!thumb-w321-webp75",material_id:"20096082226"},
{name:"法兰西",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/8QzFJz90eZ3lExp.jpeg!thumb-w321-webp75",material_id:"20096082227"},
{name:"油画",thumbnail:"https://xximg1.meitudata.com/BNPTPRjbyl.jpeg!thumb-w321-webp75",material_id:"20096082032"},
{name:"油画Ⅱ",thumbnail:"https://xximg1.meitudata.com/8QYIw41QVq.jpeg!thumb-w321-webp75",material_id:"20096082033"},
{name:"安东尼亚",thumbnail:"https://xximg1.meitudata.com/2LqS1vmqv0.png!thumb-w321-webp75",material_id:"20096082038"},
{name:"情人节限定",thumbnail:"https://xximg1.meitudata.com/8QYIwbzm81.jpeg!thumb-w321-webp75",material_id:"20096082019"},
{name:"勒芒",thumbnail:"https://xximg1.meitudata.com/ndzuolR3v9.jpeg!thumb-w321-webp75",material_id:"20096081869"},
{name:"电影",thumbnail:"https://xximg1.meitudata.com/PBXUkm2yq5.jpeg!thumb-w321-webp75",material_id:"20096081274"},
{name:"1980",thumbnail:"http://xximg2.meitudata.com/LEKSJx0N8y.jpeg!thumb-w321-webp75",material_id:"20096081108"},
{name:"电影",thumbnail:"http://xximg2.meitudata.com/6kOHRa1OpD.jpeg!thumb-w321-webp75",material_id:"20096081253"},
{name:"中环码头",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/496TnZaRxddxonY.jpeg!thumb-w321-webp75",material_id:"2009608530"},
{name:"显影",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/8QYIJLL6NE94K2l.jpeg!thumb-w321-webp75",material_id:"20086391964"},
{name:"焦点",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/8QYIJLL6o5PVGyv.jpeg!thumb-w321-webp75",material_id:"20086391965"},
{name:"扫街",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/5JOi8ooNJ25wpg2.jpeg!thumb-w321-webp75",material_id:"20086391963"},
{name:"Photog",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/OX8iREk4LJ3qgad.jpeg!thumb-w321-webp75",material_id:"20086391968"},
{name:"超焦距",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/5JOi8ZQeZkvzQQD.jpeg!thumb-w321-webp75",material_id:"20086391970"},
{name:"影调",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/XeVH5bx1bz4NVdk.jpeg!thumb-w321-webp75",material_id:"20086391967"},
{name:"名称一",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/MKosgAWo5VKpo9Z.jpeg!thumb-w321-webp75",material_id:"50600999"},
{name:"修改测试",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/69MiA9VxKdkzjWR.png!thumb-w321-webp75",material_id:"50600229"},
{name:"有门槛的我",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/P98i3gdgDw3Rmx5.png!thumb-w321-webp75",material_id:"506093422"},
{name:"222嗯嗯1",thumbnail:"https://stage.meitudata.com/public/creator/ed70a3c696c8e7b.jpg!thumb-w321-webp75",material_id:"50693244"},
{name:"抠图批量拼图",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/pA2S9lvNpMY4X3N.jpeg!thumb-w321-webp75",material_id:"506002368"},
{name:"滤镜流程11",thumbnail:"https://material-center-pre.meitudata.com/material/image/6194a57b5b9ef7678.jpg!thumb-w321-webp75",material_id:"506017292"},
{name:"月辉",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/wOXiBYpWgxA7ej5.jpeg!thumb-w321-webp75",material_id:"5060112313"},
{name:"旧-美食手绘1",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/0lZCW9BrDgMroLL.jpeg!thumb-w321-webp75",material_id:"5060002001"},
{name:"hsxTest11.8",thumbnail:"https://material-center-pre.meitudata.com/material/image/6189f29b48f165954.jpg!thumb-w321-webp75",material_id:"506530963"},
{name:"GT G",thumbnail:"http://xximg2.meitudata.com/Z9DCJpkB2l.jpeg!thumb-w321-webp75",material_id:"20085081215"},
{name:"自然",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/j4QUVvP9GPkJ4n3.jpeg!thumb-w321-webp75",material_id:"20076051317"},
{name:"自然",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/5JOi8o1nKlqXmb2.jpeg!thumb-w321-webp75",material_id:"20076051233"},
{name:"Room",thumbnail:"https://xximg1.meitudata.com/WYphm4QnOx.jpeg!thumb-w321-webp75",material_id:"20076052148"},
{name:"模糊",thumbnail:"https://xximg1.meitudata.com/qR1tJmaVZg.jpeg!thumb-w321-webp75",material_id:"20076052016"},
{name:"追光",thumbnail:"https://xximg1.meitudata.com/mbZHyl6E8Y.jpeg!thumb-w321-webp75",material_id:"20076051714"},
{name:"春樱",thumbnail:"https://xximg1.meitudata.com/OX8i0kV1vG.jpeg!thumb-w321-webp75",material_id:"20076051634"},
{name:"夏橙",thumbnail:"https://xximg1.meitudata.com/YkVH1doZzv.jpeg!thumb-w321-webp75",material_id:"20076051635"},
{name:"梨花白",thumbnail:"https://xximg1.meitudata.com/bBLUvgJmoK.jpeg!thumb-w321-webp75",material_id:"20076051633"},
{name:"青柠",thumbnail:"https://xximg1.meitudata.com/gn9SOPYgQ6.jpeg!thumb-w321-webp75",material_id:"20076051733"},
{name:"西柚",thumbnail:"https://xximg1.meitudata.com/WXgfmKYZJv.jpeg!thumb-w321-webp75",material_id:"20076051628"},
{name:"恋人未满",thumbnail:"https://xximg1.meitudata.com/3YVfO0zBXJ.jpeg!thumb-w321-webp75",material_id:"20076051075"},
{name:"春樱",thumbnail:"https://xximg1.meitudata.com/k5DIOxgJpN.jpeg!thumb-w321-webp75",material_id:"20076291634"},
{name:"自然",thumbnail:"https://xximg1.meitudata.com/nBqUoGPX5Q.jpeg!thumb-w321-webp75",material_id:"20076051907"},
{name:"Forest",thumbnail:"https://xximg1.meitudata.com/V2jTkoYa96.jpeg!thumb-w321-webp75",material_id:"20106191835"},
{name:"高级灰Ⅱ",thumbnail:"https://xximg1.meitudata.com/LEKSJO5x8V.jpeg!thumb-w321-webp75",material_id:"20076051853"},
{name:"晴空",thumbnail:"https://xximg1.meitudata.com/LEKSJO5VaL.jpeg!thumb-w321-webp75",material_id:"20076052027"},
{name:"白兔糖",thumbnail:"https://xximg1.meitudata.com/k5DIOjzV9d.jpeg!thumb-w321-webp75",material_id:"2007605675"},
{name:"测",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/zwdte8R2e5KMMmm.jpeg!thumb-w321-webp75",material_id:"506000000"},
{name:"素颜",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/DyOHJNKyxWGbpeg.jpeg!thumb-w321-webp75",material_id:"20076052222"},
{name:"奶杏",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/3YVf1DOlq5jVlLe.jpeg!thumb-w321-webp75",material_id:"20076052221"},
{name:"蜜桃",thumbnail:"https://xximg1.meitudata.com/9QktygQgDn.jpeg!thumb-w321-webp75",material_id:"20076291732"},
{name:"青柠",thumbnail:"https://xximg1.meitudata.com/edzuvqDqwJ.jpeg!thumb-w321-webp75",material_id:"20076291733"},
{name:"西柚",thumbnail:"https://xximg1.meitudata.com/kGVuOxgxm5.jpeg!thumb-w321-webp75",material_id:"20076291628"},
{name:"牛油果",thumbnail:"https://xximg1.meitudata.com/1zXU1zyp3V.jpeg!thumb-w321-webp75",material_id:"20076292053"},
{name:"胶片字体1",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/wkQsv9BqOlk01j6.jpeg!thumb-w321-webp75",material_id:"506001241"},
{name:"503cw",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/YadfjNxP2ng3b0v.jpeg!thumb-w321-webp75",material_id:"506001236"},
{name:"爱心",thumbnail:"https://xximg1.meitudata.com/8D5Fwm9VLE.jpeg!thumb-w321-webp75",material_id:"20079971111"},
{name:"",thumbnail:"https://xximg1.meitudata.com/xkbsQOl9bX.jpeg!thumb-w321-webp75",material_id:"20079971995"},
{name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/YadfjWvZDeK8Pjb.jpeg!thumb-w321-webp75",material_id:"200799700078"},
{name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/54Kf8ZNP6YkBdnZ.jpeg!thumb-w321-webp75",material_id:"200799700077"},
{name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/20dfEzWa33vvbEJ.jpeg!thumb-w321-webp75",material_id:"200799700076"},
{name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/L3xFj5Y1l5qyO8k.jpeg!thumb-w321-webp75",material_id:"200799700075"},
{name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/qp4IRaqOvg208Vx.jpeg!thumb-w321-webp75",material_id:"200799700074"},
{name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/opkIW3BY6gJ6DP8.jpeg!thumb-w321-webp75",material_id:"200799700073"},
{name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/39nT1zN9v2p5BBy.jpeg!thumb-w321-webp75",material_id:"200799700072"},
{name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/Kz3fp1lekbGJY52.jpeg!thumb-w321-webp75",material_id:"200799700071"},
{name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/20dfEz9V3L935WD.jpeg!thumb-w321-webp75",material_id:"200799700070"},
{name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/R3GFJpZEd0pD5xY.jpeg!thumb-w321-webp75",material_id:"200799700069"},
{name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/54Kf8o3GlPJgW3Q.jpeg!thumb-w321-webp75",material_id:"200799700067"},
{name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/DaofJN9Gzxd8O5a.jpeg!thumb-w321-webp75",material_id:"200799700063"},
{name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/qp4IRN9PaZ1Penl.jpeg!thumb-w321-webp75",material_id:"200799700055"},
{name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/vkRsK6OxQ60gkJR.jpeg!thumb-w321-webp75",material_id:"200799700045"},
{name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/1ZLIm5ExEmVpobj.jpeg!thumb-w321-webp75",material_id:"200799700053"},
{name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/wkQsvL9y9XX1ZL8.jpeg!thumb-w321-webp75",material_id:"200799700054"},
{name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/BmDFqnXBXod6LKx.jpeg!thumb-w321-webp75",material_id:"200799700061"},
{name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/39nT1DmnGNQp8Gy.jpeg!thumb-w321-webp75",material_id:"200799700060"},
{name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/k2ou2a6aPWDR5nX.jpeg!thumb-w321-webp75",material_id:"200799700058"},
{name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/Q3bFyBOB1DxY6Dx.jpeg!thumb-w321-webp75",material_id:"200799700059"},
{name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/O3RFRL3v0Jpd0Wk.jpeg!thumb-w321-webp75",material_id:"200799700057"},
{name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/BmDFqnWadYGzXxP.jpeg!thumb-w321-webp75",material_id:"20079970049"},
{name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/Q3bFyBQ8JLx2Wvb.jpeg!thumb-w321-webp75",material_id:"20079970051"},
{name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/vkRsK6eLxeGj9w8.jpeg!thumb-w321-webp75",material_id:"200799700041"},
{name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/gkmsKBGp36w8wEO.jpeg!thumb-w321-webp75",material_id:"200799700056"},
{name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/ee9h6Qk4Y1wJpoY.jpeg!thumb-w321-webp75",material_id:"200799700047"},
{name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/jeyhVvLBDqo64yy.jpeg!thumb-w321-webp75",material_id:"20079970050"},
{name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/DaofJNY4pKnpQxa.jpeg!thumb-w321-webp75",material_id:"20079970053"},
{name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/99ETG9z6NzjmBwQ.jpeg!thumb-w321-webp75",material_id:"200799700046"},
{name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/ee9h6QD4PGmGBGa.jpeg!thumb-w321-webp75",material_id:"200799700042"},
{name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/BmDFqnwGbGvXPq3.png!thumb-w321-webp75",material_id:"200799700038"},
{name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/VwJigjRRPoRz8Xl.png!thumb-w321-webp75",material_id:"200799700039"},
{name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/54Kf8BmB9dyqY2k.jpeg!thumb-w321-webp75",material_id:"200799700027"},
{name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/ze1hXRywlnq18zj.jpeg!thumb-w321-webp75",material_id:"200799700025"},
{name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/xkbs1eVvOEB46wE.jpeg!thumb-w321-webp75",material_id:"200799700032"},
{name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/bxgsY85V4j5W3PY.jpeg!thumb-w321-webp75",material_id:"200799700034"},
{name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/54Kf8oxaX5kVpN6.jpeg!thumb-w321-webp75",material_id:"200799700033"},
{name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/EVvIj5VjGJyBNLO.png!thumb-w321-webp75",material_id:"200799700031"},
{name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/Q3bFyJ2yqXlmJJz.png!thumb-w321-webp75",material_id:"200799700030"},
{name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/1ZLImgemPooxWqv.jpeg!thumb-w321-webp75",material_id:"200799700024"},
{name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/8D5FJjdJmO4VRbg.jpeg!thumb-w321-webp75",material_id:"200799700029"},
{name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/EVvIj595ekZpN3X.jpeg!thumb-w321-webp75",material_id:"200799700023"},
{name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/vkRsKg3OONyzZLb.png!thumb-w321-webp75",material_id:"200799700021"},
{name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/496TndEvWqJynwo.png!thumb-w321-webp75",material_id:"200799700019"},
{name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/8D5FJjkBmkNlpkd.png!thumb-w321-webp75",material_id:"200799700020"},
{name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/WPWF3ODzRYPzo3K.jpeg!thumb-w321-webp75",material_id:"200799700018"},
{name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/PVQIdBDb3b998XB.jpeg!thumb-w321-webp75",material_id:"200799700017"},
{name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/99ETGwpo0Lv8dEZ.jpeg!thumb-w321-webp75",material_id:"200799700008"},
{name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/gkmsKQKGPVm3j8E.jpeg!thumb-w321-webp75",material_id:"200799700012"},
{name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/8D5FJjJJ310zYBQ.jpeg!thumb-w321-webp75",material_id:"200799700010"},
{name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/lpvIjojjEYRbwWL.jpeg!thumb-w321-webp75",material_id:"200799700011"},
{name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/xkbs1e1ee83wlP0.jpeg!thumb-w321-webp75",material_id:"200799700014"},
{name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/DaofJWJnxRe3W09.jpeg!thumb-w321-webp75",material_id:"200799700015"},
{name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/XRLI50Bdlg9joZ2.png!thumb-w321-webp75",material_id:"200799700009"},
{name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/99ETGwkej4aqVjo.png!thumb-w321-webp75",material_id:"200799700016"},
{name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/VwJikyzE29.png!thumb-w321-webp75",material_id:"200799700000"},
{name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/ze1h5O9oKb.jpeg!thumb-w321-webp75",material_id:"200799700002"},
{name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/a3wFLXLnx2.jpeg!thumb-w321-webp75",material_id:"200799700001"},
{name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/6DqFRdykvn.png!thumb-w321-webp75",material_id:"200799700004"},
{name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/1ZLI1pjZgP.jpeg!thumb-w321-webp75",material_id:"200799700003"},
{name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/opkIn0ZXgW.jpeg!thumb-w321-webp75",material_id:"200799700006"},
{name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/ze1h5VwNLD.jpeg!thumb-w321-webp75",material_id:"20079976666"},
{name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/mlahykPGYd.jpeg!thumb-w321-webp75",material_id:"2007997666"},
{name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/XRLIPQX4qj.jpeg!thumb-w321-webp75",material_id:"20079972"},
{name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/k2ouOWwP2b.jpeg!thumb-w321-webp75",material_id:"20079971"},
{name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/xkbsQP2W5z.jpeg!thumb-w321-webp75",material_id:"20079971234"},
{name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/EVvIjl5B2q1P3Ld.jpeg!thumb-w321-webp75",material_id:"200799700062"},
{name:"新年静物",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/8D5FJzenN2v99KG.jpeg!thumb-w321-webp75",material_id:"200799700079"},
{name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/20dfEzd1lndjOwg.jpeg!thumb-w321-webp75",material_id:"20079972282"},
{name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/nplIyLnnEm9o41W.png!thumb-w321-webp75",material_id:"200799700022"},
{name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/ze1h5ONoeg.png!thumb-w321-webp75",material_id:"200799700007"},
{name:"原生",thumbnail:"https://xximg1.meitudata.com/XeVHPQpbgR.jpeg!thumb-w321-webp75",material_id:"20079930000"},
{name:"减龄2",thumbnail:"https://xximg1.meitudata.com/GPoUPW5m8n.jpeg!thumb-w321-webp75",material_id:"20079930003"},
{name:"质感",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/nBJcyLgw0QZmvB2.png!thumb-w321-webp75",material_id:"20079932147"},
{name:"眼睑下至",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/1zVH1xKebW.jpeg!thumb-w321-webp75",material_id:"20079930007"},
{name:"原生2",thumbnail:"https://xximg1.meitudata.com/aOWsLZ14vp.jpeg!thumb-w321-webp75",material_id:"20079930001"},
{name:"减龄2优化",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/5JOiDRnL9l.jpeg!thumb-w321-webp75",material_id:"20079930070"},
{name:"DIOR",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/5JOi8BVv09mRyGK.jpeg!thumb-w321-webp75",material_id:"20079930075"},
{name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/N3OFqdNzda.jpeg!thumb-w321-webp75",material_id:"20079932157"},
{name:"bling",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/9nzUy0eQGq.png!thumb-w321-webp75",material_id:"20079932158"},
{name:"色散光",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/JdaUWkbq92.png!thumb-w321-webp75",material_id:"20079932154"},
{name:"闪光夏日",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/bBLUvkadVZ.jpeg!thumb-w321-webp75",material_id:"20079932153"},
{name:"闪光女团",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/qR1tJPGR0j.jpeg!thumb-w321-webp75",material_id:"20079930053"},
{name:"闪光少女",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/eqOHv3wnlD.jpeg!thumb-w321-webp75",material_id:"20079932152"},
{name:"bling01",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/EPdULXNn66.jpeg!thumb-w321-webp75",material_id:"20079930010"},
{name:"bling02",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/6kOHR9OGvP.jpeg!thumb-w321-webp75",material_id:"20079930011"},
{name:"bling03",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/eqOHv38nPz.jpeg!thumb-w321-webp75",material_id:"20079930012"},
{name:"Disco6",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/RwXHmzP9Y0.jpeg!thumb-w321-webp75",material_id:"20079930009"},
{name:"Dream1",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/XeVHPQWGGZ.jpeg!thumb-w321-webp75",material_id:"20079930013"},
{name:"Hypno1",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/j4QUeORQE4.jpeg!thumb-w321-webp75",material_id:"20079930014"},
{name:"Stellar2",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/5JOiDpKNRz.jpeg!thumb-w321-webp75",material_id:"20079930008"},
{name:"光1",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/OX8i06ZB9D.jpeg!thumb-w321-webp75",material_id:"20079930004"},
{name:"Prisma1",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/JdXHWkgq5D.jpeg!thumb-w321-webp75",material_id:"20079930017"},
{name:"Plastic1",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/V2jTkWZbP6.jpeg!thumb-w321-webp75",material_id:"20079930016"},
{name:"莫奈",thumbnail:"https://xximg1.meitudata.com/9nzUy0bwDV.png!thumb-w321-webp75",material_id:"20079932086"},
{name:"雾柔水光",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/JdaUWkEplJ.png!thumb-w321-webp75",material_id:"20079932146"},
{name:"muji",thumbnail:"https://xximg1.meitudata.com/LEasJNJplP.png!thumb-w321-webp75",material_id:"20079932148"},
{name:"相机打光测试",thumbnail:"https://xximg1.meitudata.com/j4QUexO3K5.jpeg!thumb-w321-webp75",material_id:"20079932054"},
{name:"1222",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/3XwSOKRJjx.jpeg!thumb-w321-webp75",material_id:"20079931222"},
{name:"1333",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/EQYuL9LqvV.jpeg!thumb-w321-webp75",material_id:"20079931333"},
{name:"1999",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/VqVfkykO5y.jpeg!thumb-w321-webp75",material_id:"20079931999"},
{name:"1666",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/1pgI1plVVv.jpeg!thumb-w321-webp75",material_id:"20079931666"},
{name:"1888",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/OJbF06VvmK.jpeg!thumb-w321-webp75",material_id:"20079931888"},
{name:"1888",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/ke8UOWwVz6.jpeg!thumb-w321-webp75",material_id:"20079931777"},
{name:"2057",thumbnail:"https://xximg1.meitudata.com/3YVfOVKVmm.jpeg!thumb-w321-webp75",material_id:"20079932057"},
{name:"五一鱼块",thumbnail:"https://xximg1.meitudata.com/39nTOVegOn.jpeg!thumb-w321-webp75",material_id:"20079932056"},
{name:"五一",thumbnail:"https://xximg1.meitudata.com/bBZcvykbxP.png!thumb-w321-webp75",material_id:"20079932053"},
{name:"bling04",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/OX8i06XB3L.jpeg!thumb-w321-webp75",material_id:"20079930015"},
{name:"元旦",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/mbZHO6bOgR5YgdB.jpeg!thumb-w321-webp75",material_id:"20106401993"},
{name:"瞬间",thumbnail:"https://xximg1.meitudata.com/y59Ib9JKjm.jpeg!thumb-w321-webp75",material_id:"20106401997"},
{name:"新专辑轰顶",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/BR7fMkae0elL9DK.png!thumb-w321-webp75",material_id:"506093294"},
{name:"新素材",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/LL8SozrWaMVRP5L.png!thumb-w321-webp75",material_id:"506093299"},
{name:"素材不在功能页",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/69MiA9JxOErJvvP.png!thumb-w321-webp75",material_id:"506093238"},
{name:"我被禁用了😄我被禁用了😄",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/D18Iz3ZaAPm0za3.png!thumb-w321-webp75",material_id:"506093239"},
{name:"低版本不可见",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/757SWMrAkzKAorX.png!thumb-w321-webp75",material_id:"506093243"},
{name:"3d立体弹窗",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/k4gtA430gyk3Wx9.png!thumb-w321-webp75",material_id:"506093241"},
{name:"加州",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/RKgUJnKn126zbGG.jpeg!thumb-w321-webp75",material_id:"50602339"},
{name:"爱心光",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/j4GcVXWgv200k0D.jpeg!thumb-w321-webp75",material_id:"506002288"},
{name:"2053太空漫游",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/wgNUven5XxgKmG4.jpeg!thumb-w321-webp75",material_id:"20096492276"},
{name:"CCD",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/XepU5b3WG3BDJNp.jpeg!thumb-w321-webp75",material_id:"20096492265"},
{name:"IMAX胶片",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/bBZcYlQVDNVde5Y.jpeg!thumb-w321-webp75",material_id:"20096492254"},
{name:"皮囊之下",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/p0LTO938OKJLV2k.jpeg!thumb-w321-webp75",material_id:"506002350"},
{name:"号手就位",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/J34FBw2bEwzGbWp.jpeg!thumb-w321-webp75",material_id:"506002317"},
{name:"海绵3",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/26guLmK1p0M13Zr.jpeg!thumb-w321-webp75",material_id:"506010277"},
{name:"海绵4",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/KgaiJr4o77waN4d.jpeg!thumb-w321-webp75",material_id:"506010276"},
{name:"海绵1",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/71MfrYOoEDyKLJA.jpeg!thumb-w321-webp75",material_id:"506010279"},
{name:"TR2",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/k51F2wNOkqQgBjX.jpeg!thumb-w321-webp75",material_id:"506002345"},
{name:"TR3",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/JdaUB94WJJqQlwK.jpeg!thumb-w321-webp75",material_id:"506002344"},
{name:"TR4",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/5JeH8WzDLm1NmPy.jpeg!thumb-w321-webp75",material_id:"506002347"},
{name:"TR5",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/lkjUjGvk4VORqlR.jpeg!thumb-w321-webp75",material_id:"506002343"},
{name:"TR6",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/k51F2wNOLjj94dK.jpeg!thumb-w321-webp75",material_id:"506002346"},
{name:"乌布",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/V2xig11N0vQLpxm.jpeg!thumb-w321-webp75",material_id:"506002333"},
{name:"微缩世界",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/oJQiWgqo5kodE1B.jpeg!thumb-w321-webp75",material_id:"506002298"},
{name:"微缩世界Ⅱ",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/N8RHzP6aP44Xex6.jpeg!thumb-w321-webp75",material_id:"506002299"},
{name:"旅程",thumbnail:"https://xximg1.meitudata.com/V2jTkEY8Y9.jpeg!thumb-w321-webp75",material_id:"20086101254"},
{name:"旅程",thumbnail:"https://xximg1.meitudata.com/GPoUPwOj1b.jpeg!thumb-w321-webp75",material_id:"20086101315"},
{name:"且听风吟",thumbnail:"https://xximg1.meitudata.com/Z3VspeGOy3.jpeg!thumb-w321-webp75",material_id:"2008610635"},
{name:"Sky",thumbnail:"https://xximg1.meitudata.com/p0GcZPbnV0.jpeg!thumb-w321-webp75",material_id:"20086101612"},
{name:"清新蓝",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/BbWiqXBp8X869e9.jpeg!thumb-w321-webp75",material_id:"20086162162"},
{name:"男友力",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/6PocqE9aB8nZgOl.jpeg!thumb-w321-webp75",material_id:"20086161259"},
{name:"男友力",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/8boiJnm9e69J3GB.jpeg!thumb-w321-webp75",material_id:"20086161256"},
{name:"男友力",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/oeGiWgmVL06ppzo.jpeg!thumb-w321-webp75",material_id:"20086161469"},
{name:"chiffon",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/JdXHB6PXY9dzmjl.jpeg!thumb-w321-webp75",material_id:"2008607975"},
{name:"新年限定",thumbnail:"https://xximg1.meitudata.com/mlahymLEBk.jpeg!thumb-w321-webp75",material_id:"20086072015"},
{name:"新春食堂",thumbnail:"https://xximg1.meitudata.com/dDpFaD19J9.jpeg!thumb-w321-webp75",material_id:"20086071687"},
{name:"围炉",thumbnail:"https://xximg1.meitudata.com/jo2UegGjqj.jpeg!thumb-w321-webp75",material_id:"20086071688"},
{name:"橘子汽水",thumbnail:"https://xximg1.meitudata.com/voWUlvO8Dd.jpeg!thumb-w321-webp75",material_id:"2008607571"},
{name:"舒芙蕾",thumbnail:"https://xximg1.meitudata.com/xmdFQwl5J0.jpeg!thumb-w321-webp75",material_id:"2008607569"},
{name:"野Ⅰ",thumbnail:"https://xximg1.meitudata.com/6KwCRlbG6g.jpeg!thumb-w321-webp75",material_id:"20086070001"},
{name:"野餐Ⅱ",thumbnail:"https://xximg1.meitudata.com/Nzjuq2XDGQ.jpeg!thumb-w321-webp75",material_id:"20086070002"},
{name:"食欲",thumbnail:"https://xximg1.meitudata.com/jo2UegGzVl.jpeg!thumb-w321-webp75",material_id:"20086071585"},
{name:"食欲",thumbnail:"https://xximg1.meitudata.com/0J6fWJbYW8.jpeg!thumb-w321-webp75",material_id:"20086071587"},
{name:"橘子汽水",thumbnail:"https://xximg1.meitudata.com/bz0uvoO5Po.jpeg!thumb-w321-webp75",material_id:"20086071908"},
{name:"",thumbnail:"https://xximg1.meitudata.com/xmdFQwgNGx.png!thumb-w321-webp75",material_id:"2008607014"},
{name:"粉花面包",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/gkmsKBakKNO6ynd.jpeg!thumb-w321-webp75",material_id:"2008607973"},
{name:"",thumbnail:"https://xximg1.meitudata.com/RzLumonEvG.png!thumb-w321-webp75",material_id:"2008607015"},
{name:"Brunch",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/V2jTgxyR4xG9k4d.jpeg!thumb-w321-webp75",material_id:"20086072197"},
{name:"vista200",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/LJwUjvN4awZDWOw.jpeg!thumb-w321-webp75",material_id:"506002301"},
{name:"胶片时光",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/kBwi28Wm6y698oy.jpeg!thumb-w321-webp75",material_id:"20086171381"},
{name:"胶片时光",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/8boiJnmYZ8NbvJ6.jpeg!thumb-w321-webp75",material_id:"20086171339"},
{name:"胶片时光",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/vEdtKOx0n2gEyBg.jpeg!thumb-w321-webp75",material_id:"20086171336"},
{name:"菲林日记",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/OdpiRJVedvxlR4m.jpeg!thumb-w321-webp75",material_id:"20096221571"},
{name:"菲林日记",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/kBwi28w05RB11de.jpeg!thumb-w321-webp75",material_id:"20096221570"},
{name:"菲林日记",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/KBPipZwDElPR1bl.jpeg!thumb-w321-webp75",material_id:"20096221783"},
{name:"菲林日记",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/2bkiEXqkWmBZzjL.jpeg!thumb-w321-webp75",material_id:"20096221781"},
{name:"菲林日记",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/PnkTd0zBvKKRYb0.jpeg!thumb-w321-webp75",material_id:"20096221780"},
{name:"Outdoors",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/NL9HzPdl9WLnlq9.jpeg!thumb-w321-webp75",material_id:"20086172023"},
{name:"蒸汽波",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/DyjUJpgEgyP8nDL.jpeg!thumb-w321-webp75",material_id:"506002182"},
{name:"落日",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/V2jTgj1akYWmEvP.jpeg!thumb-w321-webp75",material_id:"20106112264"},
{name:"音浪",thumbnail:"http://xximg2.meitudata.com/VXgfk8zEJ3.jpeg!thumb-w321-webp75",material_id:"20106111100"},
{name:"毕业季",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/y56Fb5qaXq.jpeg!thumb-w321-webp75",material_id:"20076121254"},
{name:"游乐园",thumbnail:"https://xximg1.meitudata.com/N8eUq2XE0E.jpeg!thumb-w321-webp75",material_id:"20076091595"},
{name:"粉黛",thumbnail:"https://xximg1.meitudata.com/wgNU3GlNRj.jpeg!thumb-w321-webp75",material_id:"20076091618"},
{name:"游乐园",thumbnail:"https://xximg1.meitudata.com/Z3GfpjWOKV.jpeg!thumb-w321-webp75",material_id:"20076091596"},
{name:"水彩画",thumbnail:"https://xximg1.meitudata.com/eqOHvqo0ej.jpeg!thumb-w321-webp75",material_id:"20106041764"},
{name:"钢笔淡彩",thumbnail:"https://xximg1.meitudata.com/V2jTkopPGQ.jpeg!thumb-w321-webp75",material_id:"20106041765"},
{name:"质感",thumbnail:"https://xximg1.meitudata.com/XepUPNP4WP.png!thumb-w321-webp75",material_id:"20076061608"},
{name:"质感",thumbnail:"https://xximg1.meitudata.com/9nzUydyWeB.png!thumb-w321-webp75",material_id:"20076061589"},
{name:"质感",thumbnail:"http://xximg2.meitudata.com/yObUbokjlb.jpeg!thumb-w321-webp75",material_id:"20076061609"},
{name:"荼白",thumbnail:"https://xximg1.meitudata.com/6kOHRW8WGD.jpeg!thumb-w321-webp75",material_id:"20076061859"}
]
public totalCount(): number {
return this.dataArray.length;
}
public getData(index: number): Material | undefined {
return this.dataArray[index];
}
public addData(index: number, data: Material): void {
this.dataArray.splice(index, 0, data);
this.notifyDataAdd(index);
}
public pushData(data: Material): void {
this.dataArray.push(data);
this.notifyDataAdd(this.dataArray.length - 1);
}
}

View File

@ -1,60 +0,0 @@
/*
* Copyright (C) 2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { ImageKnifeComponent, ImageKnifeOption, FileUtils, ImageKnifeGlobal, GetRes1 } from '@ohos/libraryimageknife'
import common from '@ohos.app.ability.common'
import { GetRes2 } from '@ohos/sharedlibrary2'
@Entry
@Component
struct Index {
@State imageOption1: ImageKnifeOption = {
loadSrc: $r('app.media.icon'),
}
@State imageOption2: ImageKnifeOption = {
loadSrc: $r('app.media.icon'),
}
build() {
Scroll() {
Column() {
Button('点击HSP1主图HSP2占位,无context').onClick(() => {
let mainRes = GetRes1.getSample1();
let placeholderRes = GetRes2.getSample2();
this.imageOption1 = {
loadSrc:mainRes,
placeholderSrc:placeholderRes
}
})
ImageKnifeComponent({ imageKnifeOption: this.imageOption1 }).width(300).height(300).backgroundColor(Color.Pink)
Button('点击HSP1主图HSP2占位,有context ').onClick(() => {
let mainRes = GetRes1.getSample1();
let placeholderRes = GetRes2.getSample2();
this.imageOption2 = {
loadSrc:mainRes,
placeholderSrc:placeholderRes,
context:getContext(this) as common.UIAbilityContext
}
})
ImageKnifeComponent({ imageKnifeOption: this.imageOption2 }).width(300).height(300).backgroundColor(Color.Pink)
}.width('100%')
}
.width('100%')
.height('100%')
}
}

View File

@ -1,92 +0,0 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an 'AS IS' BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {ImageKnifeComponent, ScaleType,ImageKnife} from '@ohos/libraryimageknife'
import {ImageKnifeOption} from '@ohos/libraryimageknife'
import {ImageKnifeGlobal} from '@ohos/libraryimageknife'
import {RotateImageTransformation} from '@ohos/libraryimageknife'
import {Material} from './model/Material'
import {TestDataSource} from './model/TestDataSource'
@Entry
@Component
struct photosPausedResumedPage {
private data: TestDataSource = new TestDataSource();
private elementScroller: Scroller = new Scroller()
build() {
Column() {
Button('点击暂停加载')
.margin({top:10,bottom:5})
.onClick(()=>{
let imageKnife:ImageKnife|undefined = ImageKnifeGlobal.getInstance().getImageKnife();
if(imageKnife!= undefined){
imageKnife.pauseRequests()
}
})
Button('点击重新加载')
.margin({top:10,bottom:5})
.onClick(()=>{
let imageKnife:ImageKnife|undefined = ImageKnifeGlobal.getInstance().getImageKnife();
if(imageKnife!= undefined){
imageKnife.resumeRequests()
}
})
List({ space: 20, scroller: this.elementScroller }) {
LazyForEach(this.data, (item: Material, index) => {
ListItem() {
Column() {
Stack({ alignContent: Alignment.BottomEnd }) {
// 滤镜图片
ImageKnifeComponent({ imageKnifeOption: {
loadSrc: item.thumbnail,
mainScaleType: ScaleType.FIT_XY,
} })
}
.width(56).height(56)
//滤镜标题
Text(item.name)
.fontSize(10)
.maxLines(1)
.fontColor(Color.White)
.textAlign(TextAlign.Center)
.layoutWeight(1)
.width('100%')
.backgroundColor(Color.Orange)
}
.width(56)
.height(72)
.clip(true)
.borderRadius(4)
}
}, (item: Material) => item.material_id)
}
.listDirection(Axis.Horizontal)
.width('100%')
.height(72)
}
}
}

View File

@ -1,104 +0,0 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an 'AS IS' BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {ImageKnifeComponent, ScaleType,ImageKnife} from '@ohos/libraryimageknife'
import {ImageKnifeOption} from '@ohos/libraryimageknife'
import {ImageKnifeGlobal} from '@ohos/libraryimageknife'
import {RotateImageTransformation} from '@ohos/libraryimageknife'
import {Material} from './model/Material'
import {TestDataSource} from './model/TestDataSource'
import {DiskLruCache} from '@ohos/disklrucache'
import ArkWorker from '@ohos.worker'
import Prompt from '@system.prompt'
@Entry
@Component
struct photosPausedResumedPage {
private data: TestDataSource = new TestDataSource();
private elementScroller: Scroller = new Scroller()
build() {
Column() {
Button('这个List通过监听 开始滑动,停止加载图片;滑动结束,恢复加载图片')
.margin({top:10,bottom:5})
.onClick(()=>{
})
List({ space: 20, scroller: this.elementScroller }) {
LazyForEach(this.data, (item: Material, index) => {
ListItem() {
Column() {
Stack({ alignContent: Alignment.BottomEnd }) {
// 滤镜图片
ImageKnifeComponent({ imageKnifeOption: {
loadSrc: item.thumbnail,
mainScaleType: ScaleType.FIT_XY,
} })
}
.width(56).height(56)
//滤镜标题
Text(item.name)
.fontSize(10)
.maxLines(1)
.fontColor(Color.White)
.textAlign(TextAlign.Center)
.layoutWeight(1)
.width('100%')
.backgroundColor(Color.Orange)
}
.width(56)
.height(72)
.clip(true)
.borderRadius(4)
}
}, (item: Material) => item.material_id)
}
.onScrollStart(()=>{
let imageKnife:ImageKnife|undefined = ImageKnifeGlobal.getInstance().getImageKnife();
if(imageKnife!= undefined){
imageKnife.pauseRequests()
}
})
.onScrollStop(()=>{
let imageKnife:ImageKnife|undefined = ImageKnifeGlobal.getInstance().getImageKnife();
if(imageKnife!= undefined){
imageKnife.resumeRequests()
}
})
.listDirection(Axis.Horizontal)
.width('100%')
.height(72)
}
}
aboutToDisappear(){
// 如果用户滑动过程中就退出了页面我们需要恢复图片加载能力
let imageKnife:ImageKnife|undefined = ImageKnifeGlobal.getInstance().getImageKnife();
if(imageKnife!= undefined){
imageKnife.resumeRequests()
}
}
}

View File

@ -1,257 +0,0 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an 'AS IS' BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Pngj } from '@ohos/libraryimageknife'
import resourceManager from '@ohos.resourceManager';
import { FileUtils,ImageKnifeGlobal } from '@ohos/libraryimageknife'
import { BusinessError } from '@ohos.base'
import common from '@ohos.app.ability.common';
interface WorkerType {
type: string
name: string
}
@Entry
@Component
struct PngjTestCasePage {
pngSource1?: ArrayBuffer = undefined;
pngSource2?: ArrayBuffer = undefined;
pngSource3?: ArrayBuffer = undefined;
pngSource4?: ArrayBuffer = undefined;
pngdecodeRun1: boolean = false;
pngdecodeRun2: boolean = false;
pngdecodeRun3: boolean = false;
pngdecodeRun4: boolean = false;
rootFolder: string = '';
@State hint1: string = 'readPngImageInfo内容展示'
@State hint2: string = 'readPngImage内容展示'
@State hint3: string = 'writePngWithString内容展示'
@State hint4: string = 'writePngWithString内容展示'
@State hint5: string = '测试readMetadata'
@State hint6: string = '测试writeMetadata'
@State hint7: string = '首先点击获取PNG图片buffer'
@State hint8: string = '首先点击获取PNG图片buffer'
@State hint9: string = '首先点击获取PNG图片buffer'
@State hint10: string = '首先点击获取PNG图片buffer'
build() {
Scroll() {
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Text('pngj接口测试列表').fontSize(20)
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Button(this.hint7).fontSize(30)
.onClick(() => {
this.rootFolder = (ImageKnifeGlobal.getInstance().getHapContext() as common.UIAbilityContext).filesDir as string;
((ImageKnifeGlobal.getInstance().getHapContext() as common.UIAbilityContext)
.resourceManager as resourceManager.ResourceManager)
.getMediaContent($r('app.media.pngSample').id)
.then(data => {
this.pngSource1 = FileUtils.getInstance().uint8ArrayToBuffer(data);
this.hint7 = '获取buffer成功可以测试'
})
.catch( (err:BusinessError) => {
console.log('点击获取Png图片buffer err=' + err)
})
})
Button('测试readPng')
.onClick(() => {
if (this.pngSource1!=undefined) {
if (!this.pngdecodeRun1) {
this.pngdecodeRun1 = true;
let pngj = new Pngj();
pngj.readPngImageInfo(this.pngSource1,{pngCallback: (sender, value) => {
this.hint1 = JSON.stringify(value);
this.pngdecodeRun1 = false;
}})
} else {
this.hint7 = '已经在执行了,请稍等'
}
} else {
this.hint7 = '请先点击此处获取buffer'
}
}).margin({ top: 5, left: 10 })
}.width('100%')
.height(60).backgroundColor(Color.Pink)
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Button(this.hint8).fontSize(30)
.onClick(() => {
this.rootFolder = (ImageKnifeGlobal.getInstance().getHapContext() as common.UIAbilityContext).filesDir as string;
((ImageKnifeGlobal.getInstance().getHapContext() as common.UIAbilityContext)
.resourceManager as resourceManager.ResourceManager)
.getMediaContent($r('app.media.pngSample').id)
.then(data => {
this.pngSource2 = FileUtils.getInstance().uint8ArrayToBuffer(data);
this.hint8 = '获取buffer成功可以测试'
})
.catch((err:BusinessError) => {
console.log('点击获取Png图片buffer err=' + err)
})
})
Button('readPngAsync')
.onClick(() => {
if (this.pngSource2!=undefined) {
if (!this.pngdecodeRun2) {
this.pngdecodeRun2 = true;
let pngj = new Pngj();
let png_worker: WorkerType = {
type: 'classic',
name: 'readPngImageAsync'
}
pngj.readPngImageAsync(png_worker, this.pngSource2!, (value:ESObject) => {
this.hint8 = '重新获取buffer才能测试'
this.hint2 = 'img with=' + value.width + ' img height=' + value.height
+ ' img depth=' + value.depth + ' img ctype=' + value.ctype
this.pngdecodeRun2 = false;
})
} else {
this.hint8 = '已经在执行了,请稍等'
}
} else {
this.hint8 = '请先点击此处获取buffer'
}
}).margin({ top: 5, left: 10 })
}.width('100%')
.height(60).backgroundColor(Color.Pink)
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Button(this.hint9).fontSize(30)
.onClick(() => {
this.rootFolder = (ImageKnifeGlobal.getInstance().getHapContext() as common.UIAbilityContext).filesDir as string;
((ImageKnifeGlobal.getInstance().getHapContext() as common.UIAbilityContext)
.resourceManager as resourceManager.ResourceManager)
.getMediaContent($r('app.media.pngSample').id)
.then(data => {
this.pngSource3 = FileUtils.getInstance().uint8ArrayToBuffer(data);
this.hint9 = '获取buffer成功可以测试'
})
.catch((err:BusinessError) => {
console.log('点击获取Png图片buffer err=' + err)
})
})
Button('测试writePngWithString')
.onClick(() => {
if (this.pngSource3 != undefined) {
if (!this.pngdecodeRun3) {
this.pngdecodeRun3 = true;
let pngj = new Pngj();
let png_worker: WorkerType = {
type: 'classic',
name: 'writePngWithStringAsync'
}
pngj.writePngWithStringAsync(png_worker, this.pngSource3, ( value:ESObject) => {
FileUtils.getInstance().createFileProcess(
this.rootFolder + '/pngj',
this.rootFolder + '/pngj/newPng.png',
value)
let png1 = new Uint8Array(value)
this.hint3 = 'png写入后长度' + png1.byteLength + '目录文件:' + this.rootFolder + '/pngj/newPng.png' + '保存后使用2进制查看数据是否新增'
this.pngdecodeRun3 = false;
},'hello world')
} else {
this.hint9 = '已经在执行了,请稍等'
}
} else {
this.hint9 = '请先点击此处获取buffer'
}
}).margin({ top: 5, left: 10 })
}.width('100%')
.height(60).backgroundColor(Color.Pink)
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Button(this.hint10).fontSize(30)
.onClick(() => {
this.rootFolder = (ImageKnifeGlobal.getInstance().getHapContext() as common.UIAbilityContext).filesDir as string;
((ImageKnifeGlobal.getInstance().getHapContext() as common.UIAbilityContext)
.resourceManager as resourceManager.ResourceManager)
.getMediaContent($r('app.media.pngSample').id)
.then(data => {
this.pngSource4 = FileUtils.getInstance().uint8ArrayToBuffer(data);
this.hint10 = '获取buffer成功可以测试'
})
.catch((err:BusinessError) => {
console.log('点击获取Png图片buffer err=' + err)
})
})
Button('writePng')
.onClick(()=>{
if (this.pngSource4 != undefined) {
if (!this.pngdecodeRun4) {
this.pngdecodeRun4 = true;
let pngj = new Pngj();
let png_worker: WorkerType = {
type: 'classic',
name: 'writePngAsync'
}
pngj.writePngAsync(png_worker, this.pngSource4, ( value:ESObject) => {
FileUtils.getInstance().createFileProcess(
this.rootFolder + '/pngj',
this.rootFolder + '/pngj/newPng2.png',
value)
let png2 = new Uint8Array(value)
this.hint4 = 'png2未写入长度' + png2.byteLength + '目录文件:' + this.rootFolder + '/pngj/newPng2.png' + '保存后使用2进制查看数据是否新增'
this.pngdecodeRun4 = false;
})
} else {
this.hint10 = '已经在执行了,请稍等'
}
} else {
this.hint10 = '请先点击此处获取buffer'
}
})
.margin({ top: 5, left: 10 })
}.width('100%')
.height(60).backgroundColor(Color.Pink)
Text(this.hint1)
.width('100%')
.height(120)
Text(this.hint2)
.width('100%')
.height(120)
Text(this.hint3)
.width('100%')
.height(120)
Text(this.hint4)
.width('100%')
.height(120)
}
.width('100%')
.height('100%')
}
}
typedArrayToBuffer(array: Uint8Array): ArrayBuffer {
return array.buffer.slice(array.byteOffset, array.byteLength + array.byteOffset)
}
}

View File

@ -1,64 +0,0 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {ImageKnifeComponent} from '@ohos/libraryimageknife'
import {ImageKnifeOption} from '@ohos/libraryimageknife'
import {RotateImageTransformation} from '@ohos/libraryimageknife'
import {RoundedCornersTransformation} from '@ohos/libraryimageknife'
@Entry
@Component
struct ShowErrorholderTestCasePage {
@State imageKnifeOption1: ImageKnifeOption =
{
loadSrc: "https://thirdwx.qlogo.cn/mmopen/xxxxx",
placeholderSrc: $r('app.media.icon_loading'),
errorholderSrc: $r('app.media.icon_failed'),
};
@State imageKnifeOption: ImageKnifeOption =
{
loadSrc: "https://hbimg.huabanimg.com/xxxxx",
placeholderSrc: $r('app.media.icon_loading'),
errorholderSrc: $r('app.media.icon_failed'),
};
@State imageKnifeOption3: ImageKnifeOption =
{
loadSrc: "https://hbimg.huabanimg.com/xxxxx",
placeholderSrc: $r('app.media.icon_loading'),
errorholderSrc: $r('app.media.icon_failed'),
};
@State imageKnifeOption4: ImageKnifeOption =
{
loadSrc: "https://hbimg.huabanimg.com/xxxxx",
placeholderSrc: $r('app.media.icon_loading'),
errorholderSrc: $r('app.media.icon_failed'),
};
build() {
Scroll() {
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
ImageKnifeComponent({ imageKnifeOption: this.imageKnifeOption1 }).width(300).height(300)
ImageKnifeComponent({ imageKnifeOption: this.imageKnifeOption }).width(300).height(300)
ImageKnifeComponent({ imageKnifeOption: this.imageKnifeOption3 }).width(300).height(300)
ImageKnifeComponent({ imageKnifeOption: this.imageKnifeOption4 }).width(300).height(300)
}
}
.width('100%')
.height('100%')
}
}

View File

@ -1,55 +0,0 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {LruCache} from '@ohos/libraryimageknife'
function getRandomInt(min:number, max:number):number {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min)) + min; //不含最大值,含最小值
}
@Entry
@Component
struct StorageTestLruCache {
@State logText:string = "打印日志结果";
@State nowNumText:string = "显示输入的数据";
mLruCache:LruCache<string,string> = new LruCache(5);
build() {
Scroll() {
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Text("默认创建一个容量为5的LruCache")
.backgroundColor(Color.Blue)
Button("随机存入一个数字0-9")
.onClick(()=>{
let randomNum = getRandomInt(0,10);
this.nowNumText = ''+randomNum;
this.mLruCache.put(randomNum+"",randomNum+"")
this.logText = "日志结果:"+this.mLruCache.print();
}) .margin({top:20})
Button(this.nowNumText)
.margin({top:20})
Scroll() {
Text(this.logText).fontSize(15)
}.width(300).height(200).margin({top:20}).backgroundColor(Color.Pink)
}
.width('100%')
.height('100%')
}
}
}

View File

@ -1,81 +0,0 @@
/*
* Copyright (C) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {SVGParseImpl} from '@ohos/libraryimageknife'
import { ImageKnifeComponent } from '@ohos/libraryimageknife'
import resourceManager from '@ohos.resourceManager';
import {BusinessError} from '@ohos.base'
import common from '@ohos.app.ability.common';
@Entry
@Component
struct svgTestCasePage {
@State svgSamplePixelMap?: Resource = undefined
@State svgIconPixelMap?: Resource = undefined
build() {
Scroll() {
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Flex({direction:FlexDirection.Row}){
Button("加载SVG图片")
.onClick(()=>{
this.svgSamplePixelMap = $r('app.media.svgSample')
}).margin({left:5}).backgroundColor(Color.Blue)
}
.margin({top:15})
Text("下面为展示图片区域").margin({top:5})
Flex({direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }){
ImageKnifeComponent({imageKnifeOption:{
loadSrc:this.svgSamplePixelMap as Resource
}})
.width(400)
.height(400)
.backgroundColor(Color.Pink)
}.width(400).height(400).margin({top:10}).backgroundColor(Color.Pink)
Flex({direction:FlexDirection.Row}){
Button("加载SVG图片")
.onClick(()=>{
this.svgIconPixelMap = $r('app.media.iconsvg')
}).margin({left:5}).backgroundColor(Color.Blue)
}
.margin({top:15})
Text("下面为展示图片区域").margin({top:5})
Flex({direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }){
ImageKnifeComponent({imageKnifeOption:{
loadSrc:this.svgIconPixelMap as Resource
}})
.width(400)
.height(400)
.backgroundColor(Color.Pink)
}.width(400).height(400).margin({top:10}).backgroundColor(Color.Pink)
}
}
.width('100%')
.height('100%')
}
aboutToAppear() {
console.log("aboutToAppear()")
}
typedArrayToBuffer(array: Uint8Array): ArrayBuffer {
return array.buffer.slice(array.byteOffset, array.byteLength + array.byteOffset)
}
}

View File

@ -1,98 +0,0 @@
/*
* Copyright (C) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {
ImageKnifeComponent,
ImageKnifeOption,
ImageKnifeGlobal,
ImageKnife,
ImageKnifeDrawFactory,
ScaleType
} from '@ohos/libraryimageknife'
import worker from '@ohos.worker';
@Entry
@Component
struct tempUrlTestPage {
@State imageKnifeOption1: ImageKnifeOption =
{
loadSrc: $r('app.media.icon'),
placeholderSrc: $r('app.media.icon_loading'),
errorholderSrc: $r('app.media.icon_failed')
};
@State imageKnifeOption2: ImageKnifeOption =
{
loadSrc: $r('app.media.icon'),
placeholderSrc: $r('app.media.icon_loading'),
errorholderSrc: $r('app.media.icon_failed')
};
build() {
Scroll() {
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Text("简单示例1加载一张本地png图片").fontSize(15)
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Button("加载PNG")
.onClick(() => {
this.imageKnifeOption1 = {
// loadSrc:"https://res.vmallres.com/cmscdn/CN/2023-03/a11790b9335a4d598d59f14795368e14.png.75.webp",
loadSrc:"https://xximg1.meitudata.com/2LqS1vmqv0.png!thumb-w321-webp75",
mainScaleType: ScaleType.FIT_XY,
placeholderSrc: $r('app.media.icon_loading'),
errorholderSrc: $r('app.media.icon_failed'),
drawLifeCycle:ImageKnifeDrawFactory.createRoundLifeCycle(0,'#00000000',30)
}
}).margin({ top: 5, left: 3 })
ImageKnifeComponent({ imageKnifeOption: this.imageKnifeOption1 }).width('100%').height(300).backgroundColor(Color.Orange)
}
.width('100%').height(400).backgroundColor(Color.Pink)
Text("简单示例2加载一张网络gif图片").fontSize(15)
Text("gif解析在子线程,请在页面构建后创建worker,注入imageknife").fontSize(15)
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Button("加载GIF")
.onClick(() => {
this.imageKnifeOption2 = {
loadSrc: 'https://res.vmallres.com/cmscdn/CN/2023-03/7052a601ac3e428c84c9415ad9734735.gif',
placeholderSrc: $r('app.media.icon_loading'),
errorholderSrc: $r('app.media.icon_failed'),
displayProgress:true,
}
}).margin({ top: 5, left: 3 })
ImageKnifeComponent({ imageKnifeOption: this.imageKnifeOption2 }).width(300).height(300)
}.width('100%').backgroundColor(Color.Pink)
}.width('100%')
}
.width('100%')
.height('100%')
}
aboutToAppear() {
}
aboutToDisappear(){
}
onBackPress() {
}
}

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