Compare commits

..

No commits in common. "master" and "1.0.5" have entirely different histories.

427 changed files with 19270 additions and 20372 deletions

View File

@ -1,2 +0,0 @@
imageknife/src/main/ets/components/3rd_party/**/*
hvigor/hvigor-wrapper.js

View File

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

View File

@ -1,47 +0,0 @@
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

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

View File

@ -1,21 +0,0 @@
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

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

View File

@ -1,72 +0,0 @@
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

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

9
.gitignore vendored
View File

@ -1,11 +1,4 @@
/node_modules
/oh_modules
/local.properties
/.idea
**/build
/.hvigor
.cxx
/.clangd
/.clang-format
/.clang-tidy
**/.test
**/build

3
.gitmodules vendored
View File

@ -1,3 +0,0 @@
[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": "3.0.0-rc.0",
"versionName": "1.0.0",
"icon": "$media:app_icon",
"label": "$string:app_name",
"distributedNotificationEnabled": true

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 6.6 KiB

View File

@ -1,510 +1,29 @@
## 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
- 适配Sendable内存共享优化
- 修改全局请求头覆盖request请求头
- imageKnife支持heic测试demo独立页面展示
- drawLifeCycle支持gif图
## 2.1.2
- 修改ImageKnife跳过网络从内存中获取图片 cacheType参数未使用bug
- 新增WEBP图片解析能力。
- 新增gif图片支持暂停播放功能
## 2.1.2-rc.12
- 新增gif播放次数功能
- 新增磁盘预加载返回文件路径接口prefetchToDiskCache
- 新增跳过网络判断缓存或者磁盘中是否存在图片接口isUrlExist
- 删除多余操作磁盘记录读写
- 清除定时器改为Gif图时清除
- uuid改为util.generateRandomUUID()
## 2.1.2-rc.11
- 修复设置磁盘容量最大值出现闪退
- 修复概率出现jscrash问题
- 修复进度条问题
- 修复单帧gif图片加载失败
- removeRunning删除running队列log设置开关
- ImageKnife新增图片宽高自适应功能
- 修复onlyRetrieveFromCache属性(仅磁盘和内存获取资源)失效
- 修改拼写错误
- 新增多线程优先级
- 修复复用场景下图片闪动以及概率错位
- 获取组件宽高改为使用CanvasRenderingContext2D对象获取宽高并修复改变字体大小导致部分图片消失
- 修复获取不到磁盘缓存文件问题
- 修复获取不到网络请求错误回调问题
## 2.1.2-rc.10
- 修复部分gif图片识别成静态图
- 修复同一张图片发送多次请求
- 复用场景缓存到树aboutToRecycle清理定时器
## 2.1.2-rc.9
- 使用taskpool实现多线程加载图片资源
- 修复部分gif图片识别成静态图
- 修复同一张图片发送多次请求
- disAppear生命周期清空定时器只在gif图片时执行
## 2.1.2-rc.8
- onAreaChange绘制图片改为component Util绘制
## 2.1.2-rc.7
- 修复图片圆角图形变换导致抗锯齿、ScaleType失效
- 修复使用模糊化出现图片变模糊和变形
## 2.1.2-rc.6
- 修复手机调节显示大小时图片消失
- imageKnife防盗链header请求头属性设置
- pngWorker线程改为taskpool
- 修复正方形裁剪有些图片裁剪创建pixelMap失败
## 2.1.2-rc.5
- moduleContext新增缓存策略缓存上限5缓存策略Lru
- 适配DevEco Studio 4.14.1.3.415--SDK:API11 4.1.0.56
## 2.1.2-rc.4
- canvas新增抗锯齿
- 修复图片缩放时出现重影
## 2.1.2-rc.3
- svg图片解码改为imageSource解码
## 2.1.2-rc.2
- HSP兼容性优化
- 暴露DetachFromLayout接口
- 修复无法识别部分svg图片的类型
## 2.1.2-rc.1
- 修复断网状态下错误占位图不显示
- 适配IDE4.1(4.1.3.322)和SDK API11(4.1.0.36)
## 2.1.2-rc.0
- 开放.jpg .png .gif的taskpool解码能力
## 2.1.1
- 屏蔽了taskpool解码能力
- 2.1.1正式版本发布
## 2.1.1-rc.5
- .jpg .png .gif解码功能使用taskpool实现
- 修复了内存缓存张数设置为1时gif图片消失的问题
- 新增内存缓存策略,新增缓存张数,缓存大小设置接口
- 磁盘存缓存setAsync改成同步
- 部分release释放放在异步
- requestInStream的回调改成异步
- 修复tasktool出现crash问题
- imageKnife依赖更名为library
- 解决外部定时器失效的问题
## 2.1.1-rc.4
- 删除pako源码依赖,使用ohpm依赖
- 删除gif软解码相关依赖库,包括gifuct-js和jsBinarySchemaParser
- 新增ImageKnife在HSP场景中的使用案例展示
- 更改ImageKnifeOption
新增可选参数context,HSP场景中在shard library中使用必须要传递当前library的context对象 (例如:getContext(this).createModuleContext('library') as common.UIAbilityContext才能保证后续程序正常获取shared library中的Resource资源
- 更改RequestOption:
新增接口setModuleContext(moduleCtx:common.UIAbilityContext)在HSP场景中必须调用该接口传入正确的context对象,保证HSP场景下正确访问资源
新增接口getModuleContext():common.UIAbilityContext | undefined
## 2.1.1-rc.3
- 门面类ImageKnife新增pauseRequests接口,全局暂停请求
- 门面类ImageKnife新增resumeRequests接口,全局恢复暂停
## 2.1.1-rc.2
- gif解码改为imageSource解码,不在对worker强依赖
- 下载接口修改为http.requestInStream
## 2.1.1-rc.1
- 新增自定义key参数配置
- 新增MemoryLruCache主动调用PixelMap的release方法,释放native的PixelMap内存
- 新增ImageSource主动调用release方法释放native持有的ImageSource内存
## 2.1.1-rc.0
- 修复不兼容API9的问题
## 2.1.0
- ArkTs语法适配:
globalThis.ImageKnife方式已经不可使用
提供了ImageKnifeGlobal对象单例全局可访问
访问ImageKnife对象需要使用ImageKnifeGlobal.getInstance().getImageKnife()
- 裁剪组件暴露PixelMapCrop组件和配置类Options, 配置类Options不再需要声明PixelMapCrop.Options中的PixelMapCrop命名空间
- 适配DevEco Studio 版本4.0(4.0.3.512), SDK: API10 (4.0.10.9)
## 2.0.5-rc.0
- 修复若干问题:
优化了内存缓存策略,修复了内存缓存策略给布尔值不生效的问题
## 2.0.4
- 修复若干问题:
修复了pngj测试页面快速点击导致应用闪退的问题
## 2.0.3
- 修复若干问题:
修复了部分url测试多次点击加载gif动画重影的问题
优化了gif测试中的测试图片加强了测试的直观性
解决gif图片只有1帧时因帧时间延时时间为NaN时导致图片帧不显示的问题
## 2.0.2
- 修复若干问题:
修复ImageKnife绘制部分复杂gif图片gif图片闪屏显示的问题
适配DevEco Studio 版本4.0 Canary2(4.0.3.312), SDK: API10 (4.0.9.3)
## 2.0.1
- 修复若干问题:
修复ImageKnifeDrawFactory中的setOval和setRect的中心点取值错误导致部分圆角绘制失效的问题。
修复因重复下载导致的漏加载的问题。
- 新增用例看护已修复的问题
## 2.0.0
- 包管理工具由npm切换为ohpm。
- 适配DevEco Studio: 3.1Beta2(3.1.0.400)。
- 适配SDK: API9 Release(3.2.11.9)。
- 新增开发者可对图片缓存进行全局配置能力。
- 新增对OpenHarmony图库的Uri数据加载的能力需要申请图库访问权限和文件读取权限动态申请图库访问权限
- 修复若干问题:
ImageKnifeOption的loadSrc为undefined导致的crash问题。
ImageKnifeComponent直接绘制GIF图片格式第几帧的时候无法绘制问题。
## 1.0.6
- 适配DevEco Studio 3.1Beta1及以上版本。
- 适配OpenHarmony SDK API version 9及以上版本。
- 以下变换支持通过GPU进行图片变换默认未开启开启需要自行调用接口.enableGPU()。
支持模糊图片变换
支持亮度滤波器
支持颜色反转滤波器
支持对比度滤波器
支持灰色滤波器
支持桑原滤波器
支持马赛克滤波器
支持乌墨色滤波器
支持素描滤波器
支持扭曲滤波器
支持动画滤波器
支持装饰滤波器
## 1.0.5
- 自定义组件已支持通用属性和通用事件绑定,因此ImageKnifeComponent将删除相关内容,相关内容由用户自定义实现,提高扩展能力
- 自定义组件已支持通用属性和通用事件绑定,因此ImageKnifeComponent将删除相关内容,相关内容由用户自定义实现,提高扩展能力
- ImageKnifeOption 支持列表绑定
- ImageKnifeOption 支持列表绑定
- ImageKnifeOption
- ImageKnifeOption
新增
- 1.onClick事件属性
- 1.onClick事件属性
删除
删除
- 1.size(设置大小)
- 2.sizeAnimated 显式动画
- 1.size(设置大小)
- 2.sizeAnimated 显式动画
- 3.backgroundColor背景色
- 4.margin 组件外间距 等属性,删除的属性将由通用属性提供支持,可支持在ImageKnifeComponent自定义组件上链式调用
## 1.0.4
- 渲染显示部分使用Canvas组件替代Image组件
- 渲染显示部分使用Canvas组件替代Image组件
- 重构渲染封装层ImageKnifeComponent自定义组件
- 重构渲染封装层ImageKnifeComponent自定义组件
- 新增GIF图片解析能力
- 新增GIF图片解析能力
- 新增SVG图片解析能力。
- RequestOption删除addRetryListener接口,重试图层监听请使用retryholder接口。
- 新增SVG图片解析能力
## 1.0.3

2
NOTICE
View File

@ -148,7 +148,7 @@ http://www.quasimondo.com/StackBlurForCanvas/StackBlurDemo.html
Java Author: Mario Klingemann <mario at quasimondo.com>
http://incubator.quasimondo.com
created February 29, 2004
created Feburary 29, 2004
port : Yahel Bouaziz <yahel at kayenko.com>
http://www.kayenko.com
ported april 5th, 2012

47
OAT.xml
View File

@ -1,45 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- 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.
This is the configuration file template for OpenHarmony OSS Audit Tool, please copy it to your project root dir and modify it refer to OpenHarmony/tools_oat/README.
-->
<configuration>
<oatconfig>
<filefilterlist>
<filefilter name="copyrightPolicyFilter" desc="Filters for compatibilitylicense header policies">
<filteritem type="filename" name="hvigorfile.*" desc="hvigor配置文件DevEco Studio自动生成不手动修改"/>
<filteritem type="filename" name="hvigorfile.js" desc="hvigor构建脚本DevEco Studio自动生成不手动修改"/>
<filteritem type="filename" name="*.json5" desc="hvigor配置文件DevEco Studio自动生成不手动修改"/>
<filteritem type="filepath" name="imageknife/src/main/ets/components/imageknife/pngj/UPNG.js" desc="使用开源库UPNG,使用其默认版权头,无需修改"/>
<filteritem type="filepath" name="imageknife/src/main/ets/components/imageknife/utils/gif/parse/lzw.js" desc="使用开源库gifuct-js,使用其默认版权头,无需修改"/>
<filteritem type="filename" name="LICENSE" desc="版权文件,不添加版权头"/>
<filteritem type="filename" name="NOTICE" desc="NOTICE文件不添加版权头"/>
<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="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自动生成不手动修改"/>
<filteritem type="filename" name="*.json5" desc="hvigor等配置文件DevEco Studio自动生成且不支持注释"/>
<filteritem type="filename" name="hvigorfile.js" desc="hvigor构建脚本DevEco Studio自动生成不手动修改"/>
<filteritem type="filename" name="*.json5" desc="hvigor配置文件DevEco Studio自动生成不手动修改"/>
<filteritem type="filepath" name="imageknife/src/main/ets/components/imageknife/pngj/UPNG.js" desc="使用开源库UPNG,使用其默认版权头,无需修改"/>
<filteritem type="filepath" name="imageknife/src/main/ets/components/imageknife/utils/gif/parse/lzw.js" desc="使用开源库gifuct-js,使用其默认版权头,无需修改"/>
<filteritem type="filename" name="LICENSE" desc="版权文件,不添加版权头"/>
<filteritem type="filename" name="NOTICE" desc="NOTICE文件不添加版权头"/>
<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="filename" name=".gitmodules" desc="git配置文件不添加版权头"/>
<filteritem type="filepath" name="library/src/main/ets/3rd_party/.*" desc="第三方开源软件源码,不修改版权头,以防有修改版权风险"/>
</filefilter>
<filefilter name="defaultPolicyFilter" desc="Filters for copyright header policies">
</filefilter>
<filefilter name="binaryFileTypePolicyFilter" desc="Filters for binary file policies">
<filteritem type="filename" name="*.dpg" desc="dpg图片格式文件,用于展示示例"/>
@ -50,12 +30,7 @@
<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="*.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/3rd_party/.*" desc="第三方开源软件源码,不修改版权头,以防有修改版权风险"/>
</filefilter>
</filefilterlist>
</oatconfig>
</configuration>
</configuration>

View File

@ -1,10 +1,10 @@
[
{
"Name": "glide",
"License": "Apache License 2.0",
"License File": "LICENSE",
"License": "under one or more license",
"License File": "https://github.com/bumptech/glide/blob/master/LICENSE",
"Version Number": "4.13.1",
"Owner" : "xiafeng@huawei.com",
"Owner" : "bumptech",
"Upstream URL": "https://github.com/bumptech/glide",
"Description": "An image loading and caching library focused on smooth scrolling"
},
@ -12,9 +12,9 @@
{
"Name": "glide-transformations",
"License": "Apache License 2.0",
"License File": "LICENSE",
"License File": "https://github.com/wasabeef/glide-transformations/blob/main/LICENSE",
"Version Number": "4.3.0",
"Owner" : "xiafeng@huawei.com",
"Owner" : "wasabeef",
"Upstream URL": "https://github.com/wasabeef/glide-transformations",
"Description": " An transformation library providing a variety of image transformations for Glide. "
},
@ -22,9 +22,9 @@
{
"Name": "fresco",
"License": "MIT License",
"License File": "LICENSE",
"License File": "https://github.com/facebook/fresco/blob/main/LICENSE",
"Version Number": "2.6.0",
"Owner" : "xiafeng@huawei.com",
"Owner" : "facebook",
"Upstream URL": "https://github.com/facebook/fresco",
"Description": " An library for managing images and the memory they use. "
},
@ -32,9 +32,9 @@
{
"Name": "UPNG.js",
"License": "MIT License",
"License File": "LICENSE",
"License File": "https://github.com/photopea/UPNG.js/blob/master/LICENSE",
"Version Number": "1.0.0",
"Owner" : "xiafeng@huawei.com",
"Owner" : "photopea",
"Upstream URL": "https://github.com/photopea/UPNG.js",
"Description": " Fast and advanced PNG (APNG) decoder and encoder (lossy / lossless) "
},
@ -42,9 +42,9 @@
{
"Name": "Luban",
"License": "Apache License 2.0",
"License File": "LICENSE",
"License File": "https://github.com/Curzibn/Luban/blob/master/LICENSE",
"Version Number": "1.1.8",
"Owner" : " xiafeng@huawei.com",
"Owner" : " Curzibn",
"Upstream URL": "https://github.com/Curzibn/Luban",
"Description": " Luban(鲁班)—Image compression with efficiency very close to WeChat Moments/可能是最接近微信朋友圈的图片压缩算法 "
},
@ -54,18 +54,9 @@
"License": "Apache License 2.0",
"License File": "https://github.com/Yalantis/uCrop/blob/develop/README.md",
"Version Number": "2.2.8",
"Owner" : " xiafeng@huawei.com",
"Owner" : " Yalantis",
"Upstream URL": "https://github.com/Yalantis/uCrop",
"Description": " Image Cropping Library "
},
{
"Name": "js-spark-md5",
"License": "MIT",
"License File": "LICENSE",
"Version Number": "v3.0.2",
"Owner" : "xiafeng@huawei.com",
"Upstream URL": "https://github.com/satazor/js-spark-md5",
"Description": "Lightning fast normal and incremental md5 for javascript"
}
]

838
README.md
View File

@ -1,389 +1,527 @@
## 🚨 **重要提示 | 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
ImageKnife is a specially crafted image loading and caching library for OpenHarmony, optimized for efficiency, lightness, and simplicity.
**专门为OpenHarmony打造的一款图像加载缓存库致力于更高效、更轻便、更简单。**
## Introduction
## 简介
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:
本项目基于开源库 [Glide](https://github.com/bumptech/glide) 进行OpenHarmony的自研版本
- 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
- 支持内存缓存使用LRUCache算法对图片数据进行内存缓存。
- 支持磁盘缓存,对于下载图片会保存一份至磁盘当中。
- 支持进行图片变换: 支持图像像素源图片变换效果。
- 支持用户配置参数使用:(例如:配置是否开启一级内存缓存,配置磁盘缓存策略,配置仅使用缓存加载数据,配置图片变换效果,配置占位图,配置加载失败占位图等)。
- 推荐使用ImageKnifeComponent组件配合ImageKnifeOption参数来实现功能。
- 支持用户自定义配置实现能力参考ImageKnifeComponent组件中对于入参ImageKnifeOption的处理。
Planned features:
<img src="screenshot/gif1.gif" width="50%"/>
- 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)
```typescript
npm install @ohos/imageknife --save
```
## How to Use
OpenHarmony npm环境配置等更多内容参考安装教程 [如何安装OpenHarmony npm包](https://gitee.com/openharmony-tpc/docs/blob/master/OpenHarmony_npm_usage.md)。
#### 1. Displaying a Local Resource Image
## 使用说明
```
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)
```
1.在AbilityStage.ts中,初始化全局ImageKnife实例。
#### 2. Displaying a File from Local Context Files
```typescript
import AbilityStage from "@ohos.application.AbilityStage"
import {ImageKnife} from '@ohos/imageknife'
```
ImageKnifeComponent({
ImageKnifeOption: {
loadSrc: this.localFile,
placeholderSrc: $r("app.media.loading"),
errorholderSrc: $r("app.media.app_icon"),
objectFit: ImageFit.Auto
}
}).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)
```
#### 4. Downloading an Image with Custom Options
```
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
export default class MyAbilityStage extends AbilityStage {
onCreate() {
// 初始化全局ImageKnife实例在AbilityStage.ts中调用ImageKnife.with(this.context)进行初始化
globalThis.ImageKnife = ImageKnife.with(this.context)
}
}
}).width(100).height(100)
// 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
}
```
#### 5. Listening for Network Download Progress
### 1.加载普通图片
```
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
```
ImageKnifeComponent({ ImageKnifeOption:
{
loadSrc: $r("app.media.rabbit"),
border: {radius:50}
}
}).width(100).height(100)
```
#### 7. Setting Image Transformation Options
```
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.
Example of circular cropping transformation:
```
ImageKnifeComponent({ ImageKnifeOption:
{
loadSrc: $r('app.media.pngSample'),
objectFit: ImageFit.Cover,
border: { radius: 150 }
}
}).width(300)
.height(300)
```
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)
```typescript
import {ImageKnifeComponent} from '@ohos/imageknife'
import {ImageKnifeOption} 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')
};
build() {
Scroll() {
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
ImageKnifeComponent({ imageKnifeOption: $imageKnifeOption1 })
.width(300) // 自定义组件支持通用属性链式调用,可以直接设置宽高
.height(300)
}
}
}
.width('100%')
.height('100%')
}
}).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数据对象然后在你需要的UI位置加入ImageKnifeComponent自定义组件就可以加载出一张图像了。
### ImageKnifeOption
### 2.加载SVG图片
| 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. |
加载svg其实和普通流程没有区别,只要将 `loadSrc: $r('app.media.jpgSample'),` `改成一张 loadSrc: $r('app.media.svgSample'),`svg类型图片即可。
### ImageKnife
目前加载SVG图片解析依赖了 [SVG三方库](https://gitee.com/openharmony-sig/ohos-svg)由于目前该库还无法解析mask标签所以这里大家需要留意一下。
| 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)
### 3.加载GIF图片
| 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**). |
3.1加载GIF其实和普通流程也没有区别只要将 `loadSrc: $r('app.media.jpgSample'),` `改成一张 loadSrc: $r('app.media.gifSample'),`GIF图片即可。
## 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"
但是解析gif图片属于耗时操作所以我们需要将其放入子线程操作。 **这里我们需要在页面的创建和销毁上添加一个worker子线程操作。**
```typescript
import router from '@system.router';
import {
ImageKnifeComponent,
ImageKnifeOption,
} from '@ohos/imageknife'
import ArkWorker from '@ohos.worker'
@Entry
@Component
struct IndexFunctionDemo {
private globalGifWorker:any = undefined
@State imageKnifeOption: ImageKnifeOption =
{
loadSrc: $r('app.media.gifSample'),
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("简单示例加载一张gif图片").fontSize(15)
ImageKnifeComponent({ imageKnifeOption: $imageKnifeOption })
.width(300) // 自定义组件支持通用属性链式调用,可以直接设置宽高
.height(300)
}
}
```
## Constraints
.width('100%')
.height('100%')
}
This project has been verified in the following version:
aboutToAppear() {
// 页面初始化创建worker
this.globalGifWorker = new ArkWorker.Worker('entry/ets/pages/workers/gifParseWorker.ts', {
type: 'classic',
name: 'ImageKnifeParseGIF'
})
// gif解析在子线程,请在页面构建后创建worker,注入imageknife
globalThis.ImageKnife.setGifWorker(this.globalGifWorker)
}
aboutToDisappear(){
// 页面销毁 销毁worker
if(this.globalGifWorker){
this.globalGifWorker.terminate();
}
}
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
#### 创建worker
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.
由于使用到了worker目前worker创建只能在entry里面所以我这边着重讲一下worker配置的流程。
## License
在entry/src/main/ets/pages目录下创建文件夹workers,然后在文件夹中创建gifParseWorker.ts文件最后填入内容:
This project is licensed under [Apache License 2.0](https://gitee.com/openharmony-tpc/ImageKnife/blob/master/LICENSE).
```typescript
import arkWorker from '@ohos.worker';
import { gifHandler } from '@ohos/imageknife/GifWorker'
## Known Issues
arkWorker.parentPort.onmessage = gifHandler;
```
- The **ImageFit** attribute cannot be set for the **ImageKnifeAnimator** component.
- The **border** attribute of the **ImageKnifeAnimator** component cannot make the image rounded corners.
代码处理流程已经封装在gifHanlder函数中了。
<img src="screenshot/jpg1.jpg" width="100%"/>
接下来我们需要在entry/build-profile.json5文件中添加配置
```typescript
{
"apiType": 'stageMode',
"buildOption": {
"sourceOption": {
"workers": [
"./src/main/ets/pages/workers/gifParseWorker.ts",
]
}
},
"targets": [
{
"name": "default",
},
{
"name": "ohosTest",
}
]
}
```
<img src="screenshot/jpg2.jpg" width="100%"/>
经过了上面的配置就配置好了worker, GIF图片加载就能顺利进行了。 **如果GIF加载未成功可以检查一下worker配置是否完成**
## 进阶使用
如果简单的加载一张图像无法满足需求我们可以看看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/> } | GIF播放控制能力可选 |
| transformation | BaseTransform<PixelMap> | 单个变换(可选) |
| transformations | Array<BaseTransform<PixelMap>> | 多个变换,目前仅支持单个变换(可选) |
| allCacheInfoCallback | IAllCacheInfoCallback | 输出缓存相关内容和信息(可选) |
| **drawLifeCycle** | **IDrawLifeCycle** | **用户自定义实现绘制方案(可选)** |
其他参数只需要在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'),
// 组件宽设置为300高设置为300必选
size: { width: '300', height: '300' },
// 占位图使用本地资源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: $imageKnifeOption1 })
}
}
.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 AbilityStage from '@ohos.application.AbilityStage'
import { ImageKnife,ImageKnifeDrawFactory} from '@ohos/imageknife'
import ArkWorker from '@ohos.worker'
export default class MyAbilityStage extends AbilityStage {
onCreate() {
globalThis.ImageKnife = ImageKnife.with(this.context);
// 全局配置网络加载进度条
globalThis.ImageKnife.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对象的内容最后使用 `globalThis.ImageKnife.call(request)`发送request执行任务即可。**
是不是很简单,而其实最重要的内容是就是: **按需配置request对象的内容** 为了更好理解,我举例说明一下:
#### 场景一: 简单加载一张图片
```typescript
let request = new RequestOption();
(必传)
request.load("图片url")
(可选 整个request监听回调
.addListener((err, data) => {
// data 是ImageKnifeData对象
if(data.isPixelMap()){
// 这样就获取到了目标PixelMap
let pixelmap = data.drawPixleMap.imagePixelMap;
}
return false;
})
let compSize = {
width: this.currentWidth,
height:this.currentHeight
}
// 必传这里setImageViewSize函数必传组件大小因为涉及到图片变换效果都需要适配图像源和组件大小。
request.setImageViewSize(compSize)
// 最后使用ImageKnife的call函数调用request即可
globalThis.ImageKnife.call(request)
```
**其他场景,可以按需加载**
比如我需要配置 **占位图** 只需要 在request对象创建好之后调用 **placeholder** 函数即可
```typescript
request.placeholder(this.imageKnifeOption.placeholderSrc, (data) => {
console.log('request.placeholder callback')
this.displayPlaceholder(data)
})
```
再比如 我对缓存配置有要求,我要禁用内存缓存,调用 **skipMemoryCache** 函数即可
```typescript
request.skipMemoryCache(true)
```
这里只是简单介绍部分使用,更多的内容请参考 **按需加载** 原则并且可以参考ImageKnifeComponent源码或者根据文档自行探索实现。
## 接口说明
### RequestOption 用户配置参数:
| 方法名 | 入参 | 接口描述 |
| ------------------------------------------------------------ | ---------------------------------------------------------- | -------------------------------------------------------- |
| load(src: string \| PixelMap \| Resource) | string \| PixelMap \| Resource | 待加载图片的资源 |
| setImageViewSize(imageSize: { width: number, height: number }) | { width: number, height: number } | 传入显示图片组件的大小,变换的时候需要作为参考 |
| diskCacheStrategy(strategy: DiskStrategy) | DiskStrategy | 配置磁盘缓存策略 NONE SOURCE RESULT ALL AUTOMATIC |
| placeholder(src: PixelMap \| Resource, func?: AsyncSuccess<PixelMap>) | src: PixelMap \| Resource, func?: AsyncSuccess<PixelMap> | 配置占位图其中func为数据回调函数 |
| errorholder(src: PixelMap \| Resource, func?: AsyncSuccess<PixelMap>) | src: PixelMap \| Resource, func?: AsyncSuccess<PixelMap> | 配置加载失败占位图其中func为数据回调函数 |
| retryholder(src: PixelMap \| Resource, func?: AsyncSuccess<PixelMap>) | src: PixelMap \| Resource, func?: AsyncSuccess<PixelMap> | 配置重试占位图,如果配置则加载失败后优先展示重试占位图 |
| addListener(func: AsyncCallback<PixelMap>) | func: AsyncCallback<PixelMap> | 配置整个监听回调,数据正常加载返回,加载失败返回错误信息 |
| thumbnail(sizeMultiplier:number, func?: AsyncSuccess<ImageKnifeData>) | sizeMultiplier:number, func?: AsyncSuccess<ImageKnifeData> | 设置缩略图比例,缩略图返回后,加载并展示缩略图 |
| addProgressListener(func?: AsyncSuccess<string>){ this.progressFunc = func; return this; } | func?: AsyncSuccess<string> | 设置网络下载百分比监听,返回数据加载百分比数值 |
| addRetryListener(func?: AsyncSuccess<any>){ this.retryFunc = func; return this; } | func?: AsyncSuccess<any> | 设置重试监听 |
| addAllCacheInfoCallback(func: IAllCacheInfoCallback) | func: IAllCacheInfoCallback | 设置获取所有缓存信息监听 |
| skipMemoryCache(skip: boolean) | skip: boolean | 配置是否跳过内存缓存 |
| retrieveDataFromCache(flag: boolean) | flag: boolean | 配置仅从缓存中加载数据 |
同时支持[图片变换相关](##'图片变换相关')接口。
### ImageKnife 启动器/门面类
| 方法名 | 入参 | 接口描述 |
| ------------------------------- | ---------------------- | ---------------------------------- |
| call(request: RequestOption) | request: RequestOption | 根据用户配置参数具体执行加载流程 |
| preload(request: RequestOption) | request: RequestOption | 根据用户配置参数具体执行预加载流程 |
### 缓存策略相关
| 使用方法 | 类型 | 策略描述 |
| ------------------------------------------ | --------- | ---------------------------------------- |
| 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 | 表示只缓存转换过后的图片 |
### 图片变换相关
| 使用方法 | 类型 | 相关描述 |
| ------------------------------ | ---------------------------------- | ---------------------------------------------------- |
| 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 | 扭曲滤波器 |
<img src="screenshot/gif4.gif" width="50%"/>
## 兼容性
支持 OpenHarmony API version 9 及以上版本。
## 目录结构
```
/imageknife/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/MainAbility
- pages # 测试page页面列表
- basicTestFeatureAbilityPage.ets # 测试列表加载
- basicTestFileIOPage.ets # 测试fileio
- basicTestMediaImage.ets # 测试媒体image
- basicTestResourceManagerPage.ets # 测试本地资源解析
- compressPage.ets # 压缩页面
- cropImagePage2.ets # 手势裁剪页面
- frescoImageTestCasePage.ets # 测试属性动画组件切换
- frescoRetryTestCasePage.ets # 测试ImageKnifeComponent加载失败重试
- gifTestCasePage.ets # 测试gif解析页面
- svgTestCasePage.ets # 测试svg解析页面
- imageknifeTestCaseIndex.ets # 测试用例页面入口
- index.ets # 程序入口页面
- loadNetworkTestCasePage.ets # 网络加载测试
- loadResourceTestCasePage.ets # 本地加载测试
- showErrorholderTestCasePage.ets # 加载失败占位图测试
- storageTestDiskLruCache.ets # 磁盘缓存测试
- storageTestLruCache.ets # 内存缓存测试
- testAllCacheInfoPage.ets # 所有缓存信息获取测试
- testGifDontAnimatePage.ets # gif加载静态图片测试
- testImageKnifeOptionChangedPage.ets # 数据切换测试
- testImageKnifeOptionChangedPage2.ets # 数据切换测试,部分变换
- testImageKnifeOptionChangedPage3.ets # 数据切换测试,组件动画
- testImageKnifeOptionChangedPage4.ets # 数据切换测试,内容动画
- testImageKnifeOptionChangedPage5.ets # 数据切换测试,ImageKnifeDrawFactory封装圆角圆环边框等
- testPreloadPage.ets # 预加载测试
- transformPixelMapPage.ets # 所有类型变换测试
- gifParseWorker.ts # gifworker子线程解析
- worker1.js # worker多线程测试
```
## 贡献代码
使用过程中发现任何问题都可以提 [issue](https://gitee.com/openharmony-tpc/ImageKnife/issues) 给我们,当然,我们也非常欢迎你给我们发 [PR](https://gitee.com/openharmony-tpc/ImageKnife/issues) 。
## 开源协议
本项目基于 [Apache License 2.0](https://gitee.com/openharmony-tpc/ImageKnife/blob/master/LICENSE) ,请自由的享受和参与开源。
## 遗留问题
1.目前只支持一种图片变换效果。
2.目前svg和gif动图不支持变换效果。
3.svg解析目前不支持mask标签。

View File

@ -1,485 +0,0 @@
## 🚨 **重要提示 | 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,25 +1,13 @@
{
"app": {
"signingConfigs": [
],
"compileSdkVersion": 9,
"compatibleSdkVersion": 9,
"products": [
{
"name": "default",
"signingConfig": "default",
"compileSdkVersion": 12,
"compatibleSdkVersion": 12,
"runtimeOS": "OpenHarmony"
"signingConfig": "default"
}
],
"buildModeSet": [
{
"name": "debug",
},
{
"name": "release"
}
]
},
"modules": [
{
@ -35,24 +23,8 @@
]
},
{
"name": "library",
"srcPath": "./library"
},
{
"name": "gpu_transform",
"srcPath": "./gpu_transform"
},
{
"name": "sharedlibrary",
"srcPath": "./sharedlibrary",
"targets": [
{
"name": "default",
"applyToProducts": [
"default"
]
}
]
"name": "imageknife",
"srcPath": "./imageknife"
}
]
}

5
entry/.gitignore vendored
View File

@ -1,6 +1,3 @@
/node_modules
/oh_modules
/.preview
/build
/.cxx
/.test
/build

View File

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

2
entry/hvigorfile.js Normal file
View File

@ -0,0 +1,2 @@
// 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

View File

@ -1,6 +0,0 @@
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

@ -1,21 +0,0 @@
# 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,13 +0,0 @@
{
"name": "entry",
"version": "1.0.0",
"description": "Please describe the basic information.",
"main": "",
"author": "",
"license": "",
"dependencies": {
"@ohos/libraryimageknife": "file:../sharedlibrary",
"@ohos/imageknife": "file:../library"
}
}

16
entry/package.json Normal file
View File

@ -0,0 +1,16 @@
{
"license": "ISC",
"devDependencies": {},
"name": "entry",
"ohos": {
"org": "huawei",
"directoryLevel": "module",
"buildTool": "hvigor"
},
"description": "example description",
"repository": {},
"version": "1.0.0",
"dependencies": {
"@ohos/imageknife": "file:../imageknife"
}
}

View File

@ -0,0 +1,27 @@
/*
* 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 AbilityStage from '@ohos.application.AbilityStage'
import { ImageKnife,ImageKnifeDrawFactory} from '@ohos/imageknife'
import ArkWorker from '@ohos.worker'
export default class MyAbilityStage extends AbilityStage {
onCreate() {
globalThis.ImageKnife = ImageKnife.with(this.context);
// 全局配置网络加载进度条
globalThis.ImageKnife.setDefaultLifeCycle(ImageKnifeDrawFactory.createProgressLifeCycle("#10a5ff", 0.5))
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* 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
@ -12,26 +12,26 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { GPUImage3x3TextureSamplingFilter } from './GPUImage3x3TextureSamplingFilter'
import { GPUFilterType } from '../gl/GPUFilterType'
export class GPUImageSketchFilter extends GPUImage3x3TextureSamplingFilter {
constructor() {
super()
import Ability from '@ohos.application.Ability'
import {ImageKnife} from '@ohos/imageknife'
export default class MainAbility extends Ability {
onCreate(want, launchParam) {
globalThis.abilityWant = want;
}
getFilterType(): GPUFilterType {
return GPUFilterType.SKETCH;
onDestroy() {
}
onInitialized() {
onWindowStageCreate(windowStage) {
windowStage.setUIContent(this.context, "pages/index", null)
}
onReadySize() {
this.setTexelWidth(this.width);
this.setTexelHeight(this.height);
onWindowStageDestroy() {
}
}
onForeground() {
}
onBackground() {
}
};

View File

@ -1,65 +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 { 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,37 +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.
*/
export class GlobalContext {
private constructor() {
}
private static instance: GlobalContext;
private _objects = new Map<string, Object>();
public static getContext(): GlobalContext {
if (!GlobalContext.instance) {
GlobalContext.instance = new GlobalContext();
}
return GlobalContext.instance;
}
getObject(value: string): Object | undefined {
return this._objects.get(value);
}
setObject(key: string, objectClass: Object): void {
this._objects.set(key, objectClass);
}
}

View File

@ -1,80 +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 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 { 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 {
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.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;
//
// }
// })
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;
}
hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. Data: %{public}s', JSON.stringify(data) ?? '');
});
}
onWindowStageDestroy(): void {
// Main window is destroyed, release UI related resources
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageDestroy');
}
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

@ -1,58 +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 { 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,220 +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 { 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

@ -1,93 +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 { 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

@ -1,102 +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 { 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

@ -1,99 +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 { 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

@ -1,432 +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 {
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

@ -1,236 +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 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

@ -1,51 +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 { 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

@ -1,51 +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 { 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

@ -1,42 +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 { 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

@ -1,116 +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 { 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

@ -1,78 +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 { 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

@ -1,43 +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 { 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

@ -1,55 +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 { 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

@ -1,55 +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 { 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

@ -1,55 +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 { 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

@ -1,151 +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 { 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

@ -1,71 +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 { 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,39 +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 { 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

@ -1,56 +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 { 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,37 +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 { 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,72 +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 { ImageKnifeComponent, ImageKnifeOption } from '@ohos/libraryimageknife';
@Entry
@Component
struct SignatureTestPage {
@State imageKnifeOption1: ImageKnifeOption =
{
loadSrc: $r('app.media.icon'),
placeholderSrc:$r('app.media.loading'),
};
@State imageKnifeOption2: ImageKnifeOption =
{
loadSrc: $r('app.media.icon'),
placeholderSrc:$r('app.media.loading'),
};
build() {
Scroll() {
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Text($r('app.string.The_key_fixed_1')).fontSize(15)
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Button($r('app.string.Load'))
.onClick(() => {
this.imageKnifeOption1 = {
loadSrc: 'https://img-blog.csdn.net/20140514114029140',
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($r('app.string.The_key_changes_timestamp')).fontSize(15)
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Button($r('app.string.Load'))
.onClick(() => {
this.imageKnifeOption2 = {
loadSrc: 'https://img-blog.csdn.net/20140514114029140',
placeholderSrc:$r('app.media.loading'),
signature: new Date().getTime().toString()
}
}).margin({ top: 5, left: 3 })
ImageKnifeComponent({ imageKnifeOption: this.imageKnifeOption2 }).width(300).height(300)
}.width('100%').backgroundColor(Color.Pink)
}
}.width('100%')
.height('100%')
}
aboutToAppear() {
console.log('唯一标识页面:' + new Date().getTime().toString())
}
}

View File

@ -1,149 +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 { 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

@ -1,126 +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 { 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

@ -1,140 +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 { 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

@ -1,112 +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 { 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

@ -1,52 +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 { 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

@ -1,47 +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 { 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

@ -1,39 +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 { 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,25 +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 { IndexComponent } from '@ohos/libraryimageknife'
@Entry
@Component
struct TestHspPreLoadImage {
build() {
Column() {
IndexComponent()
}.width('100%').height('100%')
}
}

View File

@ -1,92 +0,0 @@
/*
* 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

@ -1,137 +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 { 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

@ -1,387 +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 { 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

@ -1,86 +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 { 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

@ -1,103 +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 { 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

@ -1,101 +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 { 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

@ -1,50 +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 { 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

@ -1,126 +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 { 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

@ -1,68 +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 { 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

@ -1,79 +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 { 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

@ -1,74 +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 { 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

@ -1,51 +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 { 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

@ -1,98 +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 { 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

@ -1,94 +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 { 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

@ -0,0 +1,82 @@
/*
* 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/imageknife'
@Entry
@Component
struct BasicTestFeatureAbilityPage {
@Watch("watchPathChange") @State filePath: string = "查看featureAbility路径";
watchPathChange() {
console.log("watchPathChange")
}
urls=[
"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> = []
aboutToAppear(){
this.options = this.urls.map((url)=>{
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) => {
ListItem() {
ImageKnifeComponent({imageKnifeOption:item}).width(300).height(300)
}
}, item => item.loadSrc)
}
.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

@ -0,0 +1,134 @@
/*
* 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 } from '@ohos/imageknife'
import resourceManager from '@ohos.resourceManager';
@Entry
@Component
struct basicTestFileIOPage {
@State filePath: string = '查看featureAbility路径';
appFilePath = '';
appCachePath = '';
@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 = globalThis.ImageKnife.getImageKnifeContext().filesDir;
console.log('ImageKnife filesPath = ' + data)
this.filePath = data
this.appFilePath = data;
})
Button('featureAbility.getContext().getCacheDir()')
.margin({ top: 10 })
.onClick(() => {
let data = globalThis.ImageKnife.getImageKnifeContext().cacheDir;
console.log('ImageKnife cachesPath = ' + data)
this.filePath = data
this.appFilePath = data;
})
Button('files目录创建Folder1和Folder2 验证statSync mkdirSync')
.margin({ top: 10 })
.onClick(() => {
console.log('files目录创建Folder1和Folder2 验证statSync mkdirSync')
FileUtils.getInstance()
.createFolder(this.appFilePath + '/Folder1');
FileUtils.getInstance()
.createFolder(this.appFilePath + '/Folder2');
})
Button('将media资源存入Folder1 验证writeSync mkdirSync createStreamSync')
.margin({ top: 10 })
.onClick(() => {
console.log('将media资源存入Folder1 验证writeSync mkdirSync createStreamSync')
globalThis.ImageKnife.getImageKnifeContext().resourceManager
.getMedia($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 => {
console.log('basicTestFileIOPage - 本地加载资源err' + JSON.stringify(err));
})
})
Button('copy:Folder1至Folder2 验证copyFileSync')
.margin({ top: 10 })
.onClick(() => {
console.log('copy:Folder1至Folder2 验证copyFileSync')
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)
})
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

@ -0,0 +1,122 @@
/*
* 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/imageknife'
import { FileTypeUtil } from '@ohos/imageknife'
import resourceManager from '@ohos.resourceManager';
import { Base64 } from '@ohos/imageknife'
import { ParseImageUtil } from '@ohos/imageknife'
@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(() => {
globalThis.ImageKnife.getImageKnifeContext().resourceManager.getMedia($r('app.media.jpgSample').id)
.then(data => {
let arrayBuffer = this.typedArrayToBuffer(data);
let parseImageUtil = new ParseImageUtil();
parseImageUtil.parseImage(arrayBuffer, (pxielmap) => {
this.imagePixelMap = pxielmap;
}, (err) => {
})
})
.catch(err => {
console.log('basicTestMediaImage - 本地加载资源err' + JSON.stringify(err));
})
}).margin({ left: 15 }).backgroundColor(Color.Blue)
Button('本地资源png')
.onClick(() => {
globalThis.ImageKnife.getImageKnifeContext().resourceManager.getMedia($r('app.media.pngSample').id)
.then(data => {
let arrayBuffer = this.typedArrayToBuffer(data);
let parseImageUtil = new ParseImageUtil();
parseImageUtil.parseImage(arrayBuffer, (pxielmap) => {
this.imagePixelMap = pxielmap;
}, (err) => {
})
})
.catch(err => {
console.log('basicTestMediaImage - 本地加载资源err' + JSON.stringify(err));
})
}).margin({ left: 15 }).backgroundColor(Color.Blue)
Button('本地资源bmp')
.onClick(() => {
globalThis.ImageKnife.getImageKnifeContext().resourceManager.getMedia($r('app.media.bmpSample').id)
.then(data => {
let arrayBuffer = this.typedArrayToBuffer(data);
let parseImageUtil = new ParseImageUtil();
parseImageUtil.parseImage(arrayBuffer, (pxielmap) => {
this.imagePixelMap = pxielmap;
}, (err) => {
})
})
.catch(err => {
console.log('basicTestMediaImage - 本地加载资源err' + JSON.stringify(err));
})
}).margin({ left: 15 }).backgroundColor(Color.Blue)
Button('本地资源webp')
.onClick(() => {
globalThis.ImageKnife.getImageKnifeContext().resourceManager.getMedia($r('app.media.jpgSample').id)
.then(data => {
let arrayBuffer = this.typedArrayToBuffer(data);
let parseImageUtil = new ParseImageUtil();
parseImageUtil.parseImage(arrayBuffer, (pxielmap) => {
this.imagePixelMap = pxielmap;
}, (err) => {
})
})
.catch(err => {
console.log('basicTestMediaImage - 本地加载资源err' + JSON.stringify(err));
})
}).margin({ left: 15 }).backgroundColor(Color.Blue)
Button('本地资源gif')
.onClick(() => {
globalThis.ImageKnife.getImageKnifeContext().resourceManager.getMedia($r('app.media.gifSample').id)
.then(data => {
let arrayBuffer = this.typedArrayToBuffer(data);
let parseImageUtil = new ParseImageUtil();
parseImageUtil.parseImage(arrayBuffer, (pxielmap) => {
this.imagePixelMap = pxielmap;
}, (err) => {
})
})
.catch(err => {
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

@ -0,0 +1,78 @@
/*
* 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/imageknife'
import {FileTypeUtil} from '@ohos/imageknife'
import resourceManager from '@ohos.resourceManager';
import {Base64} from '@ohos/imageknife'
@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(() => {
globalThis.ImageKnife.getImageKnifeContext().resourceManager.getMedia($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);
this.fileTypeStr = fileType;
})
.catch(err => {
console.log('basicTestFileIOPage - 本地加载资源err' + JSON.stringify(err));
})
})
Button('getMediaBase64解析一张png图片')
.margin({ top: 10 })
.onClick(() => {
globalThis.ImageKnife.getImageKnifeContext().resourceManager.getMediaBase64($r('app.media.pngSample')
.id)
.then(data => {
console.log('ParseResClientBase64 - 本地加载资源 解析后数据data')
let matchReg = ';base64,';
var 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);
this.fileTypeStr = fileType;
})
.catch(err => {
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

@ -0,0 +1,147 @@
/*
* 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/imageknife'
import {OnRenameListener} from '@ohos/imageknife'
import {OnCompressListener} from '@ohos/imageknife'
@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 )
.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 )
.width(200)
.height(200)
.margin({ top: 10 });
}.margin({ top: 10 }).visibility(Visibility.Hidden);
}.margin({ bottom: 30 });
}.width('100%').height('100%');
}
private compressAsyncRecource() {
var data = new Array<Resource>();
data.push($r('app.media.jpgSample'))
console.info("asasd start compress")
globalThis.ImageKnife
.compressBuilder()
.load(data)
.ignoreBy(100)
.get()
.then((path)=>{
this.mAsyncPathHint = path;
this.mAsyncPath='file://' + path;
})
;
console.info("asasd start compress end")
}
private cropressRecource() {
var data = new Array<Resource>();
data.push($r('app.media.jpgSample'))
var rename: OnRenameListener = {
reName() {
return "test_1.jpg";
}
}
var that = this;
var listener: OnCompressListener = {
start() {
that.mResultText = "start"
console.info("asasd start")
},
onScuccess(p: PixelMap, path: string) {
let pack = undefined;
pack = p;
that.mRPixelMap = pack;
console.info("asasd success path:" + this.mRPixelMap)
that.mResultText = "success";
that.mResultPath = path;
},
onError(s: string) {
console.info("asasd onError:" + s)
that.mResultText = "fail";
}
}
console.info("asasd start compress")
globalThis.ImageKnife
.compressBuilder()
.load(data)
.ignoreBy(100)
.setRenameListener(rename)
.setCompressListener(listener)
.launch();
console.info("asasd start compress end")
}
}

View File

@ -0,0 +1,100 @@
/*
* 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/imageknife'
import { CropOptions } from '@ohos/imageknife'
import { Crop } from '@ohos/imageknife'
import { RecourseProvider } from '@ohos/imageknife'
import { PixelMapCrop } from '@ohos/imageknife'
import { CropCallback } from '@ohos/imageknife'
import { FileUtils } from '@ohos/imageknife'
@Component
@Entry
export struct CropImagePage2 {
@State options1: PixelMapCrop.Options = new PixelMapCrop.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(() => {
globalThis.ImageKnife.getImageKnifeContext().resourceManager.getMedia($r('app.media.bmpSample').id)
.then(data => {
let arrayBuffer = FileUtils.getInstance().uint8ArrayToBuffer(data);
let optionx = new PixelMapCrop.Options();
optionx.setWidth(800)
.setHeight(800)
.setCropFunction((err, pixelmap, sx, sy) => {
console.log('PMC setCropFunction callback')
if (err) {
console.error('PMC crop err =' + err)
} else {
this.width1 = sx * px2vp(1);
this.height1 = sy * px2vp(1);
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 => {
this._rotate = event.angle;
}), PinchGesture({ fingers: 2 }).onActionUpdate(event => {
this._scale = event.scale;
})))
}
.backgroundColor(Color.Brown)
.width('100%')
}
}
}

View File

@ -1,59 +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 { ImageKnifeComponent, ImageKnifeOption } from '@ohos/libraryimageknife'
import { dataSharePredicates } from '@kit.ArkData';
import { photoAccessHelper } from '@kit.MediaLibraryKit';
@Entry
@Component
struct DataShareUriLoadPage {
@State imageKnifeOption1: ImageKnifeOption =
{
loadSrc: $r('app.media.icon'),
placeholderSrc: $r('app.media.loading'),
errorholderSrc: $r('app.media.failed')
};
build() {
Scroll() {
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Text($r('app.string.Retrieve_media_gallery')).fontSize(15)
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
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)
}
}
.width('100%')
.height('100%')
}
}

View File

@ -0,0 +1,77 @@
/*
* 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/imageknife'
import {ImageKnifeOption} from '@ohos/imageknife'
import {RotateImageTransformation} from '@ohos/imageknife'
import {RoundedCornersTransformation} from '@ohos/imageknife'
@Entry
@Component
struct FrescoImageTestCasePage {
@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,
};
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)
// Scroll() {
// Text(this.progresshint).fontSize(15)
// }.width(300).height(200)
}
}
.width('100%')
.height('100%')
}
}

View File

@ -0,0 +1,78 @@
/*
* 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/imageknife'
import {ImageKnifeOption} from '@ohos/imageknife'
import {RotateImageTransformation} from '@ohos/imageknife'
import {RoundedCornersTransformation} from '@ohos/imageknife'
@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

@ -0,0 +1,130 @@
/*
* 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 {GIFParseImpl} from '@ohos/imageknife'
import ArkWorker from '@ohos.worker'
@Entry
@Component
struct gifTestCasePage {
@State pixels:PixelMap = undefined
private globalGifWorker = undefined;
build() {
Scroll() {
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Flex({direction:FlexDirection.Row}){
Button("加载gif图片")
.onClick(()=>{
globalThis.ImageKnife.getImageKnifeContext().resourceManager.getMedia($r('app.media.gifSample').id)
.then(data => {
console.log('basicTestFileIOPage - 本地加载资源 解析后数据data length= ' + data.byteLength)
let gifImpl = new GIFParseImpl();
gifImpl.parseGifs(data.buffer, (data,err)=>{
if(err){
console.log('加载gif图片 err='+err);
}
if(!!data){
console.log('加载gif图片 suc,长度='+data.length)
this.pixels = data[0]['drawPixelMap']
}
},undefined,true)
})
.catch(err => {
console.log('basicTestFileIOPage - 本地加载资源err' + JSON.stringify(err));
})
}).margin({left:5}).backgroundColor(Color.Blue)
Button("加载gif图片自带worker")
.onClick(()=>{
globalThis.ImageKnife.getImageKnifeContext().resourceManager.getMedia($r('app.media.gifSample').id)
.then(data => {
console.log('basicTestFileIOPage - 本地加载资源 解析后数据data length = ' + data.byteLength)
let worker = new ArkWorker.Worker('entry/ets/pages/workers/gifParseWorker.ts', {
type: 'classic',
name: 'ImageKnifeParseGIF'
})
let gifImpl = new GIFParseImpl();
gifImpl.parseGifs(data.buffer, (data,err)=>{
if(err){
console.log('加载gif图片自带worker err='+err);
}
if(!!data){
console.log('加载gif图片自带worker suc,长度='+data.length)
this.pixels = data[0]['drawPixelMap']
}
},worker)
})
.catch(err => {
console.log('basicTestFileIOPage - 本地加载资源err' + JSON.stringify(err));
})
}).margin({left:5}).backgroundColor(Color.Blue)
Button("加载gif图片全局配置worker")
.onClick(()=>{
globalThis.ImageKnife.getImageKnifeContext().resourceManager.getMedia($r('app.media.gifSample').id)
.then(data => {
console.log('basicTestFileIOPage - 本地加载资源 解析后数据data length = ' + data.byteLength)
let gifImpl = new GIFParseImpl();
gifImpl.parseGifs(data.buffer, (data,err)=>{
if(err){
console.log('加载gif图片自带worker err='+err);
}
if(!!data){
console.log('加载gif图片自带worker suc,长度='+data.length)
this.pixels = data[0]['drawPixelMap']
}
})
})
.catch(err => {
console.log('basicTestFileIOPage - 本地加载资源err' + JSON.stringify(err));
})
}).margin({left:5}).backgroundColor(Color.Blue)
}
.margin({top:15})
Text("下面为展示图片区域").margin({top:5})
Flex({direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }){
Image(this.pixels)
.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()")
this.globalGifWorker = new ArkWorker.Worker('entry/ets/pages/workers/gifParseWorker.ts', {
type: 'classic',
name: 'ImageKnifeParseGIF'
})
globalThis.ImageKnife.setGifWorker(this.globalGifWorker)
}
aboutToDisappear(){
if(this.globalGifWorker){
this.globalGifWorker.terminate();
}
}
typedArrayToBuffer(array: Uint8Array): ArrayBuffer {
return array.buffer.slice(array.byteOffset, array.byteLength + array.byteOffset)
}
}

View File

@ -0,0 +1,205 @@
/*
* 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';
@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.push({ uri: "pages/basicTestFeatureAbilityPage" });
}).margin({ top: 5, left: 3 })
Button("测试文件")
.onClick(() => {
console.log("测试文件子系统")
router.push({ uri: "pages/basicTestFileIOPage" });
}).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.push({ uri: "pages/basicTestResourceManagerPage" });
}).margin({ top: 5, left: 3 })
Button("测试媒体")
.onClick(() => {
console.log("测试媒体子系统")
router.push({ uri: "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.push({ uri: "pages/testImageKnifeOptionChangedPage" });
}).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.push({ uri: "pages/testImageKnifeOptionChangedPage2" });
}).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.push({ uri: "pages/storageTestLruCache" });
}).margin({ top: 5, left: 3 })
Button("测试所有缓存信息输出")
.onClick(() => {
console.log("pages/testAllCacheInfoPage 页面跳转")
router.push({ uri: "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.push({ uri: "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.push({ uri: "pages/testPreloadPage" });
}).margin({ top: 5, left: 3 })
Button("测试gif静态动态切换")
.onClick(() => {
console.log("测试gif静态动态切换")
router.push({ uri: "pages/testGifDontAnimatePage" });
}).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.push({ uri: "pages/transformPixelMapPage" });
}).margin({ top: 5, left: 3 })
Button("测试图片压缩")
.onClick(() => {
console.log("测试图片压缩")
router.push({ uri: "pages/compressPage" });
}).margin({ top: 5, left: 3 })
}.width('100%').height(60).backgroundColor(Color.Pink)
Text("测试fresco").fontSize(15)
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Button("加载百分比")
.onClick(() => {
console.log("加载百分比")
router.push({ uri: "pages/frescoImageTestCasePage" });
}).margin({ top: 5, left: 3 })
Button("重试Retry")
.onClick(() => {
console.log("重试Retry")
router.push({ uri: "pages/frescoRetryTestCasePage" });
}).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.push({ uri: "pages/pngjTestCasePage" });
}).margin({ top: 5, left: 3 })
Button("图片裁剪")
.onClick(() => {
console.log("图片裁剪")
router.push({ uri: "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.push({ uri: "pages/svgTestCasePage" });
}).margin({ top: 15 })
Button("测试gif")
.onClick(() => {
console.log("pages/gifTestCasePage 页面跳转")
router.push({ uri: "pages/gifTestCasePage" });
}).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.push({ uri: "pages/testImageKnifeOptionChangedPage3" });
}).margin({ top: 15 })
Button("组件内容动画")
.onClick(() => {
console.log("pages/testImageKnifeOptionChangedPage4 页面跳转")
router.push({ uri: "pages/testImageKnifeOptionChangedPage4" });
}).margin({ top: 15 })
Button("自定义圆角椭圆")
.onClick(() => {
console.log("pages/testImageKnifeOptionChangedPage5 页面跳转")
router.push({ uri: "pages/testImageKnifeOptionChangedPage5" });
}).margin({ top: 15 })
}.width('100%').height(60).backgroundColor(Color.Pink)
}
}
.width('100%')
.height('100%')
}
aboutToAppear() {
}
onBackPress() {
}
}

View File

@ -0,0 +1,104 @@
/*
* 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,
} from '@ohos/imageknife'
import ArkWorker from '@ohos.worker'
@Entry
@Component
struct IndexFunctionDemo {
private globalGifWorker:any = undefined
@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.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')
}
}).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://pic.ibaotu.com/gif/18/17/16/51u888piCtqj.gif!fwpaa70/fw/700',
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.push({ uri: "pages/imageknifeTestCaseIndex" });
}).margin({ top: 15 })
}.width('100%').height(60).backgroundColor(Color.Pink)
}
}
.width('100%')
.height('100%')
}
aboutToAppear() {
this.globalGifWorker = new ArkWorker.Worker('entry/ets/pages/workers/gifParseWorker.ts', {
type: 'classic',
name: 'ImageKnifeParseGIF'
})
// gif解析在子线程,请在页面构建后创建worker,注入imageknife
globalThis.ImageKnife.setGifWorker(this.globalGifWorker)
}
aboutToDisappear(){
if(this.globalGifWorker){
this.globalGifWorker.terminate();
}
}
onBackPress() {
}
}

View File

@ -1,55 +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.
*/
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

@ -1,93 +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 {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

@ -1,146 +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 { 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

@ -0,0 +1,186 @@
/*
* 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 router from '@system.router';
import { Pngj } from '@ohos/imageknife'
import resourceManager from '@ohos.resourceManager';
import { FileUtils } from '@ohos/imageknife'
import featureability from '@ohos.ability.featureAbility'
import ArkWorker from '@ohos.worker'
@Entry
@Component
struct PngjTestCasePage {
pngSource: ArrayBuffer = new ArrayBuffer(0);
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'
build() {
Scroll() {
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Text('pngj接口测试列表').fontSize(20)
Button(this.hint7).fontSize(30)
.onClick(() => {
this.rootFolder = globalThis.ImageKnife.getImageKnifeContext().filesDir;
globalThis.ImageKnife.getImageKnifeContext().resourceManager.getMedia($r('app.media.pngSample').id)
.then(data => {
this.pngSource = FileUtils.getInstance().uint8ArrayToBuffer(data);
this.hint7 = '获取buffer成功可以测试'
})
.catch(err => {
console.log('点击获取Png图片buffer err=' + err)
})
})
// Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
// Button('测试readPngImageInfo')
// .onClick(() => {
// let pngj = new Pngj();
// pngj.readPngImageInfo(this.pngSource, (sender, value) => {
// this.hint1 = JSON.stringify(value);
// })
// }).margin({ top: 5, left: 10 })
// Button('测试readPngImage')
// .onClick(() => {
// let pngj = new Pngj();
// pngj.readPngImage(this.pngSource, (sender, value) => {
// this.hint2 = 'img with=' + value.width + ' img height=' + value.height
// + ' img depth=' + value.depth + ' img ctype=' + value.ctype
// console.log('png data =' + value.data);
// })
// }).margin({ top: 5, left: 10 })
// Button('测试writePngWithString')
// .onClick(() => {
// let pngj = new Pngj();
// pngj.writePngWithString('hello world', this.pngSource, (sender, value) => {
//
// 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进制查看数据是否新增'
// })
// }).margin({ top: 5, left: 10 })
// Button('测试writePng')
// .onClick(() => {
// let pngj = new Pngj();
// pngj.writePng(this.pngSource, (sender, value) => {
// 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进制查看数据是否新增'
// })
// }).margin({ top: 5, left: 10 })
// }.width('100%')
// .height(60).backgroundColor(Color.Pink)
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Button('测试readPng')
.onClick(() => {
let pngj = new Pngj();
pngj.readPngImageInfo(this.pngSource, (sender, value) => {
this.hint1 = JSON.stringify(value);
})
}).margin({ top: 5, left: 10 })
Button('readPngAsync')
.onClick(() => {
let pngj = new Pngj();
let worker = new ArkWorker.Worker('entry/ets/pages/workers/worker1.js', {
type: 'classic',
name: 'readPngImageAsync'
})
pngj.readPngImageAsync(worker, this.pngSource, (sender, value) => {
this.pngSource = sender
this.hint2 = 'img with=' + value.width + ' img height=' + value.height
+ ' img depth=' + value.depth + ' img ctype=' + value.ctype
})
}).margin({ top: 5, left: 10 })
}.width('100%')
.height(60).backgroundColor(Color.Pink)
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Button('测试writePngWithString')
.onClick(() => {
let pngj = new Pngj();
let worker = new ArkWorker.Worker('entry/ets/pages/workers/worker1.js', {
type: 'classic',
name: 'writePngWithStringAsync'
})
pngj.writePngWithStringAsync(worker, 'hello world', this.pngSource, (sender, value) => {
this.pngSource = sender
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进制查看数据是否新增'
})
}).margin({ top: 5, left: 10 })
Button('writePng')
.onClick(() => {
let pngj = new Pngj();
let worker = new ArkWorker.Worker('entry/ets/pages/workers/worker1.js', {
type: 'classic',
name: 'writePngAsync'
})
pngj.writePngAsync(worker, this.pngSource, (sender, value) => {
this.pngSource = sender
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进制查看数据是否新增'
})
}).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

@ -0,0 +1,64 @@
/*
* 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/imageknife'
import {ImageKnifeOption} from '@ohos/imageknife'
import {RotateImageTransformation} from '@ohos/imageknife'
import {RoundedCornersTransformation} from '@ohos/imageknife'
@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

@ -0,0 +1,55 @@
/*
* 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/imageknife'
function getRandomInt(min, max) {
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

@ -0,0 +1,68 @@
/*
* 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/imageknife'
@Entry
@Component
struct svgTestCasePage {
@State pixels:PixelMap = undefined
build() {
Scroll() {
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Flex({direction:FlexDirection.Row}){
Button("加载SVG图片")
.onClick(()=>{
globalThis.ImageKnife.getImageKnifeContext().resourceManager.getMedia($r('app.media.svgSample').id)
.then(data => {
console.log('basicTestFileIOPage - 本地加载资源 解析后数据data = ' + data)
let svgImpl = new SVGParseImpl();
svgImpl.parseSvg(data.buffer).then((pixelmap)=>{
this.pixels = pixelmap;
})
})
.catch(err => {
console.log('basicTestFileIOPage - 本地加载资源err' + JSON.stringify(err));
})
}).margin({left:5}).backgroundColor(Color.Blue)
}
.margin({top:15})
Text("下面为展示图片区域").margin({top:5})
Flex({direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }){
Image(this.pixels)
.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

@ -0,0 +1,209 @@
/*
* 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 {RequestOption} from '@ohos/imageknife'
import {AllCacheInfo,IAllCacheInfoCallback} from '@ohos/imageknife'
import {ImageKnifeComponent} from '@ohos/imageknife'
import {TransformType} from '@ohos/imageknife'
import {ImageKnifeOption} from '@ohos/imageknife'
import {RotateImageTransformation} from '@ohos/imageknife'
@Entry
@Component
struct TestAllCacheInfoPage {
@State nativePixelMap: PixelMap = undefined;
@State networkPixelMap: PixelMap = undefined;
allCacheInfoCallback1 =(allCacheInfo)=>{
let info = allCacheInfo as AllCacheInfo;
console.log("AllCacheInfoCallback imageknifecomponent1 memory ="+JSON.stringify(info.memoryCacheInfo))
console.log("AllCacheInfoCallback imageknifecomponent1 resource ="+JSON.stringify(info.resourceCacheInfo))
console.log("AllCacheInfoCallback imageknifecomponent1 data ="+JSON.stringify(info.dataCacheInfo))
this.cacheinfo3 = "memory="+JSON.stringify(info.memoryCacheInfo)+
"\n resource ="+JSON.stringify(info.resourceCacheInfo)+
"\n data ="+JSON.stringify(info.dataCacheInfo)
}
allCacheInfoCallback2 =(allCacheInfo)=>{
let info = allCacheInfo as AllCacheInfo;
console.log("AllCacheInfoCallback ImageKnifeComponent memory ="+JSON.stringify(info.memoryCacheInfo))
console.log("AllCacheInfoCallback ImageKnifeComponent resource ="+JSON.stringify(info.resourceCacheInfo))
console.log("AllCacheInfoCallback ImageKnifeComponent data ="+JSON.stringify(info.dataCacheInfo))
this.cacheinfo4 = "memory="+JSON.stringify(info.memoryCacheInfo)+
"\n resource ="+JSON.stringify(info.resourceCacheInfo)+
"\n data ="+JSON.stringify(info.dataCacheInfo)
}
@State imageKnifeOption1: ImageKnifeOption =
{
loadSrc: $r('app.media.pngSample'),
placeholderSrc: $r('app.media.icon_loading'),
errorholderSrc: $r('app.media.icon_failed'),
transform: {
transformType:TransformType.RotateImageTransformation,
rotateImage:180
},
allCacheInfoCallback:this.allCacheInfoCallback1
};
@State imageKnifeOption: ImageKnifeOption =
{
loadSrc: "https://thirdwx.qlogo.cn/mmopen/vi_32/DYAIOgq83ericA1Mv66TwicuYOtbDMBcUhv1aa9RJBeAn9uURfcZD0AUGrJebAn1g2AjN0vb2E1XTET7fTuLBNmA/132",
placeholderSrc: $r('app.media.icon_loading'),
errorholderSrc: $r('app.media.icon_failed'),
transform: {
transformType:TransformType.RotateImageTransformation,
rotateImage:180
},
allCacheInfoCallback:this.allCacheInfoCallback2
};
imageKnifeComponentAngle:number = 90;
@State cacheinfo1:string = "观察本地资源获取缓存信息输出"
@State cacheinfo2:string = "观察网络资源获取缓存信息输出"
@State cacheinfo3:string = "观察ImageKnifeComponent本地缓存输出"
@State cacheinfo4:string = "观察ImageKnifeComponent网络缓存输出"
build() {
Scroll() {
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Button("加载本地资源获取缓存信息")
.width(300).height(25)
.onClick(() => {
this.testAllCacheInfoNative();
}).margin({ top: 15 })
Scroll() {
Text(this.cacheinfo1).fontSize(15)
}.width(300).height(200)
Image(this.nativePixelMap )
.width(300)
.height(300)
.objectFit(ImageFit.Contain)
.backgroundColor(Color.Green)
.margin({ top: 15 })
Button("加载网络资源获取缓存信息").width(300).height(25)
.onClick(() => {
this.testAllCacheInfoNetwork();
}).margin({ top: 15 })
Scroll() {
Text(this.cacheinfo2).fontSize(15)
}.width(300).height(200)
Image(this.networkPixelMap )
.width(300)
.height(300)
.objectFit(ImageFit.Contain)
.backgroundColor(Color.Green)
.margin({ top: 15 })
Button("ImageKnifeComponent加载本地资源获取缓存信息").width(300).height(25)
.onClick(() => {
this.imageKnifeComponentAngle = this.imageKnifeComponentAngle + 45;
this.imageKnifeOption1 =
{
loadSrc: $r('app.media.pngSample'),
placeholderSrc: $r('app.media.icon_loading'),
errorholderSrc: $r('app.media.icon_failed'),
transform: {
transformType:TransformType.RotateImageTransformation,
rotateImage:this.imageKnifeComponentAngle
},
allCacheInfoCallback:this.allCacheInfoCallback1
};
}).margin({ top: 15 })
Scroll() {
Text(this.cacheinfo3).fontSize(15)
}.width(300).height(200)
ImageKnifeComponent({ imageKnifeOption: this.imageKnifeOption1 })
Button("ImageKnifeComponent加载网络资源获取缓存信息").width(300).height(25)
.onClick(() => {
this.imageKnifeComponentAngle = this.imageKnifeComponentAngle + 45;
this.imageKnifeOption =
{
loadSrc: "https://thirdwx.qlogo.cn/mmopen/vi_32/DYAIOgq83ericA1Mv66TwicuYOtbDMBcUhv1aa9RJBeAn9uURfcZD0AUGrJebAn1g2AjN0vb2E1XTET7fTuLBNmA/132",
placeholderSrc: $r('app.media.icon_loading'),
errorholderSrc: $r('app.media.icon_failed'),
transform: {
transformType:TransformType.RotateImageTransformation,
rotateImage:this.imageKnifeComponentAngle
},
allCacheInfoCallback:this.allCacheInfoCallback2
};
})
Scroll() {
Text(this.cacheinfo4).fontSize(15)
}.width(300).height(200)
ImageKnifeComponent({ imageKnifeOption: this.imageKnifeOption }).width(300).height(300)
}
}
.width('100%')
.height('100%')
}
aboutToAppear() {
}
private testAllCacheInfoNative() {
let imageKnifeOption = new RequestOption();
imageKnifeOption.load($r('app.media.pngSample'))
.setImageViewSize({width:300,height:300})
.addListener((err, data) => {
let pack = undefined;
pack = data.drawPixelMap.imagePixelMap as PixelMap;;
this.nativePixelMap = pack;
return false;
}).addAllCacheInfoCallback((allCacheInfo)=>{
let info = allCacheInfo as AllCacheInfo;
console.log("AllCacheInfoCallback memory ="+JSON.stringify(info.memoryCacheInfo))
console.log("AllCacheInfoCallback resource ="+JSON.stringify(info.resourceCacheInfo))
console.log("AllCacheInfoCallback data ="+JSON.stringify(info.dataCacheInfo))
this.cacheinfo1 = "memory="+JSON.stringify(info.memoryCacheInfo)+
"\n resource ="+JSON.stringify(info.resourceCacheInfo)+
"\n data ="+JSON.stringify(info.dataCacheInfo)
})
ImageKnife.call(imageKnifeOption);
}
private testAllCacheInfoNetwork() {
let ImageKnifeOption = new RequestOption();
ImageKnifeOption.load("https://hbimg.huabanimg.com/0ef60041445edcfd6b38d20e19024b2cd9281dcc3525a4-Vy8fYO_fw658/format/webp")
.addListener((err, data) => {
let pack = undefined;
pack = data.drawPixelMap.imagePixelMap as PixelMap;
this.networkPixelMap = pack;
console.log("imageknife2 图片2 赋值!")
return false;
}).addAllCacheInfoCallback((allCacheInfo)=>{
let info = allCacheInfo as AllCacheInfo;
console.log("AllCacheInfoCallback memory ="+JSON.stringify(info.memoryCacheInfo))
console.log("AllCacheInfoCallback resource ="+JSON.stringify(info.resourceCacheInfo))
console.log("AllCacheInfoCallback data ="+JSON.stringify(info.dataCacheInfo))
this.cacheinfo2 = "memory="+JSON.stringify(info.memoryCacheInfo)+
"\n resource ="+JSON.stringify(info.resourceCacheInfo)+
"\n data ="+JSON.stringify(info.dataCacheInfo)
})
.setImageViewSize({width:300,height:300})
.rotateImage(180)
ImageKnife.call(ImageKnifeOption);
}
}
var ImageKnife = globalThis.ImageKnife

View File

@ -0,0 +1,100 @@
/*
* 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/imageknife'
import {ImageKnifeOption} from '@ohos/imageknife'
import {RotateImageTransformation} from '@ohos/imageknife'
import ArkWorker from '@ohos.worker'
@Entry
@Component
struct TestGifDontAnimatePage {
private globalGifWorker:any = undefined
@State imageKnifeOption1: ImageKnifeOption =
{
loadSrc: $r('app.media.jpgSample'),
placeholderSrc: $r('app.media.icon_loading'),
errorholderSrc: $r('app.media.icon_failed')
};
build() {
Scroll() {
Column() {
Flex({ direction: FlexDirection.Row }) {
Button('本地资源gif')
.onClick(() => {
this.imageKnifeOption1 = {
loadSrc: $r('app.media.gifSample'),
placeholderSrc: $r('app.media.icon_loading'),
errorholderSrc: $r('app.media.icon_failed'),
}
}).margin({left:15}).backgroundColor(Color.Grey)
Button('本地资源gif静态')
.onClick(()=>{
this.imageKnifeOption1 = {
loadSrc: $r('app.media.gifSample'),
placeholderSrc: $r('app.media.icon_loading'),
errorholderSrc: $r('app.media.icon_failed'),
dontAnimateFlag:true
}
}).margin({left:15}).backgroundColor(Color.Grey)
}
.margin({top:15})
Flex({direction:FlexDirection.Row}){
Button('网络资源gif')
.onClick(()=>{
this.imageKnifeOption1 = {
loadSrc: 'https://pic.ibaotu.com/gif/18/17/16/51u888piCtqj.gif!fwpaa70/fw/700',
placeholderSrc: $r('app.media.icon_loading'),
errorholderSrc: $r('app.media.icon_failed'),
};
}).margin({left:15}).backgroundColor(Color.Grey)
Button('网络资源gif静态')
.onClick(()=>{
this.imageKnifeOption1 = {
loadSrc: 'https://pic.ibaotu.com/gif/18/17/16/51u888piCtqj.gif!fwpaa70/fw/700',
placeholderSrc: $r('app.media.icon_loading'),
errorholderSrc: $r('app.media.icon_failed'),
dontAnimateFlag:true
};
}).margin({left:15}).backgroundColor(Color.Grey)
}
.margin({top:15})
ImageKnifeComponent({ imageKnifeOption: this.imageKnifeOption1 })
.width(300)
.height(300)
}
}
.width('100%')
.height('100%')
}
aboutToAppear() {
this.globalGifWorker = new ArkWorker.Worker('entry/ets/pages/workers/gifParseWorker.ts', {
type: 'classic',
name: 'ImageKnifeParseGIF'
})
globalThis.ImageKnife.setGifWorker(this.globalGifWorker)
}
aboutToDisappear(){
if(this.globalGifWorker){
this.globalGifWorker.terminate();
}
}
}

View File

@ -0,0 +1,201 @@
/*
* 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/imageknife'
import {ImageKnifeOption} from '@ohos/imageknife'
import {RotateImageTransformation} from '@ohos/imageknife'
import ArkWorker from '@ohos.worker'
@Entry
@Component
struct TestImageKnifeOptionChangedPage {
private globalGifWorker:any = undefined
@State imageKnifeOption1: ImageKnifeOption =
{
loadSrc: $r('app.media.jpgSample'),
placeholderSrc: $r('app.media.icon_loading'),
errorholderSrc: $r('app.media.icon_failed'),
};
build() {
Scroll() {
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Flex({direction:FlexDirection.Row}){
Button('本地jpg')
.onClick(()=>{
this.imageKnifeOption1 = {
loadSrc: $r('app.media.jpgSample'),
placeholderSrc: $r('app.media.icon_loading'),
errorholderSrc: $r('app.media.icon_failed'),
};
}).margin({left:5}).backgroundColor(Color.Blue)
Button('png')
.onClick(()=>{
this.imageKnifeOption1 = {
loadSrc: $r('app.media.pngSample'),
placeholderSrc: $r('app.media.icon_loading'),
errorholderSrc: $r('app.media.icon_failed'),
};
}).margin({left:5}).backgroundColor(Color.Blue)
Button('bmp')
.onClick(()=>{
this.imageKnifeOption1 = {
loadSrc: $r('app.media.bmpSample'),
placeholderSrc: $r('app.media.icon_loading'),
errorholderSrc: $r('app.media.icon_failed'),
};
}).margin({left:5}).backgroundColor(Color.Blue)
Button('webp')
.onClick(()=>{
this.imageKnifeOption1 = {
loadSrc: $r('app.media.jpgSample'),
placeholderSrc: $r('app.media.icon_loading'),
errorholderSrc: $r('app.media.icon_failed')
};
}).margin({left:5}).backgroundColor(Color.Blue)
Button('svg')
.onClick(()=>{
this.imageKnifeOption1 = {
loadSrc: $r('app.media.svgSample'),
placeholderSrc: $r('app.media.icon_loading'),
errorholderSrc: $r('app.media.icon_failed')
};
}).margin({left:5}).backgroundColor(Color.Blue)
Button('gif')
.onClick(()=>{
this.imageKnifeOption1 = {
loadSrc: $r('app.media.gifSample'),
placeholderSrc: $r('app.media.icon_loading'),
errorholderSrc: $r('app.media.icon_failed')
};
}).margin({left:5}).backgroundColor(Color.Blue)
}
.margin({top:15})
Flex({direction:FlexDirection.Row}){
Button('网络jpg')
.onClick(()=>{
this.imageKnifeOption1 = {
loadSrc: 'https://hbimg.huabanimg.com/cc6af25f8d782d3cf3122bef4e61571378271145735e9-vEVggB',
placeholderSrc: $r('app.media.icon_loading'),
errorholderSrc: $r('app.media.icon_failed')
};
}).margin({left:5}).backgroundColor(Color.Blue)
Button('png')
.onClick(()=>{
this.imageKnifeOption1 = {
loadSrc: 'https://img-blog.csdnimg.cn/20191215043500229.png',
placeholderSrc: $r('app.media.icon_loading'),
errorholderSrc: $r('app.media.icon_failed')
};
}).margin({left:5}).backgroundColor(Color.Blue)
Button('bmp')
.onClick(()=>{
this.imageKnifeOption1 = {
loadSrc: 'https://img-blog.csdn.net/20140514114029140',
placeholderSrc: $r('app.media.icon_loading'),
errorholderSrc: $r('app.media.icon_failed')
};
}).margin({left:5}).backgroundColor(Color.Blue)
Button('webp')
.onClick(()=>{
this.imageKnifeOption1 = {
loadSrc: 'https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp',
placeholderSrc: $r('app.media.icon_loading'),
errorholderSrc: $r('app.media.icon_failed')
};
}).margin({left:5}).backgroundColor(Color.Blue)
Button('svg')
.onClick(()=>{
this.imageKnifeOption1 = {
loadSrc: 'http://design-svc.fat.lunz.cn/StaticFiles/BP9999999772/BV9999999422/SA9999998420/30df266a-485e-411e-b178-b9fb1d8e0748.svg',
placeholderSrc: $r('app.media.icon_loading'),
errorholderSrc: $r('app.media.icon_failed')
};
}).margin({left:5}).backgroundColor(Color.Blue)
Button('gif')
.onClick(()=>{
this.imageKnifeOption1 = {
loadSrc: 'https://pic.ibaotu.com/gif/18/17/16/51u888piCtqj.gif!fwpaa70/fw/700',
placeholderSrc: $r('app.media.icon_loading'),
errorholderSrc: $r('app.media.icon_failed')
};
}).margin({left:5}).backgroundColor(Color.Blue)
Button("dpg")
.onClick(()=>{
this.imageKnifeOption1 = {
loadSrc: "https://img13.360buyimg.com/n1/jfs/t1/220646/38/10395/30916/61d6e061E1a6d91c8/c0a9a67e726dd7a4.jpg.dpg",
placeholderSrc: $r('app.media.icon_loading'),
errorholderSrc: $r('app.media.icon_failed')
};
}).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: this.imageKnifeOption1 })
.width(300)
.height(300)
}.width(400).height(400).margin({top:10}).backgroundColor(Color.Pink)
}
}
.width('100%')
.height('100%')
}
aboutToAppear() {
console.log("aboutToAppear()")
this.globalGifWorker = new ArkWorker.Worker('entry/ets/pages/workers/gifParseWorker.ts', {
type: 'classic',
name: 'ImageKnifeParseGIF'
})
globalThis.ImageKnife.setGifWorker(this.globalGifWorker)
}
aboutToDisappear(){
if(this.globalGifWorker){
this.globalGifWorker.terminate();
}
}
}

View File

@ -0,0 +1,107 @@
/*
* 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/imageknife'
import {ImageKnifeOption} from '@ohos/imageknife'
import {RotateImageTransformation} from '@ohos/imageknife'
import {GrayscaleTransformation} from '@ohos/imageknife'
import {SketchFilterTransformation} from '@ohos/imageknife'
@Entry
@Component
struct TestImageKnifeOptionChangedPage2 {
@State imageKnifeOption1: ImageKnifeOption =
{
loadSrc: $r('app.media.jpgSample'),
placeholderSrc: $r('app.media.icon_loading'),
errorholderSrc: $r('app.media.icon_failed'),
thumbSizeMultiplier:0.1
};
build() {
Scroll() {
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Flex({direction:FlexDirection.Row}){
Button("网络jpg")
.onClick(()=>{
this.imageKnifeOption1 = {
loadSrc: "https://hbimg.huabanimg.com/cc6af25f8d782d3cf3122bef4e61571378271145735e9-vEVggB",
placeholderSrc: $r('app.media.icon_loading'),
errorholderSrc: $r('app.media.icon_failed'),
thumbSizeMultiplier:0.1,
transformation:new RotateImageTransformation(180)
};
}).margin({left:5}).backgroundColor(Color.Blue)
Button("png")
.onClick(()=>{
this.imageKnifeOption1 = {
loadSrc: "https://img-blog.csdnimg.cn/20191215043500229.png",
placeholderSrc: $r('app.media.icon_loading'),
errorholderSrc: $r('app.media.icon_failed'),
thumbSizeMultiplier:0.1,
transformations:[new RotateImageTransformation(180)]
};
}).margin({left:5}).backgroundColor(Color.Blue)
Button("bmp")
.onClick(()=>{
this.imageKnifeOption1 = {
loadSrc: "https://img-blog.csdn.net/20140514114029140",
placeholderSrc: $r('app.media.icon_loading'),
errorholderSrc: $r('app.media.icon_failed'),
thumbSizeMultiplier:0.1,
transformations:[new GrayscaleTransformation()]
};
}).margin({left:5}).backgroundColor(Color.Blue)
Button("webp")
.onClick(()=>{
this.imageKnifeOption1 = {
loadSrc: "https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp",
placeholderSrc: $r('app.media.icon_loading'),
errorholderSrc: $r('app.media.icon_failed'),
thumbSizeMultiplier:0.1,
transformations:[new SketchFilterTransformation()]
};
}).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: this.imageKnifeOption1 }).width(300).height(300)
}.width(400).height(400).margin({top:10}).backgroundColor(Color.Pink)
}
}
.width('100%')
.height('100%')
}
aboutToAppear() {
console.log("aboutToAppear()")
}
}

View File

@ -0,0 +1,214 @@
/*
* 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/imageknife'
import {ImageKnifeOption} from '@ohos/imageknife'
import {ScaleType} from '@ohos/imageknife'
import {RotateImageTransformation} from '@ohos/imageknife'
import {GrayscaleTransformation} from '@ohos/imageknife'
import {SketchFilterTransformation} from '@ohos/imageknife'
import ArkWorker from '@ohos.worker'
@Entry
@Component
struct TestImageKnifeOptionChangedPage3 {
private globalGifWorker:any = undefined
@State imageKnifeOption1: ImageKnifeOption =
{
loadSrc: $r('app.media.jpgSample'),
mainScaleType: ScaleType.FIT_CENTER,
placeholderSrc: $r('app.media.icon_loading'),
errorholderSrc: $r('app.media.icon_failed'),
};
@State compWidht:number = 300
@State compHeight:number = 300
build() {
Scroll() {
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Flex({direction:FlexDirection.Row}){
Button("本地jpg")
.onClick(()=>{
this.imageKnifeOption1 = {
loadSrc: $r('app.media.jpgSample'),
mainScaleType: ScaleType.FIT_CENTER,
placeholderSrc: $r('app.media.icon_loading'),
errorholderSrc: $r('app.media.icon_failed'),
thumbSizeMultiplier:0.1,
transformation:new RotateImageTransformation(180),
};
animateTo({
duration: 500,
curve: Curve.EaseInOut,
delay: 100,
iterations: 1,
playMode:PlayMode.Normal,
onFinish:()=>{
console.log('play end!')
}
},()=>{
this.compHeight = 350
this.compWidht = 350
})
}).margin({left:5}).backgroundColor(Color.Blue)
Button("本地png")
.onClick(()=>{
this.imageKnifeOption1 = {
loadSrc: $r('app.media.pngSample'),
mainScaleType: ScaleType.FIT_CENTER,
placeholderSrc: $r('app.media.icon_loading'),
errorholderSrc: $r('app.media.icon_failed'),
thumbSizeMultiplier:0.1,
transformation:new RotateImageTransformation(180),
};
animateTo({
duration: 500,
curve: Curve.EaseInOut,
delay: 100,
iterations: 1,
playMode:PlayMode.Normal,
onFinish:()=>{
console.log('play end!')
}
},()=>{
this.compHeight = 400
this.compWidht = 300
})
}).margin({left:5}).backgroundColor(Color.Blue)
}.margin({top:15})
Flex({direction:FlexDirection.Row}){
Button("本地bmp")
.onClick(()=>{
this.imageKnifeOption1 = {
loadSrc: $r('app.media.bmpSample'),
mainScaleType: ScaleType.FIT_CENTER,
placeholderSrc: $r('app.media.icon_loading'),
errorholderSrc: $r('app.media.icon_failed'),
thumbSizeMultiplier:0.1,
transformations:[new GrayscaleTransformation()],
};
animateTo({
duration: 500,
curve: Curve.EaseInOut,
delay: 100,
iterations: 1,
playMode:PlayMode.Normal,
onFinish:()=>{
console.log('play end!')
}
},()=>{
this.compHeight = 250
this.compWidht = 350
})
}).margin({left:5}).backgroundColor(Color.Blue)
Button("本地webp")
.onClick(()=>{
this.imageKnifeOption1 = {
loadSrc: $r('app.media.webpSample'),
mainScaleType: ScaleType.FIT_CENTER,
placeholderSrc: $r('app.media.icon_loading'),
errorholderSrc: $r('app.media.icon_failed'),
thumbSizeMultiplier:0.1,
transformations:[new SketchFilterTransformation()],
};
animateTo({
duration: 500,
curve: Curve.EaseInOut,
delay: 100,
iterations: 1,
playMode:PlayMode.Normal,
onFinish:()=>{
console.log('play end!')
}
},()=>{
this.compHeight = 400
this.compWidht = 400
})
}).margin({left:5}).backgroundColor(Color.Blue)
}.margin({top:15})
Flex({direction:FlexDirection.Row}){
Button("网络jpg")
.onClick(()=>{
this.imageKnifeOption1 = {
loadSrc: "https://hbimg.huabanimg.com/cc6af25f8d782d3cf3122bef4e61571378271145735e9-vEVggB",
placeholderSrc: $r('app.media.icon_loading'),
errorholderSrc: $r('app.media.icon_failed'),
displayProgress:true,
thumbSizeMultiplier:0.1,
transformation:new RotateImageTransformation(180)
};
}).margin({left:5}).backgroundColor(Color.Blue)
Button("网络png")
.onClick(()=>{
this.imageKnifeOption1 = {
loadSrc: "https://img-blog.csdnimg.cn/20191215043500229.png",
placeholderSrc: $r('app.media.icon_loading'),
errorholderSrc: $r('app.media.icon_failed'),
displayProgress:true,
thumbSizeMultiplier:0.1,
transformations:[new RotateImageTransformation(180)]
};
}).margin({left:5}).backgroundColor(Color.Blue)
}.margin({top:15})
Flex({direction:FlexDirection.Row}){
Button("网络bmp")
.onClick(()=>{
this.imageKnifeOption1 = {
loadSrc: "https://img-blog.csdn.net/20140514114029140",
placeholderSrc: $r('app.media.icon_loading'),
errorholderSrc: $r('app.media.icon_failed'),
displayProgress:true,
thumbSizeMultiplier:0.1,
transformations:[new GrayscaleTransformation()]
};
}).margin({left:5}).backgroundColor(Color.Blue)
Button("网络webp")
.onClick(()=>{
this.imageKnifeOption1 = {
loadSrc: "https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp",
placeholderSrc: $r('app.media.icon_loading'),
errorholderSrc: $r('app.media.icon_failed'),
displayProgress:true,
thumbSizeMultiplier:0.1,
};
}).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: this.imageKnifeOption1 }).width(this.compWidht).height(this.compHeight)
}.width(400).height(400).margin({top:10}).backgroundColor(Color.Pink)
}
}
.width('100%')
.height('100%')
}
aboutToAppear() {
console.log("aboutToAppear()")
this.globalGifWorker = new ArkWorker.Worker('entry/ets/pages/workers/gifParseWorker.ts', {
type: 'classic',
name: 'ImageKnifeParseGIF'
})
globalThis.ImageKnife.setGifWorker(this.globalGifWorker)
}
aboutToDisappear(){
if(this.globalGifWorker){
this.globalGifWorker.terminate();
}
}
}

View File

@ -0,0 +1,255 @@
/*
* 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 {
GrayscaleTransformation,
ImageKnifeComponent,
ImageKnifeData,
ImageKnifeOption,
RotateImageTransformation,
SketchFilterTransformation,
ScaleTypeHelper,
IDrawLifeCycle,
ScaleType
} from '@ohos/imageknife'
import ArkWorker from '@ohos.worker'
@Entry
@Component
struct TestImageKnifeOptionChangedPage4 {
private globalGifWorker:any = undefined
@State imageKnifeOption1: ImageKnifeOption =
{
loadSrc: $r('app.media.jpgSample'),
placeholderSrc: $r('app.media.icon_loading'),
errorholderSrc: $r('app.media.icon_failed'),
thumbSizeMultiplier: 0.1,
drawLifeCycle:this.createViewLifeCycle()
};
private mTimerId: number = 0
build() {
Scroll() {
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Flex({ direction: FlexDirection.Row }) {
Button("网络jpg")
.onClick(() => {
this.imageKnifeOption1 = {
loadSrc: "https://hbimg.huabanimg.com/cc6af25f8d782d3cf3122bef4e61571378271145735e9-vEVggB",
placeholderSrc: $r('app.media.icon_loading'),
errorholderSrc: $r('app.media.icon_failed'),
thumbSizeMultiplier: 0.1,
transformation: new RotateImageTransformation(180),
drawLifeCycle:this.createViewLifeCycle()
};
}).margin({ left: 5 }).backgroundColor(Color.Blue)
Button("网络png")
.onClick(() => {
this.imageKnifeOption1 = {
loadSrc: "https://img-blog.csdnimg.cn/20191215043500229.png",
placeholderSrc: $r('app.media.icon_loading'),
errorholderSrc: $r('app.media.icon_failed'),
thumbSizeMultiplier: 0.1,
transformations: [new RotateImageTransformation(180)],
drawLifeCycle:this.createViewLifeCycle()
};
}).margin({ left: 5 }).backgroundColor(Color.Blue)
}.margin({ top: 15 })
Flex({ direction: FlexDirection.Row }) {
Button("网络bmp")
.onClick(() => {
this.imageKnifeOption1 = {
loadSrc: "https://img-blog.csdn.net/20140514114029140",
placeholderSrc: $r('app.media.icon_loading'),
errorholderSrc: $r('app.media.icon_failed'),
thumbSizeMultiplier: 0.1,
transformations: [new GrayscaleTransformation()],
drawLifeCycle:this.createViewLifeCycle()
};
}).margin({ left: 5 }).backgroundColor(Color.Blue)
Button("网络webp")
.onClick(() => {
this.imageKnifeOption1 = {
loadSrc: "https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp",
placeholderSrc: $r('app.media.icon_loading'),
errorholderSrc: $r('app.media.icon_failed'),
thumbSizeMultiplier: 0.1,
transformations: [new SketchFilterTransformation()],
drawLifeCycle:this.createViewLifeCycle()
};
}).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: this.imageKnifeOption1 }).width(300).height(300)
}.width(400).height(400).margin({ top: 10 }).backgroundColor(Color.Pink)
}
}
.width('100%')
.height('100%')
}
aboutToAppear() {
console.log("aboutToAppear()")
this.globalGifWorker = new ArkWorker.Worker('entry/ets/pages/workers/gifParseWorker.ts', {
type: 'classic',
name: 'ImageKnifeParseGIF'
})
globalThis.ImageKnife.setGifWorker(this.globalGifWorker)
}
aboutToDisappear(){
if(this.globalGifWorker){
this.globalGifWorker.terminate();
}
}
drawMainAnimate(index, context, scaleType, imagePixelMap, widthPixel, heightPixel, compWidth, compHeight) {
console.log('drawMainAnimate index = '+index)
let clipScale = (index / 30.0)
context.save()
context.beginPath();
let path2d = new Path2D()
let maxRadius = Math.sqrt(compWidth / 2 * compWidth / 2 + compHeight / 2 * compHeight / 2)
path2d.arc(compWidth / 2, compHeight / 2, maxRadius * clipScale, 0, Math.PI * 2)
context.clip(path2d)
context.save()
ScaleTypeHelper.drawImageWithScaleType(context, scaleType, imagePixelMap, px2vp(widthPixel), px2vp(heightPixel), compWidth, compHeight,0,0)
context.restore();
context.restore();
if(index<30){
index++
let nextFunc = this.drawMainAnimate.bind(this,index, context, scaleType, imagePixelMap, widthPixel, heightPixel, compWidth, compHeight)
this.mTimerId = setTimeout(nextFunc, 1000/30.0)
}else{
// 不做处理
}
}
private stopAnimate(){
if(this.mTimerId > 0){
clearTimeout(this.mTimerId)
this.mTimerId = 0
}else{
}
}
private createViewLifeCycle(): IDrawLifeCycle {
let viewLifeCycle: IDrawLifeCycle = {
// 展示占位图
displayPlaceholder: (context: CanvasRenderingContext2D, data: ImageKnifeData, imageKnifeOption: ImageKnifeOption, compWidth: number, compHeight: number, setGifTimeId?: (timeId: number) => void) => {
// @ts-ignore
this.stopAnimate()
return false;
},
// 展示加载进度
displayProgress: (context: CanvasRenderingContext2D, progress: number, imageKnifeOption: ImageKnifeOption, compWidth: number, compHeight: number, setGifTimeId?: (timeId: number) => void) => {
// @ts-ignore
this.stopAnimate()
context.save();
context.clearRect(0,0,compWidth,compHeight)
let pi = Math.PI * 2 / 100; //pi 讲圆的周长划分为100份
let rate = progress - 25;
let diameter = compWidth > compHeight ? compHeight : compWidth
context.lineWidth = Math.floor(diameter * 0.03)
context.lineCap = "round"
context.fillStyle = "white"
context.font = Math.floor(diameter * 0.5) + 'px'
let x0 = (compWidth - diameter) / 2.0 + Math.floor(diameter * 0.5)
let y0 = (compHeight - diameter) / 2.0 + Math.floor(diameter * 0.1)
let x1 = (compWidth - diameter) / 2.0 + Math.floor(diameter * 0.5)
let y1 = (compHeight - diameter) / 2.0 + Math.floor(diameter * 0.8)
let gradient = context.createLinearGradient(x0, y0, x1, y1)
gradient.addColorStop(0, "#11ffe4")
gradient.addColorStop(0.5, "#03c6fd")
gradient.addColorStop(1, "#10a5ff")
context.clearRect(0, 0, compWidth, compHeight)
context.shadowBlur = 0
context.beginPath()
context.strokeStyle = "#15222d"
let radius = Math.floor(diameter * 0.3)
let arcX = compWidth / 2.0
let arcY = compHeight / 2.0
context.arc(arcX, arcY, radius, 0, Math.PI * 2, true)
context.stroke()
context.beginPath()
let showText = rate + 25 + '%'
let metrics = context.measureText(showText)
let textX = (compWidth / 2.0) - metrics.width / 2.0
let textY = (compHeight / 2.0) + metrics.height * 0.3
context.fillText(showText, textX, textY)
context.stroke()
context.beginPath()
context.strokeStyle = gradient
context.arc(arcX, arcY, radius, pi * -25, pi * rate)
context.stroke();
context.restore();
return true;
},
// 展示缩略图
displayThumbSizeMultiplier: (context: CanvasRenderingContext2D, data: ImageKnifeData, imageKnifeOption: ImageKnifeOption, compWidth: number, compHeight: number, setGifTimeId?: (timeId: number) => void) => {
// @ts-ignore
this.stopAnimate()
return false;
},
// 展示主图
displayMainSource: (context: CanvasRenderingContext2D, data: ImageKnifeData, imageKnifeOption: ImageKnifeOption, compWidth: number, compHeight: number, setGifTimeId?: (timeId: number) => void) => {
this.stopAnimate()
if (data.isPixelMap()) {
// @ts-ignore
data.drawPixelMap.imagePixelMap.getImageInfo().then((imageInfo) => {
let scaleType = (typeof imageKnifeOption.mainScaleType == 'number') ? imageKnifeOption.mainScaleType : ScaleType.FIT_CENTER
console.log('imageinfo width =' + imageInfo.size.width + ' height=' + imageInfo.size.height + 'scaleType=' + scaleType)
let func = this.drawMainAnimate.bind(this,0, context, scaleType, data.drawPixelMap.imagePixelMap, imageInfo.size.width, imageInfo.size.height, compWidth, compHeight)
this.mTimerId = setTimeout(func, 1000/30.0)
console.log('TestImageKnifeOptionChangedPage4 drawMainSource end!')
})
return true;
}
return false;
},
// 展示重试图层
displayRetryholder: (context: CanvasRenderingContext2D, data: ImageKnifeData, imageKnifeOption: ImageKnifeOption, compWidth: number, compHeight: number, setGifTimeId?: (timeId: number) => void) => {
// @ts-ignore
this.stopAnimate()
return false;
},
// 展示失败占位图
displayErrorholder: (context: CanvasRenderingContext2D, data: ImageKnifeData, imageKnifeOption: ImageKnifeOption, compWidth: number, compHeight: number, setGifTimeId?: (timeId: number) => void) => {
// @ts-ignore
this.stopAnimate()
return false;
}
}
return viewLifeCycle;
}
}

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