Compare commits
139 Commits
3.1.0-rc.2
...
master
Author | SHA1 | Date |
---|---|---|
|
bc55de9e2e | |
|
c1426cd35a | |
|
adb78853af | |
|
9e387602f6 | |
|
115118e238 | |
|
acb45a66bc | |
|
25b7899746 | |
|
e41fce46bf | |
|
8601f87865 | |
|
933cc284ec | |
|
fbf4cc88bd | |
|
a21a8f025f | |
|
996fc5c909 | |
|
677ea73337 | |
|
5c22496b96 | |
|
425aa3a5bc | |
|
226d9939be | |
|
2c7473f422 | |
|
17e3787cfa | |
|
915eded1ab | |
|
a1e8e0b15f | |
|
1615da7b7c | |
|
3378d36046 | |
|
f709bd3f01 | |
|
a844860bae | |
|
60ec83850a | |
|
9939c748a8 | |
|
1efe55db1e | |
|
990a9a363f | |
|
618320843f | |
|
db56763a50 | |
|
2f2e562aed | |
|
fc6668cb0d | |
|
ba48f233a7 | |
|
549d9edf48 | |
|
db78e56e9a | |
|
68672e1dc7 | |
|
6719e8ab19 | |
|
7b025a7415 | |
|
912c23f34b | |
|
5f548d1090 | |
|
303ff79be1 | |
|
51e4675957 | |
|
47edcfed3e | |
|
e475dcd30a | |
|
e98984c56a | |
|
fba280904e | |
|
8aebc58a53 | |
|
9ff70d9c78 | |
|
e29c659e89 | |
|
83b42f36b0 | |
|
74bc24d61d | |
|
dac7731794 | |
|
1ae2ce8d92 | |
|
65c39faf8a | |
|
328257bb96 | |
|
a45fb6af7d | |
|
5296bf7a1d | |
|
30c327747b | |
|
73bc96e524 | |
|
32da743bcc | |
|
630b0df448 | |
|
f552f57713 | |
|
3dd622e4e2 | |
|
3423f4cd5d | |
|
0e0f1a96c2 | |
|
8adc342444 | |
|
95ffcb9e74 | |
|
b0661e83ac | |
|
04e2d430f2 | |
|
80ba246aeb | |
|
c75bb9226a | |
|
1153390393 | |
|
7210d5060b | |
|
1c7bedc6d5 | |
|
5f2e80400a | |
|
fd0394a80a | |
|
c5a861f4fe | |
|
b57194cf4c | |
|
1a2326c691 | |
|
9c0b4ebace | |
|
8d4442157c | |
|
a34e20acfa | |
|
8dd224e7e6 | |
|
a7fa5de2de | |
|
346c704193 | |
|
e857a41129 | |
|
7f51e9164e | |
|
41be71bb73 | |
|
08b36b7803 | |
|
da4c159d44 | |
|
29e0df8d2b | |
|
5fa004afc0 | |
|
d82d85ea19 | |
|
8e55d336f9 | |
|
e31c592ee4 | |
|
1027fc0304 | |
|
ec651e91df | |
|
7b9da8d9fa | |
|
2a81312ed5 | |
|
cde07275c3 | |
|
43dd3c528c | |
|
4383fa3659 | |
|
78770a430c | |
|
2201fec90c | |
|
aa2cd9c1bf | |
|
1787fffea7 | |
|
8e773e929a | |
|
a3ed45a468 | |
|
ccd4455b83 | |
|
2fc1f4c776 | |
|
6dcf2840b3 | |
|
f7cef581b1 | |
|
ddb8fc89be | |
|
858e28c3a2 | |
|
565938c98a | |
|
f1008e869e | |
|
afde885ae1 | |
|
9f98c174f2 | |
|
b491bc8dae | |
|
6cbe5eadc5 | |
|
0dd26b9e75 | |
|
233b24032e | |
|
d78ba39efe | |
|
dcdc17f51f | |
|
483803a302 | |
|
2cbce5790b | |
|
f9e83786a8 | |
|
f415bb7aa1 | |
|
55fcfe6021 | |
|
587d35f085 | |
|
b3114dd47b | |
|
0c8a777c82 | |
|
ddbff75a7d | |
|
2911708267 | |
|
7252a2fe05 | |
|
47c178fe1f | |
|
6612dea1d5 | |
|
fae5b3c7fd |
|
@ -0,0 +1,13 @@
|
|||
### 该问题是怎么引起的?
|
||||
|
||||
|
||||
|
||||
### 重现步骤
|
||||
|
||||
|
||||
|
||||
### 报错信息
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
name: 缺陷反馈|Bug
|
||||
description: 当您发现了一个缺陷,需要向社区反馈时,请使用此模板。
|
||||
title: "[Bug]: "
|
||||
labels: ["bug"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
感谢对OpenHarmony社区的支持与关注,欢迎反馈缺陷。
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: 发生了什么问题?
|
||||
description: 提供尽可能多的信息描述产生了什么问题。
|
||||
placeholder: ""
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: 期望行为是什么?
|
||||
description: 描述期望的行为应该是什么样子的。
|
||||
placeholder: ""
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: 如何复现该缺陷
|
||||
description: 提供尽可能多的信息描述如何复现该缺陷。
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: 其他补充信息
|
||||
description: 补充下其他您认为需要提供的信息。
|
||||
validations:
|
||||
required: false
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: 版本或分支信息
|
||||
description: 在哪些版本、分支存在该缺陷的?
|
||||
options:
|
||||
- label: master
|
||||
- label: Release 3.2
|
||||
- label: Release 3.1
|
||||
- label: Release 3.0
|
||||
- label: Release 2.x
|
||||
validations:
|
||||
required: true
|
|
@ -0,0 +1 @@
|
|||
blank_issues_enabled: false
|
|
@ -0,0 +1,21 @@
|
|||
name: 新需求|Feature
|
||||
description: 您需要反馈或实现一个新需求时,使用此模板。
|
||||
title: "[新需求]: "
|
||||
labels: ["enhancement"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
感谢提出新需求。
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: 新需求提供了什么功能?
|
||||
description: 请描述下新需求的功能是什么,解决了什么问题
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: 该需求带来的价值、应用场景?
|
||||
description: 请描述下该需求的价值,应用场景等。
|
||||
validations:
|
||||
required: false
|
|
@ -0,0 +1,15 @@
|
|||
name: 问题咨询|Question
|
||||
description: 如果您对OpenHarmony社区有疑问,欢迎反馈咨询。
|
||||
title: "[问题咨询]: "
|
||||
labels: ["question"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
感谢提出问题,我们将安排人答复!
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: 问题描述
|
||||
description: 请描述下您的问题
|
||||
validations:
|
||||
required: true
|
|
@ -0,0 +1,72 @@
|
|||
name: 安全问题|Security Issue
|
||||
description: 当您发现安全问题时,使用此模板反馈。
|
||||
title: "[安全问题]: "
|
||||
labels: ["SIG_Security"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
感谢对OpenHarmony社区的支持与关注,欢迎反馈安全问题。
|
||||
- type: input
|
||||
attributes:
|
||||
label: 漏洞编号:
|
||||
description: 请描述下漏洞编号。
|
||||
placeholder: ""
|
||||
validations:
|
||||
required: false
|
||||
- type: input
|
||||
attributes:
|
||||
label: 漏洞归属组件
|
||||
description: 请描述下漏洞归属组件。
|
||||
placeholder: ""
|
||||
validations:
|
||||
required: false
|
||||
- type: input
|
||||
attributes:
|
||||
label: 漏洞归属版本
|
||||
description: 请描述下漏洞归属版本。
|
||||
placeholder: ""
|
||||
validations:
|
||||
required: false
|
||||
- type: input
|
||||
attributes:
|
||||
label: CVSS V3.0分值
|
||||
description: 请描述下CVSS V3.0分值。
|
||||
placeholder: ""
|
||||
validations:
|
||||
required: false
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: 漏洞简述
|
||||
description: 请提供下漏洞的描述信息。
|
||||
placeholder: ""
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: 影响性分析说明
|
||||
description: 请描述下该漏洞的影响。
|
||||
placeholder: ""
|
||||
validations:
|
||||
required: false
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: 原理分析
|
||||
description: 请分析下该漏洞的原理。
|
||||
placeholder: ""
|
||||
validations:
|
||||
required: false
|
||||
- type: input
|
||||
attributes:
|
||||
label: 受影响版本
|
||||
description: 请描述下该漏洞的影响版本。
|
||||
placeholder: ""
|
||||
validations:
|
||||
required: false
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: 规避方案或消减措施
|
||||
description: 请描述下该漏洞的规避方案或消减措施。
|
||||
placeholder: ""
|
||||
validations:
|
||||
required: false
|
|
@ -0,0 +1,8 @@
|
|||
### 一、修改说明
|
||||
|
||||
|
||||
### 二、变更内容
|
||||
|
||||
|
||||
### 三、测试建议
|
||||
|
113
CHANGELOG.md
|
@ -1,3 +1,87 @@
|
|||
## 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图片显示有毛边
|
||||
|
||||
|
@ -10,6 +94,35 @@
|
|||
- 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
|
||||
|
|
3
OAT.xml
|
@ -27,6 +27,7 @@
|
|||
<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 compatibility,license header policies">
|
||||
|
@ -37,6 +38,7 @@
|
|||
<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="binaryFileTypePolicyFilter" desc="Filters for binary file policies">
|
||||
|
@ -48,6 +50,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">
|
||||
|
|
362
README.md
|
@ -1,228 +1,234 @@
|
|||
## 🚨 **重要提示 | IMPORTANT**
|
||||
>
|
||||
> **⚠️ 此代码仓已归档。新地址请访问 [ImageKnife](https://gitcode.com/openharmony-tpc/ImageKnife)。| ⚠️ This repository has been archived. For the new address, please visit [ImageKnife](https://gitcode.com/openharmony-tpc/ImageKnife).**
|
||||
>
|
||||
---
|
||||
>
|
||||
# ImageKnife
|
||||
|
||||
**专门为OpenHarmony打造的一款图像加载缓存库,致力于更高效、更轻便、更简单。**
|
||||
ImageKnife is a specially crafted image loading and caching library for OpenHarmony, optimized for efficiency, lightness, and simplicity.
|
||||
|
||||
## 简介
|
||||
## Introduction
|
||||
|
||||
本项目参考开源库 [Glide](https://github.com/bumptech/glide) 进行OpenHarmony的自研版本:
|
||||
This project is a self-developed version for OpenHarmony, inspired by the open-source [Glide](https://github.com/bumptech/glide) library. It sports the following features:
|
||||
|
||||
- 支持自定义内存缓存策略,支持设置内存缓存的大小(默认LRU策略)。
|
||||
- 支持磁盘二级缓存,对于下载图片会保存一份至磁盘当中。
|
||||
- 支持自定义实现图片获取/网络下载
|
||||
- 支持监听网络下载回调进度
|
||||
- 继承Image的能力,支持option传入border,设置边框,圆角
|
||||
- 继承Image的能力,支持option传入objectFit设置图片缩放,包括objectFit为auto时根据图片自适应高度
|
||||
- 支持通过设置transform缩放图片
|
||||
- 并发请求数量,支持请求排队队列的优先级
|
||||
- 支持生命周期已销毁的图片,不再发起请求
|
||||
- 自定义缓存key
|
||||
- 自定义http网络请求头
|
||||
- 支持writeCacheStrategy控制缓存的存入策略(只存入内存或文件缓存)
|
||||
- 支持preLoadCache预加载图片
|
||||
- 支持onlyRetrieveFromCache仅用缓存加载
|
||||
- 支持使用一个或多个图片变换,如模糊,高亮等
|
||||
- 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
|
||||
|
||||
待实现特性
|
||||
Planned features:
|
||||
|
||||
- 内存降采样优化,节约内存的占用
|
||||
- 支持自定义图片解码
|
||||
- Memory downsampling optimization to save memory usage
|
||||
- Support for custom image decoding
|
||||
|
||||
注意:3.x版本相对2.x版本做了重大的重构,主要体现在:
|
||||
Note: The 3.x version has been significantly restructured from the 2.x version, mainly in the following aspects:
|
||||
|
||||
- 使用Image组件代替Canvas组件渲染
|
||||
- 重构Dispatch分发逻辑,支持控制并发请求数,支持请求排队队列的优先级
|
||||
- 支持通过initMemoryCache自定义策略内存缓存策略和大小
|
||||
- 支持option自定义实现图片获取/网络下载
|
||||
- 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
|
||||
|
||||
因此API及能力上,目前有部分差异,主要体现在:
|
||||
Therefore, there are some differences in APIs and capabilities, which mainly include the following:
|
||||
|
||||
- 不支持drawLifeCycle接口,通过canvas自会图片
|
||||
- mainScaleType,border等参数,新版本与系统Image保持一致
|
||||
- gif/webp动图播放与控制(ImageAnimator实现)
|
||||
- 抗锯齿相关参数
|
||||
- The **drawLifeCycle** API is not supported; images are drawn manually through the canvas.
|
||||
- In the new version, parameters such as **mainScaleType** and **border** are consistent with the system **Image** component.
|
||||
- GIF/WebP animation playback and control (implemented by **ImageAnimator**).
|
||||
- Anti-aliasing related parameters.
|
||||
|
||||
## 下载安装
|
||||
## How to Install
|
||||
|
||||
```
|
||||
ohpm install @ohos/imageknife
|
||||
|
||||
// 如果需要用文件缓存,需要提前初始化文件缓存
|
||||
// If file caching is required, initialize the file cache in advance.
|
||||
await ImageKnife.getInstance().initFileCache(context, 256, 256 * 1024 * 1024)
|
||||
```
|
||||
|
||||
## 使用说明
|
||||
## How to Use
|
||||
|
||||
#### 1.显示本地资源图片
|
||||
#### 1. Displaying a Local Resource Image
|
||||
|
||||
```
|
||||
ImageKnifeComponent({
|
||||
ImageKnifeOption: new ImageKnifeOption({
|
||||
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下文件
|
||||
#### 2. Displaying a File from Local Context Files
|
||||
|
||||
```
|
||||
ImageKnifeComponent({
|
||||
ImageKnifeOption: new ImageKnifeOption({
|
||||
ImageKnifeOption: {
|
||||
loadSrc: this.localFile,
|
||||
placeholderSrc: $r("app.media.loading"),
|
||||
errorholderSrc: $r("app.media.app_icon"),
|
||||
objectFit: ImageFit.Auto
|
||||
})
|
||||
}
|
||||
}).width(100).height(100)
|
||||
```
|
||||
|
||||
#### 3.显示网络图片
|
||||
#### 3. Displaying a Network Image
|
||||
|
||||
```
|
||||
ImageKnifeComponent({
|
||||
ImageKnifeOption: new ImageKnifeOption({
|
||||
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.自定义下载图片
|
||||
#### 4. Downloading an Image with Custom Options
|
||||
|
||||
```
|
||||
ImageKnifeComponent({
|
||||
ImageKnifeOption: new ImageKnifeOption({
|
||||
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)
|
||||
|
||||
// 自定义实现图片获取方法,如自定义网络下载
|
||||
// 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)
|
||||
// 举例写死从本地文件读取,也可以自己请求网络图片
|
||||
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.监听网络下载进度
|
||||
#### 5. Listening for Network Download Progress
|
||||
|
||||
```
|
||||
ImageKnifeComponent({
|
||||
ImageKnifeOption: new ImageKnifeOption({
|
||||
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,设置边框,圆角
|
||||
#### 6. Setting Border Options
|
||||
|
||||
```
|
||||
ImageKnifeComponent({ ImageKnifeOption: new ImageKnifeOption(
|
||||
ImageKnifeComponent({ ImageKnifeOption:
|
||||
{
|
||||
loadSrc: $r("app.media.rabbit"),
|
||||
border: {radius:50}
|
||||
})
|
||||
}
|
||||
}).width(100).height(100)
|
||||
```
|
||||
|
||||
#### 7.支持option图片变换
|
||||
#### 7. Setting Image Transformation Options
|
||||
|
||||
```
|
||||
ImageKnifeComponent({ ImageKnifeOption: new ImageKnifeOption(
|
||||
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: new ImageKnifeOption({
|
||||
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 // 图形变换组
|
||||
})
|
||||
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 }) // 旋转90度
|
||||
.contrast(12) // 对比度滤波器
|
||||
.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:new ImageKnifeOption(
|
||||
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:new ImageKnifeOption(
|
||||
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: new ImageKnifeOption({
|
||||
imageKnifeOption: {
|
||||
loadSrc: $r('app.media.pngSample')
|
||||
})
|
||||
}
|
||||
}).width(300)
|
||||
.height(300)
|
||||
.contrast(12)
|
||||
```
|
||||
|
||||
旋转变换示例
|
||||
Example of rotation transformation:
|
||||
|
||||
```
|
||||
ImageKnifeComponent({
|
||||
imageKnifeOption: new ImageKnifeOption({
|
||||
imageKnifeOption:({
|
||||
loadSrc: $r('app.media.pngSample')
|
||||
})
|
||||
}
|
||||
}).width(300)
|
||||
.height(300)
|
||||
.rotate({angle:90})
|
||||
.backgroundColor(Color.Pink)
|
||||
```
|
||||
|
||||
#### 8.监听图片加载成功与失败
|
||||
#### 8. Listening for Image Loading Success and Failure
|
||||
|
||||
```
|
||||
ImageKnifeComponent({ ImageKnifeOption: new ImageKnifeOption(
|
||||
ImageKnifeComponent({ ImageKnifeOption:
|
||||
{
|
||||
loadSrc: $r("app.media.rabbit"),
|
||||
onLoadListener:{
|
||||
|
@ -241,133 +247,143 @@ ImageKnifeComponent({ ImageKnifeOption: new ImageKnifeOption(
|
|||
console.info(err)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}).width(100).height(100)
|
||||
```
|
||||
#### 9.ImageKnifeComponent - syncLoad
|
||||
设置是否同步加载图片,默认是异步加载。建议加载尺寸较小的本地图片时将syncLoad设为true,因为耗时较短,在主线程上执行即可
|
||||
#### 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:new ImageKnifeOption({
|
||||
imageKnifeOption:{
|
||||
loadSrc:$r("app.media.pngSample"),
|
||||
placeholderSrc:$r("app.media.loading")
|
||||
}),syncLoad:true
|
||||
},syncLoad:true
|
||||
})
|
||||
```
|
||||
#### 10.ImageKnifeAnimatorComponent 示例
|
||||
#### 10. Use of ImageKnifeAnimatorComponent
|
||||
```
|
||||
ImageKnifeAnimatorComponent({
|
||||
imageKnifeOption:new ImageKnifeOption({
|
||||
imageKnifeOption:{
|
||||
loadSrc:"https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658",
|
||||
placeholderSrc:$r('app.media.loading'),
|
||||
errorholderSrc:$r('app.media.failed')
|
||||
}),animatorOption:this.animatorOption
|
||||
},animatorOption:this.animatorOption
|
||||
}).width(300).height(300).backgroundColor(Color.Orange).margin({top:30})
|
||||
```
|
||||
## 接口说明
|
||||
### ImageKnife组件
|
||||
| 组件名称 | 入参内容 | 功能简介 |
|
||||
|-----------------------------|---------------------------------|--------|
|
||||
| ImageKnifeComponent | ImageKnifeOption | 图片显示组件 |
|
||||
| ImageKnifeAnimatorComponent | ImageKnifeOption、AnimatorOption | 动图控制组件 |
|
||||
#### 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参数列表
|
||||
| 参数名称 | 入参内容 | 功能简介 |
|
||||
|------------|-----------------|----------|
|
||||
| state | AnimationStatus | 播放状态(可选) |
|
||||
| iterations | number | 播放次数(可选) |
|
||||
| reverse | boolean | 播放顺序(可选) |
|
||||
| onStart | ()=>void | 动画开始播放时触发(可选) |
|
||||
| onFinish | ()=>void | 动画播放完成时或者停止播放时触发(可选) |
|
||||
| onPause | ()=>void | 动画暂停播放时触发(可选) |
|
||||
| onCancel | ()=>void | 动画返回最初状态时触发(可选) |
|
||||
| onRepeat | ()=>void | 动画重复播放时触发(可选) |
|
||||
### 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参数列表
|
||||
### ImageKnifeOption
|
||||
|
||||
| 参数名称 | 入参内容 | 功能简介 |
|
||||
|-----------------------|-------------------------------------------------------|-----------------|
|
||||
| loadSrc | string、PixelMap、Resource | 主图展示 |
|
||||
| placeholderSrc | PixelMap、Resource | 占位图图展示(可选) |
|
||||
| errorholderSrc | PixelMap、Resource | 错误图展示(可选) |
|
||||
| objectFit | ImageFit | 主图填充效果(可选) |
|
||||
| placeholderObjectFit | ImageFit | 占位图填充效果(可选) |
|
||||
| errorholderObjectFit | ImageFit | 错误图填充效果(可选) |
|
||||
| writeCacheStrategy | CacheStrategyType | 写入缓存策略(可选) |
|
||||
| onlyRetrieveFromCache | boolean | 是否跳过网络和本地请求(可选) |
|
||||
| customGetImage | (context: Context, src: string | 自定义下载图片(可选) | | 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) => voi | 颜色滤镜效果(可选) |
|
||||
| onLoadListener | onLoadStart: () => void、onLoadSuccess: (data: string | PixelMap | undefined) => void、onLoadFailed: (err: string) => void| 监听图片加载成功与失败 |
|
||||
| Parameter | Type | Description |
|
||||
| --------------------- | ----------------------------------------------------- | ------------------------------ |
|
||||
| loadSrc | string, PixelMap, Resource | Main image. |
|
||||
| placeholderSrc | PixelMap, Resource | Placeholder image. Optional. |
|
||||
| errorholderSrc | PixelMap, Resource | Error image. Optional. |
|
||||
| objectFit | ImageFit | How the main image is resized to fit its container. Optional. |
|
||||
| placeholderObjectFit | ImageFit | How the placeholder image is resized to fit its container. Optional. |
|
||||
| errorholderObjectFit | ImageFit | How the error image is resized to fit its container. Optional. |
|
||||
| writeCacheStrategy | CacheStrategyType | Cache writing strategy. Optional. |
|
||||
| onlyRetrieveFromCache | boolean | Whether to skip network and local requests. Optional.|
|
||||
| customGetImage | (context: Context, src: string | Custom image download. Optional. |
|
||||
| border | BorderOptions | Border corner. Optional. |
|
||||
| priority | taskpool.Priority | Load priority. Optional. |
|
||||
| context | common.UIAbilityContext | Context. Optional. |
|
||||
| progressListener | (progress: number)=>void | Progress. Optional. |
|
||||
| signature | String | Custom cache signature. Optional. |
|
||||
| headerOption | Array\<HeaderOptions> | Request headers. Optional. |
|
||||
| transformation | PixelMapTransformation | Image transformation. Optional. |
|
||||
| drawingColorFilter | ColorFilter | Drawing color filter. Optional. |
|
||||
| onComplete | (event:EventImage \| undefined)=>void | Callback for image loading completion. Optional. |
|
||||
| onLoadListener | onLoadStart:()=>void,onLoadSuccess:(data:string\|Pixelmap)=>void | Callback for image loading events. Optional. |
|
||||
|
||||
### ImageKnife接口
|
||||
### ImageKnife
|
||||
|
||||
| 参数名称 | 入参内容 | 功能简介 |
|
||||
|------------------|-------------------------------------------------------------------------------------------------------|---------------|
|
||||
| initMemoryCache | newMemoryCache: IMemoryCache | 自定义内存缓存策略 |
|
||||
| initFileCache | context: Context, size: number, memory: number | 初始化文件缓存数量和大小 |
|
||||
| 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) => Promise<ArrayBuffer | undefined> | 全局设置自定义下载 |
|
||||
| setEngineKeyImpl | IEngineKey | 全局配置缓存key生成策略 |
|
||||
| putCacheImage | url: string, pixelMap: PixelMap, cacheType: CacheStrategy = CacheStrategy.Default, signature?: string | 写入内存磁盘缓存 |
|
||||
| removeMemoryCache| url: string | ImageKnifeOption | 清理指定内存缓存 |
|
||||
| removeFileCache | url: string | ImageKnifeOption | 清理指定磁盘缓存 |
|
||||
### 图形变换类型(需要为GPUImage添加依赖项)
|
||||
| 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)
|
||||
|
||||
| 类型 | 相关描述 |
|
||||
| ---------------------------------- | ----------------------------- |
|
||||
| BlurTransformation | 模糊处理 |
|
||||
| BrightnessTransformation | 亮度滤波器 |
|
||||
| CropSquareTransformation | 正方形剪裁 |
|
||||
| CropTransformation | 自定义矩形剪裁 |
|
||||
| GrayScaleTransformation | 灰度级滤波器 |
|
||||
| InvertTransformation | 反转滤波器 |
|
||||
| KuwaharaTransformation | 桑原滤波器(使用GPUIImage) |
|
||||
| MaskTransformation | 遮罩 |
|
||||
| PixelationTransformation | 像素化滤波器(使用GPUIImage) |
|
||||
| SepiaTransformation | 乌墨色滤波器(使用GPUIImage) |
|
||||
| SketchTransformation | 素描滤波器(使用GPUIImage) |
|
||||
| SwirlTransformation | 扭曲滤波器(使用GPUIImage) |
|
||||
| ToonTransformation | 动画滤波器(使用GPUIImage) |
|
||||
| VignetterTransformation | 装饰滤波器(使用GPUIImage) |
|
||||
| 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**). |
|
||||
|
||||
## 下载安装GPUImage依赖
|
||||
方法一:在Terminal窗口中,执行如下命令安装三方包,DevEco Studio会自动在工程的oh-package.json5中自动添加三方包依赖。
|
||||
## 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
|
||||
```
|
||||
方法二: 在工程的oh-package.json5中设置三方包依赖,配置示例如下:
|
||||
Method 2: Set the third-party HAR as a dependency in the **oh-package.json5** file of the project. The following is a configuration example:
|
||||
```
|
||||
"dependencies": {
|
||||
"@ohos/gpu_transform": "^1.0.2"
|
||||
}
|
||||
```
|
||||
## 约束与限制
|
||||
## Constraints
|
||||
|
||||
在下述版本验证通过:
|
||||
DevEco Studio 5.0 Canary3(5.0.3.502)--SDK:API12 (5.0.0.31)
|
||||
This project has been verified in the following version:
|
||||
|
||||
## 贡献代码
|
||||
DevEco Studio: NEXT Beta1-5.0.3.806, SDK: API12 Release(5.0.0.66)
|
||||
|
||||
使用过程中发现任何问题都可以提 [issue](https://gitee.com/openharmony-tpc/ImageKnife/issues)
|
||||
给我们,当然,我们也非常欢迎你给我们发 [PR](https://gitee.com/openharmony-tpc/ImageKnife/issues) 。
|
||||
## 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
|
||||
|
||||
本项目基于 [Apache License 2.0](https://gitee.com/openharmony-tpc/ImageKnife/blob/master/LICENSE) ,请自由的享受和参与开源。
|
||||
If you find any problem during the use, submit an [Issue](https://gitee.com/openharmony-tpc/ImageKnife/issues) or a [PR](https://gitee.com/openharmony-tpc/ImageKnife/issues) to us.
|
||||
|
||||
## 遗留问题
|
||||
## License
|
||||
|
||||
- ImageKnifeAnimator组件无法设置ImageFit属性
|
||||
- ImageKnifeAnimator组件设置border属性无法将图片变为圆角
|
||||
This project is licensed under [Apache License 2.0](https://gitee.com/openharmony-tpc/ImageKnife/blob/master/LICENSE).
|
||||
|
||||
## Known Issues
|
||||
|
||||
- The **ImageFit** attribute cannot be set for the **ImageKnifeAnimator** component.
|
||||
- The **border** attribute of the **ImageKnifeAnimator** component cannot make the image rounded corners.
|
|
@ -0,0 +1,485 @@
|
|||
## 🚨 **重要提示 | IMPORTANT**
|
||||
>
|
||||
> **⚠️ 此代码仓已归档。新地址请访问 [ImageKnife](https://gitcode.com/openharmony-tpc/ImageKnife)。| ⚠️ This repository has been archived. For the new address, please visit [ImageKnife](https://gitcode.com/openharmony-tpc/ImageKnife).**
|
||||
>
|
||||
---
|
||||
>
|
||||
# ImageKnife
|
||||
|
||||
**专门为OpenHarmony打造的一款图像加载缓存库,致力于更高效、更轻便、更简单。**
|
||||
|
||||
## 简介
|
||||
|
||||
本项目参考开源库 [Glide](https://github.com/bumptech/glide) 进行OpenHarmony的自研版本:
|
||||
|
||||
- 支持自定义内存缓存策略,支持设置内存缓存的大小(默认LRU策略)。
|
||||
- 支持磁盘二级缓存,对于下载图片会保存一份至磁盘当中。
|
||||
- 支持自定义实现图片获取/网络下载
|
||||
- 支持监听网络下载回调进度
|
||||
- 继承Image的能力,支持option传入border,设置边框,圆角
|
||||
- 继承Image的能力,支持option传入objectFit设置图片缩放,包括objectFit为auto时根据图片自适应高度
|
||||
- 支持通过设置transform缩放图片
|
||||
- 并发请求数量,支持请求排队队列的优先级
|
||||
- 支持生命周期已销毁的图片,不再发起请求
|
||||
- 自定义缓存key
|
||||
- 自定义http网络请求头
|
||||
- 支持writeCacheStrategy控制缓存的存入策略(只存入内存或文件缓存)
|
||||
- 支持preLoadCache预加载图片
|
||||
- 支持onlyRetrieveFromCache仅用缓存加载
|
||||
- 支持使用一个或多个图片变换,如模糊,高亮等
|
||||
|
||||
待实现特性
|
||||
|
||||
- 内存降采样优化,节约内存的占用
|
||||
- 支持自定义图片解码
|
||||
|
||||
注意:3.x版本相对2.x版本做了重大的重构,主要体现在:
|
||||
|
||||
- 使用Image组件代替Canvas组件渲染
|
||||
- 重构Dispatch分发逻辑,支持控制并发请求数,支持请求排队队列的优先级
|
||||
- 支持通过initMemoryCache自定义策略内存缓存策略和大小
|
||||
- 支持option自定义实现图片获取/网络下载
|
||||
|
||||
因此API及能力上,目前有部分差异,主要体现在:
|
||||
|
||||
- 不支持drawLifeCycle接口,通过canvas自会图片
|
||||
- mainScaleType,border等参数,新版本与系统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<ArrayBuffer、undefined> | 自定义下载图片(可选) | | 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<ArrayBuffer、undefined>| 全局设置自定义下载 |
|
||||
| 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,包含此次请求错误信息(ErrorInfo,TimeInfo),ErrorInfo其中包含了,错误阶段、错误码及其网络请求的错误码;TimeInfo中包含请求结束时间、磁盘检查时间、网络请求开始结束、图片解码开始结束等时间点 |
|
||||
| onLoadCancel | reason: string, req?: ImageKnifeRequest | reason:取消回调原因;req:图片请求的信息,同时其中的ImageKnifeData,包含此次请求错误信息(ErrorInfo,TimeInfo),ErrorInfo其中包含了,错误阶段、错误码及其网络请求的错误码;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属性
|
|
@ -8,7 +8,8 @@
|
|||
"name": "default",
|
||||
"signingConfig": "default",
|
||||
"compileSdkVersion": 12,
|
||||
"compatibleSdkVersion": 12
|
||||
"compatibleSdkVersion": 12,
|
||||
"runtimeOS": "OpenHarmony"
|
||||
}
|
||||
],
|
||||
"buildModeSet": [
|
||||
|
|
|
@ -16,3 +16,6 @@
|
|||
# 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
|
|
@ -12,7 +12,8 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { IEngineKey, ImageKnifeOption, PixelMapTransformation,SparkMD5 ,ImageKnifeRequestSource} from '@ohos/libraryimageknife';
|
||||
import { IEngineKey, ImageKnifeOption, PixelMapTransformation,SparkMD5 ,ImageKnifeRequestSource,
|
||||
DownsampleStrategy} from '@ohos/libraryimageknife';
|
||||
|
||||
//全局自定义key demo
|
||||
@Sendable
|
||||
|
@ -35,6 +36,9 @@ export class CustomEngineKeyImpl implements IEngineKey {
|
|||
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
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ 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, LogUtil } from '@ohos/libraryimageknife';
|
||||
import { ImageKnife, InitImageKnife } from '@ohos/libraryimageknife';
|
||||
import { CustomEngineKeyImpl } from '../common/CustomEngineKeyImpl';
|
||||
import abilityAccessCtrl, { Permissions } from '@ohos.abilityAccessCtrl';
|
||||
import { BusinessError } from '@ohos.base'
|
||||
|
@ -47,7 +47,6 @@ export default class EntryAbility extends UIAbility {
|
|||
|
||||
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate');
|
||||
|
||||
LogUtil.mLogLevel = LogUtil.ALL
|
||||
// 初始化ImageKnife的文件缓存
|
||||
await InitImageKnife.init(this.context)
|
||||
ImageKnife.getInstance().setEngineKeyImpl(new CustomEngineKeyImpl())
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* Copyright (C) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { ImageKnifeComponent } from '@ohos/libraryimageknife';
|
||||
import { display } from '@kit.ArkUI';
|
||||
|
||||
@Entry
|
||||
@Component
|
||||
struct AutoImageFit {
|
||||
@State imageWidth: number = 200;
|
||||
private maxWidth: number = px2vp(display.getDefaultDisplaySync().width);
|
||||
|
||||
build() {
|
||||
|
||||
Column() {
|
||||
this.Slider()
|
||||
Column() {
|
||||
Text('Image')
|
||||
Image('https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/56/v3/8MdhfSsCSMKj4sA6okUWrg/5uBx56tLTUO3RYQl-E5JiQ.jpg')
|
||||
.width('100%')
|
||||
.objectFit(ImageFit.Auto)
|
||||
Text('ImageKnife')
|
||||
ImageKnifeComponent({
|
||||
imageKnifeOption: {
|
||||
loadSrc: 'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/56/v3/8MdhfSsCSMKj4sA6okUWrg/5uBx56tLTUO3RYQl-E5JiQ.jpg',
|
||||
objectFit: ImageFit.Auto,
|
||||
}
|
||||
}).width('100%')
|
||||
}.width(this.imageWidth).border({ width: 1 })
|
||||
}
|
||||
}
|
||||
|
||||
@Builder
|
||||
Slider() {
|
||||
Slider({
|
||||
value: this.imageWidth,
|
||||
min: 100,
|
||||
max: this.maxWidth,
|
||||
style: SliderStyle.OutSet
|
||||
})
|
||||
.blockColor(Color.White)
|
||||
.width('100%')
|
||||
.onChange((value: number) => {
|
||||
this.imageWidth = value;
|
||||
})
|
||||
}
|
||||
}
|
|
@ -0,0 +1,220 @@
|
|||
/*
|
||||
* Copyright (C) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { DownsampleStrategy, ImageKnifeOption, } from '@ohos/imageknife';
|
||||
import { ImageKnifeComponent } from '@ohos/libraryimageknife';
|
||||
import { image } from '@kit.ImageKit';
|
||||
import { BusinessError } from '@kit.BasicServicesKit';
|
||||
import { Downsampler } from '@ohos/imageknife/src/main/ets/downsampling/Downsampler';
|
||||
import { FileTypeUtil } from '@ohos/imageknife/src/main/ets/utils/FileTypeUtil';
|
||||
|
||||
@Entry
|
||||
@Component
|
||||
struct DownSamplePage {
|
||||
@State imageKnifeOption: ImageKnifeOption = {
|
||||
loadSrc: $r('app.media.startIcon'),
|
||||
placeholderSrc: $r('app.media.loading'),
|
||||
errorholderSrc: $r('app.media.app_icon'),
|
||||
objectFit: ImageFit.Contain
|
||||
}
|
||||
isBrightness: boolean = false
|
||||
@State beforeSampling: number = 0
|
||||
@State afterSampling: number = 0
|
||||
@State SamplingList: SamplingType[] = [
|
||||
|
||||
new SamplingType(7, 'AT_LEAST'),
|
||||
new SamplingType(1, 'AT_MOST'),
|
||||
|
||||
new SamplingType(2, 'FIT_CENTER_MEMORY'),
|
||||
new SamplingType(4, 'FIT_CENTER_QUALITY'),
|
||||
new SamplingType(5, 'CENTER_INSIDE_MEMORY'),
|
||||
new SamplingType(6, 'CENTER_INSIDE_QUALITY'),
|
||||
new SamplingType(0, 'NONE'),
|
||||
|
||||
]
|
||||
@State checked: boolean = false
|
||||
|
||||
updateImageKnifeOption(value: string) {
|
||||
if (value === 'NONE') {
|
||||
this.imageKnifeOption = {
|
||||
loadSrc: $r('app.media.pngSample'),
|
||||
placeholderSrc: $r('app.media.loading'),
|
||||
errorholderSrc: $r('app.media.app_icon'),
|
||||
objectFit: ImageFit.Contain,
|
||||
downsampleOf: DownsampleStrategy.NONE
|
||||
}
|
||||
this.originalPixMap($r('app.media.pngSample'))
|
||||
this.afterSamplingFunc($r('app.media.pngSample'))
|
||||
} else if (value === 'AT_MOST') {
|
||||
this.imageKnifeOption = {
|
||||
loadSrc: $r('app.media.pngSample'),
|
||||
placeholderSrc: $r('app.media.loading'),
|
||||
errorholderSrc: $r('app.media.app_icon'),
|
||||
objectFit: ImageFit.Contain,
|
||||
downsampleOf: DownsampleStrategy.AT_MOST
|
||||
}
|
||||
this.originalPixMap($r('app.media.pngSample'))
|
||||
this.afterSamplingFunc($r('app.media.pngSample'))
|
||||
} else if (value === 'FIT_CENTER_MEMORY') {
|
||||
this.imageKnifeOption = {
|
||||
loadSrc: $r('app.media.pngSample'),
|
||||
placeholderSrc: $r('app.media.loading'),
|
||||
errorholderSrc: $r('app.media.app_icon'),
|
||||
objectFit: ImageFit.Contain,
|
||||
downsampleOf: DownsampleStrategy.FIT_CENTER_MEMORY
|
||||
}
|
||||
this.originalPixMap($r('app.media.pngSample'))
|
||||
this.afterSamplingFunc($r('app.media.pngSample'))
|
||||
} else if (value === 'FIT_CENTER_QUALITY') {
|
||||
this.imageKnifeOption = {
|
||||
loadSrc: $r('app.media.pngSample'),
|
||||
placeholderSrc: $r('app.media.loading'),
|
||||
errorholderSrc: $r('app.media.app_icon'),
|
||||
objectFit: ImageFit.Contain,
|
||||
downsampleOf: DownsampleStrategy.FIT_CENTER_QUALITY
|
||||
}
|
||||
this.originalPixMap($r('app.media.pngSample'))
|
||||
this.afterSamplingFunc($r('app.media.pngSample'))
|
||||
} else if (value === 'CENTER_INSIDE_MEMORY') {
|
||||
this.imageKnifeOption = {
|
||||
loadSrc: $r('app.media.pngSample'),
|
||||
placeholderSrc: $r('app.media.loading'),
|
||||
errorholderSrc: $r('app.media.app_icon'),
|
||||
objectFit: ImageFit.Contain,
|
||||
downsampleOf: DownsampleStrategy.CENTER_INSIDE_MEMORY
|
||||
}
|
||||
this.originalPixMap($r('app.media.pngSample'))
|
||||
this.afterSamplingFunc($r('app.media.pngSample'))
|
||||
} else if (value === 'CENTER_INSIDE_QUALITY') {
|
||||
this.imageKnifeOption = {
|
||||
loadSrc: $r('app.media.pngSample'),
|
||||
placeholderSrc: $r('app.media.loading'),
|
||||
errorholderSrc: $r('app.media.app_icon'),
|
||||
objectFit: ImageFit.Contain,
|
||||
downsampleOf: DownsampleStrategy.CENTER_INSIDE_QUALITY
|
||||
}
|
||||
this.originalPixMap($r('app.media.pngSample'))
|
||||
this.afterSamplingFunc($r('app.media.pngSample'))
|
||||
} else {
|
||||
this.imageKnifeOption = {
|
||||
loadSrc: $r('app.media.pngSample'),
|
||||
placeholderSrc: $r('app.media.loading'),
|
||||
errorholderSrc: $r('app.media.app_icon'),
|
||||
objectFit: ImageFit.Contain,
|
||||
downsampleOf: DownsampleStrategy.AT_LEAST
|
||||
}
|
||||
this.originalPixMap($r('app.media.pngSample'))
|
||||
this.afterSamplingFunc($r('app.media.pngSample'))
|
||||
}
|
||||
}
|
||||
|
||||
async afterSamplingFunc(imgs: Resource) {
|
||||
let img: Uint8Array = await getContext(this).resourceManager.getMediaContent(imgs);
|
||||
let imageSource: image.ImageSource = image.createImageSource(img.buffer.slice(0));
|
||||
let fileTypeUtil = new FileTypeUtil();
|
||||
let typeValue = fileTypeUtil.getFileType(img.buffer.slice(0)) as string;
|
||||
let decodingOptions: image.DecodingOptions = {
|
||||
editable: true,
|
||||
desiredPixelFormat: 3,
|
||||
}
|
||||
let imageInfo = await imageSource.getImageInfo()
|
||||
|
||||
if (this.imageKnifeOption.downsampleOf !== DownsampleStrategy.NONE && this.imageKnifeOption.downsampleOf != undefined ) {
|
||||
let reqSize =
|
||||
new Downsampler().calculateScaling(typeValue, imageInfo.size.width, imageInfo.size.height, 300,
|
||||
300, this.imageKnifeOption.downsampleOf)
|
||||
decodingOptions = {
|
||||
editable: true,
|
||||
desiredSize: {
|
||||
width: reqSize.width,
|
||||
height: reqSize.height
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 创建pixelMap
|
||||
imageSource.createPixelMap(decodingOptions).then((pixelMap: image.PixelMap) => {
|
||||
imageSource.release()
|
||||
this.afterSampling = pixelMap.getPixelBytesNumber()
|
||||
pixelMap.release()
|
||||
}).catch((err: BusinessError) => {
|
||||
imageSource.release()
|
||||
console.error('Failed to create PixelMap')
|
||||
});
|
||||
}
|
||||
|
||||
async originalPixMap(imgs: Resource,) {
|
||||
let img: Uint8Array = await getContext(this).resourceManager.getMediaContent(imgs);
|
||||
let imageSource: image.ImageSource = image.createImageSource(img.buffer.slice(0));
|
||||
let decodingOptions: image.DecodingOptions = {
|
||||
editable: true,
|
||||
desiredPixelFormat: 3,
|
||||
}
|
||||
// 创建pixelMap
|
||||
imageSource.createPixelMap(decodingOptions).then((pixelMap: image.PixelMap) => {
|
||||
imageSource.release()
|
||||
this.beforeSampling = pixelMap.getPixelBytesNumber()
|
||||
pixelMap.release()
|
||||
}).catch((err: BusinessError) => {
|
||||
imageSource.release()
|
||||
console.error('Failed to create PixelMap')
|
||||
});
|
||||
}
|
||||
getResourceString(res:Resource){
|
||||
return getContext().resourceManager.getStringSync(res.id)
|
||||
}
|
||||
build() {
|
||||
Scroll() {
|
||||
Column() {
|
||||
ForEach(this.SamplingList, (item: SamplingType, index) => {
|
||||
Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
|
||||
Radio({ value: item.value + 'radio', group: 'radioGroup' })
|
||||
.height(50)
|
||||
.width(50)
|
||||
.checked(this.checked)
|
||||
.onClick(() => {
|
||||
this.updateImageKnifeOption(item.value)
|
||||
})
|
||||
Text(this.getResourceString($r('app.string.Sampling_pecification'))+ item.value).fontSize(20)
|
||||
}
|
||||
}, (item: SamplingType) => JSON.stringify(item))
|
||||
Column() {
|
||||
Text(`${this.getResourceString($r('app.string.Unreal_samples'))}:${this.beforeSampling}`).fontSize(20)
|
||||
Text(`${ this.getResourceString($r('app.string.After_the_sampling'))}:${this.afterSampling}`).fontSize(20)
|
||||
}
|
||||
|
||||
ImageKnifeComponent({
|
||||
imageKnifeOption: this.imageKnifeOption
|
||||
})
|
||||
.height(px2vp(300))
|
||||
.width(px2vp(300))
|
||||
.borderWidth(1)
|
||||
.borderColor(Color.Pink)
|
||||
}
|
||||
|
||||
}
|
||||
.height('100%')
|
||||
.width('100%')
|
||||
}
|
||||
}
|
||||
|
||||
class SamplingType {
|
||||
key: number
|
||||
value: string
|
||||
|
||||
constructor(key: number, value: string) {
|
||||
this.key = key
|
||||
this.value = value
|
||||
}
|
||||
}
|
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
* Copyright (C) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { ImageKnifeComponent } from '@ohos/libraryimageknife'
|
||||
@Entry
|
||||
@Component
|
||||
struct ErrorMessageDownload {
|
||||
@State httpCode: string = ''
|
||||
@State httpError: string = ''
|
||||
@State storageError: string = ''
|
||||
@State fileError: string = ''
|
||||
@State notPic: string = ''
|
||||
build() {
|
||||
Column() {
|
||||
Text(this.httpCode)
|
||||
ImageKnifeComponent({
|
||||
imageKnifeOption:{
|
||||
loadSrc:'https://gitee.com/openharmony-tpc/ImageKnife/issues/1111111',
|
||||
errorholderSrc:$r('app.media.failed'),
|
||||
onLoadListener:{
|
||||
onLoadFailed:(err)=>{
|
||||
this.httpCode = err
|
||||
}
|
||||
}
|
||||
}
|
||||
}).width(100).height(100).margin({bottom:10})
|
||||
|
||||
Text(this.httpError)
|
||||
ImageKnifeComponent({
|
||||
imageKnifeOption:{
|
||||
loadSrc:'https://xx.xx.xx',
|
||||
errorholderSrc:$r('app.media.failed'),
|
||||
onLoadListener:{
|
||||
onLoadFailed:(err)=>{
|
||||
this.httpError = err
|
||||
}
|
||||
}
|
||||
}
|
||||
}).width(100).height(100).margin({bottom:10})
|
||||
|
||||
Text(this.storageError)
|
||||
ImageKnifeComponent({
|
||||
imageKnifeOption:{
|
||||
loadSrc:'/data/storage/el2/base/haps/entry/cache/a/b',
|
||||
errorholderSrc:$r('app.media.failed'),
|
||||
onLoadListener:{
|
||||
onLoadFailed:(err)=>{
|
||||
this.storageError = err
|
||||
}
|
||||
}
|
||||
}
|
||||
}).width(100).height(100).margin({bottom:10})
|
||||
|
||||
Text(this.fileError)
|
||||
ImageKnifeComponent({
|
||||
imageKnifeOption:{
|
||||
loadSrc:'file://xx.xx.xx',
|
||||
errorholderSrc:$r('app.media.failed'),
|
||||
onLoadListener:{
|
||||
onLoadFailed:(err)=>{
|
||||
this.fileError = err
|
||||
}
|
||||
}
|
||||
}
|
||||
}).width(100).height(100).margin({bottom:10})
|
||||
|
||||
Text(this.notPic)
|
||||
ImageKnifeComponent({
|
||||
imageKnifeOption:{
|
||||
loadSrc:'xx.xx.xx',
|
||||
errorholderSrc:$r('app.media.failed'),
|
||||
onLoadListener:{
|
||||
onLoadFailed:(err)=>{
|
||||
this.notPic = err
|
||||
}
|
||||
}
|
||||
}
|
||||
}).width(100).height(100).margin({bottom:10})
|
||||
}
|
||||
}
|
||||
}
|
|
@ -12,82 +12,91 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { AnimatorOption, ImageKnifeAnimatorComponent,ImageKnifeOption } from "@ohos/libraryimageknife"
|
||||
import { AnimatorOption, ImageKnifeAnimatorComponent, ImageKnifeOption } from '@ohos/libraryimageknife'
|
||||
|
||||
@Entry
|
||||
@ComponentV2
|
||||
@Component
|
||||
struct ImageAnimatorPage {
|
||||
@Local animatorOption: AnimatorOption = new AnimatorOption({
|
||||
@State animatorOption: AnimatorOption = {
|
||||
state: AnimationStatus.Running,
|
||||
iterations: -1,
|
||||
onFinish:()=>{
|
||||
console.log("ImageKnifeAnimatorComponent animatorOption onFinish")
|
||||
onFinish: () => {
|
||||
console.log('ImageKnifeAnimatorComponent animatorOption onFinish')
|
||||
},
|
||||
onStart:()=>{
|
||||
console.log("ImageKnifeAnimatorComponent animatorOption onStart")
|
||||
onStart: () => {
|
||||
console.log('ImageKnifeAnimatorComponent animatorOption onStart')
|
||||
},
|
||||
onPause:()=>{
|
||||
console.log("ImageKnifeAnimatorComponent animatorOption onPause")
|
||||
onPause: () => {
|
||||
console.log('ImageKnifeAnimatorComponent animatorOption onPause')
|
||||
},
|
||||
onCancel:()=>{
|
||||
console.log("ImageKnifeAnimatorComponent animatorOption onCancel")
|
||||
onCancel: () => {
|
||||
console.log('ImageKnifeAnimatorComponent animatorOption onCancel')
|
||||
},
|
||||
onRepeat:()=>{
|
||||
console.log("ImageKnifeAnimatorComponent animatorOption onRepeat")
|
||||
onRepeat: () => {
|
||||
console.log('ImageKnifeAnimatorComponent animatorOption onRepeat')
|
||||
}
|
||||
})
|
||||
@Local animatorOption1: AnimatorOption = new AnimatorOption({
|
||||
}
|
||||
@State animatorOptionFirstFrame: AnimatorOption = {
|
||||
state: AnimationStatus.Initial
|
||||
})
|
||||
@Local animatorOption2: AnimatorOption = new AnimatorOption({
|
||||
}
|
||||
@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(){
|
||||
Flex(){
|
||||
Button("播放").onClick(()=>{
|
||||
Column() {
|
||||
Row() {
|
||||
Button($r('app.string.Play')).onClick(() => {
|
||||
this.animatorOption.state = AnimationStatus.Running
|
||||
})
|
||||
Button("暂停").onClick(()=>{
|
||||
Button($r('app.string.Pause')).onClick(() => {
|
||||
this.animatorOption.state = AnimationStatus.Paused
|
||||
})
|
||||
Button("停止").onClick(()=>{
|
||||
Button($r('app.string.Stop')).onClick(() => {
|
||||
this.animatorOption.state = AnimationStatus.Stopped
|
||||
})
|
||||
Button("无限循环").onClick(()=>{
|
||||
}
|
||||
|
||||
Row() {
|
||||
Button($r('app.string.Infinite_loop')).onClick(() => {
|
||||
this.animatorOption.iterations = -1
|
||||
})
|
||||
Button("播放一次").onClick(()=>{
|
||||
Button($r('app.string.Play_once')).onClick(() => {
|
||||
this.animatorOption.iterations = 1
|
||||
})
|
||||
Button("播放两次").onClick(()=>{
|
||||
Button($r('app.string.Play_twice')).onClick(() => {
|
||||
this.animatorOption.iterations = 2
|
||||
})
|
||||
}
|
||||
|
||||
ImageKnifeAnimatorComponent({
|
||||
imageKnifeOption:new ImageKnifeOption({
|
||||
loadSrc:"https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658",
|
||||
placeholderSrc:$r('app.media.loading'),
|
||||
errorholderSrc:$r('app.media.failed')
|
||||
}),animatorOption:this.animatorOption
|
||||
}).width(200).height(200).backgroundColor(Color.Orange).margin({top:30})
|
||||
Text("动画显示第一帧").fontSize(20)
|
||||
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:new ImageKnifeOption({
|
||||
loadSrc:"https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658",
|
||||
placeholderSrc:$r('app.media.loading'),
|
||||
errorholderSrc:$r('app.media.failed')
|
||||
}),animatorOption:this.animatorOption1
|
||||
}).width(200).height(200).backgroundColor(Color.Orange).margin({top:30})
|
||||
Text("动画显示最后一帧").fontSize(20)
|
||||
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:new ImageKnifeOption({
|
||||
loadSrc:"https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658",
|
||||
placeholderSrc:$r('app.media.loading'),
|
||||
errorholderSrc:$r('app.media.failed')
|
||||
}),animatorOption:this.animatorOption2
|
||||
}).width(200).height(200).backgroundColor(Color.Orange).margin({top:30})
|
||||
}.width("100%").height("100%")
|
||||
imageKnifeOption: this.imageKnifeOption,
|
||||
animatorOption: this.animatorOptionLastFrame
|
||||
}).width(120).height(120).backgroundColor(Color.Orange)
|
||||
}
|
||||
}.margin({ top: 50 }).padding(10)
|
||||
}.width('100%').height('100%')
|
||||
}
|
||||
}
|
|
@ -0,0 +1,99 @@
|
|||
/*
|
||||
* Copyright (C) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { connection } from '@kit.NetworkKit'
|
||||
import { List } from '@kit.ArkTS'
|
||||
import { ImageKnifeRequest,ImageKnife,ImageKnifeComponent } from '@ohos/libraryimageknife'
|
||||
|
||||
@Entry
|
||||
@Component
|
||||
struct ImageKnifeReload {
|
||||
@State index: number = 0
|
||||
aboutToAppear(): void {
|
||||
NetWatchState.init()
|
||||
}
|
||||
build() {
|
||||
Column() {
|
||||
ImageKnifeComponent({
|
||||
imageKnifeOption:{
|
||||
loadSrc:'https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp',
|
||||
placeholderSrc:$r('app.media.loading'),
|
||||
errorholderSrc:$r('app.media.failed'),
|
||||
onLoadListener:{
|
||||
onLoadFailed(err,request){
|
||||
NetWatchState.requestList.add(request)
|
||||
}
|
||||
}
|
||||
}
|
||||
}).width(200).height(200)
|
||||
ImageKnifeComponent({
|
||||
imageKnifeOption:{
|
||||
loadSrc:'https://img-blog.csdn.net/20140514114029140',
|
||||
placeholderSrc:$r('app.media.loading'),
|
||||
errorholderSrc:$r('app.media.failed'),
|
||||
onLoadListener:{
|
||||
onLoadFailed(err,request){
|
||||
NetWatchState.requestList.add(request)
|
||||
}
|
||||
}
|
||||
}
|
||||
}).width(200).height(200).margin({top:10})
|
||||
Text("重试5次:" + this.index)
|
||||
ImageKnifeComponent({
|
||||
imageKnifeOption:{
|
||||
loadSrc:'https://img-blog.csdn.net/20140514114029140',
|
||||
placeholderSrc:$r('app.media.loading'),
|
||||
errorholderSrc:$r('app.media.failed'),
|
||||
onLoadListener:{
|
||||
onLoadFailed:(err,request) => {
|
||||
this.index++
|
||||
if(request != undefined && this.index < 5) {
|
||||
ImageKnife.getInstance().reload(request)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}).width(200).height(200).margin({top:10})
|
||||
}.width('100%')
|
||||
.height('100%')
|
||||
}
|
||||
}
|
||||
|
||||
class NetWatchState {
|
||||
public static netConnection: connection.NetConnection | undefined = undefined
|
||||
public static requestList: List<ImageKnifeRequest> = new List()
|
||||
|
||||
static init() {
|
||||
NetWatchState.netConnection = connection.createNetConnection()
|
||||
// 注册订阅事件
|
||||
NetWatchState.netConnection.register(()=>{
|
||||
})
|
||||
// 订阅网络能力变化事件。调用register后,才能接收到此事件通知
|
||||
NetWatchState.netConnection.on('netCapabilitiesChange',(data:connection.NetCapabilityInfo)=>{
|
||||
if(NetWatchState.requestList.length > 0 && data.netHandle.netId >= 100) {
|
||||
NetWatchState.requestList.forEach((request)=>{
|
||||
ImageKnife.getInstance().reload(request)
|
||||
NetWatchState.requestList.remove(request)
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
static cancel(){
|
||||
if(NetWatchState.netConnection != undefined) {
|
||||
// 取消订阅
|
||||
NetWatchState.netConnection.unregister(()=>{})
|
||||
}
|
||||
}
|
||||
}
|
|
@ -35,17 +35,17 @@ import {
|
|||
import { collections } from '@kit.ArkTS'
|
||||
|
||||
@Entry
|
||||
@ComponentV2
|
||||
@Component
|
||||
struct ImageTransformation {
|
||||
@Local imageKnifeOption: ImageKnifeOption = new ImageKnifeOption({
|
||||
@State imageKnifeOption: ImageKnifeOption = {
|
||||
loadSrc: $r('app.media.pngSample'),
|
||||
placeholderSrc: $r("app.media.loading"),
|
||||
errorholderSrc: $r("app.media.app_icon"),
|
||||
placeholderSrc: $r('app.media.loading'),
|
||||
errorholderSrc: $r('app.media.app_icon'),
|
||||
objectFit: ImageFit.Contain
|
||||
})
|
||||
@Local isRound: boolean = false;
|
||||
@Local isContrast: boolean = false;
|
||||
@Local isRotate: boolean = false;
|
||||
}
|
||||
@State isRound: boolean = false;
|
||||
@State isContrast: boolean = false;
|
||||
@State isRotate: boolean = false;
|
||||
isBlur: boolean = false
|
||||
isBrightness: boolean = false
|
||||
isGrayScale: boolean = false;
|
||||
|
@ -78,7 +78,7 @@ struct ImageTransformation {
|
|||
})
|
||||
.width(30)
|
||||
.height(30)
|
||||
Text('模糊效果').fontSize(20)
|
||||
Text($r('app.string.Blur_effect')).fontSize(20)
|
||||
}
|
||||
|
||||
Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
|
||||
|
@ -91,7 +91,7 @@ struct ImageTransformation {
|
|||
})
|
||||
.width(30)
|
||||
.height(30)
|
||||
Text('高亮效果').fontSize(20)
|
||||
Text($r('app.string.Highlighting_effect')).fontSize(20)
|
||||
}
|
||||
|
||||
Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
|
||||
|
@ -104,7 +104,7 @@ struct ImageTransformation {
|
|||
})
|
||||
.width(30)
|
||||
.height(30)
|
||||
Text('灰化效果').fontSize(20)
|
||||
Text($r('app.string.Ashing_effect')).fontSize(20)
|
||||
}
|
||||
|
||||
Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
|
||||
|
@ -117,7 +117,7 @@ struct ImageTransformation {
|
|||
})
|
||||
.width(30)
|
||||
.height(30)
|
||||
Text('反转效果').fontSize(20)
|
||||
Text($r('app.string.Inverse_effect')).fontSize(20)
|
||||
}
|
||||
|
||||
Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
|
||||
|
@ -130,7 +130,7 @@ struct ImageTransformation {
|
|||
})
|
||||
.width(30)
|
||||
.height(30)
|
||||
Text('动画滤镜效果').fontSize(20)
|
||||
Text($r('app.string.Animation_filter_effect')).fontSize(20)
|
||||
}
|
||||
|
||||
Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
|
||||
|
@ -143,7 +143,7 @@ struct ImageTransformation {
|
|||
})
|
||||
.width(30)
|
||||
.height(30)
|
||||
Text('裁剪圆形效果').fontSize(20)
|
||||
Text($r('app.string.Crop_circular_effect')).fontSize(20)
|
||||
}
|
||||
|
||||
Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
|
||||
|
@ -156,7 +156,7 @@ struct ImageTransformation {
|
|||
})
|
||||
.width(30)
|
||||
.height(30)
|
||||
Text('裁剪圆形带边框效果').fontSize(20)
|
||||
Text($r('app.string.Crop_circular_with_border_effect')).fontSize(20)
|
||||
}
|
||||
|
||||
Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
|
||||
|
@ -168,7 +168,7 @@ struct ImageTransformation {
|
|||
})
|
||||
.width(30)
|
||||
.height(30)
|
||||
Text('对比度效果').fontSize(20)
|
||||
Text($r('app.string.Contrast_effect')).fontSize(20)
|
||||
}
|
||||
|
||||
Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
|
||||
|
@ -181,7 +181,7 @@ struct ImageTransformation {
|
|||
})
|
||||
.width(30)
|
||||
.height(30)
|
||||
Text('乌墨色滤波效果').fontSize(20)
|
||||
Text($r('app.string.Black_ink_filtering_effect')).fontSize(20)
|
||||
}
|
||||
|
||||
Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
|
||||
|
@ -193,7 +193,7 @@ struct ImageTransformation {
|
|||
})
|
||||
.width(30)
|
||||
.height(30)
|
||||
Text('旋转效果').fontSize(20)
|
||||
Text($r('app.string.Rotate')).fontSize(20)
|
||||
}
|
||||
|
||||
Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
|
||||
|
@ -206,7 +206,7 @@ struct ImageTransformation {
|
|||
})
|
||||
.width(30)
|
||||
.height(30)
|
||||
Text('圆角效果').fontSize(20)
|
||||
Text($r('app.string.Corners')).fontSize(20)
|
||||
}
|
||||
|
||||
Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
|
||||
|
@ -219,7 +219,7 @@ struct ImageTransformation {
|
|||
})
|
||||
.width(30)
|
||||
.height(30)
|
||||
Text('桑原滤波效果').fontSize(20)
|
||||
Text($r('app.string.Kuwahara_Filter_effect')).fontSize(20)
|
||||
}
|
||||
|
||||
Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
|
||||
|
@ -232,7 +232,7 @@ struct ImageTransformation {
|
|||
})
|
||||
.width(30)
|
||||
.height(30)
|
||||
Text('像素化滤波效果').fontSize(20)
|
||||
Text($r('app.string.Pixelated_Filter_effect')).fontSize(20)
|
||||
}
|
||||
|
||||
Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
|
||||
|
@ -245,7 +245,7 @@ struct ImageTransformation {
|
|||
})
|
||||
.width(30)
|
||||
.height(30)
|
||||
Text('素描滤波效果').fontSize(20)
|
||||
Text($r('app.string.Sketch_Filter_effect')).fontSize(20)
|
||||
}
|
||||
|
||||
Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
|
||||
|
@ -258,7 +258,7 @@ struct ImageTransformation {
|
|||
})
|
||||
.width(30)
|
||||
.height(30)
|
||||
Text('扭曲滤波效果').fontSize(20)
|
||||
Text($r('app.string.Distortion_Filter_effect')).fontSize(20)
|
||||
}
|
||||
|
||||
Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
|
||||
|
@ -271,7 +271,7 @@ struct ImageTransformation {
|
|||
})
|
||||
.width(30)
|
||||
.height(30)
|
||||
Text('装饰滤波效果').fontSize(20)
|
||||
Text($r('app.string.Decorative_Filter_effect')).fontSize(20)
|
||||
}
|
||||
|
||||
Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
|
||||
|
@ -284,7 +284,7 @@ struct ImageTransformation {
|
|||
})
|
||||
.width(30)
|
||||
.height(30)
|
||||
Text('正方形裁剪效果').fontSize(20)
|
||||
Text($r('app.string.Square_cutting_effect')).fontSize(20)
|
||||
}
|
||||
|
||||
Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
|
||||
|
@ -297,7 +297,7 @@ struct ImageTransformation {
|
|||
})
|
||||
.width(30)
|
||||
.height(30)
|
||||
Text('上方裁剪效果').fontSize(20)
|
||||
Text($r('app.string.Top_cutting_effect')).fontSize(20)
|
||||
}
|
||||
|
||||
Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
|
||||
|
@ -310,7 +310,7 @@ struct ImageTransformation {
|
|||
})
|
||||
.width(30)
|
||||
.height(30)
|
||||
Text('中间裁剪效果').fontSize(20)
|
||||
Text($r('app.string.Middle_cutting_effect')).fontSize(20)
|
||||
}
|
||||
|
||||
Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
|
||||
|
@ -323,7 +323,7 @@ struct ImageTransformation {
|
|||
})
|
||||
.width(30)
|
||||
.height(30)
|
||||
Text('底下裁剪效果').fontSize(20)
|
||||
Text($r('app.string.Bottom_cutting_effect')).fontSize(20)
|
||||
}
|
||||
|
||||
Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
|
||||
|
@ -336,7 +336,7 @@ struct ImageTransformation {
|
|||
})
|
||||
.width(30)
|
||||
.height(30)
|
||||
Text('遮罩效果').fontSize(20)
|
||||
Text($r('app.string.Mask_effect')).fontSize(20)
|
||||
}
|
||||
|
||||
if (this.isContrast) {
|
||||
|
@ -398,13 +398,13 @@ struct ImageTransformation {
|
|||
transformations.push(new CropSquareTransformation());
|
||||
}
|
||||
if (this.isCropTop) {
|
||||
transformations.push(new CropTransformation(25, 25, 0));
|
||||
transformations.push(new CropTransformation(100, 100, 0));
|
||||
}
|
||||
if (this.isCropCenter) {
|
||||
transformations.push(new CropTransformation(25, 25, 1));
|
||||
transformations.push(new CropTransformation(100, 100, 1));
|
||||
}
|
||||
if (this.isCropBottom) {
|
||||
transformations.push(new CropTransformation(25, 25, 2));
|
||||
transformations.push(new CropTransformation(100, 100, 2));
|
||||
}
|
||||
if (this.isSepia) {
|
||||
transformations.push(new SepiaTransformation());
|
||||
|
@ -412,14 +412,14 @@ struct ImageTransformation {
|
|||
if (this.isMask) {
|
||||
transformations.push(new MaskTransformation($r('app.media.mask_starfish')));
|
||||
}
|
||||
this.imageKnifeOption = new ImageKnifeOption({
|
||||
this.imageKnifeOption = {
|
||||
loadSrc: $r('app.media.pngSample'),
|
||||
placeholderSrc: $r("app.media.loading"),
|
||||
errorholderSrc: $r("app.media.app_icon"),
|
||||
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 };
|
||||
|
|
|
@ -15,9 +15,13 @@
|
|||
import router from '@system.router';
|
||||
|
||||
@Entry
|
||||
@ComponentV2
|
||||
@Component
|
||||
struct Index {
|
||||
|
||||
getResourceString(res:Resource){
|
||||
return getContext().resourceManager.getStringSync(res.id)
|
||||
}
|
||||
|
||||
|
||||
aboutToAppear(): void {
|
||||
|
||||
|
@ -26,95 +30,141 @@ struct Index {
|
|||
build() {
|
||||
Scroll(){
|
||||
Column() {
|
||||
Button("测试ImageAnimator组件").onClick(()=>{
|
||||
Button($r('app.string.Test_ImageAnimator')).onClick(()=>{
|
||||
router.push({
|
||||
uri: 'pages/ImageAnimatorPage',
|
||||
});
|
||||
})
|
||||
Button("测试加载多张相同图片").margin({top:10}).onClick(()=>{
|
||||
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("测试HSP场景预加载").margin({top:10}).onClick(()=>{
|
||||
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("单个图片使用").margin({top:10}).onClick(()=>{
|
||||
Button($r('app.string.Test_SingleImage')).margin({top:10}).onClick(()=>{
|
||||
router.push({
|
||||
uri: 'pages/SingleImage',
|
||||
|
||||
});
|
||||
})
|
||||
Button("全局自定义下载").margin({top:10}).onClick(()=>{
|
||||
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("多图 + LazyForEach").margin({top:10}).onClick(()=>{
|
||||
router.push({
|
||||
uri: 'pages/ManyPhotoShowPage',
|
||||
|
||||
});
|
||||
})
|
||||
Button("多图 + reuse + LazyForeach").margin({top:10}).onClick(()=>{
|
||||
Button(this.getResourceString($r('app.string.Multiple_images')) + ' + reuse + LazyForeach').margin({top:10}).onClick(()=>{
|
||||
router.push({
|
||||
uri: 'pages/UserPage',
|
||||
|
||||
});
|
||||
})
|
||||
Button("长图显示").margin({top:10}).onClick(()=>{
|
||||
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("缩放图片").margin({top:10}).onClick(()=>{
|
||||
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("消息+List").margin({top:10}).onClick(()=>{
|
||||
Button(this.getResourceString($r('app.string.Message_list')) + ' + List').margin({top:10}).onClick(()=>{
|
||||
router.push({
|
||||
uri: 'pages/TestImageFlash',
|
||||
|
||||
});
|
||||
})
|
||||
Button("自定义缓存key").margin({top:10}).onClick(()=>{
|
||||
Button($r('app.string.Custom_cache_key')).margin({top:10}).onClick(()=>{
|
||||
router.push({
|
||||
uri: 'pages/SignatureTestPage',
|
||||
|
||||
});
|
||||
})
|
||||
Button("预加载图片到文件缓存").margin({top:10}).onClick(()=>{
|
||||
Button($r('app.string.Preloading_images_to_cache')).margin({top:10}).onClick(()=>{
|
||||
router.push({
|
||||
uri: 'pages/TestPrefetchToFileCache',
|
||||
|
||||
});
|
||||
})
|
||||
Button("从缓存获取图片显示").margin({top:10}).onClick(()=>{
|
||||
Button($r('app.string.Retrieve_image_display_from_cache')).margin({top:10}).onClick(()=>{
|
||||
router.push({
|
||||
uri: 'pages/TestIsUrlExist',
|
||||
|
||||
});
|
||||
})
|
||||
Button("测试单个请求头").margin({top:10}).onClick(()=>{
|
||||
Button($r('app.string.Test_single_request_header')).margin({top:10}).onClick(()=>{
|
||||
router.push({
|
||||
uri: 'pages/TestHeader',
|
||||
|
||||
});
|
||||
})
|
||||
Button("测试写入缓存策略").margin({top:10}).onClick(()=>{
|
||||
Button($r('app.string.Test_write_cache_strategy')).margin({top:10}).onClick(()=>{
|
||||
router.push({
|
||||
uri: 'pages/TestWriteCacheStage',
|
||||
|
||||
});
|
||||
})
|
||||
Button("图片变换").margin({top:10}).onClick(()=>{
|
||||
Button($r('app.string.Image_Transformation')).margin({top:10}).onClick(()=>{
|
||||
router.push({
|
||||
uri: 'pages/ImageTransformation',
|
||||
|
||||
|
@ -122,7 +172,7 @@ struct Index {
|
|||
|
||||
})
|
||||
|
||||
Button("不同的ObjectFit").margin({top:10}).onClick(()=>{
|
||||
Button($r('app.string.Different_ObjectFit')).margin({top:10}).onClick(()=>{
|
||||
router.push({
|
||||
uri: 'pages/ObjectFitPage',
|
||||
|
||||
|
@ -130,30 +180,55 @@ struct Index {
|
|||
|
||||
})
|
||||
|
||||
Button('测试图片加载成功/失败事件').margin({top:10}).onClick(()=>{
|
||||
Button($r('app.string.Test_image_loading_success_or_failure_events')).margin({top:10}).onClick(()=>{
|
||||
router.push({
|
||||
uri: 'pages/LoadStatePage',
|
||||
})
|
||||
})
|
||||
|
||||
Button('测试移除图片缓存接口').margin({top:10}).onClick(()=>{
|
||||
Button($r('app.string.Test_removing_image_cache_interface')).margin({top:10}).onClick(()=>{
|
||||
router.push({
|
||||
uri: 'pages/TestRemoveCache',
|
||||
});
|
||||
})
|
||||
Button("测试错误图显示").margin({top:10}).onClick(()=>{
|
||||
Button($r('app.string.Test_error_image_display')).margin({top:10}).onClick(()=>{
|
||||
router.push({
|
||||
uri: 'pages/TestErrorHolderPage',
|
||||
|
||||
});
|
||||
})
|
||||
Button("测试媒体url").margin({top:10}).onClick(()=>{
|
||||
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%')
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* Copyright (C) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { InfoItem } from './model/DataSourcePrefetching';
|
||||
import { PageViewModel } from './model/PageViewModel';
|
||||
import { ImageKnifeComponent, ImageKnifeOption } from '@ohos/libraryimageknife';
|
||||
import { CommonDataSource } from './model/CommonDataSource';
|
||||
|
||||
@Entry
|
||||
@Component
|
||||
export struct LazyForEachCache {
|
||||
@State hotCommendList:CommonDataSource<InfoItem> = new CommonDataSource<InfoItem>([])
|
||||
aboutToAppear(): void {
|
||||
this.hotCommendList.addData(this.hotCommendList.totalCount(),PageViewModel.getItems())
|
||||
}
|
||||
build() {
|
||||
Column() {
|
||||
List({ space: 16 }) {
|
||||
LazyForEach(this.hotCommendList, (item: InfoItem,index) => {
|
||||
ListItem() {
|
||||
Column({ space: 12 }) {
|
||||
ImageKnifeComponent({
|
||||
imageKnifeOption:{
|
||||
loadSrc: item.albumUrl,
|
||||
placeholderSrc:$r('app.media.loading')
|
||||
}
|
||||
}).width(100).height(100)
|
||||
Text(`${index}`)
|
||||
}.border({ width: 5 , color: '#000000'})
|
||||
}
|
||||
})
|
||||
}
|
||||
.cachedCount(5)
|
||||
.width('100%')
|
||||
.height('100%')
|
||||
.margin({ left: 10, right: 10 })
|
||||
.layoutWeight(1)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* Copyright (C) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { InfoItem } from './model/DataSourcePrefetching';
|
||||
import { PageViewModel } from './model/PageViewModel';
|
||||
import { ImageKnifeComponent, ImageKnifeOption } from '@ohos/libraryimageknife';
|
||||
import { CommonDataSource } from './model/CommonDataSource';
|
||||
|
||||
@Entry
|
||||
@Component
|
||||
export struct LazyForEachCount {
|
||||
@State hotCommendList:CommonDataSource<InfoItem> = new CommonDataSource<InfoItem>([])
|
||||
aboutToAppear(): void {
|
||||
this.hotCommendList.addData(this.hotCommendList.totalCount(),PageViewModel.getItems())
|
||||
}
|
||||
build() {
|
||||
Column() {
|
||||
List({ space: 16 }) {
|
||||
LazyForEach(this.hotCommendList, (item: InfoItem,index) => {
|
||||
ListItem() {
|
||||
Column({ space: 12 }) {
|
||||
ImageKnifeComponent({
|
||||
imageKnifeOption:{
|
||||
loadSrc: item.albumUrl,
|
||||
placeholderSrc:$r('app.media.loading')
|
||||
}
|
||||
}).width(100).height(100)
|
||||
Text(`${index}`)
|
||||
}.border({ width: 5 , color: '#000000'})
|
||||
}
|
||||
})
|
||||
}
|
||||
.cachedCount(30)
|
||||
.width('100%')
|
||||
.height('100%')
|
||||
.margin({ left: 10, right: 10 })
|
||||
.layoutWeight(1)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -15,11 +15,11 @@
|
|||
import { ImageKnifeComponent, ImageKnifeOption } from '@ohos/libraryimageknife';
|
||||
|
||||
@Entry
|
||||
@ComponentV2
|
||||
@Component
|
||||
struct ListPage {
|
||||
|
||||
private data: string[] = []
|
||||
@Local ImageKnifeOption: ImageKnifeOption = new ImageKnifeOption({ loadSrc: $r('app.media.startIcon')})
|
||||
@State ImageKnifeOption: ImageKnifeOption = { loadSrc: $r('app.media.startIcon')}
|
||||
|
||||
|
||||
aboutToAppear(): void {
|
||||
|
|
|
@ -12,59 +12,59 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { ImageKnifeComponent, ImageKnifeOption } from "@ohos/libraryimageknife"
|
||||
import { ImageKnifeComponent, ImageKnifeOption } from '@ohos/libraryimageknife'
|
||||
import matrix4 from '@ohos.matrix4'
|
||||
|
||||
@Entry
|
||||
@ComponentV2
|
||||
@Component
|
||||
struct LoadStatePage {
|
||||
|
||||
starTime:number = new Date().getTime()
|
||||
|
||||
@Local ImageKnifeOption: ImageKnifeOption = new ImageKnifeOption({
|
||||
loadSrc: $r("app.media.rabbit"),
|
||||
placeholderSrc: $r("app.media.loading"),
|
||||
errorholderSrc: $r("app.media.app_icon"),
|
||||
@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);
|
||||
console.error('Load Failed Reason: ' + err);
|
||||
},
|
||||
onLoadSuccess: (data) => {
|
||||
return data;
|
||||
},
|
||||
},
|
||||
border: { radius: 50 }
|
||||
})
|
||||
@Local imageKnifeOption1: ImageKnifeOption = new ImageKnifeOption({
|
||||
}
|
||||
@State imageKnifeOption1: ImageKnifeOption = {
|
||||
loadSrc: $r('app.media.startIcon')
|
||||
})
|
||||
@Local message: string = ""
|
||||
@Local currentWidth: number = 200
|
||||
@Local currentHeight: number = 200
|
||||
@Local typeValue: string = ""
|
||||
}
|
||||
@State message: string = ''
|
||||
@State currentWidth: number = 200
|
||||
@State currentHeight: number = 200
|
||||
@State typeValue: string = ''
|
||||
build() {
|
||||
Column() {
|
||||
Text('测试失败场景请先关闭网络,并保证本地没有此网络图片的缓存')
|
||||
Text($r('app.string.TIPS'))
|
||||
.margin({ top: 20 })
|
||||
Row() {
|
||||
Button('测试失败/成功场景')
|
||||
Button($r('app.string.Test_failure_success'))
|
||||
.onClick(() => {
|
||||
this.ImageKnifeOption = new ImageKnifeOption({
|
||||
loadSrc: "https://www.openharmony.cn/_nuxt/img/logo.dcf95b3.png",
|
||||
placeholderSrc: $r("app.media.loading"),
|
||||
errorholderSrc: $r("app.media.app_icon"),
|
||||
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: ");
|
||||
console.info('Load start: ');
|
||||
},
|
||||
onLoadFailed: (err) => {
|
||||
console.error("Load Failed Reason: " + err + " cost " + (new Date().getTime() - this.starTime) + " milliseconds");
|
||||
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");
|
||||
console.info('Load Successful: cost ' + (new Date().getTime() - this.starTime) + ' milliseconds');
|
||||
this.currentWidth = imageData.imageWidth!
|
||||
this.currentHeight = imageData.imageHeight!
|
||||
this.typeValue = imageData.type!
|
||||
|
@ -73,27 +73,29 @@ struct LoadStatePage {
|
|||
},
|
||||
border: { radius: 50 },
|
||||
onComplete:(event)=>{
|
||||
console.error("Load onComplete width:"+event?.width , " height:"+event?.height , " componentWidth:"+event?.componentWidth," componentHeight:" + event?.componentHeight);
|
||||
console.error('Load onComplete width:'+event?.width , ' height:'+event?.height , ' componentWidth:'+event?.componentWidth,' componentHeight:' + event?.componentHeight);
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
.margin({ top: 20 })
|
||||
Text(this.typeValue)
|
||||
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("自定义下载失败").onClick(()=>{
|
||||
this.imageKnifeOption1 = new ImageKnifeOption({
|
||||
loadSrc: "abc",
|
||||
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
|
||||
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)
|
||||
|
@ -107,8 +109,8 @@ struct LoadStatePage {
|
|||
}
|
||||
// 自定义下载方法
|
||||
@Concurrent
|
||||
async function custom(context: Context, src: string | PixelMap | Resource): Promise<ArrayBuffer | undefined> {
|
||||
console.info("ImageKnife:: custom download:" + src)
|
||||
async function custom(context: Context, src: string | PixelMap | Resource,headers?: Record<string,Object>): Promise<ArrayBuffer | undefined> {
|
||||
console.info('ImageKnife:: custom download:' + src)
|
||||
// 举例写死从本地文件读取,也可以自己请求网络图片
|
||||
return undefined
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
* Copyright (C) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { ImageKnifeComponent } from '@ohos/libraryimageknife';
|
||||
import fs from '@ohos.file.fs';
|
||||
|
||||
@Entry
|
||||
@Component
|
||||
struct LocalImage {
|
||||
scroller: Scroller = new Scroller;
|
||||
localFile: string = getContext(this).filesDir + '/icon.png'
|
||||
|
||||
aboutToAppear(): void {
|
||||
// 拷贝本地文件
|
||||
let icon: Uint8Array = getContext(this).resourceManager.getMediaContentSync($r('app.media.startIcon'));
|
||||
let file = fs.openSync(this.localFile, fs.OpenMode.CREATE | fs.OpenMode.READ_WRITE);
|
||||
fs.writeSync(file.fd, icon.buffer);
|
||||
fs.fsyncSync(file.fd);
|
||||
fs.closeSync(file);
|
||||
}
|
||||
|
||||
build() {
|
||||
Scroll(this.scroller) {
|
||||
Column() {
|
||||
Text($r('app.string.local_r_file'))
|
||||
.fontSize(30)
|
||||
.fontWeight(FontWeight.Bold)
|
||||
ImageKnifeComponent({
|
||||
imageKnifeOption: {
|
||||
loadSrc: $r('app.media.startIcon'),
|
||||
objectFit: ImageFit.Contain
|
||||
}
|
||||
}).width(100).height(100)
|
||||
Text($r('app.string.local_rawfile'))
|
||||
.fontSize(30)
|
||||
.fontWeight(FontWeight.Bold)
|
||||
ImageKnifeComponent({
|
||||
imageKnifeOption: {
|
||||
loadSrc: $rawfile('image/startIcon.png'),
|
||||
objectFit: ImageFit.Contain
|
||||
}
|
||||
}).width(100).height(100)
|
||||
Text($r('app.string.Under_context_file'))
|
||||
.fontSize(30)
|
||||
.fontWeight(FontWeight.Bold)
|
||||
ImageKnifeComponent({
|
||||
imageKnifeOption: {
|
||||
loadSrc: this.localFile,
|
||||
objectFit: ImageFit.Contain
|
||||
}
|
||||
}).width(100).height(100)
|
||||
Text($r('app.string.local_other_module'))
|
||||
.fontSize(30)
|
||||
.fontWeight(FontWeight.Bold)
|
||||
ImageKnifeComponent({
|
||||
imageKnifeOption: {
|
||||
loadSrc: $r('[sharedlibrary].media.startIcon'),
|
||||
objectFit: ImageFit.Contain
|
||||
}
|
||||
}).width(100).height(100)
|
||||
}
|
||||
.width('100%')
|
||||
}
|
||||
.height('100%')
|
||||
}
|
||||
}
|
||||
|
|
@ -12,26 +12,30 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { ImageKnifeComponent,ImageKnifeOption } from '@ohos/libraryimageknife'
|
||||
import { ImageKnifeComponent } from '@ohos/libraryimageknife'
|
||||
|
||||
@Entry
|
||||
@ComponentV2
|
||||
@Component
|
||||
struct LongImagePage {
|
||||
|
||||
build() {
|
||||
Scroll() {
|
||||
|
||||
// Image("https://wx2.sinaimg.cn/mw690/006HyQKGgy1hnqp08dw09j30u04twu0x.jpg").objectFit(ImageFit.Auto).height(300)
|
||||
// Image('https://wx2.sinaimg.cn/mw690/006HyQKGgy1hnqp08dw09j30u04twu0x.jpg').objectFit(ImageFit.Auto).height(300)
|
||||
|
||||
// Image($r("app.media.aaa")).objectFit(ImageFit.Auto).width(200)
|
||||
// Image($r('app.media.aaa')).objectFit(ImageFit.Auto).width(200)
|
||||
ImageKnifeComponent({
|
||||
imageKnifeOption: new ImageKnifeOption({
|
||||
loadSrc:"https://wx2.sinaimg.cn/mw690/006HyQKGgy1hnqp08dw09j30u04twu0x.jpg",
|
||||
//src:$r("app.media.aaa"),
|
||||
placeholderSrc: $r("app.media.loading"),
|
||||
errorholderSrc: $r("app.media.failed"),
|
||||
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%')
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Copyright (C) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { ImageKnifeComponent,ImageKnife } from '@ohos/libraryimageknife';
|
||||
import { CommonDataSource } from './model/CommonDataSource';
|
||||
|
||||
@Entry
|
||||
@Component
|
||||
struct MaxRequest1 {
|
||||
@State hotCommendList:CommonDataSource<string> = new CommonDataSource<string>([])
|
||||
private data: Array<string> = []
|
||||
aboutToAppear(): void {
|
||||
ImageKnife.getInstance().setMaxRequests(8)
|
||||
for (let index = 0; index < 200; index++) {
|
||||
this.data.push(`https://img-blog.csdn.net/20140514114029140?${index}`)
|
||||
}
|
||||
this.hotCommendList.addData(this.hotCommendList.totalCount(),this.data)
|
||||
}
|
||||
build() {
|
||||
Column() {
|
||||
WaterFlow() {
|
||||
LazyForEach(this.hotCommendList,(item: string)=>{
|
||||
FlowItem() {
|
||||
Column(){
|
||||
ImageKnifeComponent({
|
||||
imageKnifeOption: {
|
||||
loadSrc: item,
|
||||
placeholderSrc: $r('app.media.loading'),
|
||||
errorholderSrc: $r('app.media.failed'),
|
||||
}
|
||||
}).width('50%').height(160)
|
||||
}
|
||||
}.height(200)
|
||||
.backgroundColor('#95efd2')
|
||||
},(item: string) => item)
|
||||
}.columnsTemplate('1fr 1fr')
|
||||
.cachedCount(8)
|
||||
.columnsGap(10)
|
||||
.rowsGap(5)
|
||||
.backgroundColor(0xFAEEE0)
|
||||
.width('100%').height('100%')
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Copyright (C) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { ImageKnifeComponent,ImageKnife } from '@ohos/libraryimageknife';
|
||||
import { CommonDataSource } from './model/CommonDataSource';
|
||||
|
||||
@Entry
|
||||
@Component
|
||||
struct MaxRequest2 {
|
||||
@State hotCommendList:CommonDataSource<string> = new CommonDataSource<string>([])
|
||||
private data: Array<string> = []
|
||||
aboutToAppear(): void {
|
||||
ImageKnife.getInstance().setMaxRequests(20)
|
||||
for (let index = 200; index < 400; index++) {
|
||||
this.data.push(`https://img-blog.csdn.net/20140514114029140?${index}`)
|
||||
}
|
||||
this.hotCommendList.addData(this.hotCommendList.totalCount(),this.data)
|
||||
}
|
||||
build() {
|
||||
Column() {
|
||||
WaterFlow() {
|
||||
LazyForEach(this.hotCommendList,(item: string)=>{
|
||||
FlowItem() {
|
||||
Column(){
|
||||
ImageKnifeComponent({
|
||||
imageKnifeOption: {
|
||||
loadSrc: item,
|
||||
placeholderSrc: $r('app.media.loading'),
|
||||
errorholderSrc: $r('app.media.failed'),
|
||||
}
|
||||
}).width('50%').height(160)
|
||||
}
|
||||
}.height(200)
|
||||
.backgroundColor('#95efd2')
|
||||
},(item: string) => item)
|
||||
}.columnsTemplate('1fr 1fr')
|
||||
.cachedCount(20)
|
||||
.columnsGap(10)
|
||||
.rowsGap(5)
|
||||
.backgroundColor(0xFAEEE0)
|
||||
.width('100%').height('100%')
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Copyright (C) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { ImageKnifeComponent,ImageKnife } from '@ohos/libraryimageknife';
|
||||
import { CommonDataSource } from './model/CommonDataSource';
|
||||
|
||||
@Entry
|
||||
@Component
|
||||
struct MaxRequest3 {
|
||||
@State hotCommendList:CommonDataSource<string> = new CommonDataSource<string>([])
|
||||
private data: Array<string> = []
|
||||
aboutToAppear(): void {
|
||||
ImageKnife.getInstance().setMaxRequests(32)
|
||||
for (let index = 400; index < 600; index++) {
|
||||
this.data.push(`https://img-blog.csdn.net/20140514114029140?${index}`)
|
||||
}
|
||||
this.hotCommendList.addData(this.hotCommendList.totalCount(),this.data)
|
||||
}
|
||||
build() {
|
||||
Column() {
|
||||
WaterFlow() {
|
||||
LazyForEach(this.hotCommendList,(item: string)=>{
|
||||
FlowItem() {
|
||||
Column(){
|
||||
ImageKnifeComponent({
|
||||
imageKnifeOption: {
|
||||
loadSrc: item,
|
||||
placeholderSrc: $r('app.media.loading'),
|
||||
errorholderSrc: $r('app.media.failed'),
|
||||
}
|
||||
}).width('50%').height(160)
|
||||
}
|
||||
}.height(200)
|
||||
.backgroundColor('#95efd2')
|
||||
},(item: string) => item)
|
||||
}.columnsTemplate('1fr 1fr')
|
||||
.cachedCount(40)
|
||||
.columnsGap(10)
|
||||
.rowsGap(5)
|
||||
.backgroundColor(0xFAEEE0)
|
||||
.width('100%').height('100%')
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,151 @@
|
|||
/*
|
||||
* Copyright (C) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { ImageKnifeComponent,ImageKnifeOption } from '@ohos/libraryimageknife';
|
||||
import { CommonDataSource } from './model/CommonDataSource'
|
||||
|
||||
@Entry
|
||||
@Component
|
||||
struct MultipleImageCallBack {
|
||||
@State hotCommendList: CommonDataSource<string> = new CommonDataSource<string>([])
|
||||
@State componentIndex: number = 0
|
||||
@State startIndex: number = 0
|
||||
@State successIndex: number = 0
|
||||
@State failIndex: number = 0
|
||||
@State cancelJobIndex: number = 0
|
||||
@State cancelLoadIndex: number = 0
|
||||
@State memoryIndex: number = 0
|
||||
@State fileCacheIndex: number = 0
|
||||
@State netIndex: number = 0
|
||||
@State checkText: string = ''
|
||||
private data: Array<string> = []
|
||||
|
||||
aboutToAppear(): void {
|
||||
for (let index = 0; index < 100; index++) {
|
||||
this.data.push(`https://img-blog.csdn.net/20140514114029140?${index}`)
|
||||
}
|
||||
this.hotCommendList.addData(this.hotCommendList.totalCount(), this.data)
|
||||
}
|
||||
|
||||
build() {
|
||||
Column() {
|
||||
Row() {
|
||||
Column() {
|
||||
Text('图片总数:' + this.componentIndex)
|
||||
Text('开始回调:' + this.startIndex)
|
||||
Text('成功回调:' + this.successIndex)
|
||||
Text('失败回调:' + this.failIndex)
|
||||
Text('队列取消回调:' + this.cancelJobIndex)
|
||||
Text('加载取消回调:' + this.cancelLoadIndex)
|
||||
Text('内存数量:' + this.memoryIndex)
|
||||
Text('文件数量:' + this.fileCacheIndex)
|
||||
Text('网络数量:' + this.netIndex)
|
||||
}.width('50%')
|
||||
Column() {
|
||||
Button('check')
|
||||
.onClick(()=>{
|
||||
this.checkText = ''
|
||||
if (this.componentIndex !== this.startIndex + this.cancelJobIndex) {
|
||||
this.checkText = this.checkText + '图片总数!=开始+队列取消,'
|
||||
}
|
||||
if(this.startIndex !== this.successIndex + this.failIndex + this.cancelLoadIndex) {
|
||||
this.checkText = this.checkText + '开始回调!=成功+失败+加载取消,'
|
||||
}
|
||||
if(this.successIndex !== this.memoryIndex + this.fileCacheIndex + this.netIndex) {
|
||||
this.checkText = this.checkText + '成功回调!=内存+文件+网络,'
|
||||
}
|
||||
if(this.componentIndex !== this.successIndex + this.failIndex + this.cancelJobIndex + this.cancelLoadIndex) {
|
||||
this.checkText = this.checkText + '图片总数!=成功+失败+加载取消+队列取消,'
|
||||
}
|
||||
if(this.checkText == '') {
|
||||
this.checkText = 'check正确'
|
||||
}
|
||||
})
|
||||
Text(this.checkText)
|
||||
}.width('50%')
|
||||
}.width('100%')
|
||||
Column() {
|
||||
WaterFlow() {
|
||||
LazyForEach(this.hotCommendList, (item: string,index: number) => {
|
||||
FlowItem() {
|
||||
Column() {
|
||||
Text(index + '')
|
||||
ImageComponent({
|
||||
imageKnifeOption: {
|
||||
loadSrc: item,
|
||||
placeholderSrc: $r('app.media.loading'),
|
||||
errorholderSrc: $r('app.media.failed'),
|
||||
onLoadListener: {
|
||||
onLoadStart:()=>{
|
||||
this.startIndex++
|
||||
console.log('image load multiple loadStart:' + this.startIndex)
|
||||
},
|
||||
onLoadSuccess:(pixelmap,imageData,request)=>{
|
||||
this.successIndex++
|
||||
let memory = request?.imageKnifeData?.timeInfo?.memoryCheckEndTime ? 1 : 0
|
||||
let fileCache = request?.imageKnifeData?.timeInfo?.diskCheckEndTime ? 1 : 0
|
||||
let net = request?.imageKnifeData?.timeInfo?.netRequestEndTime ? 1 : 0
|
||||
memory = memory - fileCache
|
||||
fileCache = fileCache - net
|
||||
this.memoryIndex = this.memoryIndex + memory
|
||||
this.fileCacheIndex = this.fileCacheIndex + fileCache
|
||||
this.netIndex = this.netIndex + net
|
||||
console.log('image load multiple loadSuccess:' + this.successIndex)
|
||||
},
|
||||
onLoadFailed:()=>{
|
||||
this.failIndex++
|
||||
console.log('image load multiple loadFail:' + this.failIndex)
|
||||
},
|
||||
onLoadCancel:(message,request)=>{
|
||||
let flag = request?.imageKnifeData?.timeInfo?.netRequestStartTime ? true : false
|
||||
if (flag) {
|
||||
this.cancelLoadIndex++
|
||||
} else {
|
||||
this.cancelJobIndex++
|
||||
}
|
||||
console.log('image load multiple cancelJobIndex:' + this.cancelJobIndex,'cancelLoadIndex' + this.cancelLoadIndex)
|
||||
}
|
||||
}
|
||||
},index:this.componentIndex
|
||||
}).width('50%').height(160)
|
||||
}
|
||||
}.height(200)
|
||||
.backgroundColor('#95efd2')
|
||||
}, (item: string) => item)
|
||||
}
|
||||
.cachedCount(0)
|
||||
.columnsTemplate('1fr 1fr')
|
||||
.columnsGap(10)
|
||||
.rowsGap(5)
|
||||
.backgroundColor(0xFAEEE0)
|
||||
.width('100%')
|
||||
}
|
||||
.height('80%')
|
||||
}.width('100%')
|
||||
.height('100%')
|
||||
}
|
||||
}
|
||||
@Component
|
||||
struct ImageComponent {
|
||||
@State imageKnifeOption: ImageKnifeOption = new ImageKnifeOption()
|
||||
@Link index: number
|
||||
aboutToAppear(): void {
|
||||
this.index++
|
||||
}
|
||||
build() {
|
||||
ImageKnifeComponent({
|
||||
imageKnifeOption: this.imageKnifeOption
|
||||
})
|
||||
}
|
||||
}
|
|
@ -15,49 +15,49 @@
|
|||
import { ImageKnife, ImageKnifeComponent, ImageKnifeOption } from '@ohos/libraryimageknife'
|
||||
|
||||
@Entry
|
||||
@ComponentV2
|
||||
@Component
|
||||
struct ObjectFitPage {
|
||||
@Local imageKnifeOption: ImageKnifeOption = new ImageKnifeOption({
|
||||
loadSrc: $r("app.media.app_icon"),
|
||||
placeholderSrc: $r("app.media.loading"),
|
||||
errorholderSrc: $r("app.media.app_icon"),
|
||||
@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("主图Fill拉伸填充").onClick(()=>{
|
||||
this.imageKnifeOption = new ImageKnifeOption({
|
||||
loadSrc: $r("app.media.app_icon"),
|
||||
placeholderSrc: $r("app.media.loading"),
|
||||
errorholderSrc: $r("app.media.app_icon"),
|
||||
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("占位图Contain保持比例填充").margin({top:10}).onClick(async () => {
|
||||
Button($r('app.string.Maintain_proportion_filling')).margin({top:10}).onClick(async () => {
|
||||
ImageKnife.getInstance().removeAllMemoryCache()
|
||||
await ImageKnife.getInstance().removeAllFileCache()
|
||||
|
||||
this.imageKnifeOption = new ImageKnifeOption({
|
||||
loadSrc: "https://wx2.sinaimg.cn/mw690/006HyQKGgy1hnqp08dw09j30u04twu0x.jpg",
|
||||
placeholderSrc: $r("app.media.app_icon"),
|
||||
errorholderSrc: $r("app.media.app_icon"),
|
||||
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("错误图None不变化").margin({top:10}).onClick(() => {
|
||||
this.imageKnifeOption = new ImageKnifeOption({
|
||||
loadSrc: "http://xxxxx",
|
||||
placeholderSrc: $r("app.media.loading"),
|
||||
errorholderSrc: $r("app.media.app_icon"),
|
||||
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({
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright (C) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { router } from '@kit.ArkUI'
|
||||
|
||||
@Entry
|
||||
@Component
|
||||
struct PrefetchAndCacheCount {
|
||||
build() {
|
||||
Column() {
|
||||
Button('cacheCount == 5')
|
||||
.onClick(()=>{
|
||||
router.pushUrl({url:'pages/LazyForEachCache'})
|
||||
})
|
||||
Button('cacheCount == 30')
|
||||
.margin({top:10})
|
||||
.onClick(()=>{
|
||||
router.pushUrl({url:'pages/LazyForEachCount'})
|
||||
})
|
||||
Button('prefetch + preload')
|
||||
.margin({top:10})
|
||||
.onClick(()=>{
|
||||
router.pushUrl({url:'pages/PrefetchAndPreload'})
|
||||
})
|
||||
}.width('100%')
|
||||
.height('100%')
|
||||
}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Copyright (C) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { BasicPrefetcher } from '@kit.ArkUI';
|
||||
import DataSourcePrefetchingImageKnife, { InfoItem } from './model/DataSourcePrefetching';
|
||||
import { PageViewModel } from './model/PageViewModel';
|
||||
import { ImageKnifeComponent, ImageKnifeOption } from '@ohos/libraryimageknife';
|
||||
@Entry
|
||||
@Component
|
||||
export struct PrefetchAndPreload {
|
||||
// 创建DataSourcePrefetchingImageKnife对象,具备任务预取、取消能力的数据源
|
||||
private readonly dataSource = new DataSourcePrefetchingImageKnife(PageViewModel.getItems());
|
||||
// 创建BasicPrefetcher对象,默认的动态预取算法实现
|
||||
private readonly prefetcher = new BasicPrefetcher(this.dataSource);
|
||||
|
||||
build() {
|
||||
Column() {
|
||||
List({ space: 16 }) {
|
||||
LazyForEach(this.dataSource, (item: InfoItem,index:number) => {
|
||||
ListItem() {
|
||||
Column({ space: 12 }) {
|
||||
ImageKnifeComponent({
|
||||
imageKnifeOption:{
|
||||
loadSrc: item.albumUrl,
|
||||
placeholderSrc:$r('app.media.loading')
|
||||
}
|
||||
}).width(100).height(100)
|
||||
Text(`${index}`)
|
||||
}.border({ width: 5 , color: '#000000'})
|
||||
}
|
||||
.reuseId('imageKnife')
|
||||
})
|
||||
}
|
||||
.cachedCount(5)
|
||||
.onScrollIndex((start: number, end: number) => {
|
||||
// 列表滚动触发visibleAreaChanged,实时更新预取范围,触发调用prefetch、cancel接口
|
||||
this.prefetcher.visibleAreaChanged(start, end)
|
||||
})
|
||||
.width('100%')
|
||||
.height('100%')
|
||||
.margin({ left: 10, right: 10 })
|
||||
.layoutWeight(1)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Copyright (C) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { router } from '@kit.ArkUI'
|
||||
|
||||
@Entry
|
||||
@Component
|
||||
struct SetMaxRequestPage {
|
||||
build() {
|
||||
Column() {
|
||||
Button('maxRequest = 8')
|
||||
.onClick(()=>{
|
||||
router.pushUrl({url:'pages/MaxRequest1'})
|
||||
})
|
||||
Button('maxRequest = 20')
|
||||
.onClick(()=>{
|
||||
router.pushUrl({url:'pages/MaxRequest2'})
|
||||
}).margin({top:20})
|
||||
Button('maxRequest = 32')
|
||||
.onClick(()=>{
|
||||
router.pushUrl({url:'pages/MaxRequest2'})
|
||||
}).margin({top:20})
|
||||
}.width('100%')
|
||||
.height('100%')
|
||||
}
|
||||
}
|
|
@ -1,13 +1,13 @@
|
|||
/*
|
||||
* Copyright (C) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
|
@ -16,45 +16,45 @@ import { ImageKnifeComponent, ImageKnifeOption } from '@ohos/libraryimageknife';
|
|||
|
||||
|
||||
@Entry
|
||||
@ComponentV2
|
||||
@Component
|
||||
struct SignatureTestPage {
|
||||
@Local imageKnifeOption1: ImageKnifeOption =new ImageKnifeOption(
|
||||
@State imageKnifeOption1: ImageKnifeOption =
|
||||
{
|
||||
loadSrc: $r('app.media.icon'),
|
||||
placeholderSrc:$r("app.media.loading"),
|
||||
});
|
||||
@Local imageKnifeOption2: ImageKnifeOption =new ImageKnifeOption(
|
||||
placeholderSrc:$r('app.media.loading'),
|
||||
};
|
||||
@State imageKnifeOption2: ImageKnifeOption =
|
||||
{
|
||||
loadSrc: $r('app.media.icon'),
|
||||
placeholderSrc:$r("app.media.loading"),
|
||||
});
|
||||
placeholderSrc:$r('app.media.loading'),
|
||||
};
|
||||
|
||||
build() {
|
||||
Scroll() {
|
||||
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
||||
|
||||
Text("key固定为 1").fontSize(15)
|
||||
Text($r('app.string.The_key_fixed_1')).fontSize(15)
|
||||
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
||||
Button("加载")
|
||||
Button($r('app.string.Load'))
|
||||
.onClick(() => {
|
||||
this.imageKnifeOption1 = new ImageKnifeOption({
|
||||
this.imageKnifeOption1 = {
|
||||
loadSrc: 'https://img-blog.csdn.net/20140514114029140',
|
||||
placeholderSrc:$r("app.media.loading"),
|
||||
signature: "1"
|
||||
})
|
||||
placeholderSrc:$r('app.media.loading'),
|
||||
signature: '1'
|
||||
}
|
||||
}).margin({ top: 5, left: 3 })
|
||||
ImageKnifeComponent({ imageKnifeOption: this.imageKnifeOption1 }).width(300).height(300)
|
||||
}.width('100%').backgroundColor(Color.Pink)
|
||||
|
||||
Text("key每次变化:时间戳").fontSize(15)
|
||||
Text($r('app.string.The_key_changes_timestamp')).fontSize(15)
|
||||
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
||||
Button("加载")
|
||||
Button($r('app.string.Load'))
|
||||
.onClick(() => {
|
||||
this.imageKnifeOption2 = new ImageKnifeOption({
|
||||
this.imageKnifeOption2 = {
|
||||
loadSrc: 'https://img-blog.csdn.net/20140514114029140',
|
||||
placeholderSrc:$r("app.media.loading"),
|
||||
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)
|
||||
|
@ -66,7 +66,7 @@ struct SignatureTestPage {
|
|||
}
|
||||
|
||||
aboutToAppear() {
|
||||
console.log("唯一标识页面:" + new Date().getTime().toString())
|
||||
console.log('唯一标识页面:' + new Date().getTime().toString())
|
||||
|
||||
}
|
||||
}
|
|
@ -12,28 +12,28 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { ImageKnifeComponent,BlurTransformation,ImageKnifeOption } from '@ohos/libraryimageknife';
|
||||
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
|
||||
@ComponentV2
|
||||
@Component
|
||||
struct SingleImage {
|
||||
resource: string = "app.media.svgSample"
|
||||
resource: string = 'app.media.svgSample'
|
||||
scroller: Scroller = new Scroller;
|
||||
localFile: string = getContext(this).filesDir + "/icon.png"
|
||||
@Local pixelMap:PixelMap | undefined = undefined;
|
||||
@Local DrawingColorFilter: ColorFilter | undefined = undefined
|
||||
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 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"))
|
||||
this.changePic(getContext().resourceManager.getMediaContentSync( $r('app.media.aaa'))
|
||||
.buffer as ArrayBuffer);
|
||||
|
||||
|
||||
|
@ -42,66 +42,80 @@ struct SingleImage {
|
|||
build() {
|
||||
Scroll(this.scroller) {
|
||||
Column() {
|
||||
Text("本地资源svg图片")
|
||||
Text($r('app.string.Local_SVG'))
|
||||
.fontSize(30)
|
||||
.fontWeight(FontWeight.Bold)
|
||||
ImageKnifeComponent({
|
||||
imageKnifeOption: new ImageKnifeOption({
|
||||
loadSrc: $r("app.media.svgSample"),
|
||||
placeholderSrc: $r("app.media.loading"),
|
||||
errorholderSrc: $r("app.media.failed"),
|
||||
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);
|
||||
})
|
||||
Text("本地context files下文件")
|
||||
.fontSize(30)
|
||||
.fontWeight(FontWeight.Bold)
|
||||
ImageKnifeComponent({
|
||||
imageKnifeOption: new ImageKnifeOption({
|
||||
loadSrc: this.localFile,
|
||||
placeholderSrc: $r("app.media.loading"),
|
||||
errorholderSrc: $r("app.media.failed"),
|
||||
imageKnifeOption: {
|
||||
loadSrc: $r('[sharedlibrary].media.pngSample'),
|
||||
placeholderSrc: $r('app.media.loading'),
|
||||
errorholderSrc: $r('app.media.failed'),
|
||||
objectFit: ImageFit.Contain
|
||||
})
|
||||
}
|
||||
}).width(100).height(100)
|
||||
Text("网络图片")
|
||||
Text($r('app.string.Under_context_file'))
|
||||
.fontSize(30)
|
||||
.fontWeight(FontWeight.Bold)
|
||||
ImageKnifeComponent({
|
||||
imageKnifeOption: new 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)}
|
||||
})
|
||||
imageKnifeOption: {
|
||||
loadSrc: this.localFile,
|
||||
placeholderSrc: $r('app.media.loading'),
|
||||
errorholderSrc: $r('app.media.failed'),
|
||||
objectFit: ImageFit.Contain
|
||||
}
|
||||
}).width(100).height(100)
|
||||
Text("自定义下载")
|
||||
Text($r('app.string.Network_images'))
|
||||
.fontSize(30)
|
||||
.fontWeight(FontWeight.Bold)
|
||||
ImageKnifeComponent({
|
||||
imageKnifeOption: new ImageKnifeOption({
|
||||
loadSrc: "https://file.atomgit.com/uploads/user/1704857786989_8994.jpeg",
|
||||
placeholderSrc: $r("app.media.loading"),
|
||||
errorholderSrc: $r("app.media.failed"),
|
||||
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("pixelMap加载图片")
|
||||
Text($r('app.string.PixelMap_loads_images'))
|
||||
.fontSize(30)
|
||||
.fontWeight(FontWeight.Bold)
|
||||
ImageKnifeComponent({
|
||||
imageKnifeOption: new ImageKnifeOption({
|
||||
imageKnifeOption: {
|
||||
loadSrc: this.pixelMap!,
|
||||
placeholderSrc: $r("app.media.loading"),
|
||||
errorholderSrc: $r("app.media.failed"),
|
||||
placeholderSrc: $r('app.media.loading'),
|
||||
errorholderSrc: $r('app.media.failed'),
|
||||
objectFit: ImageFit.Contain,
|
||||
})
|
||||
}
|
||||
}).width(100).height(100)
|
||||
}
|
||||
.width('100%')
|
||||
|
@ -116,6 +130,7 @@ struct SingleImage {
|
|||
editable: true,
|
||||
}
|
||||
imageSource.createPixelMap(decodingOptions,(err,pixelMap)=>{
|
||||
imageSource.release()
|
||||
this.pixelMap = pixelMap;
|
||||
})
|
||||
}
|
||||
|
@ -124,9 +139,11 @@ struct SingleImage {
|
|||
|
||||
// 自定义下载方法
|
||||
@Concurrent
|
||||
async function custom(context: Context, src: string | PixelMap | Resource): Promise<ArrayBuffer | undefined> {
|
||||
console.info("ImageKnife:: custom download:" + src)
|
||||
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)
|
||||
// 举例写死从本地文件读取,也可以自己请求网络图片
|
||||
return context.resourceManager.getMediaContentSync($r("app.media.startIcon").id).buffer as ArrayBuffer
|
||||
let buffer = context.resourceManager.getMediaContentSync($r('app.media.startIcon').id).buffer as ArrayBuffer
|
||||
return buffer
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,126 @@
|
|||
/*
|
||||
* Copyright (C) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { ImageKnifeComponent,ImageKnifeOption } from '@ohos/libraryimageknife';
|
||||
import { CommonDataSource } from './model/CommonDataSource'
|
||||
|
||||
@Entry
|
||||
@Component
|
||||
struct SingleImageCallBack {
|
||||
@State hotCommendList: CommonDataSource<string> = new CommonDataSource<string>([])
|
||||
@State componentIndex: number = 0
|
||||
@State startIndex: number = 0
|
||||
@State successIndex: number = 0
|
||||
@State failIndex: number = 0
|
||||
@State cancelJobIndex: number = 0
|
||||
@State cancelLoadIndex: number = 0
|
||||
@State memoryIndex: number = 0
|
||||
@State fileCacheIndex: number = 0
|
||||
@State netIndex: number = 0
|
||||
@State checkText: string = ''
|
||||
build() {
|
||||
Column() {
|
||||
Row() {
|
||||
Column() {
|
||||
Text('图片总数:' + this.componentIndex)
|
||||
Text('开始回调:' + this.startIndex)
|
||||
Text('成功回调:' + this.successIndex)
|
||||
Text('失败回调:' + this.failIndex)
|
||||
Text('队列取消回调:' + this.cancelJobIndex)
|
||||
Text('加载取消回调:' + this.cancelLoadIndex)
|
||||
Text('内存数量:' + this.memoryIndex)
|
||||
Text('文件数量:' + this.fileCacheIndex)
|
||||
Text('网络数量:' + this.netIndex)
|
||||
}.width('50%')
|
||||
Column() {
|
||||
Button('check')
|
||||
.onClick(()=>{
|
||||
this.checkText = ''
|
||||
if (this.componentIndex !== this.startIndex + this.cancelJobIndex) {
|
||||
this.checkText = this.checkText + '图片总数!=开始+队列取消,'
|
||||
}
|
||||
if(this.startIndex !== this.successIndex + this.failIndex + this.cancelLoadIndex) {
|
||||
this.checkText = this.checkText + '开始回调!=成功+失败+加载取消,'
|
||||
}
|
||||
if(this.successIndex !== this.memoryIndex + this.fileCacheIndex + this.netIndex) {
|
||||
this.checkText = this.checkText + '成功回调!=内存+文件+网络,'
|
||||
}
|
||||
if(this.componentIndex !== this.successIndex + this.failIndex + this.cancelJobIndex + this.cancelLoadIndex) {
|
||||
this.checkText = this.checkText + '图片总数!=成功+失败+加载取消+队列取消,'
|
||||
}
|
||||
if(this.checkText == '') {
|
||||
this.checkText = 'check正确'
|
||||
}
|
||||
})
|
||||
Text(this.checkText)
|
||||
}.width('50%')
|
||||
}.width('100%')
|
||||
Column() {
|
||||
ImageComponent({
|
||||
imageKnifeOption: {
|
||||
loadSrc: 'https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp',
|
||||
placeholderSrc: $r('app.media.loading'),
|
||||
errorholderSrc: $r('app.media.failed'),
|
||||
onLoadListener: {
|
||||
onLoadStart: () => {
|
||||
this.startIndex++
|
||||
console.log('image load multiple loadStart:' + this.startIndex)
|
||||
},
|
||||
onLoadSuccess: (pixelmap, imageData, request) => {
|
||||
this.successIndex++
|
||||
let memory = request?.imageKnifeData?.timeInfo?.memoryCheckEndTime ? 1 : 0
|
||||
let fileCache = request?.imageKnifeData?.timeInfo?.diskCheckEndTime ? 1 : 0
|
||||
let net = request?.imageKnifeData?.timeInfo?.netRequestEndTime ? 1 : 0
|
||||
memory = memory - fileCache
|
||||
fileCache = fileCache - net
|
||||
this.memoryIndex = this.memoryIndex + memory
|
||||
this.fileCacheIndex = this.fileCacheIndex + fileCache
|
||||
this.netIndex = this.netIndex + net
|
||||
console.log('image load multiple loadSuccess:' + this.successIndex)
|
||||
},
|
||||
onLoadFailed: () => {
|
||||
this.failIndex++
|
||||
console.log('image load multiple loadFail:' + this.failIndex)
|
||||
},
|
||||
onLoadCancel: (message,request) => {
|
||||
let flag = request?.imageKnifeData?.type ? true : false
|
||||
if (flag) {
|
||||
this.cancelLoadIndex++
|
||||
} else {
|
||||
this.cancelJobIndex++
|
||||
}
|
||||
console.log('image load multiple cancelJobIndex:' + this.cancelJobIndex,'cancelLoadIndex' + this.cancelLoadIndex)
|
||||
}
|
||||
}
|
||||
},index:this.componentIndex
|
||||
}).width(300).height(300)
|
||||
}
|
||||
.height('80%')
|
||||
}.width('100%')
|
||||
.height('100%')
|
||||
}
|
||||
}
|
||||
@Component
|
||||
struct ImageComponent {
|
||||
@State imageKnifeOption: ImageKnifeOption = new ImageKnifeOption()
|
||||
@Link index: number
|
||||
aboutToAppear(): void {
|
||||
this.index++
|
||||
}
|
||||
build() {
|
||||
ImageKnifeComponent({
|
||||
imageKnifeOption: this.imageKnifeOption
|
||||
})
|
||||
}
|
||||
}
|
|
@ -0,0 +1,140 @@
|
|||
/*
|
||||
* Copyright (C) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { ImageKnife, CacheStrategy, ImageKnifeComponent, ImageKnifeOption } from '@ohos/libraryimageknife';
|
||||
|
||||
@Entry
|
||||
@Component
|
||||
struct TestCacheDataPage {
|
||||
@State cacheUpLimit: number = 0;
|
||||
@State currentNum: number = 0;
|
||||
@State currentSize: number = 0;
|
||||
@State currentWidth: number = 200
|
||||
@State currentHeight: number = 200
|
||||
@State markersLimitText: string = getContext(this).resourceManager.getStringSync($r('app.string.memory'))
|
||||
@State markersNumText: string = getContext(this).resourceManager.getStringSync($r('app.string.memory'))
|
||||
@State markersSizeText: string = getContext(this).resourceManager.getStringSync($r('app.string.memory'))
|
||||
@State ImageKnifeOption: ImageKnifeOption = {
|
||||
loadSrc: '',
|
||||
objectFit: ImageFit.Contain,
|
||||
onLoadListener: {
|
||||
onLoadFailed: (err) => {
|
||||
console.error('Load Failed Reason: ' + err);
|
||||
},
|
||||
onLoadSuccess: (data) => {
|
||||
return data;
|
||||
},
|
||||
},
|
||||
border: { radius: 50 }
|
||||
}
|
||||
|
||||
aboutToAppear(): void {
|
||||
ImageKnife.getInstance().initFileCache(getContext(this), 256, 256 * 1024 * 1024, 'ImageKnifeCache1')
|
||||
}
|
||||
|
||||
build() {
|
||||
Column() {
|
||||
|
||||
ImageKnifeComponent(
|
||||
{ imageKnifeOption: this.ImageKnifeOption })
|
||||
.height(this.currentHeight)
|
||||
.width(this.currentWidth)
|
||||
.margin({ top: 10 })
|
||||
|
||||
Button($r('app.string.load_memory'))
|
||||
.onClick(() => {
|
||||
this.ImageKnifeOption = {
|
||||
loadSrc: 'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/3e/v3/LqRoLI-PRSu9Nqa8KdJ-pQ/dSqskBpSR9eraAMn7NBdqA.jpg',
|
||||
objectFit: ImageFit.Contain,
|
||||
writeCacheStrategy: CacheStrategy.Memory,
|
||||
border: { radius: 50 },
|
||||
}
|
||||
})
|
||||
Button($r('app.string.load_disk'))
|
||||
.onClick(() => {
|
||||
this.ImageKnifeOption = {
|
||||
loadSrc: 'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/56/v3/8MdhfSsCSMKj4sA6okUWrg/5uBx56tLTUO3RYQl-E5JiQ.jpg',
|
||||
objectFit: ImageFit.Contain,
|
||||
writeCacheStrategy: CacheStrategy.File,
|
||||
border: { radius: 50 },
|
||||
}
|
||||
})
|
||||
Text($r('app.string.cur_cache_limit', this.markersLimitText, this.cacheUpLimit))
|
||||
.fontSize(20)
|
||||
.margin({ bottom: 8 });
|
||||
Text($r('app.string.cur_cache_image_num', this.markersNumText, this.currentNum))
|
||||
.fontSize(20)
|
||||
.margin({ bottom: 8 });
|
||||
Text($r('app.string.cur_cache_size', this.markersSizeText, this.currentSize)).fontSize(20).margin({ bottom: 20 });
|
||||
|
||||
Button($r('app.string.get_cur_memory_limit')).onClick(() => {
|
||||
let result = ImageKnife.getInstance().getCacheLimitSize(CacheStrategy.Memory);
|
||||
this.markersLimitText = getContext(this).resourceManager.getStringSync($r('app.string.memory'))
|
||||
if (result) {
|
||||
this.cacheUpLimit = result / (1024 * 1024);
|
||||
} else {
|
||||
this.cacheUpLimit = 0;
|
||||
}
|
||||
}).margin({ bottom: 8 });
|
||||
Button($r('app.string.get_img_number_of_cache')).onClick(() => {
|
||||
let result = ImageKnife.getInstance().getCurrentCacheNum(CacheStrategy.Memory);
|
||||
this.markersNumText = getContext(this).resourceManager.getStringSync($r('app.string.memory'))
|
||||
if (result) {
|
||||
this.currentNum = result;
|
||||
} else {
|
||||
this.currentNum = 0;
|
||||
}
|
||||
}).margin({ bottom: 8 });
|
||||
Button($r('app.string.get_cur_memory_size')).onClick(() => {
|
||||
let result = ImageKnife.getInstance().getCurrentCacheSize(CacheStrategy.Memory);
|
||||
this.markersSizeText = getContext(this).resourceManager.getStringSync($r('app.string.memory'))
|
||||
if (result) {
|
||||
this.currentSize = result / (1024 * 1024);
|
||||
} else {
|
||||
this.currentSize = 0;
|
||||
}
|
||||
}).margin({ bottom: 8 });
|
||||
|
||||
Button($r('app.string.get_cur_disk_limit')).onClick(() => {
|
||||
let result = ImageKnife.getInstance().getCacheLimitSize(CacheStrategy.File);
|
||||
this.markersLimitText = getContext(this).resourceManager.getStringSync($r('app.string.disk'))
|
||||
if (result) {
|
||||
this.cacheUpLimit = result / (1024 * 1024);
|
||||
} else {
|
||||
this.cacheUpLimit = 0;
|
||||
}
|
||||
}).margin({ bottom: 8 });
|
||||
Button($r('app.string.get_img_number_of_disk')).onClick(() => {
|
||||
let result = ImageKnife.getInstance().getCurrentCacheNum(CacheStrategy.File);
|
||||
this.markersNumText = getContext(this).resourceManager.getStringSync($r('app.string.disk'))
|
||||
if (result) {
|
||||
this.currentNum = result;
|
||||
} else {
|
||||
this.currentNum = 0;
|
||||
}
|
||||
}).margin({ bottom: 8 });
|
||||
Button($r('app.string.get_cur_disk_size')).onClick(() => {
|
||||
let result = ImageKnife.getInstance().getCurrentCacheSize(CacheStrategy.File);
|
||||
this.markersSizeText = getContext(this).resourceManager.getStringSync($r('app.string.disk'))
|
||||
if (result) {
|
||||
this.currentSize = result / (1024 * 1024);
|
||||
} else {
|
||||
this.currentSize = 0;
|
||||
}
|
||||
}).margin({ bottom: 8 });
|
||||
}
|
||||
.height('100%').width('100%').margin({ top: 50 })
|
||||
}
|
||||
}
|
|
@ -0,0 +1,112 @@
|
|||
/*
|
||||
* Copyright (C) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { drawing, common2D } from '@kit.ArkGraphics2D';
|
||||
import { ImageKnifeComponent, ImageKnifeOption } from '@ohos/imageknife';
|
||||
|
||||
@Entry
|
||||
@Component
|
||||
struct TestChangeColorPage {
|
||||
private imageOne: Resource = $r('app.media.ic_test_change_color_png');
|
||||
private imageTwo: Resource = $r('app.media.ic_test_change_color_png');
|
||||
@State src: Resource = this.imageOne
|
||||
@State src2: Resource = this.imageTwo
|
||||
@State color: common2D.Color = {
|
||||
alpha: 255,
|
||||
red: 255,
|
||||
green: 1,
|
||||
blue: 1
|
||||
};
|
||||
@State DrawingColorFilterFirst: ColorFilter | undefined = undefined
|
||||
|
||||
build() {
|
||||
Column() {
|
||||
Text($r('app.string.select_color_btn')).margin({ top: 20 })
|
||||
Row() {
|
||||
Button($r('app.string.red')).backgroundColor(Color.Red).margin(5).onClick(() => {
|
||||
this.color = {
|
||||
alpha: 255,
|
||||
red: 255,
|
||||
green: 1,
|
||||
blue: 1
|
||||
};
|
||||
})
|
||||
Button($r('app.string.yellow')).backgroundColor(Color.Yellow).margin(5).onClick(() => {
|
||||
this.color = {
|
||||
alpha: 255,
|
||||
red: 255,
|
||||
green: 255,
|
||||
blue: 1
|
||||
};
|
||||
})
|
||||
Button($r('app.string.green')).backgroundColor(Color.Green).margin(5).onClick(() => {
|
||||
this.color = {
|
||||
alpha: 255,
|
||||
red: 1,
|
||||
green: 255,
|
||||
blue: 1
|
||||
};
|
||||
})
|
||||
Button($r('app.string.blue')).backgroundColor(Color.Blue).margin(5).onClick(() => {
|
||||
this.color = {
|
||||
alpha: 255,
|
||||
red: 1,
|
||||
green: 1,
|
||||
blue: 255
|
||||
};
|
||||
})
|
||||
}
|
||||
.width('100%')
|
||||
.height(50)
|
||||
.justifyContent(FlexAlign.Center)
|
||||
|
||||
Text($r('app.string.master_image')).margin({ top: 20 })
|
||||
ImageKnifeComponent({
|
||||
imageKnifeOption: {
|
||||
loadSrc: this.src
|
||||
}
|
||||
}).width(110).height(110)
|
||||
|
||||
Text($r('app.string.click_img_to_change_color')).margin({ top: 30 })
|
||||
ImageKnifeComponent({
|
||||
imageKnifeOption: {
|
||||
loadSrc: this.src,
|
||||
drawingColorFilter: this.DrawingColorFilterFirst
|
||||
}
|
||||
})
|
||||
.onClick(() => {
|
||||
this.DrawingColorFilterFirst =
|
||||
drawing.ColorFilter.createBlendModeColorFilter(this.color, drawing.BlendMode.SRC_IN);
|
||||
}).width(110).height(110)
|
||||
|
||||
Text($r('app.string.test_non_svg_color')).margin({ top: 30 })
|
||||
ImageKnifeComponent({
|
||||
imageKnifeOption: {
|
||||
loadSrc: $r('app.media.ic_test_change_color_png'),
|
||||
drawingColorFilter: drawing.ColorFilter.createBlendModeColorFilter(this.color, drawing.BlendMode.SRC_IN)
|
||||
}
|
||||
}).width(110).height(110)
|
||||
|
||||
Text($r('app.string.test_svg_color')).margin({ top: 30 })
|
||||
ImageKnifeComponent({
|
||||
imageKnifeOption: {
|
||||
loadSrc: $r('app.media.ic_test_change_color_svg'),
|
||||
drawingColorFilter: drawing.ColorFilter.createBlendModeColorFilter(this.color, drawing.BlendMode.SRC_IN)
|
||||
}
|
||||
}).width(110).height(110)
|
||||
|
||||
}.width('100%').height('100%')
|
||||
}
|
||||
}
|
|
@ -12,10 +12,10 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { ImageKnifeComponent ,ImageKnifeOption} from '@ohos/libraryimageknife';
|
||||
import { ImageKnifeComponent } from '@ohos/libraryimageknife';
|
||||
|
||||
@Entry
|
||||
@ComponentV2
|
||||
@Component
|
||||
struct TestCommonImage {
|
||||
private data: Array<string> = []
|
||||
aboutToAppear(): void {
|
||||
|
@ -30,23 +30,23 @@ struct TestCommonImage {
|
|||
FlowItem() {
|
||||
Column(){
|
||||
ImageKnifeComponent({
|
||||
imageKnifeOption: new ImageKnifeOption({
|
||||
imageKnifeOption: {
|
||||
loadSrc: item,
|
||||
placeholderSrc: $r("app.media.loading"),
|
||||
errorholderSrc: $r("app.media.failed"),
|
||||
placeholderSrc: $r('app.media.loading'),
|
||||
errorholderSrc: $r('app.media.failed'),
|
||||
objectFit: ImageFit.Contain,
|
||||
signature: "aaa"
|
||||
})
|
||||
}).width("50%").height(200)
|
||||
signature: 'aaa'
|
||||
}
|
||||
}).width('50%').height(200)
|
||||
}
|
||||
}.height(200)
|
||||
.backgroundColor("#95efd2")
|
||||
.backgroundColor('#95efd2')
|
||||
},(item: string) => item)
|
||||
}.columnsTemplate("1fr 1fr")
|
||||
}.columnsTemplate('1fr 1fr')
|
||||
.columnsGap(10)
|
||||
.rowsGap(5)
|
||||
.backgroundColor(0xFAEEE0)
|
||||
.width("100%").height("100%")
|
||||
.width('100%').height('100%')
|
||||
}
|
||||
}
|
||||
}
|
|
@ -12,34 +12,34 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { ImageKnifeComponent,ImageKnifeOption } from '@ohos/libraryimageknife'
|
||||
import { ImageKnifeComponent } from '@ohos/libraryimageknife'
|
||||
|
||||
@Entry
|
||||
@ComponentV2
|
||||
@Component
|
||||
struct TestErrorHolderPage {
|
||||
|
||||
build() {
|
||||
Column() {
|
||||
Text("ImageKnifeComponent1").fontSize(20)
|
||||
Text('ImageKnifeComponent1').fontSize(20)
|
||||
ImageKnifeComponent({
|
||||
imageKnifeOption: new ImageKnifeOption({
|
||||
loadSrc: "abc",
|
||||
imageKnifeOption: {
|
||||
loadSrc: 'abc',
|
||||
errorholderSrc:$r('app.media.failed')
|
||||
})
|
||||
}
|
||||
}).width(200).height(200)
|
||||
Text("ImageKnifeComponent2").fontSize(20)
|
||||
Text('ImageKnifeComponent2').fontSize(20)
|
||||
ImageKnifeComponent({
|
||||
imageKnifeOption: new ImageKnifeOption({
|
||||
loadSrc: "abc",
|
||||
imageKnifeOption: {
|
||||
loadSrc: 'abc',
|
||||
errorholderSrc:$r('app.media.startIcon')
|
||||
})
|
||||
}
|
||||
}).width(200).height(200)
|
||||
Text("ImageKnifeComponent2").fontSize(20)
|
||||
Text('ImageKnifeComponent2').fontSize(20)
|
||||
ImageKnifeComponent({
|
||||
imageKnifeOption: new ImageKnifeOption({
|
||||
loadSrc: "abc",
|
||||
imageKnifeOption: {
|
||||
loadSrc: 'abc',
|
||||
errorholderSrc:$r('app.media.mask_starfish')
|
||||
})
|
||||
}
|
||||
}).width(200).height(200)
|
||||
}
|
||||
.height('100%') .width('100%')
|
||||
|
|
|
@ -15,18 +15,18 @@
|
|||
import { ImageKnifeComponent,ImageKnifeOption } from '@ohos/libraryimageknife'
|
||||
|
||||
@Entry
|
||||
@ComponentV2
|
||||
@Component
|
||||
struct TestPrefetchToFileCachePage {
|
||||
@Local imageKnifeOption: ImageKnifeOption = new ImageKnifeOption({
|
||||
loadSrc:"https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658",
|
||||
@State imageKnifeOption: ImageKnifeOption = {
|
||||
loadSrc:'https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658',
|
||||
placeholderSrc:$r('app.media.loading'),
|
||||
headerOption:[
|
||||
{
|
||||
key:"abc",
|
||||
value:"单个"
|
||||
key:'abc',
|
||||
value:'单个'
|
||||
}
|
||||
]
|
||||
})
|
||||
}
|
||||
|
||||
build() {
|
||||
Column() {
|
||||
|
|
|
@ -12,14 +12,14 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { IndexComponent } from "@ohos/libraryimageknife"
|
||||
import { IndexComponent } from '@ohos/libraryimageknife'
|
||||
|
||||
@Entry
|
||||
@ComponentV2
|
||||
@Component
|
||||
struct TestHspPreLoadImage {
|
||||
build() {
|
||||
Column() {
|
||||
IndexComponent()
|
||||
}.width("100%").height('100%')
|
||||
}.width('100%').height('100%')
|
||||
}
|
||||
}
|
|
@ -0,0 +1,92 @@
|
|||
/*
|
||||
* Copyright (C) 2025 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { ImageKnifeComponent } from '@ohos/libraryimageknife';
|
||||
import fs from '@ohos.file.fs';
|
||||
|
||||
@Entry
|
||||
@Component
|
||||
struct LocalImage {
|
||||
scroller: Scroller = new Scroller;
|
||||
|
||||
build() {
|
||||
Scroll(this.scroller) {
|
||||
Column() {
|
||||
Column() {
|
||||
Text($r('app.string.base_image'))
|
||||
.fontSize(20)
|
||||
.fontWeight(FontWeight.Bold)
|
||||
Row() {
|
||||
Image($rawfile('rotate/rotate.jpg')).width(100).height(100).margin({ right: 10 })
|
||||
ImageKnifeComponent({
|
||||
imageKnifeOption: {
|
||||
loadSrc: $rawfile('rotate/rotate.jpg'),
|
||||
objectFit: ImageFit.Contain
|
||||
}
|
||||
}).width(100).height(100)
|
||||
}
|
||||
}
|
||||
.margin({ bottom: 20 })
|
||||
|
||||
Column() {
|
||||
Text($r('app.string.rotate_mirror'))
|
||||
.fontSize(20)
|
||||
.fontWeight(FontWeight.Bold)
|
||||
Row() {
|
||||
Image($rawfile('rotate/rotate_mirror.jpg')).width(100).height(100).margin({ right: 10 })
|
||||
ImageKnifeComponent({
|
||||
imageKnifeOption: {
|
||||
loadSrc: $rawfile('rotate/rotate_mirror.jpg'),
|
||||
objectFit: ImageFit.Contain
|
||||
}
|
||||
}).width(100).height(100)
|
||||
}
|
||||
}.margin({ bottom: 20 })
|
||||
|
||||
Column() {
|
||||
Text($r('app.string.rotate_rotate90'))
|
||||
.fontSize(20)
|
||||
.fontWeight(FontWeight.Bold)
|
||||
Row() {
|
||||
Image($rawfile('rotate/rotate_rotate90.jpg')).width(100).height(100).margin({ right: 10 })
|
||||
ImageKnifeComponent({
|
||||
imageKnifeOption: {
|
||||
loadSrc: $rawfile('rotate/rotate_rotate90.jpg'),
|
||||
objectFit: ImageFit.Contain
|
||||
}
|
||||
}).width(100).height(100)
|
||||
}
|
||||
}.margin({ bottom: 20 })
|
||||
|
||||
Column() {
|
||||
Text($r('app.string.rotate_mirror_rotate270'))
|
||||
.fontSize(20)
|
||||
.fontWeight(FontWeight.Bold)
|
||||
Row() {
|
||||
Image($rawfile('rotate/rotate_mirror_rotate270.jpg')).width(100).height(100).margin({ right: 10 })
|
||||
ImageKnifeComponent({
|
||||
imageKnifeOption: {
|
||||
loadSrc: $rawfile('rotate/rotate_mirror_rotate270.jpg'),
|
||||
objectFit: ImageFit.Contain
|
||||
}
|
||||
}).width(100).height(100)
|
||||
}
|
||||
}
|
||||
}
|
||||
.width('100%')
|
||||
}
|
||||
.height('100%')
|
||||
}
|
||||
}
|
||||
|
|
@ -12,9 +12,9 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { ImageKnifeComponent,ImageKnifeOption } from '@ohos/libraryimageknife'
|
||||
import { ImageKnifeComponent } from '@ohos/libraryimageknife'
|
||||
|
||||
@ObservedV2
|
||||
@Observed
|
||||
export class MsgModel {
|
||||
id: string
|
||||
cId: string
|
||||
|
@ -30,66 +30,66 @@ export class MsgModel {
|
|||
}
|
||||
|
||||
|
||||
// @Reusable
|
||||
@ComponentV2
|
||||
@Reusable
|
||||
@Component
|
||||
export struct MsgItem {
|
||||
@Param count: number = 0
|
||||
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",
|
||||
'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:new ImageKnifeOption({
|
||||
loadSrc:$r("app.media.startIcon"),
|
||||
placeholderSrc:$r("app.media.loading")
|
||||
}),syncLoad:true
|
||||
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:new ImageKnifeOption({
|
||||
imageKnifeOption:{
|
||||
loadSrc:this.data[this.count - 6],
|
||||
placeholderSrc:$r("app.media.loading")
|
||||
}),syncLoad:true
|
||||
placeholderSrc:$r('app.media.loading')
|
||||
},syncLoad:true
|
||||
})
|
||||
}else {
|
||||
ImageKnifeComponent({
|
||||
imageKnifeOption:new ImageKnifeOption({
|
||||
loadSrc:$r("app.media.pngSample"),
|
||||
placeholderSrc:$r("app.media.loading")
|
||||
}),syncLoad:true
|
||||
imageKnifeOption:{
|
||||
loadSrc:$r('app.media.pngSample'),
|
||||
placeholderSrc:$r('app.media.loading')
|
||||
},syncLoad:true
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Entry
|
||||
@ComponentV2
|
||||
@Component
|
||||
struct ImageTestPage {
|
||||
count : number = 0
|
||||
rCount: number = 0
|
||||
scroller: Scroller = new Scroller()
|
||||
@Local list: MsgModel[] = []
|
||||
@Local imageSize: number =100
|
||||
@State list: MsgModel[] = []
|
||||
@State imageSize: number =100
|
||||
handAdd(){
|
||||
this.count++
|
||||
const msgItem = new MsgModel('add_id'+this.count, 'addBody'+this.count,'cId'+ this.count)
|
||||
|
@ -103,20 +103,20 @@ struct ImageTestPage {
|
|||
build(){
|
||||
Column(){
|
||||
Row(){
|
||||
Button("addItem").onClick(()=> {
|
||||
Button('addItem').onClick(()=> {
|
||||
this.handAdd()
|
||||
})
|
||||
Button("remove").onClick(()=> {
|
||||
Button('remove').onClick(()=> {
|
||||
this.list.splice(0,1)
|
||||
})
|
||||
}
|
||||
Row(){
|
||||
Text("点击尺寸加50")
|
||||
Text($r('app.string.Click_on_add'))
|
||||
.onClick(()=> {
|
||||
this.imageSize = this.imageSize + 50
|
||||
})
|
||||
.width('50%').backgroundColor(0x88ff0000).textAlign(TextAlign.Center).height(50)
|
||||
Text("点击尺寸减50")
|
||||
Text($r('app.string.Click_on_reduce'))
|
||||
.onClick(()=> {
|
||||
this.imageSize = Math.max(this.imageSize - 50, 0)
|
||||
})
|
||||
|
|
|
@ -0,0 +1,387 @@
|
|||
/*
|
||||
* Copyright (C) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { ImageKnifeComponent, ImageKnifeData, ImageKnifeOption, ImageKnifeRequest } from '@ohos/libraryimageknife';
|
||||
import { router } from '@kit.ArkUI';
|
||||
|
||||
@Entry
|
||||
@Component
|
||||
struct TestImageKnifeCallbackPage {
|
||||
@State imageKnifeOption: ImageKnifeOption = {
|
||||
loadSrc: '',
|
||||
objectFit: ImageFit.Contain,
|
||||
border: { radius: 50 }
|
||||
};
|
||||
@State currentWidth: number = 200
|
||||
@State currentHeight: number = 200
|
||||
@State url: string | undefined = ''
|
||||
@State imageType: string | undefined = ''
|
||||
@State imageWidth: number | undefined = 0
|
||||
@State imageHeight: number | undefined = 0
|
||||
@State imageSize: number | undefined = 0
|
||||
@State componentWidth: number | undefined = 0
|
||||
@State componentHeight: number | undefined = 0
|
||||
@State frameNum: number | undefined = 0
|
||||
@State decodeSize: string | undefined = ''
|
||||
@State errMsg: string | undefined = ''
|
||||
@State errPhase: string | undefined = ''
|
||||
@State errCode: number | undefined = 0
|
||||
@State httpCode: number | undefined = 0
|
||||
@State reqStartTime: string | undefined = ''
|
||||
@State reqEndTime: string | undefined = ''
|
||||
@State reqCancelTime: string | undefined = ''
|
||||
@State memoryStartTime: string | undefined = ''
|
||||
@State memoryEndTime: string | undefined = ''
|
||||
@State diskStartTime: string | undefined = ''
|
||||
@State diskEndTime: string | undefined = ''
|
||||
@State netStartTime: string | undefined = ''
|
||||
@State netEndTime: string | undefined = ''
|
||||
@State decodeStartTime: string | undefined = ''
|
||||
@State decodeEndTime: string | undefined = ''
|
||||
@State showChild: boolean = true;
|
||||
@State requestFrom: string = '';
|
||||
|
||||
build() {
|
||||
Column() {
|
||||
Text($r('app.string.img_url', this.url)).fontSize(14)
|
||||
Text($r('app.string.img_format', this.imageType)).fontSize(14)
|
||||
Text($r('app.string.img_master_size', this.imageWidth, this.imageHeight, this.imageSize)).fontSize(14)
|
||||
Text($r('app.string.componentWH', this.componentWidth, this.componentHeight)).fontSize(14)
|
||||
Text($r('app.string.img_frame', this.frameNum)).fontSize(14)
|
||||
Text($r('app.string.img_content_size', this.decodeSize)).fontSize(14)
|
||||
Text($r('app.string.err_msg', this.errMsg)).fontSize(14)
|
||||
Text($r('app.string.err_phase', this.errPhase)).fontSize(14)
|
||||
Text($r('app.string.err_code', this.errCode)).fontSize(14)
|
||||
Text($r('app.string.http_code', this.httpCode)).fontSize(14)
|
||||
Text($r('app.string.req_start_time', this.reqStartTime)).fontSize(14)
|
||||
Text($r('app.string.req_end_time', this.reqEndTime)).fontSize(14)
|
||||
Text($r('app.string.req_cancel_time', this.reqCancelTime)).fontSize(14)
|
||||
Text($r('app.string.memory_start_time', this.memoryStartTime)).fontSize(14)
|
||||
Text($r('app.string.memory_end_time', this.memoryEndTime)).fontSize(14)
|
||||
Text($r('app.string.disk_start_time', this.diskStartTime)).fontSize(14)
|
||||
Text($r('app.string.disk_end_time', this.diskEndTime)).fontSize(14)
|
||||
Text($r('app.string.net_start_time', this.netStartTime)).fontSize(14)
|
||||
Text($r('app.string.net_end_time', this.netEndTime)).fontSize(14)
|
||||
Text($r('app.string.decode_start_time', this.decodeStartTime)).fontSize(14)
|
||||
Text($r('app.string.decode_end_time', this.decodeEndTime)).fontSize(14)
|
||||
Text($r('app.string.request_data_from', this.requestFrom)).fontSize(14)
|
||||
|
||||
Scroll() {
|
||||
Column() {
|
||||
|
||||
Row() {
|
||||
Button($r('app.string.Network_images'))
|
||||
.fontSize(13)
|
||||
.onClick(() => {
|
||||
this.destroy();
|
||||
this.imageKnifeOption = {
|
||||
loadSrc: 'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/10/v3/qaEzwkU0QeKb1yehnP2Xig/q7fxAlgMQKup-HUBayRLGQ.jpg',
|
||||
objectFit: ImageFit.Contain,
|
||||
onLoadListener: {
|
||||
onLoadStart: (data) => {
|
||||
this.analyzeStartCallBackData(data);
|
||||
},
|
||||
onLoadFailed: (res, req) => {
|
||||
this.analyzeFailedBackData(res, req?.imageKnifeData);
|
||||
},
|
||||
onLoadSuccess: (data, imageData, req) => {
|
||||
this.analyzeSuccessCallBackData(req?.imageKnifeData);
|
||||
},
|
||||
onLoadCancel: (res, req) => {
|
||||
this.analyzeFailedBackData(res, req?.imageKnifeData);
|
||||
}
|
||||
},
|
||||
border: { radius: 50 },
|
||||
}
|
||||
})
|
||||
|
||||
Button($r('app.string.gif'))
|
||||
.fontSize(13)
|
||||
.onClick(() => {
|
||||
this.destroy();
|
||||
this.imageKnifeOption = {
|
||||
loadSrc: 'https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658',
|
||||
objectFit: ImageFit.Contain,
|
||||
onLoadListener: {
|
||||
onLoadStart: (data) => {
|
||||
this.analyzeStartCallBackData(data);
|
||||
},
|
||||
onLoadFailed: (res, req) => {
|
||||
this.analyzeFailedBackData(res, req?.imageKnifeData);
|
||||
},
|
||||
onLoadSuccess: (data, imageData, req) => {
|
||||
this.analyzeSuccessCallBackData(req?.imageKnifeData);
|
||||
},
|
||||
onLoadCancel: (res, req) => {
|
||||
this.analyzeFailedBackData(res, req?.imageKnifeData);
|
||||
}
|
||||
},
|
||||
border: { radius: 50 },
|
||||
}
|
||||
})
|
||||
Button($r('app.string.local_pic'))
|
||||
.fontSize(13)
|
||||
.onClick(() => {
|
||||
this.destroy();
|
||||
this.imageKnifeOption = {
|
||||
loadSrc: $r('app.media.pngSample'),
|
||||
objectFit: ImageFit.Contain,
|
||||
onLoadListener: {
|
||||
onLoadStart: (data) => {
|
||||
this.analyzeStartCallBackData(data);
|
||||
},
|
||||
onLoadFailed: (res, req) => {
|
||||
this.analyzeFailedBackData(res, req?.imageKnifeData);
|
||||
},
|
||||
onLoadSuccess: (data, imageData, req) => {
|
||||
this.analyzeSuccessCallBackData(req?.imageKnifeData);
|
||||
},
|
||||
onLoadCancel: (res, req) => {
|
||||
this.analyzeFailedBackData(res, req?.imageKnifeData);
|
||||
}
|
||||
},
|
||||
border: { radius: 50 },
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
Row() {
|
||||
Button($r('app.string.net_load_failed'))
|
||||
.fontSize(13)
|
||||
.onClick(() => {
|
||||
this.destroy();
|
||||
this.imageKnifeOption = {
|
||||
loadSrc: 'https://img-blog.csdn.net/20140514114039140',
|
||||
objectFit: ImageFit.Contain,
|
||||
onLoadListener: {
|
||||
onLoadStart: (data) => {
|
||||
this.analyzeStartCallBackData(data);
|
||||
},
|
||||
onLoadFailed: (res, req) => {
|
||||
this.analyzeFailedBackData(res, req?.imageKnifeData);
|
||||
},
|
||||
onLoadSuccess: (data, imageData, req) => {
|
||||
this.analyzeSuccessCallBackData(req?.imageKnifeData);
|
||||
},
|
||||
onLoadCancel: (res, req) => {
|
||||
this.analyzeFailedBackData(res, req?.imageKnifeData);
|
||||
}
|
||||
},
|
||||
border: { radius: 50 },
|
||||
}
|
||||
})
|
||||
|
||||
Button($r('app.string.local_load_failed'))
|
||||
.fontSize(13)
|
||||
.onClick(() => {
|
||||
this.destroy();
|
||||
this.imageKnifeOption = {
|
||||
loadSrc: 'app.media.xxx',
|
||||
objectFit: ImageFit.Contain,
|
||||
onLoadListener: {
|
||||
onLoadStart: (data) => {
|
||||
this.analyzeStartCallBackData(data);
|
||||
},
|
||||
onLoadFailed: (res, req) => {
|
||||
this.analyzeFailedBackData(res, req?.imageKnifeData);
|
||||
},
|
||||
onLoadSuccess: (data, imageData, req) => {
|
||||
this.analyzeSuccessCallBackData(req?.imageKnifeData);
|
||||
},
|
||||
onLoadCancel: (res, req) => {
|
||||
this.analyzeFailedBackData(res, req?.imageKnifeData);
|
||||
}
|
||||
},
|
||||
border: { radius: 50 },
|
||||
}
|
||||
})
|
||||
Button($r('app.string.share_load_failed'))
|
||||
.fontSize(13)
|
||||
.onClick(() => {
|
||||
this.destroy();
|
||||
this.imageKnifeOption = {
|
||||
loadSrc: 'datashare://ssas',
|
||||
objectFit: ImageFit.Contain,
|
||||
onLoadListener: {
|
||||
onLoadStart: (data) => {
|
||||
this.analyzeStartCallBackData(data);
|
||||
},
|
||||
onLoadFailed: (res, req) => {
|
||||
this.analyzeFailedBackData(res, req?.imageKnifeData);
|
||||
},
|
||||
onLoadSuccess: (data, imageData, req) => {
|
||||
this.analyzeSuccessCallBackData(req?.imageKnifeData);
|
||||
},
|
||||
onLoadCancel: (res, req) => {
|
||||
this.analyzeFailedBackData(res, req?.imageKnifeData);
|
||||
}
|
||||
},
|
||||
border: { radius: 50 },
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
Button($r('app.string.test_cancel_callback_btn'))
|
||||
.fontSize(13)
|
||||
.onClick(() => {
|
||||
this.destroy();
|
||||
this.imageKnifeOption = {
|
||||
loadSrc: 'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/bf/v3/lSjrRwFcS-ez6jp1ALSQFg/0n7R7XinSPyrYLqDu_1dfw.jpg',
|
||||
objectFit: ImageFit.Contain,
|
||||
onLoadListener: {
|
||||
onLoadStart: (data) => {
|
||||
this.showChild = false;
|
||||
this.analyzeStartCallBackData(data);
|
||||
},
|
||||
onLoadFailed: (res, req) => {
|
||||
this.analyzeFailedBackData(res, req?.imageKnifeData);
|
||||
},
|
||||
onLoadSuccess: (data, imageData, req) => {
|
||||
this.analyzeSuccessCallBackData(req?.imageKnifeData);
|
||||
},
|
||||
onLoadCancel: (res, req) => {
|
||||
this.analyzeFailedBackData(res, req?.imageKnifeData);
|
||||
}
|
||||
},
|
||||
border: { radius: 50 },
|
||||
}
|
||||
})
|
||||
|
||||
Button($r('app.string.list_pic'))
|
||||
.fontSize(13)
|
||||
.onClick(() => {
|
||||
router.push({
|
||||
url: 'pages/TestListImageKnifeCallbackPage',
|
||||
});
|
||||
})
|
||||
if (this.showChild) {
|
||||
ImageKnifeComponent(
|
||||
{ imageKnifeOption: this.imageKnifeOption })
|
||||
.height(this.currentHeight)
|
||||
.width(this.currentWidth)
|
||||
.margin({ top: 20, bottom: 20 })
|
||||
|
||||
}
|
||||
}
|
||||
.width('100%')
|
||||
}
|
||||
}.alignItems(HorizontalAlign.Start)
|
||||
}
|
||||
|
||||
formatDate(time: number | undefined) {
|
||||
if (!time) {
|
||||
return;
|
||||
}
|
||||
let date = new Date(time);
|
||||
const year = date.getFullYear().toString()
|
||||
let month = (date.getMonth() + 1).toString()
|
||||
let day = date.getDate().toString()
|
||||
let hour = date.getHours().toString()
|
||||
let min = date.getMinutes().toString()
|
||||
let seconds = date.getSeconds().toString()
|
||||
let mill = date.getMilliseconds();
|
||||
return `${year}-${month}-${day} ${hour}:${min}:${seconds}:${mill}`
|
||||
}
|
||||
|
||||
analyzeStartCallBackData(req: ImageKnifeRequest | undefined) {
|
||||
let data = req?.imageKnifeData;
|
||||
if (data) {
|
||||
if (typeof req?.imageKnifeOption.loadSrc == 'string') {
|
||||
this.url = req?.imageKnifeOption.loadSrc;
|
||||
}
|
||||
this.componentWidth = req?.componentWidth;
|
||||
this.componentHeight = req?.componentHeight;
|
||||
this.reqStartTime = this.formatDate(data.timeInfo?.requestStartTime);
|
||||
this.memoryStartTime = this.formatDate(data.timeInfo?.memoryCheckStartTime);
|
||||
this.memoryEndTime = this.formatDate(data.timeInfo?.memoryCheckEndTime);
|
||||
this.requestFrom = '';
|
||||
}
|
||||
}
|
||||
|
||||
analyzeSuccessCallBackData(data: ImageKnifeData | undefined) {
|
||||
if (data) {
|
||||
this.imageWidth = data.imageWidth;
|
||||
this.imageHeight = data.imageHeight;
|
||||
this.imageSize = data.bufSize;
|
||||
this.frameNum = data.frameCount;
|
||||
this.httpCode = data.httpCode
|
||||
this.decodeSize = JSON.stringify(data.decodeImages);
|
||||
this.imageType = data.type;
|
||||
this.reqEndTime = this.formatDate(data.timeInfo?.requestEndTime);
|
||||
this.diskStartTime = this.formatDate(data.timeInfo?.diskCheckStartTime);
|
||||
this.diskEndTime = this.formatDate(data.timeInfo?.diskCheckEndTime);
|
||||
this.netStartTime = this.formatDate(data.timeInfo?.netRequestStartTime);
|
||||
this.netEndTime = this.formatDate(data.timeInfo?.netRequestEndTime);
|
||||
this.decodeStartTime = this.formatDate(data.timeInfo?.diskCheckStartTime);
|
||||
this.decodeEndTime = this.formatDate(data.timeInfo?.diskCheckEndTime);
|
||||
if (data.timeInfo?.netRequestEndTime !== undefined) {
|
||||
this.requestFrom = 'Http request';
|
||||
} else if (data.timeInfo?.diskCheckEndTime !== undefined) {
|
||||
this.requestFrom = 'File Cache';
|
||||
} else {
|
||||
this.requestFrom = 'Memory Cache';
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
analyzeFailedBackData(res: string, data: ImageKnifeData | undefined) {
|
||||
if (data) {
|
||||
this.errMsg = res;
|
||||
this.errPhase = data.errorInfo?.phase;
|
||||
this.errCode = data.errorInfo?.code;
|
||||
this.httpCode = data.httpCode;
|
||||
this.reqEndTime = this.formatDate(data.timeInfo?.requestEndTime);
|
||||
this.diskStartTime = this.formatDate(data.timeInfo?.diskCheckStartTime);
|
||||
this.diskEndTime = this.formatDate(data.timeInfo?.diskCheckEndTime);
|
||||
this.netStartTime = this.formatDate(data.timeInfo?.netRequestStartTime);
|
||||
this.netEndTime = this.formatDate(data.timeInfo?.netRequestEndTime);
|
||||
this.decodeStartTime = this.formatDate(data.timeInfo?.diskCheckStartTime);
|
||||
this.decodeEndTime = this.formatDate(data.timeInfo?.diskCheckEndTime);
|
||||
this.reqCancelTime = this.formatDate(data.timeInfo?.requestCancelTime)
|
||||
this.requestFrom = '';
|
||||
}
|
||||
}
|
||||
|
||||
destroy() {
|
||||
this.currentWidth = 200
|
||||
this.currentHeight = 200
|
||||
this.url = ''
|
||||
this.imageType = ''
|
||||
this.imageWidth = 0
|
||||
this.imageHeight = 0
|
||||
this.imageSize = 0
|
||||
this.componentWidth = 0
|
||||
this.componentHeight = 0
|
||||
this.frameNum = 0
|
||||
this.decodeSize = ''
|
||||
this.errMsg = ''
|
||||
this.errPhase = ''
|
||||
this.errCode = 0
|
||||
this.httpCode = 0
|
||||
this.reqStartTime = ''
|
||||
this.reqEndTime = ''
|
||||
this.reqCancelTime = ''
|
||||
this.memoryStartTime = ''
|
||||
this.memoryEndTime = ''
|
||||
this.diskStartTime = ''
|
||||
this.diskEndTime = ''
|
||||
this.netStartTime = ''
|
||||
this.netEndTime = ''
|
||||
this.decodeStartTime = ''
|
||||
this.decodeEndTime = ''
|
||||
this.showChild = true;
|
||||
}
|
||||
}
|
|
@ -15,47 +15,47 @@
|
|||
import { ImageKnifeComponent, ImageKnife, ImageKnifeOption, CacheStrategy } from '@ohos/libraryimageknife'
|
||||
|
||||
@Entry
|
||||
@ComponentV2
|
||||
@Component
|
||||
struct TestIsUrlExist {
|
||||
@Local imageKnifeOption: ImageKnifeOption = new ImageKnifeOption({
|
||||
@State imageKnifeOption: ImageKnifeOption = {
|
||||
loadSrc: $r('app.media.startIcon'),
|
||||
placeholderSrc: $r('app.media.loading'),
|
||||
errorholderSrc:$r('app.media.failed')
|
||||
})
|
||||
@Local source: PixelMap | string | Resource = $r("app.media.startIcon")
|
||||
@Local source1: PixelMap | string | Resource = $r("app.media.startIcon")
|
||||
}
|
||||
@State source: PixelMap | string | Resource = $r('app.media.startIcon')
|
||||
@State source1: PixelMap | string | Resource = $r('app.media.startIcon')
|
||||
|
||||
build() {
|
||||
Column() {
|
||||
Flex() {
|
||||
Button("预加载gif图").onClick(() => {
|
||||
Button($r('app.string.Preloading_GIF')).onClick(() => {
|
||||
this.imageKnifeOption.loadSrc =
|
||||
"https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658"
|
||||
'https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658'
|
||||
})
|
||||
Button("内存缓存获取gif").onClick(() => {
|
||||
Button($r('app.string.Retrieve_GIF_from_memory')).onClick(() => {
|
||||
ImageKnife.getInstance()
|
||||
.getCacheImage("https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658",
|
||||
.getCacheImage('https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658',
|
||||
CacheStrategy.Memory)
|
||||
.then((data) => {
|
||||
this.source = data !== undefined ? data.source : $r("app.media.startIcon")
|
||||
this.source = data !== undefined ? data.source : $r('app.media.startIcon')
|
||||
})
|
||||
})
|
||||
Button("文件缓存获取gif").onClick(() => {
|
||||
Button($r('app.string.Retrieve_GIF_from_disk')).onClick(() => {
|
||||
ImageKnife.getInstance()
|
||||
.getCacheImage("https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658",
|
||||
.getCacheImage('https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658',
|
||||
CacheStrategy.File)
|
||||
.then((data) => {
|
||||
this.source1 = data !== undefined ? data.source : $r("app.media.startIcon")
|
||||
this.source1 = data !== undefined ? data.source : $r('app.media.startIcon')
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
Flex() {
|
||||
Button("预加载静态图").onClick(() => {
|
||||
Button($r('app.string.Preloading_static_images')).onClick(() => {
|
||||
this.imageKnifeOption.loadSrc =
|
||||
'https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp'
|
||||
})
|
||||
Button("内存缓存获取").onClick(() => {
|
||||
Button($r('app.string.Retrieve_images_from_memory')).onClick(() => {
|
||||
ImageKnife.getInstance()
|
||||
.getCacheImage('https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp',
|
||||
CacheStrategy.Memory)
|
||||
|
@ -63,7 +63,7 @@ struct TestIsUrlExist {
|
|||
this.source = data!.source
|
||||
})
|
||||
})
|
||||
Button("文件缓存获取").onClick(() => {
|
||||
Button($r('app.string.Retrieve_images_from_disk')).onClick(() => {
|
||||
ImageKnife.getInstance()
|
||||
.getCacheImage('https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp',
|
||||
CacheStrategy.File)
|
||||
|
|
|
@ -0,0 +1,103 @@
|
|||
/*
|
||||
* Copyright (C) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { ImageKnifeComponent} from '@ohos/libraryimageknife';
|
||||
|
||||
class ArrayElement {
|
||||
public src: string = '';
|
||||
public w: number = 0;
|
||||
public h: number = 0;
|
||||
}
|
||||
|
||||
@Entry
|
||||
@Component
|
||||
struct TestListImageKnifeCallbackPage {
|
||||
private wid: number = 200;
|
||||
private hig: number = 200;
|
||||
private dataArray: ESObject[] = [
|
||||
'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/56/v3/8MdhfSsCSMKj4sA6okUWrg/5uBx56tLTUO3RYQl-E5JiQ.jpg',
|
||||
'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/56/v3/8MdhfSsCSMKj4sA6okUWrg/5uBx56tLTUO3RYQl-E5JiQ.jpg',
|
||||
'https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658',
|
||||
'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/78/v3/qQJpAtRGQe2e_VhbGHDgIw/b3zlit99S6GybD3XdNwqJw.jpg',
|
||||
'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/55/v3/5DZ2LLqYSsK85-shqgLveQ/7ZXcyCWNTvOzQP5FFLBGkg.jpg',
|
||||
'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/3e/v3/LqRoLI-PRSu9Nqa8KdJ-pQ/dSqskBpSR9eraAMn7NBdqA.jpg',
|
||||
'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/25/v3/jgB2ekkTRX-3yTYZalnANQ/xff_x9cbSPqb7fbNwgJa7A.jpg',
|
||||
'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/fb/v3/alXwXLHKSyCAIWt_ydgD2g/BCCuu25TREOitQxM7eYOEw.jpg',
|
||||
'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/63/v3/qbe6NZkCQyGcITvdWoZBgg/Y-5U1z3GT_yaK8CBD3jkwg.jpg',
|
||||
'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/16/v3/fm2tO4TsRH6mv_D_nSSd5w/FscLpLwQQ-KuV7oaprFK2Q.jpg',
|
||||
'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/89/v3/UAUvtPHqRD-GWWANsEC57Q/zcRJCQebQ322Aby4jzmwmQ.jpg',
|
||||
'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/30/v3/tUUzzx73R4yp8G--lMhuWQ/EBbcu_dLTT-Jj68XAh6mtA.jpg',
|
||||
'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/76/v3/EyF6z4FISpCHhae38eEexw/OtyAiu-zSSevNQYvUdtVmA.jpg',
|
||||
'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/37/v3/12rH1yiEQmK9wlOOcy5avQ/RzBXiEBRRqOC7LRkwNj6VA.jpg',
|
||||
'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/9a/v3/TpRN4AIzRoyUXIqWdKoE0g/ShOnD_tfS46HDbpSWhbCkQ.jpg',
|
||||
'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/03/v3/H3X17s8eTdS2w56JgbB5jQ/a45sT-j8Sbe8sSQXTzeYvQ.jpg',
|
||||
'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/10/v3/qaEzwkU0QeKb1yehnP2Xig/q7fxAlgMQKup-HUBayRLGQ.jpg',
|
||||
'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/96/v3/rMJJoAflTDSWa1z2pHs2wg/8dOqD0GlQBOCL5AvQok9FQ.jpg',
|
||||
'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/ed/v3/KMO4D6D2QGuVOCLX4AhOFA/ef51xAaLQuK7BsnuD9abog.jpg',
|
||||
'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/d9/v3/FSZH0aTdSqWxeAaxoPvi0g/RqxPxUCXQFiTMBfKTF9kkw.jpg',
|
||||
'https://hbimg.huabanimg.com/cc6af25f8d782d3cf3122bef4e61571378271145735e9-vEVggB',
|
||||
'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/bf/v3/lSjrRwFcS-ez6jp1ALSQFg/0n7R7XinSPyrYLqDu_1dfw.jpg',
|
||||
'https://img-blog.csdn.net/20140514114029140',
|
||||
'https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp',
|
||||
$r('app.media.pngSample'),
|
||||
$r('app.media.rabbit')
|
||||
]
|
||||
private data: Array<ArrayElement> = [];
|
||||
|
||||
aboutToAppear(): void {
|
||||
for (let i = 0; i < this.dataArray.length; i++) {
|
||||
let element: ArrayElement = {
|
||||
src: this.dataArray[i],
|
||||
w: this.wid -(i*5),
|
||||
h: this.hig -(i*5)
|
||||
}
|
||||
this.data.push(element);
|
||||
}
|
||||
}
|
||||
|
||||
build() {
|
||||
List({ space: 3 }) {
|
||||
ForEach(this.data, (item: ArrayElement) => {
|
||||
ListItem() {
|
||||
ImageKnifeComponent({
|
||||
imageKnifeOption:
|
||||
{
|
||||
loadSrc: item.src,
|
||||
objectFit: ImageFit.Contain,
|
||||
onLoadListener: {
|
||||
onLoadStart: (data) => {
|
||||
console.log('listCache start:{ url:' + data?.imageKnifeOption.loadSrc +
|
||||
',componentWidth:' + data?.componentWidth +
|
||||
',componentHeight:' + data?.componentHeight +
|
||||
'},' + JSON.stringify(data?.imageKnifeData))
|
||||
},
|
||||
onLoadFailed: (res, req) => {
|
||||
console.log('listCache onLoadFailed:res:' + res + ';' + JSON.stringify(req?.imageKnifeData))
|
||||
},
|
||||
onLoadSuccess: (data, imageData,req) => {
|
||||
console.log('listCache onLoadSuccess:' + JSON.stringify(req?.imageKnifeData))
|
||||
},
|
||||
onLoadCancel: (res, req) => {
|
||||
console.log('listCache onLoadCancel:res:' + res + ';' + JSON.stringify(req?.imageKnifeData))
|
||||
}
|
||||
},
|
||||
border: { radius: 50 },
|
||||
}
|
||||
}).height(item.w).width(item.h)
|
||||
}.width('100%')
|
||||
}, (item: ArrayElement,index) => (item.src+index))
|
||||
}.width('100%').height('100%')
|
||||
}
|
||||
}
|
|
@ -0,0 +1,101 @@
|
|||
/*
|
||||
* Copyright (C) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { ImageKnife, ImageKnifeComponent, ImageKnifeOption } from '@ohos/libraryimageknife';
|
||||
|
||||
|
||||
@Entry
|
||||
@Component
|
||||
struct TestLoadCancelListenerPage {
|
||||
@State currentWidth: number = 200
|
||||
@State currentHeight: number = 200
|
||||
@State showChild: boolean = true;
|
||||
@State text: string = '';
|
||||
@State ImageKnifeOption: ImageKnifeOption = {
|
||||
loadSrc: '',
|
||||
objectFit: ImageFit.Contain,
|
||||
border: { radius: 50 }
|
||||
};
|
||||
|
||||
build() {
|
||||
Column() {
|
||||
Text($r('app.string.onLoadCancel_reason', this.text)).margin(20).fontSize(15)
|
||||
Button($r('app.string.rm_component_of_net'))
|
||||
.margin(20)
|
||||
.onClick(() => {
|
||||
this.clearCache();
|
||||
this.ImageKnifeOption = {
|
||||
loadSrc: 'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/76/v3/EyF6z4FISpCHhae38eEexw/OtyAiu-zSSevNQYvUdtVmA.jpg',
|
||||
objectFit: ImageFit.Contain,
|
||||
onLoadListener: {
|
||||
onLoadStart: () => {
|
||||
this.showChild = false;
|
||||
},
|
||||
onLoadCancel: (res) => {
|
||||
this.text = res
|
||||
console.log('TestLoadCancelListenerPage----onLoadCancel> url:' + res)
|
||||
}
|
||||
},
|
||||
border: { radius: 50 }
|
||||
}
|
||||
})
|
||||
|
||||
Button($r('app.string.component_display'))
|
||||
.margin(20).onClick(() => {
|
||||
this.text = '';
|
||||
this.showChild = true;
|
||||
this.ImageKnifeOption = {
|
||||
loadSrc: '',
|
||||
objectFit: ImageFit.Contain,
|
||||
border: { radius: 50 }
|
||||
}
|
||||
})
|
||||
Button($r('app.string.rm_component_of_local'))
|
||||
.margin(20)
|
||||
.onClick(() => {
|
||||
this.clearCache();
|
||||
this.ImageKnifeOption = {
|
||||
loadSrc: $r('app.media.loading'),
|
||||
objectFit: ImageFit.Contain,
|
||||
onLoadListener: {
|
||||
onLoadStart: () => {
|
||||
this.showChild = false;
|
||||
},
|
||||
onLoadCancel: (res) => {
|
||||
this.text = res
|
||||
console.log('TestLoadCancelListenerPage----onLoadCancel> url:' + res)
|
||||
}
|
||||
},
|
||||
border: { radius: 50 }
|
||||
}
|
||||
})
|
||||
|
||||
if (this.showChild) {
|
||||
ImageKnifeComponent(
|
||||
{ imageKnifeOption: this.ImageKnifeOption })
|
||||
.height(150)
|
||||
.width(150)
|
||||
.backgroundColor(Color.Orange)
|
||||
.margin({ top: 20 })
|
||||
}
|
||||
}
|
||||
.height('100%')
|
||||
.width('100%')
|
||||
}
|
||||
|
||||
clearCache(){
|
||||
ImageKnife.getInstance().removeAllMemoryCache();
|
||||
}
|
||||
}
|
|
@ -15,31 +15,31 @@
|
|||
import { ImageKnifeComponent,ImageKnife,ImageKnifeOption } from '@ohos/libraryimageknife'
|
||||
|
||||
@Entry
|
||||
@ComponentV2
|
||||
@Component
|
||||
struct TestPrefetchToFileCachePage {
|
||||
@Local imageKnifeOption: ImageKnifeOption = new ImageKnifeOption({
|
||||
@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)
|
||||
console.log('preload-fileCachePath=='+ fileCachePath)
|
||||
}
|
||||
async preload1(url:string) {
|
||||
let fileCachePath = await ImageKnife.getInstance().preLoadCache(new ImageKnifeOption({ loadSrc: url }))
|
||||
console.log("preload-fileCachePath1=="+ fileCachePath)
|
||||
let fileCachePath = await ImageKnife.getInstance().preLoadCache({ loadSrc: url })
|
||||
console.log('preload-fileCachePath1=='+ fileCachePath)
|
||||
}
|
||||
build() {
|
||||
Column() {
|
||||
Button("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_URL')).margin({top:10}).onClick(async ()=>{
|
||||
await this.preload('https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658')
|
||||
})
|
||||
Button("option预加载图片到文件缓存").margin({top:10}).onClick(async ()=>{
|
||||
await this.preload1("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("加载图片(预加载后可断网加载)").margin({top:10}).onClick(()=>{
|
||||
this.imageKnifeOption.loadSrc = "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
|
||||
|
|
|
@ -15,52 +15,52 @@
|
|||
import { ImageKnifeComponent, ImageKnife, ImageKnifeOption, CacheStrategy } from '@ohos/libraryimageknife'
|
||||
|
||||
@Entry
|
||||
@ComponentV2
|
||||
@Component
|
||||
struct TestRemoveCache {
|
||||
@Local imageKnifeOption: ImageKnifeOption = new ImageKnifeOption({
|
||||
@State imageKnifeOption: ImageKnifeOption = {
|
||||
loadSrc: $r('app.media.startIcon'),
|
||||
placeholderSrc: $r('app.media.loading'),
|
||||
errorholderSrc:$r('app.media.failed')
|
||||
})
|
||||
@Local source: PixelMap | string | Resource = $r("app.media.startIcon");
|
||||
@Local source1: PixelMap | string | Resource = $r("app.media.startIcon");
|
||||
@Local url: string = '';
|
||||
}
|
||||
@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("预加载gif图").onClick(() => {
|
||||
this.imageKnifeOption.loadSrc = "https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658";
|
||||
this.url = "https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658";
|
||||
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("内存缓存获取gif").onClick(() => {
|
||||
Button($r('app.string.Retrieve_GIF_from_memory')).onClick(() => {
|
||||
ImageKnife.getInstance()
|
||||
.getCacheImage("https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658",
|
||||
.getCacheImage('https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658',
|
||||
CacheStrategy.Memory)
|
||||
.then((data) => {
|
||||
this.source = data !== undefined ? data.source : $r("app.media.startIcon");
|
||||
this.source = data !== undefined ? data.source : $r('app.media.startIcon');
|
||||
})
|
||||
})
|
||||
.margin({left:10})
|
||||
Button("文件缓存获取gif").onClick(() => {
|
||||
Button($r('app.string.Retrieve_GIF_from_disk')).onClick(() => {
|
||||
ImageKnife.getInstance()
|
||||
.getCacheImage("https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658",
|
||||
.getCacheImage('https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658',
|
||||
CacheStrategy.File)
|
||||
.then((data) => {
|
||||
this.source1 = data !== undefined ? data.source : $r("app.media.startIcon");
|
||||
this.source1 = data !== undefined ? data.source : $r('app.media.startIcon');
|
||||
})
|
||||
})
|
||||
.margin({left:10})
|
||||
}
|
||||
|
||||
Flex() {
|
||||
Button("预加载静态图").onClick(() => {
|
||||
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("内存缓存获取").onClick(() => {
|
||||
Button($r('app.string.Retrieve_images_from_memory')).onClick(() => {
|
||||
ImageKnife.getInstance()
|
||||
.getCacheImage('https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp',
|
||||
CacheStrategy.Memory)
|
||||
|
@ -69,7 +69,7 @@ struct TestRemoveCache {
|
|||
})
|
||||
})
|
||||
.margin({left:10})
|
||||
Button("文件缓存获取").onClick(() => {
|
||||
Button($r('app.string.Retrieve_images_from_disk')).onClick(() => {
|
||||
ImageKnife.getInstance()
|
||||
.getCacheImage('https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp',
|
||||
CacheStrategy.File)
|
||||
|
@ -81,19 +81,19 @@ struct TestRemoveCache {
|
|||
}.margin({ top: 10 })
|
||||
|
||||
Flex() {
|
||||
Button("删除全部缓存").onClick(() => {
|
||||
Button($r('app.string.Delete_all_caches')).onClick(() => {
|
||||
ImageKnife.getInstance()
|
||||
.removeAllMemoryCache()
|
||||
ImageKnife.getInstance()
|
||||
.removeAllFileCache()
|
||||
})
|
||||
.margin({left:5})
|
||||
Button("删除全部内存缓存").onClick(() => {
|
||||
Button($r('app.string.Delete_all_memory_caches')).onClick(() => {
|
||||
ImageKnife.getInstance()
|
||||
.removeAllMemoryCache()
|
||||
})
|
||||
.margin({left:5})
|
||||
Button("删除全部文件缓存").onClick(() => {
|
||||
Button($r('app.string.Delete_all_file_caches')).onClick(() => {
|
||||
ImageKnife.getInstance()
|
||||
.removeAllFileCache()
|
||||
})
|
||||
|
@ -101,12 +101,12 @@ struct TestRemoveCache {
|
|||
}.margin({ top: 10 })
|
||||
|
||||
Flex() {
|
||||
Button("删除自定义内存缓存").onClick(() => {
|
||||
Button($r('app.string.Delete_all_custom_memory_caches')).onClick(() => {
|
||||
ImageKnife.getInstance()
|
||||
.removeMemoryCache(this.url)
|
||||
})
|
||||
.margin({left:20})
|
||||
Button("删除自定义文件缓存").onClick(() => {
|
||||
Button($r('app.string.Delete_all_custom_file_caches')).onClick(() => {
|
||||
ImageKnife.getInstance()
|
||||
.removeFileCache(this.url)
|
||||
})
|
||||
|
|
|
@ -15,50 +15,54 @@
|
|||
import { ImageKnifeComponent, ImageKnife, ImageKnifeOption } from '@ohos/libraryimageknife'
|
||||
|
||||
@Entry
|
||||
@ComponentV2
|
||||
@Component
|
||||
struct TestSetCustomImagePage {
|
||||
@Local imageKnifeOption: ImageKnifeOption = new ImageKnifeOption({
|
||||
@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("自定义下载a").onClick(()=>{
|
||||
this.imageKnifeOption = new ImageKnifeOption({
|
||||
loadSrc: "aaa",
|
||||
Button(this.getResourceString($r('app.string.Custom_network_download')) + ' a').onClick(()=>{
|
||||
this.imageKnifeOption ={
|
||||
loadSrc: 'aaa',
|
||||
placeholderSrc: $r('app.media.loading')
|
||||
}
|
||||
})
|
||||
})
|
||||
Button("自定义下载b").onClick(()=>{
|
||||
this.imageKnifeOption = new ImageKnifeOption({
|
||||
loadSrc: "bbb",
|
||||
Button(this.getResourceString($r('app.string.Custom_network_download')) + ' b').onClick(()=>{
|
||||
this.imageKnifeOption = {
|
||||
loadSrc: 'bbb',
|
||||
placeholderSrc: $r('app.media.loading')
|
||||
}
|
||||
})
|
||||
})
|
||||
Button("自定义下载c").onClick(()=>{
|
||||
this.imageKnifeOption = new ImageKnifeOption({
|
||||
loadSrc: "ccc",
|
||||
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%")
|
||||
.width('100%')
|
||||
.height('100%')
|
||||
}
|
||||
}
|
||||
@Concurrent
|
||||
async function custom(context: Context, src: string | PixelMap | Resource): Promise<ArrayBuffer | undefined> {
|
||||
console.info("ImageKnife:: custom download:" + src)
|
||||
async function custom(context: Context, src: string | PixelMap | Resource,headers?: Record<string,Object>): Promise<ArrayBuffer | undefined> {
|
||||
console.info('ImageKnife:: custom download:' + src)
|
||||
// 举例写死从本地文件读取,也可以自己请求网络图片
|
||||
return context.resourceManager.getMediaContentSync($r("app.media.pngSample").id).buffer as ArrayBuffer
|
||||
let buffer = context.resourceManager.getMediaContentSync($r('app.media.pngSample').id).buffer as ArrayBuffer
|
||||
return buffer
|
||||
}
|
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
* Copyright (C) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { ImageKnifeComponent, ImageKnifeOption } from '@ohos/libraryimageknife'
|
||||
|
||||
@ComponentV2
|
||||
export struct ZuImage {
|
||||
@Param @Require src: PixelMap | ResourceStr | string | undefined
|
||||
@Param @Require placeholderSrc: PixelMap | ResourceStr | string | undefined
|
||||
@Local errorholderSrc: PixelMap | ResourceStr | string | undefined
|
||||
|
||||
build() {
|
||||
if (this.src) {
|
||||
//当前版本存在bug
|
||||
ImageKnifeComponent({
|
||||
imageKnifeOption: {
|
||||
loadSrc: this.src,
|
||||
placeholderSrc: this.placeholderSrc,
|
||||
errorholderSrc: this.errorholderSrc ?? this.placeholderSrc,
|
||||
objectFit: ImageFit.Cover
|
||||
}
|
||||
})
|
||||
} else {
|
||||
Image(this.placeholderSrc)
|
||||
.objectFit(ImageFit.Cover)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Entry
|
||||
@ComponentV2
|
||||
struct TestTaskResourcePage {
|
||||
@Local stateMenus: Array<string> = [
|
||||
'https://hbimg.huabanimg.com/cc6af25f8d782d3cf3122bef4e61571378271145735e9-vEVggB',
|
||||
'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/bf/v3/lSjrRwFcS-ez6jp1ALSQFg/0n7R7XinSPyrYLqDu_1dfw.jpg',
|
||||
'https://img-blog.csdn.net/20140514114029140',
|
||||
'https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp',
|
||||
]
|
||||
@Builder
|
||||
_buildItem(item: string) {
|
||||
Column({ space: 8 }) {
|
||||
ZuImage({
|
||||
src: item,
|
||||
placeholderSrc: $r('app.media.loading')
|
||||
}).width(44)
|
||||
.height(44)
|
||||
}
|
||||
}
|
||||
build() {
|
||||
|
||||
Grid() {
|
||||
ForEach(this.stateMenus, (item: string) => {
|
||||
GridItem() {
|
||||
this._buildItem(item)
|
||||
}
|
||||
})
|
||||
}.width('100%')
|
||||
.columnsTemplate('1fr 1fr 1fr 1fr 1fr')
|
||||
.rowsGap(24)
|
||||
.padding({
|
||||
top: 24,
|
||||
bottom: 24,
|
||||
left: 24,
|
||||
right: 24
|
||||
})
|
||||
}
|
||||
}
|
|
@ -15,55 +15,55 @@
|
|||
import { ImageKnifeComponent,CacheStrategy,ImageKnifeOption } from '@ohos/libraryimageknife'
|
||||
|
||||
@Entry
|
||||
@ComponentV2
|
||||
@Component
|
||||
struct TestWriteCacheStage {
|
||||
@Local imageKnifeOption1: ImageKnifeOption = new ImageKnifeOption({
|
||||
@State imageKnifeOption1: ImageKnifeOption = {
|
||||
loadSrc:$r('app.media.startIcon'),
|
||||
placeholderSrc:$r('app.media.loading'),
|
||||
errorholderSrc:$r('app.media.failed')
|
||||
})
|
||||
@Local imageKnifeOption2: ImageKnifeOption = new ImageKnifeOption({
|
||||
}
|
||||
@State imageKnifeOption2: ImageKnifeOption = {
|
||||
loadSrc:$r('app.media.startIcon'),
|
||||
placeholderSrc:$r('app.media.loading'),
|
||||
errorholderSrc:$r('app.media.failed')
|
||||
})
|
||||
@Local imageKnifeOption3: ImageKnifeOption = new ImageKnifeOption({
|
||||
}
|
||||
@State imageKnifeOption3: ImageKnifeOption = {
|
||||
loadSrc:$r('app.media.startIcon'),
|
||||
placeholderSrc:$r('app.media.loading'),
|
||||
errorholderSrc:$r('app.media.failed')
|
||||
})
|
||||
}
|
||||
|
||||
build() {
|
||||
Column() {
|
||||
Button("写入内存文件缓存").margin({top:10}).onClick(async ()=>{
|
||||
this.imageKnifeOption1 = new ImageKnifeOption({
|
||||
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("写入内存缓存").margin({top:10}).onClick(async ()=>{
|
||||
this.imageKnifeOption2 = new ImageKnifeOption({
|
||||
loadSrc:"https://hbimg.huabanimg.com/cc6af25f8d782d3cf3122bef4e61571378271145735e9-vEVggB",
|
||||
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("写入文件缓存").margin({top:10}).onClick(async ()=>{
|
||||
this.imageKnifeOption3 = new ImageKnifeOption({
|
||||
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
|
||||
|
|
|
@ -12,34 +12,34 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { ImageKnifeComponent, ImageKnifeOption } from "@ohos/libraryimageknife"
|
||||
import { ImageKnifeComponent, ImageKnifeOption } from '@ohos/libraryimageknife'
|
||||
import matrix4 from '@ohos.matrix4'
|
||||
|
||||
|
||||
@Entry
|
||||
@ComponentV2
|
||||
@Component
|
||||
struct TransformPage {
|
||||
private custom_scale:number = 1
|
||||
@Local matrix1:object = matrix4.identity().scale({ x: 1, y: 1 })
|
||||
@Local ImageKnifeOption: ImageKnifeOption = new ImageKnifeOption({
|
||||
loadSrc: $r("app.media.rabbit"),
|
||||
placeholderSrc: $r("app.media.loading"),
|
||||
errorholderSrc: $r("app.media.app_icon"),
|
||||
@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("放大").onClick(()=>{
|
||||
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("缩小").onClick(()=>{
|
||||
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 })
|
||||
})
|
||||
|
|
|
@ -15,50 +15,24 @@
|
|||
import { ImageKnifeComponent, ImageKnifeOption } from '@ohos/libraryimageknife'
|
||||
|
||||
// const logger = new imUtils.logger.IMLogger('Avatar')
|
||||
@ObservedV2
|
||||
export class MyStorage {
|
||||
static instance:MyStorage | undefined = undefined
|
||||
static getInstance(){
|
||||
if(MyStorage.instance == undefined) {
|
||||
MyStorage.instance = new MyStorage()
|
||||
}
|
||||
return MyStorage.instance
|
||||
}
|
||||
@Trace WeLink_Mob_fontSize_multiple: number = 1
|
||||
|
||||
class MyImageOption extends ImageKnifeOption {
|
||||
account?: string
|
||||
}
|
||||
|
||||
@ComponentV2
|
||||
@Component
|
||||
export struct UserAvatar {
|
||||
// @Prop userInfo: string = ""
|
||||
@Prop @Watch('userInfoUpdate') userInfo: string = ''
|
||||
// @Prop userInfo: string = ''
|
||||
imgSize: number = 100
|
||||
radius: number = 12
|
||||
borderSize: number = 0
|
||||
imgSizes: number = 1
|
||||
@Local ImageKnifeOption: ImageKnifeOption = new ImageKnifeOption()
|
||||
@State ImageKnifeOption: ImageKnifeOption = new ImageKnifeOption()
|
||||
@StorageProp('WeLink_Mob_fontSize_multiple') @Watch('updateImgSize') WeLink_Mob_fontSize_multiple: number = 0
|
||||
scalable: boolean = true;
|
||||
@Local calcImgSize: number = 100
|
||||
@Param userInfo: string = ""
|
||||
@Monitor('userInfo')
|
||||
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 = new 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())
|
||||
})
|
||||
}
|
||||
@Local storage: MyStorage = MyStorage.getInstance()
|
||||
@Monitor('storage.WeLink_Mob_fontSize_multiple')
|
||||
updateImgSize() {
|
||||
this.setImageSize()
|
||||
}
|
||||
@State calcImgSize: number = 100
|
||||
|
||||
aboutToAppear(): void {
|
||||
this.userInfoUpdate()
|
||||
this.setImageSize()
|
||||
|
@ -67,19 +41,39 @@ export struct UserAvatar {
|
|||
setImageSize() {
|
||||
if (!this.scalable) {
|
||||
this.calcImgSize = this.imgSize
|
||||
} else if (this.storage.WeLink_Mob_fontSize_multiple < 0.9) {
|
||||
} else if (this.WeLink_Mob_fontSize_multiple < 0.9) {
|
||||
this.calcImgSize = this.imgSize * 0.9
|
||||
} else if (this.storage.WeLink_Mob_fontSize_multiple > 1.6) {
|
||||
} else if (this.WeLink_Mob_fontSize_multiple > 1.6) {
|
||||
this.calcImgSize = this.imgSize * 1.6
|
||||
} else {
|
||||
this.calcImgSize = this.imgSize * this.storage.WeLink_Mob_fontSize_multiple
|
||||
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)
|
||||
|
|
|
@ -12,138 +12,83 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { MyStorage, UserAvatar } from './User'
|
||||
import { CommonDataSource } from './model/CommonDataSource'
|
||||
import { UserAvatar } from './User'
|
||||
|
||||
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)
|
||||
})
|
||||
}
|
||||
}
|
||||
@Entry
|
||||
@ComponentV2
|
||||
@Component
|
||||
struct Index {
|
||||
@Local hotCommendList:CommonDataSource<string> = new CommonDataSource<string>([])
|
||||
@State hotCommendList:CommonDataSource<string> = new CommonDataSource<string>([])
|
||||
private data:string[] = [
|
||||
"http://e.hiphotos.baidu.com/image/pic/item/a1ec08fa513d2697e542494057fbb2fb4316d81e.jpg",
|
||||
"http://c.hiphotos.baidu.com/image/pic/item/30adcbef76094b36de8a2fe5a1cc7cd98d109d99.jpg",
|
||||
"http://h.hiphotos.baidu.com/image/pic/item/7c1ed21b0ef41bd5f2c2a9e953da81cb39db3d1d.jpg",
|
||||
"http://g.hiphotos.baidu.com/image/pic/item/55e736d12f2eb938d5277fd5d0628535e5dd6f4a.jpg",
|
||||
"http://e.hiphotos.baidu.com/image/pic/item/4e4a20a4462309f7e41f5cfe760e0cf3d6cad6ee.jpg",
|
||||
"http://b.hiphotos.baidu.com/image/pic/item/9d82d158ccbf6c81b94575cfb93eb13533fa40a2.jpg",
|
||||
"http://e.hiphotos.baidu.com/image/pic/item/4bed2e738bd4b31c1badd5a685d6277f9e2ff81e.jpg",
|
||||
"http://g.hiphotos.baidu.com/image/pic/item/0d338744ebf81a4c87a3add4d52a6059252da61e.jpg",
|
||||
"http://a.hiphotos.baidu.com/image/pic/item/f2deb48f8c5494ee5080c8142ff5e0fe99257e19.jpg",
|
||||
"http://f.hiphotos.baidu.com/image/pic/item/4034970a304e251f503521f5a586c9177e3e53f9.jpg",
|
||||
"http://b.hiphotos.baidu.com/image/pic/item/279759ee3d6d55fbb3586c0168224f4a20a4dd7e.jpg",
|
||||
"http://img2.xkhouse.com/bbs/hfhouse/data/attachment/forum/corebbs/2009-11/2009113011534566298.jpg",
|
||||
"http://a.hiphotos.baidu.com/image/pic/item/e824b899a9014c087eb617650e7b02087af4f464.jpg",
|
||||
"http://c.hiphotos.baidu.com/image/pic/item/9c16fdfaaf51f3de1e296fa390eef01f3b29795a.jpg",
|
||||
"http://d.hiphotos.baidu.com/image/pic/item/b58f8c5494eef01f119945cbe2fe9925bc317d2a.jpg",
|
||||
"http://h.hiphotos.baidu.com/image/pic/item/902397dda144ad340668b847d4a20cf430ad851e.jpg",
|
||||
"http://b.hiphotos.baidu.com/image/pic/item/359b033b5bb5c9ea5c0e3c23d139b6003bf3b374.jpg",
|
||||
"http://a.hiphotos.baidu.com/image/pic/item/8d5494eef01f3a292d2472199d25bc315d607c7c.jpg",
|
||||
"http://b.hiphotos.baidu.com/image/pic/item/e824b899a9014c08878b2c4c0e7b02087af4f4a3.jpg",
|
||||
"http://g.hiphotos.baidu.com/image/pic/item/6d81800a19d8bc3e770bd00d868ba61ea9d345f2.jpg",
|
||||
"https://hbimg.huabanimg.com/cc6af25f8d782d3cf3122bef4e61571378271145735e9-vEVggB",
|
||||
'https://img-blog.csdnimg.cn/20191215043500229.png',
|
||||
'https://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 {
|
||||
MyStorage.getInstance().WeLink_Mob_fontSize_multiple = 1
|
||||
this.hotCommendList.addData(this.hotCommendList.totalCount(),this.data)
|
||||
AppStorage.set('WeLink_Mob_fontSize_multiple',1)
|
||||
}
|
||||
|
||||
build() {
|
||||
Column() {
|
||||
Button("bigger").onClick(()=>{
|
||||
MyStorage.getInstance().WeLink_Mob_fontSize_multiple = 1.6
|
||||
Button('bigger').onClick(()=>{
|
||||
AppStorage.set('WeLink_Mob_fontSize_multiple',1.6)
|
||||
})
|
||||
Button("small").onClick(()=>{
|
||||
MyStorage.getInstance().WeLink_Mob_fontSize_multiple = 0.8
|
||||
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})
|
||||
// })
|
||||
Repeat(this.data)
|
||||
.each((repeatItem)=>{
|
||||
LazyForEach(this.hotCommendList,(item:string)=>{
|
||||
ListItem(){
|
||||
ReuseImage({
|
||||
userInfo:repeatItem.item
|
||||
}).width("100%").height("100%").backgroundColor(Color.Yellow)
|
||||
}.width(200).height(200).margin({bottom:5}).key("reuse")
|
||||
})
|
||||
.key(item => item+"reuse")
|
||||
.virtualScroll()
|
||||
.template("1",(repeatItem)=>{
|
||||
ListItem(){
|
||||
ReuseImage({
|
||||
userInfo:repeatItem.item
|
||||
}).width("100%").height("100%").backgroundColor(Color.Yellow)
|
||||
}.width(200).height(200).margin({bottom:5}).key("reuse")
|
||||
userInfo:item
|
||||
}).width('100%').height('100%').backgroundColor(Color.Yellow)
|
||||
}.width(200).height(200).margin({bottom:5})
|
||||
})
|
||||
}
|
||||
// .cachedCount(20)
|
||||
.width("100%")
|
||||
.height("100%")
|
||||
.width('100%')
|
||||
.height('100%')
|
||||
.backgroundColor(0xFAEEE0)
|
||||
}.width('100%').height("100%")
|
||||
}.width('100%').height('100%')
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// @Reusable
|
||||
@ComponentV2
|
||||
@Reusable
|
||||
@Component
|
||||
struct ReuseImage {
|
||||
@Param userInfo:string = ""
|
||||
// aboutToReuse(params: ESObject): void {
|
||||
// this.userInfo = params.userInfo
|
||||
// }
|
||||
@State userInfo:string = ''
|
||||
aboutToReuse(params: ESObject): void {
|
||||
this.userInfo = params.userInfo
|
||||
}
|
||||
|
||||
build() {
|
||||
Column(){
|
||||
UserAvatar({
|
||||
userInfo:this.userInfo
|
||||
})
|
||||
}.width("100%").height("100%")
|
||||
}.width('100%').height('100%')
|
||||
}
|
||||
}
|
|
@ -1,13 +1,13 @@
|
|||
/*
|
||||
* Copyright (C) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
|
@ -18,23 +18,23 @@ import { photoAccessHelper } from '@kit.MediaLibraryKit';
|
|||
|
||||
|
||||
@Entry
|
||||
@ComponentV2
|
||||
@Component
|
||||
struct DataShareUriLoadPage {
|
||||
@Local imageKnifeOption1: ImageKnifeOption =
|
||||
new ImageKnifeOption({
|
||||
@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("获取媒体图库的uri用ImageKnife展示").fontSize(15)
|
||||
Text($r('app.string.Retrieve_media_gallery')).fontSize(15)
|
||||
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
||||
Button("点击加载Uri并展示")
|
||||
Button($r('app.string.Click_load_Uri'))
|
||||
.onClick(async () => {
|
||||
let photoSelectOptions = new photoAccessHelper.PhotoSelectOptions();
|
||||
photoSelectOptions.MIMEType = photoAccessHelper.PhotoViewMIMETypes.IMAGE_TYPE;
|
||||
|
@ -43,10 +43,10 @@ struct DataShareUriLoadPage {
|
|||
let photoViewPicker = new photoAccessHelper.PhotoViewPicker();
|
||||
let photoSelectResult: photoAccessHelper.PhotoSelectResult = await photoViewPicker.select(photoSelectOptions);
|
||||
uris = photoSelectResult.photoUris;
|
||||
this.imageKnifeOption1 = new ImageKnifeOption({
|
||||
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)
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Copyright (C) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export class CommonDataSource <T> implements IDataSource {
|
||||
private dataArray: T[] = []
|
||||
private listeners: DataChangeListener[] = []
|
||||
|
||||
constructor(element: []) {
|
||||
this.dataArray = element
|
||||
}
|
||||
|
||||
public getData(index: number) {
|
||||
return this.dataArray[index]
|
||||
}
|
||||
|
||||
public totalCount(): number {
|
||||
return this.dataArray.length
|
||||
}
|
||||
|
||||
public addData(index: number, data: T[]): void {
|
||||
this.dataArray = this.dataArray.concat(data)
|
||||
this.notifyDataAdd(index)
|
||||
}
|
||||
|
||||
unregisterDataChangeListener(listener: DataChangeListener): void {
|
||||
const pos = this.listeners.indexOf(listener);
|
||||
if (pos >= 0) {
|
||||
this.listeners.splice(pos, 1);
|
||||
}
|
||||
}
|
||||
|
||||
registerDataChangeListener(listener: DataChangeListener): void {
|
||||
if (this.listeners.indexOf(listener) < 0) {
|
||||
this.listeners.push(listener)
|
||||
}
|
||||
}
|
||||
|
||||
notifyDataAdd(index: number): void {
|
||||
this.listeners.forEach((listener: DataChangeListener) => {
|
||||
listener.onDataAdd(index)
|
||||
})
|
||||
}
|
||||
}
|
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
* Copyright (C) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import {ImageKnife, ImageKnifeRequest} from '@ohos/libraryimageknife'
|
||||
import { IDataSourcePrefetching } from '@kit.ArkUI';
|
||||
import { HashMap } from '@kit.ArkTS';
|
||||
|
||||
const IMADE_UNAVAILABLE = $r('app.media.failed')
|
||||
export interface InfoItem {
|
||||
albumUrl: string | Resource
|
||||
}
|
||||
export default class DataSourcePrefetchingImageKnife implements IDataSourcePrefetching {
|
||||
private dataArray: Array<InfoItem>
|
||||
private readonly requestList: HashMap<number,ImageKnifeRequest> = new HashMap()
|
||||
private listeners: DataChangeListener[] = [];
|
||||
|
||||
constructor(dataArray: Array<InfoItem>) {
|
||||
this.dataArray = dataArray;
|
||||
}
|
||||
public getData(index: number) {
|
||||
return this.dataArray[index]
|
||||
}
|
||||
|
||||
public totalCount(): number {
|
||||
return this.dataArray.length
|
||||
}
|
||||
|
||||
public addData(index: number, data: InfoItem[]): void {
|
||||
this.dataArray = this.dataArray.concat(data)
|
||||
this.notifyDataAdd(index)
|
||||
}
|
||||
|
||||
unregisterDataChangeListener(listener: DataChangeListener): void {
|
||||
const pos = this.listeners.indexOf(listener);
|
||||
if (pos >= 0) {
|
||||
this.listeners.splice(pos, 1);
|
||||
}
|
||||
}
|
||||
|
||||
registerDataChangeListener(listener: DataChangeListener): void {
|
||||
if (this.listeners.indexOf(listener) < 0) {
|
||||
this.listeners.push(listener)
|
||||
}
|
||||
}
|
||||
|
||||
notifyDataAdd(index: number): void {
|
||||
this.listeners.forEach((listener: DataChangeListener) => {
|
||||
listener.onDataAdd(index)
|
||||
})
|
||||
}
|
||||
async prefetch(index: number): Promise<void> {
|
||||
let item = this.dataArray[index]
|
||||
if (typeof item.albumUrl == 'string') {
|
||||
// 图片预加载
|
||||
let request = ImageKnife.getInstance().preload({
|
||||
loadSrc:item.albumUrl,
|
||||
onLoadListener:{
|
||||
onLoadSuccess:()=>{
|
||||
// 预加载成功,删除成功请求
|
||||
this.requestList.remove(index)
|
||||
},
|
||||
onLoadFailed:()=>{
|
||||
// 移除失败请求
|
||||
this.requestList.remove(index)
|
||||
}
|
||||
}
|
||||
})
|
||||
this.requestList.set(index,request)
|
||||
}
|
||||
}
|
||||
// 取消请求处理
|
||||
cancel(index: number) {
|
||||
if(this.requestList.hasKey(index)) {
|
||||
// 返回MAP对象指定元素
|
||||
const request = this.requestList.get(index)
|
||||
// 取消请求
|
||||
ImageKnife.getInstance().cancel(request)
|
||||
// 移除被取消的请求对象
|
||||
this.requestList.remove(index)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,146 @@
|
|||
/*
|
||||
* Copyright (C) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { InfoItem } from './DataSourcePrefetching'
|
||||
|
||||
export class PageViewModel {
|
||||
private static dataArray: Array<InfoItem> = [
|
||||
{
|
||||
albumUrl: 'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/56/v3/8MdhfSsCSMKj4sA6okUWrg/5uBx56tLTUO3RYQl-E5JiQ.jpg'
|
||||
},
|
||||
{
|
||||
albumUrl: 'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/e2/v3/4zI1Xm_3STmV30aZXWRrKw/6aN7WodDRUiBApgffiLPCg.jpg'
|
||||
},
|
||||
{
|
||||
albumUrl: 'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/42/v3/2dSQCqERTP2TTPyssOMEbQ/zL1ebnKKQ_ilqTDcwCAkOw.jpg'
|
||||
},
|
||||
{
|
||||
albumUrl: 'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/78/v3/qQJpAtRGQe2e_VhbGHDgIw/b3zlit99S6GybD3XdNwqJw.jpg'
|
||||
},
|
||||
{
|
||||
albumUrl: 'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/55/v3/5DZ2LLqYSsK85-shqgLveQ/7ZXcyCWNTvOzQP5FFLBGkg.jpg'
|
||||
},
|
||||
{
|
||||
albumUrl: 'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/3e/v3/LqRoLI-PRSu9Nqa8KdJ-pQ/dSqskBpSR9eraAMn7NBdqA.jpg'
|
||||
},
|
||||
{
|
||||
albumUrl: 'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/25/v3/jgB2ekkTRX-3yTYZalnANQ/xff_x9cbSPqb7fbNwgJa7A.jpg'
|
||||
},
|
||||
{
|
||||
albumUrl: 'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/fb/v3/alXwXLHKSyCAIWt_ydgD2g/BCCuu25TREOitQxM7eYOEw.jpg'
|
||||
},
|
||||
{
|
||||
albumUrl: 'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/63/v3/qbe6NZkCQyGcITvdWoZBgg/Y-5U1z3GT_yaK8CBD3jkwg.jpg'
|
||||
},
|
||||
{
|
||||
albumUrl: 'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/16/v3/fm2tO4TsRH6mv_D_nSSd5w/FscLpLwQQ-KuV7oaprFK2Q.jpg'
|
||||
},
|
||||
{
|
||||
albumUrl: 'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/89/v3/UAUvtPHqRD-GWWANsEC57Q/zcRJCQebQ322Aby4jzmwmQ.jpg'
|
||||
},
|
||||
{
|
||||
albumUrl: 'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/30/v3/tUUzzx73R4yp8G--lMhuWQ/EBbcu_dLTT-Jj68XAh6mtA.jpg'
|
||||
},
|
||||
{
|
||||
albumUrl: 'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/76/v3/EyF6z4FISpCHhae38eEexw/OtyAiu-zSSevNQYvUdtVmA.jpg'
|
||||
},
|
||||
{
|
||||
albumUrl: 'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/37/v3/12rH1yiEQmK9wlOOcy5avQ/RzBXiEBRRqOC7LRkwNj6VA.jpg'
|
||||
},
|
||||
{
|
||||
albumUrl: 'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/9a/v3/TpRN4AIzRoyUXIqWdKoE0g/ShOnD_tfS46HDbpSWhbCkQ.jpg'
|
||||
},
|
||||
{
|
||||
albumUrl: 'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/03/v3/H3X17s8eTdS2w56JgbB5jQ/a45sT-j8Sbe8sSQXTzeYvQ.jpg'
|
||||
},
|
||||
{
|
||||
albumUrl: 'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/10/v3/qaEzwkU0QeKb1yehnP2Xig/q7fxAlgMQKup-HUBayRLGQ.jpg'
|
||||
},
|
||||
{
|
||||
albumUrl: 'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/96/v3/rMJJoAflTDSWa1z2pHs2wg/8dOqD0GlQBOCL5AvQok9FQ.jpg'
|
||||
},
|
||||
{
|
||||
albumUrl: 'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/ed/v3/KMO4D6D2QGuVOCLX4AhOFA/ef51xAaLQuK7BsnuD9abog.jpg'
|
||||
},
|
||||
{
|
||||
albumUrl: 'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/d9/v3/FSZH0aTdSqWxeAaxoPvi0g/RqxPxUCXQFiTMBfKTF9kkw.jpg'
|
||||
},
|
||||
{
|
||||
albumUrl: 'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/bf/v3/lSjrRwFcS-ez6jp1ALSQFg/0n7R7XinSPyrYLqDu_1dfw.jpg'
|
||||
},
|
||||
{
|
||||
albumUrl: 'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/8a/v3/ZKzYV5BJTuCk5hCE0y_xNA/8JT95OQnSZSd6_xQQUONhQ.jpg'
|
||||
},
|
||||
{
|
||||
albumUrl: 'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/1/v3/sTXb_I7URBKjdMyLDYa19w/qpcwa_FNQmi3-EzjbGsJ8A.jpg'
|
||||
},
|
||||
{
|
||||
albumUrl: 'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/e5/v3/m7wFvw_eQIuDV0Mk0IKi8g/gJU4migzTHKYk5KrgdZbBw.jpg'
|
||||
},
|
||||
{
|
||||
albumUrl: 'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/3f/v3/k_UWbB5_RGW7JemQZ0OQdw/_DUdmaZRQyG-Oyvkb663Bw.jpg'
|
||||
},
|
||||
{
|
||||
albumUrl: 'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/39/v3/rFRN7G_VSo-p4mBjTZtkRw/gBwTI-ieSIqSsSmLNBEcgw.jpg'
|
||||
},
|
||||
{
|
||||
albumUrl: 'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/04/v3/6K8BPYKVQFOr7KCuAG9nog/qKd3pZlrQy2M-feB3ycVPA.jpg'
|
||||
},
|
||||
{
|
||||
albumUrl: 'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/7d/v3/f0GQFzm1T6eduVeMUhO3Wg/-4cvzIJiRCegjIno3ofIbQ.jpg'
|
||||
},
|
||||
{
|
||||
albumUrl: 'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/e4/v3/C0xxsSeySxW-2iYR5OEbpQ/f1GlaD3zTeKPX8Vd-M1oVQ.jpg'
|
||||
},
|
||||
{
|
||||
albumUrl: 'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/c2/v3/32LCyXN4TuWKWcdf9gAwWw/ej14_BCJQNCaWOKoI9aZAw.jpg'
|
||||
},
|
||||
{
|
||||
albumUrl: 'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/fd/v3/LyYJMdMmQNaC5GyBYEZ5Pw/uFLiovypRSagKyIS-UJPVw.jpg'
|
||||
},
|
||||
{
|
||||
albumUrl: 'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/15/v3/MHM9KaWGTgubn6M8-B_6nw/1YO9JyYhTHSBWsoiqYkGZw.jpg'
|
||||
},
|
||||
{
|
||||
albumUrl: 'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/4c/v3/UdYfbv1_QYqn_ulDHp89OA/VkjexMluTqGO3yt3gPK1DA.jpg'
|
||||
},
|
||||
{
|
||||
albumUrl: 'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/e8/v3/N8blT_7qSK-tRtahIyov7g/M_kjGEEmSzOlTc47Zrfozg.jpg'
|
||||
},
|
||||
{
|
||||
albumUrl: 'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/28/v3/VS_h3m4YRrSgbgxnqE3vtQ/h-2Q1Qy2SSGEuXM36-Rq_w.jpg'
|
||||
},
|
||||
{
|
||||
albumUrl: 'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/2e/v3/R-BaM5ToRNGq5rwtNTcnww/Q2e01VHiR2y9KtFaZmpmNQ.jpg'
|
||||
},
|
||||
{
|
||||
albumUrl: 'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/88/v3/3djkAJKKTdC539XqMdstSg/wHO7DxvXQS2xbt2Y_-4BNg.jpg'
|
||||
},
|
||||
{
|
||||
albumUrl: 'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/fb/v3/guw4eiggR3uWjscFTxITYg/TzRB35iPTdCztrZUUaNuFg.jpg'
|
||||
},
|
||||
{
|
||||
albumUrl: 'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/93/v3/UvSh_f1LT66i0-3hvsYN_A/eYnE3Z8YT5Sk7F-vS2ZmCQ.jpg'
|
||||
},
|
||||
{
|
||||
albumUrl: 'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/5/v3/tv8Vqf9hQrKpozGeZWg2mw/VEICB-bmQYi0Iv6TGADbhw.jpg'
|
||||
},
|
||||
{
|
||||
albumUrl: 'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/30/v3/4v1Ot5BRR6OFVQ9MGn9Xxg/xrPgRn0LS1ep-r7ewIuwiw.jpg'
|
||||
},
|
||||
]
|
||||
static getItems() {
|
||||
return PageViewModel.dataArray
|
||||
}
|
||||
}
|
|
@ -6,7 +6,11 @@
|
|||
"mainElement": "EntryAbility",
|
||||
"deviceTypes": [
|
||||
"default",
|
||||
"tablet"
|
||||
"tablet",
|
||||
"tv",
|
||||
"wearable",
|
||||
"car",
|
||||
"2in1"
|
||||
],
|
||||
"deliveryWithInstall": true,
|
||||
"installationFree": false,
|
||||
|
@ -42,6 +46,15 @@
|
|||
],
|
||||
"when": "always"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "ohos.permission.GET_NETWORK_INFO",
|
||||
"usedScene": {
|
||||
"abilities": [
|
||||
"EntryAbility"
|
||||
],
|
||||
"when": "always"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
@ -19,6 +19,694 @@
|
|||
{
|
||||
"name": "app_permission_READ_IMAGEVIDEO",
|
||||
"value": "获取读媒体资源权限"
|
||||
},
|
||||
{
|
||||
"name": "Test_ImageAnimator",
|
||||
"value": "Test ImageAnimator component"
|
||||
},
|
||||
{
|
||||
"name": "Test_multiple_images",
|
||||
"value": "Test loading multiple identical images"
|
||||
},
|
||||
{
|
||||
"name": "Test_Task_error",
|
||||
"value": "Test placeholder map Task error"
|
||||
},
|
||||
{
|
||||
"name": "Test_HSP",
|
||||
"value": "Test HSP scene preloading"
|
||||
},
|
||||
{
|
||||
"name": "Test_SingleImage",
|
||||
"value": "SingleImage"
|
||||
},
|
||||
{
|
||||
"name": "Test_LocalImageShow",
|
||||
"value": "LocalImageShow"
|
||||
},
|
||||
{
|
||||
"name": "Test_custom_download",
|
||||
"value": "Global custom download"
|
||||
},
|
||||
{
|
||||
"name": "Multiple_images",
|
||||
"value": "Multiple images"
|
||||
},
|
||||
{
|
||||
"name": "Display_long_image",
|
||||
"value": "Display long image"
|
||||
},
|
||||
{
|
||||
"name": "Image_scaling",
|
||||
"value": "Image scaling"
|
||||
},
|
||||
{
|
||||
"name": "Message_list",
|
||||
"value": "Message list"
|
||||
},
|
||||
{
|
||||
"name": "Custom_cache_key",
|
||||
"value": "Custom cache key"
|
||||
},
|
||||
{
|
||||
"name": "Preloading_images_to_cache",
|
||||
"value": "Preloading images to file cache"
|
||||
},
|
||||
{
|
||||
"name": "Retrieve_image_display_from_cache",
|
||||
"value": "Retrieve image display from cache"
|
||||
},
|
||||
{
|
||||
"name": "Test_single_request_header",
|
||||
"value": "Test a single request header"
|
||||
},
|
||||
{
|
||||
"name": "Test_write_cache_strategy",
|
||||
"value": "Test write cache strategy"
|
||||
},
|
||||
{
|
||||
"name": "Image_Transformation",
|
||||
"value": "Image Transformation"
|
||||
},
|
||||
{
|
||||
"name": "Different_ObjectFit",
|
||||
"value": "Different ObjectFit"
|
||||
},
|
||||
{
|
||||
"name": "Test_image_loading_success_or_failure_events",
|
||||
"value": "Test image loading success/failure events"
|
||||
},
|
||||
{
|
||||
"name": "Test_removing_image_cache_interface",
|
||||
"value": "Test removing image cache interface"
|
||||
},
|
||||
{
|
||||
"name": "Test_error_image_display",
|
||||
"value": "Test error image display"
|
||||
},
|
||||
{
|
||||
"name": "Test_media_URL",
|
||||
"value": "Test media URL"
|
||||
},
|
||||
{
|
||||
"name": "Display_the_first_frame",
|
||||
"value": "first frame"
|
||||
},
|
||||
{
|
||||
"name": "Display_the_last_frame",
|
||||
"value": "last frame"
|
||||
},
|
||||
{
|
||||
"name": "Play",
|
||||
"value": "Play"
|
||||
},
|
||||
{
|
||||
"name": "Pause",
|
||||
"value": "Pause"
|
||||
},
|
||||
{
|
||||
"name": "Stop",
|
||||
"value": "Stop"
|
||||
},
|
||||
{
|
||||
"name": "Infinite_loop",
|
||||
"value": "Infinite loop"
|
||||
},
|
||||
{
|
||||
"name": "Play_once",
|
||||
"value": "Play once"
|
||||
},
|
||||
{
|
||||
"name": "Play_twice",
|
||||
"value": "Play twice"
|
||||
},
|
||||
{
|
||||
"name": "Local_SVG",
|
||||
"value": "Local SVG image"
|
||||
},
|
||||
{
|
||||
"name": "local_r_file",
|
||||
"value": "Local $r file"
|
||||
},
|
||||
{
|
||||
"name": "local_rawfile",
|
||||
"value": "Local rawfile"
|
||||
},
|
||||
{
|
||||
"name": "Under_context_file",
|
||||
"value": "Files under context file"
|
||||
},
|
||||
{
|
||||
"name": "local_other_module",
|
||||
"value": "Local other module"
|
||||
},
|
||||
{
|
||||
"name": "in_other_module",
|
||||
"value": "in other module"
|
||||
},
|
||||
{
|
||||
"name": "Network_images",
|
||||
"value": "Network images"
|
||||
},
|
||||
{
|
||||
"name": "Custom_network_download",
|
||||
"value": "Custom network download"
|
||||
},
|
||||
{
|
||||
"name": "PixelMap_loads_images",
|
||||
"value": "PixelMap loads images"
|
||||
},
|
||||
{
|
||||
"name": "Enlarge",
|
||||
"value": "Enlarge"
|
||||
},
|
||||
{
|
||||
"name": "Reduce",
|
||||
"value": "Reduce"
|
||||
},
|
||||
{
|
||||
"name": "Click_on_add",
|
||||
"value": "Click on the size to add 50"
|
||||
},
|
||||
{
|
||||
"name": "Click_on_reduce",
|
||||
"value": "Click to reduce size by 50"
|
||||
},
|
||||
{
|
||||
"name": "The_key_fixed_1",
|
||||
"value": "The key is fixed at 1"
|
||||
},
|
||||
{
|
||||
"name": "The_key_changes_timestamp",
|
||||
"value": "Key changes every time: timestamp"
|
||||
},
|
||||
{
|
||||
"name": "Load",
|
||||
"value": "Load"
|
||||
},
|
||||
{
|
||||
"name": "Preloading_images_to_file_cache_using_URL",
|
||||
"value": "Preloading images to file cache using URL"
|
||||
},
|
||||
{
|
||||
"name": "Preloading_images_to_file_cache_using_option",
|
||||
"value": "Preloading images to file cache using option"
|
||||
},
|
||||
{
|
||||
"name": "Load_image_offline_after_preloading",
|
||||
"value": "Load image (can be loaded offline after preloading)"
|
||||
},
|
||||
{
|
||||
"name": "Preloading_GIF",
|
||||
"value": "Preloading GIF"
|
||||
},
|
||||
{
|
||||
"name": "Retrieve_GIF_from_memory",
|
||||
"value": "Retrieve GIF from memory cache"
|
||||
},
|
||||
{
|
||||
"name": "Retrieve_GIF_from_disk",
|
||||
"value": "Retrieve GIF from disk cache"
|
||||
},
|
||||
{
|
||||
"name": "Preloading_static_images",
|
||||
"value": "Preloading static images"
|
||||
},
|
||||
{
|
||||
"name": "Retrieve_images_from_memory",
|
||||
"value": "Retrieve images from memory cache"
|
||||
},
|
||||
{
|
||||
"name": "Retrieve_images_from_disk",
|
||||
"value": "Retrieve images from memory disk"
|
||||
},
|
||||
{
|
||||
"name": "Write_memory_and_file",
|
||||
"value": "Write to memory and file cache"
|
||||
},
|
||||
{
|
||||
"name": "Write_memory",
|
||||
"value": "Write to memory cache"
|
||||
},
|
||||
{
|
||||
"name": "Write_file",
|
||||
"value": "Write to file cache"
|
||||
},
|
||||
{
|
||||
"name": "Main_image_Fill",
|
||||
"value": "Main image Fill Stretch Fill"
|
||||
},
|
||||
{
|
||||
"name": "Maintain_proportion_filling",
|
||||
"value": "Maintain proportion filling in the placeholder map 'Include'"
|
||||
},
|
||||
{
|
||||
"name": "Error_graph_None",
|
||||
"value": "Error graph None remains unchanged"
|
||||
},
|
||||
{
|
||||
"name": "Test_failure_success",
|
||||
"value": "Test failure/success"
|
||||
},
|
||||
{
|
||||
"name": "Custom_download_failed",
|
||||
"value": "Custom download failed"
|
||||
},
|
||||
{
|
||||
"name": "Retrieve_media_gallery",
|
||||
"value": "Retrieve the URI of the media gallery and display it using ImageKnife"
|
||||
},
|
||||
{
|
||||
"name": "Click_load_Uri",
|
||||
"value": "Click to load Uri and display"
|
||||
},
|
||||
{
|
||||
"name": "Delete_all_caches",
|
||||
"value": "Delete all caches"
|
||||
},
|
||||
{
|
||||
"name": "Delete_all_memory_caches",
|
||||
"value": "Delete all memory caches"
|
||||
},
|
||||
{
|
||||
"name": "Delete_all_file_caches",
|
||||
"value": "Delete all file caches"
|
||||
},
|
||||
{
|
||||
"name": "Delete_all_custom_memory_caches",
|
||||
"value": "Delete all custom memory caches"
|
||||
},
|
||||
{
|
||||
"name": "Delete_all_custom_file_caches",
|
||||
"value": "Delete all custom file caches"
|
||||
},
|
||||
{
|
||||
"name": "Blur_effect",
|
||||
"value": "Blur effect"
|
||||
},
|
||||
{
|
||||
"name": "Highlighting_effect",
|
||||
"value": "Highlighting effect"
|
||||
},
|
||||
{
|
||||
"name": "Ashing_effect",
|
||||
"value": "Ashing effect"
|
||||
},
|
||||
{
|
||||
"name": "Inverse_effect",
|
||||
"value": "Inverse effect"
|
||||
},
|
||||
{
|
||||
"name": "Animation_filter_effect",
|
||||
"value": "Animation filter effect"
|
||||
},
|
||||
{
|
||||
"name": "Crop_circular_effect",
|
||||
"value": "Crop circular effect"
|
||||
},
|
||||
{
|
||||
"name": "Crop_circular_with_border_effect",
|
||||
"value": "Crop circular with border effect"
|
||||
},
|
||||
{
|
||||
"name": "Contrast_effect",
|
||||
"value": "Contrast effect"
|
||||
},
|
||||
{
|
||||
"name": "Black_ink_filtering_effect",
|
||||
"value": "Black ink filtering effect"
|
||||
},
|
||||
{
|
||||
"name": "Rotate",
|
||||
"value": "Rotate"
|
||||
},
|
||||
{
|
||||
"name": "Corners",
|
||||
"value": "Corners"
|
||||
},
|
||||
{
|
||||
"name": "Kuwahara_Filter_effect",
|
||||
"value": "Kuwahara filter effect"
|
||||
},
|
||||
{
|
||||
"name": "Pixelated_Filter_effect",
|
||||
"value": "Pixelated filtering effect"
|
||||
},
|
||||
{
|
||||
"name": "Sketch_Filter_effect",
|
||||
"value": "Sketch Filter effect"
|
||||
},
|
||||
{
|
||||
"name": "Distortion_Filter_effect",
|
||||
"value": "Distortion Filter effect"
|
||||
},
|
||||
{
|
||||
"name": "Decorative_Filter_effect",
|
||||
"value": "Decorative Filter effect"
|
||||
},
|
||||
{
|
||||
"name": "Square_cutting_effect",
|
||||
"value": "Square cutting effect"
|
||||
},
|
||||
{
|
||||
"name": "Top_cutting_effect",
|
||||
"value": "Top cutting effect"
|
||||
},
|
||||
{
|
||||
"name": "Middle_cutting_effect",
|
||||
"value": "Middle cutting effect"
|
||||
},
|
||||
{
|
||||
"name": "Bottom_cutting_effect",
|
||||
"value": "Bottom cutting effect"
|
||||
},
|
||||
{
|
||||
"name": "Mask_effect",
|
||||
"value": "Mask effect"
|
||||
},
|
||||
{
|
||||
"name": "TIPS",
|
||||
"value": "Please shut down the network first and ensure that there is no cache of images from this network in the test failure scenario locally"
|
||||
},
|
||||
{
|
||||
"name": "Network_reload",
|
||||
"value": "Network recovery reload"
|
||||
},
|
||||
{
|
||||
"name": "preloading_prefetch",
|
||||
"value": "Dynamic preloading prefetch"
|
||||
},
|
||||
{
|
||||
"name": "image_format",
|
||||
"value": "picture format:%s"
|
||||
},
|
||||
{
|
||||
"name": "image_width",
|
||||
"value": "image width:%d"
|
||||
},
|
||||
{
|
||||
"name": "image_height",
|
||||
"value": "image height:%d"
|
||||
},
|
||||
{
|
||||
"name": "cur_cache_limit",
|
||||
"value": "%s:current cache limit:%fM"
|
||||
},
|
||||
{
|
||||
"name": "cur_cache_image_num",
|
||||
"value": "%s:current cache image number:%d"
|
||||
},
|
||||
{
|
||||
"name": "cur_cache_size",
|
||||
"value": "%s:current cache size:%fM"
|
||||
},
|
||||
{
|
||||
"name": "load_memory",
|
||||
"value": "memory loaded picture"
|
||||
},
|
||||
{
|
||||
"name": "load_disk",
|
||||
"value": "disk cache loads images"
|
||||
},
|
||||
{
|
||||
"name": "get_cur_memory_limit",
|
||||
"value": "gets the current memory cache upper limit"
|
||||
},
|
||||
{
|
||||
"name": "get_img_number_of_cache",
|
||||
"value": "gets the number of images cached in memory"
|
||||
},
|
||||
{
|
||||
"name": "get_cur_memory_size",
|
||||
"value": "gets the size of the current cache"
|
||||
},
|
||||
{
|
||||
"name": "get_cur_disk_limit",
|
||||
"value": "Gets the current disk cache upper limit"
|
||||
},
|
||||
{
|
||||
"name": "get_img_number_of_disk",
|
||||
"value": "gets the number of images cached on disk"
|
||||
},
|
||||
{
|
||||
"name": "get_cur_disk_size",
|
||||
"value": "gets the size of the current disk"
|
||||
},
|
||||
{
|
||||
"name": "select_color_btn",
|
||||
"value": "click to select the color you want to change"
|
||||
},
|
||||
{
|
||||
"name": "click_img_to_change_color",
|
||||
"value": "click on the image to change the image color"
|
||||
},
|
||||
{
|
||||
"name": "test_non_svg_color",
|
||||
"value": "test non-SVG images for color change"
|
||||
},
|
||||
{
|
||||
"name": "test_svg_color",
|
||||
"value": "Test svg picture color change"
|
||||
},
|
||||
{
|
||||
"name": "red",
|
||||
"value": "red"
|
||||
},
|
||||
{
|
||||
"name": "yellow",
|
||||
"value": "yellow"
|
||||
},
|
||||
{
|
||||
"name": "green",
|
||||
"value": "green"
|
||||
},
|
||||
{
|
||||
"name": "blue",
|
||||
"value": "blue"
|
||||
},
|
||||
{
|
||||
"name": "master_image",
|
||||
"value": "master image:"
|
||||
},
|
||||
{
|
||||
"name": "rm_component_of_net",
|
||||
"value": "remove Component - Network load picture"
|
||||
},
|
||||
{
|
||||
"name": "rm_component_of_local",
|
||||
"value": "remove Component - Local resource picture"
|
||||
},
|
||||
{
|
||||
"name": "component_display",
|
||||
"value": "recovery component display"
|
||||
},
|
||||
{
|
||||
"name": "onLoadCancel_reason",
|
||||
"value": "onLoadCancel callback reason:%s"
|
||||
},
|
||||
{
|
||||
"name": "test_cache_btn",
|
||||
"value": "test data for in cache"
|
||||
},
|
||||
{
|
||||
"name": "test_change_color_btn",
|
||||
"value": "test change color for image"
|
||||
},
|
||||
{
|
||||
"name": "test_cancel_callback_btn",
|
||||
"value": "test callback of cancel"
|
||||
},
|
||||
{
|
||||
"name": "memory",
|
||||
"value": "Memory"
|
||||
},
|
||||
{
|
||||
"name": "disk",
|
||||
"value": "Disk"
|
||||
},
|
||||
{
|
||||
"name": "Customize_RCP_network",
|
||||
"value": "Customize RCP network request"
|
||||
},
|
||||
{
|
||||
"name": "request_concurrency",
|
||||
"value": "Set request concurrency"
|
||||
},
|
||||
{
|
||||
"name": "test_callback",
|
||||
"value": "test callback data of load pic"
|
||||
},
|
||||
{
|
||||
"name": "gif",
|
||||
"value": "gif"
|
||||
},
|
||||
{
|
||||
"name": "local_pic",
|
||||
"value": "local picture"
|
||||
},
|
||||
{
|
||||
"name": "share_pic",
|
||||
"value": "share picture"
|
||||
},
|
||||
{
|
||||
"name": "net_load_failed",
|
||||
"value": "netWork load failed"
|
||||
},
|
||||
{
|
||||
"name": "local_load_failed",
|
||||
"value": "local load failed"
|
||||
},
|
||||
{
|
||||
"name": "share_load_failed",
|
||||
"value": "shared load failed"
|
||||
},
|
||||
{
|
||||
"name": "list_pic",
|
||||
"value": "load picture list"
|
||||
},
|
||||
{
|
||||
"name": "img_url",
|
||||
"value": "url of the service setting:%s"
|
||||
},
|
||||
{
|
||||
"name": "img_format",
|
||||
"value": "picture format:%s"
|
||||
},
|
||||
{
|
||||
"name": "img_master_size",
|
||||
"value": "the original width and height of the picture-w:%d ,h:%d, size:%d"
|
||||
},
|
||||
{
|
||||
"name": "componentWH",
|
||||
"value": "component width and height-w:%d ,h:%d "
|
||||
},
|
||||
{
|
||||
"name": "img_frame",
|
||||
"value": "the frames of the animator:%d "
|
||||
},
|
||||
{
|
||||
"name": "img_content_size",
|
||||
"value": "decoded width and height size of image:%s "
|
||||
},
|
||||
{
|
||||
"name": "err_msg",
|
||||
"value": "error message:%s "
|
||||
},
|
||||
{
|
||||
"name": "err_phase",
|
||||
"value": "error phase:%s "
|
||||
},
|
||||
{
|
||||
"name": "err_code",
|
||||
"value": "error code:%d "
|
||||
},
|
||||
{
|
||||
"name": "http_code",
|
||||
"value": "http code:%d "
|
||||
},
|
||||
{
|
||||
"name": "req_start_time",
|
||||
"value": "request start time:%s "
|
||||
},
|
||||
{
|
||||
"name": "req_end_time",
|
||||
"value": "request end time:%s "
|
||||
},
|
||||
{
|
||||
"name": "req_cancel_time",
|
||||
"value": "request cancel time:%s "
|
||||
},
|
||||
{
|
||||
"name": "memory_start_time",
|
||||
"value": "start checking the memory cache point in time:%s "
|
||||
},
|
||||
{
|
||||
"name": "memory_end_time",
|
||||
"value": "end Check the memory cache time point:%s "
|
||||
},
|
||||
{
|
||||
"name": "disk_start_time",
|
||||
"value": "start checking the disk cache point in time:%s "
|
||||
},
|
||||
{
|
||||
"name": "disk_end_time",
|
||||
"value": "end Check the disk cache time point:%s "
|
||||
},
|
||||
{
|
||||
"name": "net_start_time",
|
||||
"value": "start time of the network request:%s "
|
||||
},
|
||||
{
|
||||
"name": "net_end_time",
|
||||
"value": "end time of the network request:%s:%s "
|
||||
},
|
||||
{
|
||||
"name": "decode_start_time",
|
||||
"value": "decoding start time point:%s "
|
||||
},
|
||||
{
|
||||
"name": "decode_end_time",
|
||||
"value": "decoding end time point:%s "
|
||||
},
|
||||
{
|
||||
"name": "request_data_from",
|
||||
"value": "request from:%s "
|
||||
},
|
||||
{
|
||||
"name": "Image_Downsampling_Functionality",
|
||||
"value": "Downsampling function"
|
||||
},
|
||||
{
|
||||
"name": "Sampling_pecification",
|
||||
"value": "Downsampling specification"
|
||||
},
|
||||
{
|
||||
"name": "Unreal_samples",
|
||||
"value": "Unsampled size"
|
||||
},
|
||||
{
|
||||
"name": "After_the_sampling",
|
||||
"value": "Size after downsampling"
|
||||
},
|
||||
{
|
||||
"name": "adjust_size",
|
||||
"value": "Adjust size"
|
||||
},
|
||||
{
|
||||
"name": "Auto_ImageFit",
|
||||
"value": "ImageFit.Auto:Auto ImageFit Height"
|
||||
},
|
||||
{
|
||||
"name": "Single_CallBack",
|
||||
"value": "Single image callback"
|
||||
},
|
||||
{
|
||||
"name": "Multiple_CallBack",
|
||||
"value": "Multiple image callback"
|
||||
},
|
||||
{
|
||||
"name": "Error_Message",
|
||||
"value": "error message"
|
||||
},
|
||||
{
|
||||
"name": "test_exif",
|
||||
"value": "Test display orientation base on the EXIF metadata "
|
||||
},
|
||||
{
|
||||
"name": "base_image",
|
||||
"value": "The image don't carry rotation information"
|
||||
},
|
||||
{
|
||||
"name": "rotate_mirror",
|
||||
"value": "Mirror horizontal"
|
||||
},
|
||||
{
|
||||
"name": "rotate_rotate90",
|
||||
"value": "Rotate 90°"
|
||||
},
|
||||
{
|
||||
"name": "rotate_mirror_rotate270",
|
||||
"value": "Mirror horizontal and rotate 270°"
|
||||
}
|
||||
]
|
||||
}
|
After Width: | Height: | Size: 3.4 KiB |
|
@ -0,0 +1,14 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<title>svg细图标</title>
|
||||
<g id="细图标" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="dot_radiowaves_left_and_right" fill="#000000" fill-rule="nonzero">
|
||||
<rect id="矩形" opacity="0" x="0" y="0" width="24" height="24"></rect>
|
||||
<g id="编组" transform="translate(0.000000, 3.000000)" fill-opacity="0.90196079">
|
||||
<path d="M12,7.01 C11.44,7.01 10.9633333,7.20666667 10.57,7.6 C10.1766667,7.98666667 9.98,8.45333333 9.98,9 C9.98,9.54666667 10.18,10.02 10.58,10.42 C10.98,10.82 11.4533333,11.02 12,11.02 C12.5466667,11.02 13.0133333,10.8233333 13.4,10.43 C13.7933333,10.0366667 13.99,9.56 13.99,9 C13.99,8.44 13.8,7.96666667 13.42,7.58 C13.0333333,7.2 12.56,7.01 12,7.01 Z" id="路径"></path>
|
||||
<path d="M5.23,9 C5.23,10.1533333 5.50666667,11.2333333 6.06,12.24 C6.61333333,13.2466667 7.37666667,14.0633333 8.35,14.69 C8.53,14.8033333 8.72,14.8333333 8.92,14.78 C9.12,14.7333333 9.27333333,14.6233333 9.38,14.45 C9.49333333,14.27 9.52666667,14.08 9.48,13.88 C9.43333333,13.68 9.33,13.5266667 9.17,13.42 C8.41666667,12.92 7.82333333,12.2833333 7.39,11.51 C6.95666667,10.73 6.74,9.89333333 6.74,9 C6.74,8.10666667 6.95333333,7.26666667 7.38,6.48 C7.80666667,5.69333333 8.40333333,5.05333333 9.17,4.56 C9.34333333,4.44666667 9.45,4.29 9.49,4.09 C9.53,3.89 9.49333333,3.70333333 9.38,3.53 C9.27333333,3.35 9.12,3.23666667 8.92,3.19 C8.72,3.14333333 8.53,3.18333333 8.35,3.31 C7.37666667,3.93666667 6.61333333,4.75 6.06,5.75 C5.50666667,6.75 5.23,7.83333333 5.23,9 Z M14.59,14.45 C14.7033333,14.6233333 14.8533333,14.7333333 15.04,14.78 C15.22,14.8333333 15.4233333,14.8033333 15.65,14.69 C16.29,14.27 16.84,13.7666667 17.3,13.18 C17.7666667,12.5866667 18.1233333,11.9333333 18.37,11.22 C18.6166667,10.5066667 18.74,9.76666667 18.74,9 C18.74,7.83333333 18.47,6.75 17.93,5.75 C17.3833333,4.75 16.6233333,3.93666667 15.65,3.31 C15.47,3.18333333 15.2766667,3.14333333 15.07,3.19 C14.8633333,3.23666667 14.7033333,3.35 14.59,3.53 C14.4766667,3.70333333 14.44,3.88666667 14.48,4.08 C14.52,4.27333333 14.63,4.42666667 14.81,4.54 L14.83,4.56 C15.5833333,5.05333333 16.1766667,5.69333333 16.61,6.48 C17.0433333,7.26666667 17.26,8.10666667 17.26,9 C17.26,9.59333333 17.1633333,10.1666667 16.97,10.72 C16.7766667,11.2666667 16.4966667,11.7733333 16.13,12.24 C15.7633333,12.7066667 15.33,13.1 14.83,13.42 C14.6566667,13.5266667 14.5466667,13.68 14.5,13.88 C14.4466667,14.08 14.4766667,14.27 14.59,14.45 Z" id="形状"></path>
|
||||
<path d="M0.77,9 C0.77,10.6666667 1.12,12.2466667 1.82,13.74 C2.52666667,15.2333333 3.51333333,16.5166667 4.78,17.59 C4.94,17.7166667 5.12,17.7733333 5.32,17.76 C5.52,17.7466667 5.69,17.6666667 5.83,17.52 C5.95666667,17.36 6.01333333,17.1766667 6,16.97 C5.98666667,16.7633333 5.9,16.5866667 5.74,16.44 C4.63333333,15.5133333 3.77666667,14.4 3.17,13.1 C2.56333333,11.8066667 2.26,10.44 2.26,9 C2.26,7.56 2.56333333,6.18666667 3.17,4.88 C3.77666667,3.58 4.64,2.46666667 5.76,1.54 C5.90666667,1.39333333 5.99,1.21666667 6.01,1.01 C6.03666667,0.803333333 5.97666667,0.626666667 5.83,0.48 C5.70333333,0.32 5.53666667,0.233333333 5.33,0.22 C5.12333333,0.2 4.94,0.253333333 4.78,0.38 C3.51333333,1.45333333 2.52666667,2.74333333 1.82,4.25 C1.12,5.75 0.77,7.33333333 0.77,9 Z M18.17,17.5 C18.2966667,17.66 18.4633333,17.7466667 18.67,17.76 C18.8766667,17.7733333 19.06,17.7166667 19.22,17.59 C20.0733333,16.89 20.8,16.0833333 21.4,15.17 C22,14.2566667 22.4533333,13.2766667 22.76,12.23 C23.0733333,11.1833333 23.23,10.1066667 23.23,9 C23.23,7.89333333 23.0733333,6.81666667 22.76,5.77 C22.4533333,4.72333333 22,3.74 21.4,2.82 C20.8,1.9 20.0733333,1.08666667 19.22,0.38 C19.06,0.253333333 18.8766667,0.2 18.67,0.22 C18.4633333,0.233333333 18.2966667,0.32 18.17,0.48 C18.0233333,0.64 17.96,0.823333333 17.98,1.03 C17.9933333,1.23666667 18.08,1.40666667 18.24,1.54 C18.9733333,2.14666667 19.6,2.85 20.12,3.65 C20.64,4.45 21.0366667,5.3 21.31,6.2 C21.5833333,7.10666667 21.72,8.04 21.72,9 C21.72,9.96 21.5833333,10.8933333 21.31,11.8 C21.0366667,12.7 20.6466667,13.5466667 20.14,14.34 C19.6266667,15.1333333 19,15.8333333 18.26,16.44 C18.1,16.5666667 18.0133333,16.7333333 18,16.94 C17.9866667,17.1533333 18.0433333,17.34 18.17,17.5 Z" id="形状"></path>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 4.4 KiB |
|
@ -3,7 +3,6 @@
|
|||
"pages/Index",
|
||||
"pages/ListPage",
|
||||
"pages/SingleImage",
|
||||
"pages/ManyPhotoShowPage",
|
||||
"pages/LongImagePage",
|
||||
"pages/TransformPage",
|
||||
"pages/UserPage",
|
||||
|
@ -22,6 +21,28 @@
|
|||
"pages/TestCommonImage",
|
||||
"pages/ImageAnimatorPage",
|
||||
"pages/TestSetCustomImagePage",
|
||||
"pages/TestErrorHolderPage"
|
||||
"pages/TestErrorHolderPage",
|
||||
"pages/TestTaskResourcePage",
|
||||
"pages/ImageKnifeReload",
|
||||
"pages/LazyForEachCount",
|
||||
"pages/LazyForEachCache",
|
||||
"pages/PrefetchAndCacheCount",
|
||||
"pages/PrefetchAndPreload",
|
||||
"pages/TestCacheDataPage",
|
||||
"pages/TestChangeColorPage",
|
||||
"pages/TestLoadCancelListenerPage",
|
||||
"pages/SetMaxRequestPage",
|
||||
"pages/MaxRequest1",
|
||||
"pages/MaxRequest2",
|
||||
"pages/MaxRequest3",
|
||||
"pages/TestImageKnifeCallbackPage",
|
||||
"pages/TestListImageKnifeCallbackPage",
|
||||
"pages/DownSamplePage",
|
||||
"pages/AutoImageFit",
|
||||
"pages/SingleImageCallBack",
|
||||
"pages/MultipleImageCallBack",
|
||||
"pages/LocalImage",
|
||||
"pages/ErrorMessageDownload",
|
||||
"pages/TestImageExif"
|
||||
]
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
{
|
||||
"string": [
|
||||
{
|
||||
"name": "module_desc",
|
||||
"value": "module description"
|
||||
},
|
||||
{
|
||||
"name": "EntryAbility_desc",
|
||||
"value": "description"
|
||||
},
|
||||
{
|
||||
"name": "EntryAbility_label",
|
||||
"value": "label"
|
||||
},
|
||||
{
|
||||
"name": "app_permission_WRITE_IMAGEVIDEO",
|
||||
"value": "获取写入媒体资源权限"
|
||||
},
|
||||
{
|
||||
"name": "app_permission_READ_IMAGEVIDEO",
|
||||
"value": "获取读媒体资源权限"
|
||||
}
|
||||
]
|
||||
}
|
After Width: | Height: | Size: 4.2 KiB |
After Width: | Height: | Size: 22 KiB |
After Width: | Height: | Size: 22 KiB |
After Width: | Height: | Size: 22 KiB |
After Width: | Height: | Size: 22 KiB |
|
@ -19,6 +19,686 @@
|
|||
{
|
||||
"name": "app_permission_READ_IMAGEVIDEO",
|
||||
"value": "获取读媒体资源权限"
|
||||
},
|
||||
{
|
||||
"name": "Test_ImageAnimator",
|
||||
"value": "测试ImageAnimator组件"
|
||||
},
|
||||
{
|
||||
"name": "Test_multiple_images",
|
||||
"value": "测试加载多张相同图片"
|
||||
},
|
||||
{
|
||||
"name": "Test_Task_error",
|
||||
"value": "测试占位图Task报错"
|
||||
},
|
||||
{
|
||||
"name": "Test_HSP",
|
||||
"value": "测试HSP场景预加载"
|
||||
},
|
||||
{
|
||||
"name": "Test_SingleImage",
|
||||
"value": "单个图片使用"
|
||||
},
|
||||
{
|
||||
"name": "Test_LocalImageShow",
|
||||
"value": "本地图片显示"
|
||||
},
|
||||
{
|
||||
"name": "Test_custom_download",
|
||||
"value": "全局自定义下载"
|
||||
},
|
||||
{
|
||||
"name": "Multiple_images",
|
||||
"value": "多图"
|
||||
},
|
||||
{
|
||||
"name": "Display_long_image",
|
||||
"value": "长图显示"
|
||||
},
|
||||
{
|
||||
"name": "Image_scaling",
|
||||
"value": "缩放图片"
|
||||
},
|
||||
{
|
||||
"name": "Message_list",
|
||||
"value": "消息列表"
|
||||
},
|
||||
{
|
||||
"name": "Custom_cache_key",
|
||||
"value": "自定义缓存key"
|
||||
},
|
||||
{
|
||||
"name": "Preloading_images_to_cache",
|
||||
"value": "预加载图片到文件缓存"
|
||||
},
|
||||
{
|
||||
"name": "Retrieve_image_display_from_cache",
|
||||
"value": "从缓存获取图片显示"
|
||||
},
|
||||
{
|
||||
"name": "Test_single_request_header",
|
||||
"value": "测试单个请求头"
|
||||
},
|
||||
{
|
||||
"name": "Test_write_cache_strategy",
|
||||
"value": "测试写入缓存策略"
|
||||
},
|
||||
{
|
||||
"name": "Image_Transformation",
|
||||
"value": "图片变换"
|
||||
},
|
||||
{
|
||||
"name": "Different_ObjectFit",
|
||||
"value": "不同的ObjectFit"
|
||||
},
|
||||
{
|
||||
"name": "Test_image_loading_success_or_failure_events",
|
||||
"value": "测试图片加载成功/失败事件"
|
||||
},
|
||||
{
|
||||
"name": "Test_removing_image_cache_interface",
|
||||
"value": "测试移除图片缓存接口"
|
||||
},
|
||||
{
|
||||
"name": "Test_error_image_display",
|
||||
"value": "测试错误图显示"
|
||||
},
|
||||
{
|
||||
"name": "Display_the_first_frame",
|
||||
"value": "第一帧"
|
||||
},
|
||||
{
|
||||
"name": "Display_the_last_frame",
|
||||
"value": "最后一帧"
|
||||
},
|
||||
{
|
||||
"name": "Play",
|
||||
"value": "播放"
|
||||
},
|
||||
{
|
||||
"name": "Pause",
|
||||
"value": "暂停"
|
||||
},
|
||||
{
|
||||
"name": "Stop",
|
||||
"value": "停止"
|
||||
},
|
||||
{
|
||||
"name": "Infinite_loop",
|
||||
"value": "无限循环"
|
||||
},
|
||||
{
|
||||
"name": "Play_once",
|
||||
"value": "播放一次"
|
||||
},
|
||||
{
|
||||
"name": "Play_twice",
|
||||
"value": "播放两次"
|
||||
},
|
||||
{
|
||||
"name": "Local_SVG",
|
||||
"value": "本地资源SVG图片"
|
||||
},
|
||||
{
|
||||
"name": "local_r_file",
|
||||
"value": "本地$r文件"
|
||||
},
|
||||
{
|
||||
"name": "local_rawfile",
|
||||
"value": "本地rawfile文件"
|
||||
},
|
||||
{
|
||||
"name": "Under_context_file",
|
||||
"value": "本地沙箱路径文件"
|
||||
},
|
||||
{
|
||||
"name": "local_other_module",
|
||||
"value": "本地其他模块文件"
|
||||
},
|
||||
{
|
||||
"name": "Network_images",
|
||||
"value": "网络图片"
|
||||
},
|
||||
{
|
||||
"name": "Custom_network_download",
|
||||
"value": "自定义下载"
|
||||
},
|
||||
{
|
||||
"name": "PixelMap_loads_images",
|
||||
"value": "PixelMap加载图片"
|
||||
},
|
||||
{
|
||||
"name": "Enlarge",
|
||||
"value": "放大"
|
||||
},
|
||||
{
|
||||
"name": "Reduce",
|
||||
"value": "缩小"
|
||||
},
|
||||
{
|
||||
"name": "Click_on_add",
|
||||
"value": "点击尺寸加50"
|
||||
},
|
||||
{
|
||||
"name": "Click_on_reduce",
|
||||
"value": "点击尺寸减50"
|
||||
},
|
||||
{
|
||||
"name": "The_key_fixed_1",
|
||||
"value": "key固定为 1"
|
||||
},
|
||||
{
|
||||
"name": "The_key_changes_timestamp",
|
||||
"value": "key每次变化:时间戳"
|
||||
},
|
||||
{
|
||||
"name": "Load",
|
||||
"value": "加载"
|
||||
},
|
||||
{
|
||||
"name": "Preloading_images_to_file_cache_using_URL",
|
||||
"value": "url预加载图片到文件缓存"
|
||||
},
|
||||
{
|
||||
"name": "Preloading_images_to_file_cache_using_option",
|
||||
"value": "option预加载图片到文件缓存"
|
||||
},
|
||||
{
|
||||
"name": "Load_image_offline_after_preloading",
|
||||
"value": "加载图片(预加载后可断网加载)"
|
||||
},
|
||||
{
|
||||
"name": "Preloading_GIF",
|
||||
"value": "预加载gif图"
|
||||
},
|
||||
{
|
||||
"name": "Retrieve_GIF_from_memory",
|
||||
"value": "内存缓存获取gif"
|
||||
},
|
||||
{
|
||||
"name": "Retrieve_GIF_from_disk",
|
||||
"value": "文件缓存获取gif"
|
||||
},
|
||||
{
|
||||
"name": "Preloading_static_images",
|
||||
"value": "预加载静态图"
|
||||
},
|
||||
{
|
||||
"name": "Retrieve_images_from_memory",
|
||||
"value": "内存缓存获取"
|
||||
},
|
||||
{
|
||||
"name": "Retrieve_images_from_disk",
|
||||
"value": "文件缓存获取"
|
||||
},
|
||||
{
|
||||
"name": "Write_memory_and_file",
|
||||
"value": "写入内存文件缓存"
|
||||
},
|
||||
{
|
||||
"name": "Write_memory",
|
||||
"value": "写入内存缓存"
|
||||
},
|
||||
{
|
||||
"name": "Write_file",
|
||||
"value": "写入文件缓存"
|
||||
},
|
||||
{
|
||||
"name": "Main_image_Fill",
|
||||
"value": "主图Fill拉伸填充"
|
||||
},
|
||||
{
|
||||
"name": "Maintain_proportion_filling",
|
||||
"value": "占位图Contain保持比例填充"
|
||||
},
|
||||
{
|
||||
"name": "Error_graph_None",
|
||||
"value": "错误图None不变化"
|
||||
},
|
||||
{
|
||||
"name": "Test_failure_success",
|
||||
"value": "测试失败/成功场景"
|
||||
},
|
||||
{
|
||||
"name": "Custom_download_failed",
|
||||
"value": "自定义下载失败"
|
||||
},
|
||||
{
|
||||
"name": "Retrieve_media_gallery",
|
||||
"value": "获取媒体图库的uri用ImageKnife展示"
|
||||
},
|
||||
{
|
||||
"name": "Click_load_Uri",
|
||||
"value": "点击加载Uri并展示"
|
||||
},
|
||||
{
|
||||
"name": "Delete_all_caches",
|
||||
"value": "删除全部缓存"
|
||||
},
|
||||
{
|
||||
"name": "Delete_all_memory_caches",
|
||||
"value": "删除全部内存缓存"
|
||||
},
|
||||
{
|
||||
"name": "Delete_all_file_caches",
|
||||
"value": "删除全部文件缓存"
|
||||
},
|
||||
{
|
||||
"name": "Delete_all_custom_memory_caches",
|
||||
"value": "删除自定义内存缓存"
|
||||
},
|
||||
{
|
||||
"name": "Delete_all_custom_file_caches",
|
||||
"value": "删除自定义文件缓存"
|
||||
},
|
||||
{
|
||||
"name": "Blur_effect",
|
||||
"value": "模糊效果"
|
||||
},
|
||||
{
|
||||
"name": "Highlighting_effect",
|
||||
"value": "高亮效果"
|
||||
},
|
||||
{
|
||||
"name": "Ashing_effect",
|
||||
"value": "灰化效果"
|
||||
},
|
||||
{
|
||||
"name": "Inverse_effect",
|
||||
"value": "反转效果"
|
||||
},
|
||||
{
|
||||
"name": "Animation_filter_effect",
|
||||
"value": "动画滤镜效果"
|
||||
},
|
||||
{
|
||||
"name": "Crop_circular_effect",
|
||||
"value": "裁剪圆形效果"
|
||||
},
|
||||
{
|
||||
"name": "Crop_circular_with_border_effect",
|
||||
"value": "裁剪圆形带边框效果"
|
||||
},
|
||||
{
|
||||
"name": "Contrast_effect",
|
||||
"value": "对比度效果"
|
||||
},
|
||||
{
|
||||
"name": "Black_ink_filtering_effect",
|
||||
"value": "乌墨色滤波效果"
|
||||
},
|
||||
{
|
||||
"name": "Rotate",
|
||||
"value": "旋转效果"
|
||||
},
|
||||
{
|
||||
"name": "Corners",
|
||||
"value": "圆角效果"
|
||||
},
|
||||
{
|
||||
"name": "Kuwahara_Filter_effect",
|
||||
"value": "桑原滤波效果"
|
||||
},
|
||||
{
|
||||
"name": "Pixelated_Filter_effect",
|
||||
"value": "像素化滤波效果"
|
||||
},
|
||||
{
|
||||
"name": "Sketch_Filter_effect",
|
||||
"value": "素描滤波效果"
|
||||
},
|
||||
{
|
||||
"name": "Distortion_Filter_effect",
|
||||
"value": "扭曲滤波效果"
|
||||
},
|
||||
{
|
||||
"name": "Decorative_Filter_effect",
|
||||
"value": "装饰滤波效果"
|
||||
},
|
||||
{
|
||||
"name": "Square_cutting_effect",
|
||||
"value": "正方形裁剪效果"
|
||||
},
|
||||
{
|
||||
"name": "Top_cutting_effect",
|
||||
"value": "上方裁剪效果"
|
||||
},
|
||||
{
|
||||
"name": "Middle_cutting_effect",
|
||||
"value": "中间裁剪效果"
|
||||
},
|
||||
{
|
||||
"name": "Bottom_cutting_effect",
|
||||
"value": "底下裁剪效果"
|
||||
},
|
||||
{
|
||||
"name": "Mask_effect",
|
||||
"value": "遮罩效果"
|
||||
},
|
||||
{
|
||||
"name": "TIPS",
|
||||
"value": "测试失败场景请先关闭网络,并保证本地没有此网络图片的缓存"
|
||||
},
|
||||
{
|
||||
"name": "Network_reload",
|
||||
"value": "网络恢复reload"
|
||||
},
|
||||
{
|
||||
"name": "preloading_prefetch",
|
||||
"value": "动态预加载prefetch"
|
||||
},
|
||||
{
|
||||
"name": "image_format",
|
||||
"value": "图片格式:%s"
|
||||
},
|
||||
{
|
||||
"name": "image_width",
|
||||
"value": "图片宽度:%d"
|
||||
},
|
||||
{
|
||||
"name": "image_height",
|
||||
"value": "图片高度:%d"
|
||||
},
|
||||
{
|
||||
"name": "cur_cache_limit",
|
||||
"value": "%s:当前缓存上限:%fM"
|
||||
},
|
||||
{
|
||||
"name": "cur_cache_image_num",
|
||||
"value": "%s:当前缓存图片数量:%d"
|
||||
},
|
||||
{
|
||||
"name": "cur_cache_size",
|
||||
"value": "%s:当前缓存的大小:%fM"
|
||||
},
|
||||
{
|
||||
"name": "load_memory",
|
||||
"value": "内存加载图片"
|
||||
},
|
||||
{
|
||||
"name": "load_disk",
|
||||
"value": "磁盘缓存加载图片"
|
||||
},
|
||||
{
|
||||
"name": "get_cur_memory_limit",
|
||||
"value": "获取当前内存缓存上限"
|
||||
},
|
||||
{
|
||||
"name": "get_img_number_of_cache",
|
||||
"value": "获取当前内存缓存图片数量"
|
||||
},
|
||||
{
|
||||
"name": "get_cur_memory_size",
|
||||
"value": "获取当前缓存的大小"
|
||||
},
|
||||
{
|
||||
"name": "get_cur_disk_limit",
|
||||
"value": "获取当前磁盘缓存上限"
|
||||
},
|
||||
{
|
||||
"name": "get_img_number_of_disk",
|
||||
"value": "获取当前磁盘缓存图片数量"
|
||||
},
|
||||
{
|
||||
"name": "get_cur_disk_size",
|
||||
"value": "获取当前磁盘的大小"
|
||||
},
|
||||
{
|
||||
"name": "select_color_btn",
|
||||
"value": "点击选择要更改的颜色"
|
||||
},
|
||||
{
|
||||
"name": "click_img_to_change_color",
|
||||
"value": "点击图片更改图片颜色"
|
||||
},
|
||||
{
|
||||
"name": "test_non_svg_color",
|
||||
"value": "测试非svg图片变色"
|
||||
},
|
||||
{
|
||||
"name": "test_svg_color",
|
||||
"value": "测试svg图片变色"
|
||||
},
|
||||
{
|
||||
"name": "red",
|
||||
"value": "红色"
|
||||
},
|
||||
{
|
||||
"name": "yellow",
|
||||
"value": "黄色"
|
||||
},
|
||||
{
|
||||
"name": "green",
|
||||
"value": "绿色"
|
||||
},
|
||||
{
|
||||
"name": "blue",
|
||||
"value": "蓝色"
|
||||
},
|
||||
{
|
||||
"name": "master_image",
|
||||
"value": "原图:"
|
||||
},
|
||||
{
|
||||
"name": "rm_component_of_net",
|
||||
"value": "移除组件-网络加载图片"
|
||||
},
|
||||
{
|
||||
"name": "rm_component_of_local",
|
||||
"value": "移除组件-本地资源图片"
|
||||
},
|
||||
{
|
||||
"name": "component_display",
|
||||
"value": "恢复组件显示"
|
||||
},
|
||||
{
|
||||
"name": "onLoadCancel_reason",
|
||||
"value": "onLoadCancel回调原因:%s"
|
||||
},
|
||||
{
|
||||
"name": "test_cache_btn",
|
||||
"value": "测试缓存数据"
|
||||
},
|
||||
{
|
||||
"name": "test_change_color_btn",
|
||||
"value": "测试颜色变换"
|
||||
},
|
||||
{
|
||||
"name": "test_cancel_callback_btn",
|
||||
"value": "测试加载取消回调接口"
|
||||
},
|
||||
{
|
||||
"name": "memory",
|
||||
"value": "内存"
|
||||
},
|
||||
{
|
||||
"name": "disk",
|
||||
"value": "磁盘"
|
||||
},
|
||||
{
|
||||
"name": "Customize_RCP_network",
|
||||
"value": "自定义rcp网络请求"
|
||||
},
|
||||
{
|
||||
"name": "request_concurrency",
|
||||
"value": "设置请求并发度"
|
||||
},
|
||||
{
|
||||
"name": "test_callback",
|
||||
"value": "测试图片加载回调数据"
|
||||
},
|
||||
{
|
||||
"name": "gif",
|
||||
"value": "gif"
|
||||
},
|
||||
{
|
||||
"name": "local_pic",
|
||||
"value": "本地图片"
|
||||
},
|
||||
{
|
||||
"name": "share_pic",
|
||||
"value": "共享图片"
|
||||
},
|
||||
{
|
||||
"name": "net_load_failed",
|
||||
"value": "网络加载失败"
|
||||
},
|
||||
{
|
||||
"name": "local_load_failed",
|
||||
"value": "本地加载失败"
|
||||
},
|
||||
{
|
||||
"name": "share_load_failed",
|
||||
"value": "共享图片加载失败"
|
||||
},
|
||||
{
|
||||
"name": "list_pic",
|
||||
"value": "加载图片列表"
|
||||
},
|
||||
{
|
||||
"name": "img_url",
|
||||
"value": "业务设置的url:%s"
|
||||
},
|
||||
{
|
||||
"name": "img_format",
|
||||
"value": "图片的格式:%s"
|
||||
},
|
||||
{
|
||||
"name": "img_master_size",
|
||||
"value": "图片的原始宽高大小-宽:%d ,高:%d, 大小:%d"
|
||||
},
|
||||
{
|
||||
"name": "componentWH",
|
||||
"value": "component的宽高-宽:%d ,高:%d "
|
||||
},
|
||||
{
|
||||
"name": "img_frame",
|
||||
"value": "动图帧数:%d "
|
||||
},
|
||||
{
|
||||
"name": "img_content_size",
|
||||
"value": "图片解码后宽高大小:%s "
|
||||
},
|
||||
{
|
||||
"name": "err_msg",
|
||||
"value": "错误信息:%s "
|
||||
},
|
||||
{
|
||||
"name": "err_phase",
|
||||
"value": "发生错误阶段:%s "
|
||||
},
|
||||
{
|
||||
"name": "err_code",
|
||||
"value": "错误code:%d "
|
||||
},
|
||||
{
|
||||
"name": "http_code",
|
||||
"value": "网络请求code:%d "
|
||||
},
|
||||
{
|
||||
"name": "req_start_time",
|
||||
"value": "请求开始时间:%s "
|
||||
},
|
||||
{
|
||||
"name": "req_end_time",
|
||||
"value": "请求结束时间:%s "
|
||||
},
|
||||
{
|
||||
"name": "req_cancel_time",
|
||||
"value": "请求取消时间:%s "
|
||||
},
|
||||
{
|
||||
"name": "memory_start_time",
|
||||
"value": "开始检查内存缓存时间点:%s "
|
||||
},
|
||||
{
|
||||
"name": "memory_end_time",
|
||||
"value": "结束检查内存缓存时间点:%s "
|
||||
},
|
||||
{
|
||||
"name": "disk_start_time",
|
||||
"value": "开始检查磁盘缓存时间点:%s "
|
||||
},
|
||||
{
|
||||
"name": "disk_end_time",
|
||||
"value": "结束检查磁盘缓存时间点:%s "
|
||||
},
|
||||
{
|
||||
"name": "net_start_time",
|
||||
"value": "网络请求开始时间点:%s "
|
||||
},
|
||||
{
|
||||
"name": "net_end_time",
|
||||
"value": "网络请求结束时间点:%s "
|
||||
},
|
||||
{
|
||||
"name": "decode_start_time",
|
||||
"value": "解码开始时间点:%s "
|
||||
},
|
||||
{
|
||||
"name": "decode_end_time",
|
||||
"value": "解码结束时间点:%s "
|
||||
},
|
||||
{
|
||||
"name": "request_data_from",
|
||||
"value": "请求数据来自于:%s "
|
||||
},
|
||||
{
|
||||
"name": "Image_Downsampling_Functionality",
|
||||
"value": "降采样功能"
|
||||
},
|
||||
{
|
||||
"name": "Sampling_pecification",
|
||||
"value": "降采样规格"
|
||||
},
|
||||
{
|
||||
"name": "Unreal_samples",
|
||||
"value": "未降采样大小"
|
||||
},
|
||||
{
|
||||
"name": "After_the_sampling",
|
||||
"value": "降采样后大小"
|
||||
},
|
||||
{
|
||||
"name": "adjust_size",
|
||||
"value": "调整大小"
|
||||
},
|
||||
{
|
||||
"name": "Auto_ImageFit",
|
||||
"value": "ImageFit.Auto:自适用图片高度"
|
||||
},
|
||||
{
|
||||
"name": "Single_CallBack",
|
||||
"value": "单个图片回调"
|
||||
},
|
||||
{
|
||||
"name": "Multiple_CallBack",
|
||||
"value": "多张图片回调"
|
||||
},
|
||||
{
|
||||
"name": "Error_Message",
|
||||
"value": "错误信息"
|
||||
},
|
||||
{
|
||||
"name": "base_image",
|
||||
"value": "图片不携带旋转信息"
|
||||
},
|
||||
{
|
||||
"name": "test_exif",
|
||||
"value": "测试图片携带的EXIF元数据作为显示方向"
|
||||
},
|
||||
{
|
||||
"name": "rotate_mirror",
|
||||
"value": "水平翻转"
|
||||
},
|
||||
{
|
||||
"name": "rotate_rotate90",
|
||||
"value": "顺时针90°"
|
||||
},
|
||||
{
|
||||
"name": "rotate_mirror_rotate270",
|
||||
"value": "水平翻转后再顺时针270°"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -13,9 +13,9 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium';
|
||||
import { ImageKnifeOption, ImageKnifeRequest } from '@ohos/imageknife/Index';
|
||||
import { DefaultJobQueue } from '@ohos/imageknife/src/main/ets/utils/DefaultJobQueue';
|
||||
import { IJobQueue } from '@ohos/imageknife/src/main/ets/utils/IJobQueue';
|
||||
import { ImageKnifeOption, ImageKnifeRequest } from '@ohos/imageknife';
|
||||
import { DefaultJobQueue } from '@ohos/imageknife/src/main/ets/queue/DefaultJobQueue';
|
||||
import { IJobQueue } from '@ohos/imageknife/src/main/ets/queue/IJobQueue';
|
||||
import taskpool from '@ohos.taskpool';
|
||||
import common from '@ohos.app.ability.common';
|
||||
|
||||
|
@ -55,12 +55,12 @@ export default function DefaultJobQueueTest() {
|
|||
|
||||
expect(job.getQueueLength()).assertEqual(7)
|
||||
expect(job.pop()!.imageKnifeOption.loadSrc).assertEqual("high1")
|
||||
expect(job.pop()!.imageKnifeOption.loadSrc).assertEqual("medium4")
|
||||
expect(job.pop()!.imageKnifeOption.loadSrc).assertEqual("medium3")
|
||||
expect(job.pop()!.imageKnifeOption.loadSrc).assertEqual("medium2")
|
||||
expect(job.pop()!.imageKnifeOption.loadSrc).assertEqual("medium1")
|
||||
expect(job.pop()!.imageKnifeOption.loadSrc).assertEqual("low2")
|
||||
expect(job.pop()!.imageKnifeOption.loadSrc).assertEqual("medium2")
|
||||
expect(job.pop()!.imageKnifeOption.loadSrc).assertEqual("medium3")
|
||||
expect(job.pop()!.imageKnifeOption.loadSrc).assertEqual("medium4")
|
||||
expect(job.pop()!.imageKnifeOption.loadSrc).assertEqual("low1")
|
||||
expect(job.pop()!.imageKnifeOption.loadSrc).assertEqual("low2")
|
||||
expect(job.pop()).assertEqual(undefined)
|
||||
expect(job.getQueueLength()).assertEqual(0)
|
||||
|
||||
|
@ -70,10 +70,10 @@ export default function DefaultJobQueueTest() {
|
|||
}
|
||||
|
||||
function makeRequest(src: string, context: common.UIAbilityContext, priority?: taskpool.Priority): ImageKnifeRequest {
|
||||
let option: ImageKnifeOption = new ImageKnifeOption({
|
||||
let option: ImageKnifeOption = {
|
||||
loadSrc: src,
|
||||
priority: priority
|
||||
})
|
||||
}
|
||||
return new ImageKnifeRequest(
|
||||
option,
|
||||
context,
|
||||
|
|
|
@ -17,7 +17,7 @@ import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from
|
|||
import Constants from '../../../main/ets/common/Constants';
|
||||
import taskpool from '@ohos.taskpool';
|
||||
import { GlobalContext } from '../../../main/ets/common/GlobalContext';
|
||||
import { FileCache } from '@ohos/imageknife/src/main/ets/utils/FileCache';
|
||||
import { FileCache } from '@ohos/imageknife/src/main/ets/cache/FileCache';
|
||||
import { IEngineKey, ImageKnifeOption } from '@ohos/imageknife';
|
||||
import { DefaultEngineKey } from '@ohos/imageknife/src/main/ets/key/DefaultEngineKey';
|
||||
|
||||
|
@ -153,9 +153,9 @@ export default function FileLruCacheTest() {
|
|||
});
|
||||
it('fileCacheEngineKey', 0, () => {
|
||||
let engineKey: IEngineKey = new DefaultEngineKey()
|
||||
let imageKnifeOption: ImageKnifeOption = new ImageKnifeOption({
|
||||
let imageKnifeOption: ImageKnifeOption = {
|
||||
loadSrc:"abc"
|
||||
})
|
||||
}
|
||||
let imageKey = engineKey.generateFileKey(imageKnifeOption.loadSrc,"")
|
||||
let imageAnimatorKey = engineKey.generateFileKey(imageKnifeOption.loadSrc,"",true)
|
||||
expect(imageKey == imageAnimatorKey).assertFalse()
|
||||
|
|
|
@ -40,10 +40,10 @@ export default function ImageKnifeTest() {
|
|||
|
||||
it('removeMemoryCache', 0, async () => {
|
||||
let a = 'https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp';
|
||||
let option: ImageKnifeOption = new ImageKnifeOption({
|
||||
let option: ImageKnifeOption = {
|
||||
loadSrc: 'https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp',
|
||||
signature: ''
|
||||
})
|
||||
}
|
||||
let key = ImageKnife.getInstance()
|
||||
.getEngineKeyImpl()
|
||||
.generateMemoryKey('https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp', ImageKnifeRequestSource.SRC, option)
|
||||
|
|
|
@ -44,7 +44,7 @@ export default function ImageKnifeOptionTest() {
|
|||
imageWidth: 0,
|
||||
imageHeight: 0,
|
||||
}
|
||||
let ImageKnifeOption: ImageKnifeOption = {
|
||||
let imageKnifeOption: ImageKnifeOption = {
|
||||
loadSrc: $r("app.media.rabbit"),
|
||||
onLoadListener: {
|
||||
onLoadFailed: (err) => {
|
||||
|
@ -59,9 +59,9 @@ export default function ImageKnifeOptionTest() {
|
|||
},
|
||||
},
|
||||
}
|
||||
if (ImageKnifeOption.onLoadListener && ImageKnifeOption.onLoadListener.onLoadSuccess && ImageKnifeOption.onLoadListener.onLoadFailed) {
|
||||
ImageKnifeOption.onLoadListener.onLoadSuccess(a,imageData);
|
||||
ImageKnifeOption.onLoadListener.onLoadFailed(a);
|
||||
if (imageKnifeOption.onLoadListener && imageKnifeOption.onLoadListener.onLoadSuccess && imageKnifeOption.onLoadListener.onLoadFailed) {
|
||||
imageKnifeOption.onLoadListener.onLoadSuccess(a,imageData);
|
||||
imageKnifeOption.onLoadListener.onLoadFailed(a);
|
||||
}
|
||||
expect(a).assertEqual(b);
|
||||
});
|
||||
|
|
|
@ -44,7 +44,7 @@ export default function ImageKnifeOptionTest() {
|
|||
imageWidth: 0,
|
||||
imageHeight: 0,
|
||||
}
|
||||
let imageKnifeOption: ImageKnifeOption = new ImageKnifeOption({
|
||||
let imageKnifeOption: ImageKnifeOption = {
|
||||
loadSrc: $r("app.media.rabbit"),
|
||||
onLoadListener: {
|
||||
onLoadFailed: (err) => {
|
||||
|
@ -58,7 +58,7 @@ export default function ImageKnifeOptionTest() {
|
|||
return data;
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
if (imageKnifeOption.onLoadListener && imageKnifeOption.onLoadListener.onLoadSuccess && imageKnifeOption.onLoadListener.onLoadFailed) {
|
||||
imageKnifeOption.onLoadListener.onLoadSuccess(a,imageData);
|
||||
imageKnifeOption.onLoadListener.onLoadFailed(a);
|
|
@ -14,10 +14,13 @@
|
|||
*/
|
||||
import DefaultJobQueueTest from './DefaultJobQueueTest.test';
|
||||
import FileLruCacheTest from './FileLruCache.test';
|
||||
import ImageKnifeOptionTest from './ImageKnifeOption.test';
|
||||
import ImageKnifeOptionTest from './ImageknifeOption.test';
|
||||
import MemoryLruCacheTest from './MemoryLruCache.test';
|
||||
import ImageKnifeTest from './ImageKnife.test';
|
||||
import Transform from './transform.test';
|
||||
import imageFormatAndSize from './imageFormatAndSize.test'
|
||||
import loadCallBackData from './loadCallBackData.test'
|
||||
import SamplingTest from './SamplingTest.test';
|
||||
|
||||
export default function testsuite() {
|
||||
MemoryLruCacheTest();
|
||||
|
@ -26,4 +29,7 @@ export default function testsuite() {
|
|||
ImageKnifeOptionTest();
|
||||
ImageKnifeTest();
|
||||
Transform();
|
||||
SamplingTest()
|
||||
imageFormatAndSize();
|
||||
loadCallBackData();
|
||||
}
|
|
@ -17,7 +17,7 @@ import image from '@ohos.multimedia.image';
|
|||
|
||||
|
||||
import Constants from '../../../main/ets/common/Constants';
|
||||
import { MemoryLruCache } from '@ohos/imageknife/src/main/ets/utils/MemoryLruCache';
|
||||
import { MemoryLruCache } from '@ohos/imageknife/src/main/ets/cache/MemoryLruCache';
|
||||
import { ImageKnifeData } from '@ohos/imageknife/src/main/ets/model/ImageKnifeData';
|
||||
import { IEngineKey, ImageKnifeOption,ImageKnifeRequestSource } from '@ohos/imageknife';
|
||||
import { DefaultEngineKey } from '@ohos/imageknife/src/main/ets/key/DefaultEngineKey';
|
||||
|
@ -122,9 +122,9 @@ export default function MemoryLruCacheTest() {
|
|||
|
||||
it('memoryCacheEngineKey', 0, () => {
|
||||
let engineKey: IEngineKey = new DefaultEngineKey()
|
||||
let imageKnifeOption: ImageKnifeOption = new ImageKnifeOption({
|
||||
let imageKnifeOption: ImageKnifeOption = {
|
||||
loadSrc:"abc"
|
||||
})
|
||||
}
|
||||
let imageKey = engineKey.generateMemoryKey(imageKnifeOption.loadSrc,ImageKnifeRequestSource.SRC,imageKnifeOption)
|
||||
let imageAnimatorKey = engineKey.generateMemoryKey(imageKnifeOption.loadSrc,ImageKnifeRequestSource.SRC,imageKnifeOption,true)
|
||||
expect(imageKey == imageAnimatorKey).assertFalse()
|
||||
|
|
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
* 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 { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'
|
||||
import { Downsampler } from '@ohos/imageknife/src/main/ets/downsampling/Downsampler'
|
||||
import { DownsampleStrategy } from '@ohos/imageknife'
|
||||
|
||||
export default function SamplingTest() {
|
||||
describe('SamplingTest', () => {
|
||||
// Defines a test suite. Two parameters are supported: test suite name and test suite function.
|
||||
beforeAll(() => {
|
||||
// Presets an action, which is performed only once before all test cases of the test suite start.
|
||||
// This API supports only one parameter: preset action function.
|
||||
})
|
||||
beforeEach(() => {
|
||||
// Presets an action, which is performed before each unit test case starts.
|
||||
// The number of execution times is the same as the number of test cases defined by **it**.
|
||||
// This API supports only one parameter: preset action function.
|
||||
})
|
||||
afterEach(() => {
|
||||
// Presets a clear action, which is performed after each unit test case ends.
|
||||
// The number of execution times is the same as the number of test cases defined by **it**.
|
||||
// This API supports only one parameter: clear action function.
|
||||
})
|
||||
afterAll(() => {
|
||||
// Presets a clear action, which is performed after all test cases of the test suite end.
|
||||
// This API supports only one parameter: clear action function.
|
||||
})
|
||||
it('AT_MOST', 0, () => {
|
||||
let reqSize: Size =
|
||||
new Downsampler().calculateScaling('jpg', 1024, 1024, 200,
|
||||
200, DownsampleStrategy.AT_MOST)
|
||||
let req = (reqSize.width < 1024 && reqSize.height < 1024)
|
||||
expect(req).assertEqual(true);
|
||||
})
|
||||
it('FIT_CENTER_MEMORY', 1, () => {
|
||||
let reqSize: Size =
|
||||
new Downsampler().calculateScaling('jpg', 1024, 1024, 200,
|
||||
200, DownsampleStrategy.FIT_CENTER_MEMORY)
|
||||
let req = (reqSize.width < 1024 && reqSize.height < 1024)
|
||||
expect(req).assertEqual(true);
|
||||
})
|
||||
it('FIT_CENTER_QUALITY', 2, () => {
|
||||
let reqSize: Size =
|
||||
new Downsampler().calculateScaling('jpg', 1024, 1024, 200,
|
||||
200, DownsampleStrategy.FIT_CENTER_QUALITY)
|
||||
let req = (reqSize.width < 1024 && reqSize.height < 1024)
|
||||
expect(req).assertEqual(true);
|
||||
})
|
||||
it('CENTER_OUTSIDE_MEMORY', 3, () => {
|
||||
let reqSize: Size =
|
||||
new Downsampler().calculateScaling('jpg', 1024, 1024, 200,
|
||||
200, DownsampleStrategy.CENTER_INSIDE_MEMORY)
|
||||
let req = (reqSize.width < 1024 && reqSize.height < 1024)
|
||||
expect(req).assertEqual(true);
|
||||
})
|
||||
it('CENTER_OUTSIDE_QUALITY', 4, () => {
|
||||
let reqSize: Size =
|
||||
new Downsampler().calculateScaling('jpg', 1024, 1024, 200,
|
||||
200, DownsampleStrategy.CENTER_INSIDE_QUALITY)
|
||||
let req = (reqSize.width < 1024 && reqSize.height < 1024)
|
||||
expect(req).assertEqual(true);
|
||||
})
|
||||
it('AT_LEAST', 5, () => {
|
||||
let reqSize: Size =
|
||||
new Downsampler().calculateScaling('jpg', 1024, 1024, 200,
|
||||
200, DownsampleStrategy.AT_LEAST)
|
||||
let req = (reqSize.width < 1024 && reqSize.height < 1024)
|
||||
expect(req).assertEqual(true);
|
||||
})
|
||||
|
||||
})
|
||||
}
|
|
@ -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 { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'
|
||||
import { SendableData } from '@ohos/imageknife/src/main/ets/components/imageknife/SendableData'
|
||||
|
||||
export default function SendableDataTest() {
|
||||
describe('SendableDataTest', ()=> {
|
||||
// Defines a test suite. Two parameters are supported: test suite name and test suite function.
|
||||
beforeAll( ()=> {
|
||||
// Presets an action, which is performed only once before all test cases of the test suite start.
|
||||
// This API supports only one parameter: preset action function.
|
||||
})
|
||||
beforeEach( ()=> {
|
||||
// Presets an action, which is performed before each unit test case starts.
|
||||
// The number of execution times is the same as the number of test cases defined by **it**.
|
||||
// This API supports only one parameter: preset action function.
|
||||
})
|
||||
afterEach( ()=> {
|
||||
// Presets a clear action, which is performed after each unit test case ends.
|
||||
// The number of execution times is the same as the number of test cases defined by **it**.
|
||||
// This API supports only one parameter: clear action function.
|
||||
})
|
||||
afterAll( ()=> {
|
||||
// Presets a clear action, which is performed after all test cases of the test suite end.
|
||||
// This API supports only one parameter: clear action function.
|
||||
})
|
||||
it('TestPlaceHolderCacheKey', 0, () => {
|
||||
let value: string = "placeholderRegisterCacheKey";
|
||||
let data: SendableData = new SendableData();
|
||||
data.setPlaceHolderRegisterCacheKey(value);
|
||||
expect(data.getPlaceHolderRegisterCacheKey()).assertEqual(value);
|
||||
})
|
||||
it('TestPlaceHolderMemoryCacheKey', 1, () => {
|
||||
let value: string = "placeholderRegisterMemoryCacheKey";
|
||||
let data: SendableData = new SendableData();
|
||||
data.setPlaceHolderRegisterMemoryCacheKey(value);
|
||||
expect(data.getPlaceHolderRegisterMemoryCacheKey()).assertEqual(value);
|
||||
})
|
||||
})
|
||||
}
|
|
@ -1,106 +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 { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'
|
||||
import { DownloadClient } from '@ohos/imageknife/src/main/ets/components/imageknife/networkmanage/DownloadClient';
|
||||
import common from '@ohos.app.ability.common';
|
||||
import { GlobalContext } from '../testability/GlobalContext';
|
||||
import { CustomDataFetchClient, DataFetchResult, ImageKnifeGlobal, RequestOption } from '@ohos/imageknife';
|
||||
|
||||
const BASE_COUNT: number = 2000;
|
||||
|
||||
export default function CustomDataFetchClientTest() {
|
||||
describe('CustomDataFetchClientTest', () => {
|
||||
// Defines a test suite. Two parameters are supported: test suite name and test suite function.
|
||||
beforeAll(() => {
|
||||
// Presets an action, which is performed only once before all test cases of the test suite start.
|
||||
// This API supports only one parameter: preset action function.
|
||||
})
|
||||
beforeEach(() => {
|
||||
// Presets an action, which is performed before each unit test case starts.
|
||||
// The number of execution times is the same as the number of test cases defined by **it**.
|
||||
// This API supports only one parameter: preset action function.
|
||||
})
|
||||
afterEach(() => {
|
||||
// Presets a clear action, which is performed after each unit test case ends.
|
||||
// The number of execution times is the same as the number of test cases defined by **it**.
|
||||
// This API supports only one parameter: clear action function.
|
||||
})
|
||||
afterAll(() => {
|
||||
// Presets a clear action, which is performed after all test cases of the test suite end.
|
||||
// This API supports only one parameter: clear action function.
|
||||
})
|
||||
it('TestIsLocalLoadSrc', 0, () => {
|
||||
let path = 'invalid path';
|
||||
let client = new DownloadClient()
|
||||
expect(client.isLocalLoadSrc(undefined, path)).assertFalse();
|
||||
let context: object | undefined = GlobalContext.getInstance().getObject("hapContext");
|
||||
if (context != undefined) {
|
||||
let loadSrc1 = (context as common.UIAbilityContext).filesDir + 'a.jpg';
|
||||
let loadSrc2 = (context as common.UIAbilityContext).cacheDir + 'b.jpg';
|
||||
expect(client.isLocalLoadSrc(context, loadSrc1)).assertTrue();
|
||||
expect(client.isLocalLoadSrc(context, loadSrc2)).assertTrue();
|
||||
}
|
||||
})
|
||||
it('TestLoadData', 1, async () => {
|
||||
let client = new CustomDataFetchClient();
|
||||
let request = new RequestOption();
|
||||
request.loadSrc = $r('app.media.icon');
|
||||
let error = (await client.loadData(request) as DataFetchResult).error as String;
|
||||
expect(error).assertEqual('CustomDataFetchClient request or loadSrc error.');
|
||||
})
|
||||
it('TestLoadData_customGetImage', 2, async () => {
|
||||
let client = new CustomDataFetchClient();
|
||||
let request = new RequestOption();
|
||||
request.loadSrc = 'http://e.hiphotos.baidu.com/image/pic/item/4e4a20a4462309f7e41f5cfe760e0cf3d6cad6ee.jpg';
|
||||
request.customGetImage = (context: Context, src: string) => {
|
||||
// 这里是模拟的customGetImage逻辑
|
||||
return Promise.resolve(new DataFetchResult());
|
||||
}
|
||||
console.log('LXH', 'TestLoadData 2 --1 customGetImage is undefined ?' + (request.customGetImage == undefined));
|
||||
let context: object | undefined = GlobalContext.getInstance().getObject("hapContext");
|
||||
let result = await client.loadData(request);
|
||||
if (context != undefined) {
|
||||
console.log('LXH', 'TestLoadData 2 --2');
|
||||
expect(typeof result)
|
||||
.assertEqual(typeof (await request?.customGetImage(context as common.UIAbilityContext, request.loadSrc)));
|
||||
}
|
||||
})
|
||||
it('TestLoadData_combineArrayBuffers', 3, () => {
|
||||
// 创建几个ArrayBuffer作为测试数据
|
||||
const arrayBuffer1 = new ArrayBuffer(4);
|
||||
const uint8Array1 = new Uint8Array(arrayBuffer1);
|
||||
uint8Array1[0] = 1;
|
||||
uint8Array1[1] = 2;
|
||||
uint8Array1[2] = 3;
|
||||
uint8Array1[3] = 4;
|
||||
|
||||
const arrayBuffer2 = new ArrayBuffer(2);
|
||||
const uint8Array2 = new Uint8Array(arrayBuffer2);
|
||||
uint8Array2[0] = 5;
|
||||
uint8Array2[1] = 6;
|
||||
let client = new CustomDataFetchClient();
|
||||
const combinedArrayBuffer = client.combineArrayBuffers([arrayBuffer1, arrayBuffer2]);
|
||||
expect(combinedArrayBuffer.byteLength).assertEqual(6);
|
||||
const combinedUint8Array = new Uint8Array(combinedArrayBuffer);
|
||||
for (let i = 0; i < 4; i++) {
|
||||
expect(combinedUint8Array[i]).assertEqual(uint8Array1[i]);
|
||||
}
|
||||
for (let i = 0; i < 2; i++) {
|
||||
expect(combinedUint8Array[i + 4]).assertEqual(uint8Array2[i]);
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
* 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 { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium';
|
||||
import {
|
||||
ImageKnifeOption,
|
||||
ImageKnife,
|
||||
ImageKnifeRequest,
|
||||
CacheStrategy
|
||||
} from "@ohos/imageknife"
|
||||
import { common } from '@kit.AbilityKit';
|
||||
|
||||
export default function imageFormatAndSize() {
|
||||
describe('imageFormatAndSize', () => {
|
||||
// Defines a test suite. Two parameters are supported: test suite name and test suite function.
|
||||
beforeAll(() => {
|
||||
// Presets an action, which is performed only once before all test cases of the test suite start.
|
||||
// This API supports only one parameter: preset action function.
|
||||
});
|
||||
beforeEach(() => {
|
||||
// Presets an action, which is performed before each unit test case starts.
|
||||
// The number of execution times is the same as the number of test cases defined by **it**.
|
||||
// This API supports only one parameter: preset action function.
|
||||
});
|
||||
afterEach(() => {
|
||||
// Presets a clear action, which is performed after each unit test case ends.
|
||||
// The number of execution times is the same as the number of test cases defined by **it**.
|
||||
// This API supports only one parameter: clear action function.
|
||||
});
|
||||
afterAll(() => {
|
||||
// Presets a clear action, which is performed after all test cases of the test suite end.
|
||||
// This API supports only one parameter: clear action function.
|
||||
});
|
||||
it('getImageSizeInCache', 0, async () => {
|
||||
let width = 0;
|
||||
let height = 0;
|
||||
let imageFormat: string = "";
|
||||
let url: string =
|
||||
"https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/ed/v3/KMO4D6D2QGuVOCLX4AhOFA/ef51xAaLQuK7BsnuD9abog.jpg"
|
||||
let imageKnifeOption: ImageKnifeOption = {
|
||||
loadSrc: url,
|
||||
}
|
||||
await new Promise<string>((resolve, reject) => {
|
||||
imageKnifeOption.onLoadListener = {
|
||||
onLoadSuccess: (data, imageknifeData) => {
|
||||
resolve("")
|
||||
},
|
||||
onLoadFailed(err) {
|
||||
reject(err)
|
||||
}
|
||||
}
|
||||
let request = new ImageKnifeRequest(
|
||||
imageKnifeOption,
|
||||
imageKnifeOption.context !== undefined ? imageKnifeOption.context : getContext() as common.UIAbilityContext,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
{
|
||||
showPixelMap(version: number, pixelMap: PixelMap | string) {
|
||||
}
|
||||
}
|
||||
)
|
||||
ImageKnife.getInstance().execute(request);
|
||||
})
|
||||
let data = await ImageKnife.getInstance()
|
||||
.getCacheImage(url, CacheStrategy.Memory);
|
||||
if (data) {
|
||||
width = data.imageWidth
|
||||
height = data.imageHeight
|
||||
imageFormat = data.type!
|
||||
}
|
||||
expect(width != 0).assertTrue();
|
||||
expect(height != 0).assertTrue();
|
||||
expect(imageFormat != "").assertTrue();
|
||||
});
|
||||
});
|
||||
}
|
|
@ -0,0 +1,116 @@
|
|||
/*
|
||||
* Copyright (C) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium';
|
||||
import {
|
||||
ImageKnifeOption,
|
||||
ImageKnife,
|
||||
ImageKnifeRequest,
|
||||
ImageKnifeData
|
||||
} from "@ohos/imageknife"
|
||||
import { common } from '@kit.AbilityKit';
|
||||
|
||||
export default function loadCallBackData() {
|
||||
describe('loadCallBackData', () => {
|
||||
// Defines a test suite. Two parameters are supported: test suite name and test suite function.
|
||||
beforeAll(() => {
|
||||
// Presets an action, which is performed only once before all test cases of the test suite start.
|
||||
// This API supports only one parameter: preset action function.
|
||||
});
|
||||
beforeEach(() => {
|
||||
// Presets an action, which is performed before each unit test case starts.
|
||||
// The number of execution times is the same as the number of test cases defined by **it**.
|
||||
// This API supports only one parameter: preset action function.
|
||||
});
|
||||
afterEach(() => {
|
||||
// Presets a clear action, which is performed after each unit test case ends.
|
||||
// The number of execution times is the same as the number of test cases defined by **it**.
|
||||
// This API supports only one parameter: clear action function.
|
||||
});
|
||||
afterAll(() => {
|
||||
// Presets a clear action, which is performed after all test cases of the test suite end.
|
||||
// This API supports only one parameter: clear action function.
|
||||
});
|
||||
it('startAndSuccess-CallBack', 0, async () => {
|
||||
let startCallBack: ImageKnifeData | undefined = undefined;
|
||||
let successCallBack: ImageKnifeData | undefined = undefined;
|
||||
let url: string =
|
||||
"https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/63/v3/qbe6NZkCQyGcITvdWoZBgg/Y-5U1z3GT_yaK8CBD3jkwg.jpg"
|
||||
let imageKnifeOption: ImageKnifeOption = {
|
||||
loadSrc: url,
|
||||
}
|
||||
await new Promise<string>((resolve, reject) => {
|
||||
imageKnifeOption.onLoadListener = {
|
||||
onLoadStart: (data) => {
|
||||
startCallBack = data?.imageKnifeData;
|
||||
},
|
||||
onLoadSuccess: (data, imageknifeData,req) => {
|
||||
successCallBack = req?.imageKnifeData;
|
||||
resolve("")
|
||||
},
|
||||
onLoadFailed(err) {
|
||||
reject(err)
|
||||
}
|
||||
}
|
||||
let request = new ImageKnifeRequest(
|
||||
imageKnifeOption,
|
||||
imageKnifeOption.context !== undefined ? imageKnifeOption.context : getContext() as common.UIAbilityContext,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
{
|
||||
showPixelMap(version: number, pixelMap: PixelMap | string) {
|
||||
}
|
||||
}
|
||||
)
|
||||
ImageKnife.getInstance().execute(request);
|
||||
})
|
||||
expect(startCallBack != undefined).assertTrue();
|
||||
expect(successCallBack != undefined).assertTrue();
|
||||
});
|
||||
it('failed-CallBack', 0, async () => {
|
||||
let failedCallBack: ImageKnifeData | undefined = undefined;
|
||||
let url: string =
|
||||
"https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/163/v3/qbe6NZkCQyGcITvdWoZBgg/Y-5U1z3GT_yaK8CBD3jkwg.jpg"
|
||||
let imageKnifeOption: ImageKnifeOption = {
|
||||
loadSrc: url,
|
||||
}
|
||||
await new Promise<string>((resolve, reject) => {
|
||||
imageKnifeOption.onLoadListener = {
|
||||
onLoadStart: (data) => {
|
||||
},
|
||||
onLoadSuccess: (data, imageknifeData) => {
|
||||
},
|
||||
onLoadFailed(res,req) {
|
||||
failedCallBack = req?.imageKnifeData;
|
||||
resolve(res)
|
||||
}
|
||||
}
|
||||
let request = new ImageKnifeRequest(
|
||||
imageKnifeOption,
|
||||
imageKnifeOption.context !== undefined ? imageKnifeOption.context : getContext() as common.UIAbilityContext,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
{
|
||||
showPixelMap(version: number, pixelMap: PixelMap | string) {
|
||||
}
|
||||
}
|
||||
)
|
||||
ImageKnife.getInstance().execute(request);
|
||||
})
|
||||
expect(failedCallBack != undefined).assertTrue();
|
||||
});
|
||||
});
|
||||
}
|
|
@ -6,7 +6,11 @@
|
|||
"mainElement": "TestAbility",
|
||||
"deviceTypes": [
|
||||
"default",
|
||||
"tablet"
|
||||
"tablet",
|
||||
"tv",
|
||||
"wearable",
|
||||
"car",
|
||||
"2in1"
|
||||
],
|
||||
"deliveryWithInstall": true,
|
||||
"installationFree": false,
|
||||
|
|
|
@ -18,9 +18,12 @@ export { ImageKnifeAnimatorComponent } from './src/main/ets/components/ImageKnif
|
|||
|
||||
export { ImageKnife } from './src/main/ets/ImageKnife'
|
||||
|
||||
export { ImageKnifeOption , AnimatorOption } from './src/main/ets/ImageKnifeOption'
|
||||
export { ImageKnifeOption,
|
||||
AnimatorOption,
|
||||
HttpRequestOption,
|
||||
HeaderOptions } from './src/main/ets/model/ImageKnifeOption'
|
||||
|
||||
export { ImageKnifeRequest } from './src/main/ets/ImageKnifeRequest'
|
||||
export { ImageKnifeRequest } from './src/main/ets/model/ImageKnifeRequest'
|
||||
|
||||
export { FileUtils } from './src/main/ets/utils/FileUtils'
|
||||
|
||||
|
@ -30,6 +33,8 @@ export { IEngineKey } from './src/main/ets/key/IEngineKey'
|
|||
|
||||
export { ImageKnifeData , CacheStrategy , ImageKnifeRequestSource} from "./src/main/ets/model/ImageKnifeData"
|
||||
|
||||
export { DownsampleStrategy } from './src/main/ets/downsampling/DownsampleStartegy'
|
||||
|
||||
export { PixelMapTransformation } from './src/main/ets/transform/PixelMapTransformation'
|
||||
|
||||
export { MultiTransTransformation } from './src/main/ets/transform/MultiTransTransformation'
|
||||
|
|
|
@ -1,6 +1,19 @@
|
|||
{
|
||||
"meta": {
|
||||
"stableOrder": false
|
||||
},
|
||||
"lockfileVersion": 3,
|
||||
"ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.",
|
||||
"specifiers": {},
|
||||
"packages": {}
|
||||
"specifiers": {
|
||||
"@ohos/gpu_transform@^1.0.2": "@ohos/gpu_transform@1.0.4"
|
||||
},
|
||||
"packages": {
|
||||
"@ohos/gpu_transform@1.0.4": {
|
||||
"name": "@ohos/gpu_transform",
|
||||
"version": "1.0.4",
|
||||
"integrity": "sha512-PrKlOK66kzObw/ANIzt55YMrOLLmtrhmAZIE2c/60GBoTl7+NLxONeHA2NsDZuiW+A0KnD4QylDYWH4/yo8T0w==",
|
||||
"resolved": "https://ohpm.openharmony.cn/ohpm/@ohos/gpu_transform/-/gpu_transform-1.0.4.har",
|
||||
"registryType": "ohpm"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -14,7 +14,7 @@
|
|||
"main": "index.ets",
|
||||
"repository": "https://gitee.com/openharmony-tpc/ImageKnife",
|
||||
"type": "module",
|
||||
"version": "3.1.0-rc.2",
|
||||
"version": "3.2.2-rc.1",
|
||||
"dependencies": {
|
||||
"@ohos/gpu_transform": "^1.0.2"
|
||||
},
|
||||
|
|
|
@ -12,19 +12,20 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { ImageKnifeRequest } from './ImageKnifeRequest';
|
||||
import { ImageKnifeRequest, ImageKnifeRequestState } from './model/ImageKnifeRequest';
|
||||
import { CacheStrategy, ImageKnifeData, ImageKnifeRequestSource } from './model/ImageKnifeData';
|
||||
import { MemoryLruCache } from './utils/MemoryLruCache';
|
||||
import { IMemoryCache } from './utils/IMemoryCache'
|
||||
import { FileCache } from './utils/FileCache';
|
||||
import { MemoryLruCache } from './cache/MemoryLruCache';
|
||||
import { IMemoryCache } from './cache/IMemoryCache'
|
||||
import { FileCache } from './cache/FileCache';
|
||||
import { ImageKnifeDispatcher } from './ImageKnifeDispatcher';
|
||||
import { IEngineKey } from './key/IEngineKey';
|
||||
import { HeaderOptions, ImageKnifeOption } from './ImageKnifeOption';
|
||||
import { HeaderOptions, ImageKnifeOption } from './model/ImageKnifeOption';
|
||||
import { FileTypeUtil } from './utils/FileTypeUtil';
|
||||
import { util } from '@kit.ArkTS';
|
||||
import { image } from '@kit.ImageKit';
|
||||
import { common } from '@kit.AbilityKit';
|
||||
import { LogUtil } from './utils/LogUtil';
|
||||
import { emitter } from '@kit.BasicServicesKit';
|
||||
|
||||
|
||||
export class ImageKnife {
|
||||
|
@ -38,7 +39,7 @@ export class ImageKnife {
|
|||
private _isRequestInSubThread: boolean = true;
|
||||
//定义全局网络请求header map
|
||||
headerMap: Map<string, Object> = new Map<string, Object>();
|
||||
customGetImage: ((context: Context, src: string | PixelMap | Resource) => Promise<ArrayBuffer | undefined>) | undefined = undefined
|
||||
customGetImage: ((context: Context, src: string | PixelMap | Resource,headers?: Record<string,Object>) => Promise<ArrayBuffer | undefined>) | undefined = undefined
|
||||
public static getInstance(): ImageKnife {
|
||||
if (!ImageKnife.instance) {
|
||||
ImageKnife.instance = new ImageKnife();
|
||||
|
@ -80,7 +81,15 @@ export class ImageKnife {
|
|||
public isFileCacheInit(): boolean {
|
||||
return this.fileCache === undefined ? false : this.fileCache.isFileCacheInit()
|
||||
}
|
||||
|
||||
/**
|
||||
* 重新加载
|
||||
*/
|
||||
reload(request: ImageKnifeRequest) {
|
||||
if (request.requestState == ImageKnifeRequestState.ERROR) {
|
||||
request.requestState = ImageKnifeRequestState.PROGRESS
|
||||
ImageKnife.getInstance().execute(request)
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 全局添加单个请求头header
|
||||
* @param key 请求头属性
|
||||
|
@ -137,8 +146,42 @@ export class ImageKnife {
|
|||
let key = this.getEngineKeyImpl().generateMemoryKey(imageKnifeOption.loadSrc, ImageKnifeRequestSource.SRC, imageKnifeOption);
|
||||
this.memoryCache.remove(key);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 预加载
|
||||
* @param loadSrc 图片地址url
|
||||
* @returns 图片请求request
|
||||
*/
|
||||
preload(loadSrc:string | ImageKnifeOption):ImageKnifeRequest{
|
||||
let imageKnifeOption = new ImageKnifeOption()
|
||||
if (typeof loadSrc == 'string') {
|
||||
imageKnifeOption.loadSrc = loadSrc
|
||||
} else {
|
||||
imageKnifeOption = loadSrc;
|
||||
}
|
||||
let request = new ImageKnifeRequest(
|
||||
imageKnifeOption,
|
||||
imageKnifeOption.context !== undefined ? imageKnifeOption.context : getContext(this) as common.UIAbilityContext,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
{
|
||||
showPixelMap(version: number, pixelMap: PixelMap | string) {
|
||||
}
|
||||
}
|
||||
)
|
||||
this.execute(request)
|
||||
return request
|
||||
}
|
||||
/**
|
||||
* 取消图片请求
|
||||
* @param request 图片请求request
|
||||
*/
|
||||
cancel(request:ImageKnifeRequest) {
|
||||
if (typeof request?.imageKnifeOption.loadSrc === 'string' && !request?.drawMainSuccess) {
|
||||
emitter.emit(request.imageKnifeOption.loadSrc + request.componentId)
|
||||
}
|
||||
request.requestState = ImageKnifeRequestState.DESTROY
|
||||
}
|
||||
/**
|
||||
* 预加载图片到文件缓存
|
||||
* @param loadSrc 图片地址url
|
||||
|
@ -147,15 +190,15 @@ export class ImageKnife {
|
|||
preLoadCache(loadSrc: string | ImageKnifeOption): Promise<string> {
|
||||
return new Promise((resolve, reject) => {
|
||||
let imageKnifeOption = new ImageKnifeOption()
|
||||
if (typeof loadSrc == "string") {
|
||||
if (typeof loadSrc == 'string') {
|
||||
imageKnifeOption.loadSrc = loadSrc
|
||||
} else {
|
||||
imageKnifeOption = loadSrc;
|
||||
}
|
||||
LogUtil.log("ImageKnife_DataTime_preLoadCache-imageKnifeOption:"+loadSrc)
|
||||
LogUtil.log('ImageKnife_DataTime_preLoadCache-imageKnifeOption:'+loadSrc)
|
||||
let fileKey = this.getEngineKeyImpl().generateFileKey(imageKnifeOption.loadSrc, imageKnifeOption.signature)
|
||||
let cachePath = ImageKnife.getInstance().getFileCache().getFileToPath(fileKey)
|
||||
if (cachePath == null || cachePath == "" || cachePath == undefined) {
|
||||
if (cachePath == null || cachePath == '' || cachePath == undefined) {
|
||||
imageKnifeOption.onLoadListener = {
|
||||
onLoadSuccess(){
|
||||
resolve(ImageKnife.getInstance().getFileCache().getFileToPath(fileKey))
|
||||
|
@ -191,10 +234,10 @@ export class ImageKnife {
|
|||
*/
|
||||
getCacheImage(loadSrc: string,
|
||||
cacheType: CacheStrategy = CacheStrategy.Default, signature?: string): Promise<ImageKnifeData | undefined> {
|
||||
let option: ImageKnifeOption = new ImageKnifeOption({
|
||||
let option: ImageKnifeOption = {
|
||||
loadSrc: loadSrc,
|
||||
signature:signature
|
||||
})
|
||||
}
|
||||
let engineKeyImpl: IEngineKey = this.getEngineKeyImpl();
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
|
@ -218,7 +261,7 @@ export class ImageKnife {
|
|||
*/
|
||||
putCacheImage(url: string, pixelMap: PixelMap, cacheType: CacheStrategy = CacheStrategy.Default, signature?: string) {
|
||||
let memoryKey = this.getEngineKeyImpl()
|
||||
.generateMemoryKey(url, ImageKnifeRequestSource.SRC, new ImageKnifeOption({ loadSrc: url, signature: signature }));
|
||||
.generateMemoryKey(url, ImageKnifeRequestSource.SRC, { loadSrc: url, signature: signature });
|
||||
let fileKey = this.getEngineKeyImpl().generateFileKey(url, signature);
|
||||
let imageKnifeData: ImageKnifeData = { source: pixelMap, imageWidth: 0, imageHeight: 0 };
|
||||
switch (cacheType) {
|
||||
|
@ -252,9 +295,9 @@ export class ImageKnife {
|
|||
if (url instanceof ImageKnifeOption) {
|
||||
imageKnifeOption = url;
|
||||
} else {
|
||||
imageKnifeOption = new ImageKnifeOption({
|
||||
imageKnifeOption = {
|
||||
loadSrc: url
|
||||
});
|
||||
};
|
||||
}
|
||||
let key = this.getEngineKeyImpl().generateFileKey(imageKnifeOption.loadSrc, imageKnifeOption.signature);
|
||||
if (this.fileCache !== undefined) {
|
||||
|
@ -278,14 +321,14 @@ export class ImageKnife {
|
|||
}
|
||||
|
||||
loadFromMemoryCache(key: string): ImageKnifeData | undefined {
|
||||
if (key !== "") {
|
||||
if (key !== '') {
|
||||
return this.memoryCache.get(key)
|
||||
}
|
||||
return undefined
|
||||
}
|
||||
|
||||
saveMemoryCache(key: string, data: ImageKnifeData): void {
|
||||
if (key !== "") {
|
||||
if (key !== '') {
|
||||
this.memoryCache.put(key, data)
|
||||
}
|
||||
}
|
||||
|
@ -302,6 +345,65 @@ export class ImageKnife {
|
|||
return this.fileCache as FileCache
|
||||
}
|
||||
|
||||
/**
|
||||
* get cache upper limit
|
||||
* @param cacheType
|
||||
* @returns
|
||||
*/
|
||||
getCacheLimitSize(cacheType?: CacheStrategy): number | undefined {
|
||||
if (cacheType == undefined || cacheType == CacheStrategy.Default) {
|
||||
cacheType = CacheStrategy.Memory;
|
||||
}
|
||||
if (cacheType == CacheStrategy.Memory) {
|
||||
return (this.memoryCache as MemoryLruCache).maxMemory;
|
||||
} else {
|
||||
if (this.isFileCacheInit()) {
|
||||
return this.fileCache?.maxMemory;
|
||||
} else {
|
||||
throw new Error('the disk cache not init');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gets the number of images currently cached
|
||||
* @param cacheType
|
||||
* @returns
|
||||
*/
|
||||
getCurrentCacheNum(cacheType: CacheStrategy): number | undefined {
|
||||
if (cacheType == undefined || cacheType == CacheStrategy.Default) {
|
||||
cacheType = CacheStrategy.Memory;
|
||||
}
|
||||
if (cacheType == CacheStrategy.Memory) {
|
||||
return (this.memoryCache as MemoryLruCache).size();
|
||||
} else {
|
||||
if (this.isFileCacheInit()) {
|
||||
return this.fileCache?.size();
|
||||
} else {
|
||||
throw new Error('the disk cache not init');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gets the current cache size
|
||||
* @param cacheType
|
||||
* @returns
|
||||
*/
|
||||
getCurrentCacheSize(cacheType: CacheStrategy): number | undefined {
|
||||
if (cacheType == undefined || cacheType == CacheStrategy.Default) {
|
||||
cacheType = CacheStrategy.Memory;
|
||||
}
|
||||
if (cacheType == CacheStrategy.Memory) {
|
||||
return (this.memoryCache as MemoryLruCache).currentMemory;
|
||||
} else {
|
||||
if (this.isFileCacheInit()) {
|
||||
return this.fileCache?.currentMemory;
|
||||
} else {
|
||||
throw new Error('the disk cache not init');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private pixelMapToArrayBuffer(pixelMap: PixelMap): ArrayBuffer {
|
||||
let imageInfo = pixelMap.getImageInfoSync();
|
||||
|
@ -326,7 +428,7 @@ export class ImageKnife {
|
|||
if (typeValue === 'gif' || typeValue === 'webp') {
|
||||
let base64Help = new util.Base64Helper()
|
||||
|
||||
let base64str = "data:image/" + typeValue + ";base64," + base64Help.encodeToStringSync(new Uint8Array(buffer))
|
||||
let base64str = 'data:image/' + typeValue + ';base64,' + base64Help.encodeToStringSync(new Uint8Array(buffer))
|
||||
onComplete({
|
||||
source: base64str,
|
||||
imageWidth: 0,
|
||||
|
@ -364,13 +466,13 @@ export class ImageKnife {
|
|||
return false
|
||||
}
|
||||
|
||||
async execute(request: ImageKnifeRequest,isAnimator?: boolean): Promise<void> {
|
||||
LogUtil.log("ImageKnife_DataTime_execute.start:"+request.imageKnifeOption.loadSrc)
|
||||
async execute(request: ImageKnifeRequest): Promise<void> {
|
||||
LogUtil.log('ImageKnife_DataTime_execute.start:'+request.imageKnifeOption.loadSrc)
|
||||
if (this.headerMap.size > 0) {
|
||||
request.addHeaderMap(this.headerMap)
|
||||
}
|
||||
this.dispatcher.enqueue(request,isAnimator)
|
||||
LogUtil.log("ImageKnife_DataTime_execute.end:"+request.imageKnifeOption.loadSrc)
|
||||
this.dispatcher.enqueue(request)
|
||||
LogUtil.log('ImageKnife_DataTime_execute.end:'+request.imageKnifeOption.loadSrc)
|
||||
}
|
||||
|
||||
setEngineKeyImpl(impl: IEngineKey): void {
|
||||
|
@ -384,10 +486,10 @@ export class ImageKnife {
|
|||
* 全局设置自定义下载
|
||||
* @param customGetImage 自定义请求函数
|
||||
*/
|
||||
setCustomGetImage(customGetImage?: (context: Context, src: string | PixelMap | Resource) => Promise<ArrayBuffer | undefined>) {
|
||||
setCustomGetImage(customGetImage?: (context: Context, src: string | PixelMap | Resource,headers?: Record<string,Object>) => Promise<ArrayBuffer | undefined>) {
|
||||
this.customGetImage = customGetImage
|
||||
}
|
||||
getCustomGetImage(): undefined | ((context: Context, src: string | PixelMap | Resource) => Promise<ArrayBuffer | undefined>){
|
||||
getCustomGetImage(): undefined | ((context: Context, src: string | PixelMap | Resource,headers?: Record<string,Object>) => Promise<ArrayBuffer | undefined>){
|
||||
return this.customGetImage
|
||||
}
|
||||
}
|
|
@ -12,24 +12,18 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { ImageKnifeRequest, ImageKnifeRequestState } from './ImageKnifeRequest'
|
||||
import { DefaultJobQueue } from './utils/DefaultJobQueue'
|
||||
import { IJobQueue } from './utils/IJobQueue'
|
||||
import { ImageKnifeRequest, ImageKnifeRequestState } from './model/ImageKnifeRequest'
|
||||
import { DefaultJobQueue } from './queue/DefaultJobQueue'
|
||||
import { IJobQueue } from './queue/IJobQueue'
|
||||
import List from '@ohos.util.List';
|
||||
import LightWeightMap from '@ohos.util.LightWeightMap';
|
||||
import { LogUtil } from './utils/LogUtil';
|
||||
import buffer from '@ohos.buffer';
|
||||
import { FileCache } from './utils/FileCache';
|
||||
import fs from '@ohos.file.fs';
|
||||
import { ImageKnife } from './ImageKnife';
|
||||
import { ImageKnifeData, CacheStrategy } from './model/ImageKnifeData';
|
||||
import http from '@ohos.net.http';
|
||||
import { ImageKnifeData, CacheStrategy, TimeInfo, ErrorInfo } from './model/ImageKnifeData';
|
||||
import image from '@ohos.multimedia.image';
|
||||
import emitter from '@ohos.events.emitter';
|
||||
import { Constants } from './utils/Constants';
|
||||
import { Constants, LoadPhase, LoadPixelMapCode } from './utils/Constants';
|
||||
import taskpool from '@ohos.taskpool';
|
||||
import { FileTypeUtil } from './utils/FileTypeUtil';
|
||||
import util from '@ohos.util';
|
||||
import { IEngineKey } from './key/IEngineKey';
|
||||
import { DefaultEngineKey } from './key/DefaultEngineKey';
|
||||
import {
|
||||
|
@ -38,8 +32,10 @@ import {
|
|||
RequestJobResult,
|
||||
RequestJobRequest
|
||||
} from './model/ImageKnifeData'
|
||||
import { combineArrayBuffers } from './model/utils';
|
||||
import { BusinessError } from '@kit.BasicServicesKit';
|
||||
import { ImageKnifeLoader } from './ImageKnifeLoader'
|
||||
import { DownsampleStrategy } from './downsampling/DownsampleStartegy';
|
||||
|
||||
|
||||
export class ImageKnifeDispatcher {
|
||||
// 最大并发
|
||||
|
@ -52,9 +48,10 @@ export class ImageKnifeDispatcher {
|
|||
private engineKey: IEngineKey = new DefaultEngineKey();
|
||||
|
||||
showFromMemomry(request: ImageKnifeRequest, imageSrc: string | PixelMap | Resource, requestSource: ImageKnifeRequestSource,isAnimator?: boolean): boolean {
|
||||
LogUtil.log("ImageKnife_DataTime_showFromMemomry.start:" + request.imageKnifeOption.loadSrc)
|
||||
LogUtil.log('showFromMemomry.start:' + request.componentId + ',srcType:' + requestSource + ',version:' + request.componentVersion + ' isAnimator=' + isAnimator)
|
||||
let memoryCache: ImageKnifeData | undefined;
|
||||
if ((typeof (request.imageKnifeOption.loadSrc as image.PixelMap).isEditable) == 'boolean') {
|
||||
let memoryCheckStartTime = Date.now();
|
||||
if ((typeof (request.imageKnifeOption.loadSrc as image.PixelMap)?.isEditable) == 'boolean') {
|
||||
memoryCache = {
|
||||
source: request.imageKnifeOption.loadSrc as image.PixelMap,
|
||||
imageWidth: 0,
|
||||
|
@ -62,45 +59,103 @@ export class ImageKnifeDispatcher {
|
|||
}
|
||||
} else {
|
||||
memoryCache = ImageKnife.getInstance()
|
||||
.loadFromMemoryCache(this.engineKey.generateMemoryKey(imageSrc, requestSource, request.imageKnifeOption,isAnimator));
|
||||
.loadFromMemoryCache(this.engineKey.generateMemoryKey(imageSrc, requestSource, request.imageKnifeOption,isAnimator, request.componentWidth, request.componentHeight));
|
||||
}
|
||||
|
||||
//记录ImageKnifeRequestSource.SRC 开始内存检查的时间点
|
||||
if (requestSource == ImageKnifeRequestSource.SRC && request.imageKnifeData) {
|
||||
let timeInfo = request.imageKnifeData?.timeInfo
|
||||
if (timeInfo) {
|
||||
timeInfo.memoryCheckStartTime = memoryCheckStartTime;
|
||||
timeInfo.memoryCheckEndTime = Date.now();
|
||||
//设置请求结束的时间点
|
||||
if (memoryCache !== undefined) {
|
||||
timeInfo.requestEndTime = Date.now();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (memoryCache !== undefined) {
|
||||
// 画主图
|
||||
if (request.requestState === ImageKnifeRequestState.PROGRESS) {
|
||||
// 回调请求开始
|
||||
if (requestSource === ImageKnifeRequestSource.SRC && request.imageKnifeOption.onLoadListener?.onLoadStart !== undefined) {
|
||||
request.imageKnifeOption.onLoadListener?.onLoadStart()
|
||||
LogUtil.log("ImageKnife_DataTime_MemoryCache_onLoadStart:" + request.imageKnifeOption.loadSrc)
|
||||
request.imageKnifeOption.onLoadListener.onLoadStart(request)
|
||||
}
|
||||
LogUtil.log("ImageKnife_DataTime_MemoryCache_showPixelMap.start:" + request.imageKnifeOption.loadSrc)
|
||||
request.ImageKnifeRequestCallback?.showPixelMap(request.componentVersion, memoryCache.source, requestSource,memoryCache.imageAnimator)
|
||||
LogUtil.log("ImageKnife_DataTime_MemoryCache_showPixelMap.end:" + request.imageKnifeOption.loadSrc)
|
||||
request.ImageKnifeRequestCallback?.showPixelMap(request.componentVersion, memoryCache.source,
|
||||
{ width: memoryCache.imageWidth, height: memoryCache.imageHeight }, requestSource, memoryCache.imageAnimator)
|
||||
|
||||
if (requestSource == ImageKnifeRequestSource.SRC) {
|
||||
request.requestState = ImageKnifeRequestState.COMPLETE
|
||||
request.drawMainSuccess = true
|
||||
// 回调请求开结束
|
||||
if (request.imageKnifeOption.onLoadListener?.onLoadSuccess !== undefined) {
|
||||
request.imageKnifeOption.onLoadListener?.onLoadSuccess(memoryCache.source,memoryCache)
|
||||
LogUtil.log("ImageKnife_DataTime_MemoryCache_onLoadSuccess:" + request.imageKnifeOption.loadSrc)
|
||||
this.copyMemoryCacheInfo(memoryCache, request.imageKnifeData);
|
||||
request.imageKnifeOption.onLoadListener.onLoadSuccess(memoryCache.source, memoryCache, request)
|
||||
}
|
||||
} else if (requestSource == ImageKnifeRequestSource.ERROR_HOLDER) {
|
||||
request.requestState = ImageKnifeRequestState.ERROR
|
||||
}
|
||||
}
|
||||
LogUtil.log("ImageKnife_DataTime_showFromMemomry.end_true:" + request.imageKnifeOption.loadSrc)
|
||||
LogUtil.log('showFromMemomry.end_hasmemory:' + request.componentId + ',srcType:' + requestSource + ',version:' + request.componentVersion)
|
||||
return true
|
||||
}
|
||||
LogUtil.log("ImageKnife_DataTime_showFromMemomry.end_false:" + request.imageKnifeOption.loadSrc)
|
||||
LogUtil.log('showFromMemomry.end_nomemory:' + request.componentId + ',srcType:' + requestSource + ',version:' + request.componentVersion)
|
||||
return false
|
||||
}
|
||||
|
||||
private copyMemoryCacheInfo(memoryCache: ImageKnifeData | undefined, target: ImageKnifeData | undefined) {
|
||||
if (!memoryCache || !target) {
|
||||
return;
|
||||
}
|
||||
target.source = memoryCache.source;
|
||||
target.imageWidth = memoryCache.imageWidth;
|
||||
target.imageHeight = memoryCache.imageHeight;
|
||||
target.type = memoryCache.type;
|
||||
target.bufSize = memoryCache.bufSize
|
||||
target.imageAnimator = memoryCache.imageAnimator;
|
||||
}
|
||||
|
||||
enqueue(request: ImageKnifeRequest,isAnimator?: boolean): void {
|
||||
private assembleImageKnifeData(beforeCallData: ImageKnifeData | undefined, afterCallData: ImageKnifeData | undefined, req: ImageKnifeRequest) {
|
||||
if (!beforeCallData || !afterCallData || !req) {
|
||||
return;
|
||||
}
|
||||
//设置图片开始加载时间及其缓存检查时间点
|
||||
if (beforeCallData.timeInfo) {
|
||||
if (afterCallData.timeInfo) {
|
||||
afterCallData.timeInfo.requestStartTime = beforeCallData.timeInfo.requestStartTime;
|
||||
afterCallData.timeInfo.memoryCheckStartTime = beforeCallData.timeInfo.memoryCheckStartTime;
|
||||
afterCallData.timeInfo.memoryCheckEndTime = beforeCallData.timeInfo.memoryCheckEndTime;
|
||||
}
|
||||
}
|
||||
req.imageKnifeData = afterCallData;
|
||||
}
|
||||
|
||||
private initCallData(request: ImageKnifeRequest) {
|
||||
if (!request) {
|
||||
return
|
||||
}
|
||||
//图片加载信息回调数据
|
||||
let callBackData: ImageKnifeData = {
|
||||
source: '',
|
||||
imageWidth: 0,
|
||||
imageHeight: 0,
|
||||
};
|
||||
|
||||
//图片加载信息回调数据时间点
|
||||
let callBackTimeInfo: TimeInfo = {};
|
||||
callBackTimeInfo.requestStartTime = Date.now();
|
||||
callBackData.timeInfo = callBackTimeInfo;
|
||||
|
||||
//跟隨請求保存回調信息點
|
||||
request.imageKnifeData = callBackData;
|
||||
}
|
||||
|
||||
enqueue(request: ImageKnifeRequest,): void {
|
||||
//初始化加载回调信息
|
||||
this.initCallData(request);
|
||||
//1.内存有的话直接渲染
|
||||
if (this.showFromMemomry(request, request.imageKnifeOption.loadSrc, ImageKnifeRequestSource.SRC,isAnimator)) {
|
||||
if (this.showFromMemomry(request, request.imageKnifeOption.loadSrc, ImageKnifeRequestSource.SRC,request.animator)) {
|
||||
return
|
||||
}
|
||||
// 2.内存获取占位图
|
||||
|
@ -110,31 +165,34 @@ export class ImageKnifeDispatcher {
|
|||
}
|
||||
}
|
||||
//3.判断是否要排队
|
||||
if (this.executingJobMap.length > this.maxRequests) {
|
||||
if (this.executingJobMap.length >= this.maxRequests) {
|
||||
this.jobQueue.add(request)
|
||||
return
|
||||
}
|
||||
this.executeJob(request,isAnimator)
|
||||
this.executeJob(request)
|
||||
}
|
||||
|
||||
executeJob(request: ImageKnifeRequest,isAnimator?: boolean): void {
|
||||
LogUtil.log("ImageKnife_DataTime_executeJob.start:" + request.imageKnifeOption.loadSrc)
|
||||
executeJob(request: ImageKnifeRequest): void {
|
||||
LogUtil.log('executeJob.start:' + request.componentId + ',version:' + request.componentVersion)
|
||||
// 加载占位符
|
||||
if (request.imageKnifeOption.placeholderSrc !== undefined && request.drawPlayHolderSuccess == false) {
|
||||
this.getAndShowImage(request, request.imageKnifeOption.placeholderSrc, ImageKnifeRequestSource.PLACE_HOLDER)
|
||||
}
|
||||
|
||||
if (request.imageKnifeOption.onLoadListener?.onLoadStart !== undefined) {
|
||||
request.imageKnifeOption.onLoadListener?.onLoadStart(request)
|
||||
}
|
||||
// 加载主图
|
||||
this.getAndShowImage(request, request.imageKnifeOption.loadSrc, ImageKnifeRequestSource.SRC,isAnimator)
|
||||
LogUtil.log("ImageKnife_DataTime_executeJob.end:" + request.imageKnifeOption.loadSrc)
|
||||
this.getAndShowImage(request, request.imageKnifeOption.loadSrc, ImageKnifeRequestSource.SRC,request.animator)
|
||||
LogUtil.log('executeJob.end:' + request.componentId + ',version:' + request.componentVersion)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取和显示图片
|
||||
*/
|
||||
getAndShowImage(currentRequest: ImageKnifeRequest, imageSrc: string | PixelMap | Resource, requestSource: ImageKnifeRequestSource,isAnimator?: boolean): void {
|
||||
LogUtil.log("ImageKnife_DataTime_getAndShowImage.start:" + currentRequest.imageKnifeOption.loadSrc)
|
||||
let memoryKey: string = this.engineKey.generateMemoryKey(imageSrc, requestSource, currentRequest.imageKnifeOption,isAnimator)
|
||||
LogUtil.log('getAndShowImage.start:' + currentRequest.componentId + ',srcType:' + requestSource + ',version:' + currentRequest.componentVersion)
|
||||
|
||||
let memoryKey: string = this.engineKey.generateMemoryKey(imageSrc, requestSource, currentRequest.imageKnifeOption,isAnimator, currentRequest.componentWidth, currentRequest.componentHeight)
|
||||
let requestList: List<ImageKnifeRequestWithSource> | undefined = this.executingJobMap.get(memoryKey)
|
||||
if (requestList == undefined) {
|
||||
requestList = new List()
|
||||
|
@ -144,23 +202,25 @@ export class ImageKnifeDispatcher {
|
|||
requestList.add({ request: currentRequest, source: requestSource })
|
||||
return
|
||||
}
|
||||
|
||||
LogUtil.info('image load getAndShowImage start:' + currentRequest.componentId + ',srcType:' + requestSource + ',version:' + currentRequest.componentVersion)
|
||||
let isWatchProgress : boolean = false
|
||||
|
||||
// 回调请求开始
|
||||
requestList.forEach((requestWithSource: ImageKnifeRequestWithSource) => {
|
||||
if (requestWithSource.source === ImageKnifeRequestSource.SRC && requestWithSource.request.imageKnifeOption.onLoadListener?.onLoadStart !== undefined) {
|
||||
requestWithSource.request.imageKnifeOption.onLoadListener?.onLoadStart()
|
||||
LogUtil.log("ImageKnife_DataTime_getAndShowImage_onLoadStart:" + currentRequest.imageKnifeOption.loadSrc)
|
||||
}
|
||||
if (requestWithSource.request.imageKnifeOption.progressListener !== undefined && requestWithSource.source === ImageKnifeRequestSource.SRC) {
|
||||
if (currentRequest.imageKnifeOption.progressListener !== undefined && requestSource === ImageKnifeRequestSource.SRC) {
|
||||
isWatchProgress = true
|
||||
}
|
||||
});
|
||||
|
||||
let src: string | number = ''
|
||||
let moduleName: string = ''
|
||||
let resName: string = ''
|
||||
if((imageSrc as Resource).id != undefined) {
|
||||
moduleName = (imageSrc as Resource).moduleName
|
||||
src = (imageSrc as Resource).id
|
||||
resName = (imageSrc as Resource).params![0]
|
||||
} else if(typeof imageSrc == 'string') {
|
||||
src = imageSrc
|
||||
}
|
||||
let request: RequestJobRequest = {
|
||||
context: currentRequest.context,
|
||||
src: imageSrc,
|
||||
src: src,
|
||||
headers: currentRequest.imageKnifeOption.headerOption,
|
||||
allHeaders: currentRequest.headers,
|
||||
componentWidth:currentRequest.componentWidth,
|
||||
|
@ -176,48 +236,92 @@ export class ImageKnifeDispatcher {
|
|||
isWatchProgress: isWatchProgress,
|
||||
memoryKey: memoryKey,
|
||||
fileCacheFolder: ImageKnife.getInstance().getFileCache()?.getCacheFolder(),
|
||||
isAnimator:isAnimator
|
||||
isAnimator:isAnimator,
|
||||
moduleName: moduleName == '' ? undefined : moduleName,
|
||||
resName: resName == '' ? undefined : resName,
|
||||
caPath: currentRequest.imageKnifeOption.httpOption?.caPath,
|
||||
targetWidth: currentRequest.componentWidth,
|
||||
targetHeight: currentRequest.componentHeight,
|
||||
downsampType: currentRequest.imageKnifeOption.downsampleOf == undefined ? DownsampleStrategy.DEFAULT : currentRequest.imageKnifeOption.downsampleOf,
|
||||
isAutoImageFit: currentRequest.imageKnifeOption.objectFit == ImageFit.Auto,
|
||||
componentId: currentRequest.componentId,
|
||||
componentVersion: currentRequest.componentVersion,
|
||||
connectTimeout: currentRequest.imageKnifeOption.httpOption?.connectTimeout,
|
||||
readTimeout: currentRequest.imageKnifeOption.httpOption?.readTimeout
|
||||
}
|
||||
|
||||
if(request.customGetImage == undefined) {
|
||||
request.customGetImage = ImageKnife.getInstance().getCustomGetImage()
|
||||
}
|
||||
emitter.on(Constants.CALLBACK_EMITTER + memoryKey,(data)=>{
|
||||
emitter.off(Constants.CALLBACK_EMITTER + memoryKey)
|
||||
let res = data?.data?.value as RequestJobResult | undefined
|
||||
this.doTaskCallback(res, requestList!, currentRequest, memoryKey, imageSrc, requestSource,isAnimator);
|
||||
if (isWatchProgress){
|
||||
emitter.off(Constants.PROGRESS_EMITTER + memoryKey)
|
||||
}
|
||||
LogUtil.log('getAndShowImage.end:'+ currentRequest.componentId + ',srcType:' + requestSource + ',version:' + currentRequest.componentVersion)
|
||||
})
|
||||
if (ImageKnife.getInstance().isRequestInSubThread){
|
||||
// 启动线程下载和解码主图
|
||||
LogUtil.log("ImageKnife_DataTime_getAndShowImage_Task.start:" + currentRequest.imageKnifeOption.loadSrc)
|
||||
LogUtil.log('etAndShowImage_Task.start:' + currentRequest.componentId + ',srcType:' + requestSource + ',version:' + currentRequest.componentVersion)
|
||||
let task = new taskpool.Task(requestJob, request)
|
||||
LogUtil.log("ImageKnife_DataTime_getAndShowImage_Task.end:" + currentRequest.imageKnifeOption.loadSrc)
|
||||
LogUtil.log('getAndShowImage_Task.end:' + currentRequest.componentId + ',srcType:' + requestSource + ',version:' + currentRequest.componentVersion)
|
||||
if (isWatchProgress){
|
||||
emitter.on(Constants.PROGRESS_EMITTER + memoryKey, (data) => {
|
||||
this.progressCallBack(requestList! , data?.data?.value as number)
|
||||
});
|
||||
}
|
||||
|
||||
LogUtil.log("ImageKnife_DataTime_getAndShowImage_execute.start:" + currentRequest.imageKnifeOption.loadSrc)
|
||||
LogUtil.log('getAndShowImage_execute.start(subthread):' + currentRequest.componentId + ',srcType:' + requestSource + ',version:' + currentRequest.componentVersion)
|
||||
taskpool.execute(task).then((res: Object) => {
|
||||
this.doTaskCallback(res as RequestJobResult | undefined, requestList!, currentRequest, memoryKey, imageSrc, requestSource,isAnimator);
|
||||
}).catch((err: BusinessError) => {
|
||||
emitter.off(Constants.CALLBACK_EMITTER + memoryKey)
|
||||
LogUtil.error('Fail to requestJob in sub thread src=' + imageSrc + ' err=' + err)
|
||||
if (isWatchProgress){
|
||||
emitter.off(Constants.PROGRESS_EMITTER + memoryKey)
|
||||
}
|
||||
LogUtil.log("ImageKnife_DataTime_getAndShowImage_execute.end:"+currentRequest.imageKnifeOption.loadSrc)
|
||||
LogUtil.log("ImageKnife_DataTime_getAndShowImage.end:"+currentRequest.imageKnifeOption.loadSrc)
|
||||
}).catch((err:BusinessError)=>{
|
||||
LogUtil.error("Fail to execute in sub thread src=" + imageSrc + " err=" + err)
|
||||
if (isWatchProgress){
|
||||
emitter.off(Constants.PROGRESS_EMITTER + memoryKey)
|
||||
|
||||
this.doTaskCallback({
|
||||
pixelMap: undefined,
|
||||
bufferSize: 0,
|
||||
fileKey: '',
|
||||
loadFail: 'Fail to requestJob in sub thread src=' + imageSrc + ' err=' + err,
|
||||
imageKnifeData: {
|
||||
source: '',
|
||||
imageWidth: 0,
|
||||
imageHeight: 0,
|
||||
timeInfo: { requestEndTime: Date.now() },
|
||||
errorInfo: {
|
||||
phase: LoadPhase.PHASE_LOAD,
|
||||
code: LoadPixelMapCode.IMAGE_CUSTOM_LOAD_FAILED_CODE,
|
||||
}
|
||||
this.executingJobMap.remove(memoryKey);
|
||||
this.dispatchNextJob();
|
||||
}
|
||||
}, requestList!, currentRequest, memoryKey, imageSrc, requestSource, isAnimator)
|
||||
})
|
||||
} else { //主线程请求
|
||||
requestJob(request, requestList).then((res: RequestJobResult | undefined) => {
|
||||
this.doTaskCallback(res, requestList!, currentRequest, memoryKey, imageSrc, requestSource,isAnimator);
|
||||
LogUtil.log("ImageKnife_DataTime_getAndShowImage_execute.end:"+currentRequest.imageKnifeOption.loadSrc)
|
||||
LogUtil.log("ImageKnife_DataTime_getAndShowImage.end:"+currentRequest.imageKnifeOption.loadSrc)
|
||||
}).catch((err:BusinessError)=>{
|
||||
LogUtil.error("Fail to execute in main thread src=" + imageSrc + " err=" + err)
|
||||
this.executingJobMap.remove(memoryKey);
|
||||
this.dispatchNextJob();
|
||||
LogUtil.log('getAndShowImage_execute.start(mainthread):' + currentRequest.componentId + ',srcType:' + requestSource + ',version:' + currentRequest.componentVersion)
|
||||
requestJob(request, requestList).then(() => {
|
||||
}).catch((err: BusinessError) => {
|
||||
emitter.off(Constants.CALLBACK_EMITTER + memoryKey)
|
||||
LogUtil.error('Fail to requestJob in main thread src=' + imageSrc + ' err=' + err)
|
||||
|
||||
this.doTaskCallback({
|
||||
pixelMap: undefined,
|
||||
bufferSize: 0,
|
||||
fileKey: '',
|
||||
loadFail: 'Fail to requestJob in main thread src=' + imageSrc + ' err=' + err,
|
||||
imageKnifeData: {
|
||||
source: '',
|
||||
imageWidth: 0,
|
||||
imageHeight: 0,
|
||||
timeInfo: { requestEndTime: Date.now() },
|
||||
errorInfo: {
|
||||
phase: LoadPhase.PHASE_LOAD,
|
||||
code: LoadPixelMapCode.IMAGE_CUSTOM_LOAD_FAILED_CODE,
|
||||
}
|
||||
}
|
||||
}, requestList!, currentRequest, memoryKey, imageSrc, requestSource, isAnimator)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -238,23 +342,79 @@ export class ImageKnifeDispatcher {
|
|||
|
||||
private doTaskCallback(requestJobResult: RequestJobResult | undefined, requestList: List<ImageKnifeRequestWithSource> ,
|
||||
currentRequest: ImageKnifeRequest, memoryKey: string, imageSrc: string | PixelMap | Resource, requestSource: ImageKnifeRequestSource,isAnimator?: boolean):void {
|
||||
LogUtil.log("ImageKnife_DataTime_getAndShowImage_CallBack.start:"+currentRequest.imageKnifeOption.loadSrc)
|
||||
LogUtil.log('getAndShowImage_CallBack.start:' + currentRequest.componentId + ',srcType:' + requestSource + ',version:' + currentRequest.componentVersion)
|
||||
if (requestJobResult === undefined){
|
||||
return
|
||||
}
|
||||
|
||||
//设置请求结束的时间
|
||||
if (requestJobResult.imageKnifeData && requestJobResult.imageKnifeData.timeInfo) {
|
||||
requestJobResult.imageKnifeData.timeInfo.requestEndTime = Date.now();
|
||||
}
|
||||
|
||||
let pixelmap = requestJobResult.pixelMap;
|
||||
if (pixelmap === undefined) {
|
||||
// 请求取消
|
||||
if (currentRequest.requestState === ImageKnifeRequestState.DESTROY) {
|
||||
this.executingJobMap.remove(memoryKey);
|
||||
requestList.forEach((requestWithSource: ImageKnifeRequestWithSource) => {
|
||||
if (currentRequest.componentId !== requestWithSource.request.componentId && requestWithSource.request.requestState !== ImageKnifeRequestState.DESTROY) {
|
||||
// 加载占位符
|
||||
if (requestWithSource.source === ImageKnifeRequestSource.PLACE_HOLDER &&
|
||||
requestWithSource.request.imageKnifeOption.placeholderSrc !== undefined &&
|
||||
requestWithSource.request.drawPlayHolderSuccess == false) {
|
||||
this.getAndShowImage(requestWithSource.request, requestWithSource.request.imageKnifeOption.placeholderSrc, ImageKnifeRequestSource.PLACE_HOLDER)
|
||||
} else if (requestWithSource.source === ImageKnifeRequestSource.ERROR_HOLDER &&
|
||||
requestWithSource.request.imageKnifeOption.errorholderSrc !== undefined) {
|
||||
this.getAndShowImage(requestWithSource.request, requestWithSource.request.imageKnifeOption.errorholderSrc, ImageKnifeRequestSource.ERROR_HOLDER)
|
||||
} else if (requestWithSource.source === ImageKnifeRequestSource.SRC) {
|
||||
// 加载主图
|
||||
this.getAndShowImage(requestWithSource.request, requestWithSource.request.imageKnifeOption.loadSrc, ImageKnifeRequestSource.SRC,requestWithSource.request.animator)
|
||||
}
|
||||
} else {
|
||||
if (pixelmap !== undefined && typeof pixelmap !== 'string') {
|
||||
(pixelmap as PixelMap).release()
|
||||
}
|
||||
if (requestWithSource.source == ImageKnifeRequestSource.SRC && requestWithSource.request.imageKnifeOption.onLoadListener?.onLoadCancel) {
|
||||
// 回调请求成功
|
||||
// 回调请求成功
|
||||
//设置失败回调的时间点
|
||||
let callBackData = requestWithSource.request.imageKnifeData;
|
||||
|
||||
if (requestJobResult.imageKnifeData && requestJobResult.imageKnifeData.timeInfo) {
|
||||
requestJobResult.imageKnifeData.timeInfo.requestCancelTime = Date.now();
|
||||
if (requestJobResult.imageKnifeData.errorInfo) {
|
||||
requestJobResult.imageKnifeData.errorInfo.phase = LoadPhase.PHASE_WILL_SHOW;
|
||||
requestJobResult.imageKnifeData.errorInfo.code = LoadPixelMapCode.IMAGE_LOAD_CANCEL_FAILED_CODE;
|
||||
}
|
||||
}
|
||||
this.assembleImageKnifeData(callBackData,requestJobResult.imageKnifeData,requestWithSource.request)
|
||||
LogUtil.log('getAndShowImage cancel:' + requestWithSource.request.componentId + ',srcType:' + requestSource + ',version:' + requestWithSource.request.componentVersion)
|
||||
requestWithSource.request.imageKnifeOption.onLoadListener.onLoadCancel(requestJobResult.loadFail ?? 'component has destroyed from load', requestWithSource.request)
|
||||
}
|
||||
}
|
||||
})
|
||||
this.dispatchNextJob()
|
||||
return
|
||||
}
|
||||
// 请求失败
|
||||
if (pixelmap === undefined) {
|
||||
this.executingJobMap.remove(memoryKey);
|
||||
requestList.forEach((requestWithSource: ImageKnifeRequestWithSource) => {
|
||||
requestWithSource.request.requestState = ImageKnifeRequestState.ERROR
|
||||
LogUtil.error('getAndShowImage_CallBack.pixelmap failed:' + currentRequest.componentId + ',srcType:' +
|
||||
requestSource + ',version:' + currentRequest.componentVersion + " error: " + requestJobResult.loadFail)
|
||||
// 回调请求失败
|
||||
if (requestWithSource.source === ImageKnifeRequestSource.SRC &&
|
||||
requestWithSource.request.imageKnifeOption.onLoadListener?.onLoadFailed !== undefined &&
|
||||
requestJobResult.loadFail) {
|
||||
requestWithSource.request.imageKnifeOption.onLoadListener.onLoadFailed(requestJobResult.loadFail);
|
||||
LogUtil.log("ImageKnife_DataTime_getAndShowImage_onLoadFailed:"+currentRequest.imageKnifeOption.loadSrc)
|
||||
this.assembleImageKnifeData(requestWithSource.request.imageKnifeData, requestJobResult.imageKnifeData,
|
||||
requestWithSource.request)
|
||||
requestWithSource.request.imageKnifeOption.onLoadListener.onLoadFailed(requestJobResult.loadFail,
|
||||
requestWithSource.request);
|
||||
}
|
||||
if (requestWithSource.source === ImageKnifeRequestSource.SRC &&
|
||||
requestWithSource.request.imageKnifeOption.errorholderSrc !== undefined) {
|
||||
|
||||
requestWithSource.request.requestState = ImageKnifeRequestState.PROGRESS
|
||||
if (this.showFromMemomry(requestWithSource.request, requestWithSource.request.imageKnifeOption.errorholderSrc,
|
||||
ImageKnifeRequestSource.ERROR_HOLDER) === false) {
|
||||
this.getAndShowImage(requestWithSource.request, requestWithSource.request.imageKnifeOption.errorholderSrc,
|
||||
|
@ -262,22 +422,29 @@ export class ImageKnifeDispatcher {
|
|||
}
|
||||
}
|
||||
});
|
||||
this.executingJobMap.remove(memoryKey);
|
||||
this.dispatchNextJob();
|
||||
return;
|
||||
}
|
||||
// 保存文件缓存
|
||||
if (requestJobResult.bufferSize > 0 && currentRequest.imageKnifeOption.writeCacheStrategy !== CacheStrategy.Memory) {
|
||||
LogUtil.log("ImageKnife_DataTime_getAndShowImage_saveWithoutWriteFile.start:"+currentRequest.imageKnifeOption.loadSrc)
|
||||
LogUtil.log('getAndShowImage_saveWithoutWriteFile.start:' + currentRequest.componentId + ',srcType:' + requestSource + ',version:' + currentRequest.componentVersion)
|
||||
ImageKnife.getInstance().saveWithoutWriteFile(requestJobResult.fileKey, requestJobResult.bufferSize);
|
||||
LogUtil.log("ImageKnife_DataTime_getAndShowImage_saveWithoutWriteFile.end:"+currentRequest.imageKnifeOption.loadSrc)
|
||||
LogUtil.log('getAndShowImage_saveWithoutWriteFile.end:' + currentRequest.componentId + ',srcType:' + requestSource + ',version:' + currentRequest.componentVersion)
|
||||
}
|
||||
|
||||
let ImageKnifeData: ImageKnifeData = {
|
||||
let imageKnifeData: ImageKnifeData;
|
||||
if (!requestJobResult.imageKnifeData) {
|
||||
imageKnifeData = {
|
||||
source: pixelmap!,
|
||||
imageWidth: requestJobResult.size == undefined ? 0 : requestJobResult.size.width,
|
||||
imageHeight: requestJobResult.size == undefined ? 0 : requestJobResult.size.height,
|
||||
type:requestJobResult.type
|
||||
type: requestJobResult.type,
|
||||
};
|
||||
} else {
|
||||
imageKnifeData = requestJobResult.imageKnifeData;
|
||||
imageKnifeData.source = pixelmap!;
|
||||
}
|
||||
|
||||
if(requestJobResult.pixelMapList != undefined) {
|
||||
let imageAnimator: Array<ImageFrameInfo> = []
|
||||
requestJobResult.pixelMapList.forEach((item,index)=>{
|
||||
|
@ -286,74 +453,98 @@ export class ImageKnifeDispatcher {
|
|||
duration:requestJobResult.delayList![index]
|
||||
})
|
||||
})
|
||||
ImageKnifeData.imageAnimator = imageAnimator
|
||||
imageKnifeData.imageAnimator = imageAnimator
|
||||
}
|
||||
|
||||
//构建缓存保存的ImageKnifeData
|
||||
let saveCacheImageData: ImageKnifeData = {
|
||||
source: pixelmap!,
|
||||
imageWidth: requestJobResult.size?.width ?? 0,
|
||||
imageHeight: requestJobResult.size?.height ?? 0,
|
||||
type: requestJobResult.type,
|
||||
bufSize: requestJobResult.bufferSize,
|
||||
imageAnimator: imageKnifeData.imageAnimator
|
||||
}
|
||||
|
||||
// 保存内存缓存
|
||||
if (currentRequest.imageKnifeOption.writeCacheStrategy !== CacheStrategy.File) {
|
||||
LogUtil.log("ImageKnife_DataTime_getAndShowImage_saveMemoryCache.start:"+currentRequest.imageKnifeOption.loadSrc)
|
||||
LogUtil.log('getAndShowImage_saveMemoryCache.start:' + currentRequest.componentId + ',srcType:' + requestSource + ',version:' + currentRequest.componentVersion)
|
||||
ImageKnife.getInstance()
|
||||
.saveMemoryCache(this.engineKey.generateMemoryKey(imageSrc, requestSource, currentRequest.imageKnifeOption,isAnimator),
|
||||
ImageKnifeData);
|
||||
LogUtil.log("ImageKnife_DataTime_getAndShowImage_saveMemoryCache.end:"+currentRequest.imageKnifeOption.loadSrc)
|
||||
.saveMemoryCache(this.engineKey.generateMemoryKey(imageSrc, requestSource, currentRequest.imageKnifeOption,isAnimator, currentRequest.componentWidth, currentRequest.componentHeight),
|
||||
saveCacheImageData);
|
||||
LogUtil.log('getAndShowImage_saveMemoryCache.end:' + currentRequest.componentId + ',srcType:' + requestSource + ',version:' + currentRequest.componentVersion)
|
||||
}
|
||||
if (requestList !== undefined) {
|
||||
|
||||
// todo 判断request生命周期,已销毁的不需要再绘制
|
||||
// key相同的request,一起绘制
|
||||
requestList.forEach((requestWithSource: ImageKnifeRequestWithSource) => {
|
||||
if (requestWithSource.request.requestState !== ImageKnifeRequestState.DESTROY) {
|
||||
// 画主图
|
||||
if (requestWithSource.source === ImageKnifeRequestSource.SRC ||
|
||||
requestWithSource.source === ImageKnifeRequestSource.ERROR_HOLDER
|
||||
|| (requestWithSource.source === ImageKnifeRequestSource.PLACE_HOLDER &&
|
||||
requestWithSource.request.requestState === ImageKnifeRequestState.PROGRESS)) {
|
||||
LogUtil.log("ImageKnife_DataTime_getAndShowImage_showPixelMap.start:"+currentRequest.imageKnifeOption.loadSrc)
|
||||
requestWithSource.request.ImageKnifeRequestCallback.showPixelMap(requestWithSource.request.componentVersion,
|
||||
ImageKnifeData.source, requestWithSource.source,ImageKnifeData.imageAnimator);
|
||||
LogUtil.log("ImageKnife_DataTime_getAndShowImage_showPixelMap.end:"+currentRequest.imageKnifeOption.loadSrc)
|
||||
imageKnifeData.source, { width: imageKnifeData.imageWidth, height: imageKnifeData.imageHeight },
|
||||
requestWithSource.source, imageKnifeData.imageAnimator);
|
||||
}
|
||||
|
||||
if (requestWithSource.source == ImageKnifeRequestSource.SRC) {
|
||||
requestWithSource.request.requestState = ImageKnifeRequestState.COMPLETE;
|
||||
requestWithSource.request.drawMainSuccess = true
|
||||
if (requestWithSource.request.imageKnifeOption.onLoadListener &&
|
||||
requestWithSource.request.imageKnifeOption.onLoadListener.onLoadSuccess) {
|
||||
// 回调请求成功
|
||||
requestWithSource.request.imageKnifeOption.onLoadListener.onLoadSuccess(ImageKnifeData.source,ImageKnifeData);
|
||||
LogUtil.log("ImageKnife_DataTime_getAndShowImage_onLoadSuccess:"+currentRequest.imageKnifeOption.loadSrc)
|
||||
this.assembleImageKnifeData(requestWithSource.request.imageKnifeData, imageKnifeData,
|
||||
requestWithSource.request);
|
||||
requestWithSource.request.imageKnifeOption.onLoadListener.onLoadSuccess(imageKnifeData.source,
|
||||
saveCacheImageData, requestWithSource.request);
|
||||
}
|
||||
} else if (requestWithSource.source == ImageKnifeRequestSource.ERROR_HOLDER) {
|
||||
requestWithSource.request.requestState = ImageKnifeRequestState.ERROR;
|
||||
}
|
||||
} else {
|
||||
if (requestWithSource.source == ImageKnifeRequestSource.SRC && requestWithSource.request.imageKnifeOption.onLoadListener?.onLoadCancel) {
|
||||
// 回调请求成功
|
||||
requestWithSource.request.imageKnifeOption.onLoadListener.onLoadCancel("component has destroyed")
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
this.executingJobMap.remove(memoryKey);
|
||||
this.dispatchNextJob();
|
||||
} else {
|
||||
LogUtil.log("error: no requestlist need to draw for key = " + memoryKey);
|
||||
LogUtil.log('error: no requestlist need to draw for key = ' + memoryKey);
|
||||
}
|
||||
LogUtil.log("ImageKnife_DataTime_getAndShowImage_CallBack.end:"+currentRequest.imageKnifeOption.loadSrc)
|
||||
LogUtil.log('getAndShowImage_CallBack.end:' + currentRequest.componentId + ',srcType:' + requestSource + ',version:' + currentRequest.componentVersion)
|
||||
}
|
||||
|
||||
|
||||
dispatchNextJob() {
|
||||
LogUtil.log("ImageKnife_DataTime_dispatchNextJob.start")
|
||||
LogUtil.log('dispatchNextJob.start')
|
||||
|
||||
// 主图和错误图并发加载时,以及主图加载失败后立即加载错误图,可能会导致短时间内并发数超过maxRequests,故此处减少响应的并发
|
||||
if (this.executingJobMap.length >= this.maxRequests) {
|
||||
return
|
||||
}
|
||||
|
||||
while (true) {
|
||||
let request = this.jobQueue.pop()
|
||||
if (request === undefined) {
|
||||
LogUtil.log('dispatchNextJob.end:no any job')
|
||||
break // 队列已无任务
|
||||
}
|
||||
else if (request.requestState === ImageKnifeRequestState.PROGRESS) {
|
||||
LogUtil.log('dispatchNextJob.start executeJob:' + request.componentId + ',version:' + request.componentVersion)
|
||||
this.executeJob(request)
|
||||
LogUtil.log("ImageKnife_DataTime_dispatchNextJob.end:" + request.imageKnifeOption.loadSrc)
|
||||
LogUtil.log('dispatchNextJob.end executeJob:' + request.componentId + ',version:' + request.componentVersion)
|
||||
break
|
||||
}else if (request.requestState == ImageKnifeRequestState.DESTROY && request.imageKnifeOption.onLoadListener?.onLoadCancel) {
|
||||
request.imageKnifeOption.onLoadListener.onLoadCancel("component has destroyed")
|
||||
//构建回调错误信息
|
||||
let callBackData = request.imageKnifeData;
|
||||
if (callBackData) {
|
||||
let timeInfo: TimeInfo = ImageKnifeLoader.getTimeInfo(callBackData)
|
||||
timeInfo.requestCancelTime = Date.now();
|
||||
timeInfo.requestEndTime = Date.now()
|
||||
let errorInfo: ErrorInfo = {
|
||||
phase: LoadPhase.PHASE_THREAD_QUEUE,
|
||||
code: LoadPixelMapCode.IMAGE_LOAD_CANCEL_FAILED_CODE,
|
||||
};
|
||||
callBackData.errorInfo = errorInfo;
|
||||
}
|
||||
LogUtil.log('dispatchNextJob cancel:' + request.componentId + ',version:' + request.componentVersion)
|
||||
request.imageKnifeOption.onLoadListener.onLoadCancel('component has destroyed from queue', request)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -380,295 +571,16 @@ export class ImageKnifeDispatcher {
|
|||
* @returns
|
||||
*/
|
||||
@Concurrent
|
||||
async function requestJob(request: RequestJobRequest, requestList?: List<ImageKnifeRequestWithSource>): Promise<RequestJobResult | undefined> {
|
||||
LogUtil.log("ImageKnife_DataTime_requestJob.start:" + request.src)
|
||||
let resBuf: ArrayBuffer | undefined
|
||||
let bufferSize: number = 0
|
||||
let loadError: string = '';
|
||||
async function requestJob(request: RequestJobRequest, requestList?: List<ImageKnifeRequestWithSource>) {
|
||||
LogUtil.log('requestJob.start:' + request.componentId + ',srcType:' + request.requestSource + ',' + request.componentVersion)
|
||||
let src = typeof request.src == 'number' ? request.resName != undefined ? request.resName : request.src + '' : request.src
|
||||
// 生成文件缓存key
|
||||
let fileKey = request.engineKey.generateFileKey(src, request.signature, request.isAnimator)
|
||||
|
||||
class RequestData {
|
||||
receiveSize: number = 2000
|
||||
totalSize: number = 2000
|
||||
}
|
||||
//获取图片资源
|
||||
ImageKnifeLoader.execute(request,requestList,fileKey)
|
||||
|
||||
// 生成文件key
|
||||
let fileKey = request.engineKey.generateFileKey(request.src, request.signature,request.isAnimator)
|
||||
|
||||
// 判断自定义下载
|
||||
if (request.customGetImage !== undefined && request.requestSource == ImageKnifeRequestSource.SRC) {
|
||||
// 先从文件缓存获取
|
||||
resBuf = FileCache.getFileCacheByFile(request.context, fileKey , request.fileCacheFolder)
|
||||
if (resBuf === undefined) {
|
||||
LogUtil.log("customGetImage customGetImage");
|
||||
resBuf = await request.customGetImage(request.context, request.src)
|
||||
loadError = resBuf == undefined ? "customGetImage loadFile" : loadError
|
||||
// 保存文件缓存
|
||||
if (resBuf !== undefined && request.writeCacheStrategy !== CacheStrategy.Memory) {
|
||||
let copyBuf = buffer.concat([buffer.from(resBuf)]).buffer; // IDE有bug,不能直接获取resBuf.byteLength
|
||||
bufferSize = copyBuf.byteLength
|
||||
FileCache.saveFileCacheOnlyFile(request.context, fileKey, resBuf , request.fileCacheFolder)
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (typeof request.src === 'string') {
|
||||
if (request.src.indexOf("http://") == 0 || request.src.indexOf("https://") == 0) { //从网络下载
|
||||
// 先从文件缓存获取
|
||||
resBuf = FileCache.getFileCacheByFile(request.context, fileKey , request.fileCacheFolder)
|
||||
if (resBuf === undefined && request.onlyRetrieveFromCache != true) {
|
||||
LogUtil.log("ImageKnife_DataTime_requestJob_httpRequest.start:"+request.src)
|
||||
let httpRequest = http.createHttp();
|
||||
let progress: number = 0
|
||||
let arrayBuffers = new Array<ArrayBuffer>()
|
||||
const headerObj: Record<string, object> = {}
|
||||
if (request.headers != undefined) {
|
||||
request.headers.forEach((value) => {
|
||||
headerObj[value.key] = value.value
|
||||
})
|
||||
} else if (request.allHeaders.size > 0) {
|
||||
request.allHeaders.forEach((value, key) => {
|
||||
headerObj[key] = value
|
||||
})
|
||||
}
|
||||
httpRequest.on("dataReceive", (data: ArrayBuffer) => {
|
||||
arrayBuffers.push(data)
|
||||
});
|
||||
|
||||
if (request.isWatchProgress) {
|
||||
httpRequest.on('dataReceiveProgress', (data: RequestData) => {
|
||||
// 下载进度
|
||||
if (data != undefined && (typeof data.receiveSize == 'number') && (typeof data.totalSize == 'number')) {
|
||||
let percent = Math.round(((data.receiveSize * 1.0) / (data.totalSize * 1.0)) * 100)
|
||||
if (progress !== percent) {
|
||||
progress = percent
|
||||
if (requestList === undefined) {
|
||||
// 子线程
|
||||
emitter.emit(Constants.PROGRESS_EMITTER + request.memoryKey, { data: { "value": progress } })
|
||||
}else {
|
||||
// 主线程请求
|
||||
requestList!.forEach((requestWithSource: ImageKnifeRequestWithSource) => {
|
||||
if (requestWithSource.request.imageKnifeOption.progressListener !== undefined && requestWithSource.source === ImageKnifeRequestSource.SRC) {
|
||||
requestWithSource.request.imageKnifeOption.progressListener(progress)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
let promise = httpRequest.requestInStream(request.src, {
|
||||
header: headerObj,
|
||||
method: http.RequestMethod.GET,
|
||||
expectDataType: http.HttpDataType.ARRAY_BUFFER,
|
||||
connectTimeout: 6000,
|
||||
readTimeout: 6000,
|
||||
// usingProtocol:http.HttpProtocol.HTTP1_1
|
||||
// header: new Header('application/json')
|
||||
});
|
||||
|
||||
await promise.then((data: number) => {
|
||||
if (data == 200 || data == 206 || data == 204) {
|
||||
resBuf = combineArrayBuffers(arrayBuffers)
|
||||
} else {
|
||||
loadError = "HttpDownloadClient has error, http code =" + JSON.stringify(data)
|
||||
}
|
||||
}).catch((err: Error) => {
|
||||
loadError = err.message;
|
||||
LogUtil.error("requestInStream ERROR : err = " + JSON.stringify(err));
|
||||
});
|
||||
LogUtil.log("ImageKnife_DataTime_requestJob_httpRequest.end:"+request.src)
|
||||
// 保存文件缓存
|
||||
if (resBuf !== undefined && request.writeCacheStrategy !== CacheStrategy.Memory) {
|
||||
LogUtil.log("ImageKnife_DataTime_requestJob_saveFileCacheOnlyFile.start:"+request.src)
|
||||
let copyBuf = combineArrayBuffers(arrayBuffers); // IDE有bug,不能直接获取resBuf.byteLength
|
||||
bufferSize = copyBuf.byteLength
|
||||
FileCache.saveFileCacheOnlyFile(request.context, fileKey, resBuf , request.fileCacheFolder)
|
||||
LogUtil.log("ImageKnife_DataTime_requestJob_saveFileCacheOnlyFile.end:"+request.src)
|
||||
}
|
||||
}
|
||||
else {
|
||||
LogUtil.log("success get image from filecache for key = " + fileKey);
|
||||
loadError = "success get image from filecache for key = " + fileKey;
|
||||
}
|
||||
} else if (request.src.startsWith('datashare://') || request.src.startsWith('file://')) {
|
||||
await fs.open(request.src, fs.OpenMode.READ_ONLY).then(async (file) => {
|
||||
await fs.stat(file.fd).then(async (stat) =>{
|
||||
let buf = new ArrayBuffer(stat.size);
|
||||
await fs.read(file.fd, buf).then((readLen) => {
|
||||
resBuf = buf;
|
||||
fs.close(file.fd);
|
||||
}).catch((err:BusinessError) => {
|
||||
loadError = 'LoadDataShareFileClient fs.read err happened uri=' + request.src + " err.msg=" + err?.message + " err.code=" + err?.code;
|
||||
})
|
||||
}).catch((err:BusinessError) => {
|
||||
loadError = 'LoadDataShareFileClient fs.stat err happened uri=' + request.src + " err.msg=" + err?.message + " err.code=" + err?.code;
|
||||
})
|
||||
}).catch((err:BusinessError) => {
|
||||
loadError ='LoadDataShareFileClient fs.open err happened uri=' + request.src + " err.msg=" + err?.message + " err.code=" + err?.code;
|
||||
})
|
||||
} else { //从本地文件获取
|
||||
try {
|
||||
let stat = fs.statSync(request.src);
|
||||
if (stat.size > 0) {
|
||||
let file = fs.openSync(request.src, fs.OpenMode.READ_ONLY);
|
||||
resBuf = new ArrayBuffer(stat.size);
|
||||
fs.readSync(file.fd, resBuf);
|
||||
fs.closeSync(file);
|
||||
}
|
||||
} catch (err) {
|
||||
if (typeof err == 'string') {
|
||||
loadError = err;
|
||||
} else {
|
||||
loadError = err.message;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if ((request.src as Resource).id !== undefined) { //从资源文件获取
|
||||
let res = request.src as Resource;
|
||||
let manager = request.context.createModuleContext(res.moduleName).resourceManager
|
||||
if (resBuf == undefined && request.onlyRetrieveFromCache != true && request.requestSource == ImageKnifeRequestSource.SRC) {
|
||||
if(res.id == -1) {
|
||||
let resName = (res.params![0] as string)
|
||||
resBuf = (await manager.getMediaByName(resName.substring(10))).buffer as ArrayBuffer
|
||||
} else {
|
||||
resBuf = manager.getMediaContentSync(res.id).buffer as ArrayBuffer
|
||||
}
|
||||
} else if (resBuf == undefined && request.requestSource != ImageKnifeRequestSource.SRC) {
|
||||
if(res.id == -1) {
|
||||
let resName = (res.params![0] as string)
|
||||
resBuf = (await manager.getMediaByName(resName.substring(10))).buffer as ArrayBuffer
|
||||
} else {
|
||||
resBuf = manager.getMediaContentSync(res.id).buffer as ArrayBuffer
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (resBuf == undefined) {
|
||||
LogUtil.log("ImageKnife_DataTime_requestJob.end_undefined:"+request.src)
|
||||
return {
|
||||
pixelMap: undefined,
|
||||
bufferSize: 0,
|
||||
fileKey: '',
|
||||
loadFail: loadError,
|
||||
}
|
||||
}
|
||||
LogUtil.log("ImageKnife_DataTime_requestJob_createPixelMap.start:"+request.src)
|
||||
let fileTypeUtil = new FileTypeUtil();
|
||||
let typeValue = fileTypeUtil.getFileType(resBuf);
|
||||
if(typeValue == null) {
|
||||
return {
|
||||
pixelMap: undefined,
|
||||
bufferSize: 0,
|
||||
fileKey: '',
|
||||
loadFail: "request is not a valid image source",
|
||||
}
|
||||
}
|
||||
let imageSource: image.ImageSource = image.createImageSource(resBuf);
|
||||
let decodingOptions: image.DecodingOptions = {
|
||||
editable: true,
|
||||
}
|
||||
if(request.isAnimator) {
|
||||
if (typeValue === 'gif' || typeValue === 'webp') {
|
||||
let pixelMapList: Array<PixelMap> = []
|
||||
let delayList: Array<number> = []
|
||||
await imageSource.createPixelMapList(decodingOptions).then(async (pixelList: Array<PixelMap>) => {
|
||||
//sdk的api接口发生变更:从.getDelayTime() 变为.getDelayTimeList()
|
||||
await imageSource.getDelayTimeList().then(delayTimes => {
|
||||
if (pixelList.length > 0) {
|
||||
for (let i = 0; i < pixelList.length; i++) {
|
||||
pixelMapList.push(pixelList[i]);
|
||||
if (i < delayTimes.length) {
|
||||
delayList.push(delayTimes[i]);
|
||||
} else {
|
||||
delayList.push(delayTimes[delayTimes.length - 1])
|
||||
}
|
||||
}
|
||||
imageSource.release();
|
||||
}
|
||||
})
|
||||
})
|
||||
return {
|
||||
pixelMap: "",
|
||||
bufferSize: bufferSize,
|
||||
fileKey: fileKey,
|
||||
type: typeValue,
|
||||
pixelMapList,
|
||||
delayList
|
||||
}
|
||||
} else {
|
||||
return {
|
||||
pixelMap: undefined,
|
||||
bufferSize: 0,
|
||||
fileKey: '',
|
||||
loadFail: "ImageKnifeAnimatorComponent组件仅支持动态图",
|
||||
}
|
||||
}
|
||||
}
|
||||
let resPixelmap: PixelMap | undefined = undefined
|
||||
if (typeValue === 'gif' || typeValue === 'webp') {
|
||||
let delayList = await imageSource.getDelayTimeList()
|
||||
if(delayList == undefined) {
|
||||
} else {
|
||||
let size = (await imageSource.getImageInfo()).size
|
||||
let base64Help = new util.Base64Helper()
|
||||
|
||||
let base64str = "data:image/" + typeValue + ";base64," + base64Help.encodeToStringSync(new Uint8Array(resBuf))
|
||||
LogUtil.log("ImageKnife_DataTime_requestJob_createPixelMap.end_GIF:"+request.src)
|
||||
LogUtil.log("ImageKnife_DataTime_requestJob.end_GIF:"+request.src)
|
||||
return {
|
||||
pixelMap: base64str,
|
||||
bufferSize: bufferSize,
|
||||
fileKey: fileKey,
|
||||
size:size,
|
||||
type:typeValue
|
||||
};
|
||||
}
|
||||
} else if(typeValue == "svg") {
|
||||
let size = (await imageSource.getImageInfo()).size
|
||||
let scale = size.height / size.width
|
||||
let hValue = Math.round(request.componentHeight);
|
||||
let wValue = Math.round(request.componentWidth);
|
||||
let defaultSize: image.Size = {
|
||||
height: vp2px(wValue) * scale,
|
||||
width: vp2px(wValue)
|
||||
};
|
||||
let opts: image.DecodingOptions = {
|
||||
editable: true,
|
||||
desiredSize: defaultSize
|
||||
};
|
||||
await imageSource.createPixelMap(opts)
|
||||
.then((pixelmap: PixelMap) => {
|
||||
resPixelmap = pixelmap
|
||||
imageSource.release()
|
||||
})
|
||||
return {
|
||||
pixelMap: resPixelmap,
|
||||
bufferSize: bufferSize,
|
||||
fileKey: fileKey,
|
||||
type:typeValue
|
||||
};
|
||||
}
|
||||
let size = (await imageSource.getImageInfo()).size
|
||||
await imageSource.createPixelMap(decodingOptions)
|
||||
.then((pixelmap: PixelMap) => {
|
||||
resPixelmap = pixelmap
|
||||
imageSource.release()
|
||||
})
|
||||
|
||||
// 图形变化
|
||||
if (request.requestSource === ImageKnifeRequestSource.SRC && request.transformation !== undefined) {
|
||||
resPixelmap = await request.transformation?.transform(request.context, resPixelmap!, request.componentWidth, request.componentHeight);
|
||||
}
|
||||
LogUtil.log("ImageKnife_DataTime_requestJob_createPixelMap.end:"+request.src)
|
||||
LogUtil.log("ImageKnife_DataTime_requestJob.end:"+request.src)
|
||||
return {
|
||||
pixelMap: resPixelmap,
|
||||
bufferSize: bufferSize,
|
||||
fileKey: fileKey,
|
||||
size:size,
|
||||
type:typeValue
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,567 @@
|
|||
/*
|
||||
* 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 {
|
||||
CacheStrategy,
|
||||
DecodeImageInfo,
|
||||
ErrorInfo,
|
||||
FlipRotate,
|
||||
ImageKnifeData,
|
||||
ImageKnifeRequestSource,
|
||||
ImageKnifeRequestWithSource, RequestJobRequest,
|
||||
TimeInfo } from './model/ImageKnifeData';
|
||||
import List from '@ohos.util.List'
|
||||
import { FileCache } from './cache/FileCache';
|
||||
import { LogUtil } from './utils/LogUtil';
|
||||
import { Constants, LoadPhase, LoadPixelMapCode } from './utils/Constants';
|
||||
import http from '@ohos.net.http';
|
||||
import { combineArrayBuffers } from './utils/ArrayBufferUtils';
|
||||
import { BusinessError } from '@kit.BasicServicesKit';
|
||||
import fs from '@ohos.file.fs';
|
||||
import emitter from '@ohos.events.emitter';
|
||||
import image from '@ohos.multimedia.image';
|
||||
import { RequestJobResult } from './model/ImageKnifeData'
|
||||
import util from '@ohos.util';
|
||||
import { FileTypeUtil } from './utils/FileTypeUtil';
|
||||
import { DownsampleStrategy } from './downsampling/DownsampleStartegy';
|
||||
import { Downsampler } from './downsampling/Downsampler';
|
||||
import { common } from '@kit.AbilityKit';
|
||||
import { ImageLoaderFactory } from './loaderStrategy/ImageLoaderFactory';
|
||||
|
||||
class RequestData {
|
||||
receiveSize: number = 2000
|
||||
totalSize: number = 2000
|
||||
}
|
||||
|
||||
/**
|
||||
* ImageKnifeDispatcher 抽取出来的方法,因@Concurrent只能import方法,故抽取到另一个类
|
||||
*/
|
||||
export class ImageKnifeLoader {
|
||||
static execute(request: RequestJobRequest, requestList: List<ImageKnifeRequestWithSource> | undefined, fileKey: string){
|
||||
ImageKnifeLoader.getImageArrayBuffer(request,requestList,fileKey)
|
||||
}
|
||||
static getUnit8Array (resBuf: ArrayBuffer) {
|
||||
let unit8 = new Uint8Array(resBuf)
|
||||
let unitString = ''
|
||||
if (unit8.length >= 3) {
|
||||
unitString = unit8[0] + ',' + unit8[1] + ',' + unit8[2]
|
||||
} else if (unit8.length > 0 && unit8.length < 3) {
|
||||
unitString = unit8.length + ''
|
||||
}
|
||||
return unitString
|
||||
}
|
||||
static async parseImage(resBuf: ArrayBuffer, fileKey: string,
|
||||
request: RequestJobRequest, callBackData: ImageKnifeData) {
|
||||
callBackData.bufSize = resBuf.byteLength;
|
||||
let typeValue = new FileTypeUtil().getFileType(resBuf);
|
||||
if(typeValue == null) {
|
||||
LogUtil.log('requestJob.end: getFileType is null: ' + request.componentId + ',srcType:' + request.requestSource + ',' + request.componentVersion)
|
||||
ImageKnifeLoader.makeEmptyResult(request,
|
||||
'request is not a valid image source:' + request.src + ',componentId' + request.componentId + ',srcType:' +
|
||||
request.requestSource + ',' +
|
||||
request.componentVersion + ',buffer:' + resBuf.byteLength + ',unit8:' + ImageKnifeLoader.getUnit8Array(resBuf),
|
||||
ImageKnifeLoader.assembleError(callBackData, LoadPhase.PHASE_GET_FORMAT,
|
||||
LoadPixelMapCode.IMAGE_PARSE_FORMAT_FAILED_CODE))
|
||||
return
|
||||
}
|
||||
callBackData.type = typeValue;
|
||||
if(request.isAnimator) {
|
||||
ImageKnifeLoader.parseForAnimatorComponent(resBuf ,typeValue ,fileKey, request, callBackData)
|
||||
return
|
||||
}
|
||||
|
||||
if (typeValue === 'gif' || typeValue === 'webp') {
|
||||
ImageKnifeLoader.parseAnimatorImage(resBuf ,typeValue ,fileKey , request, callBackData)
|
||||
return
|
||||
} else if(typeValue == 'svg') {
|
||||
ImageKnifeLoader.parseSvgImage(resBuf ,typeValue ,fileKey , request, callBackData)
|
||||
return
|
||||
}
|
||||
|
||||
ImageKnifeLoader.parseNormalImage(resBuf, typeValue, fileKey, request, callBackData)
|
||||
}
|
||||
|
||||
static makeEmptyResult(request:RequestJobRequest,error: string, data?: ImageKnifeData){
|
||||
let res: RequestJobResult = {
|
||||
pixelMap: undefined,
|
||||
bufferSize: 0,
|
||||
fileKey: '',
|
||||
loadFail: error,
|
||||
imageKnifeData: data
|
||||
}
|
||||
emitter.emit(Constants.CALLBACK_EMITTER + request.memoryKey, { data: { 'value': res } })
|
||||
}
|
||||
|
||||
static assembleError(data: ImageKnifeData | undefined, phase: string, code?: number): ImageKnifeData | undefined {
|
||||
let errorCallBackData = data?.errorInfo;
|
||||
if (!errorCallBackData) {
|
||||
return data;
|
||||
}
|
||||
errorCallBackData.phase = phase;
|
||||
errorCallBackData.code = code? code: 0;
|
||||
return data
|
||||
}
|
||||
|
||||
static getTimeInfo(callBackData: ImageKnifeData): TimeInfo {
|
||||
let timeInfo: TimeInfo;
|
||||
if (callBackData.timeInfo) {
|
||||
timeInfo = callBackData.timeInfo;
|
||||
}else {
|
||||
timeInfo = {};
|
||||
callBackData.timeInfo = timeInfo;
|
||||
}
|
||||
return timeInfo;
|
||||
}
|
||||
|
||||
static async parseNormalImage(resBuf: ArrayBuffer, typeValue: string, fileKey: string, request: RequestJobRequest, callBackData: ImageKnifeData) {
|
||||
LogUtil.log('image parse pixelmap start:' + request.componentId + ',srcType:' + request.requestSource + ',' + request.componentVersion)
|
||||
let resPixelmap: PixelMap | undefined = undefined
|
||||
let timeInfo: TimeInfo = ImageKnifeLoader.getTimeInfo(callBackData);
|
||||
|
||||
let decodingOptions: image.DecodingOptions = {
|
||||
editable: request.requestSource === ImageKnifeRequestSource.SRC && request.transformation !== undefined ? true : false,
|
||||
}
|
||||
let imageSource: image.ImageSource = image.createImageSource(resBuf)
|
||||
if (imageSource === undefined){
|
||||
ImageKnifeLoader.makeEmptyResult(request,'image.createImageSource failed', ImageKnifeLoader.assembleError(callBackData, LoadPhase.PHASE_CREATE_SOURCE, LoadPixelMapCode.IMAGE_SOURCE_ERROR_CODE))
|
||||
return
|
||||
}
|
||||
|
||||
let imageInfoSync = imageSource.getImageInfoSync()
|
||||
if (imageInfoSync == undefined){
|
||||
imageSource.release()
|
||||
ImageKnifeLoader.makeEmptyResult(request, 'getImageInfoSync failed')
|
||||
return
|
||||
}
|
||||
let size = imageInfoSync.size
|
||||
callBackData.imageWidth = size.width;
|
||||
callBackData.imageHeight = size.height;
|
||||
|
||||
if (request.isAutoImageFit && request.requestSource == ImageKnifeRequestSource.SRC){
|
||||
request.componentHeight = request.componentWidth * size.height / size.width
|
||||
}
|
||||
|
||||
try {
|
||||
if ((request.downsampType !== DownsampleStrategy.NONE) &&
|
||||
request.requestSource == ImageKnifeRequestSource.SRC) {
|
||||
decodingOptions =
|
||||
ImageKnifeLoader.getDownsamplerDecodingOptions(typeValue, request, size, ImageKnifeRequestSource.SRC)
|
||||
}
|
||||
} catch (err) {
|
||||
imageSource.release()
|
||||
ImageKnifeLoader.makeEmptyResult(request, 'getDownsamplerDecodingOptions failed:' + err)
|
||||
return
|
||||
}
|
||||
timeInfo.decodeStartTime = Date.now();
|
||||
|
||||
// 获取旋转信息
|
||||
let exif: string | undefined = undefined;
|
||||
await imageSource.getImageProperty(image.PropertyKey.ORIENTATION).then((res)=>{
|
||||
exif = res;
|
||||
}).catch((error: BusinessError)=>{
|
||||
LogUtil.info("The normal image don't have rotation information, " + error.message);
|
||||
})
|
||||
|
||||
await imageSource.createPixelMap(decodingOptions)
|
||||
.then((pixelmap: PixelMap) => {
|
||||
timeInfo.decodeEndTime = Date.now();
|
||||
resPixelmap = pixelmap
|
||||
imageSource.release()
|
||||
}).catch((error: BusinessError) => {
|
||||
timeInfo.decodeEndTime = Date.now();
|
||||
imageSource.release()
|
||||
ImageKnifeLoader.makeEmptyResult(request, 'createPixelMap failed:' + JSON.stringify(error),
|
||||
ImageKnifeLoader.assembleError(callBackData, LoadPhase.PHASE_CREATE_PIXEL_MAP, LoadPixelMapCode.IMAGE_DECODE_ERROR_CODE))
|
||||
return
|
||||
})
|
||||
if (request.requestSource === ImageKnifeRequestSource.SRC && request.transformation !== undefined && resPixelmap !== undefined) {
|
||||
LogUtil.log('requestJob.transform.start:' + request.componentId + ',srcType:' + request.requestSource + ',' + request.componentVersion)
|
||||
resPixelmap = await request.transformation?.transform(request.context, resPixelmap, request.componentWidth, request.componentHeight);
|
||||
LogUtil.log('requestJob.transform.end:' + request.componentId + ',srcType:' + request.requestSource + ',' + request.componentVersion)
|
||||
}
|
||||
try {
|
||||
resPixelmap?.setTransferDetached(true)
|
||||
} catch (e) {
|
||||
LogUtil.error('PixelMap setTransferDetached failed:' + JSON.stringify(e))
|
||||
}
|
||||
// 设置翻转和旋转角度
|
||||
if(exif && exif !== 'Top-left'){
|
||||
let result = ImageKnifeLoader.getOrientation(exif);
|
||||
if(result.horizontal || result.vertical) {
|
||||
resPixelmap?.flipSync(result.horizontal, result.vertical);
|
||||
}
|
||||
if(result.rotate > 0) {
|
||||
resPixelmap?.rotateSync(result.rotate);
|
||||
}
|
||||
LogUtil.log('The normal image set flip , horizontal=' + result.horizontal + ', vertical=' +result.vertical + ', rotate=' + result.rotate);
|
||||
}
|
||||
|
||||
//获取各个pixelMap的大小
|
||||
if (resPixelmap !== undefined) {
|
||||
let decodeImages: DecodeImageInfo[] = [];
|
||||
let size = (resPixelmap as PixelMap).getImageInfoSync().size;
|
||||
let decodeImage: DecodeImageInfo = {
|
||||
contentWidth: size.width,
|
||||
contentHeight: size.height,
|
||||
contentSize: (resPixelmap as PixelMap).getPixelBytesNumber()
|
||||
}
|
||||
decodeImages.push(decodeImage);
|
||||
callBackData.decodeImages = decodeImages;
|
||||
}
|
||||
|
||||
let res: RequestJobResult = {
|
||||
pixelMap: resPixelmap,
|
||||
bufferSize: resBuf.byteLength,
|
||||
fileKey: fileKey,
|
||||
size:size,
|
||||
type:typeValue,
|
||||
imageKnifeData:callBackData
|
||||
}
|
||||
LogUtil.log('image parse pixelmap end:' + request.componentId + ',srcType:' + request.requestSource + ',' + request.componentVersion)
|
||||
emitter.emit(Constants.CALLBACK_EMITTER + request.memoryKey, { data: { 'value': res } })
|
||||
}
|
||||
static async parseSvgImage(resBuf: ArrayBuffer, typeValue: string, fileKey: string,
|
||||
request: RequestJobRequest, callBackData: ImageKnifeData) {
|
||||
let resPixelmap: PixelMap | undefined = undefined
|
||||
let timeInfo: TimeInfo = ImageKnifeLoader.getTimeInfo(callBackData);
|
||||
|
||||
let imageSource: image.ImageSource = image.createImageSource(resBuf)
|
||||
if (imageSource === undefined){
|
||||
ImageKnifeLoader.makeEmptyResult(request,'image.createImageSource failed', ImageKnifeLoader.assembleError(callBackData, LoadPhase.PHASE_CREATE_SOURCE, LoadPixelMapCode.IMAGE_SOURCE_ERROR_CODE))
|
||||
return
|
||||
}
|
||||
|
||||
let imageInfoSync = imageSource.getImageInfoSync()
|
||||
if (imageInfoSync == undefined){
|
||||
imageSource.release()
|
||||
ImageKnifeLoader.makeEmptyResult(request, 'getImageInfoSync failed')
|
||||
return
|
||||
}
|
||||
let size = imageInfoSync.size
|
||||
let scale = size.height / size.width
|
||||
let hValue = Math.round(request.componentHeight);
|
||||
let wValue = Math.round(request.componentWidth);
|
||||
let defaultSize: image.Size = {
|
||||
height: vp2px(wValue) * scale,
|
||||
width: vp2px(wValue)
|
||||
};
|
||||
let opts: image.DecodingOptions = {
|
||||
editable: true,
|
||||
desiredSize: defaultSize
|
||||
};
|
||||
callBackData.imageWidth = size.width;
|
||||
callBackData.imageHeight = size.height;
|
||||
try {
|
||||
if ((request.downsampType !== DownsampleStrategy.NONE) &&
|
||||
request.requestSource == ImageKnifeRequestSource.SRC) {
|
||||
opts = ImageKnifeLoader.getDownsamplerDecodingOptions(typeValue, request, size)
|
||||
}
|
||||
} catch (err) {
|
||||
imageSource.release()
|
||||
ImageKnifeLoader.makeEmptyResult(request,'getDownsamplerDecodingOptions failed:' + err)
|
||||
return
|
||||
}
|
||||
timeInfo.decodeStartTime = Date.now();
|
||||
|
||||
// 获取旋转信息
|
||||
let exif: string | undefined = undefined;
|
||||
await imageSource.getImageProperty(image.PropertyKey.ORIENTATION).then((res)=>{
|
||||
exif = res;
|
||||
}).catch((error: BusinessError)=>{
|
||||
LogUtil.info("Svg image don't have rotation information, " + error.message);
|
||||
})
|
||||
|
||||
await imageSource.createPixelMap(opts)
|
||||
.then((pixelmap: PixelMap) => {
|
||||
timeInfo.decodeEndTime = Date.now();
|
||||
resPixelmap = pixelmap
|
||||
imageSource.release()
|
||||
try {
|
||||
resPixelmap.setTransferDetached(true)
|
||||
// 设置翻转和旋转角度
|
||||
if(exif && exif !== 'Top-left'){
|
||||
let result = ImageKnifeLoader.getOrientation(exif);
|
||||
if(result.horizontal || result.vertical) {
|
||||
resPixelmap?.flipSync(result.horizontal, result.vertical);
|
||||
}
|
||||
if(result.rotate > 0) {
|
||||
resPixelmap?.rotateSync(result.rotate);
|
||||
}
|
||||
LogUtil.log('Svg image set flip , horizontal=' + result.horizontal + ', vertical=' +result.vertical + ', rotate=' + result.rotate);
|
||||
}
|
||||
} catch (e) {
|
||||
LogUtil.error('PixelMap setTransferDetached failed:' + JSON.stringify(e))
|
||||
}
|
||||
}).catch((error: BusinessError) => {
|
||||
timeInfo.decodeEndTime = Date.now();
|
||||
imageSource.release()
|
||||
ImageKnifeLoader.makeEmptyResult(request,'getImageInfoSync failed:' + JSON.stringify(error), ImageKnifeLoader.assembleError(callBackData, LoadPhase.PHASE_CREATE_PIXEL_MAP, LoadPixelMapCode.IMAGE_DECODE_ERROR_CODE))
|
||||
return
|
||||
})
|
||||
|
||||
//获取各个pixelMap的大小
|
||||
if (resPixelmap && typeof resPixelmap !== 'string') {
|
||||
let decodeImages: DecodeImageInfo[] = [];
|
||||
let decodeImage: DecodeImageInfo = {
|
||||
contentWidth: defaultSize.width,
|
||||
contentHeight: defaultSize.height,
|
||||
contentSize: (resPixelmap as PixelMap).getPixelBytesNumber()
|
||||
}
|
||||
decodeImages.push(decodeImage);
|
||||
}
|
||||
|
||||
let res: RequestJobResult = {
|
||||
pixelMap: resPixelmap,
|
||||
bufferSize: resBuf.byteLength,
|
||||
fileKey: fileKey,
|
||||
type:typeValue,
|
||||
imageKnifeData:callBackData
|
||||
}
|
||||
emitter.emit(Constants.CALLBACK_EMITTER + request.memoryKey, { data: { 'value': res } })
|
||||
}
|
||||
static async parseAnimatorImage(resBuf: ArrayBuffer, typeValue: string,
|
||||
fileKey: string,request: RequestJobRequest, callBackData: ImageKnifeData) {
|
||||
let timeInfo: TimeInfo = ImageKnifeLoader.getTimeInfo(callBackData);
|
||||
let imageSource: image.ImageSource = image.createImageSource(resBuf)
|
||||
if (imageSource === undefined){
|
||||
ImageKnifeLoader.makeEmptyResult(request,'image.createImageSource failed', ImageKnifeLoader.assembleError(callBackData,LoadPhase.PHASE_CREATE_SOURCE,LoadPixelMapCode.IMAGE_SOURCE_ERROR_CODE))
|
||||
return
|
||||
}
|
||||
|
||||
let frameCount = await imageSource.getFrameCount()
|
||||
let imageInfoSync = imageSource.getImageInfoSync()
|
||||
imageSource.release()
|
||||
if (imageInfoSync == undefined){
|
||||
ImageKnifeLoader.makeEmptyResult(request, 'getImageInfoSync failed')
|
||||
return
|
||||
}
|
||||
let size = imageInfoSync.size
|
||||
callBackData.frameCount = frameCount;
|
||||
callBackData.imageWidth = size.width;
|
||||
callBackData.imageHeight = size.height;
|
||||
|
||||
if(frameCount == undefined || frameCount == 1) {
|
||||
} else {
|
||||
timeInfo.decodeStartTime = Date.now()
|
||||
let base64str = 'data:image/' + typeValue + ';base64,' + new util.Base64Helper().encodeToStringSync(new Uint8Array(resBuf))
|
||||
timeInfo.decodeEndTime = Date.now()
|
||||
let res: RequestJobResult = {
|
||||
pixelMap: base64str,
|
||||
bufferSize: resBuf.byteLength,
|
||||
fileKey: fileKey,
|
||||
size:size,
|
||||
type:typeValue,
|
||||
imageKnifeData:callBackData
|
||||
}
|
||||
emitter.emit(Constants.CALLBACK_EMITTER + request.memoryKey, { data: { 'value': res } })
|
||||
return
|
||||
}
|
||||
ImageKnifeLoader.parseNormalImage(resBuf, typeValue, fileKey, request, callBackData)
|
||||
}
|
||||
// 为AnimatorComponent解析动图
|
||||
static async parseForAnimatorComponent(resBuf: ArrayBuffer, typeValue: string, fileKey: string,request: RequestJobRequest, callBackData: ImageKnifeData) {
|
||||
let timeInfo: TimeInfo = ImageKnifeLoader.getTimeInfo(callBackData);
|
||||
|
||||
if (typeValue === 'gif' || typeValue === 'webp') {
|
||||
let imageSource: image.ImageSource = image.createImageSource(resBuf);
|
||||
if (imageSource === undefined){
|
||||
ImageKnifeLoader.makeEmptyResult(request,'image.createImageSource failed', ImageKnifeLoader.assembleError(callBackData, LoadPhase.PHASE_CREATE_SOURCE, LoadPixelMapCode.IMAGE_SOURCE_ERROR_CODE))
|
||||
return
|
||||
}
|
||||
let decodingOptions: image.DecodingOptions = {
|
||||
editable: request.requestSource === ImageKnifeRequestSource.SRC && request.transformation !== undefined ? true : false,
|
||||
}
|
||||
|
||||
let imageInfoSync = imageSource.getImageInfoSync()
|
||||
if (imageInfoSync == undefined){
|
||||
imageSource.release()
|
||||
ImageKnifeLoader.makeEmptyResult(request, 'getImageInfoSync failed')
|
||||
return
|
||||
}
|
||||
callBackData.imageWidth = imageInfoSync.size.width;
|
||||
callBackData.imageHeight = imageInfoSync.size.height;
|
||||
let pixelMapList: Array<PixelMap> = []
|
||||
let delayList: Array<number> = []
|
||||
timeInfo.decodeStartTime = Date.now();
|
||||
let decodeImages: Array<DecodeImageInfo> = [];
|
||||
await imageSource.createPixelMapList(decodingOptions).then(async (pixelList: Array<PixelMap>) => {
|
||||
timeInfo.decodeEndTime = Date.now();
|
||||
//sdk的api接口发生变更:从.getDelayTime() 变为.getDelayTimeList()
|
||||
await imageSource.getDelayTimeList().then(delayTimes => {
|
||||
if (pixelList.length > 0) {
|
||||
for (let i = 0; i < pixelList.length; i++) {
|
||||
pixelMapList.push(pixelList[i]);
|
||||
if (i < delayTimes.length) {
|
||||
delayList.push(delayTimes[i]);
|
||||
} else {
|
||||
delayList.push(delayTimes[delayTimes.length - 1])
|
||||
}
|
||||
//获取各个pixelMap的大小
|
||||
let size = pixelList[i].getImageInfoSync().size
|
||||
let decodeImage: DecodeImageInfo = {
|
||||
contentWidth: size.width,
|
||||
contentHeight: size.height,
|
||||
contentSize: pixelList[i].getPixelBytesNumber()
|
||||
}
|
||||
decodeImages.push(decodeImage);
|
||||
}
|
||||
imageSource.release();
|
||||
}
|
||||
})
|
||||
}).catch((error: BusinessError) => {
|
||||
imageSource.release()
|
||||
timeInfo.decodeEndTime = Date.now();
|
||||
ImageKnifeLoader.makeEmptyResult(request,'createPixelMapList failed:' + JSON.stringify(error),
|
||||
ImageKnifeLoader.assembleError(callBackData,LoadPhase.PHASE_CREATE_PIXEL_MAP,LoadPixelMapCode.IMAGE_DECODE_ERROR_CODE))
|
||||
return
|
||||
})
|
||||
callBackData.decodeImages = decodeImages;
|
||||
let res: RequestJobResult = {
|
||||
pixelMap: '',
|
||||
bufferSize: resBuf.byteLength,
|
||||
fileKey: fileKey,
|
||||
type: typeValue,
|
||||
imageKnifeData:callBackData,
|
||||
pixelMapList,
|
||||
delayList
|
||||
}
|
||||
emitter.emit(Constants.CALLBACK_EMITTER + request.memoryKey, { data: { 'value': res } })
|
||||
} else {
|
||||
ImageKnifeLoader.makeEmptyResult(request,'ImageKnifeAnimatorComponent not support format', ImageKnifeLoader.assembleError(callBackData,LoadPhase.PHASE_PARSE_IAMGE,LoadPixelMapCode.IMAGE_FORMAT_ERROR_CODE))
|
||||
}
|
||||
}
|
||||
static getHeaderObj(request:RequestJobRequest){
|
||||
const headerObj: Record<string, Object> = {}
|
||||
if (request.headers != undefined) {
|
||||
request.headers.forEach((value) => {
|
||||
headerObj[value.key] = value.value
|
||||
})
|
||||
} else if (request.allHeaders.size > 0) {
|
||||
request.allHeaders.forEach((value, key) => {
|
||||
headerObj[key] = value
|
||||
})
|
||||
}
|
||||
return headerObj
|
||||
}
|
||||
static FileCacheParseImage(request:RequestJobRequest,resBuf:ArrayBuffer,fileKey:string, callBackData: ImageKnifeData){
|
||||
try {
|
||||
// 保存文件缓存
|
||||
if (resBuf !== undefined && request.writeCacheStrategy !== CacheStrategy.Memory) {
|
||||
LogUtil.log('requestJob_saveFileCacheOnlyFile.start:' + request.componentId + ',srcType:' + request.requestSource + ',' + request.componentVersion)
|
||||
FileCache.saveFileCacheOnlyFile(request.context, fileKey, resBuf , request.fileCacheFolder)
|
||||
LogUtil.log('requestJob_saveFileCacheOnlyFile.end:' + request.componentId + ',srcType:' + request.requestSource + ',' + request.componentVersion)
|
||||
}
|
||||
ImageKnifeLoader.parseImage(resBuf,fileKey,request, callBackData)
|
||||
} catch (e) {
|
||||
ImageKnifeLoader.makeEmptyResult(request,
|
||||
'image load FileCacheParseImage error:' + e + ',componentId' + request.componentId + ',srcType:' +
|
||||
request.requestSource + ',' + request.componentVersion)
|
||||
}
|
||||
}
|
||||
// 获取图片资源
|
||||
static async getImageArrayBuffer(request: RequestJobRequest, requestList: List<ImageKnifeRequestWithSource> | undefined,fileKey:string) {
|
||||
let resBuf: ArrayBuffer | undefined
|
||||
let loadError: string = ''
|
||||
//定义图片各个阶段错误信息
|
||||
let error: ErrorInfo = { code: 0, phase: LoadPhase.PHASE_LOAD }
|
||||
//定义加载时间点
|
||||
let callBackTimeInfo: TimeInfo = {};
|
||||
//定义加载信息回调数据
|
||||
let callBackData: ImageKnifeData = {
|
||||
source: '',
|
||||
imageWidth: 0,
|
||||
imageHeight: 0,
|
||||
timeInfo: callBackTimeInfo,
|
||||
errorInfo: error
|
||||
};
|
||||
|
||||
const loaderStrategy = ImageLoaderFactory.getLoaderStrategy(request);
|
||||
if (loaderStrategy) {
|
||||
await loaderStrategy.loadImage(request, requestList, fileKey, callBackData, callBackTimeInfo);
|
||||
} else {
|
||||
loadError = `Unsupported request type: ${request.src}`;
|
||||
callBackTimeInfo.requestEndTime = Date.now();
|
||||
ImageKnifeLoader.makeEmptyResult(request, loadError, callBackData);
|
||||
}
|
||||
}
|
||||
static isLocalLoadSrc(context: Object | undefined, loadSrc: string): boolean {
|
||||
if (context != undefined) {
|
||||
let fileDir: string = (context as common.UIAbilityContext).filesDir as string;
|
||||
let cacheDir: string = (context as common.UIAbilityContext).cacheDir as string
|
||||
if (loadSrc.startsWith(fileDir) || loadSrc.startsWith(cacheDir)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
static getDownsamplerDecodingOptions(typeValue: string, request: RequestJobRequest, size: Size,
|
||||
SRC?: ImageKnifeRequestSource):image.DecodingOptions {
|
||||
let reqSize =
|
||||
new Downsampler().calculateScaling(typeValue, size.width, size.height,
|
||||
vp2px(request.targetWidth), vp2px(request.targetHeight), request.downsampType)
|
||||
if (typeValue == 'svg') {
|
||||
return {
|
||||
editable: true,
|
||||
desiredSize: {
|
||||
height: vp2px(reqSize.height),
|
||||
width: vp2px(reqSize.width)
|
||||
}
|
||||
|
||||
}
|
||||
} else {
|
||||
return {
|
||||
editable: request.requestSource === SRC && request.transformation !== undefined ? true : false,
|
||||
desiredSize:{
|
||||
width: reqSize.width,
|
||||
height: reqSize.height
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static getOrientation(orientation: string | undefined){
|
||||
let horizontal: boolean = false;
|
||||
let vertical: boolean = false;
|
||||
let rotate: number= 0;
|
||||
switch (orientation){
|
||||
case 'Top-left': break
|
||||
case 'Top-right':
|
||||
horizontal = true;
|
||||
break;
|
||||
case 'Bottom-left':
|
||||
vertical = true;
|
||||
break
|
||||
case 'Bottom-right':
|
||||
rotate = 180;
|
||||
break;
|
||||
case 'Left-top':
|
||||
horizontal = true;
|
||||
rotate = 270;
|
||||
break
|
||||
case 'Right-top':
|
||||
rotate = 90;
|
||||
break;
|
||||
case 'Left-bottom':
|
||||
rotate = 270;
|
||||
break
|
||||
case 'Right-bottom':
|
||||
horizontal = true;
|
||||
rotate = 90;
|
||||
break;
|
||||
}
|
||||
|
||||
let data: FlipRotate = { horizontal: horizontal, vertical: vertical, rotate:rotate };
|
||||
return data
|
||||
}
|
||||
}
|
|
@ -1,161 +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 taskpool from '@ohos.taskpool';
|
||||
import common from '@ohos.app.ability.common'
|
||||
import { CacheStrategy, ImageKnifeData,EventImage } from './model/ImageKnifeData';
|
||||
import { PixelMapTransformation } from './transform/PixelMapTransformation';
|
||||
import { drawing } from '@kit.ArkGraphics2D';
|
||||
|
||||
export interface HeaderOptions {
|
||||
key: string;
|
||||
value: Object;
|
||||
}
|
||||
interface AnimatorType {
|
||||
state?: AnimationStatus
|
||||
iterations?: number
|
||||
reverse?: boolean
|
||||
onStart?:()=>void
|
||||
onFinish?:()=>void
|
||||
onPause?:()=>void
|
||||
onCancel?:()=>void
|
||||
onRepeat?:()=>void
|
||||
}
|
||||
@ObservedV2
|
||||
export class AnimatorOption {
|
||||
@Trace
|
||||
state?: AnimationStatus = AnimationStatus.Running
|
||||
@Trace
|
||||
iterations?: number = -1
|
||||
@Trace
|
||||
reverse?: boolean = false
|
||||
@Trace
|
||||
onStart?:()=>void
|
||||
@Trace
|
||||
onFinish?:()=>void
|
||||
@Trace
|
||||
onPause?:()=>void
|
||||
@Trace
|
||||
onCancel?:()=>void
|
||||
@Trace
|
||||
onRepeat?:()=>void
|
||||
constructor(option?:AnimatorType) {
|
||||
this.state = option?.state
|
||||
this.iterations = option?.iterations
|
||||
this.reverse = option?.reverse
|
||||
this.onStart = option?.onStart
|
||||
this.onFinish = option?.onFinish
|
||||
this.onPause = option?.onPause
|
||||
this.onCancel = option?.onCancel
|
||||
this.onRepeat = option?.onRepeat
|
||||
}
|
||||
}
|
||||
interface ImageOption {
|
||||
// 主图资源
|
||||
loadSrc: string | PixelMap | Resource
|
||||
// 占位图
|
||||
placeholderSrc?: string | PixelMap | Resource
|
||||
// 失败占位图
|
||||
errorholderSrc?: string | PixelMap | Resource
|
||||
headerOption?: Array<HeaderOptions>;
|
||||
// 自定义缓存关键字
|
||||
signature?: string
|
||||
// 主图填充效果
|
||||
objectFit?: ImageFit
|
||||
// 占位图填充效果
|
||||
placeholderObjectFit?: ImageFit
|
||||
// 错误图填充效果
|
||||
errorholderObjectFit?: ImageFit
|
||||
customGetImage?: (context: Context, src: string | PixelMap | Resource) => Promise<ArrayBuffer | undefined>
|
||||
border?: BorderOptions
|
||||
// 缓存策略
|
||||
writeCacheStrategy?: CacheStrategy
|
||||
// 仅使用缓存加载数据
|
||||
onlyRetrieveFromCache?: boolean;
|
||||
priority?: taskpool.Priority
|
||||
context?: common.UIAbilityContext;
|
||||
progressListener?: (progress: number) => void;
|
||||
transformation?: PixelMapTransformation
|
||||
onLoadListener?: OnLoadCallBack | undefined;
|
||||
onComplete?:(event:EventImage | undefined) => void
|
||||
drawingColorFilter?: ColorFilter | drawing.ColorFilter
|
||||
}
|
||||
@ObservedV2
|
||||
export class ImageKnifeOption {
|
||||
// 主图资源
|
||||
@Trace loadSrc: string | PixelMap | Resource = "";
|
||||
// 占位图
|
||||
placeholderSrc?: string | PixelMap | Resource;
|
||||
// 失败占位图
|
||||
errorholderSrc?: string | PixelMap | Resource;
|
||||
headerOption?: Array<HeaderOptions>;
|
||||
// 自定义缓存关键字
|
||||
@Trace signature?: string;
|
||||
// 主图填充效果
|
||||
@Trace objectFit?: ImageFit
|
||||
// 占位图填充效果
|
||||
placeholderObjectFit?: ImageFit
|
||||
// 错误图填充效果
|
||||
errorholderObjectFit?: ImageFit
|
||||
customGetImage?: (context: Context, src: string | PixelMap | Resource) => Promise<ArrayBuffer | undefined>
|
||||
@Trace border?: BorderOptions
|
||||
// 缓存策略
|
||||
writeCacheStrategy?: CacheStrategy
|
||||
// 仅使用缓存加载数据
|
||||
onlyRetrieveFromCache?: boolean = false;
|
||||
priority?: taskpool.Priority = taskpool.Priority.LOW
|
||||
context?: common.UIAbilityContext;
|
||||
progressListener?: (progress: number) => void;
|
||||
@Trace transformation?: PixelMapTransformation
|
||||
onLoadListener?: OnLoadCallBack | undefined;
|
||||
onComplete?:(event:EventImage | undefined) => void
|
||||
drawingColorFilter?: ColorFilter | drawing.ColorFilter
|
||||
constructor(option?:ImageOption) {
|
||||
this.loadSrc = option?.loadSrc == undefined ? "" : option?.loadSrc
|
||||
this.placeholderSrc = option?.placeholderSrc
|
||||
this.errorholderSrc = option?.errorholderSrc
|
||||
this.headerOption = option?.headerOption
|
||||
this.signature = option?.signature
|
||||
this.objectFit = option?.objectFit
|
||||
this.placeholderObjectFit = option?.placeholderObjectFit
|
||||
this.errorholderObjectFit = option?.errorholderObjectFit
|
||||
this.customGetImage = option?.customGetImage
|
||||
this.border = option?.border
|
||||
this.writeCacheStrategy = option?.writeCacheStrategy
|
||||
this.onlyRetrieveFromCache = option?.onlyRetrieveFromCache
|
||||
this.priority = option?.priority
|
||||
this.context = option?.context
|
||||
this.progressListener = option?.progressListener
|
||||
this.transformation = option?.transformation
|
||||
this.onLoadListener = option?.onLoadListener
|
||||
this.onComplete = option?.onComplete
|
||||
this.drawingColorFilter = option?.drawingColorFilter
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 请求回调
|
||||
*/
|
||||
export interface OnLoadCallBack {
|
||||
// 请求开始
|
||||
onLoadStart?: () => void;
|
||||
|
||||
// 请求成功
|
||||
onLoadSuccess?: (data: string | PixelMap | undefined, imageKnifeData: ImageKnifeData) => void;
|
||||
|
||||
// 请求结束
|
||||
onLoadFailed?: (err: string) => void;
|
||||
// 请求取消
|
||||
onLoadCancel?: (reason: string) => void;
|
||||
}
|
|
@ -13,10 +13,9 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
import util from '@ohos.util';
|
||||
import { FileUtils } from './FileUtils';
|
||||
import { FileUtils } from '../utils/FileUtils';
|
||||
import fs from '@ohos.file.fs';
|
||||
import { LogUtil } from './LogUtil';
|
||||
import { SparkMD5 } from '../3rd_party/sparkmd5/spark-md5';
|
||||
import { LogUtil } from '../utils/LogUtil';
|
||||
|
||||
const INT_MAX = 2147483647
|
||||
/**
|
||||
|
@ -25,32 +24,29 @@ const INT_MAX = 2147483647
|
|||
* 子线程直接读写文件
|
||||
*/
|
||||
export class FileCache {
|
||||
static CACHE_FOLDER: string = "ImageKnife" // context cacheDir 的缓存文件目录
|
||||
static CACHE_FOLDER: string = 'ImageKnife' // context cacheDir 的缓存文件目录
|
||||
maxMemory: number = 0
|
||||
currentMemory: number = 0
|
||||
maxSize: number = 0
|
||||
path: string = ""
|
||||
path: string = ''
|
||||
private lruCache: util.LRUCache<string, number>
|
||||
private isInited: boolean = false
|
||||
private context?: Context
|
||||
readonly defaultMaxSize: number = 512;
|
||||
readonly defaultSize: number = INT_MAX;
|
||||
readonly defaultMaxMemorySize: number = 512 * 1024 * 1024;
|
||||
readonly defaultMemorySize: number = 128 * 1024 * 1024;
|
||||
readonly defaultMaxMemorySize: number = 10 * 1024 * 1024 * 1024;
|
||||
readonly defaultMemorySize: number = 1024 * 1024 * 1024;
|
||||
|
||||
constructor(context: Context, size: number, memory: number) {
|
||||
if (size <= 0 || size > INT_MAX) {
|
||||
size = this.defaultSize
|
||||
size = INT_MAX;
|
||||
}
|
||||
if (memory <= 0 || memory > this.defaultMaxMemorySize) {
|
||||
memory = this.defaultMemorySize
|
||||
memory = this.defaultMemorySize;
|
||||
}
|
||||
|
||||
this.lruCache = new util.LRUCache(size);
|
||||
this.maxMemory = memory
|
||||
this.maxMemory = memory;
|
||||
this.currentMemory = 0;
|
||||
this.maxSize = size
|
||||
this.context = context
|
||||
this.maxSize = size;
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -60,6 +56,7 @@ export class FileCache {
|
|||
if (this.isInited) {
|
||||
return
|
||||
}
|
||||
let startTime = Date.now()
|
||||
if (this.context && path.startsWith(this.context.cacheDir) === true) {
|
||||
this.path = path
|
||||
} else {
|
||||
|
@ -73,6 +70,7 @@ export class FileCache {
|
|||
interface CacheFileInfo {
|
||||
file: string;
|
||||
ctime: number;
|
||||
size: number;
|
||||
}
|
||||
|
||||
// 按照上次访问该文件的时间排序
|
||||
|
@ -81,29 +79,29 @@ export class FileCache {
|
|||
let stat: fs.Stat | undefined = await FileUtils.getInstance().Stat(this.path + filenames[i])
|
||||
cachefiles.push({
|
||||
file: filenames[i],
|
||||
ctime: stat === undefined ? 0 : stat.ctime
|
||||
ctime: stat === undefined ? 0 : stat.ctime,
|
||||
size: stat?.size ?? 0
|
||||
})
|
||||
}
|
||||
let sortedCachefiles: CacheFileInfo[] = cachefiles.sort((a, b) => a.ctime - b.ctime)
|
||||
|
||||
for (let i = 0; i < sortedCachefiles.length; i++) {
|
||||
let buf: ArrayBuffer | undefined = await FileUtils.getInstance().readFile(this.path + sortedCachefiles[i].file)
|
||||
if (buf !== undefined) {
|
||||
const fileSize: number = sortedCachefiles[i].size;
|
||||
// 处理数量超过size的场景,移除即将排除的文件
|
||||
if (this.lruCache.length == this.maxSize && !this.lruCache.contains(sortedCachefiles[i].file)) {
|
||||
let remove: number | undefined = this.lruCache.remove(this.lruCache.keys()[0])
|
||||
if (remove !== undefined) {
|
||||
FileUtils.getInstance().deleteFile(this.path + this.lruCache.keys()[0])
|
||||
this.removeMemorySize(buf)
|
||||
this.removeMemorySize(fileSize)
|
||||
}
|
||||
}
|
||||
|
||||
this.lruCache.put(sortedCachefiles[i].file, buf.byteLength)
|
||||
this.addMemorySize(buf)
|
||||
}
|
||||
this.lruCache.put(sortedCachefiles[i].file, fileSize)
|
||||
this.addMemorySize(fileSize)
|
||||
}
|
||||
|
||||
this.trimToSize();
|
||||
LogUtil.info('image init initFileCache:' + (Date.now() - startTime) + ',num:' + filenames.length + ',nums:' + this.lruCache.length + ',size:' + this.currentMemory)
|
||||
this.isInited = true
|
||||
}
|
||||
|
||||
|
@ -153,11 +151,11 @@ export class FileCache {
|
|||
this.remove(this.lruCache.keys()[0])
|
||||
} else if (this.lruCache.contains(key)) {
|
||||
this.lruCache.remove(key)
|
||||
this.lruCache.put(key, typeof value == "number" ? value : value.byteLength)
|
||||
this.lruCache.put(key, typeof value == 'number' ? value : value.byteLength)
|
||||
return
|
||||
}
|
||||
|
||||
this.lruCache.put(key, typeof value == "number" ? value : value.byteLength)
|
||||
this.lruCache.put(key, typeof value == 'number' ? value : value.byteLength)
|
||||
this.addMemorySize(value)
|
||||
this.trimToSize()
|
||||
}
|
||||
|
@ -194,7 +192,6 @@ export class FileCache {
|
|||
if (!this.isInited) {
|
||||
return
|
||||
}
|
||||
this.isInited = false
|
||||
this.lruCache.clear()
|
||||
this.currentMemory = 0;
|
||||
|
||||
|
@ -202,8 +199,6 @@ export class FileCache {
|
|||
for (let i = 0; i < filenames.length; i++) {
|
||||
await FileUtils.getInstance().deleteFile(this.path + filenames[i])
|
||||
}
|
||||
|
||||
this.isInited = true
|
||||
}
|
||||
|
||||
size(): number {
|
||||
|
@ -227,23 +222,23 @@ export class FileCache {
|
|||
}
|
||||
|
||||
private removeMemorySize(value: ArrayBuffer | number): void {
|
||||
if (typeof value == "number") {
|
||||
if (typeof value == 'number') {
|
||||
this.currentMemory -= value
|
||||
}
|
||||
else if (value != undefined) {
|
||||
this.currentMemory -= value.byteLength
|
||||
LogUtil.info("FileCache removeMemorySize: " + value.byteLength + " currentMemory:" + this.currentMemory)
|
||||
LogUtil.debug('FileCache removeMemorySize: ' + value.byteLength + ' currentMemory:' + this.currentMemory)
|
||||
}
|
||||
}
|
||||
|
||||
private addMemorySize(value: ArrayBuffer | number): void {
|
||||
if (typeof value == "number") {
|
||||
if (typeof value == 'number') {
|
||||
this.currentMemory += value
|
||||
LogUtil.info("FileCache addMemorySize: " + value + " currentMemory:" + this.currentMemory)
|
||||
LogUtil.debug('FileCache addMemorySize: ' + value + ' currentMemory:' + this.currentMemory)
|
||||
}
|
||||
else if (value != undefined) {
|
||||
this.currentMemory += value.byteLength
|
||||
LogUtil.info("FileCache addMemorySize: " + value.byteLength + " currentMemory:" + this.currentMemory)
|
||||
LogUtil.debug('FileCache addMemorySize: ' + value.byteLength + ' currentMemory:' + this.currentMemory)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -279,13 +274,13 @@ export class FileCache {
|
|||
*/
|
||||
getFileToPath(key: string): string {
|
||||
if(!!!key) {
|
||||
throw new Error("key is null,checking the parameter")
|
||||
throw new Error('key is null,checking the parameter')
|
||||
}
|
||||
let path = this.path + key
|
||||
if(FileUtils.getInstance().exist(path)) {
|
||||
return path
|
||||
} else {
|
||||
return ""
|
||||
return ''
|
||||
}
|
||||
}
|
||||
}
|
|
@ -21,23 +21,23 @@ export class MemoryLruCache implements IMemoryCache {
|
|||
currentMemory: number = 0
|
||||
maxSize: number = 0
|
||||
private lruCache: util.LRUCache<string, ImageKnifeData>
|
||||
readonly defaultMaxSize: number = 4096
|
||||
readonly defaultSize: number = 512
|
||||
readonly defaultMaxMemorySize: number = 1024 * 1024 * 1024
|
||||
readonly defaultMemorySize: number = 128 * 1024 * 1024
|
||||
readonly defaultMaxSize: number = 65536;
|
||||
readonly defaultSize: number = 512;
|
||||
readonly defaultMaxMemorySize: number = 10 * 1024 * 1024 * 1024;
|
||||
readonly defaultMemorySize: number = 1024 * 1024 * 1024;
|
||||
|
||||
constructor(size: number, memory: number) {
|
||||
if (size <= 0 || size > this.defaultMaxSize) {
|
||||
size = this.defaultSize
|
||||
size = this.defaultSize;
|
||||
}
|
||||
if (memory <= 0 || memory > this.defaultMaxMemorySize) {
|
||||
memory = this.defaultMemorySize
|
||||
memory = this.defaultMemorySize;
|
||||
}
|
||||
|
||||
this.lruCache = new util.LRUCache(size);
|
||||
this.maxMemory = memory
|
||||
this.maxSize = size
|
||||
this.currentMemory = 0
|
||||
this.maxMemory = memory;
|
||||
this.maxSize = size;
|
||||
this.currentMemory = 0;
|
||||
}
|
||||
|
||||
// 添加缓存键值对
|
||||
|
@ -46,6 +46,11 @@ export class MemoryLruCache implements IMemoryCache {
|
|||
throw new Error('key or value is invalid ');
|
||||
}
|
||||
|
||||
let size = this.getImageKnifeDataSize(value)
|
||||
if (size <= 0 || size >= this.maxMemory) {
|
||||
return
|
||||
}
|
||||
|
||||
// 如果size满了的话,需要按照LRU的方式删除第一个
|
||||
if (this.lruCache.length == this.maxSize && !this.lruCache.contains(key)) {
|
||||
this.remove(this.lruCache.keys()[0])
|
||||
|
@ -53,12 +58,9 @@ export class MemoryLruCache implements IMemoryCache {
|
|||
this.remove(key)
|
||||
}
|
||||
|
||||
let pre: ImageKnifeData = this.lruCache.put(key, value)
|
||||
this.addMemorySize(value)
|
||||
// if (pre !== undefined) { // 当前返回不是key的之前value
|
||||
// this.removeMemorySize(pre)
|
||||
// }
|
||||
this.trimToSize();
|
||||
this.lruCache.put(key, value)
|
||||
this.currentMemory += size
|
||||
this.trimToSize()
|
||||
}
|
||||
|
||||
get(key: string): ImageKnifeData | undefined {
|
||||
|
@ -104,34 +106,35 @@ export class MemoryLruCache implements IMemoryCache {
|
|||
|
||||
private removeMemorySize(value: ImageKnifeData): void {
|
||||
if (value.source != undefined) {
|
||||
if (typeof value.source === 'string' && value.source != "") {
|
||||
if (typeof value.source === 'string' && value.source != '') {
|
||||
this.currentMemory -= value.source.length
|
||||
} else if (value.source == "") {
|
||||
} else if (value.source == '') {
|
||||
for (let index = 0;index < value.imageAnimator!.length;index++) {
|
||||
let pixelMap = value.imageAnimator![index].src as PixelMap
|
||||
this.currentMemory -= pixelMap.getPixelBytesNumber()
|
||||
}
|
||||
} else {
|
||||
this.currentMemory -= value.source.getPixelBytesNumber();
|
||||
value.source.release()
|
||||
// value.source.release()
|
||||
}
|
||||
// LogUtil.info("MemoryCache removeMemorySize: " + value.source.getPixelBytesNumber() + " currentMemory:" + this.currentMemory)
|
||||
}
|
||||
}
|
||||
|
||||
private addMemorySize(value: ImageKnifeData): void {
|
||||
private getImageKnifeDataSize(value: ImageKnifeData): number {
|
||||
if (value.source != undefined) {
|
||||
if (typeof value.source === 'string' && value.source != "") {
|
||||
this.currentMemory += value.source.length
|
||||
} else if (value.source == "") {
|
||||
for (let index = 0;index < value.imageAnimator!.length;index++) {
|
||||
if (typeof value.source === 'string' && value.source != '') {
|
||||
return value.source.length
|
||||
} else if (value.source == '') {
|
||||
let size: number = 0
|
||||
for (let index = 0; index < value.imageAnimator!.length; index++) {
|
||||
let pixelMap = value.imageAnimator![index].src as PixelMap
|
||||
this.currentMemory += pixelMap.getPixelBytesNumber()
|
||||
size += pixelMap.getPixelBytesNumber()
|
||||
}
|
||||
return size
|
||||
} else {
|
||||
this.currentMemory += value.source.getPixelBytesNumber();
|
||||
return value.source.getPixelBytesNumber();
|
||||
}
|
||||
//LogUtil.log("MemoryCache addMemorySize: " + value.source.getPixelBytesNumber() + " currentMemory:" + this.currentMemory)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
}
|
|
@ -12,64 +12,69 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { AnimatorOption, ImageKnifeOption } from '../ImageKnifeOption';
|
||||
import { ImageKnifeRequest, ImageKnifeRequestState } from '../ImageKnifeRequest';
|
||||
import { AnimatorOption, ImageKnifeOption } from '../model/ImageKnifeOption';
|
||||
import { ImageKnifeRequest, ImageKnifeRequestState } from '../model/ImageKnifeRequest';
|
||||
import common from '@ohos.app.ability.common';
|
||||
import { ImageKnife } from '../ImageKnife';
|
||||
import { LogUtil } from '../utils/LogUtil';
|
||||
import { ImageKnifeRequestSource } from '../model/ImageKnifeData';
|
||||
import { emitter } from '@kit.BasicServicesKit';
|
||||
|
||||
@ComponentV2
|
||||
@Component
|
||||
export struct ImageKnifeAnimatorComponent {
|
||||
@Param animatorOption: AnimatorOption = new AnimatorOption();
|
||||
@Local pixelMap: PixelMap | string | undefined = undefined
|
||||
@Local imageAnimator: Array<ImageFrameInfo> | undefined = undefined
|
||||
@Local adaptiveWidth: Length = '100%'
|
||||
@Local adaptiveHeight: Length = '100%'
|
||||
@Local objectFit: ImageFit = ImageFit.Contain
|
||||
@Watch('watchImageKnifeOption') @ObjectLink imageKnifeOption: ImageKnifeOption;
|
||||
@State animatorOption: AnimatorOption = new AnimatorOption();
|
||||
@State pixelMap: PixelMap | string | undefined = undefined
|
||||
@State imageAnimator: Array<ImageFrameInfo> | undefined = undefined
|
||||
@State adaptiveWidth: Length = '100%'
|
||||
@State adaptiveHeight: Length | undefined = '100%'
|
||||
@State objectFit: ImageFit = ImageFit.Contain
|
||||
private componentId: number = 0
|
||||
private request: ImageKnifeRequest | undefined
|
||||
private lastWidth: number = 0
|
||||
private lastHeight: number = 0
|
||||
private isImageFitAutoResize: boolean = false
|
||||
private currentWidth: number = 0
|
||||
private currentHeight: number = 0
|
||||
private componentVersion: number = 0
|
||||
private currentContext: common.UIAbilityContext | undefined = undefined
|
||||
@Param imageKnifeOption: ImageKnifeOption = new ImageKnifeOption();
|
||||
@Monitor('imageKnifeOption',
|
||||
"imageKnifeOption.loadSrc","imageKnifeOption.signature","imageKnifeOption.transformation","imageKnifeOption.border","imageKnifeOption.objectFit")
|
||||
watchImageKnifeOption() {
|
||||
if (this.request !== undefined) {
|
||||
this.request.requestState = ImageKnifeRequestState.DESTROY
|
||||
}
|
||||
this.request = undefined
|
||||
this.componentVersion++
|
||||
ImageKnife.getInstance().execute(this.getRequest(this.currentWidth, this.currentHeight))
|
||||
}
|
||||
|
||||
aboutToAppear(): void {
|
||||
this.objectFit = this.imageKnifeOption.objectFit === undefined ? ImageFit.Contain : this.imageKnifeOption.objectFit
|
||||
this.componentId = this.getUniqueId()
|
||||
}
|
||||
|
||||
aboutToDisappear(): void {
|
||||
if (this.request !== undefined) {
|
||||
this.request.requestState = ImageKnifeRequestState.DESTROY
|
||||
this.request = undefined
|
||||
}
|
||||
this.emitterDestroy()
|
||||
this.clearLastRequest()
|
||||
}
|
||||
|
||||
aboutToRecycle() {
|
||||
this.emitterDestroy()
|
||||
this.clearLastRequest()
|
||||
}
|
||||
|
||||
emitterDestroy() {
|
||||
if (typeof this.request?.imageKnifeOption.loadSrc === 'string' && !this.request?.drawMainSuccess) {
|
||||
emitter.emit(this.request.imageKnifeOption.loadSrc + this.componentId)
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 对已DESTROY的组件不再发起请求
|
||||
*/
|
||||
private clearLastRequest(){
|
||||
if (this.request !== undefined) {
|
||||
this.request.requestState = ImageKnifeRequestState.DESTROY
|
||||
this.request = undefined
|
||||
}
|
||||
this.objectFit = this.imageKnifeOption.objectFit === undefined ? ImageFit.Contain : this.imageKnifeOption.objectFit
|
||||
}
|
||||
|
||||
build() {
|
||||
ImageAnimator()
|
||||
.images(this.imageAnimator)
|
||||
.width(this.adaptiveWidth)
|
||||
.height(this.adaptiveHeight)
|
||||
.border(this.imageKnifeOption.border)
|
||||
.clip(this.imageKnifeOption.border?.radius == undefined ? false : true)
|
||||
.state(this.animatorOption.state == undefined ? AnimationStatus.Running : this.animatorOption.state)
|
||||
.iterations(this.animatorOption.iterations == undefined ? -1 : this.animatorOption.iterations)
|
||||
.reverse(this.animatorOption.reverse == undefined ? false : this.animatorOption.reverse)
|
||||
|
@ -83,8 +88,18 @@ export struct ImageKnifeAnimatorComponent {
|
|||
} else {
|
||||
// 前提:宽高值均有效,值>0. 条件1:当前宽高与上一次宽高不同 条件2:当前是第一次绘制
|
||||
if (this.currentHeight != this.lastHeight || this.currentWidth != this.lastWidth) {
|
||||
LogUtil.log("execute request:width=" + this.currentWidth + " height= " + this.currentHeight)
|
||||
ImageKnife.getInstance().execute(this.getRequest(this.currentWidth, this.currentHeight),true)
|
||||
LogUtil.log('onSizeChange execute request:width=' + this.currentWidth + ' height= ' + this.currentHeight +
|
||||
' loadSrc = ' + this.imageKnifeOption.loadSrc +
|
||||
' placeholderSrc = ' + this.imageKnifeOption.placeholderSrc +
|
||||
' errorholderSrc = ' + this.imageKnifeOption.errorholderSrc +
|
||||
' componentId = ' + this.componentId)
|
||||
|
||||
if (this.imageKnifeOption.objectFit === ImageFit.Auto && this.isImageFitAutoResize) {
|
||||
this.isImageFitAutoResize = false
|
||||
} else {
|
||||
ImageKnife.getInstance().execute(this.getRequest(
|
||||
this.currentWidth, this.currentHeight, this.componentId))
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
@ -95,6 +110,20 @@ export struct ImageKnifeAnimatorComponent {
|
|||
.onRepeat(this.animatorOption.onRepeat)
|
||||
}
|
||||
|
||||
watchImageKnifeOption() {
|
||||
this.clearLastRequest()
|
||||
this.componentVersion++
|
||||
this.isImageFitAutoResize = false
|
||||
this.objectFit = this.imageKnifeOption.objectFit === undefined ? ImageFit.Contain : this.imageKnifeOption.objectFit
|
||||
LogUtil.log('watchImageKnifeOption execute request:width=' + this.currentWidth + ' height= ' + this.currentHeight +
|
||||
' loadSrc = ' + this.imageKnifeOption.loadSrc +
|
||||
' placeholderSrc = ' + this.imageKnifeOption.placeholderSrc +
|
||||
' errorholderSrc = ' + this.imageKnifeOption.errorholderSrc +
|
||||
' componentId = ' + this.componentId)
|
||||
ImageKnife.getInstance().execute(this.getRequest(
|
||||
this.currentWidth, this.currentHeight, this.componentId))
|
||||
}
|
||||
|
||||
getCurrentContext(): common.UIAbilityContext {
|
||||
if (this.currentContext == undefined) {
|
||||
this.currentContext = getContext(this) as common.UIAbilityContext
|
||||
|
@ -102,8 +131,7 @@ export struct ImageKnifeAnimatorComponent {
|
|||
return this.currentContext
|
||||
}
|
||||
|
||||
getRequest(width: number, height: number): ImageKnifeRequest {
|
||||
if (this.request == undefined) {
|
||||
getRequest(width: number, height: number,componentId: number): ImageKnifeRequest {
|
||||
this.request = new ImageKnifeRequest(
|
||||
this.imageKnifeOption,
|
||||
this.imageKnifeOption.context !== undefined ? this.imageKnifeOption.context : this.getCurrentContext(),
|
||||
|
@ -111,7 +139,8 @@ export struct ImageKnifeAnimatorComponent {
|
|||
height,
|
||||
this.componentVersion,
|
||||
{
|
||||
showPixelMap: async (version: number, pixelMap: PixelMap | string, requestSource: ImageKnifeRequestSource,imageAnimator?: Array<ImageFrameInfo>) => {
|
||||
showPixelMap: (version: number, pixelMap: PixelMap | string, size: Size, requestSource: ImageKnifeRequestSource,
|
||||
imageAnimator?: Array<ImageFrameInfo>) => {
|
||||
if (version !== this.componentVersion) {
|
||||
return //针对reuse场景,不显示历史图片
|
||||
}
|
||||
|
@ -125,20 +154,29 @@ export struct ImageKnifeAnimatorComponent {
|
|||
]
|
||||
}
|
||||
|
||||
if (this.imageKnifeOption.objectFit === ImageFit.Auto && this.isImageFitAutoResize == false &&
|
||||
requestSource == ImageKnifeRequestSource.SRC) {
|
||||
this.adaptiveHeight = undefined
|
||||
this.isImageFitAutoResize = true
|
||||
}
|
||||
|
||||
if (requestSource == ImageKnifeRequestSource.SRC) {
|
||||
this.objectFit =
|
||||
this.imageKnifeOption.objectFit === undefined ? ImageFit.Contain : this.imageKnifeOption.objectFit
|
||||
} else if (requestSource == ImageKnifeRequestSource.PLACE_HOLDER) {
|
||||
this.objectFit =
|
||||
this.imageKnifeOption.placeholderObjectFit === undefined ? (this.imageKnifeOption.objectFit === undefined ? ImageFit.Contain : this.imageKnifeOption.objectFit) : this.imageKnifeOption.placeholderObjectFit
|
||||
this.imageKnifeOption.placeholderObjectFit === undefined ?
|
||||
(this.imageKnifeOption.objectFit === undefined ? ImageFit.Contain : this.imageKnifeOption.objectFit) :
|
||||
this.imageKnifeOption.placeholderObjectFit
|
||||
} else {
|
||||
this.objectFit =
|
||||
this.imageKnifeOption.errorholderObjectFit === undefined ? (this.imageKnifeOption.objectFit === undefined ? ImageFit.Contain : this.imageKnifeOption.objectFit) : this.imageKnifeOption.errorholderObjectFit
|
||||
this.imageKnifeOption.errorholderObjectFit === undefined ?
|
||||
(this.imageKnifeOption.objectFit === undefined ? ImageFit.Contain : this.imageKnifeOption.objectFit) :
|
||||
this.imageKnifeOption.errorholderObjectFit
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
this.request.animator = true
|
||||
return this.request
|
||||
}
|
||||
}
|