forked from floraachy/ImageKnife
Compare commits
25 Commits
Author | SHA1 | Date |
---|---|---|
|
1153390393 | |
|
7210d5060b | |
|
1c7bedc6d5 | |
|
5f2e80400a | |
|
fd0394a80a | |
|
c5a861f4fe | |
|
b57194cf4c | |
|
1a2326c691 | |
|
9c0b4ebace | |
|
8d4442157c | |
|
a34e20acfa | |
|
8dd224e7e6 | |
|
7f51e9164e | |
|
41be71bb73 | |
|
08b36b7803 | |
|
cde07275c3 | |
|
43dd3c528c | |
|
4383fa3659 | |
|
aa2cd9c1bf | |
|
1787fffea7 | |
|
8e773e929a | |
|
a3ed45a468 | |
|
ccd4455b83 | |
|
2fc1f4c776 | |
|
6dcf2840b3 |
|
@ -1,3 +0,0 @@
|
|||
[submodule "gpu_transform/src/main/cpp/boundscheck/third_party_bounds_checking_function"]
|
||||
path = gpu_transform/src/main/cpp/boundscheck/third_party_bounds_checking_function
|
||||
url = https://gitee.com/openharmony/third_party_bounds_checking_function.git
|
50
CHANGELOG.md
50
CHANGELOG.md
|
@ -1,27 +1,45 @@
|
|||
## 3.1.1-rc.1
|
||||
- Photo reduction sampling
|
||||
## 3.1.1-rc.0
|
||||
- 重构代码:抽取ImageKnifeDispatcher子线程requestJob相关代码到ImageKnifeLoader中,降低函数复杂度
|
||||
## 3.1.0
|
||||
## 3.2.0-rc.1
|
||||
- Added callback information for image loading
|
||||
- Added the interface for obtaining the upper limit and size of the current cache and the number of images corresponding to the current cache
|
||||
- Change the queue from Stack to Queue
|
||||
- ShowPixelMap callback PixelMap assigns value to Image component to synchronize
|
||||
|
||||
## 3.2.0-rc.0
|
||||
- Rollback the old version V1 decorator. V2 decorator will be provided in version 4.x
|
||||
- The sub-thread network request is changed to asynchronous, thereby increasing the number of concurrent sub-thread network requests
|
||||
- Set the concurrency through the setMaxRequests interface under the ImageKnife class
|
||||
- aboutToRecycle life cycle clear image content
|
||||
- Fixed bug for receive only the first onLoadStart for concurrent identical requests
|
||||
- Modify the condition for determining whether to queue to be greater than or equal to maxRequests
|
||||
|
||||
## 3.0.3
|
||||
- Released version 3.0.3
|
||||
|
||||
## 3.0.3-rc.0
|
||||
- Custom network method to add request header parameters
|
||||
|
||||
## 3.0.2
|
||||
- Added new image reloading interface reload
|
||||
- Added return request preload interface preload
|
||||
- Added cancel request interface cancel
|
||||
|
||||
## 3.0.2-rc.2
|
||||
- ImageKnifeAnimatorComponent新增开始、结束、暂停的回调事件
|
||||
- 文件缓存数量负数和超过INT最大值时默认为INT最大值
|
||||
- 修复宽高不等svg图片显示有毛边
|
||||
- 部分静态webp图片有delay属性导致识别成动图,改用getFrameCount识别
|
||||
- 修复加载错误图后未去请求排队队列中的请求
|
||||
- 子线程本地Resource参数类型转换成number
|
||||
- 修改使用hilog记录日志,默认打开debug级别的日志
|
||||
- file格式图片,fd同步close
|
||||
- 解码pixelMap默认不可编辑,图形变化可编辑
|
||||
- 修改网络请求超时设置
|
||||
- 重构代码:抽取ImageKnifeDispatcher子线程requestJob相关代码到ImageKnifeLoader中,降低函数复杂度
|
||||
|
||||
## 3.1.0-rc.2
|
||||
- 修复宽高不等svg图片显示有毛边
|
||||
## 3.0.2-rc.1
|
||||
- release打包关闭混淆
|
||||
|
||||
## 3.1.0-rc.1
|
||||
- ImageKnifeAnimatorComponent新增开始、结束、暂停的回调事件
|
||||
- 文件缓存数量负数和超过INT最大值时默认为INT最大值
|
||||
|
||||
## 3.1.0-rc.0
|
||||
- ComponentV2装饰器适配
|
||||
- imageKnifeOption={...}用法改为new ImageKnifeOption({...})
|
||||
- animatorOption={...}用法改为new AnimatorOption({...})
|
||||
## 3.0.2-rc.0
|
||||
- FileUtil.readFile接口和file格式图片同步关闭fd
|
||||
|
||||
## 3.0.1
|
||||
- 修复animatorOption属性设置初始化值失效
|
||||
|
|
17
OAT.xml
17
OAT.xml
|
@ -1,21 +1,4 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
This is the configuration file template for OpenHarmony OSS Audit Tool, please copy it to your project root dir and modify it refer to OpenHarmony/tools_oat/README.
|
||||
|
||||
-->
|
||||
<configuration>
|
||||
<oatconfig>
|
||||
<filefilterlist>
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
{
|
||||
"Name": "glide",
|
||||
"License": "Apache License 2.0",
|
||||
"License File": "LICENSE",
|
||||
"License File": "https://github.com/bumptech/glide/blob/master/LICENSE",
|
||||
"Version Number": "4.13.1",
|
||||
"Owner" : "xiafeng@huawei.com",
|
||||
"Owner" : "bumptech",
|
||||
"Upstream URL": "https://github.com/bumptech/glide",
|
||||
"Description": "An image loading and caching library focused on smooth scrolling"
|
||||
},
|
||||
|
@ -12,9 +12,9 @@
|
|||
{
|
||||
"Name": "glide-transformations",
|
||||
"License": "Apache License 2.0",
|
||||
"License File": "LICENSE",
|
||||
"License File": "https://github.com/wasabeef/glide-transformations/blob/main/LICENSE",
|
||||
"Version Number": "4.3.0",
|
||||
"Owner" : "xiafeng@huawei.com",
|
||||
"Owner" : "wasabeef",
|
||||
"Upstream URL": "https://github.com/wasabeef/glide-transformations",
|
||||
"Description": " An transformation library providing a variety of image transformations for Glide. "
|
||||
},
|
||||
|
@ -22,9 +22,9 @@
|
|||
{
|
||||
"Name": "fresco",
|
||||
"License": "MIT License",
|
||||
"License File": "LICENSE",
|
||||
"License File": "https://github.com/facebook/fresco/blob/main/LICENSE",
|
||||
"Version Number": "2.6.0",
|
||||
"Owner" : "xiafeng@huawei.com",
|
||||
"Owner" : "facebook",
|
||||
"Upstream URL": "https://github.com/facebook/fresco",
|
||||
"Description": " An library for managing images and the memory they use. "
|
||||
},
|
||||
|
@ -32,9 +32,9 @@
|
|||
{
|
||||
"Name": "UPNG.js",
|
||||
"License": "MIT License",
|
||||
"License File": "LICENSE",
|
||||
"License File": "https://github.com/photopea/UPNG.js/blob/master/LICENSE",
|
||||
"Version Number": "1.0.0",
|
||||
"Owner" : "xiafeng@huawei.com",
|
||||
"Owner" : "photopea",
|
||||
"Upstream URL": "https://github.com/photopea/UPNG.js",
|
||||
"Description": " Fast and advanced PNG (APNG) decoder and encoder (lossy / lossless) "
|
||||
},
|
||||
|
@ -42,9 +42,9 @@
|
|||
{
|
||||
"Name": "Luban",
|
||||
"License": "Apache License 2.0",
|
||||
"License File": "LICENSE",
|
||||
"License File": "https://github.com/Curzibn/Luban/blob/master/LICENSE",
|
||||
"Version Number": "1.1.8",
|
||||
"Owner" : " xiafeng@huawei.com",
|
||||
"Owner" : " Curzibn",
|
||||
"Upstream URL": "https://github.com/Curzibn/Luban",
|
||||
"Description": " Luban(鲁班)—Image compression with efficiency very close to WeChat Moments/可能是最接近微信朋友圈的图片压缩算法 "
|
||||
},
|
||||
|
@ -54,16 +54,16 @@
|
|||
"License": "Apache License 2.0",
|
||||
"License File": "https://github.com/Yalantis/uCrop/blob/develop/README.md",
|
||||
"Version Number": "2.2.8",
|
||||
"Owner" : " xiafeng@huawei.com",
|
||||
"Owner" : " Yalantis",
|
||||
"Upstream URL": "https://github.com/Yalantis/uCrop",
|
||||
"Description": " Image Cropping Library "
|
||||
},
|
||||
{
|
||||
"Name": "js-spark-md5",
|
||||
"License": "MIT",
|
||||
"License File": "LICENSE",
|
||||
"License File": "https://github.com/satazor/js-spark-md5/blob/master/LICENSE",
|
||||
"Version Number": "v3.0.2",
|
||||
"Owner" : "xiafeng@huawei.com",
|
||||
"Owner" : "satazor",
|
||||
"Upstream URL": "https://github.com/satazor/js-spark-md5",
|
||||
"Description": "Lightning fast normal and incremental md5 for javascript"
|
||||
}
|
||||
|
|
85
README.md
85
README.md
|
@ -56,12 +56,12 @@ await ImageKnife.getInstance().initFileCache(context, 256, 256 * 1024 * 1024)
|
|||
|
||||
```
|
||||
ImageKnifeComponent({
|
||||
ImageKnifeOption: new ImageKnifeOption({
|
||||
ImageKnifeOption:{
|
||||
loadSrc: $r("app.media.app_icon"),
|
||||
placeholderSrc: $r("app.media.loading"),
|
||||
errorholderSrc: $r("app.media.app_icon"),
|
||||
objectFit: ImageFit.Auto
|
||||
})
|
||||
}
|
||||
}).width(100).height(100)
|
||||
```
|
||||
|
||||
|
@ -69,12 +69,12 @@ ImageKnifeComponent({
|
|||
|
||||
```
|
||||
ImageKnifeComponent({
|
||||
ImageKnifeOption: new ImageKnifeOption({
|
||||
ImageKnifeOption: {
|
||||
loadSrc: this.localFile,
|
||||
placeholderSrc: $r("app.media.loading"),
|
||||
errorholderSrc: $r("app.media.app_icon"),
|
||||
objectFit: ImageFit.Auto
|
||||
})
|
||||
}
|
||||
}).width(100).height(100)
|
||||
```
|
||||
|
||||
|
@ -82,12 +82,12 @@ ImageKnifeComponent({
|
|||
|
||||
```
|
||||
ImageKnifeComponent({
|
||||
ImageKnifeOption: new ImageKnifeOption({
|
||||
ImageKnifeOption: {
|
||||
loadSrc:"https://www.openharmony.cn/_nuxt/img/logo.dcf95b3.png",
|
||||
placeholderSrc: $r("app.media.loading"),
|
||||
errorholderSrc: $r("app.media.app_icon"),
|
||||
objectFit: ImageFit.Auto
|
||||
})
|
||||
}
|
||||
}).width(100).height(100)
|
||||
```
|
||||
|
||||
|
@ -95,13 +95,13 @@ ImageKnifeComponent({
|
|||
|
||||
```
|
||||
ImageKnifeComponent({
|
||||
ImageKnifeOption: new ImageKnifeOption({
|
||||
ImageKnifeOption: {
|
||||
loadSrc: "https://file.atomgit.com/uploads/user/1704857786989_8994.jpeg",
|
||||
placeholderSrc: $r("app.media.loading"),
|
||||
errorholderSrc: $r("app.media.app_icon"),
|
||||
objectFit: ImageFit.Auto,
|
||||
customGetImage: custom
|
||||
})
|
||||
}
|
||||
}).width(100).height(100)
|
||||
|
||||
// Custom implementation of the image acquisition method, such as custom network download。
|
||||
|
@ -117,33 +117,33 @@ async function custom(context: Context, src: string | PixelMap | Resource): Prom
|
|||
|
||||
```
|
||||
ImageKnifeComponent({
|
||||
ImageKnifeOption: new ImageKnifeOption({
|
||||
ImageKnifeOption: {
|
||||
loadSrc:"https://www.openharmony.cn/_nuxt/img/logo.dcf95b3.png",
|
||||
progressListener:(progress:number)=>{console.info("ImageKinfe:: call back progress = " + progress)}
|
||||
})
|
||||
}
|
||||
}).width(100).height(100)
|
||||
```
|
||||
|
||||
#### 6. Setting Border Options
|
||||
|
||||
```
|
||||
ImageKnifeComponent({ ImageKnifeOption: new ImageKnifeOption(
|
||||
ImageKnifeComponent({ ImageKnifeOption:
|
||||
{
|
||||
loadSrc: $r("app.media.rabbit"),
|
||||
border: {radius:50}
|
||||
})
|
||||
}
|
||||
}).width(100).height(100)
|
||||
```
|
||||
|
||||
#### 7. Setting Image Transformation Options
|
||||
|
||||
```
|
||||
ImageKnifeComponent({ ImageKnifeOption: new ImageKnifeOption(
|
||||
ImageKnifeComponent({ ImageKnifeOption:
|
||||
{
|
||||
loadSrc: $r("app.media.rabbit"),
|
||||
border: {radius:50},
|
||||
transformation: new BlurTransformation(3)
|
||||
})
|
||||
}
|
||||
}).width(100).height(100)
|
||||
```
|
||||
Multiple combined transformation usages:
|
||||
|
@ -153,14 +153,14 @@ let transformations: collections.Array<PixelMapTransformation> = new collections
|
|||
transformations.push(new BlurTransformation(5));
|
||||
transformations.push(new BrightnessTransformation(0.2));
|
||||
ImageKnifeComponent({
|
||||
imageKnifeOption: new ImageKnifeOption({
|
||||
imageKnifeOption: {
|
||||
loadSrc: $r('app.media.pngSample'),
|
||||
placeholderSrc: $r("app.media.loading"),
|
||||
errorholderSrc: $r("app.media.app_icon"),
|
||||
objectFit: ImageFit.Contain,
|
||||
border: { radius: { topLeft: 50, bottomRight: 50 } }, // Rounded corner settings
|
||||
transformation: transformations.length > 0 ? new MultiTransTransformation(transformations) : undefined // Graphic transformation group
|
||||
})
|
||||
}
|
||||
}).width(300)
|
||||
.height(300)
|
||||
.rotate ({angle: 90}) // Rotate by 90 degrees.
|
||||
|
@ -171,12 +171,12 @@ Other transformation-related properties can be stacked to achieve combined trans
|
|||
Example of circular cropping transformation:
|
||||
|
||||
```
|
||||
ImageKnifeComponent({ ImageKnifeOption:new ImageKnifeOption(
|
||||
ImageKnifeComponent({ ImageKnifeOption:
|
||||
{
|
||||
loadSrc: $r('app.media.pngSample'),
|
||||
objectFit: ImageFit.Cover,
|
||||
border: { radius: 150 }
|
||||
})
|
||||
}
|
||||
}).width(300)
|
||||
.height(300)
|
||||
```
|
||||
|
@ -184,12 +184,12 @@ ImageKnifeComponent({ ImageKnifeOption:new ImageKnifeOption(
|
|||
Example of Circular cropping with border transformation:
|
||||
|
||||
```
|
||||
ImageKnifeComponent({ ImageKnifeOption:new ImageKnifeOption(
|
||||
ImageKnifeComponent({ ImageKnifeOption:
|
||||
{
|
||||
loadSrc: $r('app.media.pngSample'),
|
||||
objectFit: ImageFit.Cover,
|
||||
border: { radius: 150, color: Color.Red, width: 5 }
|
||||
})
|
||||
}
|
||||
}).width(300)
|
||||
.height(300)
|
||||
```
|
||||
|
@ -198,9 +198,9 @@ Example of contrast filtering transformation:
|
|||
|
||||
```
|
||||
ImageKnifeComponent({
|
||||
imageKnifeOption: new ImageKnifeOption({
|
||||
imageKnifeOption: {
|
||||
loadSrc: $r('app.media.pngSample')
|
||||
})
|
||||
}
|
||||
}).width(300)
|
||||
.height(300)
|
||||
.contrast(12)
|
||||
|
@ -210,9 +210,9 @@ Example of rotation transformation:
|
|||
|
||||
```
|
||||
ImageKnifeComponent({
|
||||
imageKnifeOption: new ImageKnifeOption({
|
||||
imageKnifeOption:({
|
||||
loadSrc: $r('app.media.pngSample')
|
||||
})
|
||||
}
|
||||
}).width(300)
|
||||
.height(300)
|
||||
.rotate({angle:90})
|
||||
|
@ -222,7 +222,7 @@ ImageKnifeComponent({
|
|||
#### 8. Listening for Image Loading Success and Failure
|
||||
|
||||
```
|
||||
ImageKnifeComponent({ ImageKnifeOption: new ImageKnifeOption(
|
||||
ImageKnifeComponent({ ImageKnifeOption:
|
||||
{
|
||||
loadSrc: $r("app.media.rabbit"),
|
||||
onLoadListener:{
|
||||
|
@ -241,40 +241,29 @@ ImageKnifeComponent({ ImageKnifeOption: new ImageKnifeOption(
|
|||
console.info(err)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}).width(100).height(100)
|
||||
```
|
||||
#### 9. Use of syncLoad
|
||||
**syncLoad** sets whether to load the image synchronously. By default, the image is loaded asynchronously. When loading a small image, you are advised to set **syncLoad** to **true** so that the image loading can be quickly completed on the main thread.
|
||||
```
|
||||
ImageKnifeComponent({
|
||||
imageKnifeOption:new ImageKnifeOption({
|
||||
imageKnifeOption:{
|
||||
loadSrc:$r("app.media.pngSample"),
|
||||
placeholderSrc:$r("app.media.loading")
|
||||
}),syncLoad:true
|
||||
},syncLoad:true
|
||||
})
|
||||
```
|
||||
#### 10. Use of ImageKnifeAnimatorComponent
|
||||
```
|
||||
ImageKnifeAnimatorComponent({
|
||||
imageKnifeOption:new ImageKnifeOption({
|
||||
imageKnifeOption:{
|
||||
loadSrc:"https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658",
|
||||
placeholderSrc:$r('app.media.loading'),
|
||||
errorholderSrc:$r('app.media.failed')
|
||||
}),animatorOption:this.animatorOption
|
||||
},animatorOption:this.animatorOption
|
||||
}).width(300).height(300).backgroundColor(Color.Orange).margin({top:30})
|
||||
```
|
||||
#### 11.图片降采样 示例
|
||||
```
|
||||
ImageKnifeComponent({
|
||||
imageKnifeOption:new ImageKnifeOption({
|
||||
loadSrc:$r("app.media.pngSample"),
|
||||
placeholderSrc:$r('app.media.loading'),
|
||||
errorholderSrc:$r('app.media.failed'),
|
||||
downsampleOf: DownsampleStrategy.NONE
|
||||
}),animatorOption:this.animatorOption
|
||||
}).width(300).height(300)
|
||||
```
|
||||
#### Reuse Scenario
|
||||
Clear the component content in the **aboutToRecycle** lifecycle and trigger image loading through watch observeration.
|
||||
## Available APIs
|
||||
|
@ -319,17 +308,7 @@ Clear the component content in the **aboutToRecycle** lifecycle and trigger imag
|
|||
| drawingColorFilter | ColorFilter | Drawing color filter. Optional. |
|
||||
| onComplete | (event:EventImage \| undefined)=>void | Callback for image loading completion. Optional. |
|
||||
| onLoadListener | onLoadStart:()=>void,onLoadSuccess:(data:string\|Pixelmap)=>void | Callback for image loading events. Optional. |
|
||||
| downsampleOf | DownsampleStrategy | 降采样(可选) |
|
||||
### 降采样类型
|
||||
| 类型 | 相关描述 |
|
||||
|---------------------|-------------------|
|
||||
| NONE | 不进行降采样 |
|
||||
| AT_MOST | 请求尺寸大于实际尺寸不进行放大 |
|
||||
| FIT_CENTER_MEMORY | 两边自适应内存优先 |
|
||||
| FIT_CENTER_QUALITY | 两边自适应质量优先 |
|
||||
| CENTER_OUTSIDE_MEMORY | 宽高缩放比最大的比例,进行缩放适配内存优先 |
|
||||
| CENTER_OUTSIDE_QUALITY | 宽高缩放比最大的比例,进行缩放适配质量优先 |
|
||||
| AT_LEAST | 根据宽高的最小的比例,进行适配 |
|
||||
|
||||
### ImageKnife
|
||||
|
||||
| Parameter | Type | Description |
|
||||
|
@ -380,7 +359,7 @@ Method 2: Set the third-party HAR as a dependency in the **oh-package.json5** fi
|
|||
|
||||
This project has been verified in the following version:
|
||||
|
||||
DevEco Studio: 5.0 Canary3 (5.0.3.502), SDK: API 12 (5.0.0.31)
|
||||
DevEco Studio: NEXT Beta1-5.0.3.806, SDK: API12 Release(5.0.0.66)
|
||||
|
||||
## How to Contribute
|
||||
|
||||
|
|
119
README_zh.md
119
README_zh.md
|
@ -56,12 +56,12 @@ await ImageKnife.getInstance().initFileCache(context, 256, 256 * 1024 * 1024)
|
|||
|
||||
```
|
||||
ImageKnifeComponent({
|
||||
ImageKnifeOption: new ImageKnifeOption({
|
||||
ImageKnifeOption: {
|
||||
loadSrc: $r("app.media.app_icon"),
|
||||
placeholderSrc: $r("app.media.loading"),
|
||||
errorholderSrc: $r("app.media.app_icon"),
|
||||
objectFit: ImageFit.Auto
|
||||
})
|
||||
}
|
||||
}).width(100).height(100)
|
||||
```
|
||||
|
||||
|
@ -69,12 +69,12 @@ ImageKnifeComponent({
|
|||
|
||||
```
|
||||
ImageKnifeComponent({
|
||||
ImageKnifeOption: new ImageKnifeOption({
|
||||
ImageKnifeOption: {
|
||||
loadSrc: this.localFile,
|
||||
placeholderSrc: $r("app.media.loading"),
|
||||
errorholderSrc: $r("app.media.app_icon"),
|
||||
objectFit: ImageFit.Auto
|
||||
})
|
||||
}
|
||||
}).width(100).height(100)
|
||||
```
|
||||
|
||||
|
@ -82,12 +82,12 @@ ImageKnifeComponent({
|
|||
|
||||
```
|
||||
ImageKnifeComponent({
|
||||
ImageKnifeOption: new ImageKnifeOption({
|
||||
ImageKnifeOption: {
|
||||
loadSrc:"https://www.openharmony.cn/_nuxt/img/logo.dcf95b3.png",
|
||||
placeholderSrc: $r("app.media.loading"),
|
||||
errorholderSrc: $r("app.media.app_icon"),
|
||||
objectFit: ImageFit.Auto
|
||||
})
|
||||
}
|
||||
}).width(100).height(100)
|
||||
```
|
||||
|
||||
|
@ -95,13 +95,13 @@ ImageKnifeComponent({
|
|||
|
||||
```
|
||||
ImageKnifeComponent({
|
||||
ImageKnifeOption: new ImageKnifeOption({
|
||||
ImageKnifeOption: {
|
||||
loadSrc: "https://file.atomgit.com/uploads/user/1704857786989_8994.jpeg",
|
||||
placeholderSrc: $r("app.media.loading"),
|
||||
errorholderSrc: $r("app.media.app_icon"),
|
||||
objectFit: ImageFit.Auto,
|
||||
customGetImage: custom
|
||||
})
|
||||
}
|
||||
}).width(100).height(100)
|
||||
|
||||
// 自定义实现图片获取方法,如自定义网络下载
|
||||
|
@ -117,33 +117,33 @@ async function custom(context: Context, src: string | PixelMap | Resource): Prom
|
|||
|
||||
```
|
||||
ImageKnifeComponent({
|
||||
ImageKnifeOption: new ImageKnifeOption({
|
||||
ImageKnifeOption: {
|
||||
loadSrc:"https://www.openharmony.cn/_nuxt/img/logo.dcf95b3.png",
|
||||
progressListener:(progress:number)=>{console.info("ImageKinfe:: call back progress = " + progress)}
|
||||
})
|
||||
}
|
||||
}).width(100).height(100)
|
||||
```
|
||||
|
||||
#### 6.支持option传入border,设置边框,圆角
|
||||
|
||||
```
|
||||
ImageKnifeComponent({ ImageKnifeOption: new ImageKnifeOption(
|
||||
ImageKnifeComponent({ ImageKnifeOption:
|
||||
{
|
||||
loadSrc: $r("app.media.rabbit"),
|
||||
border: {radius:50}
|
||||
})
|
||||
}
|
||||
}).width(100).height(100)
|
||||
```
|
||||
|
||||
#### 7.支持option图片变换
|
||||
|
||||
```
|
||||
ImageKnifeComponent({ ImageKnifeOption: new ImageKnifeOption(
|
||||
ImageKnifeComponent({ ImageKnifeOption:
|
||||
{
|
||||
loadSrc: $r("app.media.rabbit"),
|
||||
border: {radius:50},
|
||||
transformation: new BlurTransformation(3)
|
||||
})
|
||||
}
|
||||
}).width(100).height(100)
|
||||
```
|
||||
多种组合变换用法
|
||||
|
@ -153,14 +153,14 @@ let transformations: collections.Array<PixelMapTransformation> = new collections
|
|||
transformations.push(new BlurTransformation(5));
|
||||
transformations.push(new BrightnessTransformation(0.2));
|
||||
ImageKnifeComponent({
|
||||
imageKnifeOption: new ImageKnifeOption({
|
||||
imageKnifeOption: {
|
||||
loadSrc: $r('app.media.pngSample'),
|
||||
placeholderSrc: $r("app.media.loading"),
|
||||
errorholderSrc: $r("app.media.app_icon"),
|
||||
objectFit: ImageFit.Contain,
|
||||
border: { radius: { topLeft: 50, bottomRight: 50 } }, // 圆角设置
|
||||
transformation: transformations.length > 0 ? new MultiTransTransformation(transformations) : undefined // 图形变换组
|
||||
})
|
||||
}
|
||||
}).width(300)
|
||||
.height(300)
|
||||
.rotate({ angle: 90 }) // 旋转90度
|
||||
|
@ -171,12 +171,12 @@ ImageKnifeComponent({
|
|||
圆形裁剪变换示例
|
||||
|
||||
```
|
||||
ImageKnifeComponent({ ImageKnifeOption:new ImageKnifeOption(
|
||||
ImageKnifeComponent({ ImageKnifeOption:
|
||||
{
|
||||
loadSrc: $r('app.media.pngSample'),
|
||||
objectFit: ImageFit.Cover,
|
||||
border: { radius: 150 }
|
||||
})
|
||||
}
|
||||
}).width(300)
|
||||
.height(300)
|
||||
```
|
||||
|
@ -184,12 +184,12 @@ ImageKnifeComponent({ ImageKnifeOption:new ImageKnifeOption(
|
|||
圆形裁剪带边框变换示例
|
||||
|
||||
```
|
||||
ImageKnifeComponent({ ImageKnifeOption:new ImageKnifeOption(
|
||||
ImageKnifeComponent({ ImageKnifeOption:
|
||||
{
|
||||
loadSrc: $r('app.media.pngSample'),
|
||||
objectFit: ImageFit.Cover,
|
||||
border: { radius: 150, color: Color.Red, width: 5 }
|
||||
})
|
||||
}
|
||||
}).width(300)
|
||||
.height(300)
|
||||
```
|
||||
|
@ -198,9 +198,9 @@ ImageKnifeComponent({ ImageKnifeOption:new ImageKnifeOption(
|
|||
|
||||
```
|
||||
ImageKnifeComponent({
|
||||
imageKnifeOption: new ImageKnifeOption({
|
||||
imageKnifeOption: {
|
||||
loadSrc: $r('app.media.pngSample')
|
||||
})
|
||||
}
|
||||
}).width(300)
|
||||
.height(300)
|
||||
.contrast(12)
|
||||
|
@ -210,9 +210,9 @@ ImageKnifeComponent({
|
|||
|
||||
```
|
||||
ImageKnifeComponent({
|
||||
imageKnifeOption: new ImageKnifeOption({
|
||||
imageKnifeOption: {
|
||||
loadSrc: $r('app.media.pngSample')
|
||||
})
|
||||
}
|
||||
}).width(300)
|
||||
.height(300)
|
||||
.rotate({angle:90})
|
||||
|
@ -222,7 +222,7 @@ ImageKnifeComponent({
|
|||
#### 8.监听图片加载成功与失败
|
||||
|
||||
```
|
||||
ImageKnifeComponent({ ImageKnifeOption: new ImageKnifeOption(
|
||||
ImageKnifeComponent({ ImageKnifeOption:
|
||||
{
|
||||
loadSrc: $r("app.media.rabbit"),
|
||||
onLoadListener:{
|
||||
|
@ -241,29 +241,60 @@ ImageKnifeComponent({ ImageKnifeOption: new ImageKnifeOption(
|
|||
console.info(err)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}).width(100).height(100)
|
||||
```
|
||||
#### 9.ImageKnifeComponent - syncLoad
|
||||
设置是否同步加载图片,默认是异步加载。建议加载尺寸较小的Resource图片时将syncLoad设为true,因为耗时较短,在主线程上执行即可
|
||||
```
|
||||
ImageKnifeComponent({
|
||||
imageKnifeOption:new ImageKnifeOption({
|
||||
imageKnifeOption:{
|
||||
loadSrc:$r("app.media.pngSample"),
|
||||
placeholderSrc:$r("app.media.loading")
|
||||
}),syncLoad:true
|
||||
},syncLoad:true
|
||||
})
|
||||
```
|
||||
#### 10.ImageKnifeAnimatorComponent 示例
|
||||
```
|
||||
ImageKnifeAnimatorComponent({
|
||||
imageKnifeOption:new ImageKnifeOption({
|
||||
imageKnifeOption: {
|
||||
loadSrc:"https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658",
|
||||
placeholderSrc:$r('app.media.loading'),
|
||||
errorholderSrc:$r('app.media.failed')
|
||||
}),animatorOption:this.animatorOption
|
||||
},animatorOption:this.animatorOption
|
||||
}).width(300).height(300).backgroundColor(Color.Orange).margin({top:30})
|
||||
```
|
||||
|
||||
#### 11.加载图片回调信息数据 示例
|
||||
```
|
||||
ImageKnifeComponent({ ImageKnifeOption: = new ImageKnifeOption({
|
||||
loadSrc: $r('app.media.pngSample'),
|
||||
objectFit: ImageFit.Contain,
|
||||
onLoadListener: {
|
||||
onLoadStart: (req) => {
|
||||
let startCallBackData = JSON.stringify(req?.getImageKnifeData());
|
||||
},
|
||||
onLoadFailed: (res, req) => {
|
||||
let failedBackData = res + ";" + JSON.stringify(req?.getImageKnifeData());
|
||||
},
|
||||
onLoadSuccess: (data, imageData, req) => {
|
||||
let successBackData = JSON.stringify(req?.getImageKnifeData());
|
||||
},
|
||||
onLoadCancel: (res, req) => {
|
||||
let cancelBackData = res + ";" + JSON.stringify(req?.getImageKnifeData());
|
||||
}
|
||||
},
|
||||
border: { radius: 50 },
|
||||
onComplete: (event) => {
|
||||
if (event && event.loadingStatus == 0) {
|
||||
let render_success = JSON.stringify(Date.now())
|
||||
}
|
||||
}
|
||||
})
|
||||
}).width(100).height(100)
|
||||
```
|
||||
|
||||
|
||||
#### 复用场景
|
||||
在aboutToRecycle生命周期清空组件内容;通过watch监听触发图片的加载。
|
||||
## 接口说明
|
||||
|
@ -288,7 +319,7 @@ ImageKnifeAnimatorComponent({
|
|||
### ImageKnifeOption参数列表
|
||||
|
||||
| 参数名称 | 入参内容 | 功能简介 |
|
||||
|-----------------------|-------------------------------------------------------|-----------------|
|
||||
|-----------------------|---------------------------------------------------------------------------------------------------------------------------------------|---------------|
|
||||
| loadSrc | string、PixelMap、Resource | 主图展示 |
|
||||
| placeholderSrc | PixelMap、Resource | 占位图图展示(可选) |
|
||||
| errorholderSrc | PixelMap、Resource | 错误图展示(可选) |
|
||||
|
@ -297,7 +328,7 @@ ImageKnifeAnimatorComponent({
|
|||
| errorholderObjectFit | ImageFit | 错误图填充效果(可选) |
|
||||
| writeCacheStrategy | CacheStrategyType | 写入缓存策略(可选) |
|
||||
| onlyRetrieveFromCache | boolean | 是否跳过网络和本地请求(可选) |
|
||||
| customGetImage | (context: Context, src: string | 自定义下载图片(可选) | | Resource | 错误占位图数据源 |
|
||||
| customGetImage | customGetImage?:(context: Context, src: string、PixelMap、Resource ,headers?: Record<string, Object>) => Promise<ArrayBuffer、undefined> | 自定义下载图片(可选) | | Resource | 错误占位图数据源 |
|
||||
| border | BorderOptions | 边框圆角(可选) |
|
||||
| priority | taskpool.Priority | 加载优先级(可选) |
|
||||
| context | common.UIAbilityContext | 上下文(可选) |
|
||||
|
@ -307,24 +338,40 @@ ImageKnifeAnimatorComponent({
|
|||
| transformation | PixelMapTransformation | 图片变换(可选) |
|
||||
| drawingColorFilter | ColorFilter | drawing.ColorFilter | 图片变换(可选) |
|
||||
| onComplete | (event:EventImage | undefined) => voi | 颜色滤镜效果(可选) |
|
||||
| onLoadListener | onLoadStart: () => void、onLoadSuccess: (data: string | PixelMap | undefined) => void、onLoadFailed: (err: string) => void| 监听图片加载成功与失败 |
|
||||
| onLoadListener | onLoadStart?: (req?: ImageKnifeRequest) => void,onLoadSuccess?: (data: string \| PixelMap \| undefined, imageData: ImageKnifeData, req?: ImageKnifeRequest) => void,onLoadFailed?: (err: string, req?: ImageKnifeRequest) => void,onLoadCancel?: (res: string, req?: ImageKnifeRequest) => void | 监听图片加载成功与失败 |
|
||||
|
||||
### ImageKnife接口
|
||||
|
||||
| 参数名称 | 入参内容 | 功能简介 |
|
||||
|------------------|-------------------------------------------------------------------------------------------------------|---------------|
|
||||
|-------------------|-------------------------------------------------------------------------------------------------------|------------------|
|
||||
| initMemoryCache | newMemoryCache: IMemoryCache | 自定义内存缓存策略 |
|
||||
| initFileCache | context: Context, size: number, memory: number | 初始化文件缓存数量和大小 |
|
||||
| reload | request: ImageKnifeRequest | 图片重新加载 |
|
||||
| preLoad | loadSrc: string I ImageKnifeOption | 预加载返回图片请求request |
|
||||
| cancel | request: ImageKnifeRequest | 取消图片请求 |
|
||||
| preLoadCache | loadSrc: string I ImageKnifeOption | 预加载并返回文件缓存路径 |
|
||||
| getCacheImage | loadSrc: string, cacheType: CacheStrategy = CacheStrategy.Default, signature?: string) | 从内存或文件缓存中获取资源 |
|
||||
| addHeader | key: string, value: Object | 全局添加http请求头 |
|
||||
| setHeaderOptions | Array<HeaderOptions> | 全局设置http请求头 |
|
||||
| deleteHeader | key: string | 全局删除http请求头 |
|
||||
| setCustomGetImage | customGetImage?: (context: Context, src: string | PixelMap | Resource) => Promise<ArrayBuffer | undefined> | 全局设置自定义下载 |
|
||||
| setCustomGetImage | customGetImage?: (context: Context, src: string、PixelMap、Resource ,headers?: Record<string, Object>) => Promise<ArrayBuffer、undefined> | PixelMap | Resource) => Promise<ArrayBuffer | undefined> | 全局设置自定义下载 |
|
||||
| setEngineKeyImpl | IEngineKey | 全局配置缓存key生成策略 |
|
||||
| putCacheImage | url: string, pixelMap: PixelMap, cacheType: CacheStrategy = CacheStrategy.Default, signature?: string | 写入内存磁盘缓存 |
|
||||
| removeMemoryCache | url: string | ImageKnifeOption | 清理指定内存缓存 |
|
||||
| removeFileCache | url: string | ImageKnifeOption | 清理指定磁盘缓存 |
|
||||
| getCacheLimitSize | cacheType?: CacheStrategy | 获取指定缓存的上限大小 |
|
||||
| getCurrentCacheNum | cacheType?: CacheStrategy | 获取指定缓存的当前缓存图片个数 |
|
||||
| getCurrentCacheSize | cacheType?: CacheStrategy | 获取指定缓存的当前大小 |
|
||||
| getCurrentCacheSize | cacheType?: CacheStrategy | 获取指定缓存的当前大小 |
|
||||
|
||||
### 回调接口说明
|
||||
| 回调接口 | 回调字段 | 回调描述 |
|
||||
|----------------|-------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| onLoadStart | req: ImageKnifeRequest | req返回字段中包含了图片请求的信息,如图片的url及其组件的宽高,同时ImageKnifeRequest包含了ImageKnifeData,其中包含此次请求的开始及其检查内存缓存的时间点 |
|
||||
| onLoadSuccess | data: string \| PixelMap \| undefined, imageData: ImageKnifeData, req?: ImageKnifeRequest | data:加载成功的结果数据;imageData:图片的存入缓存中的信息 ,req:图片请求的信息,同时其中的ImageKnifeData,包含此次请求中图片的原始大小、图片的解码大小、格式、图片帧、请求结束时间、磁盘检查时间、网络请求开始结束、图片解码开始结束等时间点 |
|
||||
| onLoadFailed | err: string, req?: ImageKnifeRequest | err:错误信息描述;req:图片请求的信息,同时其中的ImageKnifeData,包含此次请求错误信息(ErrorInfo,TimeInfo),ErrorInfo其中包含了,错误阶段、错误码及其网络请求的错误码;TimeInfo中包含请求结束时间、磁盘检查时间、网络请求开始结束、图片解码开始结束等时间点 |
|
||||
| onLoadCancel | reason: string, req?: ImageKnifeRequest | reason:取消回调原因;req:图片请求的信息,同时其中的ImageKnifeData,包含此次请求错误信息(ErrorInfo,TimeInfo),ErrorInfo其中包含了,错误阶段、错误码及其网络请求的错误码;TimeInfo中包含请求结束时间、磁盘检查时间、网络请求开始结束、图片解码开始结束及其请求取消等时间点 |
|
||||
|
||||
### 图形变换类型(需要为GPUImage添加依赖项)
|
||||
|
||||
| 类型 | 相关描述 |
|
||||
|
@ -358,7 +405,7 @@ ImageKnifeAnimatorComponent({
|
|||
## 约束与限制
|
||||
|
||||
在下述版本验证通过:
|
||||
DevEco Studio 5.0 Canary3(5.0.3.502)--SDK:API12 (5.0.0.31)
|
||||
DevEco Studio: NEXT Beta1-5.0.3.806, SDK: API12 Release(5.0.0.66)
|
||||
|
||||
## 贡献代码
|
||||
|
||||
|
|
|
@ -7,8 +7,9 @@
|
|||
{
|
||||
"name": "default",
|
||||
"signingConfig": "default",
|
||||
"compileSdkVersion": 12,
|
||||
"compatibleSdkVersion": 12
|
||||
"compileSdkVersion": "5.0.0(12)",
|
||||
"compatibleSdkVersion": "5.0.0(12)",
|
||||
"runtimeOS": "HarmonyOS",
|
||||
}
|
||||
],
|
||||
"buildModeSet": [
|
||||
|
@ -37,10 +38,6 @@
|
|||
"name": "library",
|
||||
"srcPath": "./library"
|
||||
},
|
||||
{
|
||||
"name": "gpu_transform",
|
||||
"srcPath": "./gpu_transform"
|
||||
},
|
||||
{
|
||||
"name": "sharedlibrary",
|
||||
"srcPath": "./sharedlibrary",
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { DownsampleStrategy } from '@ohos/imageknife';
|
||||
import { IEngineKey, ImageKnifeOption, PixelMapTransformation,SparkMD5 ,ImageKnifeRequestSource} from '@ohos/libraryimageknife';
|
||||
|
||||
//全局自定义key demo
|
||||
|
@ -36,9 +35,6 @@ export class CustomEngineKeyImpl implements IEngineKey {
|
|||
if (imageKnifeOption.transformation) {
|
||||
key += "transformation=" + this.getTransformation(imageKnifeOption.transformation) + ";"
|
||||
}
|
||||
if ((imageKnifeOption.downsampleOf !== DownsampleStrategy.NONE && imageKnifeOption.downsampleOf !== undefined)) {
|
||||
key += "downsampleOf" + imageKnifeOption.downsampleOf +"width="+width+"height="+ height
|
||||
}
|
||||
}
|
||||
return key
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ import hilog from '@ohos.hilog';
|
|||
import UIAbility from '@ohos.app.ability.UIAbility';
|
||||
import Want from '@ohos.app.ability.Want';
|
||||
import window from '@ohos.window';
|
||||
import { ImageKnife, InitImageKnife, LogUtil } from '@ohos/libraryimageknife';
|
||||
import { ImageKnife, InitImageKnife } from '@ohos/libraryimageknife';
|
||||
import { CustomEngineKeyImpl } from '../common/CustomEngineKeyImpl';
|
||||
import abilityAccessCtrl, { Permissions } from '@ohos.abilityAccessCtrl';
|
||||
import { BusinessError } from '@ohos.base'
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
* Copyright (C) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { InfoItem } from './model/DataSourcePrefetching';
|
||||
import { PageViewModel } from './model/PageViewModel';
|
||||
import { ImageKnifeComponent, ImageKnife } from '@ohos/libraryimageknife';
|
||||
import { CommonDataSource, GetSession } from './model/CommonDataSource';
|
||||
import { rcp } from '@kit.RemoteCommunicationKit';
|
||||
import { BusinessError } from '@kit.BasicServicesKit';
|
||||
|
||||
@Entry
|
||||
@Component
|
||||
export struct CustomNetImagePage {
|
||||
@State hotCommendList:CommonDataSource<InfoItem> = new CommonDataSource<InfoItem>([])
|
||||
aboutToAppear(): void {
|
||||
ImageKnife.getInstance().setMaxRequests(32)
|
||||
this.hotCommendList.addData(this.hotCommendList.totalCount(),PageViewModel.getItems())
|
||||
}
|
||||
aboutToDisappear(): void {
|
||||
ImageKnife.getInstance().setMaxRequests(8)
|
||||
}
|
||||
build() {
|
||||
Column() {
|
||||
WaterFlow() {
|
||||
LazyForEach(this.hotCommendList,(item: InfoItem)=>{
|
||||
FlowItem() {
|
||||
Column(){
|
||||
ImageKnifeComponent({
|
||||
imageKnifeOption: {
|
||||
loadSrc: item.albumUrl,
|
||||
placeholderSrc: $r("app.media.loading"),
|
||||
errorholderSrc: $r("app.media.failed"),
|
||||
customGetImage:custom
|
||||
}
|
||||
}).width("50%").height(200)
|
||||
}
|
||||
}.height(200)
|
||||
.backgroundColor("#95efd2")
|
||||
},(item: string) => item)
|
||||
}.columnsTemplate("1fr 1fr")
|
||||
.columnsGap(10)
|
||||
.rowsGap(5)
|
||||
.backgroundColor(0xFAEEE0)
|
||||
.width("100%").height("100%")
|
||||
}
|
||||
}
|
||||
}
|
||||
// 自定义下载方法
|
||||
@Concurrent
|
||||
async function custom(context: Context, src: string | PixelMap | Resource,headers?: Record<string,Object>): Promise<ArrayBuffer | undefined> {
|
||||
return new Promise((resolve,reject)=>{
|
||||
if (typeof src == "string") {
|
||||
let session = GetSession.session
|
||||
let req = new rcp.Request(src,"GET");
|
||||
session.fetch(req).then((response)=>{
|
||||
if(response.statusCode == 200) {
|
||||
let buffer = response.body
|
||||
resolve(buffer)
|
||||
} else {
|
||||
reject("rcp code:"+response.statusCode)
|
||||
}
|
||||
}).catch((err:BusinessError)=>{
|
||||
reject("error rcp src:"+src+",err:"+JSON.stringify(err))
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
|
@ -1,214 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { DownsampleStrategy, ImageKnifeOption, } from '@ohos/imageknife';
|
||||
import { ImageKnifeComponent } from '@ohos/libraryimageknife';
|
||||
import { image } from '@kit.ImageKit';
|
||||
import { BusinessError } from '@kit.BasicServicesKit';
|
||||
import { Downsampler } from '@ohos/imageknife/src/main/ets/downsampling/Downsampler';
|
||||
import { FileTypeUtil } from '@ohos/imageknife/src/main/ets/utils/FileTypeUtil';
|
||||
|
||||
@Entry
|
||||
@ComponentV2
|
||||
struct DownSamplePage {
|
||||
@Local imageKnifeOption: ImageKnifeOption = new ImageKnifeOption({
|
||||
loadSrc: $r('app.media.startIcon'),
|
||||
placeholderSrc: $r("app.media.loading"),
|
||||
errorholderSrc: $r("app.media.app_icon"),
|
||||
objectFit: ImageFit.Contain
|
||||
})
|
||||
isBrightness: boolean = false
|
||||
@Local beforeSampling: number = 0
|
||||
@Local afterSampling: number = 0
|
||||
@Local SamplingList: SamplingType[] = [
|
||||
|
||||
new SamplingType(7, "AT_LEAST"),
|
||||
new SamplingType(1, "AT_MOST"),
|
||||
|
||||
new SamplingType(2, "FIT_CENTER_MEMORY"),
|
||||
new SamplingType(4, "FIT_CENTER_QUALITY"),
|
||||
new SamplingType(5, "CENTER_OUTSIDE_MEMORY"),
|
||||
new SamplingType(6, "CENTER_OUTSIDE_QUALITY"),
|
||||
new SamplingType(0, "NONE"),
|
||||
|
||||
]
|
||||
@Local checked: boolean = false
|
||||
|
||||
updateImageKnifeOption(value: string) {
|
||||
if (value === 'NONE') {
|
||||
this.imageKnifeOption = new ImageKnifeOption({
|
||||
loadSrc: $r('app.media.pngSample'),
|
||||
placeholderSrc: $r("app.media.loading"),
|
||||
errorholderSrc: $r("app.media.app_icon"),
|
||||
objectFit: ImageFit.Contain,
|
||||
downsampleOf: DownsampleStrategy.NONE
|
||||
})
|
||||
this.originalPixMap($r('app.media.pngSample'))
|
||||
this.afterSamplingFunc($r('app.media.pngSample'))
|
||||
} else if (value === 'AT_MOST') {
|
||||
this.imageKnifeOption = new ImageKnifeOption({
|
||||
loadSrc: $r('app.media.pngSample'),
|
||||
placeholderSrc: $r("app.media.loading"),
|
||||
errorholderSrc: $r("app.media.app_icon"),
|
||||
objectFit: ImageFit.Contain,
|
||||
downsampleOf: DownsampleStrategy.AT_MOST
|
||||
})
|
||||
this.originalPixMap($r('app.media.pngSample'))
|
||||
this.afterSamplingFunc($r('app.media.pngSample'))
|
||||
} else if (value === 'FIT_CENTER_MEMORY') {
|
||||
this.imageKnifeOption = new ImageKnifeOption({
|
||||
loadSrc: $r('app.media.pngSample'),
|
||||
placeholderSrc: $r("app.media.loading"),
|
||||
errorholderSrc: $r("app.media.app_icon"),
|
||||
objectFit: ImageFit.Contain,
|
||||
downsampleOf: DownsampleStrategy.FIT_CENTER_MEMORY
|
||||
})
|
||||
this.originalPixMap($r('app.media.pngSample'))
|
||||
this.afterSamplingFunc($r('app.media.pngSample'))
|
||||
} else if (value === 'FIT_CENTER_QUALITY') {
|
||||
this.imageKnifeOption = new ImageKnifeOption({
|
||||
loadSrc: $r('app.media.pngSample'),
|
||||
placeholderSrc: $r("app.media.loading"),
|
||||
errorholderSrc: $r("app.media.app_icon"),
|
||||
objectFit: ImageFit.Contain,
|
||||
downsampleOf: DownsampleStrategy.FIT_CENTER_QUALITY
|
||||
})
|
||||
this.originalPixMap($r('app.media.pngSample'))
|
||||
this.afterSamplingFunc($r('app.media.pngSample'))
|
||||
} else if (value === 'CENTER_OUTSIDE_MEMORY') {
|
||||
this.imageKnifeOption = new ImageKnifeOption({
|
||||
loadSrc: $r('app.media.pngSample'),
|
||||
placeholderSrc: $r("app.media.loading"),
|
||||
errorholderSrc: $r("app.media.app_icon"),
|
||||
objectFit: ImageFit.Contain,
|
||||
downsampleOf: DownsampleStrategy.CENTER_OUTSIDE_MEMORY
|
||||
})
|
||||
this.originalPixMap($r('app.media.pngSample'))
|
||||
this.afterSamplingFunc($r('app.media.pngSample'))
|
||||
} else if (value === 'CENTER_OUTSIDE_QUALITY') {
|
||||
this.imageKnifeOption = new ImageKnifeOption({
|
||||
loadSrc: $r('app.media.pngSample'),
|
||||
placeholderSrc: $r("app.media.loading"),
|
||||
errorholderSrc: $r("app.media.app_icon"),
|
||||
objectFit: ImageFit.Contain,
|
||||
downsampleOf: DownsampleStrategy.CENTER_OUTSIDE_QUALITY
|
||||
})
|
||||
this.originalPixMap($r('app.media.pngSample'))
|
||||
this.afterSamplingFunc($r('app.media.pngSample'))
|
||||
} else {
|
||||
this.imageKnifeOption = new ImageKnifeOption({
|
||||
loadSrc: $r('app.media.pngSample'),
|
||||
placeholderSrc: $r("app.media.loading"),
|
||||
errorholderSrc: $r("app.media.app_icon"),
|
||||
objectFit: ImageFit.Contain,
|
||||
downsampleOf: DownsampleStrategy.AT_LEAST
|
||||
})
|
||||
this.originalPixMap($r('app.media.pngSample'))
|
||||
this.afterSamplingFunc($r('app.media.pngSample'))
|
||||
}
|
||||
}
|
||||
|
||||
async afterSamplingFunc(imgs: Resource) {
|
||||
let img: Uint8Array = await getContext(this).resourceManager.getMediaContent(imgs);
|
||||
let imageSource: image.ImageSource = image.createImageSource(img.buffer.slice(0));
|
||||
let fileTypeUtil = new FileTypeUtil();
|
||||
let typeValue = fileTypeUtil.getFileType(img.buffer.slice(0)) as string;
|
||||
let decodingOptions: image.DecodingOptions = {
|
||||
editable: true,
|
||||
desiredPixelFormat: 3,
|
||||
}
|
||||
let imageInfo = await imageSource.getImageInfo()
|
||||
|
||||
if (this.imageKnifeOption.downsampleOf !== DownsampleStrategy.NONE){
|
||||
let reqSize =
|
||||
new Downsampler().calculateScaling(typeValue, imageInfo.size.width, imageInfo.size.height, 300,
|
||||
300, this.imageKnifeOption.downsampleOf)
|
||||
decodingOptions = {
|
||||
editable: true,
|
||||
desiredSize: {
|
||||
width: reqSize.width,
|
||||
height: reqSize.height
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 创建pixelMap
|
||||
imageSource.createPixelMap(decodingOptions).then((pixelMap: image.PixelMap) => {
|
||||
this.afterSampling = pixelMap.getPixelBytesNumber()
|
||||
}).catch((err: BusinessError) => {
|
||||
console.error("Failed to create PixelMap")
|
||||
});
|
||||
}
|
||||
|
||||
async originalPixMap(imgs: Resource,) {
|
||||
let img: Uint8Array = await getContext(this).resourceManager.getMediaContent(imgs);
|
||||
let imageSource: image.ImageSource = image.createImageSource(img.buffer.slice(0));
|
||||
let decodingOptions: image.DecodingOptions = {
|
||||
editable: true,
|
||||
desiredPixelFormat: 3,
|
||||
}
|
||||
// 创建pixelMap
|
||||
imageSource.createPixelMap(decodingOptions).then((pixelMap: image.PixelMap) => {
|
||||
this.beforeSampling = pixelMap.getPixelBytesNumber()
|
||||
}).catch((err: BusinessError) => {
|
||||
console.error("Failed to create PixelMap")
|
||||
});
|
||||
}
|
||||
getResourceString(res:Resource){
|
||||
return getContext().resourceManager.getStringSync(res.id)
|
||||
}
|
||||
build() {
|
||||
Scroll() {
|
||||
Column() {
|
||||
ForEach(this.SamplingList, (item: SamplingType, index) => {
|
||||
Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
|
||||
Radio({ value: item.value + 'radio', group: 'radioGroup' })
|
||||
.height(50)
|
||||
.width(50)
|
||||
.checked(this.checked)
|
||||
.onClick(() => {
|
||||
this.updateImageKnifeOption(item.value)
|
||||
})
|
||||
Text(this.getResourceString($r('app.string.Sampling_pecification'))+ item.value).fontSize(20)
|
||||
}
|
||||
}, (item: SamplingType) => JSON.stringify(item))
|
||||
Column() {
|
||||
Text(`${this.getResourceString($r('app.string.Unreal_samples'))}:${this.beforeSampling}`).fontSize(20)
|
||||
Text(`${ this.getResourceString($r('app.string.After_the_sampling'))}:${this.afterSampling}`).fontSize(20)
|
||||
}
|
||||
|
||||
ImageKnifeComponent({
|
||||
imageKnifeOption: this.imageKnifeOption
|
||||
})
|
||||
.height(300)
|
||||
.width(300)
|
||||
.borderWidth(1)
|
||||
.borderColor(Color.Pink)
|
||||
}
|
||||
|
||||
}
|
||||
.height('100%')
|
||||
.width('100%')
|
||||
}
|
||||
}
|
||||
|
||||
class SamplingType {
|
||||
key: number
|
||||
value: string
|
||||
|
||||
constructor(key: number, value: string) {
|
||||
this.key = key
|
||||
this.value = value
|
||||
}
|
||||
}
|
|
@ -12,14 +12,14 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { AnimatorOption, ImageKnifeAnimatorComponent,ImageKnifeOption } from "@ohos/libraryimageknife"
|
||||
import { AnimatorOption, ImageKnifeAnimatorComponent } from "@ohos/libraryimageknife"
|
||||
|
||||
@Entry
|
||||
@ComponentV2
|
||||
@Component
|
||||
struct ImageAnimatorPage {
|
||||
@Local animatorOption: AnimatorOption = new AnimatorOption({
|
||||
@State animatorOption: AnimatorOption = {
|
||||
state: AnimationStatus.Running,
|
||||
iterations: -1,
|
||||
iterations: 1,
|
||||
onFinish:()=>{
|
||||
console.log("ImageKnifeAnimatorComponent animatorOption onFinish")
|
||||
},
|
||||
|
@ -35,14 +35,14 @@ struct ImageAnimatorPage {
|
|||
onRepeat:()=>{
|
||||
console.log("ImageKnifeAnimatorComponent animatorOption onRepeat")
|
||||
}
|
||||
})
|
||||
@Local animatorOption1: AnimatorOption = new AnimatorOption({
|
||||
}
|
||||
@State animatorOption1: AnimatorOption = {
|
||||
state: AnimationStatus.Initial
|
||||
})
|
||||
@Local animatorOption2: AnimatorOption = new AnimatorOption({
|
||||
}
|
||||
@State animatorOption2: AnimatorOption = {
|
||||
state: AnimationStatus.Initial,
|
||||
reverse: true
|
||||
})
|
||||
}
|
||||
build() {
|
||||
Column(){
|
||||
Flex(){
|
||||
|
@ -66,27 +66,27 @@ struct ImageAnimatorPage {
|
|||
})
|
||||
}
|
||||
ImageKnifeAnimatorComponent({
|
||||
imageKnifeOption:new ImageKnifeOption({
|
||||
imageKnifeOption:{
|
||||
loadSrc:"https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658",
|
||||
placeholderSrc:$r('app.media.loading'),
|
||||
errorholderSrc:$r('app.media.failed')
|
||||
}),animatorOption:this.animatorOption
|
||||
}).width(200).height(200).backgroundColor(Color.Orange).margin({top:30})
|
||||
},animatorOption:this.animatorOption
|
||||
}).width(300).height(300).backgroundColor(Color.Orange).margin({top:30})
|
||||
Text($r('app.string.Display_the_first_frame')).fontSize(20)
|
||||
ImageKnifeAnimatorComponent({
|
||||
imageKnifeOption:new ImageKnifeOption({
|
||||
imageKnifeOption:{
|
||||
loadSrc:"https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658",
|
||||
placeholderSrc:$r('app.media.loading'),
|
||||
errorholderSrc:$r('app.media.failed')
|
||||
}),animatorOption:this.animatorOption1
|
||||
},animatorOption:this.animatorOption1
|
||||
}).width(200).height(200).backgroundColor(Color.Orange).margin({top:30})
|
||||
Text($r('app.string.Display_the_last_frame')).fontSize(20)
|
||||
ImageKnifeAnimatorComponent({
|
||||
imageKnifeOption:new ImageKnifeOption({
|
||||
imageKnifeOption:{
|
||||
loadSrc:"https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658",
|
||||
placeholderSrc:$r('app.media.loading'),
|
||||
errorholderSrc:$r('app.media.failed')
|
||||
}),animatorOption:this.animatorOption2
|
||||
},animatorOption:this.animatorOption2
|
||||
}).width(200).height(200).backgroundColor(Color.Orange).margin({top:30})
|
||||
}.width("100%").height("100%")
|
||||
}
|
||||
|
|
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
* Copyright (C) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { connection } from '@kit.NetworkKit'
|
||||
import { List } from '@kit.ArkTS'
|
||||
import { ImageKnifeRequest,ImageKnife,ImageKnifeComponent } from '@ohos/libraryimageknife'
|
||||
|
||||
@Entry
|
||||
@Component
|
||||
struct ImageKnifeReload {
|
||||
aboutToAppear(): void {
|
||||
NetWatchState.init()
|
||||
}
|
||||
build() {
|
||||
Column() {
|
||||
ImageKnifeComponent({
|
||||
imageKnifeOption:{
|
||||
loadSrc:"https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp",
|
||||
placeholderSrc:$r('app.media.loading'),
|
||||
errorholderSrc:$r('app.media.failed'),
|
||||
onLoadListener:{
|
||||
onLoadFailed(err,request){
|
||||
NetWatchState.requestList.add(request)
|
||||
}
|
||||
}
|
||||
}
|
||||
}).width(200).height(200)
|
||||
ImageKnifeComponent({
|
||||
imageKnifeOption:{
|
||||
loadSrc:"https://img-blog.csdn.net/20140514114029140",
|
||||
placeholderSrc:$r('app.media.loading'),
|
||||
errorholderSrc:$r('app.media.failed'),
|
||||
onLoadListener:{
|
||||
onLoadFailed(err,request){
|
||||
NetWatchState.requestList.add(request)
|
||||
}
|
||||
}
|
||||
}
|
||||
}).width(200).height(200).margin({top:10})
|
||||
}.width("100%")
|
||||
.height("100%")
|
||||
}
|
||||
}
|
||||
|
||||
class NetWatchState {
|
||||
public static netConnection: connection.NetConnection | undefined = undefined
|
||||
public static requestList: List<ImageKnifeRequest> = new List()
|
||||
|
||||
static init() {
|
||||
NetWatchState.netConnection = connection.createNetConnection()
|
||||
// 注册订阅事件
|
||||
NetWatchState.netConnection.register(()=>{
|
||||
})
|
||||
// 订阅网络能力变化事件。调用register后,才能接收到此事件通知
|
||||
NetWatchState.netConnection.on("netCapabilitiesChange",(data:connection.NetCapabilityInfo)=>{
|
||||
if(NetWatchState.requestList.length > 0 && data.netHandle.netId >= 100) {
|
||||
NetWatchState.requestList.forEach((request)=>{
|
||||
ImageKnife.getInstance().reload(request)
|
||||
NetWatchState.requestList.remove(request)
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
static cancel(){
|
||||
if(NetWatchState.netConnection != undefined) {
|
||||
// 取消订阅
|
||||
NetWatchState.netConnection.unregister(()=>{})
|
||||
}
|
||||
}
|
||||
}
|
|
@ -35,17 +35,17 @@ import {
|
|||
import { collections } from '@kit.ArkTS'
|
||||
|
||||
@Entry
|
||||
@ComponentV2
|
||||
@Component
|
||||
struct ImageTransformation {
|
||||
@Local imageKnifeOption: ImageKnifeOption = new ImageKnifeOption({
|
||||
@State imageKnifeOption: ImageKnifeOption = {
|
||||
loadSrc: $r('app.media.pngSample'),
|
||||
placeholderSrc: $r("app.media.loading"),
|
||||
errorholderSrc: $r("app.media.app_icon"),
|
||||
objectFit: ImageFit.Contain
|
||||
})
|
||||
@Local isRound: boolean = false;
|
||||
@Local isContrast: boolean = false;
|
||||
@Local isRotate: boolean = false;
|
||||
}
|
||||
@State isRound: boolean = false;
|
||||
@State isContrast: boolean = false;
|
||||
@State isRotate: boolean = false;
|
||||
isBlur: boolean = false
|
||||
isBrightness: boolean = false
|
||||
isGrayScale: boolean = false;
|
||||
|
@ -412,14 +412,14 @@ struct ImageTransformation {
|
|||
if (this.isMask) {
|
||||
transformations.push(new MaskTransformation($r('app.media.mask_starfish')));
|
||||
}
|
||||
this.imageKnifeOption = new ImageKnifeOption({
|
||||
this.imageKnifeOption = {
|
||||
loadSrc: $r('app.media.pngSample'),
|
||||
placeholderSrc: $r("app.media.loading"),
|
||||
errorholderSrc: $r("app.media.app_icon"),
|
||||
objectFit: ImageFit.Contain,
|
||||
border: { radius: this.isRound ? { topLeft: 50, bottomRight: 50 } : 0 },
|
||||
transformation: transformations.length > 0 ? new MultiTransTransformation(transformations) : undefined
|
||||
})
|
||||
}
|
||||
if (this.isCropCircle) {
|
||||
this.imageKnifeOption.objectFit = ImageFit.Cover;
|
||||
this.imageKnifeOption.border = { radius: 150 };
|
||||
|
|
|
@ -15,12 +15,14 @@
|
|||
import router from '@system.router';
|
||||
|
||||
@Entry
|
||||
@ComponentV2
|
||||
@Component
|
||||
struct Index {
|
||||
|
||||
getResourceString(res:Resource){
|
||||
return getContext().resourceManager.getStringSync(res.id)
|
||||
}
|
||||
|
||||
|
||||
aboutToAppear(): void {
|
||||
|
||||
}
|
||||
|
@ -33,16 +35,39 @@ struct Index {
|
|||
uri: 'pages/ImageAnimatorPage',
|
||||
});
|
||||
})
|
||||
Button($r('app.string.Network_reload')).margin({top:10}).onClick(()=>{
|
||||
router.push({
|
||||
uri: 'pages/ImageKnifeReload',
|
||||
});
|
||||
})
|
||||
Button($r('app.string.preloading_prefetch')).margin({top:10}).onClick(()=>{
|
||||
router.push({
|
||||
uri: 'pages/PrefetchAndCacheCount',
|
||||
});
|
||||
})
|
||||
Button($r('app.string.request_concurrency')).margin({top:10}).onClick(()=>{
|
||||
router.push({
|
||||
uri: 'pages/SetMaxRequestPage',
|
||||
});
|
||||
})
|
||||
Button($r('app.string.Test_multiple_images')).margin({top:10}).onClick(()=>{
|
||||
router.push({
|
||||
uri: 'pages/TestCommonImage',
|
||||
});
|
||||
})
|
||||
Button(this.getResourceString($r('app.string.Multiple_images')) + " + reuse + LazyForeach")
|
||||
.margin({ top: 10 })
|
||||
.onClick(() => {
|
||||
Button($r('app.string.Customize_RCP_network')).margin({top:10}).onClick(()=>{
|
||||
router.push({
|
||||
uri: 'pages/UserPage',
|
||||
uri: 'pages/CustomNetImagePage',
|
||||
});
|
||||
})
|
||||
Button($r('app.string.Test_Task_error')).margin({top:10}).onClick(()=>{
|
||||
router.push({
|
||||
uri: 'pages/TestTaskResourcePage',
|
||||
});
|
||||
})
|
||||
Button($r('app.string.Test_HSP')).margin({top:10}).onClick(()=>{
|
||||
router.push({
|
||||
uri: 'pages/TestHspPreLoadImage',
|
||||
|
||||
});
|
||||
})
|
||||
|
@ -52,9 +77,22 @@ struct Index {
|
|||
|
||||
});
|
||||
})
|
||||
Button($r('app.string.Image_Downsampling_Functionality')).margin({top:10}).onClick(()=>{
|
||||
Button($r('app.string.Test_custom_download')).margin({top:10}).onClick(()=>{
|
||||
router.push({
|
||||
uri: 'pages/DownSamplePage',
|
||||
uri: 'pages/TestSetCustomImagePage',
|
||||
|
||||
});
|
||||
})
|
||||
// Button(this.getResourceString($r('app.string.Multiple_images')) + " + LazyForEach").margin({top:10}).onClick(()=>{
|
||||
// router.push({
|
||||
// uri: 'pages/ManyPhotoShowPage',
|
||||
//
|
||||
// });
|
||||
// })
|
||||
Button(this.getResourceString($r('app.string.Multiple_images')) + " + reuse + LazyForeach").margin({top:10}).onClick(()=>{
|
||||
router.push({
|
||||
uri: 'pages/UserPage',
|
||||
|
||||
});
|
||||
})
|
||||
Button($r('app.string.Display_long_image')).margin({top:10}).onClick(()=>{
|
||||
|
@ -63,25 +101,17 @@ struct Index {
|
|||
|
||||
});
|
||||
})
|
||||
Button($r('app.string.Image_Transformation')).margin({ top: 10 }).onClick(() => {
|
||||
Button($r('app.string.Image_scaling')).margin({top:10}).onClick(()=>{
|
||||
router.push({
|
||||
uri: 'pages/ImageTransformation',
|
||||
|
||||
});
|
||||
|
||||
})
|
||||
Button($r('app.string.Test_media_URL')).margin({ top: 10 }).onClick(() => {
|
||||
router.push({
|
||||
uri: 'pages/dataShareUriLoadPage',
|
||||
uri: 'pages/TransformPage',
|
||||
|
||||
});
|
||||
})
|
||||
Button($r('app.string.Different_ObjectFit')).margin({ top: 10 }).onClick(() => {
|
||||
Button(this.getResourceString($r('app.string.Message_list')) + " + List").margin({top:10}).onClick(()=>{
|
||||
router.push({
|
||||
uri: 'pages/ObjectFitPage',
|
||||
uri: 'pages/TestImageFlash',
|
||||
|
||||
});
|
||||
|
||||
})
|
||||
Button($r('app.string.Custom_cache_key')).margin({top:10}).onClick(()=>{
|
||||
router.push({
|
||||
|
@ -89,39 +119,6 @@ struct Index {
|
|||
|
||||
});
|
||||
})
|
||||
Button($r('app.string.Test_image_loading_success_or_failure_events')).margin({ top: 10 }).onClick(() => {
|
||||
router.push({
|
||||
uri: 'pages/LoadStatePage',
|
||||
})
|
||||
})
|
||||
Button($r('app.string.Image_scaling')).margin({ top: 10 }).onClick(() => {
|
||||
router.push({
|
||||
uri: 'pages/TransformPage',
|
||||
|
||||
});
|
||||
})
|
||||
|
||||
Button($r('app.string.Test_HSP')).margin({ top: 10 }).onClick(() => {
|
||||
router.push({
|
||||
uri: 'pages/TestHspPreLoadImage',
|
||||
|
||||
});
|
||||
})
|
||||
|
||||
Button($r('app.string.Test_custom_download')).margin({ top: 10 }).onClick(() => {
|
||||
router.push({
|
||||
uri: 'pages/TestSetCustomImagePage',
|
||||
|
||||
});
|
||||
})
|
||||
|
||||
Button(this.getResourceString($r('app.string.Message_list')) + " + List").margin({ top: 10 }).onClick(() => {
|
||||
router.push({
|
||||
uri: 'pages/TestImageFlash',
|
||||
|
||||
});
|
||||
})
|
||||
|
||||
Button($r('app.string.Preloading_images_to_cache')).margin({top:10}).onClick(()=>{
|
||||
router.push({
|
||||
uri: 'pages/TestPrefetchToFileCache',
|
||||
|
@ -146,7 +143,27 @@ struct Index {
|
|||
|
||||
});
|
||||
})
|
||||
Button($r('app.string.Image_Transformation')).margin({top:10}).onClick(()=>{
|
||||
router.push({
|
||||
uri: 'pages/ImageTransformation',
|
||||
|
||||
});
|
||||
|
||||
})
|
||||
|
||||
Button($r('app.string.Different_ObjectFit')).margin({top:10}).onClick(()=>{
|
||||
router.push({
|
||||
uri: 'pages/ObjectFitPage',
|
||||
|
||||
});
|
||||
|
||||
})
|
||||
|
||||
Button($r('app.string.Test_image_loading_success_or_failure_events')).margin({top:10}).onClick(()=>{
|
||||
router.push({
|
||||
uri: 'pages/LoadStatePage',
|
||||
})
|
||||
})
|
||||
|
||||
Button($r('app.string.Test_removing_image_cache_interface')).margin({top:10}).onClick(()=>{
|
||||
router.push({
|
||||
|
@ -159,9 +176,10 @@ struct Index {
|
|||
|
||||
});
|
||||
})
|
||||
Button($r('app.string.Test_Task_error')).margin({ top: 10 }).onClick(() => {
|
||||
Button($r('app.string.Test_media_URL')).margin({top:10}).onClick(()=>{
|
||||
router.push({
|
||||
uri: 'pages/TestTaskResourcePage',
|
||||
uri: 'pages/dataShareUriLoadPage',
|
||||
|
||||
});
|
||||
})
|
||||
Button($r('app.string.test_cache_btn')).margin({ top: 10 }).onClick(() => {
|
||||
|
@ -179,6 +197,12 @@ struct Index {
|
|||
uri: 'pages/TestLoadCancelListenerPage',
|
||||
});
|
||||
})
|
||||
Button($r('app.string.test_callback')).margin({ top: 10 }).onClick(() => {
|
||||
router.push({
|
||||
uri: 'pages/TestImageKnifeCallbackPage',
|
||||
|
||||
});
|
||||
})
|
||||
}
|
||||
} .width('100%')
|
||||
.height('100%')
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* Copyright (C) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { InfoItem } from './model/DataSourcePrefetching';
|
||||
import { PageViewModel } from './model/PageViewModel';
|
||||
import { ImageKnifeComponent, ImageKnifeOption } from '@ohos/libraryimageknife';
|
||||
import { CommonDataSource } from './model/CommonDataSource';
|
||||
|
||||
@Entry
|
||||
@Component
|
||||
export struct LazyForEachCache {
|
||||
@State hotCommendList:CommonDataSource<InfoItem> = new CommonDataSource<InfoItem>([])
|
||||
aboutToAppear(): void {
|
||||
this.hotCommendList.addData(this.hotCommendList.totalCount(),PageViewModel.getItems())
|
||||
}
|
||||
build() {
|
||||
Column() {
|
||||
List({ space: 16 }) {
|
||||
LazyForEach(this.hotCommendList, (item: InfoItem,index) => {
|
||||
ListItem() {
|
||||
Column({ space: 12 }) {
|
||||
ImageKnifeComponent({
|
||||
imageKnifeOption:{
|
||||
loadSrc: item.albumUrl,
|
||||
placeholderSrc:$r('app.media.loading')
|
||||
}
|
||||
}).width(100).height(100)
|
||||
Text(`${index}`)
|
||||
}.border({ width: 5 , color: "#000000"})
|
||||
}
|
||||
})
|
||||
}
|
||||
.cachedCount(5)
|
||||
.width("100%")
|
||||
.height("100%")
|
||||
.margin({ left: 10, right: 10 })
|
||||
.layoutWeight(1)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* Copyright (C) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { InfoItem } from './model/DataSourcePrefetching';
|
||||
import { PageViewModel } from './model/PageViewModel';
|
||||
import { ImageKnifeComponent, ImageKnifeOption } from '@ohos/libraryimageknife';
|
||||
import { CommonDataSource } from './model/CommonDataSource';
|
||||
|
||||
@Entry
|
||||
@Component
|
||||
export struct LazyForEachCount {
|
||||
@State hotCommendList:CommonDataSource<InfoItem> = new CommonDataSource<InfoItem>([])
|
||||
aboutToAppear(): void {
|
||||
this.hotCommendList.addData(this.hotCommendList.totalCount(),PageViewModel.getItems())
|
||||
}
|
||||
build() {
|
||||
Column() {
|
||||
List({ space: 16 }) {
|
||||
LazyForEach(this.hotCommendList, (item: InfoItem,index) => {
|
||||
ListItem() {
|
||||
Column({ space: 12 }) {
|
||||
ImageKnifeComponent({
|
||||
imageKnifeOption:{
|
||||
loadSrc: item.albumUrl,
|
||||
placeholderSrc:$r('app.media.loading')
|
||||
}
|
||||
}).width(100).height(100)
|
||||
Text(`${index}`)
|
||||
}.border({ width: 5 , color: "#000000"})
|
||||
}
|
||||
})
|
||||
}
|
||||
.cachedCount(30)
|
||||
.width("100%")
|
||||
.height("100%")
|
||||
.margin({ left: 10, right: 10 })
|
||||
.layoutWeight(1)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -15,11 +15,11 @@
|
|||
import { ImageKnifeComponent, ImageKnifeOption } from '@ohos/libraryimageknife';
|
||||
|
||||
@Entry
|
||||
@ComponentV2
|
||||
@Component
|
||||
struct ListPage {
|
||||
|
||||
private data: string[] = []
|
||||
@Local ImageKnifeOption: ImageKnifeOption = new ImageKnifeOption({ loadSrc: $r('app.media.startIcon')})
|
||||
@State ImageKnifeOption: ImageKnifeOption = { loadSrc: $r('app.media.startIcon')}
|
||||
|
||||
|
||||
aboutToAppear(): void {
|
||||
|
|
|
@ -16,12 +16,12 @@ import { ImageKnifeComponent, ImageKnifeOption } from "@ohos/libraryimageknife"
|
|||
import matrix4 from '@ohos.matrix4'
|
||||
|
||||
@Entry
|
||||
@ComponentV2
|
||||
@Component
|
||||
struct LoadStatePage {
|
||||
|
||||
starTime:number = new Date().getTime()
|
||||
|
||||
@Local ImageKnifeOption: ImageKnifeOption = new ImageKnifeOption({
|
||||
@State ImageKnifeOption: ImageKnifeOption = {
|
||||
loadSrc: $r("app.media.rabbit"),
|
||||
placeholderSrc: $r("app.media.loading"),
|
||||
errorholderSrc: $r("app.media.app_icon"),
|
||||
|
@ -35,14 +35,14 @@ struct LoadStatePage {
|
|||
},
|
||||
},
|
||||
border: { radius: 50 }
|
||||
})
|
||||
@Local imageKnifeOption1: ImageKnifeOption = new ImageKnifeOption({
|
||||
}
|
||||
@State imageKnifeOption1: ImageKnifeOption = {
|
||||
loadSrc: $r('app.media.startIcon')
|
||||
})
|
||||
@Local message: string = ""
|
||||
@Local currentWidth: number = 200
|
||||
@Local currentHeight: number = 200
|
||||
@Local typeValue: string = ""
|
||||
}
|
||||
@State message: string = ""
|
||||
@State currentWidth: number = 200
|
||||
@State currentHeight: number = 200
|
||||
@State typeValue: string = ""
|
||||
build() {
|
||||
Column() {
|
||||
Text($r('app.string.TIPS'))
|
||||
|
@ -50,7 +50,7 @@ struct LoadStatePage {
|
|||
Row() {
|
||||
Button($r('app.string.Test_failure_success'))
|
||||
.onClick(() => {
|
||||
this.ImageKnifeOption = new ImageKnifeOption({
|
||||
this.ImageKnifeOption = {
|
||||
loadSrc: "https://www.openharmony.cn/_nuxt/img/logo.dcf95b3.png",
|
||||
placeholderSrc: $r("app.media.loading"),
|
||||
errorholderSrc: $r("app.media.app_icon"),
|
||||
|
@ -75,7 +75,7 @@ struct LoadStatePage {
|
|||
onComplete:(event)=>{
|
||||
console.error("Load onComplete width:"+event?.width , " height:"+event?.height , " componentWidth:"+event?.componentWidth," componentHeight:" + event?.componentHeight);
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
.margin({ top: 20 })
|
||||
|
@ -85,7 +85,7 @@ struct LoadStatePage {
|
|||
ImageKnifeComponent({ imageKnifeOption: this.ImageKnifeOption }).height(this.currentHeight).width(this.currentWidth)
|
||||
.margin({ top: 20 })
|
||||
Button($r('app.string.Custom_download_failed')).onClick(()=>{
|
||||
this.imageKnifeOption1 = new ImageKnifeOption({
|
||||
this.imageKnifeOption1 = {
|
||||
loadSrc: "abc",
|
||||
placeholderSrc:$r('app.media.loading'),
|
||||
errorholderSrc:$r('app.media.failed'),
|
||||
|
@ -95,7 +95,7 @@ struct LoadStatePage {
|
|||
this.message = "err:" + err
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}).margin({ top: 20 })
|
||||
Text(this.message).fontSize(20).margin({ top: 20 })
|
||||
ImageKnifeComponent({ imageKnifeOption: this.imageKnifeOption1 }).height(this.currentHeight).width(this.currentWidth)
|
||||
|
@ -109,7 +109,7 @@ struct LoadStatePage {
|
|||
}
|
||||
// 自定义下载方法
|
||||
@Concurrent
|
||||
async function custom(context: Context, src: string | PixelMap | Resource): Promise<ArrayBuffer | undefined> {
|
||||
async function custom(context: Context, src: string | PixelMap | Resource,headers?: Record<string,Object>): Promise<ArrayBuffer | undefined> {
|
||||
console.info("ImageKnife:: custom download:" + src)
|
||||
// 举例写死从本地文件读取,也可以自己请求网络图片
|
||||
return undefined
|
||||
|
|
|
@ -12,10 +12,10 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { ImageKnifeComponent,ImageKnifeOption } from '@ohos/libraryimageknife'
|
||||
import { ImageKnifeComponent } from '@ohos/libraryimageknife'
|
||||
|
||||
@Entry
|
||||
@ComponentV2
|
||||
@Component
|
||||
struct LongImagePage {
|
||||
|
||||
build() {
|
||||
|
@ -25,13 +25,13 @@ struct LongImagePage {
|
|||
|
||||
// Image($r("app.media.aaa")).objectFit(ImageFit.Auto).width(200)
|
||||
ImageKnifeComponent({
|
||||
imageKnifeOption: new ImageKnifeOption({
|
||||
imageKnifeOption: {
|
||||
loadSrc:"https://wx2.sinaimg.cn/mw690/006HyQKGgy1hnqp08dw09j30u04twu0x.jpg",
|
||||
//src:$r("app.media.aaa"),
|
||||
placeholderSrc: $r("app.media.loading"),
|
||||
errorholderSrc: $r("app.media.failed"),
|
||||
objectFit: ImageFit.Auto
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
.height('100%') .width('100%')
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Copyright (C) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { ImageKnifeComponent,ImageKnife } from '@ohos/libraryimageknife';
|
||||
import { CommonDataSource } from './model/CommonDataSource';
|
||||
|
||||
@Entry
|
||||
@Component
|
||||
struct MaxRequest1 {
|
||||
@State hotCommendList:CommonDataSource<string> = new CommonDataSource<string>([])
|
||||
private data: Array<string> = []
|
||||
aboutToAppear(): void {
|
||||
ImageKnife.getInstance().setMaxRequests(8)
|
||||
for (let index = 0; index < 200; index++) {
|
||||
this.data.push(`https://img-blog.csdn.net/20140514114029140?${index}`)
|
||||
}
|
||||
this.hotCommendList.addData(this.hotCommendList.totalCount(),this.data)
|
||||
}
|
||||
build() {
|
||||
Column() {
|
||||
WaterFlow() {
|
||||
LazyForEach(this.hotCommendList,(item: string)=>{
|
||||
FlowItem() {
|
||||
Column(){
|
||||
ImageKnifeComponent({
|
||||
imageKnifeOption: {
|
||||
loadSrc: item,
|
||||
placeholderSrc: $r("app.media.loading"),
|
||||
errorholderSrc: $r("app.media.failed"),
|
||||
}
|
||||
}).width("50%").height(160)
|
||||
}
|
||||
}.height(200)
|
||||
.backgroundColor("#95efd2")
|
||||
},(item: string) => item)
|
||||
}.columnsTemplate("1fr 1fr")
|
||||
.cachedCount(8)
|
||||
.columnsGap(10)
|
||||
.rowsGap(5)
|
||||
.backgroundColor(0xFAEEE0)
|
||||
.width("100%").height("100%")
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Copyright (C) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { ImageKnifeComponent,ImageKnife } from '@ohos/libraryimageknife';
|
||||
import { CommonDataSource } from './model/CommonDataSource';
|
||||
|
||||
@Entry
|
||||
@Component
|
||||
struct MaxRequest2 {
|
||||
@State hotCommendList:CommonDataSource<string> = new CommonDataSource<string>([])
|
||||
private data: Array<string> = []
|
||||
aboutToAppear(): void {
|
||||
ImageKnife.getInstance().setMaxRequests(20)
|
||||
for (let index = 200; index < 400; index++) {
|
||||
this.data.push(`https://img-blog.csdn.net/20140514114029140?${index}`)
|
||||
}
|
||||
this.hotCommendList.addData(this.hotCommendList.totalCount(),this.data)
|
||||
}
|
||||
build() {
|
||||
Column() {
|
||||
WaterFlow() {
|
||||
LazyForEach(this.hotCommendList,(item: string)=>{
|
||||
FlowItem() {
|
||||
Column(){
|
||||
ImageKnifeComponent({
|
||||
imageKnifeOption: {
|
||||
loadSrc: item,
|
||||
placeholderSrc: $r("app.media.loading"),
|
||||
errorholderSrc: $r("app.media.failed"),
|
||||
}
|
||||
}).width("50%").height(160)
|
||||
}
|
||||
}.height(200)
|
||||
.backgroundColor("#95efd2")
|
||||
},(item: string) => item)
|
||||
}.columnsTemplate("1fr 1fr")
|
||||
.cachedCount(20)
|
||||
.columnsGap(10)
|
||||
.rowsGap(5)
|
||||
.backgroundColor(0xFAEEE0)
|
||||
.width("100%").height("100%")
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Copyright (C) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { ImageKnifeComponent,ImageKnife } from '@ohos/libraryimageknife';
|
||||
import { CommonDataSource } from './model/CommonDataSource';
|
||||
|
||||
@Entry
|
||||
@Component
|
||||
struct MaxRequest3 {
|
||||
@State hotCommendList:CommonDataSource<string> = new CommonDataSource<string>([])
|
||||
private data: Array<string> = []
|
||||
aboutToAppear(): void {
|
||||
ImageKnife.getInstance().setMaxRequests(32)
|
||||
for (let index = 400; index < 600; index++) {
|
||||
this.data.push(`https://img-blog.csdn.net/20140514114029140?${index}`)
|
||||
}
|
||||
this.hotCommendList.addData(this.hotCommendList.totalCount(),this.data)
|
||||
}
|
||||
build() {
|
||||
Column() {
|
||||
WaterFlow() {
|
||||
LazyForEach(this.hotCommendList,(item: string)=>{
|
||||
FlowItem() {
|
||||
Column(){
|
||||
ImageKnifeComponent({
|
||||
imageKnifeOption: {
|
||||
loadSrc: item,
|
||||
placeholderSrc: $r("app.media.loading"),
|
||||
errorholderSrc: $r("app.media.failed"),
|
||||
}
|
||||
}).width("50%").height(160)
|
||||
}
|
||||
}.height(200)
|
||||
.backgroundColor("#95efd2")
|
||||
},(item: string) => item)
|
||||
}.columnsTemplate("1fr 1fr")
|
||||
.cachedCount(40)
|
||||
.columnsGap(10)
|
||||
.rowsGap(5)
|
||||
.backgroundColor(0xFAEEE0)
|
||||
.width("100%").height("100%")
|
||||
}
|
||||
}
|
||||
}
|
|
@ -15,49 +15,49 @@
|
|||
import { ImageKnife, ImageKnifeComponent, ImageKnifeOption } from '@ohos/libraryimageknife'
|
||||
|
||||
@Entry
|
||||
@ComponentV2
|
||||
@Component
|
||||
struct ObjectFitPage {
|
||||
@Local imageKnifeOption: ImageKnifeOption = new ImageKnifeOption({
|
||||
@State imageKnifeOption: ImageKnifeOption = {
|
||||
loadSrc: $r("app.media.app_icon"),
|
||||
placeholderSrc: $r("app.media.loading"),
|
||||
errorholderSrc: $r("app.media.app_icon"),
|
||||
objectFit: ImageFit.Fill
|
||||
})
|
||||
}
|
||||
|
||||
build() {
|
||||
Column() {
|
||||
|
||||
Button($r('app.string.Main_image_Fill')).onClick(()=>{
|
||||
this.imageKnifeOption = new ImageKnifeOption({
|
||||
this.imageKnifeOption = {
|
||||
loadSrc: $r("app.media.app_icon"),
|
||||
placeholderSrc: $r("app.media.loading"),
|
||||
errorholderSrc: $r("app.media.app_icon"),
|
||||
objectFit: ImageFit.Fill
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
Button($r('app.string.Maintain_proportion_filling')).margin({top:10}).onClick(async () => {
|
||||
ImageKnife.getInstance().removeAllMemoryCache()
|
||||
await ImageKnife.getInstance().removeAllFileCache()
|
||||
|
||||
this.imageKnifeOption = new ImageKnifeOption({
|
||||
this.imageKnifeOption = {
|
||||
loadSrc: "https://wx2.sinaimg.cn/mw690/006HyQKGgy1hnqp08dw09j30u04twu0x.jpg",
|
||||
placeholderSrc: $r("app.media.app_icon"),
|
||||
errorholderSrc: $r("app.media.app_icon"),
|
||||
objectFit: ImageFit.Fill,
|
||||
placeholderObjectFit: ImageFit.Contain
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
Button($r('app.string.Error_graph_None')).margin({top:10}).onClick(() => {
|
||||
this.imageKnifeOption = new ImageKnifeOption({
|
||||
this.imageKnifeOption = {
|
||||
loadSrc: "http://xxxxx",
|
||||
placeholderSrc: $r("app.media.loading"),
|
||||
errorholderSrc: $r("app.media.app_icon"),
|
||||
objectFit: ImageFit.Fill,
|
||||
errorholderObjectFit: ImageFit.None
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
ImageKnifeComponent({
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright (C) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { router } from '@kit.ArkUI'
|
||||
|
||||
@Entry
|
||||
@Component
|
||||
struct PrefetchAndCacheCount {
|
||||
build() {
|
||||
Column() {
|
||||
Button("cacheCount == 5")
|
||||
.onClick(()=>{
|
||||
router.pushUrl({url:"pages/LazyForEachCache"})
|
||||
})
|
||||
Button("cacheCount == 30")
|
||||
.margin({top:10})
|
||||
.onClick(()=>{
|
||||
router.pushUrl({url:"pages/LazyForEachCount"})
|
||||
})
|
||||
Button("prefetch + preload")
|
||||
.margin({top:10})
|
||||
.onClick(()=>{
|
||||
router.pushUrl({url:"pages/PrefetchAndPreload"})
|
||||
})
|
||||
}.width("100%")
|
||||
.height("100%")
|
||||
}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Copyright (C) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { BasicPrefetcher } from '@kit.ArkUI';
|
||||
import DataSourcePrefetchingImageKnife, { InfoItem } from './model/DataSourcePrefetching';
|
||||
import { PageViewModel } from './model/PageViewModel';
|
||||
import { ImageKnifeComponent, ImageKnifeOption } from '@ohos/libraryimageknife';
|
||||
@Entry
|
||||
@Component
|
||||
export struct PrefetchAndPreload {
|
||||
// 创建DataSourcePrefetchingImageKnife对象,具备任务预取、取消能力的数据源
|
||||
private readonly dataSource = new DataSourcePrefetchingImageKnife(PageViewModel.getItems());
|
||||
// 创建BasicPrefetcher对象,默认的动态预取算法实现
|
||||
private readonly prefetcher = new BasicPrefetcher(this.dataSource);
|
||||
|
||||
build() {
|
||||
Column() {
|
||||
List({ space: 16 }) {
|
||||
LazyForEach(this.dataSource, (item: InfoItem,index:number) => {
|
||||
ListItem() {
|
||||
Column({ space: 12 }) {
|
||||
ImageKnifeComponent({
|
||||
imageKnifeOption:{
|
||||
loadSrc: item.albumUrl,
|
||||
placeholderSrc:$r('app.media.loading')
|
||||
}
|
||||
}).width(100).height(100)
|
||||
Text(`${index}`)
|
||||
}.border({ width: 5 , color: "#000000"})
|
||||
}
|
||||
.reuseId('imageKnife')
|
||||
})
|
||||
}
|
||||
.cachedCount(5)
|
||||
.onScrollIndex((start: number, end: number) => {
|
||||
// 列表滚动触发visibleAreaChanged,实时更新预取范围,触发调用prefetch、cancel接口
|
||||
this.prefetcher.visibleAreaChanged(start, end)
|
||||
})
|
||||
.width("100%")
|
||||
.height("100%")
|
||||
.margin({ left: 10, right: 10 })
|
||||
.layoutWeight(1)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
import { router } from '@kit.ArkUI'
|
||||
|
||||
@Entry
|
||||
@Component
|
||||
struct SetMaxRequestPage {
|
||||
build() {
|
||||
Column() {
|
||||
Button("maxRequest = 8")
|
||||
.onClick(()=>{
|
||||
router.pushUrl({url:"pages/MaxRequest1"})
|
||||
})
|
||||
Button("maxRequest = 20")
|
||||
.onClick(()=>{
|
||||
router.pushUrl({url:"pages/MaxRequest2"})
|
||||
}).margin({top:20})
|
||||
Button("maxRequest = 32")
|
||||
.onClick(()=>{
|
||||
router.pushUrl({url:"pages/MaxRequest2"})
|
||||
}).margin({top:20})
|
||||
}.width("100%")
|
||||
.height("100%")
|
||||
}
|
||||
}
|
|
@ -16,18 +16,18 @@ import { ImageKnifeComponent, ImageKnifeOption } from '@ohos/libraryimageknife';
|
|||
|
||||
|
||||
@Entry
|
||||
@ComponentV2
|
||||
@Component
|
||||
struct SignatureTestPage {
|
||||
@Local imageKnifeOption1: ImageKnifeOption =new ImageKnifeOption(
|
||||
@State imageKnifeOption1: ImageKnifeOption =
|
||||
{
|
||||
loadSrc: $r('app.media.icon'),
|
||||
placeholderSrc:$r("app.media.loading"),
|
||||
});
|
||||
@Local imageKnifeOption2: ImageKnifeOption =new ImageKnifeOption(
|
||||
};
|
||||
@State imageKnifeOption2: ImageKnifeOption =
|
||||
{
|
||||
loadSrc: $r('app.media.icon'),
|
||||
placeholderSrc:$r("app.media.loading"),
|
||||
});
|
||||
};
|
||||
|
||||
build() {
|
||||
Scroll() {
|
||||
|
@ -37,11 +37,11 @@ struct SignatureTestPage {
|
|||
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
||||
Button($r('app.string.Load'))
|
||||
.onClick(() => {
|
||||
this.imageKnifeOption1 = new ImageKnifeOption({
|
||||
this.imageKnifeOption1 = {
|
||||
loadSrc: 'https://img-blog.csdn.net/20140514114029140',
|
||||
placeholderSrc:$r("app.media.loading"),
|
||||
signature: "1"
|
||||
})
|
||||
}
|
||||
}).margin({ top: 5, left: 3 })
|
||||
ImageKnifeComponent({ imageKnifeOption: this.imageKnifeOption1 }).width(300).height(300)
|
||||
}.width('100%').backgroundColor(Color.Pink)
|
||||
|
@ -50,11 +50,11 @@ struct SignatureTestPage {
|
|||
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
||||
Button($r('app.string.Load'))
|
||||
.onClick(() => {
|
||||
this.imageKnifeOption2 = new ImageKnifeOption({
|
||||
this.imageKnifeOption2 = {
|
||||
loadSrc: 'https://img-blog.csdn.net/20140514114029140',
|
||||
placeholderSrc:$r("app.media.loading"),
|
||||
signature: new Date().getTime().toString()
|
||||
})
|
||||
}
|
||||
}).margin({ top: 5, left: 3 })
|
||||
ImageKnifeComponent({ imageKnifeOption: this.imageKnifeOption2 }).width(300).height(300)
|
||||
}.width('100%').backgroundColor(Color.Pink)
|
||||
|
|
|
@ -12,19 +12,19 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { ImageKnifeComponent,BlurTransformation,ImageKnifeOption } from '@ohos/libraryimageknife';
|
||||
import { ImageKnifeComponent,BlurTransformation } from '@ohos/libraryimageknife';
|
||||
import fs from '@ohos.file.fs';
|
||||
import image from '@ohos.multimedia.image';
|
||||
import { common2D, drawing } from '@kit.ArkGraphics2D';
|
||||
|
||||
@Entry
|
||||
@ComponentV2
|
||||
@Component
|
||||
struct SingleImage {
|
||||
resource: string = "app.media.svgSample"
|
||||
scroller: Scroller = new Scroller;
|
||||
localFile: string = getContext(this).filesDir + "/icon.png"
|
||||
@Local pixelMap:PixelMap | undefined = undefined;
|
||||
@Local DrawingColorFilter: ColorFilter | undefined = undefined
|
||||
@State pixelMap:PixelMap | undefined = undefined;
|
||||
@State DrawingColorFilter: ColorFilter | undefined = undefined
|
||||
private color: common2D.Color = { alpha: 255, red: 255, green: 0, blue: 0 };
|
||||
aboutToAppear(): void {
|
||||
// 拷贝本地文件
|
||||
|
@ -46,12 +46,12 @@ struct SingleImage {
|
|||
.fontSize(30)
|
||||
.fontWeight(FontWeight.Bold)
|
||||
ImageKnifeComponent({
|
||||
imageKnifeOption: new ImageKnifeOption({
|
||||
imageKnifeOption: {
|
||||
loadSrc: $r("app.media.svgSample"),
|
||||
placeholderSrc: $r("app.media.loading"),
|
||||
errorholderSrc: $r("app.media.failed"),
|
||||
objectFit: ImageFit.Contain
|
||||
})
|
||||
}
|
||||
}).width(100).height(100)
|
||||
.onClick(()=>{
|
||||
this.DrawingColorFilter = drawing.ColorFilter.createBlendModeColorFilter(this.color, drawing.BlendMode.SRC_IN);
|
||||
|
@ -60,48 +60,52 @@ struct SingleImage {
|
|||
.fontSize(30)
|
||||
.fontWeight(FontWeight.Bold)
|
||||
ImageKnifeComponent({
|
||||
imageKnifeOption: new ImageKnifeOption({
|
||||
imageKnifeOption: {
|
||||
loadSrc: this.localFile,
|
||||
placeholderSrc: $r("app.media.loading"),
|
||||
errorholderSrc: $r("app.media.failed"),
|
||||
objectFit: ImageFit.Contain
|
||||
})
|
||||
}
|
||||
}).width(100).height(100)
|
||||
Text($r('app.string.Network_images'))
|
||||
.fontSize(30)
|
||||
.fontWeight(FontWeight.Bold)
|
||||
ImageKnifeComponent({
|
||||
imageKnifeOption: new ImageKnifeOption({
|
||||
imageKnifeOption: {
|
||||
loadSrc:"https://www.openharmony.cn/_nuxt/img/logo.dcf95b3.png",
|
||||
placeholderSrc: $r("app.media.loading"),
|
||||
errorholderSrc: $r("app.media.failed"),
|
||||
objectFit: ImageFit.Contain,
|
||||
progressListener:(progress:number)=>{console.info("ImageKnife:: call back progress = " + progress)}
|
||||
})
|
||||
}
|
||||
}).width(100).height(100)
|
||||
Text($r('app.string.Custom_network_download'))
|
||||
.fontSize(30)
|
||||
.fontWeight(FontWeight.Bold)
|
||||
ImageKnifeComponent({
|
||||
imageKnifeOption: new ImageKnifeOption({
|
||||
imageKnifeOption: {
|
||||
loadSrc: "https://file.atomgit.com/uploads/user/1704857786989_8994.jpeg",
|
||||
placeholderSrc: $r("app.media.loading"),
|
||||
errorholderSrc: $r("app.media.failed"),
|
||||
objectFit: ImageFit.Contain,
|
||||
headerOption:[{
|
||||
key:"refer",
|
||||
value:"xx.xx.xx.xx"
|
||||
}],
|
||||
customGetImage: custom,
|
||||
transformation: new BlurTransformation(10)
|
||||
})
|
||||
}
|
||||
}).width(100).height(100)
|
||||
Text($r('app.string.PixelMap_loads_images'))
|
||||
.fontSize(30)
|
||||
.fontWeight(FontWeight.Bold)
|
||||
ImageKnifeComponent({
|
||||
imageKnifeOption: new ImageKnifeOption({
|
||||
imageKnifeOption: {
|
||||
loadSrc: this.pixelMap!,
|
||||
placeholderSrc: $r("app.media.loading"),
|
||||
errorholderSrc: $r("app.media.failed"),
|
||||
objectFit: ImageFit.Contain,
|
||||
})
|
||||
}
|
||||
}).width(100).height(100)
|
||||
}
|
||||
.width('100%')
|
||||
|
@ -124,9 +128,11 @@ struct SingleImage {
|
|||
|
||||
// 自定义下载方法
|
||||
@Concurrent
|
||||
async function custom(context: Context, src: string | PixelMap | Resource): Promise<ArrayBuffer | undefined> {
|
||||
console.info("ImageKnife:: custom download:" + src)
|
||||
async function custom(context: Context, src: string | PixelMap | Resource,headers?: Record<string,Object>): Promise<ArrayBuffer | undefined> {
|
||||
let refer = headers!["refer"] as string
|
||||
console.info("ImageKnife:: custom download:" + src,"refer:"+refer)
|
||||
// 举例写死从本地文件读取,也可以自己请求网络图片
|
||||
return context.resourceManager.getMediaContentSync($r("app.media.startIcon").id).buffer as ArrayBuffer
|
||||
let buffer = context.resourceManager.getMediaContentSync($r("app.media.startIcon").id).buffer as ArrayBuffer
|
||||
return buffer
|
||||
}
|
||||
|
||||
|
|
|
@ -13,20 +13,20 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { ImageKnife, CacheStrategy, ImageKnifeComponent, ImageKnifeOption } from '@ohos/imageknife';
|
||||
import { ImageKnife, CacheStrategy, ImageKnifeComponent, ImageKnifeOption } from '@ohos/libraryimageknife';
|
||||
|
||||
@Entry
|
||||
@ComponentV2
|
||||
@Component
|
||||
struct TestCacheDataPage {
|
||||
@Local cacheUpLimit: number = 0;
|
||||
@Local currentNum: number = 0;
|
||||
@Local currentSize: number = 0;
|
||||
@Local currentWidth: number = 200
|
||||
@Local currentHeight: number = 200
|
||||
@Local markersLimitText: string = getContext(this).resourceManager.getStringSync($r('app.string.memory'))
|
||||
@Local markersNumText: string = getContext(this).resourceManager.getStringSync($r('app.string.memory'))
|
||||
@Local markersSizeText: string = getContext(this).resourceManager.getStringSync($r('app.string.memory'))
|
||||
@Local ImageKnifeOption: ImageKnifeOption = new ImageKnifeOption({
|
||||
@State cacheUpLimit: number = 0;
|
||||
@State currentNum: number = 0;
|
||||
@State currentSize: number = 0;
|
||||
@State currentWidth: number = 200
|
||||
@State currentHeight: number = 200
|
||||
@State markersLimitText: string = getContext(this).resourceManager.getStringSync($r('app.string.memory'))
|
||||
@State markersNumText: string = getContext(this).resourceManager.getStringSync($r('app.string.memory'))
|
||||
@State markersSizeText: string = getContext(this).resourceManager.getStringSync($r('app.string.memory'))
|
||||
@State ImageKnifeOption: ImageKnifeOption = {
|
||||
loadSrc: "",
|
||||
objectFit: ImageFit.Contain,
|
||||
onLoadListener: {
|
||||
|
@ -38,7 +38,7 @@ struct TestCacheDataPage {
|
|||
},
|
||||
},
|
||||
border: { radius: 50 }
|
||||
})
|
||||
}
|
||||
|
||||
aboutToAppear(): void {
|
||||
ImageKnife.getInstance().initFileCache(getContext(this), 256, 256 * 1024 * 1024, "ImageKnifeCache1")
|
||||
|
@ -55,21 +55,21 @@ struct TestCacheDataPage {
|
|||
|
||||
Button($r('app.string.load_memory'))
|
||||
.onClick(() => {
|
||||
this.ImageKnifeOption = new ImageKnifeOption({
|
||||
this.ImageKnifeOption = {
|
||||
loadSrc: "https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/3e/v3/LqRoLI-PRSu9Nqa8KdJ-pQ/dSqskBpSR9eraAMn7NBdqA.jpg",
|
||||
objectFit: ImageFit.Contain,
|
||||
writeCacheStrategy: CacheStrategy.Memory,
|
||||
border: { radius: 50 },
|
||||
})
|
||||
}
|
||||
})
|
||||
Button($r('app.string.load_disk'))
|
||||
.onClick(() => {
|
||||
this.ImageKnifeOption = new ImageKnifeOption({
|
||||
this.ImageKnifeOption = {
|
||||
loadSrc: "https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/56/v3/8MdhfSsCSMKj4sA6okUWrg/5uBx56tLTUO3RYQl-E5JiQ.jpg",
|
||||
objectFit: ImageFit.Contain,
|
||||
writeCacheStrategy: CacheStrategy.File,
|
||||
border: { radius: 50 },
|
||||
})
|
||||
}
|
||||
})
|
||||
Text($r('app.string.cur_cache_limit', this.markersLimitText, this.cacheUpLimit))
|
||||
.fontSize(20)
|
||||
|
@ -80,7 +80,7 @@ struct TestCacheDataPage {
|
|||
Text($r('app.string.cur_cache_size', this.markersSizeText, this.currentSize)).fontSize(20).margin({ bottom: 20 });
|
||||
|
||||
Button($r('app.string.get_cur_memory_limit')).onClick(() => {
|
||||
let result = ImageKnife.getInstance().getCacheUpperLimit(CacheStrategy.Memory);
|
||||
let result = ImageKnife.getInstance().getCacheLimitSize(CacheStrategy.Memory);
|
||||
this.markersLimitText = getContext(this).resourceManager.getStringSync($r('app.string.memory'))
|
||||
if (result) {
|
||||
this.cacheUpLimit = result / (1024 * 1024);
|
||||
|
@ -89,7 +89,7 @@ struct TestCacheDataPage {
|
|||
}
|
||||
}).margin({ bottom: 8 });
|
||||
Button($r('app.string.get_img_number_of_cache')).onClick(() => {
|
||||
let result = ImageKnife.getInstance().getCurrentPicturesNum(CacheStrategy.Memory);
|
||||
let result = ImageKnife.getInstance().getCurrentCacheNum(CacheStrategy.Memory);
|
||||
this.markersNumText = getContext(this).resourceManager.getStringSync($r('app.string.memory'))
|
||||
if (result) {
|
||||
this.currentNum = result;
|
||||
|
@ -108,7 +108,7 @@ struct TestCacheDataPage {
|
|||
}).margin({ bottom: 8 });
|
||||
|
||||
Button($r('app.string.get_cur_disk_limit')).onClick(() => {
|
||||
let result = ImageKnife.getInstance().getCacheUpperLimit(CacheStrategy.File);
|
||||
let result = ImageKnife.getInstance().getCacheLimitSize(CacheStrategy.File);
|
||||
this.markersLimitText = getContext(this).resourceManager.getStringSync($r('app.string.disk'))
|
||||
if (result) {
|
||||
this.cacheUpLimit = result / (1024 * 1024);
|
||||
|
@ -117,7 +117,7 @@ struct TestCacheDataPage {
|
|||
}
|
||||
}).margin({ bottom: 8 });
|
||||
Button($r('app.string.get_img_number_of_disk')).onClick(() => {
|
||||
let result = ImageKnife.getInstance().getCurrentPicturesNum(CacheStrategy.File);
|
||||
let result = ImageKnife.getInstance().getCurrentCacheNum(CacheStrategy.File);
|
||||
this.markersNumText = getContext(this).resourceManager.getStringSync($r('app.string.disk'))
|
||||
if (result) {
|
||||
this.currentNum = result;
|
||||
|
|
|
@ -74,17 +74,17 @@ struct TestChangeColorPage {
|
|||
|
||||
Text($r('app.string.master_image')).margin({ top: 20 })
|
||||
ImageKnifeComponent({
|
||||
imageKnifeOption: new ImageKnifeOption({
|
||||
imageKnifeOption: {
|
||||
loadSrc: this.src
|
||||
})
|
||||
}
|
||||
}).width(110).height(110)
|
||||
|
||||
Text($r('app.string.click_img_to_change_color')).margin({ top: 30 })
|
||||
ImageKnifeComponent({
|
||||
imageKnifeOption: new ImageKnifeOption({
|
||||
imageKnifeOption: {
|
||||
loadSrc: this.src,
|
||||
drawingColorFilter: this.DrawingColorFilterFirst
|
||||
})
|
||||
}
|
||||
})
|
||||
.onClick(() => {
|
||||
this.DrawingColorFilterFirst =
|
||||
|
@ -93,18 +93,18 @@ struct TestChangeColorPage {
|
|||
|
||||
Text($r('app.string.test_non_svg_color')).margin({ top: 30 })
|
||||
ImageKnifeComponent({
|
||||
imageKnifeOption: new ImageKnifeOption({
|
||||
imageKnifeOption: {
|
||||
loadSrc: $r('app.media.ic_test_change_color_png'),
|
||||
drawingColorFilter: drawing.ColorFilter.createBlendModeColorFilter(this.color, drawing.BlendMode.SRC_IN)
|
||||
})
|
||||
}
|
||||
}).width(110).height(110)
|
||||
|
||||
Text($r('app.string.test_svg_color')).margin({ top: 30 })
|
||||
ImageKnifeComponent({
|
||||
imageKnifeOption: new ImageKnifeOption({
|
||||
imageKnifeOption: {
|
||||
loadSrc: $r("app.media.ic_test_change_color_svg"),
|
||||
drawingColorFilter: drawing.ColorFilter.createBlendModeColorFilter(this.color, drawing.BlendMode.SRC_IN)
|
||||
})
|
||||
}
|
||||
}).width(110).height(110)
|
||||
|
||||
}.width('100%').height('100%')
|
||||
|
|
|
@ -12,10 +12,10 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { ImageKnifeComponent ,ImageKnifeOption} from '@ohos/libraryimageknife';
|
||||
import { ImageKnifeComponent } from '@ohos/libraryimageknife';
|
||||
|
||||
@Entry
|
||||
@ComponentV2
|
||||
@Component
|
||||
struct TestCommonImage {
|
||||
private data: Array<string> = []
|
||||
aboutToAppear(): void {
|
||||
|
@ -30,13 +30,13 @@ struct TestCommonImage {
|
|||
FlowItem() {
|
||||
Column(){
|
||||
ImageKnifeComponent({
|
||||
imageKnifeOption: new ImageKnifeOption({
|
||||
imageKnifeOption: {
|
||||
loadSrc: item,
|
||||
placeholderSrc: $r("app.media.loading"),
|
||||
errorholderSrc: $r("app.media.failed"),
|
||||
objectFit: ImageFit.Contain,
|
||||
signature: "aaa"
|
||||
})
|
||||
}
|
||||
}).width("50%").height(200)
|
||||
}
|
||||
}.height(200)
|
||||
|
|
|
@ -12,34 +12,34 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { ImageKnifeComponent,ImageKnifeOption } from '@ohos/libraryimageknife'
|
||||
import { ImageKnifeComponent } from '@ohos/libraryimageknife'
|
||||
|
||||
@Entry
|
||||
@ComponentV2
|
||||
@Component
|
||||
struct TestErrorHolderPage {
|
||||
|
||||
build() {
|
||||
Column() {
|
||||
Text("ImageKnifeComponent1").fontSize(20)
|
||||
ImageKnifeComponent({
|
||||
imageKnifeOption: new ImageKnifeOption({
|
||||
imageKnifeOption: {
|
||||
loadSrc: "abc",
|
||||
errorholderSrc:$r('app.media.failed')
|
||||
})
|
||||
}
|
||||
}).width(200).height(200)
|
||||
Text("ImageKnifeComponent2").fontSize(20)
|
||||
ImageKnifeComponent({
|
||||
imageKnifeOption: new ImageKnifeOption({
|
||||
imageKnifeOption: {
|
||||
loadSrc: "abc",
|
||||
errorholderSrc:$r('app.media.startIcon')
|
||||
})
|
||||
}
|
||||
}).width(200).height(200)
|
||||
Text("ImageKnifeComponent2").fontSize(20)
|
||||
ImageKnifeComponent({
|
||||
imageKnifeOption: new ImageKnifeOption({
|
||||
imageKnifeOption: {
|
||||
loadSrc: "abc",
|
||||
errorholderSrc:$r('app.media.mask_starfish')
|
||||
})
|
||||
}
|
||||
}).width(200).height(200)
|
||||
}
|
||||
.height('100%') .width('100%')
|
||||
|
|
|
@ -15,9 +15,9 @@
|
|||
import { ImageKnifeComponent,ImageKnifeOption } from '@ohos/libraryimageknife'
|
||||
|
||||
@Entry
|
||||
@ComponentV2
|
||||
@Component
|
||||
struct TestPrefetchToFileCachePage {
|
||||
@Local imageKnifeOption: ImageKnifeOption = new ImageKnifeOption({
|
||||
@State imageKnifeOption: ImageKnifeOption = {
|
||||
loadSrc:"https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658",
|
||||
placeholderSrc:$r('app.media.loading'),
|
||||
headerOption:[
|
||||
|
@ -26,7 +26,7 @@ struct TestPrefetchToFileCachePage {
|
|||
value:"单个"
|
||||
}
|
||||
]
|
||||
})
|
||||
}
|
||||
|
||||
build() {
|
||||
Column() {
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
import { IndexComponent } from "@ohos/libraryimageknife"
|
||||
|
||||
@Entry
|
||||
@ComponentV2
|
||||
@Component
|
||||
struct TestHspPreLoadImage {
|
||||
build() {
|
||||
Column() {
|
||||
|
|
|
@ -12,9 +12,9 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { ImageKnifeComponent,ImageKnifeOption } from '@ohos/libraryimageknife'
|
||||
import { ImageKnifeComponent } from '@ohos/libraryimageknife'
|
||||
|
||||
@ObservedV2
|
||||
@Observed
|
||||
export class MsgModel {
|
||||
id: string
|
||||
cId: string
|
||||
|
@ -30,10 +30,10 @@ export class MsgModel {
|
|||
}
|
||||
|
||||
|
||||
// @Reusable
|
||||
@ComponentV2
|
||||
@Reusable
|
||||
@Component
|
||||
export struct MsgItem {
|
||||
@Param count: number = 0
|
||||
count: number = 0
|
||||
private data: Array<string> = [
|
||||
"http://e.hiphotos.baidu.com/image/pic/item/a1ec08fa513d2697e542494057fbb2fb4316d81e.jpg",
|
||||
"http://c.hiphotos.baidu.com/image/pic/item/30adcbef76094b36de8a2fe5a1cc7cd98d109d99.jpg",
|
||||
|
@ -59,37 +59,37 @@ export struct MsgItem {
|
|||
build(){
|
||||
if (this.count % 2 == 0 && this.count <6){
|
||||
ImageKnifeComponent({
|
||||
imageKnifeOption:new ImageKnifeOption({
|
||||
imageKnifeOption:{
|
||||
loadSrc:$r("app.media.startIcon"),
|
||||
placeholderSrc:$r("app.media.loading")
|
||||
}),syncLoad:true
|
||||
},syncLoad:true
|
||||
})
|
||||
}else if (this.count > 6 && this.count - 6 < this.data.length){
|
||||
ImageKnifeComponent({
|
||||
imageKnifeOption:new ImageKnifeOption({
|
||||
imageKnifeOption:{
|
||||
loadSrc:this.data[this.count - 6],
|
||||
placeholderSrc:$r("app.media.loading")
|
||||
}),syncLoad:true
|
||||
},syncLoad:true
|
||||
})
|
||||
}else {
|
||||
ImageKnifeComponent({
|
||||
imageKnifeOption:new ImageKnifeOption({
|
||||
imageKnifeOption:{
|
||||
loadSrc:$r("app.media.pngSample"),
|
||||
placeholderSrc:$r("app.media.loading")
|
||||
}),syncLoad:true
|
||||
},syncLoad:true
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Entry
|
||||
@ComponentV2
|
||||
@Component
|
||||
struct ImageTestPage {
|
||||
count : number = 0
|
||||
rCount: number = 0
|
||||
scroller: Scroller = new Scroller()
|
||||
@Local list: MsgModel[] = []
|
||||
@Local imageSize: number =100
|
||||
@State list: MsgModel[] = []
|
||||
@State imageSize: number =100
|
||||
handAdd(){
|
||||
this.count++
|
||||
const msgItem = new MsgModel('add_id'+this.count, 'addBody'+this.count,'cId'+ this.count)
|
||||
|
|
|
@ -0,0 +1,412 @@
|
|||
/*
|
||||
* Copyright (C) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { ImageKnifeComponent, ImageKnifeData, ImageKnifeOption, ImageKnifeRequest } from '@ohos/libraryimageknife';
|
||||
import { router } from '@kit.ArkUI';
|
||||
|
||||
@Entry
|
||||
@Component
|
||||
struct TestImageKnifeCallbackPage {
|
||||
@State imageKnifeOption: ImageKnifeOption = {
|
||||
loadSrc: "",
|
||||
objectFit: ImageFit.Contain,
|
||||
border: { radius: 50 }
|
||||
};
|
||||
@State currentWidth: number = 200
|
||||
@State currentHeight: number = 200
|
||||
@State url: string | undefined = ""
|
||||
@State imageType: string | undefined = ""
|
||||
@State imageWidth: number | undefined = 0
|
||||
@State imageHeight: number | undefined = 0
|
||||
@State imageSize: number | undefined = 0
|
||||
@State componentWidth: number | undefined = 0
|
||||
@State componentHeight: number | undefined = 0
|
||||
@State frameNum: number | undefined = 0
|
||||
@State decodeSize: string | undefined = ""
|
||||
@State err_msg: string | undefined = ""
|
||||
@State err_phase: string | undefined = ""
|
||||
@State err_code: number | undefined = 0
|
||||
@State http_code: number | undefined = 0
|
||||
@State reqStartTime: string | undefined = ""
|
||||
@State reqEndTime: string | undefined = ""
|
||||
@State reqCancelTime: string | undefined = ""
|
||||
@State memoryStartTime: string | undefined = ""
|
||||
@State memoryEndTime: string | undefined = ""
|
||||
@State diskStartTime: string | undefined = ""
|
||||
@State diskEndTime: string | undefined = ""
|
||||
@State netStartTime: string | undefined = ""
|
||||
@State netEndTime: string | undefined = ""
|
||||
@State decodeStartTime: string | undefined = ""
|
||||
@State decodeEndTime: string | undefined = ""
|
||||
@State renderTime: string | undefined = ""
|
||||
@State showChild: boolean = true;
|
||||
|
||||
build() {
|
||||
Column() {
|
||||
Text($r('app.string.img_url', this.url)).fontSize(14)
|
||||
Text($r('app.string.img_format', this.imageType)).fontSize(14)
|
||||
Text($r('app.string.img_master_size', this.imageWidth, this.imageHeight, this.imageSize)).fontSize(14)
|
||||
Text($r('app.string.componentWH', this.componentWidth, this.componentHeight)).fontSize(14)
|
||||
Text($r('app.string.img_frame', this.frameNum)).fontSize(14)
|
||||
Text($r('app.string.img_content_size', this.decodeSize)).fontSize(14)
|
||||
Text($r('app.string.err_msg', this.err_msg)).fontSize(14)
|
||||
Text($r('app.string.err_phase', this.err_phase)).fontSize(14)
|
||||
Text($r('app.string.err_code', this.err_code)).fontSize(14)
|
||||
Text($r('app.string.http_code', this.http_code)).fontSize(14)
|
||||
Text($r('app.string.req_start_time', this.reqStartTime)).fontSize(14)
|
||||
Text($r('app.string.req_end_time', this.reqEndTime)).fontSize(14)
|
||||
Text($r('app.string.req_cancel_time', this.reqCancelTime)).fontSize(14)
|
||||
Text($r('app.string.memory_start_time', this.memoryStartTime)).fontSize(14)
|
||||
Text($r('app.string.memory_end_time', this.memoryEndTime)).fontSize(14)
|
||||
Text($r('app.string.disk_start_time', this.diskStartTime)).fontSize(14)
|
||||
Text($r('app.string.disk_end_time', this.diskEndTime)).fontSize(14)
|
||||
Text($r('app.string.net_start_time', this.netStartTime)).fontSize(14)
|
||||
Text($r('app.string.net_end_time', this.netEndTime)).fontSize(14)
|
||||
Text($r('app.string.decode_start_time', this.decodeStartTime)).fontSize(14)
|
||||
Text($r('app.string.decode_end_time', this.decodeEndTime)).fontSize(14)
|
||||
Text($r('app.string.render_time', this.renderTime)).fontSize(14)
|
||||
|
||||
Scroll() {
|
||||
Column() {
|
||||
|
||||
Row() {
|
||||
Button($r('app.string.Network_images'))
|
||||
.fontSize(13)
|
||||
.onClick(() => {
|
||||
this.destroy();
|
||||
this.imageKnifeOption = {
|
||||
loadSrc: "https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/10/v3/qaEzwkU0QeKb1yehnP2Xig/q7fxAlgMQKup-HUBayRLGQ.jpg",
|
||||
objectFit: ImageFit.Contain,
|
||||
onLoadListener: {
|
||||
onLoadStart: (data) => {
|
||||
this.analyzeStartCallBackData(data);
|
||||
},
|
||||
onLoadFailed: (res, req) => {
|
||||
this.analyzeFailedBackData(res, req?.getImageKnifeData());
|
||||
},
|
||||
onLoadSuccess: (data, imageData, req) => {
|
||||
this.analyzeSuccessCallBackData(req?.getImageKnifeData());
|
||||
},
|
||||
onLoadCancel: (res, req) => {
|
||||
this.analyzeFailedBackData(res, req?.getImageKnifeData());
|
||||
}
|
||||
},
|
||||
border: { radius: 50 },
|
||||
onComplete: (event) => {
|
||||
if (event && event.loadingStatus == 0) {
|
||||
this.renderTime = this.formatDate(Date.now());
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
Button($r('app.string.gif'))
|
||||
.fontSize(13)
|
||||
.onClick(() => {
|
||||
this.destroy();
|
||||
this.imageKnifeOption = {
|
||||
loadSrc: 'https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658',
|
||||
objectFit: ImageFit.Contain,
|
||||
onLoadListener: {
|
||||
onLoadStart: (data) => {
|
||||
this.analyzeStartCallBackData(data);
|
||||
},
|
||||
onLoadFailed: (res, req) => {
|
||||
this.analyzeFailedBackData(res, req?.getImageKnifeData());
|
||||
},
|
||||
onLoadSuccess: (data, imageData, req) => {
|
||||
this.analyzeSuccessCallBackData(req?.getImageKnifeData());
|
||||
},
|
||||
onLoadCancel: (res, req) => {
|
||||
this.analyzeFailedBackData(res, req?.getImageKnifeData());
|
||||
}
|
||||
},
|
||||
border: { radius: 50 },
|
||||
onComplete: (event) => {
|
||||
if (event && event.loadingStatus == 0) {
|
||||
this.renderTime = this.formatDate(Date.now());
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
Button($r('app.string.local_pic'))
|
||||
.fontSize(13)
|
||||
.onClick(() => {
|
||||
this.destroy();
|
||||
this.imageKnifeOption = {
|
||||
loadSrc: $r('app.media.pngSample'),
|
||||
objectFit: ImageFit.Contain,
|
||||
onLoadListener: {
|
||||
onLoadStart: (data) => {
|
||||
this.analyzeStartCallBackData(data);
|
||||
},
|
||||
onLoadFailed: (res, req) => {
|
||||
this.analyzeFailedBackData(res, req?.getImageKnifeData());
|
||||
},
|
||||
onLoadSuccess: (data, imageData, req) => {
|
||||
this.analyzeSuccessCallBackData(req?.getImageKnifeData());
|
||||
},
|
||||
onLoadCancel: (res, req) => {
|
||||
this.analyzeFailedBackData(res, req?.getImageKnifeData());
|
||||
}
|
||||
},
|
||||
border: { radius: 50 },
|
||||
onComplete: (event) => {
|
||||
if (event && event.loadingStatus == 0) {
|
||||
this.renderTime = this.formatDate(Date.now());
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
Row() {
|
||||
Button($r('app.string.net_load_failed'))
|
||||
.fontSize(13)
|
||||
.onClick(() => {
|
||||
this.destroy();
|
||||
this.imageKnifeOption = {
|
||||
loadSrc: "https://img-blog.csdn.net/20140514114039140",
|
||||
objectFit: ImageFit.Contain,
|
||||
onLoadListener: {
|
||||
onLoadStart: (data) => {
|
||||
this.analyzeStartCallBackData(data);
|
||||
},
|
||||
onLoadFailed: (res, req) => {
|
||||
this.analyzeFailedBackData(res, req?.getImageKnifeData());
|
||||
},
|
||||
onLoadSuccess: (data, imageData, req) => {
|
||||
this.analyzeSuccessCallBackData(req?.getImageKnifeData());
|
||||
},
|
||||
onLoadCancel: (res, req) => {
|
||||
this.analyzeFailedBackData(res, req?.getImageKnifeData());
|
||||
}
|
||||
},
|
||||
border: { radius: 50 },
|
||||
onComplete: (event) => {
|
||||
if (event && event.loadingStatus == 0) {
|
||||
this.renderTime = this.formatDate(Date.now());
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
Button($r('app.string.local_load_failed'))
|
||||
.fontSize(13)
|
||||
.onClick(() => {
|
||||
this.destroy();
|
||||
this.imageKnifeOption = {
|
||||
loadSrc: 'app.media.xxx',
|
||||
objectFit: ImageFit.Contain,
|
||||
onLoadListener: {
|
||||
onLoadStart: (data) => {
|
||||
this.analyzeStartCallBackData(data);
|
||||
},
|
||||
onLoadFailed: (res, req) => {
|
||||
this.analyzeFailedBackData(res, req?.getImageKnifeData());
|
||||
},
|
||||
onLoadSuccess: (data, imageData, req) => {
|
||||
this.analyzeSuccessCallBackData(req?.getImageKnifeData());
|
||||
},
|
||||
onLoadCancel: (res, req) => {
|
||||
this.analyzeFailedBackData(res, req?.getImageKnifeData());
|
||||
}
|
||||
},
|
||||
border: { radius: 50 },
|
||||
onComplete: (event) => {
|
||||
if (event && event.loadingStatus == 0) {
|
||||
this.renderTime = this.formatDate(Date.now());
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
Button($r('app.string.share_load_failed'))
|
||||
.fontSize(13)
|
||||
.onClick(() => {
|
||||
this.destroy();
|
||||
this.imageKnifeOption = {
|
||||
loadSrc: 'datashare://ssas',
|
||||
objectFit: ImageFit.Contain,
|
||||
onLoadListener: {
|
||||
onLoadStart: (data) => {
|
||||
this.analyzeStartCallBackData(data);
|
||||
},
|
||||
onLoadFailed: (res, req) => {
|
||||
this.analyzeFailedBackData(res, req?.getImageKnifeData());
|
||||
},
|
||||
onLoadSuccess: (data, imageData, req) => {
|
||||
this.analyzeSuccessCallBackData(req?.getImageKnifeData());
|
||||
},
|
||||
onLoadCancel: (res, req) => {
|
||||
this.analyzeFailedBackData(res, req?.getImageKnifeData());
|
||||
}
|
||||
},
|
||||
border: { radius: 50 },
|
||||
onComplete: (event) => {
|
||||
if (event && event.loadingStatus == 0) {
|
||||
this.renderTime = this.formatDate(Date.now());
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
Button($r('app.string.test_cancel_callback_btn'))
|
||||
.fontSize(13)
|
||||
.onClick(() => {
|
||||
this.destroy();
|
||||
this.imageKnifeOption = {
|
||||
loadSrc: "https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/bf/v3/lSjrRwFcS-ez6jp1ALSQFg/0n7R7XinSPyrYLqDu_1dfw.jpg",
|
||||
objectFit: ImageFit.Contain,
|
||||
onLoadListener: {
|
||||
onLoadStart: (data) => {
|
||||
this.showChild = false;
|
||||
this.analyzeStartCallBackData(data);
|
||||
},
|
||||
onLoadFailed: (res, req) => {
|
||||
this.analyzeFailedBackData(res, req?.getImageKnifeData());
|
||||
},
|
||||
onLoadSuccess: (data, imageData, req) => {
|
||||
this.analyzeSuccessCallBackData(req?.getImageKnifeData());
|
||||
},
|
||||
onLoadCancel: (res, req) => {
|
||||
this.analyzeFailedBackData(res, req?.getImageKnifeData());
|
||||
}
|
||||
},
|
||||
border: { radius: 50 },
|
||||
onComplete: (event) => {
|
||||
if (event && event.loadingStatus == 0) {
|
||||
this.renderTime = this.formatDate(Date.now());
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
Button($r('app.string.list_pic'))
|
||||
.fontSize(13)
|
||||
.onClick(() => {
|
||||
router.push({
|
||||
url: 'pages/TestListImageKnifeCallbackPage',
|
||||
});
|
||||
})
|
||||
if (this.showChild) {
|
||||
ImageKnifeComponent(
|
||||
{ imageKnifeOption: this.imageKnifeOption })
|
||||
.height(this.currentHeight)
|
||||
.width(this.currentWidth)
|
||||
.margin({ top: 20, bottom: 20 })
|
||||
|
||||
}
|
||||
}
|
||||
.width('100%')
|
||||
}
|
||||
}.alignItems(HorizontalAlign.Start)
|
||||
}
|
||||
|
||||
formatDate(time: number | undefined) {
|
||||
if (!time) {
|
||||
return;
|
||||
}
|
||||
let date = new Date(time);
|
||||
const year = date.getFullYear().toString()
|
||||
let month = (date.getMonth() + 1).toString()
|
||||
let day = date.getDate().toString()
|
||||
let hour = date.getHours().toString()
|
||||
let min = date.getMinutes().toString()
|
||||
let seconds = date.getSeconds().toString()
|
||||
let mill = date.getMilliseconds();
|
||||
return `${year}-${month}-${day} ${hour}:${min}:${seconds}:${mill}`
|
||||
}
|
||||
|
||||
analyzeStartCallBackData(req: ImageKnifeRequest | undefined) {
|
||||
let data = req?.getImageKnifeData();
|
||||
if (data) {
|
||||
if (typeof req?.imageKnifeOption.loadSrc == 'string') {
|
||||
this.url = req?.imageKnifeOption.loadSrc;
|
||||
}
|
||||
this.componentWidth = req?.componentWidth;
|
||||
this.componentHeight = req?.componentHeight;
|
||||
this.reqStartTime = this.formatDate(data.timeInfo?.requestStartTime);
|
||||
this.memoryStartTime = this.formatDate(data.timeInfo?.memoryCheckStartTime);
|
||||
this.memoryEndTime = this.formatDate(data.timeInfo?.memoryCheckEndTime);
|
||||
}
|
||||
}
|
||||
|
||||
analyzeSuccessCallBackData(data: ImageKnifeData | undefined) {
|
||||
if (data) {
|
||||
this.imageWidth = data.imageWidth;
|
||||
this.imageHeight = data.imageHeight;
|
||||
this.imageSize = data.bufSize;
|
||||
this.frameNum = data.frameCount;
|
||||
this.decodeSize = JSON.stringify(data.decodeImages);
|
||||
this.imageType = data.type;
|
||||
this.reqEndTime = this.formatDate(data.timeInfo?.requestEndTime);
|
||||
this.diskStartTime = this.formatDate(data.timeInfo?.diskCheckStartTime);
|
||||
this.diskEndTime = this.formatDate(data.timeInfo?.diskCheckEndTime);
|
||||
this.netStartTime = this.formatDate(data.timeInfo?.netRequestStartTime);
|
||||
this.netEndTime = this.formatDate(data.timeInfo?.netRequestEndTime);
|
||||
this.decodeStartTime = this.formatDate(data.timeInfo?.diskCheckStartTime);
|
||||
this.decodeEndTime = this.formatDate(data.timeInfo?.diskCheckEndTime);
|
||||
}
|
||||
}
|
||||
|
||||
analyzeFailedBackData(res: string, data: ImageKnifeData | undefined) {
|
||||
if (data) {
|
||||
this.err_msg = res;
|
||||
this.err_phase = data.errorInfo?.phase;
|
||||
this.err_code = data.errorInfo?.code;
|
||||
this.http_code = data.errorInfo?.httpCode;
|
||||
this.reqEndTime = this.formatDate(data.timeInfo?.requestEndTime);
|
||||
this.diskStartTime = this.formatDate(data.timeInfo?.diskCheckStartTime);
|
||||
this.diskEndTime = this.formatDate(data.timeInfo?.diskCheckEndTime);
|
||||
this.netStartTime = this.formatDate(data.timeInfo?.netRequestStartTime);
|
||||
this.netEndTime = this.formatDate(data.timeInfo?.netRequestEndTime);
|
||||
this.decodeStartTime = this.formatDate(data.timeInfo?.diskCheckStartTime);
|
||||
this.decodeEndTime = this.formatDate(data.timeInfo?.diskCheckEndTime);
|
||||
this.reqCancelTime = this.formatDate(data.timeInfo?.requestCancelTime)
|
||||
}
|
||||
}
|
||||
|
||||
destroy() {
|
||||
this.currentWidth = 200
|
||||
this.currentHeight = 200
|
||||
this.url = ""
|
||||
this.imageType = ""
|
||||
this.imageWidth = 0
|
||||
this.imageHeight = 0
|
||||
this.imageSize = 0
|
||||
this.componentWidth = 0
|
||||
this.componentHeight = 0
|
||||
this.frameNum = 0
|
||||
this.decodeSize = ""
|
||||
this.err_msg = ""
|
||||
this.err_phase = ""
|
||||
this.err_code = 0
|
||||
this.http_code = 0
|
||||
this.reqStartTime = ""
|
||||
this.reqEndTime = ""
|
||||
this.reqCancelTime = ""
|
||||
this.memoryStartTime = ""
|
||||
this.memoryEndTime = ""
|
||||
this.diskStartTime = ""
|
||||
this.diskEndTime = ""
|
||||
this.netStartTime = ""
|
||||
this.netEndTime = ""
|
||||
this.decodeStartTime = ""
|
||||
this.decodeEndTime = ""
|
||||
this.renderTime = ""
|
||||
this.showChild = true;
|
||||
}
|
||||
}
|
|
@ -15,15 +15,15 @@
|
|||
import { ImageKnifeComponent, ImageKnife, ImageKnifeOption, CacheStrategy } from '@ohos/libraryimageknife'
|
||||
|
||||
@Entry
|
||||
@ComponentV2
|
||||
@Component
|
||||
struct TestIsUrlExist {
|
||||
@Local imageKnifeOption: ImageKnifeOption = new ImageKnifeOption({
|
||||
@State imageKnifeOption: ImageKnifeOption = {
|
||||
loadSrc: $r('app.media.startIcon'),
|
||||
placeholderSrc: $r('app.media.loading'),
|
||||
errorholderSrc:$r('app.media.failed')
|
||||
})
|
||||
@Local source: PixelMap | string | Resource = $r("app.media.startIcon")
|
||||
@Local source1: PixelMap | string | Resource = $r("app.media.startIcon")
|
||||
}
|
||||
@State source: PixelMap | string | Resource = $r("app.media.startIcon")
|
||||
@State source1: PixelMap | string | Resource = $r("app.media.startIcon")
|
||||
|
||||
build() {
|
||||
Column() {
|
||||
|
|
|
@ -0,0 +1,101 @@
|
|||
/*
|
||||
* Copyright (C) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { ImageKnifeComponent} from '@ohos/libraryimageknife';
|
||||
|
||||
class ArrayElement {
|
||||
src: string = "";
|
||||
w: number = 0;
|
||||
h: number = 0;
|
||||
}
|
||||
|
||||
@Entry
|
||||
@Component
|
||||
struct TestListImageKnifeCallbackPage {
|
||||
private wid: number = 200;
|
||||
private hig: number = 200;
|
||||
private dataArray: ESObject[] = [
|
||||
"https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/56/v3/8MdhfSsCSMKj4sA6okUWrg/5uBx56tLTUO3RYQl-E5JiQ.jpg",
|
||||
"https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/56/v3/8MdhfSsCSMKj4sA6okUWrg/5uBx56tLTUO3RYQl-E5JiQ.jpg",
|
||||
"https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658",
|
||||
"https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/78/v3/qQJpAtRGQe2e_VhbGHDgIw/b3zlit99S6GybD3XdNwqJw.jpg",
|
||||
"https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/55/v3/5DZ2LLqYSsK85-shqgLveQ/7ZXcyCWNTvOzQP5FFLBGkg.jpg",
|
||||
"https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/3e/v3/LqRoLI-PRSu9Nqa8KdJ-pQ/dSqskBpSR9eraAMn7NBdqA.jpg",
|
||||
"https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/25/v3/jgB2ekkTRX-3yTYZalnANQ/xff_x9cbSPqb7fbNwgJa7A.jpg",
|
||||
"https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/fb/v3/alXwXLHKSyCAIWt_ydgD2g/BCCuu25TREOitQxM7eYOEw.jpg",
|
||||
"https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/63/v3/qbe6NZkCQyGcITvdWoZBgg/Y-5U1z3GT_yaK8CBD3jkwg.jpg",
|
||||
"https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/16/v3/fm2tO4TsRH6mv_D_nSSd5w/FscLpLwQQ-KuV7oaprFK2Q.jpg",
|
||||
"https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/89/v3/UAUvtPHqRD-GWWANsEC57Q/zcRJCQebQ322Aby4jzmwmQ.jpg",
|
||||
"https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/30/v3/tUUzzx73R4yp8G--lMhuWQ/EBbcu_dLTT-Jj68XAh6mtA.jpg",
|
||||
"https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/76/v3/EyF6z4FISpCHhae38eEexw/OtyAiu-zSSevNQYvUdtVmA.jpg",
|
||||
"https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/37/v3/12rH1yiEQmK9wlOOcy5avQ/RzBXiEBRRqOC7LRkwNj6VA.jpg",
|
||||
"https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/9a/v3/TpRN4AIzRoyUXIqWdKoE0g/ShOnD_tfS46HDbpSWhbCkQ.jpg",
|
||||
"https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/03/v3/H3X17s8eTdS2w56JgbB5jQ/a45sT-j8Sbe8sSQXTzeYvQ.jpg",
|
||||
"https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/10/v3/qaEzwkU0QeKb1yehnP2Xig/q7fxAlgMQKup-HUBayRLGQ.jpg",
|
||||
"https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/96/v3/rMJJoAflTDSWa1z2pHs2wg/8dOqD0GlQBOCL5AvQok9FQ.jpg",
|
||||
"https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/ed/v3/KMO4D6D2QGuVOCLX4AhOFA/ef51xAaLQuK7BsnuD9abog.jpg",
|
||||
"https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/d9/v3/FSZH0aTdSqWxeAaxoPvi0g/RqxPxUCXQFiTMBfKTF9kkw.jpg",
|
||||
"https://hbimg.huabanimg.com/cc6af25f8d782d3cf3122bef4e61571378271145735e9-vEVggB",
|
||||
'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/bf/v3/lSjrRwFcS-ez6jp1ALSQFg/0n7R7XinSPyrYLqDu_1dfw.jpg',
|
||||
'https://img-blog.csdn.net/20140514114029140',
|
||||
'https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp',
|
||||
$r('app.media.pngSample'),
|
||||
$r('app.media.rabbit')
|
||||
]
|
||||
private data: Array<ArrayElement> = [];
|
||||
|
||||
aboutToAppear(): void {
|
||||
for (let i = 0; i < this.dataArray.length; i++) {
|
||||
let element: ArrayElement = {
|
||||
src: this.dataArray[i],
|
||||
w: this.wid -(i*5),
|
||||
h: this.hig -(i*5)
|
||||
}
|
||||
this.data.push(element);
|
||||
}
|
||||
}
|
||||
|
||||
build() {
|
||||
List({ space: 3 }) {
|
||||
ForEach(this.data, (item: ArrayElement) => {
|
||||
ListItem() {
|
||||
ImageKnifeComponent({
|
||||
imageKnifeOption:
|
||||
{
|
||||
loadSrc: item.src,
|
||||
objectFit: ImageFit.Contain,
|
||||
onLoadListener: {
|
||||
onLoadStart: (data) => {
|
||||
console.log("listCache start:{ url:"+data?.imageKnifeOption.loadSrc +",componentWidth:"+data?.componentWidth+",componentHeight:"+data?.componentHeight+"},"
|
||||
+ JSON.stringify(data?.getImageKnifeData()))
|
||||
},
|
||||
onLoadFailed: (res, req) => {
|
||||
console.log("listCache onLoadFailed:res:" + res + ";" + JSON.stringify(req?.getImageKnifeData()))
|
||||
},
|
||||
onLoadSuccess: (data, imageData,req) => {
|
||||
console.log("listCache onLoadSuccess:" + JSON.stringify(req?.getImageKnifeData()))
|
||||
},
|
||||
onLoadCancel: (res, req) => {
|
||||
console.log("listCache onLoadCancel:res:" + res + ";" + JSON.stringify(req?.getImageKnifeData()))
|
||||
}
|
||||
},
|
||||
border: { radius: 50 },
|
||||
}
|
||||
}).height(item.w).width(item.h)
|
||||
}.width('100%')
|
||||
}, (item: ArrayElement,index) => (item.src+index))
|
||||
}.width('100%').height('100%')
|
||||
}
|
||||
}
|
|
@ -13,20 +13,21 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { ImageKnifeComponent, ImageKnifeOption } from '@ohos/imageknife';
|
||||
import { ImageKnife, ImageKnifeComponent, ImageKnifeOption } from '@ohos/libraryimageknife';
|
||||
|
||||
|
||||
@Entry
|
||||
@ComponentV2
|
||||
@Component
|
||||
struct TestLoadCancelListenerPage {
|
||||
@Local currentWidth: number = 200
|
||||
@Local currentHeight: number = 200
|
||||
@Local showChild: boolean = true;
|
||||
@Local text: string = "";
|
||||
@Local ImageKnifeOption: ImageKnifeOption = new ImageKnifeOption({
|
||||
@State currentWidth: number = 200
|
||||
@State currentHeight: number = 200
|
||||
@State showChild: boolean = true;
|
||||
@State text: string = "";
|
||||
@State ImageKnifeOption: ImageKnifeOption = {
|
||||
loadSrc: "",
|
||||
objectFit: ImageFit.Contain,
|
||||
border: { radius: 50 }
|
||||
})
|
||||
};
|
||||
|
||||
build() {
|
||||
Column() {
|
||||
|
@ -34,7 +35,8 @@ struct TestLoadCancelListenerPage {
|
|||
Button($r('app.string.rm_component_of_net'))
|
||||
.margin(20)
|
||||
.onClick(() => {
|
||||
this.ImageKnifeOption = new ImageKnifeOption({
|
||||
this.clearCache();
|
||||
this.ImageKnifeOption = {
|
||||
loadSrc: "https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/76/v3/EyF6z4FISpCHhae38eEexw/OtyAiu-zSSevNQYvUdtVmA.jpg",
|
||||
objectFit: ImageFit.Contain,
|
||||
onLoadListener: {
|
||||
|
@ -47,23 +49,24 @@ struct TestLoadCancelListenerPage {
|
|||
}
|
||||
},
|
||||
border: { radius: 50 }
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
Button($r('app.string.component_display'))
|
||||
.margin(20).onClick(() => {
|
||||
this.text = "";
|
||||
this.showChild = true;
|
||||
this.ImageKnifeOption = new ImageKnifeOption({
|
||||
this.ImageKnifeOption = {
|
||||
loadSrc: "",
|
||||
objectFit: ImageFit.Contain,
|
||||
border: { radius: 50 }
|
||||
})
|
||||
}
|
||||
})
|
||||
Button($r('app.string.rm_component_of_local'))
|
||||
.margin(20)
|
||||
.onClick(() => {
|
||||
this.ImageKnifeOption = new ImageKnifeOption({
|
||||
this.clearCache();
|
||||
this.ImageKnifeOption = {
|
||||
loadSrc: $r('app.media.loading'),
|
||||
objectFit: ImageFit.Contain,
|
||||
onLoadListener: {
|
||||
|
@ -76,7 +79,7 @@ struct TestLoadCancelListenerPage {
|
|||
}
|
||||
},
|
||||
border: { radius: 50 }
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
if (this.showChild) {
|
||||
|
@ -91,4 +94,8 @@ struct TestLoadCancelListenerPage {
|
|||
.height('100%')
|
||||
.width('100%')
|
||||
}
|
||||
|
||||
clearCache(){
|
||||
ImageKnife.getInstance().removeAllMemoryCache();
|
||||
}
|
||||
}
|
|
@ -15,19 +15,19 @@
|
|||
import { ImageKnifeComponent,ImageKnife,ImageKnifeOption } from '@ohos/libraryimageknife'
|
||||
|
||||
@Entry
|
||||
@ComponentV2
|
||||
@Component
|
||||
struct TestPrefetchToFileCachePage {
|
||||
@Local imageKnifeOption: ImageKnifeOption = new ImageKnifeOption({
|
||||
@State imageKnifeOption: ImageKnifeOption = {
|
||||
loadSrc:$r('app.media.startIcon'),
|
||||
placeholderSrc:$r('app.media.loading'),
|
||||
errorholderSrc:$r('app.media.failed')
|
||||
})
|
||||
}
|
||||
async preload(url:string) {
|
||||
let fileCachePath = await ImageKnife.getInstance().preLoadCache(url)
|
||||
console.log("preload-fileCachePath=="+ fileCachePath)
|
||||
}
|
||||
async preload1(url:string) {
|
||||
let fileCachePath = await ImageKnife.getInstance().preLoadCache(new ImageKnifeOption({ loadSrc: url }))
|
||||
let fileCachePath = await ImageKnife.getInstance().preLoadCache({ loadSrc: url })
|
||||
console.log("preload-fileCachePath1=="+ fileCachePath)
|
||||
}
|
||||
build() {
|
||||
|
|
|
@ -15,16 +15,16 @@
|
|||
import { ImageKnifeComponent, ImageKnife, ImageKnifeOption, CacheStrategy } from '@ohos/libraryimageknife'
|
||||
|
||||
@Entry
|
||||
@ComponentV2
|
||||
@Component
|
||||
struct TestRemoveCache {
|
||||
@Local imageKnifeOption: ImageKnifeOption = new ImageKnifeOption({
|
||||
@State imageKnifeOption: ImageKnifeOption = {
|
||||
loadSrc: $r('app.media.startIcon'),
|
||||
placeholderSrc: $r('app.media.loading'),
|
||||
errorholderSrc:$r('app.media.failed')
|
||||
})
|
||||
@Local source: PixelMap | string | Resource = $r("app.media.startIcon");
|
||||
@Local source1: PixelMap | string | Resource = $r("app.media.startIcon");
|
||||
@Local url: string = '';
|
||||
}
|
||||
@State source: PixelMap | string | Resource = $r("app.media.startIcon");
|
||||
@State source1: PixelMap | string | Resource = $r("app.media.startIcon");
|
||||
@State url: string = '';
|
||||
|
||||
build() {
|
||||
Column() {
|
||||
|
|
|
@ -15,42 +15,40 @@
|
|||
import { ImageKnifeComponent, ImageKnife, ImageKnifeOption } from '@ohos/libraryimageknife'
|
||||
|
||||
@Entry
|
||||
@ComponentV2
|
||||
@Component
|
||||
struct TestSetCustomImagePage {
|
||||
|
||||
getResourceString(res:Resource){
|
||||
return getContext().resourceManager.getStringSync(res.id)
|
||||
}
|
||||
|
||||
@Local imageKnifeOption: ImageKnifeOption = new ImageKnifeOption({
|
||||
@State imageKnifeOption: ImageKnifeOption = {
|
||||
loadSrc: $r('app.media.startIcon'),
|
||||
placeholderSrc: $r('app.media.loading')
|
||||
})
|
||||
}
|
||||
aboutToAppear(): void {
|
||||
ImageKnife.getInstance().setCustomGetImage(custom)
|
||||
}
|
||||
aboutToDisappear(): void {
|
||||
ImageKnife.getInstance().setCustomGetImage()
|
||||
}
|
||||
getResourceString(res:Resource){
|
||||
return getContext().resourceManager.getStringSync(res.id)
|
||||
}
|
||||
build() {
|
||||
Column() {
|
||||
Button(this.getResourceString($r('app.string.Custom_network_download')) + " a").onClick(()=>{
|
||||
this.imageKnifeOption = new ImageKnifeOption({
|
||||
this.imageKnifeOption ={
|
||||
loadSrc: "aaa",
|
||||
placeholderSrc: $r('app.media.loading')
|
||||
})
|
||||
}
|
||||
})
|
||||
Button(this.getResourceString($r('app.string.Custom_network_download')) + " b").onClick(()=>{
|
||||
this.imageKnifeOption = new ImageKnifeOption({
|
||||
this.imageKnifeOption = {
|
||||
loadSrc: "bbb",
|
||||
placeholderSrc: $r('app.media.loading')
|
||||
})
|
||||
}
|
||||
})
|
||||
Button(this.getResourceString($r('app.string.Custom_network_download')) + " c").onClick(()=>{
|
||||
this.imageKnifeOption = new ImageKnifeOption({
|
||||
this.imageKnifeOption = {
|
||||
loadSrc: "ccc",
|
||||
placeholderSrc: $r('app.media.loading')
|
||||
})
|
||||
}
|
||||
})
|
||||
ImageKnifeComponent({
|
||||
imageKnifeOption: this.imageKnifeOption
|
||||
|
@ -62,8 +60,9 @@ struct TestSetCustomImagePage {
|
|||
}
|
||||
}
|
||||
@Concurrent
|
||||
async function custom(context: Context, src: string | PixelMap | Resource): Promise<ArrayBuffer | undefined> {
|
||||
async function custom(context: Context, src: string | PixelMap | Resource,headers?: Record<string,Object>): Promise<ArrayBuffer | undefined> {
|
||||
console.info("ImageKnife:: custom download:" + src)
|
||||
// 举例写死从本地文件读取,也可以自己请求网络图片
|
||||
return context.resourceManager.getMediaContentSync($r("app.media.pngSample").id).buffer as ArrayBuffer
|
||||
let buffer = context.resourceManager.getMediaContentSync($r("app.media.pngSample").id).buffer as ArrayBuffer
|
||||
return buffer
|
||||
}
|
|
@ -24,12 +24,12 @@ export struct ZuImage {
|
|||
if (this.src) {
|
||||
//当前版本存在bug
|
||||
ImageKnifeComponent({
|
||||
imageKnifeOption: new ImageKnifeOption({
|
||||
imageKnifeOption: {
|
||||
loadSrc: this.src,
|
||||
placeholderSrc: this.placeholderSrc,
|
||||
errorholderSrc: this.errorholderSrc ?? this.placeholderSrc,
|
||||
objectFit: ImageFit.Cover
|
||||
})
|
||||
}
|
||||
})
|
||||
} else {
|
||||
Image(this.placeholderSrc)
|
||||
|
|
|
@ -15,55 +15,55 @@
|
|||
import { ImageKnifeComponent,CacheStrategy,ImageKnifeOption } from '@ohos/libraryimageknife'
|
||||
|
||||
@Entry
|
||||
@ComponentV2
|
||||
@Component
|
||||
struct TestWriteCacheStage {
|
||||
@Local imageKnifeOption1: ImageKnifeOption = new ImageKnifeOption({
|
||||
@State imageKnifeOption1: ImageKnifeOption = {
|
||||
loadSrc:$r('app.media.startIcon'),
|
||||
placeholderSrc:$r('app.media.loading'),
|
||||
errorholderSrc:$r('app.media.failed')
|
||||
})
|
||||
@Local imageKnifeOption2: ImageKnifeOption = new ImageKnifeOption({
|
||||
}
|
||||
@State imageKnifeOption2: ImageKnifeOption = {
|
||||
loadSrc:$r('app.media.startIcon'),
|
||||
placeholderSrc:$r('app.media.loading'),
|
||||
errorholderSrc:$r('app.media.failed')
|
||||
})
|
||||
@Local imageKnifeOption3: ImageKnifeOption = new ImageKnifeOption({
|
||||
}
|
||||
@State imageKnifeOption3: ImageKnifeOption = {
|
||||
loadSrc:$r('app.media.startIcon'),
|
||||
placeholderSrc:$r('app.media.loading'),
|
||||
errorholderSrc:$r('app.media.failed')
|
||||
})
|
||||
}
|
||||
|
||||
build() {
|
||||
Column() {
|
||||
Button($r('app.string.Write_memory_and_file')).margin({top:10}).onClick(async ()=>{
|
||||
this.imageKnifeOption1 = new ImageKnifeOption({
|
||||
this.imageKnifeOption1 = {
|
||||
loadSrc:'https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp',
|
||||
placeholderSrc:$r('app.media.loading'),
|
||||
errorholderSrc:$r('app.media.failed'),
|
||||
writeCacheStrategy:CacheStrategy.Default
|
||||
})
|
||||
}
|
||||
})
|
||||
ImageKnifeComponent({
|
||||
imageKnifeOption: this.imageKnifeOption1
|
||||
}).width(200).height(200).margin({top:10})
|
||||
Button($r('app.string.Write_memory')).margin({top:10}).onClick(async ()=>{
|
||||
this.imageKnifeOption2 = new ImageKnifeOption({
|
||||
this.imageKnifeOption2 = {
|
||||
loadSrc:"https://hbimg.huabanimg.com/cc6af25f8d782d3cf3122bef4e61571378271145735e9-vEVggB",
|
||||
placeholderSrc:$r('app.media.loading'),
|
||||
errorholderSrc:$r('app.media.failed'),
|
||||
writeCacheStrategy:CacheStrategy.Memory
|
||||
})
|
||||
}
|
||||
})
|
||||
ImageKnifeComponent({
|
||||
imageKnifeOption: this.imageKnifeOption2
|
||||
}).width(200).height(200).margin({top:10})
|
||||
Button($r('app.string.Write_file')).margin({top:10}).onClick(async ()=>{
|
||||
this.imageKnifeOption3 = new ImageKnifeOption({
|
||||
this.imageKnifeOption3 = {
|
||||
loadSrc:'https://img-blog.csdn.net/20140514114029140',
|
||||
placeholderSrc:$r('app.media.loading'),
|
||||
errorholderSrc:$r('app.media.failed'),
|
||||
writeCacheStrategy:CacheStrategy.File
|
||||
})
|
||||
}
|
||||
})
|
||||
ImageKnifeComponent({
|
||||
imageKnifeOption: this.imageKnifeOption3
|
||||
|
|
|
@ -17,17 +17,17 @@ import matrix4 from '@ohos.matrix4'
|
|||
|
||||
|
||||
@Entry
|
||||
@ComponentV2
|
||||
@Component
|
||||
struct TransformPage {
|
||||
private custom_scale:number = 1
|
||||
@Local matrix1:object = matrix4.identity().scale({ x: 1, y: 1 })
|
||||
@Local ImageKnifeOption: ImageKnifeOption = new ImageKnifeOption({
|
||||
@State matrix1:object = matrix4.identity().scale({ x: 1, y: 1 })
|
||||
@State ImageKnifeOption: ImageKnifeOption = {
|
||||
loadSrc: $r("app.media.rabbit"),
|
||||
placeholderSrc: $r("app.media.loading"),
|
||||
errorholderSrc: $r("app.media.app_icon"),
|
||||
objectFit: ImageFit.Contain,
|
||||
border: { radius: 50 }
|
||||
})
|
||||
}
|
||||
|
||||
build() {
|
||||
Column() {
|
||||
|
|
|
@ -15,50 +15,24 @@
|
|||
import { ImageKnifeComponent, ImageKnifeOption } from '@ohos/libraryimageknife'
|
||||
|
||||
// const logger = new imUtils.logger.IMLogger('Avatar')
|
||||
@ObservedV2
|
||||
export class MyStorage {
|
||||
static instance:MyStorage | undefined = undefined
|
||||
static getInstance(){
|
||||
if(MyStorage.instance == undefined) {
|
||||
MyStorage.instance = new MyStorage()
|
||||
}
|
||||
return MyStorage.instance
|
||||
}
|
||||
@Trace WeLink_Mob_fontSize_multiple: number = 1
|
||||
|
||||
class MyImageOption extends ImageKnifeOption {
|
||||
account?: string
|
||||
}
|
||||
|
||||
@ComponentV2
|
||||
@Component
|
||||
export struct UserAvatar {
|
||||
@Prop @Watch('userInfoUpdate') userInfo: string = ""
|
||||
// @Prop userInfo: string = ""
|
||||
imgSize: number = 100
|
||||
radius: number = 12
|
||||
borderSize: number = 0
|
||||
imgSizes: number = 1
|
||||
@Local ImageKnifeOption: ImageKnifeOption = new ImageKnifeOption()
|
||||
@State ImageKnifeOption: ImageKnifeOption = new ImageKnifeOption()
|
||||
@StorageProp('WeLink_Mob_fontSize_multiple') @Watch('updateImgSize') WeLink_Mob_fontSize_multiple: number = 0
|
||||
scalable: boolean = true;
|
||||
@Local calcImgSize: number = 100
|
||||
@Param userInfo: string = ""
|
||||
@Monitor('userInfo')
|
||||
userInfoUpdate() {
|
||||
// if (uri === 'userInfo' && this.imageKnifeOption.account !== this.userInfo.contactId) return;
|
||||
// // logger.info(`userInfoUpdate uri=${uri} oldAcc=${this.imageKnifeOption.loadSrc} nowAcc=${this.userInfo.externalHeadUrl}`)
|
||||
// if (this.userInfo.externalHeadUrl === this.imageKnifeOption.loadSrc && this.userInfo.infoUpdateTime.getTime()
|
||||
// .toString() === this.imageKnifeOption?.signature?.getKey()) return;
|
||||
this.ImageKnifeOption = new ImageKnifeOption({
|
||||
//TODO:写死loadSRC,场景:变更组件大小,所有图片不显示
|
||||
loadSrc: this.userInfo,
|
||||
placeholderSrc: $r('app.media.loading'),
|
||||
errorholderSrc: $r('app.media.failed'),
|
||||
border: { radius:20,width:5,color:$r('app.color.start_window_background') },
|
||||
objectFit:ImageFit.Contain
|
||||
// signature: new ObjectKey(this.userInfo.infoUpdateTime.getTime().toString())
|
||||
})
|
||||
}
|
||||
@Local storage: MyStorage = MyStorage.getInstance()
|
||||
@Monitor('storage.WeLink_Mob_fontSize_multiple')
|
||||
updateImgSize() {
|
||||
this.setImageSize()
|
||||
}
|
||||
@State calcImgSize: number = 100
|
||||
|
||||
aboutToAppear(): void {
|
||||
this.userInfoUpdate()
|
||||
this.setImageSize()
|
||||
|
@ -67,19 +41,39 @@ export struct UserAvatar {
|
|||
setImageSize() {
|
||||
if (!this.scalable) {
|
||||
this.calcImgSize = this.imgSize
|
||||
} else if (this.storage.WeLink_Mob_fontSize_multiple < 0.9) {
|
||||
} else if (this.WeLink_Mob_fontSize_multiple < 0.9) {
|
||||
this.calcImgSize = this.imgSize * 0.9
|
||||
} else if (this.storage.WeLink_Mob_fontSize_multiple > 1.6) {
|
||||
} else if (this.WeLink_Mob_fontSize_multiple > 1.6) {
|
||||
this.calcImgSize = this.imgSize * 1.6
|
||||
} else {
|
||||
this.calcImgSize = this.imgSize * this.storage.WeLink_Mob_fontSize_multiple
|
||||
this.calcImgSize = this.imgSize * this.WeLink_Mob_fontSize_multiple
|
||||
}
|
||||
}
|
||||
|
||||
updateImgSize() {
|
||||
this.setImageSize()
|
||||
}
|
||||
|
||||
aboutToReuse(param: ESObject) {
|
||||
this.userInfoUpdate()
|
||||
}
|
||||
|
||||
userInfoUpdate() {
|
||||
// if (uri === 'userInfo' && this.imageKnifeOption.account !== this.userInfo.contactId) return;
|
||||
// // logger.info(`userInfoUpdate uri=${uri} oldAcc=${this.imageKnifeOption.loadSrc} nowAcc=${this.userInfo.externalHeadUrl}`)
|
||||
// if (this.userInfo.externalHeadUrl === this.imageKnifeOption.loadSrc && this.userInfo.infoUpdateTime.getTime()
|
||||
// .toString() === this.imageKnifeOption?.signature?.getKey()) return;
|
||||
this.ImageKnifeOption = {
|
||||
//TODO:写死loadSRC,场景:变更组件大小,所有图片不显示
|
||||
loadSrc: this.userInfo,
|
||||
placeholderSrc: $r('app.media.loading'),
|
||||
errorholderSrc: $r('app.media.failed'),
|
||||
border: { radius:20,width:5,color:$r('app.color.start_window_background') },
|
||||
objectFit:ImageFit.Contain
|
||||
// signature: new ObjectKey(this.userInfo.infoUpdateTime.getTime().toString())
|
||||
}
|
||||
}
|
||||
|
||||
build() {
|
||||
Row() {
|
||||
// Image(this.imageKnifeOption.loadSrc)
|
||||
|
|
|
@ -12,52 +12,13 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { MyStorage, UserAvatar } from './User'
|
||||
import { CommonDataSource } from './model/CommonDataSource'
|
||||
import { UserAvatar } from './User'
|
||||
|
||||
class CommonDataSource <T> implements IDataSource {
|
||||
private dataArray: T[] = []
|
||||
private listeners: DataChangeListener[] = []
|
||||
|
||||
constructor(element: []) {
|
||||
this.dataArray = element
|
||||
}
|
||||
|
||||
public getData(index: number) {
|
||||
return this.dataArray[index]
|
||||
}
|
||||
|
||||
public totalCount(): number {
|
||||
return this.dataArray.length
|
||||
}
|
||||
|
||||
public addData(index: number, data: T[]): void {
|
||||
this.dataArray = this.dataArray.concat(data)
|
||||
this.notifyDataAdd(index)
|
||||
}
|
||||
|
||||
unregisterDataChangeListener(listener: DataChangeListener): void {
|
||||
const pos = this.listeners.indexOf(listener);
|
||||
if (pos >= 0) {
|
||||
this.listeners.splice(pos, 1);
|
||||
}
|
||||
}
|
||||
|
||||
registerDataChangeListener(listener: DataChangeListener): void {
|
||||
if (this.listeners.indexOf(listener) < 0) {
|
||||
this.listeners.push(listener)
|
||||
}
|
||||
}
|
||||
|
||||
notifyDataAdd(index: number): void {
|
||||
this.listeners.forEach((listener: DataChangeListener) => {
|
||||
listener.onDataAdd(index)
|
||||
})
|
||||
}
|
||||
}
|
||||
@Entry
|
||||
@ComponentV2
|
||||
@Component
|
||||
struct Index {
|
||||
@Local hotCommendList:CommonDataSource<string> = new CommonDataSource<string>([])
|
||||
@State hotCommendList:CommonDataSource<string> = new CommonDataSource<string>([])
|
||||
private data:string[] = [
|
||||
"https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/56/v3/8MdhfSsCSMKj4sA6okUWrg/5uBx56tLTUO3RYQl-E5JiQ.jpg",
|
||||
"https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/e2/v3/4zI1Xm_3STmV30aZXWRrKw/6aN7WodDRUiBApgffiLPCg.jpg",
|
||||
|
@ -85,41 +46,25 @@ struct Index {
|
|||
'https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp',
|
||||
]
|
||||
aboutToAppear(): void {
|
||||
MyStorage.getInstance().WeLink_Mob_fontSize_multiple = 1
|
||||
this.hotCommendList.addData(this.hotCommendList.totalCount(),this.data)
|
||||
AppStorage.set("WeLink_Mob_fontSize_multiple",1)
|
||||
}
|
||||
|
||||
build() {
|
||||
Column() {
|
||||
Button("bigger").onClick(()=>{
|
||||
MyStorage.getInstance().WeLink_Mob_fontSize_multiple = 1.6
|
||||
AppStorage.set("WeLink_Mob_fontSize_multiple",1.6)
|
||||
})
|
||||
Button("small").onClick(()=>{
|
||||
MyStorage.getInstance().WeLink_Mob_fontSize_multiple = 0.8
|
||||
AppStorage.set("WeLink_Mob_fontSize_multiple",0.8)
|
||||
})
|
||||
List(){
|
||||
// LazyForEach(this.hotCommendList,(item:string)=>{
|
||||
// ListItem(){
|
||||
// ReuseImage({
|
||||
// userInfo:item
|
||||
// }).width("100%").height("100%").backgroundColor(Color.Yellow)
|
||||
// }.width(200).height(200).margin({bottom:5})
|
||||
// })
|
||||
Repeat(this.data)
|
||||
.each((repeatItem)=>{
|
||||
LazyForEach(this.hotCommendList,(item:string)=>{
|
||||
ListItem(){
|
||||
ReuseImage({
|
||||
userInfo:repeatItem.item
|
||||
userInfo:item
|
||||
}).width("100%").height("100%").backgroundColor(Color.Yellow)
|
||||
}.width(200).height(200).margin({bottom:5}).key("reuse")
|
||||
})
|
||||
.key(item => item+"reuse")
|
||||
.virtualScroll()
|
||||
.template("1",(repeatItem)=>{
|
||||
ListItem(){
|
||||
ReuseImage({
|
||||
userInfo:repeatItem.item
|
||||
}).width("100%").height("100%").backgroundColor(Color.Yellow)
|
||||
}.width(200).height(200).margin({bottom:5}).key("reuse")
|
||||
}.width(200).height(200).margin({bottom:5})
|
||||
})
|
||||
}
|
||||
// .cachedCount(20)
|
||||
|
@ -131,13 +76,13 @@ struct Index {
|
|||
}
|
||||
|
||||
|
||||
// @Reusable
|
||||
@ComponentV2
|
||||
@Reusable
|
||||
@Component
|
||||
struct ReuseImage {
|
||||
@Param userInfo:string = ""
|
||||
// aboutToReuse(params: ESObject): void {
|
||||
// this.userInfo = params.userInfo
|
||||
// }
|
||||
@State userInfo:string = ""
|
||||
aboutToReuse(params: ESObject): void {
|
||||
this.userInfo = params.userInfo
|
||||
}
|
||||
|
||||
build() {
|
||||
Column(){
|
||||
|
|
|
@ -18,15 +18,15 @@ import { photoAccessHelper } from '@kit.MediaLibraryKit';
|
|||
|
||||
|
||||
@Entry
|
||||
@ComponentV2
|
||||
@Component
|
||||
struct DataShareUriLoadPage {
|
||||
@Local imageKnifeOption1: ImageKnifeOption =
|
||||
new ImageKnifeOption({
|
||||
@State imageKnifeOption1: ImageKnifeOption =
|
||||
{
|
||||
loadSrc: $r('app.media.icon'),
|
||||
|
||||
placeholderSrc: $r('app.media.loading'),
|
||||
errorholderSrc: $r('app.media.failed')
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
build() {
|
||||
|
@ -43,10 +43,10 @@ struct DataShareUriLoadPage {
|
|||
let photoViewPicker = new photoAccessHelper.PhotoViewPicker();
|
||||
let photoSelectResult: photoAccessHelper.PhotoSelectResult = await photoViewPicker.select(photoSelectOptions);
|
||||
uris = photoSelectResult.photoUris;
|
||||
this.imageKnifeOption1 = new ImageKnifeOption({
|
||||
this.imageKnifeOption1 = {
|
||||
loadSrc: uris[0],
|
||||
placeholderSrc:$r('app.media.loading')
|
||||
})
|
||||
}
|
||||
}).margin({ top: 5, left: 3 })
|
||||
ImageKnifeComponent({ imageKnifeOption: this.imageKnifeOption1 }).width(300).height(300)
|
||||
}.width('100%').backgroundColor(Color.Pink)
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* 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 { statfs } from '@kit.CoreFileKit'
|
||||
import { rcp } from '@kit.RemoteCommunicationKit'
|
||||
|
||||
export class CommonDataSource <T> implements IDataSource {
|
||||
private dataArray: T[] = []
|
||||
private listeners: DataChangeListener[] = []
|
||||
|
||||
constructor(element: []) {
|
||||
this.dataArray = element
|
||||
}
|
||||
|
||||
public getData(index: number) {
|
||||
return this.dataArray[index]
|
||||
}
|
||||
|
||||
public totalCount(): number {
|
||||
return this.dataArray.length
|
||||
}
|
||||
|
||||
public addData(index: number, data: T[]): void {
|
||||
this.dataArray = this.dataArray.concat(data)
|
||||
this.notifyDataAdd(index)
|
||||
}
|
||||
|
||||
unregisterDataChangeListener(listener: DataChangeListener): void {
|
||||
const pos = this.listeners.indexOf(listener);
|
||||
if (pos >= 0) {
|
||||
this.listeners.splice(pos, 1);
|
||||
}
|
||||
}
|
||||
|
||||
registerDataChangeListener(listener: DataChangeListener): void {
|
||||
if (this.listeners.indexOf(listener) < 0) {
|
||||
this.listeners.push(listener)
|
||||
}
|
||||
}
|
||||
|
||||
notifyDataAdd(index: number): void {
|
||||
this.listeners.forEach((listener: DataChangeListener) => {
|
||||
listener.onDataAdd(index)
|
||||
})
|
||||
}
|
||||
}
|
||||
export class GetSession {
|
||||
static session:rcp.Session = rcp.createSession()
|
||||
}
|
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
* Copyright (C) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import {ImageKnife, ImageKnifeRequest} from "@ohos/libraryimageknife"
|
||||
import { IDataSourcePrefetching } from '@kit.ArkUI';
|
||||
import { HashMap } from '@kit.ArkTS';
|
||||
|
||||
const IMADE_UNAVAILABLE = $r('app.media.failed')
|
||||
export interface InfoItem {
|
||||
albumUrl: string | Resource
|
||||
}
|
||||
export default class DataSourcePrefetchingImageKnife implements IDataSourcePrefetching {
|
||||
private dataArray: Array<InfoItem>
|
||||
private readonly requestList: HashMap<number,ImageKnifeRequest> = new HashMap()
|
||||
private listeners: DataChangeListener[] = [];
|
||||
|
||||
constructor(dataArray: Array<InfoItem>) {
|
||||
this.dataArray = dataArray;
|
||||
}
|
||||
public getData(index: number) {
|
||||
return this.dataArray[index]
|
||||
}
|
||||
|
||||
public totalCount(): number {
|
||||
return this.dataArray.length
|
||||
}
|
||||
|
||||
public addData(index: number, data: InfoItem[]): void {
|
||||
this.dataArray = this.dataArray.concat(data)
|
||||
this.notifyDataAdd(index)
|
||||
}
|
||||
|
||||
unregisterDataChangeListener(listener: DataChangeListener): void {
|
||||
const pos = this.listeners.indexOf(listener);
|
||||
if (pos >= 0) {
|
||||
this.listeners.splice(pos, 1);
|
||||
}
|
||||
}
|
||||
|
||||
registerDataChangeListener(listener: DataChangeListener): void {
|
||||
if (this.listeners.indexOf(listener) < 0) {
|
||||
this.listeners.push(listener)
|
||||
}
|
||||
}
|
||||
|
||||
notifyDataAdd(index: number): void {
|
||||
this.listeners.forEach((listener: DataChangeListener) => {
|
||||
listener.onDataAdd(index)
|
||||
})
|
||||
}
|
||||
async prefetch(index: number): Promise<void> {
|
||||
let item = this.dataArray[index]
|
||||
if (typeof item.albumUrl == "string") {
|
||||
// 图片预加载
|
||||
let request = ImageKnife.getInstance().preload({
|
||||
loadSrc:item.albumUrl,
|
||||
onLoadListener:{
|
||||
onLoadSuccess:()=>{
|
||||
// 预加载成功,删除成功请求
|
||||
this.requestList.remove(index)
|
||||
},
|
||||
onLoadFailed:()=>{
|
||||
// 移除失败请求
|
||||
this.requestList.remove(index)
|
||||
}
|
||||
}
|
||||
})
|
||||
this.requestList.set(index,request)
|
||||
}
|
||||
}
|
||||
// 取消请求处理
|
||||
cancel(index: number) {
|
||||
if(this.requestList.hasKey(index)) {
|
||||
// 返回MAP对象指定元素
|
||||
const request = this.requestList.get(index)
|
||||
// 取消请求
|
||||
ImageKnife.getInstance().cancel(request)
|
||||
// 移除被取消的请求对象
|
||||
this.requestList.remove(index)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,146 @@
|
|||
/*
|
||||
* Copyright (C) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { InfoItem } from './DataSourcePrefetching'
|
||||
|
||||
export class PageViewModel {
|
||||
private static dataArray: Array<InfoItem> = [
|
||||
{
|
||||
albumUrl: "https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/56/v3/8MdhfSsCSMKj4sA6okUWrg/5uBx56tLTUO3RYQl-E5JiQ.jpg"
|
||||
},
|
||||
{
|
||||
albumUrl: "https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/e2/v3/4zI1Xm_3STmV30aZXWRrKw/6aN7WodDRUiBApgffiLPCg.jpg"
|
||||
},
|
||||
{
|
||||
albumUrl: "https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/42/v3/2dSQCqERTP2TTPyssOMEbQ/zL1ebnKKQ_ilqTDcwCAkOw.jpg"
|
||||
},
|
||||
{
|
||||
albumUrl: "https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/78/v3/qQJpAtRGQe2e_VhbGHDgIw/b3zlit99S6GybD3XdNwqJw.jpg"
|
||||
},
|
||||
{
|
||||
albumUrl: "https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/55/v3/5DZ2LLqYSsK85-shqgLveQ/7ZXcyCWNTvOzQP5FFLBGkg.jpg"
|
||||
},
|
||||
{
|
||||
albumUrl: "https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/3e/v3/LqRoLI-PRSu9Nqa8KdJ-pQ/dSqskBpSR9eraAMn7NBdqA.jpg"
|
||||
},
|
||||
{
|
||||
albumUrl: "https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/25/v3/jgB2ekkTRX-3yTYZalnANQ/xff_x9cbSPqb7fbNwgJa7A.jpg"
|
||||
},
|
||||
{
|
||||
albumUrl: "https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/fb/v3/alXwXLHKSyCAIWt_ydgD2g/BCCuu25TREOitQxM7eYOEw.jpg"
|
||||
},
|
||||
{
|
||||
albumUrl: "https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/63/v3/qbe6NZkCQyGcITvdWoZBgg/Y-5U1z3GT_yaK8CBD3jkwg.jpg"
|
||||
},
|
||||
{
|
||||
albumUrl: "https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/16/v3/fm2tO4TsRH6mv_D_nSSd5w/FscLpLwQQ-KuV7oaprFK2Q.jpg"
|
||||
},
|
||||
{
|
||||
albumUrl: "https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/89/v3/UAUvtPHqRD-GWWANsEC57Q/zcRJCQebQ322Aby4jzmwmQ.jpg"
|
||||
},
|
||||
{
|
||||
albumUrl: "https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/30/v3/tUUzzx73R4yp8G--lMhuWQ/EBbcu_dLTT-Jj68XAh6mtA.jpg"
|
||||
},
|
||||
{
|
||||
albumUrl: "https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/76/v3/EyF6z4FISpCHhae38eEexw/OtyAiu-zSSevNQYvUdtVmA.jpg"
|
||||
},
|
||||
{
|
||||
albumUrl: "https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/37/v3/12rH1yiEQmK9wlOOcy5avQ/RzBXiEBRRqOC7LRkwNj6VA.jpg"
|
||||
},
|
||||
{
|
||||
albumUrl: "https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/9a/v3/TpRN4AIzRoyUXIqWdKoE0g/ShOnD_tfS46HDbpSWhbCkQ.jpg"
|
||||
},
|
||||
{
|
||||
albumUrl: "https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/03/v3/H3X17s8eTdS2w56JgbB5jQ/a45sT-j8Sbe8sSQXTzeYvQ.jpg"
|
||||
},
|
||||
{
|
||||
albumUrl: "https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/10/v3/qaEzwkU0QeKb1yehnP2Xig/q7fxAlgMQKup-HUBayRLGQ.jpg"
|
||||
},
|
||||
{
|
||||
albumUrl: "https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/96/v3/rMJJoAflTDSWa1z2pHs2wg/8dOqD0GlQBOCL5AvQok9FQ.jpg"
|
||||
},
|
||||
{
|
||||
albumUrl: "https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/ed/v3/KMO4D6D2QGuVOCLX4AhOFA/ef51xAaLQuK7BsnuD9abog.jpg"
|
||||
},
|
||||
{
|
||||
albumUrl: "https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/d9/v3/FSZH0aTdSqWxeAaxoPvi0g/RqxPxUCXQFiTMBfKTF9kkw.jpg"
|
||||
},
|
||||
{
|
||||
albumUrl: "https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/bf/v3/lSjrRwFcS-ez6jp1ALSQFg/0n7R7XinSPyrYLqDu_1dfw.jpg"
|
||||
},
|
||||
{
|
||||
albumUrl: "https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/8a/v3/ZKzYV5BJTuCk5hCE0y_xNA/8JT95OQnSZSd6_xQQUONhQ.jpg"
|
||||
},
|
||||
{
|
||||
albumUrl: "https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/1/v3/sTXb_I7URBKjdMyLDYa19w/qpcwa_FNQmi3-EzjbGsJ8A.jpg"
|
||||
},
|
||||
{
|
||||
albumUrl: "https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/e5/v3/m7wFvw_eQIuDV0Mk0IKi8g/gJU4migzTHKYk5KrgdZbBw.jpg"
|
||||
},
|
||||
{
|
||||
albumUrl: "https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/3f/v3/k_UWbB5_RGW7JemQZ0OQdw/_DUdmaZRQyG-Oyvkb663Bw.jpg"
|
||||
},
|
||||
{
|
||||
albumUrl: "https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/39/v3/rFRN7G_VSo-p4mBjTZtkRw/gBwTI-ieSIqSsSmLNBEcgw.jpg"
|
||||
},
|
||||
{
|
||||
albumUrl: "https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/04/v3/6K8BPYKVQFOr7KCuAG9nog/qKd3pZlrQy2M-feB3ycVPA.jpg"
|
||||
},
|
||||
{
|
||||
albumUrl: "https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/7d/v3/f0GQFzm1T6eduVeMUhO3Wg/-4cvzIJiRCegjIno3ofIbQ.jpg"
|
||||
},
|
||||
{
|
||||
albumUrl: "https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/e4/v3/C0xxsSeySxW-2iYR5OEbpQ/f1GlaD3zTeKPX8Vd-M1oVQ.jpg"
|
||||
},
|
||||
{
|
||||
albumUrl: "https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/c2/v3/32LCyXN4TuWKWcdf9gAwWw/ej14_BCJQNCaWOKoI9aZAw.jpg"
|
||||
},
|
||||
{
|
||||
albumUrl: "https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/fd/v3/LyYJMdMmQNaC5GyBYEZ5Pw/uFLiovypRSagKyIS-UJPVw.jpg"
|
||||
},
|
||||
{
|
||||
albumUrl: "https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/15/v3/MHM9KaWGTgubn6M8-B_6nw/1YO9JyYhTHSBWsoiqYkGZw.jpg"
|
||||
},
|
||||
{
|
||||
albumUrl: "https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/4c/v3/UdYfbv1_QYqn_ulDHp89OA/VkjexMluTqGO3yt3gPK1DA.jpg"
|
||||
},
|
||||
{
|
||||
albumUrl: "https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/e8/v3/N8blT_7qSK-tRtahIyov7g/M_kjGEEmSzOlTc47Zrfozg.jpg"
|
||||
},
|
||||
{
|
||||
albumUrl: "https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/28/v3/VS_h3m4YRrSgbgxnqE3vtQ/h-2Q1Qy2SSGEuXM36-Rq_w.jpg"
|
||||
},
|
||||
{
|
||||
albumUrl: "https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/2e/v3/R-BaM5ToRNGq5rwtNTcnww/Q2e01VHiR2y9KtFaZmpmNQ.jpg"
|
||||
},
|
||||
{
|
||||
albumUrl: "https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/88/v3/3djkAJKKTdC539XqMdstSg/wHO7DxvXQS2xbt2Y_-4BNg.jpg"
|
||||
},
|
||||
{
|
||||
albumUrl: "https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/fb/v3/guw4eiggR3uWjscFTxITYg/TzRB35iPTdCztrZUUaNuFg.jpg"
|
||||
},
|
||||
{
|
||||
albumUrl: "https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/93/v3/UvSh_f1LT66i0-3hvsYN_A/eYnE3Z8YT5Sk7F-vS2ZmCQ.jpg"
|
||||
},
|
||||
{
|
||||
albumUrl: "https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/5/v3/tv8Vqf9hQrKpozGeZWg2mw/VEICB-bmQYi0Iv6TGADbhw.jpg"
|
||||
},
|
||||
{
|
||||
albumUrl: "https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/30/v3/4v1Ot5BRR6OFVQ9MGn9Xxg/xrPgRn0LS1ep-r7ewIuwiw.jpg"
|
||||
},
|
||||
]
|
||||
static getItems() {
|
||||
return PageViewModel.dataArray
|
||||
}
|
||||
}
|
|
@ -5,8 +5,9 @@
|
|||
"description": "$string:module_desc",
|
||||
"mainElement": "EntryAbility",
|
||||
"deviceTypes": [
|
||||
"default",
|
||||
"tablet"
|
||||
"phone",
|
||||
"tablet",
|
||||
"2in1"
|
||||
],
|
||||
"deliveryWithInstall": true,
|
||||
"installationFree": false,
|
||||
|
@ -42,6 +43,15 @@
|
|||
],
|
||||
"when": "always"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "ohos.permission.GET_NETWORK_INFO",
|
||||
"usedScene": {
|
||||
"abilities": [
|
||||
"EntryAbility"
|
||||
],
|
||||
"when": "always"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
@ -369,20 +369,12 @@
|
|||
"value": "Please shut down the network first and ensure that there is no cache of images from this network in the test failure scenario locally"
|
||||
},
|
||||
{
|
||||
"name": "Image_Downsampling_Functionality",
|
||||
"value": "Downscale Image effect"
|
||||
"name": "Network_reload",
|
||||
"value": "Network recovery reload"
|
||||
},
|
||||
{
|
||||
"name": "Sampling_pecification",
|
||||
"value": "降采样规格"
|
||||
},
|
||||
{
|
||||
"name": "Unreal_samples",
|
||||
"value": "未降采样大小"
|
||||
},
|
||||
{
|
||||
"name": "After_the_sampling",
|
||||
"value": "降采样后大小"
|
||||
"name": "preloading_prefetch",
|
||||
"value": "Dynamic preloading prefetch"
|
||||
},
|
||||
{
|
||||
"name": "image_format",
|
||||
|
@ -511,6 +503,134 @@
|
|||
{
|
||||
"name": "disk",
|
||||
"value": "Disk"
|
||||
},
|
||||
{
|
||||
"name": "Customize_RCP_network",
|
||||
"value": "Customize RCP network request"
|
||||
},
|
||||
{
|
||||
"name": "request_concurrency",
|
||||
"value": "Set request concurrency"
|
||||
},
|
||||
{
|
||||
"name": "test_callback",
|
||||
"value": "test callback data of load pic"
|
||||
},
|
||||
{
|
||||
"name": "gif",
|
||||
"value": "gif"
|
||||
},
|
||||
{
|
||||
"name": "local_pic",
|
||||
"value": "local picture"
|
||||
},
|
||||
{
|
||||
"name": "share_pic",
|
||||
"value": "share picture"
|
||||
},
|
||||
{
|
||||
"name": "net_load_failed",
|
||||
"value": "netWork load failed"
|
||||
},
|
||||
{
|
||||
"name": "local_load_failed",
|
||||
"value": "local load failed"
|
||||
},
|
||||
{
|
||||
"name": "share_load_failed",
|
||||
"value": "shared load failed"
|
||||
},
|
||||
{
|
||||
"name": "list_pic",
|
||||
"value": "load picture list"
|
||||
},
|
||||
{
|
||||
"name": "img_url",
|
||||
"value": "url of the service setting:%s"
|
||||
},
|
||||
{
|
||||
"name": "img_format",
|
||||
"value": "picture format:%s"
|
||||
},
|
||||
{
|
||||
"name": "img_master_size",
|
||||
"value": "the original width and height of the picture-w:%d ,h:%d, size:%d"
|
||||
},
|
||||
{
|
||||
"name": "componentWH",
|
||||
"value": "component width and height-w:%d ,h:%d "
|
||||
},
|
||||
{
|
||||
"name": "img_frame",
|
||||
"value": "the number of frames of the picture:%d "
|
||||
},
|
||||
{
|
||||
"name": "img_content_size",
|
||||
"value": "picture decoded width and height size:%s "
|
||||
},
|
||||
{
|
||||
"name": "err_msg",
|
||||
"value": "error message:%s "
|
||||
},
|
||||
{
|
||||
"name": "err_phase",
|
||||
"value": "error phase:%s "
|
||||
},
|
||||
{
|
||||
"name": "err_code",
|
||||
"value": "error code:%d "
|
||||
},
|
||||
{
|
||||
"name": "http_code",
|
||||
"value": "http code:%d "
|
||||
},
|
||||
{
|
||||
"name": "req_start_time",
|
||||
"value": "image request start time point:%s "
|
||||
},
|
||||
{
|
||||
"name": "req_end_time",
|
||||
"value": "the point in time at which the image request ends:%s "
|
||||
},
|
||||
{
|
||||
"name": "req_cancel_time",
|
||||
"value": "the point at which the image request is cancelled:%s "
|
||||
},
|
||||
{
|
||||
"name": "memory_start_time",
|
||||
"value": "start checking the memory cache point in time:%s "
|
||||
},
|
||||
{
|
||||
"name": "memory_end_time",
|
||||
"value": "end Check the memory cache time point:%s "
|
||||
},
|
||||
{
|
||||
"name": "disk_start_time",
|
||||
"value": "start checking the disk cache point in time:%s "
|
||||
},
|
||||
{
|
||||
"name": "disk_end_time",
|
||||
"value": "end Check the disk cache time point:%s "
|
||||
},
|
||||
{
|
||||
"name": "net_start_time",
|
||||
"value": "start time of the network request:%s "
|
||||
},
|
||||
{
|
||||
"name": "net_end_time",
|
||||
"value": "end time of the network request:%s:%s "
|
||||
},
|
||||
{
|
||||
"name": "decode_start_time",
|
||||
"value": "decoding start time point:%s "
|
||||
},
|
||||
{
|
||||
"name": "decode_end_time",
|
||||
"value": "decoding end time point:%s "
|
||||
},
|
||||
{
|
||||
"name": "render_time",
|
||||
"value": "render successful time:%s "
|
||||
}
|
||||
]
|
||||
}
|
|
@ -3,6 +3,7 @@
|
|||
"pages/Index",
|
||||
"pages/ListPage",
|
||||
"pages/SingleImage",
|
||||
"pages/ManyPhotoShowPage",
|
||||
"pages/LongImagePage",
|
||||
"pages/TransformPage",
|
||||
"pages/UserPage",
|
||||
|
@ -23,9 +24,20 @@
|
|||
"pages/TestSetCustomImagePage",
|
||||
"pages/TestErrorHolderPage",
|
||||
"pages/TestTaskResourcePage",
|
||||
"pages/DownSamplePage",
|
||||
"pages/ImageKnifeReload",
|
||||
"pages/LazyForEachCount",
|
||||
"pages/LazyForEachCache",
|
||||
"pages/PrefetchAndCacheCount",
|
||||
"pages/PrefetchAndPreload",
|
||||
"pages/TestCacheDataPage",
|
||||
"pages/TestChangeColorPage",
|
||||
"pages/TestLoadCancelListenerPage"
|
||||
"pages/TestLoadCancelListenerPage",
|
||||
"pages/CustomNetImagePage",
|
||||
"pages/SetMaxRequestPage",
|
||||
"pages/MaxRequest1",
|
||||
"pages/MaxRequest2",
|
||||
"pages/MaxRequest3",
|
||||
"pages/TestImageKnifeCallbackPage",
|
||||
"pages/TestListImageKnifeCallbackPage"
|
||||
]
|
||||
}
|
|
@ -19,6 +19,362 @@
|
|||
{
|
||||
"name": "app_permission_READ_IMAGEVIDEO",
|
||||
"value": "获取读媒体资源权限"
|
||||
},
|
||||
{
|
||||
"name": "Test_ImageAnimator",
|
||||
"value": "Test ImageAnimator component"
|
||||
},
|
||||
{
|
||||
"name": "Test_multiple_images",
|
||||
"value": "Test loading multiple identical images"
|
||||
},
|
||||
{
|
||||
"name": "Test_Task_error",
|
||||
"value": "Test placeholder map Task error"
|
||||
},
|
||||
{
|
||||
"name": "Test_HSP",
|
||||
"value": "Test HSP scene preloading"
|
||||
},
|
||||
{
|
||||
"name": "Test_SingleImage",
|
||||
"value": "SingleImage"
|
||||
},
|
||||
{
|
||||
"name": "Test_custom_download",
|
||||
"value": "Global custom download"
|
||||
},
|
||||
{
|
||||
"name": "Multiple_images",
|
||||
"value": "Multiple images"
|
||||
},
|
||||
{
|
||||
"name": "Display_long_image",
|
||||
"value": "Display long image"
|
||||
},
|
||||
{
|
||||
"name": "Image_scaling",
|
||||
"value": "Image scaling"
|
||||
},
|
||||
{
|
||||
"name": "Message_list",
|
||||
"value": "Message list"
|
||||
},
|
||||
{
|
||||
"name": "Custom_cache_key",
|
||||
"value": "Custom cache key"
|
||||
},
|
||||
{
|
||||
"name": "Preloading_images_to_cache",
|
||||
"value": "Preloading images to file cache"
|
||||
},
|
||||
{
|
||||
"name": "Retrieve_image_display_from_cache",
|
||||
"value": "Retrieve image display from cache"
|
||||
},
|
||||
{
|
||||
"name": "Test_single_request_header",
|
||||
"value": "Test a single request header"
|
||||
},
|
||||
{
|
||||
"name": "Test_write_cache_strategy",
|
||||
"value": "Test write cache strategy"
|
||||
},
|
||||
{
|
||||
"name": "Image_Transformation",
|
||||
"value": "Image Transformation"
|
||||
},
|
||||
{
|
||||
"name": "Different_ObjectFit",
|
||||
"value": "Different ObjectFit"
|
||||
},
|
||||
{
|
||||
"name": "Test_image_loading_success_or_failure_events",
|
||||
"value": "Test image loading success/failure events"
|
||||
},
|
||||
{
|
||||
"name": "Test_removing_image_cache_interface",
|
||||
"value": "Test removing image cache interface"
|
||||
},
|
||||
{
|
||||
"name": "Test_error_image_display",
|
||||
"value": "Test error image display"
|
||||
},
|
||||
{
|
||||
"name": "Test_media_URL",
|
||||
"value": "Test media URL"
|
||||
},
|
||||
{
|
||||
"name": "Display_the_first_frame",
|
||||
"value": "Display the first frame of the animation"
|
||||
},
|
||||
{
|
||||
"name": "Display_the_last_frame",
|
||||
"value": "Display the last frame of the animation"
|
||||
},
|
||||
{
|
||||
"name": "Play",
|
||||
"value": "Play"
|
||||
},
|
||||
{
|
||||
"name": "Pause",
|
||||
"value": "Pause"
|
||||
},
|
||||
{
|
||||
"name": "Stop",
|
||||
"value": "Stop"
|
||||
},
|
||||
{
|
||||
"name": "Infinite_loop",
|
||||
"value": "Infinite loop"
|
||||
},
|
||||
{
|
||||
"name": "Play_once",
|
||||
"value": "Play once"
|
||||
},
|
||||
{
|
||||
"name": "Play_twice",
|
||||
"value": "Play twice"
|
||||
},
|
||||
{
|
||||
"name": "Local_SVG",
|
||||
"value": "Local SVG image"
|
||||
},
|
||||
{
|
||||
"name": "Under_context_file",
|
||||
"value": "Files under context file"
|
||||
},
|
||||
{
|
||||
"name": "Network_images",
|
||||
"value": "Network images"
|
||||
},
|
||||
{
|
||||
"name": "Custom_network_download",
|
||||
"value": "Custom network download"
|
||||
},
|
||||
{
|
||||
"name": "PixelMap_loads_images",
|
||||
"value": "PixelMap loads images"
|
||||
},
|
||||
{
|
||||
"name": "Enlarge",
|
||||
"value": "Enlarge"
|
||||
},
|
||||
{
|
||||
"name": "Reduce",
|
||||
"value": "Reduce"
|
||||
},
|
||||
{
|
||||
"name": "Click_on_add",
|
||||
"value": "Click on the size to add 50"
|
||||
},
|
||||
{
|
||||
"name": "Click_on_reduce",
|
||||
"value": "Click to reduce size by 50"
|
||||
},
|
||||
{
|
||||
"name": "The_key_fixed_1",
|
||||
"value": "The key is fixed at 1"
|
||||
},
|
||||
{
|
||||
"name": "The_key_changes_timestamp",
|
||||
"value": "Key changes every time: timestamp"
|
||||
},
|
||||
{
|
||||
"name": "Load",
|
||||
"value": "Load"
|
||||
},
|
||||
{
|
||||
"name": "Preloading_images_to_file_cache_using_URL",
|
||||
"value": "Preloading images to file cache using URL"
|
||||
},
|
||||
{
|
||||
"name": "Preloading_images_to_file_cache_using_option",
|
||||
"value": "Preloading images to file cache using option"
|
||||
},
|
||||
{
|
||||
"name": "Load_image_offline_after_preloading",
|
||||
"value": "Load image (can be loaded offline after preloading)"
|
||||
},
|
||||
{
|
||||
"name": "Preloading_GIF",
|
||||
"value": "Preloading GIF"
|
||||
},
|
||||
{
|
||||
"name": "Retrieve_GIF_from_memory",
|
||||
"value": "Retrieve GIF from memory cache"
|
||||
},
|
||||
{
|
||||
"name": "Retrieve_GIF_from_disk",
|
||||
"value": "Retrieve GIF from disk cache"
|
||||
},
|
||||
{
|
||||
"name": "Preloading_static_images",
|
||||
"value": "Preloading static images"
|
||||
},
|
||||
{
|
||||
"name": "Retrieve_images_from_memory",
|
||||
"value": "Retrieve images from memory cache"
|
||||
},
|
||||
{
|
||||
"name": "Retrieve_images_from_disk",
|
||||
"value": "Retrieve images from memory disk"
|
||||
},
|
||||
{
|
||||
"name": "Write_memory_and_file",
|
||||
"value": "Write to memory and file cache"
|
||||
},
|
||||
{
|
||||
"name": "Write_memory",
|
||||
"value": "Write to memory cache"
|
||||
},
|
||||
{
|
||||
"name": "Write_file",
|
||||
"value": "Write to file cache"
|
||||
},
|
||||
{
|
||||
"name": "Main_image_Fill",
|
||||
"value": "Main image Fill Stretch Fill"
|
||||
},
|
||||
{
|
||||
"name": "Maintain_proportion_filling",
|
||||
"value": "Maintain proportion filling in the placeholder map 'Include'"
|
||||
},
|
||||
{
|
||||
"name": "Error_graph_None",
|
||||
"value": "Error graph None remains unchanged"
|
||||
},
|
||||
{
|
||||
"name": "Test_failure_success",
|
||||
"value": "Test failure/success"
|
||||
},
|
||||
{
|
||||
"name": "Custom_download_failed",
|
||||
"value": "Custom download failed"
|
||||
},
|
||||
{
|
||||
"name": "Retrieve_media_gallery",
|
||||
"value": "Retrieve the URI of the media gallery and display it using ImageKnife"
|
||||
},
|
||||
{
|
||||
"name": "Click_load_Uri",
|
||||
"value": "Click to load Uri and display"
|
||||
},
|
||||
{
|
||||
"name": "Delete_all_caches",
|
||||
"value": "Delete all caches"
|
||||
},
|
||||
{
|
||||
"name": "Delete_all_memory_caches",
|
||||
"value": "Delete all memory caches"
|
||||
},
|
||||
{
|
||||
"name": "Delete_all_file_caches",
|
||||
"value": "Delete all file caches"
|
||||
},
|
||||
{
|
||||
"name": "Delete_all_custom_memory_caches",
|
||||
"value": "Delete all custom memory caches"
|
||||
},
|
||||
{
|
||||
"name": "Delete_all_custom_file_caches",
|
||||
"value": "Delete all custom file caches"
|
||||
},
|
||||
{
|
||||
"name": "Blur_effect",
|
||||
"value": "Blur effect"
|
||||
},
|
||||
{
|
||||
"name": "Highlighting_effect",
|
||||
"value": "Highlighting effect"
|
||||
},
|
||||
{
|
||||
"name": "Ashing_effect",
|
||||
"value": "Ashing effect"
|
||||
},
|
||||
{
|
||||
"name": "Inverse_effect",
|
||||
"value": "Inverse effect"
|
||||
},
|
||||
{
|
||||
"name": "Animation_filter_effect",
|
||||
"value": "Animation filter effect"
|
||||
},
|
||||
{
|
||||
"name": "Crop_circular_effect",
|
||||
"value": "Crop circular effect"
|
||||
},
|
||||
{
|
||||
"name": "Crop_circular_with_border_effect",
|
||||
"value": "Crop circular with border effect"
|
||||
},
|
||||
{
|
||||
"name": "Contrast_effect",
|
||||
"value": "Contrast effect"
|
||||
},
|
||||
{
|
||||
"name": "Black_ink_filtering_effect",
|
||||
"value": "Black ink filtering effect"
|
||||
},
|
||||
{
|
||||
"name": "Rotate",
|
||||
"value": "Rotate"
|
||||
},
|
||||
{
|
||||
"name": "Corners",
|
||||
"value": "Corners"
|
||||
},
|
||||
{
|
||||
"name": "Kuwahara_Filter_effect",
|
||||
"value": "Kuwahara filter effect"
|
||||
},
|
||||
{
|
||||
"name": "Pixelated_Filter_effect",
|
||||
"value": "Pixelated filtering effect"
|
||||
},
|
||||
{
|
||||
"name": "Sketch_Filter_effect",
|
||||
"value": "Sketch Filter effect"
|
||||
},
|
||||
{
|
||||
"name": "Distortion_Filter_effect",
|
||||
"value": "Distortion Filter effect"
|
||||
},
|
||||
{
|
||||
"name": "Decorative_Filter_effect",
|
||||
"value": "Decorative Filter effect"
|
||||
},
|
||||
{
|
||||
"name": "Square_cutting_effect",
|
||||
"value": "Square cutting effect"
|
||||
},
|
||||
{
|
||||
"name": "Top_cutting_effect",
|
||||
"value": "Top cutting effect"
|
||||
},
|
||||
{
|
||||
"name": "Middle_cutting_effect",
|
||||
"value": "Middle cutting effect"
|
||||
},
|
||||
{
|
||||
"name": "Bottom_cutting_effect",
|
||||
"value": "Bottom cutting effect"
|
||||
},
|
||||
{
|
||||
"name": "Mask_effect",
|
||||
"value": "Mask effect"
|
||||
},
|
||||
{
|
||||
"name": "TIPS",
|
||||
"value": "Please shut down the network first and ensure that there is no cache of images from this network in the test failure scenario locally"
|
||||
},
|
||||
{
|
||||
"name": "Network_reload",
|
||||
"value": "Network recovery reload"
|
||||
},
|
||||
{
|
||||
"name": "preloading_prefetch",
|
||||
"value": "Dynamic preloading prefetch"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -365,20 +365,12 @@
|
|||
"value": "测试失败场景请先关闭网络,并保证本地没有此网络图片的缓存"
|
||||
},
|
||||
{
|
||||
"name": "Image_Downsampling_Functionality",
|
||||
"value": "降采样功能"
|
||||
"name": "Network_reload",
|
||||
"value": "网络恢复reload"
|
||||
},
|
||||
{
|
||||
"name": "Sampling_pecification",
|
||||
"value": "降采样规格"
|
||||
},
|
||||
{
|
||||
"name": "Unreal_samples",
|
||||
"value": "未降采样大小"
|
||||
},
|
||||
{
|
||||
"name": "After_the_sampling",
|
||||
"value": "降采样后大小"
|
||||
"name": "preloading_prefetch",
|
||||
"value": "动态预加载prefetch"
|
||||
},
|
||||
{
|
||||
"name": "image_format",
|
||||
|
@ -507,6 +499,134 @@
|
|||
{
|
||||
"name": "disk",
|
||||
"value": "磁盘"
|
||||
},
|
||||
{
|
||||
"name": "Customize_RCP_network",
|
||||
"value": "自定义rcp网络请求"
|
||||
},
|
||||
{
|
||||
"name": "request_concurrency",
|
||||
"value": "设置请求并发度"
|
||||
},
|
||||
{
|
||||
"name": "test_callback",
|
||||
"value": "测试图片加载回调数据"
|
||||
},
|
||||
{
|
||||
"name": "gif",
|
||||
"value": "gif"
|
||||
},
|
||||
{
|
||||
"name": "local_pic",
|
||||
"value": "本地图片"
|
||||
},
|
||||
{
|
||||
"name": "share_pic",
|
||||
"value": "共享图片"
|
||||
},
|
||||
{
|
||||
"name": "net_load_failed",
|
||||
"value": "网络加载失败"
|
||||
},
|
||||
{
|
||||
"name": "local_load_failed",
|
||||
"value": "本地加载失败"
|
||||
},
|
||||
{
|
||||
"name": "share_load_failed",
|
||||
"value": "共享图片加载失败"
|
||||
},
|
||||
{
|
||||
"name": "list_pic",
|
||||
"value": "加载图片列表"
|
||||
},
|
||||
{
|
||||
"name": "img_url",
|
||||
"value": "业务设置的url:%s"
|
||||
},
|
||||
{
|
||||
"name": "img_format",
|
||||
"value": "图片的格式:%s"
|
||||
},
|
||||
{
|
||||
"name": "img_master_size",
|
||||
"value": "图片的原始宽高大小-宽:%d ,高:%d, 大小:%d"
|
||||
},
|
||||
{
|
||||
"name": "componentWH",
|
||||
"value": "component的宽高-宽:%d ,高:%d "
|
||||
},
|
||||
{
|
||||
"name": "img_frame",
|
||||
"value": "图片的帧数:%d "
|
||||
},
|
||||
{
|
||||
"name": "img_content_size",
|
||||
"value": "图片解码后宽高大小:%s "
|
||||
},
|
||||
{
|
||||
"name": "err_msg",
|
||||
"value": "错误信息:%s "
|
||||
},
|
||||
{
|
||||
"name": "err_phase",
|
||||
"value": "发生错误阶段:%s "
|
||||
},
|
||||
{
|
||||
"name": "err_code",
|
||||
"value": "错误code:%d "
|
||||
},
|
||||
{
|
||||
"name": "http_code",
|
||||
"value": "网络请求code:%d "
|
||||
},
|
||||
{
|
||||
"name": "req_start_time",
|
||||
"value": "图片的请求开始时间点:%s "
|
||||
},
|
||||
{
|
||||
"name": "req_end_time",
|
||||
"value": "图片请求结束的时间点:%s "
|
||||
},
|
||||
{
|
||||
"name": "req_cancel_time",
|
||||
"value": "图片请求取消的时间点:%s "
|
||||
},
|
||||
{
|
||||
"name": "memory_start_time",
|
||||
"value": "开始检查内存缓存时间点:%s "
|
||||
},
|
||||
{
|
||||
"name": "memory_end_time",
|
||||
"value": "结束检查内存缓存时间点:%s "
|
||||
},
|
||||
{
|
||||
"name": "disk_start_time",
|
||||
"value": "开始检查磁盘缓存时间点:%s "
|
||||
},
|
||||
{
|
||||
"name": "disk_end_time",
|
||||
"value": "结束检查磁盘缓存时间点:%s "
|
||||
},
|
||||
{
|
||||
"name": "net_start_time",
|
||||
"value": "网络请求开始时间点:%s "
|
||||
},
|
||||
{
|
||||
"name": "net_end_time",
|
||||
"value": "网络请求结束时间点:%s "
|
||||
},
|
||||
{
|
||||
"name": "decode_start_time",
|
||||
"value": "解码开始时间点:%s "
|
||||
},
|
||||
{
|
||||
"name": "decode_end_time",
|
||||
"value": "解码结束时间点:%s "
|
||||
},
|
||||
{
|
||||
"name": "render_time",
|
||||
"value": "渲染成功的时间:%s "
|
||||
}
|
||||
]
|
||||
}
|
|
@ -55,12 +55,12 @@ export default function DefaultJobQueueTest() {
|
|||
|
||||
expect(job.getQueueLength()).assertEqual(7)
|
||||
expect(job.pop()!.imageKnifeOption.loadSrc).assertEqual("high1")
|
||||
expect(job.pop()!.imageKnifeOption.loadSrc).assertEqual("medium4")
|
||||
expect(job.pop()!.imageKnifeOption.loadSrc).assertEqual("medium3")
|
||||
expect(job.pop()!.imageKnifeOption.loadSrc).assertEqual("medium2")
|
||||
expect(job.pop()!.imageKnifeOption.loadSrc).assertEqual("medium1")
|
||||
expect(job.pop()!.imageKnifeOption.loadSrc).assertEqual("low2")
|
||||
expect(job.pop()!.imageKnifeOption.loadSrc).assertEqual("medium2")
|
||||
expect(job.pop()!.imageKnifeOption.loadSrc).assertEqual("medium3")
|
||||
expect(job.pop()!.imageKnifeOption.loadSrc).assertEqual("medium4")
|
||||
expect(job.pop()!.imageKnifeOption.loadSrc).assertEqual("low1")
|
||||
expect(job.pop()!.imageKnifeOption.loadSrc).assertEqual("low2")
|
||||
expect(job.pop()).assertEqual(undefined)
|
||||
expect(job.getQueueLength()).assertEqual(0)
|
||||
|
||||
|
@ -70,10 +70,10 @@ export default function DefaultJobQueueTest() {
|
|||
}
|
||||
|
||||
function makeRequest(src: string, context: common.UIAbilityContext, priority?: taskpool.Priority): ImageKnifeRequest {
|
||||
let option: ImageKnifeOption = new ImageKnifeOption({
|
||||
let option: ImageKnifeOption = {
|
||||
loadSrc: src,
|
||||
priority: priority
|
||||
})
|
||||
}
|
||||
return new ImageKnifeRequest(
|
||||
option,
|
||||
context,
|
||||
|
|
|
@ -153,9 +153,9 @@ export default function FileLruCacheTest() {
|
|||
});
|
||||
it('fileCacheEngineKey', 0, () => {
|
||||
let engineKey: IEngineKey = new DefaultEngineKey()
|
||||
let imageKnifeOption: ImageKnifeOption = new ImageKnifeOption({
|
||||
let imageKnifeOption: ImageKnifeOption = {
|
||||
loadSrc:"abc"
|
||||
})
|
||||
}
|
||||
let imageKey = engineKey.generateFileKey(imageKnifeOption.loadSrc,"")
|
||||
let imageAnimatorKey = engineKey.generateFileKey(imageKnifeOption.loadSrc,"",true)
|
||||
expect(imageKey == imageAnimatorKey).assertFalse()
|
||||
|
|
|
@ -40,10 +40,10 @@ export default function ImageKnifeTest() {
|
|||
|
||||
it('removeMemoryCache', 0, async () => {
|
||||
let a = 'https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp';
|
||||
let option: ImageKnifeOption = new ImageKnifeOption({
|
||||
let option: ImageKnifeOption = {
|
||||
loadSrc: 'https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp',
|
||||
signature: ''
|
||||
})
|
||||
}
|
||||
let key = ImageKnife.getInstance()
|
||||
.getEngineKeyImpl()
|
||||
.generateMemoryKey('https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp', ImageKnifeRequestSource.SRC, option)
|
||||
|
|
|
@ -44,7 +44,7 @@ export default function ImageKnifeOptionTest() {
|
|||
imageWidth: 0,
|
||||
imageHeight: 0,
|
||||
}
|
||||
let imageKnifeOption: ImageKnifeOption = new ImageKnifeOption({
|
||||
let ImageKnifeOption: ImageKnifeOption = {
|
||||
loadSrc: $r("app.media.rabbit"),
|
||||
onLoadListener: {
|
||||
onLoadFailed: (err) => {
|
||||
|
@ -58,10 +58,10 @@ export default function ImageKnifeOptionTest() {
|
|||
return data;
|
||||
},
|
||||
},
|
||||
})
|
||||
if (imageKnifeOption.onLoadListener && imageKnifeOption.onLoadListener.onLoadSuccess && imageKnifeOption.onLoadListener.onLoadFailed) {
|
||||
imageKnifeOption.onLoadListener.onLoadSuccess(a,imageData);
|
||||
imageKnifeOption.onLoadListener.onLoadFailed(a);
|
||||
}
|
||||
if (ImageKnifeOption.onLoadListener && ImageKnifeOption.onLoadListener.onLoadSuccess && ImageKnifeOption.onLoadListener.onLoadFailed) {
|
||||
ImageKnifeOption.onLoadListener.onLoadSuccess(a,imageData);
|
||||
ImageKnifeOption.onLoadListener.onLoadFailed(a);
|
||||
}
|
||||
expect(a).assertEqual(b);
|
||||
});
|
||||
|
|
|
@ -18,8 +18,8 @@ import ImageKnifeOptionTest from './ImageKnifeOption.test';
|
|||
import MemoryLruCacheTest from './MemoryLruCache.test';
|
||||
import ImageKnifeTest from './ImageKnife.test';
|
||||
import Transform from './transform.test';
|
||||
import SamplingTest from './SamplingTest.test';
|
||||
import imageFormatAndSize from './imageFormatAndSize.test'
|
||||
import loadCallBackData from './loadCallBackData.test'
|
||||
|
||||
export default function testsuite() {
|
||||
MemoryLruCacheTest();
|
||||
|
@ -28,6 +28,6 @@ export default function testsuite() {
|
|||
ImageKnifeOptionTest();
|
||||
ImageKnifeTest();
|
||||
Transform();
|
||||
SamplingTest()
|
||||
imageFormatAndSize();
|
||||
loadCallBackData();
|
||||
}
|
|
@ -122,9 +122,9 @@ export default function MemoryLruCacheTest() {
|
|||
|
||||
it('memoryCacheEngineKey', 0, () => {
|
||||
let engineKey: IEngineKey = new DefaultEngineKey()
|
||||
let imageKnifeOption: ImageKnifeOption = new ImageKnifeOption({
|
||||
let imageKnifeOption: ImageKnifeOption = {
|
||||
loadSrc:"abc"
|
||||
})
|
||||
}
|
||||
let imageKey = engineKey.generateMemoryKey(imageKnifeOption.loadSrc,ImageKnifeRequestSource.SRC,imageKnifeOption)
|
||||
let imageAnimatorKey = engineKey.generateMemoryKey(imageKnifeOption.loadSrc,ImageKnifeRequestSource.SRC,imageKnifeOption,true)
|
||||
expect(imageKey == imageAnimatorKey).assertFalse()
|
||||
|
|
|
@ -1,79 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'
|
||||
import { image } from '@kit.ImageKit'
|
||||
import { BusinessError } from '@kit.BasicServicesKit'
|
||||
import { calculateScaleType, Downsampler } from '@ohos/imageknife/src/main/ets/downsampling/Downsampler'
|
||||
import { DownsampleStrategy } from '@ohos/imageknife'
|
||||
|
||||
export default function SamplingTest() {
|
||||
describe('SamplingTest', () => {
|
||||
// Defines a test suite. Two parameters are supported: test suite name and test suite function.
|
||||
beforeAll(() => {
|
||||
// Presets an action, which is performed only once before all test cases of the test suite start.
|
||||
// This API supports only one parameter: preset action function.
|
||||
})
|
||||
beforeEach(() => {
|
||||
// Presets an action, which is performed before each unit test case starts.
|
||||
// The number of execution times is the same as the number of test cases defined by **it**.
|
||||
// This API supports only one parameter: preset action function.
|
||||
})
|
||||
afterEach(() => {
|
||||
// Presets a clear action, which is performed after each unit test case ends.
|
||||
// The number of execution times is the same as the number of test cases defined by **it**.
|
||||
// This API supports only one parameter: clear action function.
|
||||
})
|
||||
afterAll(() => {
|
||||
// Presets a clear action, which is performed after all test cases of the test suite end.
|
||||
// This API supports only one parameter: clear action function.
|
||||
})
|
||||
it('NONE', 0, () => {
|
||||
let reqSize: calculateScaleType =
|
||||
new Downsampler().calculateScaling('jpg', 1024, 1024, 200,
|
||||
200, DownsampleStrategy.NONE,)
|
||||
let req = (reqSize.targetWidth == 1024 && reqSize.targetHeight == 1024)
|
||||
expect(req).assertEqual(true);
|
||||
})
|
||||
it('AT_MOST', 1, () => {
|
||||
let reqSize: calculateScaleType =
|
||||
new Downsampler().calculateScaling('jpg', 1024, 1024, 200,
|
||||
200, DownsampleStrategy.AT_MOST)
|
||||
let req = (reqSize.targetWidth < 1024 && reqSize.targetHeight < 1024)
|
||||
expect(req).assertEqual(true);
|
||||
})
|
||||
it('FIT_CENTER', 2, () => {
|
||||
let reqSize: calculateScaleType =
|
||||
new Downsampler().calculateScaling('jpg', 1024, 1024, 200,
|
||||
200, DownsampleStrategy.FIT_CENTER_MEMORY)
|
||||
let req = (reqSize.targetWidth < 1024 && reqSize.targetHeight < 1024)
|
||||
expect(req).assertEqual(true);
|
||||
})
|
||||
it('CENTER_OUTSIDE', 3, () => {
|
||||
let reqSize: calculateScaleType =
|
||||
new Downsampler().calculateScaling('jpg', 1024, 1024, 200,
|
||||
200, DownsampleStrategy.CENTER_OUTSIDE_MEMORY)
|
||||
let req = (reqSize.targetWidth < 1024 && reqSize.targetHeight < 1024)
|
||||
expect(req).assertEqual(true);
|
||||
})
|
||||
it('AT_LEAST', 4, () => {
|
||||
let reqSize: calculateScaleType =
|
||||
new Downsampler().calculateScaling('jpg', 1024, 1024, 200,
|
||||
200, DownsampleStrategy.AT_LEAST)
|
||||
let req = (reqSize.targetWidth < 1024 && reqSize.targetHeight < 1024)
|
||||
expect(req).assertEqual(true);
|
||||
})
|
||||
|
||||
})
|
||||
}
|
|
@ -1,52 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'
|
||||
import { SendableData } from '@ohos/imageknife/src/main/ets/components/imageknife/SendableData'
|
||||
|
||||
export default function SendableDataTest() {
|
||||
describe('SendableDataTest', ()=> {
|
||||
// Defines a test suite. Two parameters are supported: test suite name and test suite function.
|
||||
beforeAll( ()=> {
|
||||
// Presets an action, which is performed only once before all test cases of the test suite start.
|
||||
// This API supports only one parameter: preset action function.
|
||||
})
|
||||
beforeEach( ()=> {
|
||||
// Presets an action, which is performed before each unit test case starts.
|
||||
// The number of execution times is the same as the number of test cases defined by **it**.
|
||||
// This API supports only one parameter: preset action function.
|
||||
})
|
||||
afterEach( ()=> {
|
||||
// Presets a clear action, which is performed after each unit test case ends.
|
||||
// The number of execution times is the same as the number of test cases defined by **it**.
|
||||
// This API supports only one parameter: clear action function.
|
||||
})
|
||||
afterAll( ()=> {
|
||||
// Presets a clear action, which is performed after all test cases of the test suite end.
|
||||
// This API supports only one parameter: clear action function.
|
||||
})
|
||||
it('TestPlaceHolderCacheKey', 0, () => {
|
||||
let value: string = "placeholderRegisterCacheKey";
|
||||
let data: SendableData = new SendableData();
|
||||
data.setPlaceHolderRegisterCacheKey(value);
|
||||
expect(data.getPlaceHolderRegisterCacheKey()).assertEqual(value);
|
||||
})
|
||||
it('TestPlaceHolderMemoryCacheKey', 1, () => {
|
||||
let value: string = "placeholderRegisterMemoryCacheKey";
|
||||
let data: SendableData = new SendableData();
|
||||
data.setPlaceHolderRegisterMemoryCacheKey(value);
|
||||
expect(data.getPlaceHolderRegisterMemoryCacheKey()).assertEqual(value);
|
||||
})
|
||||
})
|
||||
}
|
|
@ -1,106 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'
|
||||
import { DownloadClient } from '@ohos/imageknife/src/main/ets/components/imageknife/networkmanage/DownloadClient';
|
||||
import common from '@ohos.app.ability.common';
|
||||
import { GlobalContext } from '../testability/GlobalContext';
|
||||
import { CustomDataFetchClient, DataFetchResult, ImageKnifeGlobal, RequestOption } from '@ohos/imageknife';
|
||||
|
||||
const BASE_COUNT: number = 2000;
|
||||
|
||||
export default function CustomDataFetchClientTest() {
|
||||
describe('CustomDataFetchClientTest', () => {
|
||||
// Defines a test suite. Two parameters are supported: test suite name and test suite function.
|
||||
beforeAll(() => {
|
||||
// Presets an action, which is performed only once before all test cases of the test suite start.
|
||||
// This API supports only one parameter: preset action function.
|
||||
})
|
||||
beforeEach(() => {
|
||||
// Presets an action, which is performed before each unit test case starts.
|
||||
// The number of execution times is the same as the number of test cases defined by **it**.
|
||||
// This API supports only one parameter: preset action function.
|
||||
})
|
||||
afterEach(() => {
|
||||
// Presets a clear action, which is performed after each unit test case ends.
|
||||
// The number of execution times is the same as the number of test cases defined by **it**.
|
||||
// This API supports only one parameter: clear action function.
|
||||
})
|
||||
afterAll(() => {
|
||||
// Presets a clear action, which is performed after all test cases of the test suite end.
|
||||
// This API supports only one parameter: clear action function.
|
||||
})
|
||||
it('TestIsLocalLoadSrc', 0, () => {
|
||||
let path = 'invalid path';
|
||||
let client = new DownloadClient()
|
||||
expect(client.isLocalLoadSrc(undefined, path)).assertFalse();
|
||||
let context: object | undefined = GlobalContext.getInstance().getObject("hapContext");
|
||||
if (context != undefined) {
|
||||
let loadSrc1 = (context as common.UIAbilityContext).filesDir + 'a.jpg';
|
||||
let loadSrc2 = (context as common.UIAbilityContext).cacheDir + 'b.jpg';
|
||||
expect(client.isLocalLoadSrc(context, loadSrc1)).assertTrue();
|
||||
expect(client.isLocalLoadSrc(context, loadSrc2)).assertTrue();
|
||||
}
|
||||
})
|
||||
it('TestLoadData', 1, async () => {
|
||||
let client = new CustomDataFetchClient();
|
||||
let request = new RequestOption();
|
||||
request.loadSrc = $r('app.media.icon');
|
||||
let error = (await client.loadData(request) as DataFetchResult).error as String;
|
||||
expect(error).assertEqual('CustomDataFetchClient request or loadSrc error.');
|
||||
})
|
||||
it('TestLoadData_customGetImage', 2, async () => {
|
||||
let client = new CustomDataFetchClient();
|
||||
let request = new RequestOption();
|
||||
request.loadSrc = 'http://e.hiphotos.baidu.com/image/pic/item/4e4a20a4462309f7e41f5cfe760e0cf3d6cad6ee.jpg';
|
||||
request.customGetImage = (context: Context, src: string) => {
|
||||
// 这里是模拟的customGetImage逻辑
|
||||
return Promise.resolve(new DataFetchResult());
|
||||
}
|
||||
console.log('LXH', 'TestLoadData 2 --1 customGetImage is undefined ?' + (request.customGetImage == undefined));
|
||||
let context: object | undefined = GlobalContext.getInstance().getObject("hapContext");
|
||||
let result = await client.loadData(request);
|
||||
if (context != undefined) {
|
||||
console.log('LXH', 'TestLoadData 2 --2');
|
||||
expect(typeof result)
|
||||
.assertEqual(typeof (await request?.customGetImage(context as common.UIAbilityContext, request.loadSrc)));
|
||||
}
|
||||
})
|
||||
it('TestLoadData_combineArrayBuffers', 3, () => {
|
||||
// 创建几个ArrayBuffer作为测试数据
|
||||
const arrayBuffer1 = new ArrayBuffer(4);
|
||||
const uint8Array1 = new Uint8Array(arrayBuffer1);
|
||||
uint8Array1[0] = 1;
|
||||
uint8Array1[1] = 2;
|
||||
uint8Array1[2] = 3;
|
||||
uint8Array1[3] = 4;
|
||||
|
||||
const arrayBuffer2 = new ArrayBuffer(2);
|
||||
const uint8Array2 = new Uint8Array(arrayBuffer2);
|
||||
uint8Array2[0] = 5;
|
||||
uint8Array2[1] = 6;
|
||||
let client = new CustomDataFetchClient();
|
||||
const combinedArrayBuffer = client.combineArrayBuffers([arrayBuffer1, arrayBuffer2]);
|
||||
expect(combinedArrayBuffer.byteLength).assertEqual(6);
|
||||
const combinedUint8Array = new Uint8Array(combinedArrayBuffer);
|
||||
for (let i = 0; i < 4; i++) {
|
||||
expect(combinedUint8Array[i]).assertEqual(uint8Array1[i]);
|
||||
}
|
||||
for (let i = 0; i < 2; i++) {
|
||||
expect(combinedUint8Array[i + 4]).assertEqual(uint8Array2[i]);
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
||||
|
|
@ -49,9 +49,9 @@ export default function imageFormatAndSize() {
|
|||
let imageFormat: string = "";
|
||||
let url: string =
|
||||
"https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/ed/v3/KMO4D6D2QGuVOCLX4AhOFA/ef51xAaLQuK7BsnuD9abog.jpg"
|
||||
let imageKnifeOption: ImageKnifeOption = new ImageKnifeOption({
|
||||
let imageKnifeOption: ImageKnifeOption = {
|
||||
loadSrc: url,
|
||||
})
|
||||
}
|
||||
await new Promise<string>((resolve, reject) => {
|
||||
imageKnifeOption.onLoadListener = {
|
||||
onLoadSuccess: (data, imageknifeData) => {
|
||||
|
|
|
@ -1,69 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium';
|
||||
import { ImageKnifeOption,ImageKnifeData } from "@ohos/imageknife"
|
||||
|
||||
export default function ImageKnifeOptionTest() {
|
||||
describe('ImageKnifeOptionTest',() => {
|
||||
// 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('onLoadListener', 0, () => {
|
||||
let a = 'abc';
|
||||
let b: string = '';
|
||||
let imageData:ImageKnifeData = {
|
||||
source: "",
|
||||
imageWidth: 0,
|
||||
imageHeight: 0,
|
||||
}
|
||||
let imageKnifeOption: ImageKnifeOption = new ImageKnifeOption({
|
||||
loadSrc: $r("app.media.rabbit"),
|
||||
onLoadListener: {
|
||||
onLoadFailed: (err) => {
|
||||
console.error("Load Failed Reason: " + err);
|
||||
},
|
||||
onLoadSuccess: (data,imageknifeData) => {
|
||||
if(typeof data == 'string') {
|
||||
return b = data;
|
||||
}
|
||||
imageData = imageknifeData
|
||||
return data;
|
||||
},
|
||||
},
|
||||
})
|
||||
if (imageKnifeOption.onLoadListener && imageKnifeOption.onLoadListener.onLoadSuccess && imageKnifeOption.onLoadListener.onLoadFailed) {
|
||||
imageKnifeOption.onLoadListener.onLoadSuccess(a,imageData);
|
||||
imageKnifeOption.onLoadListener.onLoadFailed(a);
|
||||
}
|
||||
expect(a).assertEqual(b);
|
||||
});
|
||||
});
|
||||
}
|
|
@ -0,0 +1,117 @@
|
|||
/*
|
||||
* Copyright (C) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium';
|
||||
import {
|
||||
ImageKnifeOption,
|
||||
ImageKnife,
|
||||
ImageKnifeRequest,
|
||||
ImageKnifeRequestSource,
|
||||
CacheStrategy
|
||||
} from "@ohos/imageknife"
|
||||
import { common } from '@kit.AbilityKit';
|
||||
|
||||
export default function loadCallBackData() {
|
||||
describe('loadCallBackData', () => {
|
||||
// Defines a test suite. Two parameters are supported: test suite name and test suite function.
|
||||
beforeAll(() => {
|
||||
// Presets an action, which is performed only once before all test cases of the test suite start.
|
||||
// This API supports only one parameter: preset action function.
|
||||
});
|
||||
beforeEach(() => {
|
||||
// Presets an action, which is performed before each unit test case starts.
|
||||
// The number of execution times is the same as the number of test cases defined by **it**.
|
||||
// This API supports only one parameter: preset action function.
|
||||
});
|
||||
afterEach(() => {
|
||||
// Presets a clear action, which is performed after each unit test case ends.
|
||||
// The number of execution times is the same as the number of test cases defined by **it**.
|
||||
// This API supports only one parameter: clear action function.
|
||||
});
|
||||
afterAll(() => {
|
||||
// Presets a clear action, which is performed after all test cases of the test suite end.
|
||||
// This API supports only one parameter: clear action function.
|
||||
});
|
||||
it('startAndSuccess-CallBack', 0, async () => {
|
||||
let startCallBack: ESObject = undefined;
|
||||
let successCallBack: ESObject = undefined;
|
||||
let url: string =
|
||||
"https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/63/v3/qbe6NZkCQyGcITvdWoZBgg/Y-5U1z3GT_yaK8CBD3jkwg.jpg"
|
||||
let imageKnifeOption: ImageKnifeOption = {
|
||||
loadSrc: url,
|
||||
}
|
||||
await new Promise<string>((resolve, reject) => {
|
||||
imageKnifeOption.onLoadListener = {
|
||||
onLoadStart: (data) => {
|
||||
startCallBack = data?.getImageKnifeData();
|
||||
},
|
||||
onLoadSuccess: (data, imageknifeData,req) => {
|
||||
successCallBack = req?.getImageKnifeData();
|
||||
resolve("")
|
||||
},
|
||||
onLoadFailed(err) {
|
||||
reject(err)
|
||||
}
|
||||
}
|
||||
let request = new ImageKnifeRequest(
|
||||
imageKnifeOption,
|
||||
imageKnifeOption.context !== undefined ? imageKnifeOption.context : getContext() as common.UIAbilityContext,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
{
|
||||
showPixelMap(version: number, pixelMap: PixelMap | string) {
|
||||
}
|
||||
}
|
||||
)
|
||||
ImageKnife.getInstance().execute(request);
|
||||
})
|
||||
expect(startCallBack != undefined).assertTrue();
|
||||
expect(successCallBack != undefined).assertTrue();
|
||||
});
|
||||
it('failed-CallBack', 0, async () => {
|
||||
let failedCallBack: ESObject = undefined;
|
||||
let url: string =
|
||||
"https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/163/v3/qbe6NZkCQyGcITvdWoZBgg/Y-5U1z3GT_yaK8CBD3jkwg.jpg"
|
||||
let imageKnifeOption: ImageKnifeOption = {
|
||||
loadSrc: url,
|
||||
}
|
||||
await new Promise<string>((resolve, reject) => {
|
||||
imageKnifeOption.onLoadListener = {
|
||||
onLoadStart: (data) => {
|
||||
},
|
||||
onLoadSuccess: (data, imageknifeData) => {
|
||||
},
|
||||
onLoadFailed(res,req) {
|
||||
failedCallBack = req?.getImageKnifeData();
|
||||
resolve(res)
|
||||
}
|
||||
}
|
||||
let request = new ImageKnifeRequest(
|
||||
imageKnifeOption,
|
||||
imageKnifeOption.context !== undefined ? imageKnifeOption.context : getContext() as common.UIAbilityContext,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
{
|
||||
showPixelMap(version: number, pixelMap: PixelMap | string) {
|
||||
}
|
||||
}
|
||||
)
|
||||
ImageKnife.getInstance().execute(request);
|
||||
})
|
||||
expect(failedCallBack != undefined).assertTrue();
|
||||
});
|
||||
});
|
||||
}
|
|
@ -5,8 +5,9 @@
|
|||
"description": "$string:module_test_desc",
|
||||
"mainElement": "TestAbility",
|
||||
"deviceTypes": [
|
||||
"default",
|
||||
"tablet"
|
||||
"phone",
|
||||
"tablet",
|
||||
"2in1"
|
||||
],
|
||||
"deliveryWithInstall": true,
|
||||
"installationFree": false,
|
||||
|
|
|
@ -1,10 +1,6 @@
|
|||
## 1.0.4
|
||||
- 修改门禁编译问题 修改点如下
|
||||
- 修改src/main/cpp/boundscheck/CMakeLists.txt文件中的内容
|
||||
- 修改src/main/cpp/util/DebugLog.h文件中hilog的大小写
|
||||
|
||||
## 1.0.3
|
||||
- 安全编译开启Strip和Ftrapv
|
||||
- 修改门禁编译问题 修改点如下
|
||||
- 修改src/main/cpp/util/DebugLog.h文件中hilog的大小写
|
||||
|
||||
## 1.0.2
|
||||
- 支持x86编译
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
"buildOption": {
|
||||
"externalNativeOptions": {
|
||||
"path": "./src/main/cpp/CMakeLists.txt",
|
||||
"arguments": " -DCMAKE_BUILD_TYPE=Release",
|
||||
"arguments": "",
|
||||
"abiFilters": [
|
||||
"armeabi-v7a",
|
||||
"arm64-v8a",
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
"main": "index.ets",
|
||||
"repository": "https://gitee.com/openharmony-tpc/ImageKnife",
|
||||
"type": "module",
|
||||
"version": "1.0.4",
|
||||
"version": "1.0.3",
|
||||
"tags": [
|
||||
"Tool"
|
||||
],
|
||||
|
|
|
@ -11,11 +11,8 @@ include_directories(${NATIVERENDER_ROOT_PATH}
|
|||
${NATIVERENDER_ROOT_PATH}/common
|
||||
${NATIVERENDER_ROOT_PATH}/render
|
||||
${NATIVERENDER_ROOT_PATH}/constant
|
||||
${NATIVERENDER_ROOT_PATH}/boundscheck
|
||||
)
|
||||
|
||||
add_subdirectory(boundscheck)
|
||||
|
||||
add_library(nativeGpu SHARED
|
||||
${NATIVERENDER_ROOT_PATH}/napi/napi_init.cpp
|
||||
${NATIVERENDER_ROOT_PATH}/render/EGLRender.cpp
|
||||
|
@ -33,4 +30,4 @@ find_library (
|
|||
GLES-lib
|
||||
GLESv3 )
|
||||
|
||||
target_link_libraries(nativeGpu PUBLIC boundscheck ${hilog-lib} ${EGL-lib} ${GLES-lib} libace_napi.z.so -s -ftrapv)
|
||||
target_link_libraries(nativeGpu PUBLIC ${hilog-lib} ${EGL-lib} ${GLES-lib} libace_napi.z.so libc++.a)
|
|
@ -1,27 +0,0 @@
|
|||
# the minimum version of CMake.
|
||||
cmake_minimum_required(VERSION 3.4.1)
|
||||
|
||||
set(can_use_assembler TRUE)
|
||||
enable_language(ASM)
|
||||
IF("${OHOS_ARCH}" STREQUAL "arm64-v8a")
|
||||
SET(ASM_OPTIONS "-x assembler-with-cpp")
|
||||
SET(CMAKE_ASM_FLAGS "${CFLAGS} ${ASM_OPTIONS} -march=armv8+crypto -D__OHOS__")
|
||||
ENDIF()
|
||||
|
||||
project(boundscheck)
|
||||
|
||||
set(TAGET_BOUNDSCHECK_SRC_PATH ${CMAKE_CURRENT_SOURCE_DIR}/third_party_bounds_checking_function/src)
|
||||
|
||||
add_library(boundscheck
|
||||
STATIC
|
||||
${TAGET_BOUNDSCHECK_SRC_PATH}/memcpy_s.c
|
||||
${TAGET_BOUNDSCHECK_SRC_PATH}/memset_s.c
|
||||
${TAGET_BOUNDSCHECK_SRC_PATH}/securecutil.c)
|
||||
|
||||
target_precompile_headers(boundscheck PUBLIC ${CMAKE_SYSROOT}/usr/include/stdint.h)
|
||||
|
||||
include_directories(${TAGET_BOUNDSCHECK_SRC_PATH}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/third_party_bounds_checking_function/include
|
||||
)
|
||||
|
||||
target_link_libraries(boundscheck)
|
|
@ -1 +0,0 @@
|
|||
Subproject commit a45b3aceed2c0138babc951850445d1cd010ce48
|
|
@ -535,10 +535,7 @@ void EGLRender::SetImageData(uint8_t *pData, int width, int height)
|
|||
m_RenderImage.height = height;
|
||||
m_RenderImage.format = IMAGE_FORMAT_RGBA;
|
||||
NativeImageUtil::AllocNativeImage(&m_RenderImage);
|
||||
if (memcpy_s(m_RenderImage.ppPlane[0],
|
||||
width * height * DEFAULT_FOUR, pData, width * height * DEFAULT_FOUR) != EOK) {
|
||||
return;
|
||||
}
|
||||
memcpy(m_RenderImage.ppPlane[0], pData, width * height * DEFAULT_FOUR);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, m_ImageTextureId);
|
||||
glTexImage2D(GL_TEXTURE_2D,
|
||||
|
|
|
@ -26,7 +26,6 @@
|
|||
#include <string>
|
||||
#include <string.h>
|
||||
#include "DebugLog.h"
|
||||
#include "third_party_bounds_checking_function/include/securec.h"
|
||||
|
||||
const int32_t MAX_STR_LENGTH = 1024;
|
||||
|
||||
|
@ -42,7 +41,7 @@ void NapiUtil::JsValueToString(const napi_env &env, const napi_value &value, con
|
|||
LOGI("%s nullptr js object to string malloc failed", __func__);
|
||||
return;
|
||||
}
|
||||
(void) memset_s(buf.get(), bufLen, 0, bufLen);
|
||||
(void) memset(buf.get(), 0, bufLen);
|
||||
size_t result = 0;
|
||||
napi_get_value_string_utf8(env, value, buf.get(), bufLen, &result);
|
||||
target = buf.get();
|
||||
|
|
|
@ -30,7 +30,6 @@
|
|||
#include <string.h>
|
||||
#include "DebugLog.h"
|
||||
#include "constant/constant_shape.h"
|
||||
#include "third_party_bounds_checking_function/include/securec.h"
|
||||
|
||||
#define IMAGE_FORMAT_RGBA 0x01
|
||||
#define IMAGE_FORMAT_NV21 0x02
|
||||
|
@ -49,7 +48,7 @@
|
|||
#define IMAGE_FORMAT_GRAY_EXT "GRAY"
|
||||
#define IMAGE_FORMAT_I444_EXT "I444"
|
||||
#define IMAGE_FORMAT_P010_EXT "P010" // 16bit NV21
|
||||
#define EOK 0
|
||||
|
||||
|
||||
struct NativeImage {
|
||||
int width;
|
||||
|
@ -141,9 +140,7 @@ public:
|
|||
if (napi_create_arraybuffer(env, srcLen, &nativePtr, res) != napi_ok || nativePtr == nullptr) {
|
||||
return false;
|
||||
}
|
||||
if (memcpy_s(nativePtr, srcLen, src, srcLen) != EOK) {
|
||||
return false;
|
||||
}
|
||||
memcpy(nativePtr, src, srcLen);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -152,17 +149,10 @@ public:
|
|||
int totalLength = width * height * DEFAULT_FOUR;
|
||||
int oneLineLength = width * DEFAULT_FOUR;
|
||||
uint8_t* tmp = (uint8_t*)malloc(totalLength);
|
||||
if (memcpy_s(tmp, totalLength, *buf, totalLength) != EOK) {
|
||||
return;
|
||||
}
|
||||
if (memset_s(*buf, sizeof(uint8_t)*totalLength, DEFAULT_ZERO, sizeof(uint8_t)*totalLength) != EOK) {
|
||||
return;
|
||||
}
|
||||
memcpy(tmp, *buf, totalLength);
|
||||
memset(*buf, DEFAULT_ZERO, sizeof(uint8_t)*totalLength);
|
||||
for (int i = 0; i < height; i++) {
|
||||
if (memcpy_s(*buf + oneLineLength * i, oneLineLength,
|
||||
tmp + totalLength - oneLineLength * (i+1), oneLineLength) != EOK) {
|
||||
break;
|
||||
}
|
||||
memcpy(*buf + oneLineLength * i, tmp + totalLength - oneLineLength * (i+1), oneLineLength);
|
||||
}
|
||||
free(tmp);
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
{
|
||||
"hvigorVersion": "4.0.2",
|
||||
"modelVersion": "5.0.0",
|
||||
"dependencies": {
|
||||
"@ohos/hvigor-ohos-plugin": "4.0.2"
|
||||
},
|
||||
"execution": {
|
||||
// "analyze": "default", /* Define the build analyze mode. Value: [ "default" | "verbose" | false ]. Default: "default" */
|
||||
|
|
File diff suppressed because one or more lines are too long
48
hvigorw
48
hvigorw
|
@ -1,48 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# Hvigor startup script, version 1.0.0
|
||||
#
|
||||
# Required ENV vars:
|
||||
# ------------------
|
||||
# NODE_HOME - location of a Node home dir
|
||||
# or
|
||||
# Add /usr/local/nodejs/bin to the PATH environment variable
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
HVIGOR_APP_HOME=$(dirname $(readlink -f $0))
|
||||
HVIGOR_WRAPPER_SCRIPT=${HVIGOR_APP_HOME}/hvigor/hvigor-wrapper.js
|
||||
warn() {
|
||||
echo ""
|
||||
echo -e "\033[1;33m`date '+[%Y-%m-%d %H:%M:%S]'`$@\033[0m"
|
||||
}
|
||||
|
||||
error() {
|
||||
echo ""
|
||||
echo -e "\033[1;31m`date '+[%Y-%m-%d %H:%M:%S]'`$@\033[0m"
|
||||
}
|
||||
|
||||
fail() {
|
||||
error "$@"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Determine node to start hvigor wrapper script
|
||||
if [ -n "${NODE_HOME}" ];then
|
||||
EXECUTABLE_NODE="${NODE_HOME}/bin/node"
|
||||
if [ ! -x "$EXECUTABLE_NODE" ];then
|
||||
fail "ERROR: NODE_HOME is set to an invalid directory,check $NODE_HOME\n\nPlease set NODE_HOME in your environment to the location where your nodejs installed"
|
||||
fi
|
||||
else
|
||||
EXECUTABLE_NODE="node"
|
||||
which ${EXECUTABLE_NODE} > /dev/null 2>&1 || fail "ERROR: NODE_HOME is not set and not 'node' command found in your path"
|
||||
fi
|
||||
|
||||
# Check hvigor wrapper script
|
||||
if [ ! -r "$HVIGOR_WRAPPER_SCRIPT" ];then
|
||||
fail "ERROR: Couldn't find hvigor/hvigor-wrapper.js in ${HVIGOR_APP_HOME}"
|
||||
fi
|
||||
|
||||
# start hvigor-wrapper script
|
||||
exec "${EXECUTABLE_NODE}" \
|
||||
"${HVIGOR_WRAPPER_SCRIPT}" "$@"
|
57
hvigorw.bat
57
hvigorw.bat
|
@ -1,57 +0,0 @@
|
|||
@if "%DEBUG%" == "" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Hvigor startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
|
||||
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
|
||||
|
||||
set WRAPPER_MODULE_PATH=%APP_HOME%\hvigor\hvigor-wrapper.js
|
||||
set NODE_EXE=node.exe
|
||||
|
||||
goto start
|
||||
|
||||
:start
|
||||
@rem Find node.exe
|
||||
if defined NODE_HOME goto findNodeFromNodeHome
|
||||
|
||||
%NODE_EXE% --version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: NODE_HOME is not set and no 'node' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the NODE_HOME variable in your environment to match the
|
||||
echo location of your NodeJs installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:findNodeFromNodeHome
|
||||
set NODE_HOME=%NODE_HOME:"=%
|
||||
set NODE_EXE_PATH=%NODE_HOME%/%NODE_EXE%
|
||||
|
||||
if exist "%NODE_EXE_PATH%" goto execute
|
||||
echo.
|
||||
echo ERROR: NODE_HOME is not set and no 'node' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the NODE_HOME variable in your environment to match the
|
||||
echo location of your NodeJs installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:execute
|
||||
@rem Execute hvigor
|
||||
"%NODE_EXE%" %WRAPPER_MODULE_PATH% %*
|
||||
|
||||
:fail
|
||||
exit /b 1
|
|
@ -67,5 +67,3 @@ export { CropTransformation } from './src/main/ets/transform/CropTransformation'
|
|||
export { MaskTransformation } from './src/main/ets/transform/MaskTransformation'
|
||||
|
||||
export { SepiaTransformation } from './src/main/ets/transform/SepiaTransformation'
|
||||
|
||||
export { DownsampleStrategy } from './src/main/ets/downsampling/DownsampleStartegy'
|
|
@ -14,7 +14,7 @@
|
|||
"main": "index.ets",
|
||||
"repository": "https://gitee.com/openharmony-tpc/ImageKnife",
|
||||
"type": "module",
|
||||
"version": "3.1.1-rc.0",
|
||||
"version": "3.2.0-rc.1",
|
||||
"dependencies": {
|
||||
"@ohos/gpu_transform": "^1.0.2"
|
||||
},
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { ImageKnifeRequest } from './model/ImageKnifeRequest';
|
||||
import { ImageKnifeRequest, ImageKnifeRequestState } from './model/ImageKnifeRequest';
|
||||
import { CacheStrategy, ImageKnifeData, ImageKnifeRequestSource } from './model/ImageKnifeData';
|
||||
import { MemoryLruCache } from './cache/MemoryLruCache';
|
||||
import { IMemoryCache } from './cache/IMemoryCache'
|
||||
|
@ -38,7 +38,7 @@ export class ImageKnife {
|
|||
private _isRequestInSubThread: boolean = true;
|
||||
//定义全局网络请求header map
|
||||
headerMap: Map<string, Object> = new Map<string, Object>();
|
||||
customGetImage: ((context: Context, src: string | PixelMap | Resource) => Promise<ArrayBuffer | undefined>) | undefined = undefined
|
||||
customGetImage: ((context: Context, src: string | PixelMap | Resource,headers?: Record<string,Object>) => Promise<ArrayBuffer | undefined>) | undefined = undefined
|
||||
public static getInstance(): ImageKnife {
|
||||
if (!ImageKnife.instance) {
|
||||
ImageKnife.instance = new ImageKnife();
|
||||
|
@ -80,7 +80,15 @@ export class ImageKnife {
|
|||
public isFileCacheInit(): boolean {
|
||||
return this.fileCache === undefined ? false : this.fileCache.isFileCacheInit()
|
||||
}
|
||||
|
||||
/**
|
||||
* 重新加载
|
||||
*/
|
||||
reload(request: ImageKnifeRequest) {
|
||||
if (request.requestState == ImageKnifeRequestState.ERROR) {
|
||||
request.requestState = ImageKnifeRequestState.PROGRESS
|
||||
ImageKnife.getInstance().execute(request)
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 全局添加单个请求头header
|
||||
* @param key 请求头属性
|
||||
|
@ -137,8 +145,39 @@ export class ImageKnife {
|
|||
let key = this.getEngineKeyImpl().generateMemoryKey(imageKnifeOption.loadSrc, ImageKnifeRequestSource.SRC, imageKnifeOption);
|
||||
this.memoryCache.remove(key);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 预加载
|
||||
* @param loadSrc 图片地址url
|
||||
* @returns 图片请求request
|
||||
*/
|
||||
preload(loadSrc:string | ImageKnifeOption):ImageKnifeRequest{
|
||||
let imageKnifeOption = new ImageKnifeOption()
|
||||
if (typeof loadSrc == "string") {
|
||||
imageKnifeOption.loadSrc = loadSrc
|
||||
} else {
|
||||
imageKnifeOption = loadSrc;
|
||||
}
|
||||
let request = new ImageKnifeRequest(
|
||||
imageKnifeOption,
|
||||
imageKnifeOption.context !== undefined ? imageKnifeOption.context : getContext(this) as common.UIAbilityContext,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
{
|
||||
showPixelMap(version: number, pixelMap: PixelMap | string) {
|
||||
}
|
||||
}
|
||||
)
|
||||
this.execute(request)
|
||||
return request
|
||||
}
|
||||
/**
|
||||
* 取消图片请求
|
||||
* @param request 图片请求request
|
||||
*/
|
||||
cancel(request:ImageKnifeRequest) {
|
||||
request.requestState = ImageKnifeRequestState.DESTROY
|
||||
}
|
||||
/**
|
||||
* 预加载图片到文件缓存
|
||||
* @param loadSrc 图片地址url
|
||||
|
@ -191,10 +230,10 @@ export class ImageKnife {
|
|||
*/
|
||||
getCacheImage(loadSrc: string,
|
||||
cacheType: CacheStrategy = CacheStrategy.Default, signature?: string): Promise<ImageKnifeData | undefined> {
|
||||
let option: ImageKnifeOption = new ImageKnifeOption({
|
||||
let option: ImageKnifeOption = {
|
||||
loadSrc: loadSrc,
|
||||
signature:signature
|
||||
})
|
||||
}
|
||||
let engineKeyImpl: IEngineKey = this.getEngineKeyImpl();
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
|
@ -218,7 +257,7 @@ export class ImageKnife {
|
|||
*/
|
||||
putCacheImage(url: string, pixelMap: PixelMap, cacheType: CacheStrategy = CacheStrategy.Default, signature?: string) {
|
||||
let memoryKey = this.getEngineKeyImpl()
|
||||
.generateMemoryKey(url, ImageKnifeRequestSource.SRC, new ImageKnifeOption({ loadSrc: url, signature: signature }));
|
||||
.generateMemoryKey(url, ImageKnifeRequestSource.SRC, { loadSrc: url, signature: signature });
|
||||
let fileKey = this.getEngineKeyImpl().generateFileKey(url, signature);
|
||||
let imageKnifeData: ImageKnifeData = { source: pixelMap, imageWidth: 0, imageHeight: 0 };
|
||||
switch (cacheType) {
|
||||
|
@ -252,9 +291,9 @@ export class ImageKnife {
|
|||
if (url instanceof ImageKnifeOption) {
|
||||
imageKnifeOption = url;
|
||||
} else {
|
||||
imageKnifeOption = new ImageKnifeOption({
|
||||
imageKnifeOption = {
|
||||
loadSrc: url
|
||||
});
|
||||
};
|
||||
}
|
||||
let key = this.getEngineKeyImpl().generateFileKey(imageKnifeOption.loadSrc, imageKnifeOption.signature);
|
||||
if (this.fileCache !== undefined) {
|
||||
|
@ -307,7 +346,7 @@ export class ImageKnife {
|
|||
* @param cacheType
|
||||
* @returns
|
||||
*/
|
||||
getCacheUpperLimit(cacheType?: CacheStrategy): number | undefined {
|
||||
getCacheLimitSize(cacheType?: CacheStrategy): number | undefined {
|
||||
if (cacheType == undefined || cacheType == CacheStrategy.Default) {
|
||||
cacheType = CacheStrategy.Memory;
|
||||
}
|
||||
|
@ -327,7 +366,7 @@ export class ImageKnife {
|
|||
* @param cacheType
|
||||
* @returns
|
||||
*/
|
||||
getCurrentPicturesNum(cacheType: CacheStrategy): number | undefined {
|
||||
getCurrentCacheNum(cacheType: CacheStrategy): number | undefined {
|
||||
if (cacheType == undefined || cacheType == CacheStrategy.Default) {
|
||||
cacheType = CacheStrategy.Memory;
|
||||
}
|
||||
|
@ -362,7 +401,6 @@ export class ImageKnife {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
private pixelMapToArrayBuffer(pixelMap: PixelMap): ArrayBuffer {
|
||||
let imageInfo = pixelMap.getImageInfoSync();
|
||||
let readBuffer: ArrayBuffer = new ArrayBuffer(imageInfo.size.height * imageInfo.size.width * 4);
|
||||
|
@ -444,10 +482,10 @@ export class ImageKnife {
|
|||
* 全局设置自定义下载
|
||||
* @param customGetImage 自定义请求函数
|
||||
*/
|
||||
setCustomGetImage(customGetImage?: (context: Context, src: string | PixelMap | Resource) => Promise<ArrayBuffer | undefined>) {
|
||||
setCustomGetImage(customGetImage?: (context: Context, src: string | PixelMap | Resource,headers?: Record<string,Object>) => Promise<ArrayBuffer | undefined>) {
|
||||
this.customGetImage = customGetImage
|
||||
}
|
||||
getCustomGetImage(): undefined | ((context: Context, src: string | PixelMap | Resource) => Promise<ArrayBuffer | undefined>){
|
||||
getCustomGetImage(): undefined | ((context: Context, src: string | PixelMap | Resource,headers?: Record<string,Object>) => Promise<ArrayBuffer | undefined>){
|
||||
return this.customGetImage
|
||||
}
|
||||
}
|
|
@ -19,10 +19,10 @@ import List from '@ohos.util.List';
|
|||
import LightWeightMap from '@ohos.util.LightWeightMap';
|
||||
import { LogUtil } from './utils/LogUtil';
|
||||
import { ImageKnife } from './ImageKnife';
|
||||
import { ImageKnifeData, CacheStrategy } from './model/ImageKnifeData';
|
||||
import { ImageKnifeData, CacheStrategy, TimeInfo, ErrorInfo } from './model/ImageKnifeData';
|
||||
import image from '@ohos.multimedia.image';
|
||||
import emitter from '@ohos.events.emitter';
|
||||
import { Constants } from './utils/Constants';
|
||||
import { Constants, LoadPhase, LoadPixelMapCode } from './utils/Constants';
|
||||
import taskpool from '@ohos.taskpool';
|
||||
import { FileTypeUtil } from './utils/FileTypeUtil';
|
||||
import { IEngineKey } from './key/IEngineKey';
|
||||
|
@ -35,7 +35,6 @@ import {
|
|||
} from './model/ImageKnifeData'
|
||||
import { BusinessError } from '@kit.BasicServicesKit';
|
||||
import { ImageKnifeLoader } from './ImageKnifeLoader'
|
||||
import { DownsampleStrategy } from './downsampling/DownsampleStartegy';
|
||||
|
||||
|
||||
export class ImageKnifeDispatcher {
|
||||
|
@ -51,6 +50,7 @@ export class ImageKnifeDispatcher {
|
|||
showFromMemomry(request: ImageKnifeRequest, imageSrc: string | PixelMap | Resource, requestSource: ImageKnifeRequestSource,isAnimator?: boolean): boolean {
|
||||
LogUtil.log("ImageKnife_DataTime_showFromMemomry.start:" + request.imageKnifeOption.loadSrc + "requestSource=" + requestSource + " isAnimator=" + isAnimator)
|
||||
let memoryCache: ImageKnifeData | undefined;
|
||||
let memoryCheckStartTime = Date.now();
|
||||
if ((typeof (request.imageKnifeOption.loadSrc as image.PixelMap).isEditable) == 'boolean') {
|
||||
memoryCache = {
|
||||
source: request.imageKnifeOption.loadSrc as image.PixelMap,
|
||||
|
@ -62,23 +62,38 @@ export class ImageKnifeDispatcher {
|
|||
.loadFromMemoryCache(this.engineKey.generateMemoryKey(imageSrc, requestSource, request.imageKnifeOption,isAnimator));
|
||||
}
|
||||
|
||||
//记录ImageKnifeRequestSource.SRC 开始内存检查的时间点
|
||||
if (requestSource == ImageKnifeRequestSource.SRC && request.getImageKnifeData()) {
|
||||
let timeInfo = request.getImageKnifeData()?.timeInfo
|
||||
if (timeInfo) {
|
||||
timeInfo.memoryCheckStartTime = memoryCheckStartTime;
|
||||
timeInfo.memoryCheckEndTime = Date.now();
|
||||
//设置请求结束的时间点
|
||||
if (memoryCache !== undefined) {
|
||||
timeInfo.requestEndTime = Date.now();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (memoryCache !== undefined) {
|
||||
// 画主图
|
||||
if (request.requestState === ImageKnifeRequestState.PROGRESS) {
|
||||
// 回调请求开始
|
||||
if (requestSource === ImageKnifeRequestSource.SRC && request.imageKnifeOption.onLoadListener?.onLoadStart !== undefined) {
|
||||
request.imageKnifeOption.onLoadListener.onLoadStart()
|
||||
request.imageKnifeOption.onLoadListener.onLoadStart(request)
|
||||
LogUtil.log("ImageKnife_DataTime_MemoryCache_onLoadStart:" + request.imageKnifeOption.loadSrc)
|
||||
}
|
||||
LogUtil.log("ImageKnife_DataTime_MemoryCache_showPixelMap.start:" + request.imageKnifeOption.loadSrc)
|
||||
request.ImageKnifeRequestCallback?.showPixelMap(request.componentVersion, memoryCache.source, requestSource,memoryCache.imageAnimator)
|
||||
request.ImageKnifeRequestCallback?.showPixelMap(request.componentVersion, memoryCache.source,
|
||||
{ width: memoryCache.imageWidth, height: memoryCache.imageHeight }, requestSource, memoryCache.imageAnimator)
|
||||
LogUtil.log("ImageKnife_DataTime_MemoryCache_showPixelMap.end:" + request.imageKnifeOption.loadSrc)
|
||||
|
||||
if (requestSource == ImageKnifeRequestSource.SRC) {
|
||||
request.requestState = ImageKnifeRequestState.COMPLETE
|
||||
// 回调请求开结束
|
||||
if (request.imageKnifeOption.onLoadListener?.onLoadSuccess !== undefined) {
|
||||
request.imageKnifeOption.onLoadListener.onLoadSuccess(memoryCache.source,memoryCache)
|
||||
this.copyMemoryCacheInfo(memoryCache, request.getImageKnifeData());
|
||||
request.imageKnifeOption.onLoadListener.onLoadSuccess(memoryCache.source, memoryCache, request)
|
||||
LogUtil.log("ImageKnife_DataTime_MemoryCache_onLoadSuccess:" + request.imageKnifeOption.loadSrc)
|
||||
}
|
||||
} else if (requestSource == ImageKnifeRequestSource.ERROR_HOLDER) {
|
||||
|
@ -92,8 +107,55 @@ export class ImageKnifeDispatcher {
|
|||
return false
|
||||
}
|
||||
|
||||
private copyMemoryCacheInfo(memoryCache: ImageKnifeData | undefined, target: ImageKnifeData | undefined) {
|
||||
if (!memoryCache || !target) {
|
||||
return;
|
||||
}
|
||||
target.source = memoryCache.source;
|
||||
target.imageWidth = memoryCache.imageWidth;
|
||||
target.imageHeight = memoryCache.imageHeight;
|
||||
target.type = memoryCache.type;
|
||||
target.imageAnimator = memoryCache.imageAnimator;
|
||||
}
|
||||
|
||||
private assembleImageKnifeData(beforeCallData: ImageKnifeData | undefined, afterCallData: ImageKnifeData | undefined, req: ImageKnifeRequest) {
|
||||
if (!beforeCallData || !afterCallData || !req) {
|
||||
return;
|
||||
}
|
||||
//设置图片开始加载时间及其缓存检查时间点
|
||||
if (beforeCallData.timeInfo) {
|
||||
if (afterCallData.timeInfo) {
|
||||
afterCallData.timeInfo.requestStartTime = beforeCallData.timeInfo.requestStartTime;
|
||||
afterCallData.timeInfo.memoryCheckStartTime = beforeCallData.timeInfo.memoryCheckStartTime;
|
||||
afterCallData.timeInfo.memoryCheckEndTime = beforeCallData.timeInfo.memoryCheckEndTime;
|
||||
}
|
||||
}
|
||||
req.setImageKnifeData(afterCallData);
|
||||
}
|
||||
|
||||
private initCallData(request: ImageKnifeRequest) {
|
||||
if (!request) {
|
||||
return
|
||||
}
|
||||
//图片加载信息回调数据
|
||||
let callBackData: ImageKnifeData = {
|
||||
source: "",
|
||||
imageWidth: 0,
|
||||
imageHeight: 0,
|
||||
};
|
||||
|
||||
//图片加载信息回调数据时间点
|
||||
let callBackTimeInfo: TimeInfo = {};
|
||||
callBackTimeInfo.requestStartTime = Date.now();
|
||||
callBackData.timeInfo = callBackTimeInfo;
|
||||
|
||||
//跟隨請求保存回調信息點
|
||||
request.setImageKnifeData(callBackData);
|
||||
}
|
||||
|
||||
enqueue(request: ImageKnifeRequest,isAnimator?: boolean): void {
|
||||
//初始化加载回调信息
|
||||
this.initCallData(request);
|
||||
//1.内存有的话直接渲染
|
||||
if (this.showFromMemomry(request, request.imageKnifeOption.loadSrc, ImageKnifeRequestSource.SRC,isAnimator)) {
|
||||
return
|
||||
|
@ -105,7 +167,7 @@ export class ImageKnifeDispatcher {
|
|||
}
|
||||
}
|
||||
//3.判断是否要排队
|
||||
if (this.executingJobMap.length > this.maxRequests) {
|
||||
if (this.executingJobMap.length >= this.maxRequests) {
|
||||
this.jobQueue.add(request)
|
||||
return
|
||||
}
|
||||
|
@ -129,6 +191,11 @@ export class ImageKnifeDispatcher {
|
|||
*/
|
||||
getAndShowImage(currentRequest: ImageKnifeRequest, imageSrc: string | PixelMap | Resource, requestSource: ImageKnifeRequestSource,isAnimator?: boolean): void {
|
||||
LogUtil.log("ImageKnife_DataTime_getAndShowImage.start:" + currentRequest.imageKnifeOption.loadSrc)
|
||||
if (requestSource === ImageKnifeRequestSource.SRC && currentRequest.imageKnifeOption.onLoadListener?.onLoadStart !== undefined) {
|
||||
currentRequest.imageKnifeOption.onLoadListener?.onLoadStart(currentRequest)
|
||||
LogUtil.log("ImageKnife_DataTime_getAndShowImage_onLoadStart:" + currentRequest.imageKnifeOption.loadSrc)
|
||||
}
|
||||
|
||||
let memoryKey: string = this.engineKey.generateMemoryKey(imageSrc, requestSource, currentRequest.imageKnifeOption,isAnimator)
|
||||
let requestList: List<ImageKnifeRequestWithSource> | undefined = this.executingJobMap.get(memoryKey)
|
||||
if (requestList == undefined) {
|
||||
|
@ -141,11 +208,14 @@ export class ImageKnifeDispatcher {
|
|||
}
|
||||
|
||||
let isWatchProgress : boolean = false
|
||||
if (currentRequest.imageKnifeOption.progressListener !== undefined && requestSource === ImageKnifeRequestSource.SRC) {
|
||||
isWatchProgress = true
|
||||
}
|
||||
|
||||
// 回调请求开始
|
||||
requestList.forEach((requestWithSource: ImageKnifeRequestWithSource) => {
|
||||
if (requestWithSource.source === ImageKnifeRequestSource.SRC && requestWithSource.request.imageKnifeOption.onLoadListener?.onLoadStart !== undefined) {
|
||||
requestWithSource.request.imageKnifeOption.onLoadListener?.onLoadStart()
|
||||
requestWithSource.request.imageKnifeOption.onLoadListener?.onLoadStart(requestWithSource.request)
|
||||
LogUtil.log("ImageKnife_DataTime_getAndShowImage_onLoadStart:" + currentRequest.imageKnifeOption.loadSrc)
|
||||
}
|
||||
if (requestWithSource.request.imageKnifeOption.progressListener !== undefined && requestWithSource.source === ImageKnifeRequestSource.SRC) {
|
||||
|
@ -184,15 +254,22 @@ export class ImageKnifeDispatcher {
|
|||
fileCacheFolder: ImageKnife.getInstance().getFileCache()?.getCacheFolder(),
|
||||
isAnimator:isAnimator,
|
||||
moduleName: moduleName == "" ? undefined : moduleName,
|
||||
resName: resName == "" ? undefined : resName,
|
||||
targetWidth: currentRequest.componentWidth,
|
||||
targetHeight: currentRequest.componentHeight,
|
||||
downsampType: currentRequest.imageKnifeOption.downsampleOf==undefined?DownsampleStrategy.NONE:currentRequest.imageKnifeOption.downsampleOf,
|
||||
resName: resName == "" ? undefined : resName
|
||||
}
|
||||
|
||||
if(request.customGetImage == undefined) {
|
||||
request.customGetImage = ImageKnife.getInstance().getCustomGetImage()
|
||||
}
|
||||
emitter.on(Constants.CALLBACK_EMITTER + memoryKey,(data)=>{
|
||||
emitter.off(Constants.CALLBACK_EMITTER + memoryKey)
|
||||
let res = data?.data?.value as RequestJobResult | undefined
|
||||
this.doTaskCallback(res, requestList!, currentRequest, memoryKey, imageSrc, requestSource,isAnimator);
|
||||
if (isWatchProgress){
|
||||
emitter.off(Constants.PROGRESS_EMITTER + memoryKey)
|
||||
}
|
||||
LogUtil.log("ImageKnife_DataTime_getAndShowImage_execute.end:"+currentRequest.imageKnifeOption.loadSrc)
|
||||
LogUtil.log("ImageKnife_DataTime_getAndShowImage.end:"+currentRequest.imageKnifeOption.loadSrc)
|
||||
})
|
||||
if (ImageKnife.getInstance().isRequestInSubThread){
|
||||
// 启动线程下载和解码主图
|
||||
LogUtil.log("ImageKnife_DataTime_getAndShowImage_Task.start:" + currentRequest.imageKnifeOption.loadSrc)
|
||||
|
@ -206,13 +283,14 @@ export class ImageKnifeDispatcher {
|
|||
|
||||
LogUtil.log("ImageKnife_DataTime_getAndShowImage_execute.start(subthread):" + currentRequest.imageKnifeOption.loadSrc)
|
||||
taskpool.execute(task).then((res: Object) => {
|
||||
this.doTaskCallback(res as RequestJobResult | undefined, requestList!, currentRequest, memoryKey, imageSrc, requestSource,isAnimator);
|
||||
if (isWatchProgress){
|
||||
emitter.off(Constants.PROGRESS_EMITTER + memoryKey)
|
||||
}
|
||||
LogUtil.log("ImageKnife_DataTime_getAndShowImage_execute.end:"+currentRequest.imageKnifeOption.loadSrc)
|
||||
LogUtil.log("ImageKnife_DataTime_getAndShowImage.end:"+currentRequest.imageKnifeOption.loadSrc)
|
||||
// this.doTaskCallback(res as RequestJobResult | undefined, requestList!, currentRequest, memoryKey, imageSrc, requestSource,isAnimator);
|
||||
// if (isWatchProgress){
|
||||
// emitter.off(Constants.PROGRESS_EMITTER + memoryKey)
|
||||
// }
|
||||
// LogUtil.log("ImageKnife_DataTime_getAndShowImage_execute.end:"+currentRequest.imageKnifeOption.loadSrc)
|
||||
// LogUtil.log("ImageKnife_DataTime_getAndShowImage.end:"+currentRequest.imageKnifeOption.loadSrc)
|
||||
}).catch((err: BusinessError) => {
|
||||
emitter.off(Constants.CALLBACK_EMITTER + memoryKey)
|
||||
LogUtil.error("Fail to requestJob in sub thread src=" + imageSrc + " err=" + err)
|
||||
LogUtil.log("ImageKnife_DataTime_getAndShowImage.end:" + currentRequest.imageKnifeOption.loadSrc)
|
||||
if (isWatchProgress){
|
||||
|
@ -223,11 +301,12 @@ export class ImageKnifeDispatcher {
|
|||
})
|
||||
} else { //主线程请求
|
||||
LogUtil.log("ImageKnife_DataTime_getAndShowImage_execute.start(mainthread):" + currentRequest.imageKnifeOption.loadSrc)
|
||||
requestJob(request, requestList).then((res: RequestJobResult | undefined) => {
|
||||
this.doTaskCallback(res, requestList!, currentRequest, memoryKey, imageSrc, requestSource,isAnimator);
|
||||
LogUtil.log("ImageKnife_DataTime_getAndShowImage_execute.end:"+currentRequest.imageKnifeOption.loadSrc)
|
||||
LogUtil.log("ImageKnife_DataTime_getAndShowImage.end:"+currentRequest.imageKnifeOption.loadSrc)
|
||||
requestJob(request, requestList).then(() => {
|
||||
// this.doTaskCallback(res, requestList!, currentRequest, memoryKey, imageSrc, requestSource,isAnimator);
|
||||
// LogUtil.log("ImageKnife_DataTime_getAndShowImage_execute.end:"+currentRequest.imageKnifeOption.loadSrc)
|
||||
// LogUtil.log("ImageKnife_DataTime_getAndShowImage.end:"+currentRequest.imageKnifeOption.loadSrc)
|
||||
}).catch((err: BusinessError) => {
|
||||
emitter.off(Constants.CALLBACK_EMITTER + memoryKey)
|
||||
LogUtil.error("Fail to requestJob in main thread src=" + imageSrc + " err=" + err)
|
||||
LogUtil.log("ImageKnife_DataTime_getAndShowImage.end:" + currentRequest.imageKnifeOption.loadSrc)
|
||||
this.executingJobMap.remove(memoryKey);
|
||||
|
@ -256,6 +335,12 @@ export class ImageKnifeDispatcher {
|
|||
if (requestJobResult === undefined){
|
||||
return
|
||||
}
|
||||
|
||||
//设置请求结束的时间
|
||||
if (requestJobResult.imageKnifeData && requestJobResult.imageKnifeData.timeInfo) {
|
||||
requestJobResult.imageKnifeData.timeInfo.requestEndTime = Date.now();
|
||||
}
|
||||
|
||||
let pixelmap = requestJobResult.pixelMap;
|
||||
if (pixelmap === undefined) {
|
||||
LogUtil.log("ImageKnife_DataTime_getAndShowImage_CallBack.pixelmap undefined:"+currentRequest.imageKnifeOption.loadSrc)
|
||||
|
@ -264,7 +349,8 @@ export class ImageKnifeDispatcher {
|
|||
if (requestWithSource.source === ImageKnifeRequestSource.SRC &&
|
||||
requestWithSource.request.imageKnifeOption.onLoadListener?.onLoadFailed !== undefined &&
|
||||
requestJobResult.loadFail) {
|
||||
requestWithSource.request.imageKnifeOption.onLoadListener.onLoadFailed(requestJobResult.loadFail);
|
||||
this.assembleImageKnifeData(requestWithSource.request.getImageKnifeData(), requestJobResult.imageKnifeData, requestWithSource.request)
|
||||
requestWithSource.request.imageKnifeOption.onLoadListener.onLoadFailed(requestJobResult.loadFail,requestWithSource.request);
|
||||
LogUtil.log("ImageKnife_DataTime_getAndShowImage_onLoadFailed:"+currentRequest.imageKnifeOption.loadSrc)
|
||||
}
|
||||
if (requestWithSource.source === ImageKnifeRequestSource.SRC &&
|
||||
|
@ -288,12 +374,19 @@ export class ImageKnifeDispatcher {
|
|||
LogUtil.log("ImageKnife_DataTime_getAndShowImage_saveWithoutWriteFile.end:"+currentRequest.imageKnifeOption.loadSrc)
|
||||
}
|
||||
|
||||
let ImageKnifeData: ImageKnifeData = {
|
||||
let imageKnifeData: ImageKnifeData;
|
||||
if (!requestJobResult.imageKnifeData) {
|
||||
imageKnifeData = {
|
||||
source: pixelmap!,
|
||||
imageWidth: requestJobResult.size == undefined ? 0 : requestJobResult.size.width,
|
||||
imageHeight: requestJobResult.size == undefined ? 0 : requestJobResult.size.height,
|
||||
type:requestJobResult.type
|
||||
type: requestJobResult.type,
|
||||
};
|
||||
} else {
|
||||
imageKnifeData = requestJobResult.imageKnifeData;
|
||||
imageKnifeData.source = pixelmap!;
|
||||
}
|
||||
|
||||
if(requestJobResult.pixelMapList != undefined) {
|
||||
let imageAnimator: Array<ImageFrameInfo> = []
|
||||
requestJobResult.pixelMapList.forEach((item,index)=>{
|
||||
|
@ -302,14 +395,24 @@ export class ImageKnifeDispatcher {
|
|||
duration:requestJobResult.delayList![index]
|
||||
})
|
||||
})
|
||||
ImageKnifeData.imageAnimator = imageAnimator
|
||||
imageKnifeData.imageAnimator = imageAnimator
|
||||
}
|
||||
|
||||
//构建缓存保存的ImageKnifeData
|
||||
let saveCacheImageData: ImageKnifeData = {
|
||||
source: pixelmap!,
|
||||
imageWidth: requestJobResult.size == undefined ? 0 : requestJobResult.size.width,
|
||||
imageHeight: requestJobResult.size == undefined ? 0 : requestJobResult.size.height,
|
||||
type: requestJobResult.type,
|
||||
imageAnimator: imageKnifeData.imageAnimator
|
||||
}
|
||||
|
||||
// 保存内存缓存
|
||||
if (currentRequest.imageKnifeOption.writeCacheStrategy !== CacheStrategy.File) {
|
||||
LogUtil.log("ImageKnife_DataTime_getAndShowImage_saveMemoryCache.start:"+currentRequest.imageKnifeOption.loadSrc)
|
||||
ImageKnife.getInstance()
|
||||
.saveMemoryCache(this.engineKey.generateMemoryKey(imageSrc, requestSource, currentRequest.imageKnifeOption,isAnimator),
|
||||
ImageKnifeData);
|
||||
saveCacheImageData);
|
||||
LogUtil.log("ImageKnife_DataTime_getAndShowImage_saveMemoryCache.end:"+currentRequest.imageKnifeOption.loadSrc)
|
||||
}
|
||||
if (requestList !== undefined) {
|
||||
|
@ -323,7 +426,8 @@ export class ImageKnifeDispatcher {
|
|||
requestWithSource.request.requestState === ImageKnifeRequestState.PROGRESS)) {
|
||||
LogUtil.log("ImageKnife_DataTime_getAndShowImage_showPixelMap.start:"+currentRequest.imageKnifeOption.loadSrc)
|
||||
requestWithSource.request.ImageKnifeRequestCallback.showPixelMap(requestWithSource.request.componentVersion,
|
||||
ImageKnifeData.source, requestWithSource.source,ImageKnifeData.imageAnimator);
|
||||
imageKnifeData.source, { width: imageKnifeData.imageWidth, height: imageKnifeData.imageHeight },
|
||||
requestWithSource.source, imageKnifeData.imageAnimator);
|
||||
LogUtil.log("ImageKnife_DataTime_getAndShowImage_showPixelMap.end:"+currentRequest.imageKnifeOption.loadSrc)
|
||||
}
|
||||
|
||||
|
@ -332,7 +436,9 @@ export class ImageKnifeDispatcher {
|
|||
if (requestWithSource.request.imageKnifeOption.onLoadListener &&
|
||||
requestWithSource.request.imageKnifeOption.onLoadListener.onLoadSuccess) {
|
||||
// 回调请求成功
|
||||
requestWithSource.request.imageKnifeOption.onLoadListener.onLoadSuccess(ImageKnifeData.source,ImageKnifeData);
|
||||
this.assembleImageKnifeData(requestWithSource.request.getImageKnifeData(), imageKnifeData,requestWithSource.request);
|
||||
requestWithSource.request.imageKnifeOption.onLoadListener.onLoadSuccess(imageKnifeData.source,
|
||||
saveCacheImageData, requestWithSource.request);
|
||||
LogUtil.log("ImageKnife_DataTime_getAndShowImage_onLoadSuccess:"+currentRequest.imageKnifeOption.loadSrc)
|
||||
}
|
||||
} else if (requestWithSource.source == ImageKnifeRequestSource.ERROR_HOLDER) {
|
||||
|
@ -341,7 +447,19 @@ export class ImageKnifeDispatcher {
|
|||
} else {
|
||||
if (requestWithSource.source == ImageKnifeRequestSource.SRC && requestWithSource.request.imageKnifeOption.onLoadListener?.onLoadCancel) {
|
||||
// 回调请求成功
|
||||
requestWithSource.request.imageKnifeOption.onLoadListener.onLoadCancel("component has destroyed")
|
||||
// 回调请求成功
|
||||
//设置失败回调的时间点
|
||||
let callBackData = requestWithSource.request.getImageKnifeData();
|
||||
|
||||
if (requestJobResult.imageKnifeData && requestJobResult.imageKnifeData.timeInfo) {
|
||||
requestJobResult.imageKnifeData.timeInfo.requestCancelTime = Date.now();
|
||||
if (requestJobResult.imageKnifeData.errorInfo) {
|
||||
requestJobResult.imageKnifeData.errorInfo.phase = LoadPhase.PHASE_WILL_SHOW;
|
||||
requestJobResult.imageKnifeData.errorInfo.code = LoadPixelMapCode.IMAGE_LOAD_CANCEL_FAILED_CODE;
|
||||
}
|
||||
}
|
||||
this.assembleImageKnifeData(callBackData,requestJobResult.imageKnifeData,requestWithSource.request)
|
||||
requestWithSource.request.imageKnifeOption.onLoadListener.onLoadCancel("component has destroyed", requestWithSource.request)
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -369,7 +487,19 @@ export class ImageKnifeDispatcher {
|
|||
LogUtil.log("ImageKnife_DataTime_dispatchNextJob.end executeJob:" + request.imageKnifeOption.loadSrc)
|
||||
break
|
||||
}else if (request.requestState == ImageKnifeRequestState.DESTROY && request.imageKnifeOption.onLoadListener?.onLoadCancel) {
|
||||
request.imageKnifeOption.onLoadListener.onLoadCancel("component has destroyed")
|
||||
//构建回调错误信息
|
||||
let callBackData = request.getImageKnifeData();
|
||||
if (callBackData) {
|
||||
let timeInfo: TimeInfo = ImageKnifeLoader.getTimeInfo(callBackData)
|
||||
timeInfo.requestCancelTime = Date.now();
|
||||
timeInfo.requestEndTime = Date.now()
|
||||
let errorInfo: ErrorInfo = {
|
||||
phase: LoadPhase.PHASE_THREAD_QUEUE,
|
||||
code: LoadPixelMapCode.IMAGE_LOAD_CANCEL_FAILED_CODE,
|
||||
};
|
||||
callBackData.errorInfo = errorInfo;
|
||||
}
|
||||
request.imageKnifeOption.onLoadListener.onLoadCancel("component has destroyed", request)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -396,44 +526,15 @@ export class ImageKnifeDispatcher {
|
|||
* @returns
|
||||
*/
|
||||
@Concurrent
|
||||
async function requestJob(request: RequestJobRequest, requestList?: List<ImageKnifeRequestWithSource>): Promise<RequestJobResult | undefined> {
|
||||
async function requestJob(request: RequestJobRequest, requestList?: List<ImageKnifeRequestWithSource>) {
|
||||
LogUtil.log("ImageKnife_DataTime_requestJob.start:" + request.src + " requestSource=" + request.requestSource)
|
||||
let src = typeof request.src == "number" ? request.resName != undefined ? request.resName : request.src + "" : request.src
|
||||
// 生成文件缓存key
|
||||
let fileKey = request.engineKey.generateFileKey(src, request.signature, request.isAnimator)
|
||||
|
||||
//获取图片资源
|
||||
let resBuf: ArrayBuffer
|
||||
try {
|
||||
LogUtil.log("ImageKnife_DataTime_requestJob.getImageArrayBuffer.start:" + request.src)
|
||||
resBuf = await ImageKnifeLoader.getImageArrayBuffer(request, requestList, fileKey)
|
||||
LogUtil.log("ImageKnife_DataTime_requestJob.getImageArrayBuffer.end:" + request.src)
|
||||
} catch (error) {
|
||||
LogUtil.error("ImageKnife_DataTime_requestJob.end: getImageArrayBuffer error " + request.src + " err=" + error)
|
||||
return ImageKnifeLoader.makeEmptyResult(error)
|
||||
}
|
||||
ImageKnifeLoader.execute(request,requestList,fileKey)
|
||||
|
||||
// 获取图片类型
|
||||
let typeValue = new FileTypeUtil().getFileType(resBuf);
|
||||
if(typeValue == null) {
|
||||
LogUtil.log("ImageKnife_DataTime_requestJob.end: getFileType is null " + request.src)
|
||||
return ImageKnifeLoader.makeEmptyResult("request is not a valid image source")
|
||||
}
|
||||
|
||||
// 解析图片
|
||||
LogUtil.log("ImageKnife_DataTime_requestJob.parseImage.start:" + request.src)
|
||||
let result: RequestJobResult = await ImageKnifeLoader.parseImage(resBuf, typeValue, fileKey, request)
|
||||
LogUtil.log("ImageKnife_DataTime_requestJob.parseImage.end:" + request.src)
|
||||
|
||||
// 图形变化
|
||||
if (request.requestSource === ImageKnifeRequestSource.SRC && request.transformation !== undefined && result?.pixelMap !== undefined && typeof result.pixelMap !== 'string') {
|
||||
LogUtil.log("ImageKnife_DataTime_requestJob.transform.start:" + request.src)
|
||||
result.pixelMap = await request.transformation?.transform(request.context, result.pixelMap, request.componentWidth, request.componentHeight);
|
||||
LogUtil.log("ImageKnife_DataTime_requestJob.transform.end:" + request.src)
|
||||
}
|
||||
|
||||
LogUtil.log("ImageKnife_DataTime_requestJob.end:" + request.src)
|
||||
return result
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -14,12 +14,16 @@
|
|||
*/
|
||||
import {
|
||||
CacheStrategy,
|
||||
DecodeImageInfo,
|
||||
ErrorInfo,
|
||||
ImageKnifeData,
|
||||
ImageKnifeRequestSource,
|
||||
ImageKnifeRequestWithSource, RequestJobRequest } from './model/ImageKnifeData';
|
||||
ImageKnifeRequestWithSource, RequestJobRequest,
|
||||
TimeInfo } from './model/ImageKnifeData';
|
||||
import List from '@ohos.util.List'
|
||||
import { FileCache } from './cache/FileCache';
|
||||
import { LogUtil } from './utils/LogUtil';
|
||||
import { Constants } from './utils/Constants';
|
||||
import { Constants, LoadPhase, LoadPixelMapCode } from './utils/Constants';
|
||||
import http from '@ohos.net.http';
|
||||
import { combineArrayBuffers } from './utils/ArrayBufferUtils';
|
||||
import { BusinessError } from '@kit.BasicServicesKit';
|
||||
|
@ -28,8 +32,7 @@ import emitter from '@ohos.events.emitter';
|
|||
import image from '@ohos.multimedia.image';
|
||||
import { RequestJobResult } from './model/ImageKnifeData'
|
||||
import util from '@ohos.util';
|
||||
import { DownsampleStrategy } from './downsampling/DownsampleStartegy';
|
||||
import { Downsampler } from './downsampling/Downsampler';
|
||||
import { FileTypeUtil } from './utils/FileTypeUtil';
|
||||
|
||||
class RequestData {
|
||||
receiveSize: number = 2000
|
||||
|
@ -40,79 +43,152 @@ class RequestData {
|
|||
* ImageKnifeDispatcher 抽取出来的方法,因@Concurrent只能import方法,故抽取到另一个类
|
||||
*/
|
||||
export class ImageKnifeLoader {
|
||||
static async parseImage(resBuf: ArrayBuffer, typeValue: string, fileKey: string,
|
||||
request: RequestJobRequest): Promise<RequestJobResult> {
|
||||
static execute(request: RequestJobRequest, requestList: List<ImageKnifeRequestWithSource> | undefined, fileKey: string){
|
||||
ImageKnifeLoader.getImageArrayBuffer(request,requestList,fileKey)
|
||||
}
|
||||
static async parseImage(resBuf: ArrayBuffer, fileKey: string,
|
||||
request: RequestJobRequest, callBackData: ImageKnifeData) {
|
||||
callBackData.bufSize = resBuf.byteLength;
|
||||
let typeValue = new FileTypeUtil().getFileType(resBuf);
|
||||
if(typeValue == null) {
|
||||
LogUtil.log("ImageKnife_DataTime_requestJob.end: getFileType is null " + request.src)
|
||||
ImageKnifeLoader.makeEmptyResult(request,"request is not a valid image source", ImageKnifeLoader.assembleError(callBackData, LoadPhase.PHASE_GET_FORMAT, LoadPixelMapCode.IMAGE_PARSE_FORMAT_FAILED_CODE))
|
||||
return
|
||||
}
|
||||
callBackData.type = typeValue;
|
||||
if(request.isAnimator) {
|
||||
return ImageKnifeLoader.parseForAnimatorComponent(resBuf ,typeValue ,fileKey, request)
|
||||
ImageKnifeLoader.parseForAnimatorComponent(resBuf ,typeValue ,fileKey, request, callBackData)
|
||||
return
|
||||
}
|
||||
|
||||
if (typeValue === 'gif' || typeValue === 'webp') {
|
||||
return ImageKnifeLoader.parseAnimatorImage(resBuf ,typeValue ,fileKey , request)
|
||||
ImageKnifeLoader.parseAnimatorImage(resBuf ,typeValue ,fileKey , request, callBackData)
|
||||
return
|
||||
} else if(typeValue == "svg") {
|
||||
return ImageKnifeLoader.parseSvgImage(resBuf ,typeValue ,fileKey , request)
|
||||
ImageKnifeLoader.parseSvgImage(resBuf ,typeValue ,fileKey , request, callBackData)
|
||||
return
|
||||
}
|
||||
|
||||
return ImageKnifeLoader.parseNormalImage(resBuf, typeValue, fileKey, request)
|
||||
ImageKnifeLoader.parseNormalImage(resBuf, typeValue, fileKey, request, callBackData)
|
||||
}
|
||||
|
||||
static makeEmptyResult(error: string): RequestJobResult{
|
||||
return {
|
||||
static makeEmptyResult(request:RequestJobRequest,error: string, data?: ImageKnifeData){
|
||||
let res: RequestJobResult = {
|
||||
pixelMap: undefined,
|
||||
bufferSize: 0,
|
||||
fileKey: '',
|
||||
loadFail: error,
|
||||
imageKnifeData: data
|
||||
}
|
||||
emitter.emit(Constants.CALLBACK_EMITTER + request.memoryKey, { data: { "value": res } })
|
||||
}
|
||||
|
||||
static async parseNormalImage(resBuf: ArrayBuffer, typeValue: string, fileKey: string, request: RequestJobRequest):Promise<RequestJobResult> {
|
||||
static assembleError(data: ImageKnifeData | undefined, phase: string, code?: number,
|
||||
httpCode?: number): ImageKnifeData | undefined {
|
||||
let errorCallBackData = data?.errorInfo;
|
||||
if (!errorCallBackData) {
|
||||
return data;
|
||||
}
|
||||
errorCallBackData.phase = phase;
|
||||
errorCallBackData.code = code? code: 0;
|
||||
if (httpCode && httpCode != 0) {
|
||||
errorCallBackData.httpCode = httpCode;
|
||||
}
|
||||
return data
|
||||
}
|
||||
|
||||
static getTimeInfo(callBackData: ImageKnifeData): TimeInfo {
|
||||
let timeInfo: TimeInfo;
|
||||
if (callBackData.timeInfo) {
|
||||
timeInfo = callBackData.timeInfo;
|
||||
}else {
|
||||
timeInfo = {};
|
||||
callBackData.timeInfo = timeInfo;
|
||||
}
|
||||
return timeInfo;
|
||||
}
|
||||
|
||||
static async parseNormalImage(resBuf: ArrayBuffer, typeValue: string, fileKey: string, request: RequestJobRequest, callBackData: ImageKnifeData) {
|
||||
let resPixelmap: PixelMap | undefined = undefined
|
||||
let timeInfo: TimeInfo = ImageKnifeLoader.getTimeInfo(callBackData);
|
||||
|
||||
let decodingOptions: image.DecodingOptions = {
|
||||
editable: request.requestSource === ImageKnifeRequestSource.SRC && request.transformation !== undefined ? true : false,
|
||||
}
|
||||
let imageSource: image.ImageSource = image.createImageSource(resBuf)
|
||||
if (imageSource === undefined){
|
||||
return ImageKnifeLoader.makeEmptyResult("image.createImageSource failed")
|
||||
ImageKnifeLoader.makeEmptyResult(request,"image.createImageSource failed", ImageKnifeLoader.assembleError(callBackData, LoadPhase.PHASE_CREATE_SOURCE, LoadPixelMapCode.IMAGE_SOURCE_ERROR_CODE))
|
||||
return
|
||||
}
|
||||
|
||||
let size = (await imageSource.getImageInfo()).size
|
||||
try {
|
||||
if ((request.downsampType !== DownsampleStrategy.NONE) &&
|
||||
request.requestSource == ImageKnifeRequestSource.SRC) {
|
||||
decodingOptions = ImageKnifeLoader.getDownsamplerDecodingOptions(typeValue, request, size, ImageKnifeRequestSource.SRC)
|
||||
}
|
||||
} catch (err) {
|
||||
return ImageKnifeLoader.makeEmptyResult(err)
|
||||
}
|
||||
callBackData.imageWidth = size.width;
|
||||
callBackData.imageHeight = size.height;
|
||||
timeInfo.decodeStartTime = Date.now();
|
||||
|
||||
await imageSource.createPixelMap(decodingOptions)
|
||||
.then((pixelmap: PixelMap) => {
|
||||
timeInfo.decodeEndTime = Date.now();
|
||||
resPixelmap = pixelmap
|
||||
imageSource.release()
|
||||
}).catch((error: BusinessError) => {
|
||||
timeInfo.decodeEndTime = Date.now();
|
||||
imageSource.release()
|
||||
return ImageKnifeLoader.makeEmptyResult(JSON.stringify(error))
|
||||
ImageKnifeLoader.makeEmptyResult(request,JSON.stringify(error), ImageKnifeLoader.assembleError(callBackData, LoadPhase.PHASE_CREATE_PIXEL_MAP, LoadPixelMapCode.IMAGE_DECODE_ERROR_CODE))
|
||||
return
|
||||
})
|
||||
if (request.requestSource === ImageKnifeRequestSource.SRC && request.transformation !== undefined && resPixelmap !== undefined) {
|
||||
LogUtil.log("ImageKnife_DataTime_requestJob.transform.start:" + request.src)
|
||||
resPixelmap = await request.transformation?.transform(request.context, resPixelmap, request.componentWidth, request.componentHeight);
|
||||
LogUtil.log("ImageKnife_DataTime_requestJob.transform.end:" + request.src)
|
||||
}
|
||||
try {
|
||||
resPixelmap?.setTransferDetached(true)
|
||||
} catch (e) {
|
||||
LogUtil.error("PixelMap setTransferDetached err:"+JSON.stringify(e))
|
||||
}
|
||||
|
||||
return {
|
||||
//获取各个pixelMap的大小
|
||||
if (resPixelmap && typeof resPixelmap !== "string") {
|
||||
let decodeImages: Array<DecodeImageInfo> = [];
|
||||
let size = (resPixelmap as PixelMap).getImageInfoSync().size;
|
||||
let decodeImage: DecodeImageInfo = {
|
||||
contentWidth: size.width,
|
||||
contentHeight: size.height,
|
||||
contentSize: (resPixelmap as PixelMap).getPixelBytesNumber()
|
||||
}
|
||||
decodeImages.push(decodeImage);
|
||||
callBackData.decodeImages = decodeImages;
|
||||
}
|
||||
|
||||
let res: RequestJobResult = {
|
||||
pixelMap: resPixelmap,
|
||||
bufferSize: resBuf.byteLength,
|
||||
fileKey: fileKey,
|
||||
size:size,
|
||||
type:typeValue
|
||||
};
|
||||
type:typeValue,
|
||||
imageKnifeData:callBackData
|
||||
}
|
||||
emitter.emit(Constants.CALLBACK_EMITTER + request.memoryKey, { data: { "value": res } })
|
||||
}
|
||||
static async parseSvgImage(resBuf: ArrayBuffer, typeValue: string, fileKey: string,
|
||||
request: RequestJobRequest): Promise<RequestJobResult> {
|
||||
request: RequestJobRequest, callBackData: ImageKnifeData) {
|
||||
let resPixelmap: PixelMap | undefined = undefined
|
||||
let timeInfo: TimeInfo = ImageKnifeLoader.getTimeInfo(callBackData);
|
||||
|
||||
let imageSource: image.ImageSource = image.createImageSource(resBuf)
|
||||
if (imageSource === undefined){
|
||||
return ImageKnifeLoader.makeEmptyResult("image.createImageSource failed")
|
||||
ImageKnifeLoader.makeEmptyResult(request,"image.createImageSource failed", ImageKnifeLoader.assembleError(callBackData, LoadPhase.PHASE_CREATE_SOURCE, LoadPixelMapCode.IMAGE_SOURCE_ERROR_CODE))
|
||||
return
|
||||
}
|
||||
|
||||
let size = (await imageSource.getImageInfo()).size
|
||||
let scale = size.height / size.width
|
||||
let hValue = Math.round(request.componentHeight);
|
||||
let wValue = Math.round(request.componentWidth);
|
||||
callBackData.imageWidth = size.width;
|
||||
callBackData.imageHeight = size.height;
|
||||
timeInfo.decodeStartTime = Date.now();
|
||||
let defaultSize: image.Size = {
|
||||
height: vp2px(wValue) * scale,
|
||||
width: vp2px(wValue)
|
||||
|
@ -121,67 +197,99 @@ export class ImageKnifeLoader {
|
|||
editable: true,
|
||||
desiredSize: defaultSize
|
||||
};
|
||||
try {
|
||||
if ((request.downsampType !== DownsampleStrategy.NONE) &&
|
||||
request.requestSource == ImageKnifeRequestSource.SRC) {
|
||||
opts = ImageKnifeLoader.getDownsamplerDecodingOptions(typeValue, request, size)
|
||||
}
|
||||
} catch (err) {
|
||||
return ImageKnifeLoader.makeEmptyResult(err)
|
||||
}
|
||||
await imageSource.createPixelMap(opts)
|
||||
.then((pixelmap: PixelMap) => {
|
||||
timeInfo.decodeEndTime = Date.now();
|
||||
resPixelmap = pixelmap
|
||||
imageSource.release()
|
||||
try {
|
||||
resPixelmap.setTransferDetached(true)
|
||||
} catch (e) {
|
||||
LogUtil.error("PixelMap setTransferDetached err:"+JSON.stringify(e))
|
||||
}
|
||||
}).catch((error: BusinessError) => {
|
||||
timeInfo.decodeEndTime = Date.now();
|
||||
imageSource.release()
|
||||
return ImageKnifeLoader.makeEmptyResult(JSON.stringify(error))
|
||||
ImageKnifeLoader.makeEmptyResult(request,JSON.stringify(error), ImageKnifeLoader.assembleError(callBackData, LoadPhase.PHASE_CREATE_PIXEL_MAP, LoadPixelMapCode.IMAGE_DECODE_ERROR_CODE))
|
||||
return
|
||||
})
|
||||
|
||||
return {
|
||||
//获取各个pixelMap的大小
|
||||
if (resPixelmap && typeof resPixelmap !== "string") {
|
||||
let decodeImages: Array<DecodeImageInfo> = [];
|
||||
let decodeImage: DecodeImageInfo = {
|
||||
contentWidth: defaultSize.width,
|
||||
contentHeight: defaultSize.height,
|
||||
contentSize: (resPixelmap as PixelMap).getPixelBytesNumber()
|
||||
}
|
||||
decodeImages.push(decodeImage);
|
||||
}
|
||||
|
||||
let res: RequestJobResult = {
|
||||
pixelMap: resPixelmap,
|
||||
bufferSize: resBuf.byteLength,
|
||||
fileKey: fileKey,
|
||||
type:typeValue
|
||||
};
|
||||
type:typeValue,
|
||||
imageKnifeData:callBackData
|
||||
}
|
||||
emitter.emit(Constants.CALLBACK_EMITTER + request.memoryKey, { data: { "value": res } })
|
||||
}
|
||||
static async parseAnimatorImage(resBuf: ArrayBuffer, typeValue: string,
|
||||
fileKey: string,request: RequestJobRequest): Promise<RequestJobResult> {
|
||||
fileKey: string,request: RequestJobRequest, callBackData: ImageKnifeData) {
|
||||
let timeInfo: TimeInfo = ImageKnifeLoader.getTimeInfo(callBackData);
|
||||
let imageSource: image.ImageSource = image.createImageSource(resBuf)
|
||||
if (imageSource === undefined){
|
||||
return ImageKnifeLoader.makeEmptyResult("image.createImageSource failed")
|
||||
ImageKnifeLoader.makeEmptyResult(request,"image.createImageSource failed", ImageKnifeLoader.assembleError(callBackData,LoadPhase.PHASE_CREATE_SOURCE,LoadPixelMapCode.IMAGE_SOURCE_ERROR_CODE))
|
||||
return
|
||||
}
|
||||
|
||||
let frameCount = await imageSource.getFrameCount()
|
||||
let size = (await imageSource.getImageInfo()).size
|
||||
callBackData.frameCount = frameCount;
|
||||
callBackData.imageWidth = size.width;
|
||||
callBackData.imageHeight = size.height;
|
||||
|
||||
imageSource.release()
|
||||
|
||||
if(frameCount == undefined || frameCount == 1) {
|
||||
} else {
|
||||
timeInfo.decodeStartTime = Date.now()
|
||||
let base64str = "data:image/" + typeValue + ";base64," + new util.Base64Helper().encodeToStringSync(new Uint8Array(resBuf))
|
||||
return {
|
||||
timeInfo.diskCheckEndTime = Date.now()
|
||||
let res: RequestJobResult = {
|
||||
pixelMap: base64str,
|
||||
bufferSize: resBuf.byteLength,
|
||||
fileKey: fileKey,
|
||||
size:size,
|
||||
type:typeValue
|
||||
};
|
||||
type:typeValue,
|
||||
imageKnifeData:callBackData
|
||||
}
|
||||
return ImageKnifeLoader.parseNormalImage(resBuf, typeValue, fileKey, request)
|
||||
emitter.emit(Constants.CALLBACK_EMITTER + request.memoryKey, { data: { "value": res } })
|
||||
return
|
||||
}
|
||||
ImageKnifeLoader.parseNormalImage(resBuf, typeValue, fileKey, request, callBackData)
|
||||
}
|
||||
// 为AnimatorComponent解析动图
|
||||
static async parseForAnimatorComponent(resBuf: ArrayBuffer, typeValue: string, fileKey: string,request: RequestJobRequest): Promise<RequestJobResult> {
|
||||
static async parseForAnimatorComponent(resBuf: ArrayBuffer, typeValue: string, fileKey: string,request: RequestJobRequest, callBackData: ImageKnifeData) {
|
||||
let timeInfo: TimeInfo = ImageKnifeLoader.getTimeInfo(callBackData);
|
||||
|
||||
if (typeValue === 'gif' || typeValue === 'webp') {
|
||||
let imageSource: image.ImageSource = image.createImageSource(resBuf);
|
||||
if (imageSource === undefined){
|
||||
return ImageKnifeLoader.makeEmptyResult("image.createImageSource failed")
|
||||
ImageKnifeLoader.makeEmptyResult(request,"image.createImageSource failed", ImageKnifeLoader.assembleError(callBackData, LoadPhase.PHASE_CREATE_SOURCE, LoadPixelMapCode.IMAGE_SOURCE_ERROR_CODE))
|
||||
return
|
||||
}
|
||||
let decodingOptions: image.DecodingOptions = {
|
||||
editable: request.requestSource === ImageKnifeRequestSource.SRC && request.transformation !== undefined ? true : false,
|
||||
}
|
||||
callBackData.imageWidth = imageSource.getImageInfoSync().size.width;
|
||||
callBackData.imageHeight = imageSource.getImageInfoSync().size.height;
|
||||
let pixelMapList: Array<PixelMap> = []
|
||||
let delayList: Array<number> = []
|
||||
timeInfo.decodeStartTime = Date.now();
|
||||
let decodeImages: Array<DecodeImageInfo> = [];
|
||||
await imageSource.createPixelMapList(decodingOptions).then(async (pixelList: Array<PixelMap>) => {
|
||||
timeInfo.decodeEndTime = Date.now();
|
||||
//sdk的api接口发生变更:从.getDelayTime() 变为.getDelayTimeList()
|
||||
await imageSource.getDelayTimeList().then(delayTimes => {
|
||||
if (pixelList.length > 0) {
|
||||
|
@ -192,68 +300,41 @@ export class ImageKnifeLoader {
|
|||
} else {
|
||||
delayList.push(delayTimes[delayTimes.length - 1])
|
||||
}
|
||||
//获取各个pixelMap的大小
|
||||
let size = pixelList[i].getImageInfoSync().size
|
||||
let decodeImage: DecodeImageInfo = {
|
||||
contentWidth: size.width,
|
||||
contentHeight: size.height,
|
||||
contentSize: pixelList[i].getPixelBytesNumber()
|
||||
}
|
||||
decodeImages.push(decodeImage);
|
||||
}
|
||||
imageSource.release();
|
||||
}
|
||||
})
|
||||
}).catch((error: BusinessError) => {
|
||||
imageSource.release()
|
||||
return ImageKnifeLoader.makeEmptyResult(JSON.stringify(error))
|
||||
timeInfo.decodeEndTime = Date.now();
|
||||
ImageKnifeLoader.makeEmptyResult(request,JSON.stringify(error), ImageKnifeLoader.assembleError(callBackData,LoadPhase.PHASE_CREATE_PIXEL_MAP,LoadPixelMapCode.IMAGE_DECODE_ERROR_CODE))
|
||||
return
|
||||
})
|
||||
return {
|
||||
callBackData.decodeImages = decodeImages;
|
||||
let res: RequestJobResult = {
|
||||
pixelMap: "",
|
||||
bufferSize: resBuf.byteLength,
|
||||
fileKey: fileKey,
|
||||
type: typeValue,
|
||||
imageKnifeData:callBackData,
|
||||
pixelMapList,
|
||||
delayList
|
||||
}
|
||||
emitter.emit(Constants.CALLBACK_EMITTER + request.memoryKey, { data: { "value": res } })
|
||||
} else {
|
||||
return ImageKnifeLoader.makeEmptyResult("ImageKnifeAnimatorComponent组件仅支持动态图")
|
||||
ImageKnifeLoader.makeEmptyResult(request,"ImageKnifeAnimatorComponent组件仅支持动态图", ImageKnifeLoader.assembleError(callBackData,LoadPhase.PHASE_PARSE_IAMGE,LoadPixelMapCode.IMAGE_FORMAT_ERROR_CODE))
|
||||
}
|
||||
}
|
||||
|
||||
// 获取图片资源
|
||||
static async getImageArrayBuffer(request: RequestJobRequest, requestList: List<ImageKnifeRequestWithSource> | undefined,fileKey:string): Promise<ArrayBuffer> {
|
||||
let resBuf: ArrayBuffer | undefined
|
||||
|
||||
// 判断自定义下载
|
||||
if (request.customGetImage !== undefined && request.requestSource == ImageKnifeRequestSource.SRC && typeof request.src == "string") {
|
||||
// 先从文件缓存获取
|
||||
resBuf = FileCache.getFileCacheByFile(request.context, fileKey , request.fileCacheFolder)
|
||||
if (resBuf === undefined) {
|
||||
LogUtil.log("start customGetImage src=" + request.src)
|
||||
try {
|
||||
resBuf = await request.customGetImage(request.context, request.src)
|
||||
LogUtil.log("end customGetImage src=" + request.src)
|
||||
} catch (err) {
|
||||
throw new Error('customGetImage loadFile failed! err = ' + err)
|
||||
}
|
||||
if (resBuf === undefined) {
|
||||
throw new Error('customGetImage loadFile failed!')
|
||||
}
|
||||
// 保存文件缓存
|
||||
if (request.writeCacheStrategy !== CacheStrategy.Memory) {
|
||||
LogUtil.log("ImageKnife_DataTime_requestJob_saveFileCacheOnlyFile.start:" + request.src)
|
||||
FileCache.saveFileCacheOnlyFile(request.context, fileKey, resBuf, request.fileCacheFolder)
|
||||
LogUtil.log("ImageKnife_DataTime_requestJob_saveFileCacheOnlyFile.end:" + request.src)
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (typeof request.src === 'string') {
|
||||
if (request.src.indexOf("http://") == 0 || request.src.indexOf("https://") == 0) { //从网络下载
|
||||
// 先从文件缓存获取
|
||||
resBuf = FileCache.getFileCacheByFile(request.context, fileKey , request.fileCacheFolder)
|
||||
if (resBuf !== undefined){
|
||||
LogUtil.log("success get image from filecache for key = " + fileKey + " src = " + request.src)
|
||||
}
|
||||
else if (request.onlyRetrieveFromCache != true) {
|
||||
LogUtil.log("HttpDownloadClient.start:" + request.src)
|
||||
let httpRequest = http.createHttp();
|
||||
let progress: number = 0
|
||||
let arrayBuffers = new Array<ArrayBuffer>()
|
||||
const headerObj: Record<string, object> = {}
|
||||
static getHeaderObj(request:RequestJobRequest){
|
||||
const headerObj: Record<string, Object> = {}
|
||||
if (request.headers != undefined) {
|
||||
request.headers.forEach((value) => {
|
||||
headerObj[value.key] = value.value
|
||||
|
@ -263,6 +344,82 @@ export class ImageKnifeLoader {
|
|||
headerObj[key] = value
|
||||
})
|
||||
}
|
||||
return headerObj
|
||||
}
|
||||
static FileCacheParseImage(request:RequestJobRequest,resBuf:ArrayBuffer,fileKey:string, callBackData: ImageKnifeData){
|
||||
// 保存文件缓存
|
||||
if (resBuf !== undefined && request.writeCacheStrategy !== CacheStrategy.Memory) {
|
||||
LogUtil.log("ImageKnife_DataTime_requestJob_saveFileCacheOnlyFile.start:"+request.src)
|
||||
FileCache.saveFileCacheOnlyFile(request.context, fileKey, resBuf , request.fileCacheFolder)
|
||||
LogUtil.log("ImageKnife_DataTime_requestJob_saveFileCacheOnlyFile.end:"+request.src)
|
||||
}
|
||||
ImageKnifeLoader.parseImage(resBuf,fileKey,request, callBackData)
|
||||
}
|
||||
// 获取图片资源
|
||||
static async getImageArrayBuffer(request: RequestJobRequest, requestList: List<ImageKnifeRequestWithSource> | undefined,fileKey:string) {
|
||||
let resBuf: ArrayBuffer | undefined
|
||||
let loadError: string = ""
|
||||
//定义图片各个阶段错误信息
|
||||
let error: ErrorInfo = { code: 0, phase: LoadPhase.PHASE_LOAD }
|
||||
//定义加载时间点
|
||||
let callBackTimeInfo: TimeInfo = {};
|
||||
//定义加载信息回调数据
|
||||
let callBackData: ImageKnifeData = {
|
||||
source: "",
|
||||
imageWidth: 0,
|
||||
imageHeight: 0,
|
||||
timeInfo: callBackTimeInfo,
|
||||
errorInfo: error
|
||||
};
|
||||
|
||||
// 判断自定义下载
|
||||
if (request.customGetImage !== undefined && request.requestSource == ImageKnifeRequestSource.SRC && typeof request.src == "string") {
|
||||
// 先从文件缓存获取
|
||||
ImageKnifeLoader.assembleError(callBackData,LoadPhase.PHASE_CUSTOM_LOAD)
|
||||
callBackTimeInfo.diskCheckStartTime = Date.now();
|
||||
resBuf = FileCache.getFileCacheByFile(request.context, fileKey , request.fileCacheFolder)
|
||||
callBackTimeInfo.diskCheckEndTime = Date.now();
|
||||
if (resBuf === undefined) {
|
||||
LogUtil.log("start customGetImage src=" + request.src)
|
||||
const headerObj: Record<string, Object> = ImageKnifeLoader.getHeaderObj(request)
|
||||
try {
|
||||
request.customGetImage(request.context, request.src, headerObj)
|
||||
.then((buffer)=>{
|
||||
if(buffer != undefined) {
|
||||
ImageKnifeLoader.FileCacheParseImage(request,buffer,fileKey,callBackData)
|
||||
} else {
|
||||
loadError = "customGetImage loadFail undefined"
|
||||
ImageKnifeLoader.makeEmptyResult(request,loadError, ImageKnifeLoader.assembleError(callBackData, LoadPhase.PHASE_CUSTOM_LOAD, LoadPixelMapCode.IMAGE_CUSTOM_LOAD_FAILED_CODE))
|
||||
}
|
||||
}).catch((err:string)=>{
|
||||
ImageKnifeLoader.makeEmptyResult(request,err, ImageKnifeLoader.assembleError(callBackData, LoadPhase.PHASE_CUSTOM_LOAD, LoadPixelMapCode.IMAGE_CUSTOM_LOAD_FAILED_CODE))
|
||||
})
|
||||
} catch (e) {
|
||||
loadError = "customGetImage loadFail failed"
|
||||
ImageKnifeLoader.makeEmptyResult(request,loadError + e, ImageKnifeLoader.assembleError(callBackData, LoadPhase.PHASE_CUSTOM_LOAD, LoadPixelMapCode.IMAGE_CUSTOM_LOAD_FAILED_CODE))
|
||||
}
|
||||
LogUtil.log("end customGetImage src=" + request.src)
|
||||
return
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (typeof request.src === 'string') {
|
||||
if (request.src.indexOf("http://") == 0 || request.src.indexOf("https://") == 0) { //从网络下载
|
||||
// 先从文件缓存获取
|
||||
ImageKnifeLoader.assembleError(callBackData,LoadPhase.PHASE_NET)
|
||||
callBackTimeInfo.diskCheckStartTime = Date.now()
|
||||
resBuf = FileCache.getFileCacheByFile(request.context, fileKey , request.fileCacheFolder)
|
||||
callBackTimeInfo.diskCheckEndTime = Date.now()
|
||||
if (resBuf !== undefined){
|
||||
LogUtil.log("success get image from filecache for key = " + fileKey + " src = " + request.src)
|
||||
}
|
||||
else if (request.onlyRetrieveFromCache != true) {
|
||||
LogUtil.log("HttpDownloadClient.start:" + request.src)
|
||||
callBackTimeInfo.netRequestStartTime = Date.now();
|
||||
let httpRequest = http.createHttp();
|
||||
let progress: number = 0
|
||||
let arrayBuffers = new Array<ArrayBuffer>()
|
||||
const headerObj: Record<string, Object> = ImageKnifeLoader.getHeaderObj(request)
|
||||
httpRequest.on("dataReceive", (data: ArrayBuffer) => {
|
||||
arrayBuffers.push(data)
|
||||
});
|
||||
|
@ -299,27 +456,30 @@ export class ImageKnifeLoader {
|
|||
// header: new Header('application/json')
|
||||
});
|
||||
|
||||
await promise.then((data: number) => {
|
||||
promise.then((data: number) => {
|
||||
ImageKnifeLoader.assembleError(callBackData,LoadPhase.PHASE_NET, undefined, data)
|
||||
callBackTimeInfo.netRequestEndTime = Date.now();
|
||||
if (data == 200 || data == 206 || data == 204) {
|
||||
resBuf = combineArrayBuffers(arrayBuffers)
|
||||
ImageKnifeLoader.FileCacheParseImage(request,resBuf,fileKey, callBackData)
|
||||
} else {
|
||||
throw new Error("HttpDownloadClient has error, http code =" + JSON.stringify(data))
|
||||
loadError = "HttpDownloadClient has error, http code =" + JSON.stringify(data)
|
||||
ImageKnifeLoader.makeEmptyResult(request,loadError, ImageKnifeLoader.assembleError(callBackData,LoadPhase.PHASE_NET, LoadPixelMapCode.IMAGE_HTTPS_LOAD_FAILED_CODE, data))
|
||||
}
|
||||
}).catch((err: Error) => {
|
||||
throw new Error("HttpDownloadClient download ERROR : err = " + JSON.stringify(err))
|
||||
loadError = "HttpDownloadClient download ERROR : err = " + JSON.stringify(err)
|
||||
callBackTimeInfo.netRequestEndTime = Date.now();
|
||||
ImageKnifeLoader.makeEmptyResult(request,loadError, ImageKnifeLoader.assembleError(callBackData,LoadPhase.PHASE_NET, LoadPixelMapCode.IMAGE_HTTPS_LOAD_FAILED_CODE, undefined))
|
||||
});
|
||||
LogUtil.log("HttpDownloadClient.end:" + request.src)
|
||||
// 保存文件缓存
|
||||
if (resBuf !== undefined && request.writeCacheStrategy !== CacheStrategy.Memory) {
|
||||
LogUtil.log("ImageKnife_DataTime_requestJob_saveFileCacheOnlyFile.start:"+request.src)
|
||||
FileCache.saveFileCacheOnlyFile(request.context, fileKey, resBuf , request.fileCacheFolder)
|
||||
LogUtil.log("ImageKnife_DataTime_requestJob_saveFileCacheOnlyFile.end:"+request.src)
|
||||
}
|
||||
return
|
||||
}
|
||||
else {
|
||||
throw new Error('onlyRetrieveFromCache,do not fetch image src = ' + request.src)
|
||||
callBackTimeInfo.netRequestEndTime = Date.now();
|
||||
loadError = 'onlyRetrieveFromCache,do not fetch image src = ' + request.src
|
||||
}
|
||||
} else if (request.src.startsWith('datashare://') || request.src.startsWith('file://')) {
|
||||
ImageKnifeLoader.assembleError(callBackData,LoadPhase.PHASE_SHARE_FILE)
|
||||
await fs.open(request.src, fs.OpenMode.READ_ONLY).then(async (file) => {
|
||||
await fs.stat(file.fd).then(async (stat) =>{
|
||||
let buf = new ArrayBuffer(stat.size);
|
||||
|
@ -327,15 +487,19 @@ export class ImageKnifeLoader {
|
|||
resBuf = buf;
|
||||
fs.closeSync(file.fd);
|
||||
}).catch((err:BusinessError) => {
|
||||
throw new Error('LoadDataShareFileClient fs.read err happened uri=' + request.src + " err.msg=" + err?.message + " err.code=" + err?.code)
|
||||
ImageKnifeLoader.assembleError(callBackData,LoadPhase.PHASE_SHARE_FILE, LoadPixelMapCode.IMAGE_LOAD_SHARE_FILE_FAILED_CODE)
|
||||
loadError = 'LoadDataShareFileClient fs.read err happened uri=' + request.src + " err.msg=" + err?.message + " err.code=" + err?.code
|
||||
})
|
||||
}).catch((err:BusinessError) => {
|
||||
throw new Error('LoadDataShareFileClient fs.stat err happened uri=' + request.src + " err.msg=" + err?.message + " err.code=" + err?.code)
|
||||
ImageKnifeLoader.assembleError(callBackData,LoadPhase.PHASE_SHARE_FILE, LoadPixelMapCode.IMAGE_LOAD_SHARE_FILE_FAILED_CODE)
|
||||
loadError = 'LoadDataShareFileClient fs.stat err happened uri=' + request.src + " err.msg=" + err?.message + " err.code=" + err?.code
|
||||
})
|
||||
}).catch((err:BusinessError) => {
|
||||
throw new Error('LoadDataShareFileClient fs.open err happened uri=' + request.src + " err.msg=" + err?.message + " err.code=" + err?.code)
|
||||
ImageKnifeLoader.assembleError(callBackData,LoadPhase.PHASE_SHARE_FILE, LoadPixelMapCode.IMAGE_LOAD_SHARE_FILE_FAILED_CODE)
|
||||
loadError = 'LoadDataShareFileClient fs.open err happened uri=' + request.src + " err.msg=" + err?.message + " err.code=" + err?.code
|
||||
})
|
||||
} else { //从本地文件获取
|
||||
ImageKnifeLoader.assembleError(callBackData,LoadPhase.PHASE_LOCAL_FILE)
|
||||
try {
|
||||
let stat = fs.statSync(request.src);
|
||||
if (stat.size > 0) {
|
||||
|
@ -345,7 +509,8 @@ export class ImageKnifeLoader {
|
|||
fs.closeSync(file);
|
||||
}
|
||||
} catch (err) {
|
||||
throw new Error(err)
|
||||
ImageKnifeLoader.assembleError(callBackData,LoadPhase.PHASE_LOCAL_FILE, LoadPixelMapCode.IMAGE_LOAD_LOCAL_FILE_FAILED_CODE)
|
||||
loadError = err
|
||||
}
|
||||
}
|
||||
} else if (typeof request.src == "number") { //从资源文件获取
|
||||
|
@ -369,34 +534,10 @@ export class ImageKnifeLoader {
|
|||
}
|
||||
|
||||
if (resBuf === undefined){
|
||||
throw new Error('getImageArrayBuffer undefined')
|
||||
callBackTimeInfo.requestEndTime = Date.now();
|
||||
ImageKnifeLoader.makeEmptyResult(request,loadError ,callBackData)
|
||||
return
|
||||
}
|
||||
return resBuf
|
||||
}
|
||||
|
||||
static getDownsamplerDecodingOptions(typeValue: string, request: RequestJobRequest, size: Size,
|
||||
SRC?: ImageKnifeRequestSource):image.DecodingOptions {
|
||||
let reqSize =
|
||||
new Downsampler().calculateScaling(typeValue, size.width, size.height, request.targetWidth, request.targetHeight,
|
||||
request.downsampType)
|
||||
if (typeValue == "svg") {
|
||||
return {
|
||||
editable: true,
|
||||
desiredSize: {
|
||||
height: vp2px(reqSize.height),
|
||||
width: vp2px(reqSize.width)
|
||||
}
|
||||
|
||||
}
|
||||
} else {
|
||||
return {
|
||||
editable: request.requestSource === SRC && request.transformation !== undefined ? true : false,
|
||||
desiredSize:{
|
||||
width: reqSize.width,
|
||||
height: reqSize.height
|
||||
ImageKnifeLoader.parseImage(resBuf,fileKey,request, callBackData)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -19,14 +19,15 @@ import { ImageKnife } from '../ImageKnife';
|
|||
import { LogUtil } from '../utils/LogUtil';
|
||||
import { ImageKnifeRequestSource } from '../model/ImageKnifeData';
|
||||
|
||||
@ComponentV2
|
||||
@Component
|
||||
export struct ImageKnifeAnimatorComponent {
|
||||
@Param animatorOption: AnimatorOption = new AnimatorOption();
|
||||
@Local pixelMap: PixelMap | string | undefined = undefined
|
||||
@Local imageAnimator: Array<ImageFrameInfo> | undefined = undefined
|
||||
@Local adaptiveWidth: Length = '100%'
|
||||
@Local adaptiveHeight: Length = '100%'
|
||||
@Local objectFit: ImageFit = ImageFit.Contain
|
||||
@Watch('watchImageKnifeOption') @ObjectLink imageKnifeOption: ImageKnifeOption;
|
||||
@State animatorOption: AnimatorOption = new AnimatorOption();
|
||||
@State pixelMap: PixelMap | string | undefined = undefined
|
||||
@State imageAnimator: Array<ImageFrameInfo> | undefined = undefined
|
||||
@State adaptiveWidth: Length = '100%'
|
||||
@State adaptiveHeight: Length = '100%'
|
||||
@State objectFit: ImageFit = ImageFit.Contain
|
||||
private request: ImageKnifeRequest | undefined
|
||||
private lastWidth: number = 0
|
||||
private lastHeight: number = 0
|
||||
|
@ -34,17 +35,7 @@ export struct ImageKnifeAnimatorComponent {
|
|||
private currentHeight: number = 0
|
||||
private componentVersion: number = 0
|
||||
private currentContext: common.UIAbilityContext | undefined = undefined
|
||||
@Param imageKnifeOption: ImageKnifeOption = new ImageKnifeOption();
|
||||
@Monitor('imageKnifeOption',
|
||||
"imageKnifeOption.loadSrc","imageKnifeOption.signature","imageKnifeOption.transformation","imageKnifeOption.border","imageKnifeOption.objectFit")
|
||||
watchImageKnifeOption() {
|
||||
if (this.request !== undefined) {
|
||||
this.request.requestState = ImageKnifeRequestState.DESTROY
|
||||
}
|
||||
this.request = undefined
|
||||
this.componentVersion++
|
||||
ImageKnife.getInstance().execute(this.getRequest(this.currentWidth, this.currentHeight))
|
||||
}
|
||||
|
||||
aboutToAppear(): void {
|
||||
this.objectFit = this.imageKnifeOption.objectFit === undefined ? ImageFit.Contain : this.imageKnifeOption.objectFit
|
||||
}
|
||||
|
@ -95,6 +86,15 @@ export struct ImageKnifeAnimatorComponent {
|
|||
.onRepeat(this.animatorOption.onRepeat)
|
||||
}
|
||||
|
||||
watchImageKnifeOption() {
|
||||
if (this.request !== undefined) {
|
||||
this.request.requestState = ImageKnifeRequestState.DESTROY
|
||||
}
|
||||
this.request = undefined
|
||||
this.componentVersion++
|
||||
ImageKnife.getInstance().execute(this.getRequest(this.currentWidth, this.currentHeight),true)
|
||||
}
|
||||
|
||||
getCurrentContext(): common.UIAbilityContext {
|
||||
if (this.currentContext == undefined) {
|
||||
this.currentContext = getContext(this) as common.UIAbilityContext
|
||||
|
@ -111,7 +111,7 @@ export struct ImageKnifeAnimatorComponent {
|
|||
height,
|
||||
this.componentVersion,
|
||||
{
|
||||
showPixelMap: async (version: number, pixelMap: PixelMap | string, requestSource: ImageKnifeRequestSource,imageAnimator?: Array<ImageFrameInfo>) => {
|
||||
showPixelMap: (version: number, pixelMap: PixelMap | string,size: Size, requestSource: ImageKnifeRequestSource,imageAnimator?: Array<ImageFrameInfo>) => {
|
||||
if (version !== this.componentVersion) {
|
||||
return //针对reuse场景,不显示历史图片
|
||||
}
|
||||
|
|
|
@ -21,13 +21,14 @@ import { ImageKnifeData, ImageKnifeRequestSource } from '../model/ImageKnifeData
|
|||
import { IEngineKey } from '../key/IEngineKey';
|
||||
import { DefaultEngineKey } from '../key/DefaultEngineKey';
|
||||
|
||||
@ComponentV2
|
||||
@Component
|
||||
export struct ImageKnifeComponent {
|
||||
@Local pixelMap: PixelMap | string | undefined = undefined
|
||||
@Param syncLoad: boolean = false
|
||||
@Local adaptiveWidth: Length = '100%'
|
||||
@Local adaptiveHeight: Length = '100%'
|
||||
@Local objectFit: ImageFit = ImageFit.Contain
|
||||
@Watch('watchImageKnifeOption') @ObjectLink imageKnifeOption: ImageKnifeOption;
|
||||
@State pixelMap: PixelMap | string | ImageContent | undefined = undefined
|
||||
@State syncLoad: boolean = false
|
||||
@State adaptiveWidth: Length = '100%'
|
||||
@State adaptiveHeight: Length = '100%'
|
||||
@State objectFit: ImageFit = ImageFit.Contain
|
||||
private request: ImageKnifeRequest | undefined
|
||||
private lastWidth: number = 0
|
||||
private lastHeight: number = 0
|
||||
|
@ -35,20 +36,6 @@ export struct ImageKnifeComponent {
|
|||
private currentHeight: number = 0
|
||||
private componentVersion: number = 0
|
||||
private currentContext: common.UIAbilityContext | undefined = undefined
|
||||
@Param imageKnifeOption: ImageKnifeOption = new ImageKnifeOption();
|
||||
|
||||
@Monitor('imageKnifeOption',
|
||||
"imageKnifeOption.loadSrc","imageKnifeOption.signature","imageKnifeOption.transformation","imageKnifeOption.border","imageKnifeOption.objectFit",'imageKnifeOption.downsampleOf')
|
||||
watchImageKnifeOption() {
|
||||
this.clearLastRequest()
|
||||
this.componentVersion++
|
||||
this.objectFit = this.imageKnifeOption.objectFit === undefined ? ImageFit.Contain : this.imageKnifeOption.objectFit
|
||||
LogUtil.log("watchImageKnifeOption execute request:width=" + this.currentWidth + " height= " + this.currentHeight
|
||||
+ " loadSrc = " + this.request?.imageKnifeOption.loadSrc
|
||||
+ " placeholderSrc = " + this.request?.imageKnifeOption.placeholderSrc
|
||||
+ " errorholderSrc = " + this.request?.imageKnifeOption.errorholderSrc)
|
||||
ImageKnife.getInstance().execute(this.getRequest(this.currentWidth, this.currentHeight))
|
||||
}
|
||||
|
||||
aboutToAppear(): void {
|
||||
this.objectFit = this.imageKnifeOption.objectFit === undefined ? ImageFit.Contain : this.imageKnifeOption.objectFit
|
||||
|
@ -81,9 +68,9 @@ export struct ImageKnifeComponent {
|
|||
}
|
||||
|
||||
aboutToRecycle() {
|
||||
this.pixelMap = ImageContent.EMPTY
|
||||
this.clearLastRequest()
|
||||
}
|
||||
|
||||
/**
|
||||
* 对已DESTROY的组件不再发起请求
|
||||
*/
|
||||
|
@ -93,7 +80,6 @@ export struct ImageKnifeComponent {
|
|||
this.request = undefined
|
||||
}
|
||||
}
|
||||
|
||||
build() {
|
||||
Image(this.pixelMap)
|
||||
.colorFilter(this.imageKnifeOption.drawingColorFilter)
|
||||
|
@ -109,18 +95,28 @@ export struct ImageKnifeComponent {
|
|||
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) {
|
||||
LogUtil.log("execute request:width=" + this.currentWidth + " height= " + this.currentHeight)
|
||||
ImageKnife.getInstance().execute(this.getRequest(this.currentWidth, this.currentHeight))
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 条件1: 宽高值均有效,值>0. 条件2:当前宽高与上一次宽高不同
|
||||
if (this.currentWidth > 0 && this.currentHeight > 0 &&
|
||||
(this.currentHeight != this.lastHeight || this.currentWidth != this.lastWidth)) {
|
||||
LogUtil.log("onSizeChange execute request:width=" + this.currentWidth + " height= " + this.currentHeight
|
||||
watchImageKnifeOption() {
|
||||
this.clearLastRequest()
|
||||
this.componentVersion++
|
||||
this.objectFit = this.imageKnifeOption.objectFit === undefined ? ImageFit.Contain : this.imageKnifeOption.objectFit
|
||||
LogUtil.log("watchImageKnifeOption execute request:width=" + this.currentWidth + " height= " + this.currentHeight
|
||||
+ " loadSrc = " + this.request?.imageKnifeOption.loadSrc
|
||||
+ " placeholderSrc = " + this.request?.imageKnifeOption.placeholderSrc
|
||||
+ " errorholderSrc = " + this.request?.imageKnifeOption.errorholderSrc)
|
||||
ImageKnife.getInstance().execute(this.getRequest(this.currentWidth, this.currentHeight))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
getCurrentContext(): common.UIAbilityContext {
|
||||
if (this.currentContext == undefined) {
|
||||
|
@ -138,15 +134,28 @@ export struct ImageKnifeComponent {
|
|||
height,
|
||||
this.componentVersion,
|
||||
{
|
||||
showPixelMap: async (version: number, pixelMap: PixelMap | string, requestSource: ImageKnifeRequestSource) => {
|
||||
showPixelMap: (version: number, pixelMap: PixelMap | string,size:Size, requestSource: ImageKnifeRequestSource) => {
|
||||
if (version !== this.componentVersion) {
|
||||
return //针对reuse场景,不显示历史图片
|
||||
}
|
||||
this.pixelMap = pixelMap
|
||||
if (typeof this.pixelMap !== 'string' && this.imageKnifeOption.objectFit === ImageFit.Auto) { //针对静态图高度自适应
|
||||
let info = await this.pixelMap.getImageInfo()
|
||||
if (typeof this.pixelMap !== 'string') {
|
||||
if (this.imageKnifeOption.objectFit === ImageFit.Auto) {
|
||||
|
||||
this.adaptiveWidth = this.currentWidth
|
||||
this.adaptiveHeight = info.size.height * this.currentWidth / info.size.width
|
||||
this.adaptiveHeight = size.height * this.currentWidth / size.width
|
||||
|
||||
// if (this.currentWidth / this.currentHeight > info.size.width / info.size.height) {
|
||||
// this.adaptiveWidth = this.currentWidth
|
||||
// this.adaptiveHeight = info.size.height * this.currentWidth / this.currentHeight
|
||||
// }
|
||||
// else {
|
||||
// this.adaptiveWidth = info.size.width * this.currentWidth / this.currentHeight
|
||||
// this.adaptiveHeight = this.currentHeight
|
||||
// }
|
||||
}
|
||||
} else {
|
||||
//console.info("KKKKKKKKKKK:" + pixelMap)
|
||||
}
|
||||
|
||||
if (requestSource == ImageKnifeRequestSource.SRC) {
|
||||
|
@ -166,3 +175,7 @@ export struct ImageKnifeComponent {
|
|||
return this.request
|
||||
}
|
||||
}
|
||||
|
||||
interface KeyCanvas {
|
||||
keyId: string
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { DownsampleStrategy } from './DownsampleStartegy';
|
||||
|
||||
import { SampleSizeRounding } from './DownsampleUtils';
|
||||
|
||||
export interface BaseDownsampling {
|
||||
getName(): string
|
||||
|
||||
getScaleFactor(sourceWidth: number, sourceHeight: number, requestWidth: number, requestHeight: number,downsampType?:DownsampleStrategy): number
|
||||
}
|
|
@ -1,148 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { BaseDownsampling } from './BaseDownsampling';
|
||||
import { getScale, highestOneBit, round, SampleSizeRounding } from './DownsampleUtils';
|
||||
|
||||
export class FitCenter implements BaseDownsampling {
|
||||
getName() {
|
||||
return "FitCenter"
|
||||
}
|
||||
|
||||
getScaleFactor(sourceWidth: number, sourceHeight: number, requestedWidth: number, requestedHeight: number,
|
||||
downsampType: DownsampleStrategy
|
||||
): number {
|
||||
//重新计算宽高比;
|
||||
let outSize: Size = {
|
||||
width: round(getScale(sourceWidth, sourceHeight, requestedWidth, requestedHeight, downsampType) * sourceWidth),
|
||||
height:round(getScale(sourceWidth, sourceHeight, requestedWidth, requestedHeight, downsampType) * sourceHeight)
|
||||
}
|
||||
let scaleFactor = downsampType === DownsampleStrategy.FIT_CENTER_QUALITY?
|
||||
Math.max(1, highestOneBit(Math.max(sourceWidth / outSize.width, sourceHeight / outSize.height))) :
|
||||
Math.max(1, highestOneBit(Math.min(sourceWidth / outSize.width, sourceHeight / outSize.height)))//将整型的缩放因子转换为2的次幂采样大小
|
||||
|
||||
if (downsampType === DownsampleStrategy.FIT_CENTER_MEMORY
|
||||
&& (scaleFactor < (1 / getScale(sourceWidth, sourceHeight, requestedWidth, requestedHeight, downsampType)))) {
|
||||
scaleFactor = scaleFactor << 1;
|
||||
}
|
||||
return scaleFactor
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*宽高进行等比缩放宽高里面最小的比例先放进去
|
||||
然后再更据原图的缩放比去适配另一边*/
|
||||
|
||||
export class AtLeast implements BaseDownsampling {
|
||||
getName() {
|
||||
return "AtLeast"
|
||||
}
|
||||
|
||||
getScaleFactor(sourceWidth: number, sourceHeight: number, requestedWidth: number, requestedHeight: number): number {
|
||||
const widthPercentage = requestedWidth / sourceWidth;
|
||||
const heightPercentage = requestedHeight / sourceHeight;
|
||||
//返回宽度和高度比例中最大的值
|
||||
let outSize: Size = {
|
||||
width: round(Math.max(widthPercentage, heightPercentage) * sourceWidth),
|
||||
height:round(Math.max(widthPercentage, heightPercentage) * sourceHeight)
|
||||
}
|
||||
let scaleFactor = Math.max(1, highestOneBit(Math.max(sourceWidth / outSize.width, sourceHeight / outSize.height)))
|
||||
|
||||
return scaleFactor
|
||||
}
|
||||
}
|
||||
|
||||
/*请求尺寸大于实际尺寸不进行放大,按照原图展示*/
|
||||
|
||||
export class AtMost implements BaseDownsampling {
|
||||
getName() {
|
||||
return "AtMost"
|
||||
}
|
||||
|
||||
|
||||
getScaleFactor(sourceWidth: number, sourceHeight: number, requestedWidth: number, requestedHeight: number): number {
|
||||
const maxIntegerFactor = Math.ceil(Math.max(sourceHeight / requestedHeight, sourceWidth / requestedWidth));
|
||||
let lesserOrEqualSampleSize = Math.max(1, highestOneBit(maxIntegerFactor));
|
||||
let greaterOrEqualSampleSize = lesserOrEqualSampleSize
|
||||
if (lesserOrEqualSampleSize < maxIntegerFactor) {
|
||||
greaterOrEqualSampleSize = lesserOrEqualSampleSize <<= 1;
|
||||
}
|
||||
greaterOrEqualSampleSize = lesserOrEqualSampleSize << (lesserOrEqualSampleSize < maxIntegerFactor ? 1 : 0)
|
||||
|
||||
let outSize: Size = {
|
||||
width: round((1 / greaterOrEqualSampleSize) * sourceWidth),
|
||||
height:round((1 / greaterOrEqualSampleSize) * sourceHeight)
|
||||
}
|
||||
let scaleFactor = Math.max(1, highestOneBit(Math.min(sourceWidth / outSize.width, sourceHeight / outSize.height)))
|
||||
if ((scaleFactor < greaterOrEqualSampleSize)) {
|
||||
scaleFactor = scaleFactor << 1;
|
||||
}
|
||||
return scaleFactor
|
||||
}
|
||||
}
|
||||
|
||||
/*宽高进行等比缩放宽高里面最大的比例先放进去
|
||||
然后再更据原图的缩放比去适配另一边*/
|
||||
export class CenterInside implements BaseDownsampling {
|
||||
getName() {
|
||||
return "CenterInside"
|
||||
}
|
||||
getScaleFactor(sourceWidth: number, sourceHeight: number, requestedWidth: number, requestedHeight: number,
|
||||
downsampType: DownsampleStrategy
|
||||
): number {
|
||||
let outSize: Size = {
|
||||
width: round(Math.min(1, getScale(sourceWidth, sourceHeight, requestedWidth, requestedHeight, downsampType)) * sourceWidth),
|
||||
height:round(Math.min(1, getScale(sourceWidth, sourceHeight, requestedWidth, requestedHeight, downsampType)) * sourceHeight)
|
||||
}
|
||||
//将整型的缩放因子转换为2的次幂采样大小
|
||||
let scaleFactor = this.getSampleSizeType(sourceWidth, sourceHeight, requestedWidth, requestedHeight,
|
||||
downsampType) == SampleSizeRounding.QUALITY ?
|
||||
Math.max(1, highestOneBit(Math.max(sourceWidth / outSize.width, sourceHeight / outSize.height))) :
|
||||
Math.max(1, highestOneBit(Math.min(sourceWidth / outSize.width, sourceHeight / outSize.height)))
|
||||
if (this.getSampleSizeType(sourceWidth, sourceHeight, requestedWidth, requestedHeight, downsampType)
|
||||
== SampleSizeRounding.MEMORY && (scaleFactor < (1 / Math.min(1, getScale(sourceWidth, sourceHeight, requestedWidth, requestedHeight, downsampType))))) {
|
||||
scaleFactor = scaleFactor << 1;
|
||||
}
|
||||
return scaleFactor
|
||||
|
||||
}
|
||||
|
||||
getSampleSizeType(sourceWidth: number, sourceHeight: number, requestedWidth: number, requestedHeight: number,
|
||||
downsampType: DownsampleStrategy
|
||||
): SampleSizeRounding {
|
||||
//如果缩放因子为 1,表示没有缩放,优先选择质量
|
||||
if (Math.min(1, getScale(sourceWidth, sourceHeight, requestedWidth, requestedHeight, downsampType)) === 1) {
|
||||
return SampleSizeRounding.QUALITY
|
||||
}
|
||||
//否则,使用 FIL_CENTER 的 SampleSizeRounding 值
|
||||
return downsampType === DownsampleStrategy.CENTER_OUTSIDE_MEMORY?SampleSizeRounding.MEMORY:SampleSizeRounding.QUALITY
|
||||
}
|
||||
}
|
||||
|
||||
export enum DownsampleStrategy {
|
||||
//请求尺寸大于实际尺寸不进行放大
|
||||
AT_MOST,
|
||||
//两边自适应内存优先
|
||||
FIT_CENTER_MEMORY,
|
||||
//两边自适应质量优先
|
||||
FIT_CENTER_QUALITY,
|
||||
//按照宽高比的最大比进行适配内存优先
|
||||
CENTER_OUTSIDE_MEMORY,
|
||||
//按照宽高比的最大比进行适配质量优先
|
||||
CENTER_OUTSIDE_QUALITY,
|
||||
//宽高进行等比缩放宽高里面最小的比例先放进去,然后再根据原图的缩放比去适配
|
||||
AT_LEAST,
|
||||
//不进行降采样
|
||||
NONE,
|
||||
}
|
|
@ -1,58 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { DownsampleStrategy } from './DownsampleStartegy';
|
||||
|
||||
export enum SampleSizeRounding {
|
||||
/**
|
||||
* Prefer to round the sample size up so that the image is downsampled to smaller than the
|
||||
* requested size to use less memory.
|
||||
*/
|
||||
//(内存优先)
|
||||
MEMORY,
|
||||
/**
|
||||
* Prefer to round the sample size down so that the image is downsampled to larger than the
|
||||
* requested size to maintain quality at the expense of extra memory usage.
|
||||
*/
|
||||
//(质量优先)
|
||||
QUALITY
|
||||
}
|
||||
//找出给定整数 i 中最高位的1(即最左边的1)所代表的值
|
||||
export function highestOneBit(i: number): number {
|
||||
i |= (i >> 1);
|
||||
i |= (i >> 2);
|
||||
i |= (i >> 4);
|
||||
i |= (i >> 8);
|
||||
i |= (i >> 16);
|
||||
return i - (i >>> 1);
|
||||
}
|
||||
|
||||
|
||||
export function getScale(sourceWidth: number, sourceHeight: number, requestedWidth: number, requestedHeight: number,
|
||||
downsampType: DownsampleStrategy
|
||||
): number {
|
||||
if (downsampType === DownsampleStrategy.FIT_CENTER_MEMORY) {
|
||||
const widthPercentage = requestedWidth / sourceWidth
|
||||
const heightPercentage = requestedHeight / sourceHeight
|
||||
return Math.min(widthPercentage, heightPercentage)
|
||||
} else {
|
||||
const maxIntegerFactor = Math.max(sourceHeight / requestedHeight, sourceWidth / requestedWidth);
|
||||
return maxIntegerFactor === 0 ? 1 : 1 / highestOneBit(maxIntegerFactor);
|
||||
|
||||
}
|
||||
}
|
||||
//四舍五入
|
||||
export function round(value: number): number {
|
||||
return Math.floor(value + 0.5);
|
||||
}
|
|
@ -1,73 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import {
|
||||
AtMost,
|
||||
CenterInside,
|
||||
AtLeast,
|
||||
DownsampleStrategy,
|
||||
FitCenter,
|
||||
} from './DownsampleStartegy';
|
||||
export class Downsampler {
|
||||
calculateScaling(
|
||||
typeValue: string,
|
||||
sourceWidth: number, //原始宽高
|
||||
sourceHeight: number, //原始宽高
|
||||
requestWidth: number, //请求宽高
|
||||
requestHeight: number, //请求宽高
|
||||
downsampType: DownsampleStrategy,
|
||||
): Size {
|
||||
|
||||
if (sourceHeight <= 0 || sourceWidth <= 0) {
|
||||
throw new Error(`Invalid width and height, sourceHeight:${sourceHeight}+ sourceWidth:${sourceWidth}`)
|
||||
}
|
||||
let downsampler = this.getDownsampler(downsampType);
|
||||
let scaleFactor: number =
|
||||
downsampler.getScaleFactor(sourceWidth, sourceHeight, requestWidth, requestHeight, downsampType);//缩放比
|
||||
//基于上一步得出的采样大小,根据不同的图片类型,计算采样后的图片尺寸
|
||||
if (typeValue === "png") {
|
||||
return {
|
||||
width: Math.floor(sourceWidth / scaleFactor),
|
||||
height: Math.floor(sourceHeight / scaleFactor)
|
||||
}
|
||||
} else if (typeValue === "webp") {
|
||||
return {
|
||||
width: Math.round(sourceWidth / scaleFactor),
|
||||
height: Math.round(sourceHeight / scaleFactor)
|
||||
}
|
||||
} else {
|
||||
return {
|
||||
width: sourceWidth / scaleFactor,
|
||||
height: sourceHeight / scaleFactor
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
getDownsampler(downsampType: DownsampleStrategy) {
|
||||
switch (downsampType) {
|
||||
case DownsampleStrategy.FIT_CENTER_MEMORY:
|
||||
case DownsampleStrategy.FIT_CENTER_QUALITY:
|
||||
return new FitCenter();
|
||||
case DownsampleStrategy.AT_MOST:
|
||||
return new AtMost();
|
||||
case DownsampleStrategy.CENTER_OUTSIDE_MEMORY:
|
||||
case DownsampleStrategy.CENTER_OUTSIDE_QUALITY:
|
||||
return new CenterInside();
|
||||
case DownsampleStrategy.AT_LEAST:
|
||||
return new AtLeast();
|
||||
default:
|
||||
throw new Error('Unsupported downsampling strategy');
|
||||
}
|
||||
}
|
||||
}
|
|
@ -17,7 +17,6 @@ import { ImageKnifeOption } from '../model/ImageKnifeOption';
|
|||
import { IEngineKey } from './IEngineKey';
|
||||
import { PixelMapTransformation } from '../transform/PixelMapTransformation';
|
||||
import { ImageKnifeRequestSource } from '../model/ImageKnifeData';
|
||||
import { DownsampleStrategy } from '../downsampling/DownsampleStartegy';
|
||||
|
||||
@Sendable
|
||||
export class DefaultEngineKey implements IEngineKey {
|
||||
|
@ -32,9 +31,6 @@ export class DefaultEngineKey implements IEngineKey {
|
|||
if (imageKnifeOption.transformation) {
|
||||
key += "transformation=" + this.getTransformation(imageKnifeOption.transformation) + ";"
|
||||
}
|
||||
if ((imageKnifeOption.downsampleOf !== DownsampleStrategy.NONE && imageKnifeOption.downsampleOf !== undefined)) {
|
||||
key += "downsampleOf" + imageKnifeOption.downsampleOf +"width="+width+"height="+ height
|
||||
}
|
||||
}
|
||||
return key
|
||||
}
|
||||
|
|
|
@ -18,15 +18,55 @@ import { IEngineKey } from '../key/IEngineKey'
|
|||
import { PixelMapTransformation } from '../transform/PixelMapTransformation'
|
||||
import common from '@ohos.app.ability.common';
|
||||
import { Size } from '@kit.ArkUI'
|
||||
import { DownsampleStrategy } from '../downsampling/DownsampleStartegy'
|
||||
|
||||
export interface ImageKnifeData {
|
||||
source: PixelMap | string,
|
||||
imageWidth: number,
|
||||
source: PixelMap | string, // url
|
||||
imageWidth: number, // 原始宽高大小
|
||||
imageHeight: number,
|
||||
bufSize?: number, // 图片的字节数
|
||||
type?:string,
|
||||
imageAnimator?: Array<ImageFrameInfo>
|
||||
frameCount ?: number // 帧
|
||||
decodeImages?: Array<DecodeImageInfo> //Image组件或者ImageAnimator组件可以加载一张或者多张
|
||||
timeInfo?: TimeInfo // 加载图片的各个时间点
|
||||
errorInfo?: ErrorInfo // 错误
|
||||
}
|
||||
|
||||
/**
|
||||
* 解码后的图片的size
|
||||
*/
|
||||
export interface DecodeImageInfo {
|
||||
contentWidth ?: number // 解码后宽高
|
||||
contentHeight?: number
|
||||
contentSize ?: number // 大小
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载的错误信息
|
||||
*/
|
||||
export interface ErrorInfo {
|
||||
phase: string, //图片加载阶段信息,如:网络加载阶段,缓存获取阶段及其解码阶段等
|
||||
code: number,
|
||||
httpCode?: number
|
||||
}
|
||||
|
||||
/**
|
||||
* load检查时间点
|
||||
*/
|
||||
export interface TimeInfo {
|
||||
requestStartTime?: number,
|
||||
requestEndTime?: number,
|
||||
requestCancelTime?: number,
|
||||
memoryCheckStartTime?: number,
|
||||
memoryCheckEndTime?: number,
|
||||
diskCheckStartTime?: number,
|
||||
diskCheckEndTime?: number,
|
||||
netRequestStartTime?: number,
|
||||
netRequestEndTime?: number,
|
||||
decodeStartTime?: number,
|
||||
decodeEndTime?: number,
|
||||
}
|
||||
|
||||
/**
|
||||
* onComplete成功回调
|
||||
*/
|
||||
|
@ -79,7 +119,8 @@ export interface RequestJobResult {
|
|||
size?:Size,
|
||||
type?: string,
|
||||
pixelMapList?:Array<PixelMap>,
|
||||
delayList?: Array<number>
|
||||
delayList?: Array<number>,
|
||||
imageKnifeData?: ImageKnifeData,
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -92,7 +133,7 @@ export interface RequestJobRequest {
|
|||
allHeaders: Map<string, Object>,
|
||||
componentWidth: number,
|
||||
componentHeight: number,
|
||||
customGetImage?: (context: Context, src: string | PixelMap | Resource) => Promise<ArrayBuffer | undefined>,
|
||||
customGetImage?: (context: Context, src: string | PixelMap | Resource,headers?: Record<string,Object>) => Promise<ArrayBuffer | undefined>,
|
||||
onlyRetrieveFromCache?: boolean
|
||||
requestSource: ImageKnifeRequestSource
|
||||
transformation?: PixelMapTransformation
|
||||
|
@ -104,9 +145,6 @@ export interface RequestJobRequest {
|
|||
fileCacheFolder: string,
|
||||
isAnimator?: boolean,
|
||||
moduleName?:string,
|
||||
resName?: string,
|
||||
targetWidth: number
|
||||
targetHeight: number
|
||||
downsampType: DownsampleStrategy
|
||||
resName?: string
|
||||
}
|
||||
|
||||
|
|
|
@ -17,101 +17,52 @@ import common from '@ohos.app.ability.common'
|
|||
import { CacheStrategy, ImageKnifeData,EventImage } from './ImageKnifeData';
|
||||
import { PixelMapTransformation } from '../transform/PixelMapTransformation';
|
||||
import { drawing } from '@kit.ArkGraphics2D';
|
||||
import { DownsampleStrategy } from '../downsampling/DownsampleStartegy';
|
||||
import { ImageKnifeRequest } from './ImageKnifeRequest';
|
||||
|
||||
export interface HeaderOptions {
|
||||
key: string;
|
||||
value: Object;
|
||||
}
|
||||
interface AnimatorType {
|
||||
state?: AnimationStatus
|
||||
iterations?: number
|
||||
reverse?: boolean
|
||||
onStart?:()=>void
|
||||
onFinish?:()=>void
|
||||
onPause?:()=>void
|
||||
onCancel?:()=>void
|
||||
onRepeat?:()=>void
|
||||
}
|
||||
@ObservedV2
|
||||
|
||||
@Observed
|
||||
export class AnimatorOption {
|
||||
@Trace
|
||||
@Track
|
||||
state?: AnimationStatus = AnimationStatus.Running
|
||||
@Trace
|
||||
@Track
|
||||
iterations?: number = -1
|
||||
@Trace
|
||||
@Track
|
||||
reverse?: boolean = false
|
||||
@Trace
|
||||
@Track
|
||||
onStart?:()=>void
|
||||
@Trace
|
||||
@Track
|
||||
onFinish?:()=>void
|
||||
@Trace
|
||||
@Track
|
||||
onPause?:()=>void
|
||||
@Trace
|
||||
@Track
|
||||
onCancel?:()=>void
|
||||
@Trace
|
||||
@Track
|
||||
onRepeat?:()=>void
|
||||
constructor(option?:AnimatorType) {
|
||||
this.state = option?.state
|
||||
this.iterations = option?.iterations
|
||||
this.reverse = option?.reverse
|
||||
this.onStart = option?.onStart
|
||||
this.onFinish = option?.onFinish
|
||||
this.onPause = option?.onPause
|
||||
this.onCancel = option?.onCancel
|
||||
this.onRepeat = option?.onRepeat
|
||||
}
|
||||
}
|
||||
interface ImageOption {
|
||||
// 主图资源
|
||||
loadSrc: string | PixelMap | Resource
|
||||
// 占位图
|
||||
placeholderSrc?: string | PixelMap | Resource
|
||||
// 失败占位图
|
||||
errorholderSrc?: string | PixelMap | Resource
|
||||
headerOption?: Array<HeaderOptions>;
|
||||
// 自定义缓存关键字
|
||||
signature?: string
|
||||
// 主图填充效果
|
||||
objectFit?: ImageFit
|
||||
// 占位图填充效果
|
||||
placeholderObjectFit?: ImageFit
|
||||
// 错误图填充效果
|
||||
errorholderObjectFit?: ImageFit
|
||||
customGetImage?: (context: Context, src: string | PixelMap | Resource) => Promise<ArrayBuffer | undefined>
|
||||
border?: BorderOptions
|
||||
// 缓存策略
|
||||
writeCacheStrategy?: CacheStrategy
|
||||
// 仅使用缓存加载数据
|
||||
onlyRetrieveFromCache?: boolean;
|
||||
priority?: taskpool.Priority
|
||||
context?: common.UIAbilityContext;
|
||||
progressListener?: (progress: number) => void;
|
||||
transformation?: PixelMapTransformation
|
||||
onLoadListener?: OnLoadCallBack | undefined;
|
||||
onComplete?:(event:EventImage | undefined) => void
|
||||
drawingColorFilter?: ColorFilter | drawing.ColorFilter
|
||||
downsampleOf?: DownsampleStrategy
|
||||
}
|
||||
@ObservedV2
|
||||
|
||||
@Observed
|
||||
export class ImageKnifeOption {
|
||||
// 主图资源
|
||||
@Trace loadSrc: string | PixelMap | Resource = "";
|
||||
loadSrc: string | PixelMap | Resource = "";
|
||||
// 占位图
|
||||
placeholderSrc?: string | PixelMap | Resource;
|
||||
// 失败占位图
|
||||
errorholderSrc?: string | PixelMap | Resource;
|
||||
headerOption?: Array<HeaderOptions>;
|
||||
// 自定义缓存关键字
|
||||
@Trace signature?: string;
|
||||
signature?: string;
|
||||
// 主图填充效果
|
||||
@Trace objectFit?: ImageFit
|
||||
objectFit?: ImageFit
|
||||
// 占位图填充效果
|
||||
placeholderObjectFit?: ImageFit
|
||||
// 错误图填充效果
|
||||
errorholderObjectFit?: ImageFit
|
||||
customGetImage?: (context: Context, src: string | PixelMap | Resource) => Promise<ArrayBuffer | undefined>
|
||||
@Trace border?: BorderOptions
|
||||
customGetImage?: (context: Context, src: string | PixelMap | Resource,headers?: Record<string,Object>) => Promise<ArrayBuffer | undefined>
|
||||
border?: BorderOptions
|
||||
// 缓存策略
|
||||
writeCacheStrategy?: CacheStrategy
|
||||
// 仅使用缓存加载数据
|
||||
|
@ -119,33 +70,12 @@ export class ImageKnifeOption {
|
|||
priority?: taskpool.Priority = taskpool.Priority.LOW
|
||||
context?: common.UIAbilityContext;
|
||||
progressListener?: (progress: number) => void;
|
||||
@Trace transformation?: PixelMapTransformation
|
||||
transformation?: PixelMapTransformation
|
||||
onLoadListener?: OnLoadCallBack | undefined;
|
||||
onComplete?:(event:EventImage | undefined) => void
|
||||
drawingColorFilter?: ColorFilter | drawing.ColorFilter
|
||||
// 下采样
|
||||
@Trace downsampleOf: DownsampleStrategy = DownsampleStrategy.NONE
|
||||
constructor(option?:ImageOption) {
|
||||
this.loadSrc = option?.loadSrc == undefined ? "" : option?.loadSrc
|
||||
this.placeholderSrc = option?.placeholderSrc
|
||||
this.errorholderSrc = option?.errorholderSrc
|
||||
this.headerOption = option?.headerOption
|
||||
this.signature = option?.signature
|
||||
this.objectFit = option?.objectFit
|
||||
this.placeholderObjectFit = option?.placeholderObjectFit
|
||||
this.errorholderObjectFit = option?.errorholderObjectFit
|
||||
this.customGetImage = option?.customGetImage
|
||||
this.border = option?.border
|
||||
this.writeCacheStrategy = option?.writeCacheStrategy
|
||||
this.onlyRetrieveFromCache = option?.onlyRetrieveFromCache
|
||||
this.priority = option?.priority
|
||||
this.context = option?.context
|
||||
this.progressListener = option?.progressListener
|
||||
this.transformation = option?.transformation
|
||||
this.onLoadListener = option?.onLoadListener
|
||||
this.onComplete = option?.onComplete
|
||||
this.drawingColorFilter = option?.drawingColorFilter
|
||||
this.downsampleOf = option?.downsampleOf==undefined?DownsampleStrategy.NONE:option?.downsampleOf
|
||||
constructor() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -154,13 +84,13 @@ export class ImageKnifeOption {
|
|||
*/
|
||||
export interface OnLoadCallBack {
|
||||
// 请求开始
|
||||
onLoadStart?: () => void;
|
||||
onLoadStart?: (request?: ImageKnifeRequest) => void;
|
||||
|
||||
// 请求成功
|
||||
onLoadSuccess?: (data: string | PixelMap | undefined, imageKnifeData: ImageKnifeData) => void;
|
||||
onLoadSuccess?: (data: string | PixelMap | undefined, imageKnifeData: ImageKnifeData, request?: ImageKnifeRequest) => void;
|
||||
|
||||
// 请求结束
|
||||
onLoadFailed?: (err: string) => void;
|
||||
onLoadFailed?: (err: string, request?: ImageKnifeRequest) => void;
|
||||
// 请求取消
|
||||
onLoadCancel?: (reason: string) => void;
|
||||
onLoadCancel?: (reason: string, request?: ImageKnifeRequest) => void;
|
||||
}
|
|
@ -14,8 +14,7 @@
|
|||
*/
|
||||
import { ImageKnifeOption } from './ImageKnifeOption';
|
||||
import common from '@ohos.app.ability.common';
|
||||
import { ImageKnifeRequestSource } from './ImageKnifeData';
|
||||
import { DownsampleStrategy } from '../downsampling/DownsampleStartegy';
|
||||
import { ImageKnifeData, ImageKnifeRequestSource } from './ImageKnifeData';
|
||||
|
||||
|
||||
export class ImageKnifeRequest {
|
||||
|
@ -28,22 +27,19 @@ export class ImageKnifeRequest {
|
|||
ImageKnifeRequestCallback: ImageKnifeRequestCallback
|
||||
componentVersion: number = 0
|
||||
headers: Map<string,Object> = new Map<string,Object>()
|
||||
downsampType?: DownsampleStrategy
|
||||
private imageCallBackData: ImageKnifeData | undefined = undefined;
|
||||
constructor(option: ImageKnifeOption,
|
||||
uIAbilityContext: common.UIAbilityContext,
|
||||
width: number,
|
||||
height: number,
|
||||
version: number,
|
||||
ImageKnifeRequestCallback: ImageKnifeRequestCallback,
|
||||
downsampType?: DownsampleStrategy
|
||||
) {
|
||||
ImageKnifeRequestCallback: ImageKnifeRequestCallback) {
|
||||
this.imageKnifeOption = option
|
||||
this.context = uIAbilityContext
|
||||
this.componentWidth = width
|
||||
this.componentHeight = height
|
||||
this.componentVersion = version
|
||||
this.ImageKnifeRequestCallback = ImageKnifeRequestCallback
|
||||
this.downsampType = downsampType
|
||||
}
|
||||
// RequestOption调用header对于的方法
|
||||
addHeader(key: string, value: Object) {
|
||||
|
@ -58,6 +54,14 @@ export class ImageKnifeRequest {
|
|||
}
|
||||
})
|
||||
}
|
||||
|
||||
setImageKnifeData(data: ImageKnifeData) {
|
||||
this.imageCallBackData = data;
|
||||
}
|
||||
|
||||
getImageKnifeData(): ImageKnifeData | undefined {
|
||||
return this.imageCallBackData
|
||||
}
|
||||
}
|
||||
|
||||
export enum ImageKnifeRequestState {
|
||||
|
@ -69,5 +73,5 @@ export enum ImageKnifeRequestState {
|
|||
|
||||
|
||||
export interface ImageKnifeRequestCallback {
|
||||
showPixelMap: (version: number, pixelMap: PixelMap | string , requestSource: ImageKnifeRequestSource,imageAnimator?: Array<ImageFrameInfo>) => void;
|
||||
showPixelMap: (version: number, pixelMap: PixelMap | string ,size: Size, requestSource: ImageKnifeRequestSource,imageAnimator?: Array<ImageFrameInfo>) => void;
|
||||
}
|
||||
|
|
|
@ -18,9 +18,9 @@ import Queue from '@ohos.util.Queue';
|
|||
import { taskpool,Stack } from '@kit.ArkTS';
|
||||
|
||||
export class DefaultJobQueue implements IJobQueue {
|
||||
highQueue: Stack<ImageKnifeRequest> = new Stack();
|
||||
normalQueue: Stack<ImageKnifeRequest> = new Stack();
|
||||
lowQueue: Stack<ImageKnifeRequest> = new Stack();
|
||||
highQueue: Queue<ImageKnifeRequest> = new Queue();
|
||||
normalQueue: Queue<ImageKnifeRequest> = new Queue();
|
||||
lowQueue: Queue<ImageKnifeRequest> = new Queue();
|
||||
|
||||
getQueueLength(): number {
|
||||
return this.highQueue.length + this.normalQueue.length + this.lowQueue.length
|
||||
|
@ -28,11 +28,11 @@ export class DefaultJobQueue implements IJobQueue {
|
|||
|
||||
add(request: ImageKnifeRequest): void {
|
||||
if (request.imageKnifeOption.priority === undefined || request.imageKnifeOption.priority === taskpool.Priority.MEDIUM) {
|
||||
this.normalQueue.push(request)
|
||||
this.normalQueue.add(request)
|
||||
} else if (request.imageKnifeOption.priority === taskpool.Priority.HIGH) {
|
||||
this.highQueue.push(request)
|
||||
this.highQueue.add(request)
|
||||
} else {
|
||||
this.lowQueue.push(request)
|
||||
this.lowQueue.add(request)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue