!19 ImageKnife 1.0.4 commit
Merge pull request !19 from zhoulisheng1/master
13
CHANGELOG.md
|
@ -1,4 +1,15 @@
|
|||
## 1.0.4
|
||||
|
||||
渲染显示部分使用Canvas组件替代Image组件
|
||||
|
||||
重构渲染封装层ImageKnifeComponent自定义组件
|
||||
|
||||
新增GIF图片解析能力
|
||||
|
||||
新增SVG图片解析能力
|
||||
|
||||
## 1.0.3
|
||||
|
||||
- 适配OpenHarmony API9 Stage模型。
|
||||
## 1.0.2
|
||||
- 支持用户自定义扩展变换接口。
|
||||
|
@ -11,7 +22,7 @@
|
|||
- 支持内存缓存,使用LRUCache算法,对图片数据进行内存缓存。
|
||||
- 支持磁盘缓存,对于下载图片会保存一份至磁盘当中。
|
||||
- 支持进行图片变换。
|
||||
- 支持用户配置参数使用:(例如:配置是否开启第一级内存缓存,配置磁盘缓存策略,配置仅使用缓存加载数据,配置图片变换效果,配置占位图,配置加载失败占位图等)。
|
||||
- 支持用户配置参数使用:(例如:配置是否开启一级内存缓存,配置磁盘缓存策略,配置仅使用缓存加载数据,配置图片变换效果,配置占位图,配置加载失败占位图等)。
|
||||
- 推荐使用ImageKnifeComponent组件配合ImageKnifeOption参数来实现功能。
|
||||
- 支持用户自定义配置实现能力参考ImageKnifeComponent组件中对于入参ImageKnifeOption的处理。
|
||||
|
||||
|
|
|
@ -0,0 +1,172 @@
|
|||
OPEN SOURCE SOFTWARE NOTICE
|
||||
|
||||
Please note we provide an open source software notice for the third party open source software along with this software and/or this software component (in the following just “this SOFTWARE”). The open source software licenses are granted by the respective right holders.
|
||||
|
||||
Warranty Disclaimer
|
||||
THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
|
||||
|
||||
Copyright Notice and License Texts
|
||||
|
||||
----------------------------------------------------------------------
|
||||
Software: gifuct-js 2.1.2
|
||||
Copyright notice:
|
||||
Copyright (c) 2015 Matt Way
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Matt Way
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
----------------------------------------------------------------------
|
||||
Software: js-spark-md5 3.0.2
|
||||
Copyright notice:
|
||||
Copyright (c) 2015 André Cruz <amdfcruz@gmail.com>
|
||||
|
||||
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
||||
Version 2, December 2004
|
||||
|
||||
Copyright (C) 2015 André Cruz <amdfcruz@gmail.com>
|
||||
|
||||
Everyone is permitted to copy and distribute verbatim or modified
|
||||
copies of this license document, and changing it is allowed as long
|
||||
as the name is changed.
|
||||
|
||||
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. You just DO WHAT THE FUCK YOU WANT TO.
|
||||
Copyright (c) 2015 André Cruz <amdfcruz@gmail.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
----------------------------------------------------------------------
|
||||
Software: jsBinarySchemaParser v1.0.1
|
||||
Copyright notice:
|
||||
Copyright (c) 2015 Matt Way
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Matt Way
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
----------------------------------------------------------------------
|
||||
Software: UPNG.js 1
|
||||
Copyright notice:
|
||||
Copyright (c) 2017 Photopea
|
||||
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2017 Photopea
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
----------------------------------------------------------------------
|
||||
Software: pako 1.0.5
|
||||
Copyright notice:
|
||||
Copyright (C) 2014-2017 by Vitaly Puzrin and Andrei Tuputcyn
|
||||
|
||||
(The MIT License)
|
||||
|
||||
Copyright (C) 2014-2017 by Vitaly Puzrin and Andrei Tuputcyn
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
----------------------------------------------------------------------
|
||||
Software:Stack Blur v1.0
|
||||
Copyright notice:
|
||||
Copyright (C) Mario Klingemann <mario at quasimondo.com>
|
||||
|
||||
Stack Blur v1.0 from
|
||||
http://www.quasimondo.com/StackBlurForCanvas/StackBlurDemo.html
|
||||
|
||||
Java Author: Mario Klingemann <mario at quasimondo.com>
|
||||
http://incubator.quasimondo.com
|
||||
created Feburary 29, 2004
|
||||
port : Yahel Bouaziz <yahel at kayenko.com>
|
||||
http://www.kayenko.com
|
||||
ported april 5th, 2012
|
||||
|
||||
This is a compromise between Gaussian Blur and Box blur
|
||||
It creates much better looking blurs than Box Blur, but is
|
||||
7x faster than my Gaussian Blur implementation.
|
||||
|
||||
I called it Stack Blur because this describes best how this
|
||||
filter works internally: it creates a kind of moving stack
|
||||
of colors whilst scanning through the image. Thereby it
|
||||
just has to add one new block of color to the right side
|
||||
of the stack and remove the leftmost color. The remaining
|
||||
colors on the topmost layer of the stack are either added on
|
||||
or reduced by one, depending on if they are on the right or
|
||||
on the left side of the stack.
|
||||
|
||||
If you are using this algorithm in your code please add
|
||||
the following line:
|
||||
|
||||
Stack Blur Algorithm by Mario Klingemann <mario@quasimondo.com>
|
7
OAT.xml
|
@ -6,11 +6,18 @@
|
|||
<filteritem type="filename" name="hvigorfile.js" desc="hvigor构建脚本,DevEco Studio自动生成,不手动修改"/>
|
||||
<filteritem type="filename" name="*.json5" desc="hvigor配置文件,DevEco Studio自动生成,不手动修改"/>
|
||||
<filteritem type="filepath" name="imageknife/src/main/ets/components/imageknife/pngj/UPNG.js" desc="使用开源库UPNG,使用其默认版权头,无需修改"/>
|
||||
<filteritem type="filepath" name="imageknife/src/main/ets/components/imageknife/utils/gif/parse/lzw.js" desc="使用开源库gifuct-js,使用其默认版权头,无需修改"/>
|
||||
<filteritem type="filename" name="LICENSE" desc="版权文件,不添加版权头"/>
|
||||
<filteritem type="filename" name="NOTICE" desc="NOTICE文件,不添加版权头"/>
|
||||
|
||||
</filefilter>
|
||||
<filefilter name="defaultPolicyFilter" desc="Filters for compatibility,license header policies">
|
||||
<filteritem type="filename" name="hvigorfile.js" desc="hvigor构建脚本,DevEco Studio自动生成,不手动修改"/>
|
||||
<filteritem type="filename" name="*.json5" desc="hvigor配置文件,DevEco Studio自动生成,不手动修改"/>
|
||||
<filteritem type="filepath" name="imageknife/src/main/ets/components/imageknife/pngj/UPNG.js" desc="使用开源库UPNG,使用其默认版权头,无需修改"/>
|
||||
<filteritem type="filepath" name="imageknife/src/main/ets/components/imageknife/utils/gif/parse/lzw.js" desc="使用开源库gifuct-js,使用其默认版权头,无需修改"/>
|
||||
<filteritem type="filename" name="LICENSE" desc="版权文件,不添加版权头"/>
|
||||
<filteritem type="filename" name="NOTICE" desc="NOTICE文件,不添加版权头"/>
|
||||
</filefilter>
|
||||
<filefilter name="defaultPolicyFilter" desc="Filters for copyright header policies">
|
||||
</filefilter>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
{
|
||||
"Name": "glide",
|
||||
"License": "under one or more license",
|
||||
"License File": "https://github.com/bumptech/imageknife/blob/master/LICENSE",
|
||||
"License File": "https://github.com/bumptech/glide/blob/master/LICENSE",
|
||||
"Version Number": "4.13.1",
|
||||
"Owner" : "bumptech",
|
||||
"Upstream URL": "https://github.com/bumptech/glide",
|
||||
|
@ -12,10 +12,10 @@
|
|||
{
|
||||
"Name": "glide-transformations",
|
||||
"License": "Apache License 2.0",
|
||||
"License File": "https://github.com/wasabeef/imageknife-transformations/blob/main/LICENSE",
|
||||
"License File": "https://github.com/wasabeef/glide-transformations/blob/main/LICENSE",
|
||||
"Version Number": "4.3.0",
|
||||
"Owner" : "wasabeef",
|
||||
"Upstream URL": "https://github.com/wasabeef/imageknife-transformations",
|
||||
"Upstream URL": "https://github.com/wasabeef/glide-transformations",
|
||||
"Description": " An transformation library providing a variety of image transformations for Glide. "
|
||||
},
|
||||
|
||||
|
|
484
README.md
|
@ -8,12 +8,12 @@
|
|||
|
||||
- 支持内存缓存,使用LRUCache算法,对图片数据进行内存缓存。
|
||||
- 支持磁盘缓存,对于下载图片会保存一份至磁盘当中。
|
||||
- 支持进行图片变换,支持自定义变换。
|
||||
- 支持用户配置参数使用:(例如:配置是否开启第一级内存缓存,配置磁盘缓存策略,配置仅使用缓存加载数据,配置图片变换效果,配置占位图,配置加载失败占位图等)。
|
||||
- 支持进行图片变换: 支持图像像素源图片变换效果。
|
||||
- 支持用户配置参数使用:(例如:配置是否开启一级内存缓存,配置磁盘缓存策略,配置仅使用缓存加载数据,配置图片变换效果,配置占位图,配置加载失败占位图等)。
|
||||
- 推荐使用ImageKnifeComponent组件配合ImageKnifeOption参数来实现功能。
|
||||
- 支持用户自定义配置实现能力参考ImageKnifeComponent组件中对于入参ImageKnifeOption的处理。
|
||||
|
||||
<img src="screenshot/g3.gif" width="100%"/>
|
||||
<img src="screenshot/gif1.gif" width="50%"/>
|
||||
|
||||
## 下载安装
|
||||
|
||||
|
@ -25,7 +25,7 @@ OpenHarmony npm环境配置等更多内容,参考安装教程 [如何安装Ope
|
|||
|
||||
## 使用说明
|
||||
|
||||
1.首先初始化全局ImageKnife实例,在AbilityStage.ts中调用ImageKnife.with(this.context)进行初始化
|
||||
1.在AbilityStage.ts中,初始化全局ImageKnife实例。
|
||||
|
||||
```typescript
|
||||
import AbilityStage from "@ohos.application.AbilityStage"
|
||||
|
@ -33,27 +33,224 @@ import {ImageKnife} from '@ohos/imageknife'
|
|||
|
||||
export default class MyAbilityStage extends AbilityStage {
|
||||
onCreate() {
|
||||
globalThis.ImageKnife = ImageKnife.with(this.context);
|
||||
// 初始化全局ImageKnife实例,在AbilityStage.ts中调用ImageKnife.with(this.context)进行初始化
|
||||
globalThis.ImageKnife = ImageKnife.with(this.context)
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
2.参考[推荐使用](###'推荐使用')或[自定义实现](###'自定义实现')
|
||||
### 1.加载普通图片
|
||||
|
||||
#### 推荐使用:
|
||||
|
||||
使用ImageKnifeOption作为入参,配合自定义组件ImageKnifeComponent使用。
|
||||
接下来我们来写个简单实例看看:
|
||||
|
||||
```typescript
|
||||
import {ImageKnifeComponent} from '@ohos/imageknife'
|
||||
import {ImageKnifeOption} from '@ohos/imageknife'
|
||||
@Entry
|
||||
@Component
|
||||
struct Index {
|
||||
@State imageKnifeOption1: ImageKnifeOption =
|
||||
{
|
||||
{ // 加载一张本地的jpg资源(必选)
|
||||
loadSrc: $r('app.media.jpgSample'),
|
||||
size: { width: 300, height: 300 },
|
||||
// 组件宽设置为300,高设置为300(必选)
|
||||
size: { width: '300', height: '300' },
|
||||
// 占位图使用本地资源icon_loading(可选)
|
||||
placeholderSrc: $r('app.media.icon_loading'),
|
||||
// 失败占位图使用本地资源icon_failed(可选)
|
||||
errorholderSrc: $r('app.media.icon_failed')
|
||||
};
|
||||
build() {
|
||||
Scroll() {
|
||||
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
||||
ImageKnifeComponent({ imageKnifeOption: $imageKnifeOption1 })
|
||||
}
|
||||
}
|
||||
.width('100%')
|
||||
.height('100%')
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
非常简单,仅需定义一个ImageKnifeOption数据对象,然后在你需要的UI位置,加入ImageKnifeComponent自定义组件就可以加载出一张图像了。
|
||||
|
||||
### 2.加载SVG图片
|
||||
|
||||
加载svg其实和普通流程没有区别,只要将 `loadSrc: $r('app.media.jpgSample'),` `改成一张 loadSrc: $r('app.media.svgSample'),`svg类型图片即可。
|
||||
|
||||
目前加载SVG图片解析依赖了 [SVG三方库](https://gitee.com/openharmony-sig/ohos-svg),由于目前该库还无法解析mask标签,所以这里大家需要留意一下。
|
||||
|
||||
### 3.加载GIF图片
|
||||
|
||||
3.1加载GIF其实和普通流程也没有区别只要将 `loadSrc: $r('app.media.jpgSample'),` `改成一张 loadSrc: $r('app.media.gifSample'),`GIF图片即可。
|
||||
|
||||
但是解析gif图片属于耗时操作,所以我们需要将其放入子线程操作。 **这里我们需要在页面的创建和销毁上添加一个worker子线程操作。**
|
||||
|
||||
```typescript
|
||||
import router from '@system.router';
|
||||
import {
|
||||
ImageKnifeComponent,
|
||||
ImageKnifeOption,
|
||||
} from '@ohos/imageknife'
|
||||
import ArkWorker from '@ohos.worker'
|
||||
@Entry
|
||||
@Component
|
||||
struct IndexFunctionDemo {
|
||||
private globalGifWorker:any = undefined
|
||||
@State imageKnifeOption: ImageKnifeOption =
|
||||
{
|
||||
loadSrc: $r('app.media.gifSample'),
|
||||
size: { width: '300', height: '300' },
|
||||
placeholderSrc: $r('app.media.icon_loading'),
|
||||
errorholderSrc: $r('app.media.icon_failed')
|
||||
};
|
||||
|
||||
build() {
|
||||
Scroll() {
|
||||
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
||||
Text("简单示例:加载一张gif图片").fontSize(15)
|
||||
ImageKnifeComponent({ imageKnifeOption: $imageKnifeOption })
|
||||
}
|
||||
}
|
||||
.width('100%')
|
||||
.height('100%')
|
||||
}
|
||||
|
||||
aboutToAppear() {
|
||||
// 页面初始化创建worker
|
||||
this.globalGifWorker = new ArkWorker.Worker('entry/ets/pages/workers/gifParseWorker.ts', {
|
||||
type: 'classic',
|
||||
name: 'ImageKnifeParseGIF'
|
||||
})
|
||||
// gif解析在子线程,请在页面构建后创建worker,注入imageknife
|
||||
globalThis.ImageKnife.setGifWorker(this.globalGifWorker)
|
||||
}
|
||||
aboutToDisappear(){
|
||||
// 页面销毁 销毁worker
|
||||
if(this.globalGifWorker){
|
||||
this.globalGifWorker.terminate();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
#### 创建worker
|
||||
|
||||
由于使用到了worker,目前worker创建只能在entry里面,所以我这边着重讲一下worker配置的流程。
|
||||
|
||||
在entry/src/main/ets/pages目录下创建文件夹workers,然后在文件夹中创建gifParseWorker.ts文件,最后填入内容:
|
||||
|
||||
```typescript
|
||||
import arkWorker from '@ohos.worker';
|
||||
import { gifHandler } from '@ohos/imageknife/GifWorker'
|
||||
|
||||
arkWorker.parentPort.onmessage = gifHandler;
|
||||
```
|
||||
|
||||
代码处理流程已经封装在gifHanlder函数中了。
|
||||
|
||||
<img src="screenshot/jpg1.jpg" width="100%"/>
|
||||
|
||||
接下来我们需要在entry/build-profile.json5文件中添加配置
|
||||
|
||||
```typescript
|
||||
{
|
||||
"apiType": 'stageMode',
|
||||
"buildOption": {
|
||||
"sourceOption": {
|
||||
"workers": [
|
||||
"./src/main/ets/pages/workers/gifParseWorker.ts",
|
||||
]
|
||||
}
|
||||
},
|
||||
"targets": [
|
||||
{
|
||||
"name": "default",
|
||||
},
|
||||
{
|
||||
"name": "ohosTest",
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
<img src="screenshot/jpg2.jpg" width="100%"/>
|
||||
|
||||
|
||||
|
||||
经过了上面的配置,就配置好了worker, GIF图片加载就能顺利进行了。 **如果GIF加载未成功,可以检查一下worker配置是否完成**。
|
||||
|
||||
## 进阶使用
|
||||
|
||||
如果简单的加载一张图像无法满足需求,我们可以看看ImageKnifeOption这个类提供了哪些扩展能力。
|
||||
|
||||
### ImageKnifeOption参数列表
|
||||
|
||||
| 参数名称 | 入参内容 | 功能简介 |
|
||||
| ---------------------------- | ------------------------------------------------------------ | ----------------------------------- |
|
||||
| size | { width: string, height: string } | 设置组件宽高(必选) |
|
||||
| loadSrc | string \| PixelMap \| Resource | 设置主图资源(必选) |
|
||||
| mainScaleType | ScaleType | 设置主图展示样式(可选) |
|
||||
| strategy | DiskStrategy | 设置磁盘缓存策略(可选) |
|
||||
| dontAnimateFlag | boolean | gif加载展示一帧(可选) |
|
||||
| placeholderSrc | PixelMap \| Resource | 设置占位图(可选) |
|
||||
| placeholderScaleType | ScaleType | 设置占位图展示样式(可选) |
|
||||
| errorholderSrc | PixelMap \| Resource | 设置加载失败占位图(可选) |
|
||||
| errorholderSrcScaleType | ScaleType | 设置失败占位图展示样式(可选) |
|
||||
| retryholderSrc | PixelMap \| Resource | 设置加载失败重试占位图(可选) |
|
||||
| retryholderScaleType | ScaleType | 设置重试占位图展示样式(可选) |
|
||||
| thumbSizeMultiplier | number 范围(0,1] | 设置缩略图占比(可选) |
|
||||
| thumbSizeDelay | number | 设置缩略图展示时间(可选) |
|
||||
| thumbSizeMultiplierScaleType | ScaleType | 设置缩略图展示样式(可选) |
|
||||
| displayProgress | boolean | 设置是否展示下载进度条(可选) |
|
||||
| canRetryClick | boolean | 设置重试图层是否点击重试(可选) |
|
||||
| onlyRetrieveFromCache | boolean | 仅使用缓存加载数据(可选) |
|
||||
| isCacheable | boolean | 是否开启一级内存缓存(可选) |
|
||||
| gif | {<br/> // 返回一周期动画gif消耗的时间<br/> loopFinish?: (loopTime?) => void<br/> // gif播放速率相关<br/> speedFactory?: number<br/> // 直接展示gif第几帧数据<br/> seekTo?: number<br/> } | GIF播放控制能力(可选) |
|
||||
| transformation | BaseTransform<PixelMap> | 单个变换(可选) |
|
||||
| transformations | Array<BaseTransform<PixelMap>> | 多个变换,目前仅支持单个变换(可选) |
|
||||
| allCacheInfoCallback | IAllCacheInfoCallback | 输出缓存相关内容和信息(可选) |
|
||||
| backgroundColor | Color \| number \| string \| Resource | 组件背景颜色(可选) |
|
||||
| margin | { <br/> top?: number \| string \| Resource, <br/> right?: number \| string \| Resource, <br/> bottom?: number \| string \| Resource,<br/> left?: number \| string \| Resource<br/> } \| number \| string \| Resource | 组件间距(可选) |
|
||||
| sizeAnimate | AnimateParam | 组件大小变化显式动画效果(可选) |
|
||||
| **drawLifeCycle** | **IDrawLifeCycle** | **用户自定义实现绘制方案(可选)** |
|
||||
|
||||
其他参数只需要在ImageKnifeOption对象上按需添加即可。
|
||||
|
||||
这里我们着重讲一下**自定义实现绘制方案**。为了增强绘制扩展能力,目前ImageKnifeComponent使用了Canvas的渲染能力作为基础。在此之上为了抽象组件绘制表达。我将图像的状态使用了**IDrawLifeCycle绘制生命周期进行表达**,
|
||||
|
||||
大致流程 展示占位图->展示网络加载进度->展示缩略图->展示主图->展示重试图层->展示失败占位图
|
||||
|
||||
<img src="screenshot/png1.png" width="100%"/>
|
||||
|
||||
ImageKnifeComponent内部,责任链实现。 用户参数设置->全局参数设置->自定义组件内部设置
|
||||
|
||||
采用责任链的好处是,用户可以通过自定义绘制,重新绘制图层。如果不想绘制也可以通过预制回调获取绘制流程信息。
|
||||
|
||||
<img src="screenshot/png2.png" width="70%"/>
|
||||
|
||||
### 场景1:默认的展示不满足需求,需要加个圆角效果。
|
||||
|
||||
代码如下:
|
||||
|
||||
```typescript
|
||||
import {ImageKnifeComponent} from '@ohos/imageknife'
|
||||
import {ImageKnifeOption} from '@ohos/imageknife'
|
||||
import {ImageKnifeDrawFactory} from '@ohos/imageknife'
|
||||
@Entry
|
||||
@Component
|
||||
struct Index {
|
||||
@State imageKnifeOption1: ImageKnifeOption =
|
||||
{ // 加载一张本地的jpg资源(必选)
|
||||
loadSrc: $r('app.media.jpgSample'),
|
||||
// 组件宽设置为300,高设置为300(必选)
|
||||
size: { width: '300', height: '300' },
|
||||
// 占位图使用本地资源icon_loading(可选)
|
||||
placeholderSrc: $r('app.media.icon_loading'),
|
||||
// 失败占位图使用本地资源icon_failed(可选)
|
||||
errorholderSrc: $r('app.media.icon_failed'),
|
||||
// 绘制圆角30,边框5,边框"#ff00ff".用户自定义绘制(可选)
|
||||
drawLifeCycle:ImageKnifeDrawFactory.createRoundLifeCycle(5,"#ff00ff",30)
|
||||
};
|
||||
|
||||
|
||||
|
@ -69,86 +266,111 @@ struct Index {
|
|||
}
|
||||
```
|
||||
|
||||
#### 自定义实现:
|
||||
`ImageKnifeDrawFactory.createRoundLifeCycle(5,"#ff00ff",30)`我们深入查看源码可以发现,实际上是对IDrawLifeCycle接口的部分实现,这里我介绍一下IDrawLifeCycle。
|
||||
|
||||
使用原生Image组件,配合用户配置参数实现。
|
||||
**IDrawLifeCycle的返回值代表事件是否被消费,如果被消费接下来组件内部就不会处理,如果没被消费就会传递到下一个使用者。目前消费流程(用户自定义->全局配置定义->组件内部默认定义)**
|
||||
|
||||
##### 步骤1:
|
||||
所以我们在当数据是一张PixelMap的时候(目前jpg png bmp webp svg返回的都是PixelMap,gif返回GIFFrame数组),我们返回了true。消费了事件,代表这个绘制流程用户自定义完成。
|
||||
|
||||
定义自定义类
|
||||
<img src="screenshot/gif2.gif" width="50%"/>
|
||||
|
||||
由于IDrawLifeCycle实现较为冗长,我们封装了ImageKnifeDrawFactory工厂,提供了网络下载百分比效果、圆角、椭圆添加边框等能力。下面我们就再看看使用工厂封装之后的场景代码。
|
||||
|
||||
### 场景2: 网络下载百分比效果展示
|
||||
|
||||
当进行加载网络图片时,可能需要展示网络下载百分比动画。但是默认的动画又不能满足需求,这个时候我们就需要自定义网络下载百分比效果。代码如下:
|
||||
|
||||
```typescript
|
||||
export default class PixelMapPack{
|
||||
pixelMap:PixelMap;
|
||||
import AbilityStage from '@ohos.application.AbilityStage'
|
||||
import { ImageKnife,ImageKnifeDrawFactory} from '@ohos/imageknife'
|
||||
|
||||
import ArkWorker from '@ohos.worker'
|
||||
|
||||
export default class MyAbilityStage extends AbilityStage {
|
||||
onCreate() {
|
||||
globalThis.ImageKnife = ImageKnife.with(this.context);
|
||||
// 全局配置网络加载进度条
|
||||
globalThis.ImageKnife.setDefaultLifeCycle(ImageKnifeDrawFactory.createProgressLifeCycle("#10a5ff", 0.5))
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
使用@State关联PixelMapPack;
|
||||
这里大家可能会问,为什么会将这个IDrawLifeCycle放在AbilityStage里面实现?
|
||||
|
||||
这是因为网络下载百分比进度很多时候都是全局通用,如果有需要全局配置的自定义展示方案。推荐在AbilityStage里面,往ImageKnife的setDefaultLifeCycle函数中注入,即可将ImageKnifeComponent中的默认绘制方案替换。
|
||||
|
||||
在这里我们实现的效果如下图所示。
|
||||
|
||||
<img src="screenshot/gif3.gif" width="50%"/>
|
||||
|
||||
## 高级用法
|
||||
|
||||
以上简单使用和进阶使用都是经过一层自定义组件封装之后形成的,RequestOption封装成了ImageKnifeOption,绘制部分封装成了自定义组件ImageKnifeComponent。
|
||||
|
||||
如果用户其实并不关心绘制部分,或者说想用自己的通用方案对自定义组件ImageKnifeComponent重构都是可以的。
|
||||
|
||||
下面我们会着重指导用户如何复用图片加载逻辑,重构自定义组件ImageKnifeComponent。
|
||||
|
||||
首先我们先看看RequestOption构建的内容,如下表格所示:
|
||||
|
||||
### 数据加载
|
||||
|
||||
#### RequestOption构建:
|
||||
|
||||
请查看[RequestOption接口方法](##'RequestOption 用户配置参数')
|
||||
|
||||
了解了RequestOption的参数内容后,我们可以参考ImageKnifeComponent组件代码进行分析。
|
||||
|
||||
**从`imageKnifeExecute()`函数入口,首先我们需要构建一个RequestOption对象,`let request = new RequestOption()`, 接下来就是按需配置request对象的内容,最后使用 `globalThis.ImageKnife.call(request)`发送request执行任务即可。**
|
||||
|
||||
是不是很简单,而其实最重要的内容是就是: **按需配置request对象的内容** 为了更好理解,我举例说明一下:
|
||||
|
||||
#### 场景一: 简单加载一张图片
|
||||
|
||||
```typescript
|
||||
@State imageKnifePixelMapPack:PixelMapPack = new PixelMapPack();
|
||||
width:number = 200;
|
||||
height:number = 200;
|
||||
let request = new RequestOption();
|
||||
(必传)
|
||||
request.load("图片url")
|
||||
(可选 整个request监听回调)
|
||||
.addListener((err, data) => {
|
||||
// data 是ImageKnifeData对象
|
||||
if(data.isPixelMap()){
|
||||
// 这样就获取到了目标PixelMap
|
||||
let pixelmap = data.drawPixleMap.imagePixelMap;
|
||||
}
|
||||
return false;
|
||||
})
|
||||
|
||||
let compSize = {
|
||||
width: this.currentWidth,
|
||||
height:this.currentHeight
|
||||
}
|
||||
// (必传)这里setImageViewSize函数必传组件大小,因为涉及到图片变换效果都需要适配图像源和组件大小。
|
||||
request.setImageViewSize(compSize)
|
||||
// 最后使用ImageKnife的call函数调用request即可
|
||||
globalThis.ImageKnife.call(request)
|
||||
```
|
||||
|
||||
##### 步骤2:
|
||||
**其他场景,可以按需加载**
|
||||
|
||||
在你的component组件中,写下一个Image组件,将基础参数(入参PixelMap,组件的宽、高)配置好。
|
||||
比如我需要配置 **占位图** 只需要 在request对象创建好之后,调用 **placeholder** 函数即可
|
||||
|
||||
```typescript
|
||||
Image(this.imageKnifePixelMapPack.pixelMap)
|
||||
.backgroundColor(Color.Grey)
|
||||
.objectFit(ImageFit.Contain)
|
||||
.width(this.width)
|
||||
.height(this.height)
|
||||
request.placeholder(this.imageKnifeOption.placeholderSrc, (data) => {
|
||||
console.log('request.placeholder callback')
|
||||
this.displayPlaceholder(data)
|
||||
})
|
||||
```
|
||||
|
||||
##### 步骤3:
|
||||
|
||||
在aboutToAppear() 函数中调用加载流程。
|
||||
再比如 我对缓存配置有要求,我要禁用内存缓存,调用 **skipMemoryCache** 函数即可
|
||||
|
||||
```typescript
|
||||
//配置参数
|
||||
let requestOptin = new RequestOption();
|
||||
//加载本地图片
|
||||
requestOptin.load($r('app.media.jpgSample'))
|
||||
.addListener((err,data) => {
|
||||
//加载成功/失败回调监听
|
||||
if (data.isPixelMap()) {
|
||||
let pixelMapPack = new PixelMapPack();
|
||||
pixelMapPack.pixelMap = data.imageKnifeValue as PixelMap;
|
||||
//当前的PixelMap资源发生变化,jpgSample图片将会由Image组件重新渲染,并展示
|
||||
this.imageKnifePixelMapPack = pixelMapPack;
|
||||
}
|
||||
})
|
||||
.placeholder( $r('app.media.icon_loading'), (data)=>{
|
||||
// 占位图回调监听
|
||||
})
|
||||
.errorholder( $r('app.media.icon_failed'), (data)=>{
|
||||
// 失败占位图回调监听
|
||||
})
|
||||
.thumbnail(0.3, (data) => {
|
||||
// 缩略图加载成功回调
|
||||
})
|
||||
// 一定要把控件大小传给RequestOption,图片变换必须
|
||||
.setImageViewSize({width:200, height:200})
|
||||
// 设置缓存策略
|
||||
.diskCacheStrategy(new AUTOMATIC())
|
||||
.addProgressListener((percentValue: string) => {
|
||||
// 图片网络加载进度条百分比回调
|
||||
})
|
||||
.addRetryListener((error: any) => {
|
||||
// 加载失败重试监听 图片加载失败时优先展示重试图层,点击重试图层,会重新进行一次加载流程
|
||||
})
|
||||
// 左上圆角10pixel像素点
|
||||
.roundedCorners({top:10})
|
||||
// 启动加载流程,执行结果将会返回到上面的回调接口中
|
||||
globalThis.ImageKnife.call(requestOptin);
|
||||
request.skipMemoryCache(true)
|
||||
```
|
||||
|
||||
##### 步骤4:
|
||||
这里只是简单介绍部分使用,更多的内容请参考 **按需加载** 原则,并且可以参考ImageKnifeComponent源码或者根据文档自行探索实现。
|
||||
|
||||
|
||||
更多细节设置请参考自定义Component的ImageKnifeComponent实现。
|
||||
|
||||
## 接口说明
|
||||
|
||||
|
@ -161,6 +383,7 @@ let requestOptin = new RequestOption();
|
|||
| diskCacheStrategy(strategy: DiskStrategy) | DiskStrategy | 配置磁盘缓存策略 NONE SOURCE RESULT ALL AUTOMATIC |
|
||||
| placeholder(src: PixelMap \| Resource, func?: AsyncSuccess<PixelMap>) | src: PixelMap \| Resource, func?: AsyncSuccess<PixelMap> | 配置占位图,其中func为数据回调函数 |
|
||||
| errorholder(src: PixelMap \| Resource, func?: AsyncSuccess<PixelMap>) | src: PixelMap \| Resource, func?: AsyncSuccess<PixelMap> | 配置加载失败占位图,其中func为数据回调函数 |
|
||||
| retryholder(src: PixelMap \| Resource, func?: AsyncSuccess<PixelMap>) | src: PixelMap \| Resource, func?: AsyncSuccess<PixelMap> | 配置重试占位图,如果配置则加载失败后优先展示重试占位图 |
|
||||
| addListener(func: AsyncCallback<PixelMap>) | func: AsyncCallback<PixelMap> | 配置整个监听回调,数据正常加载返回,加载失败返回错误信息 |
|
||||
| thumbnail(sizeMultiplier:number, func?: AsyncSuccess<ImageKnifeData>) | sizeMultiplier:number, func?: AsyncSuccess<ImageKnifeData> | 设置缩略图比例,缩略图返回后,加载并展示缩略图 |
|
||||
| addProgressListener(func?: AsyncSuccess<string>){ this.progressFunc = func; return this; } | func?: AsyncSuccess<string> | 设置网络下载百分比监听,返回数据加载百分比数值 |
|
||||
|
@ -169,6 +392,8 @@ let requestOptin = new RequestOption();
|
|||
| skipMemoryCache(skip: boolean) | skip: boolean | 配置是否跳过内存缓存 |
|
||||
| retrieveDataFromCache(flag: boolean) | flag: boolean | 配置仅从缓存中加载数据 |
|
||||
|
||||
|
||||
|
||||
同时支持[图片变换相关](##'图片变换相关')接口。
|
||||
|
||||
### ImageKnife 启动器/门面类
|
||||
|
@ -183,7 +408,7 @@ let requestOptin = new RequestOption();
|
|||
| 使用方法 | 类型 | 策略描述 |
|
||||
| ------------------------------------------ | --------- | ---------------------------------------- |
|
||||
| request.diskCacheStrategy(new ALL()) | ALL | 表示既缓存原始图片,也缓存转换过后的图片 |
|
||||
| request.diskCacheStrategy(new AUTOMATIC()) | AUTOMATIC | 表示尝试对本地和远程图片使用最佳的策略 |
|
||||
| request.diskCacheStrategy(new AUTOMATIC()) | AUTOMATIC | 表示尝试对本地和远程图片使用适合的策略 |
|
||||
| request.diskCacheStrategy(new DATA()) | DATA | 表示只缓存原始图片 |
|
||||
| request.diskCacheStrategy(new NONE()) | NONE | 表示不缓存任何内容 |
|
||||
| request.diskCacheStrategy(new RESOURCE()) | RESOURCE | 表示只缓存转换过后的图片 |
|
||||
|
@ -212,6 +437,8 @@ let requestOptin = new RequestOption();
|
|||
| request.mask() | MaskTransformation | 遮罩 |
|
||||
| request.swirlFilter() | SwirlFilterTransformation | 扭曲滤波器 |
|
||||
|
||||
<img src="screenshot/gif4.gif" width="50%"/>
|
||||
|
||||
## 兼容性
|
||||
|
||||
支持 OpenHarmony API version 9 及以上版本。
|
||||
|
@ -221,72 +448,69 @@ let requestOptin = new RequestOption();
|
|||
```
|
||||
/imageknife/src/
|
||||
- main/ets/components
|
||||
- cache # 缓存相关内容
|
||||
- diskstrategy # 缓存策略
|
||||
- key # 缓存key生成策略
|
||||
- Base64.ets # Base64算法
|
||||
- cache # 缓存相关内容
|
||||
- diskstrategy # 缓存策略
|
||||
- key # 缓存key生成策略
|
||||
- Base64.ets # Base64算法
|
||||
- CustomMap.ets # 自定义Map封装
|
||||
- DiskCacheEntry.ets# 磁盘缓存entry
|
||||
- DiskLruCache.ets # 磁盘LRU缓存策略
|
||||
- FileReader.ets # 文件读取相关
|
||||
- DiskCacheEntry.ets # 磁盘缓存entry
|
||||
- DiskLruCache.ets # 磁盘LRU缓存策略
|
||||
- FileReader.ets # 文件读取相关
|
||||
- FileUtils.ets # 文件工具类
|
||||
- LruCache.ets # 内存LRU缓存策略
|
||||
- Md5.ets # MD5算法
|
||||
- LruCache.ets # 内存LRU缓存策略
|
||||
- Md5.ets # MD5算法
|
||||
|
||||
- imageknife # imageknife主要内容
|
||||
- compress # 压缩相关
|
||||
- constants # 常量相关
|
||||
- entry # 部分数据结构
|
||||
- holder # 占位图相关解析
|
||||
- interface # 接口相关
|
||||
- imageknife # imageknife主要内容
|
||||
- compress # 压缩相关
|
||||
- constants # 常量相关
|
||||
- entry # 部分数据结构
|
||||
- holder # 占位图相关解析
|
||||
- interface # 接口相关
|
||||
- networkmanage # 网络相关
|
||||
- pngj # pngj相关
|
||||
- pngj # pngj相关
|
||||
- requestmanage # imageknife请求相关
|
||||
- resourcemanage # 本地资源解析相关
|
||||
- transform # 图片变换相关
|
||||
- utils # 工具类相关
|
||||
- ImageKnife.ets # imageknife门面,app持久化类
|
||||
- ImageKnifeData.ets # 数据封装
|
||||
- ImageKnifeComponent.ets # 自定义控件封装
|
||||
- ImageKnifeOption.ets # 用户传参数封装
|
||||
- PixelMapPack.ets # PixelMap封装
|
||||
- RequestOption.ets # 用户设置参数封装
|
||||
- resourcemanage # 本地资源解析相关
|
||||
- transform # 图片变换相关
|
||||
- utils # 工具类相关
|
||||
- ImageKnife.ets # imageknife门面,app持久化类
|
||||
- ImageKnifeData.ets # 数据封装
|
||||
- ImageKnifeComponent.ets # 自定义控件封装
|
||||
- ImageKnifeDrawFactory.ets # IDrawLifeCycle用户自定义实现
|
||||
- ImageKnifeOption.ets # 用户传参数封装
|
||||
- RequestOption.ets # 用户设置参数封装
|
||||
|
||||
/entry/src/
|
||||
- main/ets/MainAbility
|
||||
- pages # 测试page页面列表
|
||||
- basicTestFeatureAbilityPage.ets # 测试元能力
|
||||
- basicTestFileIOPage.ets # 测试fileio
|
||||
- basicTestMediaImage.ets # 测试媒体image
|
||||
- basicTestResourceManagerPage.ets # 测试本地资源解析
|
||||
- compressPage.ets # 压缩页面
|
||||
- cropImagePage.ets # 裁剪页面
|
||||
- cropImagePage2.ets # 手势裁剪页面
|
||||
- frescoImageTestCasePage.ets # 测试属性动画组件切换
|
||||
- frescoLayerTestCasePage.ets # 测试ImageKnifeComponent组件切换配合属性动画
|
||||
- frescoRetryTestCasePage.ets # 测试ImageKnifeComponent加载失败重试
|
||||
- index.ets # 测试页面入口
|
||||
- indexFresco.ets # 二级测试页面入口
|
||||
- loadNetworkTestCasePage.ets # 网络加载测试
|
||||
- loadResourceTestCasePage.ets # 本地加载测试
|
||||
- showErrorholderTestCasePage.ets # 加载失败占位图测试
|
||||
- storageTestDiskLruCache.ets # 磁盘缓存测试
|
||||
- storageTestLruCache.ets # 内存缓存测试
|
||||
- testAllCacheInfoPage.ets # 所有缓存信息获取测试
|
||||
- testAllTypeImageKnifeComponentPage.ets # 所有类型图片加载测试
|
||||
- testAllTypeNativeImagePage.ets # 所有类型本地图片加载测试
|
||||
- testGifDontAnimatePage.ets # gif加载静态图片测试
|
||||
- testImageKnifeOptionChangedPage.ets # ImageKnifeOption数据切换测试
|
||||
- testImageKnifeOptionChangedPage2.ets # ImageKnifeOption数据切换测试
|
||||
- testMultiThreadWorkerPage2.ets # 多线程测试
|
||||
- testPlaceholderPage.ets # 加载占位图测试
|
||||
- testPreloadPage.ets # 预加载测试
|
||||
- testResourceManagerPage.ets # 解析本地资源测试
|
||||
- transformPixelMapPage.ets # 所有类型变换测试
|
||||
- transformTestCasePage.ets # 所有类型变换配合ImageKnifeComponent测试
|
||||
- pages # 测试page页面列表
|
||||
- basicTestFeatureAbilityPage.ets # 测试元能力
|
||||
- basicTestFileIOPage.ets # 测试fileio
|
||||
- basicTestMediaImage.ets # 测试媒体image
|
||||
- basicTestResourceManagerPage.ets # 测试本地资源解析
|
||||
- compressPage.ets # 压缩页面
|
||||
- cropImagePage2.ets # 手势裁剪页面
|
||||
- frescoImageTestCasePage.ets # 测试属性动画组件切换
|
||||
- frescoRetryTestCasePage.ets # 测试ImageKnifeComponent加载失败重试
|
||||
- gifTestCasePage.ets # 测试gif解析页面
|
||||
- svgTestCasePage.ets # 测试svg解析页面
|
||||
- imageknifeTestCaseIndex.ets # 测试用例页面入口
|
||||
- index.ets # 程序入口页面
|
||||
- loadNetworkTestCasePage.ets # 网络加载测试
|
||||
- loadResourceTestCasePage.ets # 本地加载测试
|
||||
- showErrorholderTestCasePage.ets # 加载失败占位图测试
|
||||
- storageTestDiskLruCache.ets # 磁盘缓存测试
|
||||
- storageTestLruCache.ets # 内存缓存测试
|
||||
- testAllCacheInfoPage.ets # 所有缓存信息获取测试
|
||||
- testGifDontAnimatePage.ets # gif加载静态图片测试
|
||||
- testImageKnifeOptionChangedPage.ets # 数据切换测试
|
||||
- testImageKnifeOptionChangedPage2.ets # 数据切换测试,部分变换
|
||||
- testImageKnifeOptionChangedPage3.ets # 数据切换测试,组件动画
|
||||
- testImageKnifeOptionChangedPage4.ets # 数据切换测试,内容动画
|
||||
- testImageKnifeOptionChangedPage5.ets # 数据切换测试,ImageKnifeDrawFactory封装圆角圆环边框等
|
||||
- testPreloadPage.ets # 预加载测试
|
||||
- transformPixelMapPage.ets # 所有类型变换测试
|
||||
|
||||
- workers # 测试worker多线程
|
||||
- worker1.js # worker多线程测试
|
||||
- gifParseWorker.ts # gifworker子线程解析
|
||||
- worker1.js # worker多线程测试
|
||||
```
|
||||
|
||||
## 贡献代码
|
||||
|
@ -301,4 +525,6 @@ let requestOptin = new RequestOption();
|
|||
|
||||
1.目前只支持一种图片变换效果。
|
||||
|
||||
2.目前svg和gif动图不支持变换效果。
|
||||
2.目前svg和gif动图不支持变换效果。
|
||||
|
||||
3.svg解析目前不支持mask标签。
|
|
@ -4,6 +4,7 @@
|
|||
"sourceOption": {
|
||||
"workers": [
|
||||
"./src/main/ets/pages/workers/worker1.js",
|
||||
"./src/main/ets/pages/workers/gifParseWorker.ts",
|
||||
]
|
||||
}
|
||||
},
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
{
|
||||
"license":"ISC",
|
||||
"devDependencies":{},
|
||||
"name":"entry",
|
||||
"ohos":{
|
||||
"org":"huawei",
|
||||
"directoryLevel":"module",
|
||||
"buildTool":"hvigor"
|
||||
"license": "ISC",
|
||||
"devDependencies": {},
|
||||
"name": "entry",
|
||||
"ohos": {
|
||||
"org": "huawei",
|
||||
"directoryLevel": "module",
|
||||
"buildTool": "hvigor"
|
||||
},
|
||||
"description":"example description",
|
||||
"repository":{},
|
||||
"version":"1.0.0",
|
||||
"dependencies":{
|
||||
"@ohos/imageknife":"file:../imageknife"
|
||||
"description": "example description",
|
||||
"repository": {},
|
||||
"version": "1.0.0",
|
||||
"dependencies": {
|
||||
"@ohos/imageknife": "file:../imageknife"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,11 +12,16 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import AbilityStage from "@ohos.application.AbilityStage"
|
||||
import {ImageKnife} from '@ohos/imageknife'
|
||||
import AbilityStage from '@ohos.application.AbilityStage'
|
||||
import { ImageKnife,ImageKnifeDrawFactory} from '@ohos/imageknife'
|
||||
|
||||
import ArkWorker from '@ohos.worker'
|
||||
|
||||
export default class MyAbilityStage extends AbilityStage {
|
||||
onCreate() {
|
||||
globalThis.ImageKnife = ImageKnife.with(this.context);
|
||||
|
||||
// 全局配置网络加载进度条
|
||||
globalThis.ImageKnife.setDefaultLifeCycle(ImageKnifeDrawFactory.createProgressLifeCycle("#10a5ff", 0.5))
|
||||
}
|
||||
}
|
|
@ -16,41 +16,22 @@ import Ability from '@ohos.application.Ability'
|
|||
import {ImageKnife} from '@ohos/imageknife'
|
||||
export default class MainAbility extends Ability {
|
||||
onCreate(want, launchParam) {
|
||||
console.log("[Demo] MainAbility onCreate")
|
||||
globalThis.abilityWant = want;
|
||||
|
||||
|
||||
// this.context.resourceManager.getMedia()
|
||||
// globalThis.ImageKnifeContext = this.context;
|
||||
// globalThis.ImageKnife = ImageKnife.with(this.context);
|
||||
// this.context.filesDir
|
||||
|
||||
console.log('globalThis.ImageKnife 1 ='+typeof globalThis.ImageKnife)
|
||||
}
|
||||
|
||||
onDestroy() {
|
||||
console.log("[Demo] MainAbility onDestroy")
|
||||
}
|
||||
|
||||
onWindowStageCreate(windowStage) {
|
||||
// Main window is created, set main page for this ability
|
||||
console.log("[Demo] MainAbility onWindowStageCreate")
|
||||
|
||||
windowStage.setUIContent(this.context, "pages/index", null)
|
||||
}
|
||||
|
||||
onWindowStageDestroy() {
|
||||
// Main window is destroyed, release UI related resources
|
||||
console.log("[Demo] MainAbility onWindowStageDestroy")
|
||||
}
|
||||
|
||||
onForeground() {
|
||||
// Ability has brought to foreground
|
||||
console.log("[Demo] MainAbility onForeground")
|
||||
}
|
||||
|
||||
onBackground() {
|
||||
// Ability has back to background
|
||||
console.log("[Demo] MainAbility onBackground")
|
||||
}
|
||||
};
|
||||
|
|
|
@ -17,13 +17,12 @@ import { FileUtils } from '@ohos/imageknife'
|
|||
import { FileTypeUtil } from '@ohos/imageknife'
|
||||
import resourceManager from '@ohos.resourceManager';
|
||||
import { Base64 } from '@ohos/imageknife'
|
||||
import { PixelMapPack } from '@ohos/imageknife'
|
||||
import { ParseImageUtil } from '@ohos/imageknife'
|
||||
|
||||
@Entry
|
||||
@Component
|
||||
struct BasicTestMediaImage {
|
||||
@State pixelMapPack: PixelMapPack = new PixelMapPack();
|
||||
@State imagePixelMap: PixelMap = undefined;
|
||||
|
||||
build() {
|
||||
Scroll() {
|
||||
|
@ -36,9 +35,7 @@ struct BasicTestMediaImage {
|
|||
let arrayBuffer = this.typedArrayToBuffer(data);
|
||||
let parseImageUtil = new ParseImageUtil();
|
||||
parseImageUtil.parseImage(arrayBuffer, (pxielmap) => {
|
||||
let jpgPack = new PixelMapPack();
|
||||
jpgPack.pixelMap = pxielmap;
|
||||
this.pixelMapPack = jpgPack;
|
||||
this.imagePixelMap = pxielmap;
|
||||
}, (err) => {
|
||||
})
|
||||
})
|
||||
|
@ -53,9 +50,7 @@ struct BasicTestMediaImage {
|
|||
let arrayBuffer = this.typedArrayToBuffer(data);
|
||||
let parseImageUtil = new ParseImageUtil();
|
||||
parseImageUtil.parseImage(arrayBuffer, (pxielmap) => {
|
||||
let pngPack = new PixelMapPack();
|
||||
pngPack.pixelMap = pxielmap;
|
||||
this.pixelMapPack = pngPack;
|
||||
this.imagePixelMap = pxielmap;
|
||||
}, (err) => {
|
||||
})
|
||||
})
|
||||
|
@ -70,9 +65,7 @@ struct BasicTestMediaImage {
|
|||
let arrayBuffer = this.typedArrayToBuffer(data);
|
||||
let parseImageUtil = new ParseImageUtil();
|
||||
parseImageUtil.parseImage(arrayBuffer, (pxielmap) => {
|
||||
let bmpPack = new PixelMapPack();
|
||||
bmpPack.pixelMap = pxielmap;
|
||||
this.pixelMapPack = bmpPack;
|
||||
this.imagePixelMap = pxielmap;
|
||||
}, (err) => {
|
||||
})
|
||||
})
|
||||
|
@ -87,9 +80,7 @@ struct BasicTestMediaImage {
|
|||
let arrayBuffer = this.typedArrayToBuffer(data);
|
||||
let parseImageUtil = new ParseImageUtil();
|
||||
parseImageUtil.parseImage(arrayBuffer, (pxielmap) => {
|
||||
let webpPack = new PixelMapPack();
|
||||
webpPack.pixelMap = pxielmap;
|
||||
this.pixelMapPack = webpPack;
|
||||
this.imagePixelMap = pxielmap;
|
||||
}, (err) => {
|
||||
})
|
||||
})
|
||||
|
@ -104,9 +95,7 @@ struct BasicTestMediaImage {
|
|||
let arrayBuffer = this.typedArrayToBuffer(data);
|
||||
let parseImageUtil = new ParseImageUtil();
|
||||
parseImageUtil.parseImage(arrayBuffer, (pxielmap) => {
|
||||
let gifPack = new PixelMapPack();
|
||||
gifPack.pixelMap = pxielmap;
|
||||
this.pixelMapPack = gifPack;
|
||||
this.imagePixelMap = pxielmap;
|
||||
}, (err) => {
|
||||
})
|
||||
})
|
||||
|
@ -117,7 +106,7 @@ struct BasicTestMediaImage {
|
|||
}
|
||||
.margin({ top: 15 })
|
||||
|
||||
Image(this.pixelMapPack.pixelMap)
|
||||
Image(this.imagePixelMap)
|
||||
.width(300)
|
||||
.height(300)
|
||||
.backgroundColor(Color.Pink)
|
||||
|
|
|
@ -13,15 +13,14 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
import {ImageKnife} from '@ohos/imageknife'
|
||||
import {PixelMapPack} from '@ohos/imageknife'
|
||||
import {OnRenameListener} from '@ohos/imageknife'
|
||||
import {OnCompressListener} from '@ohos/imageknife'
|
||||
|
||||
@Entry
|
||||
@Component
|
||||
struct CompressPage {
|
||||
@State mRPixelMap: PixelMapPack = new PixelMapPack();
|
||||
@State mFPixelMap: PixelMapPack = new PixelMapPack();
|
||||
@State mRPixelMap: PixelMap = undefined;
|
||||
@State mFPixelMap: PixelMap = undefined;
|
||||
@State mResultText: string= "压缩回调结果"
|
||||
@State mResultPath: string= "压缩路径:"
|
||||
@State mAsyncPath: string= ""
|
||||
|
@ -64,8 +63,7 @@ struct CompressPage {
|
|||
.onClick(() => {
|
||||
this.cropressRecource();
|
||||
});
|
||||
Image(this.mRPixelMap.pixelMap)
|
||||
.objectFit(ImageFit.None)
|
||||
Image(this.mRPixelMap )
|
||||
.width(200)
|
||||
.height(200)
|
||||
.margin({ top: 10 })
|
||||
|
@ -83,8 +81,7 @@ struct CompressPage {
|
|||
.margin({ top: 10 })
|
||||
.onClick(() => {
|
||||
});
|
||||
Image(this.mFPixelMap.pixelMap)
|
||||
.objectFit(ImageFit.None)
|
||||
Image(this.mFPixelMap )
|
||||
.width(200)
|
||||
.height(200)
|
||||
.margin({ top: 10 });
|
||||
|
@ -124,8 +121,8 @@ struct CompressPage {
|
|||
console.info("asasd start")
|
||||
},
|
||||
onScuccess(p: PixelMap, path: string) {
|
||||
let pack = new PixelMapPack();
|
||||
pack.pixelMap = p;
|
||||
let pack = undefined;
|
||||
pack = p;
|
||||
that.mRPixelMap = pack;
|
||||
console.info("asasd success path:" + this.mRPixelMap)
|
||||
that.mResultText = "success";
|
||||
|
|
|
@ -1,119 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {CropImage} from '@ohos/imageknife'
|
||||
import {CropOptions} from '@ohos/imageknife'
|
||||
import {Crop} from '@ohos/imageknife'
|
||||
import {RecourseProvider} from '@ohos/imageknife'
|
||||
import {PixelMapPack} from '@ohos/imageknife'
|
||||
|
||||
|
||||
@Component
|
||||
@Entry
|
||||
export struct CropImagePage {
|
||||
private _resource: Resource= $r('app.media.jpgSample');
|
||||
@State x: number = 0;
|
||||
@State y: number = 0;
|
||||
@State crop_size: number = 100;
|
||||
@State colorRotate: number = 100;
|
||||
@State _mCropPixelMap: PixelMapPack= new PixelMapPack();
|
||||
@State _mCropOptions: CropOptions= {
|
||||
src: this._mCropPixelMap.pixelMap,
|
||||
size: {
|
||||
width: 200,
|
||||
height: 200
|
||||
}
|
||||
}
|
||||
|
||||
build() {
|
||||
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
||||
Text('原图').fontSize(20)
|
||||
Image(this._resource).width(300).height(300).margin(10).objectFit(ImageFit.Contain);
|
||||
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
||||
TextInput({ text: '', placeholder: '裁X坐标' })
|
||||
.type(InputType.Number)
|
||||
.placeholderColor(Color.Gray)
|
||||
.placeholderFont({ size: 20 })
|
||||
.onChange((value: string) => {
|
||||
this.x = parseInt(value);
|
||||
})
|
||||
.height(60)
|
||||
.width(130)
|
||||
.margin(2)
|
||||
TextInput({ text: '', placeholder: '裁Y坐标' })
|
||||
.type(InputType.Number)
|
||||
.placeholderColor(Color.Gray)
|
||||
.placeholderFont({ size: 20 })
|
||||
.onChange((value: string) => {
|
||||
this.y = parseInt(value);
|
||||
})
|
||||
.height(60)
|
||||
.width(130)
|
||||
.margin(2)
|
||||
|
||||
TextInput({ text: '', placeholder: '裁剪长度' })
|
||||
.type(InputType.Number)
|
||||
.placeholderColor(Color.Gray)
|
||||
.placeholderFont({ size: 20 })
|
||||
.onChange((value: string) => {
|
||||
this.crop_size = parseInt(value);
|
||||
})
|
||||
.height(60)
|
||||
.width(130)
|
||||
.margin(2)
|
||||
|
||||
TextInput({ text: '', placeholder: '颜色比<1' })
|
||||
.type(InputType.Number)
|
||||
.placeholderColor(Color.Gray)
|
||||
.placeholderFont({ size: 20 })
|
||||
.onChange((value: string) => {
|
||||
this.colorRotate = parseFloat(value);
|
||||
})
|
||||
.height(60)
|
||||
.width(130)
|
||||
.margin(2)
|
||||
|
||||
}.width('100%')
|
||||
.height(60).backgroundColor(Color.Pink)
|
||||
|
||||
Button() {
|
||||
Text('Crop').fontSize(15).fontColor(Color.White)
|
||||
}
|
||||
.height(35)
|
||||
.width(150)
|
||||
.onClick(() => {
|
||||
var provider = new RecourseProvider(this._resource);
|
||||
provider.openInternal((buffer) => {
|
||||
Crop.crop(buffer, this.x, this.y, this.crop_size, this.crop_size, (error, data) => {
|
||||
let result = new CropOptions();
|
||||
result.src=null;
|
||||
this._mCropOptions=result;
|
||||
setTimeout(() => {
|
||||
this._mCropOptions = {
|
||||
src: data,
|
||||
size: {
|
||||
width: 200,
|
||||
height: 200
|
||||
}
|
||||
}
|
||||
},100)
|
||||
|
||||
}, this.colorRotate);
|
||||
})
|
||||
}).margin(10);
|
||||
CropImage({ _mOptions: $_mCropOptions })
|
||||
}.width('100%').height('100%');
|
||||
}
|
||||
}
|
|
@ -17,7 +17,6 @@ import { CropImage } from '@ohos/imageknife'
|
|||
import { CropOptions } from '@ohos/imageknife'
|
||||
import { Crop } from '@ohos/imageknife'
|
||||
import { RecourseProvider } from '@ohos/imageknife'
|
||||
import { PixelMapPack } from '@ohos/imageknife'
|
||||
import { PixelMapCrop } from '@ohos/imageknife'
|
||||
import { CropCallback } from '@ohos/imageknife'
|
||||
import { FileUtils } from '@ohos/imageknife'
|
||||
|
@ -28,77 +27,74 @@ import { FileUtils } from '@ohos/imageknife'
|
|||
export struct CropImagePage2 {
|
||||
@State options1: PixelMapCrop.Options = new PixelMapCrop.Options();
|
||||
@State cropTap: boolean = false;
|
||||
@State pack: PixelMapPack = new PixelMapPack();
|
||||
|
||||
@State width1: number = 0;
|
||||
@State height1: number = 0;
|
||||
@State _rotate: number = 0;
|
||||
@State _scale: number = 1;
|
||||
private _resource: Resource = $r('app.media.bmpSample');
|
||||
|
||||
private settings: RenderingContextSettings = new RenderingContextSettings(true)
|
||||
private canvasContext: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings)
|
||||
build() {
|
||||
Column() {
|
||||
Scroll() {
|
||||
Column() {
|
||||
Button('点击解析图片')
|
||||
.onClick(() => {
|
||||
globalThis.ImageKnife.getImageKnifeContext().resourceManager.getMedia($r('app.media.bmpSample').id)
|
||||
.then(data => {
|
||||
let arrayBuffer = FileUtils.getInstance().uint8ArrayToBuffer(data);
|
||||
let optionx = new PixelMapCrop.Options();
|
||||
optionx.setWidth(800)
|
||||
.setHeight(800)
|
||||
.setCropFunction((err, pixelmap, sx, sy) => {
|
||||
console.log('PMC setCropFunction callback')
|
||||
if (err) {
|
||||
console.error('PMC crop err =' + err)
|
||||
} else {
|
||||
|
||||
Button('点击解析图片')
|
||||
.onClick(() => {
|
||||
globalThis.ImageKnife.getImageKnifeContext().resourceManager.getMedia($r('app.media.bmpSample').id)
|
||||
.then(data => {
|
||||
let arrayBuffer = FileUtils.getInstance().uint8ArrayToBuffer(data);
|
||||
let optionx = new PixelMapCrop.Options();
|
||||
optionx.setWidth(800)
|
||||
.setHeight(800)
|
||||
.setCropFunction((err, pixelmap, sx, sy) => {
|
||||
console.log('PMC setCropFunction callback')
|
||||
if (err) {
|
||||
console.error('PMC crop err =' + err)
|
||||
} else {
|
||||
let pack1 = new PixelMapPack();
|
||||
pack1.pixelMap = pixelmap;
|
||||
this.pack = pack1;
|
||||
this.width1 = sx * px2vp(1);
|
||||
this.height1 = sy * px2vp(1);
|
||||
}
|
||||
this.width1 = sx * px2vp(1);
|
||||
this.height1 = sy * px2vp(1);
|
||||
this.canvasContext.drawImage(pixelmap,0,0,this.width1,this.height1)
|
||||
}
|
||||
|
||||
|
||||
})
|
||||
optionx.loadBuffer(arrayBuffer, () => {
|
||||
this.options1 = optionx;
|
||||
})
|
||||
optionx.loadBuffer(arrayBuffer, () => {
|
||||
this.options1 = optionx;
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
})
|
||||
})
|
||||
|
||||
PixelMapCrop({ options: this.options1, cropTap: this.cropTap })
|
||||
PixelMapCrop({ options: $options1, cropTap: this.cropTap })
|
||||
|
||||
Button('点击裁剪图片')
|
||||
.onClick(() => {
|
||||
this.cropTap = !this.cropTap;
|
||||
})
|
||||
|
||||
|
||||
Image(this.pack.pixelMap)
|
||||
.width(this.width1)
|
||||
.height(this.height1)
|
||||
.objectFit(ImageFit.Contain)
|
||||
.rotate({
|
||||
z: 1,
|
||||
centerX: this.width1 / 2,
|
||||
centerY: this.height1 / 2,
|
||||
angle: this._rotate
|
||||
})
|
||||
.scale({ x: this._scale, y: this._scale, z: 1.0 })
|
||||
.gesture(GestureGroup(GestureMode.Parallel,
|
||||
RotationGesture({ fingers: 2 }).onActionUpdate(event => {
|
||||
this._rotate = event.angle;
|
||||
}), PinchGesture({ fingers: 2 }).onActionUpdate(event => {
|
||||
this._scale = event.scale;
|
||||
})))
|
||||
Button('点击裁剪图片')
|
||||
.onClick(() => {
|
||||
this.cropTap = !this.cropTap;
|
||||
})
|
||||
|
||||
|
||||
Canvas(this.canvasContext)
|
||||
.width(this.width1)
|
||||
.height(this.height1)
|
||||
.rotate({
|
||||
z: 1,
|
||||
centerX: this.width1 / 2,
|
||||
centerY: this.height1 / 2,
|
||||
angle: this._rotate
|
||||
})
|
||||
.scale({ x: this._scale, y: this._scale, z: 1.0 })
|
||||
.gesture(GestureGroup(GestureMode.Parallel,
|
||||
RotationGesture({ fingers: 2 }).onActionUpdate(event => {
|
||||
this._rotate = event.angle;
|
||||
}), PinchGesture({ fingers: 2 }).onActionUpdate(event => {
|
||||
this._scale = event.scale;
|
||||
})))
|
||||
}
|
||||
.backgroundColor(Color.Brown)
|
||||
.width('100%')
|
||||
}
|
||||
.backgroundColor(Color.Brown)
|
||||
.width('100%')
|
||||
.height('100%')
|
||||
|
||||
}
|
||||
}
|
|
@ -1,80 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import {ImageKnifeComponent} from '@ohos/imageknife'
|
||||
import {ImageKnifeOption} from '@ohos/imageknife'
|
||||
import {RotateImageTransformation} from '@ohos/imageknife'
|
||||
import {GrayscaleTransformation} from '@ohos/imageknife'
|
||||
import {SketchFilterTransformation} from '@ohos/imageknife'
|
||||
|
||||
@Entry
|
||||
@Component
|
||||
struct DpgTestCasePage {
|
||||
@State imageKnifeOption1: ImageKnifeOption =
|
||||
{
|
||||
loadSrc: $r('app.media.jpgSample'),
|
||||
size: { width: 300, height: 300 },
|
||||
placeholderSrc: $r('app.media.icon_loading'),
|
||||
errorholderSrc: $r('app.media.icon_failed'),
|
||||
margin:{left:5,top:5,right:5,bottom:5},
|
||||
|
||||
};
|
||||
|
||||
|
||||
build() {
|
||||
Scroll() {
|
||||
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
||||
Flex({direction:FlexDirection.Row}){
|
||||
Button("dpg网络资源")
|
||||
.onClick(()=>{
|
||||
this.imageKnifeOption1 = {
|
||||
loadSrc: "https://img13.360buyimg.com/n1/jfs/t1/220646/38/10395/30916/61d6e061E1a6d91c8/c0a9a67e726dd7a4.jpg.dpg",
|
||||
size: { width: 300, height: 300 },
|
||||
placeholderSrc: $r('app.media.icon_loading'),
|
||||
errorholderSrc: $r('app.media.icon_failed'),
|
||||
margin:{left:5,top:5,right:5,bottom:5},
|
||||
};
|
||||
}).margin({left:5}).backgroundColor(Color.Blue)
|
||||
Button("dpg本地资源")
|
||||
.onClick(()=>{
|
||||
this.imageKnifeOption1 = {
|
||||
loadSrc: $r('app.media.dpgSample'),
|
||||
size: { width: 300, height: 300 },
|
||||
placeholderSrc: $r('app.media.icon_loading'),
|
||||
errorholderSrc: $r('app.media.icon_failed'),
|
||||
margin:{left:5,top:5,right:5,bottom:5},
|
||||
};
|
||||
}).margin({left:5}).backgroundColor(Color.Blue)
|
||||
|
||||
}
|
||||
.margin({top:15})
|
||||
|
||||
Text("下面为展示图片区域").margin({top:5})
|
||||
Flex({direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }){
|
||||
ImageKnifeComponent({ imageKnifeOption: $imageKnifeOption1 })
|
||||
}.width(400).height(400).margin({top:10}).backgroundColor(Color.Pink)
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
.width('100%')
|
||||
.height('100%')
|
||||
}
|
||||
|
||||
aboutToAppear() {
|
||||
console.log("aboutToAppear()")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -25,15 +25,15 @@ struct FrescoImageTestCasePage {
|
|||
@State imageKnifeOption1: ImageKnifeOption =
|
||||
{
|
||||
loadSrc: "https://thirdwx.qlogo.cn/mmopen/vi_32/DYAIOgq83ericA1Mv66TwicuYOtbDMBcUhv1aa9RJBeAn9uURfcZD0AUGrJebAn1g2AjN0vb2E1XTET7fTuLBNmA/132",
|
||||
size: { width: 300, height: 300 },
|
||||
size: { width: '300', height: '300' },
|
||||
placeholderSrc: $r('app.media.icon_loading'),
|
||||
errorholderSrc: $r('app.media.icon_failed'),
|
||||
displayProgress: true
|
||||
};
|
||||
@State imageKnifeOption2: ImageKnifeOption =
|
||||
@State ImageKnifeOption: ImageKnifeOption =
|
||||
{
|
||||
loadSrc: "https://hbimg.huabanimg.com/0ef60041445edcfd6b38d20e19024b2cd9281dcc3525a4-Vy8fYO_fw658/format/webp",
|
||||
size: { width: 300, height: 300 },
|
||||
size: { width: '300', height: '300' },
|
||||
placeholderSrc: $r('app.media.icon_loading'),
|
||||
errorholderSrc: $r('app.media.icon_failed'),
|
||||
displayProgress: true
|
||||
|
@ -41,7 +41,7 @@ struct FrescoImageTestCasePage {
|
|||
@State imageKnifeOption3: ImageKnifeOption =
|
||||
{
|
||||
loadSrc: "https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp",
|
||||
size: { width: 300, height: 300 },
|
||||
size: { width: '300', height: '300' },
|
||||
placeholderSrc: $r('app.media.icon_loading'),
|
||||
errorholderSrc: $r('app.media.icon_failed'),
|
||||
displayProgress: true
|
||||
|
@ -49,27 +49,22 @@ struct FrescoImageTestCasePage {
|
|||
@State imageKnifeOption4: ImageKnifeOption =
|
||||
{
|
||||
loadSrc: "https://hbimg.huabanimg.com/cc6af25f8d782d3cf3122bef4e61571378271145735e9-vEVggB",
|
||||
size: { width: 300, height: 300 },
|
||||
size: { width: '300', height: '300' },
|
||||
placeholderSrc: $r('app.media.icon_loading'),
|
||||
errorholderSrc: $r('app.media.icon_failed'),
|
||||
displayProgress: true,
|
||||
displayProgressListener:(value)=>{
|
||||
console.log("百分比value:"+value)
|
||||
this.progresshint+="\n"+value;
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
build() {
|
||||
Scroll() {
|
||||
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
||||
// ImageKnifeComponent({ imageKnifeOption: $imageKnifeOption1 })
|
||||
// ImageKnifeComponent({ imageKnifeOption: $imageKnifeOption2 })
|
||||
// ImageKnifeComponent({ imageKnifeOption: $ImageKnifeOption })
|
||||
// ImageKnifeComponent({ imageKnifeOption: $imageKnifeOption3 })
|
||||
ImageKnifeComponent({ imageKnifeOption: $imageKnifeOption4 })
|
||||
Scroll() {
|
||||
Text(this.progresshint).fontSize(15)
|
||||
}.width(300).height(200)
|
||||
// Scroll() {
|
||||
// Text(this.progresshint).fontSize(15)
|
||||
// }.width(300).height(200)
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -1,132 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import router from '@system.router';
|
||||
|
||||
@Entry
|
||||
@Component
|
||||
struct FrescoLayerTestCasePage {
|
||||
|
||||
@Watch("watchV1") @State v1:Visibility = Visibility.Visible
|
||||
@Watch("watchV2") @State v2:Visibility = Visibility.Visible
|
||||
@Watch("watchV3") @State v3:Visibility = Visibility.Visible
|
||||
|
||||
@State v1Width:string = "100%";
|
||||
@State v1Height:string = "100%";
|
||||
@State v2Width:string = "100%";
|
||||
@State v2Height:string = "100%";
|
||||
@State v3Width:string = "100%";
|
||||
@State v3Height:string = "100%";
|
||||
|
||||
|
||||
|
||||
|
||||
watchV1(){
|
||||
console.log("watchV1")
|
||||
}
|
||||
watchV2(){
|
||||
console.log("watchV2")
|
||||
}
|
||||
watchV3(){
|
||||
console.log("watchV3")
|
||||
}
|
||||
|
||||
|
||||
build() {
|
||||
Scroll() {
|
||||
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
||||
Stack() {
|
||||
Text('1%')
|
||||
.fontSize(100)
|
||||
.fontWeight(FontWeight.Bold)
|
||||
.visibility(this.v1)
|
||||
.width(this.v1Width)
|
||||
.height(this.v1Height)
|
||||
Image($r('app.media.icon_failed'))
|
||||
.visibility(this.v2)
|
||||
.width(this.v2Width)
|
||||
.height(this.v2Height)
|
||||
Image($r('app.media.jpgSample'))
|
||||
.visibility(this.v3)
|
||||
.width(this.v3Width)
|
||||
.height(this.v3Height)
|
||||
}
|
||||
.width(200)
|
||||
.height(200)
|
||||
|
||||
Button("显示第一个组件")
|
||||
.onClick(()=>{
|
||||
this.v1 = Visibility.Visible;
|
||||
this.v2 = Visibility.Hidden;
|
||||
this.v3 = Visibility.Hidden;
|
||||
|
||||
animateTo({duration:500,curve:Curve.Linear},()=>{
|
||||
this.v1Width = "100%";
|
||||
this.v1Height = "100%";
|
||||
|
||||
this.v2Width = "0%";
|
||||
this.v2Height = "0%";
|
||||
|
||||
this.v3Width = "0%";
|
||||
this.v3Height = "0%";
|
||||
})
|
||||
|
||||
|
||||
})
|
||||
Button("显示第二个组件")
|
||||
.onClick(()=>{
|
||||
this.v2 = Visibility.Visible;
|
||||
this.v1 = Visibility.Hidden;
|
||||
this.v3 = Visibility.Hidden;
|
||||
|
||||
animateTo({duration:500,curve:Curve.Linear},()=>{
|
||||
this.v2Width = "100%";
|
||||
this.v2Height = "100%";
|
||||
|
||||
this.v1Width = "0%";
|
||||
this.v1Height = "0%";
|
||||
|
||||
this.v3Width = "0%";
|
||||
this.v3Height = "0%";
|
||||
})
|
||||
})
|
||||
Button("显示第三个组件")
|
||||
.onClick(()=>{
|
||||
this.v3 = Visibility.Visible;
|
||||
this.v2 = Visibility.Hidden;
|
||||
this.v1 = Visibility.Hidden;
|
||||
|
||||
animateTo({duration:500,curve:Curve.Linear},()=>{
|
||||
this.v3Width = "100%";
|
||||
this.v3Height = "100%";
|
||||
|
||||
this.v2Width = "0%";
|
||||
this.v2Height = "0%";
|
||||
|
||||
this.v1Width = "0%";
|
||||
this.v1Height = "0%";
|
||||
})
|
||||
})
|
||||
|
||||
}
|
||||
}
|
||||
.width('100%')
|
||||
.height('100%')
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -23,53 +23,49 @@ struct FrescoImageTestCasePage {
|
|||
@State imageKnifeOption1: ImageKnifeOption =
|
||||
{
|
||||
loadSrc: "https://thirdwx.qlogo.cn/mmopen/vi_32/DYAIOgq83ericA1Mv66TwicuYOtbDMBcUhv1aa9RJBeAn9uURfcZD0AUGrJebAn1g2AjN0vb2E1XTET7fTuLBNmA/132",
|
||||
size: { width: 300, height: 300 },
|
||||
size: { width: '300', height: '300' },
|
||||
placeholderSrc: $r('app.media.icon_loading'),
|
||||
errorholderSrc: $r('app.media.icon_failed'),
|
||||
retryholderSrc: $r('app.media.icon_retry'),
|
||||
displayProgress: true,
|
||||
animateDuration: 300,
|
||||
retryLoad:true
|
||||
canRetryClick:true
|
||||
};
|
||||
@State imageKnifeOption2: ImageKnifeOption =
|
||||
@State ImageKnifeOption: ImageKnifeOption =
|
||||
{
|
||||
loadSrc: "https://hbimg.huabanimg.com/0ef60041445edcfd6b38d20e19024b2cd9281dcc3525a4-Vy8fYO_fw658/format/webp",
|
||||
size: { width: 300, height: 300 },
|
||||
size: { width: '300', height: '300' },
|
||||
placeholderSrc: $r('app.media.icon_loading'),
|
||||
errorholderSrc: $r('app.media.icon_failed'),
|
||||
retryholderSrc: $r('app.media.icon_retry'),
|
||||
displayProgress: true,
|
||||
animateDuration: 300,
|
||||
retryLoad:true
|
||||
canRetryClick:true
|
||||
};
|
||||
@State imageKnifeOption3: ImageKnifeOption =
|
||||
{
|
||||
loadSrc: "https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp",
|
||||
size: { width: 300, height: 300 },
|
||||
size: { width: '300', height: '300' },
|
||||
placeholderSrc: $r('app.media.icon_loading'),
|
||||
errorholderSrc: $r('app.media.icon_failed'),
|
||||
retryholderSrc: $r('app.media.icon_retry'),
|
||||
displayProgress: true,
|
||||
animateDuration: 300,
|
||||
retryLoad:true
|
||||
canRetryClick:true
|
||||
};
|
||||
@State imageKnifeOption4: ImageKnifeOption =
|
||||
{
|
||||
loadSrc: "https://hbimg.huabanimg.com/testRetryxxxx",
|
||||
size: { width: 300, height: 300 },
|
||||
size: { width: '300', height: '300' },
|
||||
placeholderSrc: $r('app.media.icon_loading'),
|
||||
errorholderSrc: $r('app.media.icon_failed'),
|
||||
retryholderSrc: $r('app.media.icon_retry'),
|
||||
displayProgress: true,
|
||||
animateDuration: 300,
|
||||
retryLoad:true
|
||||
canRetryClick:true
|
||||
};
|
||||
|
||||
build() {
|
||||
Scroll() {
|
||||
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
||||
// ImageKnifeComponent({ imageKnifeOption: $imageKnifeOption1 })
|
||||
// ImageKnifeComponent({ imageKnifeOption: $imageKnifeOption2 })
|
||||
// ImageKnifeComponent({ imageKnifeOption: $ImageKnifeOption })
|
||||
// ImageKnifeComponent({ imageKnifeOption: $imageKnifeOption3 })
|
||||
ImageKnifeComponent({ imageKnifeOption: $imageKnifeOption4 })
|
||||
}
|
||||
|
|
|
@ -0,0 +1,130 @@
|
|||
/*
|
||||
* Copyright (C) 2022 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import {GIFParseImpl} from '@ohos/imageknife'
|
||||
import ArkWorker from '@ohos.worker'
|
||||
@Entry
|
||||
@Component
|
||||
struct gifTestCasePage {
|
||||
|
||||
@State pixels:PixelMap = undefined
|
||||
private globalGifWorker = undefined;
|
||||
|
||||
build() {
|
||||
Scroll() {
|
||||
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
||||
Flex({direction:FlexDirection.Row}){
|
||||
Button("加载gif图片")
|
||||
.onClick(()=>{
|
||||
globalThis.ImageKnife.getImageKnifeContext().resourceManager.getMedia($r('app.media.gifSample').id)
|
||||
.then(data => {
|
||||
console.log('basicTestFileIOPage - 本地加载资源 解析后数据data length= ' + data.byteLength)
|
||||
let gifImpl = new GIFParseImpl();
|
||||
gifImpl.parseGifs(data.buffer, (data,err)=>{
|
||||
if(err){
|
||||
console.log('加载gif图片 err='+err);
|
||||
}
|
||||
if(!!data){
|
||||
console.log('加载gif图片 suc,长度='+data.length)
|
||||
this.pixels = data[0]['drawPixelMap']
|
||||
}
|
||||
},undefined,true)
|
||||
})
|
||||
.catch(err => {
|
||||
console.log('basicTestFileIOPage - 本地加载资源err' + JSON.stringify(err));
|
||||
})
|
||||
|
||||
}).margin({left:5}).backgroundColor(Color.Blue)
|
||||
Button("加载gif图片自带worker")
|
||||
.onClick(()=>{
|
||||
globalThis.ImageKnife.getImageKnifeContext().resourceManager.getMedia($r('app.media.gifSample').id)
|
||||
.then(data => {
|
||||
console.log('basicTestFileIOPage - 本地加载资源 解析后数据data length = ' + data.byteLength)
|
||||
let worker = new ArkWorker.Worker('entry/ets/pages/workers/gifParseWorker.ts', {
|
||||
type: 'classic',
|
||||
name: 'ImageKnifeParseGIF'
|
||||
})
|
||||
let gifImpl = new GIFParseImpl();
|
||||
gifImpl.parseGifs(data.buffer, (data,err)=>{
|
||||
if(err){
|
||||
console.log('加载gif图片自带worker err='+err);
|
||||
}
|
||||
if(!!data){
|
||||
console.log('加载gif图片自带worker suc,长度='+data.length)
|
||||
this.pixels = data[0]['drawPixelMap']
|
||||
}
|
||||
},worker)
|
||||
})
|
||||
.catch(err => {
|
||||
console.log('basicTestFileIOPage - 本地加载资源err' + JSON.stringify(err));
|
||||
})
|
||||
|
||||
}).margin({left:5}).backgroundColor(Color.Blue)
|
||||
Button("加载gif图片全局配置worker")
|
||||
.onClick(()=>{
|
||||
globalThis.ImageKnife.getImageKnifeContext().resourceManager.getMedia($r('app.media.gifSample').id)
|
||||
.then(data => {
|
||||
console.log('basicTestFileIOPage - 本地加载资源 解析后数据data length = ' + data.byteLength)
|
||||
|
||||
let gifImpl = new GIFParseImpl();
|
||||
gifImpl.parseGifs(data.buffer, (data,err)=>{
|
||||
if(err){
|
||||
console.log('加载gif图片自带worker err='+err);
|
||||
}
|
||||
if(!!data){
|
||||
console.log('加载gif图片自带worker suc,长度='+data.length)
|
||||
this.pixels = data[0]['drawPixelMap']
|
||||
}
|
||||
})
|
||||
})
|
||||
.catch(err => {
|
||||
console.log('basicTestFileIOPage - 本地加载资源err' + JSON.stringify(err));
|
||||
})
|
||||
|
||||
}).margin({left:5}).backgroundColor(Color.Blue)
|
||||
}
|
||||
.margin({top:15})
|
||||
|
||||
Text("下面为展示图片区域").margin({top:5})
|
||||
Flex({direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }){
|
||||
Image(this.pixels)
|
||||
.width(400)
|
||||
.height(400)
|
||||
.backgroundColor(Color.Pink)
|
||||
}.width(400).height(400).margin({top:10}).backgroundColor(Color.Pink)
|
||||
}
|
||||
}
|
||||
.width('100%')
|
||||
.height('100%')
|
||||
}
|
||||
|
||||
aboutToAppear() {
|
||||
console.log("aboutToAppear()")
|
||||
this.globalGifWorker = new ArkWorker.Worker('entry/ets/pages/workers/gifParseWorker.ts', {
|
||||
type: 'classic',
|
||||
name: 'ImageKnifeParseGIF'
|
||||
})
|
||||
globalThis.ImageKnife.setGifWorker(this.globalGifWorker)
|
||||
}
|
||||
aboutToDisappear(){
|
||||
if(this.globalGifWorker){
|
||||
this.globalGifWorker.terminate();
|
||||
}
|
||||
}
|
||||
typedArrayToBuffer(array: Uint8Array): ArrayBuffer {
|
||||
return array.buffer.slice(array.byteOffset, array.byteLength + array.byteOffset)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,205 @@
|
|||
/*
|
||||
* Copyright (C) 2022 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import router from '@system.router';
|
||||
|
||||
|
||||
|
||||
@Entry
|
||||
@Component
|
||||
struct IndexFunctionDemo {
|
||||
@State hint1: string = '启用网络模拟加载替换网络加载'
|
||||
|
||||
build() {
|
||||
Scroll() {
|
||||
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
||||
Text("OHOS基础接口测试列表").fontSize(15)
|
||||
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
||||
Button("测试元能力")
|
||||
.onClick(() => {
|
||||
console.log("测试元能力子系统")
|
||||
router.push({ uri: "pages/basicTestFeatureAbilityPage" });
|
||||
}).margin({ top: 5, left: 3 })
|
||||
Button("测试文件")
|
||||
.onClick(() => {
|
||||
console.log("测试文件子系统")
|
||||
router.push({ uri: "pages/basicTestFileIOPage" });
|
||||
}).margin({ top: 5, left: 3 })
|
||||
|
||||
}.width('100%').height(60).backgroundColor(Color.Pink)
|
||||
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
||||
Button("测试全球化")
|
||||
.onClick(() => {
|
||||
console.log("测试全球化子系统")
|
||||
router.push({ uri: "pages/basicTestResourceManagerPage" });
|
||||
}).margin({ top: 5, left: 3 })
|
||||
Button("测试媒体")
|
||||
.onClick(() => {
|
||||
console.log("测试媒体子系统")
|
||||
router.push({ uri: "pages/basicTestMediaImage" });
|
||||
}).margin({ top: 5, left: 3 })
|
||||
|
||||
}.width('100%').height(60).backgroundColor(Color.Pink)
|
||||
|
||||
|
||||
|
||||
|
||||
Text("测试图片切换功能点").fontSize(15)
|
||||
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
||||
|
||||
Button("测试图片切换")
|
||||
.onClick(() => {
|
||||
console.log("测试ImageKnifeComponent所有图片切换")
|
||||
router.push({ uri: "pages/testImageKnifeOptionChangedPage" });
|
||||
}).margin({ top: 5, left: 3 })
|
||||
|
||||
}.width('100%').height(60).backgroundColor(Color.Pink)
|
||||
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
||||
Button("测试thumbnail")
|
||||
.onClick(() => {
|
||||
console.log("测试ImageKnifeComponent thumbnail")
|
||||
router.push({ uri: "pages/testImageKnifeOptionChangedPage2" });
|
||||
}).margin({ top: 5, left: 3 })
|
||||
|
||||
}.width('100%').height(60).backgroundColor(Color.Pink)
|
||||
|
||||
Text("测试缓存功能点").fontSize(15)
|
||||
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
||||
Button("测试内存缓存LRU")
|
||||
.onClick(() => {
|
||||
console.log("测试一级内存缓存")
|
||||
router.push({ uri: "pages/storageTestLruCache" });
|
||||
}).margin({ top: 5, left: 3 })
|
||||
Button("测试所有缓存信息输出")
|
||||
.onClick(() => {
|
||||
console.log("pages/testAllCacheInfoPage 页面跳转")
|
||||
router.push({ uri: "pages/testAllCacheInfoPage" });
|
||||
}).margin({ top: 5, left: 3 })
|
||||
|
||||
}.width('100%')
|
||||
.height(60).backgroundColor(Color.Pink)
|
||||
|
||||
Text("测试占位图 失败占位图 功能点").fontSize(15)
|
||||
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
||||
Button("测试失败占位图")
|
||||
.onClick(() => {
|
||||
console.log("测试失败占位图")
|
||||
router.push({ uri: "pages/showErrorholderTestCasePage" });
|
||||
}).margin({ top: 5, left: 3 })
|
||||
}.width('100%').height(60).backgroundColor(Color.Pink)
|
||||
|
||||
Text("测试预加载 gif静态动态切换功能点").fontSize(15)
|
||||
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
||||
Button("测试预加载")
|
||||
.onClick(() => {
|
||||
console.log("测试预加载")
|
||||
router.push({ uri: "pages/testPreloadPage" });
|
||||
}).margin({ top: 5, left: 3 })
|
||||
Button("测试gif静态动态切换")
|
||||
.onClick(() => {
|
||||
console.log("测试gif静态动态切换")
|
||||
router.push({ uri: "pages/testGifDontAnimatePage" });
|
||||
}).margin({ top: 5, left: 3 })
|
||||
}.width('100%').height(60).backgroundColor(Color.Pink)
|
||||
|
||||
Text("测试图片变换 图片压缩 功能点").fontSize(15)
|
||||
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
||||
Button("测试图片变换")
|
||||
.onClick(() => {
|
||||
console.log("测试图片变换")
|
||||
router.push({ uri: "pages/transformPixelMapPage" });
|
||||
}).margin({ top: 5, left: 3 })
|
||||
Button("测试图片压缩")
|
||||
.onClick(() => {
|
||||
console.log("测试图片压缩")
|
||||
router.push({ uri: "pages/compressPage" });
|
||||
}).margin({ top: 5, left: 3 })
|
||||
}.width('100%').height(60).backgroundColor(Color.Pink)
|
||||
|
||||
Text("测试fresco").fontSize(15)
|
||||
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
||||
Button("加载百分比")
|
||||
.onClick(() => {
|
||||
console.log("加载百分比")
|
||||
router.push({ uri: "pages/frescoImageTestCasePage" });
|
||||
}).margin({ top: 5, left: 3 })
|
||||
Button("重试Retry")
|
||||
.onClick(() => {
|
||||
console.log("重试Retry")
|
||||
router.push({ uri: "pages/frescoRetryTestCasePage" });
|
||||
}).margin({ top: 5, left: 3 })
|
||||
}.width('100%').height(60).backgroundColor(Color.Pink)
|
||||
|
||||
Text("测试pngj和裁剪").fontSize(15)
|
||||
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
||||
Button("测试pngj")
|
||||
.onClick(() => {
|
||||
console.log("测试pngj")
|
||||
router.push({ uri: "pages/pngjTestCasePage" });
|
||||
}).margin({ top: 5, left: 3 })
|
||||
Button("图片裁剪")
|
||||
.onClick(() => {
|
||||
console.log("图片裁剪")
|
||||
router.push({ uri: "pages/cropImagePage2" });
|
||||
}).margin({ top: 5, left: 3 })
|
||||
}.width('100%').height(60).backgroundColor(Color.Pink)
|
||||
|
||||
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
||||
|
||||
Button("测试svg")
|
||||
.onClick(() => {
|
||||
console.log("pages/svgTestCasePage 页面跳转")
|
||||
router.push({ uri: "pages/svgTestCasePage" });
|
||||
}).margin({ top: 15 })
|
||||
|
||||
Button("测试gif")
|
||||
.onClick(() => {
|
||||
console.log("pages/gifTestCasePage 页面跳转")
|
||||
router.push({ uri: "pages/gifTestCasePage" });
|
||||
}).margin({ top: 15 })
|
||||
}.width('100%').height(60).backgroundColor(Color.Pink)
|
||||
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
||||
|
||||
Button("组件显式动画")
|
||||
.onClick(() => {
|
||||
console.log("pages/testImageKnifeOptionChangedPage3 页面跳转")
|
||||
router.push({ uri: "pages/testImageKnifeOptionChangedPage3" });
|
||||
}).margin({ top: 15 })
|
||||
|
||||
Button("组件内容动画")
|
||||
.onClick(() => {
|
||||
console.log("pages/testImageKnifeOptionChangedPage4 页面跳转")
|
||||
router.push({ uri: "pages/testImageKnifeOptionChangedPage4" });
|
||||
}).margin({ top: 15 })
|
||||
|
||||
Button("自定义圆角椭圆")
|
||||
.onClick(() => {
|
||||
console.log("pages/testImageKnifeOptionChangedPage5 页面跳转")
|
||||
router.push({ uri: "pages/testImageKnifeOptionChangedPage5" });
|
||||
}).margin({ top: 15 })
|
||||
|
||||
}.width('100%').height(60).backgroundColor(Color.Pink)
|
||||
}
|
||||
}
|
||||
.width('100%')
|
||||
.height('100%')
|
||||
}
|
||||
|
||||
aboutToAppear() {
|
||||
}
|
||||
|
||||
onBackPress() {
|
||||
|
||||
}
|
||||
}
|
|
@ -13,165 +13,71 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
import router from '@system.router';
|
||||
|
||||
|
||||
|
||||
import {
|
||||
ImageKnifeComponent,
|
||||
ImageKnifeOption,
|
||||
} from '@ohos/imageknife'
|
||||
import ArkWorker from '@ohos.worker'
|
||||
@Entry
|
||||
@Component
|
||||
struct IndexFunctionDemo {
|
||||
@State hint1: string = '启用网络模拟加载替换网络加载'
|
||||
private globalGifWorker:any = undefined
|
||||
@State imageKnifeOption1: ImageKnifeOption =
|
||||
{
|
||||
loadSrc: $r('app.media.icon'),
|
||||
size: { width: '300', height: '300' },
|
||||
placeholderSrc: $r('app.media.icon_loading'),
|
||||
errorholderSrc: $r('app.media.icon_failed')
|
||||
};
|
||||
|
||||
@State imageKnifeOption2: ImageKnifeOption =
|
||||
{
|
||||
loadSrc: $r('app.media.icon'),
|
||||
size: { width: '300', height: '300' },
|
||||
placeholderSrc: $r('app.media.icon_loading'),
|
||||
errorholderSrc: $r('app.media.icon_failed')
|
||||
};
|
||||
|
||||
build() {
|
||||
Scroll() {
|
||||
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
||||
Text("OHOS基础接口测试列表").fontSize(15)
|
||||
Text("简单示例1:加载一张本地png图片").fontSize(15)
|
||||
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
||||
Button("测试元能力")
|
||||
Button("加载PNG")
|
||||
.onClick(() => {
|
||||
console.log("测试元能力子系统")
|
||||
router.push({ uri: "pages/basicTestFeatureAbilityPage" });
|
||||
}).margin({ top: 5, left: 3 })
|
||||
Button("测试文件")
|
||||
.onClick(() => {
|
||||
console.log("测试文件子系统")
|
||||
router.push({ uri: "pages/basicTestFileIOPage" });
|
||||
}).margin({ top: 5, left: 3 })
|
||||
Button("测试全球化")
|
||||
.onClick(() => {
|
||||
console.log("测试全球化子系统")
|
||||
router.push({ uri: "pages/basicTestResourceManagerPage" });
|
||||
}).margin({ top: 5, left: 3 })
|
||||
Button("测试媒体")
|
||||
.onClick(() => {
|
||||
console.log("测试媒体子系统")
|
||||
router.push({ uri: "pages/basicTestMediaImage" });
|
||||
this.imageKnifeOption1 = {
|
||||
loadSrc: $r('app.media.pngSample'),
|
||||
size: { width: '300', height: '300' },
|
||||
placeholderSrc: $r('app.media.icon_loading'),
|
||||
errorholderSrc: $r('app.media.icon_failed')
|
||||
}
|
||||
}).margin({ top: 5, left: 3 })
|
||||
ImageKnifeComponent({ imageKnifeOption: $imageKnifeOption1 })
|
||||
}.width('100%').backgroundColor(Color.Pink)
|
||||
|
||||
}.width('100%')
|
||||
.height(60).backgroundColor(Color.Pink)
|
||||
|
||||
Text("测试图片切换功能点").fontSize(15)
|
||||
Text("简单示例2:加载一张网络gif图片").fontSize(15)
|
||||
Text("gif解析在子线程,请在页面构建后创建worker,注入imageknife").fontSize(15)
|
||||
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
||||
Button("测试本地加载")
|
||||
Button("加载GIF")
|
||||
.onClick(() => {
|
||||
console.log("测试bmp,webp,jpg,png本地加载 页面跳转")
|
||||
router.push({ uri: "pages/loadResourceTestCasePage" });
|
||||
this.imageKnifeOption2 = {
|
||||
loadSrc: 'https://pic.ibaotu.com/gif/18/17/16/51u888piCtqj.gif!fwpaa70/fw/700',
|
||||
size: { width: '300', height: '300' },
|
||||
placeholderSrc: $r('app.media.icon_loading'),
|
||||
errorholderSrc: $r('app.media.icon_failed'),
|
||||
displayProgress:true,
|
||||
}
|
||||
}).margin({ top: 5, left: 3 })
|
||||
Button("测试图片切换")
|
||||
.onClick(() => {
|
||||
console.log("测试ImageKnifeComponent所有图片切换")
|
||||
router.push({ uri: "pages/testImageKnifeOptionChangedPage" });
|
||||
}).margin({ top: 5, left: 3 })
|
||||
Button("测试thumbnail")
|
||||
.onClick(() => {
|
||||
console.log("测试ImageKnifeComponent thumbnail")
|
||||
router.push({ uri: "pages/testImageKnifeOptionChangedPage2" });
|
||||
}).margin({ top: 5, left: 3 })
|
||||
|
||||
}.width('100%')
|
||||
.height(60).backgroundColor(Color.Pink)
|
||||
|
||||
Text("测试存储(1级 2级缓存)功能点").fontSize(15)
|
||||
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
||||
Button("测试一级内存缓存")
|
||||
.onClick(() => {
|
||||
console.log("测试一级内存缓存")
|
||||
router.push({ uri: "pages/storageTestLruCache" });
|
||||
}).margin({ top: 5, left: 3 })
|
||||
Button("测试二级内存缓存")
|
||||
.onClick(() => {
|
||||
console.log("测试二级内存缓存")
|
||||
router.push({ uri: "pages/storageTestDiskLruCache" });
|
||||
}).margin({ top: 5, left: 3 })
|
||||
|
||||
}.width('100%')
|
||||
.height(60).backgroundColor(Color.Pink)
|
||||
|
||||
Text("测试占位图 失败占位图 功能点").fontSize(15)
|
||||
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
||||
Button("测试占位图")
|
||||
.onClick(() => {
|
||||
console.log("测试占位图")
|
||||
router.push({ uri: "pages/loadNetworkTestCasePage" });
|
||||
}).margin({ top: 5, left: 3 })
|
||||
Button("测试失败占位图")
|
||||
.onClick(() => {
|
||||
console.log("测试失败占位图")
|
||||
router.push({ uri: "pages/showErrorholderTestCasePage" });
|
||||
}).margin({ top: 5, left: 3 })
|
||||
}.width('100%')
|
||||
.height(60).backgroundColor(Color.Pink)
|
||||
|
||||
Text("测试预加载 gif静态动态切换功能点").fontSize(15)
|
||||
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
||||
Button("测试预加载")
|
||||
.onClick(() => {
|
||||
console.log("测试预加载")
|
||||
router.push({ uri: "pages/testPreloadPage" });
|
||||
}).margin({ top: 5, left: 3 })
|
||||
Button("测试gif静态动态切换")
|
||||
.onClick(() => {
|
||||
console.log("测试gif静态动态切换")
|
||||
router.push({ uri: "pages/testGifDontAnimatePage" });
|
||||
}).margin({ top: 5, left: 3 })
|
||||
}.width('100%')
|
||||
.height(60).backgroundColor(Color.Pink)
|
||||
|
||||
Text("测试图片变换 图片压缩 功能点").fontSize(15)
|
||||
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
||||
Button("测试图片变换")
|
||||
.onClick(() => {
|
||||
console.log("测试图片变换")
|
||||
router.push({ uri: "pages/transformPixelMapPage" });
|
||||
}).margin({ top: 5, left: 3 })
|
||||
Button("测试图片压缩")
|
||||
.onClick(() => {
|
||||
console.log("测试图片压缩")
|
||||
router.push({ uri: "pages/compressPage" });
|
||||
}).margin({ top: 5, left: 3 })
|
||||
}.width('100%')
|
||||
.height(60).backgroundColor(Color.Pink)
|
||||
|
||||
|
||||
Button("测试所有缓存信息输出")
|
||||
.onClick(() => {
|
||||
console.log("pages/testAllCacheInfoPage 页面跳转")
|
||||
router.push({ uri: "pages/testAllCacheInfoPage" });
|
||||
}).margin({ top: 15 })
|
||||
|
||||
Button("测试fresco部分AR")
|
||||
.onClick(() => {
|
||||
console.log("pages/indexFresco 页面跳转")
|
||||
router.push({ uri: "pages/indexFresco" });
|
||||
}).margin({ top: 15 })
|
||||
Button("测试pngj")
|
||||
.onClick(() => {
|
||||
console.log("pages/pngjTestCasePage 页面跳转")
|
||||
router.push({ uri: "pages/pngjTestCasePage" });
|
||||
}).margin({ top: 15 })
|
||||
ImageKnifeComponent({ imageKnifeOption: $imageKnifeOption2 })
|
||||
}.width('100%').backgroundColor(Color.Pink)
|
||||
|
||||
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
||||
Button("测试图片的裁剪")
|
||||
Button("ImageKnife测试目录页面")
|
||||
.onClick(() => {
|
||||
console.log("pages/cropImagePage 页面跳转")
|
||||
router.push({ uri: "pages/cropImagePage" });
|
||||
console.log("pages/imageknifeTestCaseIndex 页面跳转")
|
||||
router.push({ uri: "pages/imageknifeTestCaseIndex" });
|
||||
}).margin({ top: 15 })
|
||||
Button("测试图片的裁剪2")
|
||||
.onClick(() => {
|
||||
console.log("pages/cropImagePage2 页面跳转")
|
||||
router.push({ uri: "pages/cropImagePage2" });
|
||||
}).margin({ top: 15 })
|
||||
}.width('100%')
|
||||
.height(60).backgroundColor(Color.Pink)
|
||||
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
||||
Button("测试dpg图片格式加载")
|
||||
.onClick(() => {
|
||||
console.log("pages/dpgTestCasePage 页面跳转")
|
||||
router.push({ uri: "pages/dpgTestCasePage" });
|
||||
}).margin({ top: 15 })
|
||||
|
||||
}.width('100%')
|
||||
.height(60).backgroundColor(Color.Pink)
|
||||
}.width('100%').height(60).backgroundColor(Color.Pink)
|
||||
}
|
||||
}
|
||||
.width('100%')
|
||||
|
@ -179,6 +85,17 @@ struct IndexFunctionDemo {
|
|||
}
|
||||
|
||||
aboutToAppear() {
|
||||
this.globalGifWorker = new ArkWorker.Worker('entry/ets/pages/workers/gifParseWorker.ts', {
|
||||
type: 'classic',
|
||||
name: 'ImageKnifeParseGIF'
|
||||
})
|
||||
// gif解析在子线程,请在页面构建后创建worker,注入imageknife
|
||||
globalThis.ImageKnife.setGifWorker(this.globalGifWorker)
|
||||
}
|
||||
aboutToDisappear(){
|
||||
if(this.globalGifWorker){
|
||||
this.globalGifWorker.terminate();
|
||||
}
|
||||
}
|
||||
|
||||
onBackPress() {
|
||||
|
|
|
@ -1,40 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import router from '@system.router';
|
||||
|
||||
@Entry
|
||||
@Component
|
||||
struct IndexFresco {
|
||||
build() {
|
||||
Scroll() {
|
||||
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
||||
Button("测试控件隐藏与展示和动画")
|
||||
.onClick(() => {
|
||||
router.push({ uri: "pages/frescoLayerTestCasePage" });
|
||||
}).margin({ top: 15 })
|
||||
Button("测试自定义控件FrescoImage的加载百分比")
|
||||
.onClick(() => {
|
||||
router.push({ uri: "pages/frescoImageTestCasePage" });
|
||||
}).margin({ top: 15 })
|
||||
Button("测试自定义控件FrescoImage重试Retry")
|
||||
.onClick(() => {
|
||||
router.push({ uri: "pages/frescoRetryTestCasePage" });
|
||||
}).margin({ top: 15 })
|
||||
}
|
||||
}
|
||||
.width('100%')
|
||||
.height('100%')
|
||||
}
|
||||
}
|
|
@ -1,64 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import {ImageKnifeComponent} from '@ohos/imageknife'
|
||||
import {ImageKnifeOption} from '@ohos/imageknife'
|
||||
import {RotateImageTransformation} from '@ohos/imageknife'
|
||||
import {RoundedCornersTransformation} from '@ohos/imageknife'
|
||||
|
||||
@Entry
|
||||
@Component
|
||||
struct LoadNetworkTestCasePage {
|
||||
@State imageKnifeOption1: ImageKnifeOption =
|
||||
{
|
||||
loadSrc: "https://thirdwx.qlogo.cn/mmopen/vi_32/DYAIOgq83ericA1Mv66TwicuYOtbDMBcUhv1aa9RJBeAn9uURfcZD0AUGrJebAn1g2AjN0vb2E1XTET7fTuLBNmA/132",
|
||||
size: { width: 300, height: 300 },
|
||||
placeholderSrc: $r('app.media.icon_loading'),
|
||||
errorholderSrc: $r('app.media.icon_failed'),
|
||||
};
|
||||
@State imageKnifeOption2: ImageKnifeOption =
|
||||
{
|
||||
loadSrc: "https://hbimg.huabanimg.com/0ef60041445edcfd6b38d20e19024b2cd9281dcc3525a4-Vy8fYO_fw658/format/webp",
|
||||
size: { width: 300, height: 300 },
|
||||
placeholderSrc: $r('app.media.icon_loading'),
|
||||
errorholderSrc: $r('app.media.icon_failed'),
|
||||
};
|
||||
@State imageKnifeOption3: ImageKnifeOption =
|
||||
{
|
||||
loadSrc: "https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp",
|
||||
size: { width: 300, height: 300 },
|
||||
placeholderSrc: $r('app.media.icon_loading'),
|
||||
errorholderSrc: $r('app.media.icon_failed'),
|
||||
};
|
||||
@State imageKnifeOption4: ImageKnifeOption =
|
||||
{
|
||||
loadSrc: "https://hbimg.huabanimg.com/cc6af25f8d782d3cf3122bef4e61571378271145735e9-vEVggB",
|
||||
size: { width: 300, height: 300 },
|
||||
placeholderSrc: $r('app.media.icon_loading'),
|
||||
errorholderSrc: $r('app.media.icon_failed'),
|
||||
};
|
||||
|
||||
build() {
|
||||
Scroll() {
|
||||
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
||||
ImageKnifeComponent({ imageKnifeOption: $imageKnifeOption1 })
|
||||
ImageKnifeComponent({ imageKnifeOption: $imageKnifeOption2 })
|
||||
ImageKnifeComponent({ imageKnifeOption: $imageKnifeOption3 })
|
||||
ImageKnifeComponent({ imageKnifeOption: $imageKnifeOption4 })
|
||||
}
|
||||
}
|
||||
.width('100%')
|
||||
.height('100%')
|
||||
}
|
||||
}
|
|
@ -1,65 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import {ImageKnifeComponent} from '@ohos/imageknife'
|
||||
import {ImageKnifeOption} from '@ohos/imageknife'
|
||||
import {RotateImageTransformation} from '@ohos/imageknife'
|
||||
import {RoundedCornersTransformation} from '@ohos/imageknife'
|
||||
|
||||
@Entry
|
||||
@Component
|
||||
struct LoadResourceTestCasePage {
|
||||
@State imageKnifeOption1: ImageKnifeOption =
|
||||
{
|
||||
loadSrc: $r('app.media.gifSample'),
|
||||
size: { width: 300, height: 300 },
|
||||
placeholderSrc: $r('app.media.icon_loading'),
|
||||
errorholderSrc: $r('app.media.icon_failed'),
|
||||
};
|
||||
@State imageKnifeOption2: ImageKnifeOption =
|
||||
{
|
||||
loadSrc: $r('app.media.bmpSample'),
|
||||
size: { width: 300, height: 300 },
|
||||
// placeholderSrc: $r('app.media.icon_loading'),
|
||||
// errorholderSrc: $r('app.media.icon_failed'),
|
||||
};
|
||||
@State imageKnifeOption3: ImageKnifeOption =
|
||||
{
|
||||
loadSrc: $r('app.media.pngSample'),
|
||||
size: { width: 300, height: 300 },
|
||||
// placeholderSrc: $r('app.media.icon_loading'),
|
||||
// errorholderSrc: $r('app.media.icon_failed'),
|
||||
};
|
||||
@State imageKnifeOption4: ImageKnifeOption =
|
||||
{
|
||||
loadSrc: $r('app.media.jpgSample'),
|
||||
size: { width: 300, height: 300 },
|
||||
// placeholderSrc: $r('app.media.icon_loading'),
|
||||
// errorholderSrc: $r('app.media.icon_failed'),
|
||||
};
|
||||
|
||||
build() {
|
||||
Scroll() {
|
||||
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
||||
ImageKnifeComponent({ imageKnifeOption: $imageKnifeOption1 })
|
||||
// ImageKnifeComponent({ imageKnifeOption: $imageKnifeOption2 })
|
||||
// ImageKnifeComponent({ imageKnifeOption: $imageKnifeOption3 })
|
||||
// ImageKnifeComponent({ imageKnifeOption: $imageKnifeOption4 })
|
||||
}
|
||||
}
|
||||
.width('100%')
|
||||
.height('100%')
|
||||
}
|
||||
}
|
||||
|
|
@ -30,13 +30,14 @@ struct PngjTestCasePage {
|
|||
@State hint4: string = 'writePngWithString内容展示'
|
||||
@State hint5: string = '测试readMetadata'
|
||||
@State hint6: string = '测试writeMetadata'
|
||||
@State hint7: string = '首先点击获取PNG图片buffer'
|
||||
|
||||
build() {
|
||||
Scroll() {
|
||||
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
||||
Text('pngj接口测试列表').fontSize(20)
|
||||
|
||||
Button('点击获取Png图片buffer').fontSize(20)
|
||||
Button(this.hint7).fontSize(30)
|
||||
.onClick(() => {
|
||||
|
||||
this.rootFolder = globalThis.ImageKnife.getImageKnifeContext().filesDir;
|
||||
|
@ -45,6 +46,7 @@ struct PngjTestCasePage {
|
|||
globalThis.ImageKnife.getImageKnifeContext().resourceManager.getMedia($r('app.media.pngSample').id)
|
||||
.then(data => {
|
||||
this.pngSource = FileUtils.getInstance().uint8ArrayToBuffer(data);
|
||||
this.hint7 = '获取buffer成功,可以测试'
|
||||
})
|
||||
.catch(err => {
|
||||
console.log('点击获取Png图片buffer err=' + err)
|
||||
|
@ -52,60 +54,59 @@ struct PngjTestCasePage {
|
|||
})
|
||||
|
||||
|
||||
// Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
||||
// Button('测试readPngImageInfo')
|
||||
// .onClick(() => {
|
||||
// let pngj = new Pngj();
|
||||
// pngj.readPngImageInfo(this.pngSource, (sender, value) => {
|
||||
// this.hint1 = JSON.stringify(value);
|
||||
// })
|
||||
// }).margin({ top: 5, left: 10 })
|
||||
// Button('测试readPngImage')
|
||||
// .onClick(() => {
|
||||
// let pngj = new Pngj();
|
||||
// pngj.readPngImage(this.pngSource, (sender, value) => {
|
||||
// this.hint2 = 'img with=' + value.width + ' img height=' + value.height
|
||||
// + ' img depth=' + value.depth + ' img ctype=' + value.ctype
|
||||
// console.log('png data =' + value.data);
|
||||
// })
|
||||
// }).margin({ top: 5, left: 10 })
|
||||
// Button('测试writePngWithString')
|
||||
// .onClick(() => {
|
||||
// let pngj = new Pngj();
|
||||
// pngj.writePngWithString('hello world', this.pngSource, (sender, value) => {
|
||||
//
|
||||
// FileUtils.getInstance().createFileProcess(
|
||||
// this.rootFolder + '/pngj',
|
||||
// this.rootFolder + '/pngj/newPng.png',
|
||||
// value)
|
||||
// let png1 = new Uint8Array(value)
|
||||
// this.hint3 = 'png写入后长度' + png1.byteLength + '目录文件:' + this.rootFolder + '/pngj/newPng.png' + '保存后使用2进制查看数据是否新增'
|
||||
// })
|
||||
// }).margin({ top: 5, left: 10 })
|
||||
// Button('测试writePng')
|
||||
// .onClick(() => {
|
||||
// let pngj = new Pngj();
|
||||
// pngj.writePng(this.pngSource, (sender, value) => {
|
||||
// FileUtils.getInstance().createFileProcess(
|
||||
// this.rootFolder + '/pngj',
|
||||
// this.rootFolder + '/pngj/newPng2.png',
|
||||
// value)
|
||||
// let png2 = new Uint8Array(value)
|
||||
// this.hint4 = 'png2未写入长度' + png2.byteLength + '目录文件:' + this.rootFolder + '/pngj/newPng2.png' + '保存后使用2进制查看数据是否新增'
|
||||
// })
|
||||
// }).margin({ top: 5, left: 10 })
|
||||
// }.width('100%')
|
||||
// .height(60).backgroundColor(Color.Pink)
|
||||
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
||||
Button('测试readPngImageInfo')
|
||||
Button('测试readPng')
|
||||
.onClick(() => {
|
||||
let pngj = new Pngj();
|
||||
pngj.readPngImageInfo(this.pngSource, (sender, value) => {
|
||||
this.hint1 = JSON.stringify(value);
|
||||
})
|
||||
}).margin({ top: 5, left: 10 })
|
||||
Button('测试readPngImage')
|
||||
.onClick(() => {
|
||||
let pngj = new Pngj();
|
||||
pngj.readPngImage(this.pngSource, (sender, value) => {
|
||||
this.hint2 = 'img with=' + value.width + ' img height=' + value.height
|
||||
+ ' img depth=' + value.depth + ' img ctype=' + value.ctype
|
||||
console.log('png data =' + value.data);
|
||||
})
|
||||
}).margin({ top: 5, left: 10 })
|
||||
Button('测试writePngWithString')
|
||||
.onClick(() => {
|
||||
let pngj = new Pngj();
|
||||
pngj.writePngWithString('hello world', this.pngSource, (sender, value) => {
|
||||
|
||||
FileUtils.getInstance().createFileProcess(
|
||||
this.rootFolder + '/pngj',
|
||||
this.rootFolder + '/pngj/newPng.png',
|
||||
value)
|
||||
let png1 = new Uint8Array(value)
|
||||
this.hint3 = 'png写入后长度' + png1.byteLength + '目录文件:' + this.rootFolder + '/pngj/newPng.png' + '保存后使用2进制查看数据是否新增'
|
||||
})
|
||||
}).margin({ top: 5, left: 10 })
|
||||
Button('测试writePng')
|
||||
.onClick(() => {
|
||||
let pngj = new Pngj();
|
||||
pngj.writePng(this.pngSource, (sender, value) => {
|
||||
FileUtils.getInstance().createFileProcess(
|
||||
this.rootFolder + '/pngj',
|
||||
this.rootFolder + '/pngj/newPng2.png',
|
||||
value)
|
||||
let png2 = new Uint8Array(value)
|
||||
this.hint4 = 'png2未写入长度' + png2.byteLength + '目录文件:' + this.rootFolder + '/pngj/newPng2.png' + '保存后使用2进制查看数据是否新增'
|
||||
})
|
||||
}).margin({ top: 5, left: 10 })
|
||||
}.width('100%')
|
||||
.height(60).backgroundColor(Color.Pink)
|
||||
|
||||
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
||||
Button('测试readPngImageInfo')
|
||||
.onClick(() => {
|
||||
let pngj = new Pngj();
|
||||
pngj.readPngImageInfo(this.pngSource, (sender, value) => {
|
||||
this.hint1 = JSON.stringify(value);
|
||||
})
|
||||
}).margin({ top: 5, left: 10 })
|
||||
Button('测试readPngImageAsync')
|
||||
Button('readPngAsync')
|
||||
.onClick(() => {
|
||||
let pngj = new Pngj();
|
||||
let worker = new ArkWorker.Worker('entry/ets/pages/workers/worker1.js', {
|
||||
|
@ -118,7 +119,12 @@ struct PngjTestCasePage {
|
|||
+ ' img depth=' + value.depth + ' img ctype=' + value.ctype
|
||||
})
|
||||
}).margin({ top: 5, left: 10 })
|
||||
Button('测试writePngWithStringAsync')
|
||||
|
||||
}.width('100%')
|
||||
.height(60).backgroundColor(Color.Pink)
|
||||
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
||||
|
||||
Button('测试writePngWithString')
|
||||
.onClick(() => {
|
||||
let pngj = new Pngj();
|
||||
let worker = new ArkWorker.Worker('entry/ets/pages/workers/worker1.js', {
|
||||
|
@ -135,7 +141,7 @@ struct PngjTestCasePage {
|
|||
this.hint3 = 'png写入后长度' + png1.byteLength + '目录文件:' + this.rootFolder + '/pngj/newPng.png' + '保存后使用2进制查看数据是否新增'
|
||||
})
|
||||
}).margin({ top: 5, left: 10 })
|
||||
Button('测试writePngAsync')
|
||||
Button('writePng')
|
||||
.onClick(() => {
|
||||
let pngj = new Pngj();
|
||||
let worker = new ArkWorker.Worker('entry/ets/pages/workers/worker1.js', {
|
||||
|
@ -155,6 +161,7 @@ struct PngjTestCasePage {
|
|||
}.width('100%')
|
||||
.height(60).backgroundColor(Color.Pink)
|
||||
|
||||
|
||||
Text(this.hint1)
|
||||
.width('100%')
|
||||
.height(120)
|
||||
|
|
|
@ -23,28 +23,28 @@ struct ShowErrorholderTestCasePage {
|
|||
@State imageKnifeOption1: ImageKnifeOption =
|
||||
{
|
||||
loadSrc: "https://thirdwx.qlogo.cn/mmopen/xxxxx",
|
||||
size: { width: 300, height: 300 },
|
||||
size: { width: '300', height: '300' },
|
||||
placeholderSrc: $r('app.media.icon_loading'),
|
||||
errorholderSrc: $r('app.media.icon_failed'),
|
||||
};
|
||||
@State imageKnifeOption2: ImageKnifeOption =
|
||||
@State ImageKnifeOption: ImageKnifeOption =
|
||||
{
|
||||
loadSrc: "https://hbimg.huabanimg.com/xxxxx",
|
||||
size: { width: 300, height: 300 },
|
||||
size: { width: '300', height: '300' },
|
||||
placeholderSrc: $r('app.media.icon_loading'),
|
||||
errorholderSrc: $r('app.media.icon_failed'),
|
||||
};
|
||||
@State imageKnifeOption3: ImageKnifeOption =
|
||||
{
|
||||
loadSrc: "https://hbimg.huabanimg.com/xxxxx",
|
||||
size: { width: 300, height: 300 },
|
||||
size: { width: '300', height: '300' },
|
||||
placeholderSrc: $r('app.media.icon_loading'),
|
||||
errorholderSrc: $r('app.media.icon_failed'),
|
||||
};
|
||||
@State imageKnifeOption4: ImageKnifeOption =
|
||||
{
|
||||
loadSrc: "https://hbimg.huabanimg.com/xxxxx",
|
||||
size: { width: 300, height: 300 },
|
||||
size: { width: '300', height: '300' },
|
||||
placeholderSrc: $r('app.media.icon_loading'),
|
||||
errorholderSrc: $r('app.media.icon_failed'),
|
||||
};
|
||||
|
@ -53,7 +53,7 @@ struct ShowErrorholderTestCasePage {
|
|||
Scroll() {
|
||||
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
||||
ImageKnifeComponent({ imageKnifeOption: $imageKnifeOption1 })
|
||||
ImageKnifeComponent({ imageKnifeOption: $imageKnifeOption2 })
|
||||
ImageKnifeComponent({ imageKnifeOption: $ImageKnifeOption })
|
||||
ImageKnifeComponent({ imageKnifeOption: $imageKnifeOption3 })
|
||||
ImageKnifeComponent({ imageKnifeOption: $imageKnifeOption4 })
|
||||
}
|
||||
|
|
|
@ -1,325 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
import {ImageKnifeOption} from '@ohos/imageknife'
|
||||
import {RequestOption} from '@ohos/imageknife'
|
||||
import {ImageKnifeData} from '@ohos/imageknife'
|
||||
import {PixelMapPack} from '@ohos/imageknife'
|
||||
|
||||
|
||||
|
||||
|
||||
@Entry
|
||||
@Component
|
||||
struct StorageTestDiskLruCache {
|
||||
@Watch('watchImageKnifeOption') @State imageKnifeOption: ImageKnifeOption =
|
||||
{
|
||||
loadSrc: $r('app.media.jpgSample'),
|
||||
size: { width: 300, height: 300 },
|
||||
placeholderSrc: $r('app.media.icon_loading'),
|
||||
errorholderSrc: $r('app.media.icon_failed'),
|
||||
};
|
||||
@State imageKnifePixelMapPack: PixelMapPack = new PixelMapPack();
|
||||
@State imageKnifeResource: Resource = $r('app.media.icon_loading')
|
||||
@State imageKnifeString: string = ""
|
||||
@State normalPixelMap: boolean = false;
|
||||
@State normalResource: boolean = true;
|
||||
previousData: ImageKnifeData = null;
|
||||
nowData: ImageKnifeData = null;
|
||||
@State logText: string = "打印日志结果";
|
||||
|
||||
|
||||
watchImageKnifeOption() {
|
||||
this.imageKnifeExecute();
|
||||
}
|
||||
|
||||
build() {
|
||||
Scroll() {
|
||||
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
||||
Text("ImageKnife测试DiskLruCache能力")
|
||||
.backgroundColor(Color.Blue)
|
||||
Button("替换ImageKnife默认DiskLruCache并设置大小1M")
|
||||
.onClick(() => {
|
||||
globalThis.ImageKnife.replaceDiskLruCache(1 * 1024 * 1024)
|
||||
}).margin({top:15, bottom:15})
|
||||
|
||||
Button("替换ImageKnife默认DiskLruCache并设置大小30M")
|
||||
.onClick(() => {
|
||||
globalThis.ImageKnife.replaceDiskLruCache(30 * 1024 * 1024)
|
||||
}).margin({top:15, bottom:15})
|
||||
|
||||
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
||||
Button("加载jpg网络图")
|
||||
.onClick(() => {
|
||||
this.imageKnifeOption = {
|
||||
loadSrc: "https://hbimg.huabanimg.com/cc6af25f8d782d3cf3122bef4e61571378271145735e9-vEVggB",
|
||||
size: { width: 300, height: 300 },
|
||||
placeholderSrc: $r('app.media.icon_loading'),
|
||||
errorholderSrc: $r('app.media.icon_failed'),
|
||||
margin:{left:5,top:5,right:5,bottom:5}
|
||||
};
|
||||
|
||||
}).margin({ top: 5, left: 10 })
|
||||
Button("加载png网络图")
|
||||
.onClick(() => {
|
||||
this.imageKnifeOption = {
|
||||
loadSrc: "https://img-blog.csdnimg.cn/20191215043500229.png",
|
||||
size: { width: 300, height: 300 },
|
||||
placeholderSrc: $r('app.media.icon_loading'),
|
||||
errorholderSrc: $r('app.media.icon_failed'),
|
||||
margin:{left:5,top:5,right:5,bottom:5}
|
||||
};
|
||||
}).margin({ top: 5, left: 10 })
|
||||
Button("加载webp网络图")
|
||||
.onClick(() => {
|
||||
this.imageKnifeOption = {
|
||||
loadSrc: "https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp",
|
||||
size: { width: 300, height: 300 },
|
||||
placeholderSrc: $r('app.media.icon_loading'),
|
||||
errorholderSrc: $r('app.media.icon_failed'),
|
||||
margin:{left:5,top:5,right:5,bottom:5}
|
||||
};
|
||||
}).margin({ top: 5, left: 10 })
|
||||
Button("加载bmp网络图")
|
||||
.onClick(() => {
|
||||
this.imageKnifeOption = {
|
||||
loadSrc: "https://img-blog.csdn.net/20140514114029140",
|
||||
size: { width: 300, height: 300 },
|
||||
placeholderSrc: $r('app.media.icon_loading'),
|
||||
errorholderSrc: $r('app.media.icon_failed'),
|
||||
margin:{left:5,top:5,right:5,bottom:5}
|
||||
};
|
||||
}).margin({ top: 5, left: 10 })
|
||||
}.width('100%')
|
||||
.height(60).backgroundColor(Color.Pink)
|
||||
|
||||
|
||||
Image(this.normalPixelMap ? this.imageKnifePixelMapPack.pixelMap : (this.normalResource ? this.imageKnifeResource : this.imageKnifeString))
|
||||
.width(this.imageKnifeOption.size ? this.imageKnifeOption.size.width : '100%')
|
||||
.height(this.imageKnifeOption.size ? this.imageKnifeOption.size.height : '100%')
|
||||
.objectFit(this.imageKnifeOption.imageFit ? this.imageKnifeOption.imageFit : ImageFit.Fill)
|
||||
.backgroundColor(this.imageKnifeOption.backgroundColor ? this.imageKnifeOption.backgroundColor : Color.White)
|
||||
.margin(this.imageKnifeOption.margin ? this.imageKnifeOption.margin : { left: 0, top: 0, right: 0, bottom: 0 })
|
||||
|
||||
|
||||
|
||||
Scroll() {
|
||||
Text(this.logText).fontSize(15)
|
||||
}.width(300).height(300).margin({top:20}).backgroundColor(Color.Pink)
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
.width('100%')
|
||||
.height('100%')
|
||||
}
|
||||
|
||||
|
||||
// imageKnife 第一次启动和数据刷新后重新发送请求
|
||||
imageKnifeExecute() {
|
||||
let request = new RequestOption();
|
||||
request.load(this.imageKnifeOption.loadSrc)
|
||||
.addListener((err, data) => {
|
||||
this.imageKnifeChangeSource(data)
|
||||
return false;
|
||||
})
|
||||
if (this.imageKnifeOption.placeholderSrc) {
|
||||
request.placeholder(this.imageKnifeOption.placeholderSrc, (data) => {
|
||||
this.imageKnifeChangeSource(data)
|
||||
})
|
||||
}
|
||||
if (this.imageKnifeOption.errorholderSrc) {
|
||||
request.errorholder(this.imageKnifeOption.errorholderSrc, (data) => {
|
||||
this.imageKnifeChangeSource(data)
|
||||
})
|
||||
}
|
||||
|
||||
if (this.imageKnifeOption.size) {
|
||||
request.setImageViewSize(this.imageKnifeOption.size)
|
||||
}
|
||||
|
||||
if (this.imageKnifeOption.onlyRetrieveFromCache) {
|
||||
request.retrieveDataFromCache(this.imageKnifeOption.onlyRetrieveFromCache)
|
||||
}
|
||||
|
||||
if (this.imageKnifeOption.isCacheable) {
|
||||
request.skipMemoryCache(!this.imageKnifeOption.isCacheable)
|
||||
}
|
||||
|
||||
if (this.imageKnifeOption.strategy) {
|
||||
request.diskCacheStrategy(this.imageKnifeOption.strategy)
|
||||
}
|
||||
|
||||
if (this.imageKnifeOption.dontAnimateFlag) {
|
||||
request.dontAnimate()
|
||||
}
|
||||
if (this.imageKnifeOption.allCacheInfoCallback) {
|
||||
request.addAllCacheInfoCallback(this.imageKnifeOption.allCacheInfoCallback)
|
||||
}
|
||||
|
||||
globalThis.ImageKnife.call(request);
|
||||
}
|
||||
|
||||
imageKnifeChangeSource(data:ImageKnifeData) {
|
||||
this.imageKnifeSpecialFixed(data);
|
||||
|
||||
|
||||
// 由于异步写入,可能读取disklrucache的时候还没删成功,为了保证成功删除这里使用了延时
|
||||
setTimeout(() => {
|
||||
//查看mImageKnife中的DiskLruCache
|
||||
let disk = globalThis.ImageKnife.getDiskMemoryCache();
|
||||
let showDisk = ''
|
||||
disk.foreachDiskLruCache((value, key, map) => {
|
||||
showDisk += "key=" + key + "&value=" + value;
|
||||
})
|
||||
this.logText = "日志结果:" + showDisk;
|
||||
}, 2000)
|
||||
|
||||
}
|
||||
|
||||
imageKnifeSpecialFixed(data:ImageKnifeData) {
|
||||
if (this.nowData) {
|
||||
this.previousData = this.nowData;
|
||||
this.nowData = data;
|
||||
if (data.isPixelMap()) {
|
||||
// PixelMap
|
||||
console.log("ImageKnife占位图输出=PixelMap")
|
||||
if (this.previousData.isSvg()) {
|
||||
console.log("ImageKnife占位图输出=PixelMap 上一个是SVG")
|
||||
this.normalPixelMap = true;
|
||||
this.normalResource = true;
|
||||
|
||||
let pixelMapPack1 = new PixelMapPack();
|
||||
|
||||
this.imageKnifePixelMapPack = pixelMapPack1;
|
||||
|
||||
setTimeout(() => {
|
||||
let pixelMapPack2 = new PixelMapPack();
|
||||
pixelMapPack2.pixelMap = data.imageKnifeValue as PixelMap;
|
||||
this.imageKnifePixelMapPack = pixelMapPack2;
|
||||
}, 100)
|
||||
} else {
|
||||
this.normalPixelMap = true;
|
||||
this.normalResource = true;
|
||||
|
||||
let pixelMapPack3 = new PixelMapPack();
|
||||
pixelMapPack3.pixelMap = data.imageKnifeValue as PixelMap;
|
||||
|
||||
this.imageKnifePixelMapPack = pixelMapPack3;
|
||||
}
|
||||
}
|
||||
else if (data.isString()) {
|
||||
// String
|
||||
console.log("imageKnifevalue=" + JSON.stringify(data));
|
||||
console.log("ImageKnife占位图输出=String")
|
||||
if (this.previousData.isSvg()) {
|
||||
|
||||
console.log("data.imageKnifeValue=" + JSON.stringify(data.imageKnifeValue))
|
||||
console.log("ImageKnife占位图输出=String 拥有上一个图片类型 上一个是SVG")
|
||||
this.normalPixelMap = false;
|
||||
this.normalResource = false;
|
||||
let firstIndex = (data.imageKnifeValue as string).indexOf(globalThis.ImageKnife.getSvgAndGifFolder());
|
||||
console.log("firstIndex=" + firstIndex);
|
||||
let suffix = (data.imageKnifeValue as string).substring(firstIndex, (data.imageKnifeValue as string).length)
|
||||
console.log("suffix =" + suffix);
|
||||
let imageKnifeNeedStr = 'internal://app/' + suffix;
|
||||
this.imageKnifeString = imageKnifeNeedStr;
|
||||
} else {
|
||||
console.log("data.imageKnifeValue=" + JSON.stringify(data.imageKnifeValue))
|
||||
console.log("ImageKnife占位图输出=String 拥有上一个图片类型 上一个不是SVG")
|
||||
|
||||
this.normalPixelMap = false;
|
||||
this.normalResource = false;
|
||||
let firstIndex = (data.imageKnifeValue as string).indexOf(globalThis.ImageKnife.getSvgAndGifFolder());
|
||||
console.log("firstIndex=" + firstIndex);
|
||||
let suffix = (data.imageKnifeValue as string).substring(firstIndex, (data.imageKnifeValue as string).length)
|
||||
console.log("suffix =" + suffix);
|
||||
let imageKnifeNeedStr = 'internal://app/' + suffix;
|
||||
this.imageKnifeString = imageKnifeNeedStr;
|
||||
}
|
||||
} else if (data.isResource()) {
|
||||
console.log("ImageKnife占位图输出=Resource")
|
||||
if (this.previousData.isSvg()) {
|
||||
console.log("ImageKnife占位图输出=Resource 上一个是SVG")
|
||||
this.normalPixelMap = false;
|
||||
this.normalResource = true;
|
||||
this.imageKnifeResource = data.imageKnifeValue as Resource;
|
||||
} else {
|
||||
this.normalPixelMap = false;
|
||||
this.normalResource = true;
|
||||
this.imageKnifeResource = data.imageKnifeValue as Resource;
|
||||
}
|
||||
} else {
|
||||
console.log("ImageKnife占位图输出=数据错误")
|
||||
}
|
||||
|
||||
} else {
|
||||
this.nowData = data;
|
||||
if (data.isPixelMap()) {
|
||||
// PixelMap
|
||||
console.log("ImageKnife占位图输出=PixelMap")
|
||||
this.normalPixelMap = true;
|
||||
this.normalResource = true;
|
||||
|
||||
let pixelMapPack4 = new PixelMapPack();
|
||||
pixelMapPack4.pixelMap = data.imageKnifeValue as PixelMap;
|
||||
|
||||
this.imageKnifePixelMapPack = pixelMapPack4;
|
||||
}
|
||||
else if (data.isString()) {
|
||||
// String
|
||||
console.log("data.imageKnifeValue=" + JSON.stringify(data.imageKnifeValue))
|
||||
console.log("ImageKnife占位图输出=String 没有上一个图片类型")
|
||||
this.normalPixelMap = false;
|
||||
this.normalResource = false;
|
||||
let firstIndex = (data.imageKnifeValue as string).indexOf(globalThis.ImageKnife.getSvgAndGifFolder());
|
||||
console.log("firstIndex=" + firstIndex);
|
||||
let suffix = (data.imageKnifeValue as string).substring(firstIndex, (data.imageKnifeValue as string).length)
|
||||
console.log("suffix =" + suffix);
|
||||
let imageKnifeNeedStr = 'internal://app/' + suffix;
|
||||
this.imageKnifeString = imageKnifeNeedStr;
|
||||
} else if (data.isResource()) {
|
||||
console.log("ImageKnife占位图输出=Resource")
|
||||
this.normalPixelMap = false;
|
||||
this.normalResource = true;
|
||||
this.imageKnifeResource = data.imageKnifeValue as Resource;
|
||||
} else {
|
||||
console.log("ImageKnife占位图输出=数据错误")
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//函数在自定义组件析构消耗之前执行。
|
||||
//不允许在aboutToDisappear函数中改变状态变量,特别是@Link变量的修改可能会导致应用程序行为不稳定。
|
||||
aboutToDisappear() {
|
||||
|
||||
}
|
||||
//当此页面显示时触发一次。包括路由过程、应用进入前后台等场景,仅@Entry修饰的自定义组件生效。
|
||||
onPageShow() {
|
||||
}
|
||||
//当此页面消失时触发一次。包括路由过程、应用进入前后台等场景,仅@Entry修饰的自定义组件生效。
|
||||
onPageHide() {
|
||||
}
|
||||
|
||||
// 当用户点击返回按钮时触发,,仅@Entry修饰的自定义组件生效。
|
||||
//返回true表示页面自己处理返回逻辑, 不进行页面路由。
|
||||
//返回false表示使用默认的返回逻辑。
|
||||
//不返回值会作为false处理。
|
||||
onBackPress() {
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* Copyright (C) 2022 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import {SVGParseImpl} from '@ohos/imageknife'
|
||||
|
||||
@Entry
|
||||
@Component
|
||||
struct svgTestCasePage {
|
||||
|
||||
@State pixels:PixelMap = undefined
|
||||
|
||||
build() {
|
||||
Scroll() {
|
||||
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
||||
Flex({direction:FlexDirection.Row}){
|
||||
Button("加载SVG图片")
|
||||
.onClick(()=>{
|
||||
|
||||
globalThis.ImageKnife.getImageKnifeContext().resourceManager.getMedia($r('app.media.svgSample').id)
|
||||
.then(data => {
|
||||
console.log('basicTestFileIOPage - 本地加载资源 解析后数据data = ' + data)
|
||||
let svgImpl = new SVGParseImpl();
|
||||
svgImpl.parseSvg(data.buffer).then((pixelmap)=>{
|
||||
this.pixels = pixelmap;
|
||||
})
|
||||
})
|
||||
.catch(err => {
|
||||
console.log('basicTestFileIOPage - 本地加载资源err' + JSON.stringify(err));
|
||||
})
|
||||
|
||||
}).margin({left:5}).backgroundColor(Color.Blue)
|
||||
|
||||
}
|
||||
.margin({top:15})
|
||||
|
||||
Text("下面为展示图片区域").margin({top:5})
|
||||
Flex({direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }){
|
||||
Image(this.pixels)
|
||||
.width(400)
|
||||
.height(400)
|
||||
.backgroundColor(Color.Pink)
|
||||
}.width(400).height(400).margin({top:10}).backgroundColor(Color.Pink)
|
||||
}
|
||||
}
|
||||
.width('100%')
|
||||
.height('100%')
|
||||
}
|
||||
|
||||
aboutToAppear() {
|
||||
console.log("aboutToAppear()")
|
||||
}
|
||||
typedArrayToBuffer(array: Uint8Array): ArrayBuffer {
|
||||
return array.buffer.slice(array.byteOffset, array.byteLength + array.byteOffset)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -16,15 +16,14 @@ import {RequestOption} from '@ohos/imageknife'
|
|||
import {AllCacheInfo,IAllCacheInfoCallback} from '@ohos/imageknife'
|
||||
import {ImageKnifeComponent} from '@ohos/imageknife'
|
||||
import {TransformType} from '@ohos/imageknife'
|
||||
import {PixelMapPack} from '@ohos/imageknife'
|
||||
import {ImageKnifeOption} from '@ohos/imageknife'
|
||||
import {RotateImageTransformation} from '@ohos/imageknife'
|
||||
|
||||
@Entry
|
||||
@Component
|
||||
struct TestAllCacheInfoPage {
|
||||
@State nativePixelMap: PixelMapPack = new PixelMapPack();
|
||||
@State networkPixelMap: PixelMapPack = new PixelMapPack();
|
||||
@State nativePixelMap: PixelMap = undefined;
|
||||
@State networkPixelMap: PixelMap = undefined;
|
||||
allCacheInfoCallback1 =(allCacheInfo)=>{
|
||||
let info = allCacheInfo as AllCacheInfo;
|
||||
console.log("AllCacheInfoCallback imageknifecomponent1 memory ="+JSON.stringify(info.memoryCacheInfo))
|
||||
|
@ -36,9 +35,9 @@ struct TestAllCacheInfoPage {
|
|||
}
|
||||
allCacheInfoCallback2 =(allCacheInfo)=>{
|
||||
let info = allCacheInfo as AllCacheInfo;
|
||||
console.log("AllCacheInfoCallback imageknifecomponent2 memory ="+JSON.stringify(info.memoryCacheInfo))
|
||||
console.log("AllCacheInfoCallback imageknifecomponent2 resource ="+JSON.stringify(info.resourceCacheInfo))
|
||||
console.log("AllCacheInfoCallback imageknifecomponent2 data ="+JSON.stringify(info.dataCacheInfo))
|
||||
console.log("AllCacheInfoCallback ImageKnifeComponent memory ="+JSON.stringify(info.memoryCacheInfo))
|
||||
console.log("AllCacheInfoCallback ImageKnifeComponent resource ="+JSON.stringify(info.resourceCacheInfo))
|
||||
console.log("AllCacheInfoCallback ImageKnifeComponent data ="+JSON.stringify(info.dataCacheInfo))
|
||||
this.cacheinfo4 = "memory="+JSON.stringify(info.memoryCacheInfo)+
|
||||
"\n resource ="+JSON.stringify(info.resourceCacheInfo)+
|
||||
"\n data ="+JSON.stringify(info.dataCacheInfo)
|
||||
|
@ -46,7 +45,7 @@ struct TestAllCacheInfoPage {
|
|||
@State imageKnifeOption1: ImageKnifeOption =
|
||||
{
|
||||
loadSrc: $r('app.media.pngSample'),
|
||||
size: { width: 300, height: 300 },
|
||||
size: { width: '300', height: '300' },
|
||||
placeholderSrc: $r('app.media.icon_loading'),
|
||||
errorholderSrc: $r('app.media.icon_failed'),
|
||||
margin:{top:15},
|
||||
|
@ -56,10 +55,10 @@ struct TestAllCacheInfoPage {
|
|||
},
|
||||
allCacheInfoCallback:this.allCacheInfoCallback1
|
||||
};
|
||||
@State imageKnifeOption2: ImageKnifeOption =
|
||||
@State ImageKnifeOption: ImageKnifeOption =
|
||||
{
|
||||
loadSrc: "https://thirdwx.qlogo.cn/mmopen/vi_32/DYAIOgq83ericA1Mv66TwicuYOtbDMBcUhv1aa9RJBeAn9uURfcZD0AUGrJebAn1g2AjN0vb2E1XTET7fTuLBNmA/132",
|
||||
size: { width: 300, height: 300 },
|
||||
size: { width: '300', height: '300' },
|
||||
placeholderSrc: $r('app.media.icon_loading'),
|
||||
errorholderSrc: $r('app.media.icon_failed'),
|
||||
margin:{top:15},
|
||||
|
@ -87,7 +86,7 @@ struct TestAllCacheInfoPage {
|
|||
Scroll() {
|
||||
Text(this.cacheinfo1).fontSize(15)
|
||||
}.width(300).height(200)
|
||||
Image(this.nativePixelMap.pixelMap)
|
||||
Image(this.nativePixelMap )
|
||||
.width(300)
|
||||
.height(300)
|
||||
.objectFit(ImageFit.Contain)
|
||||
|
@ -100,7 +99,7 @@ struct TestAllCacheInfoPage {
|
|||
Scroll() {
|
||||
Text(this.cacheinfo2).fontSize(15)
|
||||
}.width(300).height(200)
|
||||
Image(this.networkPixelMap.pixelMap)
|
||||
Image(this.networkPixelMap )
|
||||
.width(300)
|
||||
.height(300)
|
||||
.objectFit(ImageFit.Contain)
|
||||
|
@ -113,7 +112,7 @@ struct TestAllCacheInfoPage {
|
|||
this.imageKnifeOption1 =
|
||||
{
|
||||
loadSrc: $r('app.media.pngSample'),
|
||||
size: { width: 300, height: 300 },
|
||||
size: { width: '300', height: '300' },
|
||||
placeholderSrc: $r('app.media.icon_loading'),
|
||||
errorholderSrc: $r('app.media.icon_failed'),
|
||||
margin: { top: 15 },
|
||||
|
@ -132,10 +131,10 @@ struct TestAllCacheInfoPage {
|
|||
Button("ImageKnifeComponent加载网络资源获取缓存信息").width(300).height(25)
|
||||
.onClick(() => {
|
||||
this.imageKnifeComponentAngle = this.imageKnifeComponentAngle + 45;
|
||||
this.imageKnifeOption2 =
|
||||
this.ImageKnifeOption =
|
||||
{
|
||||
loadSrc: "https://thirdwx.qlogo.cn/mmopen/vi_32/DYAIOgq83ericA1Mv66TwicuYOtbDMBcUhv1aa9RJBeAn9uURfcZD0AUGrJebAn1g2AjN0vb2E1XTET7fTuLBNmA/132",
|
||||
size: { width: 300, height: 300 },
|
||||
size: { width: '300', height: '300' },
|
||||
placeholderSrc: $r('app.media.icon_loading'),
|
||||
errorholderSrc: $r('app.media.icon_failed'),
|
||||
margin: { top: 15 },
|
||||
|
@ -149,7 +148,7 @@ struct TestAllCacheInfoPage {
|
|||
Scroll() {
|
||||
Text(this.cacheinfo4).fontSize(15)
|
||||
}.width(300).height(200)
|
||||
ImageKnifeComponent({ imageKnifeOption: $imageKnifeOption2 })
|
||||
ImageKnifeComponent({ imageKnifeOption: $ImageKnifeOption })
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -166,8 +165,8 @@ struct TestAllCacheInfoPage {
|
|||
imageKnifeOption.load($r('app.media.pngSample'))
|
||||
.setImageViewSize({width:300,height:300})
|
||||
.addListener((err, data) => {
|
||||
let pack = new PixelMapPack();
|
||||
pack.pixelMap = data.imageKnifeValue as PixelMap;;
|
||||
let pack = undefined;
|
||||
pack = data.drawPixelMap.imagePixelMap as PixelMap;;
|
||||
this.nativePixelMap = pack;
|
||||
return false;
|
||||
}).addAllCacheInfoCallback((allCacheInfo)=>{
|
||||
|
@ -183,11 +182,11 @@ struct TestAllCacheInfoPage {
|
|||
}
|
||||
|
||||
private testAllCacheInfoNetwork() {
|
||||
let imageKnifeOption2 = new RequestOption();
|
||||
imageKnifeOption2.load("https://hbimg.huabanimg.com/0ef60041445edcfd6b38d20e19024b2cd9281dcc3525a4-Vy8fYO_fw658/format/webp")
|
||||
let ImageKnifeOption = new RequestOption();
|
||||
ImageKnifeOption.load("https://hbimg.huabanimg.com/0ef60041445edcfd6b38d20e19024b2cd9281dcc3525a4-Vy8fYO_fw658/format/webp")
|
||||
.addListener((err, data) => {
|
||||
let pack = new PixelMapPack();
|
||||
pack.pixelMap = data.imageKnifeValue as PixelMap;
|
||||
let pack = undefined;
|
||||
pack = data.drawPixelMap.imagePixelMap as PixelMap;
|
||||
this.networkPixelMap = pack;
|
||||
console.log("imageknife2 图片2 赋值!")
|
||||
return false;
|
||||
|
@ -202,7 +201,7 @@ struct TestAllCacheInfoPage {
|
|||
})
|
||||
.setImageViewSize({width:300,height:300})
|
||||
.rotateImage(180)
|
||||
ImageKnife.call(imageKnifeOption2);
|
||||
ImageKnife.call(ImageKnifeOption);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,99 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import {ImageKnifeComponent} from '@ohos/imageknife'
|
||||
import {ImageKnifeOption} from '@ohos/imageknife'
|
||||
import {RotateImageTransformation} from '@ohos/imageknife'
|
||||
import {TransformType} from '@ohos/imageknife'
|
||||
|
||||
@Entry
|
||||
@Component
|
||||
struct TestAllTypeImageKnifeComponentPage {
|
||||
@State imageKnifeOption1: ImageKnifeOption =
|
||||
{
|
||||
loadSrc: $r('app.media.jpgSample'),
|
||||
size: { width: 300, height: 300 },
|
||||
placeholderSrc: $r('app.media.jpgSample'),
|
||||
errorholderSrc: $r('app.media.pngSample'),
|
||||
transform: {
|
||||
transformType:TransformType.RotateImageTransformation,
|
||||
rotateImage:180
|
||||
}
|
||||
};
|
||||
@State imageKnifeOption2: ImageKnifeOption =
|
||||
{
|
||||
loadSrc: $r('app.media.pngSample'),
|
||||
size: { width: 300, height: 300 },
|
||||
placeholderSrc: $r('app.media.jpgSample'),
|
||||
errorholderSrc: $r('app.media.pngSample'),
|
||||
transform: {
|
||||
transformType:TransformType.RotateImageTransformation,
|
||||
rotateImage:180
|
||||
}
|
||||
};
|
||||
@State imageKnifeOption3: ImageKnifeOption =
|
||||
{
|
||||
loadSrc: $r('app.media.jpgSample'),
|
||||
size: { width: 300, height: 300 },
|
||||
placeholderSrc: $r('app.media.jpgSample'),
|
||||
errorholderSrc: $r('app.media.pngSample'),
|
||||
transform: {
|
||||
transformType:TransformType.RotateImageTransformation,
|
||||
rotateImage:180
|
||||
}
|
||||
};
|
||||
@State imageKnifeOption4: ImageKnifeOption =
|
||||
{
|
||||
loadSrc: $r('app.media.svgSample'),
|
||||
size: { width: 300, height: 300 },
|
||||
placeholderSrc: $r('app.media.jpgSample'),
|
||||
errorholderSrc: $r('app.media.pngSample'),
|
||||
transform: {
|
||||
transformType:TransformType.RotateImageTransformation,
|
||||
rotateImage:180
|
||||
}
|
||||
};
|
||||
@State imageKnifeOption5: ImageKnifeOption =
|
||||
{
|
||||
loadSrc: $r('app.media.bmpSample'),
|
||||
size: { width: 300, height: 300 },
|
||||
placeholderSrc: $r('app.media.jpgSample'),
|
||||
errorholderSrc: $r('app.media.pngSample'),
|
||||
transform: {
|
||||
transformType:TransformType.RotateImageTransformation,
|
||||
rotateImage:180
|
||||
}
|
||||
};
|
||||
|
||||
build() {
|
||||
Scroll() {
|
||||
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
||||
ImageKnifeComponent({ imageKnifeOption: $imageKnifeOption1 })
|
||||
ImageKnifeComponent({ imageKnifeOption: $imageKnifeOption2 })
|
||||
ImageKnifeComponent({ imageKnifeOption: $imageKnifeOption3 })
|
||||
ImageKnifeComponent({ imageKnifeOption: $imageKnifeOption4 })
|
||||
ImageKnifeComponent({ imageKnifeOption: $imageKnifeOption5 })
|
||||
}
|
||||
}
|
||||
.width('100%')
|
||||
.height('100%')
|
||||
}
|
||||
|
||||
aboutToAppear() {
|
||||
console.log("aboutToAppear()")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var ImageKnife = globalThis.exports.default.data.imageKnife
|
|
@ -1,52 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import {ImageKnifeComponent} from '@ohos/imageknife'
|
||||
import {ImageKnifeOption} from '@ohos/imageknife'
|
||||
import {RotateImageTransformation} from '@ohos/imageknife'
|
||||
|
||||
@Entry
|
||||
@Component
|
||||
struct TestAllTypeNativeImagePage {
|
||||
build() {
|
||||
Scroll() {
|
||||
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
||||
Image($r('app.media.jpgSample'))
|
||||
.width(300)
|
||||
.height(300)
|
||||
Image($r('app.media.pngSample'))
|
||||
.width(300)
|
||||
.height(300)
|
||||
Image($r('app.media.jpgSample'))
|
||||
.width(300)
|
||||
.height(300)
|
||||
Image($r('app.media.svgSample'))
|
||||
.width(300)
|
||||
.height(300)
|
||||
Image($r('app.media.bmpSample'))
|
||||
.width(300)
|
||||
.height(300)
|
||||
}
|
||||
}
|
||||
.width('100%')
|
||||
.height('100%')
|
||||
}
|
||||
|
||||
aboutToAppear() {
|
||||
console.log("aboutToAppear()")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var ImageKnife = globalThis.exports.default.data.imageKnife
|
|
@ -15,14 +15,15 @@
|
|||
import {ImageKnifeComponent} from '@ohos/imageknife'
|
||||
import {ImageKnifeOption} from '@ohos/imageknife'
|
||||
import {RotateImageTransformation} from '@ohos/imageknife'
|
||||
|
||||
import ArkWorker from '@ohos.worker'
|
||||
@Entry
|
||||
@Component
|
||||
struct TestGifDontAnimatePage {
|
||||
private globalGifWorker:any = undefined
|
||||
@State imageKnifeOption1: ImageKnifeOption =
|
||||
{
|
||||
loadSrc: $r('app.media.jpgSample'),
|
||||
size: { width: 300, height: 300 },
|
||||
size: { width: '300', height: '300' },
|
||||
placeholderSrc: $r('app.media.icon_loading'),
|
||||
errorholderSrc: $r('app.media.icon_failed'),
|
||||
margin:{left:15,top:15,right:15,bottom:15}
|
||||
|
@ -37,7 +38,7 @@ struct TestGifDontAnimatePage {
|
|||
.onClick(() => {
|
||||
this.imageKnifeOption1 = {
|
||||
loadSrc: $r('app.media.gifSample'),
|
||||
size: { width: 300, height: 300 },
|
||||
size: { width: '300', height: '300' },
|
||||
placeholderSrc: $r('app.media.icon_loading'),
|
||||
errorholderSrc: $r('app.media.icon_failed'),
|
||||
margin: { left: 15, top: 15, right: 15, bottom: 15 }
|
||||
|
@ -48,7 +49,7 @@ struct TestGifDontAnimatePage {
|
|||
.onClick(()=>{
|
||||
this.imageKnifeOption1 = {
|
||||
loadSrc: $r('app.media.gifSample'),
|
||||
size: { width: 300, height: 300 },
|
||||
size: { width: '300', height: '300' },
|
||||
placeholderSrc: $r('app.media.icon_loading'),
|
||||
errorholderSrc: $r('app.media.icon_failed'),
|
||||
margin:{left:15,top:15,right:15,bottom:15},
|
||||
|
@ -63,7 +64,7 @@ struct TestGifDontAnimatePage {
|
|||
.onClick(()=>{
|
||||
this.imageKnifeOption1 = {
|
||||
loadSrc: 'https://pic.ibaotu.com/gif/18/17/16/51u888piCtqj.gif!fwpaa70/fw/700',
|
||||
size: { width: 300, height: 300 },
|
||||
size: { width: '300', height: '300' },
|
||||
placeholderSrc: $r('app.media.icon_loading'),
|
||||
errorholderSrc: $r('app.media.icon_failed'),
|
||||
margin:{left:15,top:15,right:15,bottom:15}
|
||||
|
@ -73,7 +74,7 @@ struct TestGifDontAnimatePage {
|
|||
.onClick(()=>{
|
||||
this.imageKnifeOption1 = {
|
||||
loadSrc: 'https://pic.ibaotu.com/gif/18/17/16/51u888piCtqj.gif!fwpaa70/fw/700',
|
||||
size: { width: 300, height: 300 },
|
||||
size: { width: '300', height: '300' },
|
||||
placeholderSrc: $r('app.media.icon_loading'),
|
||||
errorholderSrc: $r('app.media.icon_failed'),
|
||||
margin:{left:15,top:15,right:15,bottom:15},
|
||||
|
@ -91,8 +92,16 @@ struct TestGifDontAnimatePage {
|
|||
}
|
||||
|
||||
aboutToAppear() {
|
||||
console.log('aboutToAppear()')
|
||||
this.globalGifWorker = new ArkWorker.Worker('entry/ets/pages/workers/gifParseWorker.ts', {
|
||||
type: 'classic',
|
||||
name: 'ImageKnifeParseGIF'
|
||||
})
|
||||
globalThis.ImageKnife.setGifWorker(this.globalGifWorker)
|
||||
}
|
||||
aboutToDisappear(){
|
||||
if(this.globalGifWorker){
|
||||
this.globalGifWorker.terminate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var ImageKnife = globalThis.ImageKnife
|
|
@ -15,14 +15,17 @@
|
|||
import {ImageKnifeComponent} from '@ohos/imageknife'
|
||||
import {ImageKnifeOption} from '@ohos/imageknife'
|
||||
import {RotateImageTransformation} from '@ohos/imageknife'
|
||||
|
||||
import ArkWorker from '@ohos.worker'
|
||||
@Entry
|
||||
@Component
|
||||
struct TestImageKnifeOptionChangedPage {
|
||||
|
||||
private globalGifWorker:any = undefined
|
||||
|
||||
@State imageKnifeOption1: ImageKnifeOption =
|
||||
{
|
||||
loadSrc: $r('app.media.jpgSample'),
|
||||
size: { width: 300, height: 300 },
|
||||
size: { width: '300', height: '300' },
|
||||
placeholderSrc: $r('app.media.icon_loading'),
|
||||
errorholderSrc: $r('app.media.icon_failed'),
|
||||
margin:{left:5,top:5,right:5,bottom:5}
|
||||
|
@ -33,135 +36,146 @@ struct TestImageKnifeOptionChangedPage {
|
|||
Scroll() {
|
||||
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
||||
Flex({direction:FlexDirection.Row}){
|
||||
Button('本地资源jpg')
|
||||
Button('本地jpg')
|
||||
.onClick(()=>{
|
||||
this.imageKnifeOption1 = {
|
||||
loadSrc: $r('app.media.jpgSample'),
|
||||
size: { width: 300, height: 300 },
|
||||
size: { width: '300', height: '300' },
|
||||
placeholderSrc: $r('app.media.icon_loading'),
|
||||
errorholderSrc: $r('app.media.icon_failed'),
|
||||
margin:{left:5,top:5,right:5,bottom:5}
|
||||
};
|
||||
|
||||
}).margin({left:5}).backgroundColor(Color.Blue)
|
||||
Button('本地资源png')
|
||||
Button('png')
|
||||
.onClick(()=>{
|
||||
this.imageKnifeOption1 = {
|
||||
loadSrc: $r('app.media.pngSample'),
|
||||
size: { width: 300, height: 300 },
|
||||
size: { width: '300', height: '300' },
|
||||
placeholderSrc: $r('app.media.icon_loading'),
|
||||
errorholderSrc: $r('app.media.icon_failed'),
|
||||
margin:{left:5,top:5,right:5,bottom:5}
|
||||
};
|
||||
|
||||
}).margin({left:5}).backgroundColor(Color.Blue)
|
||||
Button('本地资源bmp')
|
||||
Button('bmp')
|
||||
.onClick(()=>{
|
||||
this.imageKnifeOption1 = {
|
||||
loadSrc: $r('app.media.bmpSample'),
|
||||
size: { width: 300, height: 300 },
|
||||
size: { width: '300', height: '300' },
|
||||
placeholderSrc: $r('app.media.icon_loading'),
|
||||
errorholderSrc: $r('app.media.icon_failed'),
|
||||
margin:{left:5,top:5,right:5,bottom:5}
|
||||
};
|
||||
|
||||
}).margin({left:5}).backgroundColor(Color.Blue)
|
||||
Button('本地资源webp')
|
||||
Button('webp')
|
||||
.onClick(()=>{
|
||||
this.imageKnifeOption1 = {
|
||||
loadSrc: $r('app.media.jpgSample'),
|
||||
size: { width: 300, height: 300 },
|
||||
size: { width: '300', height: '300' },
|
||||
placeholderSrc: $r('app.media.icon_loading'),
|
||||
errorholderSrc: $r('app.media.icon_failed'),
|
||||
margin:{left:5,top:5,right:5,bottom:5}
|
||||
};
|
||||
|
||||
}).margin({left:5}).backgroundColor(Color.Blue)
|
||||
Button('本地资源svg')
|
||||
Button('svg')
|
||||
.onClick(()=>{
|
||||
this.imageKnifeOption1 = {
|
||||
loadSrc: $r('app.media.svgSample'),
|
||||
size: { width: 300, height: 300 },
|
||||
size: { width: '300', height: '300' },
|
||||
placeholderSrc: $r('app.media.icon_loading'),
|
||||
errorholderSrc: $r('app.media.icon_failed'),
|
||||
margin:{left:5,top:5,right:5,bottom:5}
|
||||
};
|
||||
|
||||
}).margin({left:5}).backgroundColor(Color.Blue)
|
||||
Button('本地资源gif')
|
||||
Button('gif')
|
||||
.onClick(()=>{
|
||||
this.imageKnifeOption1 = {
|
||||
loadSrc: $r('app.media.gifSample'),
|
||||
size: { width: 300, height: 300 },
|
||||
size: { width: '300', height: '300' },
|
||||
placeholderSrc: $r('app.media.icon_loading'),
|
||||
errorholderSrc: $r('app.media.icon_failed'),
|
||||
margin:{left:5,top:5,right:5,bottom:5}
|
||||
};;
|
||||
};
|
||||
|
||||
}).margin({left:5}).backgroundColor(Color.Blue)
|
||||
}
|
||||
.margin({top:15})
|
||||
Flex({direction:FlexDirection.Row}){
|
||||
Button('网络资源jpg')
|
||||
Button('网络jpg')
|
||||
.onClick(()=>{
|
||||
this.imageKnifeOption1 = {
|
||||
loadSrc: 'https://hbimg.huabanimg.com/cc6af25f8d782d3cf3122bef4e61571378271145735e9-vEVggB',
|
||||
size: { width: 300, height: 300 },
|
||||
size: { width: '300', height: '300' },
|
||||
placeholderSrc: $r('app.media.icon_loading'),
|
||||
errorholderSrc: $r('app.media.icon_failed'),
|
||||
margin:{left:5,top:5,right:5,bottom:5}
|
||||
};
|
||||
}).margin({left:5}).backgroundColor(Color.Blue)
|
||||
Button('网络资源png')
|
||||
Button('png')
|
||||
.onClick(()=>{
|
||||
this.imageKnifeOption1 = {
|
||||
loadSrc: 'https://img-blog.csdnimg.cn/20191215043500229.png',
|
||||
size: { width: 300, height: 300 },
|
||||
size: { width: '300', height: '300' },
|
||||
placeholderSrc: $r('app.media.icon_loading'),
|
||||
errorholderSrc: $r('app.media.icon_failed'),
|
||||
margin:{left:5,top:5,right:5,bottom:5}
|
||||
};
|
||||
}).margin({left:5}).backgroundColor(Color.Blue)
|
||||
Button('网络资源bmp')
|
||||
Button('bmp')
|
||||
.onClick(()=>{
|
||||
this.imageKnifeOption1 = {
|
||||
loadSrc: 'https://img-blog.csdn.net/20140514114029140',
|
||||
size: { width: 300, height: 300 },
|
||||
size: { width: '300', height: '300' },
|
||||
placeholderSrc: $r('app.media.icon_loading'),
|
||||
errorholderSrc: $r('app.media.icon_failed'),
|
||||
margin:{left:5,top:5,right:5,bottom:5}
|
||||
};
|
||||
}).margin({left:5}).backgroundColor(Color.Blue)
|
||||
Button('网络资源webp')
|
||||
Button('webp')
|
||||
.onClick(()=>{
|
||||
this.imageKnifeOption1 = {
|
||||
loadSrc: 'https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp',
|
||||
size: { width: 300, height: 300 },
|
||||
size: { width: '300', height: '300' },
|
||||
placeholderSrc: $r('app.media.icon_loading'),
|
||||
errorholderSrc: $r('app.media.icon_failed'),
|
||||
margin:{left:5,top:5,right:5,bottom:5}
|
||||
};
|
||||
}).margin({left:5}).backgroundColor(Color.Blue)
|
||||
Button('网络资源svg')
|
||||
Button('svg')
|
||||
.onClick(()=>{
|
||||
this.imageKnifeOption1 = {
|
||||
loadSrc: 'http://design-svc.fat.lunz.cn/StaticFiles/BP9999999772/BV9999999422/SA9999998420/30df266a-485e-411e-b178-b9fb1d8e0748.svg',
|
||||
size: { width: 300, height: 300 },
|
||||
size: { width: '300', height: '300' },
|
||||
placeholderSrc: $r('app.media.icon_loading'),
|
||||
errorholderSrc: $r('app.media.icon_failed'),
|
||||
margin:{left:5,top:5,right:5,bottom:5}
|
||||
};
|
||||
}).margin({left:5}).backgroundColor(Color.Blue)
|
||||
Button('网络资源gif')
|
||||
Button('gif')
|
||||
.onClick(()=>{
|
||||
this.imageKnifeOption1 = {
|
||||
loadSrc: 'https://pic.ibaotu.com/gif/18/17/16/51u888piCtqj.gif!fwpaa70/fw/700',
|
||||
size: { width: 300, height: 300 },
|
||||
size: { width: '300', height: '300' },
|
||||
placeholderSrc: $r('app.media.icon_loading'),
|
||||
errorholderSrc: $r('app.media.icon_failed'),
|
||||
margin:{left:5,top:5,right:5,bottom:5}
|
||||
};
|
||||
}).margin({left:5}).backgroundColor(Color.Blue)
|
||||
|
||||
Button("dpg")
|
||||
.onClick(()=>{
|
||||
this.imageKnifeOption1 = {
|
||||
loadSrc: "https://img13.360buyimg.com/n1/jfs/t1/220646/38/10395/30916/61d6e061E1a6d91c8/c0a9a67e726dd7a4.jpg.dpg",
|
||||
size: { width: '300', height: '300' },
|
||||
placeholderSrc: $r('app.media.icon_loading'),
|
||||
errorholderSrc: $r('app.media.icon_failed'),
|
||||
margin:{left:5,top:5,right:5,bottom:5},
|
||||
};
|
||||
}).margin({left:5}).backgroundColor(Color.Blue)
|
||||
}
|
||||
.margin({top:15})
|
||||
|
||||
|
@ -178,7 +192,17 @@ struct TestImageKnifeOptionChangedPage {
|
|||
}
|
||||
|
||||
aboutToAppear() {
|
||||
console.log('aboutToAppear()')
|
||||
console.log("aboutToAppear()")
|
||||
this.globalGifWorker = new ArkWorker.Worker('entry/ets/pages/workers/gifParseWorker.ts', {
|
||||
type: 'classic',
|
||||
name: 'ImageKnifeParseGIF'
|
||||
})
|
||||
globalThis.ImageKnife.setGifWorker(this.globalGifWorker)
|
||||
}
|
||||
aboutToDisappear(){
|
||||
if(this.globalGifWorker){
|
||||
this.globalGifWorker.terminate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ struct TestImageKnifeOptionChangedPage2 {
|
|||
@State imageKnifeOption1: ImageKnifeOption =
|
||||
{
|
||||
loadSrc: $r('app.media.jpgSample'),
|
||||
size: { width: 300, height: 300 },
|
||||
size: { width: '300', height: '300' },
|
||||
placeholderSrc: $r('app.media.icon_loading'),
|
||||
errorholderSrc: $r('app.media.icon_failed'),
|
||||
margin:{left:5,top:5,right:5,bottom:5},
|
||||
|
@ -36,11 +36,11 @@ struct TestImageKnifeOptionChangedPage2 {
|
|||
Scroll() {
|
||||
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
||||
Flex({direction:FlexDirection.Row}){
|
||||
Button("网络资源jpg")
|
||||
Button("网络jpg")
|
||||
.onClick(()=>{
|
||||
this.imageKnifeOption1 = {
|
||||
loadSrc: "https://hbimg.huabanimg.com/cc6af25f8d782d3cf3122bef4e61571378271145735e9-vEVggB",
|
||||
size: { width: 300, height: 300 },
|
||||
size: { width: '300', height: '300' },
|
||||
placeholderSrc: $r('app.media.icon_loading'),
|
||||
errorholderSrc: $r('app.media.icon_failed'),
|
||||
margin:{left:5,top:5,right:5,bottom:5},
|
||||
|
@ -48,11 +48,11 @@ struct TestImageKnifeOptionChangedPage2 {
|
|||
transformation:new RotateImageTransformation(180)
|
||||
};
|
||||
}).margin({left:5}).backgroundColor(Color.Blue)
|
||||
Button("网络资源png")
|
||||
Button("png")
|
||||
.onClick(()=>{
|
||||
this.imageKnifeOption1 = {
|
||||
loadSrc: "https://img-blog.csdnimg.cn/20191215043500229.png",
|
||||
size: { width: 300, height: 300 },
|
||||
size: { width: '300', height: '300' },
|
||||
placeholderSrc: $r('app.media.icon_loading'),
|
||||
errorholderSrc: $r('app.media.icon_failed'),
|
||||
margin:{left:5,top:5,right:5,bottom:5},
|
||||
|
@ -60,11 +60,11 @@ struct TestImageKnifeOptionChangedPage2 {
|
|||
transformations:[new RotateImageTransformation(180)]
|
||||
};
|
||||
}).margin({left:5}).backgroundColor(Color.Blue)
|
||||
Button("网络资源bmp")
|
||||
Button("bmp")
|
||||
.onClick(()=>{
|
||||
this.imageKnifeOption1 = {
|
||||
loadSrc: "https://img-blog.csdn.net/20140514114029140",
|
||||
size: { width: 300, height: 300 },
|
||||
size: { width: '300', height: '300' },
|
||||
placeholderSrc: $r('app.media.icon_loading'),
|
||||
errorholderSrc: $r('app.media.icon_failed'),
|
||||
margin:{left:5,top:5,right:5,bottom:5},
|
||||
|
@ -72,11 +72,11 @@ struct TestImageKnifeOptionChangedPage2 {
|
|||
transformations:[new GrayscaleTransformation()]
|
||||
};
|
||||
}).margin({left:5}).backgroundColor(Color.Blue)
|
||||
Button("网络资源webp")
|
||||
Button("webp")
|
||||
.onClick(()=>{
|
||||
this.imageKnifeOption1 = {
|
||||
loadSrc: "https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp",
|
||||
size: { width: 300, height: 300 },
|
||||
size: { width: '300', height: '300' },
|
||||
placeholderSrc: $r('app.media.icon_loading'),
|
||||
errorholderSrc: $r('app.media.icon_failed'),
|
||||
margin:{left:5,top:5,right:5,bottom:5},
|
||||
|
|
|
@ -0,0 +1,257 @@
|
|||
/*
|
||||
* Copyright (C) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import {ImageKnifeComponent} from '@ohos/imageknife'
|
||||
import {ImageKnifeOption} from '@ohos/imageknife'
|
||||
import {ScaleType} from '@ohos/imageknife'
|
||||
import {RotateImageTransformation} from '@ohos/imageknife'
|
||||
import {GrayscaleTransformation} from '@ohos/imageknife'
|
||||
import {SketchFilterTransformation} from '@ohos/imageknife'
|
||||
import ArkWorker from '@ohos.worker'
|
||||
@Entry
|
||||
@Component
|
||||
struct TestImageKnifeOptionChangedPage3 {
|
||||
private globalGifWorker:any = undefined
|
||||
@State imageKnifeOption1: ImageKnifeOption =
|
||||
{
|
||||
loadSrc: $r('app.media.jpgSample'),
|
||||
mainScaleType: ScaleType.FIT_CENTER,
|
||||
size: { width: '300', height: '300' },
|
||||
placeholderSrc: $r('app.media.icon_loading'),
|
||||
errorholderSrc: $r('app.media.icon_failed'),
|
||||
};
|
||||
|
||||
|
||||
build() {
|
||||
Scroll() {
|
||||
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
||||
Flex({direction:FlexDirection.Row}){
|
||||
Button("本地jpg")
|
||||
.onClick(()=>{
|
||||
this.imageKnifeOption1 = {
|
||||
loadSrc: $r('app.media.jpgSample'),
|
||||
mainScaleType: ScaleType.FIT_CENTER,
|
||||
size: { width: '350', height: '350' },
|
||||
placeholderSrc: $r('app.media.icon_loading'),
|
||||
errorholderSrc: $r('app.media.icon_failed'),
|
||||
margin:{left:5,top:5,right:5,bottom:5},
|
||||
thumbSizeMultiplier:0.1,
|
||||
transformation:new RotateImageTransformation(180),
|
||||
sizeAnimate: {
|
||||
duration: 500,
|
||||
curve: Curve.EaseInOut,
|
||||
delay: 100,
|
||||
iterations: 1,
|
||||
playMode:PlayMode.Normal,
|
||||
onFinish:()=>{
|
||||
console.log('play end!')
|
||||
}
|
||||
}
|
||||
};
|
||||
}).margin({left:5}).backgroundColor(Color.Blue)
|
||||
Button("本地png")
|
||||
.onClick(()=>{
|
||||
this.imageKnifeOption1 = {
|
||||
loadSrc: $r('app.media.pngSample'),
|
||||
mainScaleType: ScaleType.FIT_CENTER,
|
||||
size: { width: '300', height: '300' },
|
||||
placeholderSrc: $r('app.media.icon_loading'),
|
||||
errorholderSrc: $r('app.media.icon_failed'),
|
||||
margin:{left:5,top:5,right:5,bottom:5},
|
||||
thumbSizeMultiplier:0.1,
|
||||
transformation:new RotateImageTransformation(180),
|
||||
sizeAnimate: {
|
||||
duration: 500,
|
||||
curve: Curve.EaseInOut,
|
||||
delay: 100,
|
||||
iterations: 1,
|
||||
playMode: PlayMode.Normal,
|
||||
onFinish: () => {
|
||||
console.log('play end!')
|
||||
}
|
||||
}
|
||||
};
|
||||
}).margin({left:5}).backgroundColor(Color.Blue)
|
||||
}.margin({top:15})
|
||||
Flex({direction:FlexDirection.Row}){
|
||||
Button("本地bmp")
|
||||
.onClick(()=>{
|
||||
this.imageKnifeOption1 = {
|
||||
loadSrc: $r('app.media.bmpSample'),
|
||||
mainScaleType: ScaleType.FIT_CENTER,
|
||||
size: { width: '100', height: '300' },
|
||||
placeholderSrc: $r('app.media.icon_loading'),
|
||||
errorholderSrc: $r('app.media.icon_failed'),
|
||||
margin:{left:5,top:5,right:5,bottom:5},
|
||||
thumbSizeMultiplier:0.1,
|
||||
transformations:[new GrayscaleTransformation()],
|
||||
sizeAnimate: {
|
||||
duration: 500,
|
||||
curve: Curve.EaseInOut,
|
||||
delay: 100,
|
||||
iterations: 1,
|
||||
playMode: PlayMode.Normal,
|
||||
onFinish: () => {
|
||||
console.log('play end!')
|
||||
}
|
||||
}
|
||||
};
|
||||
}).margin({left:5}).backgroundColor(Color.Blue)
|
||||
Button("本地webp")
|
||||
.onClick(()=>{
|
||||
this.imageKnifeOption1 = {
|
||||
loadSrc: $r('app.media.webpSample'),
|
||||
mainScaleType: ScaleType.FIT_CENTER,
|
||||
size: { width: '300', height: '100' },
|
||||
placeholderSrc: $r('app.media.icon_loading'),
|
||||
errorholderSrc: $r('app.media.icon_failed'),
|
||||
margin:{left:5,top:5,right:5,bottom:5},
|
||||
thumbSizeMultiplier:0.1,
|
||||
transformations:[new SketchFilterTransformation()],
|
||||
sizeAnimate: {
|
||||
duration: 500,
|
||||
curve: Curve.EaseInOut,
|
||||
delay: 100,
|
||||
iterations: 1,
|
||||
playMode: PlayMode.Normal,
|
||||
onFinish: () => {
|
||||
console.log('play end!')
|
||||
}
|
||||
}
|
||||
};
|
||||
}).margin({left:5}).backgroundColor(Color.Blue)
|
||||
}.margin({top:15})
|
||||
Flex({direction:FlexDirection.Row}){
|
||||
Button("网络jpg")
|
||||
.onClick(()=>{
|
||||
this.imageKnifeOption1 = {
|
||||
loadSrc: "https://hbimg.huabanimg.com/cc6af25f8d782d3cf3122bef4e61571378271145735e9-vEVggB",
|
||||
size: { width: '200', height: '200' },
|
||||
placeholderSrc: $r('app.media.icon_loading'),
|
||||
errorholderSrc: $r('app.media.icon_failed'),
|
||||
margin:{left:5,top:5,right:5,bottom:5},
|
||||
displayProgress:true,
|
||||
sizeAnimate: {
|
||||
duration: 500,
|
||||
curve: Curve.EaseInOut,
|
||||
delay: 100,
|
||||
iterations: 1,
|
||||
playMode: PlayMode.Normal,
|
||||
onFinish: () => {
|
||||
console.log('play end!')
|
||||
}
|
||||
},
|
||||
thumbSizeMultiplier:0.1,
|
||||
transformation:new RotateImageTransformation(180)
|
||||
};
|
||||
}).margin({left:5}).backgroundColor(Color.Blue)
|
||||
Button("网络png")
|
||||
.onClick(()=>{
|
||||
this.imageKnifeOption1 = {
|
||||
loadSrc: "https://img-blog.csdnimg.cn/20191215043500229.png",
|
||||
size: { width: '300', height: '300' },
|
||||
placeholderSrc: $r('app.media.icon_loading'),
|
||||
errorholderSrc: $r('app.media.icon_failed'),
|
||||
margin:{left:5,top:5,right:5,bottom:5},
|
||||
displayProgress:true,
|
||||
thumbSizeMultiplier:0.1,
|
||||
sizeAnimate: {
|
||||
duration: 500,
|
||||
curve: Curve.EaseInOut,
|
||||
delay: 100,
|
||||
iterations: 1,
|
||||
playMode: PlayMode.Normal,
|
||||
onFinish: () => {
|
||||
console.log('play end!')
|
||||
}
|
||||
},
|
||||
transformations:[new RotateImageTransformation(180)]
|
||||
};
|
||||
}).margin({left:5}).backgroundColor(Color.Blue)
|
||||
}.margin({top:15})
|
||||
Flex({direction:FlexDirection.Row}){
|
||||
Button("网络bmp")
|
||||
.onClick(()=>{
|
||||
this.imageKnifeOption1 = {
|
||||
loadSrc: "https://img-blog.csdn.net/20140514114029140",
|
||||
size: { width: '400', height: '400' },
|
||||
placeholderSrc: $r('app.media.icon_loading'),
|
||||
errorholderSrc: $r('app.media.icon_failed'),
|
||||
margin:{left:5,top:5,right:5,bottom:5},
|
||||
displayProgress:true,
|
||||
thumbSizeMultiplier:0.1,
|
||||
sizeAnimate: {
|
||||
duration: 500,
|
||||
curve: Curve.EaseInOut,
|
||||
delay: 100,
|
||||
iterations: 1,
|
||||
playMode: PlayMode.Normal,
|
||||
onFinish: () => {
|
||||
console.log('play end!')
|
||||
}
|
||||
},
|
||||
transformations:[new GrayscaleTransformation()]
|
||||
};
|
||||
}).margin({left:5}).backgroundColor(Color.Blue)
|
||||
Button("网络webp")
|
||||
.onClick(()=>{
|
||||
this.imageKnifeOption1 = {
|
||||
loadSrc: "https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp",
|
||||
size: { width: '500', height: '500' },
|
||||
placeholderSrc: $r('app.media.icon_loading'),
|
||||
errorholderSrc: $r('app.media.icon_failed'),
|
||||
margin:{left:5,top:5,right:5,bottom:5},
|
||||
displayProgress:true,
|
||||
thumbSizeMultiplier:0.1,
|
||||
sizeAnimate: {
|
||||
duration: 500,
|
||||
curve: Curve.EaseInOut,
|
||||
delay: 100,
|
||||
iterations: 1,
|
||||
playMode: PlayMode.Normal,
|
||||
onFinish: () => {
|
||||
console.log('play end!')
|
||||
}
|
||||
},
|
||||
};
|
||||
}).margin({left:5}).backgroundColor(Color.Blue)
|
||||
}.margin({top:15})
|
||||
|
||||
Text("下面为展示图片区域").margin({top:5})
|
||||
Flex({direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }){
|
||||
ImageKnifeComponent({ imageKnifeOption: $imageKnifeOption1 })
|
||||
}.width(400).height(400).margin({top:10}).backgroundColor(Color.Pink)
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
.width('100%')
|
||||
.height('100%')
|
||||
}
|
||||
aboutToAppear() {
|
||||
console.log("aboutToAppear()")
|
||||
this.globalGifWorker = new ArkWorker.Worker('entry/ets/pages/workers/gifParseWorker.ts', {
|
||||
type: 'classic',
|
||||
name: 'ImageKnifeParseGIF'
|
||||
})
|
||||
globalThis.ImageKnife.setGifWorker(this.globalGifWorker)
|
||||
}
|
||||
aboutToDisappear(){
|
||||
if(this.globalGifWorker){
|
||||
this.globalGifWorker.terminate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,255 @@
|
|||
/*
|
||||
* Copyright (C) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import {
|
||||
GrayscaleTransformation,
|
||||
ImageKnifeComponent,
|
||||
ImageKnifeData,
|
||||
ImageKnifeOption,
|
||||
RotateImageTransformation,
|
||||
SketchFilterTransformation,
|
||||
ScaleTypeHelper,
|
||||
IDrawLifeCycle,
|
||||
ScaleType
|
||||
} from '@ohos/imageknife'
|
||||
import ArkWorker from '@ohos.worker'
|
||||
@Entry
|
||||
@Component
|
||||
struct TestImageKnifeOptionChangedPage4 {
|
||||
private globalGifWorker:any = undefined
|
||||
@State imageKnifeOption1: ImageKnifeOption =
|
||||
{
|
||||
loadSrc: $r('app.media.jpgSample'),
|
||||
size: { width: '300', height: '300' },
|
||||
placeholderSrc: $r('app.media.icon_loading'),
|
||||
errorholderSrc: $r('app.media.icon_failed'),
|
||||
margin: { left: 5, top: 5, right: 5, bottom: 5 },
|
||||
thumbSizeMultiplier: 0.1,
|
||||
drawLifeCycle:this.createViewLifeCycle()
|
||||
};
|
||||
private mTimerId: number = 0
|
||||
|
||||
build() {
|
||||
Scroll() {
|
||||
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
||||
Flex({ direction: FlexDirection.Row }) {
|
||||
Button("网络jpg")
|
||||
.onClick(() => {
|
||||
this.imageKnifeOption1 = {
|
||||
loadSrc: "https://hbimg.huabanimg.com/cc6af25f8d782d3cf3122bef4e61571378271145735e9-vEVggB",
|
||||
size: { width: '300', height: '300' },
|
||||
placeholderSrc: $r('app.media.icon_loading'),
|
||||
errorholderSrc: $r('app.media.icon_failed'),
|
||||
margin: { left: 5, top: 5, right: 5, bottom: 5 },
|
||||
thumbSizeMultiplier: 0.1,
|
||||
transformation: new RotateImageTransformation(180),
|
||||
drawLifeCycle:this.createViewLifeCycle()
|
||||
};
|
||||
}).margin({ left: 5 }).backgroundColor(Color.Blue)
|
||||
Button("网络png")
|
||||
.onClick(() => {
|
||||
this.imageKnifeOption1 = {
|
||||
loadSrc: "https://img-blog.csdnimg.cn/20191215043500229.png",
|
||||
size: { width: '300', height: '300' },
|
||||
placeholderSrc: $r('app.media.icon_loading'),
|
||||
errorholderSrc: $r('app.media.icon_failed'),
|
||||
margin: { left: 5, top: 5, right: 5, bottom: 5 },
|
||||
thumbSizeMultiplier: 0.1,
|
||||
transformations: [new RotateImageTransformation(180)],
|
||||
drawLifeCycle:this.createViewLifeCycle()
|
||||
};
|
||||
}).margin({ left: 5 }).backgroundColor(Color.Blue)
|
||||
}.margin({ top: 15 })
|
||||
Flex({ direction: FlexDirection.Row }) {
|
||||
Button("网络bmp")
|
||||
.onClick(() => {
|
||||
this.imageKnifeOption1 = {
|
||||
loadSrc: "https://img-blog.csdn.net/20140514114029140",
|
||||
size: { width: '300', height: '300' },
|
||||
placeholderSrc: $r('app.media.icon_loading'),
|
||||
errorholderSrc: $r('app.media.icon_failed'),
|
||||
margin: { left: 5, top: 5, right: 5, bottom: 5 },
|
||||
thumbSizeMultiplier: 0.1,
|
||||
transformations: [new GrayscaleTransformation()],
|
||||
drawLifeCycle:this.createViewLifeCycle()
|
||||
};
|
||||
}).margin({ left: 5 }).backgroundColor(Color.Blue)
|
||||
Button("网络webp")
|
||||
.onClick(() => {
|
||||
this.imageKnifeOption1 = {
|
||||
loadSrc: "https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp",
|
||||
size: { width: '300', height: '300' },
|
||||
placeholderSrc: $r('app.media.icon_loading'),
|
||||
errorholderSrc: $r('app.media.icon_failed'),
|
||||
margin: { left: 5, top: 5, right: 5, bottom: 5 },
|
||||
thumbSizeMultiplier: 0.1,
|
||||
transformations: [new SketchFilterTransformation()],
|
||||
drawLifeCycle:this.createViewLifeCycle()
|
||||
};
|
||||
}).margin({ left: 5 }).backgroundColor(Color.Blue)
|
||||
}.margin({ top: 15 })
|
||||
|
||||
Text("下面为展示图片区域").margin({ top: 5 })
|
||||
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
||||
ImageKnifeComponent({ imageKnifeOption: $imageKnifeOption1 })
|
||||
}.width(400).height(400).margin({ top: 10 }).backgroundColor(Color.Pink)
|
||||
|
||||
}
|
||||
}
|
||||
.width('100%')
|
||||
.height('100%')
|
||||
}
|
||||
|
||||
aboutToAppear() {
|
||||
console.log("aboutToAppear()")
|
||||
this.globalGifWorker = new ArkWorker.Worker('entry/ets/pages/workers/gifParseWorker.ts', {
|
||||
type: 'classic',
|
||||
name: 'ImageKnifeParseGIF'
|
||||
})
|
||||
globalThis.ImageKnife.setGifWorker(this.globalGifWorker)
|
||||
}
|
||||
aboutToDisappear(){
|
||||
if(this.globalGifWorker){
|
||||
this.globalGifWorker.terminate();
|
||||
}
|
||||
}
|
||||
|
||||
drawMainAnimate(index, context, scaleType, imagePixelMap, widthPixel, heightPixel, compWidth, compHeight) {
|
||||
console.log('drawMainAnimate index = '+index)
|
||||
|
||||
let clipScale = (index / 30.0)
|
||||
context.save()
|
||||
context.beginPath();
|
||||
let path2d = new Path2D()
|
||||
let maxRadius = Math.sqrt(compWidth / 2 * compWidth / 2 + compHeight / 2 * compHeight / 2)
|
||||
path2d.arc(compWidth / 2, compHeight / 2, maxRadius * clipScale, 0, Math.PI * 2)
|
||||
context.clip(path2d)
|
||||
context.save()
|
||||
ScaleTypeHelper.drawImageWithScaleType(context, scaleType, imagePixelMap, px2vp(widthPixel), px2vp(heightPixel), compWidth, compHeight,0,0)
|
||||
context.restore();
|
||||
context.restore();
|
||||
if(index<30){
|
||||
index++
|
||||
let nextFunc = this.drawMainAnimate.bind(this,index, context, scaleType, imagePixelMap, widthPixel, heightPixel, compWidth, compHeight)
|
||||
this.mTimerId = setTimeout(nextFunc, 1000/30.0)
|
||||
}else{
|
||||
// 不做处理
|
||||
}
|
||||
}
|
||||
private stopAnimate(){
|
||||
if(this.mTimerId > 0){
|
||||
clearTimeout(this.mTimerId)
|
||||
this.mTimerId = 0
|
||||
}else{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private createViewLifeCycle(): IDrawLifeCycle {
|
||||
let viewLifeCycle: IDrawLifeCycle = {
|
||||
// 展示占位图
|
||||
displayPlaceholder: (context: CanvasRenderingContext2D, data: ImageKnifeData, imageKnifeOption: ImageKnifeOption, compWidth: number, compHeight: number, setGifTimeId?: (timeId: number) => void) => {
|
||||
// @ts-ignore
|
||||
this.stopAnimate()
|
||||
return false;
|
||||
},
|
||||
// 展示加载进度
|
||||
displayProgress: (context: CanvasRenderingContext2D, progress: number, imageKnifeOption: ImageKnifeOption, compWidth: number, compHeight: number, setGifTimeId?: (timeId: number) => void) => {
|
||||
// @ts-ignore
|
||||
this.stopAnimate()
|
||||
context.save();
|
||||
context.clearRect(0,0,compWidth,compHeight)
|
||||
let pi = Math.PI * 2 / 100; //pi 讲圆的周长划分为100份
|
||||
let rate = progress - 25;
|
||||
let diameter = compWidth > compHeight ? compHeight : compWidth
|
||||
context.lineWidth = Math.floor(diameter * 0.03)
|
||||
context.lineCap = "round"
|
||||
context.fillStyle = "white"
|
||||
context.font = Math.floor(diameter * 0.5) + 'px'
|
||||
let x0 = (compWidth - diameter) / 2.0 + Math.floor(diameter * 0.5)
|
||||
let y0 = (compHeight - diameter) / 2.0 + Math.floor(diameter * 0.1)
|
||||
let x1 = (compWidth - diameter) / 2.0 + Math.floor(diameter * 0.5)
|
||||
let y1 = (compHeight - diameter) / 2.0 + Math.floor(diameter * 0.8)
|
||||
let gradient = context.createLinearGradient(x0, y0, x1, y1)
|
||||
gradient.addColorStop(0, "#11ffe4")
|
||||
gradient.addColorStop(0.5, "#03c6fd")
|
||||
gradient.addColorStop(1, "#10a5ff")
|
||||
context.clearRect(0, 0, compWidth, compHeight)
|
||||
context.shadowBlur = 0
|
||||
context.beginPath()
|
||||
context.strokeStyle = "#15222d"
|
||||
let radius = Math.floor(diameter * 0.3)
|
||||
let arcX = compWidth / 2.0
|
||||
let arcY = compHeight / 2.0
|
||||
context.arc(arcX, arcY, radius, 0, Math.PI * 2, true)
|
||||
context.stroke()
|
||||
context.beginPath()
|
||||
let showText = rate + 25 + '%'
|
||||
let metrics = context.measureText(showText)
|
||||
let textX = (compWidth / 2.0) - metrics.width / 2.0
|
||||
let textY = (compHeight / 2.0) + metrics.height * 0.3
|
||||
context.fillText(showText, textX, textY)
|
||||
context.stroke()
|
||||
context.beginPath()
|
||||
context.strokeStyle = gradient
|
||||
context.arc(arcX, arcY, radius, pi * -25, pi * rate)
|
||||
context.stroke();
|
||||
context.restore();
|
||||
return true;
|
||||
},
|
||||
// 展示缩略图
|
||||
displayThumbSizeMultiplier: (context: CanvasRenderingContext2D, data: ImageKnifeData, imageKnifeOption: ImageKnifeOption, compWidth: number, compHeight: number, setGifTimeId?: (timeId: number) => void) => {
|
||||
// @ts-ignore
|
||||
this.stopAnimate()
|
||||
return false;
|
||||
},
|
||||
|
||||
// 展示主图
|
||||
displayMainSource: (context: CanvasRenderingContext2D, data: ImageKnifeData, imageKnifeOption: ImageKnifeOption, compWidth: number, compHeight: number, setGifTimeId?: (timeId: number) => void) => {
|
||||
this.stopAnimate()
|
||||
if (data.isPixelMap()) {
|
||||
// @ts-ignore
|
||||
data.drawPixelMap.imagePixelMap.getImageInfo().then((imageInfo) => {
|
||||
let scaleType = (typeof imageKnifeOption.mainScaleType == 'number') ? imageKnifeOption.mainScaleType : ScaleType.FIT_CENTER
|
||||
console.log('imageinfo width =' + imageInfo.size.width + ' height=' + imageInfo.size.height + 'scaleType=' + scaleType)
|
||||
|
||||
let func = this.drawMainAnimate.bind(this,0, context, scaleType, data.drawPixelMap.imagePixelMap, imageInfo.size.width, imageInfo.size.height, compWidth, compHeight)
|
||||
this.mTimerId = setTimeout(func, 1000/30.0)
|
||||
|
||||
console.log('TestImageKnifeOptionChangedPage4 drawMainSource end!')
|
||||
})
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
// 展示重试图层
|
||||
displayRetryholder: (context: CanvasRenderingContext2D, data: ImageKnifeData, imageKnifeOption: ImageKnifeOption, compWidth: number, compHeight: number, setGifTimeId?: (timeId: number) => void) => {
|
||||
// @ts-ignore
|
||||
this.stopAnimate()
|
||||
return false;
|
||||
},
|
||||
|
||||
// 展示失败占位图
|
||||
displayErrorholder: (context: CanvasRenderingContext2D, data: ImageKnifeData, imageKnifeOption: ImageKnifeOption, compWidth: number, compHeight: number, setGifTimeId?: (timeId: number) => void) => {
|
||||
// @ts-ignore
|
||||
this.stopAnimate()
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return viewLifeCycle;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,187 @@
|
|||
/*
|
||||
* Copyright (C) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import {
|
||||
GrayscaleTransformation,
|
||||
ImageKnifeComponent,
|
||||
ImageKnifeData,
|
||||
ImageKnifeOption,
|
||||
RotateImageTransformation,
|
||||
SketchFilterTransformation,
|
||||
ScaleTypeHelper,
|
||||
IDrawLifeCycle,
|
||||
ScaleType,
|
||||
ImageKnifeDrawFactory
|
||||
} from '@ohos/imageknife'
|
||||
import ArkWorker from '@ohos.worker'
|
||||
@Entry
|
||||
@Component
|
||||
struct TestImageKnifeOptionChangedPage5 {
|
||||
private globalGifWorker:any = undefined
|
||||
@State imageKnifeOption1: ImageKnifeOption =
|
||||
{
|
||||
loadSrc: $r('app.media.jpgSample'),
|
||||
size: { width: '300', height: '300' },
|
||||
placeholderSrc: $r('app.media.icon_loading'),
|
||||
errorholderSrc: $r('app.media.icon_failed'),
|
||||
drawLifeCycle:this.choiceViewLifeCycle(DrawType.Oval)
|
||||
};
|
||||
private mTimerId: number = 0
|
||||
|
||||
build() {
|
||||
Scroll() {
|
||||
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
||||
Flex({ direction: FlexDirection.Row }) {
|
||||
Button("网络jpg")
|
||||
.onClick(() => {
|
||||
this.imageKnifeOption1 = {
|
||||
loadSrc: "https://hbimg.huabanimg.com/cc6af25f8d782d3cf3122bef4e61571378271145735e9-vEVggB",
|
||||
size: { width: '300', height: '300' },
|
||||
placeholderSrc: $r('app.media.icon_loading'),
|
||||
errorholderSrc: $r('app.media.icon_failed'),
|
||||
drawLifeCycle:this.choiceViewLifeCycle(DrawType.Oval)
|
||||
};
|
||||
}).margin({ left: 5 }).backgroundColor(Color.Blue)
|
||||
Button("网络png")
|
||||
.onClick(() => {
|
||||
this.imageKnifeOption1 = {
|
||||
loadSrc: "https://img-blog.csdnimg.cn/20191215043500229.png",
|
||||
size: { width: '300', height: '300' },
|
||||
placeholderSrc: $r('app.media.icon_loading'),
|
||||
errorholderSrc: $r('app.media.icon_failed'),
|
||||
drawLifeCycle:this.choiceViewLifeCycle(DrawType.Oval)
|
||||
};
|
||||
}).margin({ left: 5 }).backgroundColor(Color.Blue)
|
||||
}.margin({ top: 15 })
|
||||
Flex({ direction: FlexDirection.Row }) {
|
||||
Button("网络bmp")
|
||||
.onClick(() => {
|
||||
this.imageKnifeOption1 = {
|
||||
loadSrc: "https://img-blog.csdn.net/20140514114029140",
|
||||
size: { width: '300', height: '300' },
|
||||
placeholderSrc: $r('app.media.icon_loading'),
|
||||
errorholderSrc: $r('app.media.icon_failed'),
|
||||
drawLifeCycle:this.choiceViewLifeCycle(DrawType.Oval)
|
||||
};
|
||||
}).margin({ left: 5 }).backgroundColor(Color.Blue)
|
||||
Button("网络webp")
|
||||
.onClick(() => {
|
||||
this.imageKnifeOption1 = {
|
||||
loadSrc: "https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp",
|
||||
size: { width: '300', height: '300' },
|
||||
placeholderSrc: $r('app.media.icon_loading'),
|
||||
errorholderSrc: $r('app.media.icon_failed'),
|
||||
drawLifeCycle:this.choiceViewLifeCycle(DrawType.Oval)
|
||||
};
|
||||
}).margin({ left: 5 }).backgroundColor(Color.Blue)
|
||||
}.margin({ top: 15 })
|
||||
|
||||
Text("下面为展示图片区域").margin({ top: 5 })
|
||||
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
||||
ImageKnifeComponent({ imageKnifeOption: $imageKnifeOption1 })
|
||||
}.width(400).height(400).margin({ top: 10 }).backgroundColor(Color.Pink)
|
||||
|
||||
}
|
||||
}
|
||||
.width('100%')
|
||||
.height('100%')
|
||||
}
|
||||
|
||||
aboutToAppear() {
|
||||
console.log("aboutToAppear()")
|
||||
this.globalGifWorker = new ArkWorker.Worker('entry/ets/pages/workers/gifParseWorker.ts', {
|
||||
type: 'classic',
|
||||
name: 'ImageKnifeParseGIF'
|
||||
})
|
||||
globalThis.ImageKnife.setGifWorker(this.globalGifWorker)
|
||||
}
|
||||
aboutToDisappear(){
|
||||
if(this.globalGifWorker){
|
||||
this.globalGifWorker.terminate();
|
||||
}
|
||||
}
|
||||
|
||||
private choiceViewLifeCycle(type:DrawType): IDrawLifeCycle {
|
||||
let viewLifeCycle = undefined;
|
||||
switch(type){
|
||||
case DrawType.Oval:
|
||||
viewLifeCycle = ImageKnifeDrawFactory.createOvalLifeCycle(5,"#ff00ff")
|
||||
break;
|
||||
case DrawType.Round:
|
||||
viewLifeCycle = ImageKnifeDrawFactory.createRoundLifeCycle(5,"#ff00ff",30)
|
||||
break;
|
||||
case DrawType.Normal:
|
||||
default:
|
||||
viewLifeCycle = {
|
||||
// 展示占位图
|
||||
displayPlaceholder: (context: CanvasRenderingContext2D, data: ImageKnifeData, imageKnifeOption: ImageKnifeOption, compWidth: number, compHeight: number, setGifTimeId?: (timeId: number) => void) => {
|
||||
// @ts-ignore
|
||||
return false;
|
||||
},
|
||||
// 展示加载进度
|
||||
displayProgress: (context: CanvasRenderingContext2D, progress: number, imageKnifeOption: ImageKnifeOption, compWidth: number, compHeight: number, setGifTimeId?: (timeId: number) => void) => {
|
||||
return false;
|
||||
},
|
||||
// 展示缩略图
|
||||
displayThumbSizeMultiplier: (context: CanvasRenderingContext2D, data: ImageKnifeData, imageKnifeOption: ImageKnifeOption, compWidth: number, compHeight: number, setGifTimeId?: (timeId: number) => void) => {
|
||||
// @ts-ignore
|
||||
return false;
|
||||
},
|
||||
|
||||
// 展示主图
|
||||
displayMainSource: (context: CanvasRenderingContext2D, data: ImageKnifeData, imageKnifeOption: ImageKnifeOption, compWidth: number, compHeight: number, setGifTimeId?: (timeId: number) => void) => {
|
||||
if (data.isPixelMap()) {
|
||||
// @ts-ignore
|
||||
data.drawPixelMap.imagePixelMap.getImageInfo().then((imageInfo) => {
|
||||
let scaleType = (typeof imageKnifeOption.mainScaleType == 'number') ? imageKnifeOption.mainScaleType : ScaleType.FIT_CENTER
|
||||
console.log('imageinfo width =' + imageInfo.size.width + ' height=' + imageInfo.size.height + 'scaleType=' + scaleType)
|
||||
context.save();
|
||||
context.clearRect(0, 0, compWidth, compHeight)
|
||||
ScaleTypeHelper.drawImageWithScaleType(context, scaleType, data.drawPixelMap.imagePixelMap, px2vp(imageInfo.size.width), px2vp(imageInfo.size.height), compWidth, compHeight,0,0)
|
||||
context.restore();
|
||||
console.log('TestImageKnifeOptionChangedPage4 drawMainSource end!')
|
||||
})
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
// 展示重试图层
|
||||
displayRetryholder: (context: CanvasRenderingContext2D, data: ImageKnifeData, imageKnifeOption: ImageKnifeOption, compWidth: number, compHeight: number, setGifTimeId?: (timeId: number) => void) => {
|
||||
return false;
|
||||
},
|
||||
// 展示失败占位图
|
||||
displayErrorholder: (context: CanvasRenderingContext2D, data: ImageKnifeData, imageKnifeOption: ImageKnifeOption, compWidth: number, compHeight: number, setGifTimeId?: (timeId: number) => void) => {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
return viewLifeCycle;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
export enum DrawType{
|
||||
|
||||
Normal = 0,
|
||||
|
||||
Oval = 1,
|
||||
|
||||
Round = 2
|
||||
|
||||
}
|
||||
|
|
@ -1,77 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import ArkWorker from '@ohos.worker'
|
||||
|
||||
@Entry
|
||||
@Component
|
||||
struct TestMultiThreadWorkerPage2 {
|
||||
build() {
|
||||
Scroll() {
|
||||
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
||||
Button("创建Worker向子线程发送携带Arraybuffer数据")
|
||||
.margin({ top: 20 })
|
||||
.onClick(() => {
|
||||
let worker = new ArkWorker.Worker("entry/ets/pages/workers/worker1.js", {
|
||||
type: "classic",
|
||||
name: "zhangsan"
|
||||
})
|
||||
worker.onerror = function (data) {
|
||||
console.info("worker:: receive onerror " + data.lineno + ", msg = " + data.message + ", filename = " + data.filename + ", colno = " + data.colno);
|
||||
}
|
||||
|
||||
worker.onmessageerror = function (e) {
|
||||
console.log("worker:: receive onmessageerror ");
|
||||
}
|
||||
|
||||
worker.onexit = function () {
|
||||
console.log("worker:: receive onexit");
|
||||
}
|
||||
|
||||
worker.onmessage = function (e) {
|
||||
var data = e.data;
|
||||
switch (data.type) {
|
||||
case "normal":
|
||||
console.log("worker:: onmessage " + data.data);
|
||||
break;
|
||||
case "buffer":
|
||||
console.log("worker:: receive buffer length is " + data.data.byteLength);
|
||||
break;
|
||||
default:
|
||||
console.log("worker:: worker.js receive unknow type");
|
||||
break
|
||||
}
|
||||
worker.terminate();
|
||||
}
|
||||
|
||||
console.log("worker:: start post buffer");
|
||||
|
||||
let uint8array = new Uint8Array([0, 1, 2, 3, 4, 5, 6, 7])
|
||||
let buffer = uint8array.buffer.slice(uint8array.byteOffset, uint8array.byteLength + uint8array.byteOffset)
|
||||
|
||||
var obj = { type: "buffer", data: buffer };
|
||||
console.log("worker:: before post, buffer length is " + obj.data.byteLength);
|
||||
worker.postMessage(obj, [buffer]);
|
||||
console.log("worker:: after post, buffer length is " + obj.data.byteLength);
|
||||
console.info("end post buffer");
|
||||
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
.width('100%')
|
||||
.height('100%')
|
||||
}
|
||||
}
|
|
@ -15,23 +15,24 @@
|
|||
import {ImageKnifeComponent} from '@ohos/imageknife'
|
||||
import {ImageKnifeOption} from '@ohos/imageknife'
|
||||
import {RequestOption} from '@ohos/imageknife'
|
||||
|
||||
import ArkWorker from '@ohos.worker'
|
||||
|
||||
@Entry
|
||||
@Component
|
||||
struct TestPreloadPage {
|
||||
private globalGifWorker:any = undefined
|
||||
@State imageKnifeOption1: ImageKnifeOption =
|
||||
{
|
||||
loadSrc: $r('app.media.jpgSample'),
|
||||
size: { width: 300, height: 300 },
|
||||
size: { width: '300', height: '300' },
|
||||
placeholderSrc: $r('app.media.icon_loading'),
|
||||
errorholderSrc: $r('app.media.icon_failed'),
|
||||
margin: { left: 15, top: 15, right: 15, bottom: 15 }
|
||||
};
|
||||
@State imageKnifeOption2: ImageKnifeOption =
|
||||
@State ImageKnifeOption: ImageKnifeOption =
|
||||
{
|
||||
loadSrc: $r('app.media.jpgSample'),
|
||||
size: { width: 300, height: 300 },
|
||||
size: { width: '300', height: '300' },
|
||||
placeholderSrc: $r('app.media.icon_loading'),
|
||||
errorholderSrc: $r('app.media.icon_failed'),
|
||||
margin: { left: 15, top: 15, right: 15, bottom: 15 }
|
||||
|
@ -39,7 +40,7 @@ struct TestPreloadPage {
|
|||
@State imageKnifeOption3: ImageKnifeOption =
|
||||
{
|
||||
loadSrc: $r('app.media.jpgSample'),
|
||||
size: { width: 300, height: 300 },
|
||||
size: { width: '300', height: '300' },
|
||||
placeholderSrc: $r('app.media.icon_loading'),
|
||||
errorholderSrc: $r('app.media.icon_failed'),
|
||||
margin: { left: 15, top: 15, right: 15, bottom: 15 }
|
||||
|
@ -48,7 +49,7 @@ struct TestPreloadPage {
|
|||
@State imageKnifeOption4: ImageKnifeOption =
|
||||
{
|
||||
loadSrc: $r('app.media.jpgSample'),
|
||||
size: { width: 300, height: 300 },
|
||||
size: { width: '300', height: '300' },
|
||||
placeholderSrc: $r('app.media.icon_loading'),
|
||||
errorholderSrc: $r('app.media.icon_failed'),
|
||||
margin: { left: 15, top: 15, right: 15, bottom: 15 }
|
||||
|
@ -56,7 +57,7 @@ struct TestPreloadPage {
|
|||
@State imageKnifeOption5: ImageKnifeOption =
|
||||
{
|
||||
loadSrc: $r('app.media.jpgSample'),
|
||||
size: { width: 300, height: 300 },
|
||||
size: { width: '300', height: '300' },
|
||||
placeholderSrc: $r('app.media.icon_loading'),
|
||||
errorholderSrc: $r('app.media.icon_failed'),
|
||||
margin: { left: 15, top: 15, right: 15, bottom: 15 }
|
||||
|
@ -64,7 +65,7 @@ struct TestPreloadPage {
|
|||
@State imageKnifeOption6: ImageKnifeOption =
|
||||
{
|
||||
loadSrc: $r('app.media.jpgSample'),
|
||||
size: { width: 300, height: 300 },
|
||||
size: { width: '300', height: '300' },
|
||||
placeholderSrc: $r('app.media.icon_loading'),
|
||||
errorholderSrc: $r('app.media.icon_failed'),
|
||||
margin: { left: 15, top: 15, right: 15, bottom: 15 }
|
||||
|
@ -88,7 +89,7 @@ struct TestPreloadPage {
|
|||
}
|
||||
return false;
|
||||
})
|
||||
ImageKnife.preload(request);
|
||||
globalThis.ImageKnife.preload(request);
|
||||
})
|
||||
.margin({ left: 15 })
|
||||
.backgroundColor(Color.Grey)
|
||||
|
@ -98,7 +99,7 @@ struct TestPreloadPage {
|
|||
.onClick(() => {
|
||||
this.imageKnifeOption1 = {
|
||||
loadSrc: $r('app.media.gifSample'),
|
||||
size: { width: 300, height: 300 },
|
||||
size: { width: '300', height: '300' },
|
||||
placeholderSrc: $r('app.media.icon_loading'),
|
||||
errorholderSrc: $r('app.media.icon_failed'),
|
||||
margin: { left: 15, top: 15, right: 15, bottom: 15 }
|
||||
|
@ -122,7 +123,7 @@ struct TestPreloadPage {
|
|||
}
|
||||
return false;
|
||||
})
|
||||
ImageKnife.preload(request);
|
||||
globalThis.ImageKnife.preload(request);
|
||||
})
|
||||
.margin({ left: 15 })
|
||||
.backgroundColor(Color.Grey)
|
||||
|
@ -131,7 +132,7 @@ struct TestPreloadPage {
|
|||
.onClick(() => {
|
||||
this.imageKnifeOption1 = {
|
||||
loadSrc: $r('app.media.gifSample'),
|
||||
size: { width: 300, height: 300 },
|
||||
size: { width: '300', height: '300' },
|
||||
placeholderSrc: $r('app.media.icon_loading'),
|
||||
errorholderSrc: $r('app.media.icon_failed'),
|
||||
margin: { left: 15, top: 15, right: 15, bottom: 15 },
|
||||
|
@ -159,7 +160,7 @@ struct TestPreloadPage {
|
|||
}
|
||||
return false;
|
||||
})
|
||||
ImageKnife.preload(request);
|
||||
globalThis.ImageKnife.preload(request);
|
||||
})
|
||||
.margin({ left: 15 })
|
||||
.backgroundColor(Color.Grey)
|
||||
|
@ -168,7 +169,7 @@ struct TestPreloadPage {
|
|||
.onClick(() => {
|
||||
this.imageKnifeOption1 = {
|
||||
loadSrc: 'https://pic.ibaotu.com/gif/18/17/16/51u888piCtqj.gif!fwpaa70/fw/700',
|
||||
size: { width: 300, height: 300 },
|
||||
size: { width: '300', height: '300' },
|
||||
placeholderSrc: $r('app.media.icon_loading'),
|
||||
errorholderSrc: $r('app.media.icon_failed'),
|
||||
margin: { left: 15, top: 15, right: 15, bottom: 15 }
|
||||
|
@ -191,7 +192,7 @@ struct TestPreloadPage {
|
|||
}
|
||||
return false;
|
||||
})
|
||||
ImageKnife.preload(request);
|
||||
globalThis.ImageKnife.preload(request);
|
||||
})
|
||||
.margin({ left: 15 })
|
||||
.backgroundColor(Color.Grey)
|
||||
|
@ -200,7 +201,7 @@ struct TestPreloadPage {
|
|||
.onClick(() => {
|
||||
this.imageKnifeOption1 = {
|
||||
loadSrc: 'https://pic.ibaotu.com/gif/18/17/16/51u888piCtqj.gif!fwpaa70/fw/700',
|
||||
size: { width: 300, height: 300 },
|
||||
size: { width: '300', height: '300' },
|
||||
placeholderSrc: $r('app.media.icon_loading'),
|
||||
errorholderSrc: $r('app.media.icon_failed'),
|
||||
margin: { left: 15, top: 15, right: 15, bottom: 15 },
|
||||
|
@ -231,7 +232,7 @@ struct TestPreloadPage {
|
|||
}
|
||||
return false;
|
||||
})
|
||||
ImageKnife.preload(request);
|
||||
globalThis.ImageKnife.preload(request);
|
||||
})
|
||||
.margin({ left: 15 })
|
||||
.backgroundColor(Color.Grey)
|
||||
|
@ -239,9 +240,9 @@ struct TestPreloadPage {
|
|||
|
||||
Button('本地资源svg')
|
||||
.onClick(() => {
|
||||
this.imageKnifeOption2 = {
|
||||
this.ImageKnifeOption = {
|
||||
loadSrc: $r('app.media.svgSample'),
|
||||
size: { width: 300, height: 300 },
|
||||
size: { width: '300', height: '300' },
|
||||
placeholderSrc: $r('app.media.icon_loading'),
|
||||
errorholderSrc: $r('app.media.icon_failed'),
|
||||
margin: { left: 15, top: 15, right: 15, bottom: 15 }
|
||||
|
@ -270,16 +271,16 @@ struct TestPreloadPage {
|
|||
}
|
||||
return false;
|
||||
})
|
||||
ImageKnife.preload(request);
|
||||
globalThis.ImageKnife.preload(request);
|
||||
})
|
||||
.margin({ left: 15 })
|
||||
.backgroundColor(Color.Grey)
|
||||
|
||||
Button('网络资源svg')
|
||||
.onClick(() => {
|
||||
this.imageKnifeOption2 = {
|
||||
this.ImageKnifeOption = {
|
||||
loadSrc: 'http://design-svc.fat.lunz.cn/StaticFiles/BP9999999772/BV9999999422/SA9999998420/4dc8463e-8ac6-4eb4-862c-783bf486a242.svg',
|
||||
size: { width: 300, height: 300 },
|
||||
size: { width: '300', height: '300' },
|
||||
placeholderSrc: $r('app.media.icon_loading'),
|
||||
errorholderSrc: $r('app.media.icon_failed'),
|
||||
margin: { left: 15, top: 15, right: 15, bottom: 15 }
|
||||
|
@ -292,7 +293,7 @@ struct TestPreloadPage {
|
|||
}
|
||||
.margin({ top: 15 })
|
||||
|
||||
ImageKnifeComponent({ imageKnifeOption: $imageKnifeOption2 })
|
||||
ImageKnifeComponent({ imageKnifeOption: $ImageKnifeOption })
|
||||
|
||||
}
|
||||
|
||||
|
@ -311,7 +312,7 @@ struct TestPreloadPage {
|
|||
}
|
||||
return false;
|
||||
})
|
||||
ImageKnife.preload(request);
|
||||
globalThis.ImageKnife.preload(request);
|
||||
})
|
||||
.margin({ left: 15 })
|
||||
.backgroundColor(Color.Grey)
|
||||
|
@ -321,7 +322,7 @@ struct TestPreloadPage {
|
|||
.onClick(() => {
|
||||
this.imageKnifeOption3 = {
|
||||
loadSrc: $r('app.media.jpgSample'),
|
||||
size: { width: 300, height: 300 },
|
||||
size: { width: '300', height: '300' },
|
||||
placeholderSrc: $r('app.media.icon_loading'),
|
||||
errorholderSrc: $r('app.media.icon_failed'),
|
||||
margin: { left: 15, top: 15, right: 15, bottom: 15 }
|
||||
|
@ -350,7 +351,7 @@ struct TestPreloadPage {
|
|||
}
|
||||
return false;
|
||||
})
|
||||
ImageKnife.preload(request);
|
||||
globalThis.ImageKnife.preload(request);
|
||||
})
|
||||
.margin({ left: 15 })
|
||||
.backgroundColor(Color.Grey)
|
||||
|
@ -359,7 +360,7 @@ struct TestPreloadPage {
|
|||
.onClick(() => {
|
||||
this.imageKnifeOption3 = {
|
||||
loadSrc: 'https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp',
|
||||
size: { width: 300, height: 300 },
|
||||
size: { width: '300', height: '300' },
|
||||
placeholderSrc: $r('app.media.icon_loading'),
|
||||
errorholderSrc: $r('app.media.icon_failed'),
|
||||
margin: { left: 15, top: 15, right: 15, bottom: 15 }
|
||||
|
@ -389,7 +390,7 @@ struct TestPreloadPage {
|
|||
}
|
||||
return false;
|
||||
})
|
||||
ImageKnife.preload(request);
|
||||
globalThis.ImageKnife.preload(request);
|
||||
})
|
||||
.margin({ left: 15 })
|
||||
.backgroundColor(Color.Grey)
|
||||
|
@ -399,7 +400,7 @@ struct TestPreloadPage {
|
|||
.onClick(() => {
|
||||
this.imageKnifeOption4 = {
|
||||
loadSrc: $r('app.media.bmpSample'),
|
||||
size: { width: 300, height: 300 },
|
||||
size: { width: '300', height: '300' },
|
||||
placeholderSrc: $r('app.media.icon_loading'),
|
||||
errorholderSrc: $r('app.media.icon_failed'),
|
||||
margin: { left: 15, top: 15, right: 15, bottom: 15 }
|
||||
|
@ -428,7 +429,7 @@ struct TestPreloadPage {
|
|||
}
|
||||
return false;
|
||||
})
|
||||
ImageKnife.preload(request);
|
||||
globalThis.ImageKnife.preload(request);
|
||||
})
|
||||
.margin({ left: 15 })
|
||||
.backgroundColor(Color.Grey)
|
||||
|
@ -437,7 +438,7 @@ struct TestPreloadPage {
|
|||
.onClick(() => {
|
||||
this.imageKnifeOption4 = {
|
||||
loadSrc: 'https://img-blog.csdn.net/20140514114029140',
|
||||
size: { width: 300, height: 300 },
|
||||
size: { width: '300', height: '300' },
|
||||
placeholderSrc: $r('app.media.icon_loading'),
|
||||
errorholderSrc: $r('app.media.icon_failed'),
|
||||
margin: { left: 15, top: 15, right: 15, bottom: 15 }
|
||||
|
@ -467,7 +468,7 @@ struct TestPreloadPage {
|
|||
}
|
||||
return false;
|
||||
})
|
||||
ImageKnife.preload(request);
|
||||
globalThis.ImageKnife.preload(request);
|
||||
})
|
||||
.margin({ left: 15 })
|
||||
.backgroundColor(Color.Grey)
|
||||
|
@ -477,7 +478,7 @@ struct TestPreloadPage {
|
|||
.onClick(() => {
|
||||
this.imageKnifeOption5 = {
|
||||
loadSrc: $r('app.media.pngSample'),
|
||||
size: { width: 300, height: 300 },
|
||||
size: { width: '300', height: '300' },
|
||||
placeholderSrc: $r('app.media.icon_loading'),
|
||||
errorholderSrc: $r('app.media.icon_failed'),
|
||||
margin: { left: 15, top: 15, right: 15, bottom: 15 }
|
||||
|
@ -506,7 +507,7 @@ struct TestPreloadPage {
|
|||
}
|
||||
return false;
|
||||
})
|
||||
ImageKnife.preload(request);
|
||||
globalThis.ImageKnife.preload(request);
|
||||
})
|
||||
.margin({ left: 15 })
|
||||
.backgroundColor(Color.Grey)
|
||||
|
@ -515,7 +516,7 @@ struct TestPreloadPage {
|
|||
.onClick(() => {
|
||||
this.imageKnifeOption5 = {
|
||||
loadSrc: 'https://img-blog.csdnimg.cn/20191215043500229.png',
|
||||
size: { width: 300, height: 300 },
|
||||
size: { width: '300', height: '300' },
|
||||
placeholderSrc: $r('app.media.icon_loading'),
|
||||
errorholderSrc: $r('app.media.icon_failed'),
|
||||
margin: { left: 15, top: 15, right: 15, bottom: 15 }
|
||||
|
@ -545,7 +546,7 @@ struct TestPreloadPage {
|
|||
}
|
||||
return false;
|
||||
})
|
||||
ImageKnife.preload(request);
|
||||
globalThis.ImageKnife.preload(request);
|
||||
})
|
||||
.margin({ left: 15 })
|
||||
.backgroundColor(Color.Grey)
|
||||
|
@ -555,7 +556,7 @@ struct TestPreloadPage {
|
|||
.onClick(() => {
|
||||
this.imageKnifeOption6 = {
|
||||
loadSrc: $r('app.media.jpgSample'),
|
||||
size: { width: 300, height: 300 },
|
||||
size: { width: '300', height: '300' },
|
||||
placeholderSrc: $r('app.media.icon_loading'),
|
||||
errorholderSrc: $r('app.media.icon_failed'),
|
||||
margin: { left: 15, top: 15, right: 15, bottom: 15 }
|
||||
|
@ -584,7 +585,7 @@ struct TestPreloadPage {
|
|||
}
|
||||
return false;
|
||||
})
|
||||
ImageKnife.preload(request);
|
||||
globalThis.ImageKnife.preload(request);
|
||||
})
|
||||
.margin({ left: 15 })
|
||||
.backgroundColor(Color.Grey)
|
||||
|
@ -593,7 +594,7 @@ struct TestPreloadPage {
|
|||
.onClick(() => {
|
||||
this.imageKnifeOption6 = {
|
||||
loadSrc: 'https://hbimg.huabanimg.com/cc6af25f8d782d3cf3122bef4e61571378271145735e9-vEVggB',
|
||||
size: { width: 300, height: 300 },
|
||||
size: { width: '300', height: '300' },
|
||||
placeholderSrc: $r('app.media.icon_loading'),
|
||||
errorholderSrc: $r('app.media.icon_failed'),
|
||||
margin: { left: 15, top: 15, right: 15, bottom: 15 }
|
||||
|
@ -616,9 +617,18 @@ struct TestPreloadPage {
|
|||
}
|
||||
|
||||
aboutToAppear() {
|
||||
console.log('aboutToAppear()')
|
||||
this.globalGifWorker = new ArkWorker.Worker('entry/ets/pages/workers/gifParseWorker.ts', {
|
||||
type: 'classic',
|
||||
name: 'ImageKnifeParseGIF'
|
||||
})
|
||||
// gif解析在子线程,请在页面构建后创建worker,注入imageknife
|
||||
globalThis.ImageKnife.setGifWorker(this.globalGifWorker)
|
||||
}
|
||||
aboutToDisappear(){
|
||||
if(this.globalGifWorker){
|
||||
this.globalGifWorker.terminate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var ImageKnife = globalThis.ImageKnife
|
|
@ -1,87 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import {RequestOption} from '@ohos/imageknife'
|
||||
import{NONE} from '@ohos/imageknife'
|
||||
import {Base64} from '@ohos/imageknife'
|
||||
import {FileTypeUtil} from '@ohos/imageknife'
|
||||
import {ImageKnifeData} from '@ohos/imageknife'
|
||||
|
||||
import resourceManager from '@ohos.resourceManager';
|
||||
@Entry
|
||||
@Component
|
||||
struct TestResourceManagerPage {
|
||||
|
||||
@State imageKnifeData: ImageKnifeData = new ImageKnifeData();
|
||||
|
||||
|
||||
build() {
|
||||
Scroll() {
|
||||
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
||||
Text(this.imageKnifeData.imageKnifeType)
|
||||
.fontSize(20)
|
||||
.backgroundColor(Color.Pink)
|
||||
.width(300)
|
||||
.height(300)
|
||||
Button("点击执行ResourceManager的Base64")
|
||||
.onClick(()=>{
|
||||
globalThis.ImageKnife.getImageKnifeContext().resourceManager.getMediaBase64($r('app.media.jpgSample').id)
|
||||
.then(data => {
|
||||
console.log("jpgSample data=" + data)
|
||||
let matchUseLess = ";base64,";
|
||||
var matchUseLessIndex = data.indexOf(matchUseLess)
|
||||
data = data.substring(matchUseLessIndex + matchUseLess.length, data.length)
|
||||
console.log("jpgSample prepare save data=" + data)
|
||||
let arrayBuffer = Base64.getInstance().decode(data);
|
||||
console.log("arrayBuffer data=" + arrayBuffer)
|
||||
let fileTypeUtil = new FileTypeUtil();
|
||||
let typeValue = fileTypeUtil.getFileType(arrayBuffer);
|
||||
console.log("typeValue data=" + typeValue)
|
||||
let newImageKnifeData = new ImageKnifeData();
|
||||
newImageKnifeData.imageKnifeType = typeValue
|
||||
|
||||
this.imageKnifeData = newImageKnifeData;
|
||||
})
|
||||
})
|
||||
Button("点击执行ResourceManager的非Base64")
|
||||
.margin({top:25})
|
||||
.onClick(()=>{
|
||||
globalThis.ImageKnife.getImageKnifeContext().resourceManager.getMedia($r('app.media.pngSample').id)
|
||||
.then(data => {
|
||||
console.log("arrayBuffer data=" + data)
|
||||
let fileTypeUtil = new FileTypeUtil();
|
||||
let typeValue = fileTypeUtil.getFileType(this.typedArrayToBuffer(data));
|
||||
console.log("typeValue data=" + typeValue)
|
||||
let newImageKnifeData = new ImageKnifeData();
|
||||
newImageKnifeData.imageKnifeType = typeValue
|
||||
this.imageKnifeData = newImageKnifeData;
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
.width('100%')
|
||||
.height('100%')
|
||||
}
|
||||
|
||||
aboutToAppear() {
|
||||
console.log("aboutToAppear()")
|
||||
}
|
||||
|
||||
typedArrayToBuffer(array: Uint8Array): ArrayBuffer {
|
||||
return array.buffer.slice(array.byteOffset, array.byteLength + array.byteOffset)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
var ImageKnife = globalThis.exports.default.data.imageKnife
|
|
@ -32,7 +32,7 @@ import {BlurTransformation} from '@ohos/imageknife'
|
|||
import {PixelationFilterTransformation} from '@ohos/imageknife'
|
||||
import {MaskTransformation} from '@ohos/imageknife'
|
||||
import {SwirlFilterTransformation} from '@ohos/imageknife'
|
||||
import {PixelMapPack} from '@ohos/imageknife'
|
||||
|
||||
|
||||
/**
|
||||
* PixelMap transform 示例
|
||||
|
@ -45,25 +45,25 @@ let mUrl = $r('app.media.pngSample');
|
|||
@Component
|
||||
struct TransformPixelMapPage {
|
||||
@State url: string= "";
|
||||
@State mCropPixelMap: PixelMapPack= new PixelMapPack();
|
||||
@State mRoundPixelMap: PixelMapPack= new PixelMapPack();
|
||||
@State mCirclePixelMap: PixelMapPack= new PixelMapPack();
|
||||
@State mCircleBorderPixelMap: PixelMapPack= new PixelMapPack();
|
||||
@State mRotatePixelMap: PixelMapPack= new PixelMapPack();
|
||||
@State mSquarePixelMap: PixelMapPack= new PixelMapPack();
|
||||
@State mClipTopPixelMap: PixelMapPack= new PixelMapPack();
|
||||
@State mClipCenterPixelMap: PixelMapPack= new PixelMapPack();
|
||||
@State mClipBottomPixelMap: PixelMapPack= new PixelMapPack();
|
||||
@State mGrayscalePixelMap: PixelMapPack= new PixelMapPack();
|
||||
@State mBrightnessPixelMap: PixelMapPack= new PixelMapPack();
|
||||
@State mContrastPixelMap: PixelMapPack= new PixelMapPack();
|
||||
@State mInvertPixelMap: PixelMapPack= new PixelMapPack();
|
||||
@State mSepiaPixelMap: PixelMapPack= new PixelMapPack();
|
||||
@State mSketchPixelMap: PixelMapPack= new PixelMapPack();
|
||||
@State mBlurPixelMap: PixelMapPack= new PixelMapPack();
|
||||
@State mPixelPixelMap: PixelMapPack= new PixelMapPack();
|
||||
@State mSwirlPixelMap: PixelMapPack= new PixelMapPack();
|
||||
@State mMaskPixelMap: PixelMapPack= new PixelMapPack();
|
||||
@State mCropPixelMap: PixelMap= undefined;
|
||||
@State mRoundPixelMap: PixelMap= undefined;
|
||||
@State mCirclePixelMap: PixelMap= undefined;
|
||||
@State mCircleBorderPixelMap: PixelMap= undefined;
|
||||
@State mRotatePixelMap: PixelMap= undefined;
|
||||
@State mSquarePixelMap: PixelMap= undefined;
|
||||
@State mClipTopPixelMap: PixelMap= undefined;
|
||||
@State mClipCenterPixelMap: PixelMap= undefined;
|
||||
@State mClipBottomPixelMap: PixelMap= undefined;
|
||||
@State mGrayscalePixelMap: PixelMap= undefined;
|
||||
@State mBrightnessPixelMap: PixelMap= undefined;
|
||||
@State mContrastPixelMap: PixelMap= undefined;
|
||||
@State mInvertPixelMap: PixelMap= undefined;
|
||||
@State mSepiaPixelMap: PixelMap= undefined;
|
||||
@State mSketchPixelMap: PixelMap= undefined;
|
||||
@State mBlurPixelMap: PixelMap= undefined;
|
||||
@State mPixelPixelMap: PixelMap= undefined;
|
||||
@State mSwirlPixelMap: PixelMap= undefined;
|
||||
@State mMaskPixelMap: PixelMap= undefined;
|
||||
|
||||
build() {
|
||||
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center }) {
|
||||
|
@ -98,7 +98,7 @@ struct TransformPixelMapPage {
|
|||
});
|
||||
}.margin({ top: 10 })
|
||||
|
||||
Image(this.mCropPixelMap.pixelMap)
|
||||
Image(this.mCropPixelMap )
|
||||
.objectFit(ImageFit.None)
|
||||
.width(100)
|
||||
.height(100)
|
||||
|
@ -151,7 +151,7 @@ struct TransformPixelMapPage {
|
|||
});
|
||||
}.margin({ top: 10 })
|
||||
|
||||
Image(this.mRoundPixelMap.pixelMap)
|
||||
Image(this.mRoundPixelMap )
|
||||
.objectFit(ImageFit.Fill)
|
||||
.width(100)
|
||||
.height(100)
|
||||
|
@ -170,7 +170,7 @@ struct TransformPixelMapPage {
|
|||
.onClick(() => {
|
||||
this.circleTransformation();
|
||||
});
|
||||
Image(this.mCirclePixelMap.pixelMap)
|
||||
Image(this.mCirclePixelMap )
|
||||
.width(200)
|
||||
.height(200)
|
||||
.margin({ top: 10 })
|
||||
|
@ -188,7 +188,7 @@ struct TransformPixelMapPage {
|
|||
.onClick(() => {
|
||||
this.circleBorderTransformation(5);
|
||||
});
|
||||
Image(this.mCircleBorderPixelMap.pixelMap)
|
||||
Image(this.mCircleBorderPixelMap )
|
||||
.width(200)
|
||||
.height(200)
|
||||
.margin({ top: 10 })
|
||||
|
@ -210,7 +210,7 @@ struct TransformPixelMapPage {
|
|||
}
|
||||
this.transformRotate(mRotate);
|
||||
});
|
||||
Image(this.mRotatePixelMap.pixelMap)
|
||||
Image(this.mRotatePixelMap )
|
||||
.width(200)
|
||||
.height(200)
|
||||
.margin({ top: 10 })
|
||||
|
@ -228,7 +228,7 @@ struct TransformPixelMapPage {
|
|||
.onClick(() => {
|
||||
this.transformSquare();
|
||||
});
|
||||
Image(this.mSquarePixelMap.pixelMap)
|
||||
Image(this.mSquarePixelMap )
|
||||
.objectFit(ImageFit.Fill)
|
||||
.width(200)
|
||||
.height(200)
|
||||
|
@ -266,17 +266,17 @@ struct TransformPixelMapPage {
|
|||
}.margin({ top: 10 })
|
||||
|
||||
Row({ space: 1 }) {
|
||||
Image(this.mClipTopPixelMap.pixelMap)
|
||||
Image(this.mClipTopPixelMap )
|
||||
.objectFit(ImageFit.Fill)
|
||||
.width(100)
|
||||
.height(100)
|
||||
.margin({ top: 10 })
|
||||
Image(this.mClipCenterPixelMap.pixelMap)
|
||||
Image(this.mClipCenterPixelMap )
|
||||
.objectFit(ImageFit.Fill)
|
||||
.width(100)
|
||||
.height(100)
|
||||
.margin({ top: 10 })
|
||||
Image(this.mClipBottomPixelMap.pixelMap)
|
||||
Image(this.mClipBottomPixelMap )
|
||||
.objectFit(ImageFit.Fill)
|
||||
.width(100)
|
||||
.height(100)
|
||||
|
@ -295,7 +295,7 @@ struct TransformPixelMapPage {
|
|||
.onClick(() => {
|
||||
this.grayscalePixelMap();
|
||||
});
|
||||
Image(this.mGrayscalePixelMap.pixelMap)
|
||||
Image(this.mGrayscalePixelMap )
|
||||
.objectFit(ImageFit.Fill)
|
||||
.width(200)
|
||||
.height(200)
|
||||
|
@ -313,7 +313,7 @@ struct TransformPixelMapPage {
|
|||
.onClick(() => {
|
||||
this.brightnessPixelMap(0.8);
|
||||
});
|
||||
Image(this.mBrightnessPixelMap.pixelMap)
|
||||
Image(this.mBrightnessPixelMap )
|
||||
.objectFit(ImageFit.Fill)
|
||||
.width(200)
|
||||
.height(200)
|
||||
|
@ -331,7 +331,7 @@ struct TransformPixelMapPage {
|
|||
.onClick(() => {
|
||||
this.contrastPixelMap(4);
|
||||
});
|
||||
Image(this.mContrastPixelMap.pixelMap)
|
||||
Image(this.mContrastPixelMap )
|
||||
.objectFit(ImageFit.Fill)
|
||||
.width(200)
|
||||
.height(200)
|
||||
|
@ -349,7 +349,7 @@ struct TransformPixelMapPage {
|
|||
.onClick(() => {
|
||||
this.invertPixelMap();
|
||||
});
|
||||
Image(this.mInvertPixelMap.pixelMap)
|
||||
Image(this.mInvertPixelMap )
|
||||
.objectFit(ImageFit.Fill)
|
||||
.width(200)
|
||||
.height(200)
|
||||
|
@ -368,7 +368,7 @@ struct TransformPixelMapPage {
|
|||
.onClick(() => {
|
||||
this.sepiaPixelMap();
|
||||
});
|
||||
Image(this.mSepiaPixelMap.pixelMap)
|
||||
Image(this.mSepiaPixelMap )
|
||||
.objectFit(ImageFit.Fill)
|
||||
.width(200)
|
||||
.height(200)
|
||||
|
@ -386,7 +386,7 @@ struct TransformPixelMapPage {
|
|||
.onClick(() => {
|
||||
this.sketchPixelMap();
|
||||
});
|
||||
Image(this.mSketchPixelMap.pixelMap)
|
||||
Image(this.mSketchPixelMap )
|
||||
.objectFit(ImageFit.Fill)
|
||||
.width(200)
|
||||
.height(200)
|
||||
|
@ -405,7 +405,7 @@ struct TransformPixelMapPage {
|
|||
.onClick(() => {
|
||||
this.blurHandlePixelMap(20);
|
||||
});
|
||||
Image(this.mBlurPixelMap.pixelMap)
|
||||
Image(this.mBlurPixelMap )
|
||||
.objectFit(ImageFit.Fill)
|
||||
.width(200)
|
||||
.height(200)
|
||||
|
@ -425,7 +425,7 @@ struct TransformPixelMapPage {
|
|||
.onClick(() => {
|
||||
this.pixelHandlePixelMap(20);
|
||||
});
|
||||
Image(this.mPixelPixelMap.pixelMap)
|
||||
Image(this.mPixelPixelMap )
|
||||
.objectFit(ImageFit.Fill)
|
||||
.width(200)
|
||||
.height(200)
|
||||
|
@ -444,7 +444,7 @@ struct TransformPixelMapPage {
|
|||
.onClick(() => {
|
||||
this.swirlHandlePixelMap();
|
||||
});
|
||||
Image(this.mSwirlPixelMap.pixelMap)
|
||||
Image(this.mSwirlPixelMap )
|
||||
.objectFit(ImageFit.Fill)
|
||||
.width(200)
|
||||
.height(200)
|
||||
|
@ -463,7 +463,7 @@ struct TransformPixelMapPage {
|
|||
.onClick(() => {
|
||||
this.maskHandlePixelMap($r('app.media.mask_starfish'));
|
||||
});
|
||||
Image(this.mMaskPixelMap.pixelMap)
|
||||
Image(this.mMaskPixelMap )
|
||||
.objectFit(ImageFit.Fill)
|
||||
.width(200)
|
||||
.height(200)
|
||||
|
@ -489,11 +489,11 @@ struct TransformPixelMapPage {
|
|||
imageKnifeOption.load($r('app.media.jpgSample'))
|
||||
// imageKnifeOption.load(mUrl)
|
||||
.addListener((err, data) => {
|
||||
let result = new PixelMapPack();
|
||||
let result = undefined;
|
||||
this.mCropPixelMap = result;
|
||||
setTimeout(() => {
|
||||
let result2 = new PixelMapPack();
|
||||
result2.pixelMap = data.imageKnifeValue as PixelMap;
|
||||
let result2 = undefined;
|
||||
result2 = data.drawPixelMap.imagePixelMap as PixelMap;
|
||||
this.mCropPixelMap = result2;
|
||||
}, 100)
|
||||
return false;
|
||||
|
@ -511,11 +511,11 @@ struct TransformPixelMapPage {
|
|||
var imageKnifeOption = new RequestOption();
|
||||
imageKnifeOption.load($r('app.media.Back'))
|
||||
.addListener((err, data) => {
|
||||
let result = new PixelMapPack();
|
||||
let result = undefined;
|
||||
this.mCropPixelMap = result;
|
||||
setTimeout(() => {
|
||||
let result2 = new PixelMapPack();
|
||||
result2.pixelMap = data.imageKnifeValue as PixelMap;
|
||||
let result2 = undefined;
|
||||
result2 = data.drawPixelMap.imagePixelMap as PixelMap;
|
||||
this.mCropPixelMap = result2;
|
||||
}, 100)
|
||||
return false;
|
||||
|
@ -533,11 +533,11 @@ struct TransformPixelMapPage {
|
|||
var imageKnifeOption = new RequestOption()
|
||||
imageKnifeOption.load($r('app.media.Back'))
|
||||
.addListener((err, data) => {
|
||||
let result = new PixelMapPack();
|
||||
let result = undefined;
|
||||
this.mCropPixelMap = result;
|
||||
setTimeout(() => {
|
||||
let result2 = new PixelMapPack();
|
||||
result2.pixelMap = data.imageKnifeValue as PixelMap;
|
||||
let result2 = undefined;
|
||||
result2 = data.drawPixelMap.imagePixelMap as PixelMap;
|
||||
this.mCropPixelMap = result2;
|
||||
}, 100)
|
||||
return false;
|
||||
|
@ -556,11 +556,11 @@ struct TransformPixelMapPage {
|
|||
var imageKnifeOption = new RequestOption();
|
||||
imageKnifeOption.load(mUrl)
|
||||
.addListener((err, data) => {
|
||||
let result = new PixelMapPack();
|
||||
let result = undefined;
|
||||
this.mRoundPixelMap = result;
|
||||
setTimeout(() => {
|
||||
let result2 = new PixelMapPack();
|
||||
result2.pixelMap = data.imageKnifeValue as PixelMap;
|
||||
let result2 = undefined;
|
||||
result2 = data.drawPixelMap.imagePixelMap as PixelMap;
|
||||
this.mRoundPixelMap = result2;
|
||||
}, 100)
|
||||
return false;
|
||||
|
@ -578,8 +578,8 @@ struct TransformPixelMapPage {
|
|||
let imageKnifeOption = new RequestOption();
|
||||
imageKnifeOption.load(mUrl)
|
||||
.addListener((err, data) => {
|
||||
let result = new PixelMapPack();
|
||||
result.pixelMap = data.imageKnifeValue as PixelMap;
|
||||
let result = undefined;
|
||||
result = data.drawPixelMap.imagePixelMap as PixelMap;
|
||||
this.mCirclePixelMap = result;
|
||||
return false;
|
||||
})
|
||||
|
@ -598,8 +598,8 @@ struct TransformPixelMapPage {
|
|||
{ r_color: 255, g_color: 204, b_color: 204 });
|
||||
imageKnifeOption.load(mUrl)
|
||||
.addListener((err, data) => {
|
||||
let result = new PixelMapPack();
|
||||
result.pixelMap = data.imageKnifeValue as PixelMap;
|
||||
let result = undefined;
|
||||
result = data.drawPixelMap.imagePixelMap as PixelMap;
|
||||
this.mCircleBorderPixelMap = result;
|
||||
return false;
|
||||
})
|
||||
|
@ -618,8 +618,8 @@ struct TransformPixelMapPage {
|
|||
var transformation = new RotateImageTransformation(angled);
|
||||
imageKnifeOption.load(mUrl)
|
||||
.addListener((err, data) => {
|
||||
let result = new PixelMapPack();
|
||||
result.pixelMap = data.imageKnifeValue as PixelMap;
|
||||
let result = undefined;
|
||||
result = data.drawPixelMap.imagePixelMap as PixelMap;
|
||||
this.mRotatePixelMap = result;
|
||||
return false;
|
||||
})
|
||||
|
@ -637,8 +637,8 @@ struct TransformPixelMapPage {
|
|||
var transformation = new CropSquareTransformation();
|
||||
imageKnifeOption.load(mUrl)
|
||||
.addListener((err, data) => {
|
||||
let result = new PixelMapPack();
|
||||
result.pixelMap = data.imageKnifeValue as PixelMap;
|
||||
let result = undefined;
|
||||
result = data.drawPixelMap.imagePixelMap as PixelMap;
|
||||
this.mSquarePixelMap = result;
|
||||
return false;
|
||||
})
|
||||
|
@ -656,15 +656,15 @@ struct TransformPixelMapPage {
|
|||
var transformation = new CropTransformation(width, height, cropType);
|
||||
imageKnifeOption.load(mUrl)
|
||||
.addListener((err, data) => {
|
||||
let result = new PixelMapPack();
|
||||
let result = undefined;
|
||||
if (cropType == CropType.TOP) {
|
||||
result.pixelMap = data.imageKnifeValue as PixelMap;
|
||||
result = data.drawPixelMap.imagePixelMap as PixelMap;
|
||||
this.mClipTopPixelMap = result;
|
||||
} else if (cropType == CropType.CENTER) {
|
||||
result.pixelMap = data.imageKnifeValue as PixelMap;
|
||||
result = data.drawPixelMap.imagePixelMap as PixelMap;
|
||||
this.mClipCenterPixelMap = result;
|
||||
} else if (cropType == CropType.BOTTOM) {
|
||||
result.pixelMap = data.imageKnifeValue as PixelMap;
|
||||
result = data.drawPixelMap.imagePixelMap as PixelMap;
|
||||
this.mClipBottomPixelMap = result;
|
||||
}
|
||||
return false;
|
||||
|
@ -684,8 +684,8 @@ struct TransformPixelMapPage {
|
|||
var transformation = new GrayscaleTransformation();
|
||||
imageKnifeOption.load(mUrl)
|
||||
.addListener((err, data) => {
|
||||
let result = new PixelMapPack();
|
||||
result.pixelMap = data.imageKnifeValue as PixelMap;
|
||||
let result = undefined;
|
||||
result = data.drawPixelMap.imagePixelMap as PixelMap;
|
||||
this.mGrayscalePixelMap = result;
|
||||
return false;
|
||||
})
|
||||
|
@ -704,8 +704,8 @@ struct TransformPixelMapPage {
|
|||
var transformation = new BrightnessFilterTransformation(brightness);
|
||||
imageKnifeOption.load(mUrl)
|
||||
.addListener((err, data) => {
|
||||
let result = new PixelMapPack();
|
||||
result.pixelMap = data.imageKnifeValue as PixelMap;
|
||||
let result = undefined;
|
||||
result = data.drawPixelMap.imagePixelMap as PixelMap;
|
||||
this.mBrightnessPixelMap = result;
|
||||
return false;
|
||||
})
|
||||
|
@ -724,8 +724,8 @@ struct TransformPixelMapPage {
|
|||
var transformation = new ContrastFilterTransformation(contrast);
|
||||
imageKnifeOption.load(mUrl)
|
||||
.addListener((err, data) => {
|
||||
let result = new PixelMapPack();
|
||||
result.pixelMap = data.imageKnifeValue as PixelMap;
|
||||
let result = undefined;
|
||||
result = data.drawPixelMap.imagePixelMap as PixelMap;
|
||||
this.mContrastPixelMap = result;
|
||||
return false;
|
||||
})
|
||||
|
@ -744,8 +744,8 @@ struct TransformPixelMapPage {
|
|||
var transformation = new InvertFilterTransformation();
|
||||
imageKnifeOption.load(mUrl)
|
||||
.addListener((err, data) => {
|
||||
let result = new PixelMapPack();
|
||||
result.pixelMap = data.imageKnifeValue as PixelMap;
|
||||
let result = undefined;
|
||||
result = data.drawPixelMap.imagePixelMap as PixelMap;
|
||||
this.mInvertPixelMap = result;
|
||||
return false;
|
||||
})
|
||||
|
@ -764,8 +764,8 @@ struct TransformPixelMapPage {
|
|||
var transformation = new SepiaFilterTransformation();
|
||||
imageKnifeOption.load(mUrl)
|
||||
.addListener((err, data) => {
|
||||
let result = new PixelMapPack();
|
||||
result.pixelMap = data.imageKnifeValue as PixelMap;
|
||||
let result = undefined;
|
||||
result = data.drawPixelMap.imagePixelMap as PixelMap;
|
||||
this.mSepiaPixelMap = result;
|
||||
return false;
|
||||
})
|
||||
|
@ -784,8 +784,8 @@ struct TransformPixelMapPage {
|
|||
var transformation = new SketchFilterTransformation();
|
||||
imageKnifeOption.load(mUrl)
|
||||
.addListener((err, data) => {
|
||||
let result = new PixelMapPack();
|
||||
result.pixelMap = data.imageKnifeValue as PixelMap;
|
||||
let result = undefined;
|
||||
result = data.drawPixelMap.imagePixelMap as PixelMap;
|
||||
this.mSketchPixelMap = result;
|
||||
return false;
|
||||
})
|
||||
|
@ -804,8 +804,8 @@ struct TransformPixelMapPage {
|
|||
var transformation = new BlurTransformation(radius);
|
||||
imageKnifeOption.load(mUrl)
|
||||
.addListener((err, data) => {
|
||||
let result = new PixelMapPack();
|
||||
result.pixelMap = data.imageKnifeValue as PixelMap;
|
||||
let result = undefined;
|
||||
result = data.drawPixelMap.imagePixelMap as PixelMap;
|
||||
this.mBlurPixelMap = result;
|
||||
return false;
|
||||
})
|
||||
|
@ -823,8 +823,8 @@ struct TransformPixelMapPage {
|
|||
var transformation = new PixelationFilterTransformation(pixel);
|
||||
imageKnifeOption.load(mUrl)
|
||||
.addListener((err, data) => {
|
||||
let result = new PixelMapPack();
|
||||
result.pixelMap = data.imageKnifeValue as PixelMap;
|
||||
let result = undefined;
|
||||
result = data.drawPixelMap.imagePixelMap as PixelMap;
|
||||
this.mPixelPixelMap = result;
|
||||
return false;
|
||||
})
|
||||
|
@ -843,8 +843,8 @@ struct TransformPixelMapPage {
|
|||
var transformation = new SwirlFilterTransformation(80);
|
||||
imageKnifeOption.load(mUrl)
|
||||
.addListener((err, data) => {
|
||||
let result = new PixelMapPack();
|
||||
result.pixelMap = data.imageKnifeValue as PixelMap;
|
||||
let result = undefined;
|
||||
result = data.drawPixelMap.imagePixelMap as PixelMap;
|
||||
this.mSwirlPixelMap = result;
|
||||
return false;
|
||||
})
|
||||
|
@ -864,8 +864,8 @@ struct TransformPixelMapPage {
|
|||
// imageKnifeOption.load($r('app.media.photo6'))
|
||||
imageKnifeOption.load(mUrl)
|
||||
.addListener((err, data) => {
|
||||
let result = new PixelMapPack();
|
||||
result.pixelMap = data.imageKnifeValue as PixelMap;
|
||||
let result = undefined;
|
||||
result = data.drawPixelMap.imagePixelMap as PixelMap;
|
||||
this.mMaskPixelMap = result;
|
||||
return false;
|
||||
})
|
||||
|
|
|
@ -1,96 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is dibistributed 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/imageknife'
|
||||
import {ImageKnifeOption} from '@ohos/imageknife'
|
||||
import {RotateImageTransformation} from '@ohos/imageknife'
|
||||
import {RoundedCornersTransformation} from '@ohos/imageknife'
|
||||
import {TransformType} from '@ohos/imageknife'
|
||||
|
||||
@Entry
|
||||
@Component
|
||||
struct Index {
|
||||
@State imageKnifeOption1: ImageKnifeOption =
|
||||
{
|
||||
loadSrc: "https://thirdwx.qlogo.cn/mmopen/vi_32/DYAIOgq83ericA1Mv66TwicuYOtbDMBcUhv1aa9RJBeAn9uURfcZD0AUGrJebAn1g2AjN0vb2E1XTET7fTuLBNmA/132",
|
||||
size: { width: 300, height: 300 },
|
||||
placeholderSrc: $r('app.media.jpgSample'),
|
||||
errorholderSrc: $r('app.media.pngSample'),
|
||||
transform: {
|
||||
transformType:TransformType.RotateImageTransformation,
|
||||
rotateImage:180
|
||||
}
|
||||
};
|
||||
@State imageKnifeOption2: ImageKnifeOption =
|
||||
{
|
||||
loadSrc: "https://thirdwx.qlogo.cn/mmopen/vi_32/DYAIOgq83ericA1Mv66TwicuYOtbDMBcUhv1aa9RJBeAn9uURfcZD0AUGrJebAn1g2AjN0vb2E1XTET7fTuLBNmA/132",
|
||||
size: { width: 300, height: 300 },
|
||||
placeholderSrc: $r('app.media.jpgSample'),
|
||||
errorholderSrc: $r('app.media.pngSample'),
|
||||
transform: {
|
||||
transformType:TransformType.RoundedCornersTransformation,
|
||||
roundedCorners:{
|
||||
top_left: 30,
|
||||
top_right: 30,
|
||||
bottom_left: 30,
|
||||
bottom_right: 30
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
@State imageKnifeOption3: ImageKnifeOption =
|
||||
{
|
||||
loadSrc: $r('app.media.pngSample'),
|
||||
size: { width: 300, height: 300 },
|
||||
placeholderSrc: $r('app.media.jpgSample'),
|
||||
errorholderSrc: $r('app.media.pngSample'),
|
||||
transform: {
|
||||
transformType:TransformType.RotateImageTransformation,
|
||||
rotateImage:180
|
||||
}
|
||||
};
|
||||
@State imageKnifeOption4: ImageKnifeOption =
|
||||
{
|
||||
loadSrc: $r('app.media.jpgSample'),
|
||||
size: { width: 300, height: 300 },
|
||||
placeholderSrc: $r('app.media.jpgSample'),
|
||||
errorholderSrc: $r('app.media.pngSample'),
|
||||
transform: {
|
||||
transformType:TransformType.RoundedCornersTransformation,
|
||||
roundedCorners:{
|
||||
top_left: 130,
|
||||
top_right: 130,
|
||||
bottom_left: 130,
|
||||
bottom_right: 130
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
build() {
|
||||
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
||||
ImageKnifeComponent({ imageKnifeOption: $imageKnifeOption1 })
|
||||
ImageKnifeComponent({ imageKnifeOption: $imageKnifeOption2 })
|
||||
ImageKnifeComponent({ imageKnifeOption: $imageKnifeOption3 })
|
||||
ImageKnifeComponent({ imageKnifeOption: $imageKnifeOption4 })
|
||||
}
|
||||
.width('100%')
|
||||
.height('100%')
|
||||
}
|
||||
|
||||
aboutToAppear() {
|
||||
console.log("aboutToAppear()")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* Copyright (C) 2022 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import arkWorker from '@ohos.worker';
|
||||
import { gifHandler } from '@ohos/imageknife/GifWorker'
|
||||
|
||||
arkWorker.parentPort.onmessage = gifHandler;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -14,7 +14,7 @@
|
|||
*/
|
||||
import arkWorker from '@ohos.worker';
|
||||
|
||||
import {handler} from '@ohos/imageknife/src/main/ets/components/imageknife/pngj/PngWork'
|
||||
import {handler} from '@ohos/imageknife/PngWork'
|
||||
|
||||
arkWorker.parentPort.onmessage = handler
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
"deliveryWithInstall": true,
|
||||
"installationFree": false,
|
||||
"pages": "$profile:main_pages",
|
||||
"requestPermissions": [{"name": "ohos.permission.INTERNET"}],
|
||||
|
||||
"uiSyntax": "ets",
|
||||
"abilities": [
|
||||
{
|
||||
|
@ -35,6 +35,17 @@
|
|||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"requestPermissions": [
|
||||
{
|
||||
"name": "ohos.permission.INTERNET",
|
||||
"usedScene": {
|
||||
"abilities": [
|
||||
"FormAbility"
|
||||
],
|
||||
"when": "always"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
Before Width: | Height: | Size: 9.0 MiB After Width: | Height: | Size: 1.1 MiB |
Before Width: | Height: | Size: 251 KiB After Width: | Height: | Size: 4.2 KiB |
|
@ -1,8 +1,6 @@
|
|||
{
|
||||
"src": [
|
||||
"pages/index",
|
||||
"pages/indexFresco",
|
||||
"pages/frescoLayerTestCasePage",
|
||||
"pages/frescoImageTestCasePage",
|
||||
"pages/frescoRetryTestCasePage",
|
||||
"pages/basicTestFeatureAbilityPage",
|
||||
|
@ -10,25 +8,21 @@
|
|||
"pages/basicTestMediaImage",
|
||||
"pages/basicTestResourceManagerPage",
|
||||
"pages/storageTestLruCache",
|
||||
"pages/storageTestDiskLruCache",
|
||||
"pages/transformTestCasePage",
|
||||
"pages/pngjTestCasePage",
|
||||
"pages/testAllTypeImageKnifeComponentPage",
|
||||
"pages/testAllTypeNativeImagePage",
|
||||
"pages/loadResourceTestCasePage",
|
||||
"pages/loadNetworkTestCasePage",
|
||||
"pages/showErrorholderTestCasePage",
|
||||
"pages/transformPixelMapPage",
|
||||
"pages/testGifDontAnimatePage",
|
||||
"pages/testPreloadPage",
|
||||
"pages/testImageKnifeOptionChangedPage",
|
||||
"pages/testImageKnifeOptionChangedPage2",
|
||||
"pages/testImageKnifeOptionChangedPage3",
|
||||
"pages/testImageKnifeOptionChangedPage4",
|
||||
"pages/testImageKnifeOptionChangedPage5",
|
||||
"pages/compressPage",
|
||||
"pages/testAllCacheInfoPage",
|
||||
"pages/testResourceManagerPage",
|
||||
"pages/testMultiThreadWorkerPage2",
|
||||
"pages/cropImagePage",
|
||||
"pages/cropImagePage2",
|
||||
"pages/dpgTestCasePage"
|
||||
"pages/svgTestCasePage",
|
||||
"pages/gifTestCasePage",
|
||||
"pages/imageknifeTestCaseIndex"
|
||||
]
|
||||
}
|
||||
|
|
|
@ -16,6 +16,6 @@ import AbilityStage from "@ohos.application.AbilityStage"
|
|||
|
||||
export default class TestAbilityStage extends AbilityStage {
|
||||
onCreate() {
|
||||
console.log("[Demo] TestAbilityStage onCreate")
|
||||
|
||||
}
|
||||
}
|
|
@ -19,35 +19,35 @@ import testsuite from '../test/List.test'
|
|||
|
||||
export default class TestAbility extends Ability {
|
||||
onCreate(want, launchParam) {
|
||||
console.log('TestAbility onCreate')
|
||||
|
||||
var abilityDelegator: any
|
||||
abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator()
|
||||
var abilityDelegatorArguments: any
|
||||
abilityDelegatorArguments = AbilityDelegatorRegistry.getArguments()
|
||||
console.info('start run testcase!!!')
|
||||
|
||||
Hypium.hypiumTest(abilityDelegator, abilityDelegatorArguments, testsuite)
|
||||
}
|
||||
|
||||
onDestroy() {
|
||||
console.log('TestAbility onDestroy')
|
||||
|
||||
}
|
||||
|
||||
onWindowStageCreate(windowStage) {
|
||||
console.log('TestAbility onWindowStageCreate')
|
||||
|
||||
windowStage.setUIContent(this.context, 'TestAbility/pages/index', null)
|
||||
|
||||
globalThis.abilityContext = this.context;
|
||||
}
|
||||
|
||||
onWindowStageDestroy() {
|
||||
console.log('TestAbility onWindowStageDestroy')
|
||||
|
||||
}
|
||||
|
||||
onForeground() {
|
||||
console.log('TestAbility onForeground')
|
||||
|
||||
}
|
||||
|
||||
onBackground() {
|
||||
console.log('TestAbility onBackground')
|
||||
|
||||
}
|
||||
};
|
|
@ -33,11 +33,11 @@ function translateParamsToString(parameters) {
|
|||
}
|
||||
|
||||
async function onAbilityCreateCallback() {
|
||||
console.log("onAbilityCreateCallback");
|
||||
|
||||
}
|
||||
|
||||
async function addAbilityMonitorCallback(err: any) {
|
||||
console.info("addAbilityMonitorCallback : " + JSON.stringify(err))
|
||||
|
||||
}
|
||||
|
||||
export default class OpenHarmonyTestRunner implements TestRunner {
|
||||
|
@ -45,11 +45,11 @@ export default class OpenHarmonyTestRunner implements TestRunner {
|
|||
}
|
||||
|
||||
onPrepare() {
|
||||
console.info("OpenHarmonyTestRunner OnPrepare ")
|
||||
|
||||
}
|
||||
|
||||
async onRun() {
|
||||
console.log('OpenHarmonyTestRunner onRun run')
|
||||
|
||||
abilityDelegatorArguments = AbilityDelegatorRegistry.getArguments()
|
||||
abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator()
|
||||
var testAbilityName = abilityDelegatorArguments.bundleName + '.TestAbility'
|
||||
|
@ -60,13 +60,13 @@ export default class OpenHarmonyTestRunner implements TestRunner {
|
|||
abilityDelegator.addAbilityMonitor(lMonitor, addAbilityMonitorCallback)
|
||||
var cmd = 'aa start -d 0 -a TestAbility' + ' -b ' + abilityDelegatorArguments.bundleName
|
||||
cmd += ' '+translateParamsToString(abilityDelegatorArguments.parameters)
|
||||
console.info('cmd : '+cmd)
|
||||
|
||||
abilityDelegator.executeShellCommand(cmd,
|
||||
(err: any, d: any) => {
|
||||
console.info('executeShellCommand : err : ' + JSON.stringify(err));
|
||||
console.info('executeShellCommand : data : ' + d.stdResult);
|
||||
console.info('executeShellCommand : data : ' + d.exitCode);
|
||||
|
||||
|
||||
|
||||
})
|
||||
console.info('OpenHarmonyTestRunner onRun end')
|
||||
|
||||
}
|
||||
};
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* Copyright (C) 2022 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import arkWorker from '@ohos.worker';
|
||||
import { parseBufferToFrame } from './src/main/ets/components/imageknife/utils/gif/parse/GIFParse'
|
||||
|
||||
export enum LoadType {
|
||||
loadBufferByWorker = "loadBufferByWorker"
|
||||
}
|
||||
|
||||
// Send or Receive Format Data Such as: {type: yourResolveType, data: yourDataJson, error?: yourErrorInfo }
|
||||
export function gifHandler(e) {
|
||||
let data = e.data;
|
||||
switch (data.type) {
|
||||
case LoadType.loadBufferByWorker:
|
||||
loadBufferByWorker(data.data, data.type);
|
||||
break;
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
||||
function loadBufferByWorker(buffer: ArrayBuffer, recType: string) {
|
||||
let images = parseBufferToFrame(buffer);
|
||||
let dimss = [];
|
||||
let delays = [];
|
||||
let disposalTypes = [];
|
||||
let patchs = [];
|
||||
let transparentIndexs = [];
|
||||
for (let i = 0; i < images.length; i++) {
|
||||
dimss.push(images[i].dims)
|
||||
delays.push(images[i].delay)
|
||||
disposalTypes.push(images[i].disposalType)
|
||||
patchs.push(images[i].patch.buffer)
|
||||
transparentIndexs.push(images[i].transparentIndex)
|
||||
}
|
||||
let frame = {
|
||||
dims: dimss,
|
||||
// 当前帧到下一帧的间隔时长
|
||||
delay: delays,
|
||||
// 当前帧绘制要求 0保留 1在上一帧绘制此帧 2恢复画布背景 3.将画布恢复到绘制当前图像之前的先前状态
|
||||
disposalType: disposalTypes,
|
||||
// Uint8CampedArray颜色转换后的补片信息用于绘制
|
||||
patch: patchs,
|
||||
// 表示透明度的可选颜色索引
|
||||
transparentIndex: transparentIndexs
|
||||
}
|
||||
let dataObj = { type: recType, data: frame }
|
||||
arkWorker.parentPort.postMessage(dataObj, patchs);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright (C) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import arkWorker from '@ohos.worker';
|
||||
import {UPNG} from './src/main/ets/components/imageknife/pngj/UPNG'
|
||||
|
||||
export function handler (e) {
|
||||
var data = e.data;
|
||||
switch (data.type) {
|
||||
case 'readPngImageAsync':
|
||||
var png = UPNG.decode(data.data);
|
||||
let array = png.data;
|
||||
let arrayData = array.buffer.slice(array.byteOffset, array.byteLength + array.byteOffset)
|
||||
png.data = arrayData;
|
||||
let dataObj = { type: 'readPngImageAsync', data: png, receiver: data.data}
|
||||
arkWorker.parentPort.postMessage(dataObj, [png.data, data.data]);
|
||||
break;
|
||||
case 'writePngWithStringAsync':
|
||||
let addInfo = data.info;
|
||||
let pngDecode = UPNG.decode(data.data);
|
||||
let newPng = UPNG.encodeWithString(addInfo, UPNG.toRGBA8(pngDecode), pngDecode.width, pngDecode.height, 0)
|
||||
let dataObj2 = { type: 'writePngWithStringAsync', data: newPng, receiver: data.data}
|
||||
arkWorker.parentPort.postMessage(dataObj2, [newPng, data.data]);
|
||||
break;
|
||||
case 'writePngAsync':
|
||||
let pngDecode3 = UPNG.decode(data.data);
|
||||
let newPng3 = UPNG.encode(UPNG.toRGBA8(pngDecode3), pngDecode3.width, pngDecode3.height, 0)
|
||||
let dataObj3 = { type: 'writePngAsync', data: newPng3, receiver: data.data}
|
||||
arkWorker.parentPort.postMessage(dataObj3, [newPng3, data.data]);
|
||||
break;
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -80,7 +80,7 @@ export * from './src/main/ets/components/imageknife/transform/pixelmap/FitCenter
|
|||
* pngj
|
||||
*/
|
||||
export * from './src/main/ets/components/imageknife/pngj/Pngj'
|
||||
export {handler} from './src/main/ets/components/imageknife/pngj/PngWork'
|
||||
export {handler} from './PngWork'
|
||||
export * from './src/main/ets/components/imageknife/pngj/UPNG'
|
||||
|
||||
|
||||
|
@ -91,9 +91,9 @@ export * from './src/main/ets/components/imageknife/pngj/UPNG'
|
|||
export * from './src/main/ets/components/imageknife/ImageKnife'
|
||||
export * from './src/main/ets/components/imageknife/RequestOption'
|
||||
export * from './src/main/ets/components/imageknife/ImageKnifeComponent'
|
||||
export * from './src/main/ets/components/imageknife/ImageKnifeDrawFactory'
|
||||
export * from './src/main/ets/components/imageknife/ImageKnifeOption'
|
||||
export * from './src/main/ets/components/imageknife/ImageKnifeData'
|
||||
export * from './src/main/ets/components/imageknife/PixelMapPack'
|
||||
export * from './src/main/ets/components/imageknife/interface/IAllCacheInfoCallback'
|
||||
export * from './src/main/ets/components/imageknife/interface/IParseImage'
|
||||
export * from './src/main/ets/components/imageknife/networkmanage/IDataFetch'
|
||||
|
@ -101,3 +101,19 @@ export * from './src/main/ets/components/imageknife/requestmanage/ICache'
|
|||
export * from './src/main/ets/components/imageknife/utils/FileTypeUtil'
|
||||
export * from './src/main/ets/components/imageknife/utils/ParseImageUtil'
|
||||
|
||||
/**
|
||||
* svg parse
|
||||
*/
|
||||
export * from './src/main/ets/components/imageknife/utils/svg/SVGParseImpl'
|
||||
|
||||
/**
|
||||
* gif parse
|
||||
*/
|
||||
export * from './src/main/ets/components/imageknife/utils/gif/GIFParseImpl'
|
||||
export * from './src/main/ets/components/imageknife/utils/gif/GIFFrame'
|
||||
// 能力增强worker 解析GIF数据
|
||||
export {gifHandler} from './GifWorker'
|
||||
|
||||
// 自定义组件新增
|
||||
// 自定义组件绘制生命周期
|
||||
export * from './src/main/ets/components/imageknife/interface/IDrawLifeCycle'
|
|
@ -12,16 +12,21 @@
|
|||
},
|
||||
"main": "index.ets",
|
||||
"repository": "https://gitee.com/openharmony-tpc/ImageKnife",
|
||||
"version": "1.0.3",
|
||||
"version": "1.0.4",
|
||||
"dependencies": {
|
||||
"pako": "^1.0.5",
|
||||
"js-binary-schema-parser": "^2.0.3",
|
||||
"@ohos/disklrucache": "^1.0.0",
|
||||
"crc-32": "^1.2.0"
|
||||
"@ohos/svg": "1.1.0",
|
||||
"crc-32": "^1.2.0",
|
||||
"spark-md5": "^3.0.2"
|
||||
},
|
||||
"tags": [
|
||||
"OpenHarmony",
|
||||
"ImageKnife",
|
||||
"glide"
|
||||
"glide",
|
||||
"ImageCache",
|
||||
"UI"
|
||||
],
|
||||
"license": "Apache License 2.0",
|
||||
"devDependencies": {},
|
||||
|
|
|
@ -19,20 +19,21 @@ import {EngineKeyFactories} from "../cache/key/EngineKeyFactories"
|
|||
import {RequestOption} from "../imageknife/RequestOption"
|
||||
import {AsyncCallback} from "../imageknife/interface/asynccallback"
|
||||
import {PlaceHolderManager} from "../imageknife/holder/PlaceHolderManager"
|
||||
import {RetryHolderManager} from "../imageknife/holder/RetryHolderManager"
|
||||
import {ErrorHolderManager} from "../imageknife/holder/ErrorHolderManager"
|
||||
import {RequestManager} from "../imageknife/requestmanage/RequstManager"
|
||||
import {RequestManager} from "../imageknife/requestmanage/RequestManager"
|
||||
import {NONE} from "../cache/diskstrategy/enum/NONE"
|
||||
import {FileTypeUtil} from '../imageknife/utils/FileTypeUtil'
|
||||
import {DownloadClient} from '../imageknife/networkmanage/DownloadClient'
|
||||
import {IDataFetch} from '../imageknife/networkmanage/IDataFetch'
|
||||
import {ParseResClient} from '../imageknife/resourcemanage/ParseResClient'
|
||||
import {IResourceFetch} from '../imageknife/resourcemanage/IResourceFetch'
|
||||
import {ImageKnifeData} from '../imageknife/ImageKnifeData'
|
||||
import {ImageKnifeData,ImageKnifeType} from '../imageknife/ImageKnifeData'
|
||||
import {FileUtils} from '../cache/FileUtils'
|
||||
import {FileReader} from '../cache/FileReader'
|
||||
import image from "@ohos.multimedia.image"
|
||||
import featureAbility from '@ohos.ability.featureAbility';
|
||||
import {CompressBuilder} from "../imageknife/compress/CompressBuilder"
|
||||
import { IDrawLifeCycle } from '../imageknife/interface/IDrawLifeCycle'
|
||||
|
||||
export class ImageKnife {
|
||||
static readonly SEPARATOR: string = '/'
|
||||
|
@ -49,11 +50,15 @@ export class ImageKnife {
|
|||
private pendingRequest: Array<RequestOption>;
|
||||
private fileTypeUtil: FileTypeUtil; // 通用文件格式辨别
|
||||
private diskCacheFolder: string = "ImageKnifeDiskCache"
|
||||
private svgAndGifFolder: string = "svgAndGifFolder"; // svg和gif的文件路径地址
|
||||
private svgAndGifCommitFile: string = "svgAndGifCommitFile" // svg和gif提交记录
|
||||
|
||||
|
||||
private defaultListener: AsyncCallback<ImageKnifeData>; // 全局监听器
|
||||
|
||||
// gifWorker
|
||||
private gifWorker;
|
||||
|
||||
private defaultLifeCycle: IDrawLifeCycle;
|
||||
|
||||
private constructor(imgCtx) {
|
||||
this.imageKnifeContext = imgCtx;
|
||||
|
||||
|
@ -71,7 +76,6 @@ export class ImageKnife {
|
|||
|
||||
// 初始化本地 文件保存
|
||||
this.filesPath = this.imageKnifeContext.filesDir;
|
||||
this.initSvgAndGifEnvironment();
|
||||
|
||||
this.runningRequest = new Array();
|
||||
this.pendingRequest = new Array();
|
||||
|
@ -103,16 +107,6 @@ export class ImageKnife {
|
|||
return this.fileTypeUtil;
|
||||
}
|
||||
|
||||
|
||||
|
||||
getSvgAndGifFolder(): string{
|
||||
return this.svgAndGifFolder;
|
||||
}
|
||||
|
||||
setSvgAndGifFolder(folderPath: string){
|
||||
this.svgAndGifFolder = folderPath;
|
||||
}
|
||||
|
||||
getImageKnifeContext() {
|
||||
return this.imageKnifeContext;
|
||||
}
|
||||
|
@ -125,31 +119,21 @@ export class ImageKnife {
|
|||
return this.defaultListener;
|
||||
}
|
||||
|
||||
private initSvgAndGifEnvironment() {
|
||||
let folderExist = FileUtils.getInstance().existFolder(this.filesPath + "/" + this.svgAndGifFolder)
|
||||
let fileExist =
|
||||
FileUtils.getInstance()
|
||||
.exist(this.filesPath + "/" + this.svgAndGifFolder + "/" + this.svgAndGifCommitFile)
|
||||
if (folderExist && fileExist) {
|
||||
// 创建完成,需要删除上次使用的文件
|
||||
var fileReader = new FileReader(this.filesPath + "/" + this.svgAndGifFolder + "/" + this.svgAndGifCommitFile)
|
||||
var line: string = ''
|
||||
while (!fileReader.isEnd()) {
|
||||
line = fileReader.readLine()
|
||||
line = line.replace('\n', "").replace('\r', "")
|
||||
FileUtils.getInstance().deleteFile(this.filesPath + "/" + this.svgAndGifFolder + "/" + line)
|
||||
}
|
||||
FileUtils.getInstance().clearFile(this.filesPath + "/" + this.svgAndGifFolder + "/" + this.svgAndGifCommitFile)
|
||||
} else {
|
||||
if (!folderExist) {
|
||||
FileUtils.getInstance().createFolder(this.filesPath + "/" + this.svgAndGifFolder);
|
||||
}
|
||||
if (!fileExist) {
|
||||
FileUtils.getInstance().createFile(this.filesPath + "/" + this.svgAndGifFolder + "/" + this.svgAndGifCommitFile)
|
||||
}
|
||||
}
|
||||
|
||||
setGifWorker(worker){
|
||||
this.gifWorker = worker
|
||||
}
|
||||
getGifWorker(){
|
||||
return this.gifWorker;
|
||||
}
|
||||
|
||||
getDefaultLifeCycle(){
|
||||
return this.defaultLifeCycle;
|
||||
}
|
||||
|
||||
setDefaultLifeCycle(viewLifeCycle:IDrawLifeCycle){
|
||||
this.defaultLifeCycle = viewLifeCycle;
|
||||
}
|
||||
|
||||
|
||||
private static sInstance: ImageKnife;
|
||||
|
||||
|
@ -195,9 +179,7 @@ export class ImageKnife {
|
|||
preload(request: RequestOption) {
|
||||
// 每个request 公共信息补充
|
||||
request.setFilesPath(this.filesPath);
|
||||
// svg特殊处理
|
||||
request._svgAndGifFolder = this.svgAndGifFolder;
|
||||
request._svgAndGifCommitFile = this.svgAndGifCommitFile;
|
||||
|
||||
return this.parseSource(request);
|
||||
}
|
||||
|
||||
|
@ -211,16 +193,16 @@ export class ImageKnife {
|
|||
// 每个request 公共信息补充
|
||||
request.setFilesPath(this.filesPath);
|
||||
|
||||
// svg特殊处理
|
||||
request._svgAndGifFolder = this.svgAndGifFolder;
|
||||
request._svgAndGifCommitFile = this.svgAndGifCommitFile;
|
||||
|
||||
// 首先执行占位图 解析任务
|
||||
if (request.placeholderSrc) {
|
||||
PlaceHolderManager.execute(request)
|
||||
}
|
||||
// 其次执行重试占位图 解析任务
|
||||
if (request.retryholderSrc) {
|
||||
RetryHolderManager.execute(request)
|
||||
}
|
||||
|
||||
// 其次解析错误占位图
|
||||
// 最后解析错误占位图
|
||||
if (request.errorholderSrc) {
|
||||
ErrorHolderManager.execute(request)
|
||||
}
|
||||
|
@ -374,9 +356,7 @@ export class ImageKnife {
|
|||
|
||||
parseSource(request: RequestOption) {
|
||||
if ((typeof (request.loadSrc as image.PixelMap).isEditable) == 'boolean') {
|
||||
let imageKnifeData = new ImageKnifeData();
|
||||
imageKnifeData.imageKnifeType = ImageKnifeData.PIXELMAP
|
||||
imageKnifeData.imageKnifeValue = request.loadSrc as PixelMap
|
||||
let imageKnifeData = ImageKnifeData.createImagePixelMap(ImageKnifeType.PIXELMAP, request.loadSrc as PixelMap)
|
||||
request.loadComplete(imageKnifeData);
|
||||
} else
|
||||
if (typeof request.loadSrc == 'string') {
|
||||
|
|
|
@ -13,98 +13,170 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {ImageKnifeOption} from '../imageknife/ImageKnifeOption'
|
||||
import {TransformType} from '../imageknife/transform/TransformType'
|
||||
import {RequestOption} from '../imageknife/RequestOption'
|
||||
import {ImageKnifeData} from '../imageknife/ImageKnifeData'
|
||||
import {PixelMapPack} from '../imageknife/PixelMapPack'
|
||||
import { ImageKnifeOption } from '../imageknife/ImageKnifeOption'
|
||||
import { TransformType } from '../imageknife/transform/TransformType'
|
||||
import { RequestOption } from '../imageknife/RequestOption'
|
||||
import { ImageKnifeData } from '../imageknife/ImageKnifeData'
|
||||
import { GIFFrame } from '../imageknife/utils/gif/GIFFrame'
|
||||
import { IDrawLifeCycle } from '../imageknife/interface/IDrawLifeCycle'
|
||||
|
||||
|
||||
@Component
|
||||
export struct ImageKnifeComponent {
|
||||
@Watch('watchImageKnifeOption') @Link imageKnifeOption: ImageKnifeOption;
|
||||
@State imageKnifePixelMapPack: PixelMapPack = new PixelMapPack();
|
||||
@State imageKnifeResource: Resource = undefined
|
||||
@State imageKnifeString: string = ''
|
||||
@State normalPixelMap: boolean = false;
|
||||
@State normalResource: boolean = true;
|
||||
previousData: ImageKnifeData = null;
|
||||
nowData: ImageKnifeData = null;
|
||||
@State percentVisible: Visibility = Visibility.Visible
|
||||
@State retryVisible: Visibility = Visibility.Visible
|
||||
@State imageVisible: Visibility = Visibility.Visible
|
||||
@State percent: string = '0%'
|
||||
@State percentWidth: string = '0%';
|
||||
@State percentHeight: string = '0%';
|
||||
@State retryWidth: string = '0%';
|
||||
@State retryHeight: string = '0%';
|
||||
@State imageWidth: string = '100%';
|
||||
@State imageHeight: string = '100%';
|
||||
@State componentWidth: string = '100%'
|
||||
@State componentHeight: string = '100%'
|
||||
@State gifPixelMap: PixelMap = undefined;
|
||||
drawLifeCycle: IDrawLifeCycle
|
||||
autoPlay = true
|
||||
// 有效onAreaChanged触发计数
|
||||
private onAreaCount: number = 0
|
||||
private preSize: {
|
||||
width: string,
|
||||
height: string
|
||||
} = { width: '0', height: '0' }
|
||||
private settings: RenderingContextSettings = new RenderingContextSettings(true)
|
||||
private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings)
|
||||
private hasDisplayRetryholder = false;
|
||||
private currentWidth: number = 0
|
||||
private currentHeight: number = 0
|
||||
|
||||
@State imageKnifeRetry: Resource = undefined;
|
||||
// 定时器id
|
||||
private gifTimerId: number = 0
|
||||
// 完整gif播放时间
|
||||
private gifLoopDuration: number = 0
|
||||
private startGifLoopTime: number = 0
|
||||
private endGifLoopTime: number = 0
|
||||
defaultLifeCycle: IDrawLifeCycle = {
|
||||
|
||||
hasRetry:boolean = false;
|
||||
// 展示占位图
|
||||
displayPlaceholder: (context: CanvasRenderingContext2D, data: ImageKnifeData, imageKnifeOption: ImageKnifeOption, compWidth: number, compHeight: number, setGifTimeId?: (timeId: number) => void) => {
|
||||
this.drawPlaceholder(context, data, imageKnifeOption, compWidth, compHeight, setGifTimeId)
|
||||
return true;
|
||||
},
|
||||
// 展示加载进度
|
||||
displayProgress: (context: CanvasRenderingContext2D, progress: number, imageKnifeOption: ImageKnifeOption, compWidth: number, compHeight: number, setGifTimeId?: (timeId: number) => void) => {
|
||||
this.drawProgress(context, progress, imageKnifeOption, compWidth, compHeight, setGifTimeId)
|
||||
return true;
|
||||
},
|
||||
// 展示缩略图
|
||||
displayThumbSizeMultiplier: (context: CanvasRenderingContext2D, data: ImageKnifeData, imageKnifeOption: ImageKnifeOption, compWidth: number, compHeight: number, setGifTimeId?: (timeId: number) => void) => {
|
||||
this.drawThumbSizeMultiplier(context, data, imageKnifeOption, compWidth, compHeight, setGifTimeId)
|
||||
return true;
|
||||
},
|
||||
|
||||
// 展示主图
|
||||
displayMainSource: (context: CanvasRenderingContext2D, data: ImageKnifeData, imageKnifeOption: ImageKnifeOption, compWidth: number, compHeight: number, setGifTimeId?: (timeId: number) => void) => {
|
||||
this.drawMainSource(context, data, imageKnifeOption, compWidth, compHeight, setGifTimeId)
|
||||
return true;
|
||||
},
|
||||
|
||||
// 展示重试图层
|
||||
displayRetryholder: (context: CanvasRenderingContext2D, data: ImageKnifeData, imageKnifeOption: ImageKnifeOption, compWidth: number, compHeight: number, setGifTimeId?: (timeId: number) => void) => {
|
||||
this.drawRetryholder(context, data, imageKnifeOption, compWidth, compHeight, setGifTimeId)
|
||||
return true;
|
||||
},
|
||||
|
||||
// 展示失败占位图
|
||||
displayErrorholder: (context: CanvasRenderingContext2D, data: ImageKnifeData, imageKnifeOption: ImageKnifeOption, compWidth: number, compHeight: number, setGifTimeId?: (timeId: number) => void) => {
|
||||
this.drawErrorholder(context, data, imageKnifeOption, compWidth, compHeight, setGifTimeId)
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
build() {
|
||||
Stack() {
|
||||
|
||||
Text(this.percent)
|
||||
.fontSize(this.imageKnifeOption.size ? Math.min(this.imageKnifeOption.size.height, this.imageKnifeOption.size.width) / 2 : 24)
|
||||
.fontWeight(FontWeight.Bold)
|
||||
.visibility(this.retryVisible)
|
||||
.width(this.percentWidth)
|
||||
.height(this.percentHeight)
|
||||
|
||||
Image(this.imageKnifeRetry)
|
||||
.onClick(()=>{
|
||||
this.retryClick();
|
||||
Canvas(this.context)
|
||||
.width(this.componentWidth)
|
||||
.height(this.componentHeight)
|
||||
.onAreaChange((oldValue: Area, newValue: Area) => {
|
||||
this.currentWidth = newValue.width as number
|
||||
this.currentHeight = newValue.height as number
|
||||
console.log('onAreaChange stack currentWidth =' + this.currentWidth + ' currentHeight=' + this.currentHeight)
|
||||
if (this.onAreaCount > 0) {
|
||||
this.onAreaCount--;
|
||||
this.imageKnifeExecute()
|
||||
}
|
||||
})
|
||||
.backgroundColor(this.imageKnifeOption.backgroundColor ? this.imageKnifeOption.backgroundColor : Color.White)
|
||||
.margin(this.imageKnifeOption.margin ? this.imageKnifeOption.margin : { left: 0, top: 0, right: 0, bottom: 0 })
|
||||
.onReady(() => {
|
||||
})
|
||||
.onClick(() => {
|
||||
if (this.imageKnifeOption.canRetryClick && this.hasDisplayRetryholder) {
|
||||
this.retryClick()
|
||||
}
|
||||
})
|
||||
.visibility(this.retryVisible)
|
||||
.width(this.retryWidth)
|
||||
.height(this.retryHeight)
|
||||
|
||||
|
||||
|
||||
Image(this.normalPixelMap ? this.imageKnifePixelMapPack.pixelMap : (this.normalResource ? this.imageKnifeResource : this.imageKnifeString))
|
||||
.objectFit(this.imageKnifeOption.imageFit ? this.imageKnifeOption.imageFit : ImageFit.Fill)
|
||||
.visibility(this.imageVisible)
|
||||
.width(this.imageWidth)
|
||||
.height(this.imageHeight)
|
||||
}
|
||||
.width(this.imageKnifeOption.size ? this.imageKnifeOption.size.width : '100%')
|
||||
.height(this.imageKnifeOption.size ? this.imageKnifeOption.size.height : '100%')
|
||||
.backgroundColor(this.imageKnifeOption.backgroundColor ? this.imageKnifeOption.backgroundColor : Color.White)
|
||||
.margin(this.imageKnifeOption.margin ? this.imageKnifeOption.margin : { left: 0, top: 0, right: 0, bottom: 0 })
|
||||
}
|
||||
|
||||
watchImageKnifeOption() {
|
||||
this.imageKnifeExecute();
|
||||
console.log('watchImageKnifeOption is happened!')
|
||||
|
||||
if (this.imageKnifeOption.sizeAnimate) {
|
||||
animateTo(this.imageKnifeOption.sizeAnimate, () => {
|
||||
this.resetGifData();
|
||||
this.whetherWaitSize();
|
||||
})
|
||||
} else {
|
||||
this.resetGifData();
|
||||
this.whetherWaitSize();
|
||||
}
|
||||
}
|
||||
|
||||
retryClick(){
|
||||
this.hasRetry = true;
|
||||
whetherWaitSize() {
|
||||
this.componentWidth = this.imageKnifeOption.size.width
|
||||
this.componentHeight = this.imageKnifeOption.size.height
|
||||
if (this.newSizeEqualPreSize(this.imageKnifeOption.size)) {
|
||||
console.log('whetherWaitSize 宽高不变 直接发送请求')
|
||||
this.imageKnifeExecute()
|
||||
} else {
|
||||
this.onAreaCount++;
|
||||
// waitSize changed
|
||||
this.preSize = this.imageKnifeOption.size
|
||||
console.log('whetherWaitSize 宽高改变 等待组件回调onAreaChange后发送请求')
|
||||
}
|
||||
}
|
||||
|
||||
newSizeEqualPreSize(newSize: {
|
||||
width: string,
|
||||
height: string
|
||||
}): boolean {
|
||||
if (this.preSize.width == newSize.width && this.preSize.height == newSize.height) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
retryClick() {
|
||||
this.hasDisplayRetryholder = false;
|
||||
this.imageKnifeExecute();
|
||||
}
|
||||
|
||||
aboutToAppear() {
|
||||
console.log('imageKnifeComponent aboutToAppear happened!')
|
||||
this.imageKnifeExecute();
|
||||
this.onAreaCount++;
|
||||
this.componentWidth = this.imageKnifeOption.size.width
|
||||
this.componentHeight = this.imageKnifeOption.size.height
|
||||
}
|
||||
|
||||
configNecessary(request: RequestOption){
|
||||
configNecessary(request: RequestOption) {
|
||||
request.load(this.imageKnifeOption.loadSrc)
|
||||
.addListener((err, data) => {
|
||||
console.log('request.load callback')
|
||||
this.imageKnifeChangeSource(data)
|
||||
this.animateTo('image');
|
||||
return false;
|
||||
})
|
||||
.addListener((err, data) => {
|
||||
console.log('request.load callback')
|
||||
this.displayMainSource(data)
|
||||
return false;
|
||||
})
|
||||
|
||||
if (this.imageKnifeOption.size) {
|
||||
request.setImageViewSize(this.imageKnifeOption.size)
|
||||
let realSize = {
|
||||
width: this.currentWidth,
|
||||
height: this.currentHeight
|
||||
}
|
||||
request.setImageViewSize(realSize)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
configCacheStrategy(request: RequestOption){
|
||||
configCacheStrategy(request: RequestOption) {
|
||||
if (this.imageKnifeOption.onlyRetrieveFromCache) {
|
||||
request.retrieveDataFromCache(this.imageKnifeOption.onlyRetrieveFromCache)
|
||||
}
|
||||
|
@ -119,36 +191,30 @@ export struct ImageKnifeComponent {
|
|||
if (this.imageKnifeOption.allCacheInfoCallback) {
|
||||
request.addAllCacheInfoCallback(this.imageKnifeOption.allCacheInfoCallback)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
configDisplay(request: RequestOption){
|
||||
if(this.imageKnifeOption.animateDuration >= 0){
|
||||
request.animateDuration = this.imageKnifeOption.animateDuration;
|
||||
}
|
||||
configDisplay(request: RequestOption) {
|
||||
if (this.imageKnifeOption.placeholderSrc) {
|
||||
request.placeholder(this.imageKnifeOption.placeholderSrc, (data) => {
|
||||
console.log('request.placeholder callback')
|
||||
this.imageKnifeChangeSource(data)
|
||||
this.animateTo('image');
|
||||
this.displayPlaceholder(data)
|
||||
|
||||
})
|
||||
}
|
||||
if (this.imageKnifeOption.thumbSizeMultiplier) {
|
||||
request.thumbnail(this.imageKnifeOption.thumbSizeMultiplier, (data) => {
|
||||
console.log('request.thumbnail callback')
|
||||
this.imageKnifeChangeSource(data)
|
||||
this.animateTo('image');
|
||||
})
|
||||
this.displayThumbSizeMultiplier(data)
|
||||
}, this.imageKnifeOption.thumbSizeDelay)
|
||||
}
|
||||
if (this.imageKnifeOption.errorholderSrc) {
|
||||
request.errorholder(this.imageKnifeOption.errorholderSrc, (data) => {
|
||||
console.log('request.errorholder callback')
|
||||
this.imageKnifeChangeSource(data)
|
||||
this.animateTo('image');
|
||||
this.displayErrorholder(data)
|
||||
|
||||
})
|
||||
}
|
||||
if (this.imageKnifeOption.retryholderSrc) {
|
||||
this.imageKnifeRetry = this.imageKnifeOption.retryholderSrc
|
||||
}
|
||||
|
||||
if (this.imageKnifeOption.transform) {
|
||||
this.requestAddTransform(request)
|
||||
}
|
||||
|
@ -164,164 +230,301 @@ export struct ImageKnifeComponent {
|
|||
|
||||
|
||||
if (this.imageKnifeOption.displayProgress) {
|
||||
request.addProgressListener((percentValue: string) => {
|
||||
request.addProgressListener((percentValue: number) => {
|
||||
// 如果进度条百分比 未展示大小,展示其动画
|
||||
this.percent = percentValue;
|
||||
if(this.imageKnifeOption.displayProgressListener){
|
||||
this.imageKnifeOption.displayProgressListener(percentValue);
|
||||
}
|
||||
this.animateTo('progress');
|
||||
this.displayProgress(percentValue)
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
if(this.imageKnifeOption.retryLoad){
|
||||
request.addRetryListener((error: any) => {
|
||||
if (this.imageKnifeOption.retryholderSrc) {
|
||||
request.retryholder(this.imageKnifeOption.retryholderSrc, (data) => {
|
||||
console.log("RetryListener callback!")
|
||||
this.animateTo('retry');
|
||||
this.hasDisplayRetryholder = true
|
||||
this.displayRetryholder(data)
|
||||
})
|
||||
}
|
||||
}
|
||||
// imageknife 第一次启动和数据刷新后重新发送请求
|
||||
imageKnifeExecute() {
|
||||
let request = new RequestOption();
|
||||
this.configNecessary(request);
|
||||
this.configCacheStrategy(request);
|
||||
this.configDisplay(request);
|
||||
let request = new RequestOption();
|
||||
this.configNecessary(request);
|
||||
this.configCacheStrategy(request);
|
||||
this.configDisplay(request);
|
||||
globalThis.ImageKnife.call(request);
|
||||
}
|
||||
|
||||
imageKnifeChangeSource(data:ImageKnifeData) {
|
||||
this.imageKnifeSpecialFixed(data);
|
||||
}
|
||||
displayPlaceholder(data: ImageKnifeData) {
|
||||
|
||||
displayPixelMap(data:ImageKnifeData){
|
||||
console.log('displayPixelMap start')
|
||||
let pixelMapPack2 = new PixelMapPack();
|
||||
pixelMapPack2.pixelMap = data.imageKnifeValue as PixelMap;
|
||||
this.imageKnifePixelMapPack = pixelMapPack2;
|
||||
this.normalPixelMap = true;
|
||||
this.normalResource = true;
|
||||
console.log('displayPixelMap end')
|
||||
}
|
||||
|
||||
displayResource(data:ImageKnifeData){
|
||||
console.log('displayResource start')
|
||||
this.imageKnifeResource = data.imageKnifeValue as Resource;
|
||||
this.normalPixelMap = false;
|
||||
this.normalResource = true;
|
||||
console.log('displayResource end')
|
||||
}
|
||||
|
||||
displayString(data:ImageKnifeData){
|
||||
console.log('displayString start')
|
||||
let imageKnifeNeedStr = 'file://' + data.imageKnifeValue;
|
||||
console.log('imageKnifeNeedStr='+imageKnifeNeedStr)
|
||||
this.imageKnifeString = imageKnifeNeedStr;
|
||||
this.normalPixelMap = false;
|
||||
this.normalResource = false;
|
||||
console.log('displayString end')
|
||||
}
|
||||
imageKnifeSpecialFixed(data:ImageKnifeData) {
|
||||
if (data.isPixelMap()) {
|
||||
this.displayPixelMap(data);
|
||||
}
|
||||
else if (data.isString()) {
|
||||
this.displayString(data);
|
||||
} else if (data.isResource()) {
|
||||
this.displayResource(data);
|
||||
} else {
|
||||
}
|
||||
}
|
||||
|
||||
animateTo(name: string) {
|
||||
if (name == 'progress') {
|
||||
this.percentVisible = Visibility.Visible;
|
||||
this.imageVisible = Visibility.Hidden;
|
||||
this.retryVisible = Visibility.Hidden;
|
||||
if (this.percentWidth == '0%' || this.percentHeight == '0%') {
|
||||
animateTo({ duration: this.imageKnifeOption.animateDuration , curve: Curve.Linear }, () => {
|
||||
this.percentWidth = '100%';
|
||||
this.percentHeight = '100%';
|
||||
this.imageWidth = '0%';
|
||||
this.imageHeight = '0%';
|
||||
this.retryWidth = '0%';
|
||||
this.retryHeight = '0%';
|
||||
})
|
||||
}
|
||||
} else if (name == 'image') {
|
||||
this.imageVisible = Visibility.Visible;
|
||||
this.percentVisible = Visibility.Hidden;
|
||||
this.retryVisible = Visibility.Hidden;
|
||||
if (this.imageWidth == '0%' || this.imageHeight == '0%') {
|
||||
animateTo({ duration: this.imageKnifeOption.animateDuration, curve: Curve.Linear }, () => {
|
||||
this.imageWidth = '100%';
|
||||
this.imageHeight = '100%';
|
||||
this.percentWidth = '0%';
|
||||
this.percentHeight = '0%';
|
||||
this.retryWidth = '0%';
|
||||
this.retryHeight = '0%';
|
||||
})
|
||||
}
|
||||
} else if (name == 'retry') {
|
||||
this.retryVisible = Visibility.Visible;
|
||||
this.imageVisible = Visibility.Hidden;
|
||||
this.percentVisible = Visibility.Hidden;
|
||||
if (this.retryWidth == '0%' || this.retryHeight == '0%') {
|
||||
animateTo({ duration: this.imageKnifeOption.animateDuration, curve: Curve.Linear }, () => {
|
||||
this.imageWidth = '0%';
|
||||
this.imageHeight = '0%';
|
||||
this.percentWidth = '0%';
|
||||
this.percentHeight = '0%';
|
||||
this.retryWidth = '100%';
|
||||
this.retryHeight = '100%';
|
||||
if (!this.drawLifeCycleHasConsumed(this.imageKnifeOption.drawLifeCycle, 'displayPlaceholder', this.context, data, this.imageKnifeOption,
|
||||
this.currentWidth, this.currentHeight, (gifTimeId) => {
|
||||
this.setGifTimeId(gifTimeId)
|
||||
})) {
|
||||
if (!this.drawLifeCycleHasConsumed(globalThis.ImageKnife.getDefaultLifeCycle(), 'displayPlaceholder', this.context, data, this.imageKnifeOption,
|
||||
this.currentWidth, this.currentHeight, (gifTimeId) => {
|
||||
this.setGifTimeId(gifTimeId)
|
||||
})) {
|
||||
this.defaultLifeCycle.displayPlaceholder(this.context, data, this.imageKnifeOption, this.currentWidth, this.currentHeight, (gifTimeId) => {
|
||||
this.setGifTimeId(gifTimeId)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
requestAddTransform(request:RequestOption){
|
||||
if(TransformType.BlurTransformation == this.imageKnifeOption.transform.transformType){
|
||||
displayProgress(percent: number) {
|
||||
|
||||
if (!this.drawLifeCycleHasConsumed(this.imageKnifeOption.drawLifeCycle, 'displayProgress', this.context, percent, this.imageKnifeOption,
|
||||
this.currentWidth, this.currentHeight, (gifTimeId) => {
|
||||
this.setGifTimeId(gifTimeId)
|
||||
})) {
|
||||
if (!this.drawLifeCycleHasConsumed(globalThis.ImageKnife.getDefaultLifeCycle(), 'displayProgress', this.context, percent, this.imageKnifeOption,
|
||||
this.currentWidth, this.currentHeight, (gifTimeId) => {
|
||||
this.setGifTimeId(gifTimeId)
|
||||
})) {
|
||||
this.defaultLifeCycle.displayProgress(this.context, percent, this.imageKnifeOption, this.currentWidth, this.currentHeight, (gifTimeId) => {
|
||||
this.setGifTimeId(gifTimeId)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
displayThumbSizeMultiplier(data: ImageKnifeData) {
|
||||
|
||||
if (!this.drawLifeCycleHasConsumed(this.imageKnifeOption.drawLifeCycle, 'displayThumbSizeMultiplier', this.context, data, this.imageKnifeOption,
|
||||
this.currentWidth, this.currentHeight, (gifTimeId) => {
|
||||
this.setGifTimeId(gifTimeId)
|
||||
})) {
|
||||
if (!this.drawLifeCycleHasConsumed(globalThis.ImageKnife.getDefaultLifeCycle(), 'displayThumbSizeMultiplier', this.context, data, this.imageKnifeOption,
|
||||
this.currentWidth, this.currentHeight, (gifTimeId) => {
|
||||
this.setGifTimeId(gifTimeId)
|
||||
})) {
|
||||
this.defaultLifeCycle.displayThumbSizeMultiplier(this.context, data, this.imageKnifeOption, this.currentWidth, this.currentHeight, (gifTimeId) => {
|
||||
this.setGifTimeId(gifTimeId)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
displayMainSource(data: ImageKnifeData) {
|
||||
|
||||
if (!this.drawLifeCycleHasConsumed(this.imageKnifeOption.drawLifeCycle, 'displayMainSource', this.context, data, this.imageKnifeOption,
|
||||
this.currentWidth, this.currentHeight, (gifTimeId) => {
|
||||
this.setGifTimeId(gifTimeId)
|
||||
})) {
|
||||
if (!this.drawLifeCycleHasConsumed(globalThis.ImageKnife.getDefaultLifeCycle(), 'displayMainSource', this.context, data, this.imageKnifeOption,
|
||||
this.currentWidth, this.currentHeight, (gifTimeId) => {
|
||||
this.setGifTimeId(gifTimeId)
|
||||
})) {
|
||||
this.defaultLifeCycle.displayMainSource(this.context, data, this.imageKnifeOption, this.currentWidth, this.currentHeight, (gifTimeId) => {
|
||||
this.setGifTimeId(gifTimeId)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
displayRetryholder(data: ImageKnifeData) {
|
||||
if (!this.drawLifeCycleHasConsumed(this.imageKnifeOption.drawLifeCycle, 'displayRetryholder', this.context, data, this.imageKnifeOption,
|
||||
this.currentWidth, this.currentHeight, (gifTimeId) => {
|
||||
this.setGifTimeId(gifTimeId)
|
||||
})) {
|
||||
if (!this.drawLifeCycleHasConsumed(globalThis.ImageKnife.getDefaultLifeCycle(), 'displayRetryholder', this.context, data, this.imageKnifeOption,
|
||||
this.currentWidth, this.currentHeight, (gifTimeId) => {
|
||||
this.setGifTimeId(gifTimeId)
|
||||
})) {
|
||||
this.defaultLifeCycle.displayRetryholder(this.context, data, this.imageKnifeOption, this.currentWidth, this.currentHeight, (gifTimeId) => {
|
||||
this.setGifTimeId(gifTimeId)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
displayErrorholder(data: ImageKnifeData) {
|
||||
|
||||
if (!this.drawLifeCycleHasConsumed(this.imageKnifeOption.drawLifeCycle, 'displayErrorholder', this.context, data, this.imageKnifeOption,
|
||||
this.currentWidth, this.currentHeight, (gifTimeId) => {
|
||||
this.setGifTimeId(gifTimeId)
|
||||
})) {
|
||||
if (!this.drawLifeCycleHasConsumed(globalThis.ImageKnife.getDefaultLifeCycle(), 'displayErrorholder', this.context, data, this.imageKnifeOption,
|
||||
this.currentWidth, this.currentHeight, (gifTimeId) => {
|
||||
this.setGifTimeId(gifTimeId)
|
||||
})) {
|
||||
this.defaultLifeCycle.displayErrorholder(this.context, data, this.imageKnifeOption, this.currentWidth, this.currentHeight, (gifTimeId) => {
|
||||
this.setGifTimeId(gifTimeId)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
drawPlaceholder(context: CanvasRenderingContext2D, data: ImageKnifeData, imageKnifeOption: ImageKnifeOption, compWidth: number, compHeight: number, setGifTimeId?: (timeId: number) => void) {
|
||||
console.log('default drawPlaceholder start!')
|
||||
// @ts-ignore
|
||||
data.drawPixelMap.imagePixelMap.getImageInfo().then((imageInfo) => {
|
||||
console.log('imageinfo widht =' + imageInfo.size.width + ' height=' + imageInfo.size.height)
|
||||
let scaleType = (typeof imageKnifeOption.placeholderScaleType == 'number') ? imageKnifeOption.placeholderScaleType : ScaleType.FIT_CENTER
|
||||
context.save();
|
||||
context.clearRect(0, 0, compWidth, compHeight)
|
||||
ScaleTypeHelper.drawImageWithScaleType(context, scaleType, data.drawPixelMap.imagePixelMap, px2vp(imageInfo.size.width), px2vp(imageInfo.size.height), compWidth, compHeight, 0, 0)
|
||||
context.restore();
|
||||
console.log('default drawPlaceholder end!')
|
||||
})
|
||||
}
|
||||
|
||||
drawProgress(context: CanvasRenderingContext2D, progress: number, imageKnifeOption: ImageKnifeOption, compWidth: number, compHeight: number, setGifTimeId?: (timeId: number) => void) {
|
||||
let pi = Math.PI * 2 / 100; //pi 讲圆的周长划分为100份
|
||||
let rate = progress - 25;
|
||||
let diameter = compWidth > compHeight ? compHeight : compWidth
|
||||
context.lineWidth = Math.floor(diameter * 0.03)
|
||||
context.lineCap = "round"
|
||||
context.fillStyle = "#10a5ff"
|
||||
context.font = Math.floor(diameter * 0.3 * px2vp(1)) + 'px'
|
||||
|
||||
let x0 = (compWidth - diameter) / 2.0 + Math.floor(diameter * 0.5)
|
||||
let y0 = (compHeight - diameter) / 2.0 + Math.floor(diameter * 0.1)
|
||||
|
||||
let x1 = (compWidth - diameter) / 2.0 + Math.floor(diameter * 0.5)
|
||||
let y1 = (compHeight - diameter) / 2.0 + Math.floor(diameter * 0.8)
|
||||
let gradient = context.createLinearGradient(x0, y0, x1, y1)
|
||||
gradient.addColorStop(0, "#11ffe4")
|
||||
gradient.addColorStop(0.5, "#03c6fd")
|
||||
gradient.addColorStop(1, "#10a5ff")
|
||||
|
||||
context.clearRect(0, 0, compWidth, compHeight)
|
||||
context.shadowBlur = 0
|
||||
context.beginPath()
|
||||
context.strokeStyle = "#15222d"
|
||||
let radius = Math.floor(diameter * 0.3)
|
||||
let arcX = compWidth / 2.0
|
||||
let arcY = compHeight / 2.0
|
||||
context.arc(arcX, arcY, radius, 0, Math.PI * 2, true)
|
||||
context.stroke()
|
||||
context.beginPath()
|
||||
let showText = rate + 25 + '%'
|
||||
let metrics = context.measureText(showText)
|
||||
let textX = (compWidth / 2.0) - metrics.width / 2.0
|
||||
let textY = (compHeight / 2.0) + metrics.height * 0.3
|
||||
context.fillText(showText, textX, textY)
|
||||
context.stroke()
|
||||
context.beginPath()
|
||||
context.strokeStyle = gradient
|
||||
context.arc(arcX, arcY, radius, pi * -25, pi * rate)
|
||||
context.stroke();
|
||||
}
|
||||
|
||||
drawThumbSizeMultiplier(context: CanvasRenderingContext2D, data: ImageKnifeData, imageKnifeOption: ImageKnifeOption, compWidth: number, compHeight: number, setGifTimeId?: (timeId: number) => void) {
|
||||
console.log('default drawThumbSizeMultiplier start!')
|
||||
// @ts-ignore
|
||||
data.drawPixelMap.imagePixelMap.getImageInfo().then((imageInfo) => {
|
||||
console.log('imageinfo widht =' + imageInfo.size.width + ' height=' + imageInfo.size.height)
|
||||
let scaleType = (typeof imageKnifeOption.thumbSizeMultiplierScaleType == 'number') ? imageKnifeOption.thumbSizeMultiplierScaleType : ScaleType.FIT_CENTER
|
||||
context.save();
|
||||
context.clearRect(0, 0, compWidth, compHeight)
|
||||
ScaleTypeHelper.drawImageWithScaleType(context, scaleType, data.drawPixelMap.imagePixelMap, px2vp(imageInfo.size.width), px2vp(imageInfo.size.height), compWidth, compHeight, 0, 0)
|
||||
context.restore();
|
||||
console.log('default drawThumbSizeMultiplier end!')
|
||||
})
|
||||
}
|
||||
|
||||
drawMainSource(context: CanvasRenderingContext2D, data: ImageKnifeData, imageKnifeOption: ImageKnifeOption, compWidth: number, compHeight: number, setGifTimeId?: (timeId: number) => void) {
|
||||
console.log('default drawMainSource start!')
|
||||
if (data.isPixelMap()) {
|
||||
// @ts-ignore
|
||||
data.drawPixelMap.imagePixelMap.getImageInfo().then((imageInfo) => {
|
||||
let scaleType = (typeof imageKnifeOption.mainScaleType == 'number') ? imageKnifeOption.mainScaleType : ScaleType.FIT_CENTER
|
||||
console.log('imageinfo width =' + imageInfo.size.width + ' height=' + imageInfo.size.height + 'scaleType=' + scaleType)
|
||||
context.save();
|
||||
context.clearRect(0, 0, compWidth, compHeight)
|
||||
ScaleTypeHelper.drawImageWithScaleType(context, scaleType, data.drawPixelMap.imagePixelMap, px2vp(imageInfo.size.width), px2vp(imageInfo.size.height), compWidth, compHeight, 0, 0)
|
||||
context.restore();
|
||||
console.log('default drawMainSource end!')
|
||||
})
|
||||
} else if (data.isGIFFrame()) {
|
||||
this.drawGIFFrame(context, data, imageKnifeOption, compWidth, compHeight, setGifTimeId)
|
||||
}
|
||||
}
|
||||
|
||||
drawRetryholder(context: CanvasRenderingContext2D, data: ImageKnifeData, imageKnifeOption: ImageKnifeOption, compWidth: number, compHeight: number, setGifTimeId?: (timeId: number) => void) {
|
||||
console.log('default drawRetryholder start!')
|
||||
// @ts-ignore
|
||||
data.drawPixelMap.imagePixelMap.getImageInfo().then((imageInfo) => {
|
||||
console.log('imageinfo width =' + imageInfo.size.width + ' height=' + imageInfo.size.height)
|
||||
let scaleType = (typeof imageKnifeOption.retryholderScaleType == 'number') ? imageKnifeOption.retryholderScaleType : ScaleType.FIT_CENTER
|
||||
context.save();
|
||||
context.clearRect(0, 0, compWidth, compHeight)
|
||||
ScaleTypeHelper.drawImageWithScaleType(context, scaleType, data.drawPixelMap.imagePixelMap, px2vp(imageInfo.size.width), px2vp(imageInfo.size.height), compWidth, compHeight, 0, 0)
|
||||
context.restore();
|
||||
console.log('default drawRetryholder end!')
|
||||
})
|
||||
}
|
||||
|
||||
drawErrorholder(context: CanvasRenderingContext2D, data: ImageKnifeData, imageKnifeOption: ImageKnifeOption, compWidth: number, compHeight: number, setGifTimeId?: (timeId: number) => void) {
|
||||
console.log('default drawErrorholder start!')
|
||||
// @ts-ignore
|
||||
data.drawPixelMap.imagePixelMap.getImageInfo().then((imageInfo) => {
|
||||
console.log('imageinfo widht =' + imageInfo.size.width + ' height=' + imageInfo.size.height)
|
||||
let scaleType = (typeof imageKnifeOption.errorholderSrcScaleType == 'number') ? imageKnifeOption.errorholderSrcScaleType : ScaleType.FIT_CENTER
|
||||
context.save();
|
||||
context.clearRect(0, 0, compWidth, compHeight)
|
||||
ScaleTypeHelper.drawImageWithScaleType(context, scaleType, data.drawPixelMap.imagePixelMap, px2vp(imageInfo.size.width), px2vp(imageInfo.size.height), compWidth, compHeight, 0, 0)
|
||||
context.restore();
|
||||
console.log('default drawErrorholder end!')
|
||||
})
|
||||
}
|
||||
|
||||
requestAddTransform(request: RequestOption) {
|
||||
if (TransformType.BlurTransformation == this.imageKnifeOption.transform.transformType) {
|
||||
request.blur(this.imageKnifeOption.transform.blur)
|
||||
}else if(TransformType.BrightnessFilterTransformation == this.imageKnifeOption.transform.transformType){
|
||||
} else if (TransformType.BrightnessFilterTransformation == this.imageKnifeOption.transform.transformType) {
|
||||
request.brightnessFilter(this.imageKnifeOption.transform.brightnessFilter)
|
||||
}else if(TransformType.ContrastFilterTransformation == this.imageKnifeOption.transform.transformType){
|
||||
} else if (TransformType.ContrastFilterTransformation == this.imageKnifeOption.transform.transformType) {
|
||||
request.contrastFilter(this.imageKnifeOption.transform.contrastFilter)
|
||||
}else if(TransformType.CropCircleTransformation == this.imageKnifeOption.transform.transformType){
|
||||
} else if (TransformType.CropCircleTransformation == this.imageKnifeOption.transform.transformType) {
|
||||
request.cropCircle()
|
||||
}else if(TransformType.CropCircleWithBorderTransformation == this.imageKnifeOption.transform.transformType){
|
||||
} else if (TransformType.CropCircleWithBorderTransformation == this.imageKnifeOption.transform.transformType) {
|
||||
request.cropCircleWithBorder(this.imageKnifeOption.transform.cropCircleWithBorder.border, this.imageKnifeOption.transform.cropCircleWithBorder.obj)
|
||||
}else if(TransformType.CropSquareTransformation == this.imageKnifeOption.transform.transformType){
|
||||
} else if (TransformType.CropSquareTransformation == this.imageKnifeOption.transform.transformType) {
|
||||
request.cropSquare()
|
||||
}else if(TransformType.CropTransformation == this.imageKnifeOption.transform.transformType){
|
||||
request.crop(this.imageKnifeOption.transform.crop.width,this.imageKnifeOption.transform.crop.height,this.imageKnifeOption.transform.crop.cropType)
|
||||
}else if(TransformType.GrayscaleTransformation == this.imageKnifeOption.transform.transformType){
|
||||
} else if (TransformType.CropTransformation == this.imageKnifeOption.transform.transformType) {
|
||||
request.crop(this.imageKnifeOption.transform.crop.width, this.imageKnifeOption.transform.crop.height, this.imageKnifeOption.transform.crop.cropType)
|
||||
} else if (TransformType.GrayscaleTransformation == this.imageKnifeOption.transform.transformType) {
|
||||
request.grayscale()
|
||||
}else if(TransformType.InvertFilterTransformation == this.imageKnifeOption.transform.transformType){
|
||||
} else if (TransformType.InvertFilterTransformation == this.imageKnifeOption.transform.transformType) {
|
||||
request.invertFilter()
|
||||
}else if(TransformType.MaskTransformation == this.imageKnifeOption.transform.transformType){
|
||||
} else if (TransformType.MaskTransformation == this.imageKnifeOption.transform.transformType) {
|
||||
request.mask(this.imageKnifeOption.transform.mask)
|
||||
}else if(TransformType.PixelationFilterTransformation == this.imageKnifeOption.transform.transformType){
|
||||
} else if (TransformType.PixelationFilterTransformation == this.imageKnifeOption.transform.transformType) {
|
||||
request.pixelationFilter(this.imageKnifeOption.transform.pixelationFilter)
|
||||
}else if(TransformType.RotateImageTransformation == this.imageKnifeOption.transform.transformType){
|
||||
} else if (TransformType.RotateImageTransformation == this.imageKnifeOption.transform.transformType) {
|
||||
request.rotateImage(this.imageKnifeOption.transform.rotateImage)
|
||||
}else if(TransformType.RoundedCornersTransformation == this.imageKnifeOption.transform.transformType){
|
||||
} else if (TransformType.RoundedCornersTransformation == this.imageKnifeOption.transform.transformType) {
|
||||
request.roundedCorners(this.imageKnifeOption.transform.roundedCorners)
|
||||
}else if(TransformType.SepiaFilterTransformation == this.imageKnifeOption.transform.transformType){
|
||||
} else if (TransformType.SepiaFilterTransformation == this.imageKnifeOption.transform.transformType) {
|
||||
request.sepiaFilter()
|
||||
}else if(TransformType.SketchFilterTransformation == this.imageKnifeOption.transform.transformType){
|
||||
} else if (TransformType.SketchFilterTransformation == this.imageKnifeOption.transform.transformType) {
|
||||
request.sketchFilter()
|
||||
}else if(TransformType.SwirlFilterTransformation == this.imageKnifeOption.transform.transformType){
|
||||
} else if (TransformType.SwirlFilterTransformation == this.imageKnifeOption.transform.transformType) {
|
||||
request.swirlFilter(this.imageKnifeOption.transform.swirlFilter)
|
||||
}else if(TransformType.CenterCrop == this.imageKnifeOption.transform.transformType){
|
||||
} else if (TransformType.CenterCrop == this.imageKnifeOption.transform.transformType) {
|
||||
request.centerCrop()
|
||||
}else if(TransformType.CenterInside == this.imageKnifeOption.transform.transformType){
|
||||
} else if (TransformType.CenterInside == this.imageKnifeOption.transform.transformType) {
|
||||
request.centerInside()
|
||||
}else if(TransformType.FitCenter == this.imageKnifeOption.transform.transformType){
|
||||
} else if (TransformType.FitCenter == this.imageKnifeOption.transform.transformType) {
|
||||
request.fitCenter()
|
||||
}
|
||||
}
|
||||
|
||||
aboutToDisappear() {
|
||||
this.resetGifData();
|
||||
}
|
||||
|
||||
onPageShow() {
|
||||
|
@ -332,6 +535,278 @@ export struct ImageKnifeComponent {
|
|||
|
||||
onBackPress() {
|
||||
}
|
||||
|
||||
setGifTimeId(timeId: number) {
|
||||
this.gifTimerId = timeId;
|
||||
}
|
||||
|
||||
private drawLifeCycleHasConsumed<K, T>(drawLifeCycle: IDrawLifeCycle, methodName: string,
|
||||
context: CanvasRenderingContext2D, data: K, imageKnifeOption: T, compWidth: number, compHeight: number, setGifTimeId?: (timeId: number) => void
|
||||
) {
|
||||
if (drawLifeCycle && drawLifeCycle[methodName]) {
|
||||
return drawLifeCycle[methodName](context, data, imageKnifeOption, compWidth, compHeight, setGifTimeId)
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private drawGIFFrame(context: CanvasRenderingContext2D, data: ImageKnifeData, imageKnifeOption: ImageKnifeOption, compWidth: number, compHeight: number, setGifTimeId?: (timeId: number) => void) {
|
||||
let frames = data.drawGIFFrame.imageGIFFrames as GIFFrame[]
|
||||
console.log('gifFrameLength =' + frames.length);
|
||||
if (imageKnifeOption.gif && (typeof (imageKnifeOption.gif.seekTo) == 'number') && imageKnifeOption.gif.seekTo >= 0) {
|
||||
this.autoPlay = false;
|
||||
context.clearRect(0, 0, compWidth, compHeight)
|
||||
this.drawSeekToFrame(frames, context, compWidth, compHeight)
|
||||
} else {
|
||||
this.autoPlay = true
|
||||
context.clearRect(0, 0, compWidth, compHeight)
|
||||
this.renderFrames.bind(this, frames, 0, context, compWidth, compHeight)()
|
||||
}
|
||||
}
|
||||
|
||||
private resetGifData() {
|
||||
clearTimeout(this.gifTimerId)
|
||||
this.gifLoopDuration = 0;
|
||||
this.startGifLoopTime = 0;
|
||||
this.endGifLoopTime = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 绘制直接到第几帧方法,由于gif非第一帧数据可能是不全的,这里采用逐帧渲染的方式来绘制保证图像的完整性
|
||||
*/
|
||||
private drawSeekToFrame(frames: GIFFrame[], context: CanvasRenderingContext2D, compWidth: number, compHeight: number) {
|
||||
for (let i = 0; i < this.imageKnifeOption.gif; i++) {
|
||||
this.drawFrame(frames, i, context, compWidth, compHeight);
|
||||
}
|
||||
}
|
||||
|
||||
private renderFrames(frames: GIFFrame[], index: number, context: CanvasRenderingContext2D, compWidth: number, compHeight: number) {
|
||||
console.log('renderFrames frames length =' + frames.length)
|
||||
let start = new Date().getTime();
|
||||
if (index === 0) {
|
||||
// 如果是第一帧,我们只从开始渲染前记录时间
|
||||
this.startGifLoopTime = start;
|
||||
}
|
||||
// draw Frame
|
||||
this.drawFrame(frames, index, context, compWidth, compHeight);
|
||||
|
||||
// 记录渲染结束时间点
|
||||
let end = new Date().getTime();
|
||||
let diff = end - start
|
||||
|
||||
if (this.autoPlay) {
|
||||
|
||||
// 理论上该帧在屏幕上保留的时间
|
||||
let stayTime = frames[index].delay;
|
||||
if (this.imageKnifeOption.gif && this.imageKnifeOption.gif.speedFactory) {
|
||||
stayTime = frames[index].delay / (this.imageKnifeOption.gif.speedFactory * 1.0);
|
||||
}
|
||||
// 减去程序执行消耗,剩余的准确延迟时间
|
||||
let delayTime = Math.max(0, Math.floor(stayTime - diff));
|
||||
|
||||
this.endGifLoopTime = end;
|
||||
// 当前gif到第N帧,所对应的N渲染时间,和N-1的停留时间。(第一帧只有渲染时间没有停留时间)
|
||||
let loopStayTime = this.endGifLoopTime - this.startGifLoopTime;
|
||||
this.startGifLoopTime = end;
|
||||
// 整个gif累计的时长;
|
||||
this.gifLoopDuration += loopStayTime;
|
||||
// 返回gif一次循环结束回调,并且把当前循环的时间给出
|
||||
if (index === (frames.length - 1) && this.imageKnifeOption.gif && this.imageKnifeOption.gif.loopFinish) {
|
||||
this.imageKnifeOption.gif.loopFinish(this.gifLoopDuration)
|
||||
this.gifLoopDuration = 0;
|
||||
}
|
||||
// update the frame index
|
||||
index++
|
||||
if (index >= frames.length) {
|
||||
index = 0;
|
||||
}
|
||||
this.gifTimerId = setTimeout(this.renderFrames.bind(this, frames, index, context, compWidth, compHeight), delayTime)
|
||||
}
|
||||
}
|
||||
|
||||
private drawFrame(frames: GIFFrame[], index: number, context: CanvasRenderingContext2D, compWidth: number, compHeight: number) {
|
||||
// get current frame
|
||||
let frame = frames[index];
|
||||
if (!frame || !context) {
|
||||
// 数据保护,绘制保护
|
||||
return;
|
||||
}
|
||||
|
||||
if (!frame['drawPixelMap']) {
|
||||
// 解码之后已经转为PixelMap
|
||||
} else {
|
||||
this.canvasDrawPixelMap(frames, index, context, compWidth, compHeight)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 具体绘制过程
|
||||
private canvasDrawPixelMap(frames: GIFFrame[], index: number, context: CanvasRenderingContext2D, compWidth: number, compHeight: number) {
|
||||
console.log('canvasDrawPixelMap index=' + index)
|
||||
let frame = frames[index];
|
||||
let pixelmap = frame['drawPixelMap']
|
||||
let disposal = 0
|
||||
// disposal value is from preFrame
|
||||
if (index >= 1) {
|
||||
let preFrame = frames[index-1]
|
||||
disposal = preFrame.disposalType
|
||||
}
|
||||
if (disposal === FrameDisposalType.DISPOSE_RestoreBackground) {
|
||||
context.clearRect(0, 0, compWidth, compHeight)
|
||||
}
|
||||
let scaleType = (typeof this.imageKnifeOption.mainScaleType == 'number') ? this.imageKnifeOption.mainScaleType : ScaleType.FIT_CENTER
|
||||
context.save();
|
||||
let frameW = frames[0].dims.left + frames[0].dims.width
|
||||
let frameH = frames[0].dims.top + frames[0].dims.height
|
||||
ScaleTypeHelper.drawImageWithScaleType(context, scaleType, pixelmap, px2vp(frameW), px2vp(frameH), compWidth, compHeight, px2vp(frame.dims.left), px2vp(frame.dims.top))
|
||||
// tips:worker如果不是在展示页面中创建,使用子线程回来的数据创建的图片,会导致canvas绘制不出来
|
||||
context.restore();
|
||||
console.log('default drawMainSource end!')
|
||||
}
|
||||
}
|
||||
|
||||
export enum FrameDisposalType {
|
||||
// 0 - No disposal specified. The decoder is not required to take any action.
|
||||
// 不使用处置方法
|
||||
DISPOSE_Nothing = 0,
|
||||
// 1-Do not dispose. The graphic is to be left in place.
|
||||
// 不处置图形,把图形从当前位置移去
|
||||
DISPOSE_NotResolve = 1,
|
||||
// 2 - Restore to background color. The area used by the graphic must be restored to the background color.
|
||||
// 回复到背景色
|
||||
DISPOSE_RestoreBackground = 2,
|
||||
// 3-Restore to previous
|
||||
DISPOSE_PreviousStatus = 3
|
||||
}
|
||||
|
||||
export enum ScaleType {
|
||||
// 图像位于用户设置组件左上角显示,图像会缩放至全部展示
|
||||
FIT_START = 1,
|
||||
// 图像位于用户设置组件右下角显示,图像会缩放至全部展示
|
||||
FIT_END = 2,
|
||||
// 图像位于用户设置组件居中,图像会缩放至全部展示
|
||||
FIT_CENTER = 3,
|
||||
// 图像绝对居中展示,不缩放
|
||||
CENTER = 4,
|
||||
// 宽高中,短的部分缩放至组件大小,超出的全部裁剪
|
||||
CENTER_CROP = 5,
|
||||
// 图像拉伸至组件大小
|
||||
FIT_XY = 6,
|
||||
// 如果图像大于组件则执行FIT_CENTER,小于组件则CENTER
|
||||
CENTER_INSIDE = 7,
|
||||
// 如果不想适配,直接展示原图大小
|
||||
NONE = 8
|
||||
}
|
||||
|
||||
export class ScaleTypeHelper {
|
||||
static drawImageWithScaleType(context: CanvasRenderingContext2D, scaleType: ScaleType, source: PixelMap | ImageBitmap, imageWidth: number, imageHeight: number, compWidth: number, compHeight: number, imageOffsetX: number, imageOffsetY: number) {
|
||||
let scaleW = compWidth / imageWidth
|
||||
let scaleH = compHeight / imageHeight
|
||||
let minScale = scaleW > scaleH ? scaleH : scaleW
|
||||
let maxScale = scaleW > scaleH ? scaleW : scaleH
|
||||
|
||||
switch (scaleType) {
|
||||
case ScaleType.FIT_START:
|
||||
ScaleTypeHelper.drawFitStart(context, source, minScale, imageWidth, imageHeight, imageOffsetX, imageOffsetY)
|
||||
break;
|
||||
case ScaleType.FIT_END:
|
||||
ScaleTypeHelper.drawFitEnd(context, source, minScale, imageWidth, imageHeight, compWidth, compHeight, imageOffsetX, imageOffsetY)
|
||||
break;
|
||||
case ScaleType.FIT_CENTER:
|
||||
ScaleTypeHelper.drawFitCenter(context, source, minScale, imageWidth, imageHeight, compWidth, compHeight, imageOffsetX, imageOffsetY)
|
||||
break;
|
||||
case ScaleType.CENTER:
|
||||
ScaleTypeHelper.drawCenter(context, source, imageWidth, imageHeight, compWidth, compHeight, imageOffsetX, imageOffsetY)
|
||||
break;
|
||||
case ScaleType.CENTER_CROP:
|
||||
ScaleTypeHelper.drawCenterCrop(context, source, maxScale, imageWidth, imageHeight, compWidth, compHeight, imageOffsetX, imageOffsetY)
|
||||
break;
|
||||
case ScaleType.FIT_XY:
|
||||
ScaleTypeHelper.drawFitXY(context, source, scaleW, scaleH, imageWidth, imageHeight, imageOffsetX, imageOffsetY)
|
||||
break;
|
||||
case ScaleType.CENTER_INSIDE:
|
||||
ScaleTypeHelper.drawCenterInside(context, source, minScale, imageWidth, imageHeight, compWidth, compHeight, imageOffsetX, imageOffsetY)
|
||||
break;
|
||||
case ScaleType.NONE:
|
||||
ScaleTypeHelper.drawNone(context, source, imageWidth, imageHeight, imageOffsetX, imageOffsetY)
|
||||
break;
|
||||
default:
|
||||
ScaleTypeHelper.drawNone(context, source, imageWidth, imageHeight, imageOffsetX, imageOffsetY)
|
||||
break
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static drawFitStart(context: CanvasRenderingContext2D, source: PixelMap | ImageBitmap, minScale: number, imageWidth: number, imageHeight: number, imageOffsetX?: number, imageOffsetY?: number) {
|
||||
context.setTransform(minScale, 0, 0, minScale, 0, 0)
|
||||
let dx = 0
|
||||
let dy = 0
|
||||
let dw = imageWidth;
|
||||
let dh = imageHeight;
|
||||
context.drawImage(source, dx + imageOffsetX, dy + imageOffsetY)
|
||||
}
|
||||
|
||||
static drawFitEnd(context: CanvasRenderingContext2D, source: PixelMap | ImageBitmap, minScale: number, imageWidth: number, imageHeight: number, compWidth: number, compHeight: number, imageOffsetX?: number, imageOffsetY?: number) {
|
||||
context.setTransform(minScale, 0, 0, minScale, 0, 0)
|
||||
|
||||
let dx = (compWidth - imageWidth * minScale) / (minScale * 1.0);
|
||||
let dy = (compHeight - imageHeight * minScale) / (minScale * 1.0);
|
||||
let dw = imageWidth;
|
||||
let dh = imageHeight;
|
||||
|
||||
context.drawImage(source, dx + imageOffsetX, dy + imageOffsetY)
|
||||
}
|
||||
|
||||
static drawFitCenter(context: CanvasRenderingContext2D, source: PixelMap | ImageBitmap, minScale: number, imageWidth: number, imageHeight: number, compWidth: number, compHeight: number, imageOffsetX?: number, imageOffsetY?: number) {
|
||||
context.setTransform(minScale, 0, 0, minScale, 0, 0)
|
||||
let dx = (compWidth - imageWidth * minScale) / (minScale * 2.0);
|
||||
let dy = (compHeight - imageHeight * minScale) / (minScale * 2.0);
|
||||
let dw = imageWidth;
|
||||
let dh = imageHeight;
|
||||
|
||||
context.drawImage(source, dx + imageOffsetX, dy + imageOffsetY)
|
||||
}
|
||||
|
||||
static drawCenter(context: CanvasRenderingContext2D, source: PixelMap | ImageBitmap, imageWidth: number, imageHeight: number, compWidth: number, compHeight: number, imageOffsetX?: number, imageOffsetY?: number) {
|
||||
let dx = (compWidth - imageWidth) / 2.0;
|
||||
let dy = (compHeight - imageHeight) / 2.0;
|
||||
let dw = imageWidth;
|
||||
let dh = imageHeight;
|
||||
context.drawImage(source, dx + imageOffsetX, dy + imageOffsetY)
|
||||
}
|
||||
|
||||
static drawCenterCrop(context: CanvasRenderingContext2D, source: PixelMap | ImageBitmap, maxScale: number, imageWidth: number, imageHeight: number, compWidth: number, compHeight: number, imageOffsetX?: number, imageOffsetY?: number) {
|
||||
context.setTransform(maxScale, 0, 0, maxScale, 0, 0)
|
||||
let dx = (compWidth - imageWidth * maxScale) / (maxScale * 2.0);
|
||||
let dy = (compHeight - imageHeight * maxScale) / (maxScale * 2.0);
|
||||
let dw = imageWidth;
|
||||
let dh = imageHeight;
|
||||
context.drawImage(source, dx + imageOffsetX, dy + imageOffsetY)
|
||||
}
|
||||
|
||||
static drawFitXY(context: CanvasRenderingContext2D, source: PixelMap | ImageBitmap, scaleW: number, scaleH: number, imageWidth: number, imageHeight: number, imageOffsetX?: number, imageOffsetY?: number) {
|
||||
context.setTransform(scaleW, 0, 0, scaleH, 0, 0)
|
||||
let dx = 0;
|
||||
let dy = 0;
|
||||
let dw = imageWidth;
|
||||
let dh = imageHeight;
|
||||
context.drawImage(source, dx + imageOffsetX, dy + imageOffsetY)
|
||||
}
|
||||
|
||||
static drawCenterInside(context: CanvasRenderingContext2D, source: PixelMap | ImageBitmap, minScale: number, imageWidth: number, imageHeight: number, compWidth: number, compHeight: number, imageOffsetX?: number, imageOffsetY?: number) {
|
||||
if (minScale < 1) {
|
||||
ScaleTypeHelper.drawFitCenter(context, source, minScale, imageWidth, imageHeight, compWidth, compHeight, imageOffsetX, imageOffsetY)
|
||||
} else {
|
||||
ScaleTypeHelper.drawCenter(context, source, imageWidth, imageHeight, compWidth, compHeight, imageOffsetX, imageOffsetY)
|
||||
}
|
||||
}
|
||||
|
||||
static drawNone(context: CanvasRenderingContext2D, source: PixelMap | ImageBitmap, imageWidth: number, imageHeight: number, imageOffsetX?: number, imageOffsetY?: number) {
|
||||
let dx = 0;
|
||||
let dy = 0;
|
||||
let dw = imageWidth;
|
||||
let dh = imageHeight;
|
||||
context.drawImage(source, dx + imageOffsetX, dy + imageOffsetY)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -12,63 +12,73 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { GIFFrame } from './utils/gif/GIFFrame'
|
||||
|
||||
export enum ImageKnifeType {
|
||||
PIXELMAP = 'PixelMap',
|
||||
STRING = 'String',
|
||||
RESOURCE = 'Resource',
|
||||
GIFFRAME = 'GIFFrame'
|
||||
}
|
||||
|
||||
export class DrawPixelMap {
|
||||
imagePixelMap: PixelMap
|
||||
}
|
||||
|
||||
export class DrawString {
|
||||
imageString: string
|
||||
}
|
||||
|
||||
export class DrawResource {
|
||||
imageResource: Resource
|
||||
}
|
||||
|
||||
export class DrawGIFFrame {
|
||||
imageGIFFrames: GIFFrame[]
|
||||
}
|
||||
|
||||
export class ImageKnifeData {
|
||||
|
||||
static PIXELMAP = 'PixelMap'
|
||||
static STRING = 'string'
|
||||
static RESOURCE ='Resource'
|
||||
|
||||
static SVG = 'svg';
|
||||
static GIF = 'gif';
|
||||
static JPG = 'jpg';
|
||||
static PNG = 'png';
|
||||
static BMP = 'bmp';
|
||||
static WEBP = 'webp';
|
||||
imageKnifeType: ImageKnifeType;
|
||||
drawPixelMap: DrawPixelMap;
|
||||
drawGIFFrame: DrawGIFFrame;
|
||||
drawResource: DrawResource;
|
||||
drawString: DrawString;
|
||||
|
||||
|
||||
imageKnifeType:string = '';
|
||||
imageKnifeValue:PixelMap|string|Resource;
|
||||
imageKnifeSourceType:string = ''
|
||||
|
||||
isSvg():boolean{
|
||||
return ImageKnifeData.SVG == this.imageKnifeSourceType;
|
||||
static createImagePixelMap(type: ImageKnifeType, value: PixelMap) {
|
||||
let data = new ImageKnifeData();
|
||||
data.imageKnifeType = type;
|
||||
data.drawPixelMap = new DrawPixelMap();
|
||||
data.drawPixelMap.imagePixelMap = value;
|
||||
return data;
|
||||
}
|
||||
|
||||
isGif():boolean{
|
||||
return ImageKnifeData.GIF == this.imageKnifeSourceType;
|
||||
static createImageGIFFrame(type: ImageKnifeType, value: GIFFrame[]) {
|
||||
let data = new ImageKnifeData();
|
||||
data.imageKnifeType = type;
|
||||
data.drawGIFFrame = new DrawGIFFrame();
|
||||
data.drawGIFFrame.imageGIFFrames = value;
|
||||
return data;
|
||||
}
|
||||
|
||||
isJpg():boolean{
|
||||
return ImageKnifeData.JPG == this.imageKnifeSourceType;
|
||||
isPixelMap(): boolean {
|
||||
return ImageKnifeType.PIXELMAP == this.imageKnifeType;
|
||||
}
|
||||
|
||||
isPng():boolean{
|
||||
return ImageKnifeData.PNG == this.imageKnifeSourceType;
|
||||
isGIFFrame(): boolean {
|
||||
return ImageKnifeType.GIFFRAME == this.imageKnifeType;
|
||||
}
|
||||
|
||||
isBmp():boolean{
|
||||
return ImageKnifeData.BMP == this.imageKnifeSourceType;
|
||||
isString(): boolean {
|
||||
return ImageKnifeType.STRING == this.imageKnifeType;
|
||||
}
|
||||
|
||||
isWebp():boolean{
|
||||
return ImageKnifeData.WEBP == this.imageKnifeSourceType;
|
||||
isResource(): boolean {
|
||||
return ImageKnifeType.RESOURCE == this.imageKnifeType;
|
||||
}
|
||||
|
||||
|
||||
isString():boolean{
|
||||
return ImageKnifeData.STRING == this.imageKnifeType;
|
||||
}
|
||||
isPixelMap():boolean{
|
||||
return ImageKnifeData.PIXELMAP == this.imageKnifeType;
|
||||
}
|
||||
isResource():boolean{
|
||||
return ImageKnifeData.RESOURCE == this.imageKnifeType;
|
||||
}
|
||||
|
||||
|
||||
can2PixelMap(){ // 可以转换为PixelMap的数据源
|
||||
return this.isPixelMap() || this.isBmp() || this.isJpg() || this.isWebp() || this.isPng();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,481 @@
|
|||
/*
|
||||
* Copyright (C) 2022 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { ImageKnifeOption } from '../imageknife/ImageKnifeOption'
|
||||
import { ImageKnifeData } from '../imageknife/ImageKnifeData'
|
||||
import { GIFFrame } from '../imageknife/utils/gif/GIFFrame'
|
||||
import { IDrawLifeCycle } from '../imageknife/interface/IDrawLifeCycle'
|
||||
import { ScaleTypeHelper,ScaleType } from '../imageknife/ImageKnifeComponent'
|
||||
|
||||
export class ImageKnifeDrawFactory{
|
||||
|
||||
/**
|
||||
* 绘制PixelMap内容情况下,主图的椭圆裁剪,可添加边框
|
||||
* @param borderWidth 外边框 borderWidth vp
|
||||
* @param colorString 例如 "#FF00FF"
|
||||
*/
|
||||
public static createOvalLifeCycle(borderWidth:number, colorString:string):IDrawLifeCycle{
|
||||
let viewLifeCycle = {
|
||||
// 展示占位图
|
||||
displayPlaceholder: (context: CanvasRenderingContext2D, data: ImageKnifeData, imageKnifeOption: ImageKnifeOption, compWidth: number, compHeight: number, setGifTimeId?: (timeId: number) => void) => {
|
||||
// @ts-ignore
|
||||
return false;
|
||||
},
|
||||
// 展示加载进度
|
||||
displayProgress: (context: CanvasRenderingContext2D, progress: number, imageKnifeOption: ImageKnifeOption, compWidth: number, compHeight: number, setGifTimeId?: (timeId: number) => void) => {
|
||||
return false;
|
||||
},
|
||||
// 展示缩略图
|
||||
displayThumbSizeMultiplier: (context: CanvasRenderingContext2D, data: ImageKnifeData, imageKnifeOption: ImageKnifeOption, compWidth: number, compHeight: number, setGifTimeId?: (timeId: number) => void) => {
|
||||
// @ts-ignore
|
||||
return false;
|
||||
},
|
||||
|
||||
// 展示主图
|
||||
displayMainSource: (context: CanvasRenderingContext2D, data: ImageKnifeData, imageKnifeOption: ImageKnifeOption, compWidth: number, compHeight: number, setGifTimeId?: (timeId: number) => void) => {
|
||||
if (data.isPixelMap()) {
|
||||
// @ts-ignore
|
||||
data.drawPixelMap.imagePixelMap.getImageInfo().then((imageInfo) => {
|
||||
let scaleType = (typeof imageKnifeOption.mainScaleType == 'number') ? imageKnifeOption.mainScaleType : ScaleType.FIT_CENTER
|
||||
|
||||
context.clearRect(0,0,compWidth,compHeight)
|
||||
context.save();
|
||||
// 绘制适配后的图像
|
||||
context.save();
|
||||
ScaleTypeHelper.drawImageWithScaleType(context, scaleType, data.drawPixelMap.imagePixelMap, px2vp(imageInfo.size.width), px2vp(imageInfo.size.height), compWidth, compHeight,0,0)
|
||||
context.restore();
|
||||
|
||||
// 使用 destination-in 裁剪出椭圆
|
||||
context.save();
|
||||
context.globalCompositeOperation = 'destination-in'
|
||||
context.beginPath();
|
||||
this.setOval(context, scaleType, data.drawPixelMap.imagePixelMap, px2vp(imageInfo.size.width), px2vp(imageInfo.size.height), compWidth, compHeight,0,0,borderWidth)
|
||||
context.closePath();
|
||||
context.fill()
|
||||
context.restore();
|
||||
|
||||
// 给椭圆加上边框
|
||||
context.save();
|
||||
if(borderWidth > 0) {
|
||||
context.strokeStyle = colorString
|
||||
context.lineWidth = borderWidth;
|
||||
context.globalCompositeOperation = 'source-over'
|
||||
context.beginPath();
|
||||
this.setOval(context, scaleType, data.drawPixelMap.imagePixelMap, px2vp(imageInfo.size.width), px2vp(imageInfo.size.height), compWidth, compHeight, 0, 0, borderWidth)
|
||||
context.closePath();
|
||||
context.stroke()
|
||||
context.restore();
|
||||
}
|
||||
context.restore();
|
||||
})
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
// 展示重试图层
|
||||
displayRetryholder: (context: CanvasRenderingContext2D, data: ImageKnifeData, imageKnifeOption: ImageKnifeOption, compWidth: number, compHeight: number, setGifTimeId?: (timeId: number) => void) => {
|
||||
return false;
|
||||
},
|
||||
// 展示失败占位图
|
||||
displayErrorholder: (context: CanvasRenderingContext2D, data: ImageKnifeData, imageKnifeOption: ImageKnifeOption, compWidth: number, compHeight: number, setGifTimeId?: (timeId: number) => void) => {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return viewLifeCycle;
|
||||
}
|
||||
|
||||
/**
|
||||
* 绘制椭圆的计算和绘制,可借鉴,私有方法不对外提供
|
||||
* @param context
|
||||
* @param scaleType
|
||||
* @param source
|
||||
* @param imageWidth
|
||||
* @param imageHeight
|
||||
* @param compWidth
|
||||
* @param compHeight
|
||||
* @param imageOffsetX
|
||||
* @param imageOffsetY
|
||||
* @param borderWidth
|
||||
*/
|
||||
private static setOval(context: CanvasRenderingContext2D, scaleType: ScaleType, source: PixelMap | ImageBitmap, imageWidth: number, imageHeight: number, compWidth: number, compHeight: number, imageOffsetX:number,imageOffsetY:number
|
||||
,borderWidth:number) {
|
||||
let scaleW = compWidth / imageWidth
|
||||
let scaleH = compHeight / imageHeight
|
||||
let minScale = scaleW > scaleH ? scaleH : scaleW
|
||||
let maxScale = scaleW > scaleH ? scaleW : scaleH
|
||||
let circleX = compWidth / 2
|
||||
let circleY = compHeight / 2
|
||||
switch (scaleType) {
|
||||
case ScaleType.FIT_START:
|
||||
circleX = imageWidth * minScale / 2
|
||||
circleY = imageWidth * minScale / 2
|
||||
context.ellipse(circleX,circleY, (imageWidth * minScale - borderWidth) / 2, (imageHeight * minScale - borderWidth) / 2, 0, 0, Math.PI * 2)
|
||||
break
|
||||
case ScaleType.FIT_END:
|
||||
if(scaleW >= scaleH){
|
||||
circleX = compWidth - imageWidth * minScale/2
|
||||
circleY = imageHeight * minScale / 2
|
||||
}else{
|
||||
circleX = imageWidth * minScale / 2
|
||||
circleY = compHeight - imageHeight * minScale / 2
|
||||
}
|
||||
context.ellipse(circleX, circleY, (imageWidth * minScale - borderWidth) / 2, (imageHeight * minScale - borderWidth) / 2, 0, 0, Math.PI * 2)
|
||||
break
|
||||
case ScaleType.FIT_CENTER:
|
||||
circleX = compWidth / 2;
|
||||
circleY = compHeight / 2;
|
||||
context.ellipse(circleX, circleY, (imageWidth * minScale - borderWidth) / 2, (imageHeight * minScale - borderWidth) / 2, 0, 0, Math.PI * 2)
|
||||
break
|
||||
case ScaleType.CENTER:
|
||||
circleX = compWidth / 2;
|
||||
circleY = compWidth / 2;
|
||||
let centerRadiusX = (Math.min(compWidth,imageWidth) - borderWidth)/2
|
||||
let centerRadiusY = (Math.min(compHeight,imageHeight) -borderWidth)/2
|
||||
context.ellipse(circleX, circleY, centerRadiusX, centerRadiusY, 0, 0, Math.PI * 2)
|
||||
break
|
||||
case ScaleType.CENTER_CROP:
|
||||
// 肯定会占满全屏
|
||||
circleX = compWidth / 2;
|
||||
circleY = compHeight / 2;
|
||||
let centerCropRadiusX = (compWidth-borderWidth)/2
|
||||
let centerCropRadiusY = (compHeight-borderWidth)/2
|
||||
|
||||
context.ellipse(circleX, circleY, centerCropRadiusX, centerCropRadiusY, 0, 0, Math.PI * 2)
|
||||
break
|
||||
case ScaleType.FIT_XY:
|
||||
context.ellipse(compWidth / 2, compHeight / 2, (imageWidth * scaleW - borderWidth) / 2, (imageHeight * scaleH - borderWidth) / 2, 0, 0, Math.PI * 2)
|
||||
break
|
||||
case ScaleType.CENTER_INSIDE:
|
||||
if(minScale < 1){ // FIT_CENTER
|
||||
circleX = compWidth / 2;
|
||||
circleY = compHeight / 2;
|
||||
context.ellipse(circleX,circleY,(imageWidth * minScale - borderWidth) / 2, (imageHeight * minScale - borderWidth) / 2, 0, 0, Math.PI * 2)
|
||||
}else{ // CENTER
|
||||
circleX = compWidth / 2;
|
||||
circleY = compWidth / 2;
|
||||
let centerRadiusX = (Math.min(compWidth,imageWidth) - borderWidth)/2
|
||||
let centerRadiusY = (Math.min(compHeight,imageHeight) -borderWidth)/2
|
||||
context.ellipse(circleX, circleY, centerRadiusX, centerRadiusY, 0, 0, Math.PI * 2)
|
||||
}
|
||||
break
|
||||
case ScaleType.NONE:
|
||||
circleX = Math.min(compWidth,imageWidth)/2
|
||||
circleY = Math.min(compHeight,imageHeight)/2
|
||||
let noneRadiusX = (Math.min(compWidth,imageWidth)-borderWidth)/2
|
||||
let noneRadiusY = (Math.min(compHeight,imageHeight)-borderWidth)/2
|
||||
context.ellipse(circleX,circleY,noneRadiusX,noneRadiusY,0,0, Math.PI*2)
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 绘制PixelMap内容情况下,主图的圆角裁剪,可添加边框
|
||||
* @param borderWidth 边框宽度
|
||||
* @param colorString 边框颜色string
|
||||
* @param connerRadius 圆角半径
|
||||
*/
|
||||
public static createRoundLifeCycle(borderWidth:number, colorString:string, connerRadius:number){
|
||||
let viewLifeCycle = {
|
||||
// 展示占位图
|
||||
displayPlaceholder: (context: CanvasRenderingContext2D, data: ImageKnifeData, imageKnifeOption: ImageKnifeOption, compWidth: number, compHeight: number, setGifTimeId?: (timeId: number) => void) => {
|
||||
// @ts-ignore
|
||||
return false;
|
||||
},
|
||||
// 展示加载进度
|
||||
displayProgress: (context: CanvasRenderingContext2D, progress: number, imageKnifeOption: ImageKnifeOption, compWidth: number, compHeight: number, setGifTimeId?: (timeId: number) => void) => {
|
||||
return false;
|
||||
},
|
||||
// 展示缩略图
|
||||
displayThumbSizeMultiplier: (context: CanvasRenderingContext2D, data: ImageKnifeData, imageKnifeOption: ImageKnifeOption, compWidth: number, compHeight: number, setGifTimeId?: (timeId: number) => void) => {
|
||||
// @ts-ignore
|
||||
return false;
|
||||
},
|
||||
|
||||
// 展示主图
|
||||
displayMainSource: (context: CanvasRenderingContext2D, data: ImageKnifeData, imageKnifeOption: ImageKnifeOption, compWidth: number, compHeight: number, setGifTimeId?: (timeId: number) => void) => {
|
||||
if (data.isPixelMap()) {
|
||||
// @ts-ignore
|
||||
data.drawPixelMap.imagePixelMap.getImageInfo().then((imageInfo) => {
|
||||
let scaleType = (typeof imageKnifeOption.mainScaleType == 'number') ? imageKnifeOption.mainScaleType : ScaleType.FIT_CENTER
|
||||
|
||||
context.clearRect(0,0,compWidth,compHeight)
|
||||
context.save();
|
||||
|
||||
// 绘制适配后的图像
|
||||
context.save();
|
||||
ScaleTypeHelper.drawImageWithScaleType(context, scaleType, data.drawPixelMap.imagePixelMap, px2vp(imageInfo.size.width), px2vp(imageInfo.size.height), compWidth, compHeight,0,0)
|
||||
context.restore();
|
||||
|
||||
// 通过 destination-in 裁剪出圆角
|
||||
context.save();
|
||||
context.globalCompositeOperation = 'destination-in'
|
||||
this.setRect(context, scaleType, data.drawPixelMap.imagePixelMap, px2vp(imageInfo.size.width), px2vp(imageInfo.size.height), compWidth, compHeight,0,0,borderWidth,connerRadius)
|
||||
context.fill()
|
||||
context.restore();
|
||||
if(borderWidth > 0){
|
||||
// 为圆角添加边框
|
||||
context.save();
|
||||
context.strokeStyle = colorString
|
||||
context.lineWidth = borderWidth
|
||||
context.globalCompositeOperation = 'source-over'
|
||||
this.setRect(context, scaleType, data.drawPixelMap.imagePixelMap, px2vp(imageInfo.size.width), px2vp(imageInfo.size.height), compWidth, compHeight,0,0,borderWidth,connerRadius)
|
||||
context.stroke()
|
||||
context.restore();
|
||||
}
|
||||
context.restore();
|
||||
console.log('TestImageKnifeOptionChangedPage4 drawMainSource end!')
|
||||
})
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
// 展示重试图层
|
||||
displayRetryholder: (context: CanvasRenderingContext2D, data: ImageKnifeData, imageKnifeOption: ImageKnifeOption, compWidth: number, compHeight: number, setGifTimeId?: (timeId: number) => void) => {
|
||||
return false;
|
||||
},
|
||||
// 展示失败占位图
|
||||
displayErrorholder: (context: CanvasRenderingContext2D, data: ImageKnifeData, imageKnifeOption: ImageKnifeOption, compWidth: number, compHeight: number, setGifTimeId?: (timeId: number) => void) => {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return viewLifeCycle;
|
||||
}
|
||||
|
||||
/**
|
||||
* 绘制圆角的计算,可借鉴,私有方法不对外提供
|
||||
* @param context
|
||||
* @param scaleType
|
||||
* @param source
|
||||
* @param imageWidth
|
||||
* @param imageHeight
|
||||
* @param compWidth
|
||||
* @param compHeight
|
||||
* @param imageOffsetX
|
||||
* @param imageOffsetY
|
||||
* @param borderWidth
|
||||
* @param cornerRadius
|
||||
*/
|
||||
private static setRect(context: CanvasRenderingContext2D, scaleType: ScaleType, source: PixelMap | ImageBitmap, imageWidth: number, imageHeight: number, compWidth: number, compHeight: number, imageOffsetX:number,imageOffsetY:number
|
||||
,borderWidth:number,cornerRadius:number) {
|
||||
let scaleW = compWidth / imageWidth
|
||||
let scaleH = compHeight / imageHeight
|
||||
let minScale = scaleW > scaleH ? scaleH : scaleW
|
||||
let maxScale = scaleW > scaleH ? scaleW : scaleH
|
||||
let x1 = borderWidth/2
|
||||
let y1 = borderWidth/2
|
||||
let w1 = compWidth - borderWidth;
|
||||
let h1 = compWidth - borderWidth;
|
||||
switch (scaleType) {
|
||||
case ScaleType.FIT_START:
|
||||
x1 = borderWidth/2
|
||||
y1 = borderWidth/2
|
||||
w1 = imageWidth * minScale - borderWidth;
|
||||
h1 = imageHeight * minScale - borderWidth;
|
||||
this.roundRect(context, x1, y1, w1, h1, cornerRadius)
|
||||
break
|
||||
case ScaleType.FIT_END:
|
||||
x1 = compWidth - imageWidth * minScale + borderWidth / 2
|
||||
y1 = compHeight - imageHeight * minScale + borderWidth / 2
|
||||
w1 = imageWidth * minScale - borderWidth;
|
||||
h1 = imageHeight * minScale - borderWidth;
|
||||
this.roundRect(context, x1, y1, w1, h1, cornerRadius)
|
||||
break
|
||||
case ScaleType.FIT_CENTER:
|
||||
x1 = (compWidth - imageWidth * minScale) / 2 + borderWidth / 2
|
||||
y1 = (compHeight - imageHeight * minScale) / 2 + borderWidth / 2
|
||||
w1 = imageWidth * minScale - borderWidth
|
||||
h1 = imageHeight * minScale - borderWidth
|
||||
this.roundRect(context, x1, y1, w1, h1, cornerRadius)
|
||||
break
|
||||
case ScaleType.CENTER:
|
||||
x1 = Math.max(0,(compWidth - Math.min(compWidth, imageWidth)))/2 + borderWidth/2
|
||||
y1 = Math.max(0,(compHeight - Math.min(compHeight, imageHeight)))/2 + borderWidth/2
|
||||
|
||||
w1 = Math.min(compWidth, imageWidth) - borderWidth;
|
||||
h1 = Math.min(compHeight, imageHeight) - borderWidth;
|
||||
|
||||
this.roundRect(context, x1, y1, w1, h1, cornerRadius)
|
||||
break
|
||||
case ScaleType.CENTER_CROP:
|
||||
x1 = borderWidth/2
|
||||
y1 = borderWidth/2
|
||||
|
||||
w1 = compWidth - borderWidth;
|
||||
h1 = compWidth - borderWidth;
|
||||
this.roundRect(context, x1, y1, w1, h1, cornerRadius)
|
||||
break
|
||||
case ScaleType.FIT_XY:
|
||||
x1 = borderWidth/2
|
||||
y1 = borderWidth/2
|
||||
|
||||
w1 = compWidth - borderWidth;
|
||||
h1 = compWidth - borderWidth;
|
||||
this.roundRect(context, x1, y1, w1, h1, cornerRadius)
|
||||
break
|
||||
case ScaleType.CENTER_INSIDE:
|
||||
if(minScale < 1){ // FIT_CENTER
|
||||
x1 = (compWidth - imageWidth * minScale) / 2 + borderWidth / 2
|
||||
y1 = (compHeight - imageHeight * minScale) / 2 + borderWidth / 2
|
||||
w1 = imageWidth * minScale - borderWidth
|
||||
h1 = imageHeight * minScale - borderWidth
|
||||
this.roundRect(context, x1, y1, w1, h1, cornerRadius)
|
||||
}else{ // CENTER
|
||||
x1 = Math.max(0,(compWidth - Math.min(compWidth, imageWidth)))/2 + borderWidth/2
|
||||
y1 = Math.max(0,(compHeight - Math.min(compHeight, imageHeight)))/2 + borderWidth/2
|
||||
|
||||
w1 = Math.min(compWidth, imageWidth) - borderWidth;
|
||||
h1 = Math.min(compHeight, imageHeight) - borderWidth;
|
||||
|
||||
this.roundRect(context, x1, y1, w1, h1, cornerRadius)
|
||||
}
|
||||
|
||||
break;
|
||||
case ScaleType.NONE:
|
||||
|
||||
x1 = borderWidth/2
|
||||
y1 = borderWidth/2
|
||||
|
||||
w1 = Math.min(compWidth, imageWidth) - borderWidth;
|
||||
h1 = Math.min(compHeight, imageHeight) - borderWidth;
|
||||
|
||||
this.roundRect(context, x1, y1, w1, h1, cornerRadius)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 绘制圆角的绘制,可借鉴,私有方法不对外提供
|
||||
* @param context
|
||||
* @param x
|
||||
* @param y
|
||||
* @param w
|
||||
* @param h
|
||||
* @param r
|
||||
*/
|
||||
private static roundRect(context: CanvasRenderingContext2D, x: number, y: number, w: number, h: number, r: number) {
|
||||
if (w < 2 * r) {
|
||||
r = w / 2;
|
||||
}
|
||||
if (h < 2 * r) {
|
||||
r = h / 2;
|
||||
}
|
||||
context.beginPath();
|
||||
context.moveTo(x + r, y);
|
||||
context.arcTo(x + w, y, x + w, y + h, r);
|
||||
context.arcTo(x + w, y + h, x, y + h, r);
|
||||
context.arcTo(x, y + h, x, y, r);
|
||||
context.arcTo(x, y, x + w, y, r);
|
||||
context.closePath();
|
||||
}
|
||||
|
||||
/**
|
||||
* 绘制下载进度条
|
||||
* @param fontColor 文字颜色
|
||||
* @param fontSizeRate 文字占半径比率[0,1]
|
||||
*/
|
||||
public static createProgressLifeCycle(fontColor:string, fontSizeRate:number){
|
||||
let viewLifeCycle: IDrawLifeCycle = {
|
||||
// 展示占位图
|
||||
displayPlaceholder: (context: CanvasRenderingContext2D, data: ImageKnifeData, imageKnifeOption: ImageKnifeOption, compWidth: number, compHeight: number, setGifTimeId?: (timeId: number) => void) => {
|
||||
// @ts-ignore
|
||||
return false;
|
||||
},
|
||||
// 展示加载进度
|
||||
displayProgress: (context: CanvasRenderingContext2D, progress: number, imageKnifeOption: ImageKnifeOption, compWidth: number, compHeight: number, setGifTimeId?: (timeId: number) => void) => {
|
||||
// @ts-ignore
|
||||
this.drawDefaultProgress(context, progress, imageKnifeOption, compWidth, compHeight,fontColor,fontSizeRate,setGifTimeId)
|
||||
return true;
|
||||
},
|
||||
// 展示缩略图
|
||||
displayThumbSizeMultiplier: (context: CanvasRenderingContext2D, data: ImageKnifeData, imageKnifeOption: ImageKnifeOption, compWidth: number, compHeight: number, setGifTimeId?: (timeId: number) => void) => {
|
||||
// @ts-ignore
|
||||
return false;
|
||||
},
|
||||
|
||||
// 展示主图
|
||||
displayMainSource: (context: CanvasRenderingContext2D, data: ImageKnifeData, imageKnifeOption: ImageKnifeOption, compWidth: number, compHeight: number, setGifTimeId?: (timeId: number) => void) => {
|
||||
// @ts-ignore
|
||||
return false;
|
||||
},
|
||||
|
||||
// 展示重试图层
|
||||
displayRetryholder: (context: CanvasRenderingContext2D, data: ImageKnifeData, imageKnifeOption: ImageKnifeOption, compWidth: number, compHeight: number, setGifTimeId?: (timeId: number) => void) => {
|
||||
// @ts-ignore
|
||||
return false;
|
||||
},
|
||||
|
||||
// 展示失败占位图
|
||||
displayErrorholder: (context: CanvasRenderingContext2D, data: ImageKnifeData, imageKnifeOption: ImageKnifeOption, compWidth: number, compHeight: number, setGifTimeId?: (timeId: number) => void) => {
|
||||
// @ts-ignore
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return viewLifeCycle;
|
||||
}
|
||||
/**
|
||||
* 绘制默认的网络下载百分比
|
||||
* @param context
|
||||
* @param progress
|
||||
* @param imageKnifeOption
|
||||
* @param compWidth
|
||||
* @param compHeight
|
||||
* @param fontColor
|
||||
* @param fontSizeRate
|
||||
* @param setGifTimeId
|
||||
*/
|
||||
private static drawDefaultProgress(context: CanvasRenderingContext2D, progress: number, imageKnifeOption: ImageKnifeOption,
|
||||
compWidth: number, compHeight: number,
|
||||
fontColor:string, fontSizeRate:number,setGifTimeId?: (timeId: number) => void,){
|
||||
let pi = Math.PI * 2 / 100; //pi 讲圆的周长划分为100份
|
||||
let rate = progress - 25;
|
||||
let diameter = compWidth > compHeight ? compHeight : compWidth
|
||||
context.lineWidth = Math.floor(diameter * 0.03)
|
||||
context.lineCap = "round"
|
||||
context.fillStyle = fontColor//"#10a5ff"
|
||||
context.font = Math.floor(diameter * fontSizeRate *px2vp(1))+'px'
|
||||
let x0 = (compWidth - diameter) / 2.0 + Math.floor(diameter * 0.5)
|
||||
let y0 = (compHeight - diameter) / 2.0 + Math.floor(diameter * 0.1)
|
||||
let x1 = (compWidth - diameter) / 2.0 + Math.floor(diameter * 0.5)
|
||||
let y1 = (compHeight - diameter) / 2.0 + Math.floor(diameter * 0.8)
|
||||
let gradient = context.createLinearGradient(x0, y0, x1, y1)
|
||||
gradient.addColorStop(0, "#11ffe4")
|
||||
gradient.addColorStop(0.5, "#03c6fd")
|
||||
gradient.addColorStop(1, "#10a5ff")
|
||||
context.clearRect(0, 0, compWidth, compHeight)
|
||||
context.shadowBlur = 0
|
||||
context.beginPath()
|
||||
context.strokeStyle = "#15222d"
|
||||
let radius = Math.floor(diameter * 0.3)
|
||||
let arcX = compWidth / 2.0
|
||||
let arcY = compHeight / 2.0
|
||||
context.arc(arcX, arcY, radius, 0, Math.PI * 2, true)
|
||||
context.stroke()
|
||||
context.beginPath()
|
||||
let showText = rate + 25 + '%'
|
||||
let metrics = context.measureText(showText)
|
||||
let textX = (compWidth / 2.0) - metrics.width / 2.0
|
||||
let textY = (compHeight / 2.0) + metrics.height * 0.3
|
||||
context.fillText(showText, textX, textY)
|
||||
context.stroke()
|
||||
context.beginPath()
|
||||
context.strokeStyle = gradient
|
||||
context.arc(arcX, arcY, radius, pi * -25, pi * rate)
|
||||
context.stroke();
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -13,17 +13,26 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {AUTOMATIC} from "../cache/diskstrategy/enum/AUTOMATIC"
|
||||
import {DiskStrategy} from "../cache/diskstrategy/DiskStrategy"
|
||||
import {BaseTransform} from "../imageknife/transform/BaseTransform"
|
||||
import {TransformType} from "../imageknife/transform/TransformType"
|
||||
import {CropType} from "../imageknife/transform/CropTransformation"
|
||||
import {AllCacheInfo, IAllCacheInfoCallback} from "../imageknife/interface/IAllCacheInfoCallback"
|
||||
import { AUTOMATIC } from '../cache/diskstrategy/enum/AUTOMATIC'
|
||||
|
||||
import { DiskStrategy } from '../cache/diskstrategy/DiskStrategy'
|
||||
import { BaseTransform } from '../imageknife/transform/BaseTransform'
|
||||
import { TransformType } from '../imageknife/transform/TransformType'
|
||||
import { CropType } from '../imageknife/transform/CropTransformation'
|
||||
import { AllCacheInfo, IAllCacheInfoCallback } from '../imageknife/interface/IAllCacheInfoCallback'
|
||||
import { IDrawLifeCycle } from '../imageknife/interface/IDrawLifeCycle'
|
||||
import { ScaleType } from '../imageknife/ImageKnifeComponent'
|
||||
|
||||
export class ImageKnifeOption {
|
||||
// 组件大小
|
||||
size: {
|
||||
width: string,
|
||||
height: string
|
||||
};
|
||||
|
||||
// 主图资源
|
||||
loadSrc: string | PixelMap | Resource;
|
||||
mainScaleType?: ScaleType = ScaleType.FIT_CENTER
|
||||
|
||||
// 磁盘缓存策略
|
||||
strategy?: DiskStrategy = new AUTOMATIC();
|
||||
|
@ -33,59 +42,83 @@ export class ImageKnifeOption {
|
|||
|
||||
// 占位图
|
||||
placeholderSrc?: PixelMap | Resource;
|
||||
placeholderScaleType?: ScaleType = ScaleType.FIT_CENTER
|
||||
|
||||
// 失败占位图
|
||||
errorholderSrc?: PixelMap | Resource;
|
||||
errorholderSrcScaleType?: ScaleType = ScaleType.FIT_CENTER
|
||||
|
||||
// 重试占位图
|
||||
retryholderSrc?: Resource;
|
||||
retryholderScaleType?: ScaleType = ScaleType.FIT_CENTER
|
||||
|
||||
// 缩略图,范围(0,1)
|
||||
thumbSizeMultiplier?: number;
|
||||
// 缩略图展示时间
|
||||
thumbSizeDelay?:number;
|
||||
// 缩略图展示类型
|
||||
thumbSizeMultiplierScaleType?: ScaleType = ScaleType.FIT_CENTER
|
||||
|
||||
// 进度条
|
||||
displayProgress?: boolean;
|
||||
|
||||
// 进度条回调
|
||||
displayProgressListener?;
|
||||
|
||||
// 重试图层
|
||||
retryLoad?: boolean;
|
||||
|
||||
// 动画时长
|
||||
animateDuration?: number = 500;
|
||||
// 重试图层 可点击
|
||||
canRetryClick?: boolean;
|
||||
|
||||
// 仅使用缓存加载数据
|
||||
onlyRetrieveFromCache?: boolean = false;
|
||||
|
||||
// 是否开启第一级内存缓存
|
||||
// 是否开启一级内存缓存
|
||||
isCacheable?: boolean = true;
|
||||
|
||||
// 变换相关
|
||||
transform?:{
|
||||
transformType:number,
|
||||
blur?:number,
|
||||
roundedCorners?:{ top_left: number, top_right: number, bottom_left: number, bottom_right: number }
|
||||
cropCircleWithBorder?:{border:number, obj:{ r_color: number, g_color: number, b_color: number }}
|
||||
crop?:{width: number, height: number, cropType: CropType}
|
||||
brightnessFilter?:number,
|
||||
contrastFilter?:number,
|
||||
pixelationFilter?:number,
|
||||
swirlFilter?:number,
|
||||
mask?:Resource,
|
||||
rotateImage?:number
|
||||
|
||||
// 用户自定义实现 绘制方案
|
||||
drawLifeCycle?: IDrawLifeCycle;
|
||||
|
||||
gif?: {
|
||||
loopFinish?: (loopTime?) => void
|
||||
speedFactory?: number
|
||||
seekTo?: number
|
||||
}
|
||||
|
||||
transformation?:BaseTransform<PixelMap>;
|
||||
|
||||
transformations?:Array<BaseTransform<PixelMap>>;
|
||||
// 变换相关
|
||||
transform?: {
|
||||
transformType: number,
|
||||
blur?: number,
|
||||
roundedCorners?: {
|
||||
top_left: number,
|
||||
top_right: number,
|
||||
bottom_left: number,
|
||||
bottom_right: number
|
||||
}
|
||||
cropCircleWithBorder?: {
|
||||
border: number,
|
||||
obj: {
|
||||
r_color: number,
|
||||
g_color: number,
|
||||
b_color: number
|
||||
}
|
||||
}
|
||||
crop?: {
|
||||
width: number,
|
||||
height: number,
|
||||
cropType: CropType
|
||||
}
|
||||
brightnessFilter?: number,
|
||||
contrastFilter?: number,
|
||||
pixelationFilter?: number,
|
||||
swirlFilter?: number,
|
||||
mask?: Resource,
|
||||
rotateImage?: number
|
||||
}
|
||||
transformation?: BaseTransform<PixelMap>;
|
||||
transformations?: Array<BaseTransform<PixelMap>>;
|
||||
|
||||
// 输出缓存相关内容和信息
|
||||
allCacheInfoCallback?: IAllCacheInfoCallback;
|
||||
size: {
|
||||
width: number,
|
||||
height: number
|
||||
};
|
||||
|
||||
imageFit?: ImageFit;
|
||||
backgroundColor?: Color | number | string | Resource;
|
||||
margin?: {
|
||||
|
@ -95,7 +128,7 @@ export class ImageKnifeOption {
|
|||
left?: number | string | Resource
|
||||
} | number | string | Resource
|
||||
|
||||
|
||||
sizeAnimate?: AnimateParam
|
||||
|
||||
constructor() {
|
||||
|
||||
|
|
|
@ -55,19 +55,19 @@ export class RequestOption {
|
|||
errorholderData: ImageKnifeData;
|
||||
thumbSizeMultiplier: number;
|
||||
|
||||
// 如果存在缩略图,则主图延时3000ms加载
|
||||
thumbDelayTime: number = 3000
|
||||
// 如果存在缩略图,则主图延时1s加载
|
||||
thumbDelayTime: number = 1000
|
||||
thumbHolderFunc: AsyncSuccess<ImageKnifeData>;
|
||||
requestListeners: Array<AsyncCallback<ImageKnifeData>>;
|
||||
|
||||
// 进度条
|
||||
progressFunc: AsyncSuccess<string>;
|
||||
progressFunc: AsyncSuccess<number>;
|
||||
|
||||
// 重试图层
|
||||
retryFunc: AsyncSuccess<ImageKnifeData>
|
||||
retryholderSrc: PixelMap | Resource;
|
||||
retryholderFunc: AsyncSuccess<ImageKnifeData>
|
||||
retryholderData: ImageKnifeData
|
||||
|
||||
// 图层切换时长
|
||||
animateDuration: number = 500;
|
||||
size: {
|
||||
width: number,
|
||||
height: number
|
||||
|
@ -98,12 +98,13 @@ export class RequestOption {
|
|||
loadMainReady = false;
|
||||
|
||||
// 失败占位图展示状态 当true 表示主图加载失败需要展示失败占位图
|
||||
loadErrorReady = false
|
||||
loadErrorReady = false;
|
||||
|
||||
// 重试占位图展示状态 当true 表示主图加载失败需要展示失败占位图
|
||||
loadRetryReady = false;
|
||||
|
||||
// 缩略图展示
|
||||
loadThumbnailReady = false;
|
||||
_svgAndGifFolder: string = "svgAndGifFolder"; // svg和gif的文件路径地址
|
||||
_svgAndGifCommitFile: string = "svgAndGifCommitFile"; // svg和gif提交记录
|
||||
|
||||
constructor() {
|
||||
// 初始化全局监听
|
||||
|
@ -166,21 +167,27 @@ export class RequestOption {
|
|||
return this;
|
||||
}
|
||||
|
||||
thumbnail(sizeMultiplier: number, func?: AsyncSuccess<ImageKnifeData>) {
|
||||
this.thumbSizeMultiplier = sizeMultiplier;
|
||||
this.thumbHolderFunc = func;
|
||||
retryholder(src: PixelMap | Resource, func?: AsyncSuccess<ImageKnifeData>) {
|
||||
this.retryholderSrc = src;
|
||||
this.retryholderFunc = func;
|
||||
return this;
|
||||
}
|
||||
|
||||
addProgressListener(func?: AsyncSuccess<string>) {
|
||||
thumbnail(sizeMultiplier: number, func?: AsyncSuccess<ImageKnifeData>,displayTime?:number) {
|
||||
this.thumbSizeMultiplier = sizeMultiplier;
|
||||
this.thumbHolderFunc = func;
|
||||
if(displayTime){
|
||||
this.thumbDelayTime = displayTime;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
addProgressListener(func?: AsyncSuccess<number>) {
|
||||
this.progressFunc = func;
|
||||
return this;
|
||||
}
|
||||
|
||||
addRetryListener(func?: AsyncSuccess<any>) {
|
||||
this.retryFunc = func;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
addListener(func: AsyncCallback<ImageKnifeData>) {
|
||||
this.requestListeners.push(func);
|
||||
|
@ -322,7 +329,7 @@ export class RequestOption {
|
|||
placeholderOnComplete(imageKnifeData: ImageKnifeData) {
|
||||
console.log("placeholderOnComplete has called!");
|
||||
console.log("Main Image is Ready:" + this.loadMainReady);
|
||||
if (!this.loadMainReady && !this.loadErrorReady && !this.loadThumbnailReady) {
|
||||
if (!this.loadMainReady && !(this.loadErrorReady || this.loadRetryReady) && !this.loadThumbnailReady) {
|
||||
// 主图未加载成功,并且未加载失败 显示占位图 主图加载成功或者加载失败后=>不展示占位图
|
||||
this.placeholderFunc(imageKnifeData)
|
||||
}
|
||||
|
@ -333,9 +340,12 @@ export class RequestOption {
|
|||
console.log("占位图解析失败 error =" + error)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// 缩略图解析成功
|
||||
thumbholderOnComplete(imageKnifeData: ImageKnifeData) {
|
||||
if (!this.loadMainReady && !this.loadErrorReady) {
|
||||
if (!this.loadMainReady && !(this.loadErrorReady || this.loadRetryReady)) {
|
||||
//主图未加载成功,并且未加载失败 显示占位图 主图加载成功或者加载失败后=>不展示占位图
|
||||
this.thumbHolderFunc(imageKnifeData)
|
||||
}
|
||||
|
@ -360,6 +370,17 @@ export class RequestOption {
|
|||
console.log("失败占位图解析失败 error =" + error)
|
||||
}
|
||||
|
||||
retryholderOnComplete(imageKnifeData: ImageKnifeData){
|
||||
this.retryholderData = imageKnifeData;
|
||||
if(this.loadRetryReady){
|
||||
this.retryholderFunc(imageKnifeData)
|
||||
}
|
||||
}
|
||||
|
||||
retryholderOnError(error){
|
||||
console.log("重试占位图解析失败 error ="+ error)
|
||||
}
|
||||
|
||||
loadComplete(imageKnifeData: ImageKnifeData) {
|
||||
this.loadMainReady = true;
|
||||
// 三级缓存数据加载成功
|
||||
|
@ -375,12 +396,17 @@ export class RequestOption {
|
|||
|
||||
loadError(err) {
|
||||
console.log("loadError:"+err);
|
||||
console.log("loadError stack=:"+JSON.stringify(err.stack));
|
||||
//失败占位图展示规则
|
||||
this.loadErrorReady = true;
|
||||
if (this.retryFunc) {
|
||||
if (this.retryholderFunc) {
|
||||
// 重试图层优先于加载失败展示
|
||||
this.retryFunc(err)
|
||||
this.loadRetryReady = true;
|
||||
if(this.retryholderData != null){
|
||||
this.retryholderFunc(this.retryholderData)
|
||||
}
|
||||
} else {
|
||||
// 失败图层标记,如果已经有数据直接展示失败图层
|
||||
this.loadErrorReady = true;
|
||||
if (this.errorholderData != null) {
|
||||
this.errorholderFunc(this.errorholderData)
|
||||
}
|
||||
|
|
|
@ -71,7 +71,7 @@ export namespace Crop {
|
|||
})
|
||||
}
|
||||
|
||||
async function colorRatioPixelMap(data: any, width: number, height: number, colorRatio: number, func?: CropCallback<PixelMap>) {
|
||||
var colorRatioPixelMap = async (data: any, width: number, height: number, colorRatio: number, func?: CropCallback<PixelMap>)=> {
|
||||
if (!data) {
|
||||
func("colorRatio pixelMap is null", null);
|
||||
return;
|
||||
|
@ -95,10 +95,10 @@ export namespace Crop {
|
|||
}
|
||||
|
||||
|
||||
function getPixelMapSize(imageSource: any, func: CropCallback<{
|
||||
var getPixelMapSize = (imageSource: any, func: CropCallback<{
|
||||
width: number,
|
||||
height: number
|
||||
}>) {
|
||||
}>)=> {
|
||||
if (!imageSource) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ import { CropCallback } from './CropCallback'
|
|||
|
||||
@Component
|
||||
struct PixelMapCrop {
|
||||
@Watch('watchOptions') @State options: PixelMapCrop.Options = new PixelMapCrop.Options();
|
||||
@Watch('watchOptions') @Link options: PixelMapCrop.Options;
|
||||
@Watch('watchCropTap') @Prop cropTap: boolean;
|
||||
@State bWidth: number = 0;
|
||||
@State bHeight: number = 0;
|
||||
|
|
|
@ -13,12 +13,14 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {RequestOption} from "../../imageknife/RequestOption"
|
||||
import {FileTypeUtil} from "../../imageknife/utils/FileTypeUtil"
|
||||
import {ImageKnifeData} from "../ImageKnifeData"
|
||||
import {ParseImageUtil} from '../utils/ParseImageUtil'
|
||||
import {ParseResClient} from '../resourcemanage/ParseResClient'
|
||||
import image from "@ohos.multimedia.image"
|
||||
import { RequestOption } from '../../imageknife/RequestOption'
|
||||
import { FileTypeUtil } from '../../imageknife/utils/FileTypeUtil'
|
||||
import { ImageKnifeData, ImageKnifeType } from '../ImageKnifeData'
|
||||
import { ParseImageUtil } from '../utils/ParseImageUtil'
|
||||
import { SupportFormat } from '../utils/FileTypeUtil'
|
||||
import { SVGParseImpl } from '../utils/svg/SVGParseImpl'
|
||||
import { ParseResClient } from '../resourcemanage/ParseResClient'
|
||||
import image from '@ohos.multimedia.image'
|
||||
|
||||
export class ErrorHolderManager {
|
||||
private options: RequestOption;
|
||||
|
@ -30,7 +32,7 @@ export class ErrorHolderManager {
|
|||
static execute(option: RequestOption) {
|
||||
let manager = new ErrorHolderManager(option);
|
||||
return new Promise(manager.process.bind(manager))
|
||||
.then(option.errorholderOnComplete.bind(option)).catch(option.errorholderOnError.bind(option));
|
||||
.then(option.errorholderOnComplete.bind(option)).catch(option.errorholderOnError.bind(option));
|
||||
}
|
||||
|
||||
process(onComplete, onError) {
|
||||
|
@ -40,9 +42,7 @@ export class ErrorHolderManager {
|
|||
private displayErrorholder(onComplete, onError) {
|
||||
console.log("displayErrorholder")
|
||||
if ((typeof (this.options.errorholderSrc as image.PixelMap).isEditable) == 'boolean') {
|
||||
let imageKnifeData = new ImageKnifeData();
|
||||
imageKnifeData.imageKnifeType = ImageKnifeData.PIXELMAP
|
||||
imageKnifeData.imageKnifeValue = this.options.placeholderSrc as PixelMap
|
||||
let imageKnifeData = ImageKnifeData.createImagePixelMap(ImageKnifeType.PIXELMAP, this.options.errorholderSrc as PixelMap)
|
||||
onComplete(imageKnifeData);
|
||||
} else if (typeof this.options.errorholderSrc == 'string') {
|
||||
|
||||
|
@ -53,22 +53,21 @@ export class ErrorHolderManager {
|
|||
let suc = (arraybuffer) => {
|
||||
let fileTypeUtil = new FileTypeUtil();
|
||||
let typeValue = fileTypeUtil.getFileType(arraybuffer);
|
||||
if ("gif" == typeValue || "svg" == typeValue) {
|
||||
let imageKnifeData = new ImageKnifeData();
|
||||
imageKnifeData.imageKnifeType = "Resource"
|
||||
imageKnifeData.imageKnifeValue = this.options.errorholderSrc as Resource
|
||||
imageKnifeData.imageKnifeSourceType = typeValue;
|
||||
onComplete(imageKnifeData);
|
||||
} else {
|
||||
let parseImageUtils = new ParseImageUtil();
|
||||
let success = (value: PixelMap) => {
|
||||
let imageKnifeData = new ImageKnifeData();
|
||||
imageKnifeData.imageKnifeType = "PixelMap"
|
||||
imageKnifeData.imageKnifeValue = value
|
||||
imageKnifeData.imageKnifeSourceType = typeValue;
|
||||
onComplete(imageKnifeData);
|
||||
}
|
||||
parseImageUtils.parseImage(arraybuffer, success, onError)
|
||||
switch (typeValue) {
|
||||
case SupportFormat.svg:
|
||||
this.svgProcess(onComplete, onError, arraybuffer, typeValue)
|
||||
break;
|
||||
case SupportFormat.jpg:
|
||||
case SupportFormat.png:
|
||||
case SupportFormat.bmp:
|
||||
case SupportFormat.gif:
|
||||
case SupportFormat.tiff:
|
||||
case SupportFormat.webp:
|
||||
this.mediaImageProcess(onComplete, onError, arraybuffer, typeValue)
|
||||
break;
|
||||
default:
|
||||
onError("ErrorHolderManager 文件类型不支持")
|
||||
break;
|
||||
}
|
||||
}
|
||||
resourceFetch.loadResource(res, suc, onError)
|
||||
|
@ -77,4 +76,24 @@ export class ErrorHolderManager {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
private svgProcess(onComplete, onError, arraybuffer, typeValue) {
|
||||
let svgParseImpl = new SVGParseImpl()
|
||||
let size = { width: this.options.size.width, height: this.options.size.height }
|
||||
svgParseImpl.parseSvg(arraybuffer, size).then((value: PixelMap) => {
|
||||
let imageKnifeData = ImageKnifeData.createImagePixelMap(ImageKnifeType.PIXELMAP, value)
|
||||
onComplete(imageKnifeData)
|
||||
}).catch(err => {
|
||||
onError(err)
|
||||
})
|
||||
}
|
||||
|
||||
private mediaImageProcess(onComplete, onError, arraybuffer, typeValue) {
|
||||
let parseImageUtil = new ParseImageUtil()
|
||||
let success = (value: PixelMap) => {
|
||||
let imageKnifeData = ImageKnifeData.createImagePixelMap(ImageKnifeType.PIXELMAP, value)
|
||||
onComplete(imageKnifeData)
|
||||
}
|
||||
parseImageUtil.parseImage(arraybuffer, success, onError)
|
||||
}
|
||||
}
|
|
@ -16,9 +16,11 @@ import {RequestOption} from "../../imageknife/RequestOption"
|
|||
import {ResourceTypeEts} from "../../imageknife/constants/ResourceTypeEts"
|
||||
import {Base64} from "../../cache/Base64"
|
||||
import {FileTypeUtil} from "../../imageknife/utils/FileTypeUtil"
|
||||
import {ImageKnifeData} from "../ImageKnifeData"
|
||||
import {ImageKnifeData,ImageKnifeType} from "../ImageKnifeData"
|
||||
import {ParseImageUtil} from '../utils/ParseImageUtil'
|
||||
import {ParseResClient} from '../resourcemanage/ParseResClient'
|
||||
import { SupportFormat } from '../utils/FileTypeUtil'
|
||||
import { SVGParseImpl } from '../utils/svg/SVGParseImpl'
|
||||
import resourceManager from '@ohos.resourceManager';
|
||||
import image from "@ohos.multimedia.image"
|
||||
|
||||
|
@ -42,9 +44,7 @@ export class PlaceHolderManager {
|
|||
private displayPlaceholder(onComplete, onError) {
|
||||
console.log("displayPlaceholder")
|
||||
if ((typeof (this.options.placeholderSrc as image.PixelMap).isEditable) == 'boolean') {
|
||||
let imageKnifeData = new ImageKnifeData();
|
||||
imageKnifeData.imageKnifeType = ImageKnifeData.PIXELMAP
|
||||
imageKnifeData.imageKnifeValue = this.options.placeholderSrc as PixelMap
|
||||
let imageKnifeData = ImageKnifeData.createImagePixelMap(ImageKnifeType.PIXELMAP, this.options.placeholderSrc as PixelMap)
|
||||
onComplete(imageKnifeData);
|
||||
} else if (typeof this.options.placeholderSrc == 'string') {
|
||||
|
||||
|
@ -55,16 +55,21 @@ export class PlaceHolderManager {
|
|||
let suc = (arraybuffer) => {
|
||||
let fileTypeUtil = new FileTypeUtil();
|
||||
let typeValue = fileTypeUtil.getFileType(arraybuffer);
|
||||
if ("gif" == typeValue || "svg" == typeValue) {
|
||||
let imageKnifeData = this.createImageKnifeData("Resource", this.options.placeholderSrc as Resource, typeValue);
|
||||
onComplete(imageKnifeData);
|
||||
} else {
|
||||
let parseImageUtils = new ParseImageUtil();
|
||||
let success = (value: PixelMap) => {
|
||||
let imageKnifeData = this.createImageKnifeData('PixelMap', value, typeValue);
|
||||
onComplete(imageKnifeData);
|
||||
}
|
||||
parseImageUtils.parseImage(arraybuffer, success, onError)
|
||||
switch (typeValue) {
|
||||
case SupportFormat.svg:
|
||||
this.svgProcess(onComplete, onError, arraybuffer, typeValue)
|
||||
break;
|
||||
case SupportFormat.jpg:
|
||||
case SupportFormat.png:
|
||||
case SupportFormat.bmp:
|
||||
case SupportFormat.gif:
|
||||
case SupportFormat.tiff:
|
||||
case SupportFormat.webp:
|
||||
this.mediaImageProcess(onComplete, onError, arraybuffer, typeValue)
|
||||
break;
|
||||
default:
|
||||
onError("PlaceHolderManager 文件类型不支持")
|
||||
break;
|
||||
}
|
||||
}
|
||||
resourceFetch.loadResource(res, suc, onError)
|
||||
|
@ -73,11 +78,26 @@ export class PlaceHolderManager {
|
|||
}
|
||||
}
|
||||
}
|
||||
private createImageKnifeData(imageKnifeType:string, imageKnifeValue:PixelMap|string|Resource, imageKnifeSourceType:string):ImageKnifeData{
|
||||
let imageKnifeData = new ImageKnifeData();
|
||||
imageKnifeData.imageKnifeType = imageKnifeType;
|
||||
imageKnifeData.imageKnifeValue = imageKnifeValue;
|
||||
imageKnifeData.imageKnifeSourceType = imageKnifeSourceType;
|
||||
return imageKnifeData;
|
||||
|
||||
|
||||
|
||||
private svgProcess(onComplete, onError, arraybuffer, typeValue) {
|
||||
let svgParseImpl = new SVGParseImpl()
|
||||
let size = { width: this.options.size.width, height: this.options.size.height }
|
||||
svgParseImpl.parseSvg(arraybuffer, size).then((value: PixelMap) => {
|
||||
let imageKnifeData = ImageKnifeData.createImagePixelMap(ImageKnifeType.PIXELMAP, value)
|
||||
onComplete(imageKnifeData)
|
||||
}).catch(err => {
|
||||
onError(err)
|
||||
})
|
||||
}
|
||||
|
||||
private mediaImageProcess(onComplete, onError, arraybuffer, typeValue) {
|
||||
let parseImageUtil = new ParseImageUtil()
|
||||
let success = (value: PixelMap) => {
|
||||
let imageKnifeData = ImageKnifeData.createImagePixelMap(ImageKnifeType.PIXELMAP, value)
|
||||
onComplete(imageKnifeData)
|
||||
}
|
||||
parseImageUtil.parseImage(arraybuffer, success, onError)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,103 @@
|
|||
/*
|
||||
* Copyright (C) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import {RequestOption} from "../../imageknife/RequestOption"
|
||||
import {ResourceTypeEts} from "../../imageknife/constants/ResourceTypeEts"
|
||||
import {Base64} from "../../cache/Base64"
|
||||
import {FileTypeUtil} from "../../imageknife/utils/FileTypeUtil"
|
||||
import {ImageKnifeData,ImageKnifeType} from "../ImageKnifeData"
|
||||
import {ParseImageUtil} from '../utils/ParseImageUtil'
|
||||
import {ParseResClient} from '../resourcemanage/ParseResClient'
|
||||
import { SupportFormat } from '../utils/FileTypeUtil'
|
||||
import { SVGParseImpl } from '../utils/svg/SVGParseImpl'
|
||||
import resourceManager from '@ohos.resourceManager';
|
||||
import image from "@ohos.multimedia.image"
|
||||
|
||||
export class RetryHolderManager {
|
||||
private options: RequestOption;
|
||||
|
||||
constructor(option: RequestOption) {
|
||||
this.options = option;
|
||||
}
|
||||
|
||||
static execute(option: RequestOption) {
|
||||
let manager = new RetryHolderManager(option);
|
||||
return new Promise(manager.process.bind(manager))
|
||||
.then(option.retryholderOnComplete.bind(option)).catch(option.retryholderOnError.bind(option));
|
||||
}
|
||||
|
||||
process(onComplete, onError) {
|
||||
this.displayRetryholder(onComplete, onError);
|
||||
}
|
||||
|
||||
private displayRetryholder(onComplete, onError) {
|
||||
console.log("displayRetryholder")
|
||||
if ((typeof (this.options.retryholderSrc as image.PixelMap).isEditable) == 'boolean') {
|
||||
let imageKnifeData = ImageKnifeData.createImagePixelMap(ImageKnifeType.PIXELMAP, this.options.placeholderSrc as PixelMap)
|
||||
onComplete(imageKnifeData);
|
||||
} else if (typeof this.options.placeholderSrc == 'string') {
|
||||
|
||||
} else {
|
||||
let res = this.options.retryholderSrc as Resource;
|
||||
if (typeof res.id != 'undefined' && typeof res.id != 'undefined') {
|
||||
let resourceFetch = new ParseResClient();
|
||||
let suc = (arraybuffer) => {
|
||||
let fileTypeUtil = new FileTypeUtil();
|
||||
let typeValue = fileTypeUtil.getFileType(arraybuffer);
|
||||
switch (typeValue) {
|
||||
case SupportFormat.svg:
|
||||
this.svgProcess(onComplete, onError, arraybuffer, typeValue)
|
||||
break;
|
||||
case SupportFormat.jpg:
|
||||
case SupportFormat.png:
|
||||
case SupportFormat.bmp:
|
||||
case SupportFormat.gif:
|
||||
case SupportFormat.tiff:
|
||||
case SupportFormat.webp:
|
||||
this.mediaImageProcess(onComplete, onError, arraybuffer, typeValue)
|
||||
break;
|
||||
default:
|
||||
onError("PlaceHolderManager 文件类型不支持")
|
||||
break;
|
||||
}
|
||||
}
|
||||
resourceFetch.loadResource(res, suc, onError)
|
||||
} else {
|
||||
onError("PlaceHolderManager 输入参数有问题!")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private svgProcess(onComplete, onError, arraybuffer, typeValue) {
|
||||
let svgParseImpl = new SVGParseImpl()
|
||||
let size = { width: this.options.size.width, height: this.options.size.height }
|
||||
svgParseImpl.parseSvg(arraybuffer, size).then((value: PixelMap) => {
|
||||
let imageKnifeData = ImageKnifeData.createImagePixelMap(ImageKnifeType.PIXELMAP, value)
|
||||
onComplete(imageKnifeData)
|
||||
}).catch(err => {
|
||||
onError(err)
|
||||
})
|
||||
}
|
||||
|
||||
private mediaImageProcess(onComplete, onError, arraybuffer, typeValue) {
|
||||
let parseImageUtil = new ParseImageUtil()
|
||||
let success = (value: PixelMap) => {
|
||||
let imageKnifeData = ImageKnifeData.createImagePixelMap(ImageKnifeType.PIXELMAP, value)
|
||||
onComplete(imageKnifeData)
|
||||
}
|
||||
parseImageUtil.parseImage(arraybuffer, success, onError)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* Copyright (C) 2022 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import {ImageKnifeData} from '../ImageKnifeData'
|
||||
export interface IDrawExtension{
|
||||
<T>(context: CanvasRenderingContext2D,data: ImageKnifeData, imageKnifeOption:T, compWidth:number,compHeight:number, setGifTimeId?:(timeId:number)=>void)
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Copyright (C) 2022 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import {ImageKnifeOption} from '../ImageKnifeOption'
|
||||
import {ImageKnifeData} from '../ImageKnifeData'
|
||||
export interface IDrawLifeCycle{
|
||||
|
||||
// 展示占位图
|
||||
displayPlaceholder?: (context: CanvasRenderingContext2D,data: ImageKnifeData, imageKnifeOption:ImageKnifeOption, compWidth:number,compHeight:number, setGifTimeId?:(timeId:number)=>void)=>boolean
|
||||
|
||||
// 展示加载进度
|
||||
displayProgress?: (context: CanvasRenderingContext2D,progress: number, imageKnifeOption:ImageKnifeOption, compWidth:number,compHeight:number, setGifTimeId?:(timeId:number)=>void)=>boolean
|
||||
|
||||
// 展示缩略图
|
||||
displayThumbSizeMultiplier?: (context: CanvasRenderingContext2D,data: ImageKnifeData, imageKnifeOption:ImageKnifeOption, compWidth:number,compHeight:number, setGifTimeId?:(timeId:number)=>void)=>boolean
|
||||
|
||||
// 展示主图
|
||||
displayMainSource?: (context: CanvasRenderingContext2D,data: ImageKnifeData, imageKnifeOption:ImageKnifeOption, compWidth:number,compHeight:number, setGifTimeId?:(timeId:number)=>void)=>boolean
|
||||
|
||||
// 展示重试图层
|
||||
displayRetryholder?: (context: CanvasRenderingContext2D,data: ImageKnifeData, imageKnifeOption:ImageKnifeOption, compWidth:number,compHeight:number, setGifTimeId?:(timeId:number)=>void)=>boolean
|
||||
|
||||
// 展示失败占位图
|
||||
displayErrorholder?: (context: CanvasRenderingContext2D,data: ImageKnifeData, imageKnifeOption:ImageKnifeOption, compWidth:number,compHeight:number, setGifTimeId?:(timeId:number)=>void)=>boolean
|
||||
|
||||
}
|
|
@ -46,7 +46,7 @@ export class DownloadClient implements IDataFetch {
|
|||
loadTask = downloadTask;
|
||||
|
||||
loadTask.on('progress', (receivedSize, totalSize) => {
|
||||
let percent = Math.round(((receivedSize * 1.0) / (totalSize * 1.0)) * 100) + "%"
|
||||
let percent = Math.round(((receivedSize * 1.0) / (totalSize * 1.0)) * 100)
|
||||
if (request.progressFunc) {
|
||||
request.progressFunc(percent);
|
||||
}
|
||||
|
|
|
@ -1,59 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import arkWorker from '@ohos.worker';
|
||||
import {UPNG} from '../../imageknife/pngj/UPNG'
|
||||
|
||||
export function handler (e) {
|
||||
var data = e.data;
|
||||
switch (data.type) {
|
||||
case 'readPngImageAsync':
|
||||
var png = UPNG.decode(data.data);
|
||||
let array = png.data;
|
||||
let arrayData = array.buffer.slice(array.byteOffset, array.byteLength + array.byteOffset)
|
||||
png.data = arrayData;
|
||||
let dataObj = { type: 'readPngImageAsync', data: png, receiver: data.data}
|
||||
arkWorker.parentPort.postMessage(dataObj, [png.data, data.data]);
|
||||
break;
|
||||
case 'writePngWithStringAsync':
|
||||
let addInfo = data.info;
|
||||
let pngDecode = UPNG.decode(data.data);
|
||||
let newPng = UPNG.encodeWithString(addInfo, UPNG.toRGBA8(pngDecode), pngDecode.width, pngDecode.height, 0)
|
||||
let dataObj2 = { type: 'writePngWithStringAsync', data: newPng, receiver: data.data}
|
||||
arkWorker.parentPort.postMessage(dataObj2, [newPng, data.data]);
|
||||
break;
|
||||
case 'writePngAsync':
|
||||
let pngDecode3 = UPNG.decode(data.data);
|
||||
let newPng3 = UPNG.encode(UPNG.toRGBA8(pngDecode3), pngDecode3.width, pngDecode3.height, 0)
|
||||
let dataObj3 = { type: 'writePngAsync', data: newPng3, receiver: data.data}
|
||||
arkWorker.parentPort.postMessage(dataObj3, [newPng3, data.data]);
|
||||
break;
|
||||
case 'normal':
|
||||
arkWorker.parentPort.postMessage(data);
|
||||
break;
|
||||
case 'error':
|
||||
throw new Error('123');
|
||||
break;
|
||||
case 'buffer':
|
||||
let uint8Array = new Uint8Array(data.data);
|
||||
arkWorker.parentPort.postMessage(data, [data.data]);
|
||||
|
||||
break;
|
||||
default:
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -23,11 +23,14 @@ import{DiskCacheProxy} from "../requestmanage/DiskCacheProxy"
|
|||
import{FileTypeUtil} from "../utils/FileTypeUtil"
|
||||
import{IDataFetch} from "../../imageknife/networkmanage/IDataFetch"
|
||||
import{IResourceFetch} from "../../imageknife/resourcemanage/IResourceFetch"
|
||||
import{ImageKnifeData} from "../ImageKnifeData"
|
||||
import{ImageKnifeData,ImageKnifeType} from "../ImageKnifeData"
|
||||
import {AllCacheInfo, IAllCacheInfoCallback} from "../../imageknife/interface/IAllCacheInfoCallback"
|
||||
import{ParseImageUtil} from '../utils/ParseImageUtil'
|
||||
import{IParseImage} from '../interface/IParseImage'
|
||||
import image from "@ohos.multimedia.image"
|
||||
import { SVGParseImpl } from '../utils/svg/SVGParseImpl'
|
||||
import { GIFParseImpl } from '../utils/gif/GIFParseImpl'
|
||||
import { GIFFrame } from '../utils/gif/GIFFrame'
|
||||
|
||||
export interface AsyncString {
|
||||
(data: string): void;
|
||||
|
@ -197,40 +200,25 @@ export class RequestManager {
|
|||
// 使用媒体子系统 ImageSource解析文件 获取PixelMap
|
||||
let fileTypeUtil = new FileTypeUtil();
|
||||
let typeValue = fileTypeUtil.getFileType(arrayBuffer)
|
||||
console.log("RequstManager - 文件类型为= " + typeValue)
|
||||
if ((ImageKnifeData.GIF == typeValue && !request.dontAnimateFlag) || ImageKnifeData.SVG == typeValue) {
|
||||
// 将图片资源 转换为文件地址
|
||||
let folderPath = this.options.getFilesPath() + "/" + this.options._svgAndGifFolder;
|
||||
let filePath = this.options.getFilesPath() + "/" + this.options._svgAndGifFolder + "/"
|
||||
+ Md5.hashStr(this.options.generateDataKey) + "." + typeValue;
|
||||
let filename = Md5.hashStr(this.options.generateDataKey) + "." + typeValue;
|
||||
new Promise((resolve, reject) => {
|
||||
// 存文件至svg目录,并且记录文件名
|
||||
resolve("svg gif 文件开始本地保存!");
|
||||
console.log("RequestManager - 文件类型为= " + typeValue)
|
||||
// gif处理
|
||||
if(ImageKnifeData.GIF == typeValue && !request.dontAnimateFlag){
|
||||
// 处理gif
|
||||
this.gifProcess(onComplete,onError, arrayBuffer,typeValue,(imageKnifeData)=>{
|
||||
this.mMemoryCacheProxy.putValue(this.options.generateCacheKey, imageKnifeData)
|
||||
})
|
||||
.then((res) => {
|
||||
// 创建文件
|
||||
FileUtils.getInstance()
|
||||
.createFileProcess(folderPath, filePath, arrayBuffer);
|
||||
// 写入记录
|
||||
FileUtils.getInstance()
|
||||
.writeData(this.options.getFilesPath() +
|
||||
"/" + this.options._svgAndGifFolder + "/" + this.options._svgAndGifCommitFile, filename + "\n");
|
||||
console.log("svg gif 本地保存成功 输出!");
|
||||
let imageKnifeData = this.createImageKnifeData(ImageKnifeData.STRING, filePath, typeValue);
|
||||
this.mMemoryCacheProxy.putValue(this.options.generateCacheKey, imageKnifeData);
|
||||
onComplete(imageKnifeData);
|
||||
}else if(ImageKnifeData.SVG == typeValue){
|
||||
// 处理svg
|
||||
this.svgProcess(onComplete,onError,arrayBuffer,typeValue,(imageKnifeData)=>{
|
||||
this.mMemoryCacheProxy.putValue(this.options.generateCacheKey,imageKnifeData)
|
||||
})
|
||||
.catch((err) => {
|
||||
onError(err)
|
||||
})
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
if (request.transformations[0]) {
|
||||
request.transformations[0].transform(arrayBuffer, request, (error, pixelMap: PixelMap) => {
|
||||
// 输出给Image
|
||||
if (pixelMap) {
|
||||
let imageKnifeData = this.createImageKnifeData(ImageKnifeData.PIXELMAP, pixelMap, typeValue);
|
||||
|
||||
let imageKnifeData = this.createImagePixelMap(ImageKnifeType.PIXELMAP, pixelMap);
|
||||
this.mMemoryCacheProxy.putValue(request.generateCacheKey, imageKnifeData);
|
||||
onComplete(imageKnifeData);
|
||||
} else {
|
||||
|
@ -240,7 +228,7 @@ export class RequestManager {
|
|||
}
|
||||
else {
|
||||
let success = (value: PixelMap) => {
|
||||
let imageKnifeData = this.createImageKnifeData(ImageKnifeData.PIXELMAP, value, typeValue);
|
||||
let imageKnifeData = this.createImagePixelMap(ImageKnifeType.PIXELMAP, value);
|
||||
this.mMemoryCacheProxy.putValue(request.generateCacheKey, imageKnifeData);
|
||||
onComplete(imageKnifeData);
|
||||
}
|
||||
|
@ -310,29 +298,16 @@ export class RequestManager {
|
|||
// 步骤一:文件转为pixelMap 然后变换 给Image组件
|
||||
let fileTypeUtil = new FileTypeUtil();
|
||||
let typeValue = fileTypeUtil.getFileType(source);
|
||||
if (((ImageKnifeData.GIF == typeValue && !request.dontAnimateFlag) || ImageKnifeData.SVG == typeValue)) {
|
||||
// 将图片资源 转换为文件地址
|
||||
let folderPath = this.options.getFilesPath() + "/" + this.options._svgAndGifFolder;
|
||||
let filePath = this.options.getFilesPath() + "/" + this.options._svgAndGifFolder + "/"
|
||||
+ Md5.hashStr(this.options.generateDataKey) + "." + typeValue;
|
||||
let filename = Md5.hashStr(this.options.generateDataKey) + "." + typeValue;
|
||||
new Promise((resolve, reject) => {
|
||||
// 存文件至svg目录,并且记录文件名
|
||||
resolve("svg gif 文件开始本地保存!");
|
||||
}).then((res) => {
|
||||
FileUtils.getInstance()
|
||||
.createFileProcess(folderPath, filePath, source);
|
||||
FileUtils.getInstance()
|
||||
.writeData(this.options.getFilesPath() +
|
||||
"/" + this.options._svgAndGifFolder + "/" + this.options._svgAndGifCommitFile, filename + "\n");
|
||||
let imageKnifeData = this.createImageKnifeData(ImageKnifeData.STRING, filePath, typeValue)
|
||||
this.mMemoryCacheProxy.putValue(this.options.generateCacheKey, imageKnifeData);
|
||||
onComplete(imageKnifeData);
|
||||
// 解析磁盘文件 gif 和 svg
|
||||
if(ImageKnifeData.GIF == typeValue && !request.dontAnimateFlag){
|
||||
// 处理gif
|
||||
this.gifProcess(onComplete,onError,source,typeValue, (imageKnifeData)=>{
|
||||
this.mMemoryCacheProxy.putValue(this.options.generateCacheKey, imageKnifeData)
|
||||
})
|
||||
.catch((err) => {
|
||||
onError(err)
|
||||
}else if(ImageKnifeData.SVG == typeValue){
|
||||
this.svgProcess(onComplete,onError, source, typeValue, (imageKnifeData)=>{
|
||||
this.mMemoryCacheProxy.putValue(this.options.generateCacheKey, imageKnifeData)
|
||||
})
|
||||
|
||||
} else {
|
||||
if (this.options.transformations[0]) {
|
||||
if (this.options.thumbSizeMultiplier) {
|
||||
|
@ -345,7 +320,7 @@ export class RequestManager {
|
|||
let thumbError = this.options.thumbholderOnError.bind(this.options);
|
||||
this.options.transformations[0].transform(source, thumbOption, (error, pixelMap: PixelMap) => {
|
||||
if (pixelMap) {
|
||||
let imageKnifeData = this.createImageKnifeData(ImageKnifeData.PIXELMAP, pixelMap, typeValue);
|
||||
let imageKnifeData = this.createImagePixelMap(ImageKnifeType.PIXELMAP, pixelMap);
|
||||
thumbCallback(imageKnifeData);
|
||||
} else {
|
||||
thumbError(error);
|
||||
|
@ -355,7 +330,7 @@ export class RequestManager {
|
|||
this.options.transformations[0].transform(source, request, (error, pixelMap: PixelMap) => {
|
||||
if (pixelMap) {
|
||||
// 保存一份变换后的图片PixelMap到MemoryCache
|
||||
let imageKnifeData = this.createImageKnifeData(ImageKnifeData.PIXELMAP, pixelMap, typeValue);
|
||||
let imageKnifeData = this.createImagePixelMap(ImageKnifeType.PIXELMAP, pixelMap);
|
||||
this.mMemoryCacheProxy.putValue(this.options.generateCacheKey, imageKnifeData);
|
||||
onComplete(imageKnifeData);
|
||||
} else {
|
||||
|
@ -368,7 +343,7 @@ export class RequestManager {
|
|||
this.options.transformations[0].transform(source, request, (error, pixelMap: PixelMap) => {
|
||||
if (pixelMap) {
|
||||
// 保存一份变换后的图片PixelMap到MemoryCache
|
||||
let imageKnifeData = this.createImageKnifeData(ImageKnifeData.PIXELMAP, pixelMap, typeValue);
|
||||
let imageKnifeData = this.createImagePixelMap(ImageKnifeType.PIXELMAP, pixelMap);
|
||||
this.mMemoryCacheProxy.putValue(this.options.generateCacheKey, imageKnifeData);
|
||||
onComplete(imageKnifeData);
|
||||
} else {
|
||||
|
@ -382,13 +357,13 @@ export class RequestManager {
|
|||
let thumbCallback = this.options.thumbholderOnComplete.bind(this.options);
|
||||
let thumbError = this.options.thumbholderOnError.bind(this.options);
|
||||
let thumbSuccess = (value: PixelMap) => {
|
||||
let imageKnifeData = this.createImageKnifeData(ImageKnifeData.PIXELMAP, value, typeValue);
|
||||
let imageKnifeData = this.createImagePixelMap(ImageKnifeType.PIXELMAP, value);
|
||||
thumbCallback(imageKnifeData);
|
||||
}
|
||||
this.mParseImageUtil.parseImageThumbnail(request.thumbSizeMultiplier, source, thumbSuccess, thumbError);
|
||||
setTimeout(()=>{
|
||||
let success = (value: PixelMap) => {
|
||||
let imageKnifeData = this.createImageKnifeData(ImageKnifeData.PIXELMAP, value, typeValue);
|
||||
let imageKnifeData = this.createImagePixelMap(ImageKnifeType.PIXELMAP, value);
|
||||
this.mMemoryCacheProxy.putValue(this.options.generateCacheKey, imageKnifeData);
|
||||
onComplete(imageKnifeData);
|
||||
}
|
||||
|
@ -397,7 +372,7 @@ export class RequestManager {
|
|||
}
|
||||
else {
|
||||
let success = (value: PixelMap) => {
|
||||
let imageKnifeData = this.createImageKnifeData(ImageKnifeData.PIXELMAP, value, typeValue);
|
||||
let imageKnifeData = this.createImagePixelMap(ImageKnifeType.PIXELMAP, value);
|
||||
this.mMemoryCacheProxy.putValue(this.options.generateCacheKey, imageKnifeData);
|
||||
onComplete(imageKnifeData);
|
||||
}
|
||||
|
@ -416,13 +391,13 @@ export class RequestManager {
|
|||
let thumbCallback = this.options.thumbholderOnComplete.bind(this.options);
|
||||
let thumbError = this.options.thumbholderOnError.bind(this.options);
|
||||
let thumbSuccess = (value: PixelMap) => {
|
||||
let imageKnifeData = this.createImageKnifeData(ImageKnifeData.PIXELMAP, value, typeValue);
|
||||
let imageKnifeData = this.createImagePixelMap(ImageKnifeType.PIXELMAP, value);
|
||||
thumbCallback(imageKnifeData);
|
||||
}
|
||||
this.mParseImageUtil.parseImageThumbnail(request.thumbSizeMultiplier, source, thumbSuccess, thumbError);
|
||||
setTimeout(()=>{
|
||||
let success = (value: PixelMap) => {
|
||||
let imageKnifeData = this.createImageKnifeData(ImageKnifeData.PIXELMAP, value, typeValue);
|
||||
let imageKnifeData = this.createImagePixelMap(ImageKnifeType.PIXELMAP, value);
|
||||
this.mMemoryCacheProxy.putValue(this.options.generateCacheKey, imageKnifeData);
|
||||
onComplete(imageKnifeData);
|
||||
}
|
||||
|
@ -430,7 +405,7 @@ export class RequestManager {
|
|||
},this.options.thumbDelayTime)
|
||||
}else{
|
||||
let success = (value: PixelMap) => {
|
||||
let imageKnifeData = this.createImageKnifeData(ImageKnifeData.PIXELMAP, value, typeValue)
|
||||
let imageKnifeData = this.createImagePixelMap(ImageKnifeType.PIXELMAP, value)
|
||||
this.mMemoryCacheProxy.putValue(this.options.generateCacheKey, imageKnifeData);
|
||||
onComplete(imageKnifeData);
|
||||
}
|
||||
|
@ -456,40 +431,35 @@ export class RequestManager {
|
|||
onError("暂不支持 下载文件类型!类型=" + filetype);
|
||||
return;
|
||||
}
|
||||
if ((ImageKnifeData.GIF == filetype && !this.options.dontAnimateFlag) || ImageKnifeData.SVG == filetype) {
|
||||
// 将图片资源 转换为文件地址
|
||||
let folderPath = this.options.getFilesPath() + "/" + this.options._svgAndGifFolder;
|
||||
let filePath = this.options.getFilesPath() + "/" + this.options._svgAndGifFolder + "/"
|
||||
+ Md5.hashStr(this.options.generateDataKey) + "." + filetype;
|
||||
let filename = Md5.hashStr(this.options.generateDataKey) + "." + filetype;
|
||||
// 1.文件保存 2.内存缓存 3.输出结果
|
||||
new Promise((resolve, reject) => {
|
||||
// 存文件至svg目录,并且记录文件名
|
||||
resolve("svg gif 文件开始本地保存!");
|
||||
|
||||
// 解析磁盘文件 gif 和 svg
|
||||
if(ImageKnifeData.GIF == filetype && !this.options.dontAnimateFlag){
|
||||
// 处理gif
|
||||
this.gifProcess(onComplete,onError,source,filetype, (imageKnifeData)=>{
|
||||
this.mMemoryCacheProxy.putValue(this.options.generateCacheKey, imageKnifeData)
|
||||
})
|
||||
.then((res) => {
|
||||
FileUtils.getInstance()
|
||||
.createFileProcess(folderPath, filePath, source);
|
||||
FileUtils.getInstance()
|
||||
.writeData(this.options.getFilesPath() +
|
||||
"/" + this.options._svgAndGifFolder + "/" + this.options._svgAndGifCommitFile, filename + "\n");
|
||||
let imageKnifeData = this.createImageKnifeData(ImageKnifeData.STRING, filePath, filetype);
|
||||
this.mMemoryCacheProxy.putValue(this.options.generateCacheKey, imageKnifeData);
|
||||
onComplete(imageKnifeData);
|
||||
})
|
||||
.catch((err) => {
|
||||
onError(err)
|
||||
})
|
||||
|
||||
// 保存二级磁盘缓存
|
||||
new Promise((resolve, reject) => {
|
||||
resolve(source)
|
||||
})
|
||||
.then(async (arraybuffer: ArrayBuffer) => {
|
||||
Promise.resolve(source)
|
||||
.then(async (arraybuffer: ArrayBuffer)=>{
|
||||
await this.mDiskCacheProxy.putValue(this.options.generateDataKey, arraybuffer)
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log("save diskLruCache error=" + err);
|
||||
.catch(err=>{
|
||||
console.log('download file is ='+ImageKnifeData.GIF+'and save diskLruCache error ='+ err)
|
||||
})
|
||||
}else if(ImageKnifeData.SVG == filetype){
|
||||
// 处理svg
|
||||
this.svgProcess(onComplete,onError, source, filetype, (imageKnifeData)=>{
|
||||
this.mMemoryCacheProxy.putValue(this.options.generateCacheKey, imageKnifeData)
|
||||
})
|
||||
|
||||
// 保存二级磁盘缓存
|
||||
Promise.resolve(source)
|
||||
.then(async (arraybuffer: ArrayBuffer)=>{
|
||||
await this.mDiskCacheProxy.putValue(this.options.generateDataKey, arraybuffer)
|
||||
})
|
||||
.catch(err=>{
|
||||
console.log('download file is ='+ImageKnifeData.SVG+'and save diskLruCache error ='+ err)
|
||||
})
|
||||
} else {
|
||||
// 进行变换
|
||||
|
@ -512,7 +482,7 @@ export class RequestManager {
|
|||
let thumbCallback = this.options.thumbholderOnComplete.bind(this.options);
|
||||
let thumbError = this.options.thumbholderOnError.bind(this.options);
|
||||
let thumbSuccess = (value: PixelMap) => {
|
||||
let imageKnifeData = this.createImageKnifeData(ImageKnifeData.PIXELMAP, value, filetype);
|
||||
let imageKnifeData = this.createImagePixelMap(ImageKnifeType.PIXELMAP, value);
|
||||
thumbCallback(imageKnifeData);
|
||||
}
|
||||
this.mParseImageUtil.parseImageThumbnail(this.options.thumbSizeMultiplier, source, thumbSuccess, thumbError);
|
||||
|
@ -532,17 +502,18 @@ export class RequestManager {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
createImageKnifeData(imageKnifeType:string, imageKnifeValue:PixelMap|string|Resource, imageKnifeSourceType:string):ImageKnifeData{
|
||||
let imageKnifeData = new ImageKnifeData();
|
||||
imageKnifeData.imageKnifeType = imageKnifeType;
|
||||
imageKnifeData.imageKnifeValue = imageKnifeValue;
|
||||
imageKnifeData.imageKnifeSourceType = imageKnifeSourceType;
|
||||
return imageKnifeData;
|
||||
createImagePixelMap(imageKnifeType: ImageKnifeType, imageKnifeValue: PixelMap): ImageKnifeData{
|
||||
return ImageKnifeData.createImagePixelMap(imageKnifeType,imageKnifeValue);
|
||||
}
|
||||
|
||||
createImageGIFFrame(imageKnifeType: ImageKnifeType, imageKnifeValue: GIFFrame[]): ImageKnifeData{
|
||||
return ImageKnifeData.createImageGIFFrame(imageKnifeType,imageKnifeValue);
|
||||
}
|
||||
|
||||
|
||||
|
||||
private saveCacheAndDisk(value: PixelMap, filetype:string, onComplete, source:ArrayBuffer) {
|
||||
let imageKnifeData = this.createImageKnifeData(ImageKnifeData.PIXELMAP, value, filetype);
|
||||
let imageKnifeData = this.createImagePixelMap(ImageKnifeType.PIXELMAP, value);
|
||||
this.mMemoryCacheProxy.putValue(this.options.generateCacheKey, imageKnifeData);
|
||||
let save2DiskCache = async (arraybuffer) => {
|
||||
await this.mDiskCacheProxy.putValue(this.options.generateDataKey, arraybuffer)
|
||||
|
@ -565,7 +536,7 @@ export class RequestManager {
|
|||
let thumbError = this.options.thumbholderOnError.bind(this.options);
|
||||
this.options.transformations[0].transform(source, thumbOption, (error, pixelMap: PixelMap) => {
|
||||
if (pixelMap) {
|
||||
let imageKnifeData = this.createImageKnifeData(ImageKnifeData.PIXELMAP, pixelMap, filetype);
|
||||
let imageKnifeData = this.createImagePixelMap(ImageKnifeType.PIXELMAP, pixelMap);
|
||||
thumbCallback(imageKnifeData);
|
||||
} else {
|
||||
thumbError(error);
|
||||
|
@ -581,6 +552,41 @@ export class RequestManager {
|
|||
})
|
||||
}, this.options.thumbDelayTime)
|
||||
}
|
||||
private svgProcess(onComplete, onError, arraybuffer, typeValue, cacheStrategy?: (cacheData: ImageKnifeData) => void) {
|
||||
let svgParseImpl = new SVGParseImpl()
|
||||
let size = { width: this.options.size.width, height: this.options.size.height }
|
||||
svgParseImpl.parseSvg(arraybuffer, size).then((value: PixelMap) => {
|
||||
let imageKnifeData = ImageKnifeData.createImagePixelMap(ImageKnifeType.PIXELMAP, value)
|
||||
if(cacheStrategy){
|
||||
cacheStrategy(imageKnifeData)
|
||||
}
|
||||
onComplete(imageKnifeData)
|
||||
}).catch(err => {
|
||||
onError(err)
|
||||
})
|
||||
}
|
||||
|
||||
private gifProcess(onComplete, onError, arraybuffer, typeValue, cacheStrategy?: (cacheData: ImageKnifeData) => void) {
|
||||
let gifParseImpl = new GIFParseImpl()
|
||||
gifParseImpl.parseGifs(arraybuffer, (data?,err?)=>{
|
||||
if(err){
|
||||
onError(err)
|
||||
}
|
||||
console.log("gifProcess data is null:"+(data == null));
|
||||
if(!!data){
|
||||
let imageKnifeData = this.createImageGIFFrame(ImageKnifeType.GIFFRAME,data)
|
||||
console.log('gifProcess 生成gif 返回数据类型')
|
||||
if(cacheStrategy){
|
||||
console.log('gifProcess 生成gif并且存入了缓存策略')
|
||||
cacheStrategy(imageKnifeData)
|
||||
}
|
||||
onComplete(imageKnifeData)
|
||||
}else{
|
||||
onError('Parse GIF callback data is null, you need check callback data!')
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -95,8 +95,8 @@ export namespace CalculatePixelUtils {
|
|||
}
|
||||
}
|
||||
|
||||
function gaussGray(psrc: Array<number>, horz: number, vert: number,
|
||||
width: number, height: number): number {
|
||||
var gaussGray = (psrc: Array<number>, horz: number, vert: number,
|
||||
width: number, height: number): number=> {
|
||||
let dst, src, n_p, n_m, d_p, d_m, bd_p, bd_m, val_p, val_m, initial_p, initial_m: Array<number>;
|
||||
let i, j, t, k, row, col, terms, std_dev, sp_p_idx, sp_m_idx, vp_idx, vm_idx: number;
|
||||
let row_stride = width;
|
||||
|
@ -203,9 +203,9 @@ export namespace CalculatePixelUtils {
|
|||
return 0;
|
||||
}
|
||||
|
||||
function findConstants(n_p: Array<number>, n_m: Array<number>, d_p: Array<number>,
|
||||
var findConstants = (n_p: Array<number>, n_m: Array<number>, d_p: Array<number>,
|
||||
d_m: Array<number>, bd_p: Array<number>
|
||||
, bd_m: Array<number>, std_dev: number) {
|
||||
, bd_m: Array<number>, std_dev: number)=> {
|
||||
let div = Math.sqrt(2 * 3.141593) * std_dev;
|
||||
let x0 = -1.783 / std_dev;
|
||||
let x1 = -1.723 / std_dev;
|
||||
|
@ -262,8 +262,8 @@ export namespace CalculatePixelUtils {
|
|||
}
|
||||
}
|
||||
|
||||
function transferGaussPixels(src1: Array<number>, src2: Array<number>,
|
||||
dest: Array<number>, bytes: number, width: number) {
|
||||
var transferGaussPixels = (src1: Array<number>, src2: Array<number>,
|
||||
dest: Array<number>, bytes: number, width: number)=> {
|
||||
let i, j, k, b, sum: number;
|
||||
let bend = bytes * width;
|
||||
i = j = k = 0;
|
||||
|
|
|
@ -24,33 +24,33 @@ export namespace fastBlur {
|
|||
|
||||
export async function blur(bitmap: any, radius: number, canReuseInBitmap: boolean, func: AsyncTransform<PixelMap>) {
|
||||
|
||||
// Stack Blur v1.0 from
|
||||
// http://www.quasimondo.com/StackBlurForCanvas/StackBlurDemo.html
|
||||
//
|
||||
// Java Author: Mario Klingemann <mario at quasimondo.com>
|
||||
// http://incubator.quasimondo.com
|
||||
// created Feburary 29, 2004
|
||||
// port : Yahel Bouaziz <yahel at kayenko.com>
|
||||
// http://www.kayenko.com
|
||||
// ported april 5th, 2012
|
||||
|
||||
// This is a compromise between Gaussian Blur and Box blur
|
||||
// It creates much better looking blurs than Box Blur, but is
|
||||
// 7x faster than my Gaussian Blur implementation.
|
||||
//
|
||||
// I called it Stack Blur because this describes best how this
|
||||
// filter works internally: it creates a kind of moving stack
|
||||
// of colors whilst scanning through the image. Thereby it
|
||||
// just has to add one new block of color to the right side
|
||||
// of the stack and remove the leftmost color. The remaining
|
||||
// colors on the topmost layer of the stack are either added on
|
||||
// or reduced by one, depending on if they are on the right or
|
||||
// on the left side of the stack.
|
||||
//
|
||||
// If you are using this algorithm in your code please add
|
||||
// the following line:
|
||||
//
|
||||
// Stack Blur Algorithm by Mario Klingemann <mario@quasimondo.com>
|
||||
// http://www.quasimondo.com/StackBlurForCanvas/StackBlurDemo.html
|
||||
//
|
||||
// Java Author: Mario Klingemann <mario at quasimondo.com>
|
||||
// http://incubator.quasimondo.com
|
||||
// created Feburary 29, 2004
|
||||
// port : Yahel Bouaziz <yahel at kayenko.com>
|
||||
// http://www.kayenko.com
|
||||
// ported april 5th, 2012
|
||||
//
|
||||
// This is a compromise between Gaussian Blur and Box blur
|
||||
// It creates much better looking blurs than Box Blur, but is
|
||||
// 7x faster than my Gaussian Blur implementation.
|
||||
//
|
||||
// I called it Stack Blur because this describes best how this
|
||||
// filter works internally: it creates a kind of moving stack
|
||||
// of colors whilst scanning through the image. Thereby it
|
||||
// just has to add one new block of color to the right side
|
||||
// of the stack and remove the leftmost color. The remaining
|
||||
// colors on the topmost layer of the stack are either added on
|
||||
// or reduced by one, depending on if they are on the right or
|
||||
// on the left side of the stack.
|
||||
//
|
||||
// If you are using this algorithm in your code please add
|
||||
// the following line:
|
||||
//
|
||||
|
||||
if (radius < 1) {
|
||||
func("error,radius must be greater than 1 ", null);
|
||||
return;
|
||||
|
|
|
@ -15,171 +15,59 @@
|
|||
|
||||
export class FileTypeUtil {
|
||||
private map = new Map();
|
||||
private READ_MIN_LENGTH;
|
||||
private SUPPORT_FORMATS = [
|
||||
PhotoFormat.jpg,
|
||||
PhotoFormat.png,
|
||||
PhotoFormat.tiff,
|
||||
PhotoFormat.bmp,
|
||||
PhotoFormat.webp,
|
||||
PhotoFormat.svg,
|
||||
PhotoFormat.gif
|
||||
]
|
||||
|
||||
constructor() {
|
||||
this.initImageType();
|
||||
this.initMediaType();
|
||||
this.initOtherType();
|
||||
this.initImageType();
|
||||
|
||||
}
|
||||
|
||||
private initImageType(){
|
||||
this.map.set("FFD8FF", "JPG")
|
||||
this.map.set("89504E47", "PNG")
|
||||
this.map.set("47494638", "GIF")
|
||||
this.map.set("49492A00", "TIF")
|
||||
this.map.set("52494646", "RIFF")
|
||||
this.map.set("57454250", "WEBP")
|
||||
this.map.set("3C3F786D6C", "SVG")
|
||||
this.map.set("424D", "BMP")
|
||||
this.map.set("424D228C010000000000", "BMP") // 16色位图(bmp)
|
||||
this.map.set("424D8240090000000000", "BMP") // 24位位图(bmp)
|
||||
this.map.set("424D8E1B030000000000", "BMP") // 256色位图(bmp)
|
||||
}
|
||||
|
||||
private initMediaType(){
|
||||
this.map.set("57415645", "WAV")
|
||||
this.map.set("41564920", "AVI")
|
||||
this.map.set("00000020667479706D70", "MP4")
|
||||
this.map.set("49443303000000002176", "MP3")
|
||||
this.map.set("464C5601050000000900", "FLV")
|
||||
}
|
||||
|
||||
private initOtherType(){
|
||||
this.map.set("41433130", "DWG")
|
||||
this.map.set("38425053", "PSD")
|
||||
this.map.set("7B5C727466", "RTF")
|
||||
/** XML */
|
||||
// this.map.set("3C3F786D6C", "XML")
|
||||
this.map.set("68746D6C3E", "HTML")
|
||||
this.map.set("44656C69766572792D646174653A", "EML")
|
||||
this.map.set("CFAD12FEC5FD746F", "DBX")
|
||||
this.map.set("2142444E", "PST")
|
||||
this.map.set("0xD0CF11E0A1B11AE1", "OLE2")
|
||||
/** Microsoft Word/Excel 注意:word 和 excel的文件头一样 */
|
||||
this.map.set("D0CF11E0", "XLS")
|
||||
|
||||
// this.map.set("DOC", "D0CF11E0")
|
||||
|
||||
// this.map.set("504B0304", "DOCX")
|
||||
|
||||
this.map.set("504B0304", "XLSX")
|
||||
this.map.set("5374616E64617264204A", "MDB")
|
||||
this.map.set("FF575043", "WPB")
|
||||
this.map.set("252150532D41646F6265", "EPS")
|
||||
this.map.set("252150532D41646F6265", "PS")
|
||||
this.map.set("255044462D312E", "PDF")
|
||||
this.map.set("AC9EBD8F", "qdf")
|
||||
this.map.set("458600000600", "qbb")
|
||||
this.map.set("E3828596", "PWL")
|
||||
this.map.set("504B0304", "ZIP")
|
||||
this.map.set("52617221", "ARAR")
|
||||
this.map.set("2E7261FD", "RAM")
|
||||
this.map.set("2E524D46", "RM")
|
||||
this.map.set("2E524D46000000120001", "RMVB")
|
||||
this.map.set("000001BA", "MPG")
|
||||
this.map.set("6D6F6F76", "MOV")
|
||||
this.map.set("3026B2758E66CF11", "ASF")
|
||||
this.map.set("60EA", "ARJ")
|
||||
this.map.set("4D546864", "MID")
|
||||
|
||||
this.map.set("1F8B08", "GZ")
|
||||
this.map.set("48544D4C207B0D0A0942", "CSS")
|
||||
this.map.set("696B2E71623D696B2E71", "JS")
|
||||
this.map.set("d0cf11e0a1b11ae10000", "VSD")
|
||||
this.map.set("d0cf11e0a1b11ae10000", "WPS")
|
||||
this.map.set("6431303A637265617465", "TORRENT")
|
||||
this.map.set("3C2540207061676520", "JSP")
|
||||
this.map.set("7061636B61676520", "JAVA")
|
||||
this.map.set("CAFEBABE0000002E00", "CLASS")
|
||||
this.map.set("504B03040A000000", "JAR")
|
||||
this.map.set("4D616E69666573742D56", "MF")
|
||||
this.map.set("4D5A9000030000000400", "EXE")
|
||||
this.map.set("7F454C4601010100", "ELF")
|
||||
this.map.set("2000604060", "WK1")
|
||||
this.map.set("00001A0000100400", "WK3")
|
||||
this.map.set("00001A0002100400", "WK4")
|
||||
this.map.set("576F726450726F", "LWP")
|
||||
this.map.set("53520100", "SLY")
|
||||
private getDataViewAt(dataView:DataView,index:number): string{
|
||||
return this.dec2Hex(dataView.getUint8(index))
|
||||
}
|
||||
|
||||
|
||||
getMaxKeyLength() {
|
||||
let length = 0;
|
||||
this.map.forEach((value, key, map) => {
|
||||
let keyName = key;
|
||||
length = Math.max(keyName.length, length);
|
||||
})
|
||||
return length;
|
||||
}
|
||||
|
||||
isImage(arraybuffer: ArrayBuffer) {
|
||||
|
||||
let value = this.getFileType(arraybuffer)
|
||||
if (
|
||||
value == "jpg" ||
|
||||
value == "png" ||
|
||||
value == "riff" ||
|
||||
value == "webp" ||
|
||||
value == "bmp" ||
|
||||
value == "gif" ||
|
||||
value == "svg"
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
isPixelMapType(arraybuffer: ArrayBuffer) {
|
||||
|
||||
let value = this.getFileType(arraybuffer)
|
||||
if (
|
||||
value == "jpg" ||
|
||||
value == "png" ||
|
||||
value == "riff" ||
|
||||
value == "webp" ||
|
||||
value == "bmp"
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
isGif(arraybuffer: ArrayBuffer) {
|
||||
let value = this.getFileType(arraybuffer)
|
||||
if (
|
||||
value == "gif"
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
isSvg(arraybuffer: ArrayBuffer) {
|
||||
let value = this.getFileType(arraybuffer)
|
||||
if (
|
||||
value == "svg"
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
getFileType(arraybuffer: ArrayBuffer) {
|
||||
if(arraybuffer == null || arraybuffer == undefined || arraybuffer.byteLength <= this.getMaxKeyLength()){
|
||||
let fileType = undefined;
|
||||
if (arraybuffer == null || arraybuffer == undefined || arraybuffer.byteLength <= this.READ_MIN_LENGTH) {
|
||||
return undefined;
|
||||
}
|
||||
let maxlen = this.getMaxKeyLength() / 2;
|
||||
|
||||
let dataView = new DataView(arraybuffer);
|
||||
let searchKey = "";
|
||||
for (let i = 0; i < maxlen; i++) {
|
||||
searchKey = searchKey + this.dec2Hex(dataView.getUint8(i));
|
||||
let value = this.map.get(searchKey);
|
||||
if (value != undefined) {
|
||||
return (value as string).toLowerCase();
|
||||
console.log('dataView +'+this.getDataViewAt(dataView,0)+this.getDataViewAt(dataView,1))
|
||||
|
||||
for(var [key,value] of this.map){
|
||||
let keySplit = key.split(',')
|
||||
if(keySplit.length == 2){
|
||||
let offset = parseInt(keySplit[0])
|
||||
let magicStringLength = keySplit[1].length;
|
||||
let readLength = magicStringLength/2;
|
||||
let start = 0;
|
||||
let fileMagic = ''
|
||||
while(start< readLength){
|
||||
fileMagic+=this.getDataViewAt(dataView,offset+start)
|
||||
start++;
|
||||
}
|
||||
// console.log('magic='+fileMagic+' keySplit[1]='+keySplit[1]+' fileMagic == keySplit[1] ='+(fileMagic == keySplit[1])+
|
||||
// ' fileMagic type ='+typeof(fileMagic) + ' keySplit[1]='+typeof(keySplit[1]))
|
||||
if(fileMagic == keySplit[1]){
|
||||
console.log('匹配到了 fileType='+value)
|
||||
fileType = value
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return fileType;
|
||||
}
|
||||
|
||||
dec2Hex(uint8: number) {
|
||||
|
@ -189,4 +77,88 @@ export class FileTypeUtil {
|
|||
}
|
||||
return hex.toUpperCase();
|
||||
}
|
||||
|
||||
private initImageType() {
|
||||
if(!this.map){
|
||||
this.map = new Map()
|
||||
}
|
||||
this.SUPPORT_FORMATS.forEach((value,index,arrs)=>{
|
||||
let values = value.split(',')
|
||||
if(values.length == 3){
|
||||
let magicSplits = values[2].split("|")
|
||||
if(magicSplits.length == 1){
|
||||
this.map.set(values[1]+','+values[2],values[0])
|
||||
}else if(magicSplits.length > 1){
|
||||
for(let i=0; i<magicSplits.length; i++){
|
||||
let magicStr = magicSplits[i];
|
||||
this.map.set(values[1]+','+magicStr,values[0])
|
||||
}
|
||||
}else{
|
||||
// 文件魔数不存在,不处理
|
||||
}
|
||||
}
|
||||
})
|
||||
this.initReadMinLength();
|
||||
|
||||
this.printMapContent();
|
||||
}
|
||||
|
||||
private printMapContent(){
|
||||
for(var [key,value] of this.map){
|
||||
console.log('key='+key+'---value='+value)
|
||||
}
|
||||
}
|
||||
|
||||
private initReadMinLength(){
|
||||
let max = 0;
|
||||
this.map.forEach((value,key,map)=>{
|
||||
let keySplit = key.split(',');
|
||||
if(keySplit.length == 2){
|
||||
let offset = parseInt(keySplit[0])
|
||||
let magicStringLength = keySplit[1].length;
|
||||
let tempMax = offset + magicStringLength/2;
|
||||
if(tempMax > max){
|
||||
max = tempMax;
|
||||
}
|
||||
}
|
||||
})
|
||||
this.READ_MIN_LENGTH =max;
|
||||
}
|
||||
|
||||
isImage(arraybuffer:ArrayBuffer){
|
||||
let value = this.getFileType(arraybuffer);
|
||||
if(
|
||||
value == SupportFormat.jpg ||
|
||||
value == SupportFormat.png ||
|
||||
value == SupportFormat.tiff ||
|
||||
value == SupportFormat.webp ||
|
||||
value == SupportFormat.bmp ||
|
||||
value == SupportFormat.gif ||
|
||||
value == SupportFormat.svg
|
||||
){
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export enum PhotoFormat {
|
||||
jpg = 'jpg,0,FFD8',
|
||||
png = 'png,0,89504E470D0A1A0A',
|
||||
bmp = 'bmp,0,424D',
|
||||
gif = 'gif,0,474946383961',
|
||||
svg = 'svg,0,3C3F786D6C',
|
||||
webp = 'webp,0,52494646',
|
||||
tiff = 'tiff,0,492049|49492A00|4D4D002A|4D4D002B'
|
||||
}
|
||||
|
||||
export enum SupportFormat {
|
||||
jpg = 'jpg',
|
||||
png = 'png',
|
||||
webp = 'webp',
|
||||
bmp = 'bmp',
|
||||
gif = 'gif',
|
||||
svg = 'svg',
|
||||
tiff = 'tiff'
|
||||
}
|
||||
|
|
|
@ -74,18 +74,18 @@ export class MaskUtils {
|
|||
let rgbDataMask = CalculatePixelUtils.createInt2DArray(heightMask, widthMask);
|
||||
let pixEntry: Array<PixelEntry> = new Array();
|
||||
|
||||
let bufferData_m = new ArrayBuffer(maskBitmap.getPixelBytesNumber());
|
||||
await maskBitmap.readPixelsToBuffer(bufferData_m);
|
||||
let dataArray_m = new Uint8Array(bufferData_m);
|
||||
let bufferDataM = new ArrayBuffer(maskBitmap.getPixelBytesNumber());
|
||||
await maskBitmap.readPixelsToBuffer(bufferDataM);
|
||||
let dataArrayM = new Uint8Array(bufferDataM);
|
||||
|
||||
let ph_m = 0;
|
||||
let pw_m = 0;
|
||||
let phM = 0;
|
||||
let pwM = 0;
|
||||
|
||||
for (let index = 0; index < dataArray_m.length; index += 4) {
|
||||
const r = dataArray_m[index];
|
||||
const g = dataArray_m[index+1];
|
||||
const b = dataArray_m[index+2];
|
||||
const f = dataArray_m[index+3];
|
||||
for (let index = 0; index < dataArrayM.length; index += 4) {
|
||||
const r = dataArrayM[index];
|
||||
const g = dataArrayM[index+1];
|
||||
const b = dataArrayM[index+2];
|
||||
const f = dataArrayM[index+3];
|
||||
|
||||
let entry = new PixelEntry();
|
||||
entry.a = 0;
|
||||
|
@ -96,16 +96,16 @@ export class MaskUtils {
|
|||
entry.pixel = ColorUtils.rgb(entry.r, entry.g, entry.b);
|
||||
pixEntry.push(entry);
|
||||
if (entry.r == 0 && entry.g == 0 && entry.b == 0) {
|
||||
rgbDataMask[ph_m][pw_m] = rgbData[ph_m][pw_m];
|
||||
rgbDataMask[phM][pwM] = rgbData[phM][pwM];
|
||||
} else {
|
||||
rgbDataMask[ph_m][pw_m] = ColorUtils.rgb(entry.r, entry.g, entry.b);
|
||||
rgbDataMask[phM][pwM] = ColorUtils.rgb(entry.r, entry.g, entry.b);
|
||||
}
|
||||
|
||||
if (pw_m == widthMask - 1) {
|
||||
pw_m = 0;
|
||||
ph_m++;
|
||||
if (pwM == widthMask - 1) {
|
||||
pwM = 0;
|
||||
phM++;
|
||||
} else {
|
||||
pw_m++;
|
||||
pwM++;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -117,7 +117,7 @@ export class MaskUtils {
|
|||
let nw = 0;
|
||||
|
||||
for (let i = 0; i < dataNewArray.length; i += 4) {
|
||||
let pixel_1 = rgbDataMask[mh][nw];
|
||||
let pixel1 = rgbDataMask[mh][nw];
|
||||
|
||||
if (nw == widthMask - 1) {
|
||||
nw = 0;
|
||||
|
@ -126,13 +126,13 @@ export class MaskUtils {
|
|||
nw++;
|
||||
}
|
||||
|
||||
let p_r = ColorUtils.red(pixel_1);
|
||||
let p_g = ColorUtils.green(pixel_1);
|
||||
let p_b = ColorUtils.blue(pixel_1);
|
||||
let pR = ColorUtils.red(pixel1);
|
||||
let pG = ColorUtils.green(pixel1);
|
||||
let pB = ColorUtils.blue(pixel1);
|
||||
|
||||
dataNewArray[i] = p_r;
|
||||
dataNewArray[i+1] = p_g;
|
||||
dataNewArray[i+2] = p_b;
|
||||
dataNewArray[i] = pR;
|
||||
dataNewArray[i+1] = pG;
|
||||
dataNewArray[i+2] = pB;
|
||||
dataNewArray[i+3] = pixEntry[index].f;
|
||||
index++;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Copyright (C) 2022 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
export class GIFFrame {
|
||||
|
||||
// 显示帧 width 宽 height 高 top上边距 left左边距
|
||||
dims: {
|
||||
width: number;
|
||||
height: number;
|
||||
top: number;
|
||||
left: number
|
||||
}
|
||||
|
||||
// 当前帧的像素数据指向的颜色数组 只为了生成patch,非必要
|
||||
colorTable?: [number, number, number][]
|
||||
|
||||
// 当前帧到下一帧的间隔时长
|
||||
delay: number
|
||||
|
||||
// 当前帧绘制要求 0保留 1在上一帧绘制此帧 2恢复画布背景 3.将画布恢复到绘制当前图像之前的先前状态
|
||||
disposalType: number
|
||||
|
||||
// Uint8CampedArray颜色转换后的补片信息用于绘制 必要
|
||||
patch?: Uint8ClampedArray
|
||||
|
||||
// drawPixelMap 如果像素转换为PixelMap后使用PixelMap展示, patch和drawPixelMap 2选1
|
||||
drawPixelMap?
|
||||
|
||||
// 当前帧每个像素的颜色表查找索引 只为了生成patch,非必要
|
||||
pixels?: number[]
|
||||
|
||||
// 表示透明度的可选颜色索引
|
||||
transparentIndex: number
|
||||
}
|
|
@ -0,0 +1,159 @@
|
|||
/*
|
||||
* Copyright (C) 2022 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { IParseGif } from './IParseGif'
|
||||
import { GIFFrame } from './GIFFrame'
|
||||
import { LoadType } from '../../../../../../../GifWorker'
|
||||
import { parseBufferToFrame } from './parse/GIFParse'
|
||||
import image from '@ohos.multimedia.image'
|
||||
|
||||
export class GIFParseImpl implements IParseGif {
|
||||
parseGifs(imageinfo: ArrayBuffer, callback: (data?, err?) => void, worker?,runMainThread?:boolean) {
|
||||
let resolveWorker = worker;
|
||||
console.log('parseGifs resolveWorker1 is null =' + (resolveWorker == null))
|
||||
if (!resolveWorker) {
|
||||
resolveWorker = globalThis.ImageKnife.getGifWorker();
|
||||
}
|
||||
console.log('parseGifs resolveWorker2 is null =' + (resolveWorker == null))
|
||||
|
||||
if (!!resolveWorker && !runMainThread) {
|
||||
console.log('parseGifs in worker thread!')
|
||||
this.useWorkerParse(resolveWorker, imageinfo, (data, err) => {
|
||||
if (err) {
|
||||
callback(undefined, err)
|
||||
} else {
|
||||
this.createPixelMapAll(data).then((pixelmaps) => {
|
||||
if (pixelmaps.length == data.length) {
|
||||
for (let i = 0;i < data.length; i++) {
|
||||
let frame = data[i];
|
||||
frame['drawPixelMap'] = pixelmaps[i];
|
||||
frame['patch'] = null;
|
||||
}
|
||||
callback(data, undefined)
|
||||
}
|
||||
}).catch(err => {
|
||||
callback(undefined, err)
|
||||
})
|
||||
}
|
||||
})
|
||||
} else {
|
||||
console.log('parseGifs in main thread!')
|
||||
let frames = parseBufferToFrame(imageinfo)
|
||||
console.log('frames length =' + frames.length)
|
||||
this.createPixelMapAll(frames).then((pixelmaps) => {
|
||||
if (pixelmaps.length == frames.length) {
|
||||
for (let i = 0;i < frames.length; i++) {
|
||||
let frame = frames[i];
|
||||
frame['drawPixelMap'] = pixelmaps[i];
|
||||
frame['patch'] = null;
|
||||
}
|
||||
console.log('parseGifs in main thread! callback is done!')
|
||||
callback(frames, undefined)
|
||||
}
|
||||
}).catch(err => {
|
||||
console.log('parseGifs in main thread! err =' + err)
|
||||
callback(undefined, err)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
private createPixelMapAll(frames): Promise<PixelMap[]> {
|
||||
let promises = []
|
||||
let filterCriteria = (item) => {
|
||||
if (!item['drawPixelMap']) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
frames.filter(filterCriteria, frames).flatMap((frame) => {
|
||||
promises.push(image.createPixelMap(frame.patch.buffer, {
|
||||
'size': {
|
||||
'height': frame.dims.height as number,
|
||||
'width': frame.dims.width as number
|
||||
}
|
||||
}))
|
||||
})
|
||||
return Promise.all(promises)
|
||||
}
|
||||
|
||||
private useWorkerParse(worker: any, buffer: ArrayBuffer, callback: (data?, err?) => void) {
|
||||
|
||||
worker.onerror = function (data) {
|
||||
callback(undefined, data)
|
||||
}
|
||||
|
||||
worker.onmessageerror = function (event) {
|
||||
callback(undefined, event)
|
||||
}
|
||||
|
||||
worker.onexit = function () {
|
||||
console.log('gifWork worker.onexit!')
|
||||
}
|
||||
|
||||
worker.onmessage = (e) => {
|
||||
var data = e.data;
|
||||
switch (data.type) {
|
||||
case LoadType.loadBufferByWorker:
|
||||
let pages = data.data;
|
||||
if (this.gifDecodeCorrect(pages)) {
|
||||
let images = this.recDecodedData(pages);
|
||||
callback(images, undefined)
|
||||
} else {
|
||||
callback(undefined, 'GIF Worker Decoder Data Is Error!')
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
var obj = { type: LoadType.loadBufferByWorker, data: buffer }
|
||||
worker.postMessage(obj, [buffer])
|
||||
|
||||
}
|
||||
|
||||
private gifDecodeCorrect(frames) {
|
||||
if (
|
||||
(frames.patch.length == frames.dims.length) &&
|
||||
(frames.patch.length == frames.delay.length) &&
|
||||
(frames.patch.length == frames.disposalType.length) &&
|
||||
(frames.patch.length == frames.patch.length) &&
|
||||
(frames.patch.length == frames.transparentIndex.length)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// 子线程数据回传处理
|
||||
private recDecodedData(pages): GIFFrame[] {
|
||||
let images = []
|
||||
for (let i = 0; i < pages.patch.length; i++) {
|
||||
let frame = {}
|
||||
frame['dims'] = pages.dims[i]
|
||||
pages.dims[i] = null
|
||||
frame['delay'] = pages.delay[i]
|
||||
pages.delay[i] = null
|
||||
frame['disposalType'] = pages.disposalType[i]
|
||||
pages.disposalType[i] = null
|
||||
let uint8ClampedArray = new Uint8ClampedArray(pages.patch[i])
|
||||
frame['patch'] = uint8ClampedArray
|
||||
pages.patch[i] = null
|
||||
frame['transparentIndex'] = pages.transparentIndex[i]
|
||||
pages.transparentIndex[i] = null
|
||||
images.push(frame)
|
||||
}
|
||||
pages = null
|
||||
return images;
|
||||
}
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2021 Huawei Device Co., Ltd.
|
||||
* Copyright (C) 2022 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
|
@ -12,7 +12,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export class PixelMapPack {
|
||||
pixelMap:PixelMap
|
||||
export interface IParseGif{
|
||||
// gif解析
|
||||
parseGifs(imageinfo:ArrayBuffer,callback:(data?,err?)=>void,worker?)
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* Copyright (C) 2022 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { decompressFrames, parseGIF } from './index'
|
||||
import { fixLoseGCE} from '../utils/ParseHelperUtils'
|
||||
import { GIFFrame } from '../GIFFrame'
|
||||
|
||||
export function parseBufferToFrame(arraybuffer: ArrayBuffer): GIFFrame[] {
|
||||
let gif = parseGIF(arraybuffer)
|
||||
fixLoseGCE(gif)
|
||||
let origins = decompressFrames(gif, true)
|
||||
return origins as GIFFrame[];
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Copyright (C) 2022 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Deinterlace function from https://github.com/shachaf/jsgif
|
||||
*/
|
||||
export function deinterlace(pixels, width) {
|
||||
var newPixels = new Array(pixels.length);
|
||||
var rows = pixels.length / width;
|
||||
|
||||
var cpRow = function cpRow(toRow, fromRow) {
|
||||
var fromPixels = pixels.slice(fromRow * width, (fromRow + 1) * width);
|
||||
newPixels.splice.apply(newPixels, [toRow * width, width].concat(fromPixels));
|
||||
}; // See appendix E.
|
||||
|
||||
|
||||
var offsets = [0, 4, 2, 1];
|
||||
var steps = [8, 8, 4, 2];
|
||||
var fromRow = 0;
|
||||
|
||||
for (var pass = 0; pass < 4; pass++) {
|
||||
for (var toRow = offsets[pass]; toRow < rows; toRow += steps[pass]) {
|
||||
cpRow(toRow, fromRow);
|
||||
fromRow++;
|
||||
}
|
||||
}
|
||||
return newPixels;
|
||||
};
|
|
@ -0,0 +1,114 @@
|
|||
/*
|
||||
* Copyright (C) 2022 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
var _gif = _interopRequireDefault(require("js-binary-schema-parser/lib/schemas/gif"));
|
||||
|
||||
var _jsBinarySchemaParser = require("js-binary-schema-parser");
|
||||
|
||||
var _uint = require("js-binary-schema-parser/lib/parsers/uint8");
|
||||
|
||||
import {deinterlace} from './deinterlace'
|
||||
import {lzw} from './lzw'
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
|
||||
|
||||
export function parseGIF(arrayBuffer) {
|
||||
var byteData = new Uint8Array(arrayBuffer);
|
||||
return (0, _jsBinarySchemaParser.parse)((0, _uint.buildStream)(byteData), _gif["default"]);
|
||||
};
|
||||
|
||||
|
||||
|
||||
export function generatePatch(image) {
|
||||
var totalPixels = image.pixels.length;
|
||||
var patchData = new Uint8ClampedArray(totalPixels * 4);
|
||||
|
||||
for (var i = 0; i < totalPixels; i++) {
|
||||
var pos = i * 4;
|
||||
var colorIndex = image.pixels[i];
|
||||
var color = image.colorTable[colorIndex] || [0, 0, 0];
|
||||
patchData[pos] = color[2];
|
||||
patchData[pos + 1] = color[1];
|
||||
patchData[pos + 2] = color[0];
|
||||
patchData[pos + 3] = colorIndex !== image.transparentIndex ? 255 : 0;
|
||||
}
|
||||
|
||||
return patchData;
|
||||
};
|
||||
|
||||
export function decompressFrame(frame, gct, buildImagePatch) {
|
||||
if (!frame.image) {
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
var image = frame.image; // get the number of pixels
|
||||
|
||||
var totalPixels = image.descriptor.width * image.descriptor.height; // do lzw decompression
|
||||
|
||||
var pixels = lzw(image.data.minCodeSize, image.data.blocks, totalPixels); // deal with interlacing if necessary
|
||||
|
||||
if (image.descriptor.lct.interlaced) {
|
||||
pixels = deinterlace(pixels, image.descriptor.width);
|
||||
}
|
||||
|
||||
var resultImage = {
|
||||
pixels: pixels,
|
||||
dims: {
|
||||
top: frame.image.descriptor.top,
|
||||
left: frame.image.descriptor.left,
|
||||
width: frame.image.descriptor.width,
|
||||
height: frame.image.descriptor.height
|
||||
}
|
||||
}; // color table
|
||||
|
||||
if (image.descriptor.lct && image.descriptor.lct.exists) {
|
||||
resultImage['colorTable'] = image.lct;
|
||||
} else {
|
||||
resultImage['colorTable'] = gct;
|
||||
} // add per frame relevant gce information
|
||||
|
||||
|
||||
if (frame.gce) {
|
||||
resultImage['delay'] = (frame.gce.delay || 10) * 10; // convert to ms
|
||||
|
||||
resultImage['disposalType'] = frame.gce.extras.disposal; // transparency
|
||||
|
||||
if (frame.gce.extras.transparentColorGiven) {
|
||||
resultImage['transparentIndex'] = frame.gce.transparentColorIndex;
|
||||
}
|
||||
} // create canvas usable imagedata if desired
|
||||
|
||||
|
||||
if (buildImagePatch) {
|
||||
resultImage['patch'] = generatePatch(resultImage);
|
||||
resultImage['colorTable'] = null
|
||||
resultImage['transparentIndex'] = null
|
||||
resultImage['pixels'] = null
|
||||
}
|
||||
|
||||
return resultImage;
|
||||
};
|
||||
|
||||
|
||||
|
||||
export function decompressFrames(parsedGif, buildImagePatches) {
|
||||
return parsedGif.frames.filter(function (f) {
|
||||
return f.image;
|
||||
}).map(function (f) {
|
||||
return decompressFrame(f, parsedGif.gct, buildImagePatches);
|
||||
});
|
||||
};
|
||||
|
|
@ -0,0 +1,139 @@
|
|||
/*
|
||||
* Copyright (C) 2022 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* javascript port of java LZW decompression
|
||||
* Original java author url: https://gist.github.com/devunwired/4479231
|
||||
*/
|
||||
export function lzw(minCodeSize, data, pixelCount) {
|
||||
var MAX_STACK_SIZE = 4096;
|
||||
var nullCode = -1;
|
||||
var npix = pixelCount;
|
||||
var available;
|
||||
var clear;
|
||||
var codeMask;
|
||||
var codeSize;
|
||||
var endOfInformation;
|
||||
var inCode;
|
||||
var oldCode;
|
||||
var bits;
|
||||
var code;
|
||||
var i;
|
||||
var datum;
|
||||
var dataSize;
|
||||
var first;
|
||||
var top;
|
||||
var bi;
|
||||
var pi;
|
||||
var dstPixels = new Array(pixelCount);
|
||||
var prefix = new Array(MAX_STACK_SIZE);
|
||||
var suffix = new Array(MAX_STACK_SIZE);
|
||||
var pixelStack = new Array(MAX_STACK_SIZE + 1); // Initialize GIF data stream decoder.
|
||||
|
||||
dataSize = minCodeSize;
|
||||
clear = 1 << dataSize;
|
||||
endOfInformation = clear + 1;
|
||||
available = clear + 2;
|
||||
oldCode = nullCode;
|
||||
codeSize = dataSize + 1;
|
||||
codeMask = (1 << codeSize) - 1;
|
||||
|
||||
for (code = 0; code < clear; code++) {
|
||||
prefix[code] = 0;
|
||||
suffix[code] = code;
|
||||
} // Decode GIF pixel stream.
|
||||
|
||||
|
||||
var datum, bits, count, first, top, pi, bi;
|
||||
datum = bits = count = first = top = pi = bi = 0;
|
||||
|
||||
for (i = 0; i < npix;) {
|
||||
if (top === 0) {
|
||||
if (bits < codeSize) {
|
||||
// get the next byte
|
||||
datum += data[bi] << bits;
|
||||
bits += 8;
|
||||
bi++;
|
||||
continue;
|
||||
} // Get the next code.
|
||||
|
||||
|
||||
code = datum & codeMask;
|
||||
datum >>= codeSize;
|
||||
bits -= codeSize; // Interpret the code
|
||||
|
||||
if (code > available || code == endOfInformation) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (code == clear) {
|
||||
// Reset decoder.
|
||||
codeSize = dataSize + 1;
|
||||
codeMask = (1 << codeSize) - 1;
|
||||
available = clear + 2;
|
||||
oldCode = nullCode;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (oldCode == nullCode) {
|
||||
pixelStack[top++] = suffix[code];
|
||||
oldCode = code;
|
||||
first = code;
|
||||
continue;
|
||||
}
|
||||
|
||||
inCode = code;
|
||||
|
||||
if (code == available) {
|
||||
pixelStack[top++] = first;
|
||||
code = oldCode;
|
||||
}
|
||||
|
||||
while (code > clear) {
|
||||
pixelStack[top++] = suffix[code];
|
||||
code = prefix[code];
|
||||
}
|
||||
|
||||
first = suffix[code] & 0xff;
|
||||
pixelStack[top++] = first; // add a new string to the table, but only if space is available
|
||||
// if not, just continue with current table until a clear code is found
|
||||
// (deferred clear code implementation as per GIF spec)
|
||||
|
||||
if (available < MAX_STACK_SIZE) {
|
||||
prefix[available] = oldCode;
|
||||
suffix[available] = first;
|
||||
available++;
|
||||
|
||||
if ((available & codeMask) === 0 && available < MAX_STACK_SIZE) {
|
||||
codeSize++;
|
||||
codeMask += available;
|
||||
}
|
||||
}
|
||||
|
||||
oldCode = inCode;
|
||||
} // Pop a pixel off the pixel stack.
|
||||
|
||||
|
||||
top--;
|
||||
dstPixels[pi++] = pixelStack[top];
|
||||
i++;
|
||||
}
|
||||
|
||||
for (i = pi; i < npix; i++) {
|
||||
dstPixels[i] = 0; // clear missing pixels
|
||||
}
|
||||
|
||||
return dstPixels;
|
||||
};
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* Copyright (C) 2022 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
export function fixLoseGCE(gif) {
|
||||
let currentGce = null;
|
||||
for (const frame of gif.frames) {
|
||||
currentGce = frame.gce ? frame.gce : currentGce;
|
||||
// fix loosing graphic control extension for same frames
|
||||
if ("image" in frame && !("gce" in frame)) {
|
||||
frame.gce = currentGce;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* Copyright (C) 2022 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
export interface IParseSvg {
|
||||
// 解析svg
|
||||
parseSvg(imageinfo: ArrayBuffer,size?:{width:number,height:number}): Promise<PixelMap>
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* Copyright (C) 2022 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import {IParseSvg} from'./IParseSvg'
|
||||
import {SVGImageView} from '@ohos/svg'
|
||||
export class SVGParseImpl implements IParseSvg{
|
||||
parseSvg(imageinfo: ArrayBuffer,size?:{width:number,height:number}): Promise<PixelMap>{
|
||||
let model = new SVGImageView.SVGImageViewModel();
|
||||
return model.getSVGPixelMap(new Uint8Array(imageinfo),size);
|
||||
}
|
||||
}
|
33
package.json
|
@ -1,19 +1,20 @@
|
|||
{
|
||||
"license":"ISC",
|
||||
"devDependencies":{},
|
||||
"name":"imageknife",
|
||||
"ohos":{
|
||||
"org":"huawei",
|
||||
"directoryLevel":"project",
|
||||
"buildTool":"hvigor"
|
||||
"license": "ISC",
|
||||
"devDependencies": {},
|
||||
"name": "imageknife",
|
||||
"ohos": {
|
||||
"org": "huawei",
|
||||
"directoryLevel": "project",
|
||||
"buildTool": "hvigor"
|
||||
},
|
||||
"description":"example description",
|
||||
"repository":{},
|
||||
"version":"1.0.0",
|
||||
"dependencies":{
|
||||
"@ohos/hypium":"1.0.1",
|
||||
"@ohos/hvigor-ohos-plugin":"1.1.6",
|
||||
"hypium":"^1.0.0",
|
||||
"@ohos/hvigor":"1.1.6"
|
||||
"description": "example description",
|
||||
"repository": {},
|
||||
"version": "1.0.0",
|
||||
"dependencies": {
|
||||
"@ohos/hvigor": "1.2.2",
|
||||
"@ohos/hvigor-ohos-plugin": "1.2.2",
|
||||
"@ohos/hypium": "1.0.2",
|
||||
"@ohos/svg": "^1.1.0",
|
||||
"hypium": "^1.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Before Width: | Height: | Size: 3.9 MiB |
Before Width: | Height: | Size: 3.7 MiB |
Before Width: | Height: | Size: 30 MiB |
After Width: | Height: | Size: 5.1 MiB |
After Width: | Height: | Size: 3.2 MiB |
After Width: | Height: | Size: 1.1 MiB |
After Width: | Height: | Size: 5.2 MiB |
After Width: | Height: | Size: 78 KiB |
After Width: | Height: | Size: 44 KiB |
After Width: | Height: | Size: 38 KiB |
After Width: | Height: | Size: 44 KiB |