Pre Merge pull request !410 from tyBrave/master
This commit is contained in:
commit
e369d45549
|
@ -1,5 +1,8 @@
|
|||
## 3.1.1-rc.1
|
||||
- 新增图片加载的回调信息
|
||||
- 新增获取当前缓存的上限、大小及其当前对应缓存图片的个数的接口
|
||||
- Photo reduction sampling
|
||||
|
||||
## 3.1.1-rc.0
|
||||
- 重构代码:抽取ImageKnifeDispatcher子线程requestJob相关代码到ImageKnifeLoader中,降低函数复杂度
|
||||
## 3.1.0
|
||||
|
|
36
README.md
36
README.md
|
@ -275,6 +275,35 @@ ImageKnifeComponent({
|
|||
}),animatorOption:this.animatorOption
|
||||
}).width(300).height(300)
|
||||
```
|
||||
#### 12.Load the image callback information data
|
||||
```
|
||||
ImageKnifeComponent({ ImageKnifeOption: = new ImageKnifeOption({
|
||||
loadSrc: $r('app.media.pngSample'),
|
||||
objectFit: ImageFit.Contain,
|
||||
onLoadListener: {
|
||||
onLoadStart: (data) => {
|
||||
let startCallBackData = JSON.stringify(data);
|
||||
},
|
||||
onLoadFailed: (res, err) => {
|
||||
let failedBackData = res + ";" + JSON.stringify(err);
|
||||
},
|
||||
onLoadSuccess: (data, imageData) => {
|
||||
let successBackData = JSON.stringify(imageData);
|
||||
},
|
||||
onLoadCancel: (res, cel) => {
|
||||
let cancelBackData = res + ";" + JSON.stringify(cel);
|
||||
}
|
||||
},
|
||||
border: { radius: 50 },
|
||||
onComplete: (event) => {
|
||||
if (event && event.loadingStatus == 0) {
|
||||
let render_success = JSON.stringify(Date.now())
|
||||
}
|
||||
}
|
||||
})
|
||||
}).width(100).height(100)
|
||||
```
|
||||
|
||||
#### Reuse Scenario
|
||||
Clear the component content in the **aboutToRecycle** lifecycle and trigger image loading through watch observeration.
|
||||
## Available APIs
|
||||
|
@ -318,8 +347,9 @@ Clear the component content in the **aboutToRecycle** lifecycle and trigger imag
|
|||
| transformation | PixelMapTransformation | Image transformation. Optional. |
|
||||
| drawingColorFilter | ColorFilter | Drawing color filter. Optional. |
|
||||
| onComplete | (event:EventImage \| undefined)=>void | Callback for image loading completion. Optional. |
|
||||
| onLoadListener | onLoadStart:()=>void,onLoadSuccess:(data:string\|Pixelmap)=>void | Callback for image loading events. Optional. |
|
||||
| onLoadListener | onLoadStart: (call?: ImageKnifeData) => void、onLoadSuccess: (data: string \| PixelMap \| undefined,call?: ImageKnifeData) => void、onLoadFailed: (err: string,errorInfo?: ErrorInfo) => void | Callback for image loading events. Optional. |
|
||||
| downsampleOf | DownsampleStrategy | 降采样(可选) |
|
||||
|
||||
### 降采样类型
|
||||
| 类型 | 相关描述 |
|
||||
|---------------------|-------------------|
|
||||
|
@ -330,6 +360,7 @@ Clear the component content in the **aboutToRecycle** lifecycle and trigger imag
|
|||
| CENTER_OUTSIDE_MEMORY | 宽高缩放比最大的比例,进行缩放适配内存优先 |
|
||||
| CENTER_OUTSIDE_QUALITY | 宽高缩放比最大的比例,进行缩放适配质量优先 |
|
||||
| AT_LEAST | 根据宽高的最小的比例,进行适配 |
|
||||
|
||||
### ImageKnife
|
||||
|
||||
| Parameter | Type | Description |
|
||||
|
@ -346,6 +377,9 @@ Clear the component content in the **aboutToRecycle** lifecycle and trigger imag
|
|||
| 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. |
|
||||
| getCacheUpperLimit | cacheType?: CacheStrategy | Gets the upper limit size of the specified cache |
|
||||
| getCurrentPicturesNum | cacheType?: CacheStrategy | Gets the number of images currently cached in the specified cache |
|
||||
| getCurrentCacheSize | cacheType?: CacheStrategy | Gets the current size of the specified cache |
|
||||
### Graphics tRansformation Types (GPUImage Dependency Required)
|
||||
|
||||
| Type | Description |
|
||||
|
|
103
README_zh.md
103
README_zh.md
|
@ -264,6 +264,35 @@ ImageKnifeAnimatorComponent({
|
|||
}),animatorOption:this.animatorOption
|
||||
}).width(300).height(300).backgroundColor(Color.Orange).margin({top:30})
|
||||
```
|
||||
#### 11.加载图片回调信息数据 示例
|
||||
```
|
||||
ImageKnifeComponent({ ImageKnifeOption: = new ImageKnifeOption({
|
||||
loadSrc: $r('app.media.pngSample'),
|
||||
objectFit: ImageFit.Contain,
|
||||
onLoadListener: {
|
||||
onLoadStart: (data) => {
|
||||
let startCallBackData = JSON.stringify(data);
|
||||
},
|
||||
onLoadFailed: (res, err) => {
|
||||
let failedBackData = res + ";" + JSON.stringify(err);
|
||||
},
|
||||
onLoadSuccess: (data, imageData) => {
|
||||
let successBackData = JSON.stringify(imageData);
|
||||
},
|
||||
onLoadCancel: (res, cel) => {
|
||||
let cancelBackData = res + ";" + JSON.stringify(cel);
|
||||
}
|
||||
},
|
||||
border: { radius: 50 },
|
||||
onComplete: (event) => {
|
||||
if (event && event.loadingStatus == 0) {
|
||||
let render_success = JSON.stringify(Date.now())
|
||||
}
|
||||
}
|
||||
})
|
||||
}).width(100).height(100)
|
||||
```
|
||||
|
||||
#### 复用场景
|
||||
在aboutToRecycle生命周期清空组件内容;通过watch监听触发图片的加载。
|
||||
## 接口说明
|
||||
|
@ -287,44 +316,48 @@ ImageKnifeAnimatorComponent({
|
|||
|
||||
### 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| 监听图片加载成功与失败 |
|
||||
| 参数名称 | 入参内容 | 功能简介 |
|
||||
|-----------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------|
|
||||
| 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: (call?: ImageKnifeData) => void、onLoadSuccess: (data: string \| PixelMap \| undefined,call?: ImageKnifeData) => void、onLoadFailed: (err: string,errorInfo?: ErrorInfo) => 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 | 清理指定磁盘缓存 |
|
||||
| 参数名称 | 入参内容 | 功能简介 |
|
||||
|------------------|-------------------------------------------------------------------------------------------------------|------------------|
|
||||
| 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 | 清理指定磁盘缓存 |
|
||||
| getCacheUpperLimit | cacheType?: CacheStrategy | 获取指定缓存的上限大小 |
|
||||
| getCurrentPicturesNum | cacheType?: CacheStrategy | 获取指定缓存的当前缓存图片个数 |
|
||||
| getCurrentCacheSize | cacheType?: CacheStrategy | 获取指定缓存的当前大小 |
|
||||
|
||||
### 图形变换类型(需要为GPUImage添加依赖项)
|
||||
|
||||
| 类型 | 相关描述 |
|
||||
|
|
|
@ -179,6 +179,13 @@ struct Index {
|
|||
uri: 'pages/TestLoadCancelListenerPage',
|
||||
});
|
||||
})
|
||||
|
||||
Button($r('app.string.test_callback')).margin({ top: 10 }).onClick(() => {
|
||||
router.push({
|
||||
uri: 'pages/TestImageKnifeCallbackPage',
|
||||
|
||||
});
|
||||
})
|
||||
}
|
||||
}.width('100%')
|
||||
.height('100%')
|
||||
|
|
|
@ -0,0 +1,285 @@
|
|||
/*
|
||||
* 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';
|
||||
import { router } from '@kit.ArkUI';
|
||||
|
||||
@Entry
|
||||
@ComponentV2
|
||||
struct TestImageKnifeCallbackPage {
|
||||
@Local imageKnifeOption: ImageKnifeOption = new ImageKnifeOption();
|
||||
@Local currentWidth: number = 200
|
||||
@Local currentHeight: number = 200
|
||||
@Local startCallBackData: string = ""
|
||||
@Local successBackData: string = ""
|
||||
@Local failedBackData: string = ""
|
||||
@Local cancelBackData: string = ""
|
||||
@Local render_success: string = ""
|
||||
@Local showChild: boolean = true;
|
||||
|
||||
build() {
|
||||
Scroll() {
|
||||
Column() {
|
||||
Text($r('app.string.start_callback', this.startCallBackData))
|
||||
Text($r('app.string.success_callback', this.successBackData))
|
||||
Text($r('app.string.failed_callback', this.failedBackData))
|
||||
Text($r('app.string.cancel_callback', this.cancelBackData))
|
||||
Text($r('app.string.render_success', this.render_success))
|
||||
|
||||
Row() {
|
||||
Button($r('app.string.Network_images'))
|
||||
.fontSize(13)
|
||||
.onClick(() => {
|
||||
this.destroy();
|
||||
this.imageKnifeOption = new ImageKnifeOption({
|
||||
loadSrc: "https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/10/v3/qaEzwkU0QeKb1yehnP2Xig/q7fxAlgMQKup-HUBayRLGQ.jpg",
|
||||
objectFit: ImageFit.Contain,
|
||||
onLoadListener: {
|
||||
onLoadStart: (data) => {
|
||||
this.startCallBackData = JSON.stringify(data);
|
||||
},
|
||||
onLoadFailed: (res, err) => {
|
||||
this.failedBackData = res + ";" + JSON.stringify(err);
|
||||
},
|
||||
onLoadSuccess: (data, imageData) => {
|
||||
this.successBackData = JSON.stringify(imageData);
|
||||
},
|
||||
onLoadCancel: (res, cel) => {
|
||||
this.cancelBackData = res + ";" + JSON.stringify(cel);
|
||||
}
|
||||
},
|
||||
border: { radius: 50 },
|
||||
onComplete: (event) => {
|
||||
if (event && event.loadingStatus == 0) {
|
||||
this.render_success = JSON.stringify(Date.now())
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
Button($r('app.string.gif'))
|
||||
.fontSize(13)
|
||||
.onClick(() => {
|
||||
this.destroy();
|
||||
this.imageKnifeOption = new ImageKnifeOption({
|
||||
loadSrc: 'https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658',
|
||||
objectFit: ImageFit.Contain,
|
||||
onLoadListener: {
|
||||
onLoadStart: (data) => {
|
||||
this.startCallBackData = JSON.stringify(data);
|
||||
},
|
||||
onLoadFailed: (res, err) => {
|
||||
this.failedBackData = res + ";" + JSON.stringify(err);
|
||||
},
|
||||
onLoadSuccess: (data, imageData) => {
|
||||
let suc = imageData;
|
||||
suc.source = ""
|
||||
this.successBackData = JSON.stringify(suc);
|
||||
},
|
||||
onLoadCancel: (res, cel) => {
|
||||
this.cancelBackData = res + ";" + JSON.stringify(cel);
|
||||
}
|
||||
},
|
||||
border: { radius: 50 },
|
||||
onComplete: (event) => {
|
||||
if (event && event.loadingStatus == 0) {
|
||||
this.render_success = JSON.stringify(Date.now())
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
Button($r('app.string.local_pic'))
|
||||
.fontSize(13)
|
||||
.onClick(() => {
|
||||
this.destroy();
|
||||
this.imageKnifeOption = new ImageKnifeOption({
|
||||
loadSrc: $r('app.media.pngSample'),
|
||||
objectFit: ImageFit.Contain,
|
||||
onLoadListener: {
|
||||
onLoadStart: (data) => {
|
||||
this.startCallBackData = JSON.stringify(data);
|
||||
},
|
||||
onLoadFailed: (res, err) => {
|
||||
this.failedBackData = res + ";" + JSON.stringify(err);
|
||||
},
|
||||
onLoadSuccess: (data, imageData) => {
|
||||
this.successBackData = JSON.stringify(imageData);
|
||||
},
|
||||
onLoadCancel: (res, cel) => {
|
||||
this.cancelBackData = res + ";" + JSON.stringify(cel);
|
||||
}
|
||||
},
|
||||
border: { radius: 50 },
|
||||
onComplete: (event) => {
|
||||
if (event && event.loadingStatus == 0) {
|
||||
this.render_success = JSON.stringify(Date.now())
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
Row() {
|
||||
Button($r('app.string.net_load_failed'))
|
||||
.fontSize(13)
|
||||
.onClick(() => {
|
||||
this.destroy();
|
||||
this.imageKnifeOption = new ImageKnifeOption({
|
||||
loadSrc: "https://img-blog.csdn.net/20140514114039140",
|
||||
objectFit: ImageFit.Contain,
|
||||
onLoadListener: {
|
||||
onLoadStart: (data) => {
|
||||
this.startCallBackData = JSON.stringify(data);
|
||||
},
|
||||
onLoadFailed: (res, err) => {
|
||||
this.failedBackData = res + ";" + JSON.stringify(err);
|
||||
},
|
||||
onLoadSuccess: (data, imageData) => {
|
||||
this.successBackData = JSON.stringify(imageData);
|
||||
},
|
||||
onLoadCancel: (res, cel) => {
|
||||
this.cancelBackData = res + ";" + JSON.stringify(cel);
|
||||
}
|
||||
},
|
||||
border: { radius: 50 },
|
||||
onComplete: (event) => {
|
||||
if (event && event.loadingStatus == 0) {
|
||||
this.render_success = JSON.stringify(Date.now())
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
Button($r('app.string.local_load_failed'))
|
||||
.fontSize(13)
|
||||
.onClick(() => {
|
||||
this.destroy();
|
||||
this.imageKnifeOption = new ImageKnifeOption({
|
||||
loadSrc: 'abd',
|
||||
objectFit: ImageFit.Contain,
|
||||
onLoadListener: {
|
||||
onLoadStart: (data) => {
|
||||
this.startCallBackData = JSON.stringify(data);
|
||||
},
|
||||
onLoadFailed: (res, err) => {
|
||||
this.failedBackData = res + ";" + JSON.stringify(err);
|
||||
},
|
||||
onLoadSuccess: (data, imageData) => {
|
||||
let suc = imageData;
|
||||
suc.source = ""
|
||||
this.successBackData = JSON.stringify(suc);
|
||||
},
|
||||
onLoadCancel: (res, cel) => {
|
||||
this.cancelBackData = res + ";" + JSON.stringify(cel);
|
||||
}
|
||||
},
|
||||
border: { radius: 50 },
|
||||
onComplete: (event) => {
|
||||
if (event && event.loadingStatus == 0) {
|
||||
this.render_success = JSON.stringify(Date.now())
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
Button($r('app.string.share_load_failed'))
|
||||
.fontSize(13)
|
||||
.onClick(() => {
|
||||
this.destroy();
|
||||
this.imageKnifeOption = new ImageKnifeOption({
|
||||
loadSrc: 'datashare://ssas',
|
||||
objectFit: ImageFit.Contain,
|
||||
onLoadListener: {
|
||||
onLoadStart: (data) => {
|
||||
this.startCallBackData = JSON.stringify(data);
|
||||
},
|
||||
onLoadFailed: (res, err) => {
|
||||
this.failedBackData = res + ";" + JSON.stringify(err);
|
||||
},
|
||||
onLoadSuccess: (data, imageData) => {
|
||||
this.successBackData = JSON.stringify(imageData);
|
||||
},
|
||||
onLoadCancel: (res, cel) => {
|
||||
this.cancelBackData = res + ";" + JSON.stringify(cel);
|
||||
}
|
||||
},
|
||||
border: { radius: 50 },
|
||||
onComplete: (event) => {
|
||||
if (event && event.loadingStatus == 0) {
|
||||
this.render_success = JSON.stringify(Date.now())
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
Button($r('app.string.test_cancel_callback_btn'))
|
||||
.fontSize(13)
|
||||
.onClick(() => {
|
||||
this.destroy();
|
||||
this.imageKnifeOption = new ImageKnifeOption({
|
||||
loadSrc: "https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/bf/v3/lSjrRwFcS-ez6jp1ALSQFg/0n7R7XinSPyrYLqDu_1dfw.jpg",
|
||||
objectFit: ImageFit.Contain,
|
||||
onLoadListener: {
|
||||
onLoadStart: (data) => {
|
||||
this.startCallBackData = JSON.stringify(data);
|
||||
this.showChild = false;
|
||||
},
|
||||
onLoadFailed: (res, err) => {
|
||||
this.failedBackData = res + ";" + JSON.stringify(err);
|
||||
},
|
||||
onLoadSuccess: (data, imageData) => {
|
||||
this.successBackData = JSON.stringify(imageData);
|
||||
},
|
||||
onLoadCancel: (res, cel) => {
|
||||
this.cancelBackData = res + ";" + JSON.stringify(cel);
|
||||
}
|
||||
},
|
||||
border: { radius: 50 },
|
||||
onComplete: (event) => {
|
||||
if (event && event.loadingStatus == 0) {
|
||||
this.render_success = JSON.stringify(Date.now())
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
Button($r('app.string.list_pic'))
|
||||
.fontSize(13)
|
||||
.onClick(() => {
|
||||
router.push({
|
||||
url: 'pages/TestListImageKnifeCallbackPage',
|
||||
});
|
||||
})
|
||||
if (this.showChild) {
|
||||
ImageKnifeComponent(
|
||||
{ imageKnifeOption: this.imageKnifeOption })
|
||||
.height(this.currentHeight)
|
||||
.width(this.currentWidth)
|
||||
.margin({ top: 20, bottom: 20 })
|
||||
|
||||
}
|
||||
}
|
||||
.width('100%')
|
||||
}
|
||||
}
|
||||
|
||||
destroy() {
|
||||
this.startCallBackData = "";
|
||||
this.successBackData = "";
|
||||
this.failedBackData = "";
|
||||
this.cancelBackData = "";
|
||||
this.render_success = "";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,101 @@
|
|||
/*
|
||||
* Copyright (C) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { ImageKnifeComponent, ImageKnifeOption } from '@ohos/imageknife';
|
||||
|
||||
class ArrayElement {
|
||||
src: string = "";
|
||||
w: number = 0;
|
||||
h: number = 0;
|
||||
}
|
||||
|
||||
@Entry
|
||||
@Component
|
||||
struct TestListImageKnifeCallbackPage {
|
||||
private wid: number = 200;
|
||||
private hig: number = 200;
|
||||
private dataArray: ESObject[] = [
|
||||
"https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/56/v3/8MdhfSsCSMKj4sA6okUWrg/5uBx56tLTUO3RYQl-E5JiQ.jpg",
|
||||
"https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/56/v3/8MdhfSsCSMKj4sA6okUWrg/5uBx56tLTUO3RYQl-E5JiQ.jpg",
|
||||
"https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658",
|
||||
"https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/78/v3/qQJpAtRGQe2e_VhbGHDgIw/b3zlit99S6GybD3XdNwqJw.jpg",
|
||||
"https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/55/v3/5DZ2LLqYSsK85-shqgLveQ/7ZXcyCWNTvOzQP5FFLBGkg.jpg",
|
||||
"https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/3e/v3/LqRoLI-PRSu9Nqa8KdJ-pQ/dSqskBpSR9eraAMn7NBdqA.jpg",
|
||||
"https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/25/v3/jgB2ekkTRX-3yTYZalnANQ/xff_x9cbSPqb7fbNwgJa7A.jpg",
|
||||
"https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/fb/v3/alXwXLHKSyCAIWt_ydgD2g/BCCuu25TREOitQxM7eYOEw.jpg",
|
||||
"https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/63/v3/qbe6NZkCQyGcITvdWoZBgg/Y-5U1z3GT_yaK8CBD3jkwg.jpg",
|
||||
"https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/16/v3/fm2tO4TsRH6mv_D_nSSd5w/FscLpLwQQ-KuV7oaprFK2Q.jpg",
|
||||
"https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/89/v3/UAUvtPHqRD-GWWANsEC57Q/zcRJCQebQ322Aby4jzmwmQ.jpg",
|
||||
"https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/30/v3/tUUzzx73R4yp8G--lMhuWQ/EBbcu_dLTT-Jj68XAh6mtA.jpg",
|
||||
"https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/76/v3/EyF6z4FISpCHhae38eEexw/OtyAiu-zSSevNQYvUdtVmA.jpg",
|
||||
"https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/37/v3/12rH1yiEQmK9wlOOcy5avQ/RzBXiEBRRqOC7LRkwNj6VA.jpg",
|
||||
"https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/9a/v3/TpRN4AIzRoyUXIqWdKoE0g/ShOnD_tfS46HDbpSWhbCkQ.jpg",
|
||||
"https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/03/v3/H3X17s8eTdS2w56JgbB5jQ/a45sT-j8Sbe8sSQXTzeYvQ.jpg",
|
||||
"https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/10/v3/qaEzwkU0QeKb1yehnP2Xig/q7fxAlgMQKup-HUBayRLGQ.jpg",
|
||||
"https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/96/v3/rMJJoAflTDSWa1z2pHs2wg/8dOqD0GlQBOCL5AvQok9FQ.jpg",
|
||||
"https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/ed/v3/KMO4D6D2QGuVOCLX4AhOFA/ef51xAaLQuK7BsnuD9abog.jpg",
|
||||
"https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/d9/v3/FSZH0aTdSqWxeAaxoPvi0g/RqxPxUCXQFiTMBfKTF9kkw.jpg",
|
||||
"https://hbimg.huabanimg.com/cc6af25f8d782d3cf3122bef4e61571378271145735e9-vEVggB",
|
||||
'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/bf/v3/lSjrRwFcS-ez6jp1ALSQFg/0n7R7XinSPyrYLqDu_1dfw.jpg',
|
||||
'https://img-blog.csdn.net/20140514114029140',
|
||||
'https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp',
|
||||
$r('app.media.pngSample'),
|
||||
$r('app.media.rabbit')
|
||||
]
|
||||
private data: Array<ArrayElement> = [];
|
||||
|
||||
aboutToAppear(): void {
|
||||
for (let i = 0; i < this.dataArray.length; i++) {
|
||||
let element: ArrayElement = {
|
||||
src: this.dataArray[i],
|
||||
w: this.wid -(i*5),
|
||||
h: this.hig -(i*5)
|
||||
}
|
||||
this.data.push(element);
|
||||
}
|
||||
}
|
||||
|
||||
build() {
|
||||
List({ space: 3 }) {
|
||||
ForEach(this.data, (item: ArrayElement) => {
|
||||
ListItem() {
|
||||
ImageKnifeComponent({
|
||||
imageKnifeOption: new ImageKnifeOption(
|
||||
{
|
||||
loadSrc: item.src,
|
||||
objectFit: ImageFit.Contain,
|
||||
onLoadListener: {
|
||||
onLoadStart: (data) => {
|
||||
console.log("listCache start:" + JSON.stringify(data))
|
||||
},
|
||||
onLoadFailed: (res, err) => {
|
||||
console.log("listCache onLoadFailed:res:" + res + ";" + JSON.stringify(err))
|
||||
},
|
||||
onLoadSuccess: (data, imageData) => {
|
||||
console.log("listCache onLoadSuccess:" + JSON.stringify(imageData))
|
||||
},
|
||||
onLoadCancel: (res, cel) => {
|
||||
console.log("listCache onLoadCancel:res:" + res + ";" + JSON.stringify(cel))
|
||||
}
|
||||
},
|
||||
border: { radius: 50 },
|
||||
}
|
||||
)
|
||||
}).height(item.w).width(item.h)
|
||||
}.width('100%')
|
||||
}, (item: ArrayElement,index) => (item.src+index))
|
||||
}.width('100%').height('100%')
|
||||
}
|
||||
}
|
|
@ -504,6 +504,10 @@
|
|||
"name": "test_cancel_callback_btn",
|
||||
"value": "test callback of cancel"
|
||||
},
|
||||
{
|
||||
"name": "test_callback",
|
||||
"value": "test callback data of load pic"
|
||||
},
|
||||
{
|
||||
"name": "memory",
|
||||
"value": "Memory"
|
||||
|
@ -511,6 +515,54 @@
|
|||
{
|
||||
"name": "disk",
|
||||
"value": "Disk"
|
||||
},
|
||||
{
|
||||
"name": "start_callback",
|
||||
"value": "startCallBack:%s"
|
||||
},
|
||||
{
|
||||
"name": "success_callback",
|
||||
"value": "successCallBack:%s"
|
||||
},
|
||||
{
|
||||
"name": "failed_callback",
|
||||
"value": "failedCallBack:%s"
|
||||
},
|
||||
{
|
||||
"name": "cancel_callback",
|
||||
"value": "cancelCallBack:%s"
|
||||
},
|
||||
{
|
||||
"name": "render_success",
|
||||
"value": "render success time point:%s"
|
||||
},
|
||||
{
|
||||
"name": "gif",
|
||||
"value": "gif"
|
||||
},
|
||||
{
|
||||
"name": "local_pic",
|
||||
"value": "local picture"
|
||||
},
|
||||
{
|
||||
"name": "share_pic",
|
||||
"value": "share picture"
|
||||
},
|
||||
{
|
||||
"name": "net_load_failed",
|
||||
"value": "netWork load failed"
|
||||
},
|
||||
{
|
||||
"name": "local_load_failed",
|
||||
"value": "local load failed"
|
||||
},
|
||||
{
|
||||
"name": "share_load_failed",
|
||||
"value": "shared load failed"
|
||||
},
|
||||
{
|
||||
"name": "list_pic",
|
||||
"value": "load picture list"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -26,6 +26,8 @@
|
|||
"pages/DownSamplePage",
|
||||
"pages/TestCacheDataPage",
|
||||
"pages/TestChangeColorPage",
|
||||
"pages/TestLoadCancelListenerPage"
|
||||
"pages/TestLoadCancelListenerPage",
|
||||
"pages/TestImageKnifeCallbackPage",
|
||||
"pages/TestListImageKnifeCallbackPage"
|
||||
]
|
||||
}
|
|
@ -500,6 +500,10 @@
|
|||
"name": "test_cancel_callback_btn",
|
||||
"value": "测试加载取消回调接口"
|
||||
},
|
||||
{
|
||||
"name": "test_callback",
|
||||
"value": "测试图片加载回调数据"
|
||||
},
|
||||
{
|
||||
"name": "memory",
|
||||
"value": "内存"
|
||||
|
@ -507,6 +511,54 @@
|
|||
{
|
||||
"name": "disk",
|
||||
"value": "磁盘"
|
||||
},
|
||||
{
|
||||
"name": "start_callback",
|
||||
"value": "开始回调:%s"
|
||||
},
|
||||
{
|
||||
"name": "success_callback",
|
||||
"value": "成功回调:%s"
|
||||
},
|
||||
{
|
||||
"name": "failed_callback",
|
||||
"value": "失败回调:%s"
|
||||
},
|
||||
{
|
||||
"name": "cancel_callback",
|
||||
"value": "取消回调:%s"
|
||||
},
|
||||
{
|
||||
"name": "render_success",
|
||||
"value": "渲染成功时间点:%s"
|
||||
},
|
||||
{
|
||||
"name": "gif",
|
||||
"value": "gif"
|
||||
},
|
||||
{
|
||||
"name": "local_pic",
|
||||
"value": "本地图片"
|
||||
},
|
||||
{
|
||||
"name": "share_pic",
|
||||
"value": "共享图片"
|
||||
},
|
||||
{
|
||||
"name": "net_load_failed",
|
||||
"value": "网络加载失败"
|
||||
},
|
||||
{
|
||||
"name": "local_load_failed",
|
||||
"value": "本地加载失败"
|
||||
},
|
||||
{
|
||||
"name": "share_load_failed",
|
||||
"value": "共享图片加载失败"
|
||||
},
|
||||
{
|
||||
"name": "list_pic",
|
||||
"value": "加载图片列表"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -20,6 +20,7 @@ import ImageKnifeTest from './ImageKnife.test';
|
|||
import Transform from './transform.test';
|
||||
import SamplingTest from './SamplingTest.test';
|
||||
import imageFormatAndSize from './imageFormatAndSize.test'
|
||||
import loadCallBackData from './loadCallBackData.test'
|
||||
|
||||
export default function testsuite() {
|
||||
MemoryLruCacheTest();
|
||||
|
@ -30,4 +31,5 @@ export default function testsuite() {
|
|||
Transform();
|
||||
SamplingTest()
|
||||
imageFormatAndSize();
|
||||
loadCallBackData();
|
||||
}
|
|
@ -0,0 +1,117 @@
|
|||
/*
|
||||
* Copyright (C) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium';
|
||||
import {
|
||||
ImageKnifeOption,
|
||||
ImageKnife,
|
||||
ImageKnifeRequest,
|
||||
ImageKnifeRequestSource,
|
||||
CacheStrategy
|
||||
} from "@ohos/imageknife"
|
||||
import { common } from '@kit.AbilityKit';
|
||||
|
||||
export default function loadCallBackData() {
|
||||
describe('loadCallBackData', () => {
|
||||
// Defines a test suite. Two parameters are supported: test suite name and test suite function.
|
||||
beforeAll(() => {
|
||||
// Presets an action, which is performed only once before all test cases of the test suite start.
|
||||
// This API supports only one parameter: preset action function.
|
||||
});
|
||||
beforeEach(() => {
|
||||
// Presets an action, which is performed before each unit test case starts.
|
||||
// The number of execution times is the same as the number of test cases defined by **it**.
|
||||
// This API supports only one parameter: preset action function.
|
||||
});
|
||||
afterEach(() => {
|
||||
// Presets a clear action, which is performed after each unit test case ends.
|
||||
// The number of execution times is the same as the number of test cases defined by **it**.
|
||||
// This API supports only one parameter: clear action function.
|
||||
});
|
||||
afterAll(() => {
|
||||
// Presets a clear action, which is performed after all test cases of the test suite end.
|
||||
// This API supports only one parameter: clear action function.
|
||||
});
|
||||
it('startAndSuccess-CallBack', 0, async () => {
|
||||
let startCallBack: ESObject = undefined;
|
||||
let successCallBack: ESObject = undefined;
|
||||
let url: string =
|
||||
"https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/63/v3/qbe6NZkCQyGcITvdWoZBgg/Y-5U1z3GT_yaK8CBD3jkwg.jpg"
|
||||
let imageKnifeOption: ImageKnifeOption = new ImageKnifeOption({
|
||||
loadSrc: url,
|
||||
})
|
||||
await new Promise<string>((resolve, reject) => {
|
||||
imageKnifeOption.onLoadListener = {
|
||||
onLoadStart: (data) => {
|
||||
startCallBack = data;
|
||||
},
|
||||
onLoadSuccess: (data, imageknifeData) => {
|
||||
successCallBack = imageknifeData;
|
||||
resolve("")
|
||||
},
|
||||
onLoadFailed(err) {
|
||||
reject(err)
|
||||
}
|
||||
}
|
||||
let request = new ImageKnifeRequest(
|
||||
imageKnifeOption,
|
||||
imageKnifeOption.context !== undefined ? imageKnifeOption.context : getContext() as common.UIAbilityContext,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
{
|
||||
showPixelMap(version: number, pixelMap: PixelMap | string) {
|
||||
}
|
||||
}
|
||||
)
|
||||
ImageKnife.getInstance().execute(request);
|
||||
})
|
||||
expect(startCallBack != undefined).assertTrue();
|
||||
expect(successCallBack != undefined).assertTrue();
|
||||
});
|
||||
it('failed-CallBack', 0, async () => {
|
||||
let failedCallBack: ESObject = undefined;
|
||||
let url: string =
|
||||
"https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/163/v3/qbe6NZkCQyGcITvdWoZBgg/Y-5U1z3GT_yaK8CBD3jkwg.jpg"
|
||||
let imageKnifeOption: ImageKnifeOption = new ImageKnifeOption({
|
||||
loadSrc: url,
|
||||
})
|
||||
await new Promise<string>((resolve, reject) => {
|
||||
imageKnifeOption.onLoadListener = {
|
||||
onLoadStart: (data) => {
|
||||
},
|
||||
onLoadSuccess: (data, imageknifeData) => {
|
||||
},
|
||||
onLoadFailed(res,err) {
|
||||
failedCallBack = err;
|
||||
resolve(res)
|
||||
}
|
||||
}
|
||||
let request = new ImageKnifeRequest(
|
||||
imageKnifeOption,
|
||||
imageKnifeOption.context !== undefined ? imageKnifeOption.context : getContext() as common.UIAbilityContext,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
{
|
||||
showPixelMap(version: number, pixelMap: PixelMap | string) {
|
||||
}
|
||||
}
|
||||
)
|
||||
ImageKnife.getInstance().execute(request);
|
||||
})
|
||||
expect(failedCallBack != undefined).assertTrue();
|
||||
});
|
||||
});
|
||||
}
|
|
@ -1,6 +0,0 @@
|
|||
{
|
||||
"lockfileVersion": 3,
|
||||
"ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.",
|
||||
"specifiers": {},
|
||||
"packages": {}
|
||||
}
|
|
@ -327,7 +327,7 @@ export class ImageKnife {
|
|||
* @param cacheType
|
||||
* @returns
|
||||
*/
|
||||
getCurrentPicturesNum(cacheType: CacheStrategy): number | undefined {
|
||||
getCurrentPicturesNum(cacheType?: CacheStrategy): number | undefined {
|
||||
if (cacheType == undefined || cacheType == CacheStrategy.Default) {
|
||||
cacheType = CacheStrategy.Memory;
|
||||
}
|
||||
|
@ -347,7 +347,7 @@ export class ImageKnife {
|
|||
* @param cacheType
|
||||
* @returns
|
||||
*/
|
||||
getCurrentCacheSize(cacheType: CacheStrategy): number | undefined {
|
||||
getCurrentCacheSize(cacheType?: CacheStrategy): number | undefined {
|
||||
if (cacheType == undefined || cacheType == CacheStrategy.Default) {
|
||||
cacheType = CacheStrategy.Memory;
|
||||
}
|
||||
|
|
|
@ -19,10 +19,10 @@ import List from '@ohos.util.List';
|
|||
import LightWeightMap from '@ohos.util.LightWeightMap';
|
||||
import { LogUtil } from './utils/LogUtil';
|
||||
import { ImageKnife } from './ImageKnife';
|
||||
import { ImageKnifeData, CacheStrategy } from './model/ImageKnifeData';
|
||||
import { ImageKnifeData, CacheStrategy, ErrorInfo, TimeInfo } from './model/ImageKnifeData';
|
||||
import image from '@ohos.multimedia.image';
|
||||
import emitter from '@ohos.events.emitter';
|
||||
import { Constants } from './utils/Constants';
|
||||
import { Constants, LoadPhase, LoadPixelMapCode } from './utils/Constants';
|
||||
import taskpool from '@ohos.taskpool';
|
||||
import { FileTypeUtil } from './utils/FileTypeUtil';
|
||||
import { IEngineKey } from './key/IEngineKey';
|
||||
|
@ -47,9 +47,19 @@ export class ImageKnifeDispatcher {
|
|||
executingJobMap: LightWeightMap<string, List<ImageKnifeRequestWithSource>> = new LightWeightMap();
|
||||
// 开发者可配置全局缓存
|
||||
private engineKey: IEngineKey = new DefaultEngineKey();
|
||||
//图片加载信息回调数据
|
||||
private callBackData: ImageKnifeData = {
|
||||
source: "",
|
||||
imageWidth: 0,
|
||||
imageHeight: 0,
|
||||
};
|
||||
private callBackTimeInfo: TimeInfo = {};
|
||||
|
||||
showFromMemomry(request: ImageKnifeRequest, imageSrc: string | PixelMap | Resource, requestSource: ImageKnifeRequestSource,isAnimator?: boolean): boolean {
|
||||
LogUtil.log("ImageKnife_DataTime_showFromMemomry.start:" + request.imageKnifeOption.loadSrc + "requestSource=" + requestSource + " isAnimator=" + isAnimator)
|
||||
showFromMemomry(request: ImageKnifeRequest, imageSrc: string | PixelMap | Resource,
|
||||
requestSource: ImageKnifeRequestSource, isAnimator?: boolean): boolean {
|
||||
LogUtil.log("ImageKnife_DataTime_showFromMemomry.start:" + request.imageKnifeOption.loadSrc + "requestSource=" +
|
||||
requestSource + " isAnimator=" + isAnimator)
|
||||
let memoryCheckStartTime = Date.now();
|
||||
let memoryCache: ImageKnifeData | undefined;
|
||||
if ((typeof (request.imageKnifeOption.loadSrc as image.PixelMap).isEditable) == 'boolean') {
|
||||
memoryCache = {
|
||||
|
@ -59,26 +69,39 @@ export class ImageKnifeDispatcher {
|
|||
}
|
||||
} else {
|
||||
memoryCache = ImageKnife.getInstance()
|
||||
.loadFromMemoryCache(this.engineKey.generateMemoryKey(imageSrc, requestSource, request.imageKnifeOption,isAnimator));
|
||||
.loadFromMemoryCache(this.engineKey.generateMemoryKey(imageSrc, requestSource, request.imageKnifeOption,
|
||||
isAnimator));
|
||||
}
|
||||
//记录ImageKnifeRequestSource.SRC 开始内存检查的时间点
|
||||
if (requestSource == ImageKnifeRequestSource.SRC) {
|
||||
this.callBackTimeInfo.memoryCheckStartTime = memoryCheckStartTime;
|
||||
this.callBackTimeInfo.memoryCheckEndTime = Date.now();
|
||||
this.callBackData.timeInfo = this.callBackTimeInfo;
|
||||
//设置请求结束的时间点
|
||||
if (memoryCache !== undefined) {
|
||||
this.callBackData.timeInfo.requestEndTime = Date.now();
|
||||
}
|
||||
}
|
||||
|
||||
if (memoryCache !== undefined) {
|
||||
// 画主图
|
||||
if (request.requestState === ImageKnifeRequestState.PROGRESS) {
|
||||
// 回调请求开始
|
||||
if (requestSource === ImageKnifeRequestSource.SRC && request.imageKnifeOption.onLoadListener?.onLoadStart !== undefined) {
|
||||
request.imageKnifeOption.onLoadListener.onLoadStart()
|
||||
if (requestSource === ImageKnifeRequestSource.SRC &&
|
||||
request.imageKnifeOption.onLoadListener?.onLoadStart !== undefined) {
|
||||
request.imageKnifeOption.onLoadListener.onLoadStart(this.callBackData)
|
||||
LogUtil.log("ImageKnife_DataTime_MemoryCache_onLoadStart:" + request.imageKnifeOption.loadSrc)
|
||||
}
|
||||
LogUtil.log("ImageKnife_DataTime_MemoryCache_showPixelMap.start:" + request.imageKnifeOption.loadSrc)
|
||||
request.ImageKnifeRequestCallback?.showPixelMap(request.componentVersion, memoryCache.source, requestSource,memoryCache.imageAnimator)
|
||||
request.ImageKnifeRequestCallback?.showPixelMap(request.componentVersion, memoryCache.source, requestSource,
|
||||
memoryCache.imageAnimator)
|
||||
LogUtil.log("ImageKnife_DataTime_MemoryCache_showPixelMap.end:" + request.imageKnifeOption.loadSrc)
|
||||
|
||||
if (requestSource == ImageKnifeRequestSource.SRC) {
|
||||
request.requestState = ImageKnifeRequestState.COMPLETE
|
||||
// 回调请求开结束
|
||||
if (request.imageKnifeOption.onLoadListener?.onLoadSuccess !== undefined) {
|
||||
request.imageKnifeOption.onLoadListener.onLoadSuccess(memoryCache.source,memoryCache)
|
||||
this.copyCallBackData(this.callBackData, memoryCache);
|
||||
request.imageKnifeOption.onLoadListener.onLoadSuccess(memoryCache.source, memoryCache)
|
||||
LogUtil.log("ImageKnife_DataTime_MemoryCache_onLoadSuccess:" + request.imageKnifeOption.loadSrc)
|
||||
}
|
||||
} else if (requestSource == ImageKnifeRequestSource.ERROR_HOLDER) {
|
||||
|
@ -92,15 +115,53 @@ export class ImageKnifeDispatcher {
|
|||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置进入线程前加载图片的callBack信息
|
||||
* @param beforeCallData
|
||||
* @param afterCallData
|
||||
*/
|
||||
private copyCallBackData(beforeCallData: ImageKnifeData | undefined, afterCallData: ImageKnifeData) {
|
||||
if (!beforeCallData || !afterCallData) {
|
||||
return;
|
||||
}
|
||||
//设置组件宽高
|
||||
afterCallData.componentWidth = beforeCallData.componentWidth;
|
||||
afterCallData.componentHeight = beforeCallData.componentWidth;
|
||||
//设置图片开始加载时间及其缓存检查时间点
|
||||
if (beforeCallData.timeInfo) {
|
||||
if (afterCallData.timeInfo) {
|
||||
afterCallData.timeInfo.requestStartTime = beforeCallData.timeInfo.requestStartTime;
|
||||
afterCallData.timeInfo.memoryCheckStartTime = beforeCallData.timeInfo.memoryCheckStartTime;
|
||||
afterCallData.timeInfo.memoryCheckEndTime = beforeCallData.timeInfo.memoryCheckEndTime;
|
||||
} else {
|
||||
afterCallData.timeInfo = beforeCallData.timeInfo;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enqueue(request: ImageKnifeRequest,isAnimator?: boolean): void {
|
||||
|
||||
enqueue(request: ImageKnifeRequest, isAnimator?: boolean): void {
|
||||
|
||||
if (typeof request.imageKnifeOption.loadSrc == "string") {
|
||||
this.callBackData.source = request.imageKnifeOption.loadSrc;
|
||||
}
|
||||
this.callBackData.componentWidth = request.componentWidth;
|
||||
this.callBackData.componentHeight = request.componentHeight;
|
||||
this.callBackTimeInfo.requestStartTime = Date.now();
|
||||
//1.内存有的话直接渲染
|
||||
if (this.showFromMemomry(request, request.imageKnifeOption.loadSrc, ImageKnifeRequestSource.SRC,isAnimator)) {
|
||||
if (this.showFromMemomry(request, request.imageKnifeOption.loadSrc, ImageKnifeRequestSource.SRC, isAnimator)) {
|
||||
return
|
||||
}
|
||||
|
||||
//这里对this.callBackData要进行深拷贝
|
||||
let call = JSON.parse(JSON.stringify(this.callBackData)) as ImageKnifeData;
|
||||
|
||||
//跟隨請求保存回調信息點
|
||||
request.setImageKnifeData(call);
|
||||
// 2.内存获取占位图
|
||||
if (request.imageKnifeOption.placeholderSrc !== undefined) {
|
||||
if (this.showFromMemomry(request, request.imageKnifeOption.placeholderSrc, ImageKnifeRequestSource.PLACE_HOLDER)) {
|
||||
if (this.showFromMemomry(request, request.imageKnifeOption.placeholderSrc,
|
||||
ImageKnifeRequestSource.PLACE_HOLDER)) {
|
||||
request.drawPlayHolderSuccess = true
|
||||
}
|
||||
}
|
||||
|
@ -109,10 +170,10 @@ export class ImageKnifeDispatcher {
|
|||
this.jobQueue.add(request)
|
||||
return
|
||||
}
|
||||
this.executeJob(request,isAnimator)
|
||||
this.executeJob(request, isAnimator)
|
||||
}
|
||||
|
||||
executeJob(request: ImageKnifeRequest,isAnimator?: boolean): void {
|
||||
executeJob(request: ImageKnifeRequest, isAnimator?: boolean): void {
|
||||
LogUtil.log("ImageKnife_DataTime_executeJob.start:" + request.imageKnifeOption.loadSrc)
|
||||
// 加载占位符
|
||||
if (request.imageKnifeOption.placeholderSrc !== undefined && request.drawPlayHolderSuccess == false) {
|
||||
|
@ -120,16 +181,18 @@ export class ImageKnifeDispatcher {
|
|||
}
|
||||
|
||||
// 加载主图
|
||||
this.getAndShowImage(request, request.imageKnifeOption.loadSrc, ImageKnifeRequestSource.SRC,isAnimator)
|
||||
this.getAndShowImage(request, request.imageKnifeOption.loadSrc, ImageKnifeRequestSource.SRC, isAnimator)
|
||||
LogUtil.log("ImageKnife_DataTime_executeJob.end:" + request.imageKnifeOption.loadSrc)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取和显示图片
|
||||
*/
|
||||
getAndShowImage(currentRequest: ImageKnifeRequest, imageSrc: string | PixelMap | Resource, requestSource: ImageKnifeRequestSource,isAnimator?: boolean): void {
|
||||
getAndShowImage(currentRequest: ImageKnifeRequest, imageSrc: string | PixelMap | Resource,
|
||||
requestSource: ImageKnifeRequestSource, isAnimator?: boolean): void {
|
||||
LogUtil.log("ImageKnife_DataTime_getAndShowImage.start:" + currentRequest.imageKnifeOption.loadSrc)
|
||||
let memoryKey: string = this.engineKey.generateMemoryKey(imageSrc, requestSource, currentRequest.imageKnifeOption,isAnimator)
|
||||
let memoryKey: string =
|
||||
this.engineKey.generateMemoryKey(imageSrc, requestSource, currentRequest.imageKnifeOption, isAnimator)
|
||||
let requestList: List<ImageKnifeRequestWithSource> | undefined = this.executingJobMap.get(memoryKey)
|
||||
if (requestList == undefined) {
|
||||
requestList = new List()
|
||||
|
@ -140,28 +203,29 @@ export class ImageKnifeDispatcher {
|
|||
return
|
||||
}
|
||||
|
||||
let isWatchProgress : boolean = false
|
||||
|
||||
let isWatchProgress: boolean = false
|
||||
// 回调请求开始
|
||||
requestList.forEach((requestWithSource: ImageKnifeRequestWithSource) => {
|
||||
if (requestWithSource.source === ImageKnifeRequestSource.SRC && requestWithSource.request.imageKnifeOption.onLoadListener?.onLoadStart !== undefined) {
|
||||
requestWithSource.request.imageKnifeOption.onLoadListener?.onLoadStart()
|
||||
if (requestWithSource.source === ImageKnifeRequestSource.SRC &&
|
||||
requestWithSource.request.imageKnifeOption.onLoadListener?.onLoadStart !== undefined) {
|
||||
requestWithSource.request.imageKnifeOption.onLoadListener?.onLoadStart(currentRequest.getImageKnifeData())
|
||||
LogUtil.log("ImageKnife_DataTime_getAndShowImage_onLoadStart:" + currentRequest.imageKnifeOption.loadSrc)
|
||||
}
|
||||
if (requestWithSource.request.imageKnifeOption.progressListener !== undefined && requestWithSource.source === ImageKnifeRequestSource.SRC) {
|
||||
if (requestWithSource.request.imageKnifeOption.progressListener !== undefined &&
|
||||
requestWithSource.source === ImageKnifeRequestSource.SRC) {
|
||||
isWatchProgress = true
|
||||
}
|
||||
});
|
||||
let src: string | number = ""
|
||||
let moduleName: string = ""
|
||||
let resName: string = ""
|
||||
if((imageSrc as Resource).id != undefined) {
|
||||
if ((imageSrc as Resource).id != undefined) {
|
||||
moduleName = (imageSrc as Resource).moduleName
|
||||
src = (imageSrc as Resource).id
|
||||
if(src == -1) {
|
||||
if (src == -1) {
|
||||
resName = (imageSrc as Resource).params![0]
|
||||
}
|
||||
} else if(typeof imageSrc == "string") {
|
||||
} else if (typeof imageSrc == "string") {
|
||||
src = imageSrc
|
||||
}
|
||||
let request: RequestJobRequest = {
|
||||
|
@ -169,20 +233,21 @@ export class ImageKnifeDispatcher {
|
|||
src: src,
|
||||
headers: currentRequest.imageKnifeOption.headerOption,
|
||||
allHeaders: currentRequest.headers,
|
||||
componentWidth:currentRequest.componentWidth,
|
||||
componentHeight:currentRequest.componentHeight,
|
||||
componentWidth: currentRequest.componentWidth,
|
||||
componentHeight: currentRequest.componentHeight,
|
||||
customGetImage: currentRequest.imageKnifeOption.customGetImage,
|
||||
onlyRetrieveFromCache: currentRequest.imageKnifeOption.onlyRetrieveFromCache,
|
||||
transformation: currentRequest.imageKnifeOption.transformation,
|
||||
writeCacheStrategy: ImageKnife.getInstance()
|
||||
.isFileCacheInit() ? currentRequest.imageKnifeOption.writeCacheStrategy : CacheStrategy.Memory, // 未初始化文件缓存时,不写文件缓存
|
||||
.isFileCacheInit() ? currentRequest.imageKnifeOption.writeCacheStrategy :
|
||||
CacheStrategy.Memory, // 未初始化文件缓存时,不写文件缓存
|
||||
engineKey: this.engineKey,
|
||||
signature: currentRequest.imageKnifeOption.signature,
|
||||
requestSource: requestSource,
|
||||
isWatchProgress: isWatchProgress,
|
||||
memoryKey: memoryKey,
|
||||
fileCacheFolder: ImageKnife.getInstance().getFileCache()?.getCacheFolder(),
|
||||
isAnimator:isAnimator,
|
||||
isAnimator: isAnimator,
|
||||
moduleName: moduleName == "" ? undefined : moduleName,
|
||||
resName: resName == "" ? undefined : resName,
|
||||
targetWidth: currentRequest.componentWidth,
|
||||
|
@ -190,43 +255,46 @@ export class ImageKnifeDispatcher {
|
|||
downsampType: currentRequest.imageKnifeOption.downsampleOf==undefined?DownsampleStrategy.NONE:currentRequest.imageKnifeOption.downsampleOf,
|
||||
}
|
||||
|
||||
if(request.customGetImage == undefined) {
|
||||
if (request.customGetImage == undefined) {
|
||||
request.customGetImage = ImageKnife.getInstance().getCustomGetImage()
|
||||
}
|
||||
if (ImageKnife.getInstance().isRequestInSubThread){
|
||||
if (ImageKnife.getInstance().isRequestInSubThread) {
|
||||
// 启动线程下载和解码主图
|
||||
LogUtil.log("ImageKnife_DataTime_getAndShowImage_Task.start:" + currentRequest.imageKnifeOption.loadSrc)
|
||||
let task = new taskpool.Task(requestJob, request)
|
||||
LogUtil.log("ImageKnife_DataTime_getAndShowImage_Task.end:" + currentRequest.imageKnifeOption.loadSrc)
|
||||
if (isWatchProgress){
|
||||
if (isWatchProgress) {
|
||||
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(subthread):" + currentRequest.imageKnifeOption.loadSrc)
|
||||
LogUtil.log("ImageKnife_DataTime_getAndShowImage_execute.start(subthread):" +
|
||||
currentRequest.imageKnifeOption.loadSrc)
|
||||
taskpool.execute(task).then((res: Object) => {
|
||||
this.doTaskCallback(res as RequestJobResult | undefined, requestList!, currentRequest, memoryKey, imageSrc, requestSource,isAnimator);
|
||||
if (isWatchProgress){
|
||||
this.doTaskCallback(res as RequestJobResult | undefined, requestList!, currentRequest, memoryKey, imageSrc,
|
||||
requestSource, isAnimator);
|
||||
if (isWatchProgress) {
|
||||
emitter.off(Constants.PROGRESS_EMITTER + memoryKey)
|
||||
}
|
||||
LogUtil.log("ImageKnife_DataTime_getAndShowImage_execute.end:"+currentRequest.imageKnifeOption.loadSrc)
|
||||
LogUtil.log("ImageKnife_DataTime_getAndShowImage.end:"+currentRequest.imageKnifeOption.loadSrc)
|
||||
LogUtil.log("ImageKnife_DataTime_getAndShowImage_execute.end:" + currentRequest.imageKnifeOption.loadSrc)
|
||||
LogUtil.log("ImageKnife_DataTime_getAndShowImage.end:" + currentRequest.imageKnifeOption.loadSrc)
|
||||
}).catch((err: BusinessError) => {
|
||||
LogUtil.error("Fail to 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)
|
||||
}
|
||||
this.executingJobMap.remove(memoryKey);
|
||||
this.dispatchNextJob();
|
||||
})
|
||||
} else { //主线程请求
|
||||
LogUtil.log("ImageKnife_DataTime_getAndShowImage_execute.start(mainthread):" + currentRequest.imageKnifeOption.loadSrc)
|
||||
LogUtil.log("ImageKnife_DataTime_getAndShowImage_execute.start(mainthread):" +
|
||||
currentRequest.imageKnifeOption.loadSrc)
|
||||
requestJob(request, requestList).then((res: RequestJobResult | undefined) => {
|
||||
this.doTaskCallback(res, requestList!, currentRequest, memoryKey, imageSrc, requestSource,isAnimator);
|
||||
LogUtil.log("ImageKnife_DataTime_getAndShowImage_execute.end:"+currentRequest.imageKnifeOption.loadSrc)
|
||||
LogUtil.log("ImageKnife_DataTime_getAndShowImage.end:"+currentRequest.imageKnifeOption.loadSrc)
|
||||
this.doTaskCallback(res, requestList!, currentRequest, memoryKey, imageSrc, requestSource, isAnimator);
|
||||
LogUtil.log("ImageKnife_DataTime_getAndShowImage_execute.end:" + currentRequest.imageKnifeOption.loadSrc)
|
||||
LogUtil.log("ImageKnife_DataTime_getAndShowImage.end:" + currentRequest.imageKnifeOption.loadSrc)
|
||||
}).catch((err: BusinessError) => {
|
||||
LogUtil.error("Fail to requestJob in main thread src=" + imageSrc + " err=" + err)
|
||||
LogUtil.log("ImageKnife_DataTime_getAndShowImage.end:" + currentRequest.imageKnifeOption.loadSrc)
|
||||
|
@ -241,31 +309,52 @@ export class ImageKnifeDispatcher {
|
|||
* @param requestList 请求列表
|
||||
* @param data 进度
|
||||
*/
|
||||
private progressCallBack(requestList:List<ImageKnifeRequestWithSource>, data: number) {
|
||||
private progressCallBack(requestList: List<ImageKnifeRequestWithSource>, data: number) {
|
||||
for (let i = 0; i < requestList.length; i++) {
|
||||
let requestWithSource:ImageKnifeRequestWithSource = requestList[i]
|
||||
if (requestWithSource.request.imageKnifeOption.progressListener !== undefined && requestWithSource.source === ImageKnifeRequestSource.SRC) {
|
||||
let requestWithSource: ImageKnifeRequestWithSource = requestList[i]
|
||||
if (requestWithSource.request.imageKnifeOption.progressListener !== undefined &&
|
||||
requestWithSource.source === ImageKnifeRequestSource.SRC) {
|
||||
requestWithSource.request.imageKnifeOption.progressListener(data)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private doTaskCallback(requestJobResult: RequestJobResult | undefined, requestList: List<ImageKnifeRequestWithSource> ,
|
||||
currentRequest: ImageKnifeRequest, memoryKey: string, imageSrc: string | PixelMap | Resource, requestSource: ImageKnifeRequestSource,isAnimator?: boolean):void {
|
||||
LogUtil.log("ImageKnife_DataTime_getAndShowImage_CallBack.start:"+currentRequest.imageKnifeOption.loadSrc)
|
||||
if (requestJobResult === undefined){
|
||||
private doTaskCallback(requestJobResult: RequestJobResult | undefined, requestList: List<ImageKnifeRequestWithSource>,
|
||||
currentRequest: ImageKnifeRequest, memoryKey: string, imageSrc: string | PixelMap | Resource,
|
||||
requestSource: ImageKnifeRequestSource, isAnimator?: boolean): void {
|
||||
LogUtil.log("ImageKnife_DataTime_getAndShowImage_CallBack.start:" + currentRequest.imageKnifeOption.loadSrc)
|
||||
if (requestJobResult === undefined) {
|
||||
return
|
||||
}
|
||||
//设置请求结束的时间
|
||||
if (requestJobResult.callBackData && requestJobResult.callBackData.timeInfo) {
|
||||
requestJobResult.callBackData.timeInfo.requestEndTime = Date.now();
|
||||
}
|
||||
|
||||
let pixelmap = requestJobResult.pixelMap;
|
||||
if (pixelmap === undefined) {
|
||||
LogUtil.log("ImageKnife_DataTime_getAndShowImage_CallBack.pixelmap undefined:"+currentRequest.imageKnifeOption.loadSrc)
|
||||
LogUtil.log("ImageKnife_DataTime_getAndShowImage_CallBack.pixelmap undefined:" +
|
||||
currentRequest.imageKnifeOption.loadSrc)
|
||||
requestList.forEach((requestWithSource: ImageKnifeRequestWithSource) => {
|
||||
|
||||
//设置失败回调的时间点
|
||||
if (requestJobResult.errorCallBackData && requestJobResult.errorCallBackData.timeInfo) {
|
||||
requestJobResult.errorCallBackData.timeInfo.requestEndTime = Date.now()
|
||||
let callBackData = requestWithSource.request.getImageKnifeData();
|
||||
if (callBackData && callBackData.timeInfo) {
|
||||
requestJobResult.errorCallBackData.timeInfo.requestStartTime = callBackData.timeInfo.requestStartTime;
|
||||
requestJobResult.errorCallBackData.timeInfo.memoryCheckStartTime =
|
||||
callBackData.timeInfo.memoryCheckStartTime;
|
||||
requestJobResult.errorCallBackData.timeInfo.memoryCheckEndTime = callBackData.timeInfo.memoryCheckEndTime;
|
||||
}
|
||||
}
|
||||
// 回调请求失败
|
||||
if (requestWithSource.source === ImageKnifeRequestSource.SRC &&
|
||||
requestWithSource.request.imageKnifeOption.onLoadListener?.onLoadFailed !== undefined &&
|
||||
requestJobResult.loadFail) {
|
||||
requestWithSource.request.imageKnifeOption.onLoadListener.onLoadFailed(requestJobResult.loadFail);
|
||||
LogUtil.log("ImageKnife_DataTime_getAndShowImage_onLoadFailed:"+currentRequest.imageKnifeOption.loadSrc)
|
||||
requestWithSource.request.imageKnifeOption.onLoadListener.onLoadFailed(requestJobResult.loadFail,
|
||||
requestJobResult.errorCallBackData);
|
||||
LogUtil.log("ImageKnife_DataTime_getAndShowImage_onLoadFailed:" + currentRequest.imageKnifeOption.loadSrc)
|
||||
}
|
||||
if (requestWithSource.source === ImageKnifeRequestSource.SRC &&
|
||||
requestWithSource.request.imageKnifeOption.errorholderSrc !== undefined) {
|
||||
|
@ -282,36 +371,57 @@ export class ImageKnifeDispatcher {
|
|||
return;
|
||||
}
|
||||
// 保存文件缓存
|
||||
if (requestJobResult.bufferSize > 0 && currentRequest.imageKnifeOption.writeCacheStrategy !== CacheStrategy.Memory) {
|
||||
LogUtil.log("ImageKnife_DataTime_getAndShowImage_saveWithoutWriteFile.start:"+currentRequest.imageKnifeOption.loadSrc)
|
||||
if (requestJobResult.bufferSize > 0 &&
|
||||
currentRequest.imageKnifeOption.writeCacheStrategy !== CacheStrategy.Memory) {
|
||||
LogUtil.log("ImageKnife_DataTime_getAndShowImage_saveWithoutWriteFile.start:" +
|
||||
currentRequest.imageKnifeOption.loadSrc)
|
||||
ImageKnife.getInstance().saveWithoutWriteFile(requestJobResult.fileKey, requestJobResult.bufferSize);
|
||||
LogUtil.log("ImageKnife_DataTime_getAndShowImage_saveWithoutWriteFile.end:"+currentRequest.imageKnifeOption.loadSrc)
|
||||
LogUtil.log("ImageKnife_DataTime_getAndShowImage_saveWithoutWriteFile.end:" +
|
||||
currentRequest.imageKnifeOption.loadSrc)
|
||||
}
|
||||
let imageKnifeData: ImageKnifeData;
|
||||
if (!requestJobResult.callBackData) {
|
||||
imageKnifeData = {
|
||||
source: pixelmap!,
|
||||
imageWidth: requestJobResult.size == undefined ? 0 : requestJobResult.size.width,
|
||||
imageHeight: requestJobResult.size == undefined ? 0 : requestJobResult.size.height,
|
||||
type: requestJobResult.type,
|
||||
};
|
||||
} else {
|
||||
imageKnifeData = requestJobResult.callBackData;
|
||||
imageKnifeData.source = pixelmap!;
|
||||
}
|
||||
|
||||
let ImageKnifeData: ImageKnifeData = {
|
||||
if (requestJobResult.pixelMapList != undefined) {
|
||||
let imageAnimator: Array<ImageFrameInfo> = []
|
||||
requestJobResult.pixelMapList.forEach((item, index) => {
|
||||
imageAnimator.push({
|
||||
src: requestJobResult.pixelMapList![index],
|
||||
duration: requestJobResult.delayList![index]
|
||||
})
|
||||
})
|
||||
imageKnifeData.imageAnimator = imageAnimator
|
||||
}
|
||||
//构建缓存保存的ImageKnifeData
|
||||
let saveCacheImageData: ImageKnifeData = {
|
||||
source: pixelmap!,
|
||||
imageWidth: requestJobResult.size == undefined ? 0 : requestJobResult.size.width,
|
||||
imageHeight: requestJobResult.size == undefined ? 0 : requestJobResult.size.height,
|
||||
type:requestJobResult.type
|
||||
};
|
||||
if(requestJobResult.pixelMapList != undefined) {
|
||||
let imageAnimator: Array<ImageFrameInfo> = []
|
||||
requestJobResult.pixelMapList.forEach((item,index)=>{
|
||||
imageAnimator.push({
|
||||
src:requestJobResult.pixelMapList![index],
|
||||
duration:requestJobResult.delayList![index]
|
||||
})
|
||||
})
|
||||
ImageKnifeData.imageAnimator = imageAnimator
|
||||
type: requestJobResult.type,
|
||||
imageAnimator: imageKnifeData.imageAnimator
|
||||
}
|
||||
// 保存内存缓存
|
||||
if (currentRequest.imageKnifeOption.writeCacheStrategy !== CacheStrategy.File) {
|
||||
LogUtil.log("ImageKnife_DataTime_getAndShowImage_saveMemoryCache.start:"+currentRequest.imageKnifeOption.loadSrc)
|
||||
LogUtil.log("ImageKnife_DataTime_getAndShowImage_saveMemoryCache.start:" +
|
||||
currentRequest.imageKnifeOption.loadSrc)
|
||||
ImageKnife.getInstance()
|
||||
.saveMemoryCache(this.engineKey.generateMemoryKey(imageSrc, requestSource, currentRequest.imageKnifeOption,isAnimator),
|
||||
ImageKnifeData);
|
||||
LogUtil.log("ImageKnife_DataTime_getAndShowImage_saveMemoryCache.end:"+currentRequest.imageKnifeOption.loadSrc)
|
||||
.saveMemoryCache(this.engineKey.generateMemoryKey(imageSrc, requestSource, currentRequest.imageKnifeOption,
|
||||
isAnimator),
|
||||
saveCacheImageData);
|
||||
LogUtil.log("ImageKnife_DataTime_getAndShowImage_saveMemoryCache.end:" + currentRequest.imageKnifeOption.loadSrc)
|
||||
}
|
||||
|
||||
|
||||
if (requestList !== undefined) {
|
||||
// key相同的request,一起绘制
|
||||
requestList.forEach((requestWithSource: ImageKnifeRequestWithSource) => {
|
||||
|
@ -321,10 +431,12 @@ export class ImageKnifeDispatcher {
|
|||
requestWithSource.source === ImageKnifeRequestSource.ERROR_HOLDER
|
||||
|| (requestWithSource.source === ImageKnifeRequestSource.PLACE_HOLDER &&
|
||||
requestWithSource.request.requestState === ImageKnifeRequestState.PROGRESS)) {
|
||||
LogUtil.log("ImageKnife_DataTime_getAndShowImage_showPixelMap.start:"+currentRequest.imageKnifeOption.loadSrc)
|
||||
LogUtil.log("ImageKnife_DataTime_getAndShowImage_showPixelMap.start:" +
|
||||
currentRequest.imageKnifeOption.loadSrc)
|
||||
requestWithSource.request.ImageKnifeRequestCallback.showPixelMap(requestWithSource.request.componentVersion,
|
||||
ImageKnifeData.source, requestWithSource.source,ImageKnifeData.imageAnimator);
|
||||
LogUtil.log("ImageKnife_DataTime_getAndShowImage_showPixelMap.end:"+currentRequest.imageKnifeOption.loadSrc)
|
||||
imageKnifeData.source, requestWithSource.source, imageKnifeData.imageAnimator);
|
||||
LogUtil.log("ImageKnife_DataTime_getAndShowImage_showPixelMap.end:" +
|
||||
currentRequest.imageKnifeOption.loadSrc)
|
||||
}
|
||||
|
||||
if (requestWithSource.source == ImageKnifeRequestSource.SRC) {
|
||||
|
@ -332,16 +444,38 @@ export class ImageKnifeDispatcher {
|
|||
if (requestWithSource.request.imageKnifeOption.onLoadListener &&
|
||||
requestWithSource.request.imageKnifeOption.onLoadListener.onLoadSuccess) {
|
||||
// 回调请求成功
|
||||
requestWithSource.request.imageKnifeOption.onLoadListener.onLoadSuccess(ImageKnifeData.source,ImageKnifeData);
|
||||
LogUtil.log("ImageKnife_DataTime_getAndShowImage_onLoadSuccess:"+currentRequest.imageKnifeOption.loadSrc)
|
||||
this.copyCallBackData(requestWithSource.request.getImageKnifeData(), imageKnifeData);
|
||||
requestWithSource.request.imageKnifeOption.onLoadListener.onLoadSuccess(imageKnifeData.source,
|
||||
imageKnifeData);
|
||||
LogUtil.log("ImageKnife_DataTime_getAndShowImage_onLoadSuccess:" +
|
||||
currentRequest.imageKnifeOption.loadSrc)
|
||||
}
|
||||
} else if (requestWithSource.source == ImageKnifeRequestSource.ERROR_HOLDER) {
|
||||
requestWithSource.request.requestState = ImageKnifeRequestState.ERROR;
|
||||
}
|
||||
} else {
|
||||
if (requestWithSource.source == ImageKnifeRequestSource.SRC && requestWithSource.request.imageKnifeOption.onLoadListener?.onLoadCancel) {
|
||||
// 回调请求成功
|
||||
requestWithSource.request.imageKnifeOption.onLoadListener.onLoadCancel("component has destroyed")
|
||||
if (requestWithSource.source == ImageKnifeRequestSource.SRC &&
|
||||
requestWithSource.request.imageKnifeOption.onLoadListener?.onLoadCancel) {
|
||||
// 回调请求取消
|
||||
//设置失败回调的时间点
|
||||
let callBackData = requestWithSource.request.getImageKnifeData();
|
||||
|
||||
if (requestJobResult.errorCallBackData && requestJobResult.errorCallBackData.timeInfo) {
|
||||
requestJobResult.errorCallBackData.timeInfo.requestCancelTime = Date.now();
|
||||
requestJobResult.errorCallBackData.timeInfo.requestEndTime = Date.now()
|
||||
requestJobResult.errorCallBackData.phase = LoadPhase.PHASE_WILL_SHOW;
|
||||
requestJobResult.errorCallBackData.code = LoadPixelMapCode.IMAGE_LOAD_CANCEL_FAILED_CODE;
|
||||
if (callBackData && callBackData.timeInfo) {
|
||||
requestJobResult.errorCallBackData.timeInfo.requestStartTime =
|
||||
callBackData.timeInfo.requestStartTime;
|
||||
requestJobResult.errorCallBackData.timeInfo.memoryCheckStartTime =
|
||||
callBackData.timeInfo.memoryCheckStartTime;
|
||||
requestJobResult.errorCallBackData.timeInfo.memoryCheckEndTime =
|
||||
callBackData.timeInfo.memoryCheckEndTime;
|
||||
}
|
||||
}
|
||||
requestWithSource.request.imageKnifeOption.onLoadListener.onLoadCancel("component has destroyed",
|
||||
requestJobResult.errorCallBackData)
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -351,7 +485,7 @@ export class ImageKnifeDispatcher {
|
|||
} else {
|
||||
LogUtil.log("error: no requestlist need to draw for key = " + memoryKey);
|
||||
}
|
||||
LogUtil.log("ImageKnife_DataTime_getAndShowImage_CallBack.end:"+currentRequest.imageKnifeOption.loadSrc)
|
||||
LogUtil.log("ImageKnife_DataTime_getAndShowImage_CallBack.end:" + currentRequest.imageKnifeOption.loadSrc)
|
||||
}
|
||||
|
||||
|
||||
|
@ -362,14 +496,32 @@ export class ImageKnifeDispatcher {
|
|||
if (request === undefined) {
|
||||
LogUtil.log("ImageKnife_DataTime_dispatchNextJob.end:no any job")
|
||||
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)
|
||||
LogUtil.log("ImageKnife_DataTime_dispatchNextJob.end executeJob:" + request.imageKnifeOption.loadSrc)
|
||||
break
|
||||
}else if (request.requestState == ImageKnifeRequestState.DESTROY && request.imageKnifeOption.onLoadListener?.onLoadCancel) {
|
||||
request.imageKnifeOption.onLoadListener.onLoadCancel("component has destroyed")
|
||||
} else if (request.requestState == ImageKnifeRequestState.DESTROY &&
|
||||
request.imageKnifeOption.onLoadListener?.onLoadCancel) {
|
||||
|
||||
//构建回调错误信息
|
||||
let callBackData = request.getImageKnifeData();
|
||||
let timeInfo: TimeInfo = {};
|
||||
timeInfo.requestCancelTime = Date.now();
|
||||
timeInfo.requestEndTime = Date.now()
|
||||
timeInfo.requestCancelTime = Date.now();
|
||||
if (callBackData && callBackData.timeInfo) {
|
||||
timeInfo.requestStartTime = callBackData.timeInfo.requestStartTime;
|
||||
timeInfo.memoryCheckStartTime = callBackData.timeInfo.memoryCheckStartTime;
|
||||
timeInfo.memoryCheckEndTime = callBackData.timeInfo.memoryCheckEndTime;
|
||||
}
|
||||
let errorInfo: ErrorInfo = {
|
||||
phase: LoadPhase.PHASE_THREAD_QUEUE,
|
||||
code: LoadPixelMapCode.IMAGE_LOAD_CANCEL_FAILED_CODE,
|
||||
timeInfo:timeInfo
|
||||
};
|
||||
|
||||
request.imageKnifeOption.onLoadListener.onLoadCancel("component has destroyed", errorInfo)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -396,43 +548,56 @@ export class ImageKnifeDispatcher {
|
|||
* @returns
|
||||
*/
|
||||
@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 + " requestSource=" + request.requestSource)
|
||||
let src = typeof request.src == "number" ? request.resName != undefined ? request.resName : request.src + "" : request.src
|
||||
let src =
|
||||
typeof request.src == "number" ? request.resName != undefined ? request.resName : request.src + "" : request.src
|
||||
// 生成文件缓存key
|
||||
let fileKey = request.engineKey.generateFileKey(src, request.signature, request.isAnimator)
|
||||
|
||||
//定义加载信息回调数据
|
||||
let callBackData: ImageKnifeData = { source: "", imageWidth: 0, imageHeight: 0 };
|
||||
//定义图片各个阶段错误信息
|
||||
let errorCallBackData: ErrorInfo = { code: 0, phase: LoadPhase.PHASE_LOAD }
|
||||
|
||||
//获取图片资源
|
||||
let resBuf: ArrayBuffer
|
||||
try {
|
||||
LogUtil.log("ImageKnife_DataTime_requestJob.getImageArrayBuffer.start:" + request.src)
|
||||
resBuf = await ImageKnifeLoader.getImageArrayBuffer(request, requestList, fileKey)
|
||||
resBuf = await ImageKnifeLoader.getImageArrayBuffer(request, requestList, fileKey, callBackData, errorCallBackData)
|
||||
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)
|
||||
return ImageKnifeLoader.makeEmptyResult(error, errorCallBackData)
|
||||
}
|
||||
|
||||
// 获取图片类型
|
||||
let typeValue = new FileTypeUtil().getFileType(resBuf);
|
||||
if(typeValue == null) {
|
||||
if (typeValue == null) {
|
||||
LogUtil.log("ImageKnife_DataTime_requestJob.end: getFileType is null " + request.src)
|
||||
return ImageKnifeLoader.makeEmptyResult("request is not a valid image source")
|
||||
return ImageKnifeLoader.makeEmptyResult("request is not a valid image source", errorCallBackData)
|
||||
}
|
||||
|
||||
// 解析图片
|
||||
|
||||
LogUtil.log("ImageKnife_DataTime_requestJob.parseImage.start:" + request.src)
|
||||
let result: RequestJobResult = await ImageKnifeLoader.parseImage(resBuf, typeValue, fileKey, request)
|
||||
let result: RequestJobResult =
|
||||
await ImageKnifeLoader.parseImage(resBuf, typeValue, fileKey, request, callBackData, errorCallBackData)
|
||||
LogUtil.log("ImageKnife_DataTime_requestJob.parseImage.end:" + request.src)
|
||||
|
||||
// 图形变化
|
||||
if (request.requestSource === ImageKnifeRequestSource.SRC && request.transformation !== undefined && result?.pixelMap !== undefined && typeof result.pixelMap !== 'string') {
|
||||
if (request.requestSource === ImageKnifeRequestSource.SRC && request.transformation !== undefined &&
|
||||
result?.pixelMap !== undefined && typeof result.pixelMap !== 'string') {
|
||||
LogUtil.log("ImageKnife_DataTime_requestJob.transform.start:" + request.src)
|
||||
result.pixelMap = await request.transformation?.transform(request.context, result.pixelMap, request.componentWidth, request.componentHeight);
|
||||
result.pixelMap = await request.transformation?.transform(request.context, result.pixelMap, request.componentWidth,
|
||||
request.componentHeight);
|
||||
LogUtil.log("ImageKnife_DataTime_requestJob.transform.end:" + request.src)
|
||||
}
|
||||
|
||||
LogUtil.log("ImageKnife_DataTime_requestJob.end:" + request.src)
|
||||
|
||||
result.callBackData = callBackData;
|
||||
result.errorCallBackData = errorCallBackData;
|
||||
return result
|
||||
}
|
||||
|
||||
|
|
|
@ -14,8 +14,14 @@
|
|||
*/
|
||||
import {
|
||||
CacheStrategy,
|
||||
DecodeImageInfo,
|
||||
ErrorInfo,
|
||||
ImageKnifeData,
|
||||
ImageKnifeRequestSource,
|
||||
ImageKnifeRequestWithSource, RequestJobRequest } from './model/ImageKnifeData';
|
||||
ImageKnifeRequestWithSource,
|
||||
RequestJobRequest,
|
||||
TimeInfo
|
||||
} from './model/ImageKnifeData';
|
||||
import List from '@ohos.util.List'
|
||||
import { FileCache } from './cache/FileCache';
|
||||
import { LogUtil } from './utils/LogUtil';
|
||||
|
@ -28,6 +34,7 @@ import emitter from '@ohos.events.emitter';
|
|||
import image from '@ohos.multimedia.image';
|
||||
import { RequestJobResult } from './model/ImageKnifeData'
|
||||
import util from '@ohos.util';
|
||||
import { LoadPixelMapCode, LoadPhase } from './utils/Constants';
|
||||
import { DownsampleStrategy } from './downsampling/DownsampleStartegy';
|
||||
import { Downsampler } from './downsampling/Downsampler';
|
||||
|
||||
|
@ -41,40 +48,61 @@ class RequestData {
|
|||
*/
|
||||
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)
|
||||
request: RequestJobRequest, callBackData: ImageKnifeData, errorCallBackData: ErrorInfo): Promise<RequestJobResult> {
|
||||
if (request.isAnimator) {
|
||||
return ImageKnifeLoader.parseForAnimatorComponent(resBuf, typeValue, fileKey, request, callBackData,
|
||||
errorCallBackData)
|
||||
}
|
||||
|
||||
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.parseAnimatorImage(resBuf, typeValue, fileKey, request, callBackData, errorCallBackData)
|
||||
} else if (typeValue == "svg") {
|
||||
return ImageKnifeLoader.parseSvgImage(resBuf, typeValue, fileKey, request, callBackData, errorCallBackData)
|
||||
}
|
||||
|
||||
return ImageKnifeLoader.parseNormalImage(resBuf, typeValue, fileKey, request)
|
||||
return ImageKnifeLoader.parseNormalImage(resBuf, typeValue, fileKey, request, callBackData, errorCallBackData)
|
||||
}
|
||||
|
||||
static makeEmptyResult(error: string): RequestJobResult{
|
||||
static makeEmptyResult(error: string, errorInfo?: ErrorInfo): RequestJobResult {
|
||||
return {
|
||||
pixelMap: undefined,
|
||||
bufferSize: 0,
|
||||
fileKey: '',
|
||||
loadFail: error,
|
||||
errorCallBackData: errorInfo
|
||||
}
|
||||
}
|
||||
|
||||
static async parseNormalImage(resBuf: ArrayBuffer, typeValue: string, fileKey: string, request: RequestJobRequest):Promise<RequestJobResult> {
|
||||
static throwError(error: string, errorInfo: ErrorInfo, code: number, timeInfo: TimeInfo) {
|
||||
errorInfo.code = code
|
||||
errorInfo.timeInfo = timeInfo;
|
||||
throw new Error(error);
|
||||
}
|
||||
|
||||
static async parseNormalImage(resBuf: ArrayBuffer, typeValue: string, fileKey: string,
|
||||
request: RequestJobRequest, callBackData: ImageKnifeData, errorCallBackData: ErrorInfo): Promise<RequestJobResult> {
|
||||
let resPixelmap: PixelMap | undefined = undefined
|
||||
let timeInfo: TimeInfo = callBackData.timeInfo ? callBackData.timeInfo : {}
|
||||
let decodingOptions: image.DecodingOptions = {
|
||||
editable: request.requestSource === ImageKnifeRequestSource.SRC && request.transformation !== undefined ? true : false,
|
||||
editable: request.requestSource === ImageKnifeRequestSource.SRC && request.transformation !== undefined ? true :
|
||||
false,
|
||||
}
|
||||
let imageSource: image.ImageSource = image.createImageSource(resBuf)
|
||||
if (imageSource === undefined){
|
||||
if (imageSource === undefined) {
|
||||
errorCallBackData.phase = LoadPhase.PHASE_CREATE_SOURCE;
|
||||
errorCallBackData.code = LoadPixelMapCode.IMAGE_SOURCE_ERROR_CODE;
|
||||
return ImageKnifeLoader.makeEmptyResult("image.createImageSource failed")
|
||||
}
|
||||
|
||||
let size = (await imageSource.getImageInfo()).size
|
||||
|
||||
callBackData.type = typeValue;
|
||||
callBackData.imageWidth = size.width;
|
||||
callBackData.imageHeight = size.height;
|
||||
callBackData.imageSize = resBuf.byteLength;
|
||||
callBackData.timeInfo = timeInfo;
|
||||
timeInfo.decodeStartTime = Date.now();
|
||||
|
||||
try {
|
||||
if ((request.downsampType !== DownsampleStrategy.NONE) &&
|
||||
request.requestSource == ImageKnifeRequestSource.SRC) {
|
||||
|
@ -87,25 +115,47 @@ export class ImageKnifeLoader {
|
|||
await imageSource.createPixelMap(decodingOptions)
|
||||
.then((pixelmap: PixelMap) => {
|
||||
resPixelmap = pixelmap
|
||||
timeInfo.decodeEndTime = Date.now();
|
||||
imageSource.release()
|
||||
}).catch((error: BusinessError) => {
|
||||
imageSource.release()
|
||||
timeInfo.decodeEndTime = Date.now();
|
||||
errorCallBackData.phase = LoadPhase.PHASE_CREATE_PIXEL_MAP;
|
||||
errorCallBackData.code = LoadPixelMapCode.IMAGE_DECODE_ERROR_CODE;
|
||||
errorCallBackData.timeInfo = timeInfo;
|
||||
return ImageKnifeLoader.makeEmptyResult(JSON.stringify(error))
|
||||
})
|
||||
|
||||
//获取各个pixelMap的大小
|
||||
if (resPixelmap && typeof resPixelmap !== "string") {
|
||||
let decodeImages: Array<DecodeImageInfo> = [];
|
||||
let size = (resPixelmap as PixelMap).getImageInfoSync().size;
|
||||
let decodeImage: DecodeImageInfo = {
|
||||
contentWidth: size.width,
|
||||
contentHeight: size.height,
|
||||
contentSize: (resPixelmap as PixelMap).getPixelBytesNumber()
|
||||
}
|
||||
decodeImages.push(decodeImage);
|
||||
callBackData.decodeImages = decodeImages;
|
||||
}
|
||||
|
||||
return {
|
||||
pixelMap: resPixelmap,
|
||||
bufferSize: resBuf.byteLength,
|
||||
fileKey: fileKey,
|
||||
size:size,
|
||||
type:typeValue
|
||||
size: size,
|
||||
type: typeValue
|
||||
};
|
||||
}
|
||||
|
||||
static async parseSvgImage(resBuf: ArrayBuffer, typeValue: string, fileKey: string,
|
||||
request: RequestJobRequest): Promise<RequestJobResult> {
|
||||
let resPixelmap: PixelMap | undefined = undefined
|
||||
request: RequestJobRequest, callBackData: ImageKnifeData, errorCallBackData: ErrorInfo): Promise<RequestJobResult> {
|
||||
let resPixelMap: PixelMap | undefined = undefined
|
||||
let timeInfo: TimeInfo = callBackData.timeInfo ? callBackData.timeInfo : {}
|
||||
let imageSource: image.ImageSource = image.createImageSource(resBuf)
|
||||
if (imageSource === undefined){
|
||||
if (imageSource === undefined) {
|
||||
errorCallBackData.phase = LoadPhase.PHASE_CREATE_SOURCE;
|
||||
errorCallBackData.code = LoadPixelMapCode.IMAGE_SOURCE_ERROR_CODE;
|
||||
return ImageKnifeLoader.makeEmptyResult("image.createImageSource failed")
|
||||
}
|
||||
|
||||
|
@ -121,6 +171,13 @@ export class ImageKnifeLoader {
|
|||
editable: true,
|
||||
desiredSize: defaultSize
|
||||
};
|
||||
callBackData.type = typeValue;
|
||||
callBackData.imageWidth = size.width;
|
||||
callBackData.imageHeight = size.height;
|
||||
callBackData.imageSize = resBuf.byteLength;
|
||||
callBackData.timeInfo = timeInfo;
|
||||
timeInfo.decodeStartTime = Date.now();
|
||||
|
||||
try {
|
||||
if ((request.downsampType !== DownsampleStrategy.NONE) &&
|
||||
request.requestSource == ImageKnifeRequestSource.SRC) {
|
||||
|
@ -130,58 +187,98 @@ export class ImageKnifeLoader {
|
|||
return ImageKnifeLoader.makeEmptyResult(err)
|
||||
}
|
||||
await imageSource.createPixelMap(opts)
|
||||
.then((pixelmap: PixelMap) => {
|
||||
resPixelmap = pixelmap
|
||||
.then((pixelMap: PixelMap) => {
|
||||
resPixelMap = pixelMap
|
||||
imageSource.release()
|
||||
}).catch((error: BusinessError) => {
|
||||
imageSource.release()
|
||||
timeInfo.decodeEndTime = Date.now();
|
||||
errorCallBackData.phase = LoadPhase.PHASE_CREATE_PIXEL_MAP;
|
||||
errorCallBackData.code = LoadPixelMapCode.IMAGE_DECODE_ERROR_CODE;
|
||||
errorCallBackData.timeInfo = timeInfo;
|
||||
return ImageKnifeLoader.makeEmptyResult(JSON.stringify(error))
|
||||
})
|
||||
|
||||
//获取各个pixelMap的大小
|
||||
if (resPixelMap && typeof resPixelMap !== "string") {
|
||||
let decodeImages: Array<DecodeImageInfo> = [];
|
||||
let decodeImage: DecodeImageInfo = {
|
||||
contentWidth: defaultSize.width,
|
||||
contentHeight: defaultSize.height,
|
||||
contentSize: (resPixelMap as PixelMap).getPixelBytesNumber()
|
||||
}
|
||||
decodeImages.push(decodeImage);
|
||||
}
|
||||
|
||||
return {
|
||||
pixelMap: resPixelmap,
|
||||
pixelMap: resPixelMap,
|
||||
bufferSize: resBuf.byteLength,
|
||||
fileKey: fileKey,
|
||||
type:typeValue
|
||||
type: typeValue
|
||||
};
|
||||
}
|
||||
|
||||
static async parseAnimatorImage(resBuf: ArrayBuffer, typeValue: string,
|
||||
fileKey: string,request: RequestJobRequest): Promise<RequestJobResult> {
|
||||
fileKey: string, request: RequestJobRequest, callBackData: ImageKnifeData,
|
||||
errorCallBackData: ErrorInfo): Promise<RequestJobResult> {
|
||||
let imageSource: image.ImageSource = image.createImageSource(resBuf)
|
||||
if (imageSource === undefined){
|
||||
if (imageSource === undefined) {
|
||||
errorCallBackData.phase = LoadPhase.PHASE_CREATE_SOURCE;
|
||||
errorCallBackData.code = LoadPixelMapCode.IMAGE_SOURCE_ERROR_CODE;
|
||||
return ImageKnifeLoader.makeEmptyResult("image.createImageSource failed")
|
||||
}
|
||||
|
||||
let frameCount = await imageSource.getFrameCount()
|
||||
let size = (await imageSource.getImageInfo()).size
|
||||
callBackData.type = typeValue;
|
||||
callBackData.frameCount = frameCount;
|
||||
callBackData.imageWidth = size.width;
|
||||
callBackData.imageHeight = size.height;
|
||||
callBackData.imageSize = resBuf.byteLength;
|
||||
imageSource.release()
|
||||
|
||||
if(frameCount == undefined || frameCount == 1) {
|
||||
if (frameCount == undefined || frameCount == 1) {
|
||||
} else {
|
||||
let base64str = "data:image/" + typeValue + ";base64," + new util.Base64Helper().encodeToStringSync(new Uint8Array(resBuf))
|
||||
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
|
||||
size: size,
|
||||
type: typeValue
|
||||
};
|
||||
}
|
||||
return ImageKnifeLoader.parseNormalImage(resBuf, typeValue, fileKey, request)
|
||||
return ImageKnifeLoader.parseNormalImage(resBuf, typeValue, fileKey, request, callBackData, errorCallBackData)
|
||||
}
|
||||
|
||||
// 为AnimatorComponent解析动图
|
||||
static async parseForAnimatorComponent(resBuf: ArrayBuffer, typeValue: string, fileKey: string,request: RequestJobRequest): Promise<RequestJobResult> {
|
||||
static async parseForAnimatorComponent(resBuf: ArrayBuffer, typeValue: string, fileKey: string,
|
||||
request: RequestJobRequest, callBackData: ImageKnifeData, errorCallBackData: ErrorInfo): Promise<RequestJobResult> {
|
||||
let timeInfo: TimeInfo = callBackData.timeInfo ? callBackData.timeInfo : {}
|
||||
|
||||
callBackData.type = typeValue;
|
||||
if (typeValue === 'gif' || typeValue === 'webp') {
|
||||
let imageSource: image.ImageSource = image.createImageSource(resBuf);
|
||||
if (imageSource === undefined){
|
||||
if (imageSource === undefined) {
|
||||
errorCallBackData.phase = LoadPhase.PHASE_CREATE_SOURCE;
|
||||
errorCallBackData.code = LoadPixelMapCode.IMAGE_SOURCE_ERROR_CODE;
|
||||
return ImageKnifeLoader.makeEmptyResult("image.createImageSource failed")
|
||||
}
|
||||
let decodingOptions: image.DecodingOptions = {
|
||||
editable: request.requestSource === ImageKnifeRequestSource.SRC && request.transformation !== undefined ? true : false,
|
||||
editable: request.requestSource === ImageKnifeRequestSource.SRC && request.transformation !== undefined ? true :
|
||||
false,
|
||||
}
|
||||
callBackData.imageWidth = imageSource.getImageInfoSync().size.width;
|
||||
callBackData.imageHeight = imageSource.getImageInfoSync().size.height;
|
||||
callBackData.imageSize = resBuf.byteLength;
|
||||
|
||||
let pixelMapList: Array<PixelMap> = []
|
||||
let delayList: Array<number> = []
|
||||
timeInfo.decodeStartTime = Date.now();
|
||||
let decodeImages: Array<DecodeImageInfo> = [];
|
||||
await imageSource.createPixelMapList(decodingOptions).then(async (pixelList: Array<PixelMap>) => {
|
||||
timeInfo.decodeEndTime = Date.now();
|
||||
//sdk的api接口发生变更:从.getDelayTime() 变为.getDelayTimeList()
|
||||
await imageSource.getDelayTimeList().then(delayTimes => {
|
||||
if (pixelList.length > 0) {
|
||||
|
@ -192,14 +289,29 @@ export class ImageKnifeLoader {
|
|||
} else {
|
||||
delayList.push(delayTimes[delayTimes.length - 1])
|
||||
}
|
||||
//获取各个pixelMap的大小
|
||||
let size = pixelList[i].getImageInfoSync().size
|
||||
let decodeImage: DecodeImageInfo = {
|
||||
contentWidth: size.width,
|
||||
contentHeight: size.height,
|
||||
contentSize: pixelList[i].getPixelBytesNumber()
|
||||
}
|
||||
decodeImages.push(decodeImage);
|
||||
}
|
||||
imageSource.release();
|
||||
}
|
||||
})
|
||||
}).catch((error: BusinessError) => {
|
||||
timeInfo.decodeEndTime = Date.now();
|
||||
imageSource.release()
|
||||
errorCallBackData.phase = LoadPhase.PHASE_CREATE_PIXEL_MAP;
|
||||
errorCallBackData.code = LoadPixelMapCode.IMAGE_DECODE_ERROR_CODE;
|
||||
errorCallBackData.timeInfo = timeInfo;
|
||||
return ImageKnifeLoader.makeEmptyResult(JSON.stringify(error))
|
||||
})
|
||||
callBackData.timeInfo = timeInfo;
|
||||
callBackData.decodeImages = decodeImages;
|
||||
errorCallBackData.timeInfo = timeInfo;
|
||||
return {
|
||||
pixelMap: "",
|
||||
bufferSize: resBuf.byteLength,
|
||||
|
@ -209,47 +321,59 @@ export class ImageKnifeLoader {
|
|||
delayList
|
||||
}
|
||||
} else {
|
||||
callBackData.timeInfo = timeInfo;
|
||||
errorCallBackData.phase = LoadPhase.PHASE_PARSE_IAMGE;
|
||||
errorCallBackData.timeInfo = timeInfo;
|
||||
errorCallBackData.code = LoadPixelMapCode.IMAGE_FORMAT_ERROR_CODE
|
||||
return ImageKnifeLoader.makeEmptyResult("ImageKnifeAnimatorComponent组件仅支持动态图")
|
||||
}
|
||||
}
|
||||
|
||||
// 获取图片资源
|
||||
static async getImageArrayBuffer(request: RequestJobRequest, requestList: List<ImageKnifeRequestWithSource> | undefined,fileKey:string): Promise<ArrayBuffer> {
|
||||
static async getImageArrayBuffer(request: RequestJobRequest,
|
||||
requestList: List<ImageKnifeRequestWithSource> | undefined,
|
||||
fileKey: string, callBackData: ImageKnifeData, errorCallBackData: ErrorInfo): Promise<ArrayBuffer> {
|
||||
let resBuf: ArrayBuffer | undefined
|
||||
|
||||
let timeInfo: TimeInfo = callBackData.timeInfo ? callBackData.timeInfo : {};
|
||||
// 判断自定义下载
|
||||
if (request.customGetImage !== undefined && request.requestSource == ImageKnifeRequestSource.SRC && typeof request.src == "string") {
|
||||
if (request.customGetImage !== undefined && request.requestSource == ImageKnifeRequestSource.SRC &&
|
||||
typeof request.src == "string") {
|
||||
// 先从文件缓存获取
|
||||
resBuf = FileCache.getFileCacheByFile(request.context, fileKey , request.fileCacheFolder)
|
||||
timeInfo.diskCheckStartTime = Date.now();
|
||||
resBuf = FileCache.getFileCacheByFile(request.context, fileKey, request.fileCacheFolder)
|
||||
timeInfo.diskCheckEndTime = Date.now();
|
||||
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)
|
||||
ImageKnifeLoader.throwError('customGetImage loadFile failed! err = ' + err,
|
||||
errorCallBackData, LoadPixelMapCode.IMAGE_CUSTOM_LOAD_FAILED_CODE, timeInfo)
|
||||
}
|
||||
if (resBuf === undefined) {
|
||||
throw new Error('customGetImage loadFile failed!')
|
||||
ImageKnifeLoader.throwError('customGetImage loadFile failed!',
|
||||
errorCallBackData, LoadPixelMapCode.IMAGE_CUSTOM_LOAD_FAILED_CODE, timeInfo)
|
||||
}
|
||||
// 保存文件缓存
|
||||
if (request.writeCacheStrategy !== CacheStrategy.Memory) {
|
||||
if (resBuf && 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 {
|
||||
} 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){
|
||||
timeInfo.diskCheckStartTime = Date.now()
|
||||
resBuf = FileCache.getFileCacheByFile(request.context, fileKey, request.fileCacheFolder)
|
||||
timeInfo.diskCheckEndTime = Date.now()
|
||||
if (resBuf !== undefined) {
|
||||
LogUtil.log("success get image from filecache for key = " + fileKey + " src = " + request.src)
|
||||
}
|
||||
else if (request.onlyRetrieveFromCache != true) {
|
||||
} else if (request.onlyRetrieveFromCache != true) {
|
||||
LogUtil.log("HttpDownloadClient.start:" + request.src)
|
||||
timeInfo.netRequestStartTime = Date.now();
|
||||
let httpRequest = http.createHttp();
|
||||
let progress: number = 0
|
||||
let arrayBuffers = new Array<ArrayBuffer>()
|
||||
|
@ -265,6 +389,11 @@ export class ImageKnifeLoader {
|
|||
}
|
||||
httpRequest.on("dataReceive", (data: ArrayBuffer) => {
|
||||
arrayBuffers.push(data)
|
||||
//获取http下载的字节数
|
||||
if (callBackData.bufSize == undefined) {
|
||||
callBackData.bufSize = 0;
|
||||
}
|
||||
callBackData.bufSize += data.byteLength;
|
||||
});
|
||||
|
||||
if (request.isWatchProgress) {
|
||||
|
@ -277,10 +406,11 @@ export class ImageKnifeLoader {
|
|||
if (requestList === undefined) {
|
||||
// 子线程
|
||||
emitter.emit(Constants.PROGRESS_EMITTER + request.memoryKey, { data: { "value": progress } })
|
||||
}else {
|
||||
} else {
|
||||
// 主线程请求
|
||||
requestList!.forEach((requestWithSource: ImageKnifeRequestWithSource) => {
|
||||
if (requestWithSource.request.imageKnifeOption.progressListener !== undefined && requestWithSource.source === ImageKnifeRequestSource.SRC) {
|
||||
if (requestWithSource.request.imageKnifeOption.progressListener !== undefined &&
|
||||
requestWithSource.source === ImageKnifeRequestSource.SRC) {
|
||||
requestWithSource.request.imageKnifeOption.progressListener(progress)
|
||||
}
|
||||
})
|
||||
|
@ -300,42 +430,59 @@ export class ImageKnifeLoader {
|
|||
});
|
||||
|
||||
await promise.then((data: number) => {
|
||||
errorCallBackData.phase = LoadPhase.PHASE_NET
|
||||
errorCallBackData.httpCode = data;
|
||||
timeInfo.netRequestEndTime = Date.now();
|
||||
if (data == 200 || data == 206 || data == 204) {
|
||||
resBuf = combineArrayBuffers(arrayBuffers)
|
||||
} else {
|
||||
throw new Error("HttpDownloadClient has error, http code =" + JSON.stringify(data))
|
||||
ImageKnifeLoader.throwError("HttpDownloadClient has error, http code =" + JSON.stringify(data),
|
||||
errorCallBackData, LoadPixelMapCode.IMAGE_HTTPS_LOAD_FAILED_CODE, timeInfo)
|
||||
}
|
||||
}).catch((err: Error) => {
|
||||
throw new Error("HttpDownloadClient download ERROR : err = " + JSON.stringify(err))
|
||||
timeInfo.netRequestEndTime = Date.now();
|
||||
ImageKnifeLoader.throwError("HttpDownloadClient download ERROR : err = " + JSON.stringify(err),
|
||||
errorCallBackData, LoadPixelMapCode.IMAGE_HTTPS_LOAD_FAILED_CODE, timeInfo)
|
||||
});
|
||||
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)
|
||||
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 {
|
||||
ImageKnifeLoader.throwError('onlyRetrieveFromCache,do not fetch image src = ' + request.src,
|
||||
errorCallBackData, LoadPixelMapCode.IMAGE_RETRIEVE_CACHE_CODE, timeInfo)
|
||||
}
|
||||
} else if (request.src.startsWith('datashare://') || request.src.startsWith('file://')) {
|
||||
errorCallBackData.phase = LoadPhase.PHASE_SHARE_FILE
|
||||
await fs.open(request.src, fs.OpenMode.READ_ONLY).then(async (file) => {
|
||||
await fs.stat(file.fd).then(async (stat) =>{
|
||||
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) => {
|
||||
ImageKnifeLoader.throwError('LoadDataShareFileClient fs.read err happened uri=' + request.src +
|
||||
" err.msg=" +
|
||||
err?.message + " err.code=" + err?.code,
|
||||
errorCallBackData, LoadPixelMapCode.IMAGE_LOAD_SHARE_FILE_FAILED_CODE, timeInfo)
|
||||
})
|
||||
}).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) => {
|
||||
ImageKnifeLoader.throwError('LoadDataShareFileClient fs.stat err happened uri=' + request.src +
|
||||
" err.msg=" +
|
||||
err?.message + " err.code=" + err?.code,
|
||||
errorCallBackData, LoadPixelMapCode.IMAGE_LOAD_SHARE_FILE_FAILED_CODE, timeInfo)
|
||||
})
|
||||
}).catch((err:BusinessError) => {
|
||||
throw new Error('LoadDataShareFileClient fs.open err happened uri=' + request.src + " err.msg=" + err?.message + " err.code=" + err?.code)
|
||||
}).catch((err: BusinessError) => {
|
||||
ImageKnifeLoader.throwError('LoadDataShareFileClient fs.open err happened uri=' + request.src +
|
||||
" err.msg=" +
|
||||
err?.message + " err.code=" + err?.code,
|
||||
errorCallBackData, LoadPixelMapCode.IMAGE_LOAD_SHARE_FILE_FAILED_CODE, timeInfo)
|
||||
})
|
||||
} else { //从本地文件获取
|
||||
errorCallBackData.phase = LoadPhase.PHASE_LOCAL_FILE
|
||||
try {
|
||||
let stat = fs.statSync(request.src);
|
||||
if (stat.size > 0) {
|
||||
|
@ -345,20 +492,22 @@ export class ImageKnifeLoader {
|
|||
fs.closeSync(file);
|
||||
}
|
||||
} catch (err) {
|
||||
throw new Error(err)
|
||||
ImageKnifeLoader.throwError(err,
|
||||
errorCallBackData, LoadPixelMapCode.IMAGE_LOAD_LOCAL_FILE_FAILED_CODE, timeInfo)
|
||||
}
|
||||
}
|
||||
} 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) {
|
||||
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) {
|
||||
if (request.src == -1) {
|
||||
let resName = request.resName as string
|
||||
resBuf = (await manager.getMediaByName(resName.substring(10))).buffer as ArrayBuffer
|
||||
} else {
|
||||
|
@ -368,9 +517,13 @@ export class ImageKnifeLoader {
|
|||
}
|
||||
}
|
||||
|
||||
if (resBuf === undefined){
|
||||
if (resBuf === undefined) {
|
||||
errorCallBackData.code = LoadPixelMapCode.IMAGE_LOAD_FAILED_CODE
|
||||
errorCallBackData.timeInfo = timeInfo;
|
||||
throw new Error('getImageArrayBuffer undefined')
|
||||
}
|
||||
callBackData.timeInfo = timeInfo;
|
||||
errorCallBackData.timeInfo = timeInfo;
|
||||
return resBuf
|
||||
}
|
||||
|
||||
|
|
|
@ -53,23 +53,28 @@ export struct ImageKnifeComponent {
|
|||
aboutToAppear(): void {
|
||||
this.objectFit = this.imageKnifeOption.objectFit === undefined ? ImageFit.Contain : this.imageKnifeOption.objectFit
|
||||
|
||||
if(this.syncLoad) { //针对部分消息列表最新消息的图片闪动问题,建议使用同步方式在aboutToAppear时加载图片
|
||||
if (this.syncLoad) { //针对部分消息列表最新消息的图片闪动问题,建议使用同步方式在aboutToAppear时加载图片
|
||||
let engineKey: IEngineKey = new DefaultEngineKey();
|
||||
let memoryCacheSrc: ImageKnifeData | undefined = ImageKnife.getInstance()
|
||||
.loadFromMemoryCache(engineKey.generateMemoryKey(this.imageKnifeOption.loadSrc,ImageKnifeRequestSource.SRC,this.imageKnifeOption))
|
||||
if (memoryCacheSrc !== undefined){
|
||||
LogUtil.log("aboutToAppear success load loadSrc from memory cache for loadSrc = "+ this.imageKnifeOption.loadSrc)
|
||||
.loadFromMemoryCache(engineKey.generateMemoryKey(this.imageKnifeOption.loadSrc, ImageKnifeRequestSource.SRC,
|
||||
this.imageKnifeOption))
|
||||
if (memoryCacheSrc !== undefined) {
|
||||
LogUtil.log("aboutToAppear success load loadSrc from memory cache for loadSrc = " +
|
||||
this.imageKnifeOption.loadSrc)
|
||||
this.pixelMap = memoryCacheSrc.source;
|
||||
}else{
|
||||
LogUtil.log("aboutToAppear fail load loadSrc from memory cache for loadSrc = "+ this.imageKnifeOption.loadSrc)
|
||||
if (this.imageKnifeOption.placeholderSrc !== undefined){
|
||||
} else {
|
||||
LogUtil.log("aboutToAppear fail load loadSrc from memory cache for loadSrc = " + this.imageKnifeOption.loadSrc)
|
||||
if (this.imageKnifeOption.placeholderSrc !== undefined) {
|
||||
let memoryCachePlace: ImageKnifeData | undefined = ImageKnife.getInstance()
|
||||
.loadFromMemoryCache(engineKey.generateMemoryKey(this.imageKnifeOption.placeholderSrc!,ImageKnifeRequestSource.PLACE_HOLDER,this.imageKnifeOption))
|
||||
if (memoryCachePlace !== undefined){
|
||||
LogUtil.log("aboutToAppear success load placeholderSrc from memory cache for placeholderSrc = " + this.imageKnifeOption.placeholderSrc)
|
||||
.loadFromMemoryCache(engineKey.generateMemoryKey(this.imageKnifeOption.placeholderSrc!,
|
||||
ImageKnifeRequestSource.PLACE_HOLDER, this.imageKnifeOption))
|
||||
if (memoryCachePlace !== undefined) {
|
||||
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)
|
||||
} else {
|
||||
LogUtil.log("aboutToAppear fail load placeholderSrc from memory cache for placeholderSrc = " +
|
||||
this.imageKnifeOption.placeholderSrc)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -87,7 +92,7 @@ export struct ImageKnifeComponent {
|
|||
/**
|
||||
* 对已DESTROY的组件不再发起请求
|
||||
*/
|
||||
private clearLastRequest(){
|
||||
private clearLastRequest() {
|
||||
if (this.request !== undefined) {
|
||||
this.request.requestState = ImageKnifeRequestState.DESTROY
|
||||
this.request = undefined
|
||||
|
@ -104,7 +109,7 @@ export struct ImageKnifeComponent {
|
|||
.syncLoad(this.syncLoad)
|
||||
.draggable(false)
|
||||
.onComplete(this.imageKnifeOption.onComplete)
|
||||
.onSizeChange((oldValue:SizeOptions, newValue:SizeOptions) => {
|
||||
.onSizeChange((oldValue: SizeOptions, newValue: SizeOptions) => {
|
||||
this.currentWidth = newValue.width as number
|
||||
this.currentHeight = newValue.height as number
|
||||
this.lastWidth = oldValue.width as number
|
||||
|
@ -138,7 +143,8 @@ export struct ImageKnifeComponent {
|
|||
height,
|
||||
this.componentVersion,
|
||||
{
|
||||
showPixelMap: async (version: number, pixelMap: PixelMap | string, requestSource: ImageKnifeRequestSource) => {
|
||||
showPixelMap: async (version: number, pixelMap: PixelMap | string,
|
||||
requestSource: ImageKnifeRequestSource) => {
|
||||
if (version !== this.componentVersion) {
|
||||
return //针对reuse场景,不显示历史图片
|
||||
}
|
||||
|
@ -154,10 +160,14 @@ export struct ImageKnifeComponent {
|
|||
this.imageKnifeOption.objectFit === undefined ? ImageFit.Contain : this.imageKnifeOption.objectFit
|
||||
} else if (requestSource == ImageKnifeRequestSource.PLACE_HOLDER) {
|
||||
this.objectFit =
|
||||
this.imageKnifeOption.placeholderObjectFit === undefined ? (this.imageKnifeOption.objectFit === undefined ? ImageFit.Contain : this.imageKnifeOption.objectFit) : this.imageKnifeOption.placeholderObjectFit
|
||||
this.imageKnifeOption.placeholderObjectFit === undefined ?
|
||||
(this.imageKnifeOption.objectFit === undefined ? ImageFit.Contain : this.imageKnifeOption.objectFit) :
|
||||
this.imageKnifeOption.placeholderObjectFit
|
||||
} else {
|
||||
this.objectFit =
|
||||
this.imageKnifeOption.errorholderObjectFit === undefined ? (this.imageKnifeOption.objectFit === undefined ? ImageFit.Contain : this.imageKnifeOption.objectFit) : this.imageKnifeOption.errorholderObjectFit
|
||||
this.imageKnifeOption.errorholderObjectFit === undefined ?
|
||||
(this.imageKnifeOption.objectFit === undefined ? ImageFit.Contain : this.imageKnifeOption.objectFit) :
|
||||
this.imageKnifeOption.errorholderObjectFit
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
|
@ -21,12 +21,56 @@ import { Size } from '@kit.ArkUI'
|
|||
import { DownsampleStrategy } from '../downsampling/DownsampleStartegy'
|
||||
|
||||
export interface ImageKnifeData {
|
||||
source: PixelMap | string,
|
||||
imageWidth: number,
|
||||
source: PixelMap | string, // url
|
||||
imageWidth: number, // 原始宽高大小
|
||||
imageHeight: number,
|
||||
type?:string,
|
||||
imageAnimator?: Array<ImageFrameInfo>
|
||||
imageSize?: number,
|
||||
type?: string,
|
||||
imageAnimator?: Array<ImageFrameInfo>,
|
||||
bufSize?: number, // 网络请求字节数
|
||||
componentWidth?: number //组件宽高
|
||||
componentHeight?: number
|
||||
frameCount ?: number // 帧
|
||||
decodeImages?: Array<DecodeImageInfo> //Image组件或者ImageAnimator组件可以加载一张或者多张
|
||||
timeInfo?: TimeInfo // 加载图片的各个时间点
|
||||
}
|
||||
|
||||
/**
|
||||
* 解码后的图片的size
|
||||
*/
|
||||
export interface DecodeImageInfo {
|
||||
contentWidth ?: number // 解码后宽高
|
||||
contentHeight?: number
|
||||
contentSize ?: number // 大小
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载的错误信息
|
||||
*/
|
||||
export interface ErrorInfo {
|
||||
phase: string, //图片加载阶段信息,如:网络加载阶段,缓存获取阶段及其解码阶段等
|
||||
code: number,
|
||||
timeInfo?: TimeInfo,
|
||||
httpCode?: number
|
||||
}
|
||||
|
||||
/**
|
||||
* lru检查时间点
|
||||
*/
|
||||
export interface TimeInfo {
|
||||
requestStartTime?: number,
|
||||
requestEndTime?: number,
|
||||
requestCancelTime?: number,
|
||||
memoryCheckStartTime?: number,
|
||||
memoryCheckEndTime?: number,
|
||||
diskCheckStartTime?: number,
|
||||
diskCheckEndTime?: number,
|
||||
netRequestStartTime?: number,
|
||||
netRequestEndTime?: number,
|
||||
decodeStartTime?: number,
|
||||
decodeEndTime?: number,
|
||||
}
|
||||
|
||||
/**
|
||||
* onComplete成功回调
|
||||
*/
|
||||
|
@ -41,6 +85,7 @@ export interface EventImage {
|
|||
contentOffsetX: number;
|
||||
contentOffsetY: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* 缓存策略
|
||||
*/
|
||||
|
@ -76,10 +121,12 @@ export interface RequestJobResult {
|
|||
bufferSize: number
|
||||
fileKey: string
|
||||
loadFail?: string,
|
||||
size?:Size,
|
||||
size?: Size,
|
||||
type?: string,
|
||||
pixelMapList?:Array<PixelMap>,
|
||||
delayList?: Array<number>
|
||||
pixelMapList?: Array<PixelMap>,
|
||||
delayList?: Array<number>,
|
||||
callBackData?: ImageKnifeData,
|
||||
errorCallBackData?: ErrorInfo
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
*/
|
||||
import taskpool from '@ohos.taskpool';
|
||||
import common from '@ohos.app.ability.common'
|
||||
import { CacheStrategy, ImageKnifeData,EventImage } from './ImageKnifeData';
|
||||
import { CacheStrategy, ImageKnifeData, EventImage, ErrorInfo } from './ImageKnifeData';
|
||||
import { PixelMapTransformation } from '../transform/PixelMapTransformation';
|
||||
import { drawing } from '@kit.ArkGraphics2D';
|
||||
import { DownsampleStrategy } from '../downsampling/DownsampleStartegy';
|
||||
|
@ -23,16 +23,18 @@ 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
|
||||
onStart?: () => void
|
||||
onFinish?: () => void
|
||||
onPause?: () => void
|
||||
onCancel?: () => void
|
||||
onRepeat?: () => void
|
||||
}
|
||||
|
||||
@ObservedV2
|
||||
export class AnimatorOption {
|
||||
@Trace
|
||||
|
@ -42,16 +44,17 @@ export class AnimatorOption {
|
|||
@Trace
|
||||
reverse?: boolean = false
|
||||
@Trace
|
||||
onStart?:()=>void
|
||||
onStart?: () => void
|
||||
@Trace
|
||||
onFinish?:()=>void
|
||||
onFinish?: () => void
|
||||
@Trace
|
||||
onPause?:()=>void
|
||||
onPause?: () => void
|
||||
@Trace
|
||||
onCancel?:()=>void
|
||||
onCancel?: () => void
|
||||
@Trace
|
||||
onRepeat?:()=>void
|
||||
constructor(option?:AnimatorType) {
|
||||
onRepeat?: () => void
|
||||
|
||||
constructor(option?: AnimatorType) {
|
||||
this.state = option?.state
|
||||
this.iterations = option?.iterations
|
||||
this.reverse = option?.reverse
|
||||
|
@ -62,6 +65,7 @@ export class AnimatorOption {
|
|||
this.onRepeat = option?.onRepeat
|
||||
}
|
||||
}
|
||||
|
||||
interface ImageOption {
|
||||
// 主图资源
|
||||
loadSrc: string | PixelMap | Resource
|
||||
|
@ -70,6 +74,7 @@ interface ImageOption {
|
|||
// 失败占位图
|
||||
errorholderSrc?: string | PixelMap | Resource
|
||||
headerOption?: Array<HeaderOptions>;
|
||||
|
||||
// 自定义缓存关键字
|
||||
signature?: string
|
||||
// 主图填充效果
|
||||
|
@ -89,10 +94,11 @@ interface ImageOption {
|
|||
progressListener?: (progress: number) => void;
|
||||
transformation?: PixelMapTransformation
|
||||
onLoadListener?: OnLoadCallBack | undefined;
|
||||
onComplete?:(event:EventImage | undefined) => void
|
||||
onComplete?: (event: EventImage | undefined) => void
|
||||
drawingColorFilter?: ColorFilter | drawing.ColorFilter
|
||||
downsampleOf?: DownsampleStrategy
|
||||
}
|
||||
|
||||
@ObservedV2
|
||||
export class ImageKnifeOption {
|
||||
// 主图资源
|
||||
|
@ -154,13 +160,14 @@ export class ImageKnifeOption {
|
|||
*/
|
||||
export interface OnLoadCallBack {
|
||||
// 请求开始
|
||||
onLoadStart?: () => void;
|
||||
onLoadStart?: (imageKnifeData?: ImageKnifeData) => void;
|
||||
|
||||
// 请求成功
|
||||
onLoadSuccess?: (data: string | PixelMap | undefined, imageKnifeData: ImageKnifeData) => void;
|
||||
|
||||
// 请求结束
|
||||
onLoadFailed?: (err: string) => void;
|
||||
onLoadFailed?: (err: string, errorInfo?: ErrorInfo) => void;
|
||||
|
||||
// 请求取消
|
||||
onLoadCancel?: (reason: string) => void;
|
||||
onLoadCancel?: (reason: string, errorInfo?: ErrorInfo) => void;
|
||||
}
|
|
@ -14,10 +14,11 @@
|
|||
*/
|
||||
import { ImageKnifeOption } from './ImageKnifeOption';
|
||||
import common from '@ohos.app.ability.common';
|
||||
import { ImageKnifeRequestSource } from './ImageKnifeData';
|
||||
import { ImageKnifeData, ImageKnifeRequestSource } from './ImageKnifeData';
|
||||
import { DownsampleStrategy } from '../downsampling/DownsampleStartegy';
|
||||
|
||||
|
||||
|
||||
export class ImageKnifeRequest {
|
||||
requestState: ImageKnifeRequestState = ImageKnifeRequestState.PROGRESS
|
||||
componentWidth: number = 0
|
||||
|
@ -29,6 +30,7 @@ export class ImageKnifeRequest {
|
|||
componentVersion: number = 0
|
||||
headers: Map<string,Object> = new Map<string,Object>()
|
||||
downsampType?: DownsampleStrategy
|
||||
private imageCallBackData: ImageKnifeData | undefined = undefined;
|
||||
constructor(option: ImageKnifeOption,
|
||||
uIAbilityContext: common.UIAbilityContext,
|
||||
width: number,
|
||||
|
@ -45,6 +47,7 @@ export class ImageKnifeRequest {
|
|||
this.ImageKnifeRequestCallback = ImageKnifeRequestCallback
|
||||
this.downsampType = downsampType
|
||||
}
|
||||
|
||||
// RequestOption调用header对于的方法
|
||||
addHeader(key: string, value: Object) {
|
||||
this.headers.set(key, value);
|
||||
|
@ -58,6 +61,14 @@ export class ImageKnifeRequest {
|
|||
}
|
||||
})
|
||||
}
|
||||
|
||||
setImageKnifeData(data: ImageKnifeData) {
|
||||
this.imageCallBackData = data;
|
||||
}
|
||||
|
||||
getImageKnifeData(): ImageKnifeData | undefined {
|
||||
return this.imageCallBackData
|
||||
}
|
||||
}
|
||||
|
||||
export enum ImageKnifeRequestState {
|
||||
|
@ -69,5 +80,6 @@ export enum ImageKnifeRequestState {
|
|||
|
||||
|
||||
export interface ImageKnifeRequestCallback {
|
||||
showPixelMap: (version: number, pixelMap: PixelMap | string , requestSource: ImageKnifeRequestSource,imageAnimator?: Array<ImageFrameInfo>) => void;
|
||||
showPixelMap: (version: number, pixelMap: PixelMap | string, requestSource: ImageKnifeRequestSource,
|
||||
imageAnimator?: Array<ImageFrameInfo>) => void;
|
||||
}
|
||||
|
|
|
@ -15,3 +15,53 @@
|
|||
export class Constants {
|
||||
public static PROGRESS_EMITTER: string = "progressEmitter"
|
||||
}
|
||||
|
||||
/**
|
||||
* 图片加载的code
|
||||
*/
|
||||
export enum LoadPixelMapCode {
|
||||
// createImageSource error code
|
||||
IMAGE_SOURCE_ERROR_CODE = 100001,
|
||||
// createPixelMap error code
|
||||
IMAGE_DECODE_ERROR_CODE = 100002,
|
||||
//ImageKnifeAnimatorComponent组件仅支持动态图 code
|
||||
IMAGE_FORMAT_ERROR_CODE = 100003,
|
||||
//load failed code
|
||||
IMAGE_LOAD_FAILED_CODE = 100004,
|
||||
//自定义下载失败 code
|
||||
IMAGE_CUSTOM_LOAD_FAILED_CODE = 100005,
|
||||
// http请求失败 code
|
||||
IMAGE_HTTPS_LOAD_FAILED_CODE = 100006,
|
||||
//设置onlyRetrieveFromCache 导致的加载失败的code
|
||||
IMAGE_RETRIEVE_CACHE_CODE = 100007,
|
||||
//加载共享图片失败
|
||||
IMAGE_LOAD_SHARE_FILE_FAILED_CODE = 100008,
|
||||
//加载本地文件图片失败
|
||||
IMAGE_LOAD_LOCAL_FILE_FAILED_CODE = 100009,
|
||||
// 取消请求加载code
|
||||
IMAGE_LOAD_CANCEL_FAILED_CODE = 1000010
|
||||
}
|
||||
|
||||
/**
|
||||
* 图片加载的各个阶段
|
||||
*/
|
||||
export enum LoadPhase {
|
||||
// 图片加载阶段
|
||||
PHASE_LOAD = "load",
|
||||
// 网络请求下载阶段
|
||||
PHASE_NET = "net",
|
||||
// createPixelMap 阶段
|
||||
PHASE_CREATE_SOURCE = "createImageSource",
|
||||
//createPixelMap 阶段
|
||||
PHASE_CREATE_PIXEL_MAP = "createPixelMap",
|
||||
//请求队列排队阶段
|
||||
PHASE_THREAD_QUEUE = "thread_queue",
|
||||
//图片解析阶段
|
||||
PHASE_PARSE_IAMGE = "parseImage",
|
||||
//加载解析datashare:// 或者file:// 阶段
|
||||
PHASE_SHARE_FILE = "datashare_or_file",
|
||||
//加载解析本地文件阶段
|
||||
PHASE_LOCAL_FILE = "load_local_file",
|
||||
//图片加载解析完成,即将显示的阶段
|
||||
PHASE_WILL_SHOW = "will_show",
|
||||
}
|
Loading…
Reference in New Issue