forked from floraachy/ImageKnife
ddd #1
|
@ -0,0 +1,3 @@
|
||||||
|
[submodule "gpu_transform/src/main/cpp/boundscheck/third_party_bounds_checking_function"]
|
||||||
|
path = gpu_transform/src/main/cpp/boundscheck/third_party_bounds_checking_function
|
||||||
|
url = https://gitee.com/openharmony/third_party_bounds_checking_function.git
|
31
CHANGELOG.md
31
CHANGELOG.md
|
@ -1,3 +1,34 @@
|
||||||
|
## 3.1.1-rc.1
|
||||||
|
- Photo reduction sampling
|
||||||
|
## 3.1.1-rc.0
|
||||||
|
- 重构代码:抽取ImageKnifeDispatcher子线程requestJob相关代码到ImageKnifeLoader中,降低函数复杂度
|
||||||
|
## 3.1.0
|
||||||
|
- 部分静态webp图片有delay属性导致识别成动图,改用getFrameCount识别
|
||||||
|
- 修复加载错误图后未去请求排队队列中的请求
|
||||||
|
- 子线程本地Resource参数类型转换成number
|
||||||
|
- 修改使用hilog记录日志,默认打开debug级别的日志
|
||||||
|
- file格式图片,fd同步close
|
||||||
|
- 解码pixelMap默认不可编辑,图形变化可编辑
|
||||||
|
- 修改网络请求超时设置
|
||||||
|
|
||||||
|
## 3.1.0-rc.2
|
||||||
|
- 修复宽高不等svg图片显示有毛边
|
||||||
|
|
||||||
|
## 3.1.0-rc.1
|
||||||
|
- ImageKnifeAnimatorComponent新增开始、结束、暂停的回调事件
|
||||||
|
- 文件缓存数量负数和超过INT最大值时默认为INT最大值
|
||||||
|
|
||||||
|
## 3.1.0-rc.0
|
||||||
|
- ComponentV2装饰器适配
|
||||||
|
- imageKnifeOption={...}用法改为new ImageKnifeOption({...})
|
||||||
|
- animatorOption={...}用法改为new AnimatorOption({...})
|
||||||
|
|
||||||
|
## 3.0.1
|
||||||
|
- 修复animatorOption属性设置初始化值失效
|
||||||
|
- 网络请求code为206、204时返回arraybuffer
|
||||||
|
- ImageKnifeComponent显示非必要文件缓存初始化
|
||||||
|
- 修复webp静态图无法设置图形变换
|
||||||
|
|
||||||
## 3.0.1-rc.2
|
## 3.0.1-rc.2
|
||||||
- 修复自定义下载失败无失败回调
|
- 修复自定义下载失败无失败回调
|
||||||
- 增加全局配置自定义下载接口
|
- 增加全局配置自定义下载接口
|
||||||
|
|
17
OAT.xml
17
OAT.xml
|
@ -1,4 +1,21 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!-- Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
|
||||||
|
This is the configuration file template for OpenHarmony OSS Audit Tool, please copy it to your project root dir and modify it refer to OpenHarmony/tools_oat/README.
|
||||||
|
|
||||||
|
-->
|
||||||
<configuration>
|
<configuration>
|
||||||
<oatconfig>
|
<oatconfig>
|
||||||
<filefilterlist>
|
<filefilterlist>
|
||||||
|
|
|
@ -2,9 +2,9 @@
|
||||||
{
|
{
|
||||||
"Name": "glide",
|
"Name": "glide",
|
||||||
"License": "Apache License 2.0",
|
"License": "Apache License 2.0",
|
||||||
"License File": "https://github.com/bumptech/glide/blob/master/LICENSE",
|
"License File": "LICENSE",
|
||||||
"Version Number": "4.13.1",
|
"Version Number": "4.13.1",
|
||||||
"Owner" : "bumptech",
|
"Owner" : "xiafeng@huawei.com",
|
||||||
"Upstream URL": "https://github.com/bumptech/glide",
|
"Upstream URL": "https://github.com/bumptech/glide",
|
||||||
"Description": "An image loading and caching library focused on smooth scrolling"
|
"Description": "An image loading and caching library focused on smooth scrolling"
|
||||||
},
|
},
|
||||||
|
@ -12,9 +12,9 @@
|
||||||
{
|
{
|
||||||
"Name": "glide-transformations",
|
"Name": "glide-transformations",
|
||||||
"License": "Apache License 2.0",
|
"License": "Apache License 2.0",
|
||||||
"License File": "https://github.com/wasabeef/glide-transformations/blob/main/LICENSE",
|
"License File": "LICENSE",
|
||||||
"Version Number": "4.3.0",
|
"Version Number": "4.3.0",
|
||||||
"Owner" : "wasabeef",
|
"Owner" : "xiafeng@huawei.com",
|
||||||
"Upstream URL": "https://github.com/wasabeef/glide-transformations",
|
"Upstream URL": "https://github.com/wasabeef/glide-transformations",
|
||||||
"Description": " An transformation library providing a variety of image transformations for Glide. "
|
"Description": " An transformation library providing a variety of image transformations for Glide. "
|
||||||
},
|
},
|
||||||
|
@ -22,9 +22,9 @@
|
||||||
{
|
{
|
||||||
"Name": "fresco",
|
"Name": "fresco",
|
||||||
"License": "MIT License",
|
"License": "MIT License",
|
||||||
"License File": "https://github.com/facebook/fresco/blob/main/LICENSE",
|
"License File": "LICENSE",
|
||||||
"Version Number": "2.6.0",
|
"Version Number": "2.6.0",
|
||||||
"Owner" : "facebook",
|
"Owner" : "xiafeng@huawei.com",
|
||||||
"Upstream URL": "https://github.com/facebook/fresco",
|
"Upstream URL": "https://github.com/facebook/fresco",
|
||||||
"Description": " An library for managing images and the memory they use. "
|
"Description": " An library for managing images and the memory they use. "
|
||||||
},
|
},
|
||||||
|
@ -32,9 +32,9 @@
|
||||||
{
|
{
|
||||||
"Name": "UPNG.js",
|
"Name": "UPNG.js",
|
||||||
"License": "MIT License",
|
"License": "MIT License",
|
||||||
"License File": "https://github.com/photopea/UPNG.js/blob/master/LICENSE",
|
"License File": "LICENSE",
|
||||||
"Version Number": "1.0.0",
|
"Version Number": "1.0.0",
|
||||||
"Owner" : "photopea",
|
"Owner" : "xiafeng@huawei.com",
|
||||||
"Upstream URL": "https://github.com/photopea/UPNG.js",
|
"Upstream URL": "https://github.com/photopea/UPNG.js",
|
||||||
"Description": " Fast and advanced PNG (APNG) decoder and encoder (lossy / lossless) "
|
"Description": " Fast and advanced PNG (APNG) decoder and encoder (lossy / lossless) "
|
||||||
},
|
},
|
||||||
|
@ -42,9 +42,9 @@
|
||||||
{
|
{
|
||||||
"Name": "Luban",
|
"Name": "Luban",
|
||||||
"License": "Apache License 2.0",
|
"License": "Apache License 2.0",
|
||||||
"License File": "https://github.com/Curzibn/Luban/blob/master/LICENSE",
|
"License File": "LICENSE",
|
||||||
"Version Number": "1.1.8",
|
"Version Number": "1.1.8",
|
||||||
"Owner" : " Curzibn",
|
"Owner" : " xiafeng@huawei.com",
|
||||||
"Upstream URL": "https://github.com/Curzibn/Luban",
|
"Upstream URL": "https://github.com/Curzibn/Luban",
|
||||||
"Description": " Luban(鲁班)—Image compression with efficiency very close to WeChat Moments/可能是最接近微信朋友圈的图片压缩算法 "
|
"Description": " Luban(鲁班)—Image compression with efficiency very close to WeChat Moments/可能是最接近微信朋友圈的图片压缩算法 "
|
||||||
},
|
},
|
||||||
|
@ -54,16 +54,16 @@
|
||||||
"License": "Apache License 2.0",
|
"License": "Apache License 2.0",
|
||||||
"License File": "https://github.com/Yalantis/uCrop/blob/develop/README.md",
|
"License File": "https://github.com/Yalantis/uCrop/blob/develop/README.md",
|
||||||
"Version Number": "2.2.8",
|
"Version Number": "2.2.8",
|
||||||
"Owner" : " Yalantis",
|
"Owner" : " xiafeng@huawei.com",
|
||||||
"Upstream URL": "https://github.com/Yalantis/uCrop",
|
"Upstream URL": "https://github.com/Yalantis/uCrop",
|
||||||
"Description": " Image Cropping Library "
|
"Description": " Image Cropping Library "
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "js-spark-md5",
|
"Name": "js-spark-md5",
|
||||||
"License": "MIT",
|
"License": "MIT",
|
||||||
"License File": "https://github.com/satazor/js-spark-md5/blob/master/LICENSE",
|
"License File": "LICENSE",
|
||||||
"Version Number": "v3.0.2",
|
"Version Number": "v3.0.2",
|
||||||
"Owner" : "satazor",
|
"Owner" : "xiafeng@huawei.com",
|
||||||
"Upstream URL": "https://github.com/satazor/js-spark-md5",
|
"Upstream URL": "https://github.com/satazor/js-spark-md5",
|
||||||
"Description": "Lightning fast normal and incremental md5 for javascript"
|
"Description": "Lightning fast normal and incremental md5 for javascript"
|
||||||
}
|
}
|
||||||
|
|
367
README.md
367
README.md
|
@ -1,229 +1,228 @@
|
||||||
# ImageKnife
|
# ImageKnife
|
||||||
|
|
||||||
**专门为OpenHarmony打造的一款图像加载缓存库,致力于更高效、更轻便、更简单。**
|
ImageKnife is a specially crafted image loading and caching library for OpenHarmony, optimized for efficiency, lightness, and simplicity.
|
||||||
|
|
||||||
## 简介
|
## Introduction
|
||||||
|
|
||||||
本项目参考开源库 [Glide](https://github.com/bumptech/glide) 进行OpenHarmony的自研版本:
|
This project is a self-developed version for OpenHarmony, inspired by the open-source [Glide](https://github.com/bumptech/glide) library. It sports the following features:
|
||||||
|
|
||||||
- 支持自定义内存缓存策略,支持设置内存缓存的大小(默认LRU策略)。
|
- Customizable memory cache strategy with adjustable cache size (default LRU)
|
||||||
- 支持磁盘二级缓存,对于下载图片会保存一份至磁盘当中。
|
- Disk L2 cache for downloaded images
|
||||||
- 支持自定义实现图片获取/网络下载
|
- Custom implementation for image acquisition and network downloading
|
||||||
- 支持监听网络下载回调进度
|
- Listening for progress of network downloads through callbacks
|
||||||
- 继承Image的能力,支持option传入border,设置边框,圆角
|
- Image options for borders and rounded corners
|
||||||
- 继承Image的能力,支持option传入objectFit设置图片缩放,包括objectFit为auto时根据图片自适应高度
|
- Image scaling with **objectFit**, including auto-adapting height
|
||||||
- 支持通过设置transform缩放图片
|
- Image scaling through transformation
|
||||||
- 并发请求数量,支持请求排队队列的优先级
|
- Concurrent request management with priority queuing
|
||||||
- 支持生命周期已销毁的图片,不再发起请求
|
- No requests made for images whose lifecycle has been destroyed
|
||||||
- 自定义缓存key
|
- Custom cache keys
|
||||||
- 自定义http网络请求头
|
- Custom HTTP request headers
|
||||||
- 支持writeCacheStrategy控制缓存的存入策略(只存入内存或文件缓存)
|
- **writeCacheStrategy** for controlling cache storage (memory or file)
|
||||||
- 支持preLoadCache预加载图片
|
- Preloading images with **preLoadCache**
|
||||||
- 支持onlyRetrieveFromCache仅用缓存加载
|
- Loading images exclusively from cache with **onlyRetrieveFromCache**
|
||||||
- 支持使用一个或多个图片变换,如模糊,高亮等
|
- Support for image transformations such as blurring and highlighting
|
||||||
|
|
||||||
待实现特性
|
Planned features:
|
||||||
|
|
||||||
- gif/webp动图显示与控制
|
- Memory downsampling optimization to save memory usage
|
||||||
- 内存降采样优化,节约内存的占用
|
- Support for custom image decoding
|
||||||
- 支持自定义图片解码
|
|
||||||
|
|
||||||
注意:3.x版本相对2.x版本做了重大的重构,主要体现在:
|
Note: The 3.x version has been significantly restructured from the 2.x version, mainly in the following aspects:
|
||||||
|
|
||||||
- 使用Image组件代替Canvas组件渲染
|
- Use of the **Image** component instead of the **Canvas** component for rendering
|
||||||
- 重构Dispatch分发逻辑,支持控制并发请求数,支持请求排队队列的优先级
|
- Refactored dispatch logic to control the number of concurrent requests and support priority in request queuing
|
||||||
- 支持通过initMemoryCache自定义策略内存缓存策略和大小
|
- Support for custom memory cache strategies and sizes through **initMemoryCache**
|
||||||
- 支持option自定义实现图片获取/网络下载
|
- Support for custom implementation of image acquisition/network downloading through options
|
||||||
|
|
||||||
因此API及能力上,目前有部分差异,主要体现在:
|
Therefore, there are some differences in APIs and capabilities, which mainly include the following:
|
||||||
|
|
||||||
- 不支持drawLifeCycle接口,通过canvas自会图片
|
- The **drawLifeCycle** API is not supported; images are drawn manually through the canvas.
|
||||||
- mainScaleType,border等参数,新版本与系统Image保持一致
|
- In the new version, parameters such as **mainScaleType** and **border** are consistent with the system **Image** component.
|
||||||
- gif/webp动图播放与控制
|
- GIF/WebP animation playback and control (implemented by **ImageAnimator**).
|
||||||
- 抗锯齿相关参数
|
- Anti-aliasing related parameters.
|
||||||
|
|
||||||
## 下载安装
|
## How to Install
|
||||||
|
|
||||||
```
|
```
|
||||||
ohpm install @ohos/imageknife
|
ohpm install @ohos/imageknife
|
||||||
|
|
||||||
// 如果需要用文件缓存,需要提前初始化文件缓存
|
// If file caching is required, initialize the file cache in advance.
|
||||||
await ImageKnife.getInstance().initFileCache(context, 256, 256 * 1024 * 1024)
|
await ImageKnife.getInstance().initFileCache(context, 256, 256 * 1024 * 1024)
|
||||||
```
|
```
|
||||||
|
|
||||||
## 使用说明
|
## How to Use
|
||||||
|
|
||||||
#### 1.显示本地资源图片
|
#### 1. Displaying a Local Resource Image
|
||||||
|
|
||||||
```
|
```
|
||||||
ImageKnifeComponent({
|
ImageKnifeComponent({
|
||||||
ImageKnifeOption: {
|
ImageKnifeOption: new ImageKnifeOption({
|
||||||
loadSrc: $r("app.media.app_icon"),
|
loadSrc: $r("app.media.app_icon"),
|
||||||
placeholderSrc: $r("app.media.loading"),
|
placeholderSrc: $r("app.media.loading"),
|
||||||
errorholderSrc: $r("app.media.app_icon"),
|
errorholderSrc: $r("app.media.app_icon"),
|
||||||
objectFit: ImageFit.Auto
|
objectFit: ImageFit.Auto
|
||||||
}
|
})
|
||||||
}).width(100).height(100)
|
}).width(100).height(100)
|
||||||
```
|
```
|
||||||
|
|
||||||
#### 2.显示本地context files下文件
|
#### 2. Displaying a File from Local Context Files
|
||||||
|
|
||||||
```
|
```
|
||||||
ImageKnifeComponent({
|
ImageKnifeComponent({
|
||||||
ImageKnifeOption: {
|
ImageKnifeOption: new ImageKnifeOption({
|
||||||
loadSrc: this.localFile,
|
loadSrc: this.localFile,
|
||||||
placeholderSrc: $r("app.media.loading"),
|
placeholderSrc: $r("app.media.loading"),
|
||||||
errorholderSrc: $r("app.media.app_icon"),
|
errorholderSrc: $r("app.media.app_icon"),
|
||||||
objectFit: ImageFit.Auto
|
objectFit: ImageFit.Auto
|
||||||
}
|
})
|
||||||
}).width(100).height(100)
|
}).width(100).height(100)
|
||||||
```
|
```
|
||||||
|
|
||||||
#### 3.显示网络图片
|
#### 3. Displaying a Network Image
|
||||||
|
|
||||||
```
|
```
|
||||||
ImageKnifeComponent({
|
ImageKnifeComponent({
|
||||||
ImageKnifeOption: {
|
ImageKnifeOption: new ImageKnifeOption({
|
||||||
loadSrc:"https://www.openharmony.cn/_nuxt/img/logo.dcf95b3.png",
|
loadSrc:"https://www.openharmony.cn/_nuxt/img/logo.dcf95b3.png",
|
||||||
placeholderSrc: $r("app.media.loading"),
|
placeholderSrc: $r("app.media.loading"),
|
||||||
errorholderSrc: $r("app.media.app_icon"),
|
errorholderSrc: $r("app.media.app_icon"),
|
||||||
objectFit: ImageFit.Auto
|
objectFit: ImageFit.Auto
|
||||||
}
|
})
|
||||||
}).width(100).height(100)
|
}).width(100).height(100)
|
||||||
```
|
```
|
||||||
|
|
||||||
#### 4.自定义下载图片
|
#### 4. Downloading an Image with Custom Options
|
||||||
|
|
||||||
```
|
```
|
||||||
ImageKnifeComponent({
|
ImageKnifeComponent({
|
||||||
ImageKnifeOption: {
|
ImageKnifeOption: new ImageKnifeOption({
|
||||||
loadSrc: "https://file.atomgit.com/uploads/user/1704857786989_8994.jpeg",
|
loadSrc: "https://file.atomgit.com/uploads/user/1704857786989_8994.jpeg",
|
||||||
placeholderSrc: $r("app.media.loading"),
|
placeholderSrc: $r("app.media.loading"),
|
||||||
errorholderSrc: $r("app.media.app_icon"),
|
errorholderSrc: $r("app.media.app_icon"),
|
||||||
objectFit: ImageFit.Auto,
|
objectFit: ImageFit.Auto,
|
||||||
customGetImage: custom
|
customGetImage: custom
|
||||||
}
|
})
|
||||||
}).width(100).height(100)
|
}).width(100).height(100)
|
||||||
|
|
||||||
// 自定义实现图片获取方法,如自定义网络下载
|
// Custom implementation of the image acquisition method, such as custom network download。
|
||||||
@Concurrent
|
@Concurrent
|
||||||
async function custom(context: Context, src: string | PixelMap | Resource): Promise<ArrayBuffer | undefined> {
|
async function custom(context: Context, src: string | PixelMap | Resource): Promise<ArrayBuffer | undefined> {
|
||||||
console.info("ImageKnife:: custom download:" + src)
|
console.info("ImageKnife:: custom download: " + src)
|
||||||
// 举例写死从本地文件读取,也可以自己请求网络图片
|
// Example of hardcoding to read from a local file. You can also request a network image.
|
||||||
return context.resourceManager.getMediaContentSync($r("app.media.bb").id).buffer as ArrayBuffer
|
return context.resourceManager.getMediaContentSync($r("app.media.bb").id).buffer as ArrayBuffer
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
#### 5.监听网络下载进度
|
#### 5. Listening for Network Download Progress
|
||||||
|
|
||||||
```
|
```
|
||||||
ImageKnifeComponent({
|
ImageKnifeComponent({
|
||||||
ImageKnifeOption: {
|
ImageKnifeOption: new ImageKnifeOption({
|
||||||
loadSrc:"https://www.openharmony.cn/_nuxt/img/logo.dcf95b3.png",
|
loadSrc:"https://www.openharmony.cn/_nuxt/img/logo.dcf95b3.png",
|
||||||
progressListener:(progress:number)=>{console.info("ImageKinfe:: call back progress = " + progress)}
|
progressListener:(progress:number)=>{console.info("ImageKinfe:: call back progress = " + progress)}
|
||||||
}
|
})
|
||||||
}).width(100).height(100)
|
}).width(100).height(100)
|
||||||
```
|
```
|
||||||
|
|
||||||
#### 6.支持option传入border,设置边框,圆角
|
#### 6. Setting Border Options
|
||||||
|
|
||||||
```
|
```
|
||||||
ImageKnifeComponent({ ImageKnifeOption:
|
ImageKnifeComponent({ ImageKnifeOption: new ImageKnifeOption(
|
||||||
{
|
{
|
||||||
loadSrc: $r("app.media.rabbit"),
|
loadSrc: $r("app.media.rabbit"),
|
||||||
border: {radius:50}
|
border: {radius:50}
|
||||||
}
|
})
|
||||||
}).width(100).height(100)
|
}).width(100).height(100)
|
||||||
```
|
```
|
||||||
|
|
||||||
#### 7.支持option图片变换
|
#### 7. Setting Image Transformation Options
|
||||||
|
|
||||||
```
|
```
|
||||||
ImageKnifeComponent({ ImageKnifeOption:
|
ImageKnifeComponent({ ImageKnifeOption: new ImageKnifeOption(
|
||||||
{
|
{
|
||||||
loadSrc: $r("app.media.rabbit"),
|
loadSrc: $r("app.media.rabbit"),
|
||||||
border: {radius:50},
|
border: {radius:50},
|
||||||
transformation: new BlurTransformation(3)
|
transformation: new BlurTransformation(3)
|
||||||
}
|
})
|
||||||
}).width(100).height(100)
|
}).width(100).height(100)
|
||||||
```
|
```
|
||||||
多种组合变换用法
|
Multiple combined transformation usages:
|
||||||
|
|
||||||
```
|
```
|
||||||
let transformations: collections.Array<PixelMapTransformation> = new collections.Array<PixelMapTransformation>();
|
let transformations: collections.Array<PixelMapTransformation> = new collections.Array<PixelMapTransformation>();
|
||||||
transformations.push(new BlurTransformation(5));
|
transformations.push(new BlurTransformation(5));
|
||||||
transformations.push(new BrightnessTransformation(0.2));
|
transformations.push(new BrightnessTransformation(0.2));
|
||||||
ImageKnifeComponent({
|
ImageKnifeComponent({
|
||||||
{
|
imageKnifeOption: new ImageKnifeOption({
|
||||||
loadSrc: $r('app.media.pngSample'),
|
loadSrc: $r('app.media.pngSample'),
|
||||||
placeholderSrc: $r("app.media.loading"),
|
placeholderSrc: $r("app.media.loading"),
|
||||||
errorholderSrc: $r("app.media.app_icon"),
|
errorholderSrc: $r("app.media.app_icon"),
|
||||||
objectFit: ImageFit.Contain,
|
objectFit: ImageFit.Contain,
|
||||||
border: { radius: { topLeft: 50, bottomRight: 50 } }, // 圆角设置
|
border: { radius: { topLeft: 50, bottomRight: 50 } }, // Rounded corner settings
|
||||||
transformation: transformations.length > 0 ? new MultiTransTransformation(transformations) : undefined // 图形变换组
|
transformation: transformations.length > 0 ? new MultiTransTransformation(transformations) : undefined // Graphic transformation group
|
||||||
}
|
})
|
||||||
}).width(300)
|
}).width(300)
|
||||||
.height(300)
|
.height(300)
|
||||||
.rotate({ angle: 90 }) // 旋转90度
|
.rotate ({angle: 90}) // Rotate by 90 degrees.
|
||||||
.contrast(12) // 对比度滤波器
|
.contrast(12) // Contrast filter
|
||||||
```
|
```
|
||||||
其他变换相关属性,可叠加实现组合变换效果
|
Other transformation-related properties can be stacked to achieve combined transformation effects.
|
||||||
|
|
||||||
圆形裁剪变换示例
|
Example of circular cropping transformation:
|
||||||
|
|
||||||
```
|
```
|
||||||
ImageKnifeComponent({ ImageKnifeOption:
|
ImageKnifeComponent({ ImageKnifeOption:new ImageKnifeOption(
|
||||||
{
|
{
|
||||||
loadSrc: $r('app.media.pngSample'),
|
loadSrc: $r('app.media.pngSample'),
|
||||||
objectFit: ImageFit.Cover,
|
objectFit: ImageFit.Cover,
|
||||||
border: { radius: 150 }
|
border: { radius: 150 }
|
||||||
}
|
})
|
||||||
}).width(300)
|
}).width(300)
|
||||||
.height(300)
|
.height(300)
|
||||||
```
|
```
|
||||||
|
|
||||||
圆形裁剪带边框变换示例
|
Example of Circular cropping with border transformation:
|
||||||
|
|
||||||
```
|
```
|
||||||
ImageKnifeComponent({ ImageKnifeOption:
|
ImageKnifeComponent({ ImageKnifeOption:new ImageKnifeOption(
|
||||||
{
|
{
|
||||||
loadSrc: $r('app.media.pngSample'),
|
loadSrc: $r('app.media.pngSample'),
|
||||||
objectFit: ImageFit.Cover,
|
objectFit: ImageFit.Cover,
|
||||||
border: { radius: 150, color: Color.Red, width: 5 }
|
border: { radius: 150, color: Color.Red, width: 5 }
|
||||||
}
|
})
|
||||||
}).width(300)
|
}).width(300)
|
||||||
.height(300)
|
.height(300)
|
||||||
```
|
```
|
||||||
|
|
||||||
对比度滤波变换示例
|
Example of contrast filtering transformation:
|
||||||
|
|
||||||
```
|
```
|
||||||
ImageKnifeComponent({
|
ImageKnifeComponent({
|
||||||
imageKnifeOption: {
|
imageKnifeOption: new ImageKnifeOption({
|
||||||
loadSrc: $r('app.media.pngSample')
|
loadSrc: $r('app.media.pngSample')
|
||||||
}
|
})
|
||||||
}).width(300)
|
}).width(300)
|
||||||
.height(300)
|
.height(300)
|
||||||
.contrast(12)
|
.contrast(12)
|
||||||
```
|
```
|
||||||
|
|
||||||
旋转变换示例
|
Example of rotation transformation:
|
||||||
|
|
||||||
```
|
```
|
||||||
ImageKnifeComponent({
|
ImageKnifeComponent({
|
||||||
imageKnifeOption: {
|
imageKnifeOption: new ImageKnifeOption({
|
||||||
loadSrc: $r('app.media.pngSample')
|
loadSrc: $r('app.media.pngSample')
|
||||||
}
|
})
|
||||||
}).width(300)
|
}).width(300)
|
||||||
.height(300)
|
.height(300)
|
||||||
.rotate({angle:90})
|
.rotate({angle:90})
|
||||||
.backgroundColor(Color.Pink)
|
.backgroundColor(Color.Pink)
|
||||||
```
|
```
|
||||||
|
|
||||||
#### 8.监听图片加载成功与失败
|
#### 8. Listening for Image Loading Success and Failure
|
||||||
|
|
||||||
```
|
```
|
||||||
ImageKnifeComponent({ ImageKnifeOption:
|
ImageKnifeComponent({ ImageKnifeOption: new ImageKnifeOption(
|
||||||
{
|
{
|
||||||
loadSrc: $r("app.media.rabbit"),
|
loadSrc: $r("app.media.rabbit"),
|
||||||
onLoadListener:{
|
onLoadListener:{
|
||||||
|
@ -242,128 +241,156 @@ ImageKnifeComponent({ ImageKnifeOption:
|
||||||
console.info(err)
|
console.info(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
}).width(100).height(100)
|
}).width(100).height(100)
|
||||||
```
|
```
|
||||||
#### 9.ImageKnifeComponent - syncLoad
|
#### 9. Use of syncLoad
|
||||||
设置是否同步加载图片,默认是异步加载。建议加载尺寸较小的本地图片时将syncLoad设为true,因为耗时较短,在主线程上执行即可
|
**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({
|
ImageKnifeComponent({
|
||||||
imageKnifeOption:{
|
imageKnifeOption:new ImageKnifeOption({
|
||||||
loadSrc:$r("app.media.pngSample"),
|
loadSrc:$r("app.media.pngSample"),
|
||||||
placeholderSrc:$r("app.media.loading")
|
placeholderSrc:$r("app.media.loading")
|
||||||
},syncLoad:true
|
}),syncLoad:true
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
#### 10.ImageKnifeAnimatorComponent 示例
|
#### 10. Use of ImageKnifeAnimatorComponent
|
||||||
```
|
```
|
||||||
ImageKnifeAnimatorComponent({
|
ImageKnifeAnimatorComponent({
|
||||||
imageKnifeOption:{
|
imageKnifeOption:new ImageKnifeOption({
|
||||||
loadSrc:"https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658",
|
loadSrc:"https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658",
|
||||||
placeholderSrc:$r('app.media.loading'),
|
placeholderSrc:$r('app.media.loading'),
|
||||||
errorholderSrc:$r('app.media.failed')
|
errorholderSrc:$r('app.media.failed')
|
||||||
},animatorOption:this.animatorOption
|
}),animatorOption:this.animatorOption
|
||||||
}).width(300).height(300).backgroundColor(Color.Orange).margin({top:30})
|
}).width(300).height(300).backgroundColor(Color.Orange).margin({top:30})
|
||||||
```
|
```
|
||||||
## 接口说明
|
#### 11.图片降采样 示例
|
||||||
### ImageKnife组件
|
```
|
||||||
| 组件名称 | 入参内容 | 功能简介 |
|
ImageKnifeComponent({
|
||||||
|-----------------------------|---------------------------------|--------|
|
imageKnifeOption:new ImageKnifeOption({
|
||||||
| ImageKnifeComponent | ImageKnifeOption | 图片显示组件 |
|
loadSrc:$r("app.media.pngSample"),
|
||||||
| ImageKnifeAnimatorComponent | ImageKnifeOption、AnimatorOption | 动图控制组件 |
|
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
|
||||||
|
### ImageKnife
|
||||||
|
| Component | Parameter | Description |
|
||||||
|
| --------------------------- | -------------------------------- | ------------ |
|
||||||
|
| ImageKnifeComponent | ImageKnifeOption | Image display component.|
|
||||||
|
| ImageKnifeAnimatorComponent | ImageKnifeOption, AnimatorOption| Animated image control component.|
|
||||||
|
|
||||||
### AnimatorOption参数列表
|
### AnimatorOption
|
||||||
| 参数名称 | 入参内容 | 功能简介 |
|
| Parameter | Type | Description |
|
||||||
|-----------------------|-------------------------------------------------------|----------|
|
| ---------- | --------------- | ---------------------------------------- |
|
||||||
| state | AnimationStatus | 播放状态(可选) |
|
| state | AnimationStatus | Playback status. Optional. |
|
||||||
| iterations | number | 播放次数(可选) |
|
| iterations | number | Number of playback times. Optional. |
|
||||||
| reverse | boolean | 播放顺序(可选) |
|
| reverse | boolean | Playback order. Optional. |
|
||||||
|
| onStart | ()=>void | Triggered when the animation starts. Optional. |
|
||||||
|
| onFinish | ()=>void | Triggered when the animation finishes or stops. Optional.|
|
||||||
|
| onPause | ()=>void | Triggered when the animation pauses. Optional. |
|
||||||
|
| onCancel | ()=>void | Triggered when the animation is canceled, that is, when it is reset to its initial state. Optional. |
|
||||||
|
| onRepeat | ()=>void | Triggered when the animation repeats. Optional. |
|
||||||
|
|
||||||
### ImageKnifeOption参数列表
|
### ImageKnifeOption
|
||||||
|
|
||||||
| 参数名称 | 入参内容 | 功能简介 |
|
| Parameter | Type | Description |
|
||||||
|-----------------------|-------------------------------------------------------|-----------------|
|
| --------------------- | ----------------------------------------------------- | ------------------------------ |
|
||||||
| loadSrc | string、PixelMap、Resource | 主图展示 |
|
| loadSrc | string, PixelMap, Resource | Main image. |
|
||||||
| placeholderSrc | PixelMap、Resource | 占位图图展示(可选) |
|
| placeholderSrc | PixelMap, Resource | Placeholder image. Optional. |
|
||||||
| errorholderSrc | PixelMap、Resource | 错误图展示(可选) |
|
| errorholderSrc | PixelMap, Resource | Error image. Optional. |
|
||||||
| objectFit | ImageFit | 主图填充效果(可选) |
|
| objectFit | ImageFit | How the main image is resized to fit its container. Optional. |
|
||||||
| placeholderObjectFit | ImageFit | 占位图填充效果(可选) |
|
| placeholderObjectFit | ImageFit | How the placeholder image is resized to fit its container. Optional. |
|
||||||
| errorholderObjectFit | ImageFit | 错误图填充效果(可选) |
|
| errorholderObjectFit | ImageFit | How the error image is resized to fit its container. Optional. |
|
||||||
| writeCacheStrategy | CacheStrategyType | 写入缓存策略(可选) |
|
| writeCacheStrategy | CacheStrategyType | Cache writing strategy. Optional. |
|
||||||
| onlyRetrieveFromCache | boolean | 是否跳过网络和本地请求(可选) |
|
| onlyRetrieveFromCache | boolean | Whether to skip network and local requests. Optional.|
|
||||||
| customGetImage | (context: Context, src: string | 自定义下载图片(可选) | | Resource | 错误占位图数据源 |
|
| customGetImage | (context: Context, src: string | Custom image download. Optional. |
|
||||||
| border | BorderOptions | 边框圆角(可选) |
|
| border | BorderOptions | Border corner. Optional. |
|
||||||
| priority | taskpool.Priority | 加载优先级(可选) |
|
| priority | taskpool.Priority | Load priority. Optional. |
|
||||||
| context | common.UIAbilityContext | 上下文(可选) |
|
| context | common.UIAbilityContext | Context. Optional. |
|
||||||
| progressListener | (progress: number)=>void | 进度(可选) |
|
| progressListener | (progress: number)=>void | Progress. Optional. |
|
||||||
| signature | String | 自定义缓存关键字(可选) |
|
| signature | String | Custom cache signature. Optional. |
|
||||||
| headerOption | Array<HeaderOptions> | 设置请求头(可选) |
|
| headerOption | Array\<HeaderOptions> | Request headers. Optional. |
|
||||||
| transformation | PixelMapTransformation | 图片变换(可选) |
|
| transformation | PixelMapTransformation | Image transformation. Optional. |
|
||||||
| drawingColorFilter | ColorFilter | drawing.ColorFilter | 图片变换(可选) |
|
| drawingColorFilter | ColorFilter | Drawing color filter. Optional. |
|
||||||
| onComplete | (event:EventImage | undefined) => voi | 颜色滤镜效果(可选) |
|
| onComplete | (event:EventImage \| undefined)=>void | Callback for image loading completion. Optional. |
|
||||||
| onLoadListener | onLoadStart: () => void、onLoadSuccess: (data: string | PixelMap | undefined) => void、onLoadFailed: (err: string) => void| 监听图片加载成功与失败 |
|
| 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
|
||||||
|
|
||||||
### ImageKnife接口
|
| Parameter | Type | Description |
|
||||||
|
| ----------------- | ------------------------------------------------------------ | -------------------------- |
|
||||||
|
| initMemoryCache | newMemoryCache: IMemoryCache | Initializes a custom memory cache strategy. |
|
||||||
|
| initFileCache | context: Context, size: number, memory: number | Initializes the file cache size and quantity |
|
||||||
|
| preLoadCache | loadSrc: string I ImageKnifeOption | Preloads and returns the file cache path. |
|
||||||
|
| getCacheImage | loadSrc: string, cacheType: CacheStrategy = CacheStrategy.Default, signature?: string) | Obtains resources from memory or file cache.|
|
||||||
|
| addHeader | key: string, value: Object | Adds a global HTTP request header. |
|
||||||
|
| setHeaderOptions | Array<HeaderOptions> | Sets global HTTP request headers. |
|
||||||
|
| deleteHeader | key: string | Deletes a global HTTP request header. |
|
||||||
|
| setCustomGetImage | customGetImage?: (context: Context, src: string | PixelMap |
|
||||||
|
| setEngineKeyImpl | IEngineKey | Sets a global cache key generation strategy. |
|
||||||
|
| putCacheImage | url: string, pixelMap: PixelMap, cacheType: CacheStrategy = CacheStrategy.Default, signature?: string | Writes to the memory disk cache. |
|
||||||
|
| removeMemoryCache | url: string | Removes an entry from the memory cache. |
|
||||||
|
| removeFileCache | url: string | Removes an entry from the file cache. |
|
||||||
|
### Graphics tRansformation Types (GPUImage Dependency Required)
|
||||||
|
|
||||||
| 参数名称 | 入参内容 | 功能简介 |
|
| Type | Description |
|
||||||
|------------------|-------------------------------------------------------------------------------------------------------|---------------|
|
| ------------------------ | ----------------------------- |
|
||||||
| initMemoryCache | newMemoryCache: IMemoryCache | 自定义内存缓存策略 |
|
| BlurTransformation | Blurs the image. |
|
||||||
| initFileCache | context: Context, size: number, memory: number | 初始化文件缓存数量和大小 |
|
| BrightnessTransformation | Applies a brightness filter. |
|
||||||
| preLoadCache | loadSrc: string I ImageKnifeOption | 预加载并返回文件缓存路径 |
|
| CropSquareTransformation | Crops the image to a square. |
|
||||||
| getCacheImage | loadSrc: string, cacheType: CacheStrategy = CacheStrategy.Default, signature?: string) | 从内存或文件缓存中获取资源 |
|
| CropTransformation | Crops the image to a custom rectangle. |
|
||||||
| addHeader | key: string, value: Object | 全局添加http请求头 |
|
| GrayScaleTransformation | Applies a grayscale filter. |
|
||||||
| setHeaderOptions | Array<HeaderOptions> | 全局设置http请求头 |
|
| InvertTransformation | Applies an inversion filter. |
|
||||||
| deleteHeader | key: string | 全局删除http请求头 |
|
| KuwaharaTransformation | Applies a Kuwahara filter (requires **GPUImage**). |
|
||||||
| setCustomGetImage | customGetImage?: (context: Context, src: string | PixelMap | Resource) => Promise<ArrayBuffer | undefined> | 全局设置自定义下载 |
|
| MaskTransformation | Applies a mask. |
|
||||||
| setEngineKeyImpl | IEngineKey | 全局配置缓存key生成策略 |
|
| PixelationTransformation | Applies a pixelation filter (requires **GPUImage**).|
|
||||||
| putCacheImage | url: string, pixelMap: PixelMap, cacheType: CacheStrategy = CacheStrategy.Default, signature?: string | 写入内存磁盘缓存 |
|
| SepiaTransformation | Applies a sepia filter (requires **GPUImage**).|
|
||||||
| removeMemoryCache| url: string | ImageKnifeOption | 清理指定内存缓存 |
|
| SketchTransformation | Applies a sketch filter (requires **GPUIImage**). |
|
||||||
| removeFileCache | url: string | ImageKnifeOption | 清理指定磁盘缓存 |
|
| SwirlTransformation | Applies a swirl filter (requires **GPUImage**). |
|
||||||
### 图形变换类型(需要为GPUImage添加依赖项)
|
| ToonTransformation | Applies a cartoon filter (requires **GPUImage**). |
|
||||||
|
| VignetterTransformation | Applies a vignette filter (requires **GPUImage**). |
|
||||||
|
|
||||||
| 类型 | 相关描述 |
|
## Downloading and Installing the GPUImage Dependency
|
||||||
| ---------------------------------- | ----------------------------- |
|
Method 1: In the **Terminal** window, run the following command to install the third-party HAR. DevEco Studio will automatically add the HAR as a dependency to the **oh-package.json5** file of the project.
|
||||||
| BlurTransformation | 模糊处理 |
|
|
||||||
| BrightnessTransformation | 亮度滤波器 |
|
|
||||||
| CropSquareTransformation | 正方形剪裁 |
|
|
||||||
| CropTransformation | 自定义矩形剪裁 |
|
|
||||||
| GrayScaleTransformation | 灰度级滤波器 |
|
|
||||||
| InvertTransformation | 反转滤波器 |
|
|
||||||
| KuwaharaTransformation | 桑原滤波器(使用GPUIImage) |
|
|
||||||
| MaskTransformation | 遮罩 |
|
|
||||||
| PixelationTransformation | 像素化滤波器(使用GPUIImage) |
|
|
||||||
| SepiaTransformation | 乌墨色滤波器(使用GPUIImage) |
|
|
||||||
| SketchTransformation | 素描滤波器(使用GPUIImage) |
|
|
||||||
| SwirlTransformation | 扭曲滤波器(使用GPUIImage) |
|
|
||||||
| ToonTransformation | 动画滤波器(使用GPUIImage) |
|
|
||||||
| VignetterTransformation | 装饰滤波器(使用GPUIImage) |
|
|
||||||
|
|
||||||
## 下载安装GPUImage依赖
|
|
||||||
方法一:在Terminal窗口中,执行如下命令安装三方包,DevEco Studio会自动在工程的oh-package.json5中自动添加三方包依赖。
|
|
||||||
```
|
```
|
||||||
ohpm install @ohos/gpu_transform
|
ohpm install @ohos/gpu_transform
|
||||||
```
|
```
|
||||||
方法二: 在工程的oh-package.json5中设置三方包依赖,配置示例如下:
|
Method 2: Set the third-party HAR as a dependency in the **oh-package.json5** file of the project. The following is a configuration example:
|
||||||
```
|
```
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ohos/gpu_transform": "^1.0.2"
|
"@ohos/gpu_transform": "^1.0.2"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
## 约束与限制
|
## Constraints
|
||||||
|
|
||||||
在下述版本验证通过:
|
This project has been verified in the following version:
|
||||||
DevEco Studio 5.0 Canary3(5.0.3.221)--SDK:API12
|
|
||||||
|
|
||||||
## 贡献代码
|
DevEco Studio: 5.0 Canary3 (5.0.3.502), SDK: API 12 (5.0.0.31)
|
||||||
|
|
||||||
使用过程中发现任何问题都可以提 [issue](https://gitee.com/openharmony-tpc/ImageKnife/issues)
|
## How to Contribute
|
||||||
给我们,当然,我们也非常欢迎你给我们发 [PR](https://gitee.com/openharmony-tpc/ImageKnife/issues) 。
|
|
||||||
|
|
||||||
## 开源协议
|
If you find any problem during the use, submit an [Issue](https://gitee.com/openharmony-tpc/ImageKnife/issues) or a [PR](https://gitee.com/openharmony-tpc/ImageKnife/issues) to us.
|
||||||
|
|
||||||
本项目基于 [Apache License 2.0](https://gitee.com/openharmony-tpc/ImageKnife/blob/master/LICENSE) ,请自由的享受和参与开源。
|
## License
|
||||||
|
|
||||||
## 遗留问题
|
This project is licensed under [Apache License 2.0](https://gitee.com/openharmony-tpc/ImageKnife/blob/master/LICENSE).
|
||||||
|
|
||||||
- ImageKnifeAnimator组件无法设置ImageFit属性
|
## Known Issues
|
||||||
- ImageKnifeAnimator组件设置border属性无法将图片变为圆角
|
|
||||||
|
- The **ImageFit** attribute cannot be set for the **ImageKnifeAnimator** component.
|
||||||
|
- The **border** attribute of the **ImageKnifeAnimator** component cannot make the image rounded corners.
|
||||||
|
|
|
@ -0,0 +1,375 @@
|
||||||
|
# ImageKnife
|
||||||
|
|
||||||
|
**专门为OpenHarmony打造的一款图像加载缓存库,致力于更高效、更轻便、更简单。**
|
||||||
|
|
||||||
|
## 简介
|
||||||
|
|
||||||
|
本项目参考开源库 [Glide](https://github.com/bumptech/glide) 进行OpenHarmony的自研版本:
|
||||||
|
|
||||||
|
- 支持自定义内存缓存策略,支持设置内存缓存的大小(默认LRU策略)。
|
||||||
|
- 支持磁盘二级缓存,对于下载图片会保存一份至磁盘当中。
|
||||||
|
- 支持自定义实现图片获取/网络下载
|
||||||
|
- 支持监听网络下载回调进度
|
||||||
|
- 继承Image的能力,支持option传入border,设置边框,圆角
|
||||||
|
- 继承Image的能力,支持option传入objectFit设置图片缩放,包括objectFit为auto时根据图片自适应高度
|
||||||
|
- 支持通过设置transform缩放图片
|
||||||
|
- 并发请求数量,支持请求排队队列的优先级
|
||||||
|
- 支持生命周期已销毁的图片,不再发起请求
|
||||||
|
- 自定义缓存key
|
||||||
|
- 自定义http网络请求头
|
||||||
|
- 支持writeCacheStrategy控制缓存的存入策略(只存入内存或文件缓存)
|
||||||
|
- 支持preLoadCache预加载图片
|
||||||
|
- 支持onlyRetrieveFromCache仅用缓存加载
|
||||||
|
- 支持使用一个或多个图片变换,如模糊,高亮等
|
||||||
|
|
||||||
|
待实现特性
|
||||||
|
|
||||||
|
- 内存降采样优化,节约内存的占用
|
||||||
|
- 支持自定义图片解码
|
||||||
|
|
||||||
|
注意:3.x版本相对2.x版本做了重大的重构,主要体现在:
|
||||||
|
|
||||||
|
- 使用Image组件代替Canvas组件渲染
|
||||||
|
- 重构Dispatch分发逻辑,支持控制并发请求数,支持请求排队队列的优先级
|
||||||
|
- 支持通过initMemoryCache自定义策略内存缓存策略和大小
|
||||||
|
- 支持option自定义实现图片获取/网络下载
|
||||||
|
|
||||||
|
因此API及能力上,目前有部分差异,主要体现在:
|
||||||
|
|
||||||
|
- 不支持drawLifeCycle接口,通过canvas自会图片
|
||||||
|
- mainScaleType,border等参数,新版本与系统Image保持一致
|
||||||
|
- gif/webp动图播放与控制(ImageAnimator实现)
|
||||||
|
- 抗锯齿相关参数
|
||||||
|
|
||||||
|
## 下载安装
|
||||||
|
|
||||||
|
```
|
||||||
|
ohpm install @ohos/imageknife
|
||||||
|
|
||||||
|
// 如果需要用文件缓存,需要提前初始化文件缓存
|
||||||
|
await ImageKnife.getInstance().initFileCache(context, 256, 256 * 1024 * 1024)
|
||||||
|
```
|
||||||
|
|
||||||
|
## 使用说明
|
||||||
|
|
||||||
|
#### 1.显示本地资源图片
|
||||||
|
|
||||||
|
```
|
||||||
|
ImageKnifeComponent({
|
||||||
|
ImageKnifeOption: new ImageKnifeOption({
|
||||||
|
loadSrc: $r("app.media.app_icon"),
|
||||||
|
placeholderSrc: $r("app.media.loading"),
|
||||||
|
errorholderSrc: $r("app.media.app_icon"),
|
||||||
|
objectFit: ImageFit.Auto
|
||||||
|
})
|
||||||
|
}).width(100).height(100)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 2.显示本地context files下文件
|
||||||
|
|
||||||
|
```
|
||||||
|
ImageKnifeComponent({
|
||||||
|
ImageKnifeOption: new ImageKnifeOption({
|
||||||
|
loadSrc: this.localFile,
|
||||||
|
placeholderSrc: $r("app.media.loading"),
|
||||||
|
errorholderSrc: $r("app.media.app_icon"),
|
||||||
|
objectFit: ImageFit.Auto
|
||||||
|
})
|
||||||
|
}).width(100).height(100)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 3.显示网络图片
|
||||||
|
|
||||||
|
```
|
||||||
|
ImageKnifeComponent({
|
||||||
|
ImageKnifeOption: new ImageKnifeOption({
|
||||||
|
loadSrc:"https://www.openharmony.cn/_nuxt/img/logo.dcf95b3.png",
|
||||||
|
placeholderSrc: $r("app.media.loading"),
|
||||||
|
errorholderSrc: $r("app.media.app_icon"),
|
||||||
|
objectFit: ImageFit.Auto
|
||||||
|
})
|
||||||
|
}).width(100).height(100)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 4.自定义下载图片
|
||||||
|
|
||||||
|
```
|
||||||
|
ImageKnifeComponent({
|
||||||
|
ImageKnifeOption: new ImageKnifeOption({
|
||||||
|
loadSrc: "https://file.atomgit.com/uploads/user/1704857786989_8994.jpeg",
|
||||||
|
placeholderSrc: $r("app.media.loading"),
|
||||||
|
errorholderSrc: $r("app.media.app_icon"),
|
||||||
|
objectFit: ImageFit.Auto,
|
||||||
|
customGetImage: custom
|
||||||
|
})
|
||||||
|
}).width(100).height(100)
|
||||||
|
|
||||||
|
// 自定义实现图片获取方法,如自定义网络下载
|
||||||
|
@Concurrent
|
||||||
|
async function custom(context: Context, src: string | PixelMap | Resource): Promise<ArrayBuffer | undefined> {
|
||||||
|
console.info("ImageKnife:: custom download:" + src)
|
||||||
|
// 举例写死从本地文件读取,也可以自己请求网络图片
|
||||||
|
return context.resourceManager.getMediaContentSync($r("app.media.bb").id).buffer as ArrayBuffer
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 5.监听网络下载进度
|
||||||
|
|
||||||
|
```
|
||||||
|
ImageKnifeComponent({
|
||||||
|
ImageKnifeOption: new 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(
|
||||||
|
{
|
||||||
|
loadSrc: $r("app.media.rabbit"),
|
||||||
|
border: {radius:50}
|
||||||
|
})
|
||||||
|
}).width(100).height(100)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 7.支持option图片变换
|
||||||
|
|
||||||
|
```
|
||||||
|
ImageKnifeComponent({ ImageKnifeOption: new ImageKnifeOption(
|
||||||
|
{
|
||||||
|
loadSrc: $r("app.media.rabbit"),
|
||||||
|
border: {radius:50},
|
||||||
|
transformation: new BlurTransformation(3)
|
||||||
|
})
|
||||||
|
}).width(100).height(100)
|
||||||
|
```
|
||||||
|
多种组合变换用法
|
||||||
|
|
||||||
|
```
|
||||||
|
let transformations: collections.Array<PixelMapTransformation> = new collections.Array<PixelMapTransformation>();
|
||||||
|
transformations.push(new BlurTransformation(5));
|
||||||
|
transformations.push(new BrightnessTransformation(0.2));
|
||||||
|
ImageKnifeComponent({
|
||||||
|
imageKnifeOption: new ImageKnifeOption({
|
||||||
|
loadSrc: $r('app.media.pngSample'),
|
||||||
|
placeholderSrc: $r("app.media.loading"),
|
||||||
|
errorholderSrc: $r("app.media.app_icon"),
|
||||||
|
objectFit: ImageFit.Contain,
|
||||||
|
border: { radius: { topLeft: 50, bottomRight: 50 } }, // 圆角设置
|
||||||
|
transformation: transformations.length > 0 ? new MultiTransTransformation(transformations) : undefined // 图形变换组
|
||||||
|
})
|
||||||
|
}).width(300)
|
||||||
|
.height(300)
|
||||||
|
.rotate({ angle: 90 }) // 旋转90度
|
||||||
|
.contrast(12) // 对比度滤波器
|
||||||
|
```
|
||||||
|
其它变换相关属性,可叠加实现组合变换效果
|
||||||
|
|
||||||
|
圆形裁剪变换示例
|
||||||
|
|
||||||
|
```
|
||||||
|
ImageKnifeComponent({ ImageKnifeOption:new ImageKnifeOption(
|
||||||
|
{
|
||||||
|
loadSrc: $r('app.media.pngSample'),
|
||||||
|
objectFit: ImageFit.Cover,
|
||||||
|
border: { radius: 150 }
|
||||||
|
})
|
||||||
|
}).width(300)
|
||||||
|
.height(300)
|
||||||
|
```
|
||||||
|
|
||||||
|
圆形裁剪带边框变换示例
|
||||||
|
|
||||||
|
```
|
||||||
|
ImageKnifeComponent({ ImageKnifeOption:new ImageKnifeOption(
|
||||||
|
{
|
||||||
|
loadSrc: $r('app.media.pngSample'),
|
||||||
|
objectFit: ImageFit.Cover,
|
||||||
|
border: { radius: 150, color: Color.Red, width: 5 }
|
||||||
|
})
|
||||||
|
}).width(300)
|
||||||
|
.height(300)
|
||||||
|
```
|
||||||
|
|
||||||
|
对比度滤波变换示例
|
||||||
|
|
||||||
|
```
|
||||||
|
ImageKnifeComponent({
|
||||||
|
imageKnifeOption: new ImageKnifeOption({
|
||||||
|
loadSrc: $r('app.media.pngSample')
|
||||||
|
})
|
||||||
|
}).width(300)
|
||||||
|
.height(300)
|
||||||
|
.contrast(12)
|
||||||
|
```
|
||||||
|
|
||||||
|
旋转变换示例
|
||||||
|
|
||||||
|
```
|
||||||
|
ImageKnifeComponent({
|
||||||
|
imageKnifeOption: new ImageKnifeOption({
|
||||||
|
loadSrc: $r('app.media.pngSample')
|
||||||
|
})
|
||||||
|
}).width(300)
|
||||||
|
.height(300)
|
||||||
|
.rotate({angle:90})
|
||||||
|
.backgroundColor(Color.Pink)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 8.监听图片加载成功与失败
|
||||||
|
|
||||||
|
```
|
||||||
|
ImageKnifeComponent({ ImageKnifeOption: new ImageKnifeOption(
|
||||||
|
{
|
||||||
|
loadSrc: $r("app.media.rabbit"),
|
||||||
|
onLoadListener:{
|
||||||
|
onLoadStart:()=>{
|
||||||
|
this.starTime = new Date().getTime()
|
||||||
|
console.info("Load start: ");
|
||||||
|
},
|
||||||
|
onLoadFailed: (err) => {
|
||||||
|
console.error("Load Failed Reason: " + err + " cost " + (new Date().getTime() - this.starTime) + " milliseconds");
|
||||||
|
},
|
||||||
|
onLoadSuccess: (data, imageData) => {
|
||||||
|
console.info("Load Successful: cost " + (new Date().getTime() - this.starTime) + " milliseconds");
|
||||||
|
return data;
|
||||||
|
},
|
||||||
|
onLoadCancel(err){
|
||||||
|
console.info(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}).width(100).height(100)
|
||||||
|
```
|
||||||
|
#### 9.ImageKnifeComponent - syncLoad
|
||||||
|
设置是否同步加载图片,默认是异步加载。建议加载尺寸较小的Resource图片时将syncLoad设为true,因为耗时较短,在主线程上执行即可
|
||||||
|
```
|
||||||
|
ImageKnifeComponent({
|
||||||
|
imageKnifeOption:new ImageKnifeOption({
|
||||||
|
loadSrc:$r("app.media.pngSample"),
|
||||||
|
placeholderSrc:$r("app.media.loading")
|
||||||
|
}),syncLoad:true
|
||||||
|
})
|
||||||
|
```
|
||||||
|
#### 10.ImageKnifeAnimatorComponent 示例
|
||||||
|
```
|
||||||
|
ImageKnifeAnimatorComponent({
|
||||||
|
imageKnifeOption:new ImageKnifeOption({
|
||||||
|
loadSrc:"https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658",
|
||||||
|
placeholderSrc:$r('app.media.loading'),
|
||||||
|
errorholderSrc:$r('app.media.failed')
|
||||||
|
}),animatorOption:this.animatorOption
|
||||||
|
}).width(300).height(300).backgroundColor(Color.Orange).margin({top:30})
|
||||||
|
```
|
||||||
|
#### 复用场景
|
||||||
|
在aboutToRecycle生命周期清空组件内容;通过watch监听触发图片的加载。
|
||||||
|
## 接口说明
|
||||||
|
### ImageKnife组件
|
||||||
|
| 组件名称 | 入参内容 | 功能简介 |
|
||||||
|
|-----------------------------|---------------------------------|--------|
|
||||||
|
| ImageKnifeComponent | ImageKnifeOption | 图片显示组件 |
|
||||||
|
| ImageKnifeAnimatorComponent | ImageKnifeOption、AnimatorOption | 动图控制组件 |
|
||||||
|
|
||||||
|
### AnimatorOption参数列表
|
||||||
|
| 参数名称 | 入参内容 | 功能简介 |
|
||||||
|
|------------|-----------------|----------|
|
||||||
|
| state | AnimationStatus | 播放状态(可选) |
|
||||||
|
| iterations | number | 播放次数(可选) |
|
||||||
|
| reverse | boolean | 播放顺序(可选) |
|
||||||
|
| onStart | ()=>void | 动画开始播放时触发(可选) |
|
||||||
|
| onFinish | ()=>void | 动画播放完成时或者停止播放时触发(可选) |
|
||||||
|
| onPause | ()=>void | 动画暂停播放时触发(可选) |
|
||||||
|
| onCancel | ()=>void | 动画返回最初状态时触发(可选) |
|
||||||
|
| onRepeat | ()=>void | 动画重复播放时触发(可选) |
|
||||||
|
|
||||||
|
### ImageKnifeOption参数列表
|
||||||
|
|
||||||
|
| 参数名称 | 入参内容 | 功能简介 |
|
||||||
|
|-----------------------|-------------------------------------------------------|-----------------|
|
||||||
|
| loadSrc | string、PixelMap、Resource | 主图展示 |
|
||||||
|
| placeholderSrc | PixelMap、Resource | 占位图图展示(可选) |
|
||||||
|
| errorholderSrc | PixelMap、Resource | 错误图展示(可选) |
|
||||||
|
| objectFit | ImageFit | 主图填充效果(可选) |
|
||||||
|
| placeholderObjectFit | ImageFit | 占位图填充效果(可选) |
|
||||||
|
| errorholderObjectFit | ImageFit | 错误图填充效果(可选) |
|
||||||
|
| writeCacheStrategy | CacheStrategyType | 写入缓存策略(可选) |
|
||||||
|
| onlyRetrieveFromCache | boolean | 是否跳过网络和本地请求(可选) |
|
||||||
|
| customGetImage | (context: Context, src: string | 自定义下载图片(可选) | | Resource | 错误占位图数据源 |
|
||||||
|
| border | BorderOptions | 边框圆角(可选) |
|
||||||
|
| priority | taskpool.Priority | 加载优先级(可选) |
|
||||||
|
| context | common.UIAbilityContext | 上下文(可选) |
|
||||||
|
| progressListener | (progress: number)=>void | 进度(可选) |
|
||||||
|
| signature | String | 自定义缓存关键字(可选) |
|
||||||
|
| headerOption | Array<HeaderOptions> | 设置请求头(可选) |
|
||||||
|
| transformation | PixelMapTransformation | 图片变换(可选) |
|
||||||
|
| drawingColorFilter | ColorFilter | drawing.ColorFilter | 图片变换(可选) |
|
||||||
|
| onComplete | (event:EventImage | undefined) => voi | 颜色滤镜效果(可选) |
|
||||||
|
| onLoadListener | onLoadStart: () => void、onLoadSuccess: (data: string | PixelMap | undefined) => void、onLoadFailed: (err: string) => void| 监听图片加载成功与失败 |
|
||||||
|
|
||||||
|
### ImageKnife接口
|
||||||
|
|
||||||
|
| 参数名称 | 入参内容 | 功能简介 |
|
||||||
|
|------------------|-------------------------------------------------------------------------------------------------------|---------------|
|
||||||
|
| initMemoryCache | newMemoryCache: IMemoryCache | 自定义内存缓存策略 |
|
||||||
|
| initFileCache | context: Context, size: number, memory: number | 初始化文件缓存数量和大小 |
|
||||||
|
| preLoadCache | loadSrc: string I ImageKnifeOption | 预加载并返回文件缓存路径 |
|
||||||
|
| getCacheImage | loadSrc: string, cacheType: CacheStrategy = CacheStrategy.Default, signature?: string) | 从内存或文件缓存中获取资源 |
|
||||||
|
| addHeader | key: string, value: Object | 全局添加http请求头 |
|
||||||
|
| setHeaderOptions | Array<HeaderOptions> | 全局设置http请求头 |
|
||||||
|
| deleteHeader | key: string | 全局删除http请求头 |
|
||||||
|
| setCustomGetImage | customGetImage?: (context: Context, src: string | PixelMap | Resource) => Promise<ArrayBuffer | undefined> | 全局设置自定义下载 |
|
||||||
|
| setEngineKeyImpl | IEngineKey | 全局配置缓存key生成策略 |
|
||||||
|
| putCacheImage | url: string, pixelMap: PixelMap, cacheType: CacheStrategy = CacheStrategy.Default, signature?: string | 写入内存磁盘缓存 |
|
||||||
|
| removeMemoryCache| url: string | ImageKnifeOption | 清理指定内存缓存 |
|
||||||
|
| removeFileCache | url: string | ImageKnifeOption | 清理指定磁盘缓存 |
|
||||||
|
### 图形变换类型(需要为GPUImage添加依赖项)
|
||||||
|
|
||||||
|
| 类型 | 相关描述 |
|
||||||
|
| ---------------------------------- | ----------------------------- |
|
||||||
|
| BlurTransformation | 模糊处理 |
|
||||||
|
| BrightnessTransformation | 亮度滤波器 |
|
||||||
|
| CropSquareTransformation | 正方形剪裁 |
|
||||||
|
| CropTransformation | 自定义矩形剪裁 |
|
||||||
|
| GrayScaleTransformation | 灰度级滤波器 |
|
||||||
|
| InvertTransformation | 反转滤波器 |
|
||||||
|
| KuwaharaTransformation | 桑原滤波器(使用GPUIImage) |
|
||||||
|
| MaskTransformation | 遮罩 |
|
||||||
|
| PixelationTransformation | 像素化滤波器(使用GPUIImage) |
|
||||||
|
| SepiaTransformation | 乌墨色滤波器(使用GPUIImage) |
|
||||||
|
| SketchTransformation | 素描滤波器(使用GPUIImage) |
|
||||||
|
| SwirlTransformation | 扭曲滤波器(使用GPUIImage) |
|
||||||
|
| ToonTransformation | 动画滤波器(使用GPUIImage) |
|
||||||
|
| VignetterTransformation | 装饰滤波器(使用GPUIImage) |
|
||||||
|
|
||||||
|
## 下载安装GPUImage依赖
|
||||||
|
方法一:在Terminal窗口中,执行如下命令安装三方包,DevEco Studio会自动在工程的oh-package.json5中自动添加三方包依赖。
|
||||||
|
```
|
||||||
|
ohpm install @ohos/gpu_transform
|
||||||
|
```
|
||||||
|
方法二: 在工程的oh-package.json5中设置三方包依赖,配置示例如下:
|
||||||
|
```
|
||||||
|
"dependencies": {
|
||||||
|
"@ohos/gpu_transform": "^1.0.2"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
## 约束与限制
|
||||||
|
|
||||||
|
在下述版本验证通过:
|
||||||
|
DevEco Studio 5.0 Canary3(5.0.3.502)--SDK:API12 (5.0.0.31)
|
||||||
|
|
||||||
|
## 贡献代码
|
||||||
|
|
||||||
|
使用过程中发现任何问题都可以提 [issue](https://gitee.com/openharmony-tpc/ImageKnife/issues)
|
||||||
|
,当然,也非常欢迎发 [PR](https://gitee.com/openharmony-tpc/ImageKnife/pulls) 共建。
|
||||||
|
|
||||||
|
## 开源协议
|
||||||
|
|
||||||
|
本项目基于 [Apache License 2.0](https://gitee.com/openharmony-tpc/ImageKnife/blob/master/LICENSE) ,请自由的享受和参与开源。
|
||||||
|
|
||||||
|
## 遗留问题
|
||||||
|
|
||||||
|
- ImageKnifeAnimator组件无法设置ImageFit属性
|
||||||
|
- ImageKnifeAnimator组件设置border属性无法将图片变为圆角
|
|
@ -7,9 +7,8 @@
|
||||||
{
|
{
|
||||||
"name": "default",
|
"name": "default",
|
||||||
"signingConfig": "default",
|
"signingConfig": "default",
|
||||||
"compileSdkVersion": "5.0.0(12)",
|
"compileSdkVersion": 12,
|
||||||
"compatibleSdkVersion": "5.0.0(12)",
|
"compatibleSdkVersion": 12
|
||||||
"runtimeOS": "HarmonyOS",
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"buildModeSet": [
|
"buildModeSet": [
|
||||||
|
@ -38,6 +37,10 @@
|
||||||
"name": "library",
|
"name": "library",
|
||||||
"srcPath": "./library"
|
"srcPath": "./library"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "gpu_transform",
|
||||||
|
"srcPath": "./gpu_transform"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "sharedlibrary",
|
"name": "sharedlibrary",
|
||||||
"srcPath": "./sharedlibrary",
|
"srcPath": "./sharedlibrary",
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
import { DownsampleStrategy } from '@ohos/imageknife';
|
||||||
import { IEngineKey, ImageKnifeOption, PixelMapTransformation,SparkMD5 ,ImageKnifeRequestSource} from '@ohos/libraryimageknife';
|
import { IEngineKey, ImageKnifeOption, PixelMapTransformation,SparkMD5 ,ImageKnifeRequestSource} from '@ohos/libraryimageknife';
|
||||||
|
|
||||||
//全局自定义key demo
|
//全局自定义key demo
|
||||||
|
@ -35,6 +36,9 @@ export class CustomEngineKeyImpl implements IEngineKey {
|
||||||
if (imageKnifeOption.transformation) {
|
if (imageKnifeOption.transformation) {
|
||||||
key += "transformation=" + this.getTransformation(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
|
return key
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,7 +47,6 @@ export default class EntryAbility extends UIAbility {
|
||||||
|
|
||||||
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate');
|
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate');
|
||||||
|
|
||||||
LogUtil.mLogLevel = LogUtil.ALL
|
|
||||||
// 初始化ImageKnife的文件缓存
|
// 初始化ImageKnife的文件缓存
|
||||||
await InitImageKnife.init(this.context)
|
await InitImageKnife.init(this.context)
|
||||||
ImageKnife.getInstance().setEngineKeyImpl(new CustomEngineKeyImpl())
|
ImageKnife.getInstance().setEngineKeyImpl(new CustomEngineKeyImpl())
|
||||||
|
|
|
@ -0,0 +1,214 @@
|
||||||
|
/*
|
||||||
|
* 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
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,41 +1,93 @@
|
||||||
import { AnimatorOption, ImageKnifeAnimatorComponent } from "@ohos/libraryimageknife"
|
/*
|
||||||
|
* Copyright (C) 2024 Huawei Device Co., Ltd.
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
import { AnimatorOption, ImageKnifeAnimatorComponent,ImageKnifeOption } from "@ohos/libraryimageknife"
|
||||||
|
|
||||||
@Entry
|
@Entry
|
||||||
@Component
|
@ComponentV2
|
||||||
struct ImageAnimatorPage {
|
struct ImageAnimatorPage {
|
||||||
@State animatorOption: AnimatorOption = {
|
@Local animatorOption: AnimatorOption = new AnimatorOption({
|
||||||
state: AnimationStatus.Running,
|
state: AnimationStatus.Running,
|
||||||
iterations: -1
|
iterations: -1,
|
||||||
}
|
onFinish:()=>{
|
||||||
|
console.log("ImageKnifeAnimatorComponent animatorOption onFinish")
|
||||||
|
},
|
||||||
|
onStart:()=>{
|
||||||
|
console.log("ImageKnifeAnimatorComponent animatorOption onStart")
|
||||||
|
},
|
||||||
|
onPause:()=>{
|
||||||
|
console.log("ImageKnifeAnimatorComponent animatorOption onPause")
|
||||||
|
},
|
||||||
|
onCancel:()=>{
|
||||||
|
console.log("ImageKnifeAnimatorComponent animatorOption onCancel")
|
||||||
|
},
|
||||||
|
onRepeat:()=>{
|
||||||
|
console.log("ImageKnifeAnimatorComponent animatorOption onRepeat")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
@Local animatorOption1: AnimatorOption = new AnimatorOption({
|
||||||
|
state: AnimationStatus.Initial
|
||||||
|
})
|
||||||
|
@Local animatorOption2: AnimatorOption = new AnimatorOption({
|
||||||
|
state: AnimationStatus.Initial,
|
||||||
|
reverse: true
|
||||||
|
})
|
||||||
build() {
|
build() {
|
||||||
Column(){
|
Column(){
|
||||||
Flex(){
|
Flex(){
|
||||||
Button("播放").onClick(()=>{
|
Button($r('app.string.Play')).onClick(()=>{
|
||||||
this.animatorOption.state = AnimationStatus.Running
|
this.animatorOption.state = AnimationStatus.Running
|
||||||
})
|
})
|
||||||
Button("暂停").onClick(()=>{
|
Button($r('app.string.Pause')).onClick(()=>{
|
||||||
this.animatorOption.state = AnimationStatus.Paused
|
this.animatorOption.state = AnimationStatus.Paused
|
||||||
})
|
})
|
||||||
Button("停止").onClick(()=>{
|
Button($r('app.string.Stop')).onClick(()=>{
|
||||||
this.animatorOption.state = AnimationStatus.Stopped
|
this.animatorOption.state = AnimationStatus.Stopped
|
||||||
})
|
})
|
||||||
Button("无限循环").onClick(()=>{
|
Button($r('app.string.Infinite_loop')).onClick(()=>{
|
||||||
this.animatorOption.iterations = -1
|
this.animatorOption.iterations = -1
|
||||||
})
|
})
|
||||||
Button("播放一次").onClick(()=>{
|
Button($r('app.string.Play_once')).onClick(()=>{
|
||||||
this.animatorOption.iterations = 1
|
this.animatorOption.iterations = 1
|
||||||
})
|
})
|
||||||
Button("播放两次").onClick(()=>{
|
Button($r('app.string.Play_twice')).onClick(()=>{
|
||||||
this.animatorOption.iterations = 2
|
this.animatorOption.iterations = 2
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
ImageKnifeAnimatorComponent({
|
ImageKnifeAnimatorComponent({
|
||||||
imageKnifeOption:{
|
imageKnifeOption:new ImageKnifeOption({
|
||||||
loadSrc:"https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658",
|
loadSrc:"https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658",
|
||||||
placeholderSrc:$r('app.media.loading'),
|
placeholderSrc:$r('app.media.loading'),
|
||||||
errorholderSrc:$r('app.media.failed')
|
errorholderSrc:$r('app.media.failed')
|
||||||
},animatorOption:this.animatorOption
|
}),animatorOption:this.animatorOption
|
||||||
}).width(300).height(300).backgroundColor(Color.Orange).margin({top:30})
|
}).width(200).height(200).backgroundColor(Color.Orange).margin({top:30})
|
||||||
|
Text($r('app.string.Display_the_first_frame')).fontSize(20)
|
||||||
|
ImageKnifeAnimatorComponent({
|
||||||
|
imageKnifeOption:new ImageKnifeOption({
|
||||||
|
loadSrc:"https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658",
|
||||||
|
placeholderSrc:$r('app.media.loading'),
|
||||||
|
errorholderSrc:$r('app.media.failed')
|
||||||
|
}),animatorOption:this.animatorOption1
|
||||||
|
}).width(200).height(200).backgroundColor(Color.Orange).margin({top:30})
|
||||||
|
Text($r('app.string.Display_the_last_frame')).fontSize(20)
|
||||||
|
ImageKnifeAnimatorComponent({
|
||||||
|
imageKnifeOption:new ImageKnifeOption({
|
||||||
|
loadSrc:"https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658",
|
||||||
|
placeholderSrc:$r('app.media.loading'),
|
||||||
|
errorholderSrc:$r('app.media.failed')
|
||||||
|
}),animatorOption:this.animatorOption2
|
||||||
|
}).width(200).height(200).backgroundColor(Color.Orange).margin({top:30})
|
||||||
}.width("100%").height("100%")
|
}.width("100%").height("100%")
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -35,17 +35,17 @@ import {
|
||||||
import { collections } from '@kit.ArkTS'
|
import { collections } from '@kit.ArkTS'
|
||||||
|
|
||||||
@Entry
|
@Entry
|
||||||
@Component
|
@ComponentV2
|
||||||
struct ImageTransformation {
|
struct ImageTransformation {
|
||||||
@State imageKnifeOption: ImageKnifeOption = {
|
@Local imageKnifeOption: ImageKnifeOption = new ImageKnifeOption({
|
||||||
loadSrc: $r('app.media.pngSample'),
|
loadSrc: $r('app.media.pngSample'),
|
||||||
placeholderSrc: $r("app.media.loading"),
|
placeholderSrc: $r("app.media.loading"),
|
||||||
errorholderSrc: $r("app.media.app_icon"),
|
errorholderSrc: $r("app.media.app_icon"),
|
||||||
objectFit: ImageFit.Contain
|
objectFit: ImageFit.Contain
|
||||||
}
|
})
|
||||||
@State isRound: boolean = false;
|
@Local isRound: boolean = false;
|
||||||
@State isContrast: boolean = false;
|
@Local isContrast: boolean = false;
|
||||||
@State isRotate: boolean = false;
|
@Local isRotate: boolean = false;
|
||||||
isBlur: boolean = false
|
isBlur: boolean = false
|
||||||
isBrightness: boolean = false
|
isBrightness: boolean = false
|
||||||
isGrayScale: boolean = false;
|
isGrayScale: boolean = false;
|
||||||
|
@ -78,7 +78,7 @@ struct ImageTransformation {
|
||||||
})
|
})
|
||||||
.width(30)
|
.width(30)
|
||||||
.height(30)
|
.height(30)
|
||||||
Text('模糊效果').fontSize(20)
|
Text($r('app.string.Blur_effect')).fontSize(20)
|
||||||
}
|
}
|
||||||
|
|
||||||
Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
|
Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
|
||||||
|
@ -91,7 +91,7 @@ struct ImageTransformation {
|
||||||
})
|
})
|
||||||
.width(30)
|
.width(30)
|
||||||
.height(30)
|
.height(30)
|
||||||
Text('高亮效果').fontSize(20)
|
Text($r('app.string.Highlighting_effect')).fontSize(20)
|
||||||
}
|
}
|
||||||
|
|
||||||
Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
|
Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
|
||||||
|
@ -104,7 +104,7 @@ struct ImageTransformation {
|
||||||
})
|
})
|
||||||
.width(30)
|
.width(30)
|
||||||
.height(30)
|
.height(30)
|
||||||
Text('灰化效果').fontSize(20)
|
Text($r('app.string.Ashing_effect')).fontSize(20)
|
||||||
}
|
}
|
||||||
|
|
||||||
Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
|
Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
|
||||||
|
@ -117,7 +117,7 @@ struct ImageTransformation {
|
||||||
})
|
})
|
||||||
.width(30)
|
.width(30)
|
||||||
.height(30)
|
.height(30)
|
||||||
Text('反转效果').fontSize(20)
|
Text($r('app.string.Inverse_effect')).fontSize(20)
|
||||||
}
|
}
|
||||||
|
|
||||||
Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
|
Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
|
||||||
|
@ -130,7 +130,7 @@ struct ImageTransformation {
|
||||||
})
|
})
|
||||||
.width(30)
|
.width(30)
|
||||||
.height(30)
|
.height(30)
|
||||||
Text('动画滤镜效果').fontSize(20)
|
Text($r('app.string.Animation_filter_effect')).fontSize(20)
|
||||||
}
|
}
|
||||||
|
|
||||||
Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
|
Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
|
||||||
|
@ -143,7 +143,7 @@ struct ImageTransformation {
|
||||||
})
|
})
|
||||||
.width(30)
|
.width(30)
|
||||||
.height(30)
|
.height(30)
|
||||||
Text('裁剪圆形效果').fontSize(20)
|
Text($r('app.string.Crop_circular_effect')).fontSize(20)
|
||||||
}
|
}
|
||||||
|
|
||||||
Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
|
Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
|
||||||
|
@ -156,7 +156,7 @@ struct ImageTransformation {
|
||||||
})
|
})
|
||||||
.width(30)
|
.width(30)
|
||||||
.height(30)
|
.height(30)
|
||||||
Text('裁剪圆形带边框效果').fontSize(20)
|
Text($r('app.string.Crop_circular_with_border_effect')).fontSize(20)
|
||||||
}
|
}
|
||||||
|
|
||||||
Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
|
Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
|
||||||
|
@ -168,7 +168,7 @@ struct ImageTransformation {
|
||||||
})
|
})
|
||||||
.width(30)
|
.width(30)
|
||||||
.height(30)
|
.height(30)
|
||||||
Text('对比度效果').fontSize(20)
|
Text($r('app.string.Contrast_effect')).fontSize(20)
|
||||||
}
|
}
|
||||||
|
|
||||||
Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
|
Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
|
||||||
|
@ -181,7 +181,7 @@ struct ImageTransformation {
|
||||||
})
|
})
|
||||||
.width(30)
|
.width(30)
|
||||||
.height(30)
|
.height(30)
|
||||||
Text('乌墨色滤波效果').fontSize(20)
|
Text($r('app.string.Black_ink_filtering_effect')).fontSize(20)
|
||||||
}
|
}
|
||||||
|
|
||||||
Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
|
Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
|
||||||
|
@ -193,7 +193,7 @@ struct ImageTransformation {
|
||||||
})
|
})
|
||||||
.width(30)
|
.width(30)
|
||||||
.height(30)
|
.height(30)
|
||||||
Text('旋转效果').fontSize(20)
|
Text($r('app.string.Rotate')).fontSize(20)
|
||||||
}
|
}
|
||||||
|
|
||||||
Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
|
Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
|
||||||
|
@ -206,7 +206,7 @@ struct ImageTransformation {
|
||||||
})
|
})
|
||||||
.width(30)
|
.width(30)
|
||||||
.height(30)
|
.height(30)
|
||||||
Text('圆角效果').fontSize(20)
|
Text($r('app.string.Corners')).fontSize(20)
|
||||||
}
|
}
|
||||||
|
|
||||||
Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
|
Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
|
||||||
|
@ -219,7 +219,7 @@ struct ImageTransformation {
|
||||||
})
|
})
|
||||||
.width(30)
|
.width(30)
|
||||||
.height(30)
|
.height(30)
|
||||||
Text('桑原滤波效果').fontSize(20)
|
Text($r('app.string.Kuwahara_Filter_effect')).fontSize(20)
|
||||||
}
|
}
|
||||||
|
|
||||||
Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
|
Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
|
||||||
|
@ -232,7 +232,7 @@ struct ImageTransformation {
|
||||||
})
|
})
|
||||||
.width(30)
|
.width(30)
|
||||||
.height(30)
|
.height(30)
|
||||||
Text('像素化滤波效果').fontSize(20)
|
Text($r('app.string.Pixelated_Filter_effect')).fontSize(20)
|
||||||
}
|
}
|
||||||
|
|
||||||
Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
|
Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
|
||||||
|
@ -245,7 +245,7 @@ struct ImageTransformation {
|
||||||
})
|
})
|
||||||
.width(30)
|
.width(30)
|
||||||
.height(30)
|
.height(30)
|
||||||
Text('素描滤波效果').fontSize(20)
|
Text($r('app.string.Sketch_Filter_effect')).fontSize(20)
|
||||||
}
|
}
|
||||||
|
|
||||||
Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
|
Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
|
||||||
|
@ -258,7 +258,7 @@ struct ImageTransformation {
|
||||||
})
|
})
|
||||||
.width(30)
|
.width(30)
|
||||||
.height(30)
|
.height(30)
|
||||||
Text('扭曲滤波效果').fontSize(20)
|
Text($r('app.string.Distortion_Filter_effect')).fontSize(20)
|
||||||
}
|
}
|
||||||
|
|
||||||
Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
|
Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
|
||||||
|
@ -271,7 +271,7 @@ struct ImageTransformation {
|
||||||
})
|
})
|
||||||
.width(30)
|
.width(30)
|
||||||
.height(30)
|
.height(30)
|
||||||
Text('装饰滤波效果').fontSize(20)
|
Text($r('app.string.Decorative_Filter_effect')).fontSize(20)
|
||||||
}
|
}
|
||||||
|
|
||||||
Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
|
Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
|
||||||
|
@ -284,7 +284,7 @@ struct ImageTransformation {
|
||||||
})
|
})
|
||||||
.width(30)
|
.width(30)
|
||||||
.height(30)
|
.height(30)
|
||||||
Text('正方形裁剪效果').fontSize(20)
|
Text($r('app.string.Square_cutting_effect')).fontSize(20)
|
||||||
}
|
}
|
||||||
|
|
||||||
Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
|
Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
|
||||||
|
@ -297,7 +297,7 @@ struct ImageTransformation {
|
||||||
})
|
})
|
||||||
.width(30)
|
.width(30)
|
||||||
.height(30)
|
.height(30)
|
||||||
Text('上方裁剪效果').fontSize(20)
|
Text($r('app.string.Top_cutting_effect')).fontSize(20)
|
||||||
}
|
}
|
||||||
|
|
||||||
Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
|
Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
|
||||||
|
@ -310,7 +310,7 @@ struct ImageTransformation {
|
||||||
})
|
})
|
||||||
.width(30)
|
.width(30)
|
||||||
.height(30)
|
.height(30)
|
||||||
Text('中间裁剪效果').fontSize(20)
|
Text($r('app.string.Middle_cutting_effect')).fontSize(20)
|
||||||
}
|
}
|
||||||
|
|
||||||
Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
|
Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
|
||||||
|
@ -323,7 +323,7 @@ struct ImageTransformation {
|
||||||
})
|
})
|
||||||
.width(30)
|
.width(30)
|
||||||
.height(30)
|
.height(30)
|
||||||
Text('底下裁剪效果').fontSize(20)
|
Text($r('app.string.Bottom_cutting_effect')).fontSize(20)
|
||||||
}
|
}
|
||||||
|
|
||||||
Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
|
Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
|
||||||
|
@ -336,7 +336,7 @@ struct ImageTransformation {
|
||||||
})
|
})
|
||||||
.width(30)
|
.width(30)
|
||||||
.height(30)
|
.height(30)
|
||||||
Text('遮罩效果').fontSize(20)
|
Text($r('app.string.Mask_effect')).fontSize(20)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.isContrast) {
|
if (this.isContrast) {
|
||||||
|
@ -412,14 +412,14 @@ struct ImageTransformation {
|
||||||
if (this.isMask) {
|
if (this.isMask) {
|
||||||
transformations.push(new MaskTransformation($r('app.media.mask_starfish')));
|
transformations.push(new MaskTransformation($r('app.media.mask_starfish')));
|
||||||
}
|
}
|
||||||
this.imageKnifeOption = {
|
this.imageKnifeOption = new ImageKnifeOption({
|
||||||
loadSrc: $r('app.media.pngSample'),
|
loadSrc: $r('app.media.pngSample'),
|
||||||
placeholderSrc: $r("app.media.loading"),
|
placeholderSrc: $r("app.media.loading"),
|
||||||
errorholderSrc: $r("app.media.app_icon"),
|
errorholderSrc: $r("app.media.app_icon"),
|
||||||
objectFit: ImageFit.Contain,
|
objectFit: ImageFit.Contain,
|
||||||
border: { radius: this.isRound ? { topLeft: 50, bottomRight: 50 } : 0 },
|
border: { radius: this.isRound ? { topLeft: 50, bottomRight: 50 } : 0 },
|
||||||
transformation: transformations.length > 0 ? new MultiTransTransformation(transformations) : undefined
|
transformation: transformations.length > 0 ? new MultiTransTransformation(transformations) : undefined
|
||||||
}
|
})
|
||||||
if (this.isCropCircle) {
|
if (this.isCropCircle) {
|
||||||
this.imageKnifeOption.objectFit = ImageFit.Cover;
|
this.imageKnifeOption.objectFit = ImageFit.Cover;
|
||||||
this.imageKnifeOption.border = { radius: 150 };
|
this.imageKnifeOption.border = { radius: 150 };
|
||||||
|
|
|
@ -15,147 +15,172 @@
|
||||||
import router from '@system.router';
|
import router from '@system.router';
|
||||||
|
|
||||||
@Entry
|
@Entry
|
||||||
@Component
|
@ComponentV2
|
||||||
struct Index {
|
struct Index {
|
||||||
|
getResourceString(res: Resource) {
|
||||||
|
return getContext().resourceManager.getStringSync(res.id)
|
||||||
|
}
|
||||||
|
|
||||||
aboutToAppear(): void {
|
aboutToAppear(): void {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
build() {
|
build() {
|
||||||
Scroll(){
|
Scroll() {
|
||||||
Column() {
|
Column() {
|
||||||
Button("测试ImageAnimator组件").onClick(()=>{
|
Button($r('app.string.Test_ImageAnimator')).onClick(() => {
|
||||||
router.push({
|
router.push({
|
||||||
uri: 'pages/ImageAnimatorPage',
|
uri: 'pages/ImageAnimatorPage',
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
Button("测试加载多张相同图片").margin({top:10}).onClick(()=>{
|
Button($r('app.string.Test_multiple_images')).margin({ top: 10 }).onClick(() => {
|
||||||
router.push({
|
router.push({
|
||||||
uri: 'pages/TestCommonImage',
|
uri: 'pages/TestCommonImage',
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
Button("测试HSP场景预加载").margin({top:10}).onClick(()=>{
|
Button(this.getResourceString($r('app.string.Multiple_images')) + " + reuse + LazyForeach")
|
||||||
router.push({
|
.margin({ top: 10 })
|
||||||
uri: 'pages/TestHspPreLoadImage',
|
.onClick(() => {
|
||||||
|
router.push({
|
||||||
|
uri: 'pages/UserPage',
|
||||||
|
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
Button("单个图片使用").margin({top:10}).onClick(()=>{
|
Button($r('app.string.Test_SingleImage')).margin({ top: 10 }).onClick(() => {
|
||||||
router.push({
|
router.push({
|
||||||
uri: 'pages/SingleImage',
|
uri: 'pages/SingleImage',
|
||||||
|
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
Button("全局自定义下载").margin({top:10}).onClick(()=>{
|
Button($r('app.string.Image_Downsampling_Functionality')).margin({top:10}).onClick(()=>{
|
||||||
router.push({
|
router.push({
|
||||||
uri: 'pages/TestSetCustomImagePage',
|
uri: 'pages/DownSamplePage',
|
||||||
|
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
Button("多图 + LazyForEach").margin({top:10}).onClick(()=>{
|
Button($r('app.string.Display_long_image')).margin({ top: 10 }).onClick(() => {
|
||||||
router.push({
|
|
||||||
uri: 'pages/ManyPhotoShowPage',
|
|
||||||
|
|
||||||
});
|
|
||||||
})
|
|
||||||
Button("多图 + reuse + LazyForeach").margin({top:10}).onClick(()=>{
|
|
||||||
router.push({
|
|
||||||
uri: 'pages/UserPage',
|
|
||||||
|
|
||||||
});
|
|
||||||
})
|
|
||||||
Button("长图显示").margin({top:10}).onClick(()=>{
|
|
||||||
router.push({
|
router.push({
|
||||||
uri: 'pages/LongImagePage',
|
uri: 'pages/LongImagePage',
|
||||||
|
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
Button("缩放图片").margin({top:10}).onClick(()=>{
|
Button($r('app.string.Image_Transformation')).margin({ top: 10 }).onClick(() => {
|
||||||
router.push({
|
|
||||||
uri: 'pages/TransformPage',
|
|
||||||
|
|
||||||
});
|
|
||||||
})
|
|
||||||
Button("消息+List").margin({top:10}).onClick(()=>{
|
|
||||||
router.push({
|
|
||||||
uri: 'pages/TestImageFlash',
|
|
||||||
|
|
||||||
});
|
|
||||||
})
|
|
||||||
Button("自定义缓存key").margin({top:10}).onClick(()=>{
|
|
||||||
router.push({
|
|
||||||
uri: 'pages/SignatureTestPage',
|
|
||||||
|
|
||||||
});
|
|
||||||
})
|
|
||||||
Button("预加载图片到文件缓存").margin({top:10}).onClick(()=>{
|
|
||||||
router.push({
|
|
||||||
uri: 'pages/TestPrefetchToFileCache',
|
|
||||||
|
|
||||||
});
|
|
||||||
})
|
|
||||||
Button("从缓存获取图片显示").margin({top:10}).onClick(()=>{
|
|
||||||
router.push({
|
|
||||||
uri: 'pages/TestIsUrlExist',
|
|
||||||
|
|
||||||
});
|
|
||||||
})
|
|
||||||
Button("测试单个请求头").margin({top:10}).onClick(()=>{
|
|
||||||
router.push({
|
|
||||||
uri: 'pages/TestHeader',
|
|
||||||
|
|
||||||
});
|
|
||||||
})
|
|
||||||
Button("测试写入缓存策略").margin({top:10}).onClick(()=>{
|
|
||||||
router.push({
|
|
||||||
uri: 'pages/TestWriteCacheStage',
|
|
||||||
|
|
||||||
});
|
|
||||||
})
|
|
||||||
Button("图片变换").margin({top:10}).onClick(()=>{
|
|
||||||
router.push({
|
router.push({
|
||||||
uri: 'pages/ImageTransformation',
|
uri: 'pages/ImageTransformation',
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
})
|
})
|
||||||
|
Button($r('app.string.Test_media_URL')).margin({ top: 10 }).onClick(() => {
|
||||||
|
router.push({
|
||||||
|
uri: 'pages/dataShareUriLoadPage',
|
||||||
|
|
||||||
Button("不同的ObjectFit").margin({top:10}).onClick(()=>{
|
});
|
||||||
|
})
|
||||||
|
Button($r('app.string.Different_ObjectFit')).margin({ top: 10 }).onClick(() => {
|
||||||
router.push({
|
router.push({
|
||||||
uri: 'pages/ObjectFitPage',
|
uri: 'pages/ObjectFitPage',
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
})
|
})
|
||||||
|
Button($r('app.string.Custom_cache_key')).margin({ top: 10 }).onClick(() => {
|
||||||
|
router.push({
|
||||||
|
uri: 'pages/SignatureTestPage',
|
||||||
|
|
||||||
Button('测试图片加载成功/失败事件').margin({top:10}).onClick(()=>{
|
});
|
||||||
|
})
|
||||||
|
Button($r('app.string.Test_image_loading_success_or_failure_events')).margin({ top: 10 }).onClick(() => {
|
||||||
router.push({
|
router.push({
|
||||||
uri: 'pages/LoadStatePage',
|
uri: 'pages/LoadStatePage',
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
Button($r('app.string.Image_scaling')).margin({ top: 10 }).onClick(() => {
|
||||||
|
router.push({
|
||||||
|
uri: 'pages/TransformPage',
|
||||||
|
|
||||||
Button('测试移除图片缓存接口').margin({top:10}).onClick(()=>{
|
});
|
||||||
|
})
|
||||||
|
|
||||||
|
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',
|
||||||
|
|
||||||
|
});
|
||||||
|
})
|
||||||
|
Button($r('app.string.Retrieve_image_display_from_cache')).margin({ top: 10 }).onClick(() => {
|
||||||
|
router.push({
|
||||||
|
uri: 'pages/TestIsUrlExist',
|
||||||
|
|
||||||
|
});
|
||||||
|
})
|
||||||
|
Button($r('app.string.Test_single_request_header')).margin({ top: 10 }).onClick(() => {
|
||||||
|
router.push({
|
||||||
|
uri: 'pages/TestHeader',
|
||||||
|
|
||||||
|
});
|
||||||
|
})
|
||||||
|
Button($r('app.string.Test_write_cache_strategy')).margin({ top: 10 }).onClick(() => {
|
||||||
|
router.push({
|
||||||
|
uri: 'pages/TestWriteCacheStage',
|
||||||
|
|
||||||
|
});
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
Button($r('app.string.Test_removing_image_cache_interface')).margin({ top: 10 }).onClick(() => {
|
||||||
router.push({
|
router.push({
|
||||||
uri: 'pages/TestRemoveCache',
|
uri: 'pages/TestRemoveCache',
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
Button("测试错误图显示").margin({top:10}).onClick(()=>{
|
Button($r('app.string.Test_error_image_display')).margin({ top: 10 }).onClick(() => {
|
||||||
router.push({
|
router.push({
|
||||||
uri: 'pages/TestErrorHolderPage',
|
uri: 'pages/TestErrorHolderPage',
|
||||||
|
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
Button("测试媒体url").margin({top:10}).onClick(()=>{
|
Button($r('app.string.Test_Task_error')).margin({ top: 10 }).onClick(() => {
|
||||||
router.push({
|
router.push({
|
||||||
uri: 'pages/dataShareUriLoadPage',
|
uri: 'pages/TestTaskResourcePage',
|
||||||
|
});
|
||||||
|
})
|
||||||
|
Button($r('app.string.test_cache_btn')).margin({ top: 10 }).onClick(() => {
|
||||||
|
router.push({
|
||||||
|
uri: 'pages/TestCacheDataPage',
|
||||||
|
});
|
||||||
|
})
|
||||||
|
Button($r('app.string.test_change_color_btn')).margin({ top: 10 }).onClick(() => {
|
||||||
|
router.push({
|
||||||
|
uri: 'pages/TestChangeColorPage',
|
||||||
|
});
|
||||||
|
})
|
||||||
|
Button($r('app.string.test_cancel_callback_btn')).margin({ top: 10 }).onClick(() => {
|
||||||
|
router.push({
|
||||||
|
uri: 'pages/TestLoadCancelListenerPage',
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
} .width('100%')
|
}.width('100%')
|
||||||
.height('100%')
|
.height('100%')
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -15,11 +15,11 @@
|
||||||
import { ImageKnifeComponent, ImageKnifeOption } from '@ohos/libraryimageknife';
|
import { ImageKnifeComponent, ImageKnifeOption } from '@ohos/libraryimageknife';
|
||||||
|
|
||||||
@Entry
|
@Entry
|
||||||
@Component
|
@ComponentV2
|
||||||
struct ListPage {
|
struct ListPage {
|
||||||
|
|
||||||
private data: string[] = []
|
private data: string[] = []
|
||||||
@State ImageKnifeOption: ImageKnifeOption = { loadSrc: $r('app.media.startIcon')}
|
@Local ImageKnifeOption: ImageKnifeOption = new ImageKnifeOption({ loadSrc: $r('app.media.startIcon')})
|
||||||
|
|
||||||
|
|
||||||
aboutToAppear(): void {
|
aboutToAppear(): void {
|
||||||
|
|
|
@ -16,12 +16,12 @@ import { ImageKnifeComponent, ImageKnifeOption } from "@ohos/libraryimageknife"
|
||||||
import matrix4 from '@ohos.matrix4'
|
import matrix4 from '@ohos.matrix4'
|
||||||
|
|
||||||
@Entry
|
@Entry
|
||||||
@Component
|
@ComponentV2
|
||||||
struct LoadStatePage {
|
struct LoadStatePage {
|
||||||
|
|
||||||
starTime:number = new Date().getTime()
|
starTime:number = new Date().getTime()
|
||||||
|
|
||||||
@State ImageKnifeOption: ImageKnifeOption = {
|
@Local ImageKnifeOption: ImageKnifeOption = new ImageKnifeOption({
|
||||||
loadSrc: $r("app.media.rabbit"),
|
loadSrc: $r("app.media.rabbit"),
|
||||||
placeholderSrc: $r("app.media.loading"),
|
placeholderSrc: $r("app.media.loading"),
|
||||||
errorholderSrc: $r("app.media.app_icon"),
|
errorholderSrc: $r("app.media.app_icon"),
|
||||||
|
@ -35,22 +35,22 @@ struct LoadStatePage {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
border: { radius: 50 }
|
border: { radius: 50 }
|
||||||
}
|
})
|
||||||
@State imageKnifeOption1: ImageKnifeOption = {
|
@Local imageKnifeOption1: ImageKnifeOption = new ImageKnifeOption({
|
||||||
loadSrc: $r('app.media.startIcon')
|
loadSrc: $r('app.media.startIcon')
|
||||||
}
|
})
|
||||||
@State message: string = ""
|
@Local message: string = ""
|
||||||
@State currentWidth: number = 200
|
@Local currentWidth: number = 200
|
||||||
@State currentHeight: number = 200
|
@Local currentHeight: number = 200
|
||||||
@State typeValue: string = ""
|
@Local typeValue: string = ""
|
||||||
build() {
|
build() {
|
||||||
Column() {
|
Column() {
|
||||||
Text('测试失败场景请先关闭网络,并保证本地没有此网络图片的缓存')
|
Text($r('app.string.TIPS'))
|
||||||
.margin({ top: 20 })
|
.margin({ top: 20 })
|
||||||
Row() {
|
Row() {
|
||||||
Button('测试失败/成功场景')
|
Button($r('app.string.Test_failure_success'))
|
||||||
.onClick(() => {
|
.onClick(() => {
|
||||||
this.ImageKnifeOption = {
|
this.ImageKnifeOption = new ImageKnifeOption({
|
||||||
loadSrc: "https://www.openharmony.cn/_nuxt/img/logo.dcf95b3.png",
|
loadSrc: "https://www.openharmony.cn/_nuxt/img/logo.dcf95b3.png",
|
||||||
placeholderSrc: $r("app.media.loading"),
|
placeholderSrc: $r("app.media.loading"),
|
||||||
errorholderSrc: $r("app.media.app_icon"),
|
errorholderSrc: $r("app.media.app_icon"),
|
||||||
|
@ -75,15 +75,17 @@ struct LoadStatePage {
|
||||||
onComplete:(event)=>{
|
onComplete:(event)=>{
|
||||||
console.error("Load onComplete width:"+event?.width , " height:"+event?.height , " componentWidth:"+event?.componentWidth," componentHeight:" + event?.componentHeight);
|
console.error("Load onComplete width:"+event?.width , " height:"+event?.height , " componentWidth:"+event?.componentWidth," componentHeight:" + event?.componentHeight);
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
.margin({ top: 20 })
|
.margin({ top: 20 })
|
||||||
Text(this.typeValue)
|
Text($r('app.string.image_format',this.typeValue))
|
||||||
|
Text($r('app.string.image_width',this.currentWidth))
|
||||||
|
Text($r('app.string.image_height',this.currentHeight))
|
||||||
ImageKnifeComponent({ imageKnifeOption: this.ImageKnifeOption }).height(this.currentHeight).width(this.currentWidth)
|
ImageKnifeComponent({ imageKnifeOption: this.ImageKnifeOption }).height(this.currentHeight).width(this.currentWidth)
|
||||||
.margin({ top: 20 })
|
.margin({ top: 20 })
|
||||||
Button("自定义下载失败").onClick(()=>{
|
Button($r('app.string.Custom_download_failed')).onClick(()=>{
|
||||||
this.imageKnifeOption1 = {
|
this.imageKnifeOption1 = new ImageKnifeOption({
|
||||||
loadSrc: "abc",
|
loadSrc: "abc",
|
||||||
placeholderSrc:$r('app.media.loading'),
|
placeholderSrc:$r('app.media.loading'),
|
||||||
errorholderSrc:$r('app.media.failed'),
|
errorholderSrc:$r('app.media.failed'),
|
||||||
|
@ -93,7 +95,7 @@ struct LoadStatePage {
|
||||||
this.message = "err:" + err
|
this.message = "err:" + err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
}).margin({ top: 20 })
|
}).margin({ top: 20 })
|
||||||
Text(this.message).fontSize(20).margin({ top: 20 })
|
Text(this.message).fontSize(20).margin({ top: 20 })
|
||||||
ImageKnifeComponent({ imageKnifeOption: this.imageKnifeOption1 }).height(this.currentHeight).width(this.currentWidth)
|
ImageKnifeComponent({ imageKnifeOption: this.imageKnifeOption1 }).height(this.currentHeight).width(this.currentWidth)
|
||||||
|
|
|
@ -12,10 +12,10 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
import { ImageKnifeComponent } from '@ohos/libraryimageknife'
|
import { ImageKnifeComponent,ImageKnifeOption } from '@ohos/libraryimageknife'
|
||||||
|
|
||||||
@Entry
|
@Entry
|
||||||
@Component
|
@ComponentV2
|
||||||
struct LongImagePage {
|
struct LongImagePage {
|
||||||
|
|
||||||
build() {
|
build() {
|
||||||
|
@ -25,13 +25,13 @@ struct LongImagePage {
|
||||||
|
|
||||||
// Image($r("app.media.aaa")).objectFit(ImageFit.Auto).width(200)
|
// Image($r("app.media.aaa")).objectFit(ImageFit.Auto).width(200)
|
||||||
ImageKnifeComponent({
|
ImageKnifeComponent({
|
||||||
imageKnifeOption: {
|
imageKnifeOption: new ImageKnifeOption({
|
||||||
loadSrc:"https://wx2.sinaimg.cn/mw690/006HyQKGgy1hnqp08dw09j30u04twu0x.jpg",
|
loadSrc:"https://wx2.sinaimg.cn/mw690/006HyQKGgy1hnqp08dw09j30u04twu0x.jpg",
|
||||||
//src:$r("app.media.aaa"),
|
//src:$r("app.media.aaa"),
|
||||||
placeholderSrc: $r("app.media.loading"),
|
placeholderSrc: $r("app.media.loading"),
|
||||||
errorholderSrc: $r("app.media.failed"),
|
errorholderSrc: $r("app.media.failed"),
|
||||||
objectFit: ImageFit.Auto
|
objectFit: ImageFit.Auto
|
||||||
}
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
.height('100%') .width('100%')
|
.height('100%') .width('100%')
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -15,49 +15,49 @@
|
||||||
import { ImageKnife, ImageKnifeComponent, ImageKnifeOption } from '@ohos/libraryimageknife'
|
import { ImageKnife, ImageKnifeComponent, ImageKnifeOption } from '@ohos/libraryimageknife'
|
||||||
|
|
||||||
@Entry
|
@Entry
|
||||||
@Component
|
@ComponentV2
|
||||||
struct ObjectFitPage {
|
struct ObjectFitPage {
|
||||||
@State imageKnifeOption: ImageKnifeOption = {
|
@Local imageKnifeOption: ImageKnifeOption = new ImageKnifeOption({
|
||||||
loadSrc: $r("app.media.app_icon"),
|
loadSrc: $r("app.media.app_icon"),
|
||||||
placeholderSrc: $r("app.media.loading"),
|
placeholderSrc: $r("app.media.loading"),
|
||||||
errorholderSrc: $r("app.media.app_icon"),
|
errorholderSrc: $r("app.media.app_icon"),
|
||||||
objectFit: ImageFit.Fill
|
objectFit: ImageFit.Fill
|
||||||
}
|
})
|
||||||
|
|
||||||
build() {
|
build() {
|
||||||
Column() {
|
Column() {
|
||||||
|
|
||||||
Button("主图Fill拉伸填充").onClick(()=>{
|
Button($r('app.string.Main_image_Fill')).onClick(()=>{
|
||||||
this.imageKnifeOption = {
|
this.imageKnifeOption = new ImageKnifeOption({
|
||||||
loadSrc: $r("app.media.app_icon"),
|
loadSrc: $r("app.media.app_icon"),
|
||||||
placeholderSrc: $r("app.media.loading"),
|
placeholderSrc: $r("app.media.loading"),
|
||||||
errorholderSrc: $r("app.media.app_icon"),
|
errorholderSrc: $r("app.media.app_icon"),
|
||||||
objectFit: ImageFit.Fill
|
objectFit: ImageFit.Fill
|
||||||
}
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
Button("占位图Contain保持比例填充").margin({top:10}).onClick(async () => {
|
Button($r('app.string.Maintain_proportion_filling')).margin({top:10}).onClick(async () => {
|
||||||
ImageKnife.getInstance().removeAllMemoryCache()
|
ImageKnife.getInstance().removeAllMemoryCache()
|
||||||
await ImageKnife.getInstance().removeAllFileCache()
|
await ImageKnife.getInstance().removeAllFileCache()
|
||||||
|
|
||||||
this.imageKnifeOption = {
|
this.imageKnifeOption = new ImageKnifeOption({
|
||||||
loadSrc: "https://wx2.sinaimg.cn/mw690/006HyQKGgy1hnqp08dw09j30u04twu0x.jpg",
|
loadSrc: "https://wx2.sinaimg.cn/mw690/006HyQKGgy1hnqp08dw09j30u04twu0x.jpg",
|
||||||
placeholderSrc: $r("app.media.app_icon"),
|
placeholderSrc: $r("app.media.app_icon"),
|
||||||
errorholderSrc: $r("app.media.app_icon"),
|
errorholderSrc: $r("app.media.app_icon"),
|
||||||
objectFit: ImageFit.Fill,
|
objectFit: ImageFit.Fill,
|
||||||
placeholderObjectFit: ImageFit.Contain
|
placeholderObjectFit: ImageFit.Contain
|
||||||
}
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
Button("错误图None不变化").margin({top:10}).onClick(() => {
|
Button($r('app.string.Error_graph_None')).margin({top:10}).onClick(() => {
|
||||||
this.imageKnifeOption = {
|
this.imageKnifeOption = new ImageKnifeOption({
|
||||||
loadSrc: "http://xxxxx",
|
loadSrc: "http://xxxxx",
|
||||||
placeholderSrc: $r("app.media.loading"),
|
placeholderSrc: $r("app.media.loading"),
|
||||||
errorholderSrc: $r("app.media.app_icon"),
|
errorholderSrc: $r("app.media.app_icon"),
|
||||||
objectFit: ImageFit.Fill,
|
objectFit: ImageFit.Fill,
|
||||||
errorholderObjectFit: ImageFit.None
|
errorholderObjectFit: ImageFit.None
|
||||||
}
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
ImageKnifeComponent({
|
ImageKnifeComponent({
|
||||||
|
|
|
@ -16,45 +16,45 @@ import { ImageKnifeComponent, ImageKnifeOption } from '@ohos/libraryimageknife';
|
||||||
|
|
||||||
|
|
||||||
@Entry
|
@Entry
|
||||||
@Component
|
@ComponentV2
|
||||||
struct SignatureTestPage {
|
struct SignatureTestPage {
|
||||||
@State imageKnifeOption1: ImageKnifeOption =
|
@Local imageKnifeOption1: ImageKnifeOption =new ImageKnifeOption(
|
||||||
{
|
{
|
||||||
loadSrc: $r('app.media.icon'),
|
loadSrc: $r('app.media.icon'),
|
||||||
placeholderSrc:$r("app.media.loading"),
|
placeholderSrc:$r("app.media.loading"),
|
||||||
};
|
});
|
||||||
@State imageKnifeOption2: ImageKnifeOption =
|
@Local imageKnifeOption2: ImageKnifeOption =new ImageKnifeOption(
|
||||||
{
|
{
|
||||||
loadSrc: $r('app.media.icon'),
|
loadSrc: $r('app.media.icon'),
|
||||||
placeholderSrc:$r("app.media.loading"),
|
placeholderSrc:$r("app.media.loading"),
|
||||||
};
|
});
|
||||||
|
|
||||||
build() {
|
build() {
|
||||||
Scroll() {
|
Scroll() {
|
||||||
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
||||||
|
|
||||||
Text("key固定为 1").fontSize(15)
|
Text($r('app.string.The_key_fixed_1')).fontSize(15)
|
||||||
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
||||||
Button("加载")
|
Button($r('app.string.Load'))
|
||||||
.onClick(() => {
|
.onClick(() => {
|
||||||
this.imageKnifeOption1 = {
|
this.imageKnifeOption1 = new ImageKnifeOption({
|
||||||
loadSrc: 'https://img-blog.csdn.net/20140514114029140',
|
loadSrc: 'https://img-blog.csdn.net/20140514114029140',
|
||||||
placeholderSrc:$r("app.media.loading"),
|
placeholderSrc:$r("app.media.loading"),
|
||||||
signature: "1"
|
signature: "1"
|
||||||
}
|
})
|
||||||
}).margin({ top: 5, left: 3 })
|
}).margin({ top: 5, left: 3 })
|
||||||
ImageKnifeComponent({ imageKnifeOption: this.imageKnifeOption1 }).width(300).height(300)
|
ImageKnifeComponent({ imageKnifeOption: this.imageKnifeOption1 }).width(300).height(300)
|
||||||
}.width('100%').backgroundColor(Color.Pink)
|
}.width('100%').backgroundColor(Color.Pink)
|
||||||
|
|
||||||
Text("key每次变化:时间戳").fontSize(15)
|
Text($r('app.string.The_key_changes_timestamp')).fontSize(15)
|
||||||
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
||||||
Button("加载")
|
Button($r('app.string.Load'))
|
||||||
.onClick(() => {
|
.onClick(() => {
|
||||||
this.imageKnifeOption2 = {
|
this.imageKnifeOption2 = new ImageKnifeOption({
|
||||||
loadSrc: 'https://img-blog.csdn.net/20140514114029140',
|
loadSrc: 'https://img-blog.csdn.net/20140514114029140',
|
||||||
placeholderSrc:$r("app.media.loading"),
|
placeholderSrc:$r("app.media.loading"),
|
||||||
signature: new Date().getTime().toString()
|
signature: new Date().getTime().toString()
|
||||||
}
|
})
|
||||||
}).margin({ top: 5, left: 3 })
|
}).margin({ top: 5, left: 3 })
|
||||||
ImageKnifeComponent({ imageKnifeOption: this.imageKnifeOption2 }).width(300).height(300)
|
ImageKnifeComponent({ imageKnifeOption: this.imageKnifeOption2 }).width(300).height(300)
|
||||||
}.width('100%').backgroundColor(Color.Pink)
|
}.width('100%').backgroundColor(Color.Pink)
|
||||||
|
|
|
@ -12,19 +12,19 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
import { ImageKnifeComponent,BlurTransformation } from '@ohos/libraryimageknife';
|
import { ImageKnifeComponent,BlurTransformation,ImageKnifeOption } from '@ohos/libraryimageknife';
|
||||||
import fs from '@ohos.file.fs';
|
import fs from '@ohos.file.fs';
|
||||||
import image from '@ohos.multimedia.image';
|
import image from '@ohos.multimedia.image';
|
||||||
import { common2D, drawing } from '@kit.ArkGraphics2D';
|
import { common2D, drawing } from '@kit.ArkGraphics2D';
|
||||||
|
|
||||||
@Entry
|
@Entry
|
||||||
@Component
|
@ComponentV2
|
||||||
struct SingleImage {
|
struct SingleImage {
|
||||||
resource: string = "app.media.svgSample"
|
resource: string = "app.media.svgSample"
|
||||||
scroller: Scroller = new Scroller;
|
scroller: Scroller = new Scroller;
|
||||||
localFile: string = getContext(this).filesDir + "/icon.png"
|
localFile: string = getContext(this).filesDir + "/icon.png"
|
||||||
@State pixelMap:PixelMap | undefined = undefined;
|
@Local pixelMap:PixelMap | undefined = undefined;
|
||||||
@State DrawingColorFilter: ColorFilter | undefined = undefined
|
@Local DrawingColorFilter: ColorFilter | undefined = undefined
|
||||||
private color: common2D.Color = { alpha: 255, red: 255, green: 0, blue: 0 };
|
private color: common2D.Color = { alpha: 255, red: 255, green: 0, blue: 0 };
|
||||||
aboutToAppear(): void {
|
aboutToAppear(): void {
|
||||||
// 拷贝本地文件
|
// 拷贝本地文件
|
||||||
|
@ -42,66 +42,66 @@ struct SingleImage {
|
||||||
build() {
|
build() {
|
||||||
Scroll(this.scroller) {
|
Scroll(this.scroller) {
|
||||||
Column() {
|
Column() {
|
||||||
Text("本地资源svg图片")
|
Text($r('app.string.Local_SVG'))
|
||||||
.fontSize(30)
|
.fontSize(30)
|
||||||
.fontWeight(FontWeight.Bold)
|
.fontWeight(FontWeight.Bold)
|
||||||
ImageKnifeComponent({
|
ImageKnifeComponent({
|
||||||
imageKnifeOption: {
|
imageKnifeOption: new ImageKnifeOption({
|
||||||
loadSrc: $r("app.media.svgSample"),
|
loadSrc: $r("app.media.svgSample"),
|
||||||
placeholderSrc: $r("app.media.loading"),
|
placeholderSrc: $r("app.media.loading"),
|
||||||
errorholderSrc: $r("app.media.failed"),
|
errorholderSrc: $r("app.media.failed"),
|
||||||
objectFit: ImageFit.Contain
|
objectFit: ImageFit.Contain
|
||||||
}
|
})
|
||||||
}).width(100).height(100)
|
}).width(100).height(100)
|
||||||
.onClick(()=>{
|
.onClick(()=>{
|
||||||
this.DrawingColorFilter = drawing.ColorFilter.createBlendModeColorFilter(this.color, drawing.BlendMode.SRC_IN);
|
this.DrawingColorFilter = drawing.ColorFilter.createBlendModeColorFilter(this.color, drawing.BlendMode.SRC_IN);
|
||||||
})
|
})
|
||||||
Text("本地context files下文件")
|
Text($r('app.string.Under_context_file'))
|
||||||
.fontSize(30)
|
.fontSize(30)
|
||||||
.fontWeight(FontWeight.Bold)
|
.fontWeight(FontWeight.Bold)
|
||||||
ImageKnifeComponent({
|
ImageKnifeComponent({
|
||||||
imageKnifeOption: {
|
imageKnifeOption: new ImageKnifeOption({
|
||||||
loadSrc: this.localFile,
|
loadSrc: this.localFile,
|
||||||
placeholderSrc: $r("app.media.loading"),
|
placeholderSrc: $r("app.media.loading"),
|
||||||
errorholderSrc: $r("app.media.failed"),
|
errorholderSrc: $r("app.media.failed"),
|
||||||
objectFit: ImageFit.Contain
|
objectFit: ImageFit.Contain
|
||||||
}
|
})
|
||||||
}).width(100).height(100)
|
}).width(100).height(100)
|
||||||
Text("网络图片")
|
Text($r('app.string.Network_images'))
|
||||||
.fontSize(30)
|
.fontSize(30)
|
||||||
.fontWeight(FontWeight.Bold)
|
.fontWeight(FontWeight.Bold)
|
||||||
ImageKnifeComponent({
|
ImageKnifeComponent({
|
||||||
imageKnifeOption: {
|
imageKnifeOption: new ImageKnifeOption({
|
||||||
loadSrc:"https://www.openharmony.cn/_nuxt/img/logo.dcf95b3.png",
|
loadSrc:"https://www.openharmony.cn/_nuxt/img/logo.dcf95b3.png",
|
||||||
placeholderSrc: $r("app.media.loading"),
|
placeholderSrc: $r("app.media.loading"),
|
||||||
errorholderSrc: $r("app.media.failed"),
|
errorholderSrc: $r("app.media.failed"),
|
||||||
objectFit: ImageFit.Contain,
|
objectFit: ImageFit.Contain,
|
||||||
progressListener:(progress:number)=>{console.info("ImageKnife:: call back progress = " + progress)}
|
progressListener:(progress:number)=>{console.info("ImageKnife:: call back progress = " + progress)}
|
||||||
}
|
})
|
||||||
}).width(100).height(100)
|
}).width(100).height(100)
|
||||||
Text("自定义下载")
|
Text($r('app.string.Custom_network_download'))
|
||||||
.fontSize(30)
|
.fontSize(30)
|
||||||
.fontWeight(FontWeight.Bold)
|
.fontWeight(FontWeight.Bold)
|
||||||
ImageKnifeComponent({
|
ImageKnifeComponent({
|
||||||
imageKnifeOption: {
|
imageKnifeOption: new ImageKnifeOption({
|
||||||
loadSrc: "https://file.atomgit.com/uploads/user/1704857786989_8994.jpeg",
|
loadSrc: "https://file.atomgit.com/uploads/user/1704857786989_8994.jpeg",
|
||||||
placeholderSrc: $r("app.media.loading"),
|
placeholderSrc: $r("app.media.loading"),
|
||||||
errorholderSrc: $r("app.media.failed"),
|
errorholderSrc: $r("app.media.failed"),
|
||||||
objectFit: ImageFit.Contain,
|
objectFit: ImageFit.Contain,
|
||||||
customGetImage: custom,
|
customGetImage: custom,
|
||||||
transformation: new BlurTransformation(10)
|
transformation: new BlurTransformation(10)
|
||||||
}
|
})
|
||||||
}).width(100).height(100)
|
}).width(100).height(100)
|
||||||
Text("pixelMap加载图片")
|
Text($r('app.string.PixelMap_loads_images'))
|
||||||
.fontSize(30)
|
.fontSize(30)
|
||||||
.fontWeight(FontWeight.Bold)
|
.fontWeight(FontWeight.Bold)
|
||||||
ImageKnifeComponent({
|
ImageKnifeComponent({
|
||||||
imageKnifeOption: {
|
imageKnifeOption: new ImageKnifeOption({
|
||||||
loadSrc: this.pixelMap!,
|
loadSrc: this.pixelMap!,
|
||||||
placeholderSrc: $r("app.media.loading"),
|
placeholderSrc: $r("app.media.loading"),
|
||||||
errorholderSrc: $r("app.media.failed"),
|
errorholderSrc: $r("app.media.failed"),
|
||||||
objectFit: ImageFit.Contain,
|
objectFit: ImageFit.Contain,
|
||||||
}
|
})
|
||||||
}).width(100).height(100)
|
}).width(100).height(100)
|
||||||
}
|
}
|
||||||
.width('100%')
|
.width('100%')
|
||||||
|
|
|
@ -0,0 +1,140 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2024 Huawei Device Co., Ltd.
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { ImageKnife, CacheStrategy, ImageKnifeComponent, ImageKnifeOption } from '@ohos/imageknife';
|
||||||
|
|
||||||
|
@Entry
|
||||||
|
@ComponentV2
|
||||||
|
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({
|
||||||
|
loadSrc: "",
|
||||||
|
objectFit: ImageFit.Contain,
|
||||||
|
onLoadListener: {
|
||||||
|
onLoadFailed: (err) => {
|
||||||
|
console.error("Load Failed Reason: " + err);
|
||||||
|
},
|
||||||
|
onLoadSuccess: (data) => {
|
||||||
|
return data;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
border: { radius: 50 }
|
||||||
|
})
|
||||||
|
|
||||||
|
aboutToAppear(): void {
|
||||||
|
ImageKnife.getInstance().initFileCache(getContext(this), 256, 256 * 1024 * 1024, "ImageKnifeCache1")
|
||||||
|
}
|
||||||
|
|
||||||
|
build() {
|
||||||
|
Column() {
|
||||||
|
|
||||||
|
ImageKnifeComponent(
|
||||||
|
{ imageKnifeOption: this.ImageKnifeOption })
|
||||||
|
.height(this.currentHeight)
|
||||||
|
.width(this.currentWidth)
|
||||||
|
.margin({ top: 10 })
|
||||||
|
|
||||||
|
Button($r('app.string.load_memory'))
|
||||||
|
.onClick(() => {
|
||||||
|
this.ImageKnifeOption = new 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({
|
||||||
|
loadSrc: "https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/56/v3/8MdhfSsCSMKj4sA6okUWrg/5uBx56tLTUO3RYQl-E5JiQ.jpg",
|
||||||
|
objectFit: ImageFit.Contain,
|
||||||
|
writeCacheStrategy: CacheStrategy.File,
|
||||||
|
border: { radius: 50 },
|
||||||
|
})
|
||||||
|
})
|
||||||
|
Text($r('app.string.cur_cache_limit', this.markersLimitText, this.cacheUpLimit))
|
||||||
|
.fontSize(20)
|
||||||
|
.margin({ bottom: 8 });
|
||||||
|
Text($r('app.string.cur_cache_image_num', this.markersNumText, this.currentNum))
|
||||||
|
.fontSize(20)
|
||||||
|
.margin({ bottom: 8 });
|
||||||
|
Text($r('app.string.cur_cache_size', this.markersSizeText, this.currentSize)).fontSize(20).margin({ bottom: 20 });
|
||||||
|
|
||||||
|
Button($r('app.string.get_cur_memory_limit')).onClick(() => {
|
||||||
|
let result = ImageKnife.getInstance().getCacheUpperLimit(CacheStrategy.Memory);
|
||||||
|
this.markersLimitText = getContext(this).resourceManager.getStringSync($r('app.string.memory'))
|
||||||
|
if (result) {
|
||||||
|
this.cacheUpLimit = result / (1024 * 1024);
|
||||||
|
} else {
|
||||||
|
this.cacheUpLimit = 0;
|
||||||
|
}
|
||||||
|
}).margin({ bottom: 8 });
|
||||||
|
Button($r('app.string.get_img_number_of_cache')).onClick(() => {
|
||||||
|
let result = ImageKnife.getInstance().getCurrentPicturesNum(CacheStrategy.Memory);
|
||||||
|
this.markersNumText = getContext(this).resourceManager.getStringSync($r('app.string.memory'))
|
||||||
|
if (result) {
|
||||||
|
this.currentNum = result;
|
||||||
|
} else {
|
||||||
|
this.currentNum = 0;
|
||||||
|
}
|
||||||
|
}).margin({ bottom: 8 });
|
||||||
|
Button($r('app.string.get_cur_memory_size')).onClick(() => {
|
||||||
|
let result = ImageKnife.getInstance().getCurrentCacheSize(CacheStrategy.Memory);
|
||||||
|
this.markersSizeText = getContext(this).resourceManager.getStringSync($r('app.string.memory'))
|
||||||
|
if (result) {
|
||||||
|
this.currentSize = result / (1024 * 1024);
|
||||||
|
} else {
|
||||||
|
this.currentSize = 0;
|
||||||
|
}
|
||||||
|
}).margin({ bottom: 8 });
|
||||||
|
|
||||||
|
Button($r('app.string.get_cur_disk_limit')).onClick(() => {
|
||||||
|
let result = ImageKnife.getInstance().getCacheUpperLimit(CacheStrategy.File);
|
||||||
|
this.markersLimitText = getContext(this).resourceManager.getStringSync($r('app.string.disk'))
|
||||||
|
if (result) {
|
||||||
|
this.cacheUpLimit = result / (1024 * 1024);
|
||||||
|
} else {
|
||||||
|
this.cacheUpLimit = 0;
|
||||||
|
}
|
||||||
|
}).margin({ bottom: 8 });
|
||||||
|
Button($r('app.string.get_img_number_of_disk')).onClick(() => {
|
||||||
|
let result = ImageKnife.getInstance().getCurrentPicturesNum(CacheStrategy.File);
|
||||||
|
this.markersNumText = getContext(this).resourceManager.getStringSync($r('app.string.disk'))
|
||||||
|
if (result) {
|
||||||
|
this.currentNum = result;
|
||||||
|
} else {
|
||||||
|
this.currentNum = 0;
|
||||||
|
}
|
||||||
|
}).margin({ bottom: 8 });
|
||||||
|
Button($r('app.string.get_cur_disk_size')).onClick(() => {
|
||||||
|
let result = ImageKnife.getInstance().getCurrentCacheSize(CacheStrategy.File);
|
||||||
|
this.markersSizeText = getContext(this).resourceManager.getStringSync($r('app.string.disk'))
|
||||||
|
if (result) {
|
||||||
|
this.currentSize = result / (1024 * 1024);
|
||||||
|
} else {
|
||||||
|
this.currentSize = 0;
|
||||||
|
}
|
||||||
|
}).margin({ bottom: 8 });
|
||||||
|
}
|
||||||
|
.height('100%').width('100%').margin({ top: 50 })
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,112 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2024 Huawei Device Co., Ltd.
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { drawing, common2D } from '@kit.ArkGraphics2D';
|
||||||
|
import { ImageKnifeComponent, ImageKnifeOption } from '@ohos/imageknife';
|
||||||
|
|
||||||
|
@Entry
|
||||||
|
@Component
|
||||||
|
struct TestChangeColorPage {
|
||||||
|
private imageOne: Resource = $r('app.media.ic_test_change_color_png');
|
||||||
|
private imageTwo: Resource = $r('app.media.ic_test_change_color_png');
|
||||||
|
@State src: Resource = this.imageOne
|
||||||
|
@State src2: Resource = this.imageTwo
|
||||||
|
@State color: common2D.Color = {
|
||||||
|
alpha: 255,
|
||||||
|
red: 255,
|
||||||
|
green: 1,
|
||||||
|
blue: 1
|
||||||
|
};
|
||||||
|
@State DrawingColorFilterFirst: ColorFilter | undefined = undefined
|
||||||
|
|
||||||
|
build() {
|
||||||
|
Column() {
|
||||||
|
Text($r('app.string.select_color_btn')).margin({ top: 20 })
|
||||||
|
Row() {
|
||||||
|
Button($r('app.string.red')).backgroundColor(Color.Red).margin(5).onClick(() => {
|
||||||
|
this.color = {
|
||||||
|
alpha: 255,
|
||||||
|
red: 255,
|
||||||
|
green: 1,
|
||||||
|
blue: 1
|
||||||
|
};
|
||||||
|
})
|
||||||
|
Button($r('app.string.yellow')).backgroundColor(Color.Yellow).margin(5).onClick(() => {
|
||||||
|
this.color = {
|
||||||
|
alpha: 255,
|
||||||
|
red: 255,
|
||||||
|
green: 255,
|
||||||
|
blue: 1
|
||||||
|
};
|
||||||
|
})
|
||||||
|
Button($r('app.string.green')).backgroundColor(Color.Green).margin(5).onClick(() => {
|
||||||
|
this.color = {
|
||||||
|
alpha: 255,
|
||||||
|
red: 1,
|
||||||
|
green: 255,
|
||||||
|
blue: 1
|
||||||
|
};
|
||||||
|
})
|
||||||
|
Button($r('app.string.blue')).backgroundColor(Color.Blue).margin(5).onClick(() => {
|
||||||
|
this.color = {
|
||||||
|
alpha: 255,
|
||||||
|
red: 1,
|
||||||
|
green: 1,
|
||||||
|
blue: 255
|
||||||
|
};
|
||||||
|
})
|
||||||
|
}
|
||||||
|
.width('100%')
|
||||||
|
.height(50)
|
||||||
|
.justifyContent(FlexAlign.Center)
|
||||||
|
|
||||||
|
Text($r('app.string.master_image')).margin({ top: 20 })
|
||||||
|
ImageKnifeComponent({
|
||||||
|
imageKnifeOption: new ImageKnifeOption({
|
||||||
|
loadSrc: this.src
|
||||||
|
})
|
||||||
|
}).width(110).height(110)
|
||||||
|
|
||||||
|
Text($r('app.string.click_img_to_change_color')).margin({ top: 30 })
|
||||||
|
ImageKnifeComponent({
|
||||||
|
imageKnifeOption: new ImageKnifeOption({
|
||||||
|
loadSrc: this.src,
|
||||||
|
drawingColorFilter: this.DrawingColorFilterFirst
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.onClick(() => {
|
||||||
|
this.DrawingColorFilterFirst =
|
||||||
|
drawing.ColorFilter.createBlendModeColorFilter(this.color, drawing.BlendMode.SRC_IN);
|
||||||
|
}).width(110).height(110)
|
||||||
|
|
||||||
|
Text($r('app.string.test_non_svg_color')).margin({ top: 30 })
|
||||||
|
ImageKnifeComponent({
|
||||||
|
imageKnifeOption: new 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({
|
||||||
|
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
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
import { ImageKnifeComponent } from '@ohos/libraryimageknife';
|
import { ImageKnifeComponent ,ImageKnifeOption} from '@ohos/libraryimageknife';
|
||||||
|
|
||||||
@Entry
|
@Entry
|
||||||
@Component
|
@ComponentV2
|
||||||
struct TestCommonImage {
|
struct TestCommonImage {
|
||||||
private data: Array<string> = []
|
private data: Array<string> = []
|
||||||
aboutToAppear(): void {
|
aboutToAppear(): void {
|
||||||
|
@ -30,13 +30,13 @@ struct TestCommonImage {
|
||||||
FlowItem() {
|
FlowItem() {
|
||||||
Column(){
|
Column(){
|
||||||
ImageKnifeComponent({
|
ImageKnifeComponent({
|
||||||
imageKnifeOption: {
|
imageKnifeOption: new ImageKnifeOption({
|
||||||
loadSrc: item,
|
loadSrc: item,
|
||||||
placeholderSrc: $r("app.media.loading"),
|
placeholderSrc: $r("app.media.loading"),
|
||||||
errorholderSrc: $r("app.media.failed"),
|
errorholderSrc: $r("app.media.failed"),
|
||||||
objectFit: ImageFit.Contain,
|
objectFit: ImageFit.Contain,
|
||||||
signature: "aaa"
|
signature: "aaa"
|
||||||
}
|
})
|
||||||
}).width("50%").height(200)
|
}).width("50%").height(200)
|
||||||
}
|
}
|
||||||
}.height(200)
|
}.height(200)
|
||||||
|
|
|
@ -12,34 +12,34 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
import { ImageKnifeComponent } from '@ohos/libraryimageknife'
|
import { ImageKnifeComponent,ImageKnifeOption } from '@ohos/libraryimageknife'
|
||||||
|
|
||||||
@Entry
|
@Entry
|
||||||
@Component
|
@ComponentV2
|
||||||
struct TestErrorHolderPage {
|
struct TestErrorHolderPage {
|
||||||
|
|
||||||
build() {
|
build() {
|
||||||
Column() {
|
Column() {
|
||||||
Text("ImageKnifeComponent1").fontSize(20)
|
Text("ImageKnifeComponent1").fontSize(20)
|
||||||
ImageKnifeComponent({
|
ImageKnifeComponent({
|
||||||
imageKnifeOption: {
|
imageKnifeOption: new ImageKnifeOption({
|
||||||
loadSrc: "abc",
|
loadSrc: "abc",
|
||||||
errorholderSrc:$r('app.media.failed')
|
errorholderSrc:$r('app.media.failed')
|
||||||
}
|
})
|
||||||
}).width(200).height(200)
|
}).width(200).height(200)
|
||||||
Text("ImageKnifeComponent2").fontSize(20)
|
Text("ImageKnifeComponent2").fontSize(20)
|
||||||
ImageKnifeComponent({
|
ImageKnifeComponent({
|
||||||
imageKnifeOption: {
|
imageKnifeOption: new ImageKnifeOption({
|
||||||
loadSrc: "abc",
|
loadSrc: "abc",
|
||||||
errorholderSrc:$r('app.media.startIcon')
|
errorholderSrc:$r('app.media.startIcon')
|
||||||
}
|
})
|
||||||
}).width(200).height(200)
|
}).width(200).height(200)
|
||||||
Text("ImageKnifeComponent2").fontSize(20)
|
Text("ImageKnifeComponent2").fontSize(20)
|
||||||
ImageKnifeComponent({
|
ImageKnifeComponent({
|
||||||
imageKnifeOption: {
|
imageKnifeOption: new ImageKnifeOption({
|
||||||
loadSrc: "abc",
|
loadSrc: "abc",
|
||||||
errorholderSrc:$r('app.media.mask_starfish')
|
errorholderSrc:$r('app.media.mask_starfish')
|
||||||
}
|
})
|
||||||
}).width(200).height(200)
|
}).width(200).height(200)
|
||||||
}
|
}
|
||||||
.height('100%') .width('100%')
|
.height('100%') .width('100%')
|
||||||
|
|
|
@ -15,9 +15,9 @@
|
||||||
import { ImageKnifeComponent,ImageKnifeOption } from '@ohos/libraryimageknife'
|
import { ImageKnifeComponent,ImageKnifeOption } from '@ohos/libraryimageknife'
|
||||||
|
|
||||||
@Entry
|
@Entry
|
||||||
@Component
|
@ComponentV2
|
||||||
struct TestPrefetchToFileCachePage {
|
struct TestPrefetchToFileCachePage {
|
||||||
@State imageKnifeOption: ImageKnifeOption = {
|
@Local imageKnifeOption: ImageKnifeOption = new ImageKnifeOption({
|
||||||
loadSrc:"https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658",
|
loadSrc:"https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658",
|
||||||
placeholderSrc:$r('app.media.loading'),
|
placeholderSrc:$r('app.media.loading'),
|
||||||
headerOption:[
|
headerOption:[
|
||||||
|
@ -26,7 +26,7 @@ struct TestPrefetchToFileCachePage {
|
||||||
value:"单个"
|
value:"单个"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
})
|
||||||
|
|
||||||
build() {
|
build() {
|
||||||
Column() {
|
Column() {
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
import { IndexComponent } from "@ohos/libraryimageknife"
|
import { IndexComponent } from "@ohos/libraryimageknife"
|
||||||
|
|
||||||
@Entry
|
@Entry
|
||||||
@Component
|
@ComponentV2
|
||||||
struct TestHspPreLoadImage {
|
struct TestHspPreLoadImage {
|
||||||
build() {
|
build() {
|
||||||
Column() {
|
Column() {
|
||||||
|
|
|
@ -12,9 +12,9 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
import { ImageKnifeComponent } from '@ohos/libraryimageknife'
|
import { ImageKnifeComponent,ImageKnifeOption } from '@ohos/libraryimageknife'
|
||||||
|
|
||||||
@Observed
|
@ObservedV2
|
||||||
export class MsgModel {
|
export class MsgModel {
|
||||||
id: string
|
id: string
|
||||||
cId: string
|
cId: string
|
||||||
|
@ -30,10 +30,10 @@ export class MsgModel {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Reusable
|
// @Reusable
|
||||||
@Component
|
@ComponentV2
|
||||||
export struct MsgItem {
|
export struct MsgItem {
|
||||||
count: number = 0
|
@Param count: number = 0
|
||||||
private data: Array<string> = [
|
private data: Array<string> = [
|
||||||
"http://e.hiphotos.baidu.com/image/pic/item/a1ec08fa513d2697e542494057fbb2fb4316d81e.jpg",
|
"http://e.hiphotos.baidu.com/image/pic/item/a1ec08fa513d2697e542494057fbb2fb4316d81e.jpg",
|
||||||
"http://c.hiphotos.baidu.com/image/pic/item/30adcbef76094b36de8a2fe5a1cc7cd98d109d99.jpg",
|
"http://c.hiphotos.baidu.com/image/pic/item/30adcbef76094b36de8a2fe5a1cc7cd98d109d99.jpg",
|
||||||
|
@ -59,37 +59,37 @@ export struct MsgItem {
|
||||||
build(){
|
build(){
|
||||||
if (this.count % 2 == 0 && this.count <6){
|
if (this.count % 2 == 0 && this.count <6){
|
||||||
ImageKnifeComponent({
|
ImageKnifeComponent({
|
||||||
imageKnifeOption:{
|
imageKnifeOption:new ImageKnifeOption({
|
||||||
loadSrc:$r("app.media.startIcon"),
|
loadSrc:$r("app.media.startIcon"),
|
||||||
placeholderSrc:$r("app.media.loading")
|
placeholderSrc:$r("app.media.loading")
|
||||||
},syncLoad:true
|
}),syncLoad:true
|
||||||
})
|
})
|
||||||
}else if (this.count > 6 && this.count - 6 < this.data.length){
|
}else if (this.count > 6 && this.count - 6 < this.data.length){
|
||||||
ImageKnifeComponent({
|
ImageKnifeComponent({
|
||||||
imageKnifeOption:{
|
imageKnifeOption:new ImageKnifeOption({
|
||||||
loadSrc:this.data[this.count - 6],
|
loadSrc:this.data[this.count - 6],
|
||||||
placeholderSrc:$r("app.media.loading")
|
placeholderSrc:$r("app.media.loading")
|
||||||
},syncLoad:true
|
}),syncLoad:true
|
||||||
})
|
})
|
||||||
}else {
|
}else {
|
||||||
ImageKnifeComponent({
|
ImageKnifeComponent({
|
||||||
imageKnifeOption:{
|
imageKnifeOption:new ImageKnifeOption({
|
||||||
loadSrc:$r("app.media.pngSample"),
|
loadSrc:$r("app.media.pngSample"),
|
||||||
placeholderSrc:$r("app.media.loading")
|
placeholderSrc:$r("app.media.loading")
|
||||||
},syncLoad:true
|
}),syncLoad:true
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Entry
|
@Entry
|
||||||
@Component
|
@ComponentV2
|
||||||
struct ImageTestPage {
|
struct ImageTestPage {
|
||||||
count : number = 0
|
count : number = 0
|
||||||
rCount: number = 0
|
rCount: number = 0
|
||||||
scroller: Scroller = new Scroller()
|
scroller: Scroller = new Scroller()
|
||||||
@State list: MsgModel[] = []
|
@Local list: MsgModel[] = []
|
||||||
@State imageSize: number =100
|
@Local imageSize: number =100
|
||||||
handAdd(){
|
handAdd(){
|
||||||
this.count++
|
this.count++
|
||||||
const msgItem = new MsgModel('add_id'+this.count, 'addBody'+this.count,'cId'+ this.count)
|
const msgItem = new MsgModel('add_id'+this.count, 'addBody'+this.count,'cId'+ this.count)
|
||||||
|
@ -111,12 +111,12 @@ struct ImageTestPage {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
Row(){
|
Row(){
|
||||||
Text("点击尺寸加50")
|
Text($r('app.string.Click_on_add'))
|
||||||
.onClick(()=> {
|
.onClick(()=> {
|
||||||
this.imageSize = this.imageSize + 50
|
this.imageSize = this.imageSize + 50
|
||||||
})
|
})
|
||||||
.width('50%').backgroundColor(0x88ff0000).textAlign(TextAlign.Center).height(50)
|
.width('50%').backgroundColor(0x88ff0000).textAlign(TextAlign.Center).height(50)
|
||||||
Text("点击尺寸减50")
|
Text($r('app.string.Click_on_reduce'))
|
||||||
.onClick(()=> {
|
.onClick(()=> {
|
||||||
this.imageSize = Math.max(this.imageSize - 50, 0)
|
this.imageSize = Math.max(this.imageSize - 50, 0)
|
||||||
})
|
})
|
||||||
|
|
|
@ -15,24 +15,24 @@
|
||||||
import { ImageKnifeComponent, ImageKnife, ImageKnifeOption, CacheStrategy } from '@ohos/libraryimageknife'
|
import { ImageKnifeComponent, ImageKnife, ImageKnifeOption, CacheStrategy } from '@ohos/libraryimageknife'
|
||||||
|
|
||||||
@Entry
|
@Entry
|
||||||
@Component
|
@ComponentV2
|
||||||
struct TestIsUrlExist {
|
struct TestIsUrlExist {
|
||||||
@State imageKnifeOption: ImageKnifeOption = {
|
@Local imageKnifeOption: ImageKnifeOption = new ImageKnifeOption({
|
||||||
loadSrc: $r('app.media.startIcon'),
|
loadSrc: $r('app.media.startIcon'),
|
||||||
placeholderSrc: $r('app.media.loading'),
|
placeholderSrc: $r('app.media.loading'),
|
||||||
errorholderSrc:$r('app.media.failed')
|
errorholderSrc:$r('app.media.failed')
|
||||||
}
|
})
|
||||||
@State source: PixelMap | string | Resource = $r("app.media.startIcon")
|
@Local source: PixelMap | string | Resource = $r("app.media.startIcon")
|
||||||
@State source1: PixelMap | string | Resource = $r("app.media.startIcon")
|
@Local source1: PixelMap | string | Resource = $r("app.media.startIcon")
|
||||||
|
|
||||||
build() {
|
build() {
|
||||||
Column() {
|
Column() {
|
||||||
Flex() {
|
Flex() {
|
||||||
Button("预加载gif图").onClick(() => {
|
Button($r('app.string.Preloading_GIF')).onClick(() => {
|
||||||
this.imageKnifeOption.loadSrc =
|
this.imageKnifeOption.loadSrc =
|
||||||
"https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658"
|
"https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658"
|
||||||
})
|
})
|
||||||
Button("内存缓存获取gif").onClick(() => {
|
Button($r('app.string.Retrieve_GIF_from_memory')).onClick(() => {
|
||||||
ImageKnife.getInstance()
|
ImageKnife.getInstance()
|
||||||
.getCacheImage("https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658",
|
.getCacheImage("https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658",
|
||||||
CacheStrategy.Memory)
|
CacheStrategy.Memory)
|
||||||
|
@ -40,7 +40,7 @@ struct TestIsUrlExist {
|
||||||
this.source = data !== undefined ? data.source : $r("app.media.startIcon")
|
this.source = data !== undefined ? data.source : $r("app.media.startIcon")
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
Button("文件缓存获取gif").onClick(() => {
|
Button($r('app.string.Retrieve_GIF_from_disk')).onClick(() => {
|
||||||
ImageKnife.getInstance()
|
ImageKnife.getInstance()
|
||||||
.getCacheImage("https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658",
|
.getCacheImage("https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658",
|
||||||
CacheStrategy.File)
|
CacheStrategy.File)
|
||||||
|
@ -51,11 +51,11 @@ struct TestIsUrlExist {
|
||||||
}
|
}
|
||||||
|
|
||||||
Flex() {
|
Flex() {
|
||||||
Button("预加载静态图").onClick(() => {
|
Button($r('app.string.Preloading_static_images')).onClick(() => {
|
||||||
this.imageKnifeOption.loadSrc =
|
this.imageKnifeOption.loadSrc =
|
||||||
'https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp'
|
'https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp'
|
||||||
})
|
})
|
||||||
Button("内存缓存获取").onClick(() => {
|
Button($r('app.string.Retrieve_images_from_memory')).onClick(() => {
|
||||||
ImageKnife.getInstance()
|
ImageKnife.getInstance()
|
||||||
.getCacheImage('https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp',
|
.getCacheImage('https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp',
|
||||||
CacheStrategy.Memory)
|
CacheStrategy.Memory)
|
||||||
|
@ -63,7 +63,7 @@ struct TestIsUrlExist {
|
||||||
this.source = data!.source
|
this.source = data!.source
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
Button("文件缓存获取").onClick(() => {
|
Button($r('app.string.Retrieve_images_from_disk')).onClick(() => {
|
||||||
ImageKnife.getInstance()
|
ImageKnife.getInstance()
|
||||||
.getCacheImage('https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp',
|
.getCacheImage('https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp',
|
||||||
CacheStrategy.File)
|
CacheStrategy.File)
|
||||||
|
|
|
@ -0,0 +1,94 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2024 Huawei Device Co., Ltd.
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { ImageKnifeComponent, ImageKnifeOption } from '@ohos/imageknife';
|
||||||
|
|
||||||
|
@Entry
|
||||||
|
@ComponentV2
|
||||||
|
struct TestLoadCancelListenerPage {
|
||||||
|
@Local currentWidth: number = 200
|
||||||
|
@Local currentHeight: number = 200
|
||||||
|
@Local showChild: boolean = true;
|
||||||
|
@Local text: string = "";
|
||||||
|
@Local ImageKnifeOption: ImageKnifeOption = new ImageKnifeOption({
|
||||||
|
loadSrc: "",
|
||||||
|
objectFit: ImageFit.Contain,
|
||||||
|
border: { radius: 50 }
|
||||||
|
})
|
||||||
|
|
||||||
|
build() {
|
||||||
|
Column() {
|
||||||
|
Text($r('app.string.onLoadCancel_reason', this.text)).margin(20).fontSize(15)
|
||||||
|
Button($r('app.string.rm_component_of_net'))
|
||||||
|
.margin(20)
|
||||||
|
.onClick(() => {
|
||||||
|
this.ImageKnifeOption = new ImageKnifeOption({
|
||||||
|
loadSrc: "https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/76/v3/EyF6z4FISpCHhae38eEexw/OtyAiu-zSSevNQYvUdtVmA.jpg",
|
||||||
|
objectFit: ImageFit.Contain,
|
||||||
|
onLoadListener: {
|
||||||
|
onLoadStart: () => {
|
||||||
|
this.showChild = false;
|
||||||
|
},
|
||||||
|
onLoadCancel: (res) => {
|
||||||
|
this.text = res
|
||||||
|
console.log("TestLoadCancelListenerPage----onLoadCancel> url:" + res)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
border: { radius: 50 }
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
Button($r('app.string.component_display'))
|
||||||
|
.margin(20).onClick(() => {
|
||||||
|
this.text = "";
|
||||||
|
this.showChild = true;
|
||||||
|
this.ImageKnifeOption = new ImageKnifeOption({
|
||||||
|
loadSrc: "",
|
||||||
|
objectFit: ImageFit.Contain,
|
||||||
|
border: { radius: 50 }
|
||||||
|
})
|
||||||
|
})
|
||||||
|
Button($r('app.string.rm_component_of_local'))
|
||||||
|
.margin(20)
|
||||||
|
.onClick(() => {
|
||||||
|
this.ImageKnifeOption = new ImageKnifeOption({
|
||||||
|
loadSrc: $r('app.media.loading'),
|
||||||
|
objectFit: ImageFit.Contain,
|
||||||
|
onLoadListener: {
|
||||||
|
onLoadStart: () => {
|
||||||
|
this.showChild = false;
|
||||||
|
},
|
||||||
|
onLoadCancel: (res) => {
|
||||||
|
this.text = res
|
||||||
|
console.log("TestLoadCancelListenerPage----onLoadCancel> url:" + res)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
border: { radius: 50 }
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
if (this.showChild) {
|
||||||
|
ImageKnifeComponent(
|
||||||
|
{ imageKnifeOption: this.ImageKnifeOption })
|
||||||
|
.height(150)
|
||||||
|
.width(150)
|
||||||
|
.backgroundColor(Color.Orange)
|
||||||
|
.margin({ top: 20 })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.height('100%')
|
||||||
|
.width('100%')
|
||||||
|
}
|
||||||
|
}
|
|
@ -15,30 +15,30 @@
|
||||||
import { ImageKnifeComponent,ImageKnife,ImageKnifeOption } from '@ohos/libraryimageknife'
|
import { ImageKnifeComponent,ImageKnife,ImageKnifeOption } from '@ohos/libraryimageknife'
|
||||||
|
|
||||||
@Entry
|
@Entry
|
||||||
@Component
|
@ComponentV2
|
||||||
struct TestPrefetchToFileCachePage {
|
struct TestPrefetchToFileCachePage {
|
||||||
@State imageKnifeOption: ImageKnifeOption = {
|
@Local imageKnifeOption: ImageKnifeOption = new ImageKnifeOption({
|
||||||
loadSrc:$r('app.media.startIcon'),
|
loadSrc:$r('app.media.startIcon'),
|
||||||
placeholderSrc:$r('app.media.loading'),
|
placeholderSrc:$r('app.media.loading'),
|
||||||
errorholderSrc:$r('app.media.failed')
|
errorholderSrc:$r('app.media.failed')
|
||||||
}
|
})
|
||||||
async preload(url:string) {
|
async preload(url:string) {
|
||||||
let fileCachePath = await ImageKnife.getInstance().preLoadCache(url)
|
let fileCachePath = await ImageKnife.getInstance().preLoadCache(url)
|
||||||
console.log("preload-fileCachePath=="+ fileCachePath)
|
console.log("preload-fileCachePath=="+ fileCachePath)
|
||||||
}
|
}
|
||||||
async preload1(url:string) {
|
async preload1(url:string) {
|
||||||
let fileCachePath = await ImageKnife.getInstance().preLoadCache({ loadSrc: url })
|
let fileCachePath = await ImageKnife.getInstance().preLoadCache(new ImageKnifeOption({ loadSrc: url }))
|
||||||
console.log("preload-fileCachePath1=="+ fileCachePath)
|
console.log("preload-fileCachePath1=="+ fileCachePath)
|
||||||
}
|
}
|
||||||
build() {
|
build() {
|
||||||
Column() {
|
Column() {
|
||||||
Button("url预加载图片到文件缓存").margin({top:10}).onClick(async ()=>{
|
Button($r('app.string.Preloading_images_to_file_cache_using_URL')).margin({top:10}).onClick(async ()=>{
|
||||||
await this.preload("https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658")
|
await this.preload("https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658")
|
||||||
})
|
})
|
||||||
Button("option预加载图片到文件缓存").margin({top:10}).onClick(async ()=>{
|
Button($r('app.string.Preloading_images_to_file_cache_using_option')).margin({top:10}).onClick(async ()=>{
|
||||||
await this.preload1("https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658")
|
await this.preload1("https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658")
|
||||||
})
|
})
|
||||||
Button("加载图片(预加载后可断网加载)").margin({top:10}).onClick(()=>{
|
Button($r('app.string.Load_image_offline_after_preloading')).margin({top:10}).onClick(()=>{
|
||||||
this.imageKnifeOption.loadSrc = "https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658"
|
this.imageKnifeOption.loadSrc = "https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658"
|
||||||
})
|
})
|
||||||
ImageKnifeComponent({
|
ImageKnifeComponent({
|
||||||
|
|
|
@ -15,26 +15,26 @@
|
||||||
import { ImageKnifeComponent, ImageKnife, ImageKnifeOption, CacheStrategy } from '@ohos/libraryimageknife'
|
import { ImageKnifeComponent, ImageKnife, ImageKnifeOption, CacheStrategy } from '@ohos/libraryimageknife'
|
||||||
|
|
||||||
@Entry
|
@Entry
|
||||||
@Component
|
@ComponentV2
|
||||||
struct TestRemoveCache {
|
struct TestRemoveCache {
|
||||||
@State imageKnifeOption: ImageKnifeOption = {
|
@Local imageKnifeOption: ImageKnifeOption = new ImageKnifeOption({
|
||||||
loadSrc: $r('app.media.startIcon'),
|
loadSrc: $r('app.media.startIcon'),
|
||||||
placeholderSrc: $r('app.media.loading'),
|
placeholderSrc: $r('app.media.loading'),
|
||||||
errorholderSrc:$r('app.media.failed')
|
errorholderSrc:$r('app.media.failed')
|
||||||
}
|
})
|
||||||
@State source: PixelMap | string | Resource = $r("app.media.startIcon");
|
@Local source: PixelMap | string | Resource = $r("app.media.startIcon");
|
||||||
@State source1: PixelMap | string | Resource = $r("app.media.startIcon");
|
@Local source1: PixelMap | string | Resource = $r("app.media.startIcon");
|
||||||
@State url: string = '';
|
@Local url: string = '';
|
||||||
|
|
||||||
build() {
|
build() {
|
||||||
Column() {
|
Column() {
|
||||||
Flex() {
|
Flex() {
|
||||||
Button("预加载gif图").onClick(() => {
|
Button($r('app.string.Preloading_GIF')).onClick(() => {
|
||||||
this.imageKnifeOption.loadSrc = "https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658";
|
this.imageKnifeOption.loadSrc = "https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658";
|
||||||
this.url = "https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658";
|
this.url = "https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658";
|
||||||
})
|
})
|
||||||
.margin({left:10})
|
.margin({left:10})
|
||||||
Button("内存缓存获取gif").onClick(() => {
|
Button($r('app.string.Retrieve_GIF_from_memory')).onClick(() => {
|
||||||
ImageKnife.getInstance()
|
ImageKnife.getInstance()
|
||||||
.getCacheImage("https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658",
|
.getCacheImage("https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658",
|
||||||
CacheStrategy.Memory)
|
CacheStrategy.Memory)
|
||||||
|
@ -43,7 +43,7 @@ struct TestRemoveCache {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.margin({left:10})
|
.margin({left:10})
|
||||||
Button("文件缓存获取gif").onClick(() => {
|
Button($r('app.string.Retrieve_GIF_from_disk')).onClick(() => {
|
||||||
ImageKnife.getInstance()
|
ImageKnife.getInstance()
|
||||||
.getCacheImage("https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658",
|
.getCacheImage("https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658",
|
||||||
CacheStrategy.File)
|
CacheStrategy.File)
|
||||||
|
@ -55,12 +55,12 @@ struct TestRemoveCache {
|
||||||
}
|
}
|
||||||
|
|
||||||
Flex() {
|
Flex() {
|
||||||
Button("预加载静态图").onClick(() => {
|
Button($r('app.string.Preloading_static_images')).onClick(() => {
|
||||||
this.imageKnifeOption.loadSrc = 'https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp';
|
this.imageKnifeOption.loadSrc = 'https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp';
|
||||||
this.url = 'https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp';
|
this.url = 'https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp';
|
||||||
})
|
})
|
||||||
.margin({left:10})
|
.margin({left:10})
|
||||||
Button("内存缓存获取").onClick(() => {
|
Button($r('app.string.Retrieve_images_from_memory')).onClick(() => {
|
||||||
ImageKnife.getInstance()
|
ImageKnife.getInstance()
|
||||||
.getCacheImage('https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp',
|
.getCacheImage('https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp',
|
||||||
CacheStrategy.Memory)
|
CacheStrategy.Memory)
|
||||||
|
@ -69,7 +69,7 @@ struct TestRemoveCache {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.margin({left:10})
|
.margin({left:10})
|
||||||
Button("文件缓存获取").onClick(() => {
|
Button($r('app.string.Retrieve_images_from_disk')).onClick(() => {
|
||||||
ImageKnife.getInstance()
|
ImageKnife.getInstance()
|
||||||
.getCacheImage('https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp',
|
.getCacheImage('https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp',
|
||||||
CacheStrategy.File)
|
CacheStrategy.File)
|
||||||
|
@ -81,19 +81,19 @@ struct TestRemoveCache {
|
||||||
}.margin({ top: 10 })
|
}.margin({ top: 10 })
|
||||||
|
|
||||||
Flex() {
|
Flex() {
|
||||||
Button("删除全部缓存").onClick(() => {
|
Button($r('app.string.Delete_all_caches')).onClick(() => {
|
||||||
ImageKnife.getInstance()
|
ImageKnife.getInstance()
|
||||||
.removeAllMemoryCache()
|
.removeAllMemoryCache()
|
||||||
ImageKnife.getInstance()
|
ImageKnife.getInstance()
|
||||||
.removeAllFileCache()
|
.removeAllFileCache()
|
||||||
})
|
})
|
||||||
.margin({left:5})
|
.margin({left:5})
|
||||||
Button("删除全部内存缓存").onClick(() => {
|
Button($r('app.string.Delete_all_memory_caches')).onClick(() => {
|
||||||
ImageKnife.getInstance()
|
ImageKnife.getInstance()
|
||||||
.removeAllMemoryCache()
|
.removeAllMemoryCache()
|
||||||
})
|
})
|
||||||
.margin({left:5})
|
.margin({left:5})
|
||||||
Button("删除全部文件缓存").onClick(() => {
|
Button($r('app.string.Delete_all_file_caches')).onClick(() => {
|
||||||
ImageKnife.getInstance()
|
ImageKnife.getInstance()
|
||||||
.removeAllFileCache()
|
.removeAllFileCache()
|
||||||
})
|
})
|
||||||
|
@ -101,12 +101,12 @@ struct TestRemoveCache {
|
||||||
}.margin({ top: 10 })
|
}.margin({ top: 10 })
|
||||||
|
|
||||||
Flex() {
|
Flex() {
|
||||||
Button("删除自定义内存缓存").onClick(() => {
|
Button($r('app.string.Delete_all_custom_memory_caches')).onClick(() => {
|
||||||
ImageKnife.getInstance()
|
ImageKnife.getInstance()
|
||||||
.removeMemoryCache(this.url)
|
.removeMemoryCache(this.url)
|
||||||
})
|
})
|
||||||
.margin({left:20})
|
.margin({left:20})
|
||||||
Button("删除自定义文件缓存").onClick(() => {
|
Button($r('app.string.Delete_all_custom_file_caches')).onClick(() => {
|
||||||
ImageKnife.getInstance()
|
ImageKnife.getInstance()
|
||||||
.removeFileCache(this.url)
|
.removeFileCache(this.url)
|
||||||
})
|
})
|
||||||
|
|
|
@ -15,12 +15,17 @@
|
||||||
import { ImageKnifeComponent, ImageKnife, ImageKnifeOption } from '@ohos/libraryimageknife'
|
import { ImageKnifeComponent, ImageKnife, ImageKnifeOption } from '@ohos/libraryimageknife'
|
||||||
|
|
||||||
@Entry
|
@Entry
|
||||||
@Component
|
@ComponentV2
|
||||||
struct TestSetCustomImagePage {
|
struct TestSetCustomImagePage {
|
||||||
@State imageKnifeOption: ImageKnifeOption = {
|
|
||||||
|
getResourceString(res:Resource){
|
||||||
|
return getContext().resourceManager.getStringSync(res.id)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Local imageKnifeOption: ImageKnifeOption = new ImageKnifeOption({
|
||||||
loadSrc: $r('app.media.startIcon'),
|
loadSrc: $r('app.media.startIcon'),
|
||||||
placeholderSrc: $r('app.media.loading')
|
placeholderSrc: $r('app.media.loading')
|
||||||
}
|
})
|
||||||
aboutToAppear(): void {
|
aboutToAppear(): void {
|
||||||
ImageKnife.getInstance().setCustomGetImage(custom)
|
ImageKnife.getInstance().setCustomGetImage(custom)
|
||||||
}
|
}
|
||||||
|
@ -29,23 +34,23 @@ struct TestSetCustomImagePage {
|
||||||
}
|
}
|
||||||
build() {
|
build() {
|
||||||
Column() {
|
Column() {
|
||||||
Button("自定义下载a").onClick(()=>{
|
Button(this.getResourceString($r('app.string.Custom_network_download')) + " a").onClick(()=>{
|
||||||
this.imageKnifeOption = {
|
this.imageKnifeOption = new ImageKnifeOption({
|
||||||
loadSrc: "aaa",
|
loadSrc: "aaa",
|
||||||
placeholderSrc: $r('app.media.loading')
|
placeholderSrc: $r('app.media.loading')
|
||||||
}
|
})
|
||||||
})
|
})
|
||||||
Button("自定义下载b").onClick(()=>{
|
Button(this.getResourceString($r('app.string.Custom_network_download')) + " b").onClick(()=>{
|
||||||
this.imageKnifeOption = {
|
this.imageKnifeOption = new ImageKnifeOption({
|
||||||
loadSrc: "bbb",
|
loadSrc: "bbb",
|
||||||
placeholderSrc: $r('app.media.loading')
|
placeholderSrc: $r('app.media.loading')
|
||||||
}
|
})
|
||||||
})
|
})
|
||||||
Button("自定义下载c").onClick(()=>{
|
Button(this.getResourceString($r('app.string.Custom_network_download')) + " c").onClick(()=>{
|
||||||
this.imageKnifeOption = {
|
this.imageKnifeOption = new ImageKnifeOption({
|
||||||
loadSrc: "ccc",
|
loadSrc: "ccc",
|
||||||
placeholderSrc: $r('app.media.loading')
|
placeholderSrc: $r('app.media.loading')
|
||||||
}
|
})
|
||||||
})
|
})
|
||||||
ImageKnifeComponent({
|
ImageKnifeComponent({
|
||||||
imageKnifeOption: this.imageKnifeOption
|
imageKnifeOption: this.imageKnifeOption
|
||||||
|
|
|
@ -0,0 +1,79 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2024 Huawei Device Co., Ltd.
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
import { ImageKnifeComponent, ImageKnifeOption } from "@ohos/libraryimageknife"
|
||||||
|
|
||||||
|
@ComponentV2
|
||||||
|
export struct ZuImage {
|
||||||
|
@Param @Require src: PixelMap | ResourceStr | string | undefined
|
||||||
|
@Param @Require placeholderSrc: PixelMap | ResourceStr | string | undefined
|
||||||
|
@Local errorholderSrc: PixelMap | ResourceStr | string | undefined
|
||||||
|
|
||||||
|
build() {
|
||||||
|
if (this.src) {
|
||||||
|
//当前版本存在bug
|
||||||
|
ImageKnifeComponent({
|
||||||
|
imageKnifeOption: new ImageKnifeOption({
|
||||||
|
loadSrc: this.src,
|
||||||
|
placeholderSrc: this.placeholderSrc,
|
||||||
|
errorholderSrc: this.errorholderSrc ?? this.placeholderSrc,
|
||||||
|
objectFit: ImageFit.Cover
|
||||||
|
})
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
Image(this.placeholderSrc)
|
||||||
|
.objectFit(ImageFit.Cover)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Entry
|
||||||
|
@ComponentV2
|
||||||
|
struct TestTaskResourcePage {
|
||||||
|
@Local stateMenus: Array<string> = [
|
||||||
|
"https://hbimg.huabanimg.com/cc6af25f8d782d3cf3122bef4e61571378271145735e9-vEVggB",
|
||||||
|
'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/bf/v3/lSjrRwFcS-ez6jp1ALSQFg/0n7R7XinSPyrYLqDu_1dfw.jpg',
|
||||||
|
'https://img-blog.csdn.net/20140514114029140',
|
||||||
|
'https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp',
|
||||||
|
]
|
||||||
|
@Builder
|
||||||
|
_buildItem(item: string) {
|
||||||
|
Column({ space: 8 }) {
|
||||||
|
ZuImage({
|
||||||
|
src: item,
|
||||||
|
placeholderSrc: $r("app.media.loading")
|
||||||
|
}).width(44)
|
||||||
|
.height(44)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
build() {
|
||||||
|
|
||||||
|
Grid() {
|
||||||
|
ForEach(this.stateMenus, (item: string) => {
|
||||||
|
GridItem() {
|
||||||
|
this._buildItem(item)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}.width("100%")
|
||||||
|
.columnsTemplate('1fr 1fr 1fr 1fr 1fr')
|
||||||
|
.rowsGap(24)
|
||||||
|
.padding({
|
||||||
|
top: 24,
|
||||||
|
bottom: 24,
|
||||||
|
left: 24,
|
||||||
|
right: 24
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
|
@ -15,55 +15,55 @@
|
||||||
import { ImageKnifeComponent,CacheStrategy,ImageKnifeOption } from '@ohos/libraryimageknife'
|
import { ImageKnifeComponent,CacheStrategy,ImageKnifeOption } from '@ohos/libraryimageknife'
|
||||||
|
|
||||||
@Entry
|
@Entry
|
||||||
@Component
|
@ComponentV2
|
||||||
struct TestWriteCacheStage {
|
struct TestWriteCacheStage {
|
||||||
@State imageKnifeOption1: ImageKnifeOption = {
|
@Local imageKnifeOption1: ImageKnifeOption = new ImageKnifeOption({
|
||||||
loadSrc:$r('app.media.startIcon'),
|
loadSrc:$r('app.media.startIcon'),
|
||||||
placeholderSrc:$r('app.media.loading'),
|
placeholderSrc:$r('app.media.loading'),
|
||||||
errorholderSrc:$r('app.media.failed')
|
errorholderSrc:$r('app.media.failed')
|
||||||
}
|
})
|
||||||
@State imageKnifeOption2: ImageKnifeOption = {
|
@Local imageKnifeOption2: ImageKnifeOption = new ImageKnifeOption({
|
||||||
loadSrc:$r('app.media.startIcon'),
|
loadSrc:$r('app.media.startIcon'),
|
||||||
placeholderSrc:$r('app.media.loading'),
|
placeholderSrc:$r('app.media.loading'),
|
||||||
errorholderSrc:$r('app.media.failed')
|
errorholderSrc:$r('app.media.failed')
|
||||||
}
|
})
|
||||||
@State imageKnifeOption3: ImageKnifeOption = {
|
@Local imageKnifeOption3: ImageKnifeOption = new ImageKnifeOption({
|
||||||
loadSrc:$r('app.media.startIcon'),
|
loadSrc:$r('app.media.startIcon'),
|
||||||
placeholderSrc:$r('app.media.loading'),
|
placeholderSrc:$r('app.media.loading'),
|
||||||
errorholderSrc:$r('app.media.failed')
|
errorholderSrc:$r('app.media.failed')
|
||||||
}
|
})
|
||||||
|
|
||||||
build() {
|
build() {
|
||||||
Column() {
|
Column() {
|
||||||
Button("写入内存文件缓存").margin({top:10}).onClick(async ()=>{
|
Button($r('app.string.Write_memory_and_file')).margin({top:10}).onClick(async ()=>{
|
||||||
this.imageKnifeOption1 = {
|
this.imageKnifeOption1 = new ImageKnifeOption({
|
||||||
loadSrc:'https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp',
|
loadSrc:'https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp',
|
||||||
placeholderSrc:$r('app.media.loading'),
|
placeholderSrc:$r('app.media.loading'),
|
||||||
errorholderSrc:$r('app.media.failed'),
|
errorholderSrc:$r('app.media.failed'),
|
||||||
writeCacheStrategy:CacheStrategy.Default
|
writeCacheStrategy:CacheStrategy.Default
|
||||||
}
|
})
|
||||||
})
|
})
|
||||||
ImageKnifeComponent({
|
ImageKnifeComponent({
|
||||||
imageKnifeOption: this.imageKnifeOption1
|
imageKnifeOption: this.imageKnifeOption1
|
||||||
}).width(200).height(200).margin({top:10})
|
}).width(200).height(200).margin({top:10})
|
||||||
Button("写入内存缓存").margin({top:10}).onClick(async ()=>{
|
Button($r('app.string.Write_memory')).margin({top:10}).onClick(async ()=>{
|
||||||
this.imageKnifeOption2 = {
|
this.imageKnifeOption2 = new ImageKnifeOption({
|
||||||
loadSrc:"https://hbimg.huabanimg.com/cc6af25f8d782d3cf3122bef4e61571378271145735e9-vEVggB",
|
loadSrc:"https://hbimg.huabanimg.com/cc6af25f8d782d3cf3122bef4e61571378271145735e9-vEVggB",
|
||||||
placeholderSrc:$r('app.media.loading'),
|
placeholderSrc:$r('app.media.loading'),
|
||||||
errorholderSrc:$r('app.media.failed'),
|
errorholderSrc:$r('app.media.failed'),
|
||||||
writeCacheStrategy:CacheStrategy.Memory
|
writeCacheStrategy:CacheStrategy.Memory
|
||||||
}
|
})
|
||||||
})
|
})
|
||||||
ImageKnifeComponent({
|
ImageKnifeComponent({
|
||||||
imageKnifeOption: this.imageKnifeOption2
|
imageKnifeOption: this.imageKnifeOption2
|
||||||
}).width(200).height(200).margin({top:10})
|
}).width(200).height(200).margin({top:10})
|
||||||
Button("写入文件缓存").margin({top:10}).onClick(async ()=>{
|
Button($r('app.string.Write_file')).margin({top:10}).onClick(async ()=>{
|
||||||
this.imageKnifeOption3 = {
|
this.imageKnifeOption3 = new ImageKnifeOption({
|
||||||
loadSrc:'https://img-blog.csdn.net/20140514114029140',
|
loadSrc:'https://img-blog.csdn.net/20140514114029140',
|
||||||
placeholderSrc:$r('app.media.loading'),
|
placeholderSrc:$r('app.media.loading'),
|
||||||
errorholderSrc:$r('app.media.failed'),
|
errorholderSrc:$r('app.media.failed'),
|
||||||
writeCacheStrategy:CacheStrategy.File
|
writeCacheStrategy:CacheStrategy.File
|
||||||
}
|
})
|
||||||
})
|
})
|
||||||
ImageKnifeComponent({
|
ImageKnifeComponent({
|
||||||
imageKnifeOption: this.imageKnifeOption3
|
imageKnifeOption: this.imageKnifeOption3
|
||||||
|
|
|
@ -17,29 +17,29 @@ import matrix4 from '@ohos.matrix4'
|
||||||
|
|
||||||
|
|
||||||
@Entry
|
@Entry
|
||||||
@Component
|
@ComponentV2
|
||||||
struct TransformPage {
|
struct TransformPage {
|
||||||
private custom_scale:number = 1
|
private custom_scale:number = 1
|
||||||
@State matrix1:object = matrix4.identity().scale({ x: 1, y: 1 })
|
@Local matrix1:object = matrix4.identity().scale({ x: 1, y: 1 })
|
||||||
@State ImageKnifeOption: ImageKnifeOption = {
|
@Local ImageKnifeOption: ImageKnifeOption = new ImageKnifeOption({
|
||||||
loadSrc: $r("app.media.rabbit"),
|
loadSrc: $r("app.media.rabbit"),
|
||||||
placeholderSrc: $r("app.media.loading"),
|
placeholderSrc: $r("app.media.loading"),
|
||||||
errorholderSrc: $r("app.media.app_icon"),
|
errorholderSrc: $r("app.media.app_icon"),
|
||||||
objectFit: ImageFit.Contain,
|
objectFit: ImageFit.Contain,
|
||||||
border: { radius: 50 }
|
border: { radius: 50 }
|
||||||
}
|
})
|
||||||
|
|
||||||
build() {
|
build() {
|
||||||
Column() {
|
Column() {
|
||||||
ImageKnifeComponent({ imageKnifeOption: this.ImageKnifeOption }).height(200).width(200)
|
ImageKnifeComponent({ imageKnifeOption: this.ImageKnifeOption }).height(200).width(200)
|
||||||
.transform(this.matrix1)
|
.transform(this.matrix1)
|
||||||
// Image($r('app.media.rabbit')).objectFit(ImageFit.Contain).height(200).width(200).transform(this.matrix1)
|
// Image($r('app.media.rabbit')).objectFit(ImageFit.Contain).height(200).width(200).transform(this.matrix1)
|
||||||
Button("放大").onClick(()=>{
|
Button($r('app.string.Enlarge')).onClick(()=>{
|
||||||
this.custom_scale = this.custom_scale * 2
|
this.custom_scale = this.custom_scale * 2
|
||||||
this.matrix1 = matrix4.identity().scale({ x: this.custom_scale, y: this.custom_scale })
|
this.matrix1 = matrix4.identity().scale({ x: this.custom_scale, y: this.custom_scale })
|
||||||
})
|
})
|
||||||
|
|
||||||
Button("缩小").onClick(()=>{
|
Button($r('app.string.Reduce')).onClick(()=>{
|
||||||
this.custom_scale = this.custom_scale / 2
|
this.custom_scale = this.custom_scale / 2
|
||||||
this.matrix1 = matrix4.identity().scale({ x: this.custom_scale, y: this.custom_scale })
|
this.matrix1 = matrix4.identity().scale({ x: this.custom_scale, y: this.custom_scale })
|
||||||
})
|
})
|
||||||
|
|
|
@ -15,24 +15,50 @@
|
||||||
import { ImageKnifeComponent, ImageKnifeOption } from '@ohos/libraryimageknife'
|
import { ImageKnifeComponent, ImageKnifeOption } from '@ohos/libraryimageknife'
|
||||||
|
|
||||||
// const logger = new imUtils.logger.IMLogger('Avatar')
|
// const logger = new imUtils.logger.IMLogger('Avatar')
|
||||||
|
@ObservedV2
|
||||||
class MyImageOption extends ImageKnifeOption {
|
export class MyStorage {
|
||||||
account?: string
|
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
|
||||||
}
|
}
|
||||||
|
|
||||||
@Component
|
@ComponentV2
|
||||||
export struct UserAvatar {
|
export struct UserAvatar {
|
||||||
@Prop @Watch('userInfoUpdate') userInfo: string = ""
|
|
||||||
// @Prop userInfo: string = ""
|
// @Prop userInfo: string = ""
|
||||||
imgSize: number = 100
|
imgSize: number = 100
|
||||||
radius: number = 12
|
radius: number = 12
|
||||||
borderSize: number = 0
|
borderSize: number = 0
|
||||||
imgSizes: number = 1
|
imgSizes: number = 1
|
||||||
@State ImageKnifeOption: ImageKnifeOption = new ImageKnifeOption()
|
@Local ImageKnifeOption: ImageKnifeOption = new ImageKnifeOption()
|
||||||
@StorageProp('WeLink_Mob_fontSize_multiple') @Watch('updateImgSize') WeLink_Mob_fontSize_multiple: number = 0
|
|
||||||
scalable: boolean = true;
|
scalable: boolean = true;
|
||||||
@State calcImgSize: number = 100
|
@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()
|
||||||
|
}
|
||||||
aboutToAppear(): void {
|
aboutToAppear(): void {
|
||||||
this.userInfoUpdate()
|
this.userInfoUpdate()
|
||||||
this.setImageSize()
|
this.setImageSize()
|
||||||
|
@ -41,39 +67,19 @@ export struct UserAvatar {
|
||||||
setImageSize() {
|
setImageSize() {
|
||||||
if (!this.scalable) {
|
if (!this.scalable) {
|
||||||
this.calcImgSize = this.imgSize
|
this.calcImgSize = this.imgSize
|
||||||
} else if (this.WeLink_Mob_fontSize_multiple < 0.9) {
|
} else if (this.storage.WeLink_Mob_fontSize_multiple < 0.9) {
|
||||||
this.calcImgSize = this.imgSize * 0.9
|
this.calcImgSize = this.imgSize * 0.9
|
||||||
} else if (this.WeLink_Mob_fontSize_multiple > 1.6) {
|
} else if (this.storage.WeLink_Mob_fontSize_multiple > 1.6) {
|
||||||
this.calcImgSize = this.imgSize * 1.6
|
this.calcImgSize = this.imgSize * 1.6
|
||||||
} else {
|
} else {
|
||||||
this.calcImgSize = this.imgSize * this.WeLink_Mob_fontSize_multiple
|
this.calcImgSize = this.imgSize * this.storage.WeLink_Mob_fontSize_multiple
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
updateImgSize() {
|
|
||||||
this.setImageSize()
|
|
||||||
}
|
|
||||||
|
|
||||||
aboutToReuse(param: ESObject) {
|
aboutToReuse(param: ESObject) {
|
||||||
this.userInfoUpdate()
|
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() {
|
build() {
|
||||||
Row() {
|
Row() {
|
||||||
// Image(this.imageKnifeOption.loadSrc)
|
// Image(this.imageKnifeOption.loadSrc)
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
import { UserAvatar } from './User'
|
import { MyStorage, UserAvatar } from './User'
|
||||||
|
|
||||||
class CommonDataSource <T> implements IDataSource {
|
class CommonDataSource <T> implements IDataSource {
|
||||||
private dataArray: T[] = []
|
private dataArray: T[] = []
|
||||||
|
@ -55,56 +55,72 @@ class CommonDataSource <T> implements IDataSource {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@Entry
|
@Entry
|
||||||
@Component
|
@ComponentV2
|
||||||
struct Index {
|
struct Index {
|
||||||
@State hotCommendList:CommonDataSource<string> = new CommonDataSource<string>([])
|
@Local hotCommendList:CommonDataSource<string> = new CommonDataSource<string>([])
|
||||||
private data:string[] = [
|
private data:string[] = [
|
||||||
"http://e.hiphotos.baidu.com/image/pic/item/a1ec08fa513d2697e542494057fbb2fb4316d81e.jpg",
|
"https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/56/v3/8MdhfSsCSMKj4sA6okUWrg/5uBx56tLTUO3RYQl-E5JiQ.jpg",
|
||||||
"http://c.hiphotos.baidu.com/image/pic/item/30adcbef76094b36de8a2fe5a1cc7cd98d109d99.jpg",
|
"https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/e2/v3/4zI1Xm_3STmV30aZXWRrKw/6aN7WodDRUiBApgffiLPCg.jpg",
|
||||||
"http://h.hiphotos.baidu.com/image/pic/item/7c1ed21b0ef41bd5f2c2a9e953da81cb39db3d1d.jpg",
|
"https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/42/v3/2dSQCqERTP2TTPyssOMEbQ/zL1ebnKKQ_ilqTDcwCAkOw.jpg",
|
||||||
"http://g.hiphotos.baidu.com/image/pic/item/55e736d12f2eb938d5277fd5d0628535e5dd6f4a.jpg",
|
"https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/78/v3/qQJpAtRGQe2e_VhbGHDgIw/b3zlit99S6GybD3XdNwqJw.jpg",
|
||||||
"http://e.hiphotos.baidu.com/image/pic/item/4e4a20a4462309f7e41f5cfe760e0cf3d6cad6ee.jpg",
|
"https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/55/v3/5DZ2LLqYSsK85-shqgLveQ/7ZXcyCWNTvOzQP5FFLBGkg.jpg",
|
||||||
"http://b.hiphotos.baidu.com/image/pic/item/9d82d158ccbf6c81b94575cfb93eb13533fa40a2.jpg",
|
"https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/3e/v3/LqRoLI-PRSu9Nqa8KdJ-pQ/dSqskBpSR9eraAMn7NBdqA.jpg",
|
||||||
"http://e.hiphotos.baidu.com/image/pic/item/4bed2e738bd4b31c1badd5a685d6277f9e2ff81e.jpg",
|
"https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/25/v3/jgB2ekkTRX-3yTYZalnANQ/xff_x9cbSPqb7fbNwgJa7A.jpg",
|
||||||
"http://g.hiphotos.baidu.com/image/pic/item/0d338744ebf81a4c87a3add4d52a6059252da61e.jpg",
|
"https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/fb/v3/alXwXLHKSyCAIWt_ydgD2g/BCCuu25TREOitQxM7eYOEw.jpg",
|
||||||
"http://a.hiphotos.baidu.com/image/pic/item/f2deb48f8c5494ee5080c8142ff5e0fe99257e19.jpg",
|
"https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/63/v3/qbe6NZkCQyGcITvdWoZBgg/Y-5U1z3GT_yaK8CBD3jkwg.jpg",
|
||||||
"http://f.hiphotos.baidu.com/image/pic/item/4034970a304e251f503521f5a586c9177e3e53f9.jpg",
|
"https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/16/v3/fm2tO4TsRH6mv_D_nSSd5w/FscLpLwQQ-KuV7oaprFK2Q.jpg",
|
||||||
"http://b.hiphotos.baidu.com/image/pic/item/279759ee3d6d55fbb3586c0168224f4a20a4dd7e.jpg",
|
"https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/89/v3/UAUvtPHqRD-GWWANsEC57Q/zcRJCQebQ322Aby4jzmwmQ.jpg",
|
||||||
"http://img2.xkhouse.com/bbs/hfhouse/data/attachment/forum/corebbs/2009-11/2009113011534566298.jpg",
|
"https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/30/v3/tUUzzx73R4yp8G--lMhuWQ/EBbcu_dLTT-Jj68XAh6mtA.jpg",
|
||||||
"http://a.hiphotos.baidu.com/image/pic/item/e824b899a9014c087eb617650e7b02087af4f464.jpg",
|
"https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/76/v3/EyF6z4FISpCHhae38eEexw/OtyAiu-zSSevNQYvUdtVmA.jpg",
|
||||||
"http://c.hiphotos.baidu.com/image/pic/item/9c16fdfaaf51f3de1e296fa390eef01f3b29795a.jpg",
|
"https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/37/v3/12rH1yiEQmK9wlOOcy5avQ/RzBXiEBRRqOC7LRkwNj6VA.jpg",
|
||||||
"http://d.hiphotos.baidu.com/image/pic/item/b58f8c5494eef01f119945cbe2fe9925bc317d2a.jpg",
|
"https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/9a/v3/TpRN4AIzRoyUXIqWdKoE0g/ShOnD_tfS46HDbpSWhbCkQ.jpg",
|
||||||
"http://h.hiphotos.baidu.com/image/pic/item/902397dda144ad340668b847d4a20cf430ad851e.jpg",
|
"https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/03/v3/H3X17s8eTdS2w56JgbB5jQ/a45sT-j8Sbe8sSQXTzeYvQ.jpg",
|
||||||
"http://b.hiphotos.baidu.com/image/pic/item/359b033b5bb5c9ea5c0e3c23d139b6003bf3b374.jpg",
|
"https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/10/v3/qaEzwkU0QeKb1yehnP2Xig/q7fxAlgMQKup-HUBayRLGQ.jpg",
|
||||||
"http://a.hiphotos.baidu.com/image/pic/item/8d5494eef01f3a292d2472199d25bc315d607c7c.jpg",
|
"https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/96/v3/rMJJoAflTDSWa1z2pHs2wg/8dOqD0GlQBOCL5AvQok9FQ.jpg",
|
||||||
"http://b.hiphotos.baidu.com/image/pic/item/e824b899a9014c08878b2c4c0e7b02087af4f4a3.jpg",
|
"https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/ed/v3/KMO4D6D2QGuVOCLX4AhOFA/ef51xAaLQuK7BsnuD9abog.jpg",
|
||||||
"http://g.hiphotos.baidu.com/image/pic/item/6d81800a19d8bc3e770bd00d868ba61ea9d345f2.jpg",
|
"https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/d9/v3/FSZH0aTdSqWxeAaxoPvi0g/RqxPxUCXQFiTMBfKTF9kkw.jpg",
|
||||||
"https://hbimg.huabanimg.com/cc6af25f8d782d3cf3122bef4e61571378271145735e9-vEVggB",
|
"https://hbimg.huabanimg.com/cc6af25f8d782d3cf3122bef4e61571378271145735e9-vEVggB",
|
||||||
'https://img-blog.csdnimg.cn/20191215043500229.png',
|
'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://img-blog.csdn.net/20140514114029140',
|
||||||
'https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp',
|
'https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp',
|
||||||
]
|
]
|
||||||
aboutToAppear(): void {
|
aboutToAppear(): void {
|
||||||
this.hotCommendList.addData(this.hotCommendList.totalCount(),this.data)
|
MyStorage.getInstance().WeLink_Mob_fontSize_multiple = 1
|
||||||
AppStorage.set("WeLink_Mob_fontSize_multiple",1)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
build() {
|
build() {
|
||||||
Column() {
|
Column() {
|
||||||
Button("bigger").onClick(()=>{
|
Button("bigger").onClick(()=>{
|
||||||
AppStorage.set("WeLink_Mob_fontSize_multiple",1.6)
|
MyStorage.getInstance().WeLink_Mob_fontSize_multiple = 1.6
|
||||||
})
|
})
|
||||||
Button("small").onClick(()=>{
|
Button("small").onClick(()=>{
|
||||||
AppStorage.set("WeLink_Mob_fontSize_multiple",0.8)
|
MyStorage.getInstance().WeLink_Mob_fontSize_multiple = 0.8
|
||||||
})
|
})
|
||||||
List(){
|
List(){
|
||||||
LazyForEach(this.hotCommendList,(item:string)=>{
|
// LazyForEach(this.hotCommendList,(item:string)=>{
|
||||||
ListItem(){
|
// ListItem(){
|
||||||
ReuseImage({
|
// ReuseImage({
|
||||||
userInfo:item
|
// userInfo:item
|
||||||
}).width("100%").height("100%").backgroundColor(Color.Yellow)
|
// }).width("100%").height("100%").backgroundColor(Color.Yellow)
|
||||||
}.width(200).height(200).margin({bottom:5})
|
// }.width(200).height(200).margin({bottom:5})
|
||||||
})
|
// })
|
||||||
|
Repeat(this.data)
|
||||||
|
.each((repeatItem)=>{
|
||||||
|
ListItem(){
|
||||||
|
ReuseImage({
|
||||||
|
userInfo:repeatItem.item
|
||||||
|
}).width("100%").height("100%").backgroundColor(Color.Yellow)
|
||||||
|
}.width(200).height(200).margin({bottom:5}).key("reuse")
|
||||||
|
})
|
||||||
|
.key(item => item+"reuse")
|
||||||
|
.virtualScroll()
|
||||||
|
.template("1",(repeatItem)=>{
|
||||||
|
ListItem(){
|
||||||
|
ReuseImage({
|
||||||
|
userInfo:repeatItem.item
|
||||||
|
}).width("100%").height("100%").backgroundColor(Color.Yellow)
|
||||||
|
}.width(200).height(200).margin({bottom:5}).key("reuse")
|
||||||
|
})
|
||||||
}
|
}
|
||||||
// .cachedCount(20)
|
// .cachedCount(20)
|
||||||
.width("100%")
|
.width("100%")
|
||||||
|
@ -115,13 +131,13 @@ struct Index {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Reusable
|
// @Reusable
|
||||||
@Component
|
@ComponentV2
|
||||||
struct ReuseImage {
|
struct ReuseImage {
|
||||||
@State userInfo:string = ""
|
@Param userInfo:string = ""
|
||||||
aboutToReuse(params: ESObject): void {
|
// aboutToReuse(params: ESObject): void {
|
||||||
this.userInfo = params.userInfo
|
// this.userInfo = params.userInfo
|
||||||
}
|
// }
|
||||||
|
|
||||||
build() {
|
build() {
|
||||||
Column(){
|
Column(){
|
||||||
|
|
|
@ -18,23 +18,23 @@ import { photoAccessHelper } from '@kit.MediaLibraryKit';
|
||||||
|
|
||||||
|
|
||||||
@Entry
|
@Entry
|
||||||
@Component
|
@ComponentV2
|
||||||
struct DataShareUriLoadPage {
|
struct DataShareUriLoadPage {
|
||||||
@State imageKnifeOption1: ImageKnifeOption =
|
@Local imageKnifeOption1: ImageKnifeOption =
|
||||||
{
|
new ImageKnifeOption({
|
||||||
loadSrc: $r('app.media.icon'),
|
loadSrc: $r('app.media.icon'),
|
||||||
|
|
||||||
placeholderSrc: $r('app.media.loading'),
|
placeholderSrc: $r('app.media.loading'),
|
||||||
errorholderSrc: $r('app.media.failed')
|
errorholderSrc: $r('app.media.failed')
|
||||||
};
|
});
|
||||||
|
|
||||||
|
|
||||||
build() {
|
build() {
|
||||||
Scroll() {
|
Scroll() {
|
||||||
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
||||||
Text("获取媒体图库的uri用ImageKnife展示").fontSize(15)
|
Text($r('app.string.Retrieve_media_gallery')).fontSize(15)
|
||||||
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
||||||
Button("点击加载Uri并展示")
|
Button($r('app.string.Click_load_Uri'))
|
||||||
.onClick(async () => {
|
.onClick(async () => {
|
||||||
let photoSelectOptions = new photoAccessHelper.PhotoSelectOptions();
|
let photoSelectOptions = new photoAccessHelper.PhotoSelectOptions();
|
||||||
photoSelectOptions.MIMEType = photoAccessHelper.PhotoViewMIMETypes.IMAGE_TYPE;
|
photoSelectOptions.MIMEType = photoAccessHelper.PhotoViewMIMETypes.IMAGE_TYPE;
|
||||||
|
@ -43,10 +43,10 @@ struct DataShareUriLoadPage {
|
||||||
let photoViewPicker = new photoAccessHelper.PhotoViewPicker();
|
let photoViewPicker = new photoAccessHelper.PhotoViewPicker();
|
||||||
let photoSelectResult: photoAccessHelper.PhotoSelectResult = await photoViewPicker.select(photoSelectOptions);
|
let photoSelectResult: photoAccessHelper.PhotoSelectResult = await photoViewPicker.select(photoSelectOptions);
|
||||||
uris = photoSelectResult.photoUris;
|
uris = photoSelectResult.photoUris;
|
||||||
this.imageKnifeOption1 = {
|
this.imageKnifeOption1 = new ImageKnifeOption({
|
||||||
loadSrc: uris[0],
|
loadSrc: uris[0],
|
||||||
placeholderSrc:$r('app.media.loading')
|
placeholderSrc:$r('app.media.loading')
|
||||||
}
|
})
|
||||||
}).margin({ top: 5, left: 3 })
|
}).margin({ top: 5, left: 3 })
|
||||||
ImageKnifeComponent({ imageKnifeOption: this.imageKnifeOption1 }).width(300).height(300)
|
ImageKnifeComponent({ imageKnifeOption: this.imageKnifeOption1 }).width(300).height(300)
|
||||||
}.width('100%').backgroundColor(Color.Pink)
|
}.width('100%').backgroundColor(Color.Pink)
|
||||||
|
|
|
@ -5,9 +5,8 @@
|
||||||
"description": "$string:module_desc",
|
"description": "$string:module_desc",
|
||||||
"mainElement": "EntryAbility",
|
"mainElement": "EntryAbility",
|
||||||
"deviceTypes": [
|
"deviceTypes": [
|
||||||
"phone",
|
"default",
|
||||||
"tablet",
|
"tablet"
|
||||||
"2in1"
|
|
||||||
],
|
],
|
||||||
"deliveryWithInstall": true,
|
"deliveryWithInstall": true,
|
||||||
"installationFree": false,
|
"installationFree": false,
|
||||||
|
|
|
@ -19,6 +19,498 @@
|
||||||
{
|
{
|
||||||
"name": "app_permission_READ_IMAGEVIDEO",
|
"name": "app_permission_READ_IMAGEVIDEO",
|
||||||
"value": "获取读媒体资源权限"
|
"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": "Image_Downsampling_Functionality",
|
||||||
|
"value": "Downscale Image effect"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Sampling_pecification",
|
||||||
|
"value": "降采样规格"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Unreal_samples",
|
||||||
|
"value": "未降采样大小"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "After_the_sampling",
|
||||||
|
"value": "降采样后大小"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "image_format",
|
||||||
|
"value": "picture format:%s"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "image_width",
|
||||||
|
"value": "image width:%d"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "image_height",
|
||||||
|
"value": "image height:%d"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "cur_cache_limit",
|
||||||
|
"value": "%s:current cache limit:%fM"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "cur_cache_image_num",
|
||||||
|
"value": "%s:current cache image number:%d"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "cur_cache_size",
|
||||||
|
"value": "%s:current cache size:%fM"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "load_memory",
|
||||||
|
"value": "memory loaded picture"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "load_disk",
|
||||||
|
"value": "disk cache loads images"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "get_cur_memory_limit",
|
||||||
|
"value": "gets the current memory cache upper limit"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "get_img_number_of_cache",
|
||||||
|
"value": "gets the number of images cached in memory"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "get_cur_memory_size",
|
||||||
|
"value": "gets the size of the current cache"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "get_cur_disk_limit",
|
||||||
|
"value": "Gets the current disk cache upper limit"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "get_img_number_of_disk",
|
||||||
|
"value": "gets the number of images cached on disk"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "get_cur_disk_size",
|
||||||
|
"value": "gets the size of the current disk"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "select_color_btn",
|
||||||
|
"value": "click to select the color you want to change"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "click_img_to_change_color",
|
||||||
|
"value": "click on the image to change the image color"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "test_non_svg_color",
|
||||||
|
"value": "test non-SVG images for color change"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "test_svg_color",
|
||||||
|
"value": "Test svg picture color change"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "red",
|
||||||
|
"value": "red"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "yellow",
|
||||||
|
"value": "yellow"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "green",
|
||||||
|
"value": "green"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "blue",
|
||||||
|
"value": "blue"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "master_image",
|
||||||
|
"value": "master image:"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "rm_component_of_net",
|
||||||
|
"value": "remove Component - Network load picture"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "rm_component_of_local",
|
||||||
|
"value": "remove Component - Local resource picture"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "component_display",
|
||||||
|
"value": "recovery component display"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "onLoadCancel_reason",
|
||||||
|
"value": "onLoadCancel callback reason:%s"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "test_cache_btn",
|
||||||
|
"value": "test data for in cache"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "test_change_color_btn",
|
||||||
|
"value": "test change color for image"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "test_cancel_callback_btn",
|
||||||
|
"value": "test callback of cancel"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "memory",
|
||||||
|
"value": "Memory"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "disk",
|
||||||
|
"value": "Disk"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
Binary file not shown.
After Width: | Height: | Size: 3.4 KiB |
|
@ -0,0 +1,14 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
|
<title>svg细图标</title>
|
||||||
|
<g id="细图标" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||||
|
<g id="dot_radiowaves_left_and_right" fill="#000000" fill-rule="nonzero">
|
||||||
|
<rect id="矩形" opacity="0" x="0" y="0" width="24" height="24"></rect>
|
||||||
|
<g id="编组" transform="translate(0.000000, 3.000000)" fill-opacity="0.90196079">
|
||||||
|
<path d="M12,7.01 C11.44,7.01 10.9633333,7.20666667 10.57,7.6 C10.1766667,7.98666667 9.98,8.45333333 9.98,9 C9.98,9.54666667 10.18,10.02 10.58,10.42 C10.98,10.82 11.4533333,11.02 12,11.02 C12.5466667,11.02 13.0133333,10.8233333 13.4,10.43 C13.7933333,10.0366667 13.99,9.56 13.99,9 C13.99,8.44 13.8,7.96666667 13.42,7.58 C13.0333333,7.2 12.56,7.01 12,7.01 Z" id="路径"></path>
|
||||||
|
<path d="M5.23,9 C5.23,10.1533333 5.50666667,11.2333333 6.06,12.24 C6.61333333,13.2466667 7.37666667,14.0633333 8.35,14.69 C8.53,14.8033333 8.72,14.8333333 8.92,14.78 C9.12,14.7333333 9.27333333,14.6233333 9.38,14.45 C9.49333333,14.27 9.52666667,14.08 9.48,13.88 C9.43333333,13.68 9.33,13.5266667 9.17,13.42 C8.41666667,12.92 7.82333333,12.2833333 7.39,11.51 C6.95666667,10.73 6.74,9.89333333 6.74,9 C6.74,8.10666667 6.95333333,7.26666667 7.38,6.48 C7.80666667,5.69333333 8.40333333,5.05333333 9.17,4.56 C9.34333333,4.44666667 9.45,4.29 9.49,4.09 C9.53,3.89 9.49333333,3.70333333 9.38,3.53 C9.27333333,3.35 9.12,3.23666667 8.92,3.19 C8.72,3.14333333 8.53,3.18333333 8.35,3.31 C7.37666667,3.93666667 6.61333333,4.75 6.06,5.75 C5.50666667,6.75 5.23,7.83333333 5.23,9 Z M14.59,14.45 C14.7033333,14.6233333 14.8533333,14.7333333 15.04,14.78 C15.22,14.8333333 15.4233333,14.8033333 15.65,14.69 C16.29,14.27 16.84,13.7666667 17.3,13.18 C17.7666667,12.5866667 18.1233333,11.9333333 18.37,11.22 C18.6166667,10.5066667 18.74,9.76666667 18.74,9 C18.74,7.83333333 18.47,6.75 17.93,5.75 C17.3833333,4.75 16.6233333,3.93666667 15.65,3.31 C15.47,3.18333333 15.2766667,3.14333333 15.07,3.19 C14.8633333,3.23666667 14.7033333,3.35 14.59,3.53 C14.4766667,3.70333333 14.44,3.88666667 14.48,4.08 C14.52,4.27333333 14.63,4.42666667 14.81,4.54 L14.83,4.56 C15.5833333,5.05333333 16.1766667,5.69333333 16.61,6.48 C17.0433333,7.26666667 17.26,8.10666667 17.26,9 C17.26,9.59333333 17.1633333,10.1666667 16.97,10.72 C16.7766667,11.2666667 16.4966667,11.7733333 16.13,12.24 C15.7633333,12.7066667 15.33,13.1 14.83,13.42 C14.6566667,13.5266667 14.5466667,13.68 14.5,13.88 C14.4466667,14.08 14.4766667,14.27 14.59,14.45 Z" id="形状"></path>
|
||||||
|
<path d="M0.77,9 C0.77,10.6666667 1.12,12.2466667 1.82,13.74 C2.52666667,15.2333333 3.51333333,16.5166667 4.78,17.59 C4.94,17.7166667 5.12,17.7733333 5.32,17.76 C5.52,17.7466667 5.69,17.6666667 5.83,17.52 C5.95666667,17.36 6.01333333,17.1766667 6,16.97 C5.98666667,16.7633333 5.9,16.5866667 5.74,16.44 C4.63333333,15.5133333 3.77666667,14.4 3.17,13.1 C2.56333333,11.8066667 2.26,10.44 2.26,9 C2.26,7.56 2.56333333,6.18666667 3.17,4.88 C3.77666667,3.58 4.64,2.46666667 5.76,1.54 C5.90666667,1.39333333 5.99,1.21666667 6.01,1.01 C6.03666667,0.803333333 5.97666667,0.626666667 5.83,0.48 C5.70333333,0.32 5.53666667,0.233333333 5.33,0.22 C5.12333333,0.2 4.94,0.253333333 4.78,0.38 C3.51333333,1.45333333 2.52666667,2.74333333 1.82,4.25 C1.12,5.75 0.77,7.33333333 0.77,9 Z M18.17,17.5 C18.2966667,17.66 18.4633333,17.7466667 18.67,17.76 C18.8766667,17.7733333 19.06,17.7166667 19.22,17.59 C20.0733333,16.89 20.8,16.0833333 21.4,15.17 C22,14.2566667 22.4533333,13.2766667 22.76,12.23 C23.0733333,11.1833333 23.23,10.1066667 23.23,9 C23.23,7.89333333 23.0733333,6.81666667 22.76,5.77 C22.4533333,4.72333333 22,3.74 21.4,2.82 C20.8,1.9 20.0733333,1.08666667 19.22,0.38 C19.06,0.253333333 18.8766667,0.2 18.67,0.22 C18.4633333,0.233333333 18.2966667,0.32 18.17,0.48 C18.0233333,0.64 17.96,0.823333333 17.98,1.03 C17.9933333,1.23666667 18.08,1.40666667 18.24,1.54 C18.9733333,2.14666667 19.6,2.85 20.12,3.65 C20.64,4.45 21.0366667,5.3 21.31,6.2 C21.5833333,7.10666667 21.72,8.04 21.72,9 C21.72,9.96 21.5833333,10.8933333 21.31,11.8 C21.0366667,12.7 20.6466667,13.5466667 20.14,14.34 C19.6266667,15.1333333 19,15.8333333 18.26,16.44 C18.1,16.5666667 18.0133333,16.7333333 18,16.94 C17.9866667,17.1533333 18.0433333,17.34 18.17,17.5 Z" id="形状"></path>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 4.4 KiB |
Binary file not shown.
After Width: | Height: | Size: 922 KiB |
Binary file not shown.
|
@ -3,7 +3,6 @@
|
||||||
"pages/Index",
|
"pages/Index",
|
||||||
"pages/ListPage",
|
"pages/ListPage",
|
||||||
"pages/SingleImage",
|
"pages/SingleImage",
|
||||||
"pages/ManyPhotoShowPage",
|
|
||||||
"pages/LongImagePage",
|
"pages/LongImagePage",
|
||||||
"pages/TransformPage",
|
"pages/TransformPage",
|
||||||
"pages/UserPage",
|
"pages/UserPage",
|
||||||
|
@ -22,6 +21,11 @@
|
||||||
"pages/TestCommonImage",
|
"pages/TestCommonImage",
|
||||||
"pages/ImageAnimatorPage",
|
"pages/ImageAnimatorPage",
|
||||||
"pages/TestSetCustomImagePage",
|
"pages/TestSetCustomImagePage",
|
||||||
"pages/TestErrorHolderPage"
|
"pages/TestErrorHolderPage",
|
||||||
|
"pages/TestTaskResourcePage",
|
||||||
|
"pages/DownSamplePage",
|
||||||
|
"pages/TestCacheDataPage",
|
||||||
|
"pages/TestChangeColorPage",
|
||||||
|
"pages/TestLoadCancelListenerPage"
|
||||||
]
|
]
|
||||||
}
|
}
|
|
@ -19,6 +19,494 @@
|
||||||
{
|
{
|
||||||
"name": "app_permission_READ_IMAGEVIDEO",
|
"name": "app_permission_READ_IMAGEVIDEO",
|
||||||
"value": "获取读媒体资源权限"
|
"value": "获取读媒体资源权限"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Test_ImageAnimator",
|
||||||
|
"value": "测试ImageAnimator组件"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Test_multiple_images",
|
||||||
|
"value": "测试加载多张相同图片"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Test_Task_error",
|
||||||
|
"value": "测试占位图Task报错"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Test_HSP",
|
||||||
|
"value": "测试HSP场景预加载"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Test_SingleImage",
|
||||||
|
"value": "单个图片使用"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Test_custom_download",
|
||||||
|
"value": "全局自定义下载"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Multiple_images",
|
||||||
|
"value": "多图"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Display_long_image",
|
||||||
|
"value": "长图显示"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Image_scaling",
|
||||||
|
"value": "缩放图片"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Message_list",
|
||||||
|
"value": "消息列表"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Custom_cache_key",
|
||||||
|
"value": "自定义缓存key"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Preloading_images_to_cache",
|
||||||
|
"value": "预加载图片到文件缓存"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Retrieve_image_display_from_cache",
|
||||||
|
"value": "从缓存获取图片显示"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Test_single_request_header",
|
||||||
|
"value": "测试单个请求头"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Test_write_cache_strategy",
|
||||||
|
"value": "测试写入缓存策略"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Image_Transformation",
|
||||||
|
"value": "图片变换"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Different_ObjectFit",
|
||||||
|
"value": "不同的ObjectFit"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Test_image_loading_success_or_failure_events",
|
||||||
|
"value": "测试图片加载成功/失败事件"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Test_removing_image_cache_interface",
|
||||||
|
"value": "测试移除图片缓存接口"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Test_error_image_display",
|
||||||
|
"value": "测试错误图显示"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Display_the_first_frame",
|
||||||
|
"value": "动画显示第一帧"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Display_the_last_frame",
|
||||||
|
"value": "动画显示最后一帧"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Play",
|
||||||
|
"value": "播放"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Pause",
|
||||||
|
"value": "暂停"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Stop",
|
||||||
|
"value": "停止"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Infinite_loop",
|
||||||
|
"value": "无限循环"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Play_once",
|
||||||
|
"value": "播放一次"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Play_twice",
|
||||||
|
"value": "播放两次"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Local_SVG",
|
||||||
|
"value": "本地资源SVG图片"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Under_context_file",
|
||||||
|
"value": "本地context files下文件"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Network_images",
|
||||||
|
"value": "网络图片"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Custom_network_download",
|
||||||
|
"value": "自定义下载"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "PixelMap_loads_images",
|
||||||
|
"value": "PixelMap加载图片"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Enlarge",
|
||||||
|
"value": "放大"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Reduce",
|
||||||
|
"value": "缩小"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Click_on_add",
|
||||||
|
"value": "点击尺寸加50"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Click_on_reduce",
|
||||||
|
"value": "点击尺寸减50"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "The_key_fixed_1",
|
||||||
|
"value": "key固定为 1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "The_key_changes_timestamp",
|
||||||
|
"value": "key每次变化:时间戳"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Load",
|
||||||
|
"value": "加载"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Preloading_images_to_file_cache_using_URL",
|
||||||
|
"value": "url预加载图片到文件缓存"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Preloading_images_to_file_cache_using_option",
|
||||||
|
"value": "option预加载图片到文件缓存"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Load_image_offline_after_preloading",
|
||||||
|
"value": "加载图片(预加载后可断网加载)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Preloading_GIF",
|
||||||
|
"value": "预加载gif图"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Retrieve_GIF_from_memory",
|
||||||
|
"value": "内存缓存获取gif"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Retrieve_GIF_from_disk",
|
||||||
|
"value": "文件缓存获取gif"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Preloading_static_images",
|
||||||
|
"value": "预加载静态图"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Retrieve_images_from_memory",
|
||||||
|
"value": "内存缓存获取"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Retrieve_images_from_disk",
|
||||||
|
"value": "文件缓存获取"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Write_memory_and_file",
|
||||||
|
"value": "写入内存文件缓存"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Write_memory",
|
||||||
|
"value": "写入内存缓存"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Write_file",
|
||||||
|
"value": "写入文件缓存"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Main_image_Fill",
|
||||||
|
"value": "主图Fill拉伸填充"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Maintain_proportion_filling",
|
||||||
|
"value": "占位图Contain保持比例填充"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Error_graph_None",
|
||||||
|
"value": "错误图None不变化"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Test_failure_success",
|
||||||
|
"value": "测试失败/成功场景"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Custom_download_failed",
|
||||||
|
"value": "自定义下载失败"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Retrieve_media_gallery",
|
||||||
|
"value": "获取媒体图库的uri用ImageKnife展示"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Click_load_Uri",
|
||||||
|
"value": "点击加载Uri并展示"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Delete_all_caches",
|
||||||
|
"value": "删除全部缓存"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Delete_all_memory_caches",
|
||||||
|
"value": "删除全部内存缓存"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Delete_all_file_caches",
|
||||||
|
"value": "删除全部文件缓存"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Delete_all_custom_memory_caches",
|
||||||
|
"value": "删除自定义内存缓存"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Delete_all_custom_file_caches",
|
||||||
|
"value": "删除自定义文件缓存"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Blur_effect",
|
||||||
|
"value": "模糊效果"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Highlighting_effect",
|
||||||
|
"value": "高亮效果"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Ashing_effect",
|
||||||
|
"value": "灰化效果"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Inverse_effect",
|
||||||
|
"value": "反转效果"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Animation_filter_effect",
|
||||||
|
"value": "动画滤镜效果"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Crop_circular_effect",
|
||||||
|
"value": "裁剪圆形效果"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Crop_circular_with_border_effect",
|
||||||
|
"value": "裁剪圆形带边框效果"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Contrast_effect",
|
||||||
|
"value": "对比度效果"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Black_ink_filtering_effect",
|
||||||
|
"value": "乌墨色滤波效果"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Rotate",
|
||||||
|
"value": "旋转效果"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Corners",
|
||||||
|
"value": "圆角效果"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Kuwahara_Filter_effect",
|
||||||
|
"value": "桑原滤波效果"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Pixelated_Filter_effect",
|
||||||
|
"value": "像素化滤波效果"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Sketch_Filter_effect",
|
||||||
|
"value": "素描滤波效果"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Distortion_Filter_effect",
|
||||||
|
"value": "扭曲滤波效果"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Decorative_Filter_effect",
|
||||||
|
"value": "装饰滤波效果"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Square_cutting_effect",
|
||||||
|
"value": "正方形裁剪效果"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Top_cutting_effect",
|
||||||
|
"value": "上方裁剪效果"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Middle_cutting_effect",
|
||||||
|
"value": "中间裁剪效果"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Bottom_cutting_effect",
|
||||||
|
"value": "底下裁剪效果"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Mask_effect",
|
||||||
|
"value": "遮罩效果"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "TIPS",
|
||||||
|
"value": "测试失败场景请先关闭网络,并保证本地没有此网络图片的缓存"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Image_Downsampling_Functionality",
|
||||||
|
"value": "降采样功能"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Sampling_pecification",
|
||||||
|
"value": "降采样规格"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Unreal_samples",
|
||||||
|
"value": "未降采样大小"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "After_the_sampling",
|
||||||
|
"value": "降采样后大小"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "image_format",
|
||||||
|
"value": "图片格式:%s"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "image_width",
|
||||||
|
"value": "图片宽度:%d"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "image_height",
|
||||||
|
"value": "图片高度:%d"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "cur_cache_limit",
|
||||||
|
"value": "%s:当前缓存上限:%fM"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "cur_cache_image_num",
|
||||||
|
"value": "%s:当前缓存图片数量:%d"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "cur_cache_size",
|
||||||
|
"value": "%s:当前缓存的大小:%fM"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "load_memory",
|
||||||
|
"value": "内存加载图片"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "load_disk",
|
||||||
|
"value": "磁盘缓存加载图片"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "get_cur_memory_limit",
|
||||||
|
"value": "获取当前内存缓存上限"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "get_img_number_of_cache",
|
||||||
|
"value": "获取当前内存缓存图片数量"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "get_cur_memory_size",
|
||||||
|
"value": "获取当前缓存的大小"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "get_cur_disk_limit",
|
||||||
|
"value": "获取当前磁盘缓存上限"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "get_img_number_of_disk",
|
||||||
|
"value": "获取当前磁盘缓存图片数量"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "get_cur_disk_size",
|
||||||
|
"value": "获取当前磁盘的大小"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "select_color_btn",
|
||||||
|
"value": "点击选择要更改的颜色"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "click_img_to_change_color",
|
||||||
|
"value": "点击图片更改图片颜色"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "test_non_svg_color",
|
||||||
|
"value": "测试非svg图片变色"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "test_svg_color",
|
||||||
|
"value": "测试svg图片变色"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "red",
|
||||||
|
"value": "红色"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "yellow",
|
||||||
|
"value": "黄色"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "green",
|
||||||
|
"value": "绿色"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "blue",
|
||||||
|
"value": "蓝色"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "master_image",
|
||||||
|
"value": "原图:"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "rm_component_of_net",
|
||||||
|
"value": "移除组件-网络加载图片"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "rm_component_of_local",
|
||||||
|
"value": "移除组件-本地资源图片"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "component_display",
|
||||||
|
"value": "恢复组件显示"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "onLoadCancel_reason",
|
||||||
|
"value": "onLoadCancel回调原因:%s"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "test_cache_btn",
|
||||||
|
"value": "测试缓存数据"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "test_change_color_btn",
|
||||||
|
"value": "测试颜色变换"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "test_cancel_callback_btn",
|
||||||
|
"value": "测试加载取消回调接口"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "memory",
|
||||||
|
"value": "内存"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "disk",
|
||||||
|
"value": "磁盘"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
|
@ -14,8 +14,8 @@
|
||||||
*/
|
*/
|
||||||
import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium';
|
import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium';
|
||||||
import { ImageKnifeOption, ImageKnifeRequest } from '@ohos/imageknife/Index';
|
import { ImageKnifeOption, ImageKnifeRequest } from '@ohos/imageknife/Index';
|
||||||
import { DefaultJobQueue } from '@ohos/imageknife/src/main/ets/utils/DefaultJobQueue';
|
import { DefaultJobQueue } from '@ohos/imageknife/src/main/ets/queue/DefaultJobQueue';
|
||||||
import { IJobQueue } from '@ohos/imageknife/src/main/ets/utils/IJobQueue';
|
import { IJobQueue } from '@ohos/imageknife/src/main/ets/queue/IJobQueue';
|
||||||
import taskpool from '@ohos.taskpool';
|
import taskpool from '@ohos.taskpool';
|
||||||
import common from '@ohos.app.ability.common';
|
import common from '@ohos.app.ability.common';
|
||||||
|
|
||||||
|
@ -70,10 +70,10 @@ export default function DefaultJobQueueTest() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function makeRequest(src: string, context: common.UIAbilityContext, priority?: taskpool.Priority): ImageKnifeRequest {
|
function makeRequest(src: string, context: common.UIAbilityContext, priority?: taskpool.Priority): ImageKnifeRequest {
|
||||||
let option: ImageKnifeOption = {
|
let option: ImageKnifeOption = new ImageKnifeOption({
|
||||||
loadSrc: src,
|
loadSrc: src,
|
||||||
priority: priority
|
priority: priority
|
||||||
}
|
})
|
||||||
return new ImageKnifeRequest(
|
return new ImageKnifeRequest(
|
||||||
option,
|
option,
|
||||||
context,
|
context,
|
||||||
|
|
|
@ -17,7 +17,7 @@ import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from
|
||||||
import Constants from '../../../main/ets/common/Constants';
|
import Constants from '../../../main/ets/common/Constants';
|
||||||
import taskpool from '@ohos.taskpool';
|
import taskpool from '@ohos.taskpool';
|
||||||
import { GlobalContext } from '../../../main/ets/common/GlobalContext';
|
import { GlobalContext } from '../../../main/ets/common/GlobalContext';
|
||||||
import { FileCache } from '@ohos/imageknife/src/main/ets/utils/FileCache';
|
import { FileCache } from '@ohos/imageknife/src/main/ets/cache/FileCache';
|
||||||
import { IEngineKey, ImageKnifeOption } from '@ohos/imageknife';
|
import { IEngineKey, ImageKnifeOption } from '@ohos/imageknife';
|
||||||
import { DefaultEngineKey } from '@ohos/imageknife/src/main/ets/key/DefaultEngineKey';
|
import { DefaultEngineKey } from '@ohos/imageknife/src/main/ets/key/DefaultEngineKey';
|
||||||
|
|
||||||
|
@ -153,9 +153,9 @@ export default function FileLruCacheTest() {
|
||||||
});
|
});
|
||||||
it('fileCacheEngineKey', 0, () => {
|
it('fileCacheEngineKey', 0, () => {
|
||||||
let engineKey: IEngineKey = new DefaultEngineKey()
|
let engineKey: IEngineKey = new DefaultEngineKey()
|
||||||
let imageKnifeOption: ImageKnifeOption = {
|
let imageKnifeOption: ImageKnifeOption = new ImageKnifeOption({
|
||||||
loadSrc:"abc"
|
loadSrc:"abc"
|
||||||
}
|
})
|
||||||
let imageKey = engineKey.generateFileKey(imageKnifeOption.loadSrc,"")
|
let imageKey = engineKey.generateFileKey(imageKnifeOption.loadSrc,"")
|
||||||
let imageAnimatorKey = engineKey.generateFileKey(imageKnifeOption.loadSrc,"",true)
|
let imageAnimatorKey = engineKey.generateFileKey(imageKnifeOption.loadSrc,"",true)
|
||||||
expect(imageKey == imageAnimatorKey).assertFalse()
|
expect(imageKey == imageAnimatorKey).assertFalse()
|
||||||
|
|
|
@ -40,10 +40,10 @@ export default function ImageKnifeTest() {
|
||||||
|
|
||||||
it('removeMemoryCache', 0, async () => {
|
it('removeMemoryCache', 0, async () => {
|
||||||
let a = 'https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp';
|
let a = 'https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp';
|
||||||
let option: ImageKnifeOption = {
|
let option: ImageKnifeOption = new ImageKnifeOption({
|
||||||
loadSrc: 'https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp',
|
loadSrc: 'https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp',
|
||||||
signature: ''
|
signature: ''
|
||||||
}
|
})
|
||||||
let key = ImageKnife.getInstance()
|
let key = ImageKnife.getInstance()
|
||||||
.getEngineKeyImpl()
|
.getEngineKeyImpl()
|
||||||
.generateMemoryKey('https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp', ImageKnifeRequestSource.SRC, option)
|
.generateMemoryKey('https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp', ImageKnifeRequestSource.SRC, option)
|
||||||
|
|
|
@ -44,7 +44,7 @@ export default function ImageKnifeOptionTest() {
|
||||||
imageWidth: 0,
|
imageWidth: 0,
|
||||||
imageHeight: 0,
|
imageHeight: 0,
|
||||||
}
|
}
|
||||||
let ImageKnifeOption: ImageKnifeOption = {
|
let imageKnifeOption: ImageKnifeOption = new ImageKnifeOption({
|
||||||
loadSrc: $r("app.media.rabbit"),
|
loadSrc: $r("app.media.rabbit"),
|
||||||
onLoadListener: {
|
onLoadListener: {
|
||||||
onLoadFailed: (err) => {
|
onLoadFailed: (err) => {
|
||||||
|
@ -58,10 +58,10 @@ export default function ImageKnifeOptionTest() {
|
||||||
return data;
|
return data;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
})
|
||||||
if (ImageKnifeOption.onLoadListener && ImageKnifeOption.onLoadListener.onLoadSuccess && ImageKnifeOption.onLoadListener.onLoadFailed) {
|
if (imageKnifeOption.onLoadListener && imageKnifeOption.onLoadListener.onLoadSuccess && imageKnifeOption.onLoadListener.onLoadFailed) {
|
||||||
ImageKnifeOption.onLoadListener.onLoadSuccess(a,imageData);
|
imageKnifeOption.onLoadListener.onLoadSuccess(a,imageData);
|
||||||
ImageKnifeOption.onLoadListener.onLoadFailed(a);
|
imageKnifeOption.onLoadListener.onLoadFailed(a);
|
||||||
}
|
}
|
||||||
expect(a).assertEqual(b);
|
expect(a).assertEqual(b);
|
||||||
});
|
});
|
||||||
|
|
|
@ -18,6 +18,8 @@ import ImageKnifeOptionTest from './ImageKnifeOption.test';
|
||||||
import MemoryLruCacheTest from './MemoryLruCache.test';
|
import MemoryLruCacheTest from './MemoryLruCache.test';
|
||||||
import ImageKnifeTest from './ImageKnife.test';
|
import ImageKnifeTest from './ImageKnife.test';
|
||||||
import Transform from './transform.test';
|
import Transform from './transform.test';
|
||||||
|
import SamplingTest from './SamplingTest.test';
|
||||||
|
import imageFormatAndSize from './imageFormatAndSize.test'
|
||||||
|
|
||||||
export default function testsuite() {
|
export default function testsuite() {
|
||||||
MemoryLruCacheTest();
|
MemoryLruCacheTest();
|
||||||
|
@ -26,4 +28,6 @@ export default function testsuite() {
|
||||||
ImageKnifeOptionTest();
|
ImageKnifeOptionTest();
|
||||||
ImageKnifeTest();
|
ImageKnifeTest();
|
||||||
Transform();
|
Transform();
|
||||||
|
SamplingTest()
|
||||||
|
imageFormatAndSize();
|
||||||
}
|
}
|
|
@ -17,7 +17,7 @@ import image from '@ohos.multimedia.image';
|
||||||
|
|
||||||
|
|
||||||
import Constants from '../../../main/ets/common/Constants';
|
import Constants from '../../../main/ets/common/Constants';
|
||||||
import { MemoryLruCache } from '@ohos/imageknife/src/main/ets/utils/MemoryLruCache';
|
import { MemoryLruCache } from '@ohos/imageknife/src/main/ets/cache/MemoryLruCache';
|
||||||
import { ImageKnifeData } from '@ohos/imageknife/src/main/ets/model/ImageKnifeData';
|
import { ImageKnifeData } from '@ohos/imageknife/src/main/ets/model/ImageKnifeData';
|
||||||
import { IEngineKey, ImageKnifeOption,ImageKnifeRequestSource } from '@ohos/imageknife';
|
import { IEngineKey, ImageKnifeOption,ImageKnifeRequestSource } from '@ohos/imageknife';
|
||||||
import { DefaultEngineKey } from '@ohos/imageknife/src/main/ets/key/DefaultEngineKey';
|
import { DefaultEngineKey } from '@ohos/imageknife/src/main/ets/key/DefaultEngineKey';
|
||||||
|
@ -122,9 +122,9 @@ export default function MemoryLruCacheTest() {
|
||||||
|
|
||||||
it('memoryCacheEngineKey', 0, () => {
|
it('memoryCacheEngineKey', 0, () => {
|
||||||
let engineKey: IEngineKey = new DefaultEngineKey()
|
let engineKey: IEngineKey = new DefaultEngineKey()
|
||||||
let imageKnifeOption: ImageKnifeOption = {
|
let imageKnifeOption: ImageKnifeOption = new ImageKnifeOption({
|
||||||
loadSrc:"abc"
|
loadSrc:"abc"
|
||||||
}
|
})
|
||||||
let imageKey = engineKey.generateMemoryKey(imageKnifeOption.loadSrc,ImageKnifeRequestSource.SRC,imageKnifeOption)
|
let imageKey = engineKey.generateMemoryKey(imageKnifeOption.loadSrc,ImageKnifeRequestSource.SRC,imageKnifeOption)
|
||||||
let imageAnimatorKey = engineKey.generateMemoryKey(imageKnifeOption.loadSrc,ImageKnifeRequestSource.SRC,imageKnifeOption,true)
|
let imageAnimatorKey = engineKey.generateMemoryKey(imageKnifeOption.loadSrc,ImageKnifeRequestSource.SRC,imageKnifeOption,true)
|
||||||
expect(imageKey == imageAnimatorKey).assertFalse()
|
expect(imageKey == imageAnimatorKey).assertFalse()
|
||||||
|
|
|
@ -0,0 +1,79 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2024 Huawei Device Co., Ltd.
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
import { 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);
|
||||||
|
})
|
||||||
|
|
||||||
|
})
|
||||||
|
}
|
|
@ -0,0 +1,52 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2024 Huawei Device Co., Ltd.
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'
|
||||||
|
import { SendableData } from '@ohos/imageknife/src/main/ets/components/imageknife/SendableData'
|
||||||
|
|
||||||
|
export default function SendableDataTest() {
|
||||||
|
describe('SendableDataTest', ()=> {
|
||||||
|
// Defines a test suite. Two parameters are supported: test suite name and test suite function.
|
||||||
|
beforeAll( ()=> {
|
||||||
|
// Presets an action, which is performed only once before all test cases of the test suite start.
|
||||||
|
// This API supports only one parameter: preset action function.
|
||||||
|
})
|
||||||
|
beforeEach( ()=> {
|
||||||
|
// Presets an action, which is performed before each unit test case starts.
|
||||||
|
// The number of execution times is the same as the number of test cases defined by **it**.
|
||||||
|
// This API supports only one parameter: preset action function.
|
||||||
|
})
|
||||||
|
afterEach( ()=> {
|
||||||
|
// Presets a clear action, which is performed after each unit test case ends.
|
||||||
|
// The number of execution times is the same as the number of test cases defined by **it**.
|
||||||
|
// This API supports only one parameter: clear action function.
|
||||||
|
})
|
||||||
|
afterAll( ()=> {
|
||||||
|
// Presets a clear action, which is performed after all test cases of the test suite end.
|
||||||
|
// This API supports only one parameter: clear action function.
|
||||||
|
})
|
||||||
|
it('TestPlaceHolderCacheKey', 0, () => {
|
||||||
|
let value: string = "placeholderRegisterCacheKey";
|
||||||
|
let data: SendableData = new SendableData();
|
||||||
|
data.setPlaceHolderRegisterCacheKey(value);
|
||||||
|
expect(data.getPlaceHolderRegisterCacheKey()).assertEqual(value);
|
||||||
|
})
|
||||||
|
it('TestPlaceHolderMemoryCacheKey', 1, () => {
|
||||||
|
let value: string = "placeholderRegisterMemoryCacheKey";
|
||||||
|
let data: SendableData = new SendableData();
|
||||||
|
data.setPlaceHolderRegisterMemoryCacheKey(value);
|
||||||
|
expect(data.getPlaceHolderRegisterMemoryCacheKey()).assertEqual(value);
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
|
@ -0,0 +1,106 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2024 Huawei Device Co., Ltd.
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'
|
||||||
|
import { DownloadClient } from '@ohos/imageknife/src/main/ets/components/imageknife/networkmanage/DownloadClient';
|
||||||
|
import common from '@ohos.app.ability.common';
|
||||||
|
import { GlobalContext } from '../testability/GlobalContext';
|
||||||
|
import { CustomDataFetchClient, DataFetchResult, ImageKnifeGlobal, RequestOption } from '@ohos/imageknife';
|
||||||
|
|
||||||
|
const BASE_COUNT: number = 2000;
|
||||||
|
|
||||||
|
export default function CustomDataFetchClientTest() {
|
||||||
|
describe('CustomDataFetchClientTest', () => {
|
||||||
|
// Defines a test suite. Two parameters are supported: test suite name and test suite function.
|
||||||
|
beforeAll(() => {
|
||||||
|
// Presets an action, which is performed only once before all test cases of the test suite start.
|
||||||
|
// This API supports only one parameter: preset action function.
|
||||||
|
})
|
||||||
|
beforeEach(() => {
|
||||||
|
// Presets an action, which is performed before each unit test case starts.
|
||||||
|
// The number of execution times is the same as the number of test cases defined by **it**.
|
||||||
|
// This API supports only one parameter: preset action function.
|
||||||
|
})
|
||||||
|
afterEach(() => {
|
||||||
|
// Presets a clear action, which is performed after each unit test case ends.
|
||||||
|
// The number of execution times is the same as the number of test cases defined by **it**.
|
||||||
|
// This API supports only one parameter: clear action function.
|
||||||
|
})
|
||||||
|
afterAll(() => {
|
||||||
|
// Presets a clear action, which is performed after all test cases of the test suite end.
|
||||||
|
// This API supports only one parameter: clear action function.
|
||||||
|
})
|
||||||
|
it('TestIsLocalLoadSrc', 0, () => {
|
||||||
|
let path = 'invalid path';
|
||||||
|
let client = new DownloadClient()
|
||||||
|
expect(client.isLocalLoadSrc(undefined, path)).assertFalse();
|
||||||
|
let context: object | undefined = GlobalContext.getInstance().getObject("hapContext");
|
||||||
|
if (context != undefined) {
|
||||||
|
let loadSrc1 = (context as common.UIAbilityContext).filesDir + 'a.jpg';
|
||||||
|
let loadSrc2 = (context as common.UIAbilityContext).cacheDir + 'b.jpg';
|
||||||
|
expect(client.isLocalLoadSrc(context, loadSrc1)).assertTrue();
|
||||||
|
expect(client.isLocalLoadSrc(context, loadSrc2)).assertTrue();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
it('TestLoadData', 1, async () => {
|
||||||
|
let client = new CustomDataFetchClient();
|
||||||
|
let request = new RequestOption();
|
||||||
|
request.loadSrc = $r('app.media.icon');
|
||||||
|
let error = (await client.loadData(request) as DataFetchResult).error as String;
|
||||||
|
expect(error).assertEqual('CustomDataFetchClient request or loadSrc error.');
|
||||||
|
})
|
||||||
|
it('TestLoadData_customGetImage', 2, async () => {
|
||||||
|
let client = new CustomDataFetchClient();
|
||||||
|
let request = new RequestOption();
|
||||||
|
request.loadSrc = 'http://e.hiphotos.baidu.com/image/pic/item/4e4a20a4462309f7e41f5cfe760e0cf3d6cad6ee.jpg';
|
||||||
|
request.customGetImage = (context: Context, src: string) => {
|
||||||
|
// 这里是模拟的customGetImage逻辑
|
||||||
|
return Promise.resolve(new DataFetchResult());
|
||||||
|
}
|
||||||
|
console.log('LXH', 'TestLoadData 2 --1 customGetImage is undefined ?' + (request.customGetImage == undefined));
|
||||||
|
let context: object | undefined = GlobalContext.getInstance().getObject("hapContext");
|
||||||
|
let result = await client.loadData(request);
|
||||||
|
if (context != undefined) {
|
||||||
|
console.log('LXH', 'TestLoadData 2 --2');
|
||||||
|
expect(typeof result)
|
||||||
|
.assertEqual(typeof (await request?.customGetImage(context as common.UIAbilityContext, request.loadSrc)));
|
||||||
|
}
|
||||||
|
})
|
||||||
|
it('TestLoadData_combineArrayBuffers', 3, () => {
|
||||||
|
// 创建几个ArrayBuffer作为测试数据
|
||||||
|
const arrayBuffer1 = new ArrayBuffer(4);
|
||||||
|
const uint8Array1 = new Uint8Array(arrayBuffer1);
|
||||||
|
uint8Array1[0] = 1;
|
||||||
|
uint8Array1[1] = 2;
|
||||||
|
uint8Array1[2] = 3;
|
||||||
|
uint8Array1[3] = 4;
|
||||||
|
|
||||||
|
const arrayBuffer2 = new ArrayBuffer(2);
|
||||||
|
const uint8Array2 = new Uint8Array(arrayBuffer2);
|
||||||
|
uint8Array2[0] = 5;
|
||||||
|
uint8Array2[1] = 6;
|
||||||
|
let client = new CustomDataFetchClient();
|
||||||
|
const combinedArrayBuffer = client.combineArrayBuffers([arrayBuffer1, arrayBuffer2]);
|
||||||
|
expect(combinedArrayBuffer.byteLength).assertEqual(6);
|
||||||
|
const combinedUint8Array = new Uint8Array(combinedArrayBuffer);
|
||||||
|
for (let i = 0; i < 4; i++) {
|
||||||
|
expect(combinedUint8Array[i]).assertEqual(uint8Array1[i]);
|
||||||
|
}
|
||||||
|
for (let i = 0; i < 2; i++) {
|
||||||
|
expect(combinedUint8Array[i + 4]).assertEqual(uint8Array2[i]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,89 @@
|
||||||
|
/*
|
||||||
|
* 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 imageFormatAndSize() {
|
||||||
|
describe('imageFormatAndSize', () => {
|
||||||
|
// Defines a test suite. Two parameters are supported: test suite name and test suite function.
|
||||||
|
beforeAll(() => {
|
||||||
|
// Presets an action, which is performed only once before all test cases of the test suite start.
|
||||||
|
// This API supports only one parameter: preset action function.
|
||||||
|
});
|
||||||
|
beforeEach(() => {
|
||||||
|
// Presets an action, which is performed before each unit test case starts.
|
||||||
|
// The number of execution times is the same as the number of test cases defined by **it**.
|
||||||
|
// This API supports only one parameter: preset action function.
|
||||||
|
});
|
||||||
|
afterEach(() => {
|
||||||
|
// Presets a clear action, which is performed after each unit test case ends.
|
||||||
|
// The number of execution times is the same as the number of test cases defined by **it**.
|
||||||
|
// This API supports only one parameter: clear action function.
|
||||||
|
});
|
||||||
|
afterAll(() => {
|
||||||
|
// Presets a clear action, which is performed after all test cases of the test suite end.
|
||||||
|
// This API supports only one parameter: clear action function.
|
||||||
|
});
|
||||||
|
it('getImageSizeInCache', 0, async () => {
|
||||||
|
let width = 0;
|
||||||
|
let height = 0;
|
||||||
|
let imageFormat: string = "";
|
||||||
|
let url: string =
|
||||||
|
"https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/ed/v3/KMO4D6D2QGuVOCLX4AhOFA/ef51xAaLQuK7BsnuD9abog.jpg"
|
||||||
|
let imageKnifeOption: ImageKnifeOption = new ImageKnifeOption({
|
||||||
|
loadSrc: url,
|
||||||
|
})
|
||||||
|
await new Promise<string>((resolve, reject) => {
|
||||||
|
imageKnifeOption.onLoadListener = {
|
||||||
|
onLoadSuccess: (data, imageknifeData) => {
|
||||||
|
resolve("")
|
||||||
|
},
|
||||||
|
onLoadFailed(err) {
|
||||||
|
reject(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let request = new ImageKnifeRequest(
|
||||||
|
imageKnifeOption,
|
||||||
|
imageKnifeOption.context !== undefined ? imageKnifeOption.context : getContext() as common.UIAbilityContext,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
{
|
||||||
|
showPixelMap(version: number, pixelMap: PixelMap | string) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
ImageKnife.getInstance().execute(request);
|
||||||
|
})
|
||||||
|
let data = await ImageKnife.getInstance()
|
||||||
|
.getCacheImage(url, CacheStrategy.Memory);
|
||||||
|
if (data) {
|
||||||
|
width = data.imageWidth
|
||||||
|
height = data.imageHeight
|
||||||
|
imageFormat = data.type!
|
||||||
|
}
|
||||||
|
expect(width != 0).assertTrue();
|
||||||
|
expect(height != 0).assertTrue();
|
||||||
|
expect(imageFormat != "").assertTrue();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
|
@ -0,0 +1,69 @@
|
||||||
|
/*
|
||||||
|
* 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);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
|
@ -5,9 +5,8 @@
|
||||||
"description": "$string:module_test_desc",
|
"description": "$string:module_test_desc",
|
||||||
"mainElement": "TestAbility",
|
"mainElement": "TestAbility",
|
||||||
"deviceTypes": [
|
"deviceTypes": [
|
||||||
"phone",
|
"default",
|
||||||
"tablet",
|
"tablet"
|
||||||
"2in1"
|
|
||||||
],
|
],
|
||||||
"deliveryWithInstall": true,
|
"deliveryWithInstall": true,
|
||||||
"installationFree": false,
|
"installationFree": false,
|
||||||
|
|
|
@ -1,7 +1,11 @@
|
||||||
## 1.0.3
|
## 1.0.4
|
||||||
- 修改门禁编译问题 修改点如下
|
- 修改门禁编译问题 修改点如下
|
||||||
|
- 修改src/main/cpp/boundscheck/CMakeLists.txt文件中的内容
|
||||||
- 修改src/main/cpp/util/DebugLog.h文件中hilog的大小写
|
- 修改src/main/cpp/util/DebugLog.h文件中hilog的大小写
|
||||||
|
|
||||||
|
## 1.0.3
|
||||||
|
- 安全编译开启Strip和Ftrapv
|
||||||
|
|
||||||
## 1.0.2
|
## 1.0.2
|
||||||
- 支持x86编译
|
- 支持x86编译
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
"buildOption": {
|
"buildOption": {
|
||||||
"externalNativeOptions": {
|
"externalNativeOptions": {
|
||||||
"path": "./src/main/cpp/CMakeLists.txt",
|
"path": "./src/main/cpp/CMakeLists.txt",
|
||||||
"arguments": "",
|
"arguments": " -DCMAKE_BUILD_TYPE=Release",
|
||||||
"abiFilters": [
|
"abiFilters": [
|
||||||
"armeabi-v7a",
|
"armeabi-v7a",
|
||||||
"arm64-v8a",
|
"arm64-v8a",
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
"main": "index.ets",
|
"main": "index.ets",
|
||||||
"repository": "https://gitee.com/openharmony-tpc/ImageKnife",
|
"repository": "https://gitee.com/openharmony-tpc/ImageKnife",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"version": "1.0.3",
|
"version": "1.0.4",
|
||||||
"tags": [
|
"tags": [
|
||||||
"Tool"
|
"Tool"
|
||||||
],
|
],
|
||||||
|
|
|
@ -11,8 +11,11 @@ include_directories(${NATIVERENDER_ROOT_PATH}
|
||||||
${NATIVERENDER_ROOT_PATH}/common
|
${NATIVERENDER_ROOT_PATH}/common
|
||||||
${NATIVERENDER_ROOT_PATH}/render
|
${NATIVERENDER_ROOT_PATH}/render
|
||||||
${NATIVERENDER_ROOT_PATH}/constant
|
${NATIVERENDER_ROOT_PATH}/constant
|
||||||
|
${NATIVERENDER_ROOT_PATH}/boundscheck
|
||||||
)
|
)
|
||||||
|
|
||||||
|
add_subdirectory(boundscheck)
|
||||||
|
|
||||||
add_library(nativeGpu SHARED
|
add_library(nativeGpu SHARED
|
||||||
${NATIVERENDER_ROOT_PATH}/napi/napi_init.cpp
|
${NATIVERENDER_ROOT_PATH}/napi/napi_init.cpp
|
||||||
${NATIVERENDER_ROOT_PATH}/render/EGLRender.cpp
|
${NATIVERENDER_ROOT_PATH}/render/EGLRender.cpp
|
||||||
|
@ -30,4 +33,4 @@ find_library (
|
||||||
GLES-lib
|
GLES-lib
|
||||||
GLESv3 )
|
GLESv3 )
|
||||||
|
|
||||||
target_link_libraries(nativeGpu PUBLIC ${hilog-lib} ${EGL-lib} ${GLES-lib} libace_napi.z.so libc++.a)
|
target_link_libraries(nativeGpu PUBLIC boundscheck ${hilog-lib} ${EGL-lib} ${GLES-lib} libace_napi.z.so -s -ftrapv)
|
|
@ -0,0 +1,27 @@
|
||||||
|
# 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)
|
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit a45b3aceed2c0138babc951850445d1cd010ce48
|
|
@ -535,7 +535,10 @@ void EGLRender::SetImageData(uint8_t *pData, int width, int height)
|
||||||
m_RenderImage.height = height;
|
m_RenderImage.height = height;
|
||||||
m_RenderImage.format = IMAGE_FORMAT_RGBA;
|
m_RenderImage.format = IMAGE_FORMAT_RGBA;
|
||||||
NativeImageUtil::AllocNativeImage(&m_RenderImage);
|
NativeImageUtil::AllocNativeImage(&m_RenderImage);
|
||||||
memcpy(m_RenderImage.ppPlane[0], pData, width * height * DEFAULT_FOUR);
|
if (memcpy_s(m_RenderImage.ppPlane[0],
|
||||||
|
width * height * DEFAULT_FOUR, pData, width * height * DEFAULT_FOUR) != EOK) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, m_ImageTextureId);
|
glBindTexture(GL_TEXTURE_2D, m_ImageTextureId);
|
||||||
glTexImage2D(GL_TEXTURE_2D,
|
glTexImage2D(GL_TEXTURE_2D,
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "DebugLog.h"
|
#include "DebugLog.h"
|
||||||
|
#include "third_party_bounds_checking_function/include/securec.h"
|
||||||
|
|
||||||
const int32_t MAX_STR_LENGTH = 1024;
|
const int32_t MAX_STR_LENGTH = 1024;
|
||||||
|
|
||||||
|
@ -41,7 +42,7 @@ void NapiUtil::JsValueToString(const napi_env &env, const napi_value &value, con
|
||||||
LOGI("%s nullptr js object to string malloc failed", __func__);
|
LOGI("%s nullptr js object to string malloc failed", __func__);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
(void) memset(buf.get(), 0, bufLen);
|
(void) memset_s(buf.get(), bufLen, 0, bufLen);
|
||||||
size_t result = 0;
|
size_t result = 0;
|
||||||
napi_get_value_string_utf8(env, value, buf.get(), bufLen, &result);
|
napi_get_value_string_utf8(env, value, buf.get(), bufLen, &result);
|
||||||
target = buf.get();
|
target = buf.get();
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "DebugLog.h"
|
#include "DebugLog.h"
|
||||||
#include "constant/constant_shape.h"
|
#include "constant/constant_shape.h"
|
||||||
|
#include "third_party_bounds_checking_function/include/securec.h"
|
||||||
|
|
||||||
#define IMAGE_FORMAT_RGBA 0x01
|
#define IMAGE_FORMAT_RGBA 0x01
|
||||||
#define IMAGE_FORMAT_NV21 0x02
|
#define IMAGE_FORMAT_NV21 0x02
|
||||||
|
@ -48,7 +49,7 @@
|
||||||
#define IMAGE_FORMAT_GRAY_EXT "GRAY"
|
#define IMAGE_FORMAT_GRAY_EXT "GRAY"
|
||||||
#define IMAGE_FORMAT_I444_EXT "I444"
|
#define IMAGE_FORMAT_I444_EXT "I444"
|
||||||
#define IMAGE_FORMAT_P010_EXT "P010" // 16bit NV21
|
#define IMAGE_FORMAT_P010_EXT "P010" // 16bit NV21
|
||||||
|
#define EOK 0
|
||||||
|
|
||||||
struct NativeImage {
|
struct NativeImage {
|
||||||
int width;
|
int width;
|
||||||
|
@ -140,7 +141,9 @@ public:
|
||||||
if (napi_create_arraybuffer(env, srcLen, &nativePtr, res) != napi_ok || nativePtr == nullptr) {
|
if (napi_create_arraybuffer(env, srcLen, &nativePtr, res) != napi_ok || nativePtr == nullptr) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
memcpy(nativePtr, src, srcLen);
|
if (memcpy_s(nativePtr, srcLen, src, srcLen) != EOK) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -149,10 +152,17 @@ public:
|
||||||
int totalLength = width * height * DEFAULT_FOUR;
|
int totalLength = width * height * DEFAULT_FOUR;
|
||||||
int oneLineLength = width * DEFAULT_FOUR;
|
int oneLineLength = width * DEFAULT_FOUR;
|
||||||
uint8_t* tmp = (uint8_t*)malloc(totalLength);
|
uint8_t* tmp = (uint8_t*)malloc(totalLength);
|
||||||
memcpy(tmp, *buf, totalLength);
|
if (memcpy_s(tmp, totalLength, *buf, totalLength) != EOK) {
|
||||||
memset(*buf, DEFAULT_ZERO, sizeof(uint8_t)*totalLength);
|
return;
|
||||||
|
}
|
||||||
|
if (memset_s(*buf, sizeof(uint8_t)*totalLength, DEFAULT_ZERO, sizeof(uint8_t)*totalLength) != EOK) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
for (int i = 0; i < height; i++) {
|
for (int i = 0; i < height; i++) {
|
||||||
memcpy(*buf + oneLineLength * i, tmp + totalLength - oneLineLength * (i+1), oneLineLength);
|
if (memcpy_s(*buf + oneLineLength * i, oneLineLength,
|
||||||
|
tmp + totalLength - oneLineLength * (i+1), oneLineLength) != EOK) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
free(tmp);
|
free(tmp);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
{
|
{
|
||||||
"modelVersion": "5.0.0",
|
"hvigorVersion": "4.0.2",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@ohos/hvigor-ohos-plugin": "4.0.2"
|
||||||
},
|
},
|
||||||
"execution": {
|
"execution": {
|
||||||
// "analyze": "default", /* Define the build analyze mode. Value: [ "default" | "verbose" | false ]. Default: "default" */
|
// "analyze": "default", /* Define the build analyze mode. Value: [ "default" | "verbose" | false ]. Default: "default" */
|
||||||
|
@ -18,4 +19,4 @@
|
||||||
"nodeOptions": {
|
"nodeOptions": {
|
||||||
// "maxOldSpaceSize": 4096 /* Enable nodeOptions maxOldSpaceSize compilation. Unit M. Used for the daemon process */
|
// "maxOldSpaceSize": 4096 /* Enable nodeOptions maxOldSpaceSize compilation. Unit M. Used for the daemon process */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,48 @@
|
||||||
|
#!/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}" "$@"
|
|
@ -0,0 +1,57 @@
|
||||||
|
@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
|
|
@ -18,9 +18,9 @@ export { ImageKnifeAnimatorComponent } from './src/main/ets/components/ImageKnif
|
||||||
|
|
||||||
export { ImageKnife } from './src/main/ets/ImageKnife'
|
export { ImageKnife } from './src/main/ets/ImageKnife'
|
||||||
|
|
||||||
export { ImageKnifeOption , AnimatorOption } from './src/main/ets/ImageKnifeOption'
|
export { ImageKnifeOption , AnimatorOption } from './src/main/ets/model/ImageKnifeOption'
|
||||||
|
|
||||||
export { ImageKnifeRequest } from './src/main/ets/ImageKnifeRequest'
|
export { ImageKnifeRequest } from './src/main/ets/model/ImageKnifeRequest'
|
||||||
|
|
||||||
export { FileUtils } from './src/main/ets/utils/FileUtils'
|
export { FileUtils } from './src/main/ets/utils/FileUtils'
|
||||||
|
|
||||||
|
@ -66,4 +66,6 @@ export { CropTransformation } from './src/main/ets/transform/CropTransformation'
|
||||||
|
|
||||||
export { MaskTransformation } from './src/main/ets/transform/MaskTransformation'
|
export { MaskTransformation } from './src/main/ets/transform/MaskTransformation'
|
||||||
|
|
||||||
export { SepiaTransformation } from './src/main/ets/transform/SepiaTransformation'
|
export { SepiaTransformation } from './src/main/ets/transform/SepiaTransformation'
|
||||||
|
|
||||||
|
export { DownsampleStrategy } from './src/main/ets/downsampling/DownsampleStartegy'
|
|
@ -14,7 +14,7 @@
|
||||||
"main": "index.ets",
|
"main": "index.ets",
|
||||||
"repository": "https://gitee.com/openharmony-tpc/ImageKnife",
|
"repository": "https://gitee.com/openharmony-tpc/ImageKnife",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"version": "3.0.1-rc.2",
|
"version": "3.1.1-rc.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ohos/gpu_transform": "^1.0.2"
|
"@ohos/gpu_transform": "^1.0.2"
|
||||||
},
|
},
|
||||||
|
|
|
@ -12,14 +12,14 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
import { ImageKnifeRequest } from './ImageKnifeRequest';
|
import { ImageKnifeRequest } from './model/ImageKnifeRequest';
|
||||||
import { CacheStrategy, ImageKnifeData, ImageKnifeRequestSource } from './model/ImageKnifeData';
|
import { CacheStrategy, ImageKnifeData, ImageKnifeRequestSource } from './model/ImageKnifeData';
|
||||||
import { MemoryLruCache } from './utils/MemoryLruCache';
|
import { MemoryLruCache } from './cache/MemoryLruCache';
|
||||||
import { IMemoryCache } from './utils/IMemoryCache'
|
import { IMemoryCache } from './cache/IMemoryCache'
|
||||||
import { FileCache } from './utils/FileCache';
|
import { FileCache } from './cache/FileCache';
|
||||||
import { ImageKnifeDispatcher } from './ImageKnifeDispatcher';
|
import { ImageKnifeDispatcher } from './ImageKnifeDispatcher';
|
||||||
import { IEngineKey } from './key/IEngineKey';
|
import { IEngineKey } from './key/IEngineKey';
|
||||||
import { HeaderOptions, ImageKnifeOption } from './ImageKnifeOption';
|
import { HeaderOptions, ImageKnifeOption } from './model/ImageKnifeOption';
|
||||||
import { FileTypeUtil } from './utils/FileTypeUtil';
|
import { FileTypeUtil } from './utils/FileTypeUtil';
|
||||||
import { util } from '@kit.ArkTS';
|
import { util } from '@kit.ArkTS';
|
||||||
import { image } from '@kit.ImageKit';
|
import { image } from '@kit.ImageKit';
|
||||||
|
@ -191,10 +191,10 @@ export class ImageKnife {
|
||||||
*/
|
*/
|
||||||
getCacheImage(loadSrc: string,
|
getCacheImage(loadSrc: string,
|
||||||
cacheType: CacheStrategy = CacheStrategy.Default, signature?: string): Promise<ImageKnifeData | undefined> {
|
cacheType: CacheStrategy = CacheStrategy.Default, signature?: string): Promise<ImageKnifeData | undefined> {
|
||||||
let option: ImageKnifeOption = {
|
let option: ImageKnifeOption = new ImageKnifeOption({
|
||||||
loadSrc: loadSrc,
|
loadSrc: loadSrc,
|
||||||
signature:signature
|
signature:signature
|
||||||
}
|
})
|
||||||
let engineKeyImpl: IEngineKey = this.getEngineKeyImpl();
|
let engineKeyImpl: IEngineKey = this.getEngineKeyImpl();
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
|
@ -218,7 +218,7 @@ export class ImageKnife {
|
||||||
*/
|
*/
|
||||||
putCacheImage(url: string, pixelMap: PixelMap, cacheType: CacheStrategy = CacheStrategy.Default, signature?: string) {
|
putCacheImage(url: string, pixelMap: PixelMap, cacheType: CacheStrategy = CacheStrategy.Default, signature?: string) {
|
||||||
let memoryKey = this.getEngineKeyImpl()
|
let memoryKey = this.getEngineKeyImpl()
|
||||||
.generateMemoryKey(url, ImageKnifeRequestSource.SRC, { loadSrc: url, signature: signature });
|
.generateMemoryKey(url, ImageKnifeRequestSource.SRC, new ImageKnifeOption({ loadSrc: url, signature: signature }));
|
||||||
let fileKey = this.getEngineKeyImpl().generateFileKey(url, signature);
|
let fileKey = this.getEngineKeyImpl().generateFileKey(url, signature);
|
||||||
let imageKnifeData: ImageKnifeData = { source: pixelMap, imageWidth: 0, imageHeight: 0 };
|
let imageKnifeData: ImageKnifeData = { source: pixelMap, imageWidth: 0, imageHeight: 0 };
|
||||||
switch (cacheType) {
|
switch (cacheType) {
|
||||||
|
@ -252,9 +252,9 @@ export class ImageKnife {
|
||||||
if (url instanceof ImageKnifeOption) {
|
if (url instanceof ImageKnifeOption) {
|
||||||
imageKnifeOption = url;
|
imageKnifeOption = url;
|
||||||
} else {
|
} else {
|
||||||
imageKnifeOption = {
|
imageKnifeOption = new ImageKnifeOption({
|
||||||
loadSrc: url
|
loadSrc: url
|
||||||
};
|
});
|
||||||
}
|
}
|
||||||
let key = this.getEngineKeyImpl().generateFileKey(imageKnifeOption.loadSrc, imageKnifeOption.signature);
|
let key = this.getEngineKeyImpl().generateFileKey(imageKnifeOption.loadSrc, imageKnifeOption.signature);
|
||||||
if (this.fileCache !== undefined) {
|
if (this.fileCache !== undefined) {
|
||||||
|
@ -302,6 +302,66 @@ export class ImageKnife {
|
||||||
return this.fileCache as FileCache
|
return this.fileCache as FileCache
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get cache upper limit
|
||||||
|
* @param cacheType
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
getCacheUpperLimit(cacheType?: CacheStrategy): number | undefined {
|
||||||
|
if (cacheType == undefined || cacheType == CacheStrategy.Default) {
|
||||||
|
cacheType = CacheStrategy.Memory;
|
||||||
|
}
|
||||||
|
if (cacheType == CacheStrategy.Memory) {
|
||||||
|
return (this.memoryCache as MemoryLruCache).maxMemory;
|
||||||
|
} else {
|
||||||
|
if (this.isFileCacheInit()) {
|
||||||
|
return this.fileCache?.maxMemory;
|
||||||
|
} else {
|
||||||
|
throw new Error("the disk cache not init");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gets the number of images currently cached
|
||||||
|
* @param cacheType
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
getCurrentPicturesNum(cacheType: CacheStrategy): number | undefined {
|
||||||
|
if (cacheType == undefined || cacheType == CacheStrategy.Default) {
|
||||||
|
cacheType = CacheStrategy.Memory;
|
||||||
|
}
|
||||||
|
if (cacheType == CacheStrategy.Memory) {
|
||||||
|
return (this.memoryCache as MemoryLruCache).size();
|
||||||
|
} else {
|
||||||
|
if (this.isFileCacheInit()) {
|
||||||
|
return this.fileCache?.size();
|
||||||
|
} else {
|
||||||
|
throw new Error("the disk cache not init");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gets the current cache size
|
||||||
|
* @param cacheType
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
getCurrentCacheSize(cacheType: CacheStrategy): number | undefined {
|
||||||
|
if (cacheType == undefined || cacheType == CacheStrategy.Default) {
|
||||||
|
cacheType = CacheStrategy.Memory;
|
||||||
|
}
|
||||||
|
if (cacheType == CacheStrategy.Memory) {
|
||||||
|
return (this.memoryCache as MemoryLruCache).currentMemory;
|
||||||
|
} else {
|
||||||
|
if (this.isFileCacheInit()) {
|
||||||
|
return this.fileCache?.currentMemory;
|
||||||
|
} else {
|
||||||
|
throw new Error("the disk cache not init");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private pixelMapToArrayBuffer(pixelMap: PixelMap): ArrayBuffer {
|
private pixelMapToArrayBuffer(pixelMap: PixelMap): ArrayBuffer {
|
||||||
let imageInfo = pixelMap.getImageInfoSync();
|
let imageInfo = pixelMap.getImageInfoSync();
|
||||||
|
|
|
@ -12,24 +12,19 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
import { ImageKnifeRequest, ImageKnifeRequestState } from './ImageKnifeRequest'
|
import { ImageKnifeRequest, ImageKnifeRequestState } from './model/ImageKnifeRequest'
|
||||||
import { DefaultJobQueue } from './utils/DefaultJobQueue'
|
import { DefaultJobQueue } from './queue/DefaultJobQueue'
|
||||||
import { IJobQueue } from './utils/IJobQueue'
|
import { IJobQueue } from './queue/IJobQueue'
|
||||||
import List from '@ohos.util.List';
|
import List from '@ohos.util.List';
|
||||||
import LightWeightMap from '@ohos.util.LightWeightMap';
|
import LightWeightMap from '@ohos.util.LightWeightMap';
|
||||||
import { LogUtil } from './utils/LogUtil';
|
import { LogUtil } from './utils/LogUtil';
|
||||||
import buffer from '@ohos.buffer';
|
|
||||||
import { FileCache } from './utils/FileCache';
|
|
||||||
import fs from '@ohos.file.fs';
|
|
||||||
import { ImageKnife } from './ImageKnife';
|
import { ImageKnife } from './ImageKnife';
|
||||||
import { ImageKnifeData, CacheStrategy } from './model/ImageKnifeData';
|
import { ImageKnifeData, CacheStrategy } from './model/ImageKnifeData';
|
||||||
import http from '@ohos.net.http';
|
|
||||||
import image from '@ohos.multimedia.image';
|
import image from '@ohos.multimedia.image';
|
||||||
import emitter from '@ohos.events.emitter';
|
import emitter from '@ohos.events.emitter';
|
||||||
import { Constants } from './utils/Constants';
|
import { Constants } from './utils/Constants';
|
||||||
import taskpool from '@ohos.taskpool';
|
import taskpool from '@ohos.taskpool';
|
||||||
import { FileTypeUtil } from './utils/FileTypeUtil';
|
import { FileTypeUtil } from './utils/FileTypeUtil';
|
||||||
import util from '@ohos.util';
|
|
||||||
import { IEngineKey } from './key/IEngineKey';
|
import { IEngineKey } from './key/IEngineKey';
|
||||||
import { DefaultEngineKey } from './key/DefaultEngineKey';
|
import { DefaultEngineKey } from './key/DefaultEngineKey';
|
||||||
import {
|
import {
|
||||||
|
@ -38,8 +33,10 @@ import {
|
||||||
RequestJobResult,
|
RequestJobResult,
|
||||||
RequestJobRequest
|
RequestJobRequest
|
||||||
} from './model/ImageKnifeData'
|
} from './model/ImageKnifeData'
|
||||||
import { combineArrayBuffers } from './model/utils';
|
|
||||||
import { BusinessError } from '@kit.BasicServicesKit';
|
import { BusinessError } from '@kit.BasicServicesKit';
|
||||||
|
import { ImageKnifeLoader } from './ImageKnifeLoader'
|
||||||
|
import { DownsampleStrategy } from './downsampling/DownsampleStartegy';
|
||||||
|
|
||||||
|
|
||||||
export class ImageKnifeDispatcher {
|
export class ImageKnifeDispatcher {
|
||||||
// 最大并发
|
// 最大并发
|
||||||
|
@ -52,7 +49,7 @@ export class ImageKnifeDispatcher {
|
||||||
private engineKey: IEngineKey = new DefaultEngineKey();
|
private engineKey: IEngineKey = new DefaultEngineKey();
|
||||||
|
|
||||||
showFromMemomry(request: ImageKnifeRequest, imageSrc: string | PixelMap | Resource, requestSource: ImageKnifeRequestSource,isAnimator?: boolean): boolean {
|
showFromMemomry(request: ImageKnifeRequest, imageSrc: string | PixelMap | Resource, requestSource: ImageKnifeRequestSource,isAnimator?: boolean): boolean {
|
||||||
LogUtil.log("ImageKnife_DataTime_showFromMemomry.start:" + request.imageKnifeOption.loadSrc)
|
LogUtil.log("ImageKnife_DataTime_showFromMemomry.start:" + request.imageKnifeOption.loadSrc + "requestSource=" + requestSource + " isAnimator=" + isAnimator)
|
||||||
let memoryCache: ImageKnifeData | undefined;
|
let memoryCache: ImageKnifeData | undefined;
|
||||||
if ((typeof (request.imageKnifeOption.loadSrc as image.PixelMap).isEditable) == 'boolean') {
|
if ((typeof (request.imageKnifeOption.loadSrc as image.PixelMap).isEditable) == 'boolean') {
|
||||||
memoryCache = {
|
memoryCache = {
|
||||||
|
@ -65,13 +62,12 @@ export class ImageKnifeDispatcher {
|
||||||
.loadFromMemoryCache(this.engineKey.generateMemoryKey(imageSrc, requestSource, request.imageKnifeOption,isAnimator));
|
.loadFromMemoryCache(this.engineKey.generateMemoryKey(imageSrc, requestSource, request.imageKnifeOption,isAnimator));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (memoryCache !== undefined) {
|
if (memoryCache !== undefined) {
|
||||||
// 画主图
|
// 画主图
|
||||||
if (request.requestState === ImageKnifeRequestState.PROGRESS) {
|
if (request.requestState === ImageKnifeRequestState.PROGRESS) {
|
||||||
// 回调请求开始
|
// 回调请求开始
|
||||||
if (requestSource === ImageKnifeRequestSource.SRC && request.imageKnifeOption.onLoadListener?.onLoadStart !== undefined) {
|
if (requestSource === ImageKnifeRequestSource.SRC && request.imageKnifeOption.onLoadListener?.onLoadStart !== undefined) {
|
||||||
request.imageKnifeOption.onLoadListener?.onLoadStart()
|
request.imageKnifeOption.onLoadListener.onLoadStart()
|
||||||
LogUtil.log("ImageKnife_DataTime_MemoryCache_onLoadStart:" + request.imageKnifeOption.loadSrc)
|
LogUtil.log("ImageKnife_DataTime_MemoryCache_onLoadStart:" + request.imageKnifeOption.loadSrc)
|
||||||
}
|
}
|
||||||
LogUtil.log("ImageKnife_DataTime_MemoryCache_showPixelMap.start:" + request.imageKnifeOption.loadSrc)
|
LogUtil.log("ImageKnife_DataTime_MemoryCache_showPixelMap.start:" + request.imageKnifeOption.loadSrc)
|
||||||
|
@ -82,23 +78,22 @@ export class ImageKnifeDispatcher {
|
||||||
request.requestState = ImageKnifeRequestState.COMPLETE
|
request.requestState = ImageKnifeRequestState.COMPLETE
|
||||||
// 回调请求开结束
|
// 回调请求开结束
|
||||||
if (request.imageKnifeOption.onLoadListener?.onLoadSuccess !== undefined) {
|
if (request.imageKnifeOption.onLoadListener?.onLoadSuccess !== undefined) {
|
||||||
request.imageKnifeOption.onLoadListener?.onLoadSuccess(memoryCache.source,memoryCache)
|
request.imageKnifeOption.onLoadListener.onLoadSuccess(memoryCache.source,memoryCache)
|
||||||
LogUtil.log("ImageKnife_DataTime_MemoryCache_onLoadSuccess:" + request.imageKnifeOption.loadSrc)
|
LogUtil.log("ImageKnife_DataTime_MemoryCache_onLoadSuccess:" + request.imageKnifeOption.loadSrc)
|
||||||
}
|
}
|
||||||
} else if (requestSource == ImageKnifeRequestSource.ERROR_HOLDER) {
|
} else if (requestSource == ImageKnifeRequestSource.ERROR_HOLDER) {
|
||||||
request.requestState = ImageKnifeRequestState.ERROR
|
request.requestState = ImageKnifeRequestState.ERROR
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LogUtil.log("ImageKnife_DataTime_showFromMemomry.end_true:" + request.imageKnifeOption.loadSrc)
|
LogUtil.log("ImageKnife_DataTime_showFromMemomry.end_hasmemory:" + request.imageKnifeOption.loadSrc)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
LogUtil.log("ImageKnife_DataTime_showFromMemomry.end_false:" + request.imageKnifeOption.loadSrc)
|
LogUtil.log("ImageKnife_DataTime_showFromMemomry.end_nomemory:" + request.imageKnifeOption.loadSrc)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
enqueue(request: ImageKnifeRequest,isAnimator?: boolean): void {
|
enqueue(request: ImageKnifeRequest,isAnimator?: boolean): void {
|
||||||
|
|
||||||
//1.内存有的话直接渲染
|
//1.内存有的话直接渲染
|
||||||
if (this.showFromMemomry(request, request.imageKnifeOption.loadSrc, ImageKnifeRequestSource.SRC,isAnimator)) {
|
if (this.showFromMemomry(request, request.imageKnifeOption.loadSrc, ImageKnifeRequestSource.SRC,isAnimator)) {
|
||||||
return
|
return
|
||||||
|
@ -157,10 +152,21 @@ export class ImageKnifeDispatcher {
|
||||||
isWatchProgress = true
|
isWatchProgress = true
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
let src: string | number = ""
|
||||||
|
let moduleName: string = ""
|
||||||
|
let resName: string = ""
|
||||||
|
if((imageSrc as Resource).id != undefined) {
|
||||||
|
moduleName = (imageSrc as Resource).moduleName
|
||||||
|
src = (imageSrc as Resource).id
|
||||||
|
if(src == -1) {
|
||||||
|
resName = (imageSrc as Resource).params![0]
|
||||||
|
}
|
||||||
|
} else if(typeof imageSrc == "string") {
|
||||||
|
src = imageSrc
|
||||||
|
}
|
||||||
let request: RequestJobRequest = {
|
let request: RequestJobRequest = {
|
||||||
context: currentRequest.context,
|
context: currentRequest.context,
|
||||||
src: imageSrc,
|
src: src,
|
||||||
headers: currentRequest.imageKnifeOption.headerOption,
|
headers: currentRequest.imageKnifeOption.headerOption,
|
||||||
allHeaders: currentRequest.headers,
|
allHeaders: currentRequest.headers,
|
||||||
componentWidth:currentRequest.componentWidth,
|
componentWidth:currentRequest.componentWidth,
|
||||||
|
@ -175,8 +181,13 @@ export class ImageKnifeDispatcher {
|
||||||
requestSource: requestSource,
|
requestSource: requestSource,
|
||||||
isWatchProgress: isWatchProgress,
|
isWatchProgress: isWatchProgress,
|
||||||
memoryKey: memoryKey,
|
memoryKey: memoryKey,
|
||||||
fileCacheFolder: ImageKnife.getInstance().getFileCache().getCacheFolder(),
|
fileCacheFolder: ImageKnife.getInstance().getFileCache()?.getCacheFolder(),
|
||||||
isAnimator:isAnimator
|
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,
|
||||||
}
|
}
|
||||||
|
|
||||||
if(request.customGetImage == undefined) {
|
if(request.customGetImage == undefined) {
|
||||||
|
@ -191,9 +202,9 @@ export class ImageKnifeDispatcher {
|
||||||
emitter.on(Constants.PROGRESS_EMITTER + memoryKey, (data) => {
|
emitter.on(Constants.PROGRESS_EMITTER + memoryKey, (data) => {
|
||||||
this.progressCallBack(requestList! , data?.data?.value as number)
|
this.progressCallBack(requestList! , data?.data?.value as number)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
LogUtil.log("ImageKnife_DataTime_getAndShowImage_execute.start:" + currentRequest.imageKnifeOption.loadSrc)
|
LogUtil.log("ImageKnife_DataTime_getAndShowImage_execute.start(subthread):" + currentRequest.imageKnifeOption.loadSrc)
|
||||||
taskpool.execute(task).then((res: Object) => {
|
taskpool.execute(task).then((res: Object) => {
|
||||||
this.doTaskCallback(res as RequestJobResult | undefined, requestList!, currentRequest, memoryKey, imageSrc, requestSource,isAnimator);
|
this.doTaskCallback(res as RequestJobResult | undefined, requestList!, currentRequest, memoryKey, imageSrc, requestSource,isAnimator);
|
||||||
if (isWatchProgress){
|
if (isWatchProgress){
|
||||||
|
@ -201,8 +212,9 @@ export class ImageKnifeDispatcher {
|
||||||
}
|
}
|
||||||
LogUtil.log("ImageKnife_DataTime_getAndShowImage_execute.end:"+currentRequest.imageKnifeOption.loadSrc)
|
LogUtil.log("ImageKnife_DataTime_getAndShowImage_execute.end:"+currentRequest.imageKnifeOption.loadSrc)
|
||||||
LogUtil.log("ImageKnife_DataTime_getAndShowImage.end:"+currentRequest.imageKnifeOption.loadSrc)
|
LogUtil.log("ImageKnife_DataTime_getAndShowImage.end:"+currentRequest.imageKnifeOption.loadSrc)
|
||||||
}).catch((err:BusinessError)=>{
|
}).catch((err: BusinessError) => {
|
||||||
LogUtil.error("Fail to execute in sub thread src=" + imageSrc + " err=" + err)
|
LogUtil.error("Fail to requestJob in sub thread src=" + imageSrc + " err=" + err)
|
||||||
|
LogUtil.log("ImageKnife_DataTime_getAndShowImage.end:" + currentRequest.imageKnifeOption.loadSrc)
|
||||||
if (isWatchProgress){
|
if (isWatchProgress){
|
||||||
emitter.off(Constants.PROGRESS_EMITTER + memoryKey)
|
emitter.off(Constants.PROGRESS_EMITTER + memoryKey)
|
||||||
}
|
}
|
||||||
|
@ -210,12 +222,14 @@ export class ImageKnifeDispatcher {
|
||||||
this.dispatchNextJob();
|
this.dispatchNextJob();
|
||||||
})
|
})
|
||||||
} else { //主线程请求
|
} else { //主线程请求
|
||||||
|
LogUtil.log("ImageKnife_DataTime_getAndShowImage_execute.start(mainthread):" + currentRequest.imageKnifeOption.loadSrc)
|
||||||
requestJob(request, requestList).then((res: RequestJobResult | undefined) => {
|
requestJob(request, requestList).then((res: RequestJobResult | undefined) => {
|
||||||
this.doTaskCallback(res, requestList!, currentRequest, memoryKey, imageSrc, requestSource,isAnimator);
|
this.doTaskCallback(res, requestList!, currentRequest, memoryKey, imageSrc, requestSource,isAnimator);
|
||||||
LogUtil.log("ImageKnife_DataTime_getAndShowImage_execute.end:"+currentRequest.imageKnifeOption.loadSrc)
|
LogUtil.log("ImageKnife_DataTime_getAndShowImage_execute.end:"+currentRequest.imageKnifeOption.loadSrc)
|
||||||
LogUtil.log("ImageKnife_DataTime_getAndShowImage.end:"+currentRequest.imageKnifeOption.loadSrc)
|
LogUtil.log("ImageKnife_DataTime_getAndShowImage.end:"+currentRequest.imageKnifeOption.loadSrc)
|
||||||
}).catch((err:BusinessError)=>{
|
}).catch((err: BusinessError) => {
|
||||||
LogUtil.error("Fail to execute in main thread src=" + imageSrc + " err=" + err)
|
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);
|
this.executingJobMap.remove(memoryKey);
|
||||||
this.dispatchNextJob();
|
this.dispatchNextJob();
|
||||||
})
|
})
|
||||||
|
@ -244,6 +258,7 @@ export class ImageKnifeDispatcher {
|
||||||
}
|
}
|
||||||
let pixelmap = requestJobResult.pixelMap;
|
let pixelmap = requestJobResult.pixelMap;
|
||||||
if (pixelmap === undefined) {
|
if (pixelmap === undefined) {
|
||||||
|
LogUtil.log("ImageKnife_DataTime_getAndShowImage_CallBack.pixelmap undefined:"+currentRequest.imageKnifeOption.loadSrc)
|
||||||
requestList.forEach((requestWithSource: ImageKnifeRequestWithSource) => {
|
requestList.forEach((requestWithSource: ImageKnifeRequestWithSource) => {
|
||||||
// 回调请求失败
|
// 回调请求失败
|
||||||
if (requestWithSource.source === ImageKnifeRequestSource.SRC &&
|
if (requestWithSource.source === ImageKnifeRequestSource.SRC &&
|
||||||
|
@ -263,6 +278,7 @@ export class ImageKnifeDispatcher {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
this.executingJobMap.remove(memoryKey);
|
this.executingJobMap.remove(memoryKey);
|
||||||
|
this.dispatchNextJob();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// 保存文件缓存
|
// 保存文件缓存
|
||||||
|
@ -297,8 +313,6 @@ export class ImageKnifeDispatcher {
|
||||||
LogUtil.log("ImageKnife_DataTime_getAndShowImage_saveMemoryCache.end:"+currentRequest.imageKnifeOption.loadSrc)
|
LogUtil.log("ImageKnife_DataTime_getAndShowImage_saveMemoryCache.end:"+currentRequest.imageKnifeOption.loadSrc)
|
||||||
}
|
}
|
||||||
if (requestList !== undefined) {
|
if (requestList !== undefined) {
|
||||||
|
|
||||||
// todo 判断request生命周期,已销毁的不需要再绘制
|
|
||||||
// key相同的request,一起绘制
|
// key相同的request,一起绘制
|
||||||
requestList.forEach((requestWithSource: ImageKnifeRequestWithSource) => {
|
requestList.forEach((requestWithSource: ImageKnifeRequestWithSource) => {
|
||||||
if (requestWithSource.request.requestState !== ImageKnifeRequestState.DESTROY) {
|
if (requestWithSource.request.requestState !== ImageKnifeRequestState.DESTROY) {
|
||||||
|
@ -326,8 +340,8 @@ export class ImageKnifeDispatcher {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (requestWithSource.source == ImageKnifeRequestSource.SRC && requestWithSource.request.imageKnifeOption.onLoadListener?.onLoadCancel) {
|
if (requestWithSource.source == ImageKnifeRequestSource.SRC && requestWithSource.request.imageKnifeOption.onLoadListener?.onLoadCancel) {
|
||||||
// 回调请求成功
|
// 回调请求成功
|
||||||
requestWithSource.request.imageKnifeOption.onLoadListener.onLoadCancel("component has destroyed")
|
requestWithSource.request.imageKnifeOption.onLoadListener.onLoadCancel("component has destroyed")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -346,11 +360,13 @@ export class ImageKnifeDispatcher {
|
||||||
while (true) {
|
while (true) {
|
||||||
let request = this.jobQueue.pop()
|
let request = this.jobQueue.pop()
|
||||||
if (request === undefined) {
|
if (request === undefined) {
|
||||||
|
LogUtil.log("ImageKnife_DataTime_dispatchNextJob.end:no any job")
|
||||||
break // 队列已无任务
|
break // 队列已无任务
|
||||||
}
|
}
|
||||||
else if (request.requestState === ImageKnifeRequestState.PROGRESS) {
|
else if (request.requestState === ImageKnifeRequestState.PROGRESS) {
|
||||||
|
LogUtil.log("ImageKnife_DataTime_dispatchNextJob.start executeJob:" + request.imageKnifeOption.loadSrc)
|
||||||
this.executeJob(request)
|
this.executeJob(request)
|
||||||
LogUtil.log("ImageKnife_DataTime_dispatchNextJob.end:" + request.imageKnifeOption.loadSrc)
|
LogUtil.log("ImageKnife_DataTime_dispatchNextJob.end executeJob:" + request.imageKnifeOption.loadSrc)
|
||||||
break
|
break
|
||||||
}else if (request.requestState == ImageKnifeRequestState.DESTROY && request.imageKnifeOption.onLoadListener?.onLoadCancel) {
|
}else if (request.requestState == ImageKnifeRequestState.DESTROY && request.imageKnifeOption.onLoadListener?.onLoadCancel) {
|
||||||
request.imageKnifeOption.onLoadListener.onLoadCancel("component has destroyed")
|
request.imageKnifeOption.onLoadListener.onLoadCancel("component has destroyed")
|
||||||
|
@ -381,288 +397,44 @@ export class ImageKnifeDispatcher {
|
||||||
*/
|
*/
|
||||||
@Concurrent
|
@Concurrent
|
||||||
async function requestJob(request: RequestJobRequest, requestList?: List<ImageKnifeRequestWithSource>): Promise<RequestJobResult | undefined> {
|
async function requestJob(request: RequestJobRequest, requestList?: List<ImageKnifeRequestWithSource>): Promise<RequestJobResult | undefined> {
|
||||||
LogUtil.log("ImageKnife_DataTime_requestJob.start:" + request.src)
|
LogUtil.log("ImageKnife_DataTime_requestJob.start:" + request.src + " requestSource=" + request.requestSource)
|
||||||
let resBuf: ArrayBuffer | undefined
|
let src = typeof request.src == "number" ? request.resName != undefined ? request.resName : request.src + "" : request.src
|
||||||
let bufferSize: number = 0
|
// 生成文件缓存key
|
||||||
let loadError: string = '';
|
let fileKey = request.engineKey.generateFileKey(src, request.signature, request.isAnimator)
|
||||||
|
|
||||||
class RequestData {
|
//获取图片资源
|
||||||
receiveSize: number = 2000
|
let resBuf: ArrayBuffer
|
||||||
totalSize: number = 2000
|
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)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 生成文件key
|
// 获取图片类型
|
||||||
let fileKey = request.engineKey.generateFileKey(request.src, request.signature,request.isAnimator)
|
let typeValue = new FileTypeUtil().getFileType(resBuf);
|
||||||
|
|
||||||
// 判断自定义下载
|
|
||||||
if (request.customGetImage !== undefined && request.requestSource == ImageKnifeRequestSource.SRC) {
|
|
||||||
// 先从文件缓存获取
|
|
||||||
resBuf = FileCache.getFileCacheByFile(request.context, fileKey , request.fileCacheFolder)
|
|
||||||
if (resBuf === undefined) {
|
|
||||||
LogUtil.log("customGetImage customGetImage");
|
|
||||||
resBuf = await request.customGetImage(request.context, request.src)
|
|
||||||
loadError = resBuf == undefined ? "customGetImage loadFile" : loadError
|
|
||||||
// 保存文件缓存
|
|
||||||
if (resBuf !== undefined && request.writeCacheStrategy !== CacheStrategy.Memory) {
|
|
||||||
let copyBuf = buffer.concat([buffer.from(resBuf)]).buffer; // IDE有bug,不能直接获取resBuf.byteLength
|
|
||||||
bufferSize = copyBuf.byteLength
|
|
||||||
FileCache.saveFileCacheOnlyFile(request.context, fileKey, resBuf , request.fileCacheFolder)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (typeof request.src === 'string') {
|
|
||||||
if (request.src.indexOf("http://") == 0 || request.src.indexOf("https://") == 0) { //从网络下载
|
|
||||||
// 先从文件缓存获取
|
|
||||||
resBuf = FileCache.getFileCacheByFile(request.context, fileKey , request.fileCacheFolder)
|
|
||||||
if (resBuf === undefined && request.onlyRetrieveFromCache != true) {
|
|
||||||
LogUtil.log("ImageKnife_DataTime_requestJob_httpRequest.start:"+request.src)
|
|
||||||
let httpRequest = http.createHttp();
|
|
||||||
let progress: number = 0
|
|
||||||
let arrayBuffers = new Array<ArrayBuffer>()
|
|
||||||
const headerObj: Record<string, object> = {}
|
|
||||||
if (request.headers != undefined) {
|
|
||||||
request.headers.forEach((value) => {
|
|
||||||
headerObj[value.key] = value.value
|
|
||||||
})
|
|
||||||
} else if (request.allHeaders.size > 0) {
|
|
||||||
request.allHeaders.forEach((value, key) => {
|
|
||||||
headerObj[key] = value
|
|
||||||
})
|
|
||||||
}
|
|
||||||
httpRequest.on("dataReceive", (data: ArrayBuffer) => {
|
|
||||||
arrayBuffers.push(data)
|
|
||||||
});
|
|
||||||
|
|
||||||
if (request.isWatchProgress) {
|
|
||||||
httpRequest.on('dataReceiveProgress', (data: RequestData) => {
|
|
||||||
// 下载进度
|
|
||||||
if (data != undefined && (typeof data.receiveSize == 'number') && (typeof data.totalSize == 'number')) {
|
|
||||||
let percent = Math.round(((data.receiveSize * 1.0) / (data.totalSize * 1.0)) * 100)
|
|
||||||
if (progress !== percent) {
|
|
||||||
progress = percent
|
|
||||||
if (requestList === undefined) {
|
|
||||||
// 子线程
|
|
||||||
emitter.emit(Constants.PROGRESS_EMITTER + request.memoryKey, { data: { "value": progress } })
|
|
||||||
}else {
|
|
||||||
// 主线程请求
|
|
||||||
requestList!.forEach((requestWithSource: ImageKnifeRequestWithSource) => {
|
|
||||||
if (requestWithSource.request.imageKnifeOption.progressListener !== undefined && requestWithSource.source === ImageKnifeRequestSource.SRC) {
|
|
||||||
requestWithSource.request.imageKnifeOption.progressListener(progress)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
let promise = httpRequest.requestInStream(request.src, {
|
|
||||||
header: headerObj,
|
|
||||||
method: http.RequestMethod.GET,
|
|
||||||
expectDataType: http.HttpDataType.ARRAY_BUFFER,
|
|
||||||
connectTimeout: 6000,
|
|
||||||
readTimeout: 6000,
|
|
||||||
// usingProtocol:http.HttpProtocol.HTTP1_1
|
|
||||||
// header: new Header('application/json')
|
|
||||||
});
|
|
||||||
|
|
||||||
await promise.then((data: number) => {
|
|
||||||
if (data == 200) {
|
|
||||||
resBuf = combineArrayBuffers(arrayBuffers)
|
|
||||||
} else {
|
|
||||||
loadError = "HttpDownloadClient has error, http code =" + JSON.stringify(data)
|
|
||||||
}
|
|
||||||
}).catch((err: Error) => {
|
|
||||||
loadError = err.message;
|
|
||||||
LogUtil.error("requestInStream ERROR : err = " + JSON.stringify(err));
|
|
||||||
});
|
|
||||||
LogUtil.log("ImageKnife_DataTime_requestJob_httpRequest.end:"+request.src)
|
|
||||||
// 保存文件缓存
|
|
||||||
if (resBuf !== undefined && request.writeCacheStrategy !== CacheStrategy.Memory) {
|
|
||||||
LogUtil.log("ImageKnife_DataTime_requestJob_saveFileCacheOnlyFile.start:"+request.src)
|
|
||||||
let copyBuf = combineArrayBuffers(arrayBuffers); // IDE有bug,不能直接获取resBuf.byteLength
|
|
||||||
bufferSize = copyBuf.byteLength
|
|
||||||
FileCache.saveFileCacheOnlyFile(request.context, fileKey, resBuf , request.fileCacheFolder)
|
|
||||||
LogUtil.log("ImageKnife_DataTime_requestJob_saveFileCacheOnlyFile.end:"+request.src)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
LogUtil.log("success get image from filecache for key = " + fileKey);
|
|
||||||
loadError = "success get image from filecache for key = " + fileKey;
|
|
||||||
}
|
|
||||||
} else if (request.src.startsWith('datashare://') || request.src.startsWith('file://')) {
|
|
||||||
await fs.open(request.src, fs.OpenMode.READ_ONLY).then(async (file) => {
|
|
||||||
await fs.stat(file.fd).then(async (stat) =>{
|
|
||||||
let buf = new ArrayBuffer(stat.size);
|
|
||||||
await fs.read(file.fd, buf).then((readLen) => {
|
|
||||||
resBuf = buf;
|
|
||||||
fs.close(file.fd);
|
|
||||||
}).catch((err:BusinessError) => {
|
|
||||||
loadError = 'LoadDataShareFileClient fs.read err happened uri=' + request.src + " err.msg=" + err?.message + " err.code=" + err?.code;
|
|
||||||
})
|
|
||||||
}).catch((err:BusinessError) => {
|
|
||||||
loadError = 'LoadDataShareFileClient fs.stat err happened uri=' + request.src + " err.msg=" + err?.message + " err.code=" + err?.code;
|
|
||||||
})
|
|
||||||
}).catch((err:BusinessError) => {
|
|
||||||
loadError ='LoadDataShareFileClient fs.open err happened uri=' + request.src + " err.msg=" + err?.message + " err.code=" + err?.code;
|
|
||||||
})
|
|
||||||
} else { //从本地文件获取
|
|
||||||
try {
|
|
||||||
let stat = fs.statSync(request.src);
|
|
||||||
if (stat.size > 0) {
|
|
||||||
let file = fs.openSync(request.src, fs.OpenMode.READ_ONLY);
|
|
||||||
resBuf = new ArrayBuffer(stat.size);
|
|
||||||
fs.readSync(file.fd, resBuf);
|
|
||||||
fs.closeSync(file);
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
if (typeof err == 'string') {
|
|
||||||
loadError = err;
|
|
||||||
} else {
|
|
||||||
loadError = err.message;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if ((request.src as Resource).id !== undefined) { //从资源文件获取
|
|
||||||
let res = request.src as Resource;
|
|
||||||
let manager = request.context.createModuleContext(res.moduleName).resourceManager
|
|
||||||
if (resBuf == undefined && request.onlyRetrieveFromCache != true && request.requestSource == ImageKnifeRequestSource.SRC) {
|
|
||||||
if(res.id == -1) {
|
|
||||||
let resName = (res.params![0] as string)
|
|
||||||
resBuf = (await manager.getMediaByName(resName.substring(10))).buffer as ArrayBuffer
|
|
||||||
} else {
|
|
||||||
resBuf = manager.getMediaContentSync(res.id).buffer as ArrayBuffer
|
|
||||||
}
|
|
||||||
} else if (resBuf == undefined && request.requestSource != ImageKnifeRequestSource.SRC) {
|
|
||||||
if(res.id == -1) {
|
|
||||||
let resName = (res.params![0] as string)
|
|
||||||
resBuf = (await manager.getMediaByName(resName.substring(10))).buffer as ArrayBuffer
|
|
||||||
} else {
|
|
||||||
resBuf = manager.getMediaContentSync(res.id).buffer as ArrayBuffer
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (resBuf == undefined) {
|
|
||||||
LogUtil.log("ImageKnife_DataTime_requestJob.end_undefined:"+request.src)
|
|
||||||
return {
|
|
||||||
pixelMap: undefined,
|
|
||||||
bufferSize: 0,
|
|
||||||
fileKey: '',
|
|
||||||
loadFail: loadError,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
LogUtil.log("ImageKnife_DataTime_requestJob_createPixelMap.start:"+request.src)
|
|
||||||
let fileTypeUtil = new FileTypeUtil();
|
|
||||||
let typeValue = fileTypeUtil.getFileType(resBuf);
|
|
||||||
if(typeValue == null) {
|
if(typeValue == null) {
|
||||||
return {
|
LogUtil.log("ImageKnife_DataTime_requestJob.end: getFileType is null " + request.src)
|
||||||
pixelMap: undefined,
|
return ImageKnifeLoader.makeEmptyResult("request is not a valid image source")
|
||||||
bufferSize: 0,
|
|
||||||
fileKey: '',
|
|
||||||
loadFail: "request is not a valid image source",
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
let imageSource: image.ImageSource = image.createImageSource(resBuf);
|
|
||||||
let decodingOptions: image.DecodingOptions = {
|
|
||||||
editable: true,
|
|
||||||
}
|
|
||||||
if(request.isAnimator) {
|
|
||||||
if (typeValue === 'gif' || typeValue === 'webp') {
|
|
||||||
let pixelMapList: Array<PixelMap> = []
|
|
||||||
let delayList: Array<number> = []
|
|
||||||
await imageSource.createPixelMapList(decodingOptions).then(async (pixelList: Array<PixelMap>) => {
|
|
||||||
//sdk的api接口发生变更:从.getDelayTime() 变为.getDelayTimeList()
|
|
||||||
await imageSource.getDelayTimeList().then(delayTimes => {
|
|
||||||
if (pixelList.length > 0) {
|
|
||||||
for (let i = 0; i < pixelList.length; i++) {
|
|
||||||
pixelMapList.push(pixelList[i]);
|
|
||||||
if (i < delayTimes.length) {
|
|
||||||
delayList.push(delayTimes[i]);
|
|
||||||
} else {
|
|
||||||
delayList.push(delayTimes[delayTimes.length - 1])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
imageSource.release();
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
return {
|
|
||||||
pixelMap: "",
|
|
||||||
bufferSize: bufferSize,
|
|
||||||
fileKey: fileKey,
|
|
||||||
type: typeValue,
|
|
||||||
pixelMapList,
|
|
||||||
delayList
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return {
|
|
||||||
pixelMap: undefined,
|
|
||||||
bufferSize: 0,
|
|
||||||
fileKey: '',
|
|
||||||
loadFail: "ImageKnifeAnimatorComponent组件仅支持动态图",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let resPixelmap: PixelMap | undefined = undefined
|
|
||||||
if (typeValue === 'gif' || typeValue === 'webp') {
|
|
||||||
let size = (await imageSource.getImageInfo()).size
|
|
||||||
let base64Help = new util.Base64Helper()
|
|
||||||
|
|
||||||
let base64str = "data:image/" + typeValue + ";base64," + base64Help.encodeToStringSync(new Uint8Array(resBuf))
|
// 解析图片
|
||||||
LogUtil.log("ImageKnife_DataTime_requestJob_createPixelMap.end_GIF:"+request.src)
|
LogUtil.log("ImageKnife_DataTime_requestJob.parseImage.start:" + request.src)
|
||||||
LogUtil.log("ImageKnife_DataTime_requestJob.end_GIF:"+request.src)
|
let result: RequestJobResult = await ImageKnifeLoader.parseImage(resBuf, typeValue, fileKey, request)
|
||||||
return {
|
LogUtil.log("ImageKnife_DataTime_requestJob.parseImage.end:" + request.src)
|
||||||
pixelMap: base64str,
|
|
||||||
bufferSize: bufferSize,
|
|
||||||
fileKey: fileKey,
|
|
||||||
size:size,
|
|
||||||
type:typeValue
|
|
||||||
};
|
|
||||||
} else if(typeValue == "svg") {
|
|
||||||
let hValue = Math.round(request.componentHeight);
|
|
||||||
let wValue = Math.round(request.componentWidth);
|
|
||||||
let defaultSize: image.Size = {
|
|
||||||
height: vp2px(hValue),
|
|
||||||
width: vp2px(wValue)
|
|
||||||
};
|
|
||||||
let opts: image.DecodingOptions = {
|
|
||||||
editable: true,
|
|
||||||
desiredSize: defaultSize
|
|
||||||
};
|
|
||||||
await imageSource.createPixelMap(opts)
|
|
||||||
.then((pixelmap: PixelMap) => {
|
|
||||||
resPixelmap = pixelmap
|
|
||||||
imageSource.release()
|
|
||||||
})
|
|
||||||
return {
|
|
||||||
pixelMap: resPixelmap,
|
|
||||||
bufferSize: bufferSize,
|
|
||||||
fileKey: fileKey,
|
|
||||||
type:typeValue
|
|
||||||
};
|
|
||||||
}
|
|
||||||
let size = (await imageSource.getImageInfo()).size
|
|
||||||
await imageSource.createPixelMap(decodingOptions)
|
|
||||||
.then((pixelmap: PixelMap) => {
|
|
||||||
resPixelmap = pixelmap
|
|
||||||
imageSource.release()
|
|
||||||
})
|
|
||||||
|
|
||||||
// 图形变化
|
// 图形变化
|
||||||
if (request.requestSource === ImageKnifeRequestSource.SRC && request.transformation !== undefined) {
|
if (request.requestSource === ImageKnifeRequestSource.SRC && request.transformation !== undefined && result?.pixelMap !== undefined && typeof result.pixelMap !== 'string') {
|
||||||
resPixelmap = await request.transformation?.transform(request.context, resPixelmap!, request.componentWidth, request.componentHeight);
|
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_createPixelMap.end:"+request.src)
|
|
||||||
LogUtil.log("ImageKnife_DataTime_requestJob.end:"+request.src)
|
LogUtil.log("ImageKnife_DataTime_requestJob.end:" + request.src)
|
||||||
return {
|
return result
|
||||||
pixelMap: resPixelmap,
|
|
||||||
bufferSize: bufferSize,
|
|
||||||
fileKey: fileKey,
|
|
||||||
size:size,
|
|
||||||
type:typeValue
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,402 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2024 Huawei Device Co., Ltd.
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
import {
|
||||||
|
CacheStrategy,
|
||||||
|
ImageKnifeRequestSource,
|
||||||
|
ImageKnifeRequestWithSource, RequestJobRequest } 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 http from '@ohos.net.http';
|
||||||
|
import { combineArrayBuffers } from './utils/ArrayBufferUtils';
|
||||||
|
import { BusinessError } from '@kit.BasicServicesKit';
|
||||||
|
import fs from '@ohos.file.fs';
|
||||||
|
import emitter from '@ohos.events.emitter';
|
||||||
|
import image from '@ohos.multimedia.image';
|
||||||
|
import { RequestJobResult } from './model/ImageKnifeData'
|
||||||
|
import util from '@ohos.util';
|
||||||
|
import { DownsampleStrategy } from './downsampling/DownsampleStartegy';
|
||||||
|
import { Downsampler } from './downsampling/Downsampler';
|
||||||
|
|
||||||
|
class RequestData {
|
||||||
|
receiveSize: number = 2000
|
||||||
|
totalSize: number = 2000
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ImageKnifeDispatcher 抽取出来的方法,因@Concurrent只能import方法,故抽取到另一个类
|
||||||
|
*/
|
||||||
|
export class ImageKnifeLoader {
|
||||||
|
static async parseImage(resBuf: ArrayBuffer, typeValue: string, fileKey: string,
|
||||||
|
request: RequestJobRequest): Promise<RequestJobResult> {
|
||||||
|
if(request.isAnimator) {
|
||||||
|
return ImageKnifeLoader.parseForAnimatorComponent(resBuf ,typeValue ,fileKey, request)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeValue === 'gif' || typeValue === 'webp') {
|
||||||
|
return ImageKnifeLoader.parseAnimatorImage(resBuf ,typeValue ,fileKey , request)
|
||||||
|
} else if(typeValue == "svg") {
|
||||||
|
return ImageKnifeLoader.parseSvgImage(resBuf ,typeValue ,fileKey , request)
|
||||||
|
}
|
||||||
|
|
||||||
|
return ImageKnifeLoader.parseNormalImage(resBuf, typeValue, fileKey, request)
|
||||||
|
}
|
||||||
|
|
||||||
|
static makeEmptyResult(error: string): RequestJobResult{
|
||||||
|
return {
|
||||||
|
pixelMap: undefined,
|
||||||
|
bufferSize: 0,
|
||||||
|
fileKey: '',
|
||||||
|
loadFail: error,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static async parseNormalImage(resBuf: ArrayBuffer, typeValue: string, fileKey: string, request: RequestJobRequest):Promise<RequestJobResult> {
|
||||||
|
let resPixelmap: PixelMap | undefined = undefined
|
||||||
|
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")
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
|
||||||
|
await imageSource.createPixelMap(decodingOptions)
|
||||||
|
.then((pixelmap: PixelMap) => {
|
||||||
|
resPixelmap = pixelmap
|
||||||
|
imageSource.release()
|
||||||
|
}).catch((error: BusinessError) => {
|
||||||
|
imageSource.release()
|
||||||
|
return ImageKnifeLoader.makeEmptyResult(JSON.stringify(error))
|
||||||
|
})
|
||||||
|
|
||||||
|
return {
|
||||||
|
pixelMap: resPixelmap,
|
||||||
|
bufferSize: resBuf.byteLength,
|
||||||
|
fileKey: fileKey,
|
||||||
|
size:size,
|
||||||
|
type:typeValue
|
||||||
|
};
|
||||||
|
}
|
||||||
|
static async parseSvgImage(resBuf: ArrayBuffer, typeValue: string, fileKey: string,
|
||||||
|
request: RequestJobRequest): Promise<RequestJobResult> {
|
||||||
|
let resPixelmap: PixelMap | undefined = undefined
|
||||||
|
let imageSource: image.ImageSource = image.createImageSource(resBuf)
|
||||||
|
if (imageSource === undefined){
|
||||||
|
return ImageKnifeLoader.makeEmptyResult("image.createImageSource failed")
|
||||||
|
}
|
||||||
|
|
||||||
|
let size = (await imageSource.getImageInfo()).size
|
||||||
|
let scale = size.height / size.width
|
||||||
|
let hValue = Math.round(request.componentHeight);
|
||||||
|
let wValue = Math.round(request.componentWidth);
|
||||||
|
let defaultSize: image.Size = {
|
||||||
|
height: vp2px(wValue) * scale,
|
||||||
|
width: vp2px(wValue)
|
||||||
|
};
|
||||||
|
let opts: image.DecodingOptions = {
|
||||||
|
editable: true,
|
||||||
|
desiredSize: defaultSize
|
||||||
|
};
|
||||||
|
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) => {
|
||||||
|
resPixelmap = pixelmap
|
||||||
|
imageSource.release()
|
||||||
|
}).catch((error: BusinessError) => {
|
||||||
|
imageSource.release()
|
||||||
|
return ImageKnifeLoader.makeEmptyResult(JSON.stringify(error))
|
||||||
|
})
|
||||||
|
|
||||||
|
return {
|
||||||
|
pixelMap: resPixelmap,
|
||||||
|
bufferSize: resBuf.byteLength,
|
||||||
|
fileKey: fileKey,
|
||||||
|
type:typeValue
|
||||||
|
};
|
||||||
|
}
|
||||||
|
static async parseAnimatorImage(resBuf: ArrayBuffer, typeValue: string,
|
||||||
|
fileKey: string,request: RequestJobRequest): Promise<RequestJobResult> {
|
||||||
|
let imageSource: image.ImageSource = image.createImageSource(resBuf)
|
||||||
|
if (imageSource === undefined){
|
||||||
|
return ImageKnifeLoader.makeEmptyResult("image.createImageSource failed")
|
||||||
|
}
|
||||||
|
|
||||||
|
let frameCount = await imageSource.getFrameCount()
|
||||||
|
let size = (await imageSource.getImageInfo()).size
|
||||||
|
imageSource.release()
|
||||||
|
|
||||||
|
if(frameCount == undefined || frameCount == 1) {
|
||||||
|
} else {
|
||||||
|
let base64str = "data:image/" + typeValue + ";base64," + new util.Base64Helper().encodeToStringSync(new Uint8Array(resBuf))
|
||||||
|
return {
|
||||||
|
pixelMap: base64str,
|
||||||
|
bufferSize: resBuf.byteLength,
|
||||||
|
fileKey: fileKey,
|
||||||
|
size:size,
|
||||||
|
type:typeValue
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return ImageKnifeLoader.parseNormalImage(resBuf, typeValue, fileKey, request)
|
||||||
|
}
|
||||||
|
// 为AnimatorComponent解析动图
|
||||||
|
static async parseForAnimatorComponent(resBuf: ArrayBuffer, typeValue: string, fileKey: string,request: RequestJobRequest): Promise<RequestJobResult> {
|
||||||
|
if (typeValue === 'gif' || typeValue === 'webp') {
|
||||||
|
let imageSource: image.ImageSource = image.createImageSource(resBuf);
|
||||||
|
if (imageSource === undefined){
|
||||||
|
return ImageKnifeLoader.makeEmptyResult("image.createImageSource failed")
|
||||||
|
}
|
||||||
|
let decodingOptions: image.DecodingOptions = {
|
||||||
|
editable: request.requestSource === ImageKnifeRequestSource.SRC && request.transformation !== undefined ? true : false,
|
||||||
|
}
|
||||||
|
let pixelMapList: Array<PixelMap> = []
|
||||||
|
let delayList: Array<number> = []
|
||||||
|
await imageSource.createPixelMapList(decodingOptions).then(async (pixelList: Array<PixelMap>) => {
|
||||||
|
//sdk的api接口发生变更:从.getDelayTime() 变为.getDelayTimeList()
|
||||||
|
await imageSource.getDelayTimeList().then(delayTimes => {
|
||||||
|
if (pixelList.length > 0) {
|
||||||
|
for (let i = 0; i < pixelList.length; i++) {
|
||||||
|
pixelMapList.push(pixelList[i]);
|
||||||
|
if (i < delayTimes.length) {
|
||||||
|
delayList.push(delayTimes[i]);
|
||||||
|
} else {
|
||||||
|
delayList.push(delayTimes[delayTimes.length - 1])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
imageSource.release();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}).catch((error: BusinessError) => {
|
||||||
|
imageSource.release()
|
||||||
|
return ImageKnifeLoader.makeEmptyResult(JSON.stringify(error))
|
||||||
|
})
|
||||||
|
return {
|
||||||
|
pixelMap: "",
|
||||||
|
bufferSize: resBuf.byteLength,
|
||||||
|
fileKey: fileKey,
|
||||||
|
type: typeValue,
|
||||||
|
pixelMapList,
|
||||||
|
delayList
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return ImageKnifeLoader.makeEmptyResult("ImageKnifeAnimatorComponent组件仅支持动态图")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取图片资源
|
||||||
|
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> = {}
|
||||||
|
if (request.headers != undefined) {
|
||||||
|
request.headers.forEach((value) => {
|
||||||
|
headerObj[value.key] = value.value
|
||||||
|
})
|
||||||
|
} else if (request.allHeaders.size > 0) {
|
||||||
|
request.allHeaders.forEach((value, key) => {
|
||||||
|
headerObj[key] = value
|
||||||
|
})
|
||||||
|
}
|
||||||
|
httpRequest.on("dataReceive", (data: ArrayBuffer) => {
|
||||||
|
arrayBuffers.push(data)
|
||||||
|
});
|
||||||
|
|
||||||
|
if (request.isWatchProgress) {
|
||||||
|
httpRequest.on('dataReceiveProgress', (data: RequestData) => {
|
||||||
|
// 下载进度
|
||||||
|
if (data != undefined && (typeof data.receiveSize == 'number') && (typeof data.totalSize == 'number')) {
|
||||||
|
let percent = Math.round(((data.receiveSize * 1.0) / (data.totalSize * 1.0)) * 100)
|
||||||
|
if (progress !== percent) {
|
||||||
|
progress = percent
|
||||||
|
if (requestList === undefined) {
|
||||||
|
// 子线程
|
||||||
|
emitter.emit(Constants.PROGRESS_EMITTER + request.memoryKey, { data: { "value": progress } })
|
||||||
|
}else {
|
||||||
|
// 主线程请求
|
||||||
|
requestList!.forEach((requestWithSource: ImageKnifeRequestWithSource) => {
|
||||||
|
if (requestWithSource.request.imageKnifeOption.progressListener !== undefined && requestWithSource.source === ImageKnifeRequestSource.SRC) {
|
||||||
|
requestWithSource.request.imageKnifeOption.progressListener(progress)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
let promise = httpRequest.requestInStream(request.src, {
|
||||||
|
header: headerObj,
|
||||||
|
method: http.RequestMethod.GET,
|
||||||
|
expectDataType: http.HttpDataType.ARRAY_BUFFER,
|
||||||
|
connectTimeout: 60000,
|
||||||
|
readTimeout: 0,
|
||||||
|
// usingProtocol:http.HttpProtocol.HTTP1_1
|
||||||
|
// header: new Header('application/json')
|
||||||
|
});
|
||||||
|
|
||||||
|
await promise.then((data: number) => {
|
||||||
|
if (data == 200 || data == 206 || data == 204) {
|
||||||
|
resBuf = combineArrayBuffers(arrayBuffers)
|
||||||
|
} else {
|
||||||
|
throw new Error("HttpDownloadClient has error, http code =" + JSON.stringify(data))
|
||||||
|
}
|
||||||
|
}).catch((err: Error) => {
|
||||||
|
throw new Error("HttpDownloadClient download ERROR : err = " + JSON.stringify(err))
|
||||||
|
});
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw new Error('onlyRetrieveFromCache,do not fetch image src = ' + request.src)
|
||||||
|
}
|
||||||
|
} else if (request.src.startsWith('datashare://') || request.src.startsWith('file://')) {
|
||||||
|
await fs.open(request.src, fs.OpenMode.READ_ONLY).then(async (file) => {
|
||||||
|
await fs.stat(file.fd).then(async (stat) =>{
|
||||||
|
let buf = new ArrayBuffer(stat.size);
|
||||||
|
await fs.read(file.fd, buf).then((readLen) => {
|
||||||
|
resBuf = buf;
|
||||||
|
fs.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)
|
||||||
|
})
|
||||||
|
}).catch((err:BusinessError) => {
|
||||||
|
throw new Error('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)
|
||||||
|
})
|
||||||
|
} else { //从本地文件获取
|
||||||
|
try {
|
||||||
|
let stat = fs.statSync(request.src);
|
||||||
|
if (stat.size > 0) {
|
||||||
|
let file = fs.openSync(request.src, fs.OpenMode.READ_ONLY);
|
||||||
|
resBuf = new ArrayBuffer(stat.size);
|
||||||
|
fs.readSync(file.fd, resBuf);
|
||||||
|
fs.closeSync(file);
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
throw new Error(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (typeof request.src == "number") { //从资源文件获取
|
||||||
|
let manager = request.context.createModuleContext(request.moduleName).resourceManager
|
||||||
|
if (resBuf == undefined && request.onlyRetrieveFromCache != true && request.requestSource == ImageKnifeRequestSource.SRC) {
|
||||||
|
if(request.src == -1) {
|
||||||
|
let resName = request.resName as string
|
||||||
|
resBuf = (await manager.getMediaByName(resName.substring(10))).buffer as ArrayBuffer
|
||||||
|
} else {
|
||||||
|
resBuf = manager.getMediaContentSync(request.src).buffer as ArrayBuffer
|
||||||
|
}
|
||||||
|
} else if (resBuf == undefined && request.requestSource != ImageKnifeRequestSource.SRC) {
|
||||||
|
if(request.src == -1) {
|
||||||
|
let resName = request.resName as string
|
||||||
|
resBuf = (await manager.getMediaByName(resName.substring(10))).buffer as ArrayBuffer
|
||||||
|
} else {
|
||||||
|
resBuf = manager.getMediaContentSync(request.src).buffer as ArrayBuffer
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (resBuf === undefined){
|
||||||
|
throw new Error('getImageArrayBuffer undefined')
|
||||||
|
}
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,85 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2024 Huawei Device Co., Ltd.
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
import taskpool from '@ohos.taskpool';
|
|
||||||
import common from '@ohos.app.ability.common'
|
|
||||||
import { CacheStrategy, ImageKnifeData,EventImage } from './model/ImageKnifeData';
|
|
||||||
import { PixelMapTransformation } from './transform/PixelMapTransformation';
|
|
||||||
import { drawing } from '@kit.ArkGraphics2D';
|
|
||||||
|
|
||||||
export interface HeaderOptions {
|
|
||||||
key: string;
|
|
||||||
value: Object;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Observed
|
|
||||||
export class AnimatorOption {
|
|
||||||
@Track
|
|
||||||
state?: AnimationStatus = AnimationStatus.Running
|
|
||||||
@Track
|
|
||||||
iterations?: number = -1
|
|
||||||
@Track
|
|
||||||
reverse?: boolean = false
|
|
||||||
}
|
|
||||||
|
|
||||||
@Observed
|
|
||||||
export class ImageKnifeOption {
|
|
||||||
// 主图资源
|
|
||||||
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 = false;
|
|
||||||
priority?: taskpool.Priority = taskpool.Priority.LOW
|
|
||||||
context?: common.UIAbilityContext;
|
|
||||||
progressListener?: (progress: number) => void;
|
|
||||||
transformation?: PixelMapTransformation
|
|
||||||
onLoadListener?: OnLoadCallBack | undefined;
|
|
||||||
onComplete?:(event:EventImage | undefined) => void
|
|
||||||
drawingColorFilter?: ColorFilter | drawing.ColorFilter
|
|
||||||
constructor() {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 请求回调
|
|
||||||
*/
|
|
||||||
export interface OnLoadCallBack {
|
|
||||||
// 请求开始
|
|
||||||
onLoadStart?: () => void;
|
|
||||||
|
|
||||||
// 请求成功
|
|
||||||
onLoadSuccess?: (data: string | PixelMap | undefined, imageKnifeData: ImageKnifeData) => void;
|
|
||||||
|
|
||||||
// 请求结束
|
|
||||||
onLoadFailed?: (err: string) => void;
|
|
||||||
// 请求取消
|
|
||||||
onLoadCancel?: (reason: string) => void;
|
|
||||||
}
|
|
|
@ -13,12 +13,12 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
import util from '@ohos.util';
|
import util from '@ohos.util';
|
||||||
import { FileUtils } from './FileUtils';
|
import { FileUtils } from '../utils/FileUtils';
|
||||||
import fs from '@ohos.file.fs';
|
import fs from '@ohos.file.fs';
|
||||||
import { LogUtil } from './LogUtil';
|
import { LogUtil } from '../utils/LogUtil';
|
||||||
import { SparkMD5 } from '../3rd_party/sparkmd5/spark-md5';
|
import { SparkMD5 } from '../3rd_party/sparkmd5/spark-md5';
|
||||||
|
|
||||||
|
const INT_MAX = 2147483647
|
||||||
/**
|
/**
|
||||||
* 二级文件缓存
|
* 二级文件缓存
|
||||||
* 主线程通过lruCache管理缓存大小
|
* 主线程通过lruCache管理缓存大小
|
||||||
|
@ -34,12 +34,12 @@ export class FileCache {
|
||||||
private isInited: boolean = false
|
private isInited: boolean = false
|
||||||
private context?: Context
|
private context?: Context
|
||||||
readonly defaultMaxSize: number = 512;
|
readonly defaultMaxSize: number = 512;
|
||||||
readonly defaultSize: number = 128;
|
readonly defaultSize: number = INT_MAX;
|
||||||
readonly defaultMaxMemorySize: number = 512 * 1024 * 1024;
|
readonly defaultMaxMemorySize: number = 512 * 1024 * 1024;
|
||||||
readonly defaultMemorySize: number = 128 * 1024 * 1024;
|
readonly defaultMemorySize: number = 128 * 1024 * 1024;
|
||||||
|
|
||||||
constructor(context: Context, size: number, memory: number) {
|
constructor(context: Context, size: number, memory: number) {
|
||||||
if (size <= 0) {
|
if (size <= 0 || size > INT_MAX) {
|
||||||
size = this.defaultSize
|
size = this.defaultSize
|
||||||
}
|
}
|
||||||
if (memory <= 0 || memory > this.defaultMaxMemorySize) {
|
if (memory <= 0 || memory > this.defaultMaxMemorySize) {
|
||||||
|
@ -232,18 +232,18 @@ export class FileCache {
|
||||||
}
|
}
|
||||||
else if (value != undefined) {
|
else if (value != undefined) {
|
||||||
this.currentMemory -= value.byteLength
|
this.currentMemory -= value.byteLength
|
||||||
LogUtil.info("FileCache removeMemorySize: " + value.byteLength + " currentMemory:" + this.currentMemory)
|
LogUtil.debug("FileCache removeMemorySize: " + value.byteLength + " currentMemory:" + this.currentMemory)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private addMemorySize(value: ArrayBuffer | number): void {
|
private addMemorySize(value: ArrayBuffer | number): void {
|
||||||
if (typeof value == "number") {
|
if (typeof value == "number") {
|
||||||
this.currentMemory += value
|
this.currentMemory += value
|
||||||
LogUtil.info("FileCache addMemorySize: " + value + " currentMemory:" + this.currentMemory)
|
LogUtil.debug("FileCache addMemorySize: " + value + " currentMemory:" + this.currentMemory)
|
||||||
}
|
}
|
||||||
else if (value != undefined) {
|
else if (value != undefined) {
|
||||||
this.currentMemory += value.byteLength
|
this.currentMemory += value.byteLength
|
||||||
LogUtil.info("FileCache addMemorySize: " + value.byteLength + " currentMemory:" + this.currentMemory)
|
LogUtil.debug("FileCache addMemorySize: " + value.byteLength + " currentMemory:" + this.currentMemory)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,25 +12,21 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
import { AnimatorOption, ImageKnifeOption } from '../ImageKnifeOption';
|
import { AnimatorOption, ImageKnifeOption } from '../model/ImageKnifeOption';
|
||||||
import { ImageKnifeRequest, ImageKnifeRequestState } from '../ImageKnifeRequest';
|
import { ImageKnifeRequest, ImageKnifeRequestState } from '../model/ImageKnifeRequest';
|
||||||
import common from '@ohos.app.ability.common';
|
import common from '@ohos.app.ability.common';
|
||||||
import { ImageKnife } from '../ImageKnife';
|
import { ImageKnife } from '../ImageKnife';
|
||||||
import { LogUtil } from '../utils/LogUtil';
|
import { LogUtil } from '../utils/LogUtil';
|
||||||
import { ImageKnifeRequestSource } from '../model/ImageKnifeData';
|
import { ImageKnifeRequestSource } from '../model/ImageKnifeData';
|
||||||
|
|
||||||
@Component
|
@ComponentV2
|
||||||
export struct ImageKnifeAnimatorComponent {
|
export struct ImageKnifeAnimatorComponent {
|
||||||
@Watch('watchImageKnifeOption') @ObjectLink imageKnifeOption: ImageKnifeOption;
|
@Param animatorOption: AnimatorOption = new AnimatorOption();
|
||||||
@Watch('watchAnimatorOption') @State animatorOption: AnimatorOption = new AnimatorOption();
|
@Local pixelMap: PixelMap | string | undefined = undefined
|
||||||
@State pixelMap: PixelMap | string | undefined = undefined
|
@Local imageAnimator: Array<ImageFrameInfo> | undefined = undefined
|
||||||
@State imageAnimator: Array<ImageFrameInfo> | undefined = undefined
|
@Local adaptiveWidth: Length = '100%'
|
||||||
@State state: AnimationStatus = AnimationStatus.Running
|
@Local adaptiveHeight: Length = '100%'
|
||||||
@State iterations: number = -1
|
@Local objectFit: ImageFit = ImageFit.Contain
|
||||||
@State reverse: boolean = false
|
|
||||||
@State adaptiveWidth: Length = '100%'
|
|
||||||
@State adaptiveHeight: Length = '100%'
|
|
||||||
@State objectFit: ImageFit = ImageFit.Contain
|
|
||||||
private request: ImageKnifeRequest | undefined
|
private request: ImageKnifeRequest | undefined
|
||||||
private lastWidth: number = 0
|
private lastWidth: number = 0
|
||||||
private lastHeight: number = 0
|
private lastHeight: number = 0
|
||||||
|
@ -38,7 +34,17 @@ export struct ImageKnifeAnimatorComponent {
|
||||||
private currentHeight: number = 0
|
private currentHeight: number = 0
|
||||||
private componentVersion: number = 0
|
private componentVersion: number = 0
|
||||||
private currentContext: common.UIAbilityContext | undefined = undefined
|
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 {
|
aboutToAppear(): void {
|
||||||
this.objectFit = this.imageKnifeOption.objectFit === undefined ? ImageFit.Contain : this.imageKnifeOption.objectFit
|
this.objectFit = this.imageKnifeOption.objectFit === undefined ? ImageFit.Contain : this.imageKnifeOption.objectFit
|
||||||
}
|
}
|
||||||
|
@ -64,9 +70,9 @@ export struct ImageKnifeAnimatorComponent {
|
||||||
.width(this.adaptiveWidth)
|
.width(this.adaptiveWidth)
|
||||||
.height(this.adaptiveHeight)
|
.height(this.adaptiveHeight)
|
||||||
.border(this.imageKnifeOption.border)
|
.border(this.imageKnifeOption.border)
|
||||||
.state(this.state)
|
.state(this.animatorOption.state == undefined ? AnimationStatus.Running : this.animatorOption.state)
|
||||||
.iterations(this.iterations)
|
.iterations(this.animatorOption.iterations == undefined ? -1 : this.animatorOption.iterations)
|
||||||
.reverse(this.reverse)
|
.reverse(this.animatorOption.reverse == undefined ? false : this.animatorOption.reverse)
|
||||||
.onSizeChange((oldValue:SizeOptions, newValue:SizeOptions) => {
|
.onSizeChange((oldValue:SizeOptions, newValue:SizeOptions) => {
|
||||||
this.currentWidth = newValue.width as number
|
this.currentWidth = newValue.width as number
|
||||||
this.currentHeight = newValue.height as number
|
this.currentHeight = newValue.height as number
|
||||||
|
@ -82,27 +88,11 @@ export struct ImageKnifeAnimatorComponent {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
.onStart(this.animatorOption.onStart)
|
||||||
|
.onFinish(this.animatorOption.onFinish)
|
||||||
watchAnimatorOption(){
|
.onPause(this.animatorOption.onPause)
|
||||||
if(this.animatorOption.state != undefined) {
|
.onCancel(this.animatorOption.onCancel)
|
||||||
this.state = this.animatorOption.state
|
.onRepeat(this.animatorOption.onRepeat)
|
||||||
}
|
|
||||||
if(this.animatorOption.iterations != undefined) {
|
|
||||||
this.iterations = this.animatorOption.iterations
|
|
||||||
}
|
|
||||||
if(this.animatorOption.reverse != undefined) {
|
|
||||||
this.reverse = this.animatorOption.reverse
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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 {
|
getCurrentContext(): common.UIAbilityContext {
|
||||||
|
|
|
@ -12,8 +12,8 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
import { ImageKnifeOption } from '../ImageKnifeOption';
|
import { ImageKnifeOption } from '../model/ImageKnifeOption';
|
||||||
import { ImageKnifeRequest, ImageKnifeRequestState } from '../ImageKnifeRequest';
|
import { ImageKnifeRequest, ImageKnifeRequestState } from '../model/ImageKnifeRequest';
|
||||||
import common from '@ohos.app.ability.common';
|
import common from '@ohos.app.ability.common';
|
||||||
import { ImageKnife } from '../ImageKnife';
|
import { ImageKnife } from '../ImageKnife';
|
||||||
import { LogUtil } from '../utils/LogUtil';
|
import { LogUtil } from '../utils/LogUtil';
|
||||||
|
@ -21,14 +21,13 @@ import { ImageKnifeData, ImageKnifeRequestSource } from '../model/ImageKnifeData
|
||||||
import { IEngineKey } from '../key/IEngineKey';
|
import { IEngineKey } from '../key/IEngineKey';
|
||||||
import { DefaultEngineKey } from '../key/DefaultEngineKey';
|
import { DefaultEngineKey } from '../key/DefaultEngineKey';
|
||||||
|
|
||||||
@Component
|
@ComponentV2
|
||||||
export struct ImageKnifeComponent {
|
export struct ImageKnifeComponent {
|
||||||
@Watch('watchImageKnifeOption') @ObjectLink imageKnifeOption: ImageKnifeOption;
|
@Local pixelMap: PixelMap | string | undefined = undefined
|
||||||
@State pixelMap: PixelMap | string | undefined = undefined
|
@Param syncLoad: boolean = false
|
||||||
@State syncLoad: boolean = false
|
@Local adaptiveWidth: Length = '100%'
|
||||||
@State adaptiveWidth: Length = '100%'
|
@Local adaptiveHeight: Length = '100%'
|
||||||
@State adaptiveHeight: Length = '100%'
|
@Local objectFit: ImageFit = ImageFit.Contain
|
||||||
@State objectFit: ImageFit = ImageFit.Contain
|
|
||||||
private request: ImageKnifeRequest | undefined
|
private request: ImageKnifeRequest | undefined
|
||||||
private lastWidth: number = 0
|
private lastWidth: number = 0
|
||||||
private lastHeight: number = 0
|
private lastHeight: number = 0
|
||||||
|
@ -36,43 +35,63 @@ export struct ImageKnifeComponent {
|
||||||
private currentHeight: number = 0
|
private currentHeight: number = 0
|
||||||
private componentVersion: number = 0
|
private componentVersion: number = 0
|
||||||
private currentContext: common.UIAbilityContext | undefined = undefined
|
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 {
|
aboutToAppear(): void {
|
||||||
//闪动问题失效,注释相应代码后续修复
|
this.objectFit = this.imageKnifeOption.objectFit === undefined ? ImageFit.Contain : this.imageKnifeOption.objectFit
|
||||||
if(this.syncLoad) {
|
|
||||||
|
if(this.syncLoad) { //针对部分消息列表最新消息的图片闪动问题,建议使用同步方式在aboutToAppear时加载图片
|
||||||
let engineKey: IEngineKey = new DefaultEngineKey();
|
let engineKey: IEngineKey = new DefaultEngineKey();
|
||||||
let memoryCacheSrc: ImageKnifeData | undefined = ImageKnife.getInstance()
|
let memoryCacheSrc: ImageKnifeData | undefined = ImageKnife.getInstance()
|
||||||
.loadFromMemoryCache(engineKey.generateMemoryKey(this.imageKnifeOption.loadSrc,ImageKnifeRequestSource.SRC,this.imageKnifeOption))
|
.loadFromMemoryCache(engineKey.generateMemoryKey(this.imageKnifeOption.loadSrc,ImageKnifeRequestSource.SRC,this.imageKnifeOption))
|
||||||
if (memoryCacheSrc !== undefined){
|
if (memoryCacheSrc !== undefined){
|
||||||
LogUtil.log("aboutToAppear load from memory cache for key = "+ engineKey.generateMemoryKey(this.imageKnifeOption.loadSrc,ImageKnifeRequestSource.SRC,this.imageKnifeOption))
|
LogUtil.log("aboutToAppear success load loadSrc from memory cache for loadSrc = "+ this.imageKnifeOption.loadSrc)
|
||||||
//画主图
|
|
||||||
this.pixelMap = memoryCacheSrc.source;
|
this.pixelMap = memoryCacheSrc.source;
|
||||||
}else {
|
}else{
|
||||||
let memoryCachePlace: ImageKnifeData | undefined = ImageKnife.getInstance()
|
LogUtil.log("aboutToAppear fail load loadSrc from memory cache for loadSrc = "+ this.imageKnifeOption.loadSrc)
|
||||||
.loadFromMemoryCache(engineKey.generateMemoryKey(this.imageKnifeOption.placeholderSrc!,ImageKnifeRequestSource.PLACE_HOLDER,this.imageKnifeOption))
|
if (this.imageKnifeOption.placeholderSrc !== undefined){
|
||||||
if (memoryCachePlace !== undefined){
|
let memoryCachePlace: ImageKnifeData | undefined = ImageKnife.getInstance()
|
||||||
LogUtil.log("aboutToAppear load from memory cache for key = "+ engineKey.generateMemoryKey(this.imageKnifeOption.loadSrc,ImageKnifeRequestSource.SRC,this.imageKnifeOption))
|
.loadFromMemoryCache(engineKey.generateMemoryKey(this.imageKnifeOption.placeholderSrc!,ImageKnifeRequestSource.PLACE_HOLDER,this.imageKnifeOption))
|
||||||
//画主图
|
if (memoryCachePlace !== undefined){
|
||||||
this.pixelMap = memoryCachePlace.source;
|
LogUtil.log("aboutToAppear success load placeholderSrc from memory cache for placeholderSrc = " + this.imageKnifeOption.placeholderSrc)
|
||||||
|
this.pixelMap = memoryCachePlace.source;
|
||||||
|
}else{
|
||||||
|
LogUtil.log("aboutToAppear fail load placeholderSrc from memory cache for placeholderSrc = " + this.imageKnifeOption.placeholderSrc)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.objectFit = this.imageKnifeOption.objectFit === undefined ? ImageFit.Contain : this.imageKnifeOption.objectFit
|
|
||||||
}
|
}
|
||||||
|
|
||||||
aboutToDisappear(): void {
|
aboutToDisappear(): void {
|
||||||
if (this.request !== undefined) {
|
this.clearLastRequest()
|
||||||
this.request.requestState = ImageKnifeRequestState.DESTROY
|
|
||||||
this.request = undefined
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
aboutToRecycle() {
|
aboutToRecycle() {
|
||||||
|
this.clearLastRequest()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对已DESTROY的组件不再发起请求
|
||||||
|
*/
|
||||||
|
private clearLastRequest(){
|
||||||
if (this.request !== undefined) {
|
if (this.request !== undefined) {
|
||||||
this.request.requestState = ImageKnifeRequestState.DESTROY
|
this.request.requestState = ImageKnifeRequestState.DESTROY
|
||||||
this.request = undefined
|
this.request = undefined
|
||||||
}
|
}
|
||||||
this.objectFit = this.imageKnifeOption.objectFit === undefined ? ImageFit.Contain : this.imageKnifeOption.objectFit
|
|
||||||
}
|
}
|
||||||
|
|
||||||
build() {
|
build() {
|
||||||
|
@ -90,27 +109,19 @@ export struct ImageKnifeComponent {
|
||||||
this.currentHeight = newValue.height as number
|
this.currentHeight = newValue.height as number
|
||||||
this.lastWidth = oldValue.width as number
|
this.lastWidth = oldValue.width as number
|
||||||
this.lastHeight = oldValue.height as number
|
this.lastHeight = oldValue.height as number
|
||||||
if (this.currentWidth <= 0 || this.currentHeight <= 0) {
|
|
||||||
// 存在宽或者高为0,此次重回无意义,无需进行request请求
|
// 条件1: 宽高值均有效,值>0. 条件2:当前宽高与上一次宽高不同
|
||||||
} else {
|
if (this.currentWidth > 0 && this.currentHeight > 0 &&
|
||||||
// 前提:宽高值均有效,值>0. 条件1:当前宽高与上一次宽高不同 条件2:当前是第一次绘制
|
(this.currentHeight != this.lastHeight || this.currentWidth != this.lastWidth)) {
|
||||||
if (this.currentHeight != this.lastHeight || this.currentWidth != this.lastWidth) {
|
LogUtil.log("onSizeChange execute request:width=" + this.currentWidth + " height= " + this.currentHeight
|
||||||
LogUtil.log("execute request:width=" + this.currentWidth + " height= " + this.currentHeight)
|
+ " loadSrc = " + this.request?.imageKnifeOption.loadSrc
|
||||||
ImageKnife.getInstance().execute(this.getRequest(this.currentWidth, this.currentHeight))
|
+ " placeholderSrc = " + this.request?.imageKnifeOption.placeholderSrc
|
||||||
}
|
+ " errorholderSrc = " + this.request?.imageKnifeOption.errorholderSrc)
|
||||||
|
ImageKnife.getInstance().execute(this.getRequest(this.currentWidth, this.currentHeight))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
watchImageKnifeOption() {
|
|
||||||
if (this.request !== undefined) {
|
|
||||||
this.request.requestState = ImageKnifeRequestState.DESTROY
|
|
||||||
}
|
|
||||||
this.request = undefined
|
|
||||||
this.componentVersion++
|
|
||||||
ImageKnife.getInstance().execute(this.getRequest(this.currentWidth, this.currentHeight))
|
|
||||||
}
|
|
||||||
|
|
||||||
getCurrentContext(): common.UIAbilityContext {
|
getCurrentContext(): common.UIAbilityContext {
|
||||||
if (this.currentContext == undefined) {
|
if (this.currentContext == undefined) {
|
||||||
this.currentContext = getContext(this) as common.UIAbilityContext
|
this.currentContext = getContext(this) as common.UIAbilityContext
|
||||||
|
@ -132,24 +143,10 @@ export struct ImageKnifeComponent {
|
||||||
return //针对reuse场景,不显示历史图片
|
return //针对reuse场景,不显示历史图片
|
||||||
}
|
}
|
||||||
this.pixelMap = pixelMap
|
this.pixelMap = pixelMap
|
||||||
if (typeof this.pixelMap !== 'string') {
|
if (typeof this.pixelMap !== 'string' && this.imageKnifeOption.objectFit === ImageFit.Auto) { //针对静态图高度自适应
|
||||||
if (this.imageKnifeOption.objectFit === ImageFit.Auto) {
|
let info = await this.pixelMap.getImageInfo()
|
||||||
let info = await this.pixelMap.getImageInfo()
|
this.adaptiveWidth = this.currentWidth
|
||||||
|
this.adaptiveHeight = info.size.height * this.currentWidth / info.size.width
|
||||||
this.adaptiveWidth = this.currentWidth
|
|
||||||
this.adaptiveHeight = info.size.height * this.currentWidth / info.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) {
|
if (requestSource == ImageKnifeRequestSource.SRC) {
|
||||||
|
@ -168,8 +165,4 @@ export struct ImageKnifeComponent {
|
||||||
|
|
||||||
return this.request
|
return this.request
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
interface KeyCanvas {
|
|
||||||
keyId: string
|
|
||||||
}
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
/*
|
||||||
|
* 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
|
||||||
|
}
|
|
@ -0,0 +1,148 @@
|
||||||
|
/*
|
||||||
|
* 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,
|
||||||
|
}
|
|
@ -0,0 +1,58 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2024 Huawei Device Co., Ltd.
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
import { 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);
|
||||||
|
}
|
|
@ -0,0 +1,73 @@
|
||||||
|
/*
|
||||||
|
* 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');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -13,10 +13,11 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
import { SparkMD5 } from '../3rd_party/sparkmd5/spark-md5';
|
import { SparkMD5 } from '../3rd_party/sparkmd5/spark-md5';
|
||||||
import { ImageKnifeOption } from '../ImageKnifeOption';
|
import { ImageKnifeOption } from '../model/ImageKnifeOption';
|
||||||
import { IEngineKey } from './IEngineKey';
|
import { IEngineKey } from './IEngineKey';
|
||||||
import { PixelMapTransformation } from '../transform/PixelMapTransformation';
|
import { PixelMapTransformation } from '../transform/PixelMapTransformation';
|
||||||
import { ImageKnifeRequestSource } from '../model/ImageKnifeData';
|
import { ImageKnifeRequestSource } from '../model/ImageKnifeData';
|
||||||
|
import { DownsampleStrategy } from '../downsampling/DownsampleStartegy';
|
||||||
|
|
||||||
@Sendable
|
@Sendable
|
||||||
export class DefaultEngineKey implements IEngineKey {
|
export class DefaultEngineKey implements IEngineKey {
|
||||||
|
@ -31,6 +32,9 @@ export class DefaultEngineKey implements IEngineKey {
|
||||||
if (imageKnifeOption.transformation) {
|
if (imageKnifeOption.transformation) {
|
||||||
key += "transformation=" + this.getTransformation(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
|
return key
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
import { ImageKnifeOption } from '../ImageKnifeOption'
|
import { ImageKnifeOption } from '../model/ImageKnifeOption'
|
||||||
import { ImageKnifeRequestSource } from '../model/ImageKnifeData'
|
import { ImageKnifeRequestSource } from '../model/ImageKnifeData'
|
||||||
|
|
||||||
export interface IEngineKey {
|
export interface IEngineKey {
|
||||||
|
|
|
@ -12,12 +12,13 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
import { HeaderOptions } from '../ImageKnifeOption'
|
import { HeaderOptions } from './ImageKnifeOption'
|
||||||
import { ImageKnifeRequest } from '../ImageKnifeRequest'
|
import { ImageKnifeRequest } from './ImageKnifeRequest'
|
||||||
import { IEngineKey } from '../key/IEngineKey'
|
import { IEngineKey } from '../key/IEngineKey'
|
||||||
import { PixelMapTransformation } from '../transform/PixelMapTransformation'
|
import { PixelMapTransformation } from '../transform/PixelMapTransformation'
|
||||||
import common from '@ohos.app.ability.common';
|
import common from '@ohos.app.ability.common';
|
||||||
import { Size } from '@kit.ArkUI'
|
import { Size } from '@kit.ArkUI'
|
||||||
|
import { DownsampleStrategy } from '../downsampling/DownsampleStartegy'
|
||||||
|
|
||||||
export interface ImageKnifeData {
|
export interface ImageKnifeData {
|
||||||
source: PixelMap | string,
|
source: PixelMap | string,
|
||||||
|
@ -86,7 +87,7 @@ export interface RequestJobResult {
|
||||||
*/
|
*/
|
||||||
export interface RequestJobRequest {
|
export interface RequestJobRequest {
|
||||||
context: common.UIAbilityContext,
|
context: common.UIAbilityContext,
|
||||||
src: string | PixelMap | Resource,
|
src: string | number,
|
||||||
headers?: Array<HeaderOptions>,
|
headers?: Array<HeaderOptions>,
|
||||||
allHeaders: Map<string, Object>,
|
allHeaders: Map<string, Object>,
|
||||||
componentWidth: number,
|
componentWidth: number,
|
||||||
|
@ -101,6 +102,11 @@ export interface RequestJobRequest {
|
||||||
isWatchProgress: boolean
|
isWatchProgress: boolean
|
||||||
memoryKey: string
|
memoryKey: string
|
||||||
fileCacheFolder: string,
|
fileCacheFolder: string,
|
||||||
isAnimator?: boolean
|
isAnimator?: boolean,
|
||||||
|
moduleName?:string,
|
||||||
|
resName?: string,
|
||||||
|
targetWidth: number
|
||||||
|
targetHeight: number
|
||||||
|
downsampType: DownsampleStrategy
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,166 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2024 Huawei Device Co., Ltd.
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
import taskpool from '@ohos.taskpool';
|
||||||
|
import common from '@ohos.app.ability.common'
|
||||||
|
import { CacheStrategy, ImageKnifeData,EventImage } from './ImageKnifeData';
|
||||||
|
import { PixelMapTransformation } from '../transform/PixelMapTransformation';
|
||||||
|
import { drawing } from '@kit.ArkGraphics2D';
|
||||||
|
import { DownsampleStrategy } from '../downsampling/DownsampleStartegy';
|
||||||
|
|
||||||
|
export interface HeaderOptions {
|
||||||
|
key: string;
|
||||||
|
value: Object;
|
||||||
|
}
|
||||||
|
interface AnimatorType {
|
||||||
|
state?: AnimationStatus
|
||||||
|
iterations?: number
|
||||||
|
reverse?: boolean
|
||||||
|
onStart?:()=>void
|
||||||
|
onFinish?:()=>void
|
||||||
|
onPause?:()=>void
|
||||||
|
onCancel?:()=>void
|
||||||
|
onRepeat?:()=>void
|
||||||
|
}
|
||||||
|
@ObservedV2
|
||||||
|
export class AnimatorOption {
|
||||||
|
@Trace
|
||||||
|
state?: AnimationStatus = AnimationStatus.Running
|
||||||
|
@Trace
|
||||||
|
iterations?: number = -1
|
||||||
|
@Trace
|
||||||
|
reverse?: boolean = false
|
||||||
|
@Trace
|
||||||
|
onStart?:()=>void
|
||||||
|
@Trace
|
||||||
|
onFinish?:()=>void
|
||||||
|
@Trace
|
||||||
|
onPause?:()=>void
|
||||||
|
@Trace
|
||||||
|
onCancel?:()=>void
|
||||||
|
@Trace
|
||||||
|
onRepeat?:()=>void
|
||||||
|
constructor(option?:AnimatorType) {
|
||||||
|
this.state = option?.state
|
||||||
|
this.iterations = option?.iterations
|
||||||
|
this.reverse = option?.reverse
|
||||||
|
this.onStart = option?.onStart
|
||||||
|
this.onFinish = option?.onFinish
|
||||||
|
this.onPause = option?.onPause
|
||||||
|
this.onCancel = option?.onCancel
|
||||||
|
this.onRepeat = option?.onRepeat
|
||||||
|
}
|
||||||
|
}
|
||||||
|
interface ImageOption {
|
||||||
|
// 主图资源
|
||||||
|
loadSrc: string | PixelMap | Resource
|
||||||
|
// 占位图
|
||||||
|
placeholderSrc?: string | PixelMap | Resource
|
||||||
|
// 失败占位图
|
||||||
|
errorholderSrc?: string | PixelMap | Resource
|
||||||
|
headerOption?: Array<HeaderOptions>;
|
||||||
|
// 自定义缓存关键字
|
||||||
|
signature?: string
|
||||||
|
// 主图填充效果
|
||||||
|
objectFit?: ImageFit
|
||||||
|
// 占位图填充效果
|
||||||
|
placeholderObjectFit?: ImageFit
|
||||||
|
// 错误图填充效果
|
||||||
|
errorholderObjectFit?: ImageFit
|
||||||
|
customGetImage?: (context: Context, src: string | PixelMap | Resource) => Promise<ArrayBuffer | undefined>
|
||||||
|
border?: BorderOptions
|
||||||
|
// 缓存策略
|
||||||
|
writeCacheStrategy?: CacheStrategy
|
||||||
|
// 仅使用缓存加载数据
|
||||||
|
onlyRetrieveFromCache?: boolean;
|
||||||
|
priority?: taskpool.Priority
|
||||||
|
context?: common.UIAbilityContext;
|
||||||
|
progressListener?: (progress: number) => void;
|
||||||
|
transformation?: PixelMapTransformation
|
||||||
|
onLoadListener?: OnLoadCallBack | undefined;
|
||||||
|
onComplete?:(event:EventImage | undefined) => void
|
||||||
|
drawingColorFilter?: ColorFilter | drawing.ColorFilter
|
||||||
|
downsampleOf?: DownsampleStrategy
|
||||||
|
}
|
||||||
|
@ObservedV2
|
||||||
|
export class ImageKnifeOption {
|
||||||
|
// 主图资源
|
||||||
|
@Trace loadSrc: string | PixelMap | Resource = "";
|
||||||
|
// 占位图
|
||||||
|
placeholderSrc?: string | PixelMap | Resource;
|
||||||
|
// 失败占位图
|
||||||
|
errorholderSrc?: string | PixelMap | Resource;
|
||||||
|
headerOption?: Array<HeaderOptions>;
|
||||||
|
// 自定义缓存关键字
|
||||||
|
@Trace signature?: string;
|
||||||
|
// 主图填充效果
|
||||||
|
@Trace objectFit?: ImageFit
|
||||||
|
// 占位图填充效果
|
||||||
|
placeholderObjectFit?: ImageFit
|
||||||
|
// 错误图填充效果
|
||||||
|
errorholderObjectFit?: ImageFit
|
||||||
|
customGetImage?: (context: Context, src: string | PixelMap | Resource) => Promise<ArrayBuffer | undefined>
|
||||||
|
@Trace border?: BorderOptions
|
||||||
|
// 缓存策略
|
||||||
|
writeCacheStrategy?: CacheStrategy
|
||||||
|
// 仅使用缓存加载数据
|
||||||
|
onlyRetrieveFromCache?: boolean = false;
|
||||||
|
priority?: taskpool.Priority = taskpool.Priority.LOW
|
||||||
|
context?: common.UIAbilityContext;
|
||||||
|
progressListener?: (progress: number) => void;
|
||||||
|
@Trace transformation?: PixelMapTransformation
|
||||||
|
onLoadListener?: OnLoadCallBack | undefined;
|
||||||
|
onComplete?:(event:EventImage | undefined) => void
|
||||||
|
drawingColorFilter?: ColorFilter | drawing.ColorFilter
|
||||||
|
// 下采样
|
||||||
|
@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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 请求回调
|
||||||
|
*/
|
||||||
|
export interface OnLoadCallBack {
|
||||||
|
// 请求开始
|
||||||
|
onLoadStart?: () => void;
|
||||||
|
|
||||||
|
// 请求成功
|
||||||
|
onLoadSuccess?: (data: string | PixelMap | undefined, imageKnifeData: ImageKnifeData) => void;
|
||||||
|
|
||||||
|
// 请求结束
|
||||||
|
onLoadFailed?: (err: string) => void;
|
||||||
|
// 请求取消
|
||||||
|
onLoadCancel?: (reason: string) => void;
|
||||||
|
}
|
|
@ -14,7 +14,8 @@
|
||||||
*/
|
*/
|
||||||
import { ImageKnifeOption } from './ImageKnifeOption';
|
import { ImageKnifeOption } from './ImageKnifeOption';
|
||||||
import common from '@ohos.app.ability.common';
|
import common from '@ohos.app.ability.common';
|
||||||
import { ImageKnifeRequestSource } from './model/ImageKnifeData';
|
import { ImageKnifeRequestSource } from './ImageKnifeData';
|
||||||
|
import { DownsampleStrategy } from '../downsampling/DownsampleStartegy';
|
||||||
|
|
||||||
|
|
||||||
export class ImageKnifeRequest {
|
export class ImageKnifeRequest {
|
||||||
|
@ -27,18 +28,22 @@ export class ImageKnifeRequest {
|
||||||
ImageKnifeRequestCallback: ImageKnifeRequestCallback
|
ImageKnifeRequestCallback: ImageKnifeRequestCallback
|
||||||
componentVersion: number = 0
|
componentVersion: number = 0
|
||||||
headers: Map<string,Object> = new Map<string,Object>()
|
headers: Map<string,Object> = new Map<string,Object>()
|
||||||
|
downsampType?: DownsampleStrategy
|
||||||
constructor(option: ImageKnifeOption,
|
constructor(option: ImageKnifeOption,
|
||||||
uIAbilityContext: common.UIAbilityContext,
|
uIAbilityContext: common.UIAbilityContext,
|
||||||
width: number,
|
width: number,
|
||||||
height: number,
|
height: number,
|
||||||
version: number,
|
version: number,
|
||||||
ImageKnifeRequestCallback: ImageKnifeRequestCallback) {
|
ImageKnifeRequestCallback: ImageKnifeRequestCallback,
|
||||||
|
downsampType?: DownsampleStrategy
|
||||||
|
) {
|
||||||
this.imageKnifeOption = option
|
this.imageKnifeOption = option
|
||||||
this.context = uIAbilityContext
|
this.context = uIAbilityContext
|
||||||
this.componentWidth = width
|
this.componentWidth = width
|
||||||
this.componentHeight = height
|
this.componentHeight = height
|
||||||
this.componentVersion = version
|
this.componentVersion = version
|
||||||
this.ImageKnifeRequestCallback = ImageKnifeRequestCallback
|
this.ImageKnifeRequestCallback = ImageKnifeRequestCallback
|
||||||
|
this.downsampType = downsampType
|
||||||
}
|
}
|
||||||
// RequestOption调用header对于的方法
|
// RequestOption调用header对于的方法
|
||||||
addHeader(key: string, value: Object) {
|
addHeader(key: string, value: Object) {
|
|
@ -12,7 +12,7 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
import { ImageKnifeRequest } from '../ImageKnifeRequest';
|
import { ImageKnifeRequest } from '../model/ImageKnifeRequest';
|
||||||
import { IJobQueue } from './IJobQueue'
|
import { IJobQueue } from './IJobQueue'
|
||||||
import Queue from '@ohos.util.Queue';
|
import Queue from '@ohos.util.Queue';
|
||||||
import { taskpool,Stack } from '@kit.ArkTS';
|
import { taskpool,Stack } from '@kit.ArkTS';
|
|
@ -12,7 +12,7 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
import { ImageKnifeRequest } from '../ImageKnifeRequest'
|
import { ImageKnifeRequest } from '../model/ImageKnifeRequest'
|
||||||
|
|
||||||
export interface IJobQueue {
|
export interface IJobQueue {
|
||||||
|
|
|
@ -12,44 +12,29 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
import { hilog } from '@kit.PerformanceAnalysisKit';
|
||||||
|
|
||||||
export class LogUtil {
|
export class LogUtil {
|
||||||
public static OFF: number = 1
|
public static readonly DOMAIN: number = 0xD002220;
|
||||||
public static LOG: number = 2
|
public static readonly TAG: string = "ImageKnife::";
|
||||||
public static DEBUG: number = 3
|
|
||||||
public static INFO: number = 4
|
|
||||||
public static WARN: number = 5
|
|
||||||
public static ERROR: number = 6
|
|
||||||
public static ALL: number = 7
|
|
||||||
public static mLogLevel: number = LogUtil.OFF;
|
|
||||||
public static TAG: string = "ImageKnife:: ";
|
|
||||||
|
|
||||||
public static debug(message: string, ...args: Object[]) {
|
public static debug(message: string, ...args: Object[]) {
|
||||||
if (LogUtil.mLogLevel >= LogUtil.DEBUG) {
|
hilog.debug(LogUtil.DOMAIN, LogUtil.TAG, message, args)
|
||||||
console.debug(LogUtil.TAG + message, args)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static info(message: string, ...args: Object[]) {
|
public static info(message: string, ...args: Object[]) {
|
||||||
if (LogUtil.mLogLevel >= LogUtil.INFO) {
|
hilog.info(LogUtil.DOMAIN, LogUtil.TAG, message, args)
|
||||||
console.info(LogUtil.TAG + message, args)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static log(message: string, ...args: Object[]) {
|
public static log(message: string, ...args: Object[]) {
|
||||||
if (LogUtil.mLogLevel >= LogUtil.LOG) {
|
hilog.debug(LogUtil.DOMAIN, LogUtil.TAG, message, args)
|
||||||
console.log(LogUtil.TAG + message, args)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static warn(message: string, ...args: Object[]) {
|
public static warn(message: string, ...args: Object[]) {
|
||||||
if (LogUtil.mLogLevel >= LogUtil.WARN) {
|
hilog.warn(LogUtil.DOMAIN, LogUtil.TAG, message, args)
|
||||||
console.warn(LogUtil.TAG + message, args)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static error(message: string, ...args: Object[]) {
|
public static error(message: string, ...args: Object[]) {
|
||||||
if (LogUtil.mLogLevel >= LogUtil.ERROR) {
|
hilog.error(LogUtil.DOMAIN, LogUtil.TAG, message, args)
|
||||||
console.error(LogUtil.TAG + message, args)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,35 +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 { SparkMD5 } from '../3rd_party/sparkmd5/spark-md5'
|
|
||||||
import util from '@ohos.util'
|
|
||||||
|
|
||||||
export class Tools {
|
|
||||||
private static keyCache: util.LRUCache<string,string> = new util.LRUCache(1024)
|
|
||||||
public static generateMemoryKey(key: string | PixelMap | Resource): string{
|
|
||||||
return typeof key == "string"? key : JSON.stringify(key)
|
|
||||||
}
|
|
||||||
// 生成唯一的key
|
|
||||||
public static generateKey(key: string | PixelMap | Resource): string{
|
|
||||||
let keyCache = typeof key == "string"? key : JSON.stringify(key)
|
|
||||||
let result = Tools.keyCache.get(keyCache)
|
|
||||||
if(result != undefined) {
|
|
||||||
return result
|
|
||||||
} else {
|
|
||||||
result = SparkMD5.hashBinary(keyCache)
|
|
||||||
Tools.keyCache.put(keyCache,result)
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Binary file not shown.
Before Width: | Height: | Size: 10 KiB |
|
@ -1,16 +1,11 @@
|
||||||
{
|
{
|
||||||
"modelVersion": "5.0.0",
|
"license": "ISC",
|
||||||
"name": "imageknife",
|
|
||||||
"version": "1.0.0",
|
|
||||||
"description": "Please describe the basic information.",
|
|
||||||
"main": "",
|
|
||||||
"author": "",
|
|
||||||
"license": "",
|
|
||||||
"dependencies": {
|
|
||||||
"@ohos/gpu_transform": "^1.0.2"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@ohos/hypium": "1.0.16"
|
"@ohos/hypium": "1.0.6"
|
||||||
},
|
},
|
||||||
"dynamicDependencies": {}
|
"name": "imageknife",
|
||||||
}
|
"description": "example description",
|
||||||
|
"repository": {},
|
||||||
|
"version": "",
|
||||||
|
"dependencies": {}
|
||||||
|
}
|
||||||
|
|
|
@ -14,14 +14,14 @@
|
||||||
*/
|
*/
|
||||||
import { ImageKnife , ImageKnifeComponent ,ImageKnifeOption } from "@ohos/imageknife"
|
import { ImageKnife , ImageKnifeComponent ,ImageKnifeOption } from "@ohos/imageknife"
|
||||||
|
|
||||||
@Component
|
@ComponentV2
|
||||||
export struct IndexComponent {
|
export struct IndexComponent {
|
||||||
@State imageKnifeOption: ImageKnifeOption = {
|
@Local imageKnifeOption: ImageKnifeOption = new ImageKnifeOption({
|
||||||
loadSrc: $r('app.media.startIcon')
|
loadSrc: $r('app.media.startIcon')
|
||||||
}
|
})
|
||||||
build() {
|
build() {
|
||||||
Column() {
|
Column() {
|
||||||
Button("预加载").onClick((event: ClickEvent) => {
|
Button($r('app.string.Preload')).onClick((event: ClickEvent) => {
|
||||||
ImageKnife.getInstance()
|
ImageKnife.getInstance()
|
||||||
.preLoadCache('https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp')
|
.preLoadCache('https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp')
|
||||||
.then((data) => {
|
.then((data) => {
|
||||||
|
|
|
@ -3,6 +3,10 @@
|
||||||
{
|
{
|
||||||
"name": "shared_desc",
|
"name": "shared_desc",
|
||||||
"value": "description"
|
"value": "description"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Preload",
|
||||||
|
"value": "Preload"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue