Compare commits
No commits in common. "master" and "3.2.0" have entirely different histories.
16
CHANGELOG.md
16
CHANGELOG.md
|
@ -1,19 +1,3 @@
|
||||||
## 3.2.2-rc.1
|
|
||||||
- Support EXIF metadata carried by images as display orientation
|
|
||||||
|
|
||||||
## 3.2.2-rc.0
|
|
||||||
- Add ImageKnifeComponent to destroy network request interruption
|
|
||||||
- Code refactoring during the download of image resources stage
|
|
||||||
|
|
||||||
## 3.2.1
|
|
||||||
- Release official version
|
|
||||||
|
|
||||||
## 3.2.1-rc.0
|
|
||||||
- Fix bug: CropTransformation is used to crop the original image
|
|
||||||
- Fix bug: After calling the clear all file cache interfaces, the file cache becomes invalid
|
|
||||||
- Optimize the efficiency of file cache initialization.
|
|
||||||
- Add protection at the location where loadSrc is passed in the pixelmap type
|
|
||||||
|
|
||||||
## 3.2.0
|
## 3.2.0
|
||||||
- When successfully requesting the network, return the httpcode as well
|
- When successfully requesting the network, return the httpcode as well
|
||||||
- Fix bug: Network error code httpCode returns no data
|
- Fix bug: Network error code httpCode returns no data
|
||||||
|
|
14
README.md
14
README.md
|
@ -1,9 +1,3 @@
|
||||||
## 🚨 **重要提示 | IMPORTANT**
|
|
||||||
>
|
|
||||||
> **⚠️ 此代码仓已归档。新地址请访问 [ImageKnife](https://gitcode.com/openharmony-tpc/ImageKnife)。| ⚠️ This repository has been archived. For the new address, please visit [ImageKnife](https://gitcode.com/openharmony-tpc/ImageKnife).**
|
|
||||||
>
|
|
||||||
---
|
|
||||||
>
|
|
||||||
# ImageKnife
|
# ImageKnife
|
||||||
|
|
||||||
ImageKnife is a specially crafted image loading and caching library for OpenHarmony, optimized for efficiency, lightness, and simplicity.
|
ImageKnife is a specially crafted image loading and caching library for OpenHarmony, optimized for efficiency, lightness, and simplicity.
|
||||||
|
@ -367,14 +361,6 @@ This project has been verified in the following version:
|
||||||
|
|
||||||
DevEco Studio: NEXT Beta1-5.0.3.806, SDK: API12 Release(5.0.0.66)
|
DevEco Studio: NEXT Beta1-5.0.3.806, SDK: API12 Release(5.0.0.66)
|
||||||
|
|
||||||
## About obfuscation
|
|
||||||
- Code obfuscation, please see[Code Obfuscation](https://docs.openharmony.cn/pages/v5.0/zh-cn/application-dev/arkts-utils/source-obfuscation.md)
|
|
||||||
- If you want the imageknife library not to be obfuscated during code obfuscation, you need to add corresponding exclusion rules in the obfuscation rule configuration file obfuscation-rules.txt:
|
|
||||||
```
|
|
||||||
-keep
|
|
||||||
./oh_modules/@ohos/imageknife
|
|
||||||
```
|
|
||||||
|
|
||||||
## How to Contribute
|
## How to Contribute
|
||||||
|
|
||||||
If you find any problem during the use, submit an [Issue](https://gitee.com/openharmony-tpc/ImageKnife/issues) or a [PR](https://gitee.com/openharmony-tpc/ImageKnife/issues) to us.
|
If you find any problem during the use, submit an [Issue](https://gitee.com/openharmony-tpc/ImageKnife/issues) or a [PR](https://gitee.com/openharmony-tpc/ImageKnife/issues) to us.
|
||||||
|
|
14
README_zh.md
14
README_zh.md
|
@ -1,9 +1,3 @@
|
||||||
## 🚨 **重要提示 | IMPORTANT**
|
|
||||||
>
|
|
||||||
> **⚠️ 此代码仓已归档。新地址请访问 [ImageKnife](https://gitcode.com/openharmony-tpc/ImageKnife)。| ⚠️ This repository has been archived. For the new address, please visit [ImageKnife](https://gitcode.com/openharmony-tpc/ImageKnife).**
|
|
||||||
>
|
|
||||||
---
|
|
||||||
>
|
|
||||||
# ImageKnife
|
# ImageKnife
|
||||||
|
|
||||||
**专门为OpenHarmony打造的一款图像加载缓存库,致力于更高效、更轻便、更简单。**
|
**专门为OpenHarmony打造的一款图像加载缓存库,致力于更高效、更轻便、更简单。**
|
||||||
|
@ -463,14 +457,6 @@ async function custom(context: Context, src: string | PixelMap | Resource,header
|
||||||
在下述版本验证通过:
|
在下述版本验证通过:
|
||||||
DevEco Studio: NEXT Beta1-5.0.3.806, SDK: API12 Release(5.0.0.66)
|
DevEco Studio: NEXT Beta1-5.0.3.806, SDK: API12 Release(5.0.0.66)
|
||||||
|
|
||||||
## 关于混淆
|
|
||||||
- 代码混淆,请查看[代码混淆简介](https://docs.openharmony.cn/pages/v5.0/zh-cn/application-dev/arkts-utils/source-obfuscation.md)
|
|
||||||
- 如果希望imageknife库在代码混淆过程中不会被混淆,需要在混淆规则配置文件obfuscation-rules.txt中添加相应的排除规则:
|
|
||||||
|
|
||||||
```
|
|
||||||
-keep
|
|
||||||
./oh_modules/@ohos/imageknife
|
|
||||||
```
|
|
||||||
## 贡献代码
|
## 贡献代码
|
||||||
|
|
||||||
使用过程中发现任何问题都可以提 [issue](https://gitee.com/openharmony-tpc/ImageKnife/issues)
|
使用过程中发现任何问题都可以提 [issue](https://gitee.com/openharmony-tpc/ImageKnife/issues)
|
||||||
|
|
|
@ -16,6 +16,3 @@
|
||||||
# Keep options:
|
# Keep options:
|
||||||
# -keep-property-name: specifies property names that you want to keep
|
# -keep-property-name: specifies property names that you want to keep
|
||||||
# -keep-global-name: specifies names that you want to keep in the global scope
|
# -keep-global-name: specifies names that you want to keep in the global scope
|
||||||
|
|
||||||
-keep
|
|
||||||
./oh_modules/@ohos/imageknife
|
|
|
@ -12,47 +12,49 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
import { ImageKnifeComponent } from '@ohos/libraryimageknife';
|
import {
|
||||||
import { display } from '@kit.ArkUI';
|
ImageKnifeComponent,
|
||||||
|
ImageKnifeData,
|
||||||
|
ImageKnifeRequest, LogUtil
|
||||||
|
} from '@ohos/libraryimageknife';
|
||||||
|
|
||||||
@Entry
|
@Entry
|
||||||
@Component
|
@Component
|
||||||
struct AutoImageFit {
|
struct AutoImageFit {
|
||||||
@State imageWidth: number = 200;
|
@State width1: Length = '100%'
|
||||||
private maxWidth: number = px2vp(display.getDefaultDisplaySync().width);
|
|
||||||
|
|
||||||
build() {
|
build() {
|
||||||
|
Scroll() {
|
||||||
Column() {
|
|
||||||
this.Slider()
|
|
||||||
Column() {
|
Column() {
|
||||||
|
Button($r('app.string.adjust_size')).onClick(() => {
|
||||||
|
if (this.width1.toString() == '100%') {
|
||||||
|
this.width1 = '60%'
|
||||||
|
} else {
|
||||||
|
this.width1 = '100%'
|
||||||
|
}
|
||||||
|
}).width('100%')
|
||||||
Text('Image')
|
Text('Image')
|
||||||
Image('https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/56/v3/8MdhfSsCSMKj4sA6okUWrg/5uBx56tLTUO3RYQl-E5JiQ.jpg')
|
Image('https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/56/v3/8MdhfSsCSMKj4sA6okUWrg/5uBx56tLTUO3RYQl-E5JiQ.jpg').width('100%').objectFit(ImageFit.Auto)
|
||||||
.width('100%')
|
|
||||||
.objectFit(ImageFit.Auto)
|
|
||||||
Text('ImageKnife')
|
Text('ImageKnife')
|
||||||
ImageKnifeComponent({
|
ImageKnifeComponent({
|
||||||
imageKnifeOption: {
|
imageKnifeOption: {
|
||||||
loadSrc: 'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/56/v3/8MdhfSsCSMKj4sA6okUWrg/5uBx56tLTUO3RYQl-E5JiQ.jpg',
|
loadSrc: 'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/56/v3/8MdhfSsCSMKj4sA6okUWrg/5uBx56tLTUO3RYQl-E5JiQ.jpg',
|
||||||
objectFit: ImageFit.Auto,
|
objectFit: ImageFit.Auto,
|
||||||
|
onLoadListener: {
|
||||||
|
onLoadStart: (request?: ImageKnifeRequest) => {
|
||||||
|
LogUtil.info('onLoadStart')
|
||||||
|
},
|
||||||
|
onLoadSuccess: (data: string | PixelMap | undefined, imageKnifeData: ImageKnifeData,
|
||||||
|
request?: ImageKnifeRequest) => {
|
||||||
|
LogUtil.info('onLoadSuccess')
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}).width('100%')
|
}).width('100%')
|
||||||
}.width(this.imageWidth).border({ width: 1 })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Builder
|
}.width(this.width1).border({ width: 1 })
|
||||||
Slider() {
|
}
|
||||||
Slider({
|
|
||||||
value: this.imageWidth,
|
|
||||||
min: 100,
|
|
||||||
max: this.maxWidth,
|
|
||||||
style: SliderStyle.OutSet
|
|
||||||
})
|
|
||||||
.blockColor(Color.White)
|
|
||||||
.width('100%')
|
|
||||||
.onChange((value: number) => {
|
|
||||||
this.imageWidth = value;
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,93 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2024 Huawei Device Co., Ltd.
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { ImageKnifeComponent } from '@ohos/libraryimageknife'
|
|
||||||
@Entry
|
|
||||||
@Component
|
|
||||||
struct ErrorMessageDownload {
|
|
||||||
@State httpCode: string = ''
|
|
||||||
@State httpError: string = ''
|
|
||||||
@State storageError: string = ''
|
|
||||||
@State fileError: string = ''
|
|
||||||
@State notPic: string = ''
|
|
||||||
build() {
|
|
||||||
Column() {
|
|
||||||
Text(this.httpCode)
|
|
||||||
ImageKnifeComponent({
|
|
||||||
imageKnifeOption:{
|
|
||||||
loadSrc:'https://gitee.com/openharmony-tpc/ImageKnife/issues/1111111',
|
|
||||||
errorholderSrc:$r('app.media.failed'),
|
|
||||||
onLoadListener:{
|
|
||||||
onLoadFailed:(err)=>{
|
|
||||||
this.httpCode = err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}).width(100).height(100).margin({bottom:10})
|
|
||||||
|
|
||||||
Text(this.httpError)
|
|
||||||
ImageKnifeComponent({
|
|
||||||
imageKnifeOption:{
|
|
||||||
loadSrc:'https://xx.xx.xx',
|
|
||||||
errorholderSrc:$r('app.media.failed'),
|
|
||||||
onLoadListener:{
|
|
||||||
onLoadFailed:(err)=>{
|
|
||||||
this.httpError = err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}).width(100).height(100).margin({bottom:10})
|
|
||||||
|
|
||||||
Text(this.storageError)
|
|
||||||
ImageKnifeComponent({
|
|
||||||
imageKnifeOption:{
|
|
||||||
loadSrc:'/data/storage/el2/base/haps/entry/cache/a/b',
|
|
||||||
errorholderSrc:$r('app.media.failed'),
|
|
||||||
onLoadListener:{
|
|
||||||
onLoadFailed:(err)=>{
|
|
||||||
this.storageError = err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}).width(100).height(100).margin({bottom:10})
|
|
||||||
|
|
||||||
Text(this.fileError)
|
|
||||||
ImageKnifeComponent({
|
|
||||||
imageKnifeOption:{
|
|
||||||
loadSrc:'file://xx.xx.xx',
|
|
||||||
errorholderSrc:$r('app.media.failed'),
|
|
||||||
onLoadListener:{
|
|
||||||
onLoadFailed:(err)=>{
|
|
||||||
this.fileError = err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}).width(100).height(100).margin({bottom:10})
|
|
||||||
|
|
||||||
Text(this.notPic)
|
|
||||||
ImageKnifeComponent({
|
|
||||||
imageKnifeOption:{
|
|
||||||
loadSrc:'xx.xx.xx',
|
|
||||||
errorholderSrc:$r('app.media.failed'),
|
|
||||||
onLoadListener:{
|
|
||||||
onLoadFailed:(err)=>{
|
|
||||||
this.notPic = err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}).width(100).height(100).margin({bottom:10})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -398,13 +398,13 @@ struct ImageTransformation {
|
||||||
transformations.push(new CropSquareTransformation());
|
transformations.push(new CropSquareTransformation());
|
||||||
}
|
}
|
||||||
if (this.isCropTop) {
|
if (this.isCropTop) {
|
||||||
transformations.push(new CropTransformation(100, 100, 0));
|
transformations.push(new CropTransformation(25, 25, 0));
|
||||||
}
|
}
|
||||||
if (this.isCropCenter) {
|
if (this.isCropCenter) {
|
||||||
transformations.push(new CropTransformation(100, 100, 1));
|
transformations.push(new CropTransformation(25, 25, 1));
|
||||||
}
|
}
|
||||||
if (this.isCropBottom) {
|
if (this.isCropBottom) {
|
||||||
transformations.push(new CropTransformation(100, 100, 2));
|
transformations.push(new CropTransformation(25, 25, 2));
|
||||||
}
|
}
|
||||||
if (this.isSepia) {
|
if (this.isSepia) {
|
||||||
transformations.push(new SepiaTransformation());
|
transformations.push(new SepiaTransformation());
|
||||||
|
|
|
@ -88,11 +88,6 @@ struct Index {
|
||||||
|
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
Button($r('app.string.Error_Message')).margin({top:10}).onClick(()=>{
|
|
||||||
router.push({
|
|
||||||
uri: 'pages/ErrorMessageDownload',
|
|
||||||
});
|
|
||||||
})
|
|
||||||
Button($r('app.string.Test_custom_download')).margin({top:10}).onClick(()=>{
|
Button($r('app.string.Test_custom_download')).margin({top:10}).onClick(()=>{
|
||||||
router.push({
|
router.push({
|
||||||
uri: 'pages/TestSetCustomImagePage',
|
uri: 'pages/TestSetCustomImagePage',
|
||||||
|
@ -224,11 +219,6 @@ struct Index {
|
||||||
|
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
Button($r('app.string.test_exif')).margin({ top: 10 }).onClick(() => {
|
|
||||||
router.push({
|
|
||||||
uri: 'pages/TestImageExif',
|
|
||||||
});
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
} .width('100%')
|
} .width('100%')
|
||||||
.height('100%')
|
.height('100%')
|
||||||
|
|
|
@ -108,7 +108,7 @@ struct MultipleImageCallBack {
|
||||||
console.log('image load multiple loadFail:' + this.failIndex)
|
console.log('image load multiple loadFail:' + this.failIndex)
|
||||||
},
|
},
|
||||||
onLoadCancel:(message,request)=>{
|
onLoadCancel:(message,request)=>{
|
||||||
let flag = request?.imageKnifeData?.timeInfo?.netRequestStartTime ? true : false
|
let flag = request?.imageKnifeData?.type ? true : false
|
||||||
if (flag) {
|
if (flag) {
|
||||||
this.cancelLoadIndex++
|
this.cancelLoadIndex++
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1,92 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2025 Huawei Device Co., Ltd.
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
import { ImageKnifeComponent } from '@ohos/libraryimageknife';
|
|
||||||
import fs from '@ohos.file.fs';
|
|
||||||
|
|
||||||
@Entry
|
|
||||||
@Component
|
|
||||||
struct LocalImage {
|
|
||||||
scroller: Scroller = new Scroller;
|
|
||||||
|
|
||||||
build() {
|
|
||||||
Scroll(this.scroller) {
|
|
||||||
Column() {
|
|
||||||
Column() {
|
|
||||||
Text($r('app.string.base_image'))
|
|
||||||
.fontSize(20)
|
|
||||||
.fontWeight(FontWeight.Bold)
|
|
||||||
Row() {
|
|
||||||
Image($rawfile('rotate/rotate.jpg')).width(100).height(100).margin({ right: 10 })
|
|
||||||
ImageKnifeComponent({
|
|
||||||
imageKnifeOption: {
|
|
||||||
loadSrc: $rawfile('rotate/rotate.jpg'),
|
|
||||||
objectFit: ImageFit.Contain
|
|
||||||
}
|
|
||||||
}).width(100).height(100)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.margin({ bottom: 20 })
|
|
||||||
|
|
||||||
Column() {
|
|
||||||
Text($r('app.string.rotate_mirror'))
|
|
||||||
.fontSize(20)
|
|
||||||
.fontWeight(FontWeight.Bold)
|
|
||||||
Row() {
|
|
||||||
Image($rawfile('rotate/rotate_mirror.jpg')).width(100).height(100).margin({ right: 10 })
|
|
||||||
ImageKnifeComponent({
|
|
||||||
imageKnifeOption: {
|
|
||||||
loadSrc: $rawfile('rotate/rotate_mirror.jpg'),
|
|
||||||
objectFit: ImageFit.Contain
|
|
||||||
}
|
|
||||||
}).width(100).height(100)
|
|
||||||
}
|
|
||||||
}.margin({ bottom: 20 })
|
|
||||||
|
|
||||||
Column() {
|
|
||||||
Text($r('app.string.rotate_rotate90'))
|
|
||||||
.fontSize(20)
|
|
||||||
.fontWeight(FontWeight.Bold)
|
|
||||||
Row() {
|
|
||||||
Image($rawfile('rotate/rotate_rotate90.jpg')).width(100).height(100).margin({ right: 10 })
|
|
||||||
ImageKnifeComponent({
|
|
||||||
imageKnifeOption: {
|
|
||||||
loadSrc: $rawfile('rotate/rotate_rotate90.jpg'),
|
|
||||||
objectFit: ImageFit.Contain
|
|
||||||
}
|
|
||||||
}).width(100).height(100)
|
|
||||||
}
|
|
||||||
}.margin({ bottom: 20 })
|
|
||||||
|
|
||||||
Column() {
|
|
||||||
Text($r('app.string.rotate_mirror_rotate270'))
|
|
||||||
.fontSize(20)
|
|
||||||
.fontWeight(FontWeight.Bold)
|
|
||||||
Row() {
|
|
||||||
Image($rawfile('rotate/rotate_mirror_rotate270.jpg')).width(100).height(100).margin({ right: 10 })
|
|
||||||
ImageKnifeComponent({
|
|
||||||
imageKnifeOption: {
|
|
||||||
loadSrc: $rawfile('rotate/rotate_mirror_rotate270.jpg'),
|
|
||||||
objectFit: ImageFit.Contain
|
|
||||||
}
|
|
||||||
}).width(100).height(100)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.width('100%')
|
|
||||||
}
|
|
||||||
.height('100%')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -6,11 +6,7 @@
|
||||||
"mainElement": "EntryAbility",
|
"mainElement": "EntryAbility",
|
||||||
"deviceTypes": [
|
"deviceTypes": [
|
||||||
"default",
|
"default",
|
||||||
"tablet",
|
"tablet"
|
||||||
"tv",
|
|
||||||
"wearable",
|
|
||||||
"car",
|
|
||||||
"2in1"
|
|
||||||
],
|
],
|
||||||
"deliveryWithInstall": true,
|
"deliveryWithInstall": true,
|
||||||
"installationFree": false,
|
"installationFree": false,
|
||||||
|
|
|
@ -683,30 +683,6 @@
|
||||||
{
|
{
|
||||||
"name": "Multiple_CallBack",
|
"name": "Multiple_CallBack",
|
||||||
"value": "Multiple image callback"
|
"value": "Multiple image callback"
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Error_Message",
|
|
||||||
"value": "error message"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "test_exif",
|
|
||||||
"value": "Test display orientation base on the EXIF metadata "
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "base_image",
|
|
||||||
"value": "The image don't carry rotation information"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "rotate_mirror",
|
|
||||||
"value": "Mirror horizontal"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "rotate_rotate90",
|
|
||||||
"value": "Rotate 90°"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "rotate_mirror_rotate270",
|
|
||||||
"value": "Mirror horizontal and rotate 270°"
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
|
@ -41,8 +41,6 @@
|
||||||
"pages/AutoImageFit",
|
"pages/AutoImageFit",
|
||||||
"pages/SingleImageCallBack",
|
"pages/SingleImageCallBack",
|
||||||
"pages/MultipleImageCallBack",
|
"pages/MultipleImageCallBack",
|
||||||
"pages/LocalImage",
|
"pages/LocalImage"
|
||||||
"pages/ErrorMessageDownload",
|
|
||||||
"pages/TestImageExif"
|
|
||||||
]
|
]
|
||||||
}
|
}
|
Binary file not shown.
Before Width: | Height: | Size: 22 KiB |
Binary file not shown.
Before Width: | Height: | Size: 22 KiB |
Binary file not shown.
Before Width: | Height: | Size: 22 KiB |
Binary file not shown.
Before Width: | Height: | Size: 22 KiB |
|
@ -675,30 +675,6 @@
|
||||||
{
|
{
|
||||||
"name": "Multiple_CallBack",
|
"name": "Multiple_CallBack",
|
||||||
"value": "多张图片回调"
|
"value": "多张图片回调"
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Error_Message",
|
|
||||||
"value": "错误信息"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "base_image",
|
|
||||||
"value": "图片不携带旋转信息"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "test_exif",
|
|
||||||
"value": "测试图片携带的EXIF元数据作为显示方向"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "rotate_mirror",
|
|
||||||
"value": "水平翻转"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "rotate_rotate90",
|
|
||||||
"value": "顺时针90°"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "rotate_mirror_rotate270",
|
|
||||||
"value": "水平翻转后再顺时针270°"
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
|
@ -6,11 +6,7 @@
|
||||||
"mainElement": "TestAbility",
|
"mainElement": "TestAbility",
|
||||||
"deviceTypes": [
|
"deviceTypes": [
|
||||||
"default",
|
"default",
|
||||||
"tablet",
|
"tablet"
|
||||||
"tv",
|
|
||||||
"wearable",
|
|
||||||
"car",
|
|
||||||
"2in1"
|
|
||||||
],
|
],
|
||||||
"deliveryWithInstall": true,
|
"deliveryWithInstall": true,
|
||||||
"installationFree": false,
|
"installationFree": false,
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
"main": "index.ets",
|
"main": "index.ets",
|
||||||
"repository": "https://gitee.com/openharmony-tpc/ImageKnife",
|
"repository": "https://gitee.com/openharmony-tpc/ImageKnife",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"version": "3.2.2-rc.1",
|
"version": "3.2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ohos/gpu_transform": "^1.0.2"
|
"@ohos/gpu_transform": "^1.0.2"
|
||||||
},
|
},
|
||||||
|
|
|
@ -25,7 +25,6 @@ import { util } from '@kit.ArkTS';
|
||||||
import { image } from '@kit.ImageKit';
|
import { image } from '@kit.ImageKit';
|
||||||
import { common } from '@kit.AbilityKit';
|
import { common } from '@kit.AbilityKit';
|
||||||
import { LogUtil } from './utils/LogUtil';
|
import { LogUtil } from './utils/LogUtil';
|
||||||
import { emitter } from '@kit.BasicServicesKit';
|
|
||||||
|
|
||||||
|
|
||||||
export class ImageKnife {
|
export class ImageKnife {
|
||||||
|
@ -177,9 +176,6 @@ export class ImageKnife {
|
||||||
* @param request 图片请求request
|
* @param request 图片请求request
|
||||||
*/
|
*/
|
||||||
cancel(request:ImageKnifeRequest) {
|
cancel(request:ImageKnifeRequest) {
|
||||||
if (typeof request?.imageKnifeOption.loadSrc === 'string' && !request?.drawMainSuccess) {
|
|
||||||
emitter.emit(request.imageKnifeOption.loadSrc + request.componentId)
|
|
||||||
}
|
|
||||||
request.requestState = ImageKnifeRequestState.DESTROY
|
request.requestState = ImageKnifeRequestState.DESTROY
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
|
@ -466,12 +462,12 @@ export class ImageKnife {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
async execute(request: ImageKnifeRequest): Promise<void> {
|
async execute(request: ImageKnifeRequest,isAnimator?: boolean): Promise<void> {
|
||||||
LogUtil.log('ImageKnife_DataTime_execute.start:'+request.imageKnifeOption.loadSrc)
|
LogUtil.log('ImageKnife_DataTime_execute.start:'+request.imageKnifeOption.loadSrc)
|
||||||
if (this.headerMap.size > 0) {
|
if (this.headerMap.size > 0) {
|
||||||
request.addHeaderMap(this.headerMap)
|
request.addHeaderMap(this.headerMap)
|
||||||
}
|
}
|
||||||
this.dispatcher.enqueue(request)
|
this.dispatcher.enqueue(request,isAnimator)
|
||||||
LogUtil.log('ImageKnife_DataTime_execute.end:'+request.imageKnifeOption.loadSrc)
|
LogUtil.log('ImageKnife_DataTime_execute.end:'+request.imageKnifeOption.loadSrc)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -51,7 +51,7 @@ export class ImageKnifeDispatcher {
|
||||||
LogUtil.log('showFromMemomry.start:' + request.componentId + ',srcType:' + requestSource + ',version:' + request.componentVersion + ' isAnimator=' + isAnimator)
|
LogUtil.log('showFromMemomry.start:' + request.componentId + ',srcType:' + requestSource + ',version:' + request.componentVersion + ' isAnimator=' + isAnimator)
|
||||||
let memoryCache: ImageKnifeData | undefined;
|
let memoryCache: ImageKnifeData | undefined;
|
||||||
let memoryCheckStartTime = Date.now();
|
let memoryCheckStartTime = Date.now();
|
||||||
if ((typeof (request.imageKnifeOption.loadSrc as image.PixelMap)?.isEditable) == 'boolean') {
|
if ((typeof (request.imageKnifeOption.loadSrc as image.PixelMap).isEditable) == 'boolean') {
|
||||||
memoryCache = {
|
memoryCache = {
|
||||||
source: request.imageKnifeOption.loadSrc as image.PixelMap,
|
source: request.imageKnifeOption.loadSrc as image.PixelMap,
|
||||||
imageWidth: 0,
|
imageWidth: 0,
|
||||||
|
@ -87,7 +87,6 @@ export class ImageKnifeDispatcher {
|
||||||
|
|
||||||
if (requestSource == ImageKnifeRequestSource.SRC) {
|
if (requestSource == ImageKnifeRequestSource.SRC) {
|
||||||
request.requestState = ImageKnifeRequestState.COMPLETE
|
request.requestState = ImageKnifeRequestState.COMPLETE
|
||||||
request.drawMainSuccess = true
|
|
||||||
// 回调请求开结束
|
// 回调请求开结束
|
||||||
if (request.imageKnifeOption.onLoadListener?.onLoadSuccess !== undefined) {
|
if (request.imageKnifeOption.onLoadListener?.onLoadSuccess !== undefined) {
|
||||||
this.copyMemoryCacheInfo(memoryCache, request.imageKnifeData);
|
this.copyMemoryCacheInfo(memoryCache, request.imageKnifeData);
|
||||||
|
@ -151,11 +150,11 @@ export class ImageKnifeDispatcher {
|
||||||
request.imageKnifeData = callBackData;
|
request.imageKnifeData = callBackData;
|
||||||
}
|
}
|
||||||
|
|
||||||
enqueue(request: ImageKnifeRequest,): void {
|
enqueue(request: ImageKnifeRequest,isAnimator?: boolean): void {
|
||||||
//初始化加载回调信息
|
//初始化加载回调信息
|
||||||
this.initCallData(request);
|
this.initCallData(request);
|
||||||
//1.内存有的话直接渲染
|
//1.内存有的话直接渲染
|
||||||
if (this.showFromMemomry(request, request.imageKnifeOption.loadSrc, ImageKnifeRequestSource.SRC,request.animator)) {
|
if (this.showFromMemomry(request, request.imageKnifeOption.loadSrc, ImageKnifeRequestSource.SRC,isAnimator)) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// 2.内存获取占位图
|
// 2.内存获取占位图
|
||||||
|
@ -169,20 +168,18 @@ export class ImageKnifeDispatcher {
|
||||||
this.jobQueue.add(request)
|
this.jobQueue.add(request)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
this.executeJob(request)
|
this.executeJob(request,isAnimator)
|
||||||
}
|
}
|
||||||
|
|
||||||
executeJob(request: ImageKnifeRequest): void {
|
executeJob(request: ImageKnifeRequest,isAnimator?: boolean): void {
|
||||||
LogUtil.log('executeJob.start:' + request.componentId + ',version:' + request.componentVersion)
|
LogUtil.log('executeJob.start:' + request.componentId + ',version:' + request.componentVersion)
|
||||||
// 加载占位符
|
// 加载占位符
|
||||||
if (request.imageKnifeOption.placeholderSrc !== undefined && request.drawPlayHolderSuccess == false) {
|
if (request.imageKnifeOption.placeholderSrc !== undefined && request.drawPlayHolderSuccess == false) {
|
||||||
this.getAndShowImage(request, request.imageKnifeOption.placeholderSrc, ImageKnifeRequestSource.PLACE_HOLDER)
|
this.getAndShowImage(request, request.imageKnifeOption.placeholderSrc, ImageKnifeRequestSource.PLACE_HOLDER)
|
||||||
}
|
}
|
||||||
if (request.imageKnifeOption.onLoadListener?.onLoadStart !== undefined) {
|
|
||||||
request.imageKnifeOption.onLoadListener?.onLoadStart(request)
|
|
||||||
}
|
|
||||||
// 加载主图
|
// 加载主图
|
||||||
this.getAndShowImage(request, request.imageKnifeOption.loadSrc, ImageKnifeRequestSource.SRC,request.animator)
|
this.getAndShowImage(request, request.imageKnifeOption.loadSrc, ImageKnifeRequestSource.SRC,isAnimator)
|
||||||
LogUtil.log('executeJob.end:' + request.componentId + ',version:' + request.componentVersion)
|
LogUtil.log('executeJob.end:' + request.componentId + ',version:' + request.componentVersion)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -191,6 +188,9 @@ export class ImageKnifeDispatcher {
|
||||||
*/
|
*/
|
||||||
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('getAndShowImage.start:' + currentRequest.componentId + ',srcType:' + requestSource + ',version:' + currentRequest.componentVersion)
|
LogUtil.log('getAndShowImage.start:' + currentRequest.componentId + ',srcType:' + requestSource + ',version:' + currentRequest.componentVersion)
|
||||||
|
if (requestSource === ImageKnifeRequestSource.SRC && currentRequest.imageKnifeOption.onLoadListener?.onLoadStart !== undefined) {
|
||||||
|
currentRequest.imageKnifeOption.onLoadListener?.onLoadStart(currentRequest)
|
||||||
|
}
|
||||||
|
|
||||||
let memoryKey: string = this.engineKey.generateMemoryKey(imageSrc, requestSource, currentRequest.imageKnifeOption,isAnimator, currentRequest.componentWidth, currentRequest.componentHeight)
|
let memoryKey: string = this.engineKey.generateMemoryKey(imageSrc, requestSource, currentRequest.imageKnifeOption,isAnimator, currentRequest.componentWidth, currentRequest.componentHeight)
|
||||||
let requestList: List<ImageKnifeRequestWithSource> | undefined = this.executingJobMap.get(memoryKey)
|
let requestList: List<ImageKnifeRequestWithSource> | undefined = this.executingJobMap.get(memoryKey)
|
||||||
|
@ -214,7 +214,9 @@ export class ImageKnifeDispatcher {
|
||||||
if((imageSrc as Resource).id != undefined) {
|
if((imageSrc as Resource).id != undefined) {
|
||||||
moduleName = (imageSrc as Resource).moduleName
|
moduleName = (imageSrc as Resource).moduleName
|
||||||
src = (imageSrc as Resource).id
|
src = (imageSrc as Resource).id
|
||||||
|
if(src == -1) {
|
||||||
resName = (imageSrc as Resource).params![0]
|
resName = (imageSrc as Resource).params![0]
|
||||||
|
}
|
||||||
} else if(typeof imageSrc == 'string') {
|
} else if(typeof imageSrc == 'string') {
|
||||||
src = imageSrc
|
src = imageSrc
|
||||||
}
|
}
|
||||||
|
@ -353,64 +355,17 @@ export class ImageKnifeDispatcher {
|
||||||
}
|
}
|
||||||
|
|
||||||
let pixelmap = requestJobResult.pixelMap;
|
let pixelmap = requestJobResult.pixelMap;
|
||||||
// 请求取消
|
|
||||||
if (currentRequest.requestState === ImageKnifeRequestState.DESTROY) {
|
|
||||||
this.executingJobMap.remove(memoryKey);
|
|
||||||
requestList.forEach((requestWithSource: ImageKnifeRequestWithSource) => {
|
|
||||||
if (currentRequest.componentId !== requestWithSource.request.componentId && requestWithSource.request.requestState !== ImageKnifeRequestState.DESTROY) {
|
|
||||||
// 加载占位符
|
|
||||||
if (requestWithSource.source === ImageKnifeRequestSource.PLACE_HOLDER &&
|
|
||||||
requestWithSource.request.imageKnifeOption.placeholderSrc !== undefined &&
|
|
||||||
requestWithSource.request.drawPlayHolderSuccess == false) {
|
|
||||||
this.getAndShowImage(requestWithSource.request, requestWithSource.request.imageKnifeOption.placeholderSrc, ImageKnifeRequestSource.PLACE_HOLDER)
|
|
||||||
} else if (requestWithSource.source === ImageKnifeRequestSource.ERROR_HOLDER &&
|
|
||||||
requestWithSource.request.imageKnifeOption.errorholderSrc !== undefined) {
|
|
||||||
this.getAndShowImage(requestWithSource.request, requestWithSource.request.imageKnifeOption.errorholderSrc, ImageKnifeRequestSource.ERROR_HOLDER)
|
|
||||||
} else if (requestWithSource.source === ImageKnifeRequestSource.SRC) {
|
|
||||||
// 加载主图
|
|
||||||
this.getAndShowImage(requestWithSource.request, requestWithSource.request.imageKnifeOption.loadSrc, ImageKnifeRequestSource.SRC,requestWithSource.request.animator)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (pixelmap !== undefined && typeof pixelmap !== 'string') {
|
|
||||||
(pixelmap as PixelMap).release()
|
|
||||||
}
|
|
||||||
if (requestWithSource.source == ImageKnifeRequestSource.SRC && requestWithSource.request.imageKnifeOption.onLoadListener?.onLoadCancel) {
|
|
||||||
// 回调请求成功
|
|
||||||
// 回调请求成功
|
|
||||||
//设置失败回调的时间点
|
|
||||||
let callBackData = requestWithSource.request.imageKnifeData;
|
|
||||||
|
|
||||||
if (requestJobResult.imageKnifeData && requestJobResult.imageKnifeData.timeInfo) {
|
|
||||||
requestJobResult.imageKnifeData.timeInfo.requestCancelTime = Date.now();
|
|
||||||
if (requestJobResult.imageKnifeData.errorInfo) {
|
|
||||||
requestJobResult.imageKnifeData.errorInfo.phase = LoadPhase.PHASE_WILL_SHOW;
|
|
||||||
requestJobResult.imageKnifeData.errorInfo.code = LoadPixelMapCode.IMAGE_LOAD_CANCEL_FAILED_CODE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.assembleImageKnifeData(callBackData,requestJobResult.imageKnifeData,requestWithSource.request)
|
|
||||||
LogUtil.log('getAndShowImage cancel:' + requestWithSource.request.componentId + ',srcType:' + requestSource + ',version:' + requestWithSource.request.componentVersion)
|
|
||||||
requestWithSource.request.imageKnifeOption.onLoadListener.onLoadCancel(requestJobResult.loadFail ?? 'component has destroyed from load', requestWithSource.request)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
this.dispatchNextJob()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// 请求失败
|
|
||||||
if (pixelmap === undefined) {
|
if (pixelmap === undefined) {
|
||||||
this.executingJobMap.remove(memoryKey);
|
this.executingJobMap.remove(memoryKey);
|
||||||
requestList.forEach((requestWithSource: ImageKnifeRequestWithSource) => {
|
requestList.forEach((requestWithSource: ImageKnifeRequestWithSource) => {
|
||||||
requestWithSource.request.requestState = ImageKnifeRequestState.ERROR
|
requestWithSource.request.requestState = ImageKnifeRequestState.ERROR
|
||||||
LogUtil.error('getAndShowImage_CallBack.pixelmap failed:' + currentRequest.componentId + ',srcType:' +
|
LogUtil.error('getAndShowImage_CallBack.pixelmap failed:' + currentRequest.componentId + ',srcType:' + requestSource + ',version:' + currentRequest.componentVersion + " error: " + requestJobResult.loadFail)
|
||||||
requestSource + ',version:' + currentRequest.componentVersion + " error: " + requestJobResult.loadFail)
|
|
||||||
// 回调请求失败
|
// 回调请求失败
|
||||||
if (requestWithSource.source === ImageKnifeRequestSource.SRC &&
|
if (requestWithSource.source === ImageKnifeRequestSource.SRC &&
|
||||||
requestWithSource.request.imageKnifeOption.onLoadListener?.onLoadFailed !== undefined &&
|
requestWithSource.request.imageKnifeOption.onLoadListener?.onLoadFailed !== undefined &&
|
||||||
requestJobResult.loadFail) {
|
requestJobResult.loadFail) {
|
||||||
this.assembleImageKnifeData(requestWithSource.request.imageKnifeData, requestJobResult.imageKnifeData,
|
this.assembleImageKnifeData(requestWithSource.request.imageKnifeData, requestJobResult.imageKnifeData, requestWithSource.request)
|
||||||
requestWithSource.request)
|
requestWithSource.request.imageKnifeOption.onLoadListener.onLoadFailed(requestJobResult.loadFail,requestWithSource.request);
|
||||||
requestWithSource.request.imageKnifeOption.onLoadListener.onLoadFailed(requestJobResult.loadFail,
|
|
||||||
requestWithSource.request);
|
|
||||||
}
|
}
|
||||||
if (requestWithSource.source === ImageKnifeRequestSource.SRC &&
|
if (requestWithSource.source === ImageKnifeRequestSource.SRC &&
|
||||||
requestWithSource.request.imageKnifeOption.errorholderSrc !== undefined) {
|
requestWithSource.request.imageKnifeOption.errorholderSrc !== undefined) {
|
||||||
|
@ -459,8 +414,8 @@ export class ImageKnifeDispatcher {
|
||||||
//构建缓存保存的ImageKnifeData
|
//构建缓存保存的ImageKnifeData
|
||||||
let saveCacheImageData: ImageKnifeData = {
|
let saveCacheImageData: ImageKnifeData = {
|
||||||
source: pixelmap!,
|
source: pixelmap!,
|
||||||
imageWidth: requestJobResult.size?.width ?? 0,
|
imageWidth: requestJobResult.size == undefined ? 0 : requestJobResult.size.width,
|
||||||
imageHeight: requestJobResult.size?.height ?? 0,
|
imageHeight: requestJobResult.size == undefined ? 0 : requestJobResult.size.height,
|
||||||
type: requestJobResult.type,
|
type: requestJobResult.type,
|
||||||
bufSize: requestJobResult.bufferSize,
|
bufSize: requestJobResult.bufferSize,
|
||||||
imageAnimator: imageKnifeData.imageAnimator
|
imageAnimator: imageKnifeData.imageAnimator
|
||||||
|
@ -477,6 +432,7 @@ export class ImageKnifeDispatcher {
|
||||||
if (requestList !== undefined) {
|
if (requestList !== undefined) {
|
||||||
// key相同的request,一起绘制
|
// key相同的request,一起绘制
|
||||||
requestList.forEach((requestWithSource: ImageKnifeRequestWithSource) => {
|
requestList.forEach((requestWithSource: ImageKnifeRequestWithSource) => {
|
||||||
|
if (requestWithSource.request.requestState !== ImageKnifeRequestState.DESTROY) {
|
||||||
// 画主图
|
// 画主图
|
||||||
if (requestWithSource.source === ImageKnifeRequestSource.SRC ||
|
if (requestWithSource.source === ImageKnifeRequestSource.SRC ||
|
||||||
requestWithSource.source === ImageKnifeRequestSource.ERROR_HOLDER
|
requestWithSource.source === ImageKnifeRequestSource.ERROR_HOLDER
|
||||||
|
@ -489,19 +445,37 @@ export class ImageKnifeDispatcher {
|
||||||
|
|
||||||
if (requestWithSource.source == ImageKnifeRequestSource.SRC) {
|
if (requestWithSource.source == ImageKnifeRequestSource.SRC) {
|
||||||
requestWithSource.request.requestState = ImageKnifeRequestState.COMPLETE;
|
requestWithSource.request.requestState = ImageKnifeRequestState.COMPLETE;
|
||||||
requestWithSource.request.drawMainSuccess = true
|
|
||||||
if (requestWithSource.request.imageKnifeOption.onLoadListener &&
|
if (requestWithSource.request.imageKnifeOption.onLoadListener &&
|
||||||
requestWithSource.request.imageKnifeOption.onLoadListener.onLoadSuccess) {
|
requestWithSource.request.imageKnifeOption.onLoadListener.onLoadSuccess) {
|
||||||
// 回调请求成功
|
// 回调请求成功
|
||||||
this.assembleImageKnifeData(requestWithSource.request.imageKnifeData, imageKnifeData,
|
this.assembleImageKnifeData(requestWithSource.request.imageKnifeData, imageKnifeData,requestWithSource.request);
|
||||||
requestWithSource.request);
|
|
||||||
requestWithSource.request.imageKnifeOption.onLoadListener.onLoadSuccess(imageKnifeData.source,
|
requestWithSource.request.imageKnifeOption.onLoadListener.onLoadSuccess(imageKnifeData.source,
|
||||||
saveCacheImageData, requestWithSource.request);
|
saveCacheImageData, requestWithSource.request);
|
||||||
}
|
}
|
||||||
} else if (requestWithSource.source == ImageKnifeRequestSource.ERROR_HOLDER) {
|
} else if (requestWithSource.source == ImageKnifeRequestSource.ERROR_HOLDER) {
|
||||||
requestWithSource.request.requestState = ImageKnifeRequestState.ERROR;
|
requestWithSource.request.requestState = ImageKnifeRequestState.ERROR;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
if (requestWithSource.source == ImageKnifeRequestSource.SRC && requestWithSource.request.imageKnifeOption.onLoadListener?.onLoadCancel) {
|
||||||
|
// 回调请求成功
|
||||||
|
// 回调请求成功
|
||||||
|
//设置失败回调的时间点
|
||||||
|
let callBackData = requestWithSource.request.imageKnifeData;
|
||||||
|
|
||||||
|
if (requestJobResult.imageKnifeData && requestJobResult.imageKnifeData.timeInfo) {
|
||||||
|
requestJobResult.imageKnifeData.timeInfo.requestCancelTime = Date.now();
|
||||||
|
if (requestJobResult.imageKnifeData.errorInfo) {
|
||||||
|
requestJobResult.imageKnifeData.errorInfo.phase = LoadPhase.PHASE_WILL_SHOW;
|
||||||
|
requestJobResult.imageKnifeData.errorInfo.code = LoadPixelMapCode.IMAGE_LOAD_CANCEL_FAILED_CODE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.assembleImageKnifeData(callBackData,requestJobResult.imageKnifeData,requestWithSource.request)
|
||||||
|
LogUtil.log('getAndShowImage cancel:' + requestWithSource.request.componentId + ',srcType:' + requestSource + ',version:' + requestWithSource.request.componentVersion)
|
||||||
|
requestWithSource.request.imageKnifeOption.onLoadListener.onLoadCancel('component has destroyed from load', requestWithSource.request)
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
this.executingJobMap.remove(memoryKey);
|
this.executingJobMap.remove(memoryKey);
|
||||||
this.dispatchNextJob();
|
this.dispatchNextJob();
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -16,7 +16,6 @@ import {
|
||||||
CacheStrategy,
|
CacheStrategy,
|
||||||
DecodeImageInfo,
|
DecodeImageInfo,
|
||||||
ErrorInfo,
|
ErrorInfo,
|
||||||
FlipRotate,
|
|
||||||
ImageKnifeData,
|
ImageKnifeData,
|
||||||
ImageKnifeRequestSource,
|
ImageKnifeRequestSource,
|
||||||
ImageKnifeRequestWithSource, RequestJobRequest,
|
ImageKnifeRequestWithSource, RequestJobRequest,
|
||||||
|
@ -37,7 +36,6 @@ import { FileTypeUtil } from './utils/FileTypeUtil';
|
||||||
import { DownsampleStrategy } from './downsampling/DownsampleStartegy';
|
import { DownsampleStrategy } from './downsampling/DownsampleStartegy';
|
||||||
import { Downsampler } from './downsampling/Downsampler';
|
import { Downsampler } from './downsampling/Downsampler';
|
||||||
import { common } from '@kit.AbilityKit';
|
import { common } from '@kit.AbilityKit';
|
||||||
import { ImageLoaderFactory } from './loaderStrategy/ImageLoaderFactory';
|
|
||||||
|
|
||||||
class RequestData {
|
class RequestData {
|
||||||
receiveSize: number = 2000
|
receiveSize: number = 2000
|
||||||
|
@ -165,14 +163,6 @@ export class ImageKnifeLoader {
|
||||||
}
|
}
|
||||||
timeInfo.decodeStartTime = Date.now();
|
timeInfo.decodeStartTime = Date.now();
|
||||||
|
|
||||||
// 获取旋转信息
|
|
||||||
let exif: string | undefined = undefined;
|
|
||||||
await imageSource.getImageProperty(image.PropertyKey.ORIENTATION).then((res)=>{
|
|
||||||
exif = res;
|
|
||||||
}).catch((error: BusinessError)=>{
|
|
||||||
LogUtil.info("The normal image don't have rotation information, " + error.message);
|
|
||||||
})
|
|
||||||
|
|
||||||
await imageSource.createPixelMap(decodingOptions)
|
await imageSource.createPixelMap(decodingOptions)
|
||||||
.then((pixelmap: PixelMap) => {
|
.then((pixelmap: PixelMap) => {
|
||||||
timeInfo.decodeEndTime = Date.now();
|
timeInfo.decodeEndTime = Date.now();
|
||||||
|
@ -195,17 +185,6 @@ export class ImageKnifeLoader {
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
LogUtil.error('PixelMap setTransferDetached failed:' + JSON.stringify(e))
|
LogUtil.error('PixelMap setTransferDetached failed:' + JSON.stringify(e))
|
||||||
}
|
}
|
||||||
// 设置翻转和旋转角度
|
|
||||||
if(exif && exif !== 'Top-left'){
|
|
||||||
let result = ImageKnifeLoader.getOrientation(exif);
|
|
||||||
if(result.horizontal || result.vertical) {
|
|
||||||
resPixelmap?.flipSync(result.horizontal, result.vertical);
|
|
||||||
}
|
|
||||||
if(result.rotate > 0) {
|
|
||||||
resPixelmap?.rotateSync(result.rotate);
|
|
||||||
}
|
|
||||||
LogUtil.log('The normal image set flip , horizontal=' + result.horizontal + ', vertical=' +result.vertical + ', rotate=' + result.rotate);
|
|
||||||
}
|
|
||||||
|
|
||||||
//获取各个pixelMap的大小
|
//获取各个pixelMap的大小
|
||||||
if (resPixelmap !== undefined) {
|
if (resPixelmap !== undefined) {
|
||||||
|
@ -273,15 +252,6 @@ export class ImageKnifeLoader {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
timeInfo.decodeStartTime = Date.now();
|
timeInfo.decodeStartTime = Date.now();
|
||||||
|
|
||||||
// 获取旋转信息
|
|
||||||
let exif: string | undefined = undefined;
|
|
||||||
await imageSource.getImageProperty(image.PropertyKey.ORIENTATION).then((res)=>{
|
|
||||||
exif = res;
|
|
||||||
}).catch((error: BusinessError)=>{
|
|
||||||
LogUtil.info("Svg image don't have rotation information, " + error.message);
|
|
||||||
})
|
|
||||||
|
|
||||||
await imageSource.createPixelMap(opts)
|
await imageSource.createPixelMap(opts)
|
||||||
.then((pixelmap: PixelMap) => {
|
.then((pixelmap: PixelMap) => {
|
||||||
timeInfo.decodeEndTime = Date.now();
|
timeInfo.decodeEndTime = Date.now();
|
||||||
|
@ -289,17 +259,6 @@ export class ImageKnifeLoader {
|
||||||
imageSource.release()
|
imageSource.release()
|
||||||
try {
|
try {
|
||||||
resPixelmap.setTransferDetached(true)
|
resPixelmap.setTransferDetached(true)
|
||||||
// 设置翻转和旋转角度
|
|
||||||
if(exif && exif !== 'Top-left'){
|
|
||||||
let result = ImageKnifeLoader.getOrientation(exif);
|
|
||||||
if(result.horizontal || result.vertical) {
|
|
||||||
resPixelmap?.flipSync(result.horizontal, result.vertical);
|
|
||||||
}
|
|
||||||
if(result.rotate > 0) {
|
|
||||||
resPixelmap?.rotateSync(result.rotate);
|
|
||||||
}
|
|
||||||
LogUtil.log('Svg image set flip , horizontal=' + result.horizontal + ', vertical=' +result.vertical + ', rotate=' + result.rotate);
|
|
||||||
}
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
LogUtil.error('PixelMap setTransferDetached failed:' + JSON.stringify(e))
|
LogUtil.error('PixelMap setTransferDetached failed:' + JSON.stringify(e))
|
||||||
}
|
}
|
||||||
|
@ -486,14 +445,178 @@ export class ImageKnifeLoader {
|
||||||
errorInfo: error
|
errorInfo: error
|
||||||
};
|
};
|
||||||
|
|
||||||
const loaderStrategy = ImageLoaderFactory.getLoaderStrategy(request);
|
// 判断自定义下载
|
||||||
if (loaderStrategy) {
|
if (request.customGetImage !== undefined && request.requestSource == ImageKnifeRequestSource.SRC && typeof request.src == 'string') {
|
||||||
await loaderStrategy.loadImage(request, requestList, fileKey, callBackData, callBackTimeInfo);
|
// 先从文件缓存获取
|
||||||
|
ImageKnifeLoader.assembleError(callBackData,LoadPhase.PHASE_CUSTOM_LOAD)
|
||||||
|
callBackTimeInfo.diskCheckStartTime = Date.now();
|
||||||
|
resBuf = FileCache.getFileCacheByFile(request.context, fileKey , request.fileCacheFolder)
|
||||||
|
callBackTimeInfo.diskCheckEndTime = Date.now();
|
||||||
|
if (resBuf === undefined) {
|
||||||
|
LogUtil.log('start customGetImage src=' + request.componentId + ',srcType:' + request.requestSource + ',' + request.componentVersion)
|
||||||
|
const headerObj: Record<string, Object> = ImageKnifeLoader.getHeaderObj(request)
|
||||||
|
try {
|
||||||
|
request.customGetImage(request.context, request.src, headerObj)
|
||||||
|
.then((buffer)=>{
|
||||||
|
if(buffer != undefined) {
|
||||||
|
ImageKnifeLoader.FileCacheParseImage(request,buffer,fileKey,callBackData)
|
||||||
} else {
|
} else {
|
||||||
loadError = `Unsupported request type: ${request.src}`;
|
loadError = 'customGetImage loadFail undefined'
|
||||||
callBackTimeInfo.requestEndTime = Date.now();
|
ImageKnifeLoader.makeEmptyResult(request,loadError, ImageKnifeLoader.assembleError(callBackData, LoadPhase.PHASE_CUSTOM_LOAD, LoadPixelMapCode.IMAGE_CUSTOM_LOAD_FAILED_CODE))
|
||||||
ImageKnifeLoader.makeEmptyResult(request, loadError, callBackData);
|
|
||||||
}
|
}
|
||||||
|
}).catch((err:string)=>{
|
||||||
|
ImageKnifeLoader.makeEmptyResult(request,err, ImageKnifeLoader.assembleError(callBackData, LoadPhase.PHASE_CUSTOM_LOAD, LoadPixelMapCode.IMAGE_CUSTOM_LOAD_FAILED_CODE))
|
||||||
|
})
|
||||||
|
} catch (e) {
|
||||||
|
loadError = 'customGetImage loadFail failed'
|
||||||
|
ImageKnifeLoader.makeEmptyResult(request,loadError + e, ImageKnifeLoader.assembleError(callBackData, LoadPhase.PHASE_CUSTOM_LOAD, LoadPixelMapCode.IMAGE_CUSTOM_LOAD_FAILED_CODE))
|
||||||
|
}
|
||||||
|
LogUtil.log('end customGetImage src=' + request.componentId + ',srcType:' + request.requestSource + ',' + request.componentVersion)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (typeof request.src === 'string') {
|
||||||
|
if (request.src.indexOf('http://') == 0 || request.src.indexOf('https://') == 0) { //从网络下载
|
||||||
|
// 先从文件缓存获取
|
||||||
|
ImageKnifeLoader.assembleError(callBackData,LoadPhase.PHASE_NET)
|
||||||
|
LogUtil.log('get fileCache buffer start:' + request.componentId + ',srcType:' + request.requestSource + ',' + request.componentVersion)
|
||||||
|
callBackTimeInfo.diskCheckStartTime = Date.now()
|
||||||
|
resBuf = FileCache.getFileCacheByFile(request.context, fileKey , request.fileCacheFolder)
|
||||||
|
callBackTimeInfo.diskCheckEndTime = Date.now()
|
||||||
|
LogUtil.log('get fileCache buffer end:' + request.componentId + ',srcType:' + request.requestSource + ',' + request.componentVersion)
|
||||||
|
if (resBuf !== undefined){
|
||||||
|
LogUtil.log('success get image from filecache for key = ' + fileKey + ' src = ' + request.componentId + ',srcType:' + request.requestSource + ',' + request.componentVersion)
|
||||||
|
}
|
||||||
|
else if (request.onlyRetrieveFromCache != true) {
|
||||||
|
LogUtil.log('HttpDownloadClient.start:' + request.componentId + ',srcType:' + request.requestSource + ',' + request.componentVersion)
|
||||||
|
callBackTimeInfo.netRequestStartTime = Date.now();
|
||||||
|
let httpRequest = http.createHttp();
|
||||||
|
let progress: number = 0
|
||||||
|
let arrayBuffers:ArrayBuffer[] = []
|
||||||
|
const headerObj: Record<string, Object> = ImageKnifeLoader.getHeaderObj(request)
|
||||||
|
httpRequest.on('dataReceive', (data: ArrayBuffer) => {
|
||||||
|
arrayBuffers.push(data)
|
||||||
|
});
|
||||||
|
|
||||||
|
if (request.isWatchProgress) {
|
||||||
|
httpRequest.on('dataReceiveProgress', (data: RequestData) => {
|
||||||
|
// 下载进度
|
||||||
|
if (data != undefined && (typeof data.receiveSize == 'number') && (typeof data.totalSize == 'number')) {
|
||||||
|
let percent = Math.round(((data.receiveSize * 1.0) / (data.totalSize * 1.0)) * 100)
|
||||||
|
if (progress !== percent) {
|
||||||
|
progress = percent
|
||||||
|
if (requestList === undefined) {
|
||||||
|
// 子线程
|
||||||
|
emitter.emit(Constants.PROGRESS_EMITTER + request.memoryKey, { data: { 'value': progress } })
|
||||||
|
}else {
|
||||||
|
// 主线程请求
|
||||||
|
requestList!.forEach((requestWithSource: ImageKnifeRequestWithSource) => {
|
||||||
|
if (requestWithSource.request.imageKnifeOption.progressListener !== undefined && requestWithSource.source === ImageKnifeRequestSource.SRC) {
|
||||||
|
requestWithSource.request.imageKnifeOption.progressListener(progress)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
let promise = httpRequest.requestInStream(request.src, {
|
||||||
|
header: headerObj,
|
||||||
|
method: http.RequestMethod.GET,
|
||||||
|
expectDataType: http.HttpDataType.ARRAY_BUFFER,
|
||||||
|
connectTimeout: request.connectTimeout == undefined ? 60000 : request.connectTimeout,
|
||||||
|
readTimeout: request.readTimeout == undefined ? 30000 : request.readTimeout,
|
||||||
|
caPath: request.caPath === undefined ? undefined : request.caPath,
|
||||||
|
});
|
||||||
|
|
||||||
|
promise.then((data: number) => {
|
||||||
|
LogUtil.log('HttpDownloadClient.end:' + request.componentId + ',srcType:' + request.requestSource + ',' + request.componentVersion)
|
||||||
|
callBackData.httpCode = data
|
||||||
|
ImageKnifeLoader.assembleError(callBackData,LoadPhase.PHASE_NET, undefined)
|
||||||
|
callBackTimeInfo.netRequestEndTime = Date.now();
|
||||||
|
if (data == 200 || data == 206 || data == 204) {
|
||||||
|
resBuf = combineArrayBuffers(arrayBuffers)
|
||||||
|
ImageKnifeLoader.FileCacheParseImage(request,resBuf,fileKey, callBackData)
|
||||||
|
} else {
|
||||||
|
loadError = 'HttpDownloadClient has error, http code =' + JSON.stringify(data)
|
||||||
|
ImageKnifeLoader.makeEmptyResult(request,loadError, ImageKnifeLoader.assembleError(callBackData,LoadPhase.PHASE_NET, LoadPixelMapCode.IMAGE_HTTPS_LOAD_FAILED_CODE))
|
||||||
|
}
|
||||||
|
}).catch((err: BusinessError) => {
|
||||||
|
callBackData.httpCode = err.code
|
||||||
|
loadError = 'HttpDownloadClient download ERROR : err = ' + JSON.stringify(err)
|
||||||
|
callBackTimeInfo.netRequestEndTime = Date.now();
|
||||||
|
ImageKnifeLoader.makeEmptyResult(request,loadError, ImageKnifeLoader.assembleError(callBackData,LoadPhase.PHASE_NET, LoadPixelMapCode.IMAGE_HTTPS_LOAD_FAILED_CODE))
|
||||||
|
});
|
||||||
|
return
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
callBackTimeInfo.netRequestEndTime = Date.now();
|
||||||
|
loadError = 'onlyRetrieveFromCache,do not fetch image src = ' + request.src
|
||||||
|
}
|
||||||
|
} else if (request.src.startsWith('datashare://') || request.src.startsWith('file://')) {
|
||||||
|
ImageKnifeLoader.assembleError(callBackData,LoadPhase.PHASE_SHARE_FILE)
|
||||||
|
await fs.open(request.src, fs.OpenMode.READ_ONLY).then(async (file) => {
|
||||||
|
await fs.stat(file.fd).then(async (stat) =>{
|
||||||
|
let buf = new ArrayBuffer(stat.size);
|
||||||
|
await fs.read(file.fd, buf).then((readLen) => {
|
||||||
|
resBuf = buf;
|
||||||
|
fs.closeSync(file.fd);
|
||||||
|
}).catch((err:BusinessError) => {
|
||||||
|
ImageKnifeLoader.assembleError(callBackData,LoadPhase.PHASE_SHARE_FILE, LoadPixelMapCode.IMAGE_LOAD_SHARE_FILE_FAILED_CODE)
|
||||||
|
loadError = 'LoadDataShareFileClient fs.read err happened uri=' + request.src + ' err.msg=' + err?.message + ' err.code=' + err?.code
|
||||||
|
})
|
||||||
|
}).catch((err:BusinessError) => {
|
||||||
|
ImageKnifeLoader.assembleError(callBackData,LoadPhase.PHASE_SHARE_FILE, LoadPixelMapCode.IMAGE_LOAD_SHARE_FILE_FAILED_CODE)
|
||||||
|
loadError = 'LoadDataShareFileClient fs.stat err happened uri=' + request.src + ' err.msg=' + err?.message + ' err.code=' + err?.code
|
||||||
|
})
|
||||||
|
}).catch((err:BusinessError) => {
|
||||||
|
ImageKnifeLoader.assembleError(callBackData,LoadPhase.PHASE_SHARE_FILE, LoadPixelMapCode.IMAGE_LOAD_SHARE_FILE_FAILED_CODE)
|
||||||
|
loadError = 'LoadDataShareFileClient fs.open err happened uri=' + request.src + ' err.msg=' + err?.message + ' err.code=' + err?.code
|
||||||
|
})
|
||||||
|
} else if (ImageKnifeLoader.isLocalLoadSrc(request.context, request.src)) { //从本地文件获取
|
||||||
|
ImageKnifeLoader.assembleError(callBackData,LoadPhase.PHASE_LOCAL_FILE)
|
||||||
|
try {
|
||||||
|
let stat = fs.statSync(request.src);
|
||||||
|
if (stat.size > 0) {
|
||||||
|
let file = fs.openSync(request.src, fs.OpenMode.READ_ONLY);
|
||||||
|
resBuf = new ArrayBuffer(stat.size);
|
||||||
|
fs.readSync(file.fd, resBuf);
|
||||||
|
fs.closeSync(file);
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
ImageKnifeLoader.assembleError(callBackData,LoadPhase.PHASE_LOCAL_FILE, LoadPixelMapCode.IMAGE_LOAD_LOCAL_FILE_FAILED_CODE)
|
||||||
|
loadError = 'LocalLoadSrc:' + request.src + ',err:' + err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
loadError = 'Parameter not supported:' + request.src
|
||||||
|
}
|
||||||
|
} else if (typeof request.src == 'number') { //从资源文件获取
|
||||||
|
let manager = request.context.createModuleContext(request.moduleName).resourceManager
|
||||||
|
if (resBuf == undefined && request.onlyRetrieveFromCache != true && request.requestSource == ImageKnifeRequestSource.SRC) {
|
||||||
|
if(request.src == -1) {
|
||||||
|
let resName = request.resName as string
|
||||||
|
resBuf = (await manager.getMediaByName(resName.substring(resName.lastIndexOf(".") + 1))).buffer as ArrayBuffer
|
||||||
|
} else {
|
||||||
|
resBuf = manager.getMediaContentSync(request.src).buffer as ArrayBuffer
|
||||||
|
}
|
||||||
|
} else if (resBuf == undefined && request.requestSource != ImageKnifeRequestSource.SRC) {
|
||||||
|
if(request.src == -1) {
|
||||||
|
let resName = request.resName as string
|
||||||
|
resBuf = (await manager.getMediaByName(resName.substring(resName.lastIndexOf(".") + 1))).buffer as ArrayBuffer
|
||||||
|
} else {
|
||||||
|
resBuf = manager.getMediaContentSync(request.src).buffer as ArrayBuffer
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (resBuf === undefined){
|
||||||
|
callBackTimeInfo.requestEndTime = Date.now();
|
||||||
|
ImageKnifeLoader.makeEmptyResult(request,loadError ,callBackData)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ImageKnifeLoader.parseImage(resBuf,fileKey,request, callBackData)
|
||||||
}
|
}
|
||||||
static isLocalLoadSrc(context: Object | undefined, loadSrc: string): boolean {
|
static isLocalLoadSrc(context: Object | undefined, loadSrc: string): boolean {
|
||||||
if (context != undefined) {
|
if (context != undefined) {
|
||||||
|
@ -529,39 +652,4 @@ export class ImageKnifeLoader {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static getOrientation(orientation: string | undefined){
|
|
||||||
let horizontal: boolean = false;
|
|
||||||
let vertical: boolean = false;
|
|
||||||
let rotate: number= 0;
|
|
||||||
switch (orientation){
|
|
||||||
case 'Top-left': break
|
|
||||||
case 'Top-right':
|
|
||||||
horizontal = true;
|
|
||||||
break;
|
|
||||||
case 'Bottom-left':
|
|
||||||
vertical = true;
|
|
||||||
break
|
|
||||||
case 'Bottom-right':
|
|
||||||
rotate = 180;
|
|
||||||
break;
|
|
||||||
case 'Left-top':
|
|
||||||
horizontal = true;
|
|
||||||
rotate = 270;
|
|
||||||
break
|
|
||||||
case 'Right-top':
|
|
||||||
rotate = 90;
|
|
||||||
break;
|
|
||||||
case 'Left-bottom':
|
|
||||||
rotate = 270;
|
|
||||||
break
|
|
||||||
case 'Right-bottom':
|
|
||||||
horizontal = true;
|
|
||||||
rotate = 90;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
let data: FlipRotate = { horizontal: horizontal, vertical: vertical, rotate:rotate };
|
|
||||||
return data
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -70,7 +70,6 @@ export class FileCache {
|
||||||
interface CacheFileInfo {
|
interface CacheFileInfo {
|
||||||
file: string;
|
file: string;
|
||||||
ctime: number;
|
ctime: number;
|
||||||
size: number;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 按照上次访问该文件的时间排序
|
// 按照上次访问该文件的时间排序
|
||||||
|
@ -79,25 +78,26 @@ export class FileCache {
|
||||||
let stat: fs.Stat | undefined = await FileUtils.getInstance().Stat(this.path + filenames[i])
|
let stat: fs.Stat | undefined = await FileUtils.getInstance().Stat(this.path + filenames[i])
|
||||||
cachefiles.push({
|
cachefiles.push({
|
||||||
file: filenames[i],
|
file: filenames[i],
|
||||||
ctime: stat === undefined ? 0 : stat.ctime,
|
ctime: stat === undefined ? 0 : stat.ctime
|
||||||
size: stat?.size ?? 0
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
let sortedCachefiles: CacheFileInfo[] = cachefiles.sort((a, b) => a.ctime - b.ctime)
|
let sortedCachefiles: CacheFileInfo[] = cachefiles.sort((a, b) => a.ctime - b.ctime)
|
||||||
|
|
||||||
for (let i = 0; i < sortedCachefiles.length; i++) {
|
for (let i = 0; i < sortedCachefiles.length; i++) {
|
||||||
const fileSize: number = sortedCachefiles[i].size;
|
let buf: ArrayBuffer | undefined = await FileUtils.getInstance().readFile(this.path + sortedCachefiles[i].file)
|
||||||
|
if (buf !== undefined) {
|
||||||
// 处理数量超过size的场景,移除即将排除的文件
|
// 处理数量超过size的场景,移除即将排除的文件
|
||||||
if (this.lruCache.length == this.maxSize && !this.lruCache.contains(sortedCachefiles[i].file)) {
|
if (this.lruCache.length == this.maxSize && !this.lruCache.contains(sortedCachefiles[i].file)) {
|
||||||
let remove: number | undefined = this.lruCache.remove(this.lruCache.keys()[0])
|
let remove: number | undefined = this.lruCache.remove(this.lruCache.keys()[0])
|
||||||
if (remove !== undefined) {
|
if (remove !== undefined) {
|
||||||
FileUtils.getInstance().deleteFile(this.path + this.lruCache.keys()[0])
|
FileUtils.getInstance().deleteFile(this.path + this.lruCache.keys()[0])
|
||||||
this.removeMemorySize(fileSize)
|
this.removeMemorySize(buf)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.lruCache.put(sortedCachefiles[i].file, fileSize)
|
this.lruCache.put(sortedCachefiles[i].file, buf.byteLength)
|
||||||
this.addMemorySize(fileSize)
|
this.addMemorySize(buf)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.trimToSize();
|
this.trimToSize();
|
||||||
|
@ -192,6 +192,7 @@ export class FileCache {
|
||||||
if (!this.isInited) {
|
if (!this.isInited) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
this.isInited = false
|
||||||
this.lruCache.clear()
|
this.lruCache.clear()
|
||||||
this.currentMemory = 0;
|
this.currentMemory = 0;
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,6 @@ import common from '@ohos.app.ability.common';
|
||||||
import { ImageKnife } from '../ImageKnife';
|
import { ImageKnife } from '../ImageKnife';
|
||||||
import { LogUtil } from '../utils/LogUtil';
|
import { LogUtil } from '../utils/LogUtil';
|
||||||
import { ImageKnifeRequestSource } from '../model/ImageKnifeData';
|
import { ImageKnifeRequestSource } from '../model/ImageKnifeData';
|
||||||
import { emitter } from '@kit.BasicServicesKit';
|
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
export struct ImageKnifeAnimatorComponent {
|
export struct ImageKnifeAnimatorComponent {
|
||||||
|
@ -27,13 +26,11 @@ export struct ImageKnifeAnimatorComponent {
|
||||||
@State pixelMap: PixelMap | string | undefined = undefined
|
@State pixelMap: PixelMap | string | undefined = undefined
|
||||||
@State imageAnimator: Array<ImageFrameInfo> | undefined = undefined
|
@State imageAnimator: Array<ImageFrameInfo> | undefined = undefined
|
||||||
@State adaptiveWidth: Length = '100%'
|
@State adaptiveWidth: Length = '100%'
|
||||||
@State adaptiveHeight: Length | undefined = '100%'
|
@State adaptiveHeight: Length = '100%'
|
||||||
@State objectFit: ImageFit = ImageFit.Contain
|
@State objectFit: ImageFit = ImageFit.Contain
|
||||||
private componentId: number = 0
|
|
||||||
private request: ImageKnifeRequest | undefined
|
private request: ImageKnifeRequest | undefined
|
||||||
private lastWidth: number = 0
|
private lastWidth: number = 0
|
||||||
private lastHeight: number = 0
|
private lastHeight: number = 0
|
||||||
private isImageFitAutoResize: boolean = false
|
|
||||||
private currentWidth: number = 0
|
private currentWidth: number = 0
|
||||||
private currentHeight: number = 0
|
private currentHeight: number = 0
|
||||||
private componentVersion: number = 0
|
private componentVersion: number = 0
|
||||||
|
@ -41,33 +38,23 @@ export struct ImageKnifeAnimatorComponent {
|
||||||
|
|
||||||
aboutToAppear(): void {
|
aboutToAppear(): void {
|
||||||
this.objectFit = this.imageKnifeOption.objectFit === undefined ? ImageFit.Contain : this.imageKnifeOption.objectFit
|
this.objectFit = this.imageKnifeOption.objectFit === undefined ? ImageFit.Contain : this.imageKnifeOption.objectFit
|
||||||
this.componentId = this.getUniqueId()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
aboutToDisappear(): void {
|
aboutToDisappear(): void {
|
||||||
this.emitterDestroy()
|
|
||||||
this.clearLastRequest()
|
|
||||||
}
|
|
||||||
|
|
||||||
aboutToRecycle() {
|
|
||||||
this.emitterDestroy()
|
|
||||||
this.clearLastRequest()
|
|
||||||
}
|
|
||||||
|
|
||||||
emitterDestroy() {
|
|
||||||
if (typeof this.request?.imageKnifeOption.loadSrc === 'string' && !this.request?.drawMainSuccess) {
|
|
||||||
emitter.emit(this.request.imageKnifeOption.loadSrc + this.componentId)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* 对已DESTROY的组件不再发起请求
|
|
||||||
*/
|
|
||||||
private clearLastRequest(){
|
|
||||||
if (this.request !== undefined) {
|
if (this.request !== undefined) {
|
||||||
this.request.requestState = ImageKnifeRequestState.DESTROY
|
this.request.requestState = ImageKnifeRequestState.DESTROY
|
||||||
this.request = undefined
|
this.request = undefined
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
aboutToRecycle() {
|
||||||
|
if (this.request !== undefined) {
|
||||||
|
this.request.requestState = ImageKnifeRequestState.DESTROY
|
||||||
|
this.request = undefined
|
||||||
|
}
|
||||||
|
this.objectFit = this.imageKnifeOption.objectFit === undefined ? ImageFit.Contain : this.imageKnifeOption.objectFit
|
||||||
|
}
|
||||||
|
|
||||||
build() {
|
build() {
|
||||||
ImageAnimator()
|
ImageAnimator()
|
||||||
.images(this.imageAnimator)
|
.images(this.imageAnimator)
|
||||||
|
@ -92,14 +79,8 @@ export struct ImageKnifeAnimatorComponent {
|
||||||
' loadSrc = ' + this.imageKnifeOption.loadSrc +
|
' loadSrc = ' + this.imageKnifeOption.loadSrc +
|
||||||
' placeholderSrc = ' + this.imageKnifeOption.placeholderSrc +
|
' placeholderSrc = ' + this.imageKnifeOption.placeholderSrc +
|
||||||
' errorholderSrc = ' + this.imageKnifeOption.errorholderSrc +
|
' errorholderSrc = ' + this.imageKnifeOption.errorholderSrc +
|
||||||
' componentId = ' + this.componentId)
|
' componentId = ' + this.getUniqueId())
|
||||||
|
ImageKnife.getInstance().execute(this.getRequest(this.currentWidth, this.currentHeight),true)
|
||||||
if (this.imageKnifeOption.objectFit === ImageFit.Auto && this.isImageFitAutoResize) {
|
|
||||||
this.isImageFitAutoResize = false
|
|
||||||
} else {
|
|
||||||
ImageKnife.getInstance().execute(this.getRequest(
|
|
||||||
this.currentWidth, this.currentHeight, this.componentId))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -111,17 +92,17 @@ export struct ImageKnifeAnimatorComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
watchImageKnifeOption() {
|
watchImageKnifeOption() {
|
||||||
this.clearLastRequest()
|
if (this.request !== undefined) {
|
||||||
|
this.request.requestState = ImageKnifeRequestState.DESTROY
|
||||||
|
}
|
||||||
|
this.request = undefined
|
||||||
this.componentVersion++
|
this.componentVersion++
|
||||||
this.isImageFitAutoResize = false
|
|
||||||
this.objectFit = this.imageKnifeOption.objectFit === undefined ? ImageFit.Contain : this.imageKnifeOption.objectFit
|
|
||||||
LogUtil.log('watchImageKnifeOption execute request:width=' + this.currentWidth + ' height= ' + this.currentHeight +
|
LogUtil.log('watchImageKnifeOption execute request:width=' + this.currentWidth + ' height= ' + this.currentHeight +
|
||||||
' loadSrc = ' + this.imageKnifeOption.loadSrc +
|
' loadSrc = ' + this.imageKnifeOption.loadSrc +
|
||||||
' placeholderSrc = ' + this.imageKnifeOption.placeholderSrc +
|
' placeholderSrc = ' + this.imageKnifeOption.placeholderSrc +
|
||||||
' errorholderSrc = ' + this.imageKnifeOption.errorholderSrc +
|
' errorholderSrc = ' + this.imageKnifeOption.errorholderSrc +
|
||||||
' componentId = ' + this.componentId)
|
' componentId = ' + this.getUniqueId())
|
||||||
ImageKnife.getInstance().execute(this.getRequest(
|
ImageKnife.getInstance().execute(this.getRequest(this.currentWidth, this.currentHeight),true)
|
||||||
this.currentWidth, this.currentHeight, this.componentId))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getCurrentContext(): common.UIAbilityContext {
|
getCurrentContext(): common.UIAbilityContext {
|
||||||
|
@ -131,7 +112,8 @@ export struct ImageKnifeAnimatorComponent {
|
||||||
return this.currentContext
|
return this.currentContext
|
||||||
}
|
}
|
||||||
|
|
||||||
getRequest(width: number, height: number,componentId: number): ImageKnifeRequest {
|
getRequest(width: number, height: number): ImageKnifeRequest {
|
||||||
|
if (this.request == undefined) {
|
||||||
this.request = new ImageKnifeRequest(
|
this.request = new ImageKnifeRequest(
|
||||||
this.imageKnifeOption,
|
this.imageKnifeOption,
|
||||||
this.imageKnifeOption.context !== undefined ? this.imageKnifeOption.context : this.getCurrentContext(),
|
this.imageKnifeOption.context !== undefined ? this.imageKnifeOption.context : this.getCurrentContext(),
|
||||||
|
@ -139,8 +121,7 @@ export struct ImageKnifeAnimatorComponent {
|
||||||
height,
|
height,
|
||||||
this.componentVersion,
|
this.componentVersion,
|
||||||
{
|
{
|
||||||
showPixelMap: (version: number, pixelMap: PixelMap | string, size: Size, requestSource: ImageKnifeRequestSource,
|
showPixelMap: (version: number, pixelMap: PixelMap | string,size: Size, requestSource: ImageKnifeRequestSource,imageAnimator?: Array<ImageFrameInfo>) => {
|
||||||
imageAnimator?: Array<ImageFrameInfo>) => {
|
|
||||||
if (version !== this.componentVersion) {
|
if (version !== this.componentVersion) {
|
||||||
return //针对reuse场景,不显示历史图片
|
return //针对reuse场景,不显示历史图片
|
||||||
}
|
}
|
||||||
|
@ -154,29 +135,20 @@ export struct ImageKnifeAnimatorComponent {
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.imageKnifeOption.objectFit === ImageFit.Auto && this.isImageFitAutoResize == false &&
|
|
||||||
requestSource == ImageKnifeRequestSource.SRC) {
|
|
||||||
this.adaptiveHeight = undefined
|
|
||||||
this.isImageFitAutoResize = true
|
|
||||||
}
|
|
||||||
|
|
||||||
if (requestSource == ImageKnifeRequestSource.SRC) {
|
if (requestSource == ImageKnifeRequestSource.SRC) {
|
||||||
this.objectFit =
|
this.objectFit =
|
||||||
this.imageKnifeOption.objectFit === undefined ? ImageFit.Contain : this.imageKnifeOption.objectFit
|
this.imageKnifeOption.objectFit === undefined ? ImageFit.Contain : this.imageKnifeOption.objectFit
|
||||||
} else if (requestSource == ImageKnifeRequestSource.PLACE_HOLDER) {
|
} else if (requestSource == ImageKnifeRequestSource.PLACE_HOLDER) {
|
||||||
this.objectFit =
|
this.objectFit =
|
||||||
this.imageKnifeOption.placeholderObjectFit === undefined ?
|
this.imageKnifeOption.placeholderObjectFit === undefined ? (this.imageKnifeOption.objectFit === undefined ? ImageFit.Contain : this.imageKnifeOption.objectFit) : this.imageKnifeOption.placeholderObjectFit
|
||||||
(this.imageKnifeOption.objectFit === undefined ? ImageFit.Contain : this.imageKnifeOption.objectFit) :
|
|
||||||
this.imageKnifeOption.placeholderObjectFit
|
|
||||||
} else {
|
} else {
|
||||||
this.objectFit =
|
this.objectFit =
|
||||||
this.imageKnifeOption.errorholderObjectFit === undefined ?
|
this.imageKnifeOption.errorholderObjectFit === undefined ? (this.imageKnifeOption.objectFit === undefined ? ImageFit.Contain : this.imageKnifeOption.objectFit) : this.imageKnifeOption.errorholderObjectFit
|
||||||
(this.imageKnifeOption.objectFit === undefined ? ImageFit.Contain : this.imageKnifeOption.objectFit) :
|
|
||||||
this.imageKnifeOption.errorholderObjectFit
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
this.request.animator = true
|
}
|
||||||
|
|
||||||
return this.request
|
return this.request
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -20,7 +20,6 @@ import { LogUtil } from '../utils/LogUtil';
|
||||||
import { ImageKnifeData, ImageKnifeRequestSource } from '../model/ImageKnifeData';
|
import { ImageKnifeData, ImageKnifeRequestSource } from '../model/ImageKnifeData';
|
||||||
import { IEngineKey } from '../key/IEngineKey';
|
import { IEngineKey } from '../key/IEngineKey';
|
||||||
import { DefaultEngineKey } from '../key/DefaultEngineKey';
|
import { DefaultEngineKey } from '../key/DefaultEngineKey';
|
||||||
import { emitter } from '@kit.BasicServicesKit';
|
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
export struct ImageKnifeComponent {
|
export struct ImageKnifeComponent {
|
||||||
|
@ -30,7 +29,6 @@ export struct ImageKnifeComponent {
|
||||||
@State adaptiveWidth: Length = '100%'
|
@State adaptiveWidth: Length = '100%'
|
||||||
@State adaptiveHeight: Length | undefined = '100%'
|
@State adaptiveHeight: Length | undefined = '100%'
|
||||||
@State objectFit: ImageFit = ImageFit.Contain
|
@State objectFit: ImageFit = ImageFit.Contain
|
||||||
private componentId: number = 0
|
|
||||||
private request: ImageKnifeRequest | undefined
|
private request: ImageKnifeRequest | undefined
|
||||||
private lastWidth: number = 0
|
private lastWidth: number = 0
|
||||||
private lastHeight: number = 0
|
private lastHeight: number = 0
|
||||||
|
@ -42,7 +40,7 @@ export struct ImageKnifeComponent {
|
||||||
|
|
||||||
aboutToAppear(): void {
|
aboutToAppear(): void {
|
||||||
this.objectFit = (this.imageKnifeOption.objectFit === undefined || this.imageKnifeOption.objectFit === ImageFit.Auto) ? ImageFit.Contain : this.imageKnifeOption.objectFit
|
this.objectFit = (this.imageKnifeOption.objectFit === undefined || this.imageKnifeOption.objectFit === ImageFit.Auto) ? ImageFit.Contain : this.imageKnifeOption.objectFit
|
||||||
this.componentId = this.getUniqueId()
|
|
||||||
if(this.syncLoad) { //针对部分消息列表最新消息的图片闪动问题,建议使用同步方式在aboutToAppear时加载图片
|
if(this.syncLoad) { //针对部分消息列表最新消息的图片闪动问题,建议使用同步方式在aboutToAppear时加载图片
|
||||||
let engineKey: IEngineKey = new DefaultEngineKey();
|
let engineKey: IEngineKey = new DefaultEngineKey();
|
||||||
let memoryCacheSrc: ImageKnifeData | undefined = ImageKnife.getInstance()
|
let memoryCacheSrc: ImageKnifeData | undefined = ImageKnife.getInstance()
|
||||||
|
@ -67,21 +65,13 @@ export struct ImageKnifeComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
aboutToDisappear(): void {
|
aboutToDisappear(): void {
|
||||||
this.emitterDestroy()
|
|
||||||
this.clearLastRequest()
|
this.clearLastRequest()
|
||||||
}
|
}
|
||||||
|
|
||||||
aboutToRecycle() {
|
aboutToRecycle() {
|
||||||
this.pixelMap = ImageContent.EMPTY
|
this.pixelMap = ImageContent.EMPTY
|
||||||
this.emitterDestroy()
|
|
||||||
this.clearLastRequest()
|
this.clearLastRequest()
|
||||||
}
|
}
|
||||||
|
|
||||||
emitterDestroy() {
|
|
||||||
if (typeof this.request?.imageKnifeOption.loadSrc === 'string' && !this.request?.drawMainSuccess) {
|
|
||||||
emitter.emit(this.request.imageKnifeOption.loadSrc + this.componentId)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/**
|
/**
|
||||||
* 对已DESTROY的组件不再发起请求
|
* 对已DESTROY的组件不再发起请求
|
||||||
*/
|
*/
|
||||||
|
@ -115,13 +105,13 @@ export struct ImageKnifeComponent {
|
||||||
' loadSrc = ' + this.imageKnifeOption.loadSrc +
|
' loadSrc = ' + this.imageKnifeOption.loadSrc +
|
||||||
' placeholderSrc = ' + this.imageKnifeOption.placeholderSrc +
|
' placeholderSrc = ' + this.imageKnifeOption.placeholderSrc +
|
||||||
' errorholderSrc = ' + this.imageKnifeOption.errorholderSrc +
|
' errorholderSrc = ' + this.imageKnifeOption.errorholderSrc +
|
||||||
' componentId = ' + this.componentId)
|
' componentId = ' + this.getUniqueId())
|
||||||
|
|
||||||
if (this.imageKnifeOption.objectFit === ImageFit.Auto && this.isImageFitAutoResize) {
|
if (this.imageKnifeOption.objectFit === ImageFit.Auto && this.isImageFitAutoResize) {
|
||||||
this.isImageFitAutoResize = false
|
this.isImageFitAutoResize = false
|
||||||
} else {
|
} else {
|
||||||
ImageKnife.getInstance().execute(this.getRequest(
|
ImageKnife.getInstance().execute(this.getRequest(
|
||||||
this.currentWidth, this.currentHeight, this.componentId))
|
this.currentWidth, this.currentHeight, this.getUniqueId()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -137,9 +127,9 @@ export struct ImageKnifeComponent {
|
||||||
' loadSrc = ' + this.imageKnifeOption.loadSrc +
|
' loadSrc = ' + this.imageKnifeOption.loadSrc +
|
||||||
' placeholderSrc = ' + this.imageKnifeOption.placeholderSrc +
|
' placeholderSrc = ' + this.imageKnifeOption.placeholderSrc +
|
||||||
' errorholderSrc = ' + this.imageKnifeOption.errorholderSrc +
|
' errorholderSrc = ' + this.imageKnifeOption.errorholderSrc +
|
||||||
' componentId = ' + this.componentId)
|
' componentId = ' + this.getUniqueId())
|
||||||
ImageKnife.getInstance().execute(this.getRequest(
|
ImageKnife.getInstance().execute(this.getRequest(
|
||||||
this.currentWidth, this.currentHeight, this.componentId))
|
this.currentWidth, this.currentHeight, this.getUniqueId()))
|
||||||
}
|
}
|
||||||
|
|
||||||
getCurrentContext(): common.UIAbilityContext {
|
getCurrentContext(): common.UIAbilityContext {
|
||||||
|
|
|
@ -1,75 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2025 Huawei Device Co., Ltd.
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
import { FileCache } from '../cache/FileCache';
|
|
||||||
import { IImageLoaderStrategy } from './IImageLoaderStrategy';
|
|
||||||
import { ImageKnifeLoader } from '../ImageKnifeLoader';
|
|
||||||
import { ImageKnifeData, ImageKnifeRequestWithSource, RequestJobRequest, TimeInfo } from '../model/ImageKnifeData';
|
|
||||||
import { LoadPhase, LoadPixelMapCode } from '../utils/Constants';
|
|
||||||
import { LogUtil } from '../utils/LogUtil';
|
|
||||||
import List from '@ohos.util.List';
|
|
||||||
|
|
||||||
// 自定义加载策略
|
|
||||||
export class CustomLoaderStrategy implements IImageLoaderStrategy {
|
|
||||||
async loadImage(
|
|
||||||
request: RequestJobRequest,
|
|
||||||
requestList: List<ImageKnifeRequestWithSource> | undefined,
|
|
||||||
fileKey: string,
|
|
||||||
callBackData: ImageKnifeData,
|
|
||||||
callBackTimeInfo: TimeInfo
|
|
||||||
): Promise<void> {
|
|
||||||
let resBuf: ArrayBuffer | undefined;
|
|
||||||
let loadError: string = '';
|
|
||||||
|
|
||||||
// 从文件缓存获取
|
|
||||||
ImageKnifeLoader.assembleError(callBackData, LoadPhase.PHASE_CUSTOM_LOAD);
|
|
||||||
callBackTimeInfo.diskCheckStartTime = Date.now();
|
|
||||||
resBuf = FileCache.getFileCacheByFile(request.context, fileKey, request.fileCacheFolder);
|
|
||||||
callBackTimeInfo.diskCheckEndTime = Date.now();
|
|
||||||
|
|
||||||
if (resBuf !== undefined) {
|
|
||||||
ImageKnifeLoader.parseImage(resBuf, fileKey, request, callBackData);
|
|
||||||
} else if (!request.onlyRetrieveFromCache) {
|
|
||||||
LogUtil.log('start customGetImage src=' + request.componentId + ',srcType:' + request.requestSource + ',' +
|
|
||||||
request.componentVersion);
|
|
||||||
const headerObj: Record<string, Object> = ImageKnifeLoader.getHeaderObj(request);
|
|
||||||
try {
|
|
||||||
request.customGetImage!(request.context, request.src as string, headerObj)
|
|
||||||
.then((buffer)=>{
|
|
||||||
if(buffer !== undefined && buffer !== null) {
|
|
||||||
ImageKnifeLoader.FileCacheParseImage(request,buffer,fileKey,callBackData);
|
|
||||||
} else {
|
|
||||||
loadError = 'customGetImage loadFail undefined';
|
|
||||||
ImageKnifeLoader.makeEmptyResult(request,loadError, ImageKnifeLoader.assembleError(callBackData,
|
|
||||||
LoadPhase.PHASE_CUSTOM_LOAD, LoadPixelMapCode.IMAGE_CUSTOM_LOAD_FAILED_CODE));
|
|
||||||
}
|
|
||||||
}).catch((err:string)=>{
|
|
||||||
ImageKnifeLoader.makeEmptyResult(request,err, ImageKnifeLoader.assembleError(callBackData,
|
|
||||||
LoadPhase.PHASE_CUSTOM_LOAD, LoadPixelMapCode.IMAGE_CUSTOM_LOAD_FAILED_CODE));
|
|
||||||
})
|
|
||||||
} catch (e) {
|
|
||||||
loadError = 'customGetImage loadFail failed';
|
|
||||||
ImageKnifeLoader.makeEmptyResult(request,loadError + e, ImageKnifeLoader.assembleError(callBackData,
|
|
||||||
LoadPhase.PHASE_CUSTOM_LOAD, LoadPixelMapCode.IMAGE_CUSTOM_LOAD_FAILED_CODE));
|
|
||||||
}
|
|
||||||
LogUtil.log('end customGetImage src=' + request.componentId + ',srcType:' +
|
|
||||||
request.requestSource + ',' + request.componentVersion);
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
loadError = `onlyRetrieveFromCache, do not fetch image src = ${request.src}`;
|
|
||||||
ImageKnifeLoader.makeEmptyResult(request, loadError, callBackData);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,62 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2025 Huawei Device Co., Ltd.
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
import { RequestJobRequest, ImageKnifeRequestWithSource, ImageKnifeData, TimeInfo } from '../model/ImageKnifeData';
|
|
||||||
import { IImageLoaderStrategy } from './IImageLoaderStrategy';
|
|
||||||
import List from '@ohos.util.List';
|
|
||||||
import { ImageKnifeLoader } from '../ImageKnifeLoader';
|
|
||||||
import { LoadPhase, LoadPixelMapCode } from '../utils/Constants';
|
|
||||||
import fs from '@ohos.file.fs';
|
|
||||||
|
|
||||||
export class FileLocalLoadStrategy implements IImageLoaderStrategy {
|
|
||||||
loadImage(request: RequestJobRequest, requestList: List<ImageKnifeRequestWithSource> | undefined, fileKey: string,
|
|
||||||
callBackData: ImageKnifeData, callBackTimeInfo: TimeInfo): Promise<void> {
|
|
||||||
let resBuf: ArrayBuffer | undefined;
|
|
||||||
let loadError: string = '';
|
|
||||||
if (typeof request.src === 'string' && ImageKnifeLoader.isLocalLoadSrc(request.context, request.src)) {
|
|
||||||
ImageKnifeLoader.assembleError(callBackData, LoadPhase.PHASE_LOCAL_FILE);
|
|
||||||
try {
|
|
||||||
const stat = fs.statSync(request.src);
|
|
||||||
if (stat.size > 0) {
|
|
||||||
const file = fs.openSync(request.src, fs.OpenMode.READ_ONLY);
|
|
||||||
resBuf = new ArrayBuffer(stat.size);
|
|
||||||
fs.readSync(file.fd, resBuf);
|
|
||||||
fs.closeSync(file);
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
ImageKnifeLoader.assembleError(callBackData, LoadPhase.PHASE_LOCAL_FILE,
|
|
||||||
LoadPixelMapCode.IMAGE_LOAD_LOCAL_FILE_FAILED_CODE);
|
|
||||||
loadError = `LocalLoadSrc: ${request.src}, err: ${err}`;
|
|
||||||
ImageKnifeLoader.makeEmptyResult(request, loadError,
|
|
||||||
ImageKnifeLoader.assembleError(
|
|
||||||
callBackData,
|
|
||||||
LoadPhase.PHASE_LOCAL_FILE,
|
|
||||||
LoadPixelMapCode.IMAGE_LOAD_LOCAL_FILE_FAILED_CODE
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
loadError = `Parameter not supported: ${request.src}`;
|
|
||||||
ImageKnifeLoader.makeEmptyResult(request, loadError, callBackData);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (resBuf === undefined || resBuf === null) {
|
|
||||||
callBackTimeInfo.requestEndTime = Date.now();
|
|
||||||
ImageKnifeLoader.makeEmptyResult(request, loadError, callBackData);
|
|
||||||
} else {
|
|
||||||
ImageKnifeLoader.parseImage(resBuf, fileKey, request, callBackData);
|
|
||||||
}
|
|
||||||
return Promise.resolve();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,66 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2025 Huawei Device Co., Ltd.
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
import { ImageKnifeData, RequestJobRequest, TimeInfo, ImageKnifeRequestWithSource } from '../model/ImageKnifeData';
|
|
||||||
import fs from '@ohos.file.fs';
|
|
||||||
import { IImageLoaderStrategy } from './IImageLoaderStrategy';
|
|
||||||
import List from '@ohos.util.List';
|
|
||||||
import { ImageKnifeLoader } from '../ImageKnifeLoader';
|
|
||||||
import { LoadPhase, LoadPixelMapCode } from '../utils/Constants';
|
|
||||||
import { BusinessError } from '@kit.BasicServicesKit';
|
|
||||||
|
|
||||||
export class FileSystemLoaderStrategy implements IImageLoaderStrategy {
|
|
||||||
async loadImage(request: RequestJobRequest, requestList: List<ImageKnifeRequestWithSource> | undefined,
|
|
||||||
fileKey: string, callBackData: ImageKnifeData, callBackTimeInfo: TimeInfo
|
|
||||||
): Promise<void> {
|
|
||||||
let resBuf: ArrayBuffer | undefined;
|
|
||||||
let loadError: string = '';
|
|
||||||
|
|
||||||
if (typeof request.src === 'string' &&
|
|
||||||
(request.src.startsWith('datashare://') || request.src.startsWith('file://'))) {
|
|
||||||
ImageKnifeLoader.assembleError(callBackData, LoadPhase.PHASE_SHARE_FILE);
|
|
||||||
await fs.open(request.src, fs.OpenMode.READ_ONLY).then(async (file) => {
|
|
||||||
await fs.stat(file.fd).then(async (stat) => {
|
|
||||||
let buf = new ArrayBuffer(stat.size);
|
|
||||||
await fs.read(file.fd, buf).then((readLen) => {
|
|
||||||
resBuf = buf;
|
|
||||||
fs.closeSync(file.fd);
|
|
||||||
}).catch((err: BusinessError) => {
|
|
||||||
ImageKnifeLoader.assembleError(callBackData, LoadPhase.PHASE_SHARE_FILE,
|
|
||||||
LoadPixelMapCode.IMAGE_LOAD_SHARE_FILE_FAILED_CODE)
|
|
||||||
loadError = 'LoadDataShareFileClient fs.read err happened uri=' + request.src + ' err.msg=' + err?.message +
|
|
||||||
' err.code=' + err?.code
|
|
||||||
})
|
|
||||||
}).catch((err: BusinessError) => {
|
|
||||||
ImageKnifeLoader.assembleError(callBackData, LoadPhase.PHASE_SHARE_FILE,
|
|
||||||
LoadPixelMapCode.IMAGE_LOAD_SHARE_FILE_FAILED_CODE)
|
|
||||||
loadError = 'LoadDataShareFileClient fs.stat err happened uri=' + request.src + ' err.msg=' + err?.message +
|
|
||||||
' err.code=' + err?.code
|
|
||||||
})
|
|
||||||
}).catch((err: BusinessError) => {
|
|
||||||
ImageKnifeLoader.assembleError(callBackData, LoadPhase.PHASE_SHARE_FILE,
|
|
||||||
LoadPixelMapCode.IMAGE_LOAD_SHARE_FILE_FAILED_CODE)
|
|
||||||
loadError = 'LoadDataShareFileClient fs.open err happened uri=' + request.src + ' err.msg=' + err?.message +
|
|
||||||
' err.code=' + err?.code
|
|
||||||
})
|
|
||||||
}
|
|
||||||
if (resBuf === undefined || resBuf === null) {
|
|
||||||
callBackTimeInfo.requestEndTime = Date.now();
|
|
||||||
ImageKnifeLoader.makeEmptyResult(request, loadError, callBackData);
|
|
||||||
} else {
|
|
||||||
ImageKnifeLoader.parseImage(resBuf, fileKey, request, callBackData);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,136 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2025 Huawei Device Co., Ltd.
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
import { FileCache } from '../cache/FileCache';
|
|
||||||
import { IImageLoaderStrategy } from './IImageLoaderStrategy';
|
|
||||||
import {
|
|
||||||
ImageKnifeData,
|
|
||||||
ImageKnifeRequestSource,
|
|
||||||
ImageKnifeRequestWithSource,
|
|
||||||
RequestJobRequest,
|
|
||||||
TimeInfo
|
|
||||||
} from '../model/ImageKnifeData';
|
|
||||||
import http from '@ohos.net.http';
|
|
||||||
import { ImageKnifeLoader } from '../ImageKnifeLoader';
|
|
||||||
import { combineArrayBuffers } from '../utils/ArrayBufferUtils';
|
|
||||||
import { BusinessError, emitter } from '@kit.BasicServicesKit';
|
|
||||||
import { Constants, LoadPhase, LoadPixelMapCode } from '../utils/Constants';
|
|
||||||
import { LogUtil } from '../utils/LogUtil';
|
|
||||||
import List from '@ohos.util.List';
|
|
||||||
|
|
||||||
class RequestData {
|
|
||||||
public receiveSize: number = 2000
|
|
||||||
public totalSize: number = 2000
|
|
||||||
}
|
|
||||||
|
|
||||||
// HTTP加载策略
|
|
||||||
export class HttpLoaderStrategy implements IImageLoaderStrategy {
|
|
||||||
async loadImage(
|
|
||||||
request: RequestJobRequest,
|
|
||||||
requestList: List<ImageKnifeRequestWithSource> | undefined,
|
|
||||||
fileKey: string,
|
|
||||||
callBackData: ImageKnifeData,
|
|
||||||
callBackTimeInfo: TimeInfo
|
|
||||||
): Promise<void> {
|
|
||||||
let resBuf: ArrayBuffer | undefined;
|
|
||||||
let loadError: string = '';
|
|
||||||
|
|
||||||
// 从文件缓存获取
|
|
||||||
ImageKnifeLoader.assembleError(callBackData, LoadPhase.PHASE_NET);
|
|
||||||
callBackTimeInfo.diskCheckStartTime = Date.now();
|
|
||||||
resBuf = FileCache.getFileCacheByFile(request.context, fileKey, request.fileCacheFolder);
|
|
||||||
callBackTimeInfo.diskCheckEndTime = Date.now();
|
|
||||||
|
|
||||||
if (resBuf !== undefined) {
|
|
||||||
LogUtil.log(`success get image from filecache for key = ${fileKey} src = ${request.componentId},
|
|
||||||
srcType:${request.requestSource}, ${request.componentVersion}`);
|
|
||||||
ImageKnifeLoader.parseImage(resBuf, fileKey, request, callBackData);
|
|
||||||
} else if (request.onlyRetrieveFromCache !== true) {
|
|
||||||
LogUtil.log(`HttpDownloadClient.start: ${request.componentId}, srcType:${request.requestSource},
|
|
||||||
${request.componentVersion}`);
|
|
||||||
callBackTimeInfo.netRequestStartTime = Date.now();
|
|
||||||
const httpRequest = http.createHttp();
|
|
||||||
emitter.once((request.src as string) + request.componentId,()=>{
|
|
||||||
httpRequest.destroy()
|
|
||||||
})
|
|
||||||
let progress: number = 0;
|
|
||||||
const arrayBuffers: ArrayBuffer[] = [];
|
|
||||||
const headerObj: Record<string, Object> = ImageKnifeLoader.getHeaderObj(request);
|
|
||||||
|
|
||||||
httpRequest.on('dataReceive', (data: ArrayBuffer) => {
|
|
||||||
arrayBuffers.push(data);
|
|
||||||
});
|
|
||||||
|
|
||||||
if (request.isWatchProgress) {
|
|
||||||
httpRequest.on('dataReceiveProgress', (data: RequestData) => {
|
|
||||||
if (data != undefined && typeof data.receiveSize === 'number' && typeof data.totalSize === 'number') {
|
|
||||||
const percent = Math.round(((data.receiveSize * 1.0) / (data.totalSize * 1.0)) * 100);
|
|
||||||
if (progress !== percent) {
|
|
||||||
progress = percent;
|
|
||||||
if (requestList === undefined) {
|
|
||||||
// 子线程
|
|
||||||
emitter.emit(Constants.PROGRESS_EMITTER + request.memoryKey, { data: { 'value': progress } });
|
|
||||||
} else {
|
|
||||||
// 主线程请求
|
|
||||||
requestList.forEach((requestWithSource: ImageKnifeRequestWithSource) => {
|
|
||||||
if (requestWithSource.request.imageKnifeOption.progressListener !== undefined &&
|
|
||||||
requestWithSource.source === ImageKnifeRequestSource.SRC) {
|
|
||||||
requestWithSource.request.imageKnifeOption.progressListener(progress);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
let promise = httpRequest.requestInStream(request.src as string, {
|
|
||||||
header: headerObj,
|
|
||||||
method: http.RequestMethod.GET,
|
|
||||||
expectDataType: http.HttpDataType.ARRAY_BUFFER,
|
|
||||||
connectTimeout: request.connectTimeout ?? 60000,
|
|
||||||
readTimeout: request.readTimeout ?? 30000,
|
|
||||||
caPath: request.caPath
|
|
||||||
});
|
|
||||||
promise.then((data: number) => {
|
|
||||||
emitter.off((request.src as string) + request.componentId)
|
|
||||||
callBackData.httpCode = data;
|
|
||||||
ImageKnifeLoader.assembleError(callBackData,LoadPhase.PHASE_NET, undefined);
|
|
||||||
callBackTimeInfo.netRequestEndTime = Date.now();
|
|
||||||
if (data == 200 || data == 206 || data == 204) {
|
|
||||||
resBuf = combineArrayBuffers(arrayBuffers);
|
|
||||||
ImageKnifeLoader.FileCacheParseImage(request,resBuf,fileKey, callBackData);
|
|
||||||
} else {
|
|
||||||
loadError = 'HttpDownloadClient has error, http code =' + JSON.stringify(data);
|
|
||||||
ImageKnifeLoader.makeEmptyResult(request,loadError, ImageKnifeLoader.assembleError(callBackData,
|
|
||||||
LoadPhase.PHASE_NET, LoadPixelMapCode.IMAGE_HTTPS_LOAD_FAILED_CODE));
|
|
||||||
}
|
|
||||||
}).catch((err: BusinessError) => {
|
|
||||||
emitter.off((request.src as string) + request.componentId)
|
|
||||||
callBackData.httpCode = err.code;
|
|
||||||
loadError = 'HttpDownloadClient download ERROR : err = ' + JSON.stringify(err);
|
|
||||||
callBackTimeInfo.netRequestEndTime = Date.now();
|
|
||||||
ImageKnifeLoader.makeEmptyResult(request,loadError, ImageKnifeLoader.assembleError(callBackData,
|
|
||||||
LoadPhase.PHASE_NET, LoadPixelMapCode.IMAGE_HTTPS_LOAD_FAILED_CODE));
|
|
||||||
});
|
|
||||||
LogUtil.log('HttpDownloadClient.end:' + request.componentId + ',srcType:' +
|
|
||||||
request.requestSource + ',' + request.componentVersion);
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
callBackTimeInfo.netRequestEndTime = Date.now();
|
|
||||||
loadError = `onlyRetrieveFromCache, do not fetch image src = ${request.src}`;
|
|
||||||
ImageKnifeLoader.makeEmptyResult(request, loadError, callBackData);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,27 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2025 Huawei Device Co., Ltd.
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
import { ImageKnifeData, ImageKnifeRequestWithSource, RequestJobRequest, TimeInfo } from '../model/ImageKnifeData';
|
|
||||||
import List from '@ohos.util.List';
|
|
||||||
|
|
||||||
// 定义图片加载策略接口
|
|
||||||
export interface IImageLoaderStrategy {
|
|
||||||
loadImage(
|
|
||||||
request: RequestJobRequest,
|
|
||||||
requestList: List<ImageKnifeRequestWithSource> | undefined,
|
|
||||||
fileKey: string,
|
|
||||||
callBackData: ImageKnifeData,
|
|
||||||
callBackTimeInfo: TimeInfo
|
|
||||||
): Promise<void>;
|
|
||||||
}
|
|
|
@ -1,44 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2025 Huawei Device Co., Ltd.
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
// 加载策略工厂
|
|
||||||
import { CustomLoaderStrategy } from './CustomLoaderStrategy';
|
|
||||||
import { FileSystemLoaderStrategy } from './FileSystemLoaderStrategy';
|
|
||||||
import { HttpLoaderStrategy } from './HttpLoaderStrategy';
|
|
||||||
import { IImageLoaderStrategy } from './IImageLoaderStrategy';
|
|
||||||
import { ImageKnifeRequestSource, RequestJobRequest } from '../model/ImageKnifeData';
|
|
||||||
import { ResourceLoaderStrategy } from './ResourceLoaderStrategy';
|
|
||||||
import { FileLocalLoadStrategy } from './FileLocalLoadStrategy';
|
|
||||||
|
|
||||||
export class ImageLoaderFactory {
|
|
||||||
static getLoaderStrategy(request: RequestJobRequest): IImageLoaderStrategy | null {
|
|
||||||
if (request.customGetImage !== undefined &&
|
|
||||||
request.requestSource === ImageKnifeRequestSource.SRC &&
|
|
||||||
typeof request.src === 'string'
|
|
||||||
) {
|
|
||||||
return new CustomLoaderStrategy();
|
|
||||||
} else if (typeof request.src === 'string') {
|
|
||||||
if (request.src.startsWith('http://') || request.src.startsWith('https://')) {
|
|
||||||
return new HttpLoaderStrategy();
|
|
||||||
} else if (request.src.startsWith('datashare://') || request.src.startsWith('file://')) {
|
|
||||||
return new FileSystemLoaderStrategy();
|
|
||||||
} else {
|
|
||||||
return new FileLocalLoadStrategy();
|
|
||||||
}
|
|
||||||
} else if (typeof request.src === 'number') {
|
|
||||||
return new ResourceLoaderStrategy();
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,65 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2025 Huawei Device Co., Ltd.
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
// 资源文件加载策略
|
|
||||||
import { IImageLoaderStrategy } from './IImageLoaderStrategy';
|
|
||||||
import {
|
|
||||||
ImageKnifeData,
|
|
||||||
ImageKnifeRequestSource,
|
|
||||||
ImageKnifeRequestWithSource,
|
|
||||||
RequestJobRequest,
|
|
||||||
TimeInfo
|
|
||||||
} from '../model/ImageKnifeData';
|
|
||||||
import List from '@ohos.util.List';
|
|
||||||
import { application } from '@kit.AbilityKit';
|
|
||||||
import { ImageKnifeLoader } from '../ImageKnifeLoader';
|
|
||||||
|
|
||||||
export class ResourceLoaderStrategy implements IImageLoaderStrategy {
|
|
||||||
async loadImage(
|
|
||||||
request: RequestJobRequest,
|
|
||||||
requestList: List<ImageKnifeRequestWithSource> | undefined,
|
|
||||||
fileKey: string,
|
|
||||||
callBackData: ImageKnifeData,
|
|
||||||
callBackTimeInfo: TimeInfo
|
|
||||||
): Promise<void> {
|
|
||||||
let resBuf: ArrayBuffer | undefined;
|
|
||||||
let loadError: string = '';
|
|
||||||
|
|
||||||
if (typeof request.src === 'number') {
|
|
||||||
const moduleContext = await application.createModuleContext(request.context, request.moduleName);
|
|
||||||
const manager = moduleContext.resourceManager;
|
|
||||||
if ((resBuf == undefined && request.onlyRetrieveFromCache !== true &&
|
|
||||||
request.requestSource === ImageKnifeRequestSource.SRC) ||
|
|
||||||
(resBuf == undefined && request.requestSource !== ImageKnifeRequestSource.SRC)) {
|
|
||||||
if (request.src === -1) {
|
|
||||||
const resName = request.resName as string;
|
|
||||||
resBuf =
|
|
||||||
(await manager.getMediaByName(resName.substring(resName.lastIndexOf('.') + 1))).buffer as ArrayBuffer;
|
|
||||||
} else {
|
|
||||||
resBuf = request.resName ?
|
|
||||||
manager.getRawFileContentSync(request.resName).buffer.slice(0) :
|
|
||||||
(manager.getMediaContentSync(request.src)).buffer as ArrayBuffer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (resBuf === undefined || resBuf === null){
|
|
||||||
callBackTimeInfo.requestEndTime = Date.now();
|
|
||||||
loadError = 'Resource load error';
|
|
||||||
ImageKnifeLoader.makeEmptyResult(request, loadError ,callBackData);
|
|
||||||
} else {
|
|
||||||
ImageKnifeLoader.parseImage(resBuf,fileKey,request, callBackData);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -158,9 +158,3 @@ export interface RequestJobRequest {
|
||||||
readTimeout?: number
|
readTimeout?: number
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface FlipRotate{
|
|
||||||
horizontal: boolean,
|
|
||||||
vertical: boolean,
|
|
||||||
rotate: number,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,6 @@ export class ImageKnifeRequest {
|
||||||
componentWidth: number = 0
|
componentWidth: number = 0
|
||||||
componentHeight: number = 0
|
componentHeight: number = 0
|
||||||
drawPlayHolderSuccess: boolean = false
|
drawPlayHolderSuccess: boolean = false
|
||||||
drawMainSuccess: boolean = false
|
|
||||||
imageKnifeOption: ImageKnifeOption
|
imageKnifeOption: ImageKnifeOption
|
||||||
context: common.UIAbilityContext
|
context: common.UIAbilityContext
|
||||||
ImageKnifeRequestCallback: ImageKnifeRequestCallback
|
ImageKnifeRequestCallback: ImageKnifeRequestCallback
|
||||||
|
@ -30,7 +29,6 @@ export class ImageKnifeRequest {
|
||||||
headers: Map<string,Object> = new Map<string,Object>()
|
headers: Map<string,Object> = new Map<string,Object>()
|
||||||
imageKnifeData?: ImageKnifeData
|
imageKnifeData?: ImageKnifeData
|
||||||
componentId?: number
|
componentId?: number
|
||||||
animator?: boolean
|
|
||||||
constructor(option: ImageKnifeOption,
|
constructor(option: ImageKnifeOption,
|
||||||
uIAbilityContext: common.UIAbilityContext,
|
uIAbilityContext: common.UIAbilityContext,
|
||||||
width: number,
|
width: number,
|
||||||
|
|
|
@ -56,12 +56,11 @@ export class CropTransformation extends PixelMapTransformation {
|
||||||
let scaledWidth: number = scale * pixelMapWidth;
|
let scaledWidth: number = scale * pixelMapWidth;
|
||||||
let scaledHeight: number = scale * pixelMapHeight;
|
let scaledHeight: number = scale * pixelMapHeight;
|
||||||
let left: number = (this.mWidth - scaledWidth) / 2;
|
let left: number = (this.mWidth - scaledWidth) / 2;
|
||||||
let top: number = Math.abs(this.getTop(scaledHeight));
|
let top: number = Math.abs(this.getTop(pixelMapHeight));
|
||||||
toTransform.scaleSync(scale,scale)
|
|
||||||
let region: image.Region = {
|
let region: image.Region = {
|
||||||
size: {
|
size: {
|
||||||
width: this.mWidth,
|
width: scaledWidth > pixelMapWidth ? pixelMapWidth : scaledWidth,
|
||||||
height: this.mHeight
|
height: scaledHeight > pixelMapHeight ? pixelMapHeight : scaledHeight
|
||||||
},
|
},
|
||||||
x: left < 0 ? 0 : left,
|
x: left < 0 ? 0 : left,
|
||||||
y: top < 0 ? 0 : top
|
y: top < 0 ? 0 : top
|
||||||
|
|
|
@ -4,11 +4,7 @@
|
||||||
"type": "har",
|
"type": "har",
|
||||||
"deviceTypes": [
|
"deviceTypes": [
|
||||||
"default",
|
"default",
|
||||||
"tablet",
|
"tablet"
|
||||||
"tv",
|
|
||||||
"wearable",
|
|
||||||
"car",
|
|
||||||
"2in1"
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,3 @@
|
||||||
# Keep options:
|
# Keep options:
|
||||||
# -keep-property-name: specifies property names that you want to keep
|
# -keep-property-name: specifies property names that you want to keep
|
||||||
# -keep-global-name: specifies names that you want to keep in the global scope
|
# -keep-global-name: specifies names that you want to keep in the global scope
|
||||||
|
|
||||||
-keep
|
|
||||||
./oh_modules/@ohos/imageknife
|
|
|
@ -5,11 +5,7 @@
|
||||||
"description": "$string:shared_desc",
|
"description": "$string:shared_desc",
|
||||||
"deviceTypes": [
|
"deviceTypes": [
|
||||||
"default",
|
"default",
|
||||||
"tablet",
|
"tablet"
|
||||||
"tv",
|
|
||||||
"wearable",
|
|
||||||
"car",
|
|
||||||
"2in1"
|
|
||||||
],
|
],
|
||||||
"deliveryWithInstall": true,
|
"deliveryWithInstall": true,
|
||||||
"pages": "$profile:main_pages"
|
"pages": "$profile:main_pages"
|
||||||
|
|
Loading…
Reference in New Issue