Merge remote-tracking branch 'origin/master'
# Conflicts: # entry/src/main/ets/pages/pngjTestCasePage.ets # library/src/main/ets/components/imageknife/pngj/Pngj.ts
This commit is contained in:
commit
9a37765b1f
65
CHANGELOG.md
65
CHANGELOG.md
|
@ -1,5 +1,70 @@
|
||||||
|
## 2.2.0-rc.1
|
||||||
|
- 修改ImageKnife跳过网络,点击默认,图片没有传入宽高,无显示bug
|
||||||
|
- ImageKnife支持根据自定义key获取已缓存的图片
|
||||||
|
- ImageKnife加载图片支持自定义网络栈和图片加载组件
|
||||||
|
- 适配复用场景触发懒加载onDataReloaded
|
||||||
|
- ImageKnife控制重要图片请求加载优先级
|
||||||
|
|
||||||
|
## 2.2.0-rc.0
|
||||||
|
- 修复自定义DataFetch接口实现不生效问题
|
||||||
|
- 修改磁盘缓存到子线程
|
||||||
|
- 更新SDK到API12
|
||||||
|
- 适配Sendable内存共享优化
|
||||||
|
- 修改全局请求头覆盖request请求头
|
||||||
|
- imageKnife支持heic测试demo独立页面展示
|
||||||
|
- drawLifeCycle支持gif图
|
||||||
|
|
||||||
|
## 2.1.2
|
||||||
|
- 修改ImageKnife跳过网络,从内存中获取图片 cacheType参数未使用bug
|
||||||
|
- 新增WEBP图片解析能力。
|
||||||
|
- 新增gif图片支持暂停播放功能
|
||||||
|
|
||||||
|
## 2.1.2-rc.12
|
||||||
|
- 新增gif播放次数功能
|
||||||
|
- 新增磁盘预加载返回文件路径接口prefetchToDiskCache
|
||||||
|
- 新增跳过网络判断缓存或者磁盘中是否存在图片接口isUrlExist
|
||||||
|
- 删除多余操作磁盘记录读写
|
||||||
|
- 清除定时器改为Gif图时清除
|
||||||
|
- uuid改为util.generateRandomUUID()
|
||||||
|
|
||||||
|
## 2.1.2-rc.11
|
||||||
|
- 修复设置磁盘容量最大值出现闪退
|
||||||
|
- 修复概率出现jscrash问题
|
||||||
|
- 修复进度条问题
|
||||||
|
- 修复单帧gif图片加载失败
|
||||||
|
- removeRunning删除running队列log设置开关
|
||||||
|
- ImageKnife新增图片宽高自适应功能
|
||||||
|
- 修复onlyRetrieveFromCache属性(仅磁盘和内存获取资源)失效
|
||||||
|
- 修改拼写错误
|
||||||
|
- 新增多线程优先级
|
||||||
|
- 修复复用场景下图片闪动以及概率错位
|
||||||
|
- 获取组件宽高改为使用CanvasRenderingContext2D对象获取宽高,并修复改变字体大小导致部分图片消失
|
||||||
|
- 修复获取不到磁盘缓存文件问题
|
||||||
|
- 修复获取不到网络请求错误回调问题
|
||||||
|
|
||||||
|
## 2.1.2-rc.10
|
||||||
|
- 修复部分gif图片识别成静态图
|
||||||
|
- 修复同一张图片发送多次请求
|
||||||
|
- 复用场景缓存到树aboutToRecycle清理定时器
|
||||||
|
|
||||||
|
## 2.1.2-rc.9
|
||||||
|
- 使用taskpool实现多线程加载图片资源
|
||||||
|
- 修复部分gif图片识别成静态图
|
||||||
|
- 修复同一张图片发送多次请求
|
||||||
|
- disAppear生命周期清空定时器只在gif图片时执行
|
||||||
|
|
||||||
|
## 2.1.2-rc.8
|
||||||
|
- onAreaChange绘制图片改为component Util绘制
|
||||||
|
|
||||||
|
## 2.1.2-rc.7
|
||||||
|
- 修复图片圆角图形变换导致抗锯齿、ScaleType失效
|
||||||
|
- 修复使用模糊化出现图片变模糊和变形
|
||||||
|
|
||||||
## 2.1.2-rc.6
|
## 2.1.2-rc.6
|
||||||
- 修复手机调节显示大小时图片消失
|
- 修复手机调节显示大小时图片消失
|
||||||
|
- imageKnife防盗链,header请求头属性设置
|
||||||
|
- pngWorker线程改为taskpool
|
||||||
|
- 修复正方形裁剪有些图片裁剪创建pixelMap失败
|
||||||
|
|
||||||
## 2.1.2-rc.5
|
## 2.1.2-rc.5
|
||||||
- moduleContext新增缓存策略,缓存上限5,缓存策略Lru
|
- moduleContext新增缓存策略,缓存上限5,缓存策略Lru
|
||||||
|
|
18
OAT.xml
18
OAT.xml
|
@ -1,4 +1,21 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!-- Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
|
||||||
|
This is the configuration file template for OpenHarmony OSS Audit Tool, please copy it to your project root dir and modify it refer to OpenHarmony/tools_oat/README.
|
||||||
|
|
||||||
|
-->
|
||||||
<configuration>
|
<configuration>
|
||||||
<oatconfig>
|
<oatconfig>
|
||||||
<filefilterlist>
|
<filefilterlist>
|
||||||
|
@ -32,6 +49,7 @@
|
||||||
<filteritem type="filename" name="*.jpg" desc="jpg图片格式文件,用于展示示例"/>
|
<filteritem type="filename" name="*.jpg" desc="jpg图片格式文件,用于展示示例"/>
|
||||||
<filteritem type="filename" name="*.jpeg" desc="jpeg图片格式文件,用于展示示例"/>
|
<filteritem type="filename" name="*.jpeg" desc="jpeg图片格式文件,用于展示示例"/>
|
||||||
<filteritem type="filename" name="*.json5" desc="hvigor配置文件"/>
|
<filteritem type="filename" name="*.json5" desc="hvigor配置文件"/>
|
||||||
|
<filteritem type="filename" name="*.heic" desc="heic图片格式文件,用于展示示例"/>
|
||||||
</filefilter>
|
</filefilter>
|
||||||
<filefilter name="defaultFilter" desc="Files not to check">
|
<filefilter name="defaultFilter" desc="Files not to check">
|
||||||
<filteritem type="filepath" name="library/src/main/ets/components/3rd_party/.*" desc="第三方开源软件源码,不修改版权头,以防有修改版权风险"/>
|
<filteritem type="filepath" name="library/src/main/ets/components/3rd_party/.*" desc="第三方开源软件源码,不修改版权头,以防有修改版权风险"/>
|
||||||
|
|
|
@ -2,9 +2,9 @@
|
||||||
{
|
{
|
||||||
"Name": "glide",
|
"Name": "glide",
|
||||||
"License": "Apache License 2.0",
|
"License": "Apache License 2.0",
|
||||||
"License File": "https://github.com/bumptech/glide/blob/master/LICENSE",
|
"License File": "LICENSE",
|
||||||
"Version Number": "4.13.1",
|
"Version Number": "4.13.1",
|
||||||
"Owner" : "bumptech",
|
"Owner" : "xiafeng@huawei.com",
|
||||||
"Upstream URL": "https://github.com/bumptech/glide",
|
"Upstream URL": "https://github.com/bumptech/glide",
|
||||||
"Description": "An image loading and caching library focused on smooth scrolling"
|
"Description": "An image loading and caching library focused on smooth scrolling"
|
||||||
},
|
},
|
||||||
|
@ -12,9 +12,9 @@
|
||||||
{
|
{
|
||||||
"Name": "glide-transformations",
|
"Name": "glide-transformations",
|
||||||
"License": "Apache License 2.0",
|
"License": "Apache License 2.0",
|
||||||
"License File": "https://github.com/wasabeef/glide-transformations/blob/main/LICENSE",
|
"License File": "LICENSE",
|
||||||
"Version Number": "4.3.0",
|
"Version Number": "4.3.0",
|
||||||
"Owner" : "wasabeef",
|
"Owner" : "xiafeng@huawei.com",
|
||||||
"Upstream URL": "https://github.com/wasabeef/glide-transformations",
|
"Upstream URL": "https://github.com/wasabeef/glide-transformations",
|
||||||
"Description": " An transformation library providing a variety of image transformations for Glide. "
|
"Description": " An transformation library providing a variety of image transformations for Glide. "
|
||||||
},
|
},
|
||||||
|
@ -22,9 +22,9 @@
|
||||||
{
|
{
|
||||||
"Name": "fresco",
|
"Name": "fresco",
|
||||||
"License": "MIT License",
|
"License": "MIT License",
|
||||||
"License File": "https://github.com/facebook/fresco/blob/main/LICENSE",
|
"License File": "LICENSE",
|
||||||
"Version Number": "2.6.0",
|
"Version Number": "2.6.0",
|
||||||
"Owner" : "facebook",
|
"Owner" : "xiafeng@huawei.com",
|
||||||
"Upstream URL": "https://github.com/facebook/fresco",
|
"Upstream URL": "https://github.com/facebook/fresco",
|
||||||
"Description": " An library for managing images and the memory they use. "
|
"Description": " An library for managing images and the memory they use. "
|
||||||
},
|
},
|
||||||
|
@ -32,9 +32,9 @@
|
||||||
{
|
{
|
||||||
"Name": "UPNG.js",
|
"Name": "UPNG.js",
|
||||||
"License": "MIT License",
|
"License": "MIT License",
|
||||||
"License File": "https://github.com/photopea/UPNG.js/blob/master/LICENSE",
|
"License File": "LICENSE",
|
||||||
"Version Number": "1.0.0",
|
"Version Number": "1.0.0",
|
||||||
"Owner" : "photopea",
|
"Owner" : "xiafeng@huawei.com",
|
||||||
"Upstream URL": "https://github.com/photopea/UPNG.js",
|
"Upstream URL": "https://github.com/photopea/UPNG.js",
|
||||||
"Description": " Fast and advanced PNG (APNG) decoder and encoder (lossy / lossless) "
|
"Description": " Fast and advanced PNG (APNG) decoder and encoder (lossy / lossless) "
|
||||||
},
|
},
|
||||||
|
@ -42,9 +42,9 @@
|
||||||
{
|
{
|
||||||
"Name": "Luban",
|
"Name": "Luban",
|
||||||
"License": "Apache License 2.0",
|
"License": "Apache License 2.0",
|
||||||
"License File": "https://github.com/Curzibn/Luban/blob/master/LICENSE",
|
"License File": "LICENSE",
|
||||||
"Version Number": "1.1.8",
|
"Version Number": "1.1.8",
|
||||||
"Owner" : " Curzibn",
|
"Owner" : " xiafeng@huawei.com",
|
||||||
"Upstream URL": "https://github.com/Curzibn/Luban",
|
"Upstream URL": "https://github.com/Curzibn/Luban",
|
||||||
"Description": " Luban(鲁班)—Image compression with efficiency very close to WeChat Moments/可能是最接近微信朋友圈的图片压缩算法 "
|
"Description": " Luban(鲁班)—Image compression with efficiency very close to WeChat Moments/可能是最接近微信朋友圈的图片压缩算法 "
|
||||||
},
|
},
|
||||||
|
@ -54,16 +54,16 @@
|
||||||
"License": "Apache License 2.0",
|
"License": "Apache License 2.0",
|
||||||
"License File": "https://github.com/Yalantis/uCrop/blob/develop/README.md",
|
"License File": "https://github.com/Yalantis/uCrop/blob/develop/README.md",
|
||||||
"Version Number": "2.2.8",
|
"Version Number": "2.2.8",
|
||||||
"Owner" : " Yalantis",
|
"Owner" : " xiafeng@huawei.com",
|
||||||
"Upstream URL": "https://github.com/Yalantis/uCrop",
|
"Upstream URL": "https://github.com/Yalantis/uCrop",
|
||||||
"Description": " Image Cropping Library "
|
"Description": " Image Cropping Library "
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "js-spark-md5",
|
"Name": "js-spark-md5",
|
||||||
"License": "MIT",
|
"License": "MIT",
|
||||||
"License File": "https://github.com/satazor/js-spark-md5/blob/master/LICENSE",
|
"License File": "LICENSE",
|
||||||
"Version Number": "v3.0.2",
|
"Version Number": "v3.0.2",
|
||||||
"Owner" : "satazor",
|
"Owner" : "xiafeng@huawei.com",
|
||||||
"Upstream URL": "https://github.com/satazor/js-spark-md5",
|
"Upstream URL": "https://github.com/satazor/js-spark-md5",
|
||||||
"Description": "Lightning fast normal and incremental md5 for javascript"
|
"Description": "Lightning fast normal and incremental md5 for javascript"
|
||||||
}
|
}
|
||||||
|
|
155
README.md
155
README.md
|
@ -86,6 +86,10 @@ svg类型图片即可。
|
||||||
加载GIF其实和普通流程也没有区别只要将 `loadSrc: $r('app.media.jpgSample'),` `改成一张 loadSrc: $r('app.media.gifSample'),`
|
加载GIF其实和普通流程也没有区别只要将 `loadSrc: $r('app.media.jpgSample'),` `改成一张 loadSrc: $r('app.media.gifSample'),`
|
||||||
GIF图片即可。
|
GIF图片即可。
|
||||||
|
|
||||||
|
#### 4.1加载GIF图片
|
||||||
|
|
||||||
|
更改ImageKnifeOption对象的autoPlay(可选autoPlay = true为开始播放,autoPlay = false为暂停播放)
|
||||||
|
|
||||||
### 5.自定义Key
|
### 5.自定义Key
|
||||||
因为通常改变标识符比较困难或者根本不可能,所以ImageKnife也提供了 签名 API 来混合(你可以控制的)额外数据到你的缓存键中。
|
因为通常改变标识符比较困难或者根本不可能,所以ImageKnife也提供了 签名 API 来混合(你可以控制的)额外数据到你的缓存键中。
|
||||||
签名(signature)适用于媒体内容,也适用于你可以自行维护的一些版本元数据。
|
签名(signature)适用于媒体内容,也适用于你可以自行维护的一些版本元数据。
|
||||||
|
@ -101,39 +105,44 @@ imageKnifeOption = {
|
||||||
|
|
||||||
代码示例
|
代码示例
|
||||||
|
|
||||||
|
### 6.自定义请求头规格
|
||||||
|
设置全局header并且设置request的header时,当key不同时全局和request并行,当key相同时request的header覆盖全局的header
|
||||||
|
|
||||||
## 进阶使用
|
## 进阶使用
|
||||||
|
|
||||||
如果简单的加载一张图像无法满足需求,我们可以看看ImageKnifeOption这个类提供了哪些扩展能力。
|
如果简单的加载一张图像无法满足需求,我们可以看看ImageKnifeOption这个类提供了哪些扩展能力。
|
||||||
|
|
||||||
### ImageKnifeOption参数列表
|
### ImageKnifeOption参数列表
|
||||||
|
|
||||||
| 参数名称 | 入参内容 | 功能简介 |
|
| 参数名称 | 入参内容 | 功能简介 |
|
||||||
| ---------------------------- | ------------------------------------------------------------ |-----------------------------------------------|
|
|------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------|
|
||||||
| loadSrc | string\| PixelMap\ |Resource | 图片数据源 |
|
| loadSrc | string\ | PixelMap\ |Resource | 图片数据源 |
|
||||||
| mainScaleType | ScaleType | 设置主图展示样式(可选) |
|
| mainScaleType | ScaleType | 设置主图展示样式(可选) |
|
||||||
| strategy | DiskStrategy | 设置磁盘缓存策略(可选) |
|
| strategy | DiskStrategy | 设置磁盘缓存策略(可选) |
|
||||||
| dontAnimateFlag | boolean | gif加载展示一帧(可选) |
|
| dontAnimateFlag | boolean | gif加载展示一帧(可选) |
|
||||||
| placeholderSrc | PixelMap\| Resource | 占位图数据源 |
|
| placeholderSrc | string\ (占位图不支持gif图且不支持网络下载功能) | PixelMap\ |Resource | 占位图数据源 |
|
||||||
| placeholderScaleType | ScaleType | 设置占位图展示样式(可选) |
|
| placeholderScaleType | ScaleType | 设置占位图展示样式(可选) |
|
||||||
| errorholderSrc | PixelMap\| Resource | 错误占位图数据源 |
|
| errorholderSrc | PixelMap\ | Resource | 错误占位图数据源 |
|
||||||
| errorholderSrcScaleType | ScaleType | 设置失败占位图展示样式(可选) |
|
| errorholderSrcScaleType | ScaleType | 设置失败占位图展示样式(可选) |
|
||||||
| retryholderSrc | PixelMap\| Resource | 重试占位图数据源 |
|
| retryholderSrc | PixelMap\ | Resource | 重试占位图数据源 |
|
||||||
| retryholderScaleType | ScaleType | 设置重试占位图展示样式(可选) |
|
| retryholderScaleType | ScaleType | 设置重试占位图展示样式(可选) |
|
||||||
| thumbSizeMultiplier | number 范围(0,1] | 设置缩略图占比(可选) |
|
| fallbackSrc | PixelMap\ | Resource | 后备回调符数据源 |
|
||||||
| thumbSizeDelay | number | 设置缩略图展示时间(可选) |
|
| thumbSizeMultiplier | number 范围(0,1] | 设置缩略图占比(可选) |
|
||||||
| thumbSizeMultiplierScaleType | ScaleType | 设置缩略图展示样式(可选) |
|
| thumbSizeDelay | number | 设置缩略图展示时间(可选) |
|
||||||
| displayProgress | boolean | 设置是否展示下载进度条(可选) |
|
| thumbSizeMultiplierScaleType | ScaleType | 设置缩略图展示样式(可选) |
|
||||||
| canRetryClick | boolean | 设置重试图层是否点击重试(可选) |
|
| displayProgress | boolean | 设置是否展示下载进度条(可选) |
|
||||||
| onlyRetrieveFromCache | boolean | 仅使用缓存加载数据(可选) |
|
| canRetryClick | boolean | 设置重试图层是否点击重试(可选) |
|
||||||
| isCacheable | boolean | 是否开启一级内存缓存(可选) |
|
| onlyRetrieveFromCache | boolean | 仅使用缓存加载数据(可选) |
|
||||||
| gif | {<br/> // 返回一周期动画gif消耗的时间<br/> loopFinish?: (loopTime?) => void<br/> // gif播放速率相关<br/> speedFactory?: number<br/> // 直接展示gif第几帧数据<br/> seekTo?: number<br/> } | GIF播放控制能力(可选) |
|
| isCacheable | boolean | 是否开启一级内存缓存(可选) |
|
||||||
| transformation | BaseTransform<PixelMap> | 单个变换(可选) |
|
| gif | {<br/> // 返回一周期动画gif消耗的时间<br/> loopFinish?: (loopTime?) => void<br/> // gif播放速率相关<br/> speedFactory?: number<br/> // 直接展示gif第几帧数据<br/> seekTo?: number<br/> playTimes?: number<br/> } | GIF播放控制能力(可选) |
|
||||||
| transformations | Array<BaseTransform<PixelMap>> | 多个变换,目前仅支持单个变换(可选) |
|
| transformation | BaseTransform<PixelMap> | 单个变换(可选) |
|
||||||
| allCacheInfoCallback | IAllCacheInfoCallback | 输出缓存相关内容和信息(可选) |
|
| transformations | Array<BaseTransform<PixelMap>> | 多个变换,目前仅支持单个变换(可选) |
|
||||||
| signature | ObjectKey | 自定key(可选) |
|
| allCacheInfoCallback | IAllCacheInfoCallback | 输出缓存相关内容和信息(可选) |
|
||||||
| **drawLifeCycle** | **IDrawLifeCycle** | **用户自定义实现绘制方案(可选)** |
|
| signature | ObjectKey | 自定key(可选) |
|
||||||
| imageSmoothingEnabled | boolean | 抗锯齿是否开启属性配置,设置为false时,imageSmoothingQuality失效 |
|
| **drawLifeCycle** | **IDrawLifeCycle** | **用户自定义实现绘制方案(可选)** |
|
||||||
| imageSmoothingQuality | AntiAliasing | 抗锯齿属性配置 |
|
| imageSmoothingEnabled | boolean | 抗锯齿是否开启属性配置,设置为false时,imageSmoothingQuality失效 |
|
||||||
|
| imageSmoothingQuality | AntiAliasing | 抗锯齿属性配置 |
|
||||||
|
| autoPlay | boolean | GIF播放暂停控制(可选) |
|
||||||
|
|
||||||
其他参数只需要在ImageKnifeOption对象上按需添加即可。
|
其他参数只需要在ImageKnifeOption对象上按需添加即可。
|
||||||
|
|
||||||
|
@ -312,9 +321,10 @@ request.skipMemoryCache(true)
|
||||||
| load(src: string \| PixelMap \|Resource) | src:string\|PixelMap\|Resource | 用户加载图片源 |
|
| load(src: string \| PixelMap \|Resource) | src:string\|PixelMap\|Resource | 用户加载图片源 |
|
||||||
| setImageViewSize(imageSize: { width: number, height: number }) | imageSize:{width: number, height: number } | 传入显示图片组件的大小,变换的时候需要作为参考 |
|
| setImageViewSize(imageSize: { width: number, height: number }) | imageSize:{width: number, height: number } | 传入显示图片组件的大小,变换的时候需要作为参考 |
|
||||||
| diskCacheStrategy(strategy: DiskStrategy) | strategy:DiskStrategy | 配置磁盘缓存策略 NONE SOURCE RESULT ALL AUTOMATIC |
|
| diskCacheStrategy(strategy: DiskStrategy) | strategy:DiskStrategy | 配置磁盘缓存策略 NONE SOURCE RESULT ALL AUTOMATIC |
|
||||||
| placeholder(src: PixelMap\|Resource, func?: AsyncSuccess<ImageKnifeData>) | src: PixelMap\|Resource, func?: AsyncSuccess<ImageKnifeData> | 占位图,占位图回调数据ImageKnifeData |
|
| placeholder(src: string \| PixelMap\|Resource, func?: AsyncSuccess<ImageKnifeData>) | src: string\|PixelMap\|Resource, func?: AsyncSuccess<ImageKnifeData> | 占位图,占位图回调数据ImageKnifeData |
|
||||||
| errorholder(src: PixelMap\|Resource, func?: AsyncSuccess<ImageKnifeData>) | src: PixelMap\|Resource, func?: AsyncSuccess<ImageKnifeData> | 错误占位图,错误占位图回调数据ImageKnifeData |
|
| errorholder(src: PixelMap\|Resource, func?: AsyncSuccess<ImageKnifeData>) | src: PixelMap\|Resource, func?: AsyncSuccess<ImageKnifeData> | 错误占位图,错误占位图回调数据ImageKnifeData |
|
||||||
| retryholder(src: PixelMap\|Resource, func?: AsyncSuccess<ImageKnifeData>) | src: PixelMap\|Resource, func?: AsyncSuccess<ImageKnifeData> | 重试占位图,重试占位图回调数据ImageKnifeData |
|
| retryholder(src: PixelMap\|Resource, func?: AsyncSuccess<ImageKnifeData>) | src: PixelMap\|Resource, func?: AsyncSuccess<ImageKnifeData> | 重试占位图,重试占位图回调数据ImageKnifeData |
|
||||||
|
| fallback(src: PixelMap\|Resource, func?: AsyncSuccess<ImageKnifeData>) | src: PixelMap\|Resource, func?: AsyncSuccess<ImageKnifeData> | 重试占位图,重试占位图回调数据ImageKnifeData |
|
||||||
| addListener(func: AsyncCallback<ImageKnifeData>) | func: AsyncCallback<ImageKnifeData> | 配置整个监听回调,数据正常加载返回,加载失败返回错误信息 |
|
| addListener(func: AsyncCallback<ImageKnifeData>) | func: AsyncCallback<ImageKnifeData> | 配置整个监听回调,数据正常加载返回,加载失败返回错误信息 |
|
||||||
| thumbnail(sizeMultiplier:number, func?: AsyncSuccess<ImageKnifeData>) | sizeMultiplier:number, func?: AsyncSuccess<ImageKnifeData> | 设置缩略图比例,缩略图返回后,加载并展示缩略图 |
|
| thumbnail(sizeMultiplier:number, func?: AsyncSuccess<ImageKnifeData>) | sizeMultiplier:number, func?: AsyncSuccess<ImageKnifeData> | 设置缩略图比例,缩略图返回后,加载并展示缩略图 |
|
||||||
| addProgressListener(func?: AsyncSuccess<number>) | func?: AsyncSuccess<number> | 设置网络下载百分比监听,返回数据加载百分比数值 |
|
| addProgressListener(func?: AsyncSuccess<number>) | func?: AsyncSuccess<number> | 设置网络下载百分比监听,返回数据加载百分比数值 |
|
||||||
|
@ -327,12 +337,14 @@ request.skipMemoryCache(true)
|
||||||
|
|
||||||
### ImageKnife 启动器/门面类
|
### ImageKnife 启动器/门面类
|
||||||
|
|
||||||
| 方法名 | 入参 | 接口描述 |
|
| 方法名 | 入参 | 接口描述 |
|
||||||
| ------------------------------- | ---------------------- | ---------------------------------- |
|
|----------------------------------| ---------------------- | ------------------------------------------------------------ |
|
||||||
| call(request: RequestOption) | request: RequestOption | 根据用户配置参数具体执行加载流程 |
|
| call(request: RequestOption) | request: RequestOption | 根据用户配置参数具体执行加载流程 |
|
||||||
| preload(request: RequestOption) | request: RequestOption | 根据用户配置参数具体执行预加载流程 |
|
| preload(request: RequestOption) | request: RequestOption | 根据用户配置参数具体执行预加载流程 |
|
||||||
| pauseRequests() | | 全局暂停请求 |
|
| pauseRequests() | | 全局暂停请求 |
|
||||||
| resumeRequests() | | 全局恢复暂停 |
|
| resumeRequests() | | 全局恢复暂停 |
|
||||||
|
| isUrlExist(url, cacheType, size) | url, CacheType, Size | 判断图片是否在 缓存和磁盘中存在,如果入参是缓存,需要传入值图片大小,参数 CacheType, Size(可选) |
|
||||||
|
| setMaxRequests(count: number) | count | 设置请求的最大并发数量 |
|
||||||
|
|
||||||
### 缓存策略相关
|
### 缓存策略相关
|
||||||
|
|
||||||
|
@ -352,6 +364,14 @@ request.skipMemoryCache(true)
|
||||||
| AntiAliasing.FIT_MEDIUM | String | 图像抗锯齿设置为中画质 |
|
| AntiAliasing.FIT_MEDIUM | String | 图像抗锯齿设置为中画质 |
|
||||||
| AntiAliasing.FIT_LOW | String | 图像抗锯齿设置为低画质 |
|
| AntiAliasing.FIT_LOW | String | 图像抗锯齿设置为低画质 |
|
||||||
|
|
||||||
|
### CacheType类型展示效果
|
||||||
|
|
||||||
|
| 使用方法 | 类型 | 策略描述 |
|
||||||
|
|-------------------------|-----|-----------------------------------|
|
||||||
|
| CacheType.Default| int | 默认值,先从内存获取,无值则从磁盘获取 |
|
||||||
|
| CacheType.Cache| int | 缓存 |
|
||||||
|
| CacheType.Disk | int | 磁盘 |
|
||||||
|
|
||||||
### ScaleType类型展示效果
|
### ScaleType类型展示效果
|
||||||
|
|
||||||
| 使用方法 | 类型 | 策略描述 |
|
| 使用方法 | 类型 | 策略描述 |
|
||||||
|
@ -364,33 +384,36 @@ request.skipMemoryCache(true)
|
||||||
| ScaleType.FIT_XY | int | 图像拉伸至组件大小 |
|
| ScaleType.FIT_XY | int | 图像拉伸至组件大小 |
|
||||||
| ScaleType.CENTER_INSIDE | int | 如果图像大于组件则执行FIT_CENTER,小于组件则CENTER |
|
| ScaleType.CENTER_INSIDE | int | 如果图像大于组件则执行FIT_CENTER,小于组件则CENTER |
|
||||||
| ScaleType.NONE | int | 如果不想适配,直接展示原图大小 |
|
| ScaleType.NONE | int | 如果不想适配,直接展示原图大小 |
|
||||||
|
| ScaleType.AUTO_HEIGHT | int | 设置宽的时候,图片高度自适应 |
|
||||||
|
| ScaleType.AUTO_WIDTH | int | 设置高的时候,图片宽度自适应 |
|
||||||
|
| ScaleType.AUTO | int | 没有设置宽和高,图片按照自身宽高显示 |
|
||||||
|
|
||||||
### 图片变换相关
|
### 图片变换相关
|
||||||
|
|
||||||
| 使用方法 | 类型 | 相关描述 |
|
| 使用方法 | 类型 | 相关描述 |
|
||||||
|--------------------------------|------------------------------------|----------------------------------|
|
|--------------------------------|------------------------------------|--------------------------------|
|
||||||
| request.centerCrop() | CenterCrop | 可以根据图片文件,目标显示大小,进行对应centerCrop |
|
| request.centerCrop() | CenterCrop | 可以根据图片文件,目标显示大小,进行对应centerCrop |
|
||||||
| request.centerInside() | CenterInside | 可以根据图片文件,目标显示大小,进行对应centerInside |
|
| request.centerInside() | CenterInside | 可以根据图片文件,目标显示大小,进行对应centerInside |
|
||||||
| request.fitCenter() | FitCenter | 可以根据图片文件,目标显示大小,进行对应fitCenter |
|
| request.fitCenter() | FitCenter | 可以根据图片文件,目标显示大小,进行对应fitCenter |
|
||||||
| request.blur() | BlurTransformation | 模糊处理 |
|
| request.blur() | BlurTransformation | 模糊处理(图片分辨率较大建议传递第二个参数将图片进行缩小) |
|
||||||
| request.brightnessFilter() | BrightnessFilterTransformation | 亮度滤波器 |
|
| request.brightnessFilter() | BrightnessFilterTransformation | 亮度滤波器 |
|
||||||
| request.contrastFilter() | ContrastFilterTransformation | 对比度滤波器 |
|
| request.contrastFilter() | ContrastFilterTransformation | 对比度滤波器 |
|
||||||
| request.cropCircle() | CropCircleTransformation | 圆形剪裁显示 |
|
| request.cropCircle() | CropCircleTransformation | 圆形剪裁显示 |
|
||||||
| request.cropCircleWithBorder() | CropCircleWithBorderTransformation | 圆环展示 |
|
| request.cropCircleWithBorder() | CropCircleWithBorderTransformation | 圆环展示 |
|
||||||
| request.cropSquare() | CropSquareTransformation | 正方形剪裁 |
|
| request.cropSquare() | CropSquareTransformation | 正方形剪裁 |
|
||||||
| request.crop() | CropTransformation | 自定义矩形剪裁 |
|
| request.crop() | CropTransformation | 自定义矩形剪裁 |
|
||||||
| request.grayscale() | GrayscaleTransformation | 灰度级转换 |
|
| request.grayscale() | GrayscaleTransformation | 灰度级转换 |
|
||||||
| request.invertFilter() | InvertFilterTransformation | 反转滤波器 |
|
| request.invertFilter() | InvertFilterTransformation | 反转滤波器 |
|
||||||
| request.pixelationFilter() | PixelationFilterTransformation | 像素化滤波器 |
|
| request.pixelationFilter() | PixelationFilterTransformation | 像素化滤波器 |
|
||||||
| request.rotateImage() | RotateImageTransformation | 图片旋转 |
|
| request.rotateImage() | RotateImageTransformation | 图片旋转 |
|
||||||
| request.roundedCorners() | RoundedCornersTransformation | 圆角剪裁 |
|
| request.roundedCorners() | RoundedCornersTransformation | 圆角剪裁 |
|
||||||
| request.sepiaFilter() | SepiaFilterTransformation | 乌墨色滤波器 |
|
| request.sepiaFilter() | SepiaFilterTransformation | 乌墨色滤波器 |
|
||||||
| request.sketchFilter() | SketchFilterTransformation | 素描滤波器 |
|
| request.sketchFilter() | SketchFilterTransformation | 素描滤波器 |
|
||||||
| request.mask() | MaskTransformation | 遮罩 |
|
| request.mask() | MaskTransformation | 遮罩 |
|
||||||
| request.swirlFilter() | SwirlFilterTransformation | 扭曲滤波器 |
|
| request.swirlFilter() | SwirlFilterTransformation | 扭曲滤波器 |
|
||||||
| request.kuwaharaFilter() | KuwaharaFilterTransform | 桑原滤波器 |
|
| request.kuwaharaFilter() | KuwaharaFilterTransform | 桑原滤波器 |
|
||||||
| request.toonFilter() | ToonFilterTransform | 动画滤波器 |
|
| request.toonFilter() | ToonFilterTransform | 动画滤波器 |
|
||||||
| request.vignetteFilter() | VignetteFilterTransform | 装饰滤波器 |
|
| request.vignetteFilter() | VignetteFilterTransform | 装饰滤波器 |
|
||||||
|
|
||||||
<img src="screenshot/gif4.gif" width="50%"/>
|
<img src="screenshot/gif4.gif" width="50%"/>
|
||||||
|
|
||||||
|
@ -426,10 +449,18 @@ export default class EntryAbility extends UIAbility {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Queue
|
||||||
|
|
||||||
|
| 方法名 | 入参 | 接口描述 |
|
||||||
|
| ----------------------------------- | ----------------------- | ------------------------------ |
|
||||||
|
| getQueueLength(): number | | 获取队列总长度 |
|
||||||
|
| add(request: RequestOption) | request:RequestOption | 在队列尾部插入元素 |
|
||||||
|
| pop(): RequestOption | undefined | | 删除队列头元素并返回该删除元素 |
|
||||||
|
|
||||||
## 约束与限制
|
## 约束与限制
|
||||||
|
|
||||||
在下述版本验证通过:
|
在下述版本验证通过:
|
||||||
|
DevEco Studio 4.1(4.1.3.520)--SDK:API11( 4.1.0.63)
|
||||||
DevEco Studio 4.1(4.1.3.418)--SDK:API11( 4.1.0.56)
|
DevEco Studio 4.1(4.1.3.418)--SDK:API11( 4.1.0.56)
|
||||||
DevEco Studio 4.1(4.1.3.322)--SDK:API11( 4.1.0.36)
|
DevEco Studio 4.1(4.1.3.322)--SDK:API11( 4.1.0.36)
|
||||||
DevEco Studio 4.0(4.0.3.700)--SDK:API10( 4.0.10.15)
|
DevEco Studio 4.0(4.0.3.700)--SDK:API10( 4.0.10.15)
|
||||||
|
@ -442,6 +473,10 @@ HSP场景适配:
|
||||||
|
|
||||||
非HSP场景不影响原功能, ImageKnifeOption配置类新增的可选参数context可以不传, RquestOption配置类新增的接口可以不调用。
|
非HSP场景不影响原功能, ImageKnifeOption配置类新增的可选参数context可以不传, RquestOption配置类新增的接口可以不调用。
|
||||||
|
|
||||||
|
注意:
|
||||||
|
|
||||||
|
基于性能优化的原因,2.1.2-rc.13及以后版本引用了API12 Sendable接口,至此以后的版本只支持API12。
|
||||||
|
|
||||||
## 目录结构
|
## 目录结构
|
||||||
|
|
||||||
```
|
```
|
||||||
|
@ -502,6 +537,9 @@ HSP场景适配:
|
||||||
- storageTestDiskLruCache.ets # 磁盘缓存测试
|
- storageTestDiskLruCache.ets # 磁盘缓存测试
|
||||||
- storageTestLruCache.ets # 内存缓存测试
|
- storageTestLruCache.ets # 内存缓存测试
|
||||||
- testAllCacheInfoPage.ets # 所有缓存信息获取测试
|
- testAllCacheInfoPage.ets # 所有缓存信息获取测试
|
||||||
|
- testImageKnifeAutoHeightPage.ets # 图片高度自适应测试
|
||||||
|
- testImageKnifeAutoWidthPage.ets # 图片宽度自适应测试
|
||||||
|
- testImageKnifeAutoPage.ets # 图片宽高自适应测试
|
||||||
- testImageKnifeOptionChangedPage.ets # 数据切换测试
|
- testImageKnifeOptionChangedPage.ets # 数据切换测试
|
||||||
- testImageKnifeOptionChangedPage2.ets # 数据切换测试,部分变换
|
- testImageKnifeOptionChangedPage2.ets # 数据切换测试,部分变换
|
||||||
- testImageKnifeOptionChangedPage3.ets # 数据切换测试,组件动画
|
- testImageKnifeOptionChangedPage3.ets # 数据切换测试,组件动画
|
||||||
|
@ -510,9 +548,12 @@ HSP场景适配:
|
||||||
- testPreloadPage.ets # 预加载测试
|
- testPreloadPage.ets # 预加载测试
|
||||||
- transformPixelMapPage.ets # 所有类型变换测试
|
- transformPixelMapPage.ets # 所有类型变换测试
|
||||||
- testSingleFrameGifPage.ets # 单帧gif加载测试
|
- testSingleFrameGifPage.ets # 单帧gif加载测试
|
||||||
|
- TestStopPlayingGifPage # gif播放暂停测试
|
||||||
|
- TestImageKnifeNetPlaceholder # 缓存获取string类型占位图以及后备回调符测试
|
||||||
|
|
||||||
- OptionTestPage.ets # 图片缓存测试
|
- OptionTestPage.ets # 图片缓存测试
|
||||||
- testManyGifLoadWithPage # 测试gif加载页面
|
- testManyGifLoadWithPage # 测试gif加载页面
|
||||||
|
- testImageKnifeCache # 测试图片是否在缓存或者磁盘中
|
||||||
-workers
|
-workers
|
||||||
- upngWorkerTestCase.ets # png子线程解析
|
- upngWorkerTestCase.ets # png子线程解析
|
||||||
- upngWorkerDepend.ts # png子线程解析具体执行
|
- upngWorkerDepend.ts # png子线程解析具体执行
|
||||||
|
|
|
@ -4,8 +4,8 @@
|
||||||
{
|
{
|
||||||
"name": "default",
|
"name": "default",
|
||||||
"signingConfig": "default",
|
"signingConfig": "default",
|
||||||
"compileSdkVersion": 10,
|
"compileSdkVersion": 12,
|
||||||
"compatibleSdkVersion": 10
|
"compatibleSdkVersion": 12
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"buildModeSet": [
|
"buildModeSet": [
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
"name": "entry",
|
"name": "entry",
|
||||||
"description": "example description",
|
"description": "example description",
|
||||||
"repository": {},
|
"repository": {},
|
||||||
"version": "2.1.2-rc.6",
|
"version": "2.1.2-rc.12",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ohos/libraryimageknife": "file:../sharedlibrary",
|
"@ohos/libraryimageknife": "file:../sharedlibrary",
|
||||||
"@ohos/sharedlibrary2": "file:../sharedlibrary2",
|
"@ohos/sharedlibrary2": "file:../sharedlibrary2",
|
||||||
|
|
|
@ -49,6 +49,9 @@ export default class EntryAbility extends UIAbility {
|
||||||
imageKnife.setEngineKeyImpl(new CustomEngineKeyImpl())
|
imageKnife.setEngineKeyImpl(new CustomEngineKeyImpl())
|
||||||
// 设置全局内存缓存大小张数
|
// 设置全局内存缓存大小张数
|
||||||
imageKnife.setLruCacheSize(100, 100 * 1204 * 1024)
|
imageKnife.setLruCacheSize(100, 100 * 1204 * 1024)
|
||||||
|
// 全局配置请求头
|
||||||
|
imageKnife.addHeader('refer', "http://1.94.37.200:7070/AntiTheftChain/downloadImage");
|
||||||
|
imageKnife.deleteHeader('refer');
|
||||||
}
|
}
|
||||||
// 开启ImageKnife所有级别日志开关
|
// 开启ImageKnife所有级别日志开关
|
||||||
LogUtil.mLogLevel = LogUtil.ALL
|
LogUtil.mLogLevel = LogUtil.ALL
|
||||||
|
|
|
@ -19,7 +19,8 @@ import {
|
||||||
Size,
|
Size,
|
||||||
ImageKnife,
|
ImageKnife,
|
||||||
ImageKnifeGlobal,
|
ImageKnifeGlobal,
|
||||||
ImageKnifeComponent
|
ImageKnifeComponent,
|
||||||
|
ObjectKey
|
||||||
} from '@ohos/libraryimageknife'
|
} from '@ohos/libraryimageknife'
|
||||||
import { BusinessError } from '@ohos.base'
|
import { BusinessError } from '@ohos.base'
|
||||||
|
|
||||||
|
@ -34,6 +35,10 @@ struct RequestOptionLoadImage {
|
||||||
load(src: string | image.PixelMap | Resource) {
|
load(src: string | image.PixelMap | Resource) {
|
||||||
clearTimeout(timeId)
|
clearTimeout(timeId)
|
||||||
let request = new RequestOption()
|
let request = new RequestOption()
|
||||||
|
//*requestOption调用*
|
||||||
|
request.addHeader('refer', 'http://1.94.37.200:7070/AntiTheftChain/downloadImage');
|
||||||
|
//通过时间戳去清除缓存
|
||||||
|
request.signature = new ObjectKey(new Date().getTime().toString())
|
||||||
request.load(src)
|
request.load(src)
|
||||||
.addListener({ callback: (err: BusinessError | string, data: ImageKnifeData) => {
|
.addListener({ callback: (err: BusinessError | string, data: ImageKnifeData) => {
|
||||||
if (data.isPixelMap()) {
|
if (data.isPixelMap()) {
|
||||||
|
|
|
@ -69,10 +69,14 @@ struct basicTestFileIOPage {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
console.log('files目录创建Folder1和Folder2 验证statSync mkdirSync')
|
console.log('files目录创建Folder1和Folder2 验证statSync mkdirSync')
|
||||||
FileUtils.getInstance()
|
try {
|
||||||
.createFolder(this.appFilePath + '/Folder1');
|
FileUtils.getInstance()
|
||||||
FileUtils.getInstance()
|
.createFolder(this.appFilePath + '/Folder1');
|
||||||
.createFolder(this.appFilePath + '/Folder2');
|
FileUtils.getInstance()
|
||||||
|
.createFolder(this.appFilePath + '/Folder2');
|
||||||
|
} catch (e) {
|
||||||
|
console.log('appFilePath未取到值,请按顺序从上往下,从左往右依次测试"'+JSON.stringify(e));
|
||||||
|
}
|
||||||
})
|
})
|
||||||
Button('将media资源存入Folder1 验证writeSync mkdirSync createStreamSync')
|
Button('将media资源存入Folder1 验证writeSync mkdirSync createStreamSync')
|
||||||
.margin({ top: 10 })
|
.margin({ top: 10 })
|
||||||
|
@ -105,13 +109,18 @@ struct basicTestFileIOPage {
|
||||||
this.imageHint2 = 'appFilePath未取到值,请按顺序从上往下,从左往右依次测试'
|
this.imageHint2 = 'appFilePath未取到值,请按顺序从上往下,从左往右依次测试'
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
let filePath1 = this.appFilePath + '/Folder1/jpgSample.gif';
|
try {
|
||||||
let filePath2 = this.appFilePath + '/Folder2/jpgSample.gif';
|
let filePath1 = this.appFilePath + '/Folder1/jpgSample.gif';
|
||||||
FileUtils.getInstance().createFolder(this.appFilePath + '/Folder1')
|
let filePath2 = this.appFilePath + '/Folder2/jpgSample.gif';
|
||||||
FileUtils.getInstance().createFolder(this.appFilePath + '/Folder2')
|
FileUtils.getInstance().createFolder(this.appFilePath + '/Folder1')
|
||||||
FileUtils.getInstance().copyFile(filePath1, filePath2);
|
FileUtils.getInstance().createFolder(this.appFilePath + '/Folder2')
|
||||||
this.imageFile = 'file://' + this.appFilePath + '/Folder2/jpgSample.gif'
|
FileUtils.getInstance().copyFile(filePath1, filePath2);
|
||||||
console.log('Folder2 imaeFile =' + this.imageFile)
|
this.imageFile = 'file://' + this.appFilePath + '/Folder2/jpgSample.gif'
|
||||||
|
console.log('Folder2 imaeFile =' + this.imageFile)
|
||||||
|
} catch (e) {
|
||||||
|
console.log('appFilePath未取到值,请按顺序从上往下,从左往右依次测试:'+JSON.stringify(e))
|
||||||
|
}
|
||||||
|
|
||||||
})
|
})
|
||||||
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
||||||
Button('显示空PixelMap')
|
Button('显示空PixelMap')
|
||||||
|
|
|
@ -15,7 +15,6 @@
|
||||||
import router from '@ohos.router';
|
import router from '@ohos.router';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Entry
|
@Entry
|
||||||
@Component
|
@Component
|
||||||
struct IndexFunctionDemo {
|
struct IndexFunctionDemo {
|
||||||
|
@ -36,8 +35,13 @@ struct IndexFunctionDemo {
|
||||||
console.log("测试文件子系统")
|
console.log("测试文件子系统")
|
||||||
router.pushUrl({ url: "pages/basicTestFileIOPage" });
|
router.pushUrl({ url: "pages/basicTestFileIOPage" });
|
||||||
}).margin({ top: 5, left: 3 })
|
}).margin({ top: 5, left: 3 })
|
||||||
|
Button("优先级加载")
|
||||||
|
.onClick(() => {
|
||||||
|
console.log("优先级加载")
|
||||||
|
router.pushUrl({ url: "pages/testPriorityComponent" });
|
||||||
|
}).margin({ top: 5, left: 3 })
|
||||||
}.width('100%').height(60).backgroundColor(Color.Pink)
|
}.width('100%').height(60).backgroundColor(Color.Pink)
|
||||||
|
|
||||||
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
||||||
Button("测试全球化")
|
Button("测试全球化")
|
||||||
.onClick(() => {
|
.onClick(() => {
|
||||||
|
@ -53,8 +57,6 @@ struct IndexFunctionDemo {
|
||||||
}.width('100%').height(60).backgroundColor(Color.Pink)
|
}.width('100%').height(60).backgroundColor(Color.Pink)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Text("测试图片切换功能点").fontSize(15)
|
Text("测试图片切换功能点").fontSize(15)
|
||||||
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
||||||
|
|
||||||
|
@ -63,8 +65,32 @@ struct IndexFunctionDemo {
|
||||||
console.log("测试ImageKnifeComponent所有图片切换")
|
console.log("测试ImageKnifeComponent所有图片切换")
|
||||||
router.pushUrl({ url: "pages/testImageKnifeOptionChangedPage" });
|
router.pushUrl({ url: "pages/testImageKnifeOptionChangedPage" });
|
||||||
}).margin({ top: 5, left: 3 })
|
}).margin({ top: 5, left: 3 })
|
||||||
|
Button("测试图片高度自适应")
|
||||||
|
.onClick(() => {
|
||||||
|
console.log("测试ImageKnifeComponent图片高度自适应")
|
||||||
|
router.pushUrl({ url: "pages/testImageKnifeAutoHeightPage" });
|
||||||
|
}).margin({ top: 5, left: 3 })
|
||||||
|
Button("测试gif播放次数")
|
||||||
|
.onClick(() => {
|
||||||
|
router.pushUrl({ url: "pages/testGifPlayTimesPage" });
|
||||||
|
}).margin({ top: 15 })
|
||||||
|
}.width('100%').height(60).backgroundColor(Color.Pink)
|
||||||
|
|
||||||
|
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
||||||
|
|
||||||
|
Button("测试图片宽度自适应")
|
||||||
|
.onClick(() => {
|
||||||
|
console.log("测试ImageKnifeComponent图片宽度自适应")
|
||||||
|
router.pushUrl({ url: "pages/testImageKnifeAutoWidthPage" });
|
||||||
|
}).margin({ top: 5, left: 3 })
|
||||||
|
Button("测试图片宽高自适应")
|
||||||
|
.onClick(() => {
|
||||||
|
console.log("测试ImageKnifeComponent图片宽高自适应")
|
||||||
|
router.pushUrl({ url: "pages/testImageKnifeAutoPage" });
|
||||||
|
}).margin({ top: 5, left: 3 })
|
||||||
|
|
||||||
}.width('100%').height(60).backgroundColor(Color.Pink)
|
}.width('100%').height(60).backgroundColor(Color.Pink)
|
||||||
|
|
||||||
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
||||||
Button("测试thumbnail")
|
Button("测试thumbnail")
|
||||||
.onClick(() => {
|
.onClick(() => {
|
||||||
|
@ -94,7 +120,20 @@ struct IndexFunctionDemo {
|
||||||
|
|
||||||
}.width('100%')
|
}.width('100%')
|
||||||
.height(60).backgroundColor(Color.Pink)
|
.height(60).backgroundColor(Color.Pink)
|
||||||
|
Text("测试复用场景").fontSize(15)
|
||||||
|
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
||||||
|
Button("懒加载复用列表")
|
||||||
|
.onClick(() => {
|
||||||
|
console.log("测试一级内存缓存")
|
||||||
|
router.pushUrl({ url: "pages/testReusePhotoPage" });
|
||||||
|
}).margin({ top: 5, left: 3 })
|
||||||
|
Button("适配复用场景")
|
||||||
|
.onClick(() => {
|
||||||
|
console.log("测试一级内存缓存")
|
||||||
|
router.pushUrl({ url: "pages/testReuseAblePages" });
|
||||||
|
}).margin({ top: 5, left: 3 })
|
||||||
|
}.width('100%')
|
||||||
|
.height(60).backgroundColor(Color.Pink)
|
||||||
Text("测试占位图 失败占位图 功能点").fontSize(15)
|
Text("测试占位图 失败占位图 功能点").fontSize(15)
|
||||||
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
||||||
Button("测试失败占位图")
|
Button("测试失败占位图")
|
||||||
|
@ -111,6 +150,11 @@ struct IndexFunctionDemo {
|
||||||
console.log("测试预加载")
|
console.log("测试预加载")
|
||||||
router.pushUrl({ url: "pages/testPreloadPage" });
|
router.pushUrl({ url: "pages/testPreloadPage" });
|
||||||
}).margin({ top: 5, left: 3 })
|
}).margin({ top: 5, left: 3 })
|
||||||
|
Button("测试磁盘预加载返回string")
|
||||||
|
.onClick(() => {
|
||||||
|
console.log("测试预加载测试磁盘预加载返回string")
|
||||||
|
router.pushUrl({ url: "pages/testDiskPreLoadPage" });
|
||||||
|
}).margin({ top: 5, left: 3 })
|
||||||
|
|
||||||
}.width('100%').height(60).backgroundColor(Color.Pink)
|
}.width('100%').height(60).backgroundColor(Color.Pink)
|
||||||
|
|
||||||
|
@ -190,6 +234,7 @@ struct IndexFunctionDemo {
|
||||||
|
|
||||||
}).margin({ top: 15 })
|
}).margin({ top: 15 })
|
||||||
}.width('100%').height(60).backgroundColor(Color.Pink)
|
}.width('100%').height(60).backgroundColor(Color.Pink)
|
||||||
|
|
||||||
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
||||||
|
|
||||||
Button("组件显式动画")
|
Button("组件显式动画")
|
||||||
|
@ -211,7 +256,6 @@ struct IndexFunctionDemo {
|
||||||
}).margin({ top: 15 })
|
}).margin({ top: 15 })
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}.width('100%').height(60).backgroundColor(Color.Pink)
|
}.width('100%').height(60).backgroundColor(Color.Pink)
|
||||||
|
|
||||||
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
||||||
|
@ -253,6 +297,10 @@ struct IndexFunctionDemo {
|
||||||
.onClick(() => {
|
.onClick(() => {
|
||||||
router.pushUrl({ url: "pages/testSingleFrameGifPage" });
|
router.pushUrl({ url: "pages/testSingleFrameGifPage" });
|
||||||
}).margin({ top: 5, left: 3 })
|
}).margin({ top: 5, left: 3 })
|
||||||
|
Button("webp测试")
|
||||||
|
.onClick(() => {
|
||||||
|
router.pushUrl({ url: "pages/webpImageTestPage" });
|
||||||
|
}).margin({ top: 5, left: 3 })
|
||||||
}.width('100%').height(60).backgroundColor(Color.Pink)
|
}.width('100%').height(60).backgroundColor(Color.Pink)
|
||||||
|
|
||||||
Text("worker测试").fontSize(15)
|
Text("worker测试").fontSize(15)
|
||||||
|
@ -262,13 +310,14 @@ struct IndexFunctionDemo {
|
||||||
|
|
||||||
}).margin({ top: 5, left: 3 })
|
}).margin({ top: 5, left: 3 })
|
||||||
}.width('100%').height(60).backgroundColor(Color.Pink)
|
}.width('100%').height(60).backgroundColor(Color.Pink)
|
||||||
|
|
||||||
Text("HSP相关测试").fontSize(15)
|
Text("HSP相关测试").fontSize(15)
|
||||||
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
||||||
|
|
||||||
Button("进入HSP的library共享包")
|
Button("进入HSP的library共享包")
|
||||||
.onClick(() => {
|
.onClick(() => {
|
||||||
router.pushUrl({url:'@bundle:com.openharmony.imageknife/sharedlibrary/ets/pages/Index'})
|
router.pushUrl({ url: '@bundle:com.openharmony.imageknife/sharedlibrary/ets/pages/Index' })
|
||||||
.then(()=>{
|
.then(() => {
|
||||||
console.log('push page suceess')
|
console.log('push page suceess')
|
||||||
})
|
})
|
||||||
}).margin({ top: 15 })
|
}).margin({ top: 15 })
|
||||||
|
@ -278,23 +327,29 @@ struct IndexFunctionDemo {
|
||||||
router.pushUrl({ url: "pages/hspCacheTestPage" });
|
router.pushUrl({ url: "pages/hspCacheTestPage" });
|
||||||
}).margin({ top: 15 })
|
}).margin({ top: 15 })
|
||||||
Button("不同的hsp资源加载")
|
Button("不同的hsp资源加载")
|
||||||
.onClick(()=>{
|
.onClick(() => {
|
||||||
console.log("pages/multiHspTestPage 页面跳转")
|
console.log("pages/multiHspTestPage 页面跳转")
|
||||||
router.pushUrl({ url: "pages/multiHspTestPage" });
|
router.pushUrl({ url: "pages/multiHspTestPage" });
|
||||||
})
|
})
|
||||||
|
|
||||||
}.width('100%').height(60).backgroundColor(Color.Pink)
|
}.width('100%').height(60).backgroundColor(Color.Pink)
|
||||||
|
|
||||||
Text("测试图片加载稳定").fontSize(15)
|
Text("测试图片加载稳定").fontSize(15)
|
||||||
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
||||||
Button("测试多张网络图片加载速度")
|
Button("测试多张网络图片加载速度")
|
||||||
.onClick(() => {
|
.onClick(() => {
|
||||||
router.pushUrl({ url: "pages/testManyNetImageLoadWithPage" });
|
router.pushUrl({ url: "pages/testManyNetImageLoadWithPage" });
|
||||||
}).margin({ top: 5, left: 3 })
|
}).margin({ top: 5, left: 3 })
|
||||||
|
Button("多线程加载大量网络图片加载速度")
|
||||||
|
.onClick(() => {
|
||||||
|
router.pushUrl({ url: "pages/testManyNetImageLoadWithPage2" });
|
||||||
|
}).margin({ top: 5, left: 3 })
|
||||||
Button("测试多张gif加载位置")
|
Button("测试多张gif加载位置")
|
||||||
.onClick(() => {
|
.onClick(() => {
|
||||||
router.pushUrl({ url: "pages/testManyGifLoadWithPage" });
|
router.pushUrl({ url: "pages/testManyGifLoadWithPage" });
|
||||||
}).margin({ top: 5, left: 3 })
|
}).margin({ top: 5, left: 3 })
|
||||||
}.width('100%').height(60).backgroundColor(Color.Pink)
|
}.width('100%').height(60).backgroundColor(Color.Pink)
|
||||||
|
|
||||||
Text('测试图片抗锯齿').fontSize(15)
|
Text('测试图片抗锯齿').fontSize(15)
|
||||||
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
||||||
Button('测试图片抗锯齿')
|
Button('测试图片抗锯齿')
|
||||||
|
@ -306,6 +361,62 @@ struct IndexFunctionDemo {
|
||||||
router.pushUrl({ url: 'pages/testImageKnifeRouter1' });
|
router.pushUrl({ url: 'pages/testImageKnifeRouter1' });
|
||||||
}).margin({ top: 5, left: 3 })
|
}).margin({ top: 5, left: 3 })
|
||||||
}.width('100%').height(60).backgroundColor(Color.Pink)
|
}.width('100%').height(60).backgroundColor(Color.Pink)
|
||||||
|
|
||||||
|
Text('测试图片header属性').fontSize(15)
|
||||||
|
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
||||||
|
Button('图片header属性设置')
|
||||||
|
.onClick(() => {
|
||||||
|
router.pushUrl({ url: 'pages/testImageKnifeHttpRequestHeader' });
|
||||||
|
}).margin({ top: 5, left: 3 })
|
||||||
|
Button('测试自定义DataFetch属性')
|
||||||
|
.onClick(() => {
|
||||||
|
router.pushUrl({ url: 'pages/testImageKnifeDataFetch' });
|
||||||
|
}).margin({ top: 5, left: 3 })
|
||||||
|
Button('全局header和request的header')
|
||||||
|
.onClick(() => {
|
||||||
|
router.pushUrl({ url: 'pages/testImageKnifeHttpRequestHeader1' });
|
||||||
|
}).margin({ top: 5, left: 3 })
|
||||||
|
}.width('100%').height(60).backgroundColor(Color.Pink)
|
||||||
|
|
||||||
|
Text('测试图片缓存内存').fontSize(15)
|
||||||
|
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
||||||
|
Button('测试图片缓存内存')
|
||||||
|
.onClick(() => {
|
||||||
|
router.pushUrl({ url: 'pages/testImageKnifeCache' });
|
||||||
|
}).margin({ top: 5, left: 3 })
|
||||||
|
}.width('100%').height(60).backgroundColor(Color.Pink)
|
||||||
|
|
||||||
|
Text('测试gif暂停播放属性').fontSize(15)
|
||||||
|
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
||||||
|
Button('测试gif暂停播放属性')
|
||||||
|
.onClick(() => {
|
||||||
|
router.pushUrl({ url: 'pages/testStopPlayingGifPage' });
|
||||||
|
}).margin({ top: 5, left: 3 })
|
||||||
|
}.width('100%').height(60).backgroundColor(Color.Pink)
|
||||||
|
|
||||||
|
Text('测试heic图片加载').fontSize(15)
|
||||||
|
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
||||||
|
Button('测试heic')
|
||||||
|
.onClick(() => {
|
||||||
|
router.pushUrl({ url: 'pages/testImageKnifeHeic' });
|
||||||
|
}).margin({ top: 5, left: 3 })
|
||||||
|
}.width('100%').height(60).backgroundColor(Color.Pink)
|
||||||
|
|
||||||
|
Text('测试string类型占位图').fontSize(15)
|
||||||
|
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
||||||
|
Button('测试string类型占位图以及后备回调符')
|
||||||
|
.onClick(() => {
|
||||||
|
router.pushUrl({ url: 'pages/testImageKnifeNetPlaceholder' });
|
||||||
|
}).margin({ top: 5, left: 3 })
|
||||||
|
}.width('100%').height(60).backgroundColor(Color.Pink)
|
||||||
|
|
||||||
|
Text('测试加载图片自定义网络栈').fontSize(15)
|
||||||
|
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
||||||
|
Button('加载图片自定义网络栈')
|
||||||
|
.onClick(() => {
|
||||||
|
router.pushUrl({ url: 'pages/testCustomDataFetchClientWithPage' });
|
||||||
|
}).margin({ top: 5, left: 3 })
|
||||||
|
}.width('100%').height(60).backgroundColor(Color.Pink)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.width('100%')
|
.width('100%')
|
||||||
|
|
|
@ -17,7 +17,8 @@ import {
|
||||||
ImageKnifeComponent,
|
ImageKnifeComponent,
|
||||||
ImageKnifeOption,
|
ImageKnifeOption,
|
||||||
ImageKnifeGlobal,
|
ImageKnifeGlobal,
|
||||||
ImageKnife
|
ImageKnife,
|
||||||
|
HeaderOptions
|
||||||
} from '@ohos/libraryimageknife'
|
} from '@ohos/libraryimageknife'
|
||||||
|
|
||||||
import { ObjectKey } from '@ohos/libraryimageknife';
|
import { ObjectKey } from '@ohos/libraryimageknife';
|
||||||
|
@ -25,23 +26,24 @@ import { ObjectKey } from '@ohos/libraryimageknife';
|
||||||
@Entry
|
@Entry
|
||||||
@Component
|
@Component
|
||||||
struct IndexFunctionDemo {
|
struct IndexFunctionDemo {
|
||||||
|
@State headerOptions1: HeaderOptions = {
|
||||||
|
key: "refer",
|
||||||
|
value: "http://1.94.37.200:7070/AntiTheftChain/downloadImage"
|
||||||
|
};
|
||||||
@State imageKnifeOption1: ImageKnifeOption =
|
@State imageKnifeOption1: ImageKnifeOption =
|
||||||
{
|
{
|
||||||
loadSrc: $r('app.media.icon'),
|
loadSrc: $r('app.media.icon'),
|
||||||
|
|
||||||
placeholderSrc: $r('app.media.icon_loading'),
|
placeholderSrc: $r('app.media.icon_loading'),
|
||||||
errorholderSrc: $r('app.media.icon_failed')
|
errorholderSrc: $r('app.media.icon_failed'),
|
||||||
|
headerOption: [this.headerOptions1]
|
||||||
};
|
};
|
||||||
|
|
||||||
@State imageKnifeOption2: ImageKnifeOption =
|
@State imageKnifeOption2: ImageKnifeOption =
|
||||||
{
|
{
|
||||||
loadSrc: $r('app.media.icon'),
|
loadSrc: $r('app.media.icon'),
|
||||||
|
|
||||||
placeholderSrc: $r('app.media.icon_loading'),
|
placeholderSrc: $r('app.media.icon_loading'),
|
||||||
errorholderSrc: $r('app.media.icon_failed')
|
errorholderSrc: $r('app.media.icon_failed'),
|
||||||
|
headerOption: [this.headerOptions1]
|
||||||
};
|
};
|
||||||
|
|
||||||
build() {
|
build() {
|
||||||
Scroll() {
|
Scroll() {
|
||||||
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
||||||
|
@ -51,7 +53,6 @@ struct IndexFunctionDemo {
|
||||||
.onClick(() => {
|
.onClick(() => {
|
||||||
this.imageKnifeOption1 = {
|
this.imageKnifeOption1 = {
|
||||||
loadSrc: $r('app.media.pngSample'),
|
loadSrc: $r('app.media.pngSample'),
|
||||||
|
|
||||||
placeholderSrc: $r('app.media.icon_loading'),
|
placeholderSrc: $r('app.media.icon_loading'),
|
||||||
errorholderSrc: $r('app.media.icon_failed'),
|
errorholderSrc: $r('app.media.icon_failed'),
|
||||||
signature: new ObjectKey('ccccccc')
|
signature: new ObjectKey('ccccccc')
|
||||||
|
|
|
@ -18,9 +18,8 @@ import {ImageKnifeGlobal} from '@ohos/libraryimageknife'
|
||||||
import {RotateImageTransformation} from '@ohos/libraryimageknife'
|
import {RotateImageTransformation} from '@ohos/libraryimageknife'
|
||||||
import {Material} from './model/Material'
|
import {Material} from './model/Material'
|
||||||
import {TestDataSource} from './model/TestDataSource'
|
import {TestDataSource} from './model/TestDataSource'
|
||||||
import {DiskLruCache} from '@ohos/disklrucache'
|
|
||||||
import ArkWorker from '@ohos.worker'
|
|
||||||
import Prompt from '@system.prompt'
|
|
||||||
@Entry
|
@Entry
|
||||||
@Component
|
@Component
|
||||||
struct photosPausedResumedPage {
|
struct photosPausedResumedPage {
|
||||||
|
|
|
@ -12,15 +12,15 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
import router from '@system.router';
|
|
||||||
import { Pngj } from '@ohos/libraryimageknife'
|
import { Pngj } from '@ohos/libraryimageknife'
|
||||||
import resourceManager from '@ohos.resourceManager';
|
import resourceManager from '@ohos.resourceManager';
|
||||||
import { FileUtils,ImageKnifeGlobal } from '@ohos/libraryimageknife'
|
import { FileUtils,ImageKnifeGlobal } from '@ohos/libraryimageknife'
|
||||||
import featureability from '@ohos.ability.featureAbility'
|
|
||||||
import ArkWorker from '@ohos.worker'
|
|
||||||
import worker from '@ohos.worker';
|
|
||||||
import { BusinessError } from '@ohos.base'
|
import { BusinessError } from '@ohos.base'
|
||||||
import common from '@ohos.app.ability.common';
|
import common from '@ohos.app.ability.common';
|
||||||
|
interface WorkerType {
|
||||||
|
type: string
|
||||||
|
name: string
|
||||||
|
}
|
||||||
@Entry
|
@Entry
|
||||||
@Component
|
@Component
|
||||||
struct PngjTestCasePage {
|
struct PngjTestCasePage {
|
||||||
|
@ -115,18 +115,17 @@ struct PngjTestCasePage {
|
||||||
if (!this.pngdecodeRun2) {
|
if (!this.pngdecodeRun2) {
|
||||||
this.pngdecodeRun2 = true;
|
this.pngdecodeRun2 = true;
|
||||||
let pngj = new Pngj();
|
let pngj = new Pngj();
|
||||||
// let png_worker = new worker.ThreadWorker('entry/ets/workers/upngWorkerTestCase.ets', )
|
let png_worker: WorkerType = {
|
||||||
let obj ={
|
type: 'classic',
|
||||||
type: 'classic',
|
name: 'readPngImageAsync'
|
||||||
name: 'readPngImageAsync'
|
}
|
||||||
}
|
pngj.readPngImageAsync(png_worker, this.pngSource2!, (value:ESObject) => {
|
||||||
pngj.readPngImageAsync(obj, this.pngSource2!, {pngCallback: (sender:ArrayBuffer, value:Record<string,Object>) => {
|
|
||||||
this.pngSource2 = sender
|
|
||||||
this.hint8 = '重新获取buffer才能测试'
|
this.hint8 = '重新获取buffer才能测试'
|
||||||
this.hint2 = 'img with=' + value.width + ' img height=' + value.height
|
this.hint2 = 'img with=' + value.width + ' img height=' + value.height
|
||||||
+ ' img depth=' + value.depth + ' img ctype=' + value.ctype
|
+ ' img depth=' + value.depth + ' img ctype=' + value.ctype
|
||||||
this.pngdecodeRun2 = false;
|
this.pngdecodeRun2 = false;
|
||||||
}})
|
})
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
this.hint8 = '已经在执行了,请稍等'
|
this.hint8 = '已经在执行了,请稍等'
|
||||||
}
|
}
|
||||||
|
@ -161,12 +160,11 @@ struct PngjTestCasePage {
|
||||||
if (!this.pngdecodeRun3) {
|
if (!this.pngdecodeRun3) {
|
||||||
this.pngdecodeRun3 = true;
|
this.pngdecodeRun3 = true;
|
||||||
let pngj = new Pngj();
|
let pngj = new Pngj();
|
||||||
let png_worker = new worker.ThreadWorker('entry/ets/workers/upngWorkerTestCase.ets', {
|
let png_worker: WorkerType = {
|
||||||
type: 'classic',
|
type: 'classic',
|
||||||
name: 'writePngWithStringAsync'
|
name: 'writePngWithStringAsync'
|
||||||
})
|
}
|
||||||
pngj.writePngWithStringAsync(png_worker, 'hello world', this.pngSource3, {pngCallback: (sender:ArrayBuffer, value:ArrayBuffer) => {
|
pngj.writePngWithStringAsync(png_worker, this.pngSource3, ( value:ESObject) => {
|
||||||
this.pngSource3 = sender
|
|
||||||
FileUtils.getInstance().createFileProcess(
|
FileUtils.getInstance().createFileProcess(
|
||||||
this.rootFolder + '/pngj',
|
this.rootFolder + '/pngj',
|
||||||
this.rootFolder + '/pngj/newPng.png',
|
this.rootFolder + '/pngj/newPng.png',
|
||||||
|
@ -174,7 +172,7 @@ struct PngjTestCasePage {
|
||||||
let png1 = new Uint8Array(value)
|
let png1 = new Uint8Array(value)
|
||||||
this.hint3 = 'png写入后长度' + png1.byteLength + '目录文件:' + this.rootFolder + '/pngj/newPng.png' + '保存后使用2进制查看数据是否新增'
|
this.hint3 = 'png写入后长度' + png1.byteLength + '目录文件:' + this.rootFolder + '/pngj/newPng.png' + '保存后使用2进制查看数据是否新增'
|
||||||
this.pngdecodeRun3 = false;
|
this.pngdecodeRun3 = false;
|
||||||
}})
|
},'hello world')
|
||||||
} else {
|
} else {
|
||||||
this.hint9 = '已经在执行了,请稍等'
|
this.hint9 = '已经在执行了,请稍等'
|
||||||
}
|
}
|
||||||
|
@ -210,12 +208,11 @@ struct PngjTestCasePage {
|
||||||
if (!this.pngdecodeRun4) {
|
if (!this.pngdecodeRun4) {
|
||||||
this.pngdecodeRun4 = true;
|
this.pngdecodeRun4 = true;
|
||||||
let pngj = new Pngj();
|
let pngj = new Pngj();
|
||||||
let png_worker = new worker.ThreadWorker('entry/ets/workers/upngWorkerTestCase.ets', {
|
let png_worker: WorkerType = {
|
||||||
type: 'classic',
|
type: 'classic',
|
||||||
name: 'writePngAsync'
|
name: 'writePngAsync'
|
||||||
})
|
}
|
||||||
pngj.writePngAsync(png_worker, this.pngSource4,{pngCallback: (sender:ArrayBuffer, value:ArrayBuffer) => {
|
pngj.writePngAsync(png_worker, this.pngSource4, ( value:ESObject) => {
|
||||||
this.pngSource4 = sender
|
|
||||||
FileUtils.getInstance().createFileProcess(
|
FileUtils.getInstance().createFileProcess(
|
||||||
this.rootFolder + '/pngj',
|
this.rootFolder + '/pngj',
|
||||||
this.rootFolder + '/pngj/newPng2.png',
|
this.rootFolder + '/pngj/newPng2.png',
|
||||||
|
@ -223,7 +220,7 @@ struct PngjTestCasePage {
|
||||||
let png2 = new Uint8Array(value)
|
let png2 = new Uint8Array(value)
|
||||||
this.hint4 = 'png2未写入长度' + png2.byteLength + '目录文件:' + this.rootFolder + '/pngj/newPng2.png' + '保存后使用2进制查看数据是否新增'
|
this.hint4 = 'png2未写入长度' + png2.byteLength + '目录文件:' + this.rootFolder + '/pngj/newPng2.png' + '保存后使用2进制查看数据是否新增'
|
||||||
this.pngdecodeRun4 = false;
|
this.pngdecodeRun4 = false;
|
||||||
}})
|
})
|
||||||
} else {
|
} else {
|
||||||
this.hint10 = '已经在执行了,请稍等'
|
this.hint10 = '已经在执行了,请稍等'
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,237 @@
|
||||||
|
/*
|
||||||
|
* 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 {
|
||||||
|
CustomDataFetchClient,
|
||||||
|
DataFetchResult,
|
||||||
|
DownloadClient,
|
||||||
|
ImageKnifeComponent,
|
||||||
|
ImageKnifeGlobal,
|
||||||
|
ImageKnifeOption,
|
||||||
|
LogUtil,
|
||||||
|
ScaleType
|
||||||
|
} from '@ohos/libraryimageknife';
|
||||||
|
|
||||||
|
import http from '@ohos.net.http';
|
||||||
|
|
||||||
|
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
|
||||||
|
@Component
|
||||||
|
struct TestCustomDataFetchClientWithPage {
|
||||||
|
@State hotCommendList: CommonDataSource<string> = new CommonDataSource<string>([])
|
||||||
|
@State singleImageKnifeOption: ImageKnifeOption =
|
||||||
|
{
|
||||||
|
loadSrc: $r('app.media.icon'),
|
||||||
|
placeholderSrc: $r('app.media.icon_loading'),
|
||||||
|
errorholderSrc: $r('app.media.icon_failed'),
|
||||||
|
};
|
||||||
|
@State isSingleImageVisible: boolean = true;
|
||||||
|
@State isAllImageVisible: boolean = false;
|
||||||
|
@State isCustom: boolean = false;
|
||||||
|
private data: Array<string> = [
|
||||||
|
"http://img2.xkhouse.com/bbs/hfhouse/data/attachment/forum/corebbs/2009-11/2009113011534566298.jpg",
|
||||||
|
"http://a.hiphotos.baidu.com/image/pic/item/e824b899a9014c087eb617650e7b02087af4f464.jpg"
|
||||||
|
]
|
||||||
|
private addData: Array<string> = [
|
||||||
|
"http://c.hiphotos.baidu.com/image/pic/item/9c16fdfaaf51f3de1e296fa390eef01f3b29795a.jpg",
|
||||||
|
"http://h.hiphotos.baidu.com/image/pic/item/902397dda144ad340668b847d4a20cf430ad851e.jpg"
|
||||||
|
|
||||||
|
]
|
||||||
|
private cancelData: Array<string> = [
|
||||||
|
"http://b.hiphotos.baidu.com/image/pic/item/359b033b5bb5c9ea5c0e3c23d139b6003bf3b374.jpg",
|
||||||
|
"http://a.hiphotos.baidu.com/image/pic/item/8d5494eef01f3a292d2472199d25bc315d607c7c.jpg"
|
||||||
|
]
|
||||||
|
|
||||||
|
aboutToAppear(): void {
|
||||||
|
this.hotCommendList.addData(this.hotCommendList.totalCount(), this.data)
|
||||||
|
LogUtil.log('TestCustomDataFetch about to appear.')
|
||||||
|
}
|
||||||
|
|
||||||
|
build() {
|
||||||
|
Scroll() {
|
||||||
|
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
||||||
|
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
||||||
|
|
||||||
|
Button("单个图片").margin(16).onClick(() => {
|
||||||
|
LogUtil.log('TestCustomDataFetch click single.');
|
||||||
|
this.isSingleImageVisible = true;
|
||||||
|
this.isAllImageVisible = false;
|
||||||
|
ImageKnifeGlobal.getInstance().getImageKnife()?.replaceDataFetch(new CustomDataFetchClient());
|
||||||
|
|
||||||
|
this.singleImageKnifeOption = {
|
||||||
|
loadSrc: 'http://e.hiphotos.baidu.com/image/pic/item/4e4a20a4462309f7e41f5cfe760e0cf3d6cad6ee.jpg',
|
||||||
|
placeholderSrc: $r('app.media.icon_loading'),
|
||||||
|
errorholderSrc: $r('app.media.icon_failed'),
|
||||||
|
customGetImage: custom
|
||||||
|
}
|
||||||
|
})
|
||||||
|
Button("全部图片").margin(16).onClick(() => {
|
||||||
|
LogUtil.log('TestCustomDataFetch click all.');
|
||||||
|
this.isSingleImageVisible = false;
|
||||||
|
this.isAllImageVisible = true;
|
||||||
|
|
||||||
|
ImageKnifeGlobal.getInstance().getImageKnife()?.replaceDataFetch(new CustomDataFetchClient());
|
||||||
|
this.hotCommendList.addData(this.hotCommendList.totalCount(), this.addData)
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
Button("取消自定义全部图片").margin(16).onClick(() => {
|
||||||
|
LogUtil.log('TestCustomDataFetch click cancel.');
|
||||||
|
this.isSingleImageVisible = false;
|
||||||
|
this.isAllImageVisible = true;
|
||||||
|
|
||||||
|
ImageKnifeGlobal.getInstance().getImageKnife()?.replaceDataFetch(new DownloadClient());
|
||||||
|
this.hotCommendList.addData(this.hotCommendList.totalCount(), this.cancelData)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 单个图片使用自定义网络栈
|
||||||
|
ImageKnifeComponent({ imageKnifeOption: this.singleImageKnifeOption })
|
||||||
|
.width(200)
|
||||||
|
.height(200)
|
||||||
|
.margin({ top: 50 })
|
||||||
|
.visibility(this.isSingleImageVisible ? Visibility.Visible : Visibility.None)
|
||||||
|
|
||||||
|
// 全部图片使用自定义网络栈
|
||||||
|
Column() {
|
||||||
|
Grid() {
|
||||||
|
LazyForEach(this.hotCommendList, (item: string) => {
|
||||||
|
GridItem() {
|
||||||
|
ImageKnifeComponent({
|
||||||
|
imageKnifeOption: {
|
||||||
|
loadSrc: item,
|
||||||
|
placeholderSrc: $r('app.media.icon'),
|
||||||
|
errorholderSrc: $r('app.media.icon_failed'),
|
||||||
|
placeholderScaleType: ScaleType.CENTER_CROP,
|
||||||
|
mainScaleType: ScaleType.CENTER_CROP,
|
||||||
|
}
|
||||||
|
}).width('100%').height('100%')
|
||||||
|
}.width('40%').height(200)
|
||||||
|
}, (item: string) => JSON.stringify(item))
|
||||||
|
}
|
||||||
|
.columnsTemplate('1fr 1fr')
|
||||||
|
.columnsGap(8)
|
||||||
|
.rowsGap(10)
|
||||||
|
.width('100%')
|
||||||
|
.hitTestBehavior(HitTestMode.None)
|
||||||
|
.maxCount(10)
|
||||||
|
}.margin({ top: 5 })
|
||||||
|
.visibility(this.isAllImageVisible ? Visibility.Visible : Visibility.None)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.width('100%')
|
||||||
|
.height('100%')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Concurrent
|
||||||
|
async function custom(context: Context, loadSrc: string): Promise<DataFetchResult> {
|
||||||
|
let result: DataFetchResult = new DataFetchResult();
|
||||||
|
try {
|
||||||
|
let arrayBuffers = new Array<ArrayBuffer>();
|
||||||
|
let httpRequest = http.createHttp()
|
||||||
|
httpRequest.on('headersReceive', (header: Object) => {
|
||||||
|
// 跟服务器连接成功准备下载
|
||||||
|
})
|
||||||
|
httpRequest.on('dataReceive', (data: ArrayBuffer) => {
|
||||||
|
// 下载数据流多次返回
|
||||||
|
arrayBuffers.push(data);
|
||||||
|
})
|
||||||
|
httpRequest.on('dataEnd', () => {
|
||||||
|
// 下载完毕
|
||||||
|
})
|
||||||
|
|
||||||
|
const resultCode = await httpRequest.requestInStream(loadSrc as string,
|
||||||
|
{
|
||||||
|
method: http.RequestMethod.GET,
|
||||||
|
expectDataType: http.HttpDataType.ARRAY_BUFFER,
|
||||||
|
connectTimeout: 60000, // 可选 默认60000ms
|
||||||
|
readTimeout: 0, // 可选, 默认为60000ms
|
||||||
|
usingProtocol: http.HttpProtocol.HTTP1_1, // 可选,协议类型默认值由系统自动指定
|
||||||
|
usingCache: false
|
||||||
|
}).catch((err: Error) => {
|
||||||
|
result.error = 'TestCustomDataFetchClientWithPage requestInStream error.' + JSON.stringify(err);
|
||||||
|
})
|
||||||
|
if (resultCode == 200) {
|
||||||
|
//let combineArray = this.combineArrayBuffers(arrayBuffers);
|
||||||
|
// 计算多个ArrayBuffer的总字节大小
|
||||||
|
let totalByteLength = 0;
|
||||||
|
for (const arrayBuffer of arrayBuffers) {
|
||||||
|
totalByteLength += arrayBuffer.byteLength;
|
||||||
|
}
|
||||||
|
// 创建一个新的ArrayBuffer
|
||||||
|
const combinedArrayBuffer = new ArrayBuffer(totalByteLength);
|
||||||
|
|
||||||
|
// 创建一个Uint8Array来操作新的ArrayBuffer
|
||||||
|
const combinedUint8Array = new Uint8Array(combinedArrayBuffer);
|
||||||
|
|
||||||
|
// 依次复制每个ArrayBuffer的内容到新的ArrayBuffer中
|
||||||
|
let offset = 0;
|
||||||
|
for (const arrayBuffer of arrayBuffers) {
|
||||||
|
const sourceUint8Array = new Uint8Array(arrayBuffer);
|
||||||
|
combinedUint8Array.set(sourceUint8Array, offset);
|
||||||
|
offset += sourceUint8Array.length;
|
||||||
|
}
|
||||||
|
result.data = combinedArrayBuffer;
|
||||||
|
} else {
|
||||||
|
result.error = 'TestCustomDataFetchClientWithPage error. resultCode = ' + resultCode;
|
||||||
|
}
|
||||||
|
console.log('TestCustomDataFetch single onComplete, code = ' + resultCode + ',length = ' + result.data?.byteLength);
|
||||||
|
} catch (error) {
|
||||||
|
result.error = 'TestCustomDataFetchClientWithPage error' + error.stack;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2022 Huawei Device Co., Ltd.
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { ImageKnife,ImageKnifeGlobal,ImageKnifeOption,ImageKnifeComponent} from '@ohos/libraryimageknife'
|
||||||
|
|
||||||
|
@Entry
|
||||||
|
@Component
|
||||||
|
struct DiskPreLoadPage {
|
||||||
|
|
||||||
|
@State imageKnifeOption2: ImageKnifeOption =
|
||||||
|
{
|
||||||
|
loadSrc: $r('app.media.icon'),
|
||||||
|
placeholderSrc: $r('app.media.icon_loading'),
|
||||||
|
errorholderSrc: $r('app.media.icon_failed'),
|
||||||
|
};
|
||||||
|
|
||||||
|
build() {
|
||||||
|
Row() {
|
||||||
|
Column() {
|
||||||
|
Button("预加载图片").onClick(()=>{
|
||||||
|
let imageKnife: ImageKnife | undefined = ImageKnifeGlobal.getInstance().getImageKnife();
|
||||||
|
if(imageKnife != undefined){
|
||||||
|
imageKnife.prefetchToDiskCache("https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658")
|
||||||
|
.then((resolve)=>{
|
||||||
|
console.log("成功回调 : " + resolve)
|
||||||
|
})
|
||||||
|
.catch((reject: ESObject) => {
|
||||||
|
console.log("失败回调 : " + reject)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
||||||
|
Button("加载GIF")
|
||||||
|
.onClick(() => {
|
||||||
|
this.imageKnifeOption2 = {
|
||||||
|
loadSrc: 'https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658',
|
||||||
|
placeholderSrc: $r('app.media.icon_loading'),
|
||||||
|
errorholderSrc: $r('app.media.icon_failed'),
|
||||||
|
displayProgress:true,
|
||||||
|
}
|
||||||
|
}).margin({ top: 5, left: 3 })
|
||||||
|
ImageKnifeComponent({ imageKnifeOption: this.imageKnifeOption2 }).width(300).height(300)
|
||||||
|
}.width('100%').backgroundColor(Color.Pink)
|
||||||
|
}
|
||||||
|
.width('100%')
|
||||||
|
}
|
||||||
|
.height('100%')
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,64 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2024 Huawei Device Co., Ltd.
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
import { ImageKnifeComponent, ImageKnifeOption } from '@ohos/libraryimageknife'
|
||||||
|
|
||||||
|
@Entry
|
||||||
|
@Component
|
||||||
|
struct TestGifPlayTimesPage {
|
||||||
|
@State ImageKnifeOption1: ImageKnifeOption = {
|
||||||
|
loadSrc: $r('app.media.icon'),
|
||||||
|
placeholderSrc: $r('app.media.icon_loading'),
|
||||||
|
errorholderSrc: $r('app.media.icon_failed')
|
||||||
|
}
|
||||||
|
|
||||||
|
build() {
|
||||||
|
Scroll() {
|
||||||
|
Column() {
|
||||||
|
Text("测试gif播放次数").fontSize(25)
|
||||||
|
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
||||||
|
Button("加载网络gif").onClick(() => {
|
||||||
|
this.ImageKnifeOption1 = {
|
||||||
|
loadSrc: "https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658",
|
||||||
|
placeholderSrc: $r('app.media.icon_loading'),
|
||||||
|
errorholderSrc: $r('app.media.icon_failed')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
Button("设置gif播放1次").onClick(() => {
|
||||||
|
this.ImageKnifeOption1 = {
|
||||||
|
loadSrc: "https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658",
|
||||||
|
placeholderSrc: $r('app.media.icon_loading'),
|
||||||
|
errorholderSrc: $r('app.media.icon_failed'),
|
||||||
|
gif: {
|
||||||
|
playTimes: 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
Button("设置gif播放2次").onClick(() => {
|
||||||
|
this.ImageKnifeOption1 = {
|
||||||
|
loadSrc: "https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658",
|
||||||
|
placeholderSrc: $r('app.media.icon_loading'),
|
||||||
|
errorholderSrc: $r('app.media.icon_failed'),
|
||||||
|
gif: {
|
||||||
|
playTimes: 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
ImageKnifeComponent({ imageKnifeOption: this.ImageKnifeOption1 }).width(300).height(300).borderWidth(3)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,71 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2021 Huawei Device Co., Ltd.
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { ComponentUtils } from '@ohos.arkui.UIContext'
|
||||||
|
import display from '@ohos.display';
|
||||||
|
import { ImageKnifeComponent,
|
||||||
|
ScaleType } from '@ohos/libraryimageknife'
|
||||||
|
import componentUtils from '@ohos.arkui.componentUtils';
|
||||||
|
|
||||||
|
@Entry
|
||||||
|
@Component
|
||||||
|
|
||||||
|
struct testImageKnifeAutoHeightPage {
|
||||||
|
|
||||||
|
|
||||||
|
private currentWidth: number =0
|
||||||
|
private currentHeight: number =0
|
||||||
|
|
||||||
|
@State value : componentUtils.ComponentInfo = componentUtils.getRectangleById("ImageKnifeCanvas");
|
||||||
|
|
||||||
|
aboutToAppear(){
|
||||||
|
let displayClas : ESObject =null
|
||||||
|
try {
|
||||||
|
displayClas = display.getDefaultDisplaySync()
|
||||||
|
console.info('........width'+ displayClas.width)
|
||||||
|
console.info('........height'+ displayClas.height)
|
||||||
|
|
||||||
|
}catch (e){
|
||||||
|
|
||||||
|
console.error('error' + e)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
build(){
|
||||||
|
Scroll(){
|
||||||
|
Column(){
|
||||||
|
ImageKnifeComponent({
|
||||||
|
imageKnifeOption:{
|
||||||
|
loadSrc :$r('app.media.pngSample'),
|
||||||
|
mainScaleType:ScaleType.AUTO_HEIGHT,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.width("100%")
|
||||||
|
Button(){
|
||||||
|
Text('getRectangleById').fontSize(40).fontWeight(FontWeight.Bold);
|
||||||
|
}
|
||||||
|
.onClick(()=> {
|
||||||
|
this.value = componentUtils.getRectangleById("ImageKnifeCanvas")
|
||||||
|
this.currentWidth = px2vp(this.value.size.width)
|
||||||
|
this.currentHeight = px2vp(this.value.size.height)
|
||||||
|
console.log('currentWidth'+this.currentWidth)
|
||||||
|
console.log('currentHeight'+this.currentHeight)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,71 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2021 Huawei Device Co., Ltd.
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { ComponentUtils } from '@ohos.arkui.UIContext'
|
||||||
|
import display from '@ohos.display';
|
||||||
|
import { ImageKnifeComponent,
|
||||||
|
ScaleType } from '@ohos/libraryimageknife'
|
||||||
|
import componentUtils from '@ohos.arkui.componentUtils';
|
||||||
|
|
||||||
|
@Entry
|
||||||
|
@Component
|
||||||
|
|
||||||
|
struct testImageKnifeAutoPage {
|
||||||
|
|
||||||
|
|
||||||
|
private currentWidth: number =0
|
||||||
|
private currentHeight: number =0
|
||||||
|
|
||||||
|
@State value : componentUtils.ComponentInfo = componentUtils.getRectangleById("ImageKnifeCanvas");
|
||||||
|
|
||||||
|
aboutToAppear(){
|
||||||
|
let displayClas : ESObject =null
|
||||||
|
try {
|
||||||
|
displayClas = display.getDefaultDisplaySync()
|
||||||
|
console.info('........width'+ displayClas.width)
|
||||||
|
console.info('........height'+ displayClas.height)
|
||||||
|
|
||||||
|
}catch (e){
|
||||||
|
|
||||||
|
console.error('error' + e)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
build(){
|
||||||
|
Scroll(){
|
||||||
|
Column(){
|
||||||
|
ImageKnifeComponent({
|
||||||
|
imageKnifeOption:{
|
||||||
|
loadSrc :$r('app.media.pngSample'),
|
||||||
|
mainScaleType:ScaleType.AUTO,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
Button(){
|
||||||
|
Text('getRectangleById').fontSize(40).fontWeight(FontWeight.Bold);
|
||||||
|
}
|
||||||
|
.onClick(()=> {
|
||||||
|
this.value = componentUtils.getRectangleById("ImageKnifeCanvas")
|
||||||
|
this.currentWidth = px2vp(this.value.size.width)
|
||||||
|
this.currentHeight = px2vp(this.value.size.height)
|
||||||
|
console.log('currentWidth'+this.currentWidth)
|
||||||
|
console.log('currentHeight'+this.currentHeight)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,72 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2021 Huawei Device Co., Ltd.
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { ComponentUtils } from '@ohos.arkui.UIContext'
|
||||||
|
import display from '@ohos.display';
|
||||||
|
import { ImageKnifeComponent,
|
||||||
|
ScaleType } from '@ohos/libraryimageknife'
|
||||||
|
import componentUtils from '@ohos.arkui.componentUtils';
|
||||||
|
|
||||||
|
@Entry
|
||||||
|
@Component
|
||||||
|
|
||||||
|
struct testImageKnifeAutoWidthPage {
|
||||||
|
|
||||||
|
|
||||||
|
private currentWidth: number =0
|
||||||
|
private currentHeight: number =0
|
||||||
|
|
||||||
|
@State value : componentUtils.ComponentInfo = componentUtils.getRectangleById("ImageKnifeCanvas");
|
||||||
|
|
||||||
|
aboutToAppear(){
|
||||||
|
let displayClas : ESObject =null
|
||||||
|
try {
|
||||||
|
displayClas = display.getDefaultDisplaySync()
|
||||||
|
console.info('........width'+ displayClas.width)
|
||||||
|
console.info('........height'+ displayClas.height)
|
||||||
|
|
||||||
|
}catch (e){
|
||||||
|
|
||||||
|
console.error('error' + e)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
build(){
|
||||||
|
Scroll(){
|
||||||
|
Column(){
|
||||||
|
ImageKnifeComponent({
|
||||||
|
imageKnifeOption:{
|
||||||
|
loadSrc :$r('app.media.pngSample'),
|
||||||
|
mainScaleType:ScaleType.AUTO_WIDTH,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.height(400)
|
||||||
|
|
||||||
|
Button(){
|
||||||
|
Text('getRectangleById').fontSize(40).fontWeight(FontWeight.Bold);
|
||||||
|
}
|
||||||
|
.onClick(()=> {
|
||||||
|
this.value = componentUtils.getRectangleById("ImageKnifeCanvas")
|
||||||
|
this.currentWidth = px2vp(this.value.size.width)
|
||||||
|
this.currentHeight = px2vp(this.value.size.height)
|
||||||
|
console.log('currentWidth'+this.currentWidth)
|
||||||
|
console.log('currentHeight'+this.currentHeight)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,239 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2022 Huawei Device Co., Ltd.
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import {
|
||||||
|
ImageKnifeComponent,
|
||||||
|
ImageKnifeOption,
|
||||||
|
ImageKnifeGlobal,
|
||||||
|
ImageKnife,
|
||||||
|
ImageKnifeData,
|
||||||
|
RequestOption,
|
||||||
|
Size,
|
||||||
|
CacheType
|
||||||
|
} from '@ohos/libraryimageknife'
|
||||||
|
import image from '@ohos.multimedia.image';
|
||||||
|
import { BusinessError } from '@ohos.base';
|
||||||
|
|
||||||
|
let imageKnife: ImageKnife | undefined = ImageKnifeGlobal.getInstance().getImageKnife();
|
||||||
|
|
||||||
|
@Entry
|
||||||
|
@Component
|
||||||
|
struct testImageKnifeCache {
|
||||||
|
@State url: string = '';
|
||||||
|
@State urlGif: string = 'https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658';
|
||||||
|
@State urlPng: string = 'https://img-blog.csdnimg.cn/20191215043500229.png';
|
||||||
|
@State urlJpg: string = 'https://hbimg.huabanimg.com/cc6af25f8d782d3cf3122bef4e61571378271145735e9-vEVggB';
|
||||||
|
@State urlBmp: string = 'https://img-blog.csdn.net/20140514114029140';
|
||||||
|
@State urlWebp: string = 'https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp';
|
||||||
|
@State imagePixelMap: PixelMap | undefined = undefined;
|
||||||
|
@State imagePixelMap_: PixelMap | undefined = undefined;
|
||||||
|
private index_: number = -1;
|
||||||
|
private tempSize: number = 200;
|
||||||
|
private timeId = -1;
|
||||||
|
private comSize: Size = {
|
||||||
|
width: this.tempSize,
|
||||||
|
height: this.tempSize,
|
||||||
|
}
|
||||||
|
@State imageKnifeOption: ImageKnifeOption =
|
||||||
|
{
|
||||||
|
loadSrc: $r('app.media.icon'),
|
||||||
|
|
||||||
|
placeholderSrc: $r('app.media.icon_loading'),
|
||||||
|
errorholderSrc: $r('app.media.icon_failed')
|
||||||
|
};
|
||||||
|
loadSuccess = (data: ImageKnifeData) => {
|
||||||
|
clearTimeout(this.timeId);
|
||||||
|
if (data.isPixelMap()) {
|
||||||
|
if (data.drawPixelMap) {
|
||||||
|
let pixelmap = data.drawPixelMap.imagePixelMap
|
||||||
|
if (pixelmap) {
|
||||||
|
if (this.index_ == 1) {
|
||||||
|
this.imagePixelMap = pixelmap;
|
||||||
|
} else if (this.index_ == 2) {
|
||||||
|
this.imagePixelMap_ = pixelmap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (data.isGIFFrame()) {
|
||||||
|
let index: number = 0
|
||||||
|
if (data.drawGIFFrame) {
|
||||||
|
if (data.drawGIFFrame.imageGIFFrames) {
|
||||||
|
let renderGif = () => {
|
||||||
|
if (data.drawGIFFrame) {
|
||||||
|
if (data.drawGIFFrame.imageGIFFrames) {
|
||||||
|
let pixelmap = data.drawGIFFrame.imageGIFFrames[index].drawPixelMap
|
||||||
|
let delay = data.drawGIFFrame.imageGIFFrames[index].delay
|
||||||
|
if (pixelmap) {
|
||||||
|
if (this.index_ == 1) {
|
||||||
|
this.imagePixelMap = pixelmap;
|
||||||
|
} else if (this.index_ == 2) {
|
||||||
|
this.imagePixelMap_ = pixelmap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
index++;
|
||||||
|
if (index == data.drawGIFFrame.imageGIFFrames.length - 1) {
|
||||||
|
index = 0
|
||||||
|
}
|
||||||
|
this.timeId = setTimeout(renderGif, data!.drawGIFFrame!.imageGIFFrames![index].delay)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
renderGif()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
loadError = (err: BusinessError) => {
|
||||||
|
}
|
||||||
|
|
||||||
|
build() {
|
||||||
|
Scroll() {
|
||||||
|
Column() {
|
||||||
|
|
||||||
|
Text('图片内存和磁盘读取').fontSize(30);
|
||||||
|
Text('加载的缓存时候关闭掉网络').fontSize(15);
|
||||||
|
|
||||||
|
Row() {
|
||||||
|
Button('png')
|
||||||
|
.onClick(() => {
|
||||||
|
this.index_ = 0;
|
||||||
|
this.url = this.urlPng;
|
||||||
|
this.imageKnifeOption =
|
||||||
|
{
|
||||||
|
loadSrc: this.url,
|
||||||
|
placeholderSrc: $r('app.media.icon_loading'),
|
||||||
|
errorholderSrc: $r('app.media.icon_failed')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
Button('bmp')
|
||||||
|
.onClick(() => {
|
||||||
|
this.index_ = 0;
|
||||||
|
this.url = this.urlBmp;
|
||||||
|
this.imageKnifeOption =
|
||||||
|
{
|
||||||
|
loadSrc: this.url,
|
||||||
|
placeholderSrc: $r('app.media.icon_loading'),
|
||||||
|
errorholderSrc: $r('app.media.icon_failed')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
Button('webp')
|
||||||
|
.onClick(() => {
|
||||||
|
this.index_ = 0;
|
||||||
|
this.url = this.urlWebp;
|
||||||
|
this.imageKnifeOption =
|
||||||
|
{
|
||||||
|
loadSrc: this.url,
|
||||||
|
placeholderSrc: $r('app.media.icon_loading'),
|
||||||
|
errorholderSrc: $r('app.media.icon_failed')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
Button('jpg')
|
||||||
|
.onClick(() => {
|
||||||
|
this.index_ = 0;
|
||||||
|
this.url = this.urlJpg;
|
||||||
|
this.imageKnifeOption =
|
||||||
|
{
|
||||||
|
loadSrc: this.url,
|
||||||
|
placeholderSrc: $r('app.media.icon_loading'),
|
||||||
|
errorholderSrc: $r('app.media.icon_failed')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
Button('gif')
|
||||||
|
.onClick(() => {
|
||||||
|
this.index_ = 0;
|
||||||
|
this.url = this.urlGif;
|
||||||
|
this.imageKnifeOption =
|
||||||
|
{
|
||||||
|
loadSrc: this.url,
|
||||||
|
placeholderSrc: $r('app.media.icon_loading'),
|
||||||
|
errorholderSrc: $r('app.media.icon_failed')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
Row() {
|
||||||
|
Button('缓存图片')
|
||||||
|
.onClick(() => {
|
||||||
|
this.index_ = 1;
|
||||||
|
imageKnife?.isUrlExist(this.url, CacheType.Cache, this.comSize).then(this.loadSuccess)
|
||||||
|
.catch(this.loadError);
|
||||||
|
})
|
||||||
|
|
||||||
|
Button('磁盘图片')
|
||||||
|
.onClick(() => {
|
||||||
|
this.index_ = 2;
|
||||||
|
imageKnife?.isUrlExist(this.url, CacheType.Disk, this.comSize).then(this.loadSuccess)
|
||||||
|
.catch(this.loadError);
|
||||||
|
})
|
||||||
|
|
||||||
|
Button('默认')
|
||||||
|
.onClick(() => {
|
||||||
|
this.index_ = 2;
|
||||||
|
imageKnife?.isUrlExist(this.url, CacheType.Default, this.comSize).then(this.loadSuccess)
|
||||||
|
.catch(this.loadError);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
Text('网络图').fontSize(15);
|
||||||
|
ImageKnifeComponent({ imageKnifeOption: this.imageKnifeOption })
|
||||||
|
.width(200)
|
||||||
|
.height(200)
|
||||||
|
.backgroundColor(Color.Orange)
|
||||||
|
Text('缓存图').fontSize(15);
|
||||||
|
|
||||||
|
ImageKnifeComponent({
|
||||||
|
imageKnifeOption: {
|
||||||
|
loadSrc: this.imagePixelMap as image.PixelMap
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.width(200)
|
||||||
|
.height(200)
|
||||||
|
.backgroundColor(Color.Orange)
|
||||||
|
Text('磁盘图').fontSize(15);
|
||||||
|
ImageKnifeComponent({
|
||||||
|
imageKnifeOption: {
|
||||||
|
loadSrc: this.imagePixelMap_ as image.PixelMap
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.width(200)
|
||||||
|
.height(200)
|
||||||
|
.backgroundColor(Color.Orange)
|
||||||
|
|
||||||
|
}
|
||||||
|
.alignItems(HorizontalAlign.Center)
|
||||||
|
.width('100%')
|
||||||
|
|
||||||
|
}
|
||||||
|
.width('100%')
|
||||||
|
.height('100%')
|
||||||
|
}
|
||||||
|
|
||||||
|
aboutToAppear() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
aboutToDisappear() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
onBackPress() {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,83 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2023 Huawei Device Co., Ltd.
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
import {
|
||||||
|
Base64,
|
||||||
|
IDataFetch,
|
||||||
|
ImageKnife,
|
||||||
|
ImageKnifeComponent,
|
||||||
|
ImageKnifeGlobal,
|
||||||
|
ImageKnifeOption,
|
||||||
|
DataFetchResult,
|
||||||
|
RequestOption} from '@ohos/libraryimageknife'
|
||||||
|
import common from '@ohos.app.ability.common';
|
||||||
|
import resourceManager from '@ohos.resourceManager';
|
||||||
|
import { BusinessError } from '@ohos.base'
|
||||||
|
|
||||||
|
@Entry
|
||||||
|
@Component
|
||||||
|
struct TestImageKnifeDataFetch {
|
||||||
|
|
||||||
|
@State imageKnifeOption1: ImageKnifeOption =
|
||||||
|
{
|
||||||
|
loadSrc: $r('app.media.icon'),
|
||||||
|
placeholderSrc: $r('app.media.icon_loading'),
|
||||||
|
errorholderSrc: $r('app.media.icon_failed'),
|
||||||
|
};
|
||||||
|
|
||||||
|
build() {
|
||||||
|
Column(){
|
||||||
|
Text("简单示例1:加载一张本地png图片").fontSize(15)
|
||||||
|
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
||||||
|
Button("加载PNG")
|
||||||
|
.onClick(() => {
|
||||||
|
let dataFetch:MyDataFetch = new MyDataFetch();
|
||||||
|
let imageKnife:ImageKnife|undefined = ImageKnifeGlobal.getInstance().getImageKnife()
|
||||||
|
if(imageKnife != undefined) {
|
||||||
|
imageKnife.replaceDataFetch(dataFetch)
|
||||||
|
}
|
||||||
|
this.imageKnifeOption1 = {
|
||||||
|
loadSrc: "",
|
||||||
|
placeholderSrc: $r('app.media.icon_loading'),
|
||||||
|
errorholderSrc: $r('app.media.icon_failed'),
|
||||||
|
isCacheable: false,
|
||||||
|
}
|
||||||
|
}).margin({ top: 5, left: 3 })
|
||||||
|
ImageKnifeComponent({ imageKnifeOption: this.imageKnifeOption1 }).width(300).height(300)
|
||||||
|
}.width('100%').backgroundColor(Color.Pink)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Sendable
|
||||||
|
class MyDataFetch implements IDataFetch{
|
||||||
|
loadData(option: RequestOption) {
|
||||||
|
let result:DataFetchResult = new DataFetchResult();
|
||||||
|
((ImageKnifeGlobal.getInstance().getHapContext() as common.UIAbilityContext).resourceManager as resourceManager.ResourceManager)
|
||||||
|
.getMediaContentBase64($r('app.media.pngSample').id)
|
||||||
|
.then(data => {
|
||||||
|
let matchReg = ';base64,';
|
||||||
|
let firstIndex = data.indexOf(matchReg);
|
||||||
|
data = data.substring(firstIndex + matchReg.length, data.length)
|
||||||
|
console.log('MyDataFetch - 本地加载资源 解析后数据剔除非必要数据后data= ' + data)
|
||||||
|
let arrayBuffer = Base64.getInstance()
|
||||||
|
.decode(data);
|
||||||
|
result.data = arrayBuffer;
|
||||||
|
}).catch((err:BusinessError) => {
|
||||||
|
result.error = 'MyDataFetch - 本地加载资源err' + JSON.stringify(err);
|
||||||
|
})
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2022 Huawei Device Co., Ltd.
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { ImageKnifeComponent, ImageKnifeOption } from '@ohos/libraryimageknife'
|
||||||
|
|
||||||
|
@Entry
|
||||||
|
@Component
|
||||||
|
struct testImageKnifeHeic {
|
||||||
|
@State imageKnifeOption1: ImageKnifeOption =
|
||||||
|
{
|
||||||
|
loadSrc: $r('app.media.yunHeic'),
|
||||||
|
placeholderSrc: $r('app.media.icon_loading'),
|
||||||
|
errorholderSrc: $r('app.media.icon_failed'),
|
||||||
|
};
|
||||||
|
|
||||||
|
@State flag: boolean = true;
|
||||||
|
|
||||||
|
build() {
|
||||||
|
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
||||||
|
Button("heic图片测试")
|
||||||
|
.onClick(() => {
|
||||||
|
this.flag = !this.flag
|
||||||
|
if (this.flag) {
|
||||||
|
this.imageKnifeOption1.errorholderSrc = $r('app.media.icon_loading')
|
||||||
|
} else {
|
||||||
|
this.imageKnifeOption1.errorholderSrc = $r('app.media.icon_failed')
|
||||||
|
}
|
||||||
|
}).margin({ top: 15 })
|
||||||
|
ImageKnifeComponent({ imageKnifeOption: this.imageKnifeOption1 }).width(300).height(300)
|
||||||
|
}.width('100%').height(300).backgroundColor(Color.Pink)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,256 @@
|
||||||
|
/*
|
||||||
|
* 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 {
|
||||||
|
HeaderOptions,ImageKnife,ImageKnifeComponent,ImageKnifeData,ImageKnifeGlobal,RequestOption,ImageKnifeOption,ObjectKey
|
||||||
|
} from '@ohos/libraryimageknife'
|
||||||
|
import image from '@ohos.multimedia.image'
|
||||||
|
import { BusinessError } from '@ohos.base'
|
||||||
|
|
||||||
|
const TAG = "TEST-"
|
||||||
|
let timeId = -1
|
||||||
|
|
||||||
|
@Entry
|
||||||
|
@Component
|
||||||
|
struct testImageKnifeHttpRequestHeader {
|
||||||
|
@State pixelMap: PixelMap | undefined = undefined;
|
||||||
|
@State pixelMap1: PixelMap | undefined = undefined;
|
||||||
|
@State pixelMap2: PixelMap | undefined = undefined;
|
||||||
|
@State pixelMap3: PixelMap | undefined = undefined;
|
||||||
|
@State domeType1: boolean = false;
|
||||||
|
@State domeType2: boolean = false;
|
||||||
|
@State domeType3: boolean = false;
|
||||||
|
@State domeType4: boolean = false;
|
||||||
|
@State domeType5: boolean = false;
|
||||||
|
@State domeType6: boolean = false;
|
||||||
|
@State successHeader: string = "requestOption调用成功";
|
||||||
|
@State errorHeader: string = "requestOption调用失败";
|
||||||
|
@State successHeader1: string = "全局调用imageKnife成功";
|
||||||
|
@State errorHeader1: string = "全局调用imageKnife失败";
|
||||||
|
@State successHeader2: string = "单个imageKnife组件调用成功";
|
||||||
|
@State errorHeader2: string = "单个imageKnife组件调用失败";
|
||||||
|
|
||||||
|
@State message: string = "图片header属性测试";
|
||||||
|
@State headerOptions1: HeaderOptions = {
|
||||||
|
key: "refer",
|
||||||
|
value: "http://1.94.37.200:7070/AntiTheftChain/downloadImage"
|
||||||
|
};
|
||||||
|
@State headerOptions2: HeaderOptions = {
|
||||||
|
key: "xx",
|
||||||
|
value: "http://1.94.37.200:7070/AntiTheftChain/downloadImage"
|
||||||
|
};
|
||||||
|
@State imageKnifeOption1: ImageKnifeOption =
|
||||||
|
{
|
||||||
|
loadSrc: 'http://1.94.37.200:7070/AntiTheftChain/downloadImage',
|
||||||
|
placeholderSrc: $r('app.media.icon_loading'),
|
||||||
|
errorholderSrc: $r('app.media.icon_failed'),
|
||||||
|
headerOption: [this.headerOptions1]
|
||||||
|
};
|
||||||
|
@State imageKnifeOption2: ImageKnifeOption =
|
||||||
|
{
|
||||||
|
loadSrc: 'http://1.94.37.200:7070/AntiTheftChain/downloadImage',
|
||||||
|
placeholderSrc: $r('app.media.icon_loading'),
|
||||||
|
errorholderSrc: $r('app.media.icon_failed'),
|
||||||
|
headerOption: [this.headerOptions2]
|
||||||
|
};
|
||||||
|
|
||||||
|
// RequestOption调用
|
||||||
|
load(src: string | image.PixelMap | Resource, type: string, num: number) {
|
||||||
|
clearTimeout(timeId)
|
||||||
|
let request = new RequestOption()
|
||||||
|
if (type == 'error') {
|
||||||
|
request.addHeader('xx', src)
|
||||||
|
} else {
|
||||||
|
request.addHeader('refer', src)
|
||||||
|
}
|
||||||
|
//清理缓存
|
||||||
|
request.signature = new ObjectKey(new Date().getTime().toString())
|
||||||
|
request.load(src)
|
||||||
|
.addListener({ callback: (err: BusinessError | string, data: ImageKnifeData) => {
|
||||||
|
if (data.isPixelMap()) {
|
||||||
|
if (data.drawPixelMap) {
|
||||||
|
let pixelmap = data.drawPixelMap.imagePixelMap
|
||||||
|
if (pixelmap) {
|
||||||
|
if (num == 1) {
|
||||||
|
this.pixelMap = pixelmap
|
||||||
|
} else if (num == 2) {
|
||||||
|
this.pixelMap1 = pixelmap
|
||||||
|
} else if (num == 3) {
|
||||||
|
this.pixelMap2 = pixelmap
|
||||||
|
} else if (num == 4) {
|
||||||
|
this.pixelMap3 = pixelmap
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (data.isGIFFrame()) {
|
||||||
|
let index: number = 0
|
||||||
|
if (data.drawGIFFrame) {
|
||||||
|
if (data.drawGIFFrame.imageGIFFrames) {
|
||||||
|
let renderGif = () => {
|
||||||
|
if (data.drawGIFFrame) {
|
||||||
|
if (data.drawGIFFrame.imageGIFFrames) {
|
||||||
|
let pixelmap = data.drawGIFFrame.imageGIFFrames[index].drawPixelMap
|
||||||
|
let delay = data.drawGIFFrame.imageGIFFrames[index].delay
|
||||||
|
if (pixelmap) {
|
||||||
|
if (num == 1) {
|
||||||
|
this.pixelMap = pixelmap
|
||||||
|
} else if (num == 2) {
|
||||||
|
this.pixelMap1 = pixelmap
|
||||||
|
} else if (num == 3) {
|
||||||
|
this.pixelMap2 = pixelmap
|
||||||
|
} else if (num == 4) {
|
||||||
|
this.pixelMap3 = pixelmap
|
||||||
|
}
|
||||||
|
}
|
||||||
|
index++;
|
||||||
|
if (index == data.drawGIFFrame.imageGIFFrames.length - 1) {
|
||||||
|
index = 0
|
||||||
|
}
|
||||||
|
timeId = setTimeout(renderGif, data!.drawGIFFrame!.imageGIFFrames![index].delay)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
renderGif()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (err) {
|
||||||
|
console.log(TAG + "error:" + JSON.stringify(err));
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
let imageknife: ImageKnife | undefined = ImageKnifeGlobal.getInstance().getImageKnife()
|
||||||
|
if (imageknife != undefined) {
|
||||||
|
imageknife.call(request)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Builder
|
||||||
|
setHeader() {
|
||||||
|
ImageKnifeComponent({
|
||||||
|
imageKnifeOption: {
|
||||||
|
loadSrc: this.pixelMap as image.PixelMap
|
||||||
|
}
|
||||||
|
}).width(200).height(200).borderWidth(1)
|
||||||
|
}
|
||||||
|
@Builder
|
||||||
|
setHeader3() {
|
||||||
|
ImageKnifeComponent({
|
||||||
|
imageKnifeOption: {
|
||||||
|
loadSrc: this.pixelMap1 as image.PixelMap
|
||||||
|
}
|
||||||
|
}).width(200).height(200).borderWidth(1)
|
||||||
|
}
|
||||||
|
@Builder
|
||||||
|
setHeader1() {
|
||||||
|
ImageKnifeComponent({
|
||||||
|
imageKnifeOption: {
|
||||||
|
loadSrc: this.pixelMap2 as image.PixelMap
|
||||||
|
}
|
||||||
|
}).width(200).height(200).borderWidth(1)
|
||||||
|
}
|
||||||
|
@Builder
|
||||||
|
setHeader4() {
|
||||||
|
ImageKnifeComponent({
|
||||||
|
imageKnifeOption: {
|
||||||
|
loadSrc: this.pixelMap3 as image.PixelMap
|
||||||
|
}
|
||||||
|
}).width(200).height(200).borderWidth(1)
|
||||||
|
}
|
||||||
|
@Builder
|
||||||
|
setHeader2() {
|
||||||
|
ImageKnifeComponent({ imageKnifeOption: this.imageKnifeOption1 })
|
||||||
|
.margin(16)
|
||||||
|
.width(200)
|
||||||
|
.height(200)
|
||||||
|
}
|
||||||
|
@Builder
|
||||||
|
setHeader5() {
|
||||||
|
ImageKnifeComponent({ imageKnifeOption: this.imageKnifeOption2 })
|
||||||
|
.margin(16)
|
||||||
|
.width(200)
|
||||||
|
.height(200)
|
||||||
|
}
|
||||||
|
|
||||||
|
build() {
|
||||||
|
Scroll() {
|
||||||
|
Column() {
|
||||||
|
Text(`${this.message}`)
|
||||||
|
.width("300vp")
|
||||||
|
.height("60vp")
|
||||||
|
.textAlign(TextAlign.Center)
|
||||||
|
.fontSize("30fp")
|
||||||
|
.fontWeight(FontWeight.Bold)
|
||||||
|
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Start }) {
|
||||||
|
Button(this.successHeader)
|
||||||
|
.margin(16)
|
||||||
|
.onClick(() => {
|
||||||
|
this.domeType1 = !this.domeType1
|
||||||
|
this.load('http://1.94.37.200:7070/AntiTheftChain/downloadImage', 'success', 1)
|
||||||
|
})
|
||||||
|
if (this.domeType1) {
|
||||||
|
this.setHeader()
|
||||||
|
}
|
||||||
|
Button(this.errorHeader)
|
||||||
|
.margin(16)
|
||||||
|
.onClick(() => {
|
||||||
|
this.domeType2 = !this.domeType2
|
||||||
|
this.load('http://1.94.37.200:7070/AntiTheftChain/downloadImage', 'error', 2)
|
||||||
|
})
|
||||||
|
if (this.domeType2) {
|
||||||
|
this.setHeader3()
|
||||||
|
}
|
||||||
|
Button(this.successHeader1)
|
||||||
|
.margin(16)
|
||||||
|
.onClick(() => {
|
||||||
|
this.domeType3 = !this.domeType3
|
||||||
|
this.load('http://1.94.37.200:7070/AntiTheftChain/downloadImage', 'success', 3)
|
||||||
|
})
|
||||||
|
if (this.domeType3) {
|
||||||
|
this.setHeader1()
|
||||||
|
}
|
||||||
|
Button(this.errorHeader1)
|
||||||
|
.margin(16)
|
||||||
|
.onClick(() => {
|
||||||
|
this.domeType4 = !this.domeType4
|
||||||
|
this.load('http://1.94.37.200:7070/AntiTheftChain/downloadImage', 'error', 4)
|
||||||
|
})
|
||||||
|
if (this.domeType4) {
|
||||||
|
this.setHeader4()
|
||||||
|
}
|
||||||
|
Button(this.successHeader2)
|
||||||
|
.margin(16)
|
||||||
|
.onClick(() => {
|
||||||
|
this.domeType5 = !this.domeType5
|
||||||
|
})
|
||||||
|
if (this.domeType5) {
|
||||||
|
this.setHeader2()
|
||||||
|
}
|
||||||
|
Button(this.errorHeader2)
|
||||||
|
.margin(16)
|
||||||
|
.onClick(() => {
|
||||||
|
this.domeType6 = !this.domeType6
|
||||||
|
})
|
||||||
|
if (this.domeType6) {
|
||||||
|
this.setHeader5()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}.width("100%")
|
||||||
|
.justifyContent(FlexAlign.Start)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,172 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2022 Huawei Device Co., Ltd.
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
import {
|
||||||
|
HeaderOptions,ImageKnife,ImageKnifeComponent,ImageKnifeData,ImageKnifeGlobal,RequestOption,ImageKnifeOption,ObjectKey
|
||||||
|
} from '@ohos/libraryimageknife'
|
||||||
|
import image from '@ohos.multimedia.image'
|
||||||
|
import { BusinessError } from '@ohos.base'
|
||||||
|
|
||||||
|
const TAG = "TEST-"
|
||||||
|
let timeId = -1
|
||||||
|
|
||||||
|
@Entry
|
||||||
|
@Component
|
||||||
|
struct testImageKnifeHttpRequestHeader1 {
|
||||||
|
@State pixelMap: PixelMap | undefined = undefined;
|
||||||
|
@State pixelMap1: PixelMap | undefined = undefined;
|
||||||
|
@State domeType1: boolean = false;
|
||||||
|
@State domeType2: boolean = false;
|
||||||
|
@State successHeader: string = "requestOption调用成功";
|
||||||
|
@State errorHeader: string = "requestOption调用失败";
|
||||||
|
@State allKeySame: string = "全局添加header和request成功的键相同值不同";
|
||||||
|
@State allKeyNoSame: string = "全局添加header和request成功的键不同";
|
||||||
|
@State clearnAllHeader: string = "清空全局header";
|
||||||
|
|
||||||
|
@State message: string = "图片header属性测试";
|
||||||
|
|
||||||
|
imageKnife: ImageKnife | undefined = ImageKnifeGlobal.getInstance().getImageKnife()
|
||||||
|
// RequestOption调用
|
||||||
|
load(src: string | image.PixelMap | Resource, type: string, num: number) {
|
||||||
|
clearTimeout(timeId)
|
||||||
|
let request = new RequestOption()
|
||||||
|
if (type == 'error') {
|
||||||
|
request.addHeader('xx', src)
|
||||||
|
} else {
|
||||||
|
request.addHeader('refer', src)
|
||||||
|
}
|
||||||
|
//清理缓存
|
||||||
|
request.signature = new ObjectKey(new Date().getTime().toString())
|
||||||
|
request.load(src)
|
||||||
|
.addListener({ callback: (err: BusinessError | string, data: ImageKnifeData) => {
|
||||||
|
if (data.isPixelMap()) {
|
||||||
|
if (data.drawPixelMap) {
|
||||||
|
let pixelmap = data.drawPixelMap.imagePixelMap
|
||||||
|
if (pixelmap) {
|
||||||
|
if (num == 1) {
|
||||||
|
this.pixelMap = pixelmap
|
||||||
|
} else if (num == 2) {
|
||||||
|
this.pixelMap1 = pixelmap
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (data.isGIFFrame()) {
|
||||||
|
let index: number = 0
|
||||||
|
if (data.drawGIFFrame) {
|
||||||
|
if (data.drawGIFFrame.imageGIFFrames) {
|
||||||
|
let renderGif = () => {
|
||||||
|
if (data.drawGIFFrame) {
|
||||||
|
if (data.drawGIFFrame.imageGIFFrames) {
|
||||||
|
let pixelmap = data.drawGIFFrame.imageGIFFrames[index].drawPixelMap
|
||||||
|
let delay = data.drawGIFFrame.imageGIFFrames[index].delay
|
||||||
|
if (pixelmap) {
|
||||||
|
if (num == 1) {
|
||||||
|
this.pixelMap = pixelmap
|
||||||
|
} else if (num == 2) {
|
||||||
|
this.pixelMap1 = pixelmap
|
||||||
|
}
|
||||||
|
}
|
||||||
|
index++;
|
||||||
|
if (index == data.drawGIFFrame.imageGIFFrames.length - 1) {
|
||||||
|
index = 0
|
||||||
|
}
|
||||||
|
timeId = setTimeout(renderGif, data!.drawGIFFrame!.imageGIFFrames![index].delay)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
renderGif()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (err) {
|
||||||
|
console.log(TAG + "error:" + JSON.stringify(err));
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
let imageknife: ImageKnife | undefined = ImageKnifeGlobal.getInstance().getImageKnife()
|
||||||
|
if (imageknife != undefined) {
|
||||||
|
imageknife.call(request)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Builder
|
||||||
|
setHeader() {
|
||||||
|
ImageKnifeComponent({
|
||||||
|
imageKnifeOption: {
|
||||||
|
loadSrc: this.pixelMap as image.PixelMap
|
||||||
|
}
|
||||||
|
}).width(200).height(200).borderWidth(1)
|
||||||
|
}
|
||||||
|
@Builder
|
||||||
|
setHeader1() {
|
||||||
|
ImageKnifeComponent({
|
||||||
|
imageKnifeOption: {
|
||||||
|
loadSrc: this.pixelMap1 as image.PixelMap
|
||||||
|
}
|
||||||
|
}).width(200).height(200).borderWidth(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
build() {
|
||||||
|
Scroll() {
|
||||||
|
Column() {
|
||||||
|
Text(`${this.message}`)
|
||||||
|
.width("300vp")
|
||||||
|
.height("60vp")
|
||||||
|
.textAlign(TextAlign.Center)
|
||||||
|
.fontSize("30fp")
|
||||||
|
.fontWeight(FontWeight.Bold)
|
||||||
|
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Start }) {
|
||||||
|
Button(this.successHeader)
|
||||||
|
.margin(16)
|
||||||
|
.onClick(() => {
|
||||||
|
this.domeType1 = !this.domeType1
|
||||||
|
this.load('http://1.94.37.200:7070/AntiTheftChain/downloadImage', 'success', 1)
|
||||||
|
})
|
||||||
|
if (this.domeType1) {
|
||||||
|
this.setHeader()
|
||||||
|
}
|
||||||
|
Button(this.errorHeader)
|
||||||
|
.margin(16)
|
||||||
|
.onClick(() => {
|
||||||
|
this.domeType2 = !this.domeType2
|
||||||
|
this.load('http://1.94.37.200:7070/AntiTheftChain/downloadImage', 'error', 2)
|
||||||
|
})
|
||||||
|
if (this.domeType2) {
|
||||||
|
this.setHeader1()
|
||||||
|
}
|
||||||
|
Button(this.allKeySame)
|
||||||
|
.margin(16)
|
||||||
|
.onClick(() => {
|
||||||
|
this.imageKnife?.addHeader('refer','test')
|
||||||
|
})
|
||||||
|
Button(this.allKeyNoSame)
|
||||||
|
.margin(16)
|
||||||
|
.onClick(() => {
|
||||||
|
this.imageKnife?.addHeader('ceshi','http://1.94.37.200:7070/AntiTheftChain/downloadImage')
|
||||||
|
})
|
||||||
|
Button(this.clearnAllHeader)
|
||||||
|
.margin(16)
|
||||||
|
.onClick(() => {
|
||||||
|
this.imageKnife?.deleteHeader('refer');
|
||||||
|
this.imageKnife?.deleteHeader('ceshi');
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}.width("100%")
|
||||||
|
.justifyContent(FlexAlign.Start)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,133 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2024 Huawei Device Co., Ltd.
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { ImageKnifeComponent, ImageKnifeOption } from '@ohos/libraryimageknife'
|
||||||
|
|
||||||
|
@Entry
|
||||||
|
@Component
|
||||||
|
struct testImageKnifeNetPlaceholder {
|
||||||
|
@State imageKnifeOption: ImageKnifeOption =
|
||||||
|
{
|
||||||
|
loadSrc: $r('app.media.icon'),
|
||||||
|
placeholderSrc: $r('app.media.icon_loading'),
|
||||||
|
errorholderSrc: $r('app.media.icon_failed'),
|
||||||
|
};
|
||||||
|
@State imageKnifeOption1: ImageKnifeOption =
|
||||||
|
{
|
||||||
|
loadSrc: $r('app.media.icon'),
|
||||||
|
placeholderSrc: $r('app.media.icon_loading'),
|
||||||
|
errorholderSrc: $r('app.media.icon_failed'),
|
||||||
|
};
|
||||||
|
@State imageKnifeOption2: ImageKnifeOption =
|
||||||
|
{
|
||||||
|
loadSrc: $r('app.media.icon'),
|
||||||
|
placeholderSrc: $r('app.media.icon_loading'),
|
||||||
|
errorholderSrc: $r('app.media.icon_failed'),
|
||||||
|
};
|
||||||
|
|
||||||
|
build() {
|
||||||
|
Scroll() {
|
||||||
|
Column() {
|
||||||
|
Text('string类型占位图支持内存和磁盘读取').fontSize(30);
|
||||||
|
Text('验证磁盘有无图片可以先主图缓存一张图片,再退出应用').fontSize(15);
|
||||||
|
Text('仅第一次打开应用加载主图可以看到效果,因主图第二次加载速度很快').fontSize(15);
|
||||||
|
|
||||||
|
Row() {
|
||||||
|
Button('缓存一张图片作为占位图 图一')
|
||||||
|
.onClick(() => {
|
||||||
|
this.imageKnifeOption =
|
||||||
|
{
|
||||||
|
loadSrc: 'https://img-blog.csdn.net/20140514114029140',
|
||||||
|
placeholderSrc: $r('app.media.icon_loading'),
|
||||||
|
errorholderSrc: $r('app.media.icon_failed'),
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
Text('当图一没有展示,会从磁盘中拿占位图').fontSize(15);
|
||||||
|
Text('当图一展示时,会从内存中拿占位图,不会走磁盘逻辑').fontSize(15);
|
||||||
|
|
||||||
|
Text('下图展示的为后备回调符的图片').fontSize(15);
|
||||||
|
ImageKnifeComponent({ imageKnifeOption: {loadSrc:$r('app.media.mask_starfish')} })
|
||||||
|
.width(200)
|
||||||
|
.height(200)
|
||||||
|
.backgroundColor(Color.Orange)
|
||||||
|
|
||||||
|
Text('下图展示的主图为图二string类型的占位图').fontSize(15);
|
||||||
|
Text('图一:').fontSize(20);
|
||||||
|
ImageKnifeComponent({ imageKnifeOption: this.imageKnifeOption })
|
||||||
|
.width(200)
|
||||||
|
.height(200)
|
||||||
|
.backgroundColor(Color.Orange)
|
||||||
|
|
||||||
|
Row() {
|
||||||
|
Button('展示已缓存的占位图')
|
||||||
|
.onClick(() => {
|
||||||
|
this.imageKnifeOption1 =
|
||||||
|
{
|
||||||
|
loadSrc : $r('app.media.pngSample'),
|
||||||
|
placeholderSrc: 'https://img-blog.csdn.net/20140514114029140',
|
||||||
|
fallbackSrc: $r('app.media.mask_starfish'),
|
||||||
|
errorholderSrc: $r('app.media.icon_failed'),
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
Button('当占位图未缓存时展示后备回调符')
|
||||||
|
.onClick(() => {
|
||||||
|
this.imageKnifeOption2 =
|
||||||
|
{
|
||||||
|
loadSrc : $r('app.media.gifSample'),
|
||||||
|
placeholderSrc: 'https://img0.baidu.com/it/u=2794536113,2700219306&fm=253&fmt=auto&app=120&f=JPEG?w=500&h=500',
|
||||||
|
fallbackSrc: $r('app.media.mask_starfish'),
|
||||||
|
errorholderSrc: $r('app.media.icon_failed'),
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
Text('展示已缓存的占位图,如图一未加载过则会显示后备回调符').fontSize(15);
|
||||||
|
Text('图二:').fontSize(20);
|
||||||
|
ImageKnifeComponent({ imageKnifeOption: this.imageKnifeOption1 })
|
||||||
|
.width(200)
|
||||||
|
.height(200)
|
||||||
|
.backgroundColor(Color.Orange)
|
||||||
|
|
||||||
|
Text('占位图未缓存展示后备回调符,如图三').fontSize(15);
|
||||||
|
Text('图三:').fontSize(20);
|
||||||
|
ImageKnifeComponent({ imageKnifeOption: this.imageKnifeOption2 })
|
||||||
|
.width(200)
|
||||||
|
.height(200)
|
||||||
|
.backgroundColor(Color.Orange)
|
||||||
|
|
||||||
|
}
|
||||||
|
.alignItems(HorizontalAlign.Center)
|
||||||
|
.width('100%')
|
||||||
|
|
||||||
|
}
|
||||||
|
.width('100%')
|
||||||
|
.height('100%')
|
||||||
|
}
|
||||||
|
|
||||||
|
aboutToAppear() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
aboutToDisappear() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
onBackPress() {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -27,6 +27,9 @@ import {
|
||||||
ImageKnifeDrawFactory
|
ImageKnifeDrawFactory
|
||||||
} from '@ohos/libraryimageknife'
|
} from '@ohos/libraryimageknife'
|
||||||
import worker from '@ohos.worker';
|
import worker from '@ohos.worker';
|
||||||
|
|
||||||
|
let gifUrl: string = 'https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658';
|
||||||
|
|
||||||
@Entry
|
@Entry
|
||||||
@Component
|
@Component
|
||||||
struct TestImageKnifeOptionChangedPage5 {
|
struct TestImageKnifeOptionChangedPage5 {
|
||||||
|
@ -83,6 +86,64 @@ struct TestImageKnifeOptionChangedPage5 {
|
||||||
};
|
};
|
||||||
}).margin({ left: 5 }).backgroundColor(Color.Blue)
|
}).margin({ left: 5 }).backgroundColor(Color.Blue)
|
||||||
}.margin({ top: 15 })
|
}.margin({ top: 15 })
|
||||||
|
Flex({ direction: FlexDirection.Row }) {
|
||||||
|
Button("本地gif")
|
||||||
|
.onClick(() => {
|
||||||
|
this.imageKnifeOption1 = {
|
||||||
|
loadSrc: $r('app.media.gifSample'),
|
||||||
|
placeholderSrc: $r('app.media.icon_loading'),
|
||||||
|
errorholderSrc: $r('app.media.icon_failed'),
|
||||||
|
};
|
||||||
|
}).margin({ left: 5 }).backgroundColor(Color.Blue)
|
||||||
|
Button("网络gif")
|
||||||
|
.onClick(() => {
|
||||||
|
this.imageKnifeOption1 = {
|
||||||
|
loadSrc: gifUrl,
|
||||||
|
placeholderSrc: $r('app.media.icon_loading'),
|
||||||
|
errorholderSrc: $r('app.media.icon_failed'),
|
||||||
|
};
|
||||||
|
}).margin({ left: 5 }).backgroundColor(Color.Blue)
|
||||||
|
}.margin({ top: 15 })
|
||||||
|
Flex({ direction: FlexDirection.Row }) {
|
||||||
|
Button("网络gif - 圆角小")
|
||||||
|
.onClick(() => {
|
||||||
|
this.imageKnifeOption1 = {
|
||||||
|
loadSrc: gifUrl,
|
||||||
|
placeholderSrc: $r('app.media.icon_loading'),
|
||||||
|
errorholderSrc: $r('app.media.icon_failed'),
|
||||||
|
drawLifeCycle: ImageKnifeDrawFactory.createRoundLifeCycle(3, "#ff0000", 30)
|
||||||
|
};
|
||||||
|
}).margin({ left: 5 }).backgroundColor(Color.Blue)
|
||||||
|
Button("本地gif - 圆角大")
|
||||||
|
.onClick(() => {
|
||||||
|
this.imageKnifeOption1 = {
|
||||||
|
loadSrc: $r('app.media.gifSample'),
|
||||||
|
placeholderSrc: $r('app.media.icon_loading'),
|
||||||
|
errorholderSrc: $r('app.media.icon_failed'),
|
||||||
|
drawLifeCycle: ImageKnifeDrawFactory.createRoundLifeCycle(5, "#ffff00", 300)
|
||||||
|
};
|
||||||
|
}).margin({ left: 5 }).backgroundColor(Color.Blue)
|
||||||
|
}.margin({ top: 15 })
|
||||||
|
Flex({ direction: FlexDirection.Row }) {
|
||||||
|
Button("网络gif-椭圆长方形资源")
|
||||||
|
.onClick(() => {
|
||||||
|
this.imageKnifeOption1 = {
|
||||||
|
loadSrc: gifUrl,
|
||||||
|
placeholderSrc: $r('app.media.icon_loading'),
|
||||||
|
errorholderSrc: $r('app.media.icon_failed'),
|
||||||
|
drawLifeCycle: ImageKnifeDrawFactory.createOvalLifeCycle(8, "#88ee00")
|
||||||
|
};
|
||||||
|
}).margin({ left: 5 }).backgroundColor(Color.Blue)
|
||||||
|
Button("本地gif-椭圆正方形资源")
|
||||||
|
.onClick(() => {
|
||||||
|
this.imageKnifeOption1 = {
|
||||||
|
loadSrc: $r('app.media.gifSample'),
|
||||||
|
placeholderSrc: $r('app.media.icon_loading'),
|
||||||
|
errorholderSrc: $r('app.media.icon_failed'),
|
||||||
|
drawLifeCycle: ImageKnifeDrawFactory.createOvalLifeCycle(5, "#ff00ff")
|
||||||
|
};
|
||||||
|
}).margin({ left: 5 }).backgroundColor(Color.Blue)
|
||||||
|
}.margin({ top: 15 })
|
||||||
|
|
||||||
Text("下面为展示图片区域").margin({ top: 5 })
|
Text("下面为展示图片区域").margin({ top: 5 })
|
||||||
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
||||||
|
|
|
@ -0,0 +1,65 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2023 Huawei Device Co., Ltd.
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
import { ScaleType, ImageKnifeComponent, NONE, DiskStrategy } from "@ohos/libraryimageknife"
|
||||||
|
import { Material } from './model/Material';
|
||||||
|
import { TestDataSource } from './model/TestDataSource';
|
||||||
|
|
||||||
|
|
||||||
|
@Entry
|
||||||
|
@Component
|
||||||
|
struct TestManyNetImageLoadWithPage2 {
|
||||||
|
private data: TestDataSource = new TestDataSource();
|
||||||
|
private setting: DiskStrategy = new NONE();
|
||||||
|
private scroller: Scroller = new Scroller()
|
||||||
|
|
||||||
|
build() {
|
||||||
|
Scroll() {
|
||||||
|
Column() {
|
||||||
|
Grid(this.scroller) {
|
||||||
|
LazyForEach(this.data, (item: Material, index) => {
|
||||||
|
GridItem() {
|
||||||
|
Stack({ alignContent: Alignment.BottomEnd }) {
|
||||||
|
ImageKnifeComponent({
|
||||||
|
imageKnifeOption: {
|
||||||
|
loadSrc: item.thumbnail,
|
||||||
|
placeholderSrc: $r('app.media.icon_loading'),
|
||||||
|
mainScaleType: ScaleType.CENTER_CROP,
|
||||||
|
placeholderScaleType: ScaleType.CENTER_CROP,
|
||||||
|
isCacheable: false,
|
||||||
|
strategy: this.setting
|
||||||
|
}
|
||||||
|
}).width('100%').height('100%')
|
||||||
|
Text(index + "." + item.name)
|
||||||
|
.fontSize(10)
|
||||||
|
.maxLines(1)
|
||||||
|
.fontColor(Color.White)
|
||||||
|
.textAlign(TextAlign.Center)
|
||||||
|
.layoutWeight(1)
|
||||||
|
.width('100%')
|
||||||
|
.backgroundColor(Color.Orange)
|
||||||
|
}
|
||||||
|
}.width('45%').height(200)
|
||||||
|
}, (item: Material,index:number) => item.material_id + index.toString())
|
||||||
|
}
|
||||||
|
.columnsTemplate('1fr 1fr')
|
||||||
|
.columnsGap(8)
|
||||||
|
.rowsGap(10)
|
||||||
|
.width('100%')
|
||||||
|
.cachedCount(3)
|
||||||
|
.height('100%')
|
||||||
|
}.margin({ top: 5 })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -88,59 +88,59 @@ struct TestPreloadPage {
|
||||||
if (err) {
|
if (err) {
|
||||||
console.log('预加载本地资源gif 出现错误! err=' + err)
|
console.log('预加载本地资源gif 出现错误! err=' + err)
|
||||||
} else {
|
} else {
|
||||||
console.log('预加载本地资源gif成功! imageKnifedata=' + JSON.stringify(data))
|
console.log('预加载本地资源gif成功! imageKnifedata=' + JSON.stringify(data))
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}})
|
}})
|
||||||
ImageKnifeGlobal.getInstance().getImageKnife()?.preload(request);
|
ImageKnifeGlobal.getInstance().getImageKnife()?.preload(request);
|
||||||
})
|
})
|
||||||
.margin({ left: 15 })
|
.margin({ left: 15 })
|
||||||
.backgroundColor(Color.Grey)
|
.backgroundColor(Color.Grey)
|
||||||
|
|
||||||
|
|
||||||
Button('本地资源gif')
|
Button('本地资源gif')
|
||||||
.onClick(() => {
|
.onClick(() => {
|
||||||
this.imageKnifeOption1 = {
|
this.imageKnifeOption1 = {
|
||||||
loadSrc: $r('app.media.gifSample'),
|
loadSrc: $r('app.media.gifSample'),
|
||||||
|
|
||||||
placeholderSrc: $r('app.media.icon_loading'),
|
placeholderSrc: $r('app.media.icon_loading'),
|
||||||
errorholderSrc: $r('app.media.icon_failed'),
|
errorholderSrc: $r('app.media.icon_failed'),
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
})
|
})
|
||||||
.margin({ left: 15 })
|
.margin({ left: 15 })
|
||||||
.backgroundColor(Color.Grey)
|
.backgroundColor(Color.Grey)
|
||||||
|
|
||||||
Button('预加载本地资源gif静态')
|
Button('预加载本地资源gif静态')
|
||||||
.onClick(() => {
|
.onClick(() => {
|
||||||
let request = new RequestOption();
|
let request = new RequestOption();
|
||||||
request.load($r('app.media.gifSample'))
|
request.load($r('app.media.gifSample'))
|
||||||
.setImageViewSize({ width: 300, height: 300 })
|
.setImageViewSize({ width: 300, height: 300 })
|
||||||
.dontAnimate()
|
.dontAnimate()
|
||||||
.addListener({callback:(err:BusinessError|string, data:ImageKnifeData) => {
|
.addListener({callback:(err:BusinessError|string, data:ImageKnifeData) => {
|
||||||
if (err ) {
|
if (err ) {
|
||||||
console.log('预加载本地资源gif静态 出现错误! err=' + err)
|
console.log('预加载本地资源gif静态 出现错误! err=' + err)
|
||||||
} else {
|
} else {
|
||||||
console.log('预加载本地资源gif静态成功! imageKnifedata=' + JSON.stringify(data))
|
console.log('预加载本地资源gif静态成功! imageKnifedata=' + JSON.stringify(data))
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}})
|
}})
|
||||||
ImageKnifeGlobal.getInstance().getImageKnife()?.preload(request);
|
ImageKnifeGlobal.getInstance().getImageKnife()?.preload(request);
|
||||||
})
|
})
|
||||||
.margin({ left: 15 })
|
.margin({ left: 15 })
|
||||||
.backgroundColor(Color.Grey)
|
.backgroundColor(Color.Grey)
|
||||||
|
|
||||||
Button('本地资源gif静态')
|
Button('本地资源gif静态')
|
||||||
.onClick(() => {
|
.onClick(() => {
|
||||||
this.imageKnifeOption1 = {
|
this.imageKnifeOption1 = {
|
||||||
loadSrc: $r('app.media.gifSample'),
|
loadSrc: $r('app.media.gifSample'),
|
||||||
placeholderSrc: $r('app.media.icon_loading'),
|
placeholderSrc: $r('app.media.icon_loading'),
|
||||||
errorholderSrc: $r('app.media.icon_failed'),
|
errorholderSrc: $r('app.media.icon_failed'),
|
||||||
dontAnimateFlag: true
|
dontAnimateFlag: true
|
||||||
}
|
}
|
||||||
|
|
||||||
})
|
})
|
||||||
.margin({ left: 15 })
|
.margin({ left: 15 })
|
||||||
.backgroundColor(Color.Grey)
|
.backgroundColor(Color.Grey)
|
||||||
}
|
}
|
||||||
|
@ -150,64 +150,64 @@ struct TestPreloadPage {
|
||||||
|
|
||||||
Button('预加载网络资源gif')
|
Button('预加载网络资源gif')
|
||||||
.onClick(() => {
|
.onClick(() => {
|
||||||
let request = new RequestOption();
|
let request = new RequestOption();
|
||||||
request.load('https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658')
|
request.load('https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658')
|
||||||
.setImageViewSize({ width: 300, height: 300 })
|
.setImageViewSize({ width: 300, height: 300 })
|
||||||
.addListener({callback:(err:BusinessError|string, data:ImageKnifeData) => {
|
.addListener({callback:(err:BusinessError|string, data:ImageKnifeData) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
console.log('预加载网络资源gif 出现错误! err=' + err)
|
console.log('预加载网络资源gif 出现错误! err=' + err)
|
||||||
} else {
|
} else {
|
||||||
console.log('预加载网络资源gif成功! imageKnifedata=' + JSON.stringify(data))
|
console.log('预加载网络资源gif成功! imageKnifedata=' + JSON.stringify(data))
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}})
|
}})
|
||||||
ImageKnifeGlobal.getInstance().getImageKnife()?.preload(request);
|
ImageKnifeGlobal.getInstance().getImageKnife()?.preload(request);
|
||||||
})
|
})
|
||||||
.margin({ left: 15 })
|
.margin({ left: 15 })
|
||||||
.backgroundColor(Color.Grey)
|
.backgroundColor(Color.Grey)
|
||||||
|
|
||||||
Button('网络资源gif')
|
Button('网络资源gif')
|
||||||
.onClick(() => {
|
.onClick(() => {
|
||||||
this.imageKnifeOption1 = {
|
this.imageKnifeOption1 = {
|
||||||
loadSrc: 'https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658',
|
loadSrc: 'https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658',
|
||||||
|
|
||||||
placeholderSrc: $r('app.media.icon_loading'),
|
placeholderSrc: $r('app.media.icon_loading'),
|
||||||
errorholderSrc: $r('app.media.icon_failed'),
|
errorholderSrc: $r('app.media.icon_failed'),
|
||||||
|
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
.margin({ left: 15 })
|
.margin({ left: 15 })
|
||||||
.backgroundColor(Color.Grey)
|
.backgroundColor(Color.Grey)
|
||||||
|
|
||||||
Button('预加载网络资源gif静态')
|
Button('预加载网络资源gif静态')
|
||||||
.onClick(() => {
|
.onClick(() => {
|
||||||
let request = new RequestOption();
|
let request = new RequestOption();
|
||||||
request.load('https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658')
|
request.load('https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658')
|
||||||
.setImageViewSize({ width: 300, height: 300 })
|
.setImageViewSize({ width: 300, height: 300 })
|
||||||
.dontAnimate()
|
.dontAnimate()
|
||||||
.addListener({callback:(err:BusinessError|string, data:ImageKnifeData) => {
|
.addListener({callback:(err:BusinessError|string, data:ImageKnifeData) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
console.log('预加载网络资源gif静态 出现错误! err=' + err)
|
console.log('预加载网络资源gif静态 出现错误! err=' + err)
|
||||||
} else {
|
} else {
|
||||||
console.log('预加载网络资源gif静态成功! imageKnifedata=' + JSON.stringify(data))
|
console.log('预加载网络资源gif静态成功! imageKnifedata=' + JSON.stringify(data))
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}})
|
}})
|
||||||
ImageKnifeGlobal.getInstance().getImageKnife()?.preload(request);
|
ImageKnifeGlobal.getInstance().getImageKnife()?.preload(request);
|
||||||
})
|
})
|
||||||
.margin({ left: 15 })
|
.margin({ left: 15 })
|
||||||
.backgroundColor(Color.Grey)
|
.backgroundColor(Color.Grey)
|
||||||
|
|
||||||
Button('网络资源gif静态')
|
Button('网络资源gif静态')
|
||||||
.onClick(() => {
|
.onClick(() => {
|
||||||
this.imageKnifeOption1 = {
|
this.imageKnifeOption1 = {
|
||||||
loadSrc: 'https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658',
|
loadSrc: 'https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658',
|
||||||
|
|
||||||
placeholderSrc: $r('app.media.icon_loading'),
|
placeholderSrc: $r('app.media.icon_loading'),
|
||||||
errorholderSrc: $r('app.media.icon_failed'),
|
errorholderSrc: $r('app.media.icon_failed'),
|
||||||
dontAnimateFlag: true
|
dontAnimateFlag: true
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
.margin({ left: 15 })
|
.margin({ left: 15 })
|
||||||
.backgroundColor(Color.Grey)
|
.backgroundColor(Color.Grey)
|
||||||
}
|
}
|
||||||
|
@ -228,27 +228,27 @@ struct TestPreloadPage {
|
||||||
if (err ) {
|
if (err ) {
|
||||||
console.log('预加载本地资源svg 出现错误! err=' + err)
|
console.log('预加载本地资源svg 出现错误! err=' + err)
|
||||||
} else {
|
} else {
|
||||||
console.log('预加载本地资源svg成功! imageKnifedata=' + JSON.stringify(data))
|
console.log('预加载本地资源svg成功! imageKnifedata=' + JSON.stringify(data))
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}})
|
}})
|
||||||
ImageKnifeGlobal.getInstance().getImageKnife()?.preload(request);
|
ImageKnifeGlobal.getInstance().getImageKnife()?.preload(request);
|
||||||
})
|
})
|
||||||
.margin({ left: 15 })
|
.margin({ left: 15 })
|
||||||
.backgroundColor(Color.Grey)
|
.backgroundColor(Color.Grey)
|
||||||
|
|
||||||
|
|
||||||
Button('本地资源svg')
|
Button('本地资源svg')
|
||||||
.onClick(() => {
|
.onClick(() => {
|
||||||
this.imageKnifeOption = {
|
this.imageKnifeOption = {
|
||||||
loadSrc: $r('app.media.svgSample'),
|
loadSrc: $r('app.media.svgSample'),
|
||||||
|
|
||||||
placeholderSrc: $r('app.media.icon_loading'),
|
placeholderSrc: $r('app.media.icon_loading'),
|
||||||
errorholderSrc: $r('app.media.icon_failed'),
|
errorholderSrc: $r('app.media.icon_failed'),
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
})
|
})
|
||||||
.margin({ left: 15 })
|
.margin({ left: 15 })
|
||||||
.backgroundColor(Color.Grey)
|
.backgroundColor(Color.Grey)
|
||||||
|
|
||||||
|
@ -275,32 +275,32 @@ struct TestPreloadPage {
|
||||||
|
|
||||||
Button('预加载网络资源svg')
|
Button('预加载网络资源svg')
|
||||||
.onClick(() => {
|
.onClick(() => {
|
||||||
let request = new RequestOption();
|
let request = new RequestOption();
|
||||||
request.load(this.svgUrl)
|
request.load(this.svgUrl)
|
||||||
.setImageViewSize({ width: 300, height: 300 })
|
.setImageViewSize({ width: 300, height: 300 })
|
||||||
.addListener({callback:(err:BusinessError|string, data:ImageKnifeData) => {
|
.addListener({callback:(err:BusinessError|string, data:ImageKnifeData) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
console.log('预加载网络资源gif 出现错误! err=' + err)
|
console.log('预加载网络资源gif 出现错误! err=' + err)
|
||||||
} else {
|
} else {
|
||||||
console.log('预加载网络资源gif成功! imageKnifedata=' + JSON.stringify(data))
|
console.log('预加载网络资源gif成功! imageKnifedata=' + JSON.stringify(data))
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}})
|
}})
|
||||||
ImageKnifeGlobal.getInstance().getImageKnife()?.preload(request);
|
ImageKnifeGlobal.getInstance().getImageKnife()?.preload(request);
|
||||||
})
|
})
|
||||||
.margin({ left: 15 })
|
.margin({ left: 15 })
|
||||||
.backgroundColor(Color.Grey)
|
.backgroundColor(Color.Grey)
|
||||||
|
|
||||||
Button('网络资源svg')
|
Button('网络资源svg')
|
||||||
.onClick(() => {
|
.onClick(() => {
|
||||||
this.imageKnifeOption = {
|
this.imageKnifeOption = {
|
||||||
loadSrc: this.svgUrl,
|
loadSrc: this.svgUrl,
|
||||||
|
|
||||||
placeholderSrc: $r('app.media.icon_loading'),
|
placeholderSrc: $r('app.media.icon_loading'),
|
||||||
errorholderSrc: $r('app.media.icon_failed'),
|
errorholderSrc: $r('app.media.icon_failed'),
|
||||||
|
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
.margin({ left: 15 })
|
.margin({ left: 15 })
|
||||||
.backgroundColor(Color.Grey)
|
.backgroundColor(Color.Grey)
|
||||||
|
|
||||||
|
@ -323,27 +323,27 @@ struct TestPreloadPage {
|
||||||
if (err) {
|
if (err) {
|
||||||
console.log('预加载本地资源webp 出现错误! err=' + err)
|
console.log('预加载本地资源webp 出现错误! err=' + err)
|
||||||
} else {
|
} else {
|
||||||
console.log('预加载本地资源webp成功! imageKnifedata=' + JSON.stringify(data))
|
console.log('预加载本地资源webp成功! imageKnifedata=' + JSON.stringify(data))
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}})
|
}})
|
||||||
ImageKnifeGlobal.getInstance().getImageKnife()?.preload(request);
|
ImageKnifeGlobal.getInstance().getImageKnife()?.preload(request);
|
||||||
})
|
})
|
||||||
.margin({ left: 15 })
|
.margin({ left: 15 })
|
||||||
.backgroundColor(Color.Grey)
|
.backgroundColor(Color.Grey)
|
||||||
|
|
||||||
|
|
||||||
Button('本地资源webp')
|
Button('本地资源webp')
|
||||||
.onClick(() => {
|
.onClick(() => {
|
||||||
this.imageKnifeOption3 = {
|
this.imageKnifeOption3 = {
|
||||||
loadSrc: $r('app.media.jpgSample'),
|
loadSrc: $r('app.media.jpgSample'),
|
||||||
|
|
||||||
placeholderSrc: $r('app.media.icon_loading'),
|
placeholderSrc: $r('app.media.icon_loading'),
|
||||||
errorholderSrc: $r('app.media.icon_failed'),
|
errorholderSrc: $r('app.media.icon_failed'),
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
})
|
})
|
||||||
.margin({ left: 15 })
|
.margin({ left: 15 })
|
||||||
.backgroundColor(Color.Grey)
|
.backgroundColor(Color.Grey)
|
||||||
|
|
||||||
|
@ -355,32 +355,32 @@ struct TestPreloadPage {
|
||||||
|
|
||||||
Button('预加载网络资源webp')
|
Button('预加载网络资源webp')
|
||||||
.onClick(() => {
|
.onClick(() => {
|
||||||
let request = new RequestOption();
|
let request = new RequestOption();
|
||||||
request.load('https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp')
|
request.load('https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp')
|
||||||
.setImageViewSize({ width: 300, height: 300 })
|
.setImageViewSize({ width: 300, height: 300 })
|
||||||
.addListener({callback:(err:BusinessError|string, data:ImageKnifeData) => {
|
.addListener({callback:(err:BusinessError|string, data:ImageKnifeData) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
console.log('预加载网络资源webp 出现错误! err=' + err)
|
console.log('预加载网络资源webp 出现错误! err=' + err)
|
||||||
} else {
|
} else {
|
||||||
console.log('预加载网络资源webp成功! imageKnifedata=' + JSON.stringify(data))
|
console.log('预加载网络资源webp成功! imageKnifedata=' + JSON.stringify(data))
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}})
|
}})
|
||||||
ImageKnifeGlobal.getInstance().getImageKnife()?.preload(request);
|
ImageKnifeGlobal.getInstance().getImageKnife()?.preload(request);
|
||||||
})
|
})
|
||||||
.margin({ left: 15 })
|
.margin({ left: 15 })
|
||||||
.backgroundColor(Color.Grey)
|
.backgroundColor(Color.Grey)
|
||||||
|
|
||||||
Button('网络资源webp')
|
Button('网络资源webp')
|
||||||
.onClick(() => {
|
.onClick(() => {
|
||||||
this.imageKnifeOption3 = {
|
this.imageKnifeOption3 = {
|
||||||
loadSrc: 'https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp',
|
loadSrc: 'https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp',
|
||||||
|
|
||||||
placeholderSrc: $r('app.media.icon_loading'),
|
placeholderSrc: $r('app.media.icon_loading'),
|
||||||
errorholderSrc: $r('app.media.icon_failed'),
|
errorholderSrc: $r('app.media.icon_failed'),
|
||||||
|
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
.margin({ left: 15 })
|
.margin({ left: 15 })
|
||||||
.backgroundColor(Color.Grey)
|
.backgroundColor(Color.Grey)
|
||||||
}
|
}
|
||||||
|
@ -401,27 +401,27 @@ struct TestPreloadPage {
|
||||||
if (err) {
|
if (err) {
|
||||||
console.log('预加载本地资源bmp 出现错误! err=' + err)
|
console.log('预加载本地资源bmp 出现错误! err=' + err)
|
||||||
} else {
|
} else {
|
||||||
console.log('预加载本地资源bmp成功! imageKnifedata=' + JSON.stringify(data))
|
console.log('预加载本地资源bmp成功! imageKnifedata=' + JSON.stringify(data))
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}})
|
}})
|
||||||
ImageKnifeGlobal.getInstance().getImageKnife()?.preload(request);
|
ImageKnifeGlobal.getInstance().getImageKnife()?.preload(request);
|
||||||
})
|
})
|
||||||
.margin({ left: 15 })
|
.margin({ left: 15 })
|
||||||
.backgroundColor(Color.Grey)
|
.backgroundColor(Color.Grey)
|
||||||
|
|
||||||
|
|
||||||
Button('本地资源bmp')
|
Button('本地资源bmp')
|
||||||
.onClick(() => {
|
.onClick(() => {
|
||||||
this.imageKnifeOption4 = {
|
this.imageKnifeOption4 = {
|
||||||
loadSrc: $r('app.media.bmpSample'),
|
loadSrc: $r('app.media.bmpSample'),
|
||||||
|
|
||||||
placeholderSrc: $r('app.media.icon_loading'),
|
placeholderSrc: $r('app.media.icon_loading'),
|
||||||
errorholderSrc: $r('app.media.icon_failed'),
|
errorholderSrc: $r('app.media.icon_failed'),
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
})
|
})
|
||||||
.margin({ left: 15 })
|
.margin({ left: 15 })
|
||||||
.backgroundColor(Color.Grey)
|
.backgroundColor(Color.Grey)
|
||||||
|
|
||||||
|
@ -433,32 +433,32 @@ struct TestPreloadPage {
|
||||||
|
|
||||||
Button('预加载网络资源bmp')
|
Button('预加载网络资源bmp')
|
||||||
.onClick(() => {
|
.onClick(() => {
|
||||||
let request = new RequestOption();
|
let request = new RequestOption();
|
||||||
request.load('https://img-blog.csdn.net/20140514114029140')
|
request.load('https://img-blog.csdn.net/20140514114029140')
|
||||||
.setImageViewSize({ width: 300, height: 300 })
|
.setImageViewSize({ width: 300, height: 300 })
|
||||||
.addListener({callback:(err:BusinessError|string, data:ImageKnifeData) => {
|
.addListener({callback:(err:BusinessError|string, data:ImageKnifeData) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
console.log('预加载网络资源bmp 出现错误! err=' + err)
|
console.log('预加载网络资源bmp 出现错误! err=' + err)
|
||||||
} else {
|
} else {
|
||||||
console.log('预加载网络资源bmp成功! imageKnifedata=' + JSON.stringify(data))
|
console.log('预加载网络资源bmp成功! imageKnifedata=' + JSON.stringify(data))
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}})
|
}})
|
||||||
ImageKnifeGlobal.getInstance().getImageKnife()?.preload(request);
|
ImageKnifeGlobal.getInstance().getImageKnife()?.preload(request);
|
||||||
})
|
})
|
||||||
.margin({ left: 15 })
|
.margin({ left: 15 })
|
||||||
.backgroundColor(Color.Grey)
|
.backgroundColor(Color.Grey)
|
||||||
|
|
||||||
Button('网络资源bmp')
|
Button('网络资源bmp')
|
||||||
.onClick(() => {
|
.onClick(() => {
|
||||||
this.imageKnifeOption4 = {
|
this.imageKnifeOption4 = {
|
||||||
loadSrc: 'https://img-blog.csdn.net/20140514114029140',
|
loadSrc: 'https://img-blog.csdn.net/20140514114029140',
|
||||||
|
|
||||||
placeholderSrc: $r('app.media.icon_loading'),
|
placeholderSrc: $r('app.media.icon_loading'),
|
||||||
errorholderSrc: $r('app.media.icon_failed'),
|
errorholderSrc: $r('app.media.icon_failed'),
|
||||||
|
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
.margin({ left: 15 })
|
.margin({ left: 15 })
|
||||||
.backgroundColor(Color.Grey)
|
.backgroundColor(Color.Grey)
|
||||||
}
|
}
|
||||||
|
@ -479,27 +479,27 @@ struct TestPreloadPage {
|
||||||
if (err) {
|
if (err) {
|
||||||
console.log('预加载本地资源png 出现错误! err=' + err)
|
console.log('预加载本地资源png 出现错误! err=' + err)
|
||||||
} else {
|
} else {
|
||||||
console.log('预加载本地资源png成功! imageKnifedata=' + JSON.stringify(data))
|
console.log('预加载本地资源png成功! imageKnifedata=' + JSON.stringify(data))
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}})
|
}})
|
||||||
ImageKnifeGlobal.getInstance().getImageKnife()?.preload(request);
|
ImageKnifeGlobal.getInstance().getImageKnife()?.preload(request);
|
||||||
})
|
})
|
||||||
.margin({ left: 15 })
|
.margin({ left: 15 })
|
||||||
.backgroundColor(Color.Grey)
|
.backgroundColor(Color.Grey)
|
||||||
|
|
||||||
|
|
||||||
Button('本地资源png')
|
Button('本地资源png')
|
||||||
.onClick(() => {
|
.onClick(() => {
|
||||||
this.imageKnifeOption5 = {
|
this.imageKnifeOption5 = {
|
||||||
loadSrc: $r('app.media.pngSample'),
|
loadSrc: $r('app.media.pngSample'),
|
||||||
|
|
||||||
placeholderSrc: $r('app.media.icon_loading'),
|
placeholderSrc: $r('app.media.icon_loading'),
|
||||||
errorholderSrc: $r('app.media.icon_failed'),
|
errorholderSrc: $r('app.media.icon_failed'),
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
})
|
})
|
||||||
.margin({ left: 15 })
|
.margin({ left: 15 })
|
||||||
.backgroundColor(Color.Grey)
|
.backgroundColor(Color.Grey)
|
||||||
|
|
||||||
|
@ -511,32 +511,32 @@ struct TestPreloadPage {
|
||||||
|
|
||||||
Button('预加载网络资源png')
|
Button('预加载网络资源png')
|
||||||
.onClick(() => {
|
.onClick(() => {
|
||||||
let request = new RequestOption();
|
let request = new RequestOption();
|
||||||
request.load('https://img-blog.csdnimg.cn/20191215043500229.png')
|
request.load('https://img-blog.csdnimg.cn/20191215043500229.png')
|
||||||
.setImageViewSize({ width: 300, height: 300 })
|
.setImageViewSize({ width: 300, height: 300 })
|
||||||
.addListener({callback:(err:BusinessError|string, data:ImageKnifeData) => {
|
.addListener({callback:(err:BusinessError|string, data:ImageKnifeData) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
console.log('预加载网络资源bmp 出现错误! err=' + err)
|
console.log('预加载网络资源bmp 出现错误! err=' + err)
|
||||||
} else {
|
} else {
|
||||||
console.log('预加载网络资源bmp成功! imageKnifedata=' + JSON.stringify(data))
|
console.log('预加载网络资源bmp成功! imageKnifedata=' + JSON.stringify(data))
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}})
|
}})
|
||||||
ImageKnifeGlobal.getInstance().getImageKnife()?.preload(request);
|
ImageKnifeGlobal.getInstance().getImageKnife()?.preload(request);
|
||||||
})
|
})
|
||||||
.margin({ left: 15 })
|
.margin({ left: 15 })
|
||||||
.backgroundColor(Color.Grey)
|
.backgroundColor(Color.Grey)
|
||||||
|
|
||||||
Button('网络资源png')
|
Button('网络资源png')
|
||||||
.onClick(() => {
|
.onClick(() => {
|
||||||
this.imageKnifeOption5 = {
|
this.imageKnifeOption5 = {
|
||||||
loadSrc: 'https://img-blog.csdnimg.cn/20191215043500229.png',
|
loadSrc: 'https://img-blog.csdnimg.cn/20191215043500229.png',
|
||||||
|
|
||||||
placeholderSrc: $r('app.media.icon_loading'),
|
placeholderSrc: $r('app.media.icon_loading'),
|
||||||
errorholderSrc: $r('app.media.icon_failed'),
|
errorholderSrc: $r('app.media.icon_failed'),
|
||||||
|
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
.margin({ left: 15 })
|
.margin({ left: 15 })
|
||||||
.backgroundColor(Color.Grey)
|
.backgroundColor(Color.Grey)
|
||||||
}
|
}
|
||||||
|
@ -557,27 +557,27 @@ struct TestPreloadPage {
|
||||||
if (err) {
|
if (err) {
|
||||||
console.log('预加载本地资源jpg 出现错误! err=' + err)
|
console.log('预加载本地资源jpg 出现错误! err=' + err)
|
||||||
} else {
|
} else {
|
||||||
console.log('预加载本地资源jpg成功! imageKnifedata=' + JSON.stringify(data))
|
console.log('预加载本地资源jpg成功! imageKnifedata=' + JSON.stringify(data))
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}})
|
}})
|
||||||
ImageKnifeGlobal.getInstance().getImageKnife()?.preload(request);
|
ImageKnifeGlobal.getInstance().getImageKnife()?.preload(request);
|
||||||
})
|
})
|
||||||
.margin({ left: 15 })
|
.margin({ left: 15 })
|
||||||
.backgroundColor(Color.Grey)
|
.backgroundColor(Color.Grey)
|
||||||
|
|
||||||
|
|
||||||
Button('本地资源jpg')
|
Button('本地资源jpg')
|
||||||
.onClick(() => {
|
.onClick(() => {
|
||||||
this.imageKnifeOption6 = {
|
this.imageKnifeOption6 = {
|
||||||
loadSrc: $r('app.media.jpgSample'),
|
loadSrc: $r('app.media.jpgSample'),
|
||||||
|
|
||||||
placeholderSrc: $r('app.media.icon_loading'),
|
placeholderSrc: $r('app.media.icon_loading'),
|
||||||
errorholderSrc: $r('app.media.icon_failed'),
|
errorholderSrc: $r('app.media.icon_failed'),
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
})
|
})
|
||||||
.margin({ left: 15 })
|
.margin({ left: 15 })
|
||||||
.backgroundColor(Color.Grey)
|
.backgroundColor(Color.Grey)
|
||||||
|
|
||||||
|
@ -589,32 +589,32 @@ struct TestPreloadPage {
|
||||||
|
|
||||||
Button('预加载网络资源jpg')
|
Button('预加载网络资源jpg')
|
||||||
.onClick(() => {
|
.onClick(() => {
|
||||||
let request = new RequestOption();
|
let request = new RequestOption();
|
||||||
request.load('https://hbimg.huabanimg.com/cc6af25f8d782d3cf3122bef4e61571378271145735e9-vEVggB')
|
request.load('https://hbimg.huabanimg.com/cc6af25f8d782d3cf3122bef4e61571378271145735e9-vEVggB')
|
||||||
.setImageViewSize({ width: 300, height: 300 })
|
.setImageViewSize({ width: 300, height: 300 })
|
||||||
.addListener({callback:(err:BusinessError|string, data:ImageKnifeData) => {
|
.addListener({callback:(err:BusinessError|string, data:ImageKnifeData) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
console.log('预加载网络资源jpg 出现错误! err=' + err)
|
console.log('预加载网络资源jpg 出现错误! err=' + err)
|
||||||
} else {
|
} else {
|
||||||
console.log('预加载网络资源jpg成功! imageknifedata=' + JSON.stringify(data))
|
console.log('预加载网络资源jpg成功! imageknifedata=' + JSON.stringify(data))
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}})
|
}})
|
||||||
ImageKnifeGlobal.getInstance().getImageKnife()?.preload(request);
|
ImageKnifeGlobal.getInstance().getImageKnife()?.preload(request);
|
||||||
})
|
})
|
||||||
.margin({ left: 15 })
|
.margin({ left: 15 })
|
||||||
.backgroundColor(Color.Grey)
|
.backgroundColor(Color.Grey)
|
||||||
|
|
||||||
Button('网络资源jpg')
|
Button('网络资源jpg')
|
||||||
.onClick(() => {
|
.onClick(() => {
|
||||||
this.imageKnifeOption6 = {
|
this.imageKnifeOption6 = {
|
||||||
loadSrc: 'https://hbimg.huabanimg.com/cc6af25f8d782d3cf3122bef4e61571378271145735e9-vEVggB',
|
loadSrc: 'https://hbimg.huabanimg.com/cc6af25f8d782d3cf3122bef4e61571378271145735e9-vEVggB',
|
||||||
|
|
||||||
placeholderSrc: $r('app.media.icon_loading'),
|
placeholderSrc: $r('app.media.icon_loading'),
|
||||||
errorholderSrc: $r('app.media.icon_failed'),
|
errorholderSrc: $r('app.media.icon_failed'),
|
||||||
|
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
.margin({ left: 15 })
|
.margin({ left: 15 })
|
||||||
.backgroundColor(Color.Grey)
|
.backgroundColor(Color.Grey)
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,188 @@
|
||||||
|
/*
|
||||||
|
* 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, Priority, NONE, ImageKnifeGlobal } from '@ohos/libraryimageknife';
|
||||||
|
const dataBak: ImageKnifeOption[] = [
|
||||||
|
{
|
||||||
|
loadSrc: "http://b.hiphotos.baidu.com/image/pic/item/9d82d158ccbf6c81b94575cfb93eb13533fa40a2.jpg",
|
||||||
|
priority: Priority.HIGH
|
||||||
|
},
|
||||||
|
{
|
||||||
|
loadSrc: "http://e.hiphotos.baidu.com/image/pic/item/4bed2e738bd4b31c1badd5a685d6277f9e2ff81e.jpg",
|
||||||
|
priority: Priority.HIGH
|
||||||
|
},
|
||||||
|
{
|
||||||
|
loadSrc: "http://g.hiphotos.baidu.com/image/pic/item/0d338744ebf81a4c87a3add4d52a6059252da61e.jpg",
|
||||||
|
priority: Priority.HIGH
|
||||||
|
},
|
||||||
|
{
|
||||||
|
loadSrc: "http://a.hiphotos.baidu.com/image/pic/item/f2deb48f8c5494ee5080c8142ff5e0fe99257e19.jpg",
|
||||||
|
priority: Priority.HIGH
|
||||||
|
},
|
||||||
|
{
|
||||||
|
loadSrc: "http://f.hiphotos.baidu.com/image/pic/item/4034970a304e251f503521f5a586c9177e3e53f9.jpg",
|
||||||
|
priority: Priority.HIGH
|
||||||
|
},
|
||||||
|
{
|
||||||
|
loadSrc: "https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658",
|
||||||
|
priority: Priority.MEDIUM
|
||||||
|
},
|
||||||
|
{
|
||||||
|
loadSrc: "http://h.hiphotos.baidu.com/image/pic/item/7c1ed21b0ef41bd5f2c2a9e953da81cb39db3d1d.jpg",
|
||||||
|
priority: Priority.MEDIUM
|
||||||
|
},
|
||||||
|
{
|
||||||
|
loadSrc: "http://a.hiphotos.baidu.com/image/pic/item/8d5494eef01f3a292d2472199d25bc315d607c7c.jpg",
|
||||||
|
priority: Priority.MEDIUM
|
||||||
|
},
|
||||||
|
{
|
||||||
|
loadSrc: "https://img-blog.csdn.net/20140514114029140",
|
||||||
|
priority: Priority.MEDIUM
|
||||||
|
},
|
||||||
|
{
|
||||||
|
loadSrc: "http://g.hiphotos.baidu.com/image/pic/item/6d81800a19d8bc3e770bd00d868ba61ea9d345f2.jpg",
|
||||||
|
priority: Priority.MEDIUM
|
||||||
|
},
|
||||||
|
{
|
||||||
|
loadSrc: "http://b.hiphotos.baidu.com/image/pic/item/e824b899a9014c08878b2c4c0e7b02087af4f4a3.jpg",
|
||||||
|
priority: Priority.LOW
|
||||||
|
},
|
||||||
|
{
|
||||||
|
loadSrc: "http://b.hiphotos.baidu.com/image/pic/item/359b033b5bb5c9ea5c0e3c23d139b6003bf3b374.jpg",
|
||||||
|
priority: Priority.LOW
|
||||||
|
},
|
||||||
|
{
|
||||||
|
loadSrc: "http://h.hiphotos.baidu.com/image/pic/item/902397dda144ad340668b847d4a20cf430ad851e.jpg",
|
||||||
|
priority: Priority.LOW
|
||||||
|
},
|
||||||
|
{
|
||||||
|
loadSrc: "http://d.hiphotos.baidu.com/image/pic/item/b58f8c5494eef01f119945cbe2fe9925bc317d2a.jpg",
|
||||||
|
priority: Priority.LOW
|
||||||
|
},
|
||||||
|
{
|
||||||
|
loadSrc:"http://img2.xkhouse.com/bbs/hfhouse/data/attachment/forum/corebbs/2009-11/2009113011534566298.jpg",
|
||||||
|
priority: Priority.LOW
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
@Entry
|
||||||
|
@Component
|
||||||
|
struct TestPriorityComponent {
|
||||||
|
@State data: ImageKnifeOption[] = [
|
||||||
|
{
|
||||||
|
loadSrc: "https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658",
|
||||||
|
priority: Priority.HIGH
|
||||||
|
},
|
||||||
|
{
|
||||||
|
loadSrc: "http://c.hiphotos.baidu.com/image/pic/item/30adcbef76094b36de8a2fe5a1cc7cd98d109d99.jpg",
|
||||||
|
priority: Priority.HIGH
|
||||||
|
},
|
||||||
|
{
|
||||||
|
loadSrc: "http://h.hiphotos.baidu.com/image/pic/item/7c1ed21b0ef41bd5f2c2a9e953da81cb39db3d1d.jpg",
|
||||||
|
priority: Priority.HIGH
|
||||||
|
},
|
||||||
|
{
|
||||||
|
loadSrc: "http://g.hiphotos.baidu.com/image/pic/item/55e736d12f2eb938d5277fd5d0628535e5dd6f4a.jpg",
|
||||||
|
priority: Priority.HIGH
|
||||||
|
},
|
||||||
|
{
|
||||||
|
loadSrc: "http://e.hiphotos.baidu.com/image/pic/item/4e4a20a4462309f7e41f5cfe760e0cf3d6cad6ee.jpg",
|
||||||
|
priority: Priority.HIGH
|
||||||
|
},
|
||||||
|
{
|
||||||
|
loadSrc: "http://b.hiphotos.baidu.com/image/pic/item/279759ee3d6d55fbb3586c0168224f4a20a4dd7e.jpg",
|
||||||
|
priority: Priority.MEDIUM
|
||||||
|
},
|
||||||
|
{
|
||||||
|
loadSrc: "http://img2.xkhouse.com/bbs/hfhouse/data/attachment/forum/corebbs/2009-11/2009113011534566298.jpg",
|
||||||
|
priority: Priority.MEDIUM
|
||||||
|
},
|
||||||
|
{
|
||||||
|
loadSrc: "http://a.hiphotos.baidu.com/image/pic/item/e824b899a9014c087eb617650e7b02087af4f464.jpg",
|
||||||
|
priority: Priority.MEDIUM
|
||||||
|
},
|
||||||
|
{
|
||||||
|
loadSrc: "http://c.hiphotos.baidu.com/image/pic/item/9c16fdfaaf51f3de1e296fa390eef01f3b29795a.jpg",
|
||||||
|
priority: Priority.MEDIUM
|
||||||
|
},
|
||||||
|
{
|
||||||
|
loadSrc: "http://d.hiphotos.baidu.com/image/pic/item/b58f8c5494eef01f119945cbe2fe9925bc317d2a.jpg",
|
||||||
|
priority: Priority.MEDIUM
|
||||||
|
},
|
||||||
|
{
|
||||||
|
loadSrc: "https://hbimg.huabanimg.com/cc6af25f8d782d3cf3122bef4e61571378271145735e9-vEVggB",
|
||||||
|
priority: Priority.LOW
|
||||||
|
},
|
||||||
|
{
|
||||||
|
loadSrc: "https://img-blog.csdnimg.cn/20191215043500229.png",
|
||||||
|
priority: Priority.LOW
|
||||||
|
},
|
||||||
|
{
|
||||||
|
loadSrc: "https://img-blog.csdn.net/20140514114029140",
|
||||||
|
priority: Priority.LOW
|
||||||
|
},
|
||||||
|
{
|
||||||
|
loadSrc: "https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp",
|
||||||
|
priority: Priority.LOW
|
||||||
|
},
|
||||||
|
{
|
||||||
|
loadSrc: "http://g.hiphotos.baidu.com/image/pic/item/6d81800a19d8bc3e770bd00d868ba61ea9d345f2.jpg",
|
||||||
|
priority: Priority.LOW
|
||||||
|
}
|
||||||
|
];
|
||||||
|
@State maxRequests: number | undefined = ImageKnifeGlobal?.getInstance()?.getImageKnife()?.maxRequests;
|
||||||
|
|
||||||
|
build() {
|
||||||
|
Scroll() {
|
||||||
|
Column() {
|
||||||
|
Text('最大并发数: ' + this.maxRequests).width('50%').height(30)
|
||||||
|
Button('修改最大并发数为1').width('50%').height(30)
|
||||||
|
.onClick(() => {
|
||||||
|
if (ImageKnifeGlobal?.getInstance()?.getImageKnife()) {
|
||||||
|
ImageKnifeGlobal?.getInstance()?.getImageKnife()?.setMaxRequests(1);
|
||||||
|
this.maxRequests = ImageKnifeGlobal?.getInstance()?.getImageKnife()?.maxRequests;
|
||||||
|
this.data = [...dataBak, ...dataBak, ...dataBak];
|
||||||
|
}
|
||||||
|
})
|
||||||
|
Grid() {
|
||||||
|
ForEach(this.data, (item: ImageKnifeOption, index: number) => {
|
||||||
|
GridItem() {
|
||||||
|
Flex() {
|
||||||
|
Text(item?.priority?.toString() || '')
|
||||||
|
ImageKnifeComponent({
|
||||||
|
imageKnifeOption: {
|
||||||
|
loadSrc: item.loadSrc,
|
||||||
|
placeholderSrc: $r('app.media.icon_loading'),
|
||||||
|
strategy: new NONE(),
|
||||||
|
isCacheable: false,
|
||||||
|
priority: item.priority
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}.height(60)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
.width("100%")
|
||||||
|
.height("100%")
|
||||||
|
.columnsTemplate("1fr 1fr 1fr 1fr 1fr")
|
||||||
|
.columnsGap(10)
|
||||||
|
.rowsGap(10)
|
||||||
|
.backgroundColor(0xFAEEE0)
|
||||||
|
.maxCount(10)
|
||||||
|
}
|
||||||
|
.backgroundColor(Color.Pink)
|
||||||
|
.margin({ top: 5 })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,204 @@
|
||||||
|
/*
|
||||||
|
* 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 BasicDataSource implements IDataSource {
|
||||||
|
private listeners: DataChangeListener[] = [];
|
||||||
|
private originDataArray: StringData[] = [];
|
||||||
|
|
||||||
|
public totalCount(): number {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getData(index: number): StringData {
|
||||||
|
return this.originDataArray[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
registerDataChangeListener(listener: DataChangeListener): void {
|
||||||
|
if (this.listeners.indexOf(listener) < 0) {
|
||||||
|
console.info('add listener');
|
||||||
|
this.listeners.push(listener);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unregisterDataChangeListener(listener: DataChangeListener): void {
|
||||||
|
const pos = this.listeners.indexOf(listener);
|
||||||
|
if (pos >= 0) {
|
||||||
|
console.info('remove listener');
|
||||||
|
this.listeners.splice(pos, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
notifyDataReload(): void {
|
||||||
|
this.listeners.forEach(listener => {
|
||||||
|
listener.onDataReloaded();
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
notifyDataAdd(index: number): void {
|
||||||
|
this.listeners.forEach(listener => {
|
||||||
|
listener.onDataAdd(index);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
notifyDataChange(index: number): void {
|
||||||
|
this.listeners.forEach(listener => {
|
||||||
|
listener.onDataChange(index);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
notifyDataDelete(index: number): void {
|
||||||
|
this.listeners.forEach(listener => {
|
||||||
|
listener.onDataDelete(index);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
notifyDataMove(from: number, to: number): void {
|
||||||
|
this.listeners.forEach(listener => {
|
||||||
|
listener.onDataMove(from, to);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class MyDataSource extends BasicDataSource {
|
||||||
|
private dataArray: StringData[] = [];
|
||||||
|
|
||||||
|
public totalCount(): number {
|
||||||
|
return this.dataArray.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getData(index: number): StringData {
|
||||||
|
return this.dataArray[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
public addData(index: number, data: StringData): void {
|
||||||
|
this.dataArray.splice(index, 0, data);
|
||||||
|
this.notifyDataAdd(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
public pushData(data: StringData): void {
|
||||||
|
this.dataArray.push(data);
|
||||||
|
this.notifyDataAdd(this.dataArray.length - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public reloadData(): void {
|
||||||
|
this.notifyDataReload();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class StringData {
|
||||||
|
message: string;
|
||||||
|
imgSrc: string;
|
||||||
|
|
||||||
|
constructor(message: string, imgSrc: string) {
|
||||||
|
this.message = message;
|
||||||
|
this.imgSrc = imgSrc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Entry
|
||||||
|
@Component
|
||||||
|
struct TestReuseAbleComponent {
|
||||||
|
@State dataArray: 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",
|
||||||
|
"https://hbimg.huabanimg.com/cc6af25f8d782d3cf3122bef4e61571378271145735e9-vEVggB",
|
||||||
|
'https://img-blog.csdnimg.cn/20191215043500229.png',
|
||||||
|
'https://img-blog.csdn.net/20140514114029140',
|
||||||
|
'https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp'
|
||||||
|
]
|
||||||
|
private data: MyDataSource = new MyDataSource();
|
||||||
|
private index: number = 0
|
||||||
|
private timeId: number = -1
|
||||||
|
|
||||||
|
aboutToAppear() {
|
||||||
|
for (let i = 0; i <= 4; i++) {
|
||||||
|
this.data.pushData(new StringData(`Hello ${i}`, this.dataArray[i]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
build() {
|
||||||
|
List({ space: 3 }) {
|
||||||
|
LazyForEach(this.data, (item: StringData, index: number) => {
|
||||||
|
ListItem() {
|
||||||
|
Column() {
|
||||||
|
Text(item.message).fontSize(50)
|
||||||
|
.onAppear(() => {
|
||||||
|
console.info("appear:" + item.message)
|
||||||
|
})
|
||||||
|
ReusableComponent({ url: item.imgSrc })
|
||||||
|
.width(500)
|
||||||
|
.height(200)
|
||||||
|
}.margin({ left: 10, right: 10 })
|
||||||
|
}
|
||||||
|
.onClick(() => {
|
||||||
|
item.message += '00';
|
||||||
|
this.data.reloadData();
|
||||||
|
})
|
||||||
|
}, (item: StringData, index: number) => JSON.stringify(item))
|
||||||
|
}.cachedCount(5)
|
||||||
|
.onReachEnd(()=>{
|
||||||
|
clearTimeout(this.timeId)
|
||||||
|
this.timeId = setTimeout(()=>{
|
||||||
|
this.data.reloadData()
|
||||||
|
if(this.data.totalCount() <= this.dataArray.length) {
|
||||||
|
this.index = this.data.totalCount()
|
||||||
|
for (let index = this.index; index <= this.index + 4; index++) {
|
||||||
|
this.data.addData(index,new StringData(`Hello ${index}`, this.dataArray[index]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},1500)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Reusable
|
||||||
|
@Component
|
||||||
|
struct ReusableComponent {
|
||||||
|
@State url: string = ""
|
||||||
|
|
||||||
|
aboutToReuse(params: Record<string, string>) {
|
||||||
|
this.url = params.url
|
||||||
|
}
|
||||||
|
|
||||||
|
build() {
|
||||||
|
Column() {
|
||||||
|
ImageKnifeComponent({
|
||||||
|
imageKnifeOption: {
|
||||||
|
loadSrc: this.url,
|
||||||
|
placeholderSrc: $r('app.media.icon_loading')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}.width("100%").height("100%")
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,203 @@
|
||||||
|
/*
|
||||||
|
* 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, ScaleType } from '@ohos/libraryimageknife'
|
||||||
|
|
||||||
|
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
|
||||||
|
@Component
|
||||||
|
struct TestReusePhotoPage {
|
||||||
|
@State hotCommendList: CommonDataSource<string> = new CommonDataSource<string>([])
|
||||||
|
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",
|
||||||
|
"https://hbimg.huabanimg.com/cc6af25f8d782d3cf3122bef4e61571378271145735e9-vEVggB",
|
||||||
|
'https://img-blog.csdnimg.cn/20191215043500229.png',
|
||||||
|
'https://img-blog.csdn.net/20140514114029140',
|
||||||
|
'https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp'
|
||||||
|
]
|
||||||
|
|
||||||
|
aboutToAppear() {
|
||||||
|
this.hotCommendList.addData(this.hotCommendList.totalCount(), this.data)
|
||||||
|
AppStorage.set("image_size",1)
|
||||||
|
}
|
||||||
|
|
||||||
|
build() {
|
||||||
|
Column() {
|
||||||
|
Button("up").onClick(()=>{
|
||||||
|
AppStorage.set("image_size",1.6)
|
||||||
|
})
|
||||||
|
Button("down").onClick(()=>{
|
||||||
|
AppStorage.set("image_size",0.9)
|
||||||
|
})
|
||||||
|
List() {
|
||||||
|
LazyForEach(this.hotCommendList, (item: string) => {
|
||||||
|
ListItem() {
|
||||||
|
ReuseComponent({ url: item }).width("100%").height("100%")
|
||||||
|
}.width(200).height(200).backgroundColor(Color.Orange)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
.width("100%")
|
||||||
|
.height("100%")
|
||||||
|
.backgroundColor(0xFAEEE0)
|
||||||
|
}.width("100%").height("100%")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Reusable
|
||||||
|
@Component
|
||||||
|
struct ReuseComponent {
|
||||||
|
@Prop url: string = ""
|
||||||
|
imgSize: number = 100
|
||||||
|
@StorageProp("image_size") @Watch("updateImageSize") image_size: number = 0
|
||||||
|
scaleAble: boolean = true
|
||||||
|
@State calcImgSize: number = 100
|
||||||
|
aboutToReuse(params: Record<string, string>) {
|
||||||
|
this.url = params.url
|
||||||
|
}
|
||||||
|
aboutToAppear(){
|
||||||
|
this.setImageSize()
|
||||||
|
}
|
||||||
|
updateImageSize() {
|
||||||
|
this.setImageSize()
|
||||||
|
}
|
||||||
|
|
||||||
|
setImageSize() {
|
||||||
|
if (!this.scaleAble) {
|
||||||
|
this.calcImgSize = this.imgSize
|
||||||
|
} else if (this.image_size < 0.9) {
|
||||||
|
this.calcImgSize = this.imgSize * 0.9
|
||||||
|
} else if (this.image_size > 1.6) {
|
||||||
|
this.calcImgSize = this.imgSize * 1.6
|
||||||
|
} else {
|
||||||
|
this.calcImgSize = this.imgSize * this.image_size
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
build() {
|
||||||
|
Column() {
|
||||||
|
ImageKnifeComponent({
|
||||||
|
imageKnifeOption:{
|
||||||
|
loadSrc: this.url,
|
||||||
|
mainScaleType: ScaleType.FIT_XY,
|
||||||
|
placeholderSrc: $r('app.media.icon_loading'),
|
||||||
|
placeholderScaleType: ScaleType.FIT_XY,
|
||||||
|
errorholderSrc: $r('app.media.icon_failed'),
|
||||||
|
errorholderSrcScaleType: ScaleType.FIT_XY
|
||||||
|
}
|
||||||
|
}).width(this.calcImgSize).height(this.calcImgSize)
|
||||||
|
}.width("100%").height("100%")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Component
|
||||||
|
struct PhotoComponent {
|
||||||
|
@Watch("updateTheUrl") @Prop url: string = ""
|
||||||
|
imgSize: number = 100
|
||||||
|
@State imageKnifeOption: ImageKnifeOption = new ImageKnifeOption()
|
||||||
|
@StorageProp("image_size") @Watch("updateImageSize") image_size: number = 0
|
||||||
|
scaleAble: boolean = true
|
||||||
|
@State calcImgSize: number = 100
|
||||||
|
|
||||||
|
updateImageSize() {
|
||||||
|
this.setImageSize()
|
||||||
|
}
|
||||||
|
|
||||||
|
setImageSize() {
|
||||||
|
if (!this.scaleAble) {
|
||||||
|
this.calcImgSize = this.imgSize
|
||||||
|
} else if (this.image_size < 0.9) {
|
||||||
|
this.calcImgSize = this.imgSize * 0.9
|
||||||
|
} else if (this.image_size > 1.6) {
|
||||||
|
this.calcImgSize = this.imgSize * 1.6
|
||||||
|
} else {
|
||||||
|
this.calcImgSize = this.imgSize * this.image_size
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
updateTheUrl() {
|
||||||
|
this.imageKnifeOption = {
|
||||||
|
loadSrc: this.url,
|
||||||
|
mainScaleType: ScaleType.FIT_XY,
|
||||||
|
placeholderSrc: $r('app.media.icon_loading'),
|
||||||
|
placeholderScaleType: ScaleType.FIT_XY,
|
||||||
|
errorholderSrc: $r('app.media.icon_failed'),
|
||||||
|
errorholderSrcScaleType: ScaleType.FIT_XY
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
build() {
|
||||||
|
Column() {
|
||||||
|
ImageKnifeComponent({ imageKnifeOption: this.imageKnifeOption })
|
||||||
|
}.width(this.calcImgSize).height(this.calcImgSize)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,75 @@
|
||||||
|
/*
|
||||||
|
* 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 { ImageKnifeOption } from '@ohos/libraryimageknife'
|
||||||
|
import display from '@ohos.display';
|
||||||
|
|
||||||
|
@Entry
|
||||||
|
@Component
|
||||||
|
struct TestStopPlayingGifPage {
|
||||||
|
@State message: string = 'gif暂停播放测试'
|
||||||
|
@State eventType: string = '';
|
||||||
|
@State options: ImageKnifeOption = {
|
||||||
|
loadSrc: $r('app.media.app_icon'),
|
||||||
|
}
|
||||||
|
|
||||||
|
build() {
|
||||||
|
Column() {
|
||||||
|
Column() {
|
||||||
|
Text(`${this.message}`)
|
||||||
|
.width("300vp")
|
||||||
|
.height("60vp")
|
||||||
|
.textAlign(TextAlign.Center)
|
||||||
|
.fontSize("30fp")
|
||||||
|
.fontWeight(FontWeight.Bold)
|
||||||
|
Button("加载gif图")
|
||||||
|
.margin(16)
|
||||||
|
.onClick(() => {
|
||||||
|
console.log("加载多帧gif")
|
||||||
|
this.options = {
|
||||||
|
loadSrc: $r('app.media.gifSample'),
|
||||||
|
placeholderSrc:$r('app.media.icon_loading'),
|
||||||
|
}
|
||||||
|
})
|
||||||
|
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
||||||
|
Text("控制")
|
||||||
|
Button("开启")
|
||||||
|
.onClick(() => {
|
||||||
|
this.options.autoPlay = true;
|
||||||
|
}).margin({ left: 3 })
|
||||||
|
|
||||||
|
Button("暂停")
|
||||||
|
.onClick(() => {
|
||||||
|
this.options.autoPlay = false;
|
||||||
|
}).margin({ left: 3 })
|
||||||
|
}.width('100%')
|
||||||
|
.height(40).backgroundColor(Color.Pink).margin({bottom:5})
|
||||||
|
ImageKnifeComponent({ imageKnifeOption: this.options })
|
||||||
|
.margin(16)
|
||||||
|
.width(300)
|
||||||
|
.height(300)
|
||||||
|
}
|
||||||
|
.width("100%")
|
||||||
|
.height("100%")
|
||||||
|
.justifyContent(FlexAlign.Center)
|
||||||
|
}
|
||||||
|
.width("100%")
|
||||||
|
.height("100%")
|
||||||
|
}
|
||||||
|
aboutToAppear() {
|
||||||
|
console.log('CTT:TestManyNetImageLoadWithPage display Height: '+ display.getDefaultDisplaySync().height)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -406,7 +406,7 @@ struct TransformPixelMapPage {
|
||||||
.width(120)
|
.width(120)
|
||||||
.margin({ top: 10 })
|
.margin({ top: 10 })
|
||||||
.onClick(() => {
|
.onClick(() => {
|
||||||
this.blurHandlePixelMap(20);
|
this.blurHandlePixelMap(20,3);
|
||||||
});
|
});
|
||||||
Image(this.mBlurPixelMap==undefined?'':this.mBlurPixelMap!)
|
Image(this.mBlurPixelMap==undefined?'':this.mBlurPixelMap!)
|
||||||
.objectFit(ImageFit.Fill)
|
.objectFit(ImageFit.Fill)
|
||||||
|
@ -847,9 +847,9 @@ struct TransformPixelMapPage {
|
||||||
/**
|
/**
|
||||||
*模糊
|
*模糊
|
||||||
*/
|
*/
|
||||||
blurHandlePixelMap(radius: number) {
|
blurHandlePixelMap(radius: number,sampling: number) {
|
||||||
let imageKnifeOption = new RequestOption();
|
let imageKnifeOption = new RequestOption();
|
||||||
let transformation = new BlurTransformation(radius);
|
let transformation = new BlurTransformation(radius,sampling);
|
||||||
imageKnifeOption.load(mUrl)
|
imageKnifeOption.load(mUrl)
|
||||||
.addListener({callback:(err:BusinessError|string, data:ImageKnifeData) => {
|
.addListener({callback:(err:BusinessError|string, data:ImageKnifeData) => {
|
||||||
|
|
||||||
|
@ -860,7 +860,7 @@ struct TransformPixelMapPage {
|
||||||
.setImageViewSize({ width: vp2px(200), height: vp2px(200) })
|
.setImageViewSize({ width: vp2px(200), height: vp2px(200) })
|
||||||
.skipMemoryCache(true)
|
.skipMemoryCache(true)
|
||||||
.enableGPU()
|
.enableGPU()
|
||||||
.blur(radius)
|
.blur(radius,sampling)
|
||||||
ImageKnife?.call(imageKnifeOption);
|
ImageKnife?.call(imageKnifeOption);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,69 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2021 Huawei Device Co., Ltd.
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
import { ImageKnifeComponent } from '@ohos/libraryimageknife'
|
||||||
|
import { ImageKnifeOption,ScaleType } from '@ohos/libraryimageknife'
|
||||||
|
|
||||||
|
@Entry
|
||||||
|
@Component
|
||||||
|
struct webpImageTestPage {
|
||||||
|
@State message: string = 'webp图片'
|
||||||
|
@State options: ImageKnifeOption = {
|
||||||
|
loadSrc: $r('app.media.app_icon')
|
||||||
|
}
|
||||||
|
|
||||||
|
build() {
|
||||||
|
Column() {
|
||||||
|
Column() {
|
||||||
|
Text(`${this.message}`)
|
||||||
|
.width("300vp")
|
||||||
|
.height("60vp")
|
||||||
|
.textAlign(TextAlign.Center)
|
||||||
|
.fontSize("50fp")
|
||||||
|
.fontWeight(FontWeight.Bold)
|
||||||
|
Button("加载单帧webp")
|
||||||
|
.margin(16)
|
||||||
|
.onClick(() => {
|
||||||
|
console.log("加载单帧webp")
|
||||||
|
this.options = {
|
||||||
|
loadSrc: $r('app.media.webpSample'),
|
||||||
|
placeholderSrc:$r('app.media.icon_loading'),
|
||||||
|
mainScaleType:ScaleType.FIT_XY
|
||||||
|
}
|
||||||
|
})
|
||||||
|
Button("加载多帧webp")
|
||||||
|
.margin(16)
|
||||||
|
.onClick(() => {
|
||||||
|
console.log("加载多帧webp")
|
||||||
|
this.options = {
|
||||||
|
loadSrc: $r('app.media.webpAtanta'),
|
||||||
|
placeholderSrc:$r('app.media.icon_loading'),
|
||||||
|
mainScaleType:ScaleType.FIT_XY
|
||||||
|
}
|
||||||
|
})
|
||||||
|
ImageKnifeComponent({ imageKnifeOption: this.options })
|
||||||
|
.margin(16)
|
||||||
|
.width(200)
|
||||||
|
.height(100)
|
||||||
|
.clip(true)
|
||||||
|
.borderRadius(50)
|
||||||
|
}
|
||||||
|
.width("100%")
|
||||||
|
.height("100%")
|
||||||
|
.justifyContent(FlexAlign.Center)
|
||||||
|
}
|
||||||
|
.width("100%")
|
||||||
|
.height("100%")
|
||||||
|
}
|
||||||
|
}
|
|
@ -22,7 +22,7 @@
|
||||||
"abilities": [
|
"abilities": [
|
||||||
{
|
{
|
||||||
"name": "MainAbility",
|
"name": "MainAbility",
|
||||||
"srcEntrance": "./ets/entryability/EntryAbility.ets",
|
"srcEntry": "./ets/entryability/EntryAbility.ets",
|
||||||
"description": "$string:MainAbility_desc",
|
"description": "$string:MainAbility_desc",
|
||||||
"icon": "$media:icon",
|
"icon": "$media:icon",
|
||||||
"label": "$string:MainAbility_label",
|
"label": "$string:MainAbility_label",
|
||||||
|
@ -53,6 +53,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "ohos.permission.MEDIA_LOCATION",
|
"name": "ohos.permission.MEDIA_LOCATION",
|
||||||
|
"reason": "$string:app_permission_MEDIA_LOCATION",
|
||||||
"usedScene": {
|
"usedScene": {
|
||||||
"abilities": [
|
"abilities": [
|
||||||
"EntryAbility"
|
"EntryAbility"
|
||||||
|
@ -62,6 +63,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "ohos.permission.READ_MEDIA",
|
"name": "ohos.permission.READ_MEDIA",
|
||||||
|
"reason": "$string:app_permission_READ_MEDIA",
|
||||||
"usedScene": {
|
"usedScene": {
|
||||||
"abilities": [
|
"abilities": [
|
||||||
"EntryAbility"
|
"EntryAbility"
|
||||||
|
|
|
@ -112,6 +112,14 @@
|
||||||
{
|
{
|
||||||
"name": "image_pixel",
|
"name": "image_pixel",
|
||||||
"value": "马赛克处理"
|
"value": "马赛克处理"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "app_permission_MEDIA_LOCATION",
|
||||||
|
"value": "获取媒体图片"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "app_permission_READ_MEDIA",
|
||||||
|
"value": "读媒体图片"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
Binary file not shown.
After Width: | Height: | Size: 922 KiB |
Binary file not shown.
|
@ -12,11 +12,13 @@
|
||||||
"pages/showErrorholderTestCasePage",
|
"pages/showErrorholderTestCasePage",
|
||||||
"pages/transformPixelMapPage",
|
"pages/transformPixelMapPage",
|
||||||
"pages/testPreloadPage",
|
"pages/testPreloadPage",
|
||||||
|
"pages/testDiskPreLoadPage",
|
||||||
"pages/testImageKnifeOptionChangedPage",
|
"pages/testImageKnifeOptionChangedPage",
|
||||||
"pages/testImageKnifeOptionChangedPage2",
|
"pages/testImageKnifeOptionChangedPage2",
|
||||||
"pages/testImageKnifeOptionChangedPage3",
|
"pages/testImageKnifeOptionChangedPage3",
|
||||||
"pages/testImageKnifeOptionChangedPage4",
|
"pages/testImageKnifeOptionChangedPage4",
|
||||||
"pages/testImageKnifeOptionChangedPage5",
|
"pages/testImageKnifeOptionChangedPage5",
|
||||||
|
"pages/testGifPlayTimesPage",
|
||||||
"pages/compressPage",
|
"pages/compressPage",
|
||||||
"pages/testAllCacheInfoPage",
|
"pages/testAllCacheInfoPage",
|
||||||
"pages/cropImagePage2",
|
"pages/cropImagePage2",
|
||||||
|
@ -34,10 +36,26 @@
|
||||||
"pages/hspCacheTestPage",
|
"pages/hspCacheTestPage",
|
||||||
"pages/multiHspTestPage",
|
"pages/multiHspTestPage",
|
||||||
"pages/testManyNetImageLoadWithPage",
|
"pages/testManyNetImageLoadWithPage",
|
||||||
|
"pages/testManyNetImageLoadWithPage2",
|
||||||
"pages/testManyGifLoadWithPage",
|
"pages/testManyGifLoadWithPage",
|
||||||
"pages/testImageAntiAliasingWithPage",
|
"pages/testImageAntiAliasingWithPage",
|
||||||
"pages/testImageKnifeRouter1",
|
"pages/testImageKnifeRouter1",
|
||||||
"pages/testImageKnifeRouter2",
|
"pages/testImageKnifeRouter2",
|
||||||
"pages/RequestOptionLoadImage"
|
"pages/RequestOptionLoadImage",
|
||||||
|
"pages/testImageKnifeHttpRequestHeader",
|
||||||
|
"pages/testImageKnifeHttpRequestHeader1",
|
||||||
|
"pages/testImageKnifeAutoPage",
|
||||||
|
"pages/testImageKnifeAutoWidthPage",
|
||||||
|
"pages/testImageKnifeAutoHeightPage",
|
||||||
|
"pages/testPriorityComponent",
|
||||||
|
"pages/testReusePhotoPage",
|
||||||
|
"pages/testImageKnifeCache",
|
||||||
|
"pages/webpImageTestPage",
|
||||||
|
"pages/testStopPlayingGifPage",
|
||||||
|
"pages/testImageKnifeDataFetch",
|
||||||
|
"pages/testImageKnifeHeic",
|
||||||
|
"pages/testImageKnifeNetPlaceholder",
|
||||||
|
"pages/testCustomDataFetchClientWithPage",
|
||||||
|
"pages/testReuseAblePages"
|
||||||
]
|
]
|
||||||
}
|
}
|
|
@ -0,0 +1,64 @@
|
||||||
|
/*
|
||||||
|
* 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, it, expect } from '@ohos/hypium';
|
||||||
|
import { ImageKnife, ImageKnifeGlobal, RequestOption } from '@ohos/imageknife/Index';
|
||||||
|
import { DefaultJobQueue } from '@ohos/imageknife/src/main/ets/components/imageknife/utils/DefaultJobQueue';
|
||||||
|
import { IJobQueue } from '@ohos/imageknife/src/main/ets/components/imageknife/utils/IJobQueue';
|
||||||
|
import taskpool from '@ohos.taskpool';
|
||||||
|
import common from '@ohos.app.ability.common';
|
||||||
|
|
||||||
|
export default function DefaultJobQueueTest() {
|
||||||
|
|
||||||
|
describe('DefaultJobQueueTest', () => {
|
||||||
|
it('testJob', 0, () => {
|
||||||
|
let job: IJobQueue = new DefaultJobQueue();
|
||||||
|
job.add(makeRequest("medium1", getContext() as common.UIAbilityContext));
|
||||||
|
job.add(makeRequest("medium2", getContext() as common.UIAbilityContext, taskpool.Priority.MEDIUM));
|
||||||
|
job.add(makeRequest("medium3", getContext() as common.UIAbilityContext));
|
||||||
|
job.add(makeRequest("low1", getContext() as common.UIAbilityContext, taskpool.Priority.LOW));
|
||||||
|
job.add(makeRequest("high1", getContext() as common.UIAbilityContext, taskpool.Priority.HIGH));
|
||||||
|
job.add(makeRequest("low2", getContext() as common.UIAbilityContext, taskpool.Priority.LOW));
|
||||||
|
job.add(makeRequest("medium4", getContext() as common.UIAbilityContext));
|
||||||
|
|
||||||
|
expect(job.getQueueLength()).assertEqual(7);
|
||||||
|
expect(job.pop()!.loadSrc).assertEqual("high1");
|
||||||
|
expect(job.pop()!.loadSrc).assertEqual("medium1");
|
||||||
|
expect(job.pop()!.loadSrc).assertEqual("medium2");
|
||||||
|
expect(job.pop()!.loadSrc).assertEqual("medium3");
|
||||||
|
expect(job.pop()!.loadSrc).assertEqual("medium4");
|
||||||
|
expect(job.pop()!.loadSrc).assertEqual("low1");
|
||||||
|
expect(job.pop()!.loadSrc).assertEqual("low2");
|
||||||
|
expect(job.pop()).assertEqual(undefined);
|
||||||
|
expect(job.getQueueLength()).assertEqual(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("testMaxRequests", 1, () => {
|
||||||
|
let imageKnife: ImageKnife | undefined = ImageKnifeGlobal.getInstance().getImageKnife();
|
||||||
|
if (imageKnife) {
|
||||||
|
expect(imageKnife.maxRequests).assertEqual(64);
|
||||||
|
imageKnife.setMaxRequests(10);
|
||||||
|
expect(imageKnife.maxRequests).assertEqual(10);
|
||||||
|
};
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function makeRequest(src: string, context: common.UIAbilityContext, priority: taskpool.Priority = taskpool.Priority.MEDIUM): RequestOption {
|
||||||
|
let request: RequestOption = new RequestOption()
|
||||||
|
request.loadSrc = src;
|
||||||
|
request.priority = priority;
|
||||||
|
request.moduleContext = context;
|
||||||
|
return request;
|
||||||
|
}
|
|
@ -15,15 +15,21 @@
|
||||||
import abilityTest from './Ability.test'
|
import abilityTest from './Ability.test'
|
||||||
import lruCacheTest from './lrucache.test'
|
import lruCacheTest from './lrucache.test'
|
||||||
import LogUtilTest from './logutil.test'
|
import LogUtilTest from './logutil.test'
|
||||||
import Transform from './transfrom.test'
|
import Transfrom from './transfrom.test'
|
||||||
import RequestOptionTest from './requestoption.test'
|
import RequestOptionTest from './requestoption.test'
|
||||||
import ImageKnifeTest from './imageknife.test'
|
import ImageKnifeTest from './imageknife.test'
|
||||||
|
import DiskLruCacheTest from './diskLruCache.test'
|
||||||
|
import SendableDataTest from './SendableData.test'
|
||||||
|
import DefaultJobQueueTest from './DefaultJobQueueTest.test';
|
||||||
|
|
||||||
export default function testsuite() {
|
export default function testsuite() {
|
||||||
abilityTest()
|
abilityTest()
|
||||||
lruCacheTest()
|
lruCacheTest()
|
||||||
|
DiskLruCacheTest()
|
||||||
LogUtilTest()
|
LogUtilTest()
|
||||||
Transform()
|
Transfrom()
|
||||||
RequestOptionTest()
|
RequestOptionTest()
|
||||||
ImageKnifeTest();
|
ImageKnifeTest();
|
||||||
|
SendableDataTest();
|
||||||
|
DefaultJobQueueTest();
|
||||||
}
|
}
|
|
@ -0,0 +1,52 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2024 Huawei Device Co., Ltd.
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
import { 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);
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
|
@ -0,0 +1,162 @@
|
||||||
|
/*
|
||||||
|
* 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 { DiskLruCache, DiskCacheEntry } from '@ohos/imageknife'
|
||||||
|
import { common } from '@kit.AbilityKit';
|
||||||
|
import fs from '@ohos.file.fs';
|
||||||
|
import { GlobalContext } from '../testability/GlobalContext'
|
||||||
|
|
||||||
|
const BASE_COUNT: number = 2000;
|
||||||
|
|
||||||
|
export default function DiskLruCacheTest() {
|
||||||
|
|
||||||
|
describe('DiskLruCacheTest', () => {
|
||||||
|
// Defines a test suite. Two parameters are supported: test suite name and test suite function.
|
||||||
|
beforeAll(() => {
|
||||||
|
//ImageKnife.with(this.context.createModuleContext("entry_test"));
|
||||||
|
// 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('testSetCahe', 0, () => {
|
||||||
|
let context: object | undefined = GlobalContext.getInstance().getObject("hapContext");
|
||||||
|
let disLruCache: DiskLruCache = DiskLruCache.create(context as common.UIAbilityContext, 1024);
|
||||||
|
let startTime = new Date().getTime();
|
||||||
|
disLruCache.set('test', "Hello World Simple Example.");
|
||||||
|
disLruCache.set('testABC', "Hello World ABC");
|
||||||
|
disLruCache.set('testDE', "Hello World Simple DE");
|
||||||
|
expect(String.fromCharCode(...new Uint8Array(disLruCache.get('test') as ArrayBufferLike)) == "Hello World Simple Example.")
|
||||||
|
.assertTrue()
|
||||||
|
expect(String.fromCharCode(...new Uint8Array(disLruCache.get('testABC') as ArrayBufferLike)) == "Hello World ABC")
|
||||||
|
.assertTrue()
|
||||||
|
expect(String.fromCharCode(...new Uint8Array(disLruCache.get('testDE') as ArrayBufferLike)) == "Hello World Simple DE")
|
||||||
|
.assertTrue()
|
||||||
|
let str: string = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa';
|
||||||
|
for (let index = 0; index < 100; index++) {
|
||||||
|
str += index;
|
||||||
|
disLruCache.set('test' + index, str);
|
||||||
|
}
|
||||||
|
expect(disLruCache.getSize() <= 1024).assertTrue()
|
||||||
|
endTime(startTime, 'testSetCahe');
|
||||||
|
disLruCache.cleanCacheData();
|
||||||
|
|
||||||
|
})
|
||||||
|
it('testGetCacheAsync', 1, () => {
|
||||||
|
let context: object | undefined = GlobalContext.getInstance().getObject("hapContext");
|
||||||
|
let filesDir: object | undefined = GlobalContext.getInstance().getObject("filesDir");
|
||||||
|
let cache: DiskLruCache = DiskLruCache.create(context as common.UIAbilityContext, 1024);
|
||||||
|
let startTime = new Date().getTime();
|
||||||
|
let path = filesDir + '/testFile.txt';
|
||||||
|
let file = fs.openSync(path, 0o102);
|
||||||
|
fs.writeSync(file.fd, "hello, world!");
|
||||||
|
let length = fs.statSync(path).size;
|
||||||
|
let dataArr = new ArrayBuffer(length);
|
||||||
|
fs.readSync(file.fd, dataArr);
|
||||||
|
cache.set('testFile', dataArr);
|
||||||
|
expect(cache.get('testFile')?.byteLength == 13).assertTrue()
|
||||||
|
endTime(startTime, 'testGetCacheAsync');
|
||||||
|
cache.cleanCacheData();
|
||||||
|
})
|
||||||
|
it('testDeleteCacheDataByKey', 2, () => {
|
||||||
|
let context: object | undefined = GlobalContext.getInstance().getObject("hapContext");
|
||||||
|
let cache: DiskLruCache = DiskLruCache.create(context as common.UIAbilityContext, 1024);
|
||||||
|
let startTime = new Date().getTime();
|
||||||
|
cache.set('test', "Hello World Simple Example.");
|
||||||
|
cache.set('testABC', "Hello World ABC");
|
||||||
|
expect(String.fromCharCode(...new Uint8Array(cache.get('test') as ArrayBufferLike)))
|
||||||
|
.assertEqual("Hello World Simple Example.");
|
||||||
|
expect(String.fromCharCode(...new Uint8Array(cache.get('testABC') as ArrayBufferLike)))
|
||||||
|
.assertEqual("Hello World ABC");
|
||||||
|
cache.deleteCacheDataByKey('test');
|
||||||
|
cache.deleteCacheDataByKey('testABC');
|
||||||
|
expect(String.fromCharCode(...new Uint8Array(cache.get('test') as ArrayBufferLike))).assertEqual('');
|
||||||
|
expect(String.fromCharCode(...new Uint8Array(cache.get('testABC') as ArrayBufferLike))).assertEqual('');
|
||||||
|
endTime(startTime, 'testDeleteCacheDataByKey');
|
||||||
|
cache.cleanCacheData();
|
||||||
|
})
|
||||||
|
it('testGetPath', 3, () => {
|
||||||
|
let context: object | undefined = GlobalContext.getInstance().getObject("hapContext");
|
||||||
|
let cache: DiskLruCache = DiskLruCache.create(context as common.UIAbilityContext, 1024);
|
||||||
|
let startTime = new Date().getTime();
|
||||||
|
cache.set('test', "Hello World Simple Example.");
|
||||||
|
let path: string = cache.getFileToPath('test');
|
||||||
|
expect(String.fromCharCode(...new Uint8Array(cache.get('test') as ArrayBufferLike)) == "Hello World Simple Example.")
|
||||||
|
.assertTrue()
|
||||||
|
expect(cache.getFileToPath('test') == path).assertTrue()
|
||||||
|
expect(cache.getPath() + cache.getCacheMap().getFirstKey() == path).assertTrue()
|
||||||
|
endTime(startTime, 'testGetPath');
|
||||||
|
cache.cleanCacheData();
|
||||||
|
})
|
||||||
|
it('testGetCacheMap', 6, () => {
|
||||||
|
let context: object | undefined = GlobalContext.getInstance().getObject("hapContext");
|
||||||
|
let cache: DiskLruCache = DiskLruCache.create(context as common.UIAbilityContext, 1024);
|
||||||
|
let startTime = new Date().getTime();
|
||||||
|
cache.set('test', "Hello World Simple Example.");
|
||||||
|
expect(cache.getCacheMap().getFirstKey() == '098f6bcd4621d373cade4e832627b4f6').assertTrue()
|
||||||
|
expect(cache.getCacheMap().hasKey('098f6bcd4621d373cade4e832627b4f6') == true).assertTrue()
|
||||||
|
endTime(startTime, 'testGetCacheMap');
|
||||||
|
cache.cleanCacheData();
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
it('testGetSize', 7, () => {
|
||||||
|
let context: object | undefined = GlobalContext.getInstance().getObject("hapContext");
|
||||||
|
let cache: DiskLruCache = DiskLruCache.create(context as common.UIAbilityContext, 1024);
|
||||||
|
let startTime = new Date().getTime();
|
||||||
|
cache.set('test', "Hello World Simple Example.");
|
||||||
|
expect(String.fromCharCode(...new Uint8Array(cache.get('test') as ArrayBufferLike)) == "Hello World Simple Example.")
|
||||||
|
.assertTrue()
|
||||||
|
expect(cache.getSize() == 27).assertTrue()
|
||||||
|
endTime(startTime, 'testGetSize');
|
||||||
|
cache.cleanCacheData();
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
it('testDiskCacheEntry', 8, () => {
|
||||||
|
let startTime = new Date().getTime();
|
||||||
|
let dentry = new DiskCacheEntry('test', 30 * 1024 * 1024)
|
||||||
|
expect(dentry.getKey() == 'test').assertTrue()
|
||||||
|
dentry.setKey('newtest')
|
||||||
|
expect(dentry.getKey() == 'newtest').assertTrue()
|
||||||
|
expect(dentry.getLength() == 30 * 1024 * 1024).assertTrue()
|
||||||
|
dentry.setLength(12 * 1024 * 1024)
|
||||||
|
expect(dentry.getLength() == 12 * 1024 * 1024).assertTrue()
|
||||||
|
expect(dentry.toString() == dentry.getKey() + ' - ' + dentry.getLength()).assertTrue()
|
||||||
|
endTime(startTime, 'testDiskCacheEntry');
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function endTime(startTime: number, tag: string) {
|
||||||
|
let endTime: number = new Date().getTime();
|
||||||
|
let averageTime = ((endTime - startTime) * 1000 / BASE_COUNT)
|
||||||
|
console.info(tag + " startTime: " + endTime)
|
||||||
|
console.info(tag + " endTime: " + endTime)
|
||||||
|
console.log(tag + " averageTime: " + averageTime + "μs");
|
||||||
|
}
|
|
@ -91,6 +91,18 @@ export default function RequestOptionTest() {
|
||||||
expect(option.loadThumbnailReady).assertFalse()
|
expect(option.loadThumbnailReady).assertFalse()
|
||||||
|
|
||||||
})
|
})
|
||||||
|
it('TestPlaceHolder', 4, () => {
|
||||||
|
let url: string = "https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658";
|
||||||
|
let option = new RequestOption();
|
||||||
|
option.placeholder(url);
|
||||||
|
expect(option.placeholderSrc).assertEqual(url);
|
||||||
|
})
|
||||||
|
it('TestFallBack', 5, () => {
|
||||||
|
let url: PixelMap | Resource = $r('app.media.icon_loading');
|
||||||
|
let option = new RequestOption();
|
||||||
|
option.fallback(url);
|
||||||
|
expect(JSON.stringify(option.fallbackSrc)).assertEqual(JSON.stringify(url));
|
||||||
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -64,11 +64,11 @@ export default function Transform() {
|
||||||
it('TestBlurTransformation', 0, ()=>{
|
it('TestBlurTransformation', 0, ()=>{
|
||||||
let startTime = new Date().getTime();
|
let startTime = new Date().getTime();
|
||||||
for (let index = 0; index < BASE_COUNT; index++) {
|
for (let index = 0; index < BASE_COUNT; index++) {
|
||||||
new BlurTransformation(15);
|
new BlurTransformation(15,3);
|
||||||
}
|
}
|
||||||
endTime(startTime, 'TestBlurTransformation');
|
endTime(startTime, 'TestBlurTransformation');
|
||||||
let blur = new BlurTransformation(15);
|
let blur = new BlurTransformation(15,3);
|
||||||
expect(blur.getName()).assertEqual('BlurTransformation _mRadius:15')
|
expect(blur.getName()).assertEqual('BlurTransformation _mRadius:15==BlurTransformation sampling:3')
|
||||||
})
|
})
|
||||||
it('TestBrightnessFilterTransformation', 1, ()=>{
|
it('TestBrightnessFilterTransformation', 1, ()=>{
|
||||||
let startTime = new Date().getTime();
|
let startTime = new Date().getTime();
|
||||||
|
@ -85,8 +85,8 @@ export default function Transform() {
|
||||||
new ContrastFilterTransformation(30);
|
new ContrastFilterTransformation(30);
|
||||||
}
|
}
|
||||||
endTime(startTime, 'TestContrastFilterTransformation');
|
endTime(startTime, 'TestContrastFilterTransformation');
|
||||||
let constrast = new ContrastFilterTransformation(30);
|
let contrast = new ContrastFilterTransformation(30);
|
||||||
expect(constrast.getName()).assertEqual("ContrastFilterTransformation:30")
|
expect(contrast.getName()).assertEqual("ContrastFilterTransformation:30")
|
||||||
})
|
})
|
||||||
it('TestCropCircleTransformation', 3, ()=>{
|
it('TestCropCircleTransformation', 3, ()=>{
|
||||||
let startTime = new Date().getTime();
|
let startTime = new Date().getTime();
|
||||||
|
|
|
@ -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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
export class GlobalContext {
|
||||||
|
private constructor() {
|
||||||
|
}
|
||||||
|
|
||||||
|
private static instance: GlobalContext;
|
||||||
|
private _objects = new Map<string, Object>();
|
||||||
|
|
||||||
|
public static getInstance(): GlobalContext {
|
||||||
|
if (!GlobalContext.instance) {
|
||||||
|
GlobalContext.instance = new GlobalContext();
|
||||||
|
}
|
||||||
|
return GlobalContext.instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
getObject(value: string): Object | undefined {
|
||||||
|
return this._objects.get(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
setObject(key: string, objectClass: Object): void {
|
||||||
|
this._objects.set(key, objectClass);
|
||||||
|
}
|
||||||
|
}
|
|
@ -22,6 +22,7 @@ import {ImageKnife,ImageKnifeDrawFactory,ImageKnifeGlobal} from '@ohos/libraryim
|
||||||
import AbilityConstant from '@ohos.app.ability.AbilityConstant';
|
import AbilityConstant from '@ohos.app.ability.AbilityConstant';
|
||||||
import Want from '@ohos.app.ability.Want';
|
import Want from '@ohos.app.ability.Want';
|
||||||
import { BusinessError } from '@ohos.base'
|
import { BusinessError } from '@ohos.base'
|
||||||
|
import {GlobalContext } from './GlobalContext'
|
||||||
export default class TestAbility extends UIAbility {
|
export default class TestAbility extends UIAbility {
|
||||||
onCreate(want: Want, param: AbilityConstant.LaunchParam) {
|
onCreate(want: Want, param: AbilityConstant.LaunchParam) {
|
||||||
|
|
||||||
|
@ -33,6 +34,8 @@ export default class TestAbility extends UIAbility {
|
||||||
Hypium.hypiumTest(abilityDelegator, abilityDelegatorArguments, testsuite)
|
Hypium.hypiumTest(abilityDelegator, abilityDelegatorArguments, testsuite)
|
||||||
// 初始化xts的ImageKnife
|
// 初始化xts的ImageKnife
|
||||||
ImageKnife.with(this.context.createModuleContext("entry_test"));
|
ImageKnife.with(this.context.createModuleContext("entry_test"));
|
||||||
|
GlobalContext.getInstance().setObject("hapContext",this.context.createModuleContext("entry_test"));
|
||||||
|
GlobalContext.getInstance().setObject("filesDir",this.context.createModuleContext("entry_test").filesDir);
|
||||||
}
|
}
|
||||||
|
|
||||||
onDestroy() {
|
onDestroy() {
|
||||||
|
|
|
@ -1,3 +1,9 @@
|
||||||
|
## 1.0.3
|
||||||
|
- 安全编译开启Strip和Ftrapv
|
||||||
|
|
||||||
|
## 1.0.2
|
||||||
|
- 支持x86编译
|
||||||
|
|
||||||
## 1.0.1
|
## 1.0.1
|
||||||
- 更新libc++sheared.so版本
|
- 更新libc++sheared.so版本
|
||||||
|
|
||||||
|
|
|
@ -68,6 +68,8 @@
|
||||||
|
|
||||||
在下述版本验证通过:
|
在下述版本验证通过:
|
||||||
|
|
||||||
|
- DevEco Studio: (5.0.3.122), SDK: API12 (5.0.0.17)
|
||||||
|
|
||||||
- DevEco Studio: (4.1.3.414), SDK: API11 (4.1.0.56)
|
- DevEco Studio: (4.1.3.414), SDK: API11 (4.1.0.56)
|
||||||
## 贡献代码
|
## 贡献代码
|
||||||
|
|
||||||
|
|
|
@ -3,10 +3,11 @@
|
||||||
"buildOption": {
|
"buildOption": {
|
||||||
"externalNativeOptions": {
|
"externalNativeOptions": {
|
||||||
"path": "./src/main/cpp/CMakeLists.txt",
|
"path": "./src/main/cpp/CMakeLists.txt",
|
||||||
"arguments": "",
|
"arguments": " -DCMAKE_BUILD_TYPE=Release",
|
||||||
"abiFilters": [
|
"abiFilters": [
|
||||||
"armeabi-v7a",
|
"armeabi-v7a",
|
||||||
"arm64-v8a"
|
"arm64-v8a",
|
||||||
|
"x86_64"
|
||||||
],
|
],
|
||||||
"cppFlags": ""
|
"cppFlags": ""
|
||||||
},
|
},
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
"main": "index.ets",
|
"main": "index.ets",
|
||||||
"repository": "https://gitee.com/openharmony-tpc/ImageKnife",
|
"repository": "https://gitee.com/openharmony-tpc/ImageKnife",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"version": "1.0.1",
|
"version": "1.0.3",
|
||||||
"tags": [
|
"tags": [
|
||||||
"Tool"
|
"Tool"
|
||||||
],
|
],
|
||||||
|
|
|
@ -30,4 +30,4 @@ find_library (
|
||||||
GLES-lib
|
GLES-lib
|
||||||
GLESv3 )
|
GLESv3 )
|
||||||
|
|
||||||
target_link_libraries(nativeGpu PUBLIC ${hilog-lib} ${EGL-lib} ${GLES-lib} libace_napi.z.so libc++.a)
|
target_link_libraries(nativeGpu PUBLIC ${hilog-lib} ${EGL-lib} ${GLES-lib} libace_napi.z.so libc++.a -s -ftrapv)
|
|
@ -0,0 +1,61 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2021 Huawei Device Co., Ltd.
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
import taskpool from '@ohos.taskpool';
|
||||||
|
import { UPNG } from './src/main/ets/components/3rd_party/upng/UPNG'
|
||||||
|
import { WorkerType } from "./src/main/ets/components/imageknife/pngj/PngCallback"
|
||||||
|
|
||||||
|
export function handler(e: WorkerType, source: ArrayBuffer, pngCallback: (value:ESObject) => void, info?: string) {
|
||||||
|
let task: taskpool.Task | undefined = undefined
|
||||||
|
if (info == undefined) {
|
||||||
|
task = new taskpool.Task(printArgs, e)
|
||||||
|
} else {
|
||||||
|
task = new taskpool.Task(printArgs, e, source)
|
||||||
|
}
|
||||||
|
let val1: ESObject = taskpool.execute(task)
|
||||||
|
pngCallback(val1)
|
||||||
|
try {
|
||||||
|
taskpool.cancel(task)
|
||||||
|
} catch (e) {
|
||||||
|
console.error("taskpool.cancel occur error:" + e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Concurrent
|
||||||
|
function printArgs(e: WorkerType, pngSource: ArrayBuffer, info?: string): Object | ArrayBufferLike | void {
|
||||||
|
let a: Object | ArrayBufferLike | undefined = undefined
|
||||||
|
let png = UPNG.decode(pngSource)
|
||||||
|
switch (e.name) {
|
||||||
|
case 'readPngImageAsync':
|
||||||
|
let array: Uint8Array = png.data;
|
||||||
|
let arrayData = array.buffer.slice(array.byteOffset, array.byteLength + array.byteOffset)
|
||||||
|
png.data = arrayData;
|
||||||
|
a = png
|
||||||
|
break;
|
||||||
|
case 'writePngWithStringAsync':
|
||||||
|
let addInfo: string | undefined = info;
|
||||||
|
let newPng = UPNG.encodeWithString(addInfo, UPNG.toRGBA8(png), png.width, png.height, 0)
|
||||||
|
a = newPng
|
||||||
|
break;
|
||||||
|
case 'writePngAsync':
|
||||||
|
let newPng3 = UPNG.encode(UPNG.toRGBA8(png), png.width, png.height, 0)
|
||||||
|
a = newPng3
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if(a != undefined) { return a }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,47 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2021 Huawei Device Co., Ltd.
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
import arkWorker from '@ohos.worker';
|
|
||||||
import {UPNG} from './src/main/ets/components/3rd_party/upng/UPNG'
|
|
||||||
|
|
||||||
export function handler (e) {
|
|
||||||
var data = e.data;
|
|
||||||
switch (data.type) {
|
|
||||||
case 'readPngImageAsync':
|
|
||||||
var png = UPNG.decode(data.data);
|
|
||||||
let array = png.data;
|
|
||||||
let arrayData = array.buffer.slice(array.byteOffset, array.byteLength + array.byteOffset)
|
|
||||||
png.data = arrayData;
|
|
||||||
let dataObj = { type: 'readPngImageAsync', data: png, receiver: data.data}
|
|
||||||
arkWorker.parentPort.postMessage(dataObj, [png.data, data.data]);
|
|
||||||
break;
|
|
||||||
case 'writePngWithStringAsync':
|
|
||||||
let addInfo = data.info;
|
|
||||||
let pngDecode = UPNG.decode(data.data);
|
|
||||||
let newPng = UPNG.encodeWithString(addInfo, UPNG.toRGBA8(pngDecode), pngDecode.width, pngDecode.height, 0)
|
|
||||||
let dataObj2 = { type: 'writePngWithStringAsync', data: newPng, receiver: data.data}
|
|
||||||
arkWorker.parentPort.postMessage(dataObj2, [newPng, data.data]);
|
|
||||||
break;
|
|
||||||
case 'writePngAsync':
|
|
||||||
let pngDecode3 = UPNG.decode(data.data);
|
|
||||||
let newPng3 = UPNG.encode(UPNG.toRGBA8(pngDecode3), pngDecode3.width, pngDecode3.height, 0)
|
|
||||||
let dataObj3 = { type: 'writePngAsync', data: newPng3, receiver: data.data}
|
|
||||||
arkWorker.parentPort.postMessage(dataObj3, [newPng3, data.data]);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,8 @@
|
||||||
export { FileUtils } from './src/main/ets/components/cache/FileUtils'
|
export { FileUtils } from './src/main/ets/components/cache/FileUtils'
|
||||||
export { Base64 } from './src/main/ets/components/cache/Base64'
|
export { Base64 } from './src/main/ets/components/cache/Base64'
|
||||||
export { LruCache } from './src/main/ets/components/cache/LruCache'
|
export { LruCache } from './src/main/ets/components/cache/LruCache'
|
||||||
|
export { DiskLruCache } from './src/main/ets/components/cache/DiskLruCache'
|
||||||
|
export { DiskCacheEntry } from './src/main/ets/components/cache/DiskCacheEntry'
|
||||||
export { DiskStrategy } from './src/main/ets/components/cache/diskstrategy/DiskStrategy'
|
export { DiskStrategy } from './src/main/ets/components/cache/diskstrategy/DiskStrategy'
|
||||||
export { ALL } from './src/main/ets/components/cache/diskstrategy/enum/ALL'
|
export { ALL } from './src/main/ets/components/cache/diskstrategy/enum/ALL'
|
||||||
export { AUTOMATIC } from './src/main/ets/components/cache/diskstrategy/enum/AUTOMATIC'
|
export { AUTOMATIC } from './src/main/ets/components/cache/diskstrategy/enum/AUTOMATIC'
|
||||||
|
@ -29,6 +31,7 @@ export { NONE } from './src/main/ets/components/cache/diskstrategy/enum/NONE'
|
||||||
export { RESOURCE } from './src/main/ets/components/cache/diskstrategy/enum/RESOURCE'
|
export { RESOURCE } from './src/main/ets/components/cache/diskstrategy/enum/RESOURCE'
|
||||||
export { EngineKeyInterface } from './src/main/ets/components/cache/key/EngineKeyInterface'
|
export { EngineKeyInterface } from './src/main/ets/components/cache/key/EngineKeyInterface'
|
||||||
export { EngineKeyFactories } from './src/main/ets/components/cache/key/EngineKeyFactories'
|
export { EngineKeyFactories } from './src/main/ets/components/cache/key/EngineKeyFactories'
|
||||||
|
export { DataFetchResult } from './src/main/ets/components/imageknife/networkmanage/DataFetchResult'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* compress
|
* compress
|
||||||
|
@ -96,10 +99,10 @@ export { UPNG } from './src/main/ets/components/3rd_party/upng/UPNG'
|
||||||
export { ImageKnife } from './src/main/ets/components/imageknife/ImageKnife'
|
export { ImageKnife } from './src/main/ets/components/imageknife/ImageKnife'
|
||||||
export { ImageKnifeGlobal } from './src/main/ets/components/imageknife/ImageKnifeGlobal'
|
export { ImageKnifeGlobal } from './src/main/ets/components/imageknife/ImageKnifeGlobal'
|
||||||
export { ObjectKey } from './src/main/ets/components/imageknife/ObjectKey'
|
export { ObjectKey } from './src/main/ets/components/imageknife/ObjectKey'
|
||||||
export {RequestOption,Size,DetachFromLayout} from './src/main/ets/components/imageknife/RequestOption'
|
export {RequestOption,Size,DetachFromLayout,Priority,CacheType} from './src/main/ets/components/imageknife/RequestOption'
|
||||||
export { ImageKnifeComponent, ScaleType, ScaleTypeHelper, AntiAliasing} from './src/main/ets/components/imageknife/ImageKnifeComponent'
|
export { ImageKnifeComponent, ScaleType, ScaleTypeHelper, AntiAliasing} from './src/main/ets/components/imageknife/ImageKnifeComponent'
|
||||||
export { ImageKnifeDrawFactory } from './src/main/ets/components/imageknife/ImageKnifeDrawFactory'
|
export { ImageKnifeDrawFactory } from './src/main/ets/components/imageknife/ImageKnifeDrawFactory'
|
||||||
export {ImageKnifeOption,CropCircleWithBorder,Crop,GifOptions,TransformOptions} from './src/main/ets/components/imageknife/ImageKnifeOption'
|
export {ImageKnifeOption,CropCircleWithBorder,Crop,GifOptions,TransformOptions,HeaderOptions} from './src/main/ets/components/imageknife/ImageKnifeOption'
|
||||||
export { ImageKnifeData } from './src/main/ets/components/imageknife/ImageKnifeData'
|
export { ImageKnifeData } from './src/main/ets/components/imageknife/ImageKnifeData'
|
||||||
export {IAllCacheInfoCallback,AllCacheInfo,ResourceCacheInfo,MemoryCacheInfo,DataCacheInfo} from './src/main/ets/components/imageknife/interface/IAllCacheInfoCallback'
|
export {IAllCacheInfoCallback,AllCacheInfo,ResourceCacheInfo,MemoryCacheInfo,DataCacheInfo} from './src/main/ets/components/imageknife/interface/IAllCacheInfoCallback'
|
||||||
export {IParseImage} from './src/main/ets/components/imageknife/interface/IParseImage'
|
export {IParseImage} from './src/main/ets/components/imageknife/interface/IParseImage'
|
||||||
|
@ -107,6 +110,8 @@ export {IDataFetch} from './src/main/ets/components/imageknife/networkmanage/IDa
|
||||||
export {ICache} from './src/main/ets/components/imageknife/requestmanage/ICache'
|
export {ICache} from './src/main/ets/components/imageknife/requestmanage/ICache'
|
||||||
export { FileTypeUtil } from './src/main/ets/components/imageknife/utils/FileTypeUtil'
|
export { FileTypeUtil } from './src/main/ets/components/imageknife/utils/FileTypeUtil'
|
||||||
export { ParseImageUtil } from './src/main/ets/components/imageknife/utils/ParseImageUtil'
|
export { ParseImageUtil } from './src/main/ets/components/imageknife/utils/ParseImageUtil'
|
||||||
|
export { DownloadClient } from './src/main/ets/components/imageknife/networkmanage/DownloadClient';
|
||||||
|
export { CustomDataFetchClient } from './src/main/ets/components/imageknife/networkmanage/CustomDataFetchClient';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* svg parse
|
* svg parse
|
||||||
|
|
|
@ -14,10 +14,9 @@
|
||||||
"main": "index.ets",
|
"main": "index.ets",
|
||||||
"repository": "https://gitee.com/openharmony-tpc/ImageKnife",
|
"repository": "https://gitee.com/openharmony-tpc/ImageKnife",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"version": "2.1.2-rc.6",
|
"version": "2.1.2-rc.12",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"pako": "^2.1.0",
|
"pako": "^2.1.0",
|
||||||
"@ohos/disklrucache": "^2.0.2-rc.0",
|
|
||||||
"@ohos/gpu_transform": "^1.0.0"
|
"@ohos/gpu_transform": "^1.0.0"
|
||||||
},
|
},
|
||||||
"tags": [
|
"tags": [
|
||||||
|
|
|
@ -0,0 +1,88 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2021 Huawei Device Co., Ltd.
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http:// www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
import { collections } from '@kit.ArkTS'
|
||||||
|
import { DiskCacheEntry } from './DiskCacheEntry';
|
||||||
|
|
||||||
|
@Sendable
|
||||||
|
export class CustomSendableMap {
|
||||||
|
map: collections.Map<string, DiskCacheEntry> = new collections.Map<string, DiskCacheEntry>()
|
||||||
|
|
||||||
|
// 获取键对应的值
|
||||||
|
get(key: string): DiskCacheEntry | undefined{
|
||||||
|
if (key == null) {
|
||||||
|
throw new Error('key is null,checking the parameter');
|
||||||
|
}
|
||||||
|
return this.map.get(key)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否含有key的缓存
|
||||||
|
*/
|
||||||
|
hasKey(key: string):boolean {
|
||||||
|
if (key == null) {
|
||||||
|
throw new Error('key is null,checking the parameter');
|
||||||
|
}
|
||||||
|
return this.map.has(key)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加键值对
|
||||||
|
put(key: string, value: DiskCacheEntry): DiskCacheEntry | undefined{
|
||||||
|
if (key == null || value == null) {
|
||||||
|
throw new Error('key or value is invalid,checking the parameter');
|
||||||
|
}
|
||||||
|
let pre = this.map.get(key) as DiskCacheEntry | undefined;
|
||||||
|
if (this.hasKey(key)) {
|
||||||
|
this.map.delete(key)
|
||||||
|
}
|
||||||
|
this.map.set(key, value);
|
||||||
|
return pre
|
||||||
|
}
|
||||||
|
|
||||||
|
// 去除键值,(去除键数据中的键名及对应的值)
|
||||||
|
remove(key: string): boolean {
|
||||||
|
if (key == null) {
|
||||||
|
throw new Error('key is null,checking the parameter');
|
||||||
|
}
|
||||||
|
return this.map.delete(key)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取最先存储的数据的key
|
||||||
|
*/
|
||||||
|
getFirstKey(): string{ // keys()可以遍历后需要优化put()方法,暂时仅获取index=0的key
|
||||||
|
return this.map.keys().next().value
|
||||||
|
}
|
||||||
|
|
||||||
|
// 判断键值元素是否为空
|
||||||
|
isEmpty(): boolean{
|
||||||
|
return this.map.size == 0;
|
||||||
|
}
|
||||||
|
// 获取键值元素大小
|
||||||
|
size(): number{
|
||||||
|
return this.map.size;
|
||||||
|
}
|
||||||
|
// 遍历Map,执行处理函数. 回调函数 function(key,value,index){..}
|
||||||
|
each(fn: (value: DiskCacheEntry, key: string, map: collections.Map<string, DiskCacheEntry>) => void) {
|
||||||
|
this.map.forEach(fn)
|
||||||
|
}
|
||||||
|
// 清除键值对
|
||||||
|
clear() {
|
||||||
|
this.map.clear()
|
||||||
|
}
|
||||||
|
// 遍历key
|
||||||
|
keys(): IterableIterator<string>{
|
||||||
|
return this.map.keys()
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2024 Huawei Device Co., Ltd.
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
@Sendable
|
||||||
|
export class DiskCacheEntry {
|
||||||
|
// 缓存的key
|
||||||
|
key: string = ''
|
||||||
|
|
||||||
|
// 缓存文件大小
|
||||||
|
length: number = 0
|
||||||
|
|
||||||
|
constructor(key: string, length?: number) {
|
||||||
|
this.key = key
|
||||||
|
this.length = length as number
|
||||||
|
}
|
||||||
|
|
||||||
|
setKey(key: string) {
|
||||||
|
this.key = key
|
||||||
|
}
|
||||||
|
|
||||||
|
getKey(): string {
|
||||||
|
return this.key
|
||||||
|
}
|
||||||
|
|
||||||
|
setLength(length: number) {
|
||||||
|
this.length = length
|
||||||
|
}
|
||||||
|
|
||||||
|
getLength(): number {
|
||||||
|
return this.length
|
||||||
|
}
|
||||||
|
|
||||||
|
toString(): string {
|
||||||
|
return this.key + ' - ' + this.length
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,388 @@
|
||||||
|
/*
|
||||||
|
* 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 { FileUtils } from './FileUtils'
|
||||||
|
import { DiskCacheEntry } from './DiskCacheEntry'
|
||||||
|
import { SparkMD5 } from '../3rd_party/sparkmd5/spark-md5'
|
||||||
|
import common from '@ohos.app.ability.common'
|
||||||
|
import { CustomSendableMap } from './CustomSendableMap'
|
||||||
|
|
||||||
|
@Sendable
|
||||||
|
export class DiskLruCache {
|
||||||
|
// 默认缓存数据最大值
|
||||||
|
private static readonly DEFAULT_MAX_SIZE: number = 300 * 1024 * 1024
|
||||||
|
// 默认缓存文件名
|
||||||
|
private static readonly DEFAULT_NAME: string = 'diskLruCache'
|
||||||
|
// 缓存文件路径地址
|
||||||
|
private path: string = ''
|
||||||
|
|
||||||
|
// 缓存数据最大值
|
||||||
|
private maxSize: number = DiskLruCache.DEFAULT_MAX_SIZE
|
||||||
|
// 当前缓存数据值
|
||||||
|
private size: number = 0
|
||||||
|
// 缓存数据集合
|
||||||
|
private cacheMap: CustomSendableMap = new CustomSendableMap()
|
||||||
|
|
||||||
|
constructor(path: string, maxSize: number) {
|
||||||
|
this.path = path
|
||||||
|
this.maxSize = maxSize
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 打开context获取的cache路径中的缓存,如果不存在缓存,则创建新缓存
|
||||||
|
*
|
||||||
|
* @param context 上下文
|
||||||
|
* @param maxSize 缓存数据最大值,默认值为300M
|
||||||
|
*/
|
||||||
|
public static create(context: common.UIAbilityContext, maxSize?: number): DiskLruCache {
|
||||||
|
if (!!!context) {
|
||||||
|
throw new Error('DiskLruCache create context is empty, checking the parameter');
|
||||||
|
}
|
||||||
|
if (!!!maxSize) {
|
||||||
|
maxSize = DiskLruCache.DEFAULT_MAX_SIZE
|
||||||
|
}
|
||||||
|
if (maxSize <= 0) {
|
||||||
|
throw new Error("DiskLruCache create maxSize <= 0, checking the parameter");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 使用默认应用在内部存储上的缓存路径,作为存储地址
|
||||||
|
let path = context.cacheDir + FileUtils.SEPARATOR + DiskLruCache.DEFAULT_NAME
|
||||||
|
if (!FileUtils.getInstance().existFolder(path)) {
|
||||||
|
FileUtils.getInstance().createFolder(path)
|
||||||
|
}
|
||||||
|
if (path.endsWith(FileUtils.SEPARATOR)) {
|
||||||
|
path = path
|
||||||
|
} else {
|
||||||
|
path = path + FileUtils.SEPARATOR
|
||||||
|
}
|
||||||
|
return new DiskLruCache(path, maxSize)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置disk缓存最大数据值
|
||||||
|
*
|
||||||
|
* @param max 缓存数据最大值
|
||||||
|
*/
|
||||||
|
setMaxSize(max: number) {
|
||||||
|
if (max <= 0 || max > DiskLruCache.DEFAULT_MAX_SIZE) {
|
||||||
|
throw new Error('setMaxSize error, checking the parameter');
|
||||||
|
}
|
||||||
|
this.maxSize = max
|
||||||
|
this.trimToSize()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 存储disk缓存数据
|
||||||
|
*
|
||||||
|
* @param key 键值
|
||||||
|
* @param content 文件内容
|
||||||
|
*/
|
||||||
|
set(key: string, content: ArrayBuffer | string) {
|
||||||
|
if (!!!key) {
|
||||||
|
throw new Error('key is null, checking the parameter')
|
||||||
|
}
|
||||||
|
let fileSize = 0;
|
||||||
|
if (content instanceof ArrayBuffer) {
|
||||||
|
if (content == null || content.byteLength == 0) {
|
||||||
|
throw new Error('content is null. checking the parameter')
|
||||||
|
}
|
||||||
|
fileSize = content.byteLength
|
||||||
|
} else {
|
||||||
|
if (!!!content) {
|
||||||
|
throw new Error('content is null, checking the parameter')
|
||||||
|
}
|
||||||
|
fileSize = content.length;
|
||||||
|
}
|
||||||
|
if (this.fileSizeMoreThenMaxSize(fileSize)) {
|
||||||
|
throw new Error('content must be less then DiskLruCache Size, checking the parameter')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
key = SparkMD5.hashBinary(key)
|
||||||
|
this.size = this.size + fileSize
|
||||||
|
this.putCacheMap(key, fileSize)
|
||||||
|
this.trimToSize()
|
||||||
|
let tempPath = this.path + key
|
||||||
|
FileUtils.getInstance().writeNewFile(tempPath, content)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 异步存储disk缓存数据
|
||||||
|
*
|
||||||
|
* @param key 键值
|
||||||
|
* @param content 文件内容
|
||||||
|
*/
|
||||||
|
async setAsync(key: string, content: ArrayBuffer | string): Promise<void> {
|
||||||
|
if (!!!key) {
|
||||||
|
throw new Error('key is null, checking the parameter')
|
||||||
|
}
|
||||||
|
let fileSize = 0;
|
||||||
|
if (content instanceof ArrayBuffer) {
|
||||||
|
if (content == null || content.byteLength == 0) {
|
||||||
|
throw new Error('content is null. checking the parameter')
|
||||||
|
}
|
||||||
|
fileSize = content.byteLength
|
||||||
|
} else {
|
||||||
|
if (!!!content) {
|
||||||
|
throw new Error('content is null, checking the parameter')
|
||||||
|
}
|
||||||
|
fileSize = content.length;
|
||||||
|
}
|
||||||
|
if (this.fileSizeMoreThenMaxSize(fileSize)) {
|
||||||
|
throw new Error('content must be less then DiskLruCache Size, checking the parameter')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
key = SparkMD5.hashBinary(key)
|
||||||
|
this.size = this.size + fileSize
|
||||||
|
this.putCacheMap(key, fileSize)
|
||||||
|
this.trimToSize()
|
||||||
|
let tempPath = this.path + key
|
||||||
|
await FileUtils.getInstance().writeNewFileAsync(tempPath, content)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取key缓存数据
|
||||||
|
*
|
||||||
|
* @param key key 键值
|
||||||
|
*/
|
||||||
|
get(key: string): ArrayBuffer | undefined {
|
||||||
|
if (!!!key) {
|
||||||
|
throw new Error('key is null,checking the parameter');
|
||||||
|
}
|
||||||
|
key = SparkMD5.hashBinary(key)
|
||||||
|
let path = this.path + key;
|
||||||
|
if (FileUtils.getInstance().exist(path)) {
|
||||||
|
let ab: ArrayBuffer = FileUtils.getInstance().readFile(path)
|
||||||
|
this.putCacheMap(key, ab.byteLength)
|
||||||
|
return ab
|
||||||
|
} else {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 异步获取key缓存数据
|
||||||
|
*
|
||||||
|
* @param key 键值
|
||||||
|
*/
|
||||||
|
async getAsync(key: string): Promise<ArrayBuffer | undefined> {
|
||||||
|
if (!!!key) {
|
||||||
|
throw new Error('key is null,checking the parameter');
|
||||||
|
}
|
||||||
|
key = SparkMD5.hashBinary(key)
|
||||||
|
let path = this.path + key;
|
||||||
|
if (FileUtils.getInstance().exist(path)) {
|
||||||
|
let ab: ArrayBuffer = await FileUtils.getInstance().readFileAsync(path)
|
||||||
|
this.putCacheMap(key, ab.byteLength)
|
||||||
|
return ab
|
||||||
|
} else {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取key缓存数据绝对路径
|
||||||
|
*
|
||||||
|
* @param key 键值
|
||||||
|
*/
|
||||||
|
getFileToPath(key: string): string {
|
||||||
|
if (!!!key) {
|
||||||
|
throw new Error('key is null,checking the parameter');
|
||||||
|
}
|
||||||
|
key = SparkMD5.hashBinary(key);
|
||||||
|
let path = this.path + key;
|
||||||
|
if (FileUtils.getInstance().exist(path)) {
|
||||||
|
return path
|
||||||
|
} else {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 异步获取key缓存数据绝对路径
|
||||||
|
*
|
||||||
|
* @param key 键值
|
||||||
|
*/
|
||||||
|
async getFileToPathAsync(key: string): Promise<string> {
|
||||||
|
if (!!!key) {
|
||||||
|
throw new Error('key is null,checking the parameter');
|
||||||
|
}
|
||||||
|
key = SparkMD5.hashBinary(key);
|
||||||
|
let path = this.path + key;
|
||||||
|
if (FileUtils.getInstance().exist(path)) {
|
||||||
|
return path
|
||||||
|
} else {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取缓存路径
|
||||||
|
*/
|
||||||
|
getPath(): string {
|
||||||
|
return this.path;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除key缓存数据
|
||||||
|
*
|
||||||
|
* @param key 键值
|
||||||
|
*/
|
||||||
|
deleteCacheDataByKey(key: string): DiskCacheEntry {
|
||||||
|
if (!!!key) {
|
||||||
|
throw new Error('key is null,checking the parameter');
|
||||||
|
}
|
||||||
|
key = SparkMD5.hashBinary(key)
|
||||||
|
let path = this.path + key;
|
||||||
|
if (FileUtils.getInstance().exist(path)) {
|
||||||
|
let ab = FileUtils.getInstance().readFile(path)
|
||||||
|
this.size = this.size - ab.byteLength
|
||||||
|
this.cacheMap.remove(key)
|
||||||
|
FileUtils.getInstance().deleteFile(path)
|
||||||
|
}
|
||||||
|
return this.cacheMap.get(key) as DiskCacheEntry;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*遍历当前的磁盘缓存数据
|
||||||
|
*
|
||||||
|
* @param fn 遍历后方法回调
|
||||||
|
*/
|
||||||
|
foreachDiskLruCache(fn: Function) {
|
||||||
|
this.cacheMap.each(fn())
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 清除所有disk缓存数据
|
||||||
|
*/
|
||||||
|
cleanCacheData() {
|
||||||
|
this.cacheMap.each((value, key) => {
|
||||||
|
FileUtils.getInstance().deleteFile(this.path + key)
|
||||||
|
})
|
||||||
|
this.cacheMap.clear()
|
||||||
|
this.size = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
getCacheMap() {
|
||||||
|
return this.cacheMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回当前DiskLruCache的size大小
|
||||||
|
*/
|
||||||
|
getSize() {
|
||||||
|
return this.size;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 缓存数据map集合
|
||||||
|
*
|
||||||
|
* @param key 键值
|
||||||
|
* @param length 缓存文件大小
|
||||||
|
*/
|
||||||
|
private putCacheMap(key: string, length?: number) {
|
||||||
|
if (length && length > 0) {
|
||||||
|
this.cacheMap.put(key, new DiskCacheEntry(key, length))
|
||||||
|
} else {
|
||||||
|
this.cacheMap.put(key, new DiskCacheEntry(key))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据LRU算法删除多余缓存数据
|
||||||
|
*/
|
||||||
|
private trimToSize() {
|
||||||
|
while (this.size > this.maxSize) {
|
||||||
|
let tempKey: string = this.cacheMap.getFirstKey()
|
||||||
|
let fileSize = FileUtils.getInstance().getFileSize(this.path + tempKey)
|
||||||
|
if (fileSize > 0) {
|
||||||
|
this.size = this.size - fileSize
|
||||||
|
}
|
||||||
|
FileUtils.getInstance().deleteFile(this.path + tempKey)
|
||||||
|
this.cacheMap.remove(tempKey)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 图片文件过大 直接超过DiskLruCache上限
|
||||||
|
*/
|
||||||
|
private fileSizeMoreThenMaxSize(fileSize: number): boolean {
|
||||||
|
if (fileSize > this.maxSize) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 子线程里只写入缓存文件
|
||||||
|
* @param context
|
||||||
|
* @param key
|
||||||
|
* @param value
|
||||||
|
*/
|
||||||
|
static saveFileCacheOnlyFile(path: string, key: string, value: ArrayBuffer): boolean {
|
||||||
|
// 写文件
|
||||||
|
if (!!!key) {
|
||||||
|
throw new Error('key is null, checking the parameter')
|
||||||
|
}
|
||||||
|
key = SparkMD5.hashBinary(key);
|
||||||
|
FileUtils.getInstance().writeNewFile(path + key, value);
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 子线程中,通过文件名,直接查找是否有文件缓存
|
||||||
|
* @param context
|
||||||
|
* @param key
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
static getFileCacheByFile(path: string, key: string): ArrayBuffer | undefined {
|
||||||
|
// 从文件获取查看是否有缓存
|
||||||
|
if (!!!key) {
|
||||||
|
throw new Error('key is null,checking the parameter');
|
||||||
|
}
|
||||||
|
key = SparkMD5.hashBinary(key)
|
||||||
|
let filepath = path + key;
|
||||||
|
if (FileUtils.getInstance().exist(filepath)) {
|
||||||
|
let ab: ArrayBuffer = FileUtils.getInstance().readFile(filepath)
|
||||||
|
return ab
|
||||||
|
} else {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加缓存键值对,但不写文件(用于子线程已经写文件的场景)
|
||||||
|
setCacheMapAndSize(key: string, content: ArrayBuffer | string): void {
|
||||||
|
if (!!!key) {
|
||||||
|
throw new Error('key is null, checking the parameter')
|
||||||
|
}
|
||||||
|
let fileSize = 0;
|
||||||
|
if (content instanceof ArrayBuffer) {
|
||||||
|
if (content == null || content.byteLength == 0) {
|
||||||
|
throw new Error('content is null. checking the parameter')
|
||||||
|
}
|
||||||
|
fileSize = content.byteLength
|
||||||
|
} else {
|
||||||
|
if (!!!content) {
|
||||||
|
throw new Error('content is null, checking the parameter')
|
||||||
|
}
|
||||||
|
fileSize = content.length;
|
||||||
|
}
|
||||||
|
if (this.fileSizeMoreThenMaxSize(fileSize)) {
|
||||||
|
throw new Error('content must be less then DiskLruCache Size, checking the parameter')
|
||||||
|
}
|
||||||
|
key = SparkMD5.hashBinary(key);
|
||||||
|
this.size = this.size + fileSize;
|
||||||
|
this.putCacheMap(key, fileSize);
|
||||||
|
this.trimToSize();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,94 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2024 Huawei Device Co., Ltd.
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
import fs from '@ohos.file.fs';
|
||||||
|
import { RequestOption } from '../imageknife/RequestOption';
|
||||||
|
|
||||||
|
export class FileReader {
|
||||||
|
// 换行符
|
||||||
|
static readonly LF: string = '\n'
|
||||||
|
// CR符
|
||||||
|
static readonly CR: string = '\r'
|
||||||
|
// 文件大小
|
||||||
|
fileLength: number = 0
|
||||||
|
// 读取的长度
|
||||||
|
length: number = 0
|
||||||
|
// 读写stream
|
||||||
|
stream: fs.Stream
|
||||||
|
// 缓存buf
|
||||||
|
buf: ArrayBuffer = new ArrayBuffer(1)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 读取文件行
|
||||||
|
*
|
||||||
|
* @param path 文件路径
|
||||||
|
*/
|
||||||
|
constructor(path: string) {
|
||||||
|
if (!!!path) {
|
||||||
|
throw new Error('FileReader constructor path is null, checking the parameter')
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.stream = fs.createStreamSync(path, 'r+');
|
||||||
|
let stat = fs.statSync(path)
|
||||||
|
this.fileLength = stat.size
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 循环读取文件数据
|
||||||
|
*/
|
||||||
|
readLine(): string {
|
||||||
|
let line = ''
|
||||||
|
while (this.stream && this.length < this.fileLength) {
|
||||||
|
this.stream?.readSync(this.buf, { offset: this.length })
|
||||||
|
this.length++
|
||||||
|
let temp = String.fromCharCode(...new Uint8Array(this.buf));
|
||||||
|
line = line + temp
|
||||||
|
// check CRLF
|
||||||
|
if (temp == FileReader.CR) {
|
||||||
|
// 边界判断 首先拿到下一个字符判断是否是LF 如果是CRLF需要再向后挪一位
|
||||||
|
if (this.length < this.fileLength) {
|
||||||
|
let nextBuf = new ArrayBuffer(1)
|
||||||
|
this.stream?.readSync(nextBuf, { offset: this.length })
|
||||||
|
let nextTemp = String.fromCharCode(...new Uint8Array(nextBuf));
|
||||||
|
// 如果是CRLF 需要给当前length+1 向后挪一位
|
||||||
|
if (nextTemp == FileReader.LF) {
|
||||||
|
this.length++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 如果不是CRLF 只有一个CR结尾length不用变
|
||||||
|
return line;
|
||||||
|
} else {
|
||||||
|
// 判断LF情况
|
||||||
|
if (temp == FileReader.LF) {
|
||||||
|
return line
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return line
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断文件是否结束
|
||||||
|
*/
|
||||||
|
isEnd() {
|
||||||
|
return this.fileLength <= 0 || this.length == this.fileLength
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 关闭stream
|
||||||
|
*/
|
||||||
|
close() {
|
||||||
|
this.stream?.closeSync()
|
||||||
|
}
|
||||||
|
}
|
|
@ -16,6 +16,7 @@
|
||||||
import fs from '@ohos.file.fs';
|
import fs from '@ohos.file.fs';
|
||||||
import { BusinessError } from '@ohos.base'
|
import { BusinessError } from '@ohos.base'
|
||||||
export class FileUtils {
|
export class FileUtils {
|
||||||
|
static readonly SEPARATOR: string = '/'
|
||||||
base64Str: string = ''
|
base64Str: string = ''
|
||||||
private static sInstance: FileUtils;
|
private static sInstance: FileUtils;
|
||||||
|
|
||||||
|
@ -32,13 +33,21 @@ export class FileUtils {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 新建文件
|
* 新建文件
|
||||||
|
*
|
||||||
* @param path 文件绝对路径及文件名
|
* @param path 文件绝对路径及文件名
|
||||||
* @return number 文件句柄id
|
* @return number 文件句柄id
|
||||||
*/
|
*/
|
||||||
createFile(path: string): number {
|
createFile(path: string): number {
|
||||||
return fs.openSync(path, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE).fd
|
let num = -1;
|
||||||
|
try {
|
||||||
|
num = fs.openSync(path, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE).fd
|
||||||
|
} catch (e) {
|
||||||
|
console.log("createFile err :" + e)
|
||||||
|
}
|
||||||
|
return num;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 删除文件
|
* 删除文件
|
||||||
* @param path 文件绝对路径及文件名
|
* @param path 文件绝对路径及文件名
|
||||||
|
@ -143,16 +152,20 @@ export class FileUtils {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 判断path文件是否存在
|
* 判断path文件是否存在
|
||||||
|
*
|
||||||
|
* @param path 文件绝对路径
|
||||||
*/
|
*/
|
||||||
exist(path: string): boolean {
|
exist(path: string): boolean {
|
||||||
try {
|
try {
|
||||||
let stat = fs.statSync(path)
|
if (fs.accessSync(path)) {
|
||||||
return stat.isFile()
|
let stat = fs.statSync(path)
|
||||||
} catch (e) {
|
return stat.isFile()
|
||||||
console.debug("FileUtils - fileutils exsit e" + e)
|
}
|
||||||
console.log("path=>" + path)
|
} catch (error) {
|
||||||
return false
|
let err: BusinessError = error as BusinessError;
|
||||||
|
console.error("accessSync failed with error message: " + err.message + ", error code: " + err.code);
|
||||||
}
|
}
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -285,7 +298,7 @@ export class FileUtils {
|
||||||
let stat = fs.statSync(path)
|
let stat = fs.statSync(path)
|
||||||
return stat.isDirectory()
|
return stat.isDirectory()
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.debug("fileutils folder exsit error=" + e)
|
console.debug("fileutils folder exist error=" + e)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -318,9 +331,84 @@ export class FileUtils {
|
||||||
return tmpUint8Array
|
return tmpUint8Array
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 异步向path写入数据
|
||||||
|
*
|
||||||
|
* @param path 文件绝对路径
|
||||||
|
* @param content 文件内容
|
||||||
|
*/
|
||||||
|
async writeDataAsync(path: string, content: ArrayBuffer | string): Promise<void> {
|
||||||
|
let fd = (await fs.open(path, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE)).fd
|
||||||
|
let stat = await fs.stat(path)
|
||||||
|
await fs.write(fd, content, { offset: stat.size })
|
||||||
|
await fs.close(fd)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 异步拷贝文件
|
||||||
|
*
|
||||||
|
* @param src 文件绝对路径及文件名
|
||||||
|
* @param dest 拷贝到对应的路径
|
||||||
|
*/
|
||||||
|
async copyFileAsync(src: string, dest: string): Promise<void> {
|
||||||
|
await fs.copyFile(src, dest);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 读取路径path的文件
|
||||||
|
*
|
||||||
|
* @param path 文件绝对路径
|
||||||
|
*/
|
||||||
|
async readFileAsync(path: string): Promise<ArrayBuffer> {
|
||||||
|
let stat = await fs.stat(path);
|
||||||
|
let fd = (await fs.open(path, fs.OpenMode.READ_WRITE)).fd;
|
||||||
|
let length = stat.size;
|
||||||
|
let buf = new ArrayBuffer(length);
|
||||||
|
await fs.read(fd, buf);
|
||||||
|
return buf
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 向path写入数据
|
||||||
|
*
|
||||||
|
* @param path 文件绝对路径
|
||||||
|
* @param data 文件内容
|
||||||
|
*/
|
||||||
|
async writeNewFileAsync(path: string, data: ArrayBuffer | string): Promise<void> {
|
||||||
|
let fd = (await fs.open(path, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE)).fd
|
||||||
|
await fs.truncate(fd)
|
||||||
|
await fs.write(fd, data)
|
||||||
|
await fs.fsync(fd)
|
||||||
|
await fs.close(fd)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
uint8ArrayToBuffer(array: Uint8Array): ArrayBuffer {
|
uint8ArrayToBuffer(array: Uint8Array): ArrayBuffer {
|
||||||
return array.buffer.slice(array.byteOffset, array.byteLength + array.byteOffset)
|
return array.buffer.slice(array.byteOffset, array.byteLength + array.byteOffset)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 向path写入数据
|
||||||
|
*
|
||||||
|
* @param path 文件绝对路径
|
||||||
|
* @param data 文件内容
|
||||||
|
*/
|
||||||
|
writeNewFile(path: string, data: ArrayBuffer | string) {
|
||||||
|
this.createFile(path)
|
||||||
|
this.writeFile(path, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 读取路径path的文件
|
||||||
|
*
|
||||||
|
* @param path 文件绝对路径
|
||||||
|
*/
|
||||||
|
readFile(path: string): ArrayBuffer {
|
||||||
|
let fd = fs.openSync(path, fs.OpenMode.READ_WRITE).fd;
|
||||||
|
let length = fs.statSync(path).size
|
||||||
|
let buf = new ArrayBuffer(length);
|
||||||
|
fs.readSync(fd, buf)
|
||||||
|
return buf
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
/*
|
||||||
|
* asdfasdfasdfasdfasdf*/
|
|
@ -0,0 +1,2 @@
|
||||||
|
/*
|
||||||
|
* dsasdafasdfasdf*/
|
|
@ -0,0 +1,2 @@
|
||||||
|
/*
|
||||||
|
* asdfasdfasdfasdfasdf*/
|
|
@ -13,10 +13,10 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { DiskLruCache } from "@ohos/disklrucache"
|
import { DiskLruCache } from "../cache/DiskLruCache"
|
||||||
import { EngineKeyFactories } from "../cache/key/EngineKeyFactories"
|
import { EngineKeyFactories } from "../cache/key/EngineKeyFactories"
|
||||||
import { EngineKeyInterface } from "../cache/key/EngineKeyInterface"
|
import { EngineKeyInterface } from "../cache/key/EngineKeyInterface"
|
||||||
import { RequestOption } from "../imageknife/RequestOption"
|
import { CacheType, RequestOption, Size } from "../imageknife/RequestOption"
|
||||||
import { AsyncCallback } from "../imageknife/interface/AsyncCallback"
|
import { AsyncCallback } from "../imageknife/interface/AsyncCallback"
|
||||||
import { PlaceHolderManager } from "../imageknife/holder/PlaceHolderManager"
|
import { PlaceHolderManager } from "../imageknife/holder/PlaceHolderManager"
|
||||||
import { RetryHolderManager } from "../imageknife/holder/RetryHolderManager"
|
import { RetryHolderManager } from "../imageknife/holder/RetryHolderManager"
|
||||||
|
@ -31,30 +31,46 @@ import { IResourceFetch } from '../imageknife/resourcemanage/IResourceFetch'
|
||||||
import { ImageKnifeData, ImageKnifeType } from '../imageknife/ImageKnifeData'
|
import { ImageKnifeData, ImageKnifeType } from '../imageknife/ImageKnifeData'
|
||||||
import { ImageKnifeGlobal } from '../imageknife/ImageKnifeGlobal'
|
import { ImageKnifeGlobal } from '../imageknife/ImageKnifeGlobal'
|
||||||
import image from "@ohos.multimedia.image"
|
import image from "@ohos.multimedia.image"
|
||||||
|
import http from '@ohos.net.http'
|
||||||
import { CompressBuilder } from "../imageknife/compress/CompressBuilder"
|
import { CompressBuilder } from "../imageknife/compress/CompressBuilder"
|
||||||
import { IDrawLifeCycle } from '../imageknife/interface/IDrawLifeCycle'
|
import { IDrawLifeCycle } from '../imageknife/interface/IDrawLifeCycle'
|
||||||
import { LogUtil } from '../imageknife/utils/LogUtil'
|
import { LogUtil } from '../imageknife/utils/LogUtil'
|
||||||
import { EasyLinkedHashMap } from './utils/base/EasyLinkedHashMap'
|
|
||||||
import { MethodMutex } from './utils/base/MethodMutex'
|
import { MethodMutex } from './utils/base/MethodMutex'
|
||||||
import worker from '@ohos.worker'
|
import worker from '@ohos.worker'
|
||||||
import common from '@ohos.app.ability.common'
|
import common from '@ohos.app.ability.common'
|
||||||
import HashMap from '@ohos.util.HashMap'
|
|
||||||
import LinkedList from '@ohos.util.LinkedList'
|
|
||||||
import { MemoryLruCache } from '../cache/MemoryLruCache'
|
import { MemoryLruCache } from '../cache/MemoryLruCache'
|
||||||
|
import { BusinessError } from '@ohos.base'
|
||||||
|
import taskpool from '@ohos.taskpool'
|
||||||
|
import { DefaultJobQueue } from './utils/DefaultJobQueue';
|
||||||
|
import { IJobQueue } from './utils/IJobQueue';
|
||||||
|
import LightWeightMap from '@ohos.util.LightWeightMap';
|
||||||
|
import List from '@ohos.util.List';
|
||||||
|
import { GIFFrame } from './utils/gif/GIFFrame'
|
||||||
|
import emitter from '@ohos.events.emitter';
|
||||||
|
|
||||||
|
import { MemoryCacheProxy } from './requestmanage/MemoryCacheProxy'
|
||||||
|
import { ObjectKey } from './ObjectKey'
|
||||||
|
import { Constants } from './constants/Constants'
|
||||||
|
import { TransformUtils } from './transform/TransformUtils'
|
||||||
|
import { GIFParseImpl } from './utils/gif/GIFParseImpl'
|
||||||
|
import { IParseImage } from './interface/IParseImage'
|
||||||
|
import { ParseImageUtil } from './utils/ParseImageUtil'
|
||||||
|
import { SVGParseImpl } from './utils/svg/SVGParseImpl'
|
||||||
|
import { SendableData } from './SendableData'
|
||||||
|
import { collections } from '@kit.ArkTS'
|
||||||
|
import { TaskParams } from './TaskParams'
|
||||||
|
import { MResource } from './utils/MResource'
|
||||||
|
|
||||||
export class ImageKnife {
|
export class ImageKnife {
|
||||||
static readonly SEPARATOR: string = '/'
|
static readonly SEPARATOR: string = '/'
|
||||||
memoryCache: MemoryLruCache;
|
memoryCache: MemoryLruCache;
|
||||||
diskMemoryCache: DiskLruCache;
|
|
||||||
dataFetch: IDataFetch;
|
dataFetch: IDataFetch;
|
||||||
resourceFetch: IResourceFetch<ArrayBuffer>;
|
resourceFetch: IResourceFetch<ArrayBuffer>;
|
||||||
filesPath: string = ""; // data/data/包名/files目录
|
filesPath: string = ""; // data/data/包名/files目录
|
||||||
|
diskMemoryCache: DiskLruCache;
|
||||||
|
memoryCacheProxy: MemoryCacheProxy<string, ImageKnifeData> = new MemoryCacheProxy(new MemoryLruCache(100, 100 * 1024 * 1024));
|
||||||
|
headerMap: Map<string, Object> = new Map<string, Object>(); //定义全局map
|
||||||
placeholderCache: string = "placeholderCache"
|
placeholderCache: string = "placeholderCache"
|
||||||
runningMaps: EasyLinkedHashMap<string, RequestOption>;
|
|
||||||
pendingMaps: EasyLinkedHashMap<string, RequestOption>;
|
|
||||||
pausedMaps: EasyLinkedHashMap<string, RequestOption>;
|
|
||||||
isPaused: boolean = false;
|
isPaused: boolean = false;
|
||||||
mutex: MethodMutex = new MethodMutex();
|
mutex: MethodMutex = new MethodMutex();
|
||||||
fileTypeUtil: FileTypeUtil; // 通用文件格式辨别
|
fileTypeUtil: FileTypeUtil; // 通用文件格式辨别
|
||||||
|
@ -70,18 +86,19 @@ export class ImageKnife {
|
||||||
defaultLifeCycle: IDrawLifeCycle | undefined = undefined;
|
defaultLifeCycle: IDrawLifeCycle | undefined = undefined;
|
||||||
// 开发者可配置全局缓存
|
// 开发者可配置全局缓存
|
||||||
engineKeyImpl: EngineKeyInterface;
|
engineKeyImpl: EngineKeyInterface;
|
||||||
|
private mParseImageUtil: IParseImage<PixelMap>;
|
||||||
|
// 最大并发
|
||||||
|
maxRequests: number = 64;
|
||||||
|
// 排队队列
|
||||||
|
private jobQueue: IJobQueue = new DefaultJobQueue();
|
||||||
|
// 执行中的请求
|
||||||
|
private executingJobMap: LightWeightMap<string, List<RequestOption>> = new LightWeightMap();
|
||||||
|
|
||||||
private constructor() {
|
private constructor() {
|
||||||
|
this.mParseImageUtil = new ParseImageUtil();
|
||||||
this.runningMaps = new EasyLinkedHashMap();
|
|
||||||
this.pendingMaps = new EasyLinkedHashMap();
|
|
||||||
this.pausedMaps = new EasyLinkedHashMap();
|
|
||||||
|
|
||||||
// 构造方法传入size 为保存文件个数
|
// 构造方法传入size 为保存文件个数
|
||||||
this.memoryCache = new MemoryLruCache(100,100*1024*1024);
|
this.memoryCache = new MemoryLruCache(100, 100 * 1024 * 1024);
|
||||||
|
|
||||||
// 创建disk缓存 传入的size 为多少比特 比如20KB 传入20*1024
|
|
||||||
this.diskMemoryCache = DiskLruCache.create(ImageKnifeGlobal.getInstance().getHapContext());
|
|
||||||
|
|
||||||
// 创建网络下载能力
|
// 创建网络下载能力
|
||||||
this.dataFetch = new DownloadClient();
|
this.dataFetch = new DownloadClient();
|
||||||
|
@ -92,18 +109,33 @@ export class ImageKnife {
|
||||||
// 初始化本地 文件保存
|
// 初始化本地 文件保存
|
||||||
this.filesPath = (ImageKnifeGlobal.getInstance().getHapContext() as common.UIAbilityContext).filesDir as string;
|
this.filesPath = (ImageKnifeGlobal.getInstance().getHapContext() as common.UIAbilityContext).filesDir as string;
|
||||||
|
|
||||||
|
this.diskMemoryCache = DiskLruCache.create(ImageKnifeGlobal.getInstance()
|
||||||
|
.getHapContext() as common.UIAbilityContext);
|
||||||
|
|
||||||
// 通用文件格式识别初始化
|
// 通用文件格式识别初始化
|
||||||
this.fileTypeUtil = new FileTypeUtil();
|
this.fileTypeUtil = new FileTypeUtil();
|
||||||
|
|
||||||
this.engineKeyImpl = new EngineKeyFactories();
|
this.engineKeyImpl = new EngineKeyFactories();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//全局设置请求头调用方法
|
||||||
|
addHeader(key: string, value: Object) {
|
||||||
|
this.headerMap.set(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
deleteHeader(key: string) {
|
||||||
|
this.headerMap.delete(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
getMemoryCache(): MemoryLruCache {
|
getMemoryCache(): MemoryLruCache {
|
||||||
return this.memoryCache;
|
return this.memoryCache;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getMemoryCacheProxy(): MemoryCacheProxy<string, ImageKnifeData> {
|
||||||
|
return this.memoryCacheProxy;
|
||||||
|
}
|
||||||
|
|
||||||
public static with(context: Object): ImageKnifeGlobal {
|
public static with(context: Object): ImageKnifeGlobal {
|
||||||
// 存入hapContext;
|
// 存入hapContext;
|
||||||
let global: ImageKnifeGlobal = ImageKnifeGlobal.getInstance();
|
let global: ImageKnifeGlobal = ImageKnifeGlobal.getInstance();
|
||||||
|
@ -174,13 +206,12 @@ export class ImageKnife {
|
||||||
return new CompressBuilder();
|
return new CompressBuilder();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// 设置缓存张数,缓存大小,单位字节
|
// 设置缓存张数,缓存大小,单位字节
|
||||||
public setLruCacheSize(size: number,memory:number) {
|
public setLruCacheSize(size: number, memory: number) {
|
||||||
if (this.memoryCache.map.size() <= 0) {
|
if (this.memoryCache.map.size() <= 0) {
|
||||||
this.memoryCache = new MemoryLruCache(size,memory);
|
this.memoryCache = new MemoryLruCache(size, memory);
|
||||||
} else {
|
} else {
|
||||||
let newLruCache = new MemoryLruCache(size,memory);
|
let newLruCache = new MemoryLruCache(size, memory);
|
||||||
this.memoryCache.foreachLruCache((value: ImageKnifeData, key: string, map: Object) => {
|
this.memoryCache.foreachLruCache((value: ImageKnifeData, key: string, map: Object) => {
|
||||||
newLruCache.put(key, value);
|
newLruCache.put(key, value);
|
||||||
})
|
})
|
||||||
|
@ -192,17 +223,19 @@ export class ImageKnife {
|
||||||
this.dataFetch = fetch;
|
this.dataFetch = fetch;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// 替代原来的DiskLruCache
|
// 替代原来的DiskLruCache
|
||||||
public replaceDiskLruCache(size: number) {
|
public replaceDiskLruCache(size: number) {
|
||||||
if (this.diskMemoryCache.getCacheMap().size() <= 0) {
|
this.diskMemoryCache.setMaxSize(size)
|
||||||
this.diskMemoryCache = DiskLruCache.create(ImageKnifeGlobal.getInstance().getHapContext(), size);
|
// if (this.diskMemoryCache.getCacheMap().size() <= 0) {
|
||||||
} else {
|
// this.diskMemoryCache = DiskLruCache.create(ImageKnifeGlobal.getInstance().getHapContext(), size);
|
||||||
let newDiskLruCache = DiskLruCache.create(ImageKnifeGlobal.getInstance().getHapContext(), size);
|
// } else {
|
||||||
this.diskMemoryCache.foreachDiskLruCache((value: string | ArrayBuffer, key: string, map: Object) => {
|
// let newDiskLruCache = DiskLruCache.create(ImageKnifeGlobal.getInstance().getHapContext(), size);
|
||||||
newDiskLruCache.set(key, value);
|
// this.diskMemoryCache.foreachDiskLruCache((value: string | ArrayBuffer, key: string, map: Object) => {
|
||||||
})
|
// newDiskLruCache.set(key, value);
|
||||||
this.diskMemoryCache = newDiskLruCache;
|
// })
|
||||||
}
|
// this.diskMemoryCache = newDiskLruCache;
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
// 预加载 resource资源一级缓存,string资源实现二级缓存
|
// 预加载 resource资源一级缓存,string资源实现二级缓存
|
||||||
|
@ -216,28 +249,6 @@ export class ImageKnife {
|
||||||
async pauseRequests(): Promise<void> {
|
async pauseRequests(): Promise<void> {
|
||||||
await this.mutex.lock(async () => {
|
await this.mutex.lock(async () => {
|
||||||
this.isPaused = true;
|
this.isPaused = true;
|
||||||
|
|
||||||
// 将未删除的所有request [run pend] 放入 [pause]
|
|
||||||
LogUtil.log('dodo pauseRequests start1 pausedMaps size=' + this.pausedMaps.size() + ' runMaps Size=' + this.runningMaps.size() + ' pendMaps Size=' + this.pendingMaps.size())
|
|
||||||
|
|
||||||
// 将run存入pause
|
|
||||||
let runNode = this.runningMaps.getHead();
|
|
||||||
while (runNode) {
|
|
||||||
let request = runNode.value;
|
|
||||||
this.pausedMaps.put(request.uuid, request)
|
|
||||||
runNode = runNode.next;
|
|
||||||
}
|
|
||||||
this.runningMaps.clear();
|
|
||||||
LogUtil.log('dodo pauseRequests start2 pausedMaps size=' + this.pausedMaps.size() + ' runMaps Size=' + this.runningMaps.size() + ' pendMaps Size=' + this.pendingMaps.size())
|
|
||||||
|
|
||||||
let pendNode = this.pendingMaps.getHead();
|
|
||||||
while (pendNode) {
|
|
||||||
let request = pendNode.value;
|
|
||||||
this.pausedMaps.put(request.uuid, request)
|
|
||||||
pendNode = pendNode.next
|
|
||||||
}
|
|
||||||
this.pendingMaps.clear()
|
|
||||||
LogUtil.log('dodo pauseRequests start3 pausedMaps size=' + this.pausedMaps.size() + ' runMaps Size=' + this.runningMaps.size() + ' pendMaps Size=' + this.pendingMaps.size())
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -245,28 +256,19 @@ export class ImageKnife {
|
||||||
async resumeRequests(): Promise<void> {
|
async resumeRequests(): Promise<void> {
|
||||||
await this.mutex.lock(async () => {
|
await this.mutex.lock(async () => {
|
||||||
this.isPaused = false;
|
this.isPaused = false;
|
||||||
LogUtil.log('dodo resumeRequest start1 pausedMaps size=' + this.pausedMaps.size() + ' runMaps Size=' + this.runningMaps.size() + ' pendMaps Size=' + this.pendingMaps.size())
|
if (this.executingJobMap.length > 0) {
|
||||||
// 重启了之后需要把paused 里面的所有request重新发送
|
this.executingJobMap.forEach((list: List<RequestOption>) => {
|
||||||
let headNode = this.pausedMaps.getHead();
|
this.taskpoolLoadResource(list.get(0), Constants.MAIN_HOLDER);
|
||||||
while (headNode) {
|
})
|
||||||
let request = headNode.value
|
} else {
|
||||||
this.loadCacheManager(request)
|
this.dispatchNextJob();
|
||||||
headNode = headNode.next
|
|
||||||
}
|
}
|
||||||
this.pausedMaps.clear()
|
|
||||||
LogUtil.log('dodo resumeRequest start1 pausedMaps size=' + this.pausedMaps.size() + ' runMaps Size=' + this.runningMaps.size() + ' pendMaps Size=' + this.pendingMaps.size())
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 删除 请求
|
// 删除 请求
|
||||||
remove(uuid: string) {
|
remove(uuid: string) {
|
||||||
if (this.isPaused) {
|
this.executingJobMap.remove(uuid);
|
||||||
this.pausedMaps.remove(uuid)
|
|
||||||
} else {
|
|
||||||
// TODO 哪些请求可以删除
|
|
||||||
this.pendingMaps.remove(uuid)
|
|
||||||
this.runningMaps.remove(uuid)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 正常加载
|
// 正常加载
|
||||||
|
@ -279,27 +281,132 @@ export class ImageKnife {
|
||||||
// 每个request 公共信息补充
|
// 每个request 公共信息补充
|
||||||
request.setFilesPath(this.filesPath);
|
request.setFilesPath(this.filesPath);
|
||||||
|
|
||||||
|
if (this.headerMap.size > 0) {
|
||||||
|
request.addHeaderMap(this.headerMap)
|
||||||
|
}
|
||||||
|
|
||||||
|
this.generateDataCacheKey(request)
|
||||||
// 首先执行占位图 解析任务
|
// 首先执行占位图 解析任务
|
||||||
if (request.placeholderSrc) {
|
if (request.placeholderSrc) {
|
||||||
PlaceHolderManager.execute(request)
|
this.taskpoolLoadResource(request, Constants.PLACE_HOLDER);
|
||||||
}
|
}
|
||||||
// 其次执行重试占位图 解析任务
|
// 其次执行重试占位图 解析任务
|
||||||
if (request.retryholderSrc) {
|
if (request.retryholderSrc) {
|
||||||
RetryHolderManager.execute(request)
|
this.taskpoolLoadResource(request, Constants.RETRY_HOLDER);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 最后解析错误占位图
|
// 最后解析错误占位图
|
||||||
if (request.errorholderSrc) {
|
if (request.errorholderSrc) {
|
||||||
ErrorHolderManager.execute(request)
|
this.taskpoolLoadResource(request, Constants.ERROR_HOLDER);
|
||||||
}
|
}
|
||||||
return this.parseSource(request);
|
return this.parseSource(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
loadResources(request: RequestOption) {
|
|
||||||
|
public isUrlExist(url: string, cacheType: CacheType = CacheType.Default, size: Size = {
|
||||||
|
width: 0,
|
||||||
|
height: 0
|
||||||
|
}): Promise<ImageKnifeData> {
|
||||||
|
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
let request = new RequestOption();
|
||||||
|
request.load(url)
|
||||||
|
.setImageViewSize(size)
|
||||||
|
this.generateDataCacheKey(request);
|
||||||
|
let loadComplete = (imageKnifeData: ImageKnifeData) => {
|
||||||
|
resolve(imageKnifeData);
|
||||||
|
}
|
||||||
|
let loadError = (err ?: BusinessError | string) => {
|
||||||
|
if (cacheType == CacheType.Default) {
|
||||||
|
this.loadMemoryDiskIsUrl(request, loadComplete, loadError);
|
||||||
|
}
|
||||||
|
reject(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cacheType == CacheType.Cache) {
|
||||||
|
this.loadMemoryCacheIsUrl(request, loadComplete, loadError);
|
||||||
|
|
||||||
|
} else if (cacheType == CacheType.Disk) {
|
||||||
|
this.loadMemoryDiskIsUrl(request, loadComplete, loadError);
|
||||||
|
}
|
||||||
|
else if (cacheType == CacheType.Default) {
|
||||||
|
this.loadMemoryCacheIsUrl(request, loadComplete, loadError);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
loadMemoryCacheIsUrl(request: RequestOption, onComplete: (imageKnifeData: ImageKnifeData) => void | PromiseLike<ImageKnifeData>, onError: (err?: BusinessError | string) => void) {
|
||||||
|
let cache = this.memoryCacheProxy.loadMemoryCache(request.generateCacheKey, true);
|
||||||
|
if (cache == null || typeof cache == 'undefined') {
|
||||||
|
onError("No data in cache!")
|
||||||
|
} else {
|
||||||
|
cache.waitSaveDisk = false;
|
||||||
|
//2.网络缓存有数据,返回
|
||||||
|
onComplete(cache);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
loadMemoryDiskIsUrl(request: RequestOption, onComplete: (imageKnifeData: ImageKnifeData) => void | PromiseLike<ImageKnifeData>, onError: (err?: BusinessError | string) => void) {
|
||||||
|
let cached = this.diskMemoryCache.get(request.generateDataKey);
|
||||||
|
if (cached != null) {
|
||||||
|
let filetype: string | null = this.fileTypeUtil.getFileType(cached);
|
||||||
|
|
||||||
|
if (filetype == null) {
|
||||||
|
onError('请检查数据源');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.fileTypeUtil.isImage(cached)) {
|
||||||
|
onError('暂不支持的类型!类型=' + filetype);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((ImageKnifeData.GIF == filetype || ImageKnifeData.WEBP == filetype) && !request.dontAnimateFlag) {
|
||||||
|
let gifParseImpl = new GIFParseImpl()
|
||||||
|
gifParseImpl.parseGifs(cached, (data?: GIFFrame[], err?: BusinessError | string) => {
|
||||||
|
if (err) {
|
||||||
|
onError(err)
|
||||||
|
}
|
||||||
|
LogUtil.log("gifProcess data is null:" + (data == null));
|
||||||
|
if (!!data) {
|
||||||
|
let imageKnifeData = ImageKnifeData.createImageGIFFrame(ImageKnifeType.GIFFRAME, data);
|
||||||
|
LogUtil.log('gifProcess 生成gif 返回数据类型')
|
||||||
|
onComplete(imageKnifeData)
|
||||||
|
} else {
|
||||||
|
onError('Parse GIF callback data is null, you need check callback data!')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
} else if (ImageKnifeData.SVG == filetype) {
|
||||||
|
let svgParseImpl = new SVGParseImpl()
|
||||||
|
let success = (value: PixelMap) => {
|
||||||
|
let imageKnifeData = ImageKnifeData.createImagePixelMap(ImageKnifeType.PIXELMAP, value);
|
||||||
|
onComplete(imageKnifeData);
|
||||||
|
}
|
||||||
|
svgParseImpl.parseSvg(request, cached, success, onError)
|
||||||
|
} else {
|
||||||
|
//5.磁盘有数据,解析错误返回onError
|
||||||
|
let success = (value: PixelMap) => {
|
||||||
|
let imageKnifeData = ImageKnifeData.createImagePixelMap(ImageKnifeType.PIXELMAP, value);
|
||||||
|
onComplete(imageKnifeData);
|
||||||
|
}
|
||||||
|
this.mParseImageUtil.parseImage(cached, success, onError)
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
//6.磁盘无数据,返回onError
|
||||||
|
onError("No data in disk cache!")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
generateDataCacheKey(request: RequestOption) {
|
||||||
let factories: EngineKeyInterface;
|
let factories: EngineKeyInterface;
|
||||||
let cacheKey: string;
|
let cacheKey: string;
|
||||||
let transferKey: string;
|
let transferKey: string;
|
||||||
let dataKey: string;
|
let dataKey: string;
|
||||||
|
//设置全局缓存key
|
||||||
if (this.engineKeyImpl) {
|
if (this.engineKeyImpl) {
|
||||||
factories = this.engineKeyImpl;
|
factories = this.engineKeyImpl;
|
||||||
} else {
|
} else {
|
||||||
|
@ -331,133 +438,265 @@ export class ImageKnife {
|
||||||
|
|
||||||
let signature = request.signature;
|
let signature = request.signature;
|
||||||
|
|
||||||
cacheKey = factories.generateMemoryCacheKey(loadKey,size,transformed,dontAnimateFlag,signature);
|
cacheKey = factories.generateMemoryCacheKey(loadKey, size, transformed, dontAnimateFlag, signature);
|
||||||
|
|
||||||
// 生成磁盘缓存变换后数据key 变换后数据保存在磁盘
|
// 生成磁盘缓存变换后数据key 变换后数据保存在磁盘
|
||||||
transferKey = factories.generateTransformedDiskCacheKey(loadKey,size,transformed,dontAnimateFlag,signature);
|
transferKey = factories.generateTransformedDiskCacheKey(loadKey, size, transformed, dontAnimateFlag, signature);
|
||||||
|
|
||||||
// 生成磁盘缓存源数据key 原始数据保存在磁盘
|
// 生成磁盘缓存源数据key 原始数据保存在磁盘
|
||||||
dataKey = factories.generateOriginalDiskCacheKey(loadKey,signature);
|
dataKey = factories.generateOriginalDiskCacheKey(loadKey, signature);
|
||||||
|
if (request.placeholderSrc) {
|
||||||
|
let placeholderLoadKey = '';
|
||||||
|
if (typeof request.placeholderSrc == 'string') {
|
||||||
|
placeholderLoadKey = request.placeholderSrc;
|
||||||
|
// string类型占位图生成内存缓存源数据key
|
||||||
|
request.placeholderRegisterMemoryCacheKey = factories.generateMemoryCacheKey(placeholderLoadKey, size, transformed, dontAnimateFlag, signature);
|
||||||
|
// string类型占位图生成磁盘缓存源数据key 原始数据保存在磁盘
|
||||||
|
request.placeholderRegisterCacheKey = factories.generateOriginalDiskCacheKey(placeholderLoadKey, signature);
|
||||||
|
} else {
|
||||||
|
placeholderLoadKey = JSON.stringify(request.placeholderSrc);
|
||||||
|
request.placeholderCacheKey = this.generateCacheKey(placeholderLoadKey, size, dontAnimateFlag, signature);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (request.retryholderSrc) {
|
||||||
|
let retryholderLoadKey = '';
|
||||||
|
if (typeof request.retryholderSrc == 'string') {
|
||||||
|
retryholderLoadKey = request.retryholderSrc;
|
||||||
|
} else {
|
||||||
|
retryholderLoadKey = JSON.stringify(request.retryholderSrc);
|
||||||
|
}
|
||||||
|
request.retryholderCacheKey = this.generateCacheKey(retryholderLoadKey, size, dontAnimateFlag, signature)
|
||||||
|
}
|
||||||
|
if (request.errorholderSrc) {
|
||||||
|
let errorholderLoadKey = '';
|
||||||
|
if (typeof request.errorholderSrc == 'string') {
|
||||||
|
errorholderLoadKey = request.errorholderSrc;
|
||||||
|
} else {
|
||||||
|
errorholderLoadKey = JSON.stringify(request.errorholderSrc);
|
||||||
|
}
|
||||||
|
request.errorholderCacheKey = this.generateCacheKey(errorholderLoadKey, size, dontAnimateFlag, signature)
|
||||||
|
}
|
||||||
request.generateCacheKey = cacheKey;
|
request.generateCacheKey = cacheKey;
|
||||||
request.generateResourceKey = transferKey;
|
request.generateResourceKey = transferKey;
|
||||||
request.generateDataKey = dataKey;
|
request.generateDataKey = dataKey;
|
||||||
|
}
|
||||||
|
|
||||||
this.loadCacheManager(request);
|
private generateCacheKey(loadkey: string, size: string, dontAnimateFlag: boolean, signature?: ObjectKey) {
|
||||||
|
let factories: EngineKeyInterface;
|
||||||
|
|
||||||
|
//设置全局缓存key
|
||||||
|
if (this.engineKeyImpl) {
|
||||||
|
factories = this.engineKeyImpl;
|
||||||
|
} else {
|
||||||
|
factories = new EngineKeyFactories();
|
||||||
|
}
|
||||||
|
return factories.generateMemoryCacheKey(loadkey, size, '', dontAnimateFlag, signature);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 删除执行结束的running
|
// 删除执行结束的running
|
||||||
removeRunning(request: RequestOption) {
|
removeRunning(request: RequestOption) {
|
||||||
if (this.isPaused) {
|
if (!this.isPaused) {
|
||||||
|
//不暂停则继续加载
|
||||||
} else {
|
this.executingJobMap.remove(request.uuid);
|
||||||
this.runningMaps.remove(request.uuid);
|
this.dispatchNextJob();
|
||||||
console.log('dodo runningMaps length =' + this.runningMaps.size())
|
|
||||||
let previousRequest = request;
|
|
||||||
this.loadNextPending(previousRequest);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 执行相同key的pending队列请求
|
|
||||||
private keyEqualPendingToRun(nextPending: RequestOption) {
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
this.pendingMaps.remove(nextPending.uuid)
|
|
||||||
this.runningMaps.put(nextPending.uuid, nextPending);
|
|
||||||
|
|
||||||
RequestManager.execute((nextPending as RequestOption), this.memoryCache, this.diskMemoryCache, this.dataFetch, this.resourceFetch)
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private searchNextKeyToRun() {
|
|
||||||
// 其次则寻找pending中第一个和running不重复的requestOrKey
|
|
||||||
let pendingTailNode = this.pendingMaps.getTail();
|
|
||||||
while (pendingTailNode) {
|
|
||||||
let pendingRequest = pendingTailNode.value;
|
|
||||||
let hasEqual = false;
|
|
||||||
let runningTailNode = this.runningMaps.getTail();
|
|
||||||
while (runningTailNode) {
|
|
||||||
let runningRequest = runningTailNode.value;
|
|
||||||
if (this.requestOrKeyEqual(pendingRequest, runningRequest)) {
|
|
||||||
hasEqual = true;
|
|
||||||
break
|
|
||||||
}
|
|
||||||
runningTailNode = runningTailNode.prev;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hasEqual) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
pendingTailNode = pendingTailNode.prev;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pendingTailNode != null && pendingTailNode.value != null) {
|
|
||||||
let nextPending = pendingTailNode.value;
|
|
||||||
this.runningMaps.put(nextPending.uuid, nextPending)
|
|
||||||
this.pendingMaps.remove(nextPending.uuid)
|
|
||||||
RequestManager.execute((nextPending as RequestOption), this.memoryCache, this.diskMemoryCache, this.dataFetch, this.resourceFetch)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// 加载下一个key的请求
|
|
||||||
private loadNextPending(request: RequestOption) {
|
|
||||||
let hasEqualRunning = false;
|
|
||||||
let tailNode = this.pendingMaps.getTail();
|
|
||||||
while (tailNode) {
|
|
||||||
if (this.requestOrKeyEqual(request, tailNode.value)) {
|
|
||||||
hasEqualRunning = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
tailNode = tailNode.prev;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hasEqualRunning) {
|
|
||||||
if(tailNode != null && tailNode.value != null) {
|
|
||||||
this.keyEqualPendingToRun(tailNode.value);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
this.searchNextKeyToRun();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 启动新线程 去磁盘取 去网络取
|
// 启动新线程 去磁盘取 去网络取
|
||||||
private loadCacheManager(request: RequestOption) {
|
private loadCacheManager(request: RequestOption) {
|
||||||
if (this.isPaused) {
|
if (this.keyNotEmpty(request)) {
|
||||||
// 将当前request存入pausedMaps
|
if (this.executingJobMap.length > this.maxRequests) {
|
||||||
this.pausedMaps.put(request.uuid, request);
|
this.jobQueue.add(request);
|
||||||
} else {
|
return
|
||||||
// 正常逻辑
|
|
||||||
if (this.keyNotEmpty(request)) {
|
|
||||||
let hasRunningRequest = false;
|
|
||||||
// 遍历双向链表 从尾巴到头
|
|
||||||
let tailNode = this.runningMaps.getTail();
|
|
||||||
while (tailNode) {
|
|
||||||
if (this.requestOrKeyEqual(request, tailNode.value)) {
|
|
||||||
hasRunningRequest = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
tailNode = tailNode.prev
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hasRunningRequest) {
|
|
||||||
this.pendingMaps.put(request.uuid, request);
|
|
||||||
|
|
||||||
|
|
||||||
} else {
|
|
||||||
this.runningMaps.put(request.uuid, request)
|
|
||||||
|
|
||||||
|
|
||||||
// 不存在相同key的 任务可以并行
|
|
||||||
RequestManager.execute(request, this.memoryCache, this.diskMemoryCache, this.dataFetch, this.resourceFetch)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
let requestList: List<RequestOption> | undefined = this.executingJobMap.get(request.uuid);
|
||||||
LogUtil.log("key没有生成无法进入存取!")
|
if (requestList == undefined) {
|
||||||
|
requestList = new List();
|
||||||
|
requestList.add(request);
|
||||||
|
this.executingJobMap.set(request.uuid, requestList);
|
||||||
|
if (!this.isPaused) {
|
||||||
|
LogUtil.log("loadCacheManager start uuid : " + request.uuid + " url : " + request.loadSrc);
|
||||||
|
//暂停则不开启加载
|
||||||
|
this.taskpoolLoadResource(request, Constants.MAIN_HOLDER);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
requestList.add(request);
|
||||||
|
this.executingJobMap.set(request.uuid, requestList);
|
||||||
|
LogUtil.log("loadCacheManager reuse uuid : " + request.uuid + " url : " + request.loadSrc);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
LogUtil.log("key没有生成无法进入存取!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private assembleSendableData(request: RequestOption, usageType: string){
|
||||||
|
//图片变换方法无法直接传递到子线程,这里先把对象名和构造参数传递到子线程,然后在子线程中实例化变换方法
|
||||||
|
|
||||||
|
let transformations: collections.Array<collections.Array<string>> = new collections.Array<collections.Array<string>>();
|
||||||
|
|
||||||
|
if (usageType == Constants.MAIN_HOLDER) {
|
||||||
|
for (let i = 0; i < request.transformations.length; i++) {
|
||||||
|
let item = collections.Array.from([request.transformations[i].getClassName(), request.transformations[i].getConstructorParams()]) as collections.Array<string>;
|
||||||
|
transformations.push(item)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
let displayProgress = request.progressFunc ? true : false;
|
||||||
|
|
||||||
|
let data: SendableData = new SendableData();
|
||||||
|
data.setUsageType(usageType)
|
||||||
|
data.setDisplayProgress(displayProgress)
|
||||||
|
data.setUuid(request.uuid)
|
||||||
|
data.setDontAnimateFlag(request.dontAnimateFlag)
|
||||||
|
data.setThumbSizeMultiplier(request.thumbSizeMultiplier)
|
||||||
|
data.setThumbDelayTime(request.thumbDelayTime)
|
||||||
|
data.setOnlyRetrieveFromCache(request.onlyRetrieveFromCache)
|
||||||
|
data.setIsCacheable(request.isCacheable)
|
||||||
|
data.setGpuEnabled(request.gpuEnabled)
|
||||||
|
data.setGenerateCacheKey(request.generateCacheKey)
|
||||||
|
data.setGenerateResourceKey(request.generateResourceKey)
|
||||||
|
data.setGenerateDataKey(request.generateDataKey)
|
||||||
|
data.setSignature(request.signature)
|
||||||
|
data.setTransformations(transformations)
|
||||||
|
data.setDiskMemoryCache(this.diskMemoryCache)
|
||||||
|
data.setDataFetch(this.dataFetch)
|
||||||
|
data.setDiskMemoryCachePath(this.diskMemoryCache.getPath())
|
||||||
|
data.setPlaceHolderRegisterCacheKey(request.placeholderRegisterCacheKey);
|
||||||
|
data.setPlaceHolderRegisterMemoryCacheKey(request.placeholderRegisterMemoryCacheKey);
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
private assembleSTaskData(request: RequestOption){
|
||||||
|
let data: TaskParams = {
|
||||||
|
headers: request.headers,
|
||||||
|
moduleContext: request.moduleContext,
|
||||||
|
priority: request.priority,
|
||||||
|
size: request.size,
|
||||||
|
loadSrc: this.transformResource(request.loadSrc) as string | PixelMap | MResource,
|
||||||
|
placeholderSrc: this.transformResource(request.placeholderSrc) as string | PixelMap | MResource | undefined,
|
||||||
|
errorholderSrc: this.transformResource(request.errorholderSrc) as PixelMap | MResource | undefined,
|
||||||
|
retryholderSrc:this.transformResource(request.retryholderSrc) as PixelMap | MResource | undefined,
|
||||||
|
fallbackSrc: this.transformResource(request.fallbackSrc) as PixelMap | MResource | undefined,
|
||||||
|
customGetImage: request.customGetImage
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
private transformResource(loadSrc:string | PixelMap | Resource | undefined):string | PixelMap | MResource | undefined{
|
||||||
|
let res = loadSrc as Resource
|
||||||
|
if (res && res.id && res.type) {
|
||||||
|
return {
|
||||||
|
bundleName: res.bundleName,
|
||||||
|
moduleName: res.moduleName,
|
||||||
|
id: res.id,
|
||||||
|
params: res.params,
|
||||||
|
type: res.type
|
||||||
|
} as MResource;
|
||||||
|
}
|
||||||
|
return loadSrc as string | PixelMap | undefined;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//多线程请求加载资源
|
||||||
|
private taskpoolLoadResource(request: RequestOption, usageType: string) {
|
||||||
|
// string类型占位图实现从缓存中获取图片
|
||||||
|
if (request.placeholderSrc == 'string') {
|
||||||
|
request.placeholderCacheKey = request.placeholderRegisterMemoryCacheKey;
|
||||||
|
}
|
||||||
|
let mainCache = this.memoryCacheProxy.loadMemoryCache(request.generateCacheKey, request.isCacheable);
|
||||||
|
let placeholderCache = this.memoryCacheProxy.loadMemoryCache(request.placeholderCacheKey, request.isCacheable);
|
||||||
|
let retryholderCache = this.memoryCacheProxy.loadMemoryCache(request.retryholderCacheKey, request.isCacheable);
|
||||||
|
let errorholderCacheKey = this.memoryCacheProxy.loadMemoryCache(request.errorholderCacheKey, request.isCacheable);
|
||||||
|
|
||||||
|
if (usageType == Constants.PLACE_HOLDER && placeholderCache && !mainCache && !retryholderCache && !errorholderCacheKey) {
|
||||||
|
LogUtil.info("imageknife load placeholder from MemoryCache")
|
||||||
|
request.placeholderOnComplete(placeholderCache);
|
||||||
|
return;
|
||||||
|
} else if (usageType == Constants.RETRY_HOLDER && retryholderCache && !mainCache && !errorholderCacheKey) {
|
||||||
|
LogUtil.info("imageknife load retryholder from MemoryCache")
|
||||||
|
request.retryholderOnComplete(retryholderCache);
|
||||||
|
return;
|
||||||
|
} else if (usageType == Constants.ERROR_HOLDER && errorholderCacheKey && !mainCache) {
|
||||||
|
LogUtil.info("imageknife load errorholder from MemoryCache")
|
||||||
|
request.errorholderOnComplete(errorholderCacheKey);
|
||||||
|
return;
|
||||||
|
} else if (usageType == Constants.MAIN_HOLDER && mainCache) {
|
||||||
|
LogUtil.info("imageknife load mainsource from MemoryCache")
|
||||||
|
mainCache.waitSaveDisk = false;
|
||||||
|
let requestList: List<RequestOption> | undefined = this.executingJobMap.get(request.uuid);
|
||||||
|
if(requestList != undefined) {
|
||||||
|
requestList.forEach((requestOption: RequestOption)=>{
|
||||||
|
requestOption.loadComplete(mainCache as ImageKnifeData);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//组装可以通过sendable传递的数据
|
||||||
|
let sendData:SendableData = this.assembleSendableData(request, usageType);
|
||||||
|
//其他不能sendable发送的数据
|
||||||
|
let taskData:TaskParams = this.assembleSTaskData(request);
|
||||||
|
|
||||||
|
//使用taskpool多线程执行资源下载
|
||||||
|
let task: ESObject = new taskpool.Task(taskExecute,sendData,taskData)
|
||||||
|
if (request.progressFunc){
|
||||||
|
emitter.on(Constants.PROGRESS_EMITTER as ESObject, (data: ESObject) => {
|
||||||
|
if (request.progressFunc && data?.data?.value) {
|
||||||
|
let percent = data.data.value as number;
|
||||||
|
request.progressFunc.asyncSuccess(percent);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
taskpool.execute(task,request.priority).then((data: ESObject) => {
|
||||||
|
if (usageType == Constants.PLACE_HOLDER) {
|
||||||
|
if ((typeof (data as PixelMap).isEditable) == 'boolean') {
|
||||||
|
let imageKnifeData = ImageKnifeData.createImagePixelMap(ImageKnifeType.PIXELMAP, data as PixelMap);
|
||||||
|
request.placeholderOnComplete(imageKnifeData)
|
||||||
|
this.memoryCacheProxy.putValue(request.placeholderCacheKey,imageKnifeData)
|
||||||
|
} else {
|
||||||
|
request.placeholderOnError("request placeholder error")
|
||||||
|
}
|
||||||
|
} else if (usageType == Constants.RETRY_HOLDER) {
|
||||||
|
if ((typeof (data as PixelMap).isEditable) == 'boolean') {
|
||||||
|
let imageKnifeData = ImageKnifeData.createImagePixelMap(ImageKnifeType.PIXELMAP, data as PixelMap);
|
||||||
|
request.retryholderOnComplete(imageKnifeData)
|
||||||
|
this.memoryCacheProxy.putValue(request.retryholderCacheKey,imageKnifeData)
|
||||||
|
} else {
|
||||||
|
request.retryholderOnError("request retryholder error")
|
||||||
|
}
|
||||||
|
} else if (usageType == Constants.ERROR_HOLDER) {
|
||||||
|
if ((typeof (data as PixelMap).isEditable) == 'boolean') {
|
||||||
|
let imageKnifeData = ImageKnifeData.createImagePixelMap(ImageKnifeType.PIXELMAP, data as PixelMap);
|
||||||
|
request.errorholderOnComplete(imageKnifeData)
|
||||||
|
this.memoryCacheProxy.putValue(request.errorholderCacheKey,imageKnifeData)
|
||||||
|
} else {
|
||||||
|
request.errorholderOnError("request errorholder error")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if ((typeof (data as PixelMap).isEditable) == 'boolean') {
|
||||||
|
let imageKnifeData = ImageKnifeData.createImagePixelMap(ImageKnifeType.PIXELMAP, data as PixelMap);
|
||||||
|
let requestList: List<RequestOption> | undefined = this.executingJobMap.get(request.uuid)
|
||||||
|
if(requestList != undefined) {
|
||||||
|
requestList.forEach((requestOption: RequestOption)=>{
|
||||||
|
requestOption.loadComplete(imageKnifeData);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
this.memoryCacheProxy.putValue(request.generateCacheKey, imageKnifeData);
|
||||||
|
} else if ((data as GIFFrame[]).length > 0) {
|
||||||
|
let imageKnifeData = ImageKnifeData.createImageGIFFrame(ImageKnifeType.GIFFRAME, data as GIFFrame[]);
|
||||||
|
let requestList: List<RequestOption> | undefined = this.executingJobMap.get(request.uuid);
|
||||||
|
if(requestList != undefined) {
|
||||||
|
requestList.forEach((requestOption: RequestOption)=>{
|
||||||
|
requestOption.loadComplete(imageKnifeData);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
this.memoryCacheProxy.putValue(request.generateCacheKey, imageKnifeData);
|
||||||
|
} else {
|
||||||
|
request.loadError("request resources error")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).catch((err: BusinessError | string) => {
|
||||||
|
request.loadError(err)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
private keyNotEmpty(request: RequestOption): boolean {
|
private keyNotEmpty(request: RequestOption): boolean {
|
||||||
|
@ -471,61 +710,162 @@ export class ImageKnife {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private keyEqual(request1: RequestOption, request2: RequestOption): boolean {
|
|
||||||
// key 完全相等的情况
|
|
||||||
if (
|
|
||||||
request1.generateCacheKey == request2.generateCacheKey &&
|
|
||||||
request1.generateResourceKey == request2.generateResourceKey &&
|
|
||||||
request1.generateDataKey == request2.generateDataKey
|
|
||||||
) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 非严格校验模式,如果所有key相等我们认为一定相等, 如果请求类型是string 网络请求url或者uri相等 我们也认为该请求应该只发送一个即可,后续请求会去缓存或者磁盘读取
|
|
||||||
private requestOrKeyEqual(request1: RequestOption, request2: RequestOption): boolean {
|
|
||||||
// key 完全相等的情况
|
|
||||||
if (
|
|
||||||
request1.generateCacheKey == request2.generateCacheKey &&
|
|
||||||
request1.generateResourceKey == request2.generateResourceKey &&
|
|
||||||
request1.generateDataKey == request2.generateDataKey
|
|
||||||
) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 如果加载的是网络url或者是本地文件uri读取,那么loadSrc相同就认为是同一个请求
|
|
||||||
if (
|
|
||||||
typeof request1.loadSrc == 'string' && typeof request2.loadSrc == 'string' && request1.loadSrc == request2.loadSrc
|
|
||||||
) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private parseSource(request: RequestOption): void {
|
private parseSource(request: RequestOption): void {
|
||||||
if ((typeof (request.loadSrc as image.PixelMap).isEditable) == 'boolean') {
|
if ((typeof (request.loadSrc as image.PixelMap).isEditable) == 'boolean') {
|
||||||
let imageKnifeData = ImageKnifeData.createImagePixelMap(ImageKnifeType.PIXELMAP, request.loadSrc as PixelMap)
|
let imageKnifeData = ImageKnifeData.createImagePixelMap(ImageKnifeType.PIXELMAP, request.loadSrc as PixelMap)
|
||||||
request.loadComplete(imageKnifeData);
|
request.loadComplete(imageKnifeData);
|
||||||
} else
|
} else if (typeof request.loadSrc == 'string') {
|
||||||
if (typeof request.loadSrc == 'string') {
|
// 进入三级缓存模型
|
||||||
// 进入三级缓存模型
|
return this.loadCacheManager(request);
|
||||||
return this.loadResources(request);
|
} else {
|
||||||
} else {
|
|
||||||
let res = request.loadSrc as Resource;
|
let res = request.loadSrc as Resource;
|
||||||
if (typeof res.id != 'undefined' && typeof res.type != 'undefined') {
|
if (typeof res.id != 'undefined' && typeof res.type != 'undefined') {
|
||||||
// 进入三级缓存模型 本地资源不参与磁盘缓存
|
// 进入三级缓存模型 本地资源不参与磁盘缓存
|
||||||
let none = new NONE();
|
let none = new NONE();
|
||||||
request.diskCacheStrategy(none);
|
request.diskCacheStrategy(none);
|
||||||
this.loadResources(request);
|
this.loadCacheManager(request);
|
||||||
} else {
|
} else {
|
||||||
LogUtil.error("输入参数有问题!")
|
LogUtil.error("输入参数有问题!")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
prefetchToDiskCache(url: string): Promise<string> {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
let key = this.engineKeyImpl.generateOriginalDiskCacheKey(url, undefined);
|
||||||
|
let cachedPath = this.getDiskMemoryCache().getFileToPath(key);
|
||||||
|
if (cachedPath == null || cachedPath == "" || cachedPath == undefined) {
|
||||||
|
let request = new RequestOption();
|
||||||
|
request.load(url)
|
||||||
|
.addListener({ callback: (err: BusinessError | string, data: ImageKnifeData) => {
|
||||||
|
if (err) {
|
||||||
|
reject(err)
|
||||||
|
} else {
|
||||||
|
let cachedPath = this.getDiskMemoryCache().getFileToPath(key);
|
||||||
|
resolve(cachedPath);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
this.call(request);
|
||||||
|
} else {
|
||||||
|
resolve(cachedPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 分发下一个任务
|
||||||
|
dispatchNextJob() {
|
||||||
|
let request: RequestOption | undefined = this.jobQueue.pop();
|
||||||
|
if (request != undefined) {
|
||||||
|
this.loadCacheManager(request);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置请求的最大并发数量
|
||||||
|
setMaxRequests(count: number) {
|
||||||
|
if (count > 0) {
|
||||||
|
this.maxRequests = count;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 加载资源子线程包含流程:网络请求资源->下载资源到本地->解码成ixelMap | GIFFrame[]->缓存到内存和磁盘
|
||||||
|
* @param taskParams:任务参数,JSON字符串类型
|
||||||
|
* @param headers:请求头
|
||||||
|
* @param moduleContext:模块上下文
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
@Concurrent
|
||||||
|
async function taskExecute(sendData:SendableData,taskData:TaskParams): Promise<PixelMap | GIFFrame[]> {
|
||||||
|
|
||||||
|
//sendable里面加载http模块有问题,需要在@Concurrent先使用下,临时规避方法,待Sendable解决后删除
|
||||||
|
let unused_arg0 = http.CertType;
|
||||||
|
|
||||||
|
let emitProgressPercent = (percentValue: number) => {
|
||||||
|
let eventData: emitter.EventData = {
|
||||||
|
data: {
|
||||||
|
"value": percentValue,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
emitter.emit(Constants.PROGRESS_EMITTER as ESObject, eventData)
|
||||||
|
}
|
||||||
|
|
||||||
|
let transformations = sendData.getTransformations();
|
||||||
|
let usageType = sendData.getUsageType();
|
||||||
|
let displayProgress = sendData.getDisplayProgress();
|
||||||
|
//子线程构造RequestOption对象
|
||||||
|
let newRequestOption = new RequestOption();
|
||||||
|
newRequestOption.priority = taskData.priority;
|
||||||
|
newRequestOption.uuid = sendData.getUuid();
|
||||||
|
newRequestOption.loadSrc = taskData.loadSrc as string | PixelMap | Resource;
|
||||||
|
newRequestOption.dontAnimateFlag = sendData.getDontAnimateFlag();
|
||||||
|
newRequestOption.generateCacheKey = sendData.getGenerateCacheKey();
|
||||||
|
newRequestOption.generateResourceKey = sendData.getGenerateResourceKey();
|
||||||
|
newRequestOption.generateDataKey = sendData.getGenerateDataKey();
|
||||||
|
newRequestOption.thumbSizeMultiplier = sendData.getThumbSizeMultiplier();
|
||||||
|
newRequestOption.thumbDelayTime = sendData.getThumbDelayTime();
|
||||||
|
newRequestOption.size = taskData.size;
|
||||||
|
newRequestOption.placeholderRegisterCacheKey = sendData.getPlaceHolderRegisterCacheKey();
|
||||||
|
newRequestOption.placeholderRegisterMemoryCacheKey = sendData.getPlaceHolderRegisterMemoryCacheKey();
|
||||||
|
|
||||||
|
if(taskData.placeholderSrc){
|
||||||
|
newRequestOption.placeholderSrc = taskData.placeholderSrc as string | PixelMap | Resource | undefined;
|
||||||
|
}
|
||||||
|
if(taskData.fallbackSrc){
|
||||||
|
newRequestOption.fallbackSrc = taskData.fallbackSrc as PixelMap | Resource | undefined;
|
||||||
|
}
|
||||||
|
if(taskData.errorholderSrc){
|
||||||
|
newRequestOption.errorholderSrc = taskData.errorholderSrc as PixelMap | Resource | undefined;
|
||||||
|
}
|
||||||
|
if(taskData.retryholderSrc){
|
||||||
|
newRequestOption.retryholderSrc = taskData.retryholderSrc as PixelMap | Resource | undefined;
|
||||||
|
}
|
||||||
|
newRequestOption.onlyRetrieveFromCache = sendData.getOnlyRetrieveFromCache();
|
||||||
|
newRequestOption.gpuEnabled = sendData.getGpuEnabled();
|
||||||
|
newRequestOption.headers = taskData.headers;
|
||||||
|
newRequestOption.signature = sendData.getSignature();
|
||||||
|
ImageKnifeGlobal.getInstance().setHapContext(taskData.moduleContext as common.UIAbilityContext);
|
||||||
|
newRequestOption.moduleContext = taskData.moduleContext as common.UIAbilityContext;
|
||||||
|
newRequestOption.isCacheable = sendData.getIsCacheable();
|
||||||
|
//设置磁盘缓存路径
|
||||||
|
newRequestOption.diskMemoryCachePath = sendData.getDiskMemoryCachePath();
|
||||||
|
newRequestOption.customGetImage = taskData.customGetImage;
|
||||||
|
if (displayProgress) {
|
||||||
|
newRequestOption.addProgressListener({
|
||||||
|
asyncSuccess: (percentValue: number) => {
|
||||||
|
// 如果进度条百分比 未展示大小,展示其动画
|
||||||
|
emitProgressPercent(percentValue)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
//如果是本地图片不作磁盘缓存
|
||||||
|
if (typeof newRequestOption.loadSrc !== 'string') {
|
||||||
|
let none = new NONE();
|
||||||
|
newRequestOption.diskCacheStrategy(none);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (usageType == Constants.PLACE_HOLDER) {
|
||||||
|
let manager = new PlaceHolderManager<PixelMap>(newRequestOption);
|
||||||
|
return await new Promise<PixelMap>(manager.process);
|
||||||
|
} else if (usageType == Constants.RETRY_HOLDER) {
|
||||||
|
let manager = new RetryHolderManager<PixelMap>(newRequestOption);
|
||||||
|
return await new Promise<PixelMap>(manager.process);
|
||||||
|
} else if (usageType == Constants.ERROR_HOLDER) {
|
||||||
|
let manager = new ErrorHolderManager<PixelMap>(newRequestOption);
|
||||||
|
return await new Promise<PixelMap>(manager.process);
|
||||||
|
} else {
|
||||||
|
if (transformations) {
|
||||||
|
newRequestOption.setTransformations(TransformUtils.addTransformations(transformations))
|
||||||
|
}
|
||||||
|
let diskMemoryCache = sendData.getDiskMemoryCache();
|
||||||
|
let newDataFetch = sendData.getDataFetch();
|
||||||
|
let newResourceFetch = new ParseResClient();
|
||||||
|
let manager = new RequestManager(newRequestOption, diskMemoryCache as DiskLruCache, newDataFetch, newResourceFetch);
|
||||||
|
return await new Promise<PixelMap | GIFFrame[]>(manager.process);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,27 +23,41 @@ import { IDrawLifeCycle } from '../imageknife/interface/IDrawLifeCycle'
|
||||||
import { LogUtil } from '../imageknife/utils/LogUtil'
|
import { LogUtil } from '../imageknife/utils/LogUtil'
|
||||||
import { BusinessError } from '@ohos.base'
|
import { BusinessError } from '@ohos.base'
|
||||||
import common from '@ohos.app.ability.common'
|
import common from '@ohos.app.ability.common'
|
||||||
|
import { ObjectKey } from './ObjectKey'
|
||||||
|
import componentUtils from '@ohos.arkui.componentUtils'
|
||||||
|
import inspector from '@ohos.arkui.inspector'
|
||||||
|
import util from '@ohos.util'
|
||||||
|
import { ImageKnifeDrawFactory } from './ImageKnifeDrawFactory'
|
||||||
|
|
||||||
|
interface KeyCanvas {
|
||||||
|
keyId:string
|
||||||
|
}
|
||||||
@Component
|
@Component
|
||||||
export struct ImageKnifeComponent {
|
export struct ImageKnifeComponent {
|
||||||
@Watch('watchImageKnifeOption') @ObjectLink imageKnifeOption: ImageKnifeOption;
|
@Watch('watchImageKnifeOption') @ObjectLink imageKnifeOption: ImageKnifeOption;
|
||||||
autoPlay: boolean = true
|
|
||||||
private settings: RenderingContextSettings = new RenderingContextSettings(true)
|
private settings: RenderingContextSettings = new RenderingContextSettings(true)
|
||||||
private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings)
|
private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings)
|
||||||
private hasDisplayRetryholder = false;
|
private hasDisplayRetryholder = false;
|
||||||
private lastWidth: number = 0
|
private lastWidth: number = 0
|
||||||
private lastHeight: number = 0
|
private lastHeight: number = 0
|
||||||
private currentWidth: number = 0
|
// 当前帧数位置
|
||||||
private currentHeight: number = 0
|
private renderFrames_index = 0;
|
||||||
// 定时器id
|
// 定时器id
|
||||||
private gifTimerId: number = -1
|
private gifTimerId: number = -1
|
||||||
// 完整gif播放时间
|
// 完整gif播放时间
|
||||||
private gifLoopDuration: number = 0
|
private gifLoopDuration: number = 0
|
||||||
private startGifLoopTime: number = 0
|
private startGifLoopTime: number = 0
|
||||||
private endGifLoopTime: number = 0
|
private endGifLoopTime: number = 0
|
||||||
|
// gif 播放次数
|
||||||
|
private playTimes: number = 0
|
||||||
// 抗锯齿属性
|
// 抗锯齿属性
|
||||||
private imageSmoothingQuality: ImageSmoothingQuality = 'low';
|
private imageSmoothingQuality: ImageSmoothingQuality = 'low';
|
||||||
private imageSmoothingEnabled: boolean = true;
|
private imageSmoothingEnabled: boolean = true;
|
||||||
|
// 是否是gif图片
|
||||||
|
private isGif: boolean = false
|
||||||
|
@State keyCanvas: KeyCanvas = {
|
||||||
|
keyId: util.generateRandomUUID()
|
||||||
|
}
|
||||||
defaultLifeCycle: IDrawLifeCycle = {
|
defaultLifeCycle: IDrawLifeCycle = {
|
||||||
|
|
||||||
// 展示占位图
|
// 展示占位图
|
||||||
|
@ -91,33 +105,20 @@ export struct ImageKnifeComponent {
|
||||||
private detachFromLayoutGIF :DetachFromLayout|undefined = undefined;
|
private detachFromLayoutGIF :DetachFromLayout|undefined = undefined;
|
||||||
|
|
||||||
private detachFromLayoutPixelMap :DetachFromLayout|undefined = undefined;
|
private detachFromLayoutPixelMap :DetachFromLayout|undefined = undefined;
|
||||||
|
private lastSrc: string | Resource | PixelMap = ""
|
||||||
|
listener: inspector.ComponentObserver = inspector.createComponentObserver(this.keyCanvas.keyId)
|
||||||
|
|
||||||
|
@State currentSize : Size = {
|
||||||
|
width: 0.01,
|
||||||
|
height: 0.01
|
||||||
|
}
|
||||||
|
|
||||||
build() {
|
build() {
|
||||||
Canvas(this.context)
|
Canvas(this.context)
|
||||||
.width('100%')
|
.key(this.keyCanvas.keyId)
|
||||||
.height('100%')
|
.width((this.imageKnifeOption!=undefined && this.imageKnifeOption.mainScaleType!= undefined && this.imageKnifeOption.mainScaleType == ScaleType.AUTO_WIDTH )? this.currentSize.width:'100%')
|
||||||
|
.height((this.imageKnifeOption!=undefined && this.imageKnifeOption.mainScaleType!= undefined && this.imageKnifeOption.mainScaleType == ScaleType.AUTO_HEIGHT )? this.currentSize.height:'100%')
|
||||||
.renderFit(RenderFit.RESIZE_FILL)
|
.renderFit(RenderFit.RESIZE_FILL)
|
||||||
.onAreaChange((oldValue: Area, newValue: Area) => {
|
|
||||||
if(newValue != undefined && newValue.width != undefined && newValue.height != undefined) {
|
|
||||||
this.currentWidth = newValue.width as number
|
|
||||||
this.currentHeight = newValue.height as number
|
|
||||||
this.lastWidth = oldValue.width as number
|
|
||||||
this.lastHeight = oldValue.height as number
|
|
||||||
if (this.currentWidth <= 0 || this.currentHeight <= 0) {
|
|
||||||
// 存在宽或者高为0,此次重回无意义,无需进行request请求
|
|
||||||
} else {
|
|
||||||
// 前提:宽高值均有效,值>0. 条件1:当前宽高与上一次宽高不同 条件2:当前是第一次绘制
|
|
||||||
if ((this.currentHeight != this.lastHeight || this.currentWidth != this.lastWidth) || this.firstDrawFlag) {
|
|
||||||
this.firstDrawFlag = false;
|
|
||||||
LogUtil.log('ImageKnifeComponent onAreaChange And Next To Execute. Canvas currentWidth =' + this.currentWidth + ' currentHeight=' + this.currentHeight)
|
|
||||||
this.imageKnifeExecute()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
LogUtil.log('ImageKnifeComponent onAreaChange Error newValue is undefined')
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.onReady(() => {
|
.onReady(() => {
|
||||||
let ctx = this.context;
|
let ctx = this.context;
|
||||||
ctx.imageSmoothingEnabled = this.imageSmoothingEnabled;
|
ctx.imageSmoothingEnabled = this.imageSmoothingEnabled;
|
||||||
|
@ -140,9 +141,24 @@ export struct ImageKnifeComponent {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
onLayoutComplete:()=>void = ():void=>{
|
||||||
|
if (this.context.width <= 0 || this.context.height <= 0) {
|
||||||
|
// 存在宽或者高为0,此次重回无意义,无需进行request请求
|
||||||
|
} else {
|
||||||
|
// 前提:宽高值均有效,值>0. 条件1:当前宽高与上一次宽高不同 条件2:当前是第一次绘制
|
||||||
|
if ((this.context.height != this.lastHeight || this.context.width != this.lastWidth) || this.firstDrawFlag) {
|
||||||
|
this.firstDrawFlag = false;
|
||||||
|
LogUtil.log('ImageKnifeComponent onAreaChange And Next To Execute. Canvas currentWidth =' + this.context.width + ' currentHeight=' + this.context.height)
|
||||||
|
this.lastWidth = this.context.width
|
||||||
|
this.lastHeight = this.context.height
|
||||||
|
this.imageKnifeExecute()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
watchImageKnifeOption() {
|
watchImageKnifeOption() {
|
||||||
LogUtil.log('ImageKnifeComponent watchImageKnifeOption is happened!')
|
LogUtil.log('ImageKnifeComponent watchImageKnifeOption is happened!')
|
||||||
|
this.lastSrc = this.imageKnifeOption.loadSrc
|
||||||
this.whetherWaitSize();
|
this.whetherWaitSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -152,7 +168,7 @@ export struct ImageKnifeComponent {
|
||||||
* @param drawFirst 是否是aboutToAppear第一次绘制
|
* @param drawFirst 是否是aboutToAppear第一次绘制
|
||||||
*/
|
*/
|
||||||
whetherWaitSize(drawFirst?: boolean) {
|
whetherWaitSize(drawFirst?: boolean) {
|
||||||
if (this.currentHeight <= 0 || this.currentWidth <= 0) {
|
if (this.context.height <= 0 || this.context.width <= 0) {
|
||||||
// 宽或者高没有高度,需要等待canvas组件初始化完成
|
// 宽或者高没有高度,需要等待canvas组件初始化完成
|
||||||
if (drawFirst) {
|
if (drawFirst) {
|
||||||
this.firstDrawFlag = true;
|
this.firstDrawFlag = true;
|
||||||
|
@ -188,11 +204,18 @@ export struct ImageKnifeComponent {
|
||||||
request.load(this.imageKnifeOption.loadSrc)
|
request.load(this.imageKnifeOption.loadSrc)
|
||||||
.addListener({ callback: (err:BusinessError|string, data:ImageKnifeData) => {
|
.addListener({ callback: (err:BusinessError|string, data:ImageKnifeData) => {
|
||||||
LogUtil.log('ImageKnifeComponent request.load callback')
|
LogUtil.log('ImageKnifeComponent request.load callback')
|
||||||
this.runNextFunction(this.displayMainSource,data);
|
if(data.isGIFFrame()) {
|
||||||
|
this.isGif = true
|
||||||
|
} else {
|
||||||
|
this.isGif = false
|
||||||
|
}
|
||||||
|
if(this.lastSrc !== request.loadSrc && this.lastSrc !== ""){}
|
||||||
|
else {
|
||||||
|
this.runNextFunction(this.displayMainSource,data);
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
let realSize:Size = {
|
let realSize:Size = {
|
||||||
width: this.context.width,
|
width: this.context.width,
|
||||||
height: this.context.height
|
height: this.context.height
|
||||||
|
@ -222,25 +245,42 @@ export struct ImageKnifeComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
configDisplay(request: RequestOption) {
|
configDisplay(request: RequestOption) {
|
||||||
|
//单个image组件多个请求头调用
|
||||||
|
if (this.imageKnifeOption.headerOption != undefined && this.imageKnifeOption.headerOption?.length > 0) {
|
||||||
|
for (let i = 0; i < this.imageKnifeOption.headerOption.length; i++) {
|
||||||
|
let headerOptions = this.imageKnifeOption.headerOption[i];
|
||||||
|
request.addHeader(headerOptions.key, headerOptions.value);
|
||||||
|
request.signature = new ObjectKey(new Date().getTime().toString())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( this.imageKnifeOption.priority != undefined) {
|
||||||
|
request.setPriority(this.imageKnifeOption.priority)
|
||||||
|
}
|
||||||
if (this.imageKnifeOption.placeholderSrc) {
|
if (this.imageKnifeOption.placeholderSrc) {
|
||||||
request.placeholder(this.imageKnifeOption.placeholderSrc, {asyncSuccess:(data:ImageKnifeData) => {
|
request.placeholder(this.imageKnifeOption.placeholderSrc, {asyncSuccess:(data:ImageKnifeData) => {
|
||||||
LogUtil.log('ImageKnifeComponent request.placeholder callback')
|
LogUtil.log('ImageKnife ImageKnifeComponent request.placeholder callback')
|
||||||
this.runNextFunction(this.displayPlaceholder,data)
|
this.runNextFunction(this.displayPlaceholder,data)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
if (this.imageKnifeOption.thumbSizeMultiplier) {
|
if (this.imageKnifeOption.thumbSizeMultiplier) {
|
||||||
request.thumbnail(this.imageKnifeOption.thumbSizeMultiplier, {asyncSuccess:(data:ImageKnifeData) => {
|
request.thumbnail(this.imageKnifeOption.thumbSizeMultiplier, {asyncSuccess:(data:ImageKnifeData) => {
|
||||||
LogUtil.log('ImageKnifeComponent request.thumbnail callback')
|
LogUtil.log('ImageKnife ImageKnifeComponent request.thumbnail callback')
|
||||||
this.runNextFunction(this.displayThumbSizeMultiplier,data)
|
this.runNextFunction(this.displayThumbSizeMultiplier,data)
|
||||||
}}, this.imageKnifeOption.thumbSizeDelay)
|
}}, this.imageKnifeOption.thumbSizeDelay)
|
||||||
}
|
}
|
||||||
if (this.imageKnifeOption.errorholderSrc) {
|
if (this.imageKnifeOption.errorholderSrc) {
|
||||||
request.errorholder(this.imageKnifeOption.errorholderSrc, {asyncSuccess:(data:ImageKnifeData) => {
|
request.errorholder(this.imageKnifeOption.errorholderSrc, {asyncSuccess:(data:ImageKnifeData) => {
|
||||||
LogUtil.log('ImageKnifeComponent request.errorholder callback')
|
LogUtil.log('ImageKnife ImageKnifeComponent request.errorholder callback')
|
||||||
this.runNextFunction(this.displayErrorholder,data)
|
this.runNextFunction(this.displayErrorholder,data)
|
||||||
}})
|
}})
|
||||||
}
|
}
|
||||||
|
if (this.imageKnifeOption.fallbackSrc) {
|
||||||
|
request.fallback(this.imageKnifeOption.fallbackSrc, {asyncSuccess:(data:ImageKnifeData) => {
|
||||||
|
LogUtil.log('ImageKnife ImageKnifeComponent request.fallback callback');
|
||||||
|
this.runNextFunction(this.displayPlaceholder,data);
|
||||||
|
}})
|
||||||
|
}
|
||||||
|
|
||||||
if (this.imageKnifeOption.transform) {
|
if (this.imageKnifeOption.transform) {
|
||||||
this.requestAddTransform(request)
|
this.requestAddTransform(request)
|
||||||
|
@ -259,18 +299,21 @@ export struct ImageKnifeComponent {
|
||||||
if (this.imageKnifeOption.displayProgress) {
|
if (this.imageKnifeOption.displayProgress) {
|
||||||
request.addProgressListener({asyncSuccess:(percentValue: number) => {
|
request.addProgressListener({asyncSuccess:(percentValue: number) => {
|
||||||
// 如果进度条百分比 未展示大小,展示其动画
|
// 如果进度条百分比 未展示大小,展示其动画
|
||||||
LogUtil.log('ImageKnifeComponent request.addProgressListener callback')
|
LogUtil.log('ImageKnife ImageKnifeComponent request.addProgressListener callback')
|
||||||
this.runNextFunction(this.displayProgress,percentValue)
|
this.runNextFunction(this.displayProgress,percentValue)
|
||||||
}})
|
}})
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.imageKnifeOption.retryholderSrc) {
|
if (this.imageKnifeOption.retryholderSrc) {
|
||||||
request.retryholder(this.imageKnifeOption.retryholderSrc,{asyncSuccess: (data:ImageKnifeData) => {
|
request.retryholder(this.imageKnifeOption.retryholderSrc,{asyncSuccess: (data:ImageKnifeData) => {
|
||||||
LogUtil.log('ImageKnifeComponent request.retryholder callback')
|
LogUtil.log('ImageKnife ImageKnifeComponent request.retryholder callback')
|
||||||
this.hasDisplayRetryholder = true
|
this.hasDisplayRetryholder = true
|
||||||
this.runNextFunction(this.displayRetryholder,data)
|
this.runNextFunction(this.displayRetryholder,data)
|
||||||
}})
|
}})
|
||||||
}
|
}
|
||||||
|
if (this.imageKnifeOption.customGetImage) {
|
||||||
|
request.customGetImage = this.imageKnifeOption.customGetImage;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
configHspContext(request: RequestOption){
|
configHspContext(request: RequestOption){
|
||||||
|
@ -296,7 +339,7 @@ export struct ImageKnifeComponent {
|
||||||
this.resetGifData()
|
this.resetGifData()
|
||||||
if (this.canvasHasReady) {
|
if (this.canvasHasReady) {
|
||||||
// 如果canvas已经初始化好了,清空原有的canvas内容
|
// 如果canvas已经初始化好了,清空原有的canvas内容
|
||||||
this.context.clearRect(0, 0, this.currentWidth, this.currentHeight)
|
this.context.clearRect(0, 0, this.context.width, this.context.height)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -306,7 +349,7 @@ export struct ImageKnifeComponent {
|
||||||
this.configNecessary(request);
|
this.configNecessary(request);
|
||||||
this.configCacheStrategy(request);
|
this.configCacheStrategy(request);
|
||||||
this.configDisplay(request);
|
this.configDisplay(request);
|
||||||
this.configHspContext(request)
|
this.configHspContext(request);
|
||||||
this.configRenderGpu(request);
|
this.configRenderGpu(request);
|
||||||
if(ImageKnifeGlobal.getInstance().getImageKnife()!=undefined) {
|
if(ImageKnifeGlobal.getInstance().getImageKnife()!=undefined) {
|
||||||
ImageKnifeGlobal.getInstance().getImageKnife()?.call(request);
|
ImageKnifeGlobal.getInstance().getImageKnife()?.call(request);
|
||||||
|
@ -318,15 +361,15 @@ export struct ImageKnifeComponent {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (!this.drawLifeCycleHasConsumed( 'displayPlaceholder', this.context, data, this.imageKnifeOption,
|
if (!this.drawLifeCycleHasConsumed( 'displayPlaceholder', this.context, data, this.imageKnifeOption,
|
||||||
this.currentWidth, this.currentHeight, (gifTimeId) => {
|
this.context.width, this.context.height, (gifTimeId) => {
|
||||||
this.setGifTimeId(gifTimeId)
|
this.setGifTimeId(gifTimeId)
|
||||||
},this.imageKnifeOption.drawLifeCycle)) {
|
},this.imageKnifeOption.drawLifeCycle)) {
|
||||||
if (!this.drawLifeCycleHasConsumed( 'displayPlaceholder', this.context, data, this.imageKnifeOption,
|
if (!this.drawLifeCycleHasConsumed( 'displayPlaceholder', this.context, data, this.imageKnifeOption,
|
||||||
this.currentWidth, this.currentHeight, (gifTimeId) => {
|
this.context.width, this.context.height, (gifTimeId) => {
|
||||||
this.setGifTimeId(gifTimeId)
|
this.setGifTimeId(gifTimeId)
|
||||||
},(ImageKnifeGlobal.getInstance().getImageKnife())?.getDefaultLifeCycle())) {
|
},(ImageKnifeGlobal.getInstance().getImageKnife())?.getDefaultLifeCycle())) {
|
||||||
if(this.defaultLifeCycle.displayPlaceholder != undefined) {
|
if(this.defaultLifeCycle.displayPlaceholder != undefined) {
|
||||||
this.defaultLifeCycle.displayPlaceholder(this.context, data, this.imageKnifeOption, this.currentWidth, this.currentHeight, (gifTimeId) => {
|
this.defaultLifeCycle.displayPlaceholder(this.context, data, this.imageKnifeOption, this.context.width, this.context.height, (gifTimeId) => {
|
||||||
this.setGifTimeId(gifTimeId)
|
this.setGifTimeId(gifTimeId)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -341,15 +384,15 @@ export struct ImageKnifeComponent {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (!this.drawLifeCycleHasConsumed( 'displayProgress', this.context, percent, this.imageKnifeOption,
|
if (!this.drawLifeCycleHasConsumed( 'displayProgress', this.context, percent, this.imageKnifeOption,
|
||||||
this.currentWidth, this.currentHeight, (gifTimeId) => {
|
this.context.width, this.context.height, (gifTimeId) => {
|
||||||
this.setGifTimeId(gifTimeId)
|
this.setGifTimeId(gifTimeId)
|
||||||
},this.imageKnifeOption.drawLifeCycle)) {
|
},this.imageKnifeOption.drawLifeCycle)) {
|
||||||
if (!this.drawLifeCycleHasConsumed( 'displayProgress', this.context, percent, this.imageKnifeOption,
|
if (!this.drawLifeCycleHasConsumed( 'displayProgress', this.context, percent, this.imageKnifeOption,
|
||||||
this.currentWidth, this.currentHeight, (gifTimeId) => {
|
this.context.width, this.context.height, (gifTimeId) => {
|
||||||
this.setGifTimeId(gifTimeId)
|
this.setGifTimeId(gifTimeId)
|
||||||
},(ImageKnifeGlobal.getInstance().getImageKnife())?.getDefaultLifeCycle())) {
|
},(ImageKnifeGlobal.getInstance().getImageKnife())?.getDefaultLifeCycle())) {
|
||||||
if(this.defaultLifeCycle.displayProgress != undefined) {
|
if(this.defaultLifeCycle.displayProgress != undefined) {
|
||||||
this.defaultLifeCycle.displayProgress(this.context, percent, this.imageKnifeOption, this.currentWidth, this.currentHeight, (gifTimeId) => {
|
this.defaultLifeCycle.displayProgress(this.context, percent, this.imageKnifeOption, this.context.width, this.context.height, (gifTimeId) => {
|
||||||
this.setGifTimeId(gifTimeId)
|
this.setGifTimeId(gifTimeId)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -364,15 +407,15 @@ export struct ImageKnifeComponent {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (!this.drawLifeCycleHasConsumed( 'displayThumbSizeMultiplier', this.context, data, this.imageKnifeOption,
|
if (!this.drawLifeCycleHasConsumed( 'displayThumbSizeMultiplier', this.context, data, this.imageKnifeOption,
|
||||||
this.currentWidth, this.currentHeight, (gifTimeId) => {
|
this.context.width, this.context.height, (gifTimeId) => {
|
||||||
this.setGifTimeId(gifTimeId)
|
this.setGifTimeId(gifTimeId)
|
||||||
},this.imageKnifeOption.drawLifeCycle)) {
|
},this.imageKnifeOption.drawLifeCycle)) {
|
||||||
if (!this.drawLifeCycleHasConsumed( 'displayThumbSizeMultiplier', this.context, data, this.imageKnifeOption,
|
if (!this.drawLifeCycleHasConsumed( 'displayThumbSizeMultiplier', this.context, data, this.imageKnifeOption,
|
||||||
this.currentWidth, this.currentHeight, (gifTimeId) => {
|
this.context.width, this.context.height, (gifTimeId) => {
|
||||||
this.setGifTimeId(gifTimeId)
|
this.setGifTimeId(gifTimeId)
|
||||||
},(ImageKnifeGlobal.getInstance().getImageKnife())?.getDefaultLifeCycle())) {
|
},(ImageKnifeGlobal.getInstance().getImageKnife())?.getDefaultLifeCycle())) {
|
||||||
if(this.defaultLifeCycle.displayThumbSizeMultiplier != undefined) {
|
if(this.defaultLifeCycle.displayThumbSizeMultiplier != undefined) {
|
||||||
this.defaultLifeCycle.displayThumbSizeMultiplier(this.context, data, this.imageKnifeOption, this.currentWidth, this.currentHeight, (gifTimeId) => {
|
this.defaultLifeCycle.displayThumbSizeMultiplier(this.context, data, this.imageKnifeOption, this.context.width, this.context.height, (gifTimeId) => {
|
||||||
this.setGifTimeId(gifTimeId)
|
this.setGifTimeId(gifTimeId)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -381,19 +424,20 @@ export struct ImageKnifeComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
displayMainSource = (data: ImageKnifeData|number|undefined)=> {
|
displayMainSource = (data: ImageKnifeData|number|undefined)=> {
|
||||||
|
ImageKnifeDrawFactory.type = undefined;
|
||||||
if(data == undefined || typeof data == 'number'){
|
if(data == undefined || typeof data == 'number'){
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (!this.drawLifeCycleHasConsumed( 'displayMainSource', this.context, data, this.imageKnifeOption,
|
if (!this.drawLifeCycleHasConsumed( 'displayMainSource', this.context, data, this.imageKnifeOption,
|
||||||
this.currentWidth, this.currentHeight, (gifTimeId) => {
|
this.context.width, this.context.height, (gifTimeId) => {
|
||||||
this.setGifTimeId(gifTimeId)
|
this.setGifTimeId(gifTimeId)
|
||||||
},this.imageKnifeOption.drawLifeCycle)) {
|
},this.imageKnifeOption.drawLifeCycle)) {
|
||||||
if (!this.drawLifeCycleHasConsumed( 'displayMainSource', this.context, data, this.imageKnifeOption,
|
if (!this.drawLifeCycleHasConsumed( 'displayMainSource', this.context, data, this.imageKnifeOption,
|
||||||
this.currentWidth, this.currentHeight, (gifTimeId) => {
|
this.context.width, this.context.height, (gifTimeId) => {
|
||||||
this.setGifTimeId(gifTimeId)
|
this.setGifTimeId(gifTimeId)
|
||||||
},(ImageKnifeGlobal.getInstance().getImageKnife())?.getDefaultLifeCycle())) {
|
},(ImageKnifeGlobal.getInstance().getImageKnife())?.getDefaultLifeCycle())) {
|
||||||
if(this.defaultLifeCycle.displayMainSource != undefined) {
|
if(this.defaultLifeCycle.displayMainSource != undefined) {
|
||||||
this.defaultLifeCycle.displayMainSource(this.context, data, this.imageKnifeOption, this.currentWidth, this.currentHeight, (gifTimeId) => {
|
this.defaultLifeCycle.displayMainSource(this.context, data, this.imageKnifeOption, this.context.width, this.context.height, (gifTimeId) => {
|
||||||
this.setGifTimeId(gifTimeId)
|
this.setGifTimeId(gifTimeId)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -408,15 +452,15 @@ export struct ImageKnifeComponent {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (!this.drawLifeCycleHasConsumed( 'displayRetryholder', this.context, data, this.imageKnifeOption,
|
if (!this.drawLifeCycleHasConsumed( 'displayRetryholder', this.context, data, this.imageKnifeOption,
|
||||||
this.currentWidth, this.currentHeight, (gifTimeId) => {
|
this.context.width, this.context.height, (gifTimeId) => {
|
||||||
this.setGifTimeId(gifTimeId)
|
this.setGifTimeId(gifTimeId)
|
||||||
},this.imageKnifeOption.drawLifeCycle)) {
|
},this.imageKnifeOption.drawLifeCycle)) {
|
||||||
if (!this.drawLifeCycleHasConsumed( 'displayRetryholder', this.context, data, this.imageKnifeOption,
|
if (!this.drawLifeCycleHasConsumed( 'displayRetryholder', this.context, data, this.imageKnifeOption,
|
||||||
this.currentWidth, this.currentHeight, (gifTimeId) => {
|
this.context.width, this.context.height, (gifTimeId) => {
|
||||||
this.setGifTimeId(gifTimeId)
|
this.setGifTimeId(gifTimeId)
|
||||||
},(ImageKnifeGlobal.getInstance().getImageKnife())?.getDefaultLifeCycle())) {
|
},(ImageKnifeGlobal.getInstance().getImageKnife())?.getDefaultLifeCycle())) {
|
||||||
if( this.defaultLifeCycle.displayRetryholder != undefined) {
|
if( this.defaultLifeCycle.displayRetryholder != undefined) {
|
||||||
this.defaultLifeCycle.displayRetryholder(this.context, data, this.imageKnifeOption, this.currentWidth, this.currentHeight, (gifTimeId) => {
|
this.defaultLifeCycle.displayRetryholder(this.context, data, this.imageKnifeOption, this.context.width, this.context.height, (gifTimeId) => {
|
||||||
this.setGifTimeId(gifTimeId)
|
this.setGifTimeId(gifTimeId)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -430,15 +474,15 @@ export struct ImageKnifeComponent {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (!this.drawLifeCycleHasConsumed( 'displayErrorholder', this.context, data, this.imageKnifeOption,
|
if (!this.drawLifeCycleHasConsumed( 'displayErrorholder', this.context, data, this.imageKnifeOption,
|
||||||
this.currentWidth, this.currentHeight, (gifTimeId) => {
|
this.context.width, this.context.height, (gifTimeId) => {
|
||||||
this.setGifTimeId(gifTimeId)
|
this.setGifTimeId(gifTimeId)
|
||||||
},this.imageKnifeOption.drawLifeCycle)) {
|
},this.imageKnifeOption.drawLifeCycle)) {
|
||||||
if (!this.drawLifeCycleHasConsumed( 'displayErrorholder', this.context, data, this.imageKnifeOption,
|
if (!this.drawLifeCycleHasConsumed( 'displayErrorholder', this.context, data, this.imageKnifeOption,
|
||||||
this.currentWidth, this.currentHeight, (gifTimeId) => {
|
this.context.width, this.context.height, (gifTimeId) => {
|
||||||
this.setGifTimeId(gifTimeId)
|
this.setGifTimeId(gifTimeId)
|
||||||
},(ImageKnifeGlobal.getInstance().getImageKnife())?.getDefaultLifeCycle())) {
|
},(ImageKnifeGlobal.getInstance().getImageKnife())?.getDefaultLifeCycle())) {
|
||||||
if(this.defaultLifeCycle.displayErrorholder != undefined) {
|
if(this.defaultLifeCycle.displayErrorholder != undefined) {
|
||||||
this.defaultLifeCycle.displayErrorholder(this.context, data, this.imageKnifeOption, this.currentWidth, this.currentHeight, (gifTimeId) => {
|
this.defaultLifeCycle.displayErrorholder(this.context, data, this.imageKnifeOption, this.context.width, this.context.height, (gifTimeId) => {
|
||||||
this.setGifTimeId(gifTimeId)
|
this.setGifTimeId(gifTimeId)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -450,7 +494,18 @@ export struct ImageKnifeComponent {
|
||||||
|
|
||||||
drawPlaceholder(context: CanvasRenderingContext2D, data: ImageKnifeData, imageKnifeOption: ImageKnifeOption, compWidth: number, compHeight: number, setGifTimeId?: (timeId: number) => void) {
|
drawPlaceholder(context: CanvasRenderingContext2D, data: ImageKnifeData, imageKnifeOption: ImageKnifeOption, compWidth: number, compHeight: number, setGifTimeId?: (timeId: number) => void) {
|
||||||
LogUtil.log('ImageKnifeComponent default drawPlaceholder start!')
|
LogUtil.log('ImageKnifeComponent default drawPlaceholder start!')
|
||||||
|
// API12 getImageInfoSync同步
|
||||||
|
// if(data.drawPixelMap?.imagePixelMap != undefined) {
|
||||||
|
// let imageInfo = data.drawPixelMap?.imagePixelMap.getImageInfoSync()
|
||||||
|
// LogUtil.log('ImageKnifeComponent imageinfo width =' + imageInfo.size.width + ' height=' + imageInfo.size.height)
|
||||||
|
// let scaleType = (typeof imageKnifeOption.placeholderScaleType == 'number') ? imageKnifeOption.placeholderScaleType : ScaleType.FIT_CENTER
|
||||||
|
// context.save();
|
||||||
|
// context.clearRect(0, 0, compWidth, compHeight)
|
||||||
|
// ScaleTypeHelper.drawImageWithScaleType(context, scaleType, data.drawPixelMap?.imagePixelMap, px2vp(imageInfo.size.width), px2vp(imageInfo.size.height), compWidth, compHeight, 0, 0)
|
||||||
|
// context.restore();
|
||||||
|
// LogUtil.log('ImageKnifeComponent default drawPlaceholder end!')
|
||||||
|
// }
|
||||||
|
// getImageInfo异步
|
||||||
data.drawPixelMap?.imagePixelMap?.getImageInfo().then((imageInfo) => {
|
data.drawPixelMap?.imagePixelMap?.getImageInfo().then((imageInfo) => {
|
||||||
LogUtil.log('ImageKnifeComponent imageinfo width =' + imageInfo.size.width + ' height=' + imageInfo.size.height)
|
LogUtil.log('ImageKnifeComponent imageinfo width =' + imageInfo.size.width + ' height=' + imageInfo.size.height)
|
||||||
let scaleType = (typeof imageKnifeOption.placeholderScaleType == 'number') ? imageKnifeOption.placeholderScaleType : ScaleType.FIT_CENTER
|
let scaleType = (typeof imageKnifeOption.placeholderScaleType == 'number') ? imageKnifeOption.placeholderScaleType : ScaleType.FIT_CENTER
|
||||||
|
@ -505,7 +560,18 @@ export struct ImageKnifeComponent {
|
||||||
|
|
||||||
drawThumbSizeMultiplier(context: CanvasRenderingContext2D, data: ImageKnifeData, imageKnifeOption: ImageKnifeOption, compWidth: number, compHeight: number, setGifTimeId?: (timeId: number) => void) {
|
drawThumbSizeMultiplier(context: CanvasRenderingContext2D, data: ImageKnifeData, imageKnifeOption: ImageKnifeOption, compWidth: number, compHeight: number, setGifTimeId?: (timeId: number) => void) {
|
||||||
LogUtil.log('ImageKnifeComponent default drawThumbSizeMultiplier start!')
|
LogUtil.log('ImageKnifeComponent default drawThumbSizeMultiplier start!')
|
||||||
|
// API12 getImageInfoSync同步
|
||||||
|
// if(data.drawPixelMap?.imagePixelMap != undefined) {
|
||||||
|
// let imageInfo = data.drawPixelMap?.imagePixelMap.getImageInfoSync()
|
||||||
|
// LogUtil.log('ImageKnifeComponent imageinfo width =' + imageInfo.size.width + ' height=' + imageInfo.size.height)
|
||||||
|
// let scaleType = (typeof imageKnifeOption.thumbSizeMultiplierScaleType == 'number') ? imageKnifeOption.thumbSizeMultiplierScaleType : ScaleType.FIT_CENTER
|
||||||
|
// context.save();
|
||||||
|
// context.clearRect(0, 0, compWidth, compHeight)
|
||||||
|
// ScaleTypeHelper.drawImageWithScaleType(context, scaleType, data.drawPixelMap?.imagePixelMap, px2vp(imageInfo.size.width), px2vp(imageInfo.size.height), compWidth, compHeight, 0, 0)
|
||||||
|
// context.restore();
|
||||||
|
// LogUtil.log('ImageKnifeComponent default drawThumbSizeMultiplier end!')
|
||||||
|
// }
|
||||||
|
// getImageInfo异步
|
||||||
data.drawPixelMap?.imagePixelMap?.getImageInfo().then((imageInfo) => {
|
data.drawPixelMap?.imagePixelMap?.getImageInfo().then((imageInfo) => {
|
||||||
LogUtil.log('ImageKnifeComponent imageinfo width =' + imageInfo.size.width + ' height=' + imageInfo.size.height)
|
LogUtil.log('ImageKnifeComponent imageinfo width =' + imageInfo.size.width + ' height=' + imageInfo.size.height)
|
||||||
let scaleType = (typeof imageKnifeOption.thumbSizeMultiplierScaleType == 'number') ? imageKnifeOption.thumbSizeMultiplierScaleType : ScaleType.FIT_CENTER
|
let scaleType = (typeof imageKnifeOption.thumbSizeMultiplierScaleType == 'number') ? imageKnifeOption.thumbSizeMultiplierScaleType : ScaleType.FIT_CENTER
|
||||||
|
@ -520,11 +586,33 @@ export struct ImageKnifeComponent {
|
||||||
drawMainSource(context: CanvasRenderingContext2D, data: ImageKnifeData, imageKnifeOption: ImageKnifeOption, compWidth: number, compHeight: number, setGifTimeId?: (timeId: number) => void) {
|
drawMainSource(context: CanvasRenderingContext2D, data: ImageKnifeData, imageKnifeOption: ImageKnifeOption, compWidth: number, compHeight: number, setGifTimeId?: (timeId: number) => void) {
|
||||||
LogUtil.log('ImageKnifeComponent default drawMainSource start!')
|
LogUtil.log('ImageKnifeComponent default drawMainSource start!')
|
||||||
if (data.isPixelMap()) {
|
if (data.isPixelMap()) {
|
||||||
|
// API12 getImageInfoSync同步
|
||||||
|
// if(data.drawPixelMap?.imagePixelMap != undefined) {
|
||||||
|
// let imageInfo = data.drawPixelMap?.imagePixelMap.getImageInfoSync()
|
||||||
|
// let scaleType = (typeof imageKnifeOption.mainScaleType == 'number') ? imageKnifeOption.mainScaleType : ScaleType.FIT_CENTER
|
||||||
|
// LogUtil.log('ImageKnifeComponent imageinfo width =' + imageInfo.size.width + ' height=' + imageInfo.size.height + 'scaleType=' + scaleType)
|
||||||
|
// context.save();
|
||||||
|
// context.clearRect(0, 0, compWidth, compHeight)
|
||||||
|
// ScaleTypeHelper.drawImageWithScaleType(context, scaleType, data.drawPixelMap?.imagePixelMap, px2vp(imageInfo.size.width), px2vp(imageInfo.size.height), compWidth, compHeight, 0, 0)
|
||||||
|
// context.restore();
|
||||||
|
// LogUtil.log('ImageKnifeComponent default drawMainSource end!')
|
||||||
|
// }
|
||||||
|
// getImageInfo异步
|
||||||
data.drawPixelMap?.imagePixelMap?.getImageInfo().then((imageInfo) => {
|
data.drawPixelMap?.imagePixelMap?.getImageInfo().then((imageInfo) => {
|
||||||
let scaleType = (typeof imageKnifeOption.mainScaleType == 'number') ? imageKnifeOption.mainScaleType : ScaleType.FIT_CENTER
|
let scaleType = (typeof imageKnifeOption.mainScaleType == 'number') ? imageKnifeOption.mainScaleType : ScaleType.FIT_CENTER
|
||||||
LogUtil.log('ImageKnifeComponent imageinfo width =' + imageInfo.size.width + ' height=' + imageInfo.size.height + 'scaleType=' + scaleType)
|
LogUtil.log('ImageKnifeComponent imageinfo width =' + imageInfo.size.width + ' height=' + imageInfo.size.height + 'scaleType=' + scaleType)
|
||||||
context.save();
|
context.save();
|
||||||
context.clearRect(0, 0, compWidth, compHeight)
|
context.clearRect(0, 0, compWidth, compHeight)
|
||||||
|
let scaleHeight = imageInfo.size.height/imageInfo.size.width
|
||||||
|
let scaleWidth = imageInfo.size.width/imageInfo.size.height
|
||||||
|
if (this.imageKnifeOption.mainScaleType == ScaleType.AUTO_WIDTH){
|
||||||
|
this.currentSize.width=this.context.height*scaleWidth
|
||||||
|
}else if (this.imageKnifeOption.mainScaleType == ScaleType.AUTO_HEIGHT){
|
||||||
|
this.currentSize.height=this.context.width*scaleHeight
|
||||||
|
}else if (this.imageKnifeOption.mainScaleType == ScaleType.AUTO){
|
||||||
|
this.currentSize.height=imageInfo.size.height
|
||||||
|
this.currentSize.width =imageInfo.size.width
|
||||||
|
}
|
||||||
ScaleTypeHelper.drawImageWithScaleType(context, scaleType, data.drawPixelMap?.imagePixelMap, px2vp(imageInfo.size.width), px2vp(imageInfo.size.height), compWidth, compHeight, 0, 0)
|
ScaleTypeHelper.drawImageWithScaleType(context, scaleType, data.drawPixelMap?.imagePixelMap, px2vp(imageInfo.size.width), px2vp(imageInfo.size.height), compWidth, compHeight, 0, 0)
|
||||||
context.restore();
|
context.restore();
|
||||||
LogUtil.log('ImageKnifeComponent default drawMainSource end!')
|
LogUtil.log('ImageKnifeComponent default drawMainSource end!')
|
||||||
|
@ -544,7 +632,18 @@ export struct ImageKnifeComponent {
|
||||||
|
|
||||||
drawRetryholder(context: CanvasRenderingContext2D, data: ImageKnifeData, imageKnifeOption: ImageKnifeOption, compWidth: number, compHeight: number, setGifTimeId?: (timeId: number) => void) {
|
drawRetryholder(context: CanvasRenderingContext2D, data: ImageKnifeData, imageKnifeOption: ImageKnifeOption, compWidth: number, compHeight: number, setGifTimeId?: (timeId: number) => void) {
|
||||||
LogUtil.log('ImageKnifeComponent default drawRetryholder start!')
|
LogUtil.log('ImageKnifeComponent default drawRetryholder start!')
|
||||||
|
// API12 getImageInfoSync同步
|
||||||
|
// if(data.drawPixelMap?.imagePixelMap != undefined) {
|
||||||
|
// let imageInfo = data.drawPixelMap?.imagePixelMap.getImageInfoSync()
|
||||||
|
// LogUtil.log('ImageKnifeComponent imageinfo width =' + imageInfo.size.width + ' height=' + imageInfo.size.height)
|
||||||
|
// let scaleType = (typeof imageKnifeOption.retryholderScaleType == 'number') ? imageKnifeOption.retryholderScaleType : ScaleType.FIT_CENTER
|
||||||
|
// context.save();
|
||||||
|
// context.clearRect(0, 0, compWidth, compHeight)
|
||||||
|
// ScaleTypeHelper.drawImageWithScaleType(context, scaleType, data.drawPixelMap?.imagePixelMap, px2vp(imageInfo.size.width), px2vp(imageInfo.size.height), compWidth, compHeight, 0, 0)
|
||||||
|
// context.restore();
|
||||||
|
// LogUtil.log('ImageKnifeComponent default drawRetryholder end!')
|
||||||
|
// }
|
||||||
|
// getImageInfo异步
|
||||||
data.drawPixelMap?.imagePixelMap?.getImageInfo().then((imageInfo) => {
|
data.drawPixelMap?.imagePixelMap?.getImageInfo().then((imageInfo) => {
|
||||||
LogUtil.log('ImageKnifeComponent imageinfo width =' + imageInfo.size.width + ' height=' + imageInfo.size.height)
|
LogUtil.log('ImageKnifeComponent imageinfo width =' + imageInfo.size.width + ' height=' + imageInfo.size.height)
|
||||||
let scaleType = (typeof imageKnifeOption.retryholderScaleType == 'number') ? imageKnifeOption.retryholderScaleType : ScaleType.FIT_CENTER
|
let scaleType = (typeof imageKnifeOption.retryholderScaleType == 'number') ? imageKnifeOption.retryholderScaleType : ScaleType.FIT_CENTER
|
||||||
|
@ -558,7 +657,18 @@ export struct ImageKnifeComponent {
|
||||||
|
|
||||||
drawErrorholder(context: CanvasRenderingContext2D, data: ImageKnifeData, imageKnifeOption: ImageKnifeOption, compWidth: number, compHeight: number, setGifTimeId?: (timeId: number) => void) {
|
drawErrorholder(context: CanvasRenderingContext2D, data: ImageKnifeData, imageKnifeOption: ImageKnifeOption, compWidth: number, compHeight: number, setGifTimeId?: (timeId: number) => void) {
|
||||||
LogUtil.log('ImageKnifeComponent default drawErrorholder start!')
|
LogUtil.log('ImageKnifeComponent default drawErrorholder start!')
|
||||||
|
// API12 getImageInfoSync同步
|
||||||
|
// if(data.drawPixelMap?.imagePixelMap != undefined) {
|
||||||
|
// let imageInfo = data.drawPixelMap?.imagePixelMap.getImageInfoSync()
|
||||||
|
// LogUtil.log('ImageKnifeComponent imageinfo width =' + imageInfo.size.width + ' height=' + imageInfo.size.height)
|
||||||
|
// let scaleType = (typeof imageKnifeOption.errorholderSrcScaleType == 'number') ? imageKnifeOption.errorholderSrcScaleType : ScaleType.FIT_CENTER
|
||||||
|
// context.save();
|
||||||
|
// context.clearRect(0, 0, compWidth, compHeight)
|
||||||
|
// ScaleTypeHelper.drawImageWithScaleType(context, scaleType, data.drawPixelMap?.imagePixelMap, px2vp(imageInfo.size.width), px2vp(imageInfo.size.height), compWidth, compHeight, 0, 0)
|
||||||
|
// context.restore();
|
||||||
|
// LogUtil.log('ImageKnifeComponent default drawErrorholder end!')
|
||||||
|
// }
|
||||||
|
// getImageInfo异步
|
||||||
data.drawPixelMap?.imagePixelMap?.getImageInfo().then((imageInfo) => {
|
data.drawPixelMap?.imagePixelMap?.getImageInfo().then((imageInfo) => {
|
||||||
LogUtil.log('ImageKnifeComponent imageinfo width =' + imageInfo.size.width + ' height=' + imageInfo.size.height)
|
LogUtil.log('ImageKnifeComponent imageinfo width =' + imageInfo.size.width + ' height=' + imageInfo.size.height)
|
||||||
let scaleType = (typeof imageKnifeOption.errorholderSrcScaleType == 'number') ? imageKnifeOption.errorholderSrcScaleType : ScaleType.FIT_CENTER
|
let scaleType = (typeof imageKnifeOption.errorholderSrcScaleType == 'number') ? imageKnifeOption.errorholderSrcScaleType : ScaleType.FIT_CENTER
|
||||||
|
@ -572,7 +682,7 @@ export struct ImageKnifeComponent {
|
||||||
|
|
||||||
requestAddTransform(request: RequestOption) {
|
requestAddTransform(request: RequestOption) {
|
||||||
if (TransformType.BlurTransformation == this.imageKnifeOption.transform?.transformType) {
|
if (TransformType.BlurTransformation == this.imageKnifeOption.transform?.transformType) {
|
||||||
request.blur(this.imageKnifeOption.transform?.blur)
|
request.blur(this.imageKnifeOption.transform?.blur?.radius,this.imageKnifeOption.transform?.blur?.sampling)
|
||||||
} else if (TransformType.BrightnessFilterTransformation == this.imageKnifeOption.transform?.transformType) {
|
} else if (TransformType.BrightnessFilterTransformation == this.imageKnifeOption.transform?.transformType) {
|
||||||
request.brightnessFilter(this.imageKnifeOption.transform?.brightnessFilter)
|
request.brightnessFilter(this.imageKnifeOption.transform?.brightnessFilter)
|
||||||
} else if (TransformType.ContrastFilterTransformation == this.imageKnifeOption.transform?.transformType) {
|
} else if (TransformType.ContrastFilterTransformation == this.imageKnifeOption.transform?.transformType) {
|
||||||
|
@ -611,11 +721,18 @@ export struct ImageKnifeComponent {
|
||||||
request.fitCenter()
|
request.fitCenter()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
aboutToRecycle(){
|
||||||
|
this.resetGifData()
|
||||||
|
}
|
||||||
|
aboutToReuse(params: ESObject) {
|
||||||
|
this.context.clearRect(0,0,this.context.width,this.context.height)
|
||||||
|
}
|
||||||
aboutToAppear() {
|
aboutToAppear() {
|
||||||
LogUtil.log('ImageKnifeComponent aboutToAppear happened!')
|
LogUtil.log('ImageKnifeComponent aboutToAppear happened!')
|
||||||
this.canvasHasReady = false;
|
this.canvasHasReady = false;
|
||||||
this.whetherWaitSize(true);
|
this.whetherWaitSize(true);
|
||||||
|
|
||||||
|
this.listener.on("layout",this.onLayoutComplete)
|
||||||
}
|
}
|
||||||
|
|
||||||
aboutToDisappear() {
|
aboutToDisappear() {
|
||||||
|
@ -629,7 +746,10 @@ export struct ImageKnifeComponent {
|
||||||
if (this.detachFromLayoutPixelMap != undefined) {
|
if (this.detachFromLayoutPixelMap != undefined) {
|
||||||
this.detachFromLayoutPixelMap.detach();
|
this.detachFromLayoutPixelMap.detach();
|
||||||
}
|
}
|
||||||
this.resetGifData();
|
if(this.isGif){
|
||||||
|
this.resetGifData();
|
||||||
|
}
|
||||||
|
this.listener.off("layout",this.onLayoutComplete)
|
||||||
}
|
}
|
||||||
|
|
||||||
onPageShow() {
|
onPageShow() {
|
||||||
|
@ -658,15 +778,15 @@ export struct ImageKnifeComponent {
|
||||||
let frames = data.drawGIFFrame?.imageGIFFrames as GIFFrame[]
|
let frames = data.drawGIFFrame?.imageGIFFrames as GIFFrame[]
|
||||||
LogUtil.log('ImageKnifeComponent gifFrameLength =' + frames.length);
|
LogUtil.log('ImageKnifeComponent gifFrameLength =' + frames.length);
|
||||||
if (imageKnifeOption.gif && (typeof (imageKnifeOption.gif.seekTo) == 'number') && imageKnifeOption.gif.seekTo >= 0) {
|
if (imageKnifeOption.gif && (typeof (imageKnifeOption.gif.seekTo) == 'number') && imageKnifeOption.gif.seekTo >= 0) {
|
||||||
this.autoPlay = false;
|
|
||||||
context.clearRect(0, 0, compWidth, compHeight)
|
context.clearRect(0, 0, compWidth, compHeight)
|
||||||
this.drawSeekToFrame(frames, context, compWidth, compHeight)
|
this.drawSeekToFrame(frames, context, compWidth, compHeight)
|
||||||
} else {
|
} else {
|
||||||
this.autoPlay = true
|
|
||||||
context.clearRect(0, 0, compWidth, compHeight)
|
context.clearRect(0, 0, compWidth, compHeight)
|
||||||
|
|
||||||
this.renderFrames_frames = frames
|
this.renderFrames_frames = frames
|
||||||
this.renderFrames_index = 0
|
if (this.imageKnifeOption.autoPlay == undefined) {
|
||||||
|
this.renderFrames_index = 0;
|
||||||
|
}
|
||||||
this.renderFrames_context = context
|
this.renderFrames_context = context
|
||||||
this.renderFrames_compWidth = compWidth
|
this.renderFrames_compWidth = compWidth
|
||||||
this.renderFrames_compHeight = compHeight
|
this.renderFrames_compHeight = compHeight
|
||||||
|
@ -676,10 +796,12 @@ export struct ImageKnifeComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
private resetGifData() {
|
private resetGifData() {
|
||||||
clearTimeout(this.gifTimerId)
|
if(this.isGif) {
|
||||||
this.gifLoopDuration = 0;
|
clearTimeout(this.gifTimerId)
|
||||||
this.startGifLoopTime = 0;
|
this.gifLoopDuration = 0;
|
||||||
this.endGifLoopTime = 0;
|
this.startGifLoopTime = 0;
|
||||||
|
this.endGifLoopTime = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -688,13 +810,13 @@ export struct ImageKnifeComponent {
|
||||||
private drawSeekToFrame(frames: GIFFrame[], context: CanvasRenderingContext2D, compWidth: number, compHeight: number) {
|
private drawSeekToFrame(frames: GIFFrame[], context: CanvasRenderingContext2D, compWidth: number, compHeight: number) {
|
||||||
if(this.imageKnifeOption.gif != undefined && this.imageKnifeOption.gif.seekTo != undefined) {
|
if(this.imageKnifeOption.gif != undefined && this.imageKnifeOption.gif.seekTo != undefined) {
|
||||||
for (let i = 0; i < this.imageKnifeOption.gif.seekTo; i++) {
|
for (let i = 0; i < this.imageKnifeOption.gif.seekTo; i++) {
|
||||||
|
this.renderFrames_index = i;
|
||||||
this.drawFrame(frames, i, context, compWidth, compHeight);
|
this.drawFrame(frames, i, context, compWidth, compHeight);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
renderFrames_frames: GIFFrame[] | undefined = undefined
|
renderFrames_frames: GIFFrame[] | undefined = undefined
|
||||||
renderFrames_index: number = 0;
|
|
||||||
renderFrames_context: CanvasRenderingContext2D | undefined = undefined;
|
renderFrames_context: CanvasRenderingContext2D | undefined = undefined;
|
||||||
renderFrames_compWidth: number = 0;
|
renderFrames_compWidth: number = 0;
|
||||||
renderFrames_compHeight: number = 0
|
renderFrames_compHeight: number = 0
|
||||||
|
@ -708,6 +830,14 @@ export struct ImageKnifeComponent {
|
||||||
}
|
}
|
||||||
// draw Frame
|
// draw Frame
|
||||||
this.drawFrame(this.renderFrames_frames, this.renderFrames_index, this.renderFrames_context, this.renderFrames_compWidth, this.renderFrames_compHeight);
|
this.drawFrame(this.renderFrames_frames, this.renderFrames_index, this.renderFrames_context, this.renderFrames_compWidth, this.renderFrames_compHeight);
|
||||||
|
// gif播放次数
|
||||||
|
if (this.renderFrames_frames != undefined && this.renderFrames_index === (this.renderFrames_frames.length - 1) && this.imageKnifeOption.gif != undefined ) {
|
||||||
|
this.playTimes++
|
||||||
|
if (this.imageKnifeOption.gif.playTimes == this.playTimes){
|
||||||
|
this.imageKnifeOption.autoPlay = false;
|
||||||
|
this.playTimes = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
//如果gif动图只有一帧的情况下,不进行后面代码的逐帧绘制循环
|
//如果gif动图只有一帧的情况下,不进行后面代码的逐帧绘制循环
|
||||||
if (this.renderFrames_frames != undefined && this.renderFrames_frames.length <= 1) {
|
if (this.renderFrames_frames != undefined && this.renderFrames_frames.length <= 1) {
|
||||||
return
|
return
|
||||||
|
@ -717,7 +847,7 @@ export struct ImageKnifeComponent {
|
||||||
let end = new Date().getTime();
|
let end = new Date().getTime();
|
||||||
let diff = end - start
|
let diff = end - start
|
||||||
|
|
||||||
if (this.autoPlay) {
|
if ((this.imageKnifeOption.autoPlay == undefined) || (this.imageKnifeOption.autoPlay)) {
|
||||||
|
|
||||||
// 理论上该帧在屏幕上保留的时间
|
// 理论上该帧在屏幕上保留的时间
|
||||||
let stayTime:number= 0
|
let stayTime:number= 0
|
||||||
|
@ -782,10 +912,58 @@ export struct ImageKnifeComponent {
|
||||||
ScaleTypeHelper.drawImageWithScaleType(context, scaleType, pixelmap, px2vp(frameW), px2vp(frameH), compWidth, compHeight, px2vp(frame.dims.left), px2vp(frame.dims.top))
|
ScaleTypeHelper.drawImageWithScaleType(context, scaleType, pixelmap, px2vp(frameW), px2vp(frameH), compWidth, compHeight, px2vp(frame.dims.left), px2vp(frame.dims.top))
|
||||||
// tips:worker如果不是在展示页面中创建,使用子线程回来的数据创建的图片,会导致canvas绘制不出来
|
// tips:worker如果不是在展示页面中创建,使用子线程回来的数据创建的图片,会导致canvas绘制不出来
|
||||||
context.restore();
|
context.restore();
|
||||||
LogUtil.log('ImageKnifeComponent default drawMainSource end!')
|
if (ImageKnifeDrawFactory.type === undefined) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 通过 destination-in 裁剪出圆角
|
||||||
|
if (ImageKnifeDrawFactory?.type === DrawType.Round || ImageKnifeDrawFactory?.type === DrawType.Oval) {
|
||||||
|
context.save();
|
||||||
|
context.globalCompositeOperation = 'destination-in';
|
||||||
|
if (ImageKnifeDrawFactory.type === DrawType.Round) {
|
||||||
|
ImageKnifeDrawFactory.setRect(context, scaleType, pixelmap, px2vp(frameW), px2vp(frameH), compWidth,
|
||||||
|
compHeight, 0, 0, ImageKnifeDrawFactory.borderWidth, ImageKnifeDrawFactory.connerRadius);
|
||||||
|
} else {
|
||||||
|
context.beginPath();
|
||||||
|
ImageKnifeDrawFactory.setOval(context, scaleType, pixelmap, px2vp(frameW), px2vp(frameH), compWidth,
|
||||||
|
compHeight, 0, 0, ImageKnifeDrawFactory.borderWidth);
|
||||||
|
context.closePath();
|
||||||
|
}
|
||||||
|
context.fill();
|
||||||
|
context.restore();
|
||||||
|
if (ImageKnifeDrawFactory.borderWidth > 0) {
|
||||||
|
// 为圆角添加边框
|
||||||
|
context.save();
|
||||||
|
context.strokeStyle = ImageKnifeDrawFactory.colorString;
|
||||||
|
context.lineWidth = ImageKnifeDrawFactory.borderWidth;
|
||||||
|
context.globalCompositeOperation = 'source-over';
|
||||||
|
if (ImageKnifeDrawFactory.type === DrawType.Round) {
|
||||||
|
ImageKnifeDrawFactory.setRect(context, scaleType, pixelmap, px2vp(frameW), px2vp(frameH), compWidth,
|
||||||
|
compHeight, 0, 0, ImageKnifeDrawFactory.borderWidth, ImageKnifeDrawFactory.connerRadius);
|
||||||
|
} else {
|
||||||
|
context.beginPath();
|
||||||
|
ImageKnifeDrawFactory.setOval(context, scaleType, pixelmap, px2vp(frameW), px2vp(frameH), compWidth,
|
||||||
|
compHeight, 0, 0, ImageKnifeDrawFactory.borderWidth);
|
||||||
|
context.closePath();
|
||||||
|
}
|
||||||
|
context.stroke();
|
||||||
|
context.restore();
|
||||||
|
}
|
||||||
|
context.restore();
|
||||||
|
}
|
||||||
|
LogUtil.log('ImageKnifeComponent canvasDrawPixelMap end!')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export enum DrawType{
|
||||||
|
|
||||||
|
Normal = 0,
|
||||||
|
|
||||||
|
Oval = 1,
|
||||||
|
|
||||||
|
Round = 2
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
export enum FrameDisposalType {
|
export enum FrameDisposalType {
|
||||||
// 0 - No disposal specified. The decoder is not required to take any action.
|
// 0 - No disposal specified. The decoder is not required to take any action.
|
||||||
// 不使用处置方法
|
// 不使用处置方法
|
||||||
|
@ -825,7 +1003,13 @@ export enum ScaleType {
|
||||||
// 如果图像大于组件则执行FIT_CENTER,小于组件则CENTER
|
// 如果图像大于组件则执行FIT_CENTER,小于组件则CENTER
|
||||||
CENTER_INSIDE = 7,
|
CENTER_INSIDE = 7,
|
||||||
// 如果不想适配,直接展示原图大小
|
// 如果不想适配,直接展示原图大小
|
||||||
NONE = 8
|
NONE = 8,
|
||||||
|
// 设置宽的时候,图片高度自适应
|
||||||
|
AUTO_HEIGHT =9,
|
||||||
|
// 设置高的时候,图片宽度自适应
|
||||||
|
AUTO_WIDTH =10,
|
||||||
|
//没有设置宽和高,图片按照自身宽高显示
|
||||||
|
AUTO =11
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -862,7 +1046,7 @@ export class ScaleTypeHelper {
|
||||||
ScaleTypeHelper.drawNone(context, source, imageWidth, imageHeight, imageOffsetX, imageOffsetY)
|
ScaleTypeHelper.drawNone(context, source, imageWidth, imageHeight, imageOffsetX, imageOffsetY)
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ScaleTypeHelper.drawNone(context, source, imageWidth, imageHeight, imageOffsetX, imageOffsetY)
|
ScaleTypeHelper.drawFitCenter(context, source, minScale, imageWidth, imageHeight, compWidth, compHeight, imageOffsetX, imageOffsetY)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,9 +16,13 @@ import { ImageKnifeOption } from '../imageknife/ImageKnifeOption'
|
||||||
import { ImageKnifeData } from '../imageknife/ImageKnifeData'
|
import { ImageKnifeData } from '../imageknife/ImageKnifeData'
|
||||||
import { GIFFrame } from '../imageknife/utils/gif/GIFFrame'
|
import { GIFFrame } from '../imageknife/utils/gif/GIFFrame'
|
||||||
import { IDrawLifeCycle } from '../imageknife/interface/IDrawLifeCycle'
|
import { IDrawLifeCycle } from '../imageknife/interface/IDrawLifeCycle'
|
||||||
import { ScaleTypeHelper,ScaleType } from '../imageknife/ImageKnifeComponent'
|
import { ScaleTypeHelper,ScaleType, DrawType } from '../imageknife/ImageKnifeComponent'
|
||||||
|
|
||||||
export class ImageKnifeDrawFactory{
|
export class ImageKnifeDrawFactory{
|
||||||
|
public static borderWidth: number;
|
||||||
|
public static type: DrawType | undefined = undefined;
|
||||||
|
public static colorString: string;
|
||||||
|
public static connerRadius: number;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 绘制PixelMap内容情况下,主图的椭圆裁剪,可添加边框
|
* 绘制PixelMap内容情况下,主图的椭圆裁剪,可添加边框
|
||||||
|
@ -81,6 +85,11 @@ export class ImageKnifeDrawFactory{
|
||||||
})
|
})
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
if (data.isGIFFrame()) {
|
||||||
|
ImageKnifeDrawFactory.type = DrawType.Oval;
|
||||||
|
ImageKnifeDrawFactory.borderWidth = borderWidth;
|
||||||
|
ImageKnifeDrawFactory.colorString = colorString;
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
// 展示重试图层
|
// 展示重试图层
|
||||||
|
@ -108,7 +117,7 @@ export class ImageKnifeDrawFactory{
|
||||||
* @param imageOffsetY
|
* @param imageOffsetY
|
||||||
* @param borderWidth
|
* @param borderWidth
|
||||||
*/
|
*/
|
||||||
private static setOval(context: CanvasRenderingContext2D, scaleType: ScaleType, source: PixelMap | undefined, imageWidth: number, imageHeight: number, compWidth: number, compHeight: number, imageOffsetX:number,imageOffsetY:number
|
public static setOval(context: CanvasRenderingContext2D, scaleType: ScaleType, source: PixelMap | undefined, imageWidth: number, imageHeight: number, compWidth: number, compHeight: number, imageOffsetX:number,imageOffsetY:number
|
||||||
,borderWidth:number) {
|
,borderWidth:number) {
|
||||||
let scaleW = compWidth / imageWidth
|
let scaleW = compWidth / imageWidth
|
||||||
let scaleH = compHeight / imageHeight
|
let scaleH = compHeight / imageHeight
|
||||||
|
@ -240,6 +249,12 @@ export class ImageKnifeDrawFactory{
|
||||||
})
|
})
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
if (data.isGIFFrame()) {
|
||||||
|
ImageKnifeDrawFactory.type = DrawType.Round;
|
||||||
|
ImageKnifeDrawFactory.borderWidth = borderWidth;
|
||||||
|
ImageKnifeDrawFactory.colorString = colorString;
|
||||||
|
ImageKnifeDrawFactory.connerRadius = connerRadius;
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
// 展示重试图层
|
// 展示重试图层
|
||||||
|
@ -268,7 +283,7 @@ export class ImageKnifeDrawFactory{
|
||||||
* @param borderWidth
|
* @param borderWidth
|
||||||
* @param cornerRadius
|
* @param cornerRadius
|
||||||
*/
|
*/
|
||||||
private static setRect(context: CanvasRenderingContext2D, scaleType: ScaleType, source: PixelMap | undefined, imageWidth: number, imageHeight: number, compWidth: number, compHeight: number, imageOffsetX:number,imageOffsetY:number
|
public static setRect(context: CanvasRenderingContext2D, scaleType: ScaleType, source: PixelMap | undefined, imageWidth: number, imageHeight: number, compWidth: number, compHeight: number, imageOffsetX:number,imageOffsetY:number
|
||||||
,borderWidth:number,cornerRadius:number) {
|
,borderWidth:number,cornerRadius:number) {
|
||||||
let scaleW = compWidth / imageWidth
|
let scaleW = compWidth / imageWidth
|
||||||
let scaleH = compHeight / imageHeight
|
let scaleH = compHeight / imageHeight
|
||||||
|
|
|
@ -26,6 +26,8 @@ import { rgbColor } from './transform/CropCircleWithBorderTransformation'
|
||||||
import { RoundCorner } from './transform/RoundedCornersTransformation'
|
import { RoundCorner } from './transform/RoundedCornersTransformation'
|
||||||
import { ObjectKey } from './ObjectKey'
|
import { ObjectKey } from './ObjectKey'
|
||||||
import common from '@ohos.app.ability.common'
|
import common from '@ohos.app.ability.common'
|
||||||
|
import { Priority } from './RequestOption'
|
||||||
|
import { DataFetchResult } from './networkmanage/DataFetchResult'
|
||||||
|
|
||||||
export interface CropCircleWithBorder{
|
export interface CropCircleWithBorder{
|
||||||
border: number,
|
border: number,
|
||||||
|
@ -37,15 +39,19 @@ export interface Crop{
|
||||||
height: number,
|
height: number,
|
||||||
cropType: CropType
|
cropType: CropType
|
||||||
}
|
}
|
||||||
|
export interface BlurType {
|
||||||
|
radius: number,
|
||||||
|
sampling: number
|
||||||
|
}
|
||||||
export interface GifOptions{
|
export interface GifOptions{
|
||||||
loopFinish?: (loopTime?:number) => void
|
loopFinish?: (loopTime?:number) => void
|
||||||
speedFactory?: number
|
speedFactory?: number
|
||||||
seekTo?: number
|
seekTo?: number
|
||||||
|
playTimes?: number
|
||||||
}
|
}
|
||||||
export interface TransformOptions{
|
export interface TransformOptions{
|
||||||
transformType: number,
|
transformType: number,
|
||||||
blur?: number,
|
blur?: BlurType,
|
||||||
roundedCorners?: RoundCorner
|
roundedCorners?: RoundCorner
|
||||||
cropCircleWithBorder?: CropCircleWithBorder
|
cropCircleWithBorder?: CropCircleWithBorder
|
||||||
crop?:Crop
|
crop?:Crop
|
||||||
|
@ -57,13 +63,22 @@ export interface TransformOptions{
|
||||||
rotateImage?: number
|
rotateImage?: number
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface HeaderOptions {
|
||||||
|
key: string;
|
||||||
|
value: string;
|
||||||
|
}
|
||||||
|
|
||||||
@Observed
|
@Observed
|
||||||
export class ImageKnifeOption {
|
export class ImageKnifeOption {
|
||||||
|
//控制gif开关
|
||||||
|
autoPlay?: boolean = true;
|
||||||
|
// header请求列表
|
||||||
|
headerOption?: Array<HeaderOptions>;
|
||||||
// 主图资源
|
// 主图资源
|
||||||
loadSrc: string | PixelMap | Resource = '';
|
loadSrc: string | PixelMap | Resource = '';
|
||||||
mainScaleType?: ScaleType = ScaleType.FIT_CENTER
|
mainScaleType?: ScaleType = ScaleType.FIT_CENTER
|
||||||
|
// 优先级
|
||||||
|
priority?: Priority = Priority.MEDIUM
|
||||||
enableGpu?:boolean = true;
|
enableGpu?:boolean = true;
|
||||||
|
|
||||||
// 磁盘缓存策略
|
// 磁盘缓存策略
|
||||||
|
@ -73,9 +88,11 @@ export class ImageKnifeOption {
|
||||||
dontAnimateFlag? = false;
|
dontAnimateFlag? = false;
|
||||||
|
|
||||||
// 占位图
|
// 占位图
|
||||||
placeholderSrc?: PixelMap | Resource;
|
placeholderSrc?: string | PixelMap | Resource;
|
||||||
placeholderScaleType?: ScaleType = ScaleType.FIT_CENTER
|
placeholderScaleType?: ScaleType = ScaleType.FIT_CENTER
|
||||||
|
|
||||||
|
// 后备回调符
|
||||||
|
fallbackSrc?: PixelMap | Resource;
|
||||||
// 失败占位图
|
// 失败占位图
|
||||||
errorholderSrc?: PixelMap | Resource;
|
errorholderSrc?: PixelMap | Resource;
|
||||||
errorholderSrcScaleType?: ScaleType = ScaleType.FIT_CENTER
|
errorholderSrcScaleType?: ScaleType = ScaleType.FIT_CENTER
|
||||||
|
@ -129,6 +146,9 @@ export class ImageKnifeOption {
|
||||||
context?: common.UIAbilityContext;
|
context?: common.UIAbilityContext;
|
||||||
// sizeAnimate?: AnimateParam 由业务自定义不再支持
|
// sizeAnimate?: AnimateParam 由业务自定义不再支持
|
||||||
|
|
||||||
|
// 设置是否使用应用自定义的方式加载图片
|
||||||
|
customGetImage?: (context: Context, src: string) => Promise<DataFetchResult>;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
@Sendable
|
||||||
export class ObjectKey{
|
export class ObjectKey{
|
||||||
|
|
||||||
private objectKey: string;
|
private objectKey: string;
|
||||||
|
|
|
@ -12,15 +12,15 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
import {ImageKnife} from './ImageKnife'
|
import { ImageKnife } from './ImageKnife'
|
||||||
import { DiskStrategy } from "../cache/diskstrategy/DiskStrategy"
|
import { DiskStrategy } from "../cache/diskstrategy/DiskStrategy"
|
||||||
import { AsyncCallback } from "../imageknife/interface/AsyncCallback"
|
import { AsyncCallback } from "../imageknife/interface/AsyncCallback"
|
||||||
import { AsyncSuccess } from "../imageknife/interface/AsyncSuccess"
|
import { AsyncSuccess } from "../imageknife/interface/AsyncSuccess"
|
||||||
import { IAllCacheInfoCallback } from "../imageknife/interface/IAllCacheInfoCallback"
|
import { AllCacheInfo, IAllCacheInfoCallback } from "../imageknife/interface/IAllCacheInfoCallback"
|
||||||
import { AUTOMATIC } from "../cache/diskstrategy/enum/AUTOMATIC"
|
import { AUTOMATIC } from "../cache/diskstrategy/enum/AUTOMATIC"
|
||||||
import { BaseTransform } from "../imageknife/transform/BaseTransform"
|
import { BaseTransform } from "../imageknife/transform/BaseTransform"
|
||||||
import { RotateImageTransformation } from "../imageknife/transform/RotateImageTransformation"
|
import { RotateImageTransformation } from "../imageknife/transform/RotateImageTransformation"
|
||||||
import { ImageKnifeData } from "../imageknife/ImageKnifeData"
|
import { ImageKnifeData, ImageKnifeType } from "../imageknife/ImageKnifeData"
|
||||||
import { CenterCrop } from '../imageknife/transform/pixelmap/CenterCrop'
|
import { CenterCrop } from '../imageknife/transform/pixelmap/CenterCrop'
|
||||||
import { CenterInside } from '../imageknife/transform/pixelmap/CenterInside'
|
import { CenterInside } from '../imageknife/transform/pixelmap/CenterInside'
|
||||||
import { FitCenter } from '../imageknife/transform/pixelmap/FitCenter'
|
import { FitCenter } from '../imageknife/transform/pixelmap/FitCenter'
|
||||||
|
@ -28,7 +28,10 @@ import { RoundedCornersTransformation, RoundCorner } from '../imageknife/transfo
|
||||||
|
|
||||||
import { CropCircleTransformation } from '../imageknife/transform/CropCircleTransformation'
|
import { CropCircleTransformation } from '../imageknife/transform/CropCircleTransformation'
|
||||||
|
|
||||||
import { CropCircleWithBorderTransformation, rgbColor } from '../imageknife/transform/CropCircleWithBorderTransformation'
|
import {
|
||||||
|
CropCircleWithBorderTransformation,
|
||||||
|
rgbColor
|
||||||
|
} from '../imageknife/transform/CropCircleWithBorderTransformation'
|
||||||
import { CropSquareTransformation } from '../imageknife/transform/CropSquareTransformation'
|
import { CropSquareTransformation } from '../imageknife/transform/CropSquareTransformation'
|
||||||
import { CropTransformation } from '../imageknife/transform/CropTransformation'
|
import { CropTransformation } from '../imageknife/transform/CropTransformation'
|
||||||
import { CropType } from '../imageknife/transform/CropTransformation'
|
import { CropType } from '../imageknife/transform/CropTransformation'
|
||||||
|
@ -50,46 +53,85 @@ import { ImageKnifeGlobal } from './ImageKnifeGlobal'
|
||||||
import { BusinessError } from '@ohos.base'
|
import { BusinessError } from '@ohos.base'
|
||||||
import { ObjectKey } from './ObjectKey'
|
import { ObjectKey } from './ObjectKey'
|
||||||
import common from '@ohos.app.ability.common'
|
import common from '@ohos.app.ability.common'
|
||||||
|
import { GIFFrame } from './utils/gif/GIFFrame'
|
||||||
|
import { DiskCacheProxy } from './requestmanage/DiskCacheProxy'
|
||||||
|
import { DiskLruCache } from '../cache/DiskLruCache'
|
||||||
|
import { SparkMD5 } from '../3rd_party/sparkmd5/spark-md5'
|
||||||
|
import { FileUtils } from '../cache/FileUtils'
|
||||||
|
import util from '@ohos.util'
|
||||||
|
import { DataFetchResult } from './networkmanage/DataFetchResult'
|
||||||
|
|
||||||
export interface Size {
|
export interface Size {
|
||||||
width: number,
|
width: number,
|
||||||
height: number
|
height: number
|
||||||
}
|
}
|
||||||
export interface DetachFromLayout{
|
|
||||||
detach:()=>void
|
export enum CacheType {
|
||||||
|
Default,
|
||||||
|
//缓存
|
||||||
|
Cache,
|
||||||
|
//磁盘
|
||||||
|
Disk
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface DetachFromLayout {
|
||||||
|
detach: () => void
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum Priority {
|
||||||
|
HIGH = 0,
|
||||||
|
MEDIUM = 1,
|
||||||
|
LOW = 2
|
||||||
|
}
|
||||||
export class RequestOption {
|
export class RequestOption {
|
||||||
uuid:string ='' // 唯一标识
|
// 遍历添加图片http请求头
|
||||||
|
headers: Map<string, Object> = new Map<string, Object>();
|
||||||
|
|
||||||
|
// RequestOption调用header对于的方法
|
||||||
|
addHeader(key: string, value: Object) {
|
||||||
|
this.headers.set(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 全局调用header对应的方法,包含RequestOption的形式
|
||||||
|
addHeaderMap(map: Map<string, Object>) {
|
||||||
|
map.forEach((value, key) => {
|
||||||
|
if (!this.headers.has(key)) {
|
||||||
|
this.addHeader(key, value);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 优先级
|
||||||
|
priority: Priority = Priority.MEDIUM;
|
||||||
|
uuid: string = '' // 唯一标识
|
||||||
loadSrc: string | PixelMap | Resource = '';
|
loadSrc: string | PixelMap | Resource = '';
|
||||||
strategy: DiskStrategy = new AUTOMATIC();
|
strategy: DiskStrategy = new AUTOMATIC();
|
||||||
dontAnimateFlag = false;
|
dontAnimateFlag = false;
|
||||||
placeholderSrc: PixelMap | Resource | undefined = undefined;
|
placeholderSrc: string | PixelMap | Resource | undefined = undefined;
|
||||||
placeholderFunc: AsyncSuccess<ImageKnifeData> | undefined = undefined;
|
placeholderFunc: AsyncSuccess<ImageKnifeData> | undefined = undefined;
|
||||||
errorholderSrc: PixelMap | Resource | undefined = undefined;
|
errorholderSrc: PixelMap | Resource | undefined = undefined;
|
||||||
errorholderFunc: AsyncSuccess<ImageKnifeData> | undefined = undefined;
|
errorholderFunc: AsyncSuccess<ImageKnifeData> | undefined = undefined;
|
||||||
errorholderData: ImageKnifeData | undefined = undefined;;
|
errorholderData: ImageKnifeData | undefined = undefined;
|
||||||
thumbSizeMultiplier: number = 0;
|
thumbSizeMultiplier: number = 0;
|
||||||
|
|
||||||
// 如果存在缩略图,则主图延时1s加载
|
// 如果存在缩略图,则主图延时1s加载
|
||||||
thumbDelayTime: number = 1000
|
thumbDelayTime: number = 1000
|
||||||
thumbHolderFunc: AsyncSuccess<ImageKnifeData> | undefined = undefined;
|
thumbHolderFunc: AsyncSuccess<ImageKnifeData> | undefined = undefined;
|
||||||
requestListeners: Array<AsyncCallback<ImageKnifeData>> | undefined = undefined;
|
requestListeners: Array<AsyncCallback<ImageKnifeData>> | undefined = undefined;
|
||||||
|
|
||||||
// 进度条
|
// 进度条
|
||||||
progressFunc: AsyncSuccess<number> | undefined = undefined;
|
progressFunc: AsyncSuccess<number> | undefined = undefined;
|
||||||
|
// 后备回调符
|
||||||
|
fallbackSrc: PixelMap | Resource | undefined = undefined;
|
||||||
|
fallbackFunc: AsyncSuccess<ImageKnifeData> | undefined = undefined;
|
||||||
|
fallbackData: ImageKnifeData | undefined = undefined;
|
||||||
// 重试图层
|
// 重试图层
|
||||||
retryholderSrc: PixelMap | Resource | undefined = undefined;
|
retryholderSrc: PixelMap | Resource | undefined = undefined;
|
||||||
retryholderFunc: AsyncSuccess<ImageKnifeData> | undefined = undefined;
|
retryholderFunc: AsyncSuccess<ImageKnifeData> | undefined = undefined;
|
||||||
retryholderData: ImageKnifeData | undefined = undefined;
|
retryholderData: ImageKnifeData | undefined = undefined;
|
||||||
size:Size= { width: -1, height: -1 };
|
size: Size = { width: -1, height: -1 };
|
||||||
|
|
||||||
// 网络下载数据回调
|
// 网络下载数据回调
|
||||||
allCacheInfoCallback: IAllCacheInfoCallback | undefined = undefined;
|
allCacheInfoCallback: IAllCacheInfoCallback | undefined = undefined;
|
||||||
onlyRetrieveFromCache: boolean = false;
|
onlyRetrieveFromCache: boolean = false;
|
||||||
isCacheable: boolean = true;
|
isCacheable: boolean = true;
|
||||||
|
|
||||||
// 开启GPU变换绘制
|
// 开启GPU变换绘制
|
||||||
gpuEnabled: boolean = false;
|
gpuEnabled: boolean = false;
|
||||||
// 变换相关
|
// 变换相关
|
||||||
|
@ -99,73 +141,76 @@ export class RequestOption {
|
||||||
generateDataKey: string = "";
|
generateDataKey: string = "";
|
||||||
filesPath: string = ""; // data/data/包名/files目录
|
filesPath: string = ""; // data/data/包名/files目录
|
||||||
cachesPath: string = ""; // 网络下载默认存储在data/data/包名/cache/ImageKnifeNetworkFolder/目标md5.img下面
|
cachesPath: string = ""; // 网络下载默认存储在data/data/包名/cache/ImageKnifeNetworkFolder/目标md5.img下面
|
||||||
|
placeholderCacheKey: string = "";
|
||||||
|
retryholderCacheKey: string = "";
|
||||||
|
errorholderCacheKey: string = "";
|
||||||
|
// string类型占位图相关缓存key值
|
||||||
|
placeholderRegisterCacheKey: string = "";
|
||||||
|
placeholderRegisterMemoryCacheKey: string = "";
|
||||||
|
fallbackCacheKey: string = "";
|
||||||
// 自定义缓存关键字
|
// 自定义缓存关键字
|
||||||
signature?: ObjectKey;
|
signature?: ObjectKey;
|
||||||
|
// 设置是否使用应用自定义的方式加载图片
|
||||||
|
customGetImage?: (context: Context, src: string) => Promise<DataFetchResult>;
|
||||||
// 下载原始文件地址
|
// 下载原始文件地址
|
||||||
downloadFilePath: string = "";
|
downloadFilePath: string = "";
|
||||||
|
//磁盘缓存文件路径
|
||||||
|
diskMemoryCachePath: string ="";
|
||||||
// 网络文件下载统一存放
|
// 网络文件下载统一存放
|
||||||
networkCacheFolder: string = "ImageKnifeNetworkFolder"
|
networkCacheFolder: string = "ImageKnifeNetworkFolder"
|
||||||
|
|
||||||
|
|
||||||
// 主线图片 状态变化 是否加载完成
|
// 主线图片 状态变化 是否加载完成
|
||||||
// 主图未加载成功 显示占位图 主图加载成功不展示占位图
|
// 主图未加载成功 显示占位图 主图加载成功不展示占位图
|
||||||
loadMainReady = false;
|
loadMainReady = false;
|
||||||
|
|
||||||
// 失败占位图展示状态 当true 表示主图加载失败需要展示失败占位图
|
// 失败占位图展示状态 当true 表示主图加载失败需要展示失败占位图
|
||||||
loadErrorReady = false;
|
loadErrorReady = false;
|
||||||
|
|
||||||
// 重试占位图展示状态 当true 表示主图加载失败需要展示失败占位图
|
// 重试占位图展示状态 当true 表示主图加载失败需要展示失败占位图
|
||||||
loadRetryReady = false;
|
loadRetryReady = false;
|
||||||
|
// 后备回调符展示状态 当true 表占位图加载失败需要展示后备回调符
|
||||||
|
loadFallBackReady = false;
|
||||||
// 缩略图展示
|
// 缩略图展示
|
||||||
loadThumbnailReady = false;
|
loadThumbnailReady = false;
|
||||||
|
detachFromLayout: DetachFromLayout = {
|
||||||
detachFromLayout:DetachFromLayout = {
|
detach: () => {
|
||||||
detach: ()=>{
|
let imageKnife: ImageKnife | undefined = ImageKnifeGlobal.getInstance().getImageKnife();
|
||||||
let imageKnife:ImageKnife | undefined = ImageKnifeGlobal.getInstance().getImageKnife();
|
if (imageKnife != undefined) {
|
||||||
if(imageKnife != undefined) {
|
|
||||||
imageKnife.remove(this.uuid);
|
imageKnife.remove(this.uuid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// module资源的需要当前的module context
|
// module资源的需要当前的module context
|
||||||
moduleContext?:common.UIAbilityContext = undefined;
|
moduleContext?: common.UIAbilityContext = undefined;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
// 初始化全局监听
|
// 初始化全局监听
|
||||||
this.requestListeners = new Array();
|
this.requestListeners = new Array();
|
||||||
// 初始化唯一标识,可以用这个标识找到ImageKnife中的对象
|
|
||||||
this.uuid = this.generateUUID();
|
|
||||||
|
|
||||||
|
let ctx = ImageKnifeGlobal.getInstance().getHapContext() as common.UIAbilityContext
|
||||||
let ctx = ImageKnifeGlobal.getInstance().getHapContext() as common.UIAbilityContext
|
if (ctx != undefined) {
|
||||||
if(ctx != undefined){
|
|
||||||
this.moduleContext = ctx;
|
this.moduleContext = ctx;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
setPriority(priority: Priority) {
|
||||||
generateUUID(): string {
|
this.priority = priority
|
||||||
let d = new Date().getTime();
|
|
||||||
const uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace( new RegExp("[xy]","g"), (c) => {
|
|
||||||
const r = (d + Math.random() * 16) % 16 | 0;
|
|
||||||
d = Math.floor(d / 16);
|
|
||||||
return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);
|
|
||||||
});
|
|
||||||
return uuid;
|
|
||||||
}
|
}
|
||||||
setModuleContext(moduleCtx:common.UIAbilityContext){
|
setTransformations( array:Array<BaseTransform<PixelMap>>){
|
||||||
|
this.transformations = array;
|
||||||
|
}
|
||||||
|
generateUUID(): string {
|
||||||
|
return SparkMD5.hashBinary(JSON.stringify(this.loadSrc)) as string;
|
||||||
|
}
|
||||||
|
|
||||||
|
setModuleContext(moduleCtx: common.UIAbilityContext) {
|
||||||
this.moduleContext = moduleCtx;
|
this.moduleContext = moduleCtx;
|
||||||
}
|
}
|
||||||
|
|
||||||
getModuleContext():common.UIAbilityContext | undefined{
|
getModuleContext(): common.UIAbilityContext | undefined {
|
||||||
return this.moduleContext;
|
return this.moduleContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* set image Component size
|
* set image Component size
|
||||||
*/
|
*/
|
||||||
setImageViewSize(imageSize:Size) {
|
setImageViewSize(imageSize: Size) {
|
||||||
this.size.width = imageSize.width;
|
this.size.width = imageSize.width;
|
||||||
this.size.height = imageSize.height;
|
this.size.height = imageSize.height;
|
||||||
return this;
|
return this;
|
||||||
|
@ -189,6 +234,8 @@ export class RequestOption {
|
||||||
|
|
||||||
load(src: string | PixelMap | Resource) {
|
load(src: string | PixelMap | Resource) {
|
||||||
this.loadSrc = src;
|
this.loadSrc = src;
|
||||||
|
// 初始化唯一标识,可以用这个标识找到ImageKnife中的对象
|
||||||
|
this.uuid = this.generateUUID();
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -203,7 +250,7 @@ export class RequestOption {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 仅支持 本地图片
|
// 仅支持 本地图片
|
||||||
placeholder(src: PixelMap | Resource, func?: AsyncSuccess<ImageKnifeData>) {
|
placeholder(src: string | PixelMap | Resource, func?: AsyncSuccess<ImageKnifeData>) {
|
||||||
this.placeholderSrc = src;
|
this.placeholderSrc = src;
|
||||||
this.placeholderFunc = func;
|
this.placeholderFunc = func;
|
||||||
return this;
|
return this;
|
||||||
|
@ -215,6 +262,12 @@ export class RequestOption {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fallback(src: PixelMap | Resource, func?: AsyncSuccess<ImageKnifeData>) {
|
||||||
|
this.fallbackSrc = src;
|
||||||
|
this.fallbackFunc = func;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
retryholder(src: PixelMap | Resource, func?: AsyncSuccess<ImageKnifeData>) {
|
retryholder(src: PixelMap | Resource, func?: AsyncSuccess<ImageKnifeData>) {
|
||||||
this.retryholderSrc = src;
|
this.retryholderSrc = src;
|
||||||
this.retryholderFunc = func;
|
this.retryholderFunc = func;
|
||||||
|
@ -236,7 +289,7 @@ export class RequestOption {
|
||||||
}
|
}
|
||||||
|
|
||||||
addListener(func: AsyncCallback<ImageKnifeData>) {
|
addListener(func: AsyncCallback<ImageKnifeData>) {
|
||||||
if(this.requestListeners != undefined) {
|
if (this.requestListeners != undefined) {
|
||||||
this.requestListeners?.push(func);
|
this.requestListeners?.push(func);
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
|
@ -256,8 +309,8 @@ export class RequestOption {
|
||||||
this.onlyRetrieveFromCache = flag;
|
this.onlyRetrieveFromCache = flag;
|
||||||
}
|
}
|
||||||
|
|
||||||
rotateImage(degreesToRotate: number|undefined) {
|
rotateImage(degreesToRotate: number | undefined) {
|
||||||
if(degreesToRotate == undefined){
|
if (degreesToRotate == undefined) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
let rotateImage = new RotateImageTransformation(degreesToRotate);
|
let rotateImage = new RotateImageTransformation(degreesToRotate);
|
||||||
|
@ -280,8 +333,8 @@ export class RequestOption {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
roundedCorners(obj: RoundCorner|undefined) {
|
roundedCorners(obj: RoundCorner | undefined) {
|
||||||
if(obj == undefined){
|
if (obj == undefined) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
let transformation = new RoundedCornersTransformation({
|
let transformation = new RoundedCornersTransformation({
|
||||||
|
@ -300,8 +353,8 @@ export class RequestOption {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
cropCircleWithBorder(border: number|undefined, obj: rgbColor|undefined) {
|
cropCircleWithBorder(border: number | undefined, obj: rgbColor | undefined) {
|
||||||
if(border == undefined || obj == undefined){
|
if (border == undefined || obj == undefined) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
let transformation = new CropCircleWithBorderTransformation(border, obj)
|
let transformation = new CropCircleWithBorderTransformation(border, obj)
|
||||||
|
@ -315,8 +368,8 @@ export class RequestOption {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
crop(width: number|undefined, height: number|undefined, cropType: CropType|undefined) {
|
crop(width: number | undefined, height: number | undefined, cropType: CropType | undefined) {
|
||||||
if(width == undefined || height == undefined || cropType == undefined){
|
if (width == undefined || height == undefined || cropType == undefined) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
let transformation = new CropTransformation(width, height, cropType)
|
let transformation = new CropTransformation(width, height, cropType)
|
||||||
|
@ -330,8 +383,8 @@ export class RequestOption {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
brightnessFilter(brightness: number|undefined) {
|
brightnessFilter(brightness: number | undefined) {
|
||||||
if(brightness == undefined){
|
if (brightness == undefined) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
let transformation = new BrightnessFilterTransformation(brightness)
|
let transformation = new BrightnessFilterTransformation(brightness)
|
||||||
|
@ -339,8 +392,8 @@ export class RequestOption {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
contrastFilter(contrast: number|undefined) {
|
contrastFilter(contrast: number | undefined) {
|
||||||
if(contrast == undefined){
|
if (contrast == undefined) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
let transformation = new ContrastFilterTransformation(contrast)
|
let transformation = new ContrastFilterTransformation(contrast)
|
||||||
|
@ -366,17 +419,22 @@ export class RequestOption {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
blur(radius: number|undefined) {
|
blur(radius: number | undefined, sampling?: number) {
|
||||||
if(radius == undefined){
|
if (radius == undefined) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
let transformation = new BlurTransformation(radius)
|
if (sampling == undefined) {
|
||||||
this.transformations.push(transformation);
|
let transformation = new BlurTransformation(radius)
|
||||||
|
this.transformations.push(transformation);
|
||||||
|
} else {
|
||||||
|
let transformation = new BlurTransformation(radius, sampling)
|
||||||
|
this.transformations.push(transformation);
|
||||||
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
pixelationFilter(pixel: number|undefined) {
|
pixelationFilter(pixel: number | undefined) {
|
||||||
if(pixel == undefined){
|
if (pixel == undefined) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
let transformation = new PixelationFilterTransformation(pixel)
|
let transformation = new PixelationFilterTransformation(pixel)
|
||||||
|
@ -384,8 +442,8 @@ export class RequestOption {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
swirlFilter(degree: number|undefined) {
|
swirlFilter(degree: number | undefined) {
|
||||||
if(degree == undefined){
|
if (degree == undefined) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
let transformation = new SwirlFilterTransformation(degree)
|
let transformation = new SwirlFilterTransformation(degree)
|
||||||
|
@ -393,8 +451,8 @@ export class RequestOption {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
mask(maskResource: Resource|undefined) {
|
mask(maskResource: Resource | undefined) {
|
||||||
if(maskResource == undefined){
|
if (maskResource == undefined) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
let transformation = new MaskTransformation(maskResource)
|
let transformation = new MaskTransformation(maskResource)
|
||||||
|
@ -402,8 +460,8 @@ export class RequestOption {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
kuwaharaFilter(radius: number|undefined) {
|
kuwaharaFilter(radius: number | undefined) {
|
||||||
if(radius == undefined){
|
if (radius == undefined) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
let transformation = new KuwaharaFilterTransform(radius);
|
let transformation = new KuwaharaFilterTransform(radius);
|
||||||
|
@ -411,8 +469,8 @@ export class RequestOption {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
toonFilter(threshold: number|undefined, quantizationLevels: number|undefined) {
|
toonFilter(threshold: number | undefined, quantizationLevels: number | undefined) {
|
||||||
if(threshold == undefined || quantizationLevels == undefined){
|
if (threshold == undefined || quantizationLevels == undefined) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
let transformation = new ToonFilterTransform(threshold, quantizationLevels);
|
let transformation = new ToonFilterTransform(threshold, quantizationLevels);
|
||||||
|
@ -420,8 +478,8 @@ export class RequestOption {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
vignetteFilter(centerPoint: Array<number>|undefined, vignetteColor: Array<number>|undefined, vignetteSpace: Array<number>|undefined) {
|
vignetteFilter(centerPoint: Array<number> | undefined, vignetteColor: Array<number> | undefined, vignetteSpace: Array<number> | undefined) {
|
||||||
if(centerPoint == undefined || vignetteColor == undefined || vignetteSpace == undefined){
|
if (centerPoint == undefined || vignetteColor == undefined || vignetteSpace == undefined) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
let transformation = new VignetteFilterTransform(centerPoint, vignetteColor, vignetteSpace);
|
let transformation = new VignetteFilterTransform(centerPoint, vignetteColor, vignetteSpace);
|
||||||
|
@ -438,6 +496,7 @@ export class RequestOption {
|
||||||
this.transformations = inputs;
|
this.transformations = inputs;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 开启GPU变换绘制
|
// 开启GPU变换绘制
|
||||||
enableGPU() {
|
enableGPU() {
|
||||||
this.gpuEnabled = true;
|
this.gpuEnabled = true;
|
||||||
|
@ -445,72 +504,82 @@ export class RequestOption {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 占位图解析成功
|
// 占位图解析成功
|
||||||
placeholderOnComplete = (imageKnifeData: ImageKnifeData)=> {
|
placeholderOnComplete = (imageKnifeData:ImageKnifeData) => {
|
||||||
LogUtil.log("placeholderOnComplete has called!");
|
LogUtil.log("placeholderOnComplete has called!");
|
||||||
LogUtil.log("Main Image is Ready:" + this.loadMainReady);
|
LogUtil.log("Main Image is Ready:" + this.loadMainReady);
|
||||||
if (!this.loadMainReady && !(this.loadErrorReady || this.loadRetryReady) && !this.loadThumbnailReady) {
|
if (!this.loadMainReady && !(this.loadErrorReady || this.loadRetryReady) && !this.loadThumbnailReady) {
|
||||||
// 主图未加载成功,并且未加载失败 显示占位图 主图加载成功或者加载失败后=>不展示占位图
|
// 主图未加载成功,并且未加载失败 显示占位图 主图加载成功或者加载失败后=>不展示占位图
|
||||||
if(this.placeholderSrc != undefined) {
|
if (this.placeholderSrc != undefined) {
|
||||||
this.placeholderFunc?.asyncSuccess(imageKnifeData)
|
this.placeholderFunc?.asyncSuccess(imageKnifeData)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 占位图解析失败
|
// 占位图解析失败
|
||||||
placeholderOnError = (error:BusinessError|string)=>{
|
placeholderOnError = (error: BusinessError | string) => {
|
||||||
LogUtil.log("占位图解析失败 error =" + error)
|
LogUtil.log("占位图解析失败 error =" + error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// 缩略图解析成功
|
// 缩略图解析成功
|
||||||
thumbholderOnComplete = (imageKnifeData: ImageKnifeData)=> {
|
thumbholderOnComplete = (value: PixelMap | GIFFrame[]) => {
|
||||||
|
let imageKnifeData = new ImageKnifeData();
|
||||||
|
if ((typeof (value as PixelMap).isEditable) == 'boolean') {
|
||||||
|
imageKnifeData = ImageKnifeData.createImagePixelMap(ImageKnifeType.PIXELMAP, value as PixelMap);
|
||||||
|
} else {
|
||||||
|
imageKnifeData = ImageKnifeData.createImageGIFFrame(ImageKnifeType.GIFFRAME, value as GIFFrame[]);
|
||||||
|
}
|
||||||
if (!this.loadMainReady && !(this.loadErrorReady || this.loadRetryReady)) {
|
if (!this.loadMainReady && !(this.loadErrorReady || this.loadRetryReady)) {
|
||||||
// 主图未加载成功,并且未加载失败 显示占位图 主图加载成功或者加载失败后=>不展示占位图
|
// 主图未加载成功,并且未加载失败 显示占位图 主图加载成功或者加载失败后=>不展示占位图
|
||||||
if(this.thumbHolderFunc != undefined) {
|
if (this.thumbHolderFunc != undefined) {
|
||||||
this.thumbHolderFunc?.asyncSuccess(imageKnifeData)
|
this.thumbHolderFunc?.asyncSuccess(imageKnifeData)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 缩略图解析失败
|
// 缩略图解析失败
|
||||||
thumbholderOnError=(error? :BusinessError|string)=>{
|
thumbholderOnError = (error?: BusinessError | string) => {
|
||||||
LogUtil.log("缩略图解析失败 error =" + error)
|
LogUtil.log("缩略图解析失败 error =" + error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 加载失败 占位图解析成功
|
// 加载失败 占位图解析成功
|
||||||
errorholderOnComplete = (imageKnifeData: ImageKnifeData)=> {
|
errorholderOnComplete = (imageKnifeData:ImageKnifeData) => {
|
||||||
// 如果有错误占位图 先解析并保存在RequestOption中 等到加载失败时候进行调用
|
// 如果有错误占位图 先解析并保存在RequestOption中 等到加载失败时候进行调用
|
||||||
this.errorholderData = imageKnifeData;
|
this.errorholderData = imageKnifeData;
|
||||||
if (this.loadErrorReady) {
|
if (this.loadErrorReady) {
|
||||||
if(this.errorholderFunc != undefined) {
|
if (this.errorholderFunc != undefined) {
|
||||||
this.errorholderFunc.asyncSuccess(imageKnifeData)
|
this.errorholderFunc.asyncSuccess(imageKnifeData)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 加载失败 占位图解析失败
|
// 加载失败 占位图解析失败
|
||||||
errorholderOnError = (error:BusinessError|string)=> {
|
errorholderOnError = (error: BusinessError | string) => {
|
||||||
LogUtil.log("失败占位图解析失败 error =" + error)
|
LogUtil.log("失败占位图解析失败 error =" + error)
|
||||||
}
|
}
|
||||||
|
retryholderOnComplete = (imageKnifeData:ImageKnifeData) => {
|
||||||
retryholderOnComplete = (imageKnifeData: ImageKnifeData)=>{
|
|
||||||
this.retryholderData = imageKnifeData;
|
this.retryholderData = imageKnifeData;
|
||||||
if (this.loadRetryReady) {
|
if (this.loadRetryReady) {
|
||||||
if(this.retryholderFunc != undefined) {
|
if (this.retryholderFunc != undefined) {
|
||||||
this.retryholderFunc?.asyncSuccess(imageKnifeData)
|
this.retryholderFunc?.asyncSuccess(imageKnifeData)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
retryholderOnError = (error: BusinessError | string) => {
|
||||||
retryholderOnError = (error:BusinessError|string)=>{
|
|
||||||
LogUtil.log("重试占位图解析失败 error =" + error)
|
LogUtil.log("重试占位图解析失败 error =" + error)
|
||||||
}
|
}
|
||||||
|
//占位图加载失败 后备回调符解析成功
|
||||||
loadComplete = (imageKnifeData: ImageKnifeData)=>{
|
fallbackOnComplete = (imageKnifeData:ImageKnifeData) => {
|
||||||
|
this.fallbackData = imageKnifeData;
|
||||||
|
if (this.loadFallBackReady) {
|
||||||
|
if (this.fallbackFunc != undefined) {
|
||||||
|
this.fallbackFunc?.asyncSuccess(imageKnifeData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 后备回调符解析失败
|
||||||
|
fallbackOnError = (error: BusinessError | string) => {
|
||||||
|
LogUtil.error("失败占位图解析失败 error =" + JSON.stringify(error));
|
||||||
|
}
|
||||||
|
loadComplete = (imageKnifeData: ImageKnifeData) => {
|
||||||
this.loadMainReady = true;
|
this.loadMainReady = true;
|
||||||
// 三级缓存数据加载成功
|
// 三级缓存数据加载成功
|
||||||
if(this.requestListeners != undefined) {
|
if (this.requestListeners != undefined) {
|
||||||
for (let i = 0;i < this.requestListeners.length; i++) {
|
for (let i = 0; i < this.requestListeners.length; i++) {
|
||||||
let requestListener = this.requestListeners[i];
|
let requestListener = this.requestListeners[i];
|
||||||
let boolInterception = requestListener.callback("", imageKnifeData);
|
let boolInterception = requestListener.callback("", imageKnifeData);
|
||||||
if (boolInterception) {
|
if (boolInterception) {
|
||||||
|
@ -518,32 +587,52 @@ export class RequestOption {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//输出缓存相关内容和信息
|
||||||
|
if (this.allCacheInfoCallback) {
|
||||||
|
// 内存缓存
|
||||||
|
let allCacheInfo: AllCacheInfo = {
|
||||||
|
memoryCacheInfo: { key: '', data: new ImageKnifeData() },
|
||||||
|
resourceCacheInfo: { key: '', path: '' },
|
||||||
|
dataCacheInfo: { key: '', path: '' }
|
||||||
|
};
|
||||||
|
allCacheInfo.memoryCacheInfo = {
|
||||||
|
key: this.generateCacheKey,
|
||||||
|
data: imageKnifeData
|
||||||
|
}
|
||||||
|
let mDiskCacheProxy = new DiskCacheProxy(DiskLruCache.create(ImageKnifeGlobal.getInstance()
|
||||||
|
.getHapContext() as common.UIAbilityContext))
|
||||||
|
// 变换后缓存
|
||||||
|
allCacheInfo.resourceCacheInfo = {
|
||||||
|
key: SparkMD5.hashBinary(this.generateResourceKey) as string,
|
||||||
|
path: (mDiskCacheProxy.getCachePath() + SparkMD5.hashBinary(this.generateResourceKey)) as string
|
||||||
|
};
|
||||||
|
|
||||||
if(imageKnifeData.waitSaveDisk){
|
// 原图缓存
|
||||||
|
allCacheInfo.dataCacheInfo = {
|
||||||
|
key: SparkMD5.hashBinary(this.generateDataKey) as string,
|
||||||
|
path: (mDiskCacheProxy.getCachePath() + SparkMD5.hashBinary(this.generateDataKey)) as string
|
||||||
|
}
|
||||||
|
this.allCacheInfoCallback.callback(allCacheInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (imageKnifeData.waitSaveDisk) {
|
||||||
// 等落盘结束后主动调用#removeCurrentAndSearchNext方法
|
// 等落盘结束后主动调用#removeCurrentAndSearchNext方法
|
||||||
}else{
|
} else {
|
||||||
// 非落盘情况,直接进行寻找下一个加载
|
// 非落盘情况,直接进行寻找下一个加载
|
||||||
let imageKnife:ImageKnife | undefined = ImageKnifeGlobal.getInstance().getImageKnife();
|
let imageKnife: ImageKnife | undefined = ImageKnifeGlobal.getInstance().getImageKnife();
|
||||||
if(imageKnife != undefined) {
|
if (imageKnife != undefined) {
|
||||||
imageKnife.removeRunning(this);
|
imageKnife.removeRunning(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 图片文件落盘之后会自动去寻找下一个数据加载
|
// 图片文件落盘之后会自动去寻找下一个数据加载
|
||||||
removeCurrentAndSearchNext =()=>{
|
removeCurrentAndSearchNext = () => {
|
||||||
if(ImageKnifeGlobal.getInstance().getImageKnife() != undefined) {
|
if (ImageKnifeGlobal.getInstance().getImageKnife() != undefined) {
|
||||||
(ImageKnifeGlobal.getInstance().getImageKnife())?.removeRunning(this);
|
(ImageKnifeGlobal.getInstance().getImageKnife())?.removeRunning(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
loadError = (err: BusinessError | string) => {
|
||||||
loadError = (err:BusinessError|string)=>{
|
|
||||||
LogUtil.log("loadError:" + err);
|
LogUtil.log("loadError:" + err);
|
||||||
// 失败占位图展示规则
|
// 失败占位图展示规则
|
||||||
if (this.retryholderFunc) {
|
if (this.retryholderFunc) {
|
||||||
|
@ -552,17 +641,32 @@ export class RequestOption {
|
||||||
if (this.retryholderData != null) {
|
if (this.retryholderData != null) {
|
||||||
this.retryholderFunc.asyncSuccess(this.retryholderData)
|
this.retryholderFunc.asyncSuccess(this.retryholderData)
|
||||||
}
|
}
|
||||||
|
} else if (!this.retryholderFunc && !this.placeholderFunc && this.fallbackFunc) {
|
||||||
|
this.loadFallBackReady = true;
|
||||||
|
if (this.fallbackData != null) {
|
||||||
|
this.fallbackFunc.asyncSuccess(this.fallbackData);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// 失败图层标记,如果已经有数据直接展示失败图层
|
// 失败图层标记,如果已经有数据直接展示失败图层
|
||||||
this.loadErrorReady = true;
|
this.loadErrorReady = true;
|
||||||
if (this.errorholderData != null) {
|
if (this.errorholderData != null) {
|
||||||
if(this.errorholderFunc != undefined) {
|
if (this.errorholderFunc != undefined) {
|
||||||
this.errorholderFunc.asyncSuccess(this.errorholderData)
|
this.errorholderFunc.asyncSuccess(this.errorholderData)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.requestListeners != undefined) {
|
||||||
|
for (let i = 0; i < this.requestListeners.length; i++) {
|
||||||
|
let requestListener = this.requestListeners[i];
|
||||||
|
let boolInterception = requestListener.callback(err as string, new ImageKnifeData());
|
||||||
|
if (boolInterception) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
// 加载失败之后
|
// 加载失败之后
|
||||||
if(ImageKnifeGlobal.getInstance().getImageKnife() != undefined) {
|
if (ImageKnifeGlobal.getInstance().getImageKnife() != undefined) {
|
||||||
(ImageKnifeGlobal.getInstance().getImageKnife())?.removeRunning(this);
|
(ImageKnifeGlobal.getInstance().getImageKnife())?.removeRunning(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,197 @@
|
||||||
|
/*
|
||||||
|
* 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 { ObjectKey } from './ObjectKey';
|
||||||
|
import common from '@ohos.app.ability.common'
|
||||||
|
import { collections } from '@kit.ArkTS';
|
||||||
|
import { IDataFetch } from './networkmanage/IDataFetch';
|
||||||
|
import { DiskLruCache } from '../cache/DiskLruCache';
|
||||||
|
import { DownloadClient } from './networkmanage/DownloadClient';
|
||||||
|
|
||||||
|
@Sendable
|
||||||
|
export class SendableData{
|
||||||
|
|
||||||
|
private usageType: string = '';
|
||||||
|
private displayProgress: boolean = false
|
||||||
|
private uuid: string = '' // 唯一标识
|
||||||
|
private dontAnimateFlag: boolean = false;
|
||||||
|
private thumbSizeMultiplier: number = 0;
|
||||||
|
private thumbDelayTime: number = 1000;
|
||||||
|
private onlyRetrieveFromCache: boolean = false;
|
||||||
|
private isCacheable: boolean = true;
|
||||||
|
private gpuEnabled: boolean = false;
|
||||||
|
private generateCacheKey: string = "";
|
||||||
|
private generateResourceKey: string = "";
|
||||||
|
private generateDataKey: string = "";
|
||||||
|
private signature?: ObjectKey;
|
||||||
|
private transformations: collections.Array<collections.Array<string>> = new collections.Array<collections.Array<string>>();
|
||||||
|
private diskMemoryCachePath: string = '';
|
||||||
|
private diskMemoryCache?: DiskLruCache;
|
||||||
|
private dataFetch: IDataFetch = new DownloadClient();
|
||||||
|
private placeholderRegisterCacheKey: string = "";
|
||||||
|
private placeholderRegisterMemoryCacheKey: string = "";
|
||||||
|
|
||||||
|
public setDataFetch(value: IDataFetch) {
|
||||||
|
this.dataFetch = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getDataFetch(): IDataFetch{
|
||||||
|
return this.dataFetch;
|
||||||
|
}
|
||||||
|
|
||||||
|
public setDiskMemoryCachePath(value: string) {
|
||||||
|
this.diskMemoryCachePath = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getDiskMemoryCachePath(): string{
|
||||||
|
return this.diskMemoryCachePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public setDiskMemoryCache(value: DiskLruCache) {
|
||||||
|
this.diskMemoryCache = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getDiskMemoryCache(): DiskLruCache | undefined{
|
||||||
|
return this.diskMemoryCache;
|
||||||
|
}
|
||||||
|
|
||||||
|
public setTransformations(value: collections.Array<collections.Array<string>>) {
|
||||||
|
this.transformations = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getTransformations(): collections.Array<collections.Array<string>>{
|
||||||
|
return this.transformations;
|
||||||
|
}
|
||||||
|
|
||||||
|
public setSignature(value: ObjectKey | undefined) {
|
||||||
|
this.signature = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getSignature(): ObjectKey | undefined{
|
||||||
|
return this.signature;
|
||||||
|
}
|
||||||
|
|
||||||
|
public setGenerateDataKey(value: string) {
|
||||||
|
this.generateDataKey = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getGenerateDataKey(): string {
|
||||||
|
return this.generateDataKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public setGenerateResourceKey(value: string) {
|
||||||
|
this.generateResourceKey = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getGenerateResourceKey(): string {
|
||||||
|
return this.generateResourceKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public setGenerateCacheKey(value: string) {
|
||||||
|
this.generateCacheKey = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getGenerateCacheKey(): string {
|
||||||
|
return this.generateCacheKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public setGpuEnabled(value: boolean) {
|
||||||
|
this.gpuEnabled = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getGpuEnabled(): boolean {
|
||||||
|
return this.gpuEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public setIsCacheable(value: boolean) {
|
||||||
|
this.isCacheable = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getIsCacheable(): boolean {
|
||||||
|
return this.isCacheable;
|
||||||
|
}
|
||||||
|
|
||||||
|
public setOnlyRetrieveFromCache(value: boolean) {
|
||||||
|
this.onlyRetrieveFromCache = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getOnlyRetrieveFromCache(): boolean {
|
||||||
|
return this.onlyRetrieveFromCache;
|
||||||
|
}
|
||||||
|
|
||||||
|
public setThumbDelayTime(value: number) {
|
||||||
|
this.thumbDelayTime = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getThumbDelayTime(): number {
|
||||||
|
return this.thumbDelayTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public setThumbSizeMultiplier(value: number) {
|
||||||
|
this.thumbSizeMultiplier = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getThumbSizeMultiplier(): number {
|
||||||
|
return this.thumbSizeMultiplier;
|
||||||
|
}
|
||||||
|
|
||||||
|
public setDontAnimateFlag(value: boolean) {
|
||||||
|
this.dontAnimateFlag = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getDontAnimateFlag(): boolean {
|
||||||
|
return this.dontAnimateFlag;
|
||||||
|
}
|
||||||
|
|
||||||
|
public setUuid(value: string) {
|
||||||
|
this.uuid = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getUuid(): string {
|
||||||
|
return this.uuid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public setDisplayProgress(value: boolean) {
|
||||||
|
this.displayProgress = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getDisplayProgress(): boolean {
|
||||||
|
return this.displayProgress;
|
||||||
|
}
|
||||||
|
|
||||||
|
public setUsageType(value: string) {
|
||||||
|
this.usageType = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getUsageType(): string {
|
||||||
|
return this.usageType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public setPlaceHolderRegisterCacheKey(value: string) {
|
||||||
|
this.placeholderRegisterCacheKey = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getPlaceHolderRegisterCacheKey(): string {
|
||||||
|
return this.placeholderRegisterCacheKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public setPlaceHolderRegisterMemoryCacheKey(value: string) {
|
||||||
|
this.placeholderRegisterMemoryCacheKey = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getPlaceHolderRegisterMemoryCacheKey(): string {
|
||||||
|
return this.placeholderRegisterMemoryCacheKey;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
/*
|
||||||
|
* 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 { ObjectKey } from './ObjectKey';
|
||||||
|
import { Priority, Size } from '../imageknife/RequestOption'
|
||||||
|
import common from '@ohos.app.ability.common'
|
||||||
|
import { MResource } from './utils/MResource';
|
||||||
|
import { DataFetchResult } from './networkmanage/DataFetchResult';
|
||||||
|
|
||||||
|
export class TaskParams {
|
||||||
|
headers: Map<string, Object> = new Map<string, Object>();
|
||||||
|
moduleContext?: common.UIAbilityContext = undefined;
|
||||||
|
priority: Priority = Priority.MEDIUM // 优先级
|
||||||
|
size: Size = { width: -1, height: -1 };
|
||||||
|
loadSrc: string | PixelMap | MResource = "";
|
||||||
|
placeholderSrc: string | PixelMap | MResource | undefined = undefined;
|
||||||
|
errorholderSrc: PixelMap | MResource | undefined = undefined;
|
||||||
|
retryholderSrc: PixelMap | MResource | undefined = undefined;
|
||||||
|
fallbackSrc: PixelMap | MResource | undefined = undefined;
|
||||||
|
customGetImage?: (context: Context, loadSrc: string) => Promise<DataFetchResult>;
|
||||||
|
}
|
|
@ -14,5 +14,11 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export class Constants {
|
export class Constants {
|
||||||
public static PROJECT_TAG: string= "ImageKnife_js"
|
public static PROJECT_TAG: string = "ImageKnife_js"
|
||||||
|
public static PROGRESS_EMITTER: string = "progressEmitter"
|
||||||
|
public static PLACE_HOLDER: string = "placeholder"
|
||||||
|
public static RETRY_HOLDER: string = "retryholder"
|
||||||
|
public static ERROR_HOLDER: string = "errorholder"
|
||||||
|
public static MAIN_HOLDER: string = "main"
|
||||||
|
public static FALL_BACK: string = "fallback"
|
||||||
}
|
}
|
|
@ -31,21 +31,15 @@ export class ErrorHolderManager<T> {
|
||||||
this.options = option;
|
this.options = option;
|
||||||
}
|
}
|
||||||
|
|
||||||
static execute(option: RequestOption) {
|
process = (onComplete:(value:PixelMap)=>void|PromiseLike<ImageKnifeData>, onError:(reason?:BusinessError|string)=>void)=>{
|
||||||
let manager:ErrorHolderManager<ImageKnifeData> = new ErrorHolderManager<ImageKnifeData>(option);
|
|
||||||
return new Promise(manager.process)
|
|
||||||
.then(option.errorholderOnComplete).catch(option.errorholderOnError);
|
|
||||||
}
|
|
||||||
|
|
||||||
process = (onComplete:(value:ImageKnifeData)=>void|PromiseLike<ImageKnifeData>, onError:(reason?:BusinessError|string)=>void)=>{
|
|
||||||
this.displayErrorholder(onComplete, onError);
|
this.displayErrorholder(onComplete, onError);
|
||||||
}
|
}
|
||||||
|
|
||||||
private displayErrorholder(onComplete:(value:ImageKnifeData)=>void|PromiseLike<ImageKnifeData>, onError:(reason?:BusinessError|string)=>void) {
|
private displayErrorholder(onComplete:(value:PixelMap)=>void|PromiseLike<ImageKnifeData>, onError:(reason?:BusinessError|string)=>void) {
|
||||||
LogUtil.log("displayErrorholder")
|
LogUtil.log("displayErrorholder")
|
||||||
if ((typeof (this.options.errorholderSrc as image.PixelMap).isEditable) == 'boolean') {
|
if ((typeof (this.options.errorholderSrc as image.PixelMap).isEditable) == 'boolean') {
|
||||||
let imageKnifeData = ImageKnifeData.createImagePixelMap(ImageKnifeType.PIXELMAP, this.options.errorholderSrc as PixelMap)
|
let imageKnifeData = ImageKnifeData.createImagePixelMap(ImageKnifeType.PIXELMAP, this.options.errorholderSrc as PixelMap)
|
||||||
onComplete(imageKnifeData);
|
onComplete(imageKnifeData?.drawPixelMap?.imagePixelMap as PixelMap);
|
||||||
} else if (typeof this.options.errorholderSrc == 'string') {
|
} else if (typeof this.options.errorholderSrc == 'string') {
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
@ -67,6 +61,7 @@ export class ErrorHolderManager<T> {
|
||||||
case SupportFormat.gif:
|
case SupportFormat.gif:
|
||||||
case SupportFormat.tiff:
|
case SupportFormat.tiff:
|
||||||
case SupportFormat.webp:
|
case SupportFormat.webp:
|
||||||
|
case SupportFormat.heic:
|
||||||
this.mediaImageProcess(onComplete, onError, arraybuffer, typeValue)
|
this.mediaImageProcess(onComplete, onError, arraybuffer, typeValue)
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -89,16 +84,16 @@ export class ErrorHolderManager<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private svgProcess(onComplete:(value:ImageKnifeData)=>void|PromiseLike<ImageKnifeData>, onError:(reason?:BusinessError|string)=>void, arraybuffer:ArrayBuffer, typeValue:string) {
|
private svgProcess(onComplete:(value:PixelMap)=>void|PromiseLike<ImageKnifeData>, onError:(reason?:BusinessError|string)=>void, arraybuffer:ArrayBuffer, typeValue:string) {
|
||||||
let svgParseImpl:SVGParseImpl = new SVGParseImpl()
|
let svgParseImpl:SVGParseImpl = new SVGParseImpl()
|
||||||
svgParseImpl.parseSvg(this.options,arraybuffer, onComplete,onError);
|
svgParseImpl.parseSvg(this.options,arraybuffer, onComplete,onError);
|
||||||
}
|
}
|
||||||
|
|
||||||
private mediaImageProcess(onComplete:(value:ImageKnifeData)=>void|PromiseLike<ImageKnifeData>, onError:(reason?:BusinessError|string)=>void, arraybuffer:ArrayBuffer, typeValue:string) {
|
private mediaImageProcess(onComplete:(value:PixelMap)=>void|PromiseLike<ImageKnifeData>, onError:(reason?:BusinessError|string)=>void, arraybuffer:ArrayBuffer, typeValue:string) {
|
||||||
let parseImageUtil = new ParseImageUtil()
|
let parseImageUtil = new ParseImageUtil()
|
||||||
let success = (value: PixelMap) => {
|
let success = (value: PixelMap) => {
|
||||||
let imageKnifeData = ImageKnifeData.createImagePixelMap(ImageKnifeType.PIXELMAP, value)
|
let imageKnifeData = ImageKnifeData.createImagePixelMap(ImageKnifeType.PIXELMAP, value)
|
||||||
onComplete(imageKnifeData)
|
onComplete(imageKnifeData?.drawPixelMap?.imagePixelMap as PixelMap)
|
||||||
}
|
}
|
||||||
parseImageUtil.parseImage(arraybuffer, success, onError)
|
parseImageUtil.parseImage(arraybuffer, success, onError)
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,9 @@ import {LogUtil} from '../../imageknife/utils/LogUtil'
|
||||||
import resourceManager from '@ohos.resourceManager';
|
import resourceManager from '@ohos.resourceManager';
|
||||||
import image from "@ohos.multimedia.image"
|
import image from "@ohos.multimedia.image"
|
||||||
import { BusinessError } from '@ohos.base'
|
import { BusinessError } from '@ohos.base'
|
||||||
|
import { GIFFrame } from '../utils/gif/GIFFrame'
|
||||||
|
import { DiskLruCache } from '../../cache/DiskLruCache'
|
||||||
|
|
||||||
export class PlaceHolderManager<T> {
|
export class PlaceHolderManager<T> {
|
||||||
private options: RequestOption;
|
private options: RequestOption;
|
||||||
|
|
||||||
|
@ -32,23 +35,84 @@ export class PlaceHolderManager<T> {
|
||||||
this.options = option;
|
this.options = option;
|
||||||
}
|
}
|
||||||
|
|
||||||
static execute(option: RequestOption) {
|
|
||||||
let manager:PlaceHolderManager<ImageKnifeData> = new PlaceHolderManager<ImageKnifeData>(option);
|
|
||||||
return new Promise(manager.process)
|
|
||||||
.then(option.placeholderOnComplete).catch(option.placeholderOnError);
|
|
||||||
}
|
|
||||||
|
|
||||||
process = (onComplete:(value:ImageKnifeData)=>void|PromiseLike<ImageKnifeData>, onError:(reason?:BusinessError|string)=>void)=>{
|
process = (onComplete:(value:PixelMap)=>void|PromiseLike<ImageKnifeData>, onError:(reason?:BusinessError|string)=>void)=>{
|
||||||
this.displayPlaceholder(onComplete, onError);
|
this.displayPlaceholder(onComplete, onError);
|
||||||
}
|
}
|
||||||
|
|
||||||
private displayPlaceholder(onComplete:(value:ImageKnifeData)=>void|PromiseLike<ImageKnifeData>, onError:(reason?:BusinessError|string)=>void){
|
private displayPlaceholder(onComplete:(value:PixelMap)=>void|PromiseLike<ImageKnifeData>, onError:(reason?:BusinessError|string)=>void){
|
||||||
LogUtil.log("displayPlaceholder")
|
LogUtil.log("ImageKnife displayPlaceholder")
|
||||||
if ((typeof (this.options.placeholderSrc as image.PixelMap).isEditable) == 'boolean') {
|
if ((typeof (this.options.placeholderSrc as image.PixelMap).isEditable) == 'boolean') {
|
||||||
let imageKnifeData = ImageKnifeData.createImagePixelMap(ImageKnifeType.PIXELMAP, this.options.placeholderSrc as PixelMap)
|
let imageKnifeData = ImageKnifeData.createImagePixelMap(ImageKnifeType.PIXELMAP, this.options.placeholderSrc as PixelMap)
|
||||||
onComplete(imageKnifeData);
|
onComplete(imageKnifeData?.drawPixelMap?.imagePixelMap as PixelMap);
|
||||||
} else if (typeof this.options.placeholderSrc == 'string') {
|
} else if (typeof this.options.placeholderSrc == 'string') {
|
||||||
|
if (typeof this.options.placeholderCacheKey == 'string' && this.options.placeholderCacheKey != '') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let cached = DiskLruCache.getFileCacheByFile(this.options.diskMemoryCachePath,this.options.placeholderRegisterCacheKey);
|
||||||
|
if (cached != null && cached.byteLength > 0) {
|
||||||
|
let fileTypeUtil = new FileTypeUtil();
|
||||||
|
let typeValue = fileTypeUtil.getFileType(cached);
|
||||||
|
switch (typeValue) {
|
||||||
|
case SupportFormat.svg:
|
||||||
|
this.svgProcess(onComplete, onError, cached, typeValue);
|
||||||
|
break;
|
||||||
|
case SupportFormat.jpg:
|
||||||
|
case SupportFormat.png:
|
||||||
|
case SupportFormat.bmp:
|
||||||
|
case SupportFormat.gif:
|
||||||
|
case SupportFormat.tiff:
|
||||||
|
case SupportFormat.webp:
|
||||||
|
case SupportFormat.heic:
|
||||||
|
this.mediaImageProcess(onComplete, onError, cached, typeValue);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
onError("PlaceHolderManager 文件类型不支持");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if ((typeof (this.options.fallbackSrc as image.PixelMap).isEditable) == 'boolean') {
|
||||||
|
let imageKnifeData = ImageKnifeData.createImagePixelMap(ImageKnifeType.PIXELMAP, this.options.fallbackSrc as PixelMap);
|
||||||
|
onComplete(imageKnifeData?.drawPixelMap?.imagePixelMap as PixelMap);
|
||||||
|
} else {
|
||||||
|
let res = this.options.fallbackSrc as Resource;
|
||||||
|
if (typeof res.id != 'undefined' && typeof res.id != 'undefined') {
|
||||||
|
let resourceFetch = new ParseResClient();
|
||||||
|
let suc = (arraybuffer:ArrayBuffer) => {
|
||||||
|
let fileTypeUtil: FileTypeUtil = new FileTypeUtil();
|
||||||
|
let typeValue: string | null = fileTypeUtil.getFileType(arraybuffer);
|
||||||
|
if (typeValue != null) {
|
||||||
|
switch (typeValue) {
|
||||||
|
case SupportFormat.svg:
|
||||||
|
this.svgProcess(onComplete, onError, arraybuffer, typeValue);
|
||||||
|
break;
|
||||||
|
case SupportFormat.jpg:
|
||||||
|
case SupportFormat.png:
|
||||||
|
case SupportFormat.bmp:
|
||||||
|
case SupportFormat.gif:
|
||||||
|
case SupportFormat.tiff:
|
||||||
|
case SupportFormat.webp:
|
||||||
|
this.mediaImageProcess(onComplete, onError, arraybuffer, typeValue);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
onError("FallBackManager 文件类型不支持");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
onError("FallBackManager 文件类型为null,请检查数据源arraybuffer");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let ctx = this.options.getModuleContext();
|
||||||
|
if(ctx != undefined){
|
||||||
|
resourceFetch.loadResource(ctx,res, suc, onError);
|
||||||
|
}else{
|
||||||
|
onError("FallBackManager moduleContext is undefined,please check it!");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
onError("FallBackManager 输入参数有问题!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
let res = this.options.placeholderSrc as Resource;
|
let res = this.options.placeholderSrc as Resource;
|
||||||
if (typeof res.id != 'undefined' && typeof res.id != 'undefined') {
|
if (typeof res.id != 'undefined' && typeof res.id != 'undefined') {
|
||||||
|
@ -66,6 +130,7 @@ export class PlaceHolderManager<T> {
|
||||||
case SupportFormat.gif:
|
case SupportFormat.gif:
|
||||||
case SupportFormat.tiff:
|
case SupportFormat.tiff:
|
||||||
case SupportFormat.webp:
|
case SupportFormat.webp:
|
||||||
|
case SupportFormat.heic:
|
||||||
this.mediaImageProcess(onComplete, onError, arraybuffer, typeValue)
|
this.mediaImageProcess(onComplete, onError, arraybuffer, typeValue)
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -87,16 +152,16 @@ export class PlaceHolderManager<T> {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private svgProcess(onComplete:(value:ImageKnifeData)=>void|PromiseLike<ImageKnifeData>, onError:(reason?:BusinessError|string)=>void, arraybuffer:ArrayBuffer, typeValue:string) {
|
private svgProcess(onComplete:(value:PixelMap)=>void|PromiseLike<ImageKnifeData>, onError:(reason?:BusinessError|string)=>void, arraybuffer:ArrayBuffer, typeValue:string) {
|
||||||
let svgParseImpl:SVGParseImpl = new SVGParseImpl()
|
let svgParseImpl:SVGParseImpl = new SVGParseImpl()
|
||||||
svgParseImpl.parseSvg(this.options,arraybuffer, onComplete,onError);
|
svgParseImpl.parseSvg(this.options,arraybuffer, onComplete,onError);
|
||||||
}
|
}
|
||||||
|
|
||||||
private mediaImageProcess(onComplete:(value:ImageKnifeData)=>void|PromiseLike<ImageKnifeData>, onError:(reason?:BusinessError|string)=>void, arraybuffer:ArrayBuffer, typeValue:string) {
|
private mediaImageProcess(onComplete:(value:PixelMap)=>void|PromiseLike<ImageKnifeData>, onError:(reason?:BusinessError|string)=>void, arraybuffer:ArrayBuffer, typeValue:string) {
|
||||||
let parseImageUtil:ParseImageUtil = new ParseImageUtil()
|
let parseImageUtil:ParseImageUtil = new ParseImageUtil()
|
||||||
let success = (value: PixelMap) => {
|
let success = (value: PixelMap) => {
|
||||||
let imageKnifeData = ImageKnifeData.createImagePixelMap(ImageKnifeType.PIXELMAP, value)
|
let imageKnifeData = ImageKnifeData.createImagePixelMap(ImageKnifeType.PIXELMAP, value)
|
||||||
onComplete(imageKnifeData)
|
onComplete(imageKnifeData?.drawPixelMap?.imagePixelMap as PixelMap)
|
||||||
}
|
}
|
||||||
parseImageUtil.parseImage(arraybuffer, success, onError)
|
parseImageUtil.parseImage(arraybuffer, success, onError)
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,21 +32,15 @@ export class RetryHolderManager<T> {
|
||||||
this.options = option;
|
this.options = option;
|
||||||
}
|
}
|
||||||
|
|
||||||
static execute(option: RequestOption) {
|
process = (onComplete:(value:PixelMap)=>void|PromiseLike<ImageKnifeData>, onError:(reason?:BusinessError|string)=>void)=>{
|
||||||
let manager:RetryHolderManager<ImageKnifeData> = new RetryHolderManager<ImageKnifeData>(option);
|
|
||||||
return new Promise(manager.process)
|
|
||||||
.then(option.retryholderOnComplete).catch(option.retryholderOnError);
|
|
||||||
}
|
|
||||||
|
|
||||||
process = (onComplete:(value:ImageKnifeData)=>void|PromiseLike<ImageKnifeData>, onError:(reason?:BusinessError|string)=>void)=>{
|
|
||||||
this.displayRetryholder(onComplete, onError);
|
this.displayRetryholder(onComplete, onError);
|
||||||
}
|
}
|
||||||
|
|
||||||
private displayRetryholder(onComplete:(value:ImageKnifeData)=>void|PromiseLike<ImageKnifeData>, onError:(reason?:BusinessError|string)=>void){
|
private displayRetryholder(onComplete:(value:PixelMap)=>void|PromiseLike<ImageKnifeData>, onError:(reason?:BusinessError|string)=>void){
|
||||||
LogUtil.log("displayRetryholder")
|
LogUtil.log("ImageKnife displayRetryholder")
|
||||||
if ((typeof (this.options.retryholderSrc as image.PixelMap).isEditable) == 'boolean') {
|
if ((typeof (this.options.retryholderSrc as image.PixelMap).isEditable) == 'boolean') {
|
||||||
let imageKnifeData = ImageKnifeData.createImagePixelMap(ImageKnifeType.PIXELMAP, this.options.placeholderSrc as PixelMap)
|
let imageKnifeData = ImageKnifeData.createImagePixelMap(ImageKnifeType.PIXELMAP, this.options.placeholderSrc as PixelMap)
|
||||||
onComplete(imageKnifeData);
|
onComplete(imageKnifeData?.drawPixelMap?.imagePixelMap as PixelMap);
|
||||||
} else if (typeof this.options.placeholderSrc == 'string') {
|
} else if (typeof this.options.placeholderSrc == 'string') {
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
@ -66,6 +60,7 @@ export class RetryHolderManager<T> {
|
||||||
case SupportFormat.gif:
|
case SupportFormat.gif:
|
||||||
case SupportFormat.tiff:
|
case SupportFormat.tiff:
|
||||||
case SupportFormat.webp:
|
case SupportFormat.webp:
|
||||||
|
case SupportFormat.heic:
|
||||||
this.mediaImageProcess(onComplete, onError, arraybuffer, typeValue)
|
this.mediaImageProcess(onComplete, onError, arraybuffer, typeValue)
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -87,16 +82,16 @@ export class RetryHolderManager<T> {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private svgProcess(onComplete:(value:ImageKnifeData)=>void|PromiseLike<ImageKnifeData>, onError:(reason?:BusinessError|string)=>void, arraybuffer:ArrayBuffer, typeValue:string) {
|
private svgProcess(onComplete:(value:PixelMap)=>void|PromiseLike<ImageKnifeData>, onError:(reason?:BusinessError|string)=>void, arraybuffer:ArrayBuffer, typeValue:string) {
|
||||||
let svgParseImpl = new SVGParseImpl()
|
let svgParseImpl = new SVGParseImpl()
|
||||||
svgParseImpl.parseSvg(this.options,arraybuffer, onComplete,onError);
|
svgParseImpl.parseSvg(this.options,arraybuffer, onComplete,onError);
|
||||||
}
|
}
|
||||||
|
|
||||||
private mediaImageProcess(onComplete:(value:ImageKnifeData)=>void|PromiseLike<ImageKnifeData>, onError:(reason?:BusinessError|string)=>void, arraybuffer:ArrayBuffer, typeValue:string) {
|
private mediaImageProcess(onComplete:(value:PixelMap)=>void|PromiseLike<ImageKnifeData>, onError:(reason?:BusinessError|string)=>void, arraybuffer:ArrayBuffer, typeValue:string) {
|
||||||
let parseImageUtil = new ParseImageUtil()
|
let parseImageUtil = new ParseImageUtil()
|
||||||
let success = (value: PixelMap) => {
|
let success = (value: PixelMap) => {
|
||||||
let imageKnifeData = ImageKnifeData.createImagePixelMap(ImageKnifeType.PIXELMAP, value)
|
let imageKnifeData = ImageKnifeData.createImagePixelMap(ImageKnifeType.PIXELMAP, value)
|
||||||
onComplete(imageKnifeData)
|
onComplete(imageKnifeData?.drawPixelMap?.imagePixelMap as PixelMap)
|
||||||
}
|
}
|
||||||
parseImageUtil.parseImage(arraybuffer, success, onError)
|
parseImageUtil.parseImage(arraybuffer, success, onError)
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,113 @@
|
||||||
|
/*
|
||||||
|
* 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 { IDataFetch } from '../networkmanage/IDataFetch'
|
||||||
|
import { RequestOption } from '../RequestOption'
|
||||||
|
import { RequestData } from './RequestData'
|
||||||
|
import { ImageKnifeGlobal } from '../ImageKnifeGlobal'
|
||||||
|
import common from '@ohos.app.ability.common'
|
||||||
|
import http from '@ohos.net.http'
|
||||||
|
import { DataFetchResult } from './DataFetchResult'
|
||||||
|
|
||||||
|
@Sendable
|
||||||
|
export class CustomDataFetchClient implements IDataFetch {
|
||||||
|
async loadData(request: RequestOption) {
|
||||||
|
let result: DataFetchResult = new DataFetchResult();
|
||||||
|
if (!request || typeof request.loadSrc !== 'string') {
|
||||||
|
result.error = 'CustomDataFetchClient request or loadSrc error.';
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
// 自定义单个图片的网络栈
|
||||||
|
if (request.customGetImage) {
|
||||||
|
return await request.customGetImage(ImageKnifeGlobal.getInstance()
|
||||||
|
.getHapContext() as common.UIAbilityContext, request.loadSrc);
|
||||||
|
}
|
||||||
|
// 所有图片的网络栈
|
||||||
|
try {
|
||||||
|
let httpRequest = http.createHttp()
|
||||||
|
let arrayBuffers = new Array<ArrayBuffer>();
|
||||||
|
httpRequest.on('headersReceive', (header: Object) => {
|
||||||
|
// 跟服务器连接成功准备下载
|
||||||
|
if (request.progressFunc) {
|
||||||
|
// 进度条为0
|
||||||
|
request.progressFunc.asyncSuccess(0)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
httpRequest.on('dataReceive', (data: ArrayBuffer) => {
|
||||||
|
// 下载数据流多次返回
|
||||||
|
arrayBuffers.push(data);
|
||||||
|
})
|
||||||
|
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 (request.progressFunc) {
|
||||||
|
request.progressFunc.asyncSuccess(percent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
httpRequest.on('dataEnd', () => {
|
||||||
|
// 下载完毕
|
||||||
|
})
|
||||||
|
const headerObj: Record<string, Object> = {}
|
||||||
|
request.headers.forEach((value, key) => {
|
||||||
|
headerObj[key] = value
|
||||||
|
})
|
||||||
|
const data = await httpRequest.requestInStream(request.loadSrc as string, {
|
||||||
|
header: headerObj,
|
||||||
|
method: http.RequestMethod.GET,
|
||||||
|
expectDataType: http.HttpDataType.ARRAY_BUFFER,
|
||||||
|
connectTimeout: 60000, // 可选 默认60000ms
|
||||||
|
readTimeout: 0, // 可选, 默认为60000ms
|
||||||
|
usingProtocol: http.HttpProtocol.HTTP1_1, // 可选,协议类型默认值由系统自动指定
|
||||||
|
usingCache: false
|
||||||
|
}).catch((err: Error) => {
|
||||||
|
result.error = 'CustomDataFetchClient has error, http code = ' + JSON.stringify(err);
|
||||||
|
})
|
||||||
|
if (data == 200) {
|
||||||
|
result.data = this.combineArrayBuffers(arrayBuffers);
|
||||||
|
} else {
|
||||||
|
result.error = 'CustomDataFetchClient resultCode error, code = ' + data;
|
||||||
|
}
|
||||||
|
console.log('TestCustomDataFetch all onComplete, code = ' + data + ',length = ' + result.data?.byteLength);
|
||||||
|
} catch (err) {
|
||||||
|
result.error = 'CustomDataFetchClient catch err request uuid =' + request.uuid;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
combineArrayBuffers(arrayBuffers: ArrayBuffer[]): ArrayBuffer {
|
||||||
|
// 计算多个ArrayBuffer的总字节大小
|
||||||
|
let totalByteLength = 0;
|
||||||
|
for (const arrayBuffer of arrayBuffers) {
|
||||||
|
totalByteLength += arrayBuffer.byteLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建一个新的ArrayBuffer
|
||||||
|
const combinedArrayBuffer = new ArrayBuffer(totalByteLength);
|
||||||
|
|
||||||
|
// 创建一个Uint8Array来操作新的ArrayBuffer
|
||||||
|
const combinedUint8Array = new Uint8Array(combinedArrayBuffer);
|
||||||
|
|
||||||
|
// 依次复制每个ArrayBuffer的内容到新的ArrayBuffer中
|
||||||
|
let offset = 0;
|
||||||
|
for (const arrayBuffer of arrayBuffers) {
|
||||||
|
const sourceUint8Array = new Uint8Array(arrayBuffer);
|
||||||
|
combinedUint8Array.set(sourceUint8Array, offset);
|
||||||
|
offset += sourceUint8Array.length;
|
||||||
|
}
|
||||||
|
return combinedArrayBuffer;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2021 Huawei Device Co., Ltd.
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
export class DataFetchResult{
|
||||||
|
data?: ArrayBuffer;
|
||||||
|
error?: string;
|
||||||
|
}
|
|
@ -23,29 +23,42 @@ import loadRequest from '@ohos.request';
|
||||||
import { ImageKnifeGlobal } from '../ImageKnifeGlobal'
|
import { ImageKnifeGlobal } from '../ImageKnifeGlobal'
|
||||||
import common from '@ohos.app.ability.common'
|
import common from '@ohos.app.ability.common'
|
||||||
import { NetworkDownloadClient } from './NetworkDownloadClient'
|
import { NetworkDownloadClient } from './NetworkDownloadClient'
|
||||||
|
import { DataFetchResult } from './DataFetchResult'
|
||||||
|
|
||||||
// 数据加载器
|
// 数据加载器
|
||||||
|
@Sendable
|
||||||
export class DownloadClient implements IDataFetch {
|
export class DownloadClient implements IDataFetch {
|
||||||
private networkDownloadClient = new NetworkDownloadClient();
|
private networkDownloadClient:NetworkDownloadClient = new NetworkDownloadClient();
|
||||||
private httpDownloadClient = new HttpDownloadClient();
|
private httpDownloadClient:HttpDownloadClient = new HttpDownloadClient();
|
||||||
private localFileClient = new LoadLocalFileClient();
|
private localFileClient:LoadLocalFileClient = new LoadLocalFileClient();
|
||||||
private dataShareFileClient = new LoadDataShareFileClient();
|
private dataShareFileClient:LoadDataShareFileClient = new LoadDataShareFileClient();
|
||||||
|
|
||||||
loadData(request: RequestOption, onCompleteFunction:(img: ArrayBuffer) => void, onErrorFunction: (err: string) => void) {
|
async loadData(request: RequestOption): Promise<DataFetchResult> {
|
||||||
if (typeof request.loadSrc == 'string') {
|
if (typeof request.loadSrc == 'string') {
|
||||||
let fileDir:string = (ImageKnifeGlobal.getInstance().getHapContext() as common.UIAbilityContext).filesDir as string;
|
if (this.isLocalLoadSrc(ImageKnifeGlobal.getInstance().getHapContext(), request.loadSrc)) {
|
||||||
let cacheDir:string = (ImageKnifeGlobal.getInstance().getHapContext() as common.UIAbilityContext).cacheDir as string
|
|
||||||
|
|
||||||
if (request.loadSrc.startsWith(fileDir) ||
|
|
||||||
request.loadSrc.startsWith(cacheDir)) {
|
|
||||||
// 本地沙盒
|
// 本地沙盒
|
||||||
this.localFileClient.loadData(request, onCompleteFunction, onErrorFunction)
|
return this.localFileClient.loadData(request)
|
||||||
} else if (request.loadSrc.startsWith('datashare://') || request.loadSrc.startsWith('file://')) {
|
} else if (request.loadSrc.startsWith('datashare://') || request.loadSrc.startsWith('file://')) {
|
||||||
this.dataShareFileClient.loadData(request, onCompleteFunction, onErrorFunction)
|
return this.dataShareFileClient.loadData(request)
|
||||||
} else {
|
} else {
|
||||||
// 网络下载
|
// 网络下载
|
||||||
this.httpDownloadClient.loadData(request, onCompleteFunction, onErrorFunction)
|
return await this.httpDownloadClient.loadData(request);
|
||||||
}
|
}
|
||||||
|
}else{
|
||||||
|
let result:DataFetchResult = new DataFetchResult()
|
||||||
|
result.error ="参数错误!";
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -13,76 +13,68 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { IDataFetch } from '../networkmanage/IDataFetch'
|
import { IDataFetch } from '../networkmanage/IDataFetch'
|
||||||
import { RequestOption } from '../RequestOption'
|
import { RequestOption } from '../RequestOption'
|
||||||
import { SparkMD5 } from '../../3rd_party/sparkmd5/spark-md5'
|
|
||||||
import { FileUtils } from '../../cache/FileUtils'
|
|
||||||
import loadRequest from '@ohos.request';
|
|
||||||
import { LogUtil } from '../utils/LogUtil'
|
|
||||||
import { ImageKnifeGlobal } from '../ImageKnifeGlobal'
|
|
||||||
import common from '@ohos.app.ability.common'
|
|
||||||
import { BusinessError } from '@ohos.base'
|
|
||||||
import http from '@ohos.net.http'
|
import http from '@ohos.net.http'
|
||||||
// 数据加载器
|
import { RequestData } from './RequestData'
|
||||||
class RequestData{
|
import { DataFetchResult } from './DataFetchResult'
|
||||||
receiveSize: number = 2000
|
|
||||||
totalSize: number = 2000
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
@Sendable
|
||||||
export class HttpDownloadClient implements IDataFetch {
|
export class HttpDownloadClient implements IDataFetch {
|
||||||
loadData(request: RequestOption, onComplete: (img: ArrayBuffer) => void, onError: (err: string) => void) {
|
async loadData(request: RequestOption) {
|
||||||
try {
|
let result:DataFetchResult = new DataFetchResult();
|
||||||
let httpRequest = http.createHttp()
|
try {
|
||||||
let arrayBuffers = new Array<ArrayBuffer>();
|
let httpRequest = http.createHttp()
|
||||||
httpRequest.on('headersReceive', (header: Object) => {
|
let arrayBuffers = new Array<ArrayBuffer>();
|
||||||
// 跟服务器连接成功准备下载
|
httpRequest.on('headersReceive', (header: Object) => {
|
||||||
if (request.progressFunc) {
|
// 跟服务器连接成功准备下载
|
||||||
// 进度条为0
|
if (request.progressFunc) {
|
||||||
request.progressFunc.asyncSuccess(0)
|
// 进度条为0
|
||||||
}
|
request.progressFunc.asyncSuccess(0)
|
||||||
})
|
}
|
||||||
httpRequest.on('dataReceive', (data: ArrayBuffer) => {
|
})
|
||||||
// 下载数据流多次返回
|
httpRequest.on('dataReceive', (data: ArrayBuffer) => {
|
||||||
arrayBuffers.push(data);
|
// 下载数据流多次返回
|
||||||
})
|
arrayBuffers.push(data);
|
||||||
|
})
|
||||||
httpRequest.on('dataReceiveProgress', (data: RequestData) => {
|
httpRequest.on('dataReceiveProgress', (data: RequestData) => {
|
||||||
// 下载进度
|
// 下载进度
|
||||||
if(data != undefined && (typeof data.receiveSize == 'number') && (typeof data.totalSize == 'number') ) {
|
if (data != undefined && (typeof data.receiveSize == 'number') && (typeof data.totalSize == 'number')) {
|
||||||
let percent = Math.round(((data.receiveSize * 1.0) / (data.totalSize * 1.0)) * 100)
|
let percent = Math.round(((data.receiveSize * 1.0) / (data.totalSize * 1.0)) * 100)
|
||||||
if (request.progressFunc) {
|
if (request.progressFunc) {
|
||||||
request.progressFunc.asyncSuccess(percent)
|
request.progressFunc.asyncSuccess(percent)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
httpRequest.on('dataEnd', () => {
|
||||||
httpRequest.on('dataEnd', () => {
|
// 下载完毕
|
||||||
// 下载完毕
|
})
|
||||||
let combineArray = this.combineArrayBuffers(arrayBuffers);
|
const headerObj: Record<string, Object> = {}
|
||||||
onComplete(combineArray)
|
request.headers.forEach((value, key) => {
|
||||||
})
|
headerObj[key] = value
|
||||||
|
})
|
||||||
httpRequest.requestInStream(
|
const data = await httpRequest.requestInStream(request.loadSrc as string, {
|
||||||
request.loadSrc as string,
|
header: headerObj,
|
||||||
{
|
method: http.RequestMethod.GET,
|
||||||
method: http.RequestMethod.GET,
|
expectDataType: http.HttpDataType.ARRAY_BUFFER,
|
||||||
expectDataType: http.HttpDataType.ARRAY_BUFFER,
|
connectTimeout: 60000, // 可选 默认60000ms
|
||||||
connectTimeout: 60000, // 可选 默认60000ms
|
readTimeout: 0, // 可选, 默认为60000ms
|
||||||
readTimeout: 0, // 可选, 默认为60000ms
|
usingProtocol: http.HttpProtocol.HTTP1_1, // 可选,协议类型默认值由系统自动指定
|
||||||
usingProtocol: http.HttpProtocol.HTTP1_1, // 可选,协议类型默认值由系统自动指定
|
usingCache: false
|
||||||
}
|
}).catch((err: Error) => {
|
||||||
).then((data)=>{
|
result.error = `HttpDownloadClient has error, http code = ` + JSON.stringify(err);
|
||||||
if(data == 200) {
|
})
|
||||||
|
if ( data == 200) {
|
||||||
} else {
|
result.data = this.combineArrayBuffers(arrayBuffers);
|
||||||
onError(`HttpDownloadClient has error, http code = ${data}`)
|
} else {
|
||||||
}
|
result.error = `HttpDownloadClient has error, http code = ` + JSON.stringify(data);
|
||||||
}).catch((err:Error)=>{
|
}
|
||||||
onError(`HttpDownloadClient has error, http code = ${err}`)
|
console.log('TestCustomDataFetch http onComplete, code = ' + data + ',length = ' + result.data?.byteLength);
|
||||||
})
|
} catch (err) {
|
||||||
} catch (err) {
|
result.error ='HttpDownloadClient catch err request uuid =' + request.uuid;
|
||||||
onError('HttpDownloadClient catch err request uuid ='+request.uuid)
|
}
|
||||||
}
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
combineArrayBuffers(arrayBuffers: ArrayBuffer[]): ArrayBuffer {
|
combineArrayBuffers(arrayBuffers: ArrayBuffer[]): ArrayBuffer {
|
||||||
|
|
|
@ -14,8 +14,11 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { RequestOption } from '../RequestOption'
|
import { RequestOption } from '../RequestOption'
|
||||||
|
import lang from '@arkts.lang';
|
||||||
|
import { DataFetchResult } from './DataFetchResult';
|
||||||
|
|
||||||
|
type ISendable = lang.ISendable;
|
||||||
// 资源加载接口
|
// 资源加载接口
|
||||||
export interface IDataFetch {
|
export interface IDataFetch extends ISendable{
|
||||||
loadData:(request: RequestOption, onComplete: (img: ArrayBuffer) => void, onError: (err: string) => void)=>void;
|
loadData(request: RequestOption): DataFetchResult|Promise<DataFetchResult>;
|
||||||
}
|
}
|
|
@ -16,25 +16,29 @@ import { IDataFetch } from '../networkmanage/IDataFetch'
|
||||||
import { RequestOption } from '../RequestOption'
|
import { RequestOption } from '../RequestOption'
|
||||||
import fs from '@ohos.file.fs';
|
import fs from '@ohos.file.fs';
|
||||||
import { BusinessError } from '@ohos.base'
|
import { BusinessError } from '@ohos.base'
|
||||||
|
import { DataFetchResult } from './DataFetchResult';
|
||||||
|
|
||||||
|
@Sendable
|
||||||
export class LoadDataShareFileClient implements IDataFetch {
|
export class LoadDataShareFileClient implements IDataFetch {
|
||||||
loadData(request: RequestOption, onComplete: (img: ArrayBuffer) => void, onError: (err: string) => void) {
|
loadData(request: RequestOption) {
|
||||||
|
let result:DataFetchResult =new DataFetchResult()
|
||||||
if (typeof request.loadSrc == 'string') {
|
if (typeof request.loadSrc == 'string') {
|
||||||
fs.open(request.loadSrc, fs.OpenMode.READ_ONLY).then((file) => {
|
fs.open(request.loadSrc, fs.OpenMode.READ_ONLY).then((file) => {
|
||||||
fs.stat(file.fd).then(stat =>{
|
fs.stat(file.fd).then(stat =>{
|
||||||
let buf = new ArrayBuffer(stat.size);
|
let buf = new ArrayBuffer(stat.size);
|
||||||
fs.read(file.fd, buf).then((readLen) => {
|
fs.read(file.fd, buf).then((readLen) => {
|
||||||
onComplete(buf);
|
result.data=buf;
|
||||||
fs.close(file.fd);
|
fs.close(file.fd);
|
||||||
}).catch((err:BusinessError) => {
|
}).catch((err:BusinessError) => {
|
||||||
onError('LoadDataShareFileClient fs.read err happened uri=' + request.loadSrc + " err.msg=" + err?.message + " err.code=" + err?.code)
|
result.error = 'LoadDataShareFileClient fs.read err happened uri=' + request.loadSrc + " err.msg=" + err?.message + " err.code=" + err?.code;
|
||||||
})
|
})
|
||||||
}).catch((err:BusinessError) => {
|
}).catch((err:BusinessError) => {
|
||||||
onError('LoadDataShareFileClient fs.stat err happened uri=' + request.loadSrc + " err.msg=" + err?.message + " err.code=" + err?.code)
|
result.error = 'LoadDataShareFileClient fs.stat err happened uri=' + request.loadSrc + " err.msg=" + err?.message + " err.code=" + err?.code;
|
||||||
})
|
})
|
||||||
}).catch((err:BusinessError) => {
|
}).catch((err:BusinessError) => {
|
||||||
onError('LoadDataShareFileClient fs.open err happened uri=' + request.loadSrc + " err.msg=" + err?.message + " err.code=" + err?.code)
|
result.error ='LoadDataShareFileClient fs.open err happened uri=' + request.loadSrc + " err.msg=" + err?.message + " err.code=" + err?.code;
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -17,19 +17,23 @@ import { IDataFetch } from '../networkmanage/IDataFetch'
|
||||||
import { RequestOption } from '../RequestOption'
|
import { RequestOption } from '../RequestOption'
|
||||||
import { FileUtils } from '../../cache/FileUtils'
|
import { FileUtils } from '../../cache/FileUtils'
|
||||||
import { BusinessError } from '@ohos.base'
|
import { BusinessError } from '@ohos.base'
|
||||||
|
import { DataFetchResult } from './DataFetchResult'
|
||||||
|
|
||||||
|
@Sendable
|
||||||
export class LoadLocalFileClient implements IDataFetch {
|
export class LoadLocalFileClient implements IDataFetch {
|
||||||
loadData(request: RequestOption, onComplete: (img: ArrayBuffer) => void, onError: (err: string) => void) {
|
loadData(request: RequestOption) {
|
||||||
|
let result:DataFetchResult =new DataFetchResult()
|
||||||
if (typeof request.loadSrc == 'string') {
|
if (typeof request.loadSrc == 'string') {
|
||||||
FileUtils.getInstance().readFilePicAsync(request.loadSrc).then(fileBuffer=>{
|
FileUtils.getInstance().readFilePicAsync(request.loadSrc).then(fileBuffer=>{
|
||||||
if (fileBuffer == null || fileBuffer.byteLength <= 0) {
|
if (fileBuffer == null || fileBuffer.byteLength <= 0) {
|
||||||
onError('LoadLocalFileClient loadLocalFileData The File Does Not Exist!Check The File!')
|
result.error = 'LoadLocalFileClient loadLocalFileData The File Does Not Exist!Check The File!';
|
||||||
} else {
|
} else {
|
||||||
onComplete(fileBuffer);
|
result.data = fileBuffer
|
||||||
}
|
}
|
||||||
}).catch((err:BusinessError)=>{
|
}).catch((err:BusinessError)=>{
|
||||||
onError('LoadLocalFileClient loadLocalFileData Error Msg ='+err?.message)
|
result.error ='LoadLocalFileClient loadLocalFileData Error Msg ='+err?.message;
|
||||||
})
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -19,12 +19,16 @@ import { SparkMD5 } from '../../3rd_party/sparkmd5/spark-md5'
|
||||||
import { FileUtils } from '../../cache/FileUtils'
|
import { FileUtils } from '../../cache/FileUtils'
|
||||||
import loadRequest from '@ohos.request';
|
import loadRequest from '@ohos.request';
|
||||||
import { LogUtil } from '../utils/LogUtil'
|
import { LogUtil } from '../utils/LogUtil'
|
||||||
import { ImageKnifeGlobal } from '../ImageKnifeGlobal'
|
|
||||||
import common from '@ohos.app.ability.common'
|
import common from '@ohos.app.ability.common'
|
||||||
import { BusinessError } from '@ohos.base'
|
import { BusinessError } from '@ohos.base'
|
||||||
|
import { DataFetchResult } from './DataFetchResult'
|
||||||
|
|
||||||
// 数据加载器
|
// 数据加载器
|
||||||
|
|
||||||
|
@Sendable
|
||||||
export class NetworkDownloadClient implements IDataFetch {
|
export class NetworkDownloadClient implements IDataFetch {
|
||||||
loadData(request: RequestOption, onComplete: (img: ArrayBuffer) => void, onError: (err: string) => void) {
|
loadData(request: RequestOption) {
|
||||||
|
let result:DataFetchResult = new DataFetchResult()
|
||||||
let filename:string = SparkMD5.hashBinary(request.generateDataKey);
|
let filename:string = SparkMD5.hashBinary(request.generateDataKey);
|
||||||
let downloadFolder = request.getFilesPath() + "/" + request.networkCacheFolder;
|
let downloadFolder = request.getFilesPath() + "/" + request.networkCacheFolder;
|
||||||
let allpath = request.getFilesPath() + "/" + request.networkCacheFolder + "/" + filename + ".img";
|
let allpath = request.getFilesPath() + "/" + request.networkCacheFolder + "/" + filename + ".img";
|
||||||
|
@ -61,14 +65,14 @@ export class NetworkDownloadClient implements IDataFetch {
|
||||||
let downloadPath = allpath;
|
let downloadPath = allpath;
|
||||||
request.downloadFilePath = downloadPath;
|
request.downloadFilePath = downloadPath;
|
||||||
FileUtils.getInstance().readFilePicAsync(downloadPath).then(arraybuffer=>{
|
FileUtils.getInstance().readFilePicAsync(downloadPath).then(arraybuffer=>{
|
||||||
onComplete(arraybuffer);
|
result.data=arraybuffer;
|
||||||
FileUtils.getInstance().deleteFileAsync(downloadPath).then(()=>{
|
FileUtils.getInstance().deleteFileAsync(downloadPath).then(()=>{
|
||||||
LogUtil.log('文件名:'+downloadPath+" 文件删除成功!")
|
LogUtil.log('文件名:'+downloadPath+" 文件删除成功!")
|
||||||
}).catch((err:BusinessError)=>{
|
}).catch((err:BusinessError)=>{
|
||||||
LogUtil.log('文件名:'+downloadPath+" 文件删除失败!")
|
LogUtil.log('文件名:'+downloadPath+" 文件删除失败!")
|
||||||
});
|
});
|
||||||
}).catch((err:BusinessError)=>{
|
}).catch((err:BusinessError)=>{
|
||||||
onError('NetworkDownloadClient Read File Async Error Msg='+ (err as BusinessError)?.message)
|
result.error='NetworkDownloadClient Read File Async Error Msg='+ (err as BusinessError)?.message;
|
||||||
})
|
})
|
||||||
|
|
||||||
if(loadTask != null) {
|
if(loadTask != null) {
|
||||||
|
@ -86,7 +90,7 @@ export class NetworkDownloadClient implements IDataFetch {
|
||||||
loadTask.on('remove', () => {})
|
loadTask.on('remove', () => {})
|
||||||
|
|
||||||
loadTask.on('fail', (err) => {
|
loadTask.on('fail', (err) => {
|
||||||
onError('NetworkDownloadClient Download task fail err =' + err)
|
result.error='NetworkDownloadClient Download task fail err =' + err;
|
||||||
if (loadTask!=null) {
|
if (loadTask!=null) {
|
||||||
loadTask.delete().then(result => {
|
loadTask.delete().then(result => {
|
||||||
if(loadTask != undefined) {
|
if(loadTask != undefined) {
|
||||||
|
@ -104,11 +108,11 @@ export class NetworkDownloadClient implements IDataFetch {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
onError('NetworkDownloadClient downloadTask dismiss!')
|
result.error='NetworkDownloadClient downloadTask dismiss!'
|
||||||
}
|
}
|
||||||
})
|
}).catch((err:BusinessError)=> {
|
||||||
.catch((err:BusinessError)=> {
|
result.error="下载子系统download错误捕获,error=" + err.message;
|
||||||
onError("下载子系统download错误捕获,error=" + err.message);
|
|
||||||
})
|
})
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2021 Huawei Device Co., Ltd.
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
// 数据加载器
|
||||||
|
@Sendable
|
||||||
|
export class RequestData {
|
||||||
|
receiveSize: number = 2000
|
||||||
|
totalSize: number = 2000
|
||||||
|
}
|
|
@ -16,3 +16,8 @@
|
||||||
export interface PngCallback<R,T>{
|
export interface PngCallback<R,T>{
|
||||||
pngCallback: (sender:R, receover:T)=>void
|
pngCallback: (sender:R, receover:T)=>void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface WorkerType {
|
||||||
|
type: string
|
||||||
|
name: string
|
||||||
|
}
|
|
@ -0,0 +1,123 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2021 Huawei Device Co., Ltd.
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
import { UPNG } from '../../3rd_party/upng/UPNG';
|
||||||
|
import { PngCallback, WorkerType } from './PngCallback';
|
||||||
|
import image from '@ohos.multimedia.image';
|
||||||
|
import taskpool from '@ohos.taskpool';
|
||||||
|
import { BusinessError } from '@ohos.base'
|
||||||
|
|
||||||
|
export class Pngj {
|
||||||
|
readPngImageInfo(arraybuffer: ArrayBuffer, callback: PngCallback<ArrayBuffer, image.ImageInfo>) {
|
||||||
|
let imageSource: image.ImageSource = image.createImageSource(arraybuffer);
|
||||||
|
if (imageSource != undefined) {
|
||||||
|
imageSource.getImageInfo((err: BusinessError, value: image.ImageInfo) => {
|
||||||
|
if (err) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
callback.pngCallback(arraybuffer, value);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param pngBuffer ArrayBuffer containing the PNG file
|
||||||
|
* @param callback
|
||||||
|
* returns an image object with following properties:
|
||||||
|
* width: the width of the image
|
||||||
|
* height: the height of the image
|
||||||
|
* depth: number of bits per channel
|
||||||
|
* ctype: color type of the file (Truecolor, Grayscale, Palette ...)
|
||||||
|
* frames: additional info about frames (frame delays etc.)
|
||||||
|
* tabs: additional chunks of the PNG file
|
||||||
|
* data: pixel data of the image
|
||||||
|
*/
|
||||||
|
readPngImage(pngBuffer: ArrayBuffer, callback: PngCallback<ArrayBuffer, Object>) {
|
||||||
|
let png = UPNG.decode(pngBuffer);
|
||||||
|
callback.pngCallback(pngBuffer, png)
|
||||||
|
}
|
||||||
|
|
||||||
|
writePngWithString(addInfo: string, pngBuffer: ArrayBuffer, callback: PngCallback<ArrayBuffer, ArrayBufferLike>) {
|
||||||
|
let pngDecode = UPNG.decode(pngBuffer);
|
||||||
|
let newPng = UPNG.encodeWithString(addInfo, UPNG.toRGBA8(pngDecode), pngDecode.width, pngDecode.height, 0)
|
||||||
|
callback.pngCallback(pngBuffer, newPng);
|
||||||
|
}
|
||||||
|
|
||||||
|
writePng(pngBuffer: ArrayBuffer, callback: PngCallback<ArrayBuffer, ArrayBufferLike>) {
|
||||||
|
let pngDecode = UPNG.decode(pngBuffer);
|
||||||
|
let newPng = UPNG.encode(UPNG.toRGBA8(pngDecode), pngDecode.width, pngDecode.height, 0)
|
||||||
|
callback.pngCallback(pngBuffer, newPng);
|
||||||
|
}
|
||||||
|
|
||||||
|
async readPngImageAsync(e: WorkerType, source: ArrayBuffer, pngCallback: (value: ESObject) => void) {
|
||||||
|
let task = new taskpool.Task(taskPngImage, e, source)
|
||||||
|
let val1: ESObject = await taskpool.execute(task)
|
||||||
|
pngCallback(val1)
|
||||||
|
try {
|
||||||
|
taskpool.cancel(task)
|
||||||
|
} catch (e) {
|
||||||
|
console.error("taskpool.cancel occur error:" + e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async writePngWithStringAsync(e: WorkerType, source: ArrayBuffer, pngCallback: (value: ESObject) => void, info: string) {
|
||||||
|
let task = new taskpool.Task(taskPngImage, e, source, info)
|
||||||
|
let val1: ESObject = await taskpool.execute(task)
|
||||||
|
pngCallback(val1)
|
||||||
|
try {
|
||||||
|
taskpool.cancel(task)
|
||||||
|
} catch (e) {
|
||||||
|
console.error("taskpool.cancel occur error:" + e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async writePngAsync(e: WorkerType, source: ArrayBuffer, pngCallback: (value: ESObject) => void) {
|
||||||
|
let task = new taskpool.Task(taskPngImage, e, source)
|
||||||
|
let val1: ESObject = await taskpool.execute(task)
|
||||||
|
pngCallback(val1)
|
||||||
|
try {
|
||||||
|
taskpool.cancel(task)
|
||||||
|
} catch (e) {
|
||||||
|
console.error("taskpool.cancel occur error:" + e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Concurrent
|
||||||
|
function taskPngImage(e: WorkerType, pngSource: ArrayBuffer, info?: string): Object | ArrayBufferLike | void {
|
||||||
|
let a: Object | ArrayBufferLike | undefined = undefined
|
||||||
|
let png = UPNG.decode(pngSource)
|
||||||
|
switch (e.name) {
|
||||||
|
case 'readPngImageAsync':
|
||||||
|
let array: Uint8Array = png.data;
|
||||||
|
let arrayData = array.buffer.slice(array.byteOffset, array.byteLength + array.byteOffset)
|
||||||
|
png.data = arrayData;
|
||||||
|
a = png
|
||||||
|
break;
|
||||||
|
case 'writePngWithStringAsync':
|
||||||
|
let addInfo: string | undefined = info;
|
||||||
|
let newPng = UPNG.encodeWithString(addInfo, UPNG.toRGBA8(png), png.width, png.height, 0)
|
||||||
|
a = newPng
|
||||||
|
break;
|
||||||
|
case 'writePngAsync':
|
||||||
|
let newPng3 = UPNG.encode(UPNG.toRGBA8(png), png.width, png.height, 0)
|
||||||
|
a = newPng3
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if(a != undefined) { return a }
|
||||||
|
}
|
|
@ -1,178 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2021 Huawei Device Co., Ltd.
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
import {UPNG} from '../../3rd_party/upng/UPNG';
|
|
||||||
import {PngCallback} from './PngCallback';
|
|
||||||
import image from '@ohos.multimedia.image';
|
|
||||||
import resourceManager from '@ohos.resourceManager';
|
|
||||||
import ArkWorker from '@ohos.worker'
|
|
||||||
import { BusinessError } from '@ohos.base'
|
|
||||||
export class Pngj {
|
|
||||||
readPngImageInfo(arraybuffer: ArrayBuffer, callback:PngCallback<ArrayBuffer, image.ImageInfo>) {
|
|
||||||
let imageSource:image.ImageSource = image.createImageSource(arraybuffer);
|
|
||||||
if (imageSource != undefined){
|
|
||||||
imageSource.getImageInfo((err:BusinessError, value:image.ImageInfo) => {
|
|
||||||
if (err) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
callback.pngCallback(arraybuffer, value);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param pngBuffer ArrayBuffer containing the PNG file
|
|
||||||
* @param callback
|
|
||||||
* returns an image object with following properties:
|
|
||||||
* width: the width of the image
|
|
||||||
* height: the height of the image
|
|
||||||
* depth: number of bits per channel
|
|
||||||
* ctype: color type of the file (Truecolor, Grayscale, Palette ...)
|
|
||||||
* frames: additional info about frames (frame delays etc.)
|
|
||||||
* tabs: additional chunks of the PNG file
|
|
||||||
* data: pixel data of the image
|
|
||||||
*/
|
|
||||||
readPngImage(pngBuffer: ArrayBuffer, callback:PngCallback<ArrayBuffer, any>) {
|
|
||||||
var png = UPNG.decode(pngBuffer);
|
|
||||||
callback.pngCallback(pngBuffer, png)
|
|
||||||
}
|
|
||||||
|
|
||||||
writePngWithString(addInfo:string, pngBuffer: ArrayBuffer,callback:PngCallback<ArrayBuffer, any>) {
|
|
||||||
var pngDecode = UPNG.decode(pngBuffer);
|
|
||||||
var newPng = UPNG.encodeWithString(addInfo, UPNG.toRGBA8(pngDecode), pngDecode.width, pngDecode.height, 0)
|
|
||||||
callback.pngCallback(pngBuffer, newPng);
|
|
||||||
}
|
|
||||||
|
|
||||||
writePng(pngBuffer: ArrayBuffer,callback:PngCallback<ArrayBuffer, any>) {
|
|
||||||
var pngDecode = UPNG.decode(pngBuffer);
|
|
||||||
var newPng = UPNG.encode(UPNG.toRGBA8(pngDecode), pngDecode.width, pngDecode.height, 0)
|
|
||||||
callback.pngCallback(pngBuffer, newPng);
|
|
||||||
}
|
|
||||||
|
|
||||||
readPngImageAsync(worker: any, pngBuffer: ArrayBuffer, callback: PngCallback<ArrayBuffer, any>) {
|
|
||||||
// worker.onerror = function (data) {
|
|
||||||
//
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// worker.onmessageerror = function (e) {
|
|
||||||
//
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// worker.onexit = function () {
|
|
||||||
//
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// worker.onmessage = function(e) {
|
|
||||||
// var data = e.data;
|
|
||||||
// switch (data.type) {
|
|
||||||
// case 'readPngImageAsync':
|
|
||||||
// callback.pngCallback(data.receiver, data.data)
|
|
||||||
// break;
|
|
||||||
// default:
|
|
||||||
// break
|
|
||||||
// }
|
|
||||||
// worker.terminate();
|
|
||||||
// }
|
|
||||||
// var obj = { type: 'readPngImageAsync', data: pngBuffer }
|
|
||||||
// worker.postMessage(obj, [pngBuffer])
|
|
||||||
let task = new taskpool.Task(taskParseImage, arrayBuffer, scale)
|
|
||||||
task.setTransferList([])
|
|
||||||
taskpool.execute(task).then((pixelmap: Object) => {
|
|
||||||
LogUtil.log('ceshi321 : Succeeded in creating pixelmap Ui .' + (pixelmap as image.PixelMap).getPixelBytesNumber())
|
|
||||||
onCompleteFunction(pixelmap as image.PixelMap);
|
|
||||||
}).catch((err: string) => {
|
|
||||||
LogUtil.log("ceshi321 : test occur error: " + err)
|
|
||||||
onErrorFunction(err);
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
writePngWithStringAsync(worker: any, addInfo: string, pngBuffer: ArrayBuffer, callback: PngCallback<ArrayBuffer, any>) {
|
|
||||||
worker.onerror = function (data) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
worker.onmessageerror = function (e) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
worker.onexit = function () {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
worker.onmessage = function(e) {
|
|
||||||
var data = e.data;
|
|
||||||
switch (data.type) {
|
|
||||||
case 'writePngWithStringAsync':
|
|
||||||
callback.pngCallback(data.receiver, data.data)
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break
|
|
||||||
}
|
|
||||||
worker.terminate();
|
|
||||||
}
|
|
||||||
|
|
||||||
var obj = { type: 'writePngWithStringAsync', data:pngBuffer, info: addInfo}
|
|
||||||
worker.postMessage(obj, [pngBuffer])
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
writePngAsync(worker: any, pngBuffer: ArrayBuffer, callback: PngCallback<ArrayBuffer, any>) {
|
|
||||||
worker.onerror = function (data) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
worker.onmessageerror = function (e) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
worker.onexit = function () {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
worker.onmessage = function(e) {
|
|
||||||
var data = e.data;
|
|
||||||
switch (data.type) {
|
|
||||||
case 'writePngAsync':
|
|
||||||
callback.pngCallback(data.receiver, data.data)
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break
|
|
||||||
}
|
|
||||||
worker.terminate();
|
|
||||||
}
|
|
||||||
|
|
||||||
var obj = { type: 'writePngAsync', data:pngBuffer}
|
|
||||||
worker.postMessage(obj, [pngBuffer])
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -14,7 +14,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { ICache } from "../requestmanage/ICache"
|
import { ICache } from "../requestmanage/ICache"
|
||||||
import { DiskLruCache } from "@ohos/disklrucache"
|
import { DiskLruCache } from "../../cache/DiskLruCache"
|
||||||
|
|
||||||
export class DiskCacheProxy implements ICache<string, ArrayBuffer> {
|
export class DiskCacheProxy implements ICache<string, ArrayBuffer> {
|
||||||
private mDiskLruCache: DiskLruCache;
|
private mDiskLruCache: DiskLruCache;
|
||||||
|
@ -29,7 +29,7 @@ export class DiskCacheProxy implements ICache<string, ArrayBuffer> {
|
||||||
}
|
}
|
||||||
|
|
||||||
getCachePath():string{
|
getCachePath():string{
|
||||||
let folderPath = this.mDiskLruCache.getPath();
|
let folderPath:string = this.mDiskLruCache.getPath();
|
||||||
if (folderPath.endsWith('/')) {
|
if (folderPath.endsWith('/')) {
|
||||||
return folderPath;
|
return folderPath;
|
||||||
} else {
|
} else {
|
||||||
|
@ -38,7 +38,7 @@ export class DiskCacheProxy implements ICache<string, ArrayBuffer> {
|
||||||
}
|
}
|
||||||
|
|
||||||
getValue(key: string): ArrayBuffer{
|
getValue(key: string): ArrayBuffer{
|
||||||
return this.mDiskLruCache.get(key);
|
return this.mDiskLruCache.get(key) as ArrayBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
putValue(key: string, value: ArrayBuffer) {
|
putValue(key: string, value: ArrayBuffer) {
|
||||||
|
|
|
@ -13,25 +13,26 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { RequestOption,Size } from '../../imageknife/RequestOption'
|
import { RequestOption, Size } from '../../imageknife/RequestOption'
|
||||||
import { DiskLruCache } from '@ohos/disklrucache'
|
import { DiskLruCache } from "../../cache/DiskLruCache"
|
||||||
import { LruCache } from '../../cache/LruCache'
|
import { LruCache } from '../../cache/LruCache'
|
||||||
import { SparkMD5 } from '../../3rd_party/sparkmd5/spark-md5'
|
import { SparkMD5 } from '../../3rd_party/sparkmd5/spark-md5'
|
||||||
import { MemoryCacheProxy } from '../requestmanage/MemoryCacheProxy'
|
import { MemoryCacheProxy } from '../requestmanage/MemoryCacheProxy'
|
||||||
import { DiskCacheProxy } from '../requestmanage/DiskCacheProxy'
|
import { DiskCacheProxy } from '../requestmanage/DiskCacheProxy'
|
||||||
import { FileTypeUtil } from '../utils/FileTypeUtil'
|
import { FileTypeUtil } from '../utils/FileTypeUtil'
|
||||||
import { IDataFetch } from '../../imageknife/networkmanage/IDataFetch'
|
import { IDataFetch } from '../../imageknife/networkmanage/IDataFetch'
|
||||||
import { IResourceFetch } from '../../imageknife/resourcemanage/IResourceFetch'
|
import { IResourceFetch } from '../../imageknife/resourcemanage/IResourceFetch'
|
||||||
import { ImageKnifeData, ImageKnifeType } from '../ImageKnifeData'
|
import { ImageKnifeData, ImageKnifeType } from '../ImageKnifeData'
|
||||||
import { AllCacheInfo } from '../../imageknife/interface/IAllCacheInfoCallback'
|
import { AllCacheInfo } from '../../imageknife/interface/IAllCacheInfoCallback'
|
||||||
import { ParseImageUtil } from '../utils/ParseImageUtil'
|
import { ParseImageUtil } from '../utils/ParseImageUtil'
|
||||||
import { IParseImage } from '../interface/IParseImage'
|
import { IParseImage } from '../interface/IParseImage'
|
||||||
import image from '@ohos.multimedia.image'
|
import image from '@ohos.multimedia.image'
|
||||||
import { SVGParseImpl } from '../utils/svg/SVGParseImpl'
|
import { SVGParseImpl } from '../utils/svg/SVGParseImpl'
|
||||||
import { GIFParseImpl } from '../utils/gif/GIFParseImpl'
|
import { GIFParseImpl } from '../utils/gif/GIFParseImpl'
|
||||||
import { GIFFrame } from '../utils/gif/GIFFrame'
|
import { GIFFrame } from '../utils/gif/GIFFrame'
|
||||||
import { LogUtil } from '../../imageknife/utils/LogUtil'
|
import { LogUtil } from '../../imageknife/utils/LogUtil'
|
||||||
import { BusinessError } from '@ohos.base'
|
import { BusinessError } from '@ohos.base'
|
||||||
|
import { DataFetchResult } from '../networkmanage/DataFetchResult'
|
||||||
|
|
||||||
|
|
||||||
export enum Stage {
|
export enum Stage {
|
||||||
|
@ -62,19 +63,15 @@ export enum RunReason {
|
||||||
export class RequestManager {
|
export class RequestManager {
|
||||||
private TAG: string = "RequestManager";
|
private TAG: string = "RequestManager";
|
||||||
private options: RequestOption;
|
private options: RequestOption;
|
||||||
private mMemoryCacheProxy: MemoryCacheProxy<string, ImageKnifeData>;
|
|
||||||
private mDiskCacheProxy: DiskCacheProxy;
|
|
||||||
private mIDataFetch: IDataFetch;
|
private mIDataFetch: IDataFetch;
|
||||||
private mIResourceFetch: IResourceFetch<ArrayBuffer>;
|
private mIResourceFetch: IResourceFetch<ArrayBuffer>;
|
||||||
private mParseImageUtil: IParseImage<PixelMap>;
|
private mParseImageUtil: IParseImage<PixelMap>;
|
||||||
|
private diskMemoryCache: DiskLruCache;
|
||||||
|
|
||||||
constructor(option: RequestOption, memoryCache1: LruCache<string, ImageKnifeData>, diskMemoryCache1: DiskLruCache, dataFetch: IDataFetch, resourceFetch: IResourceFetch<ArrayBuffer>) {
|
constructor(option: RequestOption,diskMemoryCache: DiskLruCache, dataFetch: IDataFetch, resourceFetch: IResourceFetch<ArrayBuffer>) {
|
||||||
this.options = option;
|
this.options = option;
|
||||||
|
|
||||||
// 缓存部分
|
this.diskMemoryCache = diskMemoryCache;
|
||||||
this.mMemoryCacheProxy = new MemoryCacheProxy(memoryCache1);
|
|
||||||
this.mDiskCacheProxy = new DiskCacheProxy(diskMemoryCache1);
|
|
||||||
|
|
||||||
// 网络下载能力
|
// 网络下载能力
|
||||||
this.mIDataFetch = dataFetch;
|
this.mIDataFetch = dataFetch;
|
||||||
|
|
||||||
|
@ -85,63 +82,16 @@ export class RequestManager {
|
||||||
this.mParseImageUtil = new ParseImageUtil();
|
this.mParseImageUtil = new ParseImageUtil();
|
||||||
}
|
}
|
||||||
|
|
||||||
static execute(option: RequestOption, memoryCache1: LruCache<string, ImageKnifeData>, diskMemoryCache1: DiskLruCache, dataFetch: IDataFetch, resourceFetch: IResourceFetch<ArrayBuffer>) {
|
|
||||||
LogUtil.log("RequestManager execute")
|
|
||||||
let manager = new RequestManager(option, memoryCache1, diskMemoryCache1, dataFetch, resourceFetch);
|
|
||||||
return new Promise<ImageKnifeData>(manager.process)
|
|
||||||
.then(option.loadComplete)
|
|
||||||
.then(manager.loadCompleteAfter)
|
|
||||||
.catch(option.loadError);
|
|
||||||
}
|
|
||||||
|
|
||||||
loadCompleteAfter =()=>{
|
|
||||||
try { // 内部消化问题
|
|
||||||
LogUtil.log("loadCompleteAfter!")
|
|
||||||
if (this.options.allCacheInfoCallback) {
|
|
||||||
LogUtil.log("RequestOption =" + JSON.stringify(this.options));
|
|
||||||
|
|
||||||
// 内存缓存
|
|
||||||
let allCacheInfo:AllCacheInfo = {
|
|
||||||
memoryCacheInfo:{key:'', data:new ImageKnifeData()},
|
|
||||||
resourceCacheInfo:{key:'', path:''},
|
|
||||||
dataCacheInfo:{key:'',path:''}
|
|
||||||
};
|
|
||||||
let memoryCache = this.mMemoryCacheProxy.getValue(this.options.generateCacheKey);
|
|
||||||
allCacheInfo.memoryCacheInfo = {
|
|
||||||
key: this.options.generateCacheKey,
|
|
||||||
data: memoryCache
|
|
||||||
}
|
|
||||||
|
|
||||||
// 变换后缓存
|
|
||||||
allCacheInfo.resourceCacheInfo = {
|
|
||||||
key: SparkMD5.hashBinary(this.options.generateResourceKey) as string,
|
|
||||||
path: (this.mDiskCacheProxy.getCachePath() + SparkMD5.hashBinary(this.options.generateResourceKey)) as string
|
|
||||||
};
|
|
||||||
|
|
||||||
// 原图缓存
|
|
||||||
allCacheInfo.dataCacheInfo = {
|
|
||||||
key: SparkMD5.hashBinary(this.options.generateDataKey) as string,
|
|
||||||
path: (this.mDiskCacheProxy.getCachePath() + SparkMD5.hashBinary(this.options.generateDataKey)) as string
|
|
||||||
}
|
|
||||||
this.options.allCacheInfoCallback.callback(allCacheInfo)
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
LogUtil.log("after err =" + err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// DecodeJob work
|
// DecodeJob work
|
||||||
private mStage: Stage = Stage.INITIALIZE;
|
private mStage: Stage = Stage.INITIALIZE;
|
||||||
private mRunReason: RunReason = RunReason.INITIALIZE;
|
private mRunReason: RunReason = RunReason.INITIALIZE;
|
||||||
|
process = (onComplete: (value: PixelMap | GIFFrame[]) => void | PromiseLike<ImageKnifeData>, onError: (reason?: BusinessError | string) => void) => {
|
||||||
process = (onComplete:(value:ImageKnifeData)=>void|PromiseLike<ImageKnifeData>, onError:(reason?:BusinessError|string)=>void)=>{
|
LogUtil.log("ImageKnife RequestManager process !");
|
||||||
LogUtil.log("RequestManager process !");
|
|
||||||
this.loadLeve1MemoryCache(onComplete, onError)
|
this.loadLeve1MemoryCache(onComplete, onError)
|
||||||
}
|
}
|
||||||
|
|
||||||
private runWrapped(request: RequestOption, runReason: RunReason, onComplete:(value:ImageKnifeData)=>void|PromiseLike<ImageKnifeData>, onError:(reason?:BusinessError|string)=>void) {
|
private runWrapped(request: RequestOption, runReason: RunReason, onComplete: (value: PixelMap | GIFFrame[]) => void | PromiseLike<ImageKnifeData>, onError: (reason?: BusinessError | string) => void) {
|
||||||
LogUtil.log("RequestManager runWrapped")
|
LogUtil.log("ImageKnife RequestManager runWrapped")
|
||||||
if (runReason == RunReason.INITIALIZE) {
|
if (runReason == RunReason.INITIALIZE) {
|
||||||
this.mStage = this.getNextStage(request, this.mStage);
|
this.mStage = this.getNextStage(request, this.mStage);
|
||||||
this.searchLoadFrom(this.options, this.mStage, onComplete, onError);
|
this.searchLoadFrom(this.options, this.mStage, onComplete, onError);
|
||||||
|
@ -150,7 +100,7 @@ export class RequestManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private getNextStage(request: RequestOption, current: Stage): Stage{
|
private getNextStage(request: RequestOption, current: Stage): Stage {
|
||||||
if (current == Stage.INITIALIZE) {
|
if (current == Stage.INITIALIZE) {
|
||||||
return request.strategy.decodeCachedResource()
|
return request.strategy.decodeCachedResource()
|
||||||
? Stage.RESOURCE_CACHE
|
? Stage.RESOURCE_CACHE
|
||||||
|
@ -166,13 +116,13 @@ export class RequestManager {
|
||||||
} else if (current == Stage.FINISHED) {
|
} else if (current == Stage.FINISHED) {
|
||||||
return Stage.FINISHED;
|
return Stage.FINISHED;
|
||||||
} else {
|
} else {
|
||||||
throw new Error("Unrecognized stage: " + current);
|
throw new Error("ImageKnife Unrecognized stage: " + current);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 究竟从哪里加载数据
|
// 究竟从哪里加载数据
|
||||||
private searchLoadFrom(request: RequestOption, current: Stage, onComplete:(value:ImageKnifeData)=>void|PromiseLike<ImageKnifeData>, onError:(reason?:BusinessError|string)=>void) {
|
private searchLoadFrom(request: RequestOption, current: Stage, onComplete: (value: PixelMap | GIFFrame[]) => void | PromiseLike<ImageKnifeData>, onError: (reason?: BusinessError | string) => void) {
|
||||||
LogUtil.log("RequestManager searchLoadFrom")
|
LogUtil.log("ImageKnife RequestManager searchLoadFrom")
|
||||||
if (current == Stage.RESOURCE_CACHE) {
|
if (current == Stage.RESOURCE_CACHE) {
|
||||||
this.loadDiskFromTransform(request, onComplete, onError);
|
this.loadDiskFromTransform(request, onComplete, onError);
|
||||||
} else if (current == Stage.DATA_CACHE) {
|
} else if (current == Stage.DATA_CACHE) {
|
||||||
|
@ -187,85 +137,90 @@ export class RequestManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 加载网络资源
|
// 加载网络资源
|
||||||
private loadSourceFromNetwork(request: RequestOption, onComplete:(value:ImageKnifeData)=>void|PromiseLike<ImageKnifeData>, onError:(reason?:BusinessError|string)=>void) {
|
private async loadSourceFromNetwork(request: RequestOption, onComplete: (value: PixelMap | GIFFrame[]) => void | PromiseLike<ImageKnifeData>, onError: (reason?: BusinessError | string) => void) {
|
||||||
let success = (arraybuffer:ArrayBuffer) => {
|
try {
|
||||||
this.downloadSuccess(request,arraybuffer, onComplete, onError)
|
LogUtil.log("ImageKnife RequestManager loadSourceFromNetwork")
|
||||||
|
let result: DataFetchResult = await this.mIDataFetch.loadData(request);
|
||||||
|
if(result.error){
|
||||||
|
onError(result.error)
|
||||||
|
}else{
|
||||||
|
if(result.data){
|
||||||
|
this.downloadSuccess(request, result.data, onComplete, onError)
|
||||||
|
}else{
|
||||||
|
onError("datafetch data is null")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
let error = (errorMsg:string) =>{
|
} catch (e) {
|
||||||
onError(errorMsg)
|
LogUtil.error("ImageKnife RequestManager loadSourceFromNetwork error")
|
||||||
}
|
}
|
||||||
this.mIDataFetch.loadData(request, success, error);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 加载本地资源
|
// 加载本地资源
|
||||||
private loadSourceFormNative(request: RequestOption, onComplete:(value:ImageKnifeData)=>void|PromiseLike<ImageKnifeData>, onError:(reason?:BusinessError|string)=>void) {
|
private loadSourceFormNative(request: RequestOption, onComplete: (value: PixelMap | GIFFrame[]) => void | PromiseLike<ImageKnifeData>, onError: (reason?: BusinessError | string) => void) {
|
||||||
LogUtil.log("RequestManager loadSourceFormNative")
|
LogUtil.log("ImageKnife RequestManager loadSourceFormNative")
|
||||||
// 本地解析后进行一级缓存
|
// 本地解析后进行一级缓存
|
||||||
let success = (arrayBuffer:ArrayBuffer) => {
|
let success = (arrayBuffer: ArrayBuffer) => {
|
||||||
// 使用媒体子系统 ImageSource解析文件 获取PixelMap
|
// 使用媒体子系统 ImageSource解析文件 获取PixelMap
|
||||||
let fileTypeUtil = new FileTypeUtil();
|
let fileTypeUtil = new FileTypeUtil();
|
||||||
let typeValue = fileTypeUtil.getFileType(arrayBuffer)
|
let typeValue = fileTypeUtil.getFileType(arrayBuffer)
|
||||||
LogUtil.log("RequestManager - 文件类型为= " + typeValue)
|
LogUtil.log("ImageKnife RequestManager - 文件类型为= " + typeValue)
|
||||||
// gif处理
|
// gif、webp处理
|
||||||
if(ImageKnifeData.GIF == typeValue && !request.dontAnimateFlag){
|
if ((ImageKnifeData.GIF == typeValue || ImageKnifeData.WEBP == typeValue) && !request.dontAnimateFlag) {
|
||||||
// 处理gif
|
// 处理gif、webp
|
||||||
this.gifProcess(onComplete,onError, arrayBuffer,typeValue,(imageKnifeData)=>{
|
this.gifProcess(onComplete, onError, arrayBuffer, typeValue)
|
||||||
this.mMemoryCacheProxy.putValue(this.options.generateCacheKey, imageKnifeData)
|
} else if (ImageKnifeData.SVG == typeValue) {
|
||||||
})
|
|
||||||
}else if(ImageKnifeData.SVG == typeValue){
|
|
||||||
// 处理svg
|
// 处理svg
|
||||||
this.svgProcess(request,onComplete,onError,arrayBuffer,typeValue,(imageKnifeData)=>{
|
this.svgProcess(request, onComplete, onError, arrayBuffer, typeValue)
|
||||||
this.mMemoryCacheProxy.putValue(this.options.generateCacheKey,imageKnifeData)
|
|
||||||
})
|
|
||||||
} else {
|
} else {
|
||||||
if (request.transformations[0]) {
|
if (request.transformations[0]) {
|
||||||
request.transformations[0].transform(arrayBuffer, request, {asyncTransform:(error:BusinessError|string, pixelMap: PixelMap|null) => {
|
request.transformations[0].transform(arrayBuffer, request, {
|
||||||
// 输出给Image
|
asyncTransform: (error: BusinessError | string, pixelMap: PixelMap | null) => {
|
||||||
if (pixelMap) {
|
// 输出给Image
|
||||||
|
if (pixelMap) {
|
||||||
let imageKnifeData = this.createImagePixelMap(ImageKnifeType.PIXELMAP, pixelMap);
|
onComplete(pixelMap);
|
||||||
this.mMemoryCacheProxy.putValue(request.generateCacheKey, imageKnifeData);
|
} else {
|
||||||
onComplete(imageKnifeData);
|
onError(error);
|
||||||
} else {
|
}
|
||||||
onError(error);
|
|
||||||
}
|
}
|
||||||
}})
|
})
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
let success = (value: PixelMap) => {
|
let success = (value: PixelMap) => {
|
||||||
let imageKnifeData = this.createImagePixelMap(ImageKnifeType.PIXELMAP, value);
|
onComplete(value);
|
||||||
this.mMemoryCacheProxy.putValue(request.generateCacheKey, imageKnifeData);
|
|
||||||
onComplete(imageKnifeData);
|
|
||||||
}
|
}
|
||||||
this.mParseImageUtil.parseImage(arrayBuffer, success, onError)
|
this.mParseImageUtil.parseImage(arrayBuffer, success, onError)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let ctx = request.getModuleContext();
|
let ctx = request.getModuleContext();
|
||||||
if(ctx!=undefined){
|
if (ctx != undefined) {
|
||||||
this.mIResourceFetch.loadResource(ctx,request.loadSrc as Resource, success, onError);
|
this.mIResourceFetch.loadResource(ctx, request.loadSrc as Resource, success, onError);
|
||||||
}else{
|
} else {
|
||||||
onError('RequestManager loadSourceFormNative moduleContext is undefined! please check it')
|
onError('ImageKnife RequestManager loadSourceFormNative moduleContext is undefined! please check it')
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 加载磁盘缓存 原图
|
// 加载磁盘缓存 原图
|
||||||
private loadDiskFromSource(request: RequestOption, onComplete:(value:ImageKnifeData)=>void|PromiseLike<ImageKnifeData>, onError:(reason?:BusinessError|string)=>void) {
|
private loadDiskFromSource(request: RequestOption, onComplete: (value: PixelMap | GIFFrame[]) => void | PromiseLike<ImageKnifeData>, onError: (reason?: BusinessError | string) => void) {
|
||||||
LogUtil.log("RequestManager loadDiskFromSource")
|
LogUtil.log("ImageKnife RequestManager loadDiskFromSource")
|
||||||
let cached = this.mDiskCacheProxy.getValue(request.generateDataKey)
|
let cached = this.diskMemoryCache.get(request.generateDataKey);
|
||||||
if (cached != null && cached.byteLength > 0) {
|
if (cached != null && cached.byteLength > 0) {
|
||||||
|
LogUtil.log("ImageKnife loadDiskFromSource load resource from DiskLruCache")
|
||||||
this.parseDiskFile2PixelMap(request, cached, onComplete, onError)
|
this.parseDiskFile2PixelMap(request, cached, onComplete, onError)
|
||||||
} else {
|
} else {
|
||||||
this.mStage = Stage.SOURCE;
|
this.mStage = Stage.SOURCE;
|
||||||
|
this.mStage = request.onlyRetrieveFromCache? Stage.FINISHED : Stage.SOURCE
|
||||||
this.searchLoadFrom(this.options, this.mStage, onComplete, onError);
|
this.searchLoadFrom(this.options, this.mStage, onComplete, onError);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 加载磁盘缓存 变换后图片
|
// 加载磁盘缓存 变换后图片
|
||||||
private loadDiskFromTransform(request: RequestOption, onComplete:(value:ImageKnifeData)=>void|PromiseLike<ImageKnifeData>, onError:(reason?:BusinessError|string)=>void) {
|
private loadDiskFromTransform(request: RequestOption, onComplete: (value: PixelMap | GIFFrame[]) => void | PromiseLike<ImageKnifeData>, onError: (reason?: BusinessError | string) => void) {
|
||||||
LogUtil.log("RequestManager loadDiskFromTransform")
|
LogUtil.log("ImageKnife RequestManager loadDiskFromTransform")
|
||||||
let cached = this.mDiskCacheProxy.getValue(request.generateResourceKey)
|
let cached = this.diskMemoryCache.get(request.generateResourceKey);
|
||||||
if (cached != null) {
|
if (cached != null) {
|
||||||
|
LogUtil.log("ImageKnife loadDiskFromTransform load resource from DiskLruCache")
|
||||||
this.parseDiskTransformFile2PixelMap(request, cached, onComplete, onError)
|
this.parseDiskTransformFile2PixelMap(request, cached, onComplete, onError)
|
||||||
} else {
|
} else {
|
||||||
this.mStage = Stage.DATA_CACHE;
|
this.mStage = Stage.DATA_CACHE;
|
||||||
|
@ -273,103 +228,95 @@ export class RequestManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
parseSource(request: RequestOption, onComplete:(value:ImageKnifeData)=>void|PromiseLike<ImageKnifeData>, onError:(reason?:BusinessError|string)=>void) {
|
parseSource(request: RequestOption, onComplete: (value: PixelMap | GIFFrame[]) => void | PromiseLike<ImageKnifeData>, onError: (reason?: BusinessError | string) => void) {
|
||||||
LogUtil.log("RequestManager parseSource")
|
LogUtil.log("ImageKnife RequestManager parseSource")
|
||||||
|
try {
|
||||||
if ((typeof (request.loadSrc as image.PixelMap).isEditable) == 'boolean') {
|
if ((typeof (request.loadSrc as image.PixelMap).isEditable) == 'boolean') {
|
||||||
// PixelMap 外层捕获效率更高,不会进入这里
|
// PixelMap 外层捕获效率更高,不会进入这里
|
||||||
} else if (typeof request.loadSrc == 'string') {
|
} else if (typeof request.loadSrc == 'string') {
|
||||||
this.loadSourceFromNetwork(request, onComplete, onError);
|
this.loadSourceFromNetwork(request, onComplete, onError);
|
||||||
} else {
|
} else {
|
||||||
let res = request.loadSrc as Resource;
|
let res = request.loadSrc as Resource;
|
||||||
if (typeof res.id != 'undefined' && typeof res.id != 'undefined') {
|
if (typeof res.id != 'undefined') {
|
||||||
this.loadSourceFormNative(request, onComplete, onError)
|
this.loadSourceFormNative(request, onComplete, onError)
|
||||||
} else {
|
} else {
|
||||||
LogUtil.log("输入参数有问题!")
|
LogUtil.log("输入参数有问题!")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} catch (e) {
|
||||||
|
LogUtil.error("ImageKnife RequestManager parseSource error")
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private loadLeve1MemoryCache(onComplete:(value:ImageKnifeData)=>void|PromiseLike<ImageKnifeData>, onError:(reason?:BusinessError|string)=>void) {
|
private loadLeve1MemoryCache(onComplete: (value: PixelMap | GIFFrame[]) => void | PromiseLike<ImageKnifeData>, onError: (reason?: BusinessError | string) => void) {
|
||||||
LogUtil.log("RequestManager loadLeve1MemoryCache")
|
try {
|
||||||
// 一级缓存 内存获取
|
|
||||||
let cache = this.mMemoryCacheProxy.loadMemoryCache(this.options.generateCacheKey, this.options.isCacheable);
|
|
||||||
if (cache == null || typeof cache == 'undefined') {
|
|
||||||
// 处理磁盘加载 网络加载
|
|
||||||
this.runWrapped(this.options, this.mRunReason, onComplete, onError)
|
this.runWrapped(this.options, this.mRunReason, onComplete, onError)
|
||||||
} else {
|
} catch (e) {
|
||||||
// 需要清理状态
|
LogUtil.error("ImageKnife loadLeve1MemoryCache error")
|
||||||
cache.waitSaveDisk = false;
|
|
||||||
onComplete(cache);
|
|
||||||
return
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 解析磁盘文件变成PixeMap
|
// 解析磁盘文件变成PixeMap
|
||||||
private parseDiskFile2PixelMap(request: RequestOption, source: ArrayBuffer, onComplete:(value:ImageKnifeData)=>void|PromiseLike<ImageKnifeData>, onError:(reason?:BusinessError|string)=>void) {
|
private parseDiskFile2PixelMap(request: RequestOption, source: ArrayBuffer, onComplete: (value: PixelMap | GIFFrame[]) => void | PromiseLike<ImageKnifeData>, onError: (reason?: BusinessError | string) => void) {
|
||||||
|
LogUtil.log("ImageKnife RequestManager parseDiskFile2PixelMap")
|
||||||
// 步骤一:文件转为pixelMap 然后变换 给Image组件
|
// 步骤一:文件转为pixelMap 然后变换 给Image组件
|
||||||
let fileTypeUtil = new FileTypeUtil();
|
let fileTypeUtil = new FileTypeUtil();
|
||||||
let typeValue = fileTypeUtil.getFileType(source);
|
let typeValue = fileTypeUtil.getFileType(source);
|
||||||
// 解析磁盘文件 gif 和 svg
|
// 解析磁盘文件 gif、webp 和 svg
|
||||||
if(ImageKnifeData.GIF == typeValue && !request.dontAnimateFlag){
|
if ((ImageKnifeData.GIF == typeValue || ImageKnifeData.WEBP == typeValue) && !request.dontAnimateFlag) {
|
||||||
// 处理gif
|
// 处理gif、webp
|
||||||
this.gifProcess(onComplete,onError,source,typeValue, (imageKnifeData)=>{
|
this.gifProcess(onComplete, onError, source, typeValue)
|
||||||
this.mMemoryCacheProxy.putValue(this.options.generateCacheKey, imageKnifeData)
|
} else if (ImageKnifeData.SVG == typeValue) {
|
||||||
})
|
this.svgProcess(request, onComplete, onError, source, typeValue)
|
||||||
}else if(ImageKnifeData.SVG == typeValue){
|
|
||||||
this.svgProcess(request,onComplete,onError, source, typeValue, (imageKnifeData)=>{
|
|
||||||
this.mMemoryCacheProxy.putValue(this.options.generateCacheKey, imageKnifeData)
|
|
||||||
})
|
|
||||||
} else {
|
} else {
|
||||||
if (this.options.transformations[0]) {
|
if (this.options.transformations[0]) {
|
||||||
if (this.options.thumbSizeMultiplier) {
|
if (this.options.thumbSizeMultiplier) {
|
||||||
let thumbOption:RequestOption = new RequestOption();
|
let thumbOption: RequestOption = new RequestOption();
|
||||||
thumbOption.setImageViewSize({
|
thumbOption.setImageViewSize({
|
||||||
width: Math.round(this.options.thumbSizeMultiplier * this.options.size.width),
|
width: Math.round(this.options.thumbSizeMultiplier * this.options.size.width),
|
||||||
height: Math.round(this.options.thumbSizeMultiplier * this.options.size.height)
|
height: Math.round(this.options.thumbSizeMultiplier * this.options.size.height)
|
||||||
})
|
})
|
||||||
let ctx = this.options.getModuleContext()
|
let ctx = this.options.getModuleContext()
|
||||||
if(ctx != undefined){
|
if (ctx != undefined) {
|
||||||
thumbOption.setModuleContext(ctx)
|
thumbOption.setModuleContext(ctx)
|
||||||
}else{
|
} else {
|
||||||
onError('RequestManager parseDiskFile2PixelMap moduleContext is undefined, please check it!')
|
onError('RequestManager parseDiskFile2PixelMap moduleContext is undefined, please check it!')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
let thumbCallback = this.options.thumbholderOnComplete;
|
let thumbCallback = this.options.thumbholderOnComplete;
|
||||||
let thumbError = this.options.thumbholderOnError;
|
let thumbError = this.options.thumbholderOnError;
|
||||||
this.options.transformations[0].transform(source, thumbOption,{asyncTransform: (error:BusinessError|string, pixelMap: PixelMap|null) => {
|
this.options.transformations[0].transform(source, thumbOption, {
|
||||||
if (pixelMap) {
|
asyncTransform: (error: BusinessError | string, pixelMap: PixelMap | null) => {
|
||||||
let imageKnifeData = this.createImagePixelMap(ImageKnifeType.PIXELMAP, pixelMap);
|
|
||||||
thumbCallback(imageKnifeData);
|
|
||||||
} else {
|
|
||||||
thumbError(error);
|
|
||||||
}
|
|
||||||
}})
|
|
||||||
setTimeout(()=>{
|
|
||||||
this.options.transformations[0].transform(source, request, {asyncTransform: (error:BusinessError|string, pixelMap: PixelMap|null) => {
|
|
||||||
if (pixelMap) {
|
if (pixelMap) {
|
||||||
// 保存一份变换后的图片PixelMap到MemoryCache
|
thumbCallback(pixelMap);
|
||||||
let imageKnifeData = this.createImagePixelMap(ImageKnifeType.PIXELMAP, pixelMap);
|
} else {
|
||||||
this.mMemoryCacheProxy.putValue(this.options.generateCacheKey, imageKnifeData);
|
thumbError(error);
|
||||||
onComplete(imageKnifeData);
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
setTimeout(() => {
|
||||||
|
this.options.transformations[0].transform(source, request, {
|
||||||
|
asyncTransform: (error: BusinessError | string, pixelMap: PixelMap | null) => {
|
||||||
|
if (pixelMap) {
|
||||||
|
onComplete(pixelMap);
|
||||||
|
} else {
|
||||||
|
onError(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}, this.options.thumbDelayTime);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.options.transformations[0].transform(source, request, {
|
||||||
|
asyncTransform: (error: BusinessError | string, pixelMap: PixelMap | null) => {
|
||||||
|
if (pixelMap) {
|
||||||
|
onComplete(pixelMap);
|
||||||
} else {
|
} else {
|
||||||
onError(error);
|
onError(error);
|
||||||
}
|
}
|
||||||
}})
|
|
||||||
},this.options.thumbDelayTime);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.options.transformations[0].transform(source, request, {asyncTransform: (error:BusinessError|string, pixelMap: PixelMap|null) => {
|
|
||||||
if (pixelMap) {
|
|
||||||
// 保存一份变换后的图片PixelMap到MemoryCache
|
|
||||||
let imageKnifeData = this.createImagePixelMap(ImageKnifeType.PIXELMAP, pixelMap);
|
|
||||||
this.mMemoryCacheProxy.putValue(this.options.generateCacheKey, imageKnifeData);
|
|
||||||
onComplete(imageKnifeData);
|
|
||||||
} else {
|
|
||||||
onError(error);
|
|
||||||
}
|
}
|
||||||
}})
|
})
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// thumbnail 缩略图部分
|
// thumbnail 缩略图部分
|
||||||
|
@ -377,24 +324,18 @@ export class RequestManager {
|
||||||
let thumbCallback = this.options.thumbholderOnComplete
|
let thumbCallback = this.options.thumbholderOnComplete
|
||||||
let thumbError = this.options.thumbholderOnError
|
let thumbError = this.options.thumbholderOnError
|
||||||
let thumbSuccess = (value: PixelMap) => {
|
let thumbSuccess = (value: PixelMap) => {
|
||||||
let imageKnifeData = this.createImagePixelMap(ImageKnifeType.PIXELMAP, value);
|
thumbCallback(value);
|
||||||
thumbCallback(imageKnifeData);
|
|
||||||
}
|
}
|
||||||
this.mParseImageUtil.parseImageThumbnail(request.thumbSizeMultiplier, source, thumbSuccess, thumbError);
|
this.mParseImageUtil.parseImageThumbnail(request.thumbSizeMultiplier, source, thumbSuccess, thumbError);
|
||||||
setTimeout(()=>{
|
setTimeout(() => {
|
||||||
let success = (value: PixelMap) => {
|
let success = (value: PixelMap) => {
|
||||||
let imageKnifeData = this.createImagePixelMap(ImageKnifeType.PIXELMAP, value);
|
onComplete(value);
|
||||||
this.mMemoryCacheProxy.putValue(this.options.generateCacheKey, imageKnifeData);
|
}
|
||||||
onComplete(imageKnifeData);
|
this.mParseImageUtil.parseImage(source, success, onError)
|
||||||
}
|
}, this.options.thumbDelayTime)
|
||||||
this.mParseImageUtil.parseImage(source, success, onError)
|
} else {
|
||||||
},this.options.thumbDelayTime)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
let success = (value: PixelMap) => {
|
let success = (value: PixelMap) => {
|
||||||
let imageKnifeData = this.createImagePixelMap(ImageKnifeType.PIXELMAP, value);
|
onComplete(value);
|
||||||
this.mMemoryCacheProxy.putValue(this.options.generateCacheKey, imageKnifeData);
|
|
||||||
onComplete(imageKnifeData);
|
|
||||||
}
|
}
|
||||||
this.mParseImageUtil.parseImage(source, success, onError)
|
this.mParseImageUtil.parseImage(source, success, onError)
|
||||||
}
|
}
|
||||||
|
@ -403,7 +344,8 @@ export class RequestManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 解析磁盘变换后文件变成PixeMap
|
// 解析磁盘变换后文件变成PixeMap
|
||||||
private parseDiskTransformFile2PixelMap(request: RequestOption, source: ArrayBuffer, onComplete:(value:ImageKnifeData)=>void|PromiseLike<ImageKnifeData>, onError:(reason?:BusinessError|string)=>void) {
|
private parseDiskTransformFile2PixelMap(request: RequestOption, source: ArrayBuffer, onComplete: (value: PixelMap) => void | PromiseLike<ImageKnifeData>, onError: (reason?: BusinessError | string) => void) {
|
||||||
|
LogUtil.log("ImageKnife RequestManager parseDiskTransformFile2PixelMap")
|
||||||
let fileTypeUtil = new FileTypeUtil();
|
let fileTypeUtil = new FileTypeUtil();
|
||||||
let typeValue = fileTypeUtil.getFileType(source);
|
let typeValue = fileTypeUtil.getFileType(source);
|
||||||
// thumbnail 缩略图部分
|
// thumbnail 缩略图部分
|
||||||
|
@ -411,33 +353,27 @@ export class RequestManager {
|
||||||
let thumbCallback = this.options.thumbholderOnComplete
|
let thumbCallback = this.options.thumbholderOnComplete
|
||||||
let thumbError = this.options.thumbholderOnError
|
let thumbError = this.options.thumbholderOnError
|
||||||
let thumbSuccess = (value: PixelMap) => {
|
let thumbSuccess = (value: PixelMap) => {
|
||||||
let imageKnifeData = this.createImagePixelMap(ImageKnifeType.PIXELMAP, value);
|
thumbCallback(value);
|
||||||
thumbCallback(imageKnifeData);
|
|
||||||
}
|
}
|
||||||
this.mParseImageUtil.parseImageThumbnail(request.thumbSizeMultiplier, source, thumbSuccess, thumbError);
|
this.mParseImageUtil.parseImageThumbnail(request.thumbSizeMultiplier, source, thumbSuccess, thumbError);
|
||||||
setTimeout(()=>{
|
setTimeout(() => {
|
||||||
let success = (value: PixelMap) => {
|
let success = (value: PixelMap) => {
|
||||||
let imageKnifeData = this.createImagePixelMap(ImageKnifeType.PIXELMAP, value);
|
onComplete(value);
|
||||||
this.mMemoryCacheProxy.putValue(this.options.generateCacheKey, imageKnifeData);
|
|
||||||
onComplete(imageKnifeData);
|
|
||||||
}
|
}
|
||||||
this.mParseImageUtil.parseImage(source, success, onError)
|
this.mParseImageUtil.parseImage(source, success, onError)
|
||||||
},this.options.thumbDelayTime)
|
}, this.options.thumbDelayTime)
|
||||||
}else{
|
} else {
|
||||||
let success = (value: PixelMap) => {
|
let success = (value: PixelMap) => {
|
||||||
let imageKnifeData = this.createImagePixelMap(ImageKnifeType.PIXELMAP, value)
|
onComplete(value);
|
||||||
this.mMemoryCacheProxy.putValue(this.options.generateCacheKey, imageKnifeData);
|
|
||||||
onComplete(imageKnifeData);
|
|
||||||
}
|
}
|
||||||
this.mParseImageUtil.parseImage(source, success, onError)
|
this.mParseImageUtil.parseImage(source, success, onError)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private downloadSuccess(request: RequestOption,source: ArrayBuffer, onComplete:(value:ImageKnifeData)=>void|PromiseLike<ImageKnifeData>, onError:(reason?:BusinessError|string)=>void) {
|
private downloadSuccess(request: RequestOption, source: ArrayBuffer, onComplete: (value: PixelMap | GIFFrame[]) => void | PromiseLike<ImageKnifeData>, onError: (reason?: BusinessError | string) => void) {
|
||||||
LogUtil.log('Download task completed.');
|
|
||||||
|
|
||||||
if(source == null || source == undefined || source.byteLength <= 0){
|
if (source == null || source == undefined || source.byteLength <= 0) {
|
||||||
onError('Download task completed. but download file is empty!')
|
onError('ImageKnife Download task completed. but download file is empty!')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -446,8 +382,8 @@ export class RequestManager {
|
||||||
// 步骤二: 文件名保存一份全局
|
// 步骤二: 文件名保存一份全局
|
||||||
// 步骤三:查看文件是否支持 非支持类型直接返回
|
// 步骤三:查看文件是否支持 非支持类型直接返回
|
||||||
let fileTypeUtil = new FileTypeUtil();
|
let fileTypeUtil = new FileTypeUtil();
|
||||||
let filetype:string|null = fileTypeUtil.getFileType(source);
|
let filetype: string | null = fileTypeUtil.getFileType(source);
|
||||||
if(filetype == null){
|
if (filetype == null) {
|
||||||
onError("下载文件解析后类型为null,请检查数据源!");
|
onError("下载文件解析后类型为null,请检查数据源!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -457,53 +393,51 @@ export class RequestManager {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 解析磁盘文件 gif 和 svg
|
// 解析磁盘文件 gif、webp 和 svg
|
||||||
if(ImageKnifeData.GIF == filetype && !this.options.dontAnimateFlag){
|
if ((ImageKnifeData.GIF == filetype || ImageKnifeData.WEBP == filetype) && !this.options.dontAnimateFlag) {
|
||||||
// 处理gif
|
// 处理gif、webp
|
||||||
this.gifProcess(onComplete,onError,source,filetype, (imageKnifeData)=>{
|
this.gifProcess(onComplete, onError, source, filetype)
|
||||||
this.mMemoryCacheProxy.putValue(this.options.generateCacheKey, imageKnifeData)
|
|
||||||
})
|
|
||||||
|
|
||||||
// 保存二级磁盘缓存
|
// 保存二级磁盘缓存
|
||||||
Promise.resolve(source)
|
Promise.resolve(source)
|
||||||
.then((arraybuffer: ArrayBuffer)=>{
|
.then((arraybuffer: ArrayBuffer) => {
|
||||||
this.mDiskCacheProxy.putValue(this.options.generateDataKey, arraybuffer)
|
this.diskMemoryCache.set(this.options.generateDataKey,arraybuffer);
|
||||||
})
|
})
|
||||||
.catch( (err:BusinessError)=>{
|
.catch((err: BusinessError) => {
|
||||||
LogUtil.log('download file is ='+ImageKnifeData.GIF+'and save diskLruCache error ='+ (err as BusinessError))
|
LogUtil.log('download file is =' + ImageKnifeData.GIF + 'and save diskLruCache error =' + (err as BusinessError))
|
||||||
})
|
})
|
||||||
}else if(ImageKnifeData.SVG == filetype){
|
} else if (ImageKnifeData.SVG == filetype) {
|
||||||
// 处理svg
|
// 处理svg
|
||||||
this.svgProcess(request,onComplete,onError, source, filetype, (imageKnifeData)=>{
|
this.svgProcess(request, onComplete, onError, source, filetype)
|
||||||
this.mMemoryCacheProxy.putValue(this.options.generateCacheKey, imageKnifeData)
|
|
||||||
})
|
|
||||||
|
|
||||||
// 保存二级磁盘缓存
|
// 保存二级磁盘缓存
|
||||||
Promise.resolve(source)
|
Promise.resolve(source)
|
||||||
.then((arraybuffer: ArrayBuffer)=>{
|
.then((arraybuffer: ArrayBuffer) => {
|
||||||
this.mDiskCacheProxy.putValue(this.options.generateDataKey, arraybuffer)
|
this.diskMemoryCache.set(this.options.generateDataKey,arraybuffer);
|
||||||
})
|
})
|
||||||
.catch((err:BusinessError)=>{
|
.catch((err: BusinessError) => {
|
||||||
LogUtil.log('download file is ='+ImageKnifeData.SVG+'and save diskLruCache error ='+ (err as BusinessError))
|
LogUtil.log('download file is =' + ImageKnifeData.SVG + 'and save diskLruCache error =' + (err as BusinessError))
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
// 进行变换
|
// 进行变换
|
||||||
if (this.options.transformations[0]) {
|
if (this.options.transformations[0]) {
|
||||||
// thumbnail 缩略图部分
|
// thumbnail 缩略图部分
|
||||||
if (this.options.thumbSizeMultiplier) {
|
if (this.options.thumbSizeMultiplier) {
|
||||||
if(filetype != null) {
|
if (filetype != null) {
|
||||||
this.thumbnailProcess(source, filetype, onComplete, onError);
|
this.thumbnailProcess(source, filetype, onComplete, onError);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this.options.transformations[0].transform(source, this.options, {asyncTransform: (error:BusinessError|string, pixelMap: PixelMap|null) => {
|
this.options.transformations[0].transform(source, this.options, {
|
||||||
if (pixelMap) {
|
asyncTransform: (error: BusinessError | string, pixelMap: PixelMap | null) => {
|
||||||
if(filetype != null) {
|
if (pixelMap) {
|
||||||
this.saveCacheAndDisk(pixelMap, filetype, onComplete, source);
|
if (filetype != null) {
|
||||||
|
this.saveCacheAndDisk(pixelMap, filetype, onComplete, source);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
onError(error);
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
onError(error);
|
|
||||||
}
|
}
|
||||||
}})
|
})
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// thumbnail 缩略图部分
|
// thumbnail 缩略图部分
|
||||||
|
@ -511,13 +445,12 @@ export class RequestManager {
|
||||||
let thumbCallback = this.options.thumbholderOnComplete
|
let thumbCallback = this.options.thumbholderOnComplete
|
||||||
let thumbError = this.options.thumbholderOnError
|
let thumbError = this.options.thumbholderOnError
|
||||||
let thumbSuccess = (value: PixelMap) => {
|
let thumbSuccess = (value: PixelMap) => {
|
||||||
let imageKnifeData = this.createImagePixelMap(ImageKnifeType.PIXELMAP, value);
|
thumbCallback(value);
|
||||||
thumbCallback(imageKnifeData);
|
|
||||||
}
|
}
|
||||||
this.mParseImageUtil.parseImageThumbnail(this.options.thumbSizeMultiplier, source, thumbSuccess, thumbError);
|
this.mParseImageUtil.parseImageThumbnail(this.options.thumbSizeMultiplier, source, thumbSuccess, thumbError);
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
let success = (value: PixelMap) => {
|
let success = (value: PixelMap) => {
|
||||||
if(filetype != null) {
|
if (filetype != null) {
|
||||||
this.saveCacheAndDisk(value, filetype, onComplete, source);
|
this.saveCacheAndDisk(value, filetype, onComplete, source);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -525,7 +458,7 @@ export class RequestManager {
|
||||||
}, this.options.thumbDelayTime)
|
}, this.options.thumbDelayTime)
|
||||||
} else {
|
} else {
|
||||||
let success = (value: PixelMap) => {
|
let success = (value: PixelMap) => {
|
||||||
if(filetype != null) {
|
if (filetype != null) {
|
||||||
this.saveCacheAndDisk(value, filetype, onComplete, source);
|
this.saveCacheAndDisk(value, filetype, onComplete, source);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -535,94 +468,90 @@ export class RequestManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
createImagePixelMap(imageKnifeType: ImageKnifeType, imageKnifeValue: PixelMap): ImageKnifeData{
|
createImagePixelMap(imageKnifeType: ImageKnifeType, imageKnifeValue: PixelMap): ImageKnifeData {
|
||||||
return ImageKnifeData.createImagePixelMap(imageKnifeType,imageKnifeValue);
|
return ImageKnifeData.createImagePixelMap(imageKnifeType, imageKnifeValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
createImageGIFFrame(imageKnifeType: ImageKnifeType, imageKnifeValue: GIFFrame[]): ImageKnifeData{
|
createImageGIFFrame(imageKnifeType: ImageKnifeType, imageKnifeValue: GIFFrame[]): ImageKnifeData {
|
||||||
return ImageKnifeData.createImageGIFFrame(imageKnifeType,imageKnifeValue);
|
return ImageKnifeData.createImageGIFFrame(imageKnifeType, imageKnifeValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private async saveCacheAndDisk(value: PixelMap, filetype: string, onComplete: (value: PixelMap) => void | PromiseLike<ImageKnifeData>, source: ArrayBuffer) {
|
||||||
private saveCacheAndDisk(value: PixelMap, filetype:string, onComplete:(value:ImageKnifeData)=>void|PromiseLike<ImageKnifeData>, source:ArrayBuffer) {
|
let save2DiskCache = (arraybuffer: ArrayBuffer) => {
|
||||||
let imageKnifeData = this.createImagePixelMap(ImageKnifeType.PIXELMAP, value);
|
this.diskMemoryCache.set(this.options.generateDataKey,arraybuffer);
|
||||||
this.mMemoryCacheProxy.putValue(this.options.generateCacheKey, imageKnifeData);
|
|
||||||
let save2DiskCache = (arraybuffer:ArrayBuffer) => {
|
|
||||||
this.mDiskCacheProxy.putValue(this.options.generateDataKey, arraybuffer)
|
|
||||||
// 落盘之后需要主动移除当前request并且调用下一个加载
|
// 落盘之后需要主动移除当前request并且调用下一个加载
|
||||||
let removeCurrentAndSearchNextRun = this.options.removeCurrentAndSearchNext
|
let removeCurrentAndSearchNextRun = this.options.removeCurrentAndSearchNext;
|
||||||
removeCurrentAndSearchNextRun();
|
removeCurrentAndSearchNextRun();
|
||||||
}
|
}
|
||||||
let runSave2Disk = (resolve:(value:ArrayBuffer)=>void|PromiseLike<ArrayBuffer>, reject:(reason?:BusinessError|string)=>void) => {
|
let runSave2Disk = (resolve: (value: ArrayBuffer) => void | PromiseLike<ArrayBuffer>, reject: (reason?: BusinessError | string) => void) => {
|
||||||
resolve(source);
|
resolve(source);
|
||||||
}
|
}
|
||||||
let promise = new Promise(runSave2Disk);
|
let promise = new Promise(runSave2Disk);
|
||||||
promise.then(save2DiskCache);
|
await promise.then(save2DiskCache);
|
||||||
imageKnifeData.waitSaveDisk = true;
|
onComplete(value);
|
||||||
onComplete(imageKnifeData);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
thumbnailProcess(source:ArrayBuffer, filetype:string, onComplete:(value:ImageKnifeData)=>void|PromiseLike<ImageKnifeData>, onError:(reason?:BusinessError|string)=>void){
|
thumbnailProcess(source: ArrayBuffer, filetype: string, onComplete: (value: PixelMap) => void | PromiseLike<ImageKnifeData>, onError: (reason?: BusinessError | string) => void) {
|
||||||
let thumbOption = new RequestOption();
|
let thumbOption = new RequestOption();
|
||||||
let ctx = this.options.getModuleContext()
|
let ctx = this.options.getModuleContext()
|
||||||
if(ctx != undefined){
|
if (ctx != undefined) {
|
||||||
thumbOption.setModuleContext(ctx)
|
thumbOption.setModuleContext(ctx)
|
||||||
}else{
|
} else {
|
||||||
onError('RequestManager thumbnailProcess moduleContext is undefined, please check it!')
|
onError('RequestManager thumbnailProcess moduleContext is undefined, please check it!')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
thumbOption.setImageViewSize({
|
thumbOption.setImageViewSize({
|
||||||
width: Math.round(this.options.thumbSizeMultiplier * this.options.size.width),
|
width: Math.round(this.options.thumbSizeMultiplier * this.options.size.width),
|
||||||
height: Math.round(this.options.thumbSizeMultiplier * this.options.size.height)
|
height: Math.round(this.options.thumbSizeMultiplier * this.options.size.height)
|
||||||
})
|
})
|
||||||
let thumbCallback = this.options.thumbholderOnComplete
|
let thumbCallback = this.options.thumbholderOnComplete
|
||||||
let thumbError = this.options.thumbholderOnError
|
let thumbError = this.options.thumbholderOnError
|
||||||
this.options.transformations[0].transform(source, thumbOption, {asyncTransform: (error:BusinessError|string, pixelMap: PixelMap|null) => {
|
this.options.transformations[0].transform(source, thumbOption, {
|
||||||
if (pixelMap) {
|
asyncTransform: (error: BusinessError | string, pixelMap: PixelMap | null) => {
|
||||||
let imageKnifeData = this.createImagePixelMap(ImageKnifeType.PIXELMAP, pixelMap);
|
|
||||||
thumbCallback(imageKnifeData);
|
|
||||||
} else {
|
|
||||||
thumbError(error);
|
|
||||||
}
|
|
||||||
}})
|
|
||||||
setTimeout(() => {
|
|
||||||
this.options.transformations[0].transform(source, this.options,{asyncTransform: (error:BusinessError|string, pixelMap: PixelMap|null) => {
|
|
||||||
if (pixelMap) {
|
if (pixelMap) {
|
||||||
this.saveCacheAndDisk(pixelMap, filetype, onComplete, source);
|
thumbCallback(pixelMap);
|
||||||
|
} else {
|
||||||
|
thumbError(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
setTimeout(() => {
|
||||||
|
this.options.transformations[0].transform(source, this.options, {
|
||||||
|
asyncTransform: (error: BusinessError | string, pixelMap: PixelMap | null) => {
|
||||||
|
if (pixelMap) {
|
||||||
|
this.saveCacheAndDisk(pixelMap, filetype, onComplete, source);
|
||||||
} else {
|
} else {
|
||||||
onError(error);
|
onError(error);
|
||||||
}
|
}
|
||||||
}})
|
}
|
||||||
}, this.options.thumbDelayTime)
|
})
|
||||||
}
|
}, this.options.thumbDelayTime)
|
||||||
private svgProcess(option: RequestOption,onComplete:(value:ImageKnifeData)=>void|PromiseLike<ImageKnifeData>, onError:(reason?:BusinessError|string)=>void, arraybuffer:ArrayBuffer, typeValue:string, cacheStrategy?: (cacheData: ImageKnifeData) => void) {
|
|
||||||
let svgParseImpl = new SVGParseImpl()
|
|
||||||
svgParseImpl.parseSvg(option,arraybuffer, onComplete,onError)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private gifProcess(onComplete:(value:ImageKnifeData)=>void|PromiseLike<ImageKnifeData>, onError:(reason?:BusinessError|string)=>void, arraybuffer:ArrayBuffer, typeValue:string, cacheStrategy?: (cacheData: ImageKnifeData) => void) {
|
private svgProcess(option: RequestOption, onComplete: (value: PixelMap) => void | PromiseLike<ImageKnifeData>, onError: (reason?: BusinessError | string) => void, arraybuffer: ArrayBuffer, typeValue: string, cacheStrategy?: (cacheData: ImageKnifeData) => void) {
|
||||||
|
let svgParseImpl = new SVGParseImpl()
|
||||||
|
svgParseImpl.parseSvg(option, arraybuffer, onComplete, onError)
|
||||||
|
}
|
||||||
|
|
||||||
|
private gifProcess(onComplete: (value: PixelMap | GIFFrame[]) => void | PromiseLike<ImageKnifeData>, onError: (reason?: BusinessError | string) => void, arraybuffer: ArrayBuffer, typeValue: string, cacheStrategy?: (cacheData: ImageKnifeData) => void) {
|
||||||
let gifParseImpl = new GIFParseImpl()
|
let gifParseImpl = new GIFParseImpl()
|
||||||
gifParseImpl.parseGifs(arraybuffer, (data?:GIFFrame[],err?:BusinessError|string)=>{
|
gifParseImpl.parseGifs(arraybuffer, (data?: GIFFrame[], err?: BusinessError | string) => {
|
||||||
if(err){
|
if (err) {
|
||||||
onError(err)
|
onError(err)
|
||||||
}
|
}
|
||||||
LogUtil.log("gifProcess data is null:"+(data == null));
|
LogUtil.log("gifProcess data is null:" + (data == null));
|
||||||
if(!!data){
|
if (!!data) {
|
||||||
let imageKnifeData = this.createImageGIFFrame(ImageKnifeType.GIFFRAME,data)
|
// let imageKnifeData = this.createImageGIFFrame(ImageKnifeType.GIFFRAME, data)
|
||||||
LogUtil.log('gifProcess 生成gif 返回数据类型')
|
// LogUtil.log('gifProcess 生成gif 返回数据类型')
|
||||||
if(cacheStrategy){
|
// if (cacheStrategy) {
|
||||||
LogUtil.log('gifProcess 生成gif并且存入了缓存策略')
|
// LogUtil.log('gifProcess 生成gif并且存入了缓存策略')
|
||||||
cacheStrategy(imageKnifeData)
|
// cacheStrategy(imageKnifeData)
|
||||||
}
|
// }
|
||||||
onComplete(imageKnifeData)
|
onComplete(data)
|
||||||
}else{
|
} else {
|
||||||
onError('Parse GIF callback data is null, you need check callback data!')
|
onError('Parse GIF callback data is null, you need check callback data!')
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ export class ParseResClientBase64 implements IResourceFetch<ArrayBuffer> {
|
||||||
if (resType == ResourceTypeEts.MEDIA) {
|
if (resType == ResourceTypeEts.MEDIA) {
|
||||||
let moduleContext = ContextCacheProxy.getInstance()
|
let moduleContext = ContextCacheProxy.getInstance()
|
||||||
.contextGetValue(res.moduleName, context);
|
.contextGetValue(res.moduleName, context);
|
||||||
(moduleContext.resourceManager as resourceManager.ResourceManager)
|
(moduleContext?.resourceManager as resourceManager.ResourceManager)
|
||||||
.getMediaContentBase64(resId)
|
.getMediaContentBase64(resId)
|
||||||
.then(data => {
|
.then(data => {
|
||||||
let matchReg = ';base64,';
|
let matchReg = ';base64,';
|
||||||
|
|
|
@ -20,5 +20,9 @@ export interface BaseTransform<T> {
|
||||||
// 实现类 返回作为key生成的一部分
|
// 实现类 返回作为key生成的一部分
|
||||||
getName(): string;
|
getName(): string;
|
||||||
|
|
||||||
|
getClassName():string;
|
||||||
|
|
||||||
|
getConstructorParams():string;
|
||||||
|
|
||||||
transform(value: ArrayBuffer, request: RequestOption, func: AsyncTransform<T>):void;
|
transform(value: ArrayBuffer, request: RequestOption, func: AsyncTransform<T>):void;
|
||||||
}
|
}
|
|
@ -26,13 +26,27 @@ import {Size} from '../../imageknife/RequestOption'
|
||||||
|
|
||||||
export class BlurTransformation implements BaseTransform<PixelMap> {
|
export class BlurTransformation implements BaseTransform<PixelMap> {
|
||||||
private _mRadius: number;
|
private _mRadius: number;
|
||||||
|
private sampling: number
|
||||||
|
|
||||||
constructor(radius: number) {
|
constructor(radius: number,sampling?:number) {
|
||||||
this._mRadius = radius;
|
this._mRadius = radius;
|
||||||
|
if(sampling == undefined){
|
||||||
|
this.sampling = 1
|
||||||
|
} else {
|
||||||
|
this.sampling = sampling
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getClassName() {
|
||||||
|
return "BlurTransformation";
|
||||||
|
}
|
||||||
|
|
||||||
|
getConstructorParams() {
|
||||||
|
return JSON.stringify([this._mRadius,this.sampling]);
|
||||||
}
|
}
|
||||||
|
|
||||||
getName() {
|
getName() {
|
||||||
return "BlurTransformation _mRadius:" + this._mRadius;
|
return "BlurTransformation _mRadius:" + this._mRadius +"==BlurTransformation sampling:"+ this.sampling;
|
||||||
}
|
}
|
||||||
|
|
||||||
transform(buf: ArrayBuffer, request: RequestOption, func?: AsyncTransform<PixelMap>) {
|
transform(buf: ArrayBuffer, request: RequestOption, func?: AsyncTransform<PixelMap>) {
|
||||||
|
@ -63,8 +77,8 @@ export class BlurTransformation implements BaseTransform<PixelMap> {
|
||||||
let options:image.DecodingOptions = {
|
let options:image.DecodingOptions = {
|
||||||
editable: true,
|
editable: true,
|
||||||
desiredSize: {
|
desiredSize: {
|
||||||
width: targetWidth,
|
width: pixelMapWidth / this.sampling,
|
||||||
height: targetHeight
|
height: pixelMapHeight / this.sampling
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
imageSource.createPixelMap(options)
|
imageSource.createPixelMap(options)
|
||||||
|
|
|
@ -33,6 +33,14 @@ export class BrightnessFilterTransformation implements BaseTransform<PixelMap> {
|
||||||
this._mBrightness = brightness;
|
this._mBrightness = brightness;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getClassName(){
|
||||||
|
return "BrightnessFilterTransformation";
|
||||||
|
}
|
||||||
|
|
||||||
|
getConstructorParams(){
|
||||||
|
return JSON.stringify([this._mBrightness]);
|
||||||
|
}
|
||||||
|
|
||||||
getName() {
|
getName() {
|
||||||
return "BrightnessFilterTransformation:" + this._mBrightness;
|
return "BrightnessFilterTransformation:" + this._mBrightness;
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,6 +45,15 @@ export class ContrastFilterTransformation implements BaseTransform<PixelMap> {
|
||||||
this._mContrast = contrast;
|
this._mContrast = contrast;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getClassName(){
|
||||||
|
return "ContrastFilterTransformation";
|
||||||
|
}
|
||||||
|
|
||||||
|
getConstructorParams(){
|
||||||
|
return JSON.stringify([this._mContrast]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
getName() {
|
getName() {
|
||||||
return "ContrastFilterTransformation:" + this._mContrast;
|
return "ContrastFilterTransformation:" + this._mContrast;
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,14 @@ export class CropCircleTransformation implements BaseTransform<PixelMap> {
|
||||||
private mCenterY: number = 0;
|
private mCenterY: number = 0;
|
||||||
private mRadius: number = 0;
|
private mRadius: number = 0;
|
||||||
|
|
||||||
|
getClassName(){
|
||||||
|
return "CropCircleTransformation";
|
||||||
|
}
|
||||||
|
|
||||||
|
getConstructorParams(){
|
||||||
|
return "[]";
|
||||||
|
}
|
||||||
|
|
||||||
getName() {
|
getName() {
|
||||||
return CropCircleTransformation.TAG + ";mCenterX:" + this.mCenterX
|
return CropCircleTransformation.TAG + ";mCenterX:" + this.mCenterX
|
||||||
+ ";mCenterY:" + this.mCenterY
|
+ ";mCenterY:" + this.mCenterY
|
||||||
|
|
|
@ -18,15 +18,17 @@ import { AsyncTransform } from "../transform/AsyncTransform"
|
||||||
import { Constants } from "../constants/Constants"
|
import { Constants } from "../constants/Constants"
|
||||||
import { RequestOption } from "../../imageknife/RequestOption"
|
import { RequestOption } from "../../imageknife/RequestOption"
|
||||||
import { TransformUtils } from "../transform/TransformUtils"
|
import { TransformUtils } from "../transform/TransformUtils"
|
||||||
import {LogUtil} from '../../imageknife/utils/LogUtil'
|
import { LogUtil } from '../../imageknife/utils/LogUtil'
|
||||||
import image from "@ohos.multimedia.image"
|
import image from "@ohos.multimedia.image"
|
||||||
import { BusinessError } from '@ohos.base'
|
import { BusinessError } from '@ohos.base'
|
||||||
import {Size} from '../../imageknife/RequestOption'
|
import { Size } from '../../imageknife/RequestOption'
|
||||||
export interface rgbColor{
|
|
||||||
|
export interface rgbColor {
|
||||||
r_color: number,
|
r_color: number,
|
||||||
g_color: number,
|
g_color: number,
|
||||||
b_color: number,
|
b_color: number,
|
||||||
}
|
}
|
||||||
|
|
||||||
export class CropCircleWithBorderTransformation implements BaseTransform<PixelMap> {
|
export class CropCircleWithBorderTransformation implements BaseTransform<PixelMap> {
|
||||||
private static TAG: string = "CropCircleTransformation";
|
private static TAG: string = "CropCircleTransformation";
|
||||||
private mBorderSize: number = 5;
|
private mBorderSize: number = 5;
|
||||||
|
@ -35,7 +37,7 @@ export class CropCircleWithBorderTransformation implements BaseTransform<PixelMa
|
||||||
private mRadius: number = 0;
|
private mRadius: number = 0;
|
||||||
private mRColor: number = 0;
|
private mRColor: number = 0;
|
||||||
private mGColor: number = 0;
|
private mGColor: number = 0;
|
||||||
private mBColor: number= 0;
|
private mBColor: number = 0;
|
||||||
|
|
||||||
constructor(border_size: number, value: rgbColor) {
|
constructor(border_size: number, value: rgbColor) {
|
||||||
this.mRColor = value.g_color;
|
this.mRColor = value.g_color;
|
||||||
|
@ -44,14 +46,26 @@ export class CropCircleWithBorderTransformation implements BaseTransform<PixelMa
|
||||||
this.mBorderSize = border_size;
|
this.mBorderSize = border_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getClassName() {
|
||||||
|
return "CropCircleWithBorderTransformation";
|
||||||
|
}
|
||||||
|
|
||||||
|
getConstructorParams() {
|
||||||
|
return JSON.stringify([this.mBorderSize, {
|
||||||
|
r_color: this.mRColor,
|
||||||
|
g_color: this.mGColor,
|
||||||
|
b_color: this.mBColor
|
||||||
|
}]);
|
||||||
|
}
|
||||||
|
|
||||||
getName() {
|
getName() {
|
||||||
return CropCircleWithBorderTransformation.TAG + ";mBorderSize:" + this.mBorderSize
|
return CropCircleWithBorderTransformation.TAG + ";mBorderSize:" + this.mBorderSize
|
||||||
+ ";mCenterX:" + this.mCenterX
|
+ ";mCenterX:" + this.mCenterX
|
||||||
+ ";mCenterY:" + this.mCenterY
|
+ ";mCenterY:" + this.mCenterY
|
||||||
+ ";mRadius:" + this.mRadius
|
+ ";mRadius:" + this.mRadius
|
||||||
+ ";mRColor:" + this.mRColor
|
+ ";mRColor:" + this.mRColor
|
||||||
+ ";mGColor:" + this.mGColor
|
+ ";mGColor:" + this.mGColor
|
||||||
+ ";mBColor:" + this.mBColor;
|
+ ";mBColor:" + this.mBColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
transform(buf: ArrayBuffer, request: RequestOption, func?: AsyncTransform<PixelMap>) {
|
transform(buf: ArrayBuffer, request: RequestOption, func?: AsyncTransform<PixelMap>) {
|
||||||
|
@ -62,28 +76,30 @@ export class CropCircleWithBorderTransformation implements BaseTransform<PixelMa
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let imageSource:image.ImageSource = image.createImageSource(buf);
|
let imageSource: image.ImageSource = image.createImageSource(buf);
|
||||||
TransformUtils.getPixelMapSize(imageSource, {asyncTransform:(error:BusinessError|string, size:Size|null) => {
|
TransformUtils.getPixelMapSize(imageSource, {
|
||||||
if (!size) {
|
asyncTransform: (error: BusinessError | string, size: Size | null) => {
|
||||||
func?.asyncTransform(error, null)
|
if (!size) {
|
||||||
return;
|
func?.asyncTransform(error, null)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let pixelMapWidth = size.width;
|
||||||
|
let pixelMapHeight = size.height;
|
||||||
|
let targetWidth = request.size.width;
|
||||||
|
let targetHeight = request.size.height;
|
||||||
|
if (pixelMapWidth < targetWidth) {
|
||||||
|
targetWidth = pixelMapWidth;
|
||||||
|
}
|
||||||
|
if (pixelMapHeight < targetHeight) {
|
||||||
|
targetHeight = pixelMapHeight;
|
||||||
|
}
|
||||||
|
this.updatePixelMapSize(imageSource, targetWidth, targetHeight, func);
|
||||||
}
|
}
|
||||||
let pixelMapWidth = size.width;
|
})
|
||||||
let pixelMapHeight = size.height;
|
|
||||||
let targetWidth = request.size.width;
|
|
||||||
let targetHeight = request.size.height;
|
|
||||||
if (pixelMapWidth < targetWidth) {
|
|
||||||
targetWidth = pixelMapWidth;
|
|
||||||
}
|
|
||||||
if (pixelMapHeight < targetHeight) {
|
|
||||||
targetHeight = pixelMapHeight;
|
|
||||||
}
|
|
||||||
this.updatePixelMapSize(imageSource, targetWidth, targetHeight, func);
|
|
||||||
}})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private updatePixelMapSize(imageSource: image.ImageSource, outWith: number, outHeight: number, func?: AsyncTransform<PixelMap>) {
|
private updatePixelMapSize(imageSource: image.ImageSource, outWith: number, outHeight: number, func?: AsyncTransform<PixelMap>) {
|
||||||
let options:image.DecodingOptions = {
|
let options: image.DecodingOptions = {
|
||||||
editable: true,
|
editable: true,
|
||||||
desiredSize: {
|
desiredSize: {
|
||||||
width: outWith,
|
width: outWith,
|
||||||
|
@ -91,13 +107,13 @@ export class CropCircleWithBorderTransformation implements BaseTransform<PixelMa
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
imageSource.createPixelMap(options)
|
imageSource.createPixelMap(options)
|
||||||
.then((pixelMap:PixelMap) => {
|
.then((pixelMap: PixelMap) => {
|
||||||
this.transformPixelMap(pixelMap, outWith, outHeight, func);
|
this.transformPixelMap(pixelMap, outWith, outHeight, func);
|
||||||
imageSource.release()
|
imageSource.release()
|
||||||
})
|
})
|
||||||
.catch((e:BusinessError) => {
|
.catch((e: BusinessError) => {
|
||||||
LogUtil.log(Constants.PROJECT_TAG + ";CropCircleWithBorderTransformation e:" + e);
|
LogUtil.log(Constants.PROJECT_TAG + ";CropCircleWithBorderTransformation e:" + e);
|
||||||
if (func!=undefined) {
|
if (func != undefined) {
|
||||||
func?.asyncTransform(Constants.PROJECT_TAG + ";CropCircleWithBorderTransformation e:" + e, null);
|
func?.asyncTransform(Constants.PROJECT_TAG + ";CropCircleWithBorderTransformation e:" + e, null);
|
||||||
}
|
}
|
||||||
imageSource.release()
|
imageSource.release()
|
||||||
|
@ -120,8 +136,8 @@ export class CropCircleWithBorderTransformation implements BaseTransform<PixelMa
|
||||||
|
|
||||||
let dataArray = new Uint8Array(bufferData);
|
let dataArray = new Uint8Array(bufferData);
|
||||||
|
|
||||||
for (let h = 0;h <= height; h++) {
|
for (let h = 0; h <= height; h++) {
|
||||||
for (let w = 0;w <= width; w++) {
|
for (let w = 0; w <= width; w++) {
|
||||||
// 不在大圆之内的设置透明
|
// 不在大圆之内的设置透明
|
||||||
// 在大圆与小圆之间的 设置rgb值
|
// 在大圆与小圆之间的 设置rgb值
|
||||||
// 小圆之内的不变
|
// 小圆之内的不变
|
||||||
|
@ -154,16 +170,16 @@ export class CropCircleWithBorderTransformation implements BaseTransform<PixelMa
|
||||||
}
|
}
|
||||||
|
|
||||||
isContainsCircle(x: number, y: number): boolean {
|
isContainsCircle(x: number, y: number): boolean {
|
||||||
let a:number = Math.pow((this.mCenterX - x), 2);
|
let a: number = Math.pow((this.mCenterX - x), 2);
|
||||||
let b:number = Math.pow((this.mCenterY - y), 2);
|
let b: number = Math.pow((this.mCenterY - y), 2);
|
||||||
let c:number = Math.sqrt((a + b));
|
let c: number = Math.sqrt((a + b));
|
||||||
return c <= this.mRadius;
|
return c <= this.mRadius;
|
||||||
}
|
}
|
||||||
|
|
||||||
isContainsSmallCircle(x: number, y: number): boolean {
|
isContainsSmallCircle(x: number, y: number): boolean {
|
||||||
let a:number = Math.pow((this.mCenterX - x), 2);
|
let a: number = Math.pow((this.mCenterX - x), 2);
|
||||||
let b:number = Math.pow((this.mCenterY - y), 2);
|
let b: number = Math.pow((this.mCenterY - y), 2);
|
||||||
let c:number = Math.sqrt((a + b));
|
let c: number = Math.sqrt((a + b));
|
||||||
return c <= (this.mRadius - this.mBorderSize);
|
return c <= (this.mRadius - this.mBorderSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -26,6 +26,14 @@ import image from "@ohos.multimedia.image"
|
||||||
export class CropSquareTransformation implements BaseTransform<PixelMap> {
|
export class CropSquareTransformation implements BaseTransform<PixelMap> {
|
||||||
private static TAG: string = "CropSquareTransformation";
|
private static TAG: string = "CropSquareTransformation";
|
||||||
|
|
||||||
|
getClassName(){
|
||||||
|
return "CropSquareTransformation";
|
||||||
|
}
|
||||||
|
|
||||||
|
getConstructorParams(){
|
||||||
|
return '[]';
|
||||||
|
}
|
||||||
|
|
||||||
getName() {
|
getName() {
|
||||||
return CropSquareTransformation.TAG;
|
return CropSquareTransformation.TAG;
|
||||||
}
|
}
|
||||||
|
@ -60,8 +68,8 @@ export class CropSquareTransformation implements BaseTransform<PixelMap> {
|
||||||
editable: true,
|
editable: true,
|
||||||
rotate: 0,
|
rotate: 0,
|
||||||
desiredSize: {
|
desiredSize: {
|
||||||
width: outWidth,
|
width: pw,
|
||||||
height: outHeight
|
height: ph
|
||||||
},
|
},
|
||||||
desiredRegion: { size: { width: targetSize, height: targetSize },
|
desiredRegion: { size: { width: targetSize, height: targetSize },
|
||||||
x: pw / 2 - targetSize / 2,
|
x: pw / 2 - targetSize / 2,
|
||||||
|
|
|
@ -35,6 +35,14 @@ export class CropTransformation implements BaseTransform<PixelMap> {
|
||||||
this.mCropType = cropType;
|
this.mCropType = cropType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getClassName(){
|
||||||
|
return "CropTransformation";
|
||||||
|
}
|
||||||
|
|
||||||
|
getConstructorParams(){
|
||||||
|
return JSON.stringify([this.mWidth,this.mHeight ,this.mCropType]);
|
||||||
|
}
|
||||||
|
|
||||||
getName() {
|
getName() {
|
||||||
return CropTransformation.TAG + ";mWidth:" + this.mWidth
|
return CropTransformation.TAG + ";mWidth:" + this.mWidth
|
||||||
+ ";mHeight:" + this.mHeight
|
+ ";mHeight:" + this.mHeight
|
||||||
|
|
|
@ -29,6 +29,14 @@ export class GrayscaleTransformation implements BaseTransform<PixelMap> {
|
||||||
return "GrayscaleTransformation";
|
return "GrayscaleTransformation";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getClassName(){
|
||||||
|
return "GrayscaleTransformation";
|
||||||
|
}
|
||||||
|
|
||||||
|
getConstructorParams(){
|
||||||
|
return '[]';
|
||||||
|
}
|
||||||
|
|
||||||
async transform(buf: ArrayBuffer, request: RequestOption, func?: AsyncTransform<PixelMap>) {
|
async transform(buf: ArrayBuffer, request: RequestOption, func?: AsyncTransform<PixelMap>) {
|
||||||
if (!buf || buf.byteLength <= 0) {
|
if (!buf || buf.byteLength <= 0) {
|
||||||
LogUtil.log(Constants.PROJECT_TAG + ";GrayscaleTransformation buf is empty");
|
LogUtil.log(Constants.PROJECT_TAG + ";GrayscaleTransformation buf is empty");
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue