1.属性改为小写imageKnifeOption
2.支持使用一个或多个图片变换,如模糊,高亮等 Signed-off-by: madixin <madixin@huawei.com>
This commit is contained in:
parent
be0f5ff8ef
commit
00f5e81571
|
@ -1,3 +1,7 @@
|
|||
|
||||
## 3.0.0-rc.2
|
||||
- 新增支持使用一个或多个图片变换,如模糊,高亮等
|
||||
|
||||
## 3.0.0-rc.1
|
||||
- 新增从内存或文件缓存获取图片数据接口getCacheImage
|
||||
- 新增图片预加载preLoadCache并返回文件缓存路径
|
||||
|
|
75
README.md
75
README.md
|
@ -6,10 +6,9 @@
|
|||
|
||||
本项目参考开源库 [Glide](https://github.com/bumptech/glide) 进行OpenHarmony的自研版本:
|
||||
|
||||
- 支持内存缓存,使用LRUCache算法,对图片数据进行内存缓存。
|
||||
- 支持通过initMemoryCache自定义策略内存缓存策略和大小。
|
||||
- 支持自定义内存缓存策略,支持设置内存缓存的大小。
|
||||
- 支持磁盘二级缓存,对于下载图片会保存一份至磁盘当中。
|
||||
- 支持option自定义实现图片获取/网络下载
|
||||
- 支持自定义实现图片获取/网络下载
|
||||
- 支持监听网络下载回调进度
|
||||
- 继承Image的能力,支持option传入border,设置边框,圆角
|
||||
- 继承Image的能力,支持option传入objectFit设置图片缩放,包括objectFit为auto时根据图片自适应高度
|
||||
|
@ -17,28 +16,27 @@
|
|||
- 并发请求数量,支持请求排队队列的优先级
|
||||
- 支持生命周期已销毁的图片,不再发起请求
|
||||
- 自定义缓存key
|
||||
- 自定义请求头规格
|
||||
- 自定义http网络请求头
|
||||
- 支持writeCacheStrategy控制缓存的存入策略(只存入内存或文件缓存)
|
||||
- 支持preLoadCache预加载图片
|
||||
- 支持onlyRetrieveFromCache仅用缓存加载
|
||||
- 支持使用一个或多个图片变换,如模糊,高亮等
|
||||
|
||||
待实现特性
|
||||
- gif/webp动图显示与控制
|
||||
- 内存降采样优化,节约内存的占用
|
||||
- 支持自定义图片解码
|
||||
- 支持进行图片变换: 支持图像像素源图片变换效果。
|
||||
|
||||
注意:3.x版本相对2.x版本做了重大的重构,主要体现在:
|
||||
- 使用Image组件代替Canvas组件渲染
|
||||
- 重构Dispatch分发逻辑,支持控制并发请求数,支持请求排队队列的优先级
|
||||
- 支持通过initMemoryCache自定义策略内存缓存策略和大小。
|
||||
- 支持option自定义实现图片获取/网络下载
|
||||
- 支持通过initMemoryCache自定义策略内存缓存策略和大小
|
||||
- 支持option自定义实现图片获取/网络下载
|
||||
|
||||
因此API及能力上,目前有部分差异,主要体现在:
|
||||
- 不支持drawLifeCycle接口,通过canvas自会图片
|
||||
- mainScaleType,border等参数,新版本与系统Image保持一致
|
||||
- gif/webp动图播放与控制
|
||||
- 支持进行图片变换: 支持图像像素源图片变换效果。
|
||||
- 抗锯齿相关参数
|
||||
|
||||
## 下载安装
|
||||
|
@ -122,34 +120,49 @@ ImageKnifeComponent({ ImageKnifeOption:
|
|||
}
|
||||
}).width(100).height(100)
|
||||
```
|
||||
#### 7.支持option图片变换
|
||||
```
|
||||
ImageKnifeComponent({ ImageKnifeOption:
|
||||
{
|
||||
loadSrc: $r("app.media.rabbit"),
|
||||
border: {radius:50},
|
||||
transformation: new BlurTransformation(3)
|
||||
}
|
||||
}).width(100).height(100)
|
||||
```
|
||||
|
||||
|
||||
## 接口说明
|
||||
### ImageKnifeOption参数列表
|
||||
|
||||
| 参数名称 | 入参内容 | 功能简介 |
|
||||
|-----------------------|-------------------------------|---------------|
|
||||
| loadSrc | string、PixelMap、Resource | 主图展示 |
|
||||
| placeholderSrc | PixelMap、Resource | 占位图图展示(可选) |
|
||||
| errorholderSrc | PixelMap、Resource | 错误图展示(可选) |
|
||||
| objectFit | ImageFit | 图片展示样式(可选) |
|
||||
| writeCacheStrategy | WriteCacheStrategyType | 写入缓存策略(可选) |
|
||||
| onlyRetrieveFromCache | boolean | 跳过网络和本地请求(可选) |
|
||||
| customGetImage | (context: Context, src: string | 自定义网络(可选) | | Resource | 错误占位图数据源 |
|
||||
| border | BorderOptions | 边框圆角(可选) |
|
||||
| priority | taskpool.Priority | 加载优先级(可选) |
|
||||
| context | common.UIAbilityContext | 上下文(可选) |
|
||||
| progressListener | (progress: number)=>void | 进度(可选) |
|
||||
| signature | ObjectKey | 自定义缓存关键字 |
|
||||
| headerOption | Array<HeaderOptions> | 设置请求头 |
|
||||
| 参数名称 | 入参内容 | 功能简介 |
|
||||
|-----------------------|-------------------------------|-----------------|
|
||||
| loadSrc | string、PixelMap、Resource | 主图展示 |
|
||||
| placeholderSrc | PixelMap、Resource | 占位图图展示(可选) |
|
||||
| errorholderSrc | PixelMap、Resource | 错误图展示(可选) |
|
||||
| objectFit | ImageFit | 图片展示样式(可选) |
|
||||
| writeCacheStrategy | WriteCacheStrategyType | 写入缓存策略(可选) |
|
||||
| onlyRetrieveFromCache | boolean | 是否跳过网络和本地请求(可选) |
|
||||
| customGetImage | (context: Context, src: string | 自定义下载图片(可选) | | Resource | 错误占位图数据源 |
|
||||
| border | BorderOptions | 边框圆角(可选) |
|
||||
| priority | taskpool.Priority | 加载优先级(可选) |
|
||||
| context | common.UIAbilityContext | 上下文(可选) |
|
||||
| progressListener | (progress: number)=>void | 进度(可选) |
|
||||
| signature | ObjectKey | 自定义缓存关键字(可选) |
|
||||
| headerOption | Array<HeaderOptions> | 设置请求头(可选) |
|
||||
| transformation | PixelMapTransformation | 图片变换(可选) |
|
||||
|
||||
### ImageKnife接口
|
||||
| 参数名称 | 入参内容 | 功能简介 |
|
||||
|--------------|---------------------------|---------------|
|
||||
| preLoadCache | url:string | 预加载并返回文件缓存路径 |
|
||||
| getCacheImage | url: string, cacheType: CacheType | 从内存或文件缓存中获取资源 |
|
||||
| addHeader | key: string, value: Object | 全局添加请求头属性 |
|
||||
| serHeaderOptions | Array<HeaderOptions> | 全局设置请求头 |
|
||||
| deleteHeader | key: string | 全局删除请求头 |
|
||||
| setEngineKeyImpl | CustomEngineKeyImpl | 全局配置缓存key |
|
||||
| 参数名称 | 入参内容 | 功能简介 |
|
||||
|------------------|---------------------------|---------------|
|
||||
| initMemoryCache | newMemoryCache: IMemoryCache | 自定义内存缓存策略 |
|
||||
| initFileCache | context: Context, size: number, memory: number | 初始化文件缓存数量和大小 |
|
||||
| preLoadCache | url:string | 预加载并返回文件缓存路径 |
|
||||
| getCacheImage | url: string, cacheType: CacheType | 从内存或文件缓存中获取资源 |
|
||||
| addHeader | key: string, value: Object | 全局添加http请求头 |
|
||||
| setHeaderOptions | Array<HeaderOptions> | 全局设置http请求头 |
|
||||
| deleteHeader | key: string | 全局删除http请求头 |
|
||||
| setEngineKeyImpl | CustomEngineKeyImpl | 全局配置缓存key |
|
||||
|
||||
## 约束与限制
|
||||
在下述版本验证通过:
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2023 Huawei Device Co., Ltd.
|
||||
* Copyright (C) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
|
@ -13,34 +13,48 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
import util from '@ohos.util';
|
||||
import { IEngineKey, ObjectKey } from '@ohos/imageknife';
|
||||
import { IEngineKey, ImageKnifeOption, ObjectKey , PixelMapTransformation } from '@ohos/imageknife';
|
||||
import { SparkMD5 } from '@ohos/imageknife/src/main/ets/3rd_party/sparkmd5/spark-md5';
|
||||
|
||||
//全局自定义key demo
|
||||
export class CustomEngineKeyImpl implements IEngineKey {
|
||||
private keyCache: util.LRUCache<string,string> = new util.LRUCache(1024)
|
||||
private memoryKeyCache: util.LRUCache<string, string> = new util.LRUCache(1024)
|
||||
private fileKeyCache: util.LRUCache<string, string> = new util.LRUCache(1024)
|
||||
|
||||
// 生成内存缓存
|
||||
generateCacheKey(loadSrc: string | PixelMap | Resource, signature?: ObjectKey | undefined): string {
|
||||
let key = "loadSrc=" + this.generateKey(loadSrc) + ";";
|
||||
if (signature) {
|
||||
key += "signature=" + signature.getKey() + ";"
|
||||
// 生成内存缓存key
|
||||
generateMemoryKey(loadSrc: string | PixelMap | Resource, imageKnifeOption: ImageKnifeOption): string {
|
||||
let src = "loadSrc=" + (typeof loadSrc == "string" ? loadSrc : JSON.stringify(loadSrc)) + ";"
|
||||
if (imageKnifeOption.signature) {
|
||||
src += "signature=" + imageKnifeOption.signature.getKey() + ";"
|
||||
}
|
||||
return key;
|
||||
if (imageKnifeOption.transformation) {
|
||||
src += "transformation=" + this.getTransformation(imageKnifeOption.transformation) + ";"
|
||||
}
|
||||
return this.generateKey(src, this.memoryKeyCache)
|
||||
}
|
||||
|
||||
// 生成文件缓存key
|
||||
generateFileKey(loadSrc: string | PixelMap | Resource, signature?: ObjectKey | undefined): string {
|
||||
let src = "loadSrc=" + (typeof loadSrc == "string" ? loadSrc : JSON.stringify(loadSrc)) + ";"
|
||||
if (signature) {
|
||||
src += "signature=" + signature.getKey() + ";"
|
||||
}
|
||||
return this.generateKey(src, this.fileKeyCache)
|
||||
}
|
||||
|
||||
// key缓存策略,避免无意义的 JSON.stringify
|
||||
private generateKey(key: string | PixelMap | Resource): string {
|
||||
let keyCache = typeof key == "string" ? key : JSON.stringify(key)
|
||||
let result = this.keyCache.get(keyCache)
|
||||
private generateKey(keyCache: string, cache: util.LRUCache<string, string>): string {
|
||||
let result = cache.get(keyCache)
|
||||
if (result != undefined) {
|
||||
return result
|
||||
} else {
|
||||
result = SparkMD5.hashBinary(keyCache)
|
||||
this.keyCache.put(keyCache, result)
|
||||
cache.put(keyCache, result)
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private getTransformation(transformation: PixelMapTransformation): string {
|
||||
return transformation.getName()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,89 @@
|
|||
import { BlurTransformation, BrightnessTransformation, ImageKnifeComponent, ImageKnifeOption,
|
||||
MultiTransTransformation,
|
||||
PixelMapTransformation } from '@ohos/imageknife'
|
||||
import { collections } from '@kit.ArkTS'
|
||||
|
||||
@Entry
|
||||
@Component
|
||||
struct ImageTransformation {
|
||||
@State imageKnifeOption: ImageKnifeOption = {
|
||||
loadSrc: "http://g.hiphotos.baidu.com/image/pic/item/6d81800a19d8bc3e770bd00d868ba61ea9d345f2.jpg",
|
||||
placeholderSrc: $r("app.media.loading"),
|
||||
errorholderSrc: $r("app.media.app_icon"),
|
||||
objectFit: ImageFit.Contain
|
||||
}
|
||||
isBlur: boolean = false
|
||||
isBrightness: boolean = false
|
||||
|
||||
build() {
|
||||
Column() {
|
||||
Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
|
||||
Checkbox({ name: 'checkbox1', group: 'checkboxGroup' })
|
||||
.selectedColor(0x39a2db)
|
||||
.shape(CheckBoxShape.ROUNDED_SQUARE)
|
||||
.onChange((value: boolean) => {
|
||||
this.isBlur = value
|
||||
this.upedateImageKnifeOption()
|
||||
})
|
||||
.mark({
|
||||
strokeColor: Color.Black,
|
||||
size: 50,
|
||||
strokeWidth: 5
|
||||
})
|
||||
.unselectedColor(Color.Red)
|
||||
.width(30)
|
||||
.height(30)
|
||||
Text('模糊效果').fontSize(20)
|
||||
}
|
||||
|
||||
Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
|
||||
Checkbox({ name: 'checkbox2', group: 'checkboxGroup' })
|
||||
.selectedColor(0x39a2db)
|
||||
.shape(CheckBoxShape.ROUNDED_SQUARE)
|
||||
.onChange((value: boolean) => {
|
||||
this.isBrightness = value
|
||||
this.upedateImageKnifeOption()
|
||||
})
|
||||
.width(30)
|
||||
.height(30)
|
||||
Text('高亮效果').fontSize(20)
|
||||
}
|
||||
|
||||
Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
|
||||
Checkbox({ name: 'checkbox3', group: 'checkboxGroup' })
|
||||
.selectedColor(0x39a2db)
|
||||
.shape(CheckBoxShape.ROUNDED_SQUARE)
|
||||
.onChange((value: boolean) => {
|
||||
console.info('Checkbox3 change is' + value)
|
||||
})
|
||||
.width(30)
|
||||
.height(30)
|
||||
Text('Checkbox3').fontSize(20)
|
||||
}
|
||||
|
||||
ImageKnifeComponent({
|
||||
imageKnifeOption: this.imageKnifeOption
|
||||
}).width(300).height(300)
|
||||
}
|
||||
.height('100%')
|
||||
.width('100%')
|
||||
}
|
||||
|
||||
upedateImageKnifeOption() {
|
||||
let transformations: collections.Array<PixelMapTransformation> = new collections.Array<PixelMapTransformation>()
|
||||
if (this.isBlur){
|
||||
transformations.push(new BlurTransformation(5))
|
||||
}
|
||||
if (this.isBrightness){
|
||||
transformations.push(new BrightnessTransformation(0.2))
|
||||
}
|
||||
|
||||
this.imageKnifeOption = {
|
||||
loadSrc: "http://g.hiphotos.baidu.com/image/pic/item/6d81800a19d8bc3e770bd00d868ba61ea9d345f2.jpg",
|
||||
placeholderSrc: $r("app.media.loading"),
|
||||
errorholderSrc: $r("app.media.app_icon"),
|
||||
objectFit: ImageFit.Contain,
|
||||
transformation: transformations.length > 0 ? new MultiTransTransformation(transformations) : undefined
|
||||
}
|
||||
}
|
||||
}
|
|
@ -87,6 +87,13 @@ struct Index {
|
|||
});
|
||||
})
|
||||
|
||||
Button("图片变换").margin({top:10}).onClick(()=>{
|
||||
router.push({
|
||||
uri: 'pages/ImageTransformation',
|
||||
|
||||
});
|
||||
})
|
||||
|
||||
}
|
||||
.width('100%')
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ struct ListPage {
|
|||
Row() {
|
||||
List({ space: 10 }) {
|
||||
ForEach(this.datas, (item: string) => {
|
||||
ImageKnifeComponent({ ImageKnifeOption: this.ImageKnifeOption }).height(200).width(200)
|
||||
ImageKnifeComponent({ imageKnifeOption: this.ImageKnifeOption }).height(200).width(200)
|
||||
}, (item: string) => item)
|
||||
}
|
||||
.width('100%')
|
||||
|
|
|
@ -25,7 +25,7 @@ struct LongImagePage {
|
|||
|
||||
// Image($r("app.media.aaa")).objectFit(ImageFit.Auto).width(200)
|
||||
ImageKnifeComponent({
|
||||
ImageKnifeOption: {
|
||||
imageKnifeOption: {
|
||||
loadSrc:"https://wx2.sinaimg.cn/mw690/006HyQKGgy1hnqp08dw09j30u04twu0x.jpg",
|
||||
//src:$r("app.media.aaa"),
|
||||
// placeholderSrc: $r("app.media.loading"),
|
||||
|
|
|
@ -36,7 +36,7 @@ struct ManyPhotoShowPage {
|
|||
// loadSrc: item.thumbnail,
|
||||
// mainScaleType: ScaleType.FIT_XY,
|
||||
// } })
|
||||
ImageKnifeComponent({ImageKnifeOption:{
|
||||
ImageKnifeComponent({imageKnifeOption:{
|
||||
loadSrc: item.thumbnail,
|
||||
//src:"https://www.openharmony.cn/_nuxt/img/logo.dcf95b3.png",
|
||||
// src: this.localFile,
|
||||
|
|
|
@ -43,7 +43,7 @@ struct SignatureTestPage {
|
|||
signature: new ObjectKey("1")
|
||||
}
|
||||
}).margin({ top: 5, left: 3 })
|
||||
ImageKnifeComponent({ ImageKnifeOption: this.imageKnifeOption1 }).width(300).height(300)
|
||||
ImageKnifeComponent({ imageKnifeOption: this.imageKnifeOption1 }).width(300).height(300)
|
||||
}.width('100%').backgroundColor(Color.Pink)
|
||||
|
||||
Text("key每次变化:时间戳").fontSize(15)
|
||||
|
@ -56,7 +56,7 @@ struct SignatureTestPage {
|
|||
signature: new ObjectKey(new Date().getTime().toString())
|
||||
}
|
||||
}).margin({ top: 5, left: 3 })
|
||||
ImageKnifeComponent({ ImageKnifeOption: this.imageKnifeOption2 }).width(300).height(300)
|
||||
ImageKnifeComponent({ imageKnifeOption: this.imageKnifeOption2 }).width(300).height(300)
|
||||
}.width('100%').backgroundColor(Color.Pink)
|
||||
}
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { ImageKnifeComponent } from '@ohos/imageknife';
|
||||
import { ImageKnifeComponent,BlurTransformation } from '@ohos/imageknife';
|
||||
import fs from '@ohos.file.fs';
|
||||
|
||||
@Entry
|
||||
|
@ -37,7 +37,7 @@ struct SingleImage {
|
|||
.fontSize(30)
|
||||
.fontWeight(FontWeight.Bold)
|
||||
ImageKnifeComponent({
|
||||
ImageKnifeOption: {
|
||||
imageKnifeOption: {
|
||||
loadSrc: $r("app.media.app_icon"),
|
||||
placeholderSrc: $r("app.media.loading"),
|
||||
errorholderSrc: $r("app.media.app_icon"),
|
||||
|
@ -48,7 +48,7 @@ struct SingleImage {
|
|||
.fontSize(30)
|
||||
.fontWeight(FontWeight.Bold)
|
||||
ImageKnifeComponent({
|
||||
ImageKnifeOption: {
|
||||
imageKnifeOption: {
|
||||
loadSrc: this.localFile,
|
||||
placeholderSrc: $r("app.media.loading"),
|
||||
errorholderSrc: $r("app.media.app_icon"),
|
||||
|
@ -59,7 +59,7 @@ struct SingleImage {
|
|||
.fontSize(30)
|
||||
.fontWeight(FontWeight.Bold)
|
||||
ImageKnifeComponent({
|
||||
ImageKnifeOption: {
|
||||
imageKnifeOption: {
|
||||
loadSrc:"https://www.openharmony.cn/_nuxt/img/logo.dcf95b3.png",
|
||||
placeholderSrc: $r("app.media.loading"),
|
||||
errorholderSrc: $r("app.media.app_icon"),
|
||||
|
@ -71,12 +71,13 @@ struct SingleImage {
|
|||
.fontSize(30)
|
||||
.fontWeight(FontWeight.Bold)
|
||||
ImageKnifeComponent({
|
||||
ImageKnifeOption: {
|
||||
imageKnifeOption: {
|
||||
loadSrc: "https://file.atomgit.com/uploads/user/1704857786989_8994.jpeg",
|
||||
placeholderSrc: $r("app.media.loading"),
|
||||
errorholderSrc: $r("app.media.app_icon"),
|
||||
objectFit: ImageFit.Contain,
|
||||
customGetImage: custom
|
||||
customGetImage: custom,
|
||||
transformation: new BlurTransformation(10)
|
||||
}
|
||||
}).width(100).height(100)
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ struct TestPrefetchToFileCachePage {
|
|||
build() {
|
||||
Column() {
|
||||
ImageKnifeComponent({
|
||||
ImageKnifeOption: this.imageKnifeOption
|
||||
imageKnifeOption: this.imageKnifeOption
|
||||
}).width(300).height(300)
|
||||
}
|
||||
.height('100%') .width('100%')
|
||||
|
|
|
@ -59,19 +59,19 @@ export struct MsgItem {
|
|||
build(){
|
||||
if (this.count % 2 == 0 && this.count <6){
|
||||
ImageKnifeComponent({
|
||||
ImageKnifeOption:{
|
||||
imageKnifeOption:{
|
||||
loadSrc:$r("app.media.startIcon")
|
||||
}
|
||||
})
|
||||
}else if (this.count > 6 && this.count - 6 < this.data.length){
|
||||
ImageKnifeComponent({
|
||||
ImageKnifeOption:{
|
||||
imageKnifeOption:{
|
||||
loadSrc:this.data[this.count - 6],
|
||||
}
|
||||
})
|
||||
}else {
|
||||
ImageKnifeComponent({
|
||||
ImageKnifeOption:{
|
||||
imageKnifeOption:{
|
||||
loadSrc:$r("app.media.loading")
|
||||
}
|
||||
})
|
||||
|
|
|
@ -73,7 +73,7 @@ struct TestIsUrlExist {
|
|||
}.margin({ top: 10 })
|
||||
|
||||
ImageKnifeComponent({
|
||||
ImageKnifeOption: this.imageKnifeOption
|
||||
imageKnifeOption: this.imageKnifeOption
|
||||
}).width(200).height(200).margin({ top: 10 })
|
||||
Image(this.source).margin({ top: 10 })
|
||||
.width(200).height(200)
|
||||
|
|
|
@ -34,7 +34,7 @@ struct TestPrefetchToFileCachePage {
|
|||
this.imageKnifeOption.loadSrc = "https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658"
|
||||
})
|
||||
ImageKnifeComponent({
|
||||
ImageKnifeOption: this.imageKnifeOption
|
||||
imageKnifeOption: this.imageKnifeOption
|
||||
}).width(300).height(300).margin({top:30})
|
||||
}
|
||||
.height('100%') .width('100%')
|
||||
|
|
|
@ -31,7 +31,7 @@ struct TransformPage {
|
|||
|
||||
build() {
|
||||
Column() {
|
||||
ImageKnifeComponent({ ImageKnifeOption: this.ImageKnifeOption }).height(200).width(200)
|
||||
ImageKnifeComponent({ imageKnifeOption: this.ImageKnifeOption }).height(200).width(200)
|
||||
.transform(this.matrix1)
|
||||
// Image($r('app.media.rabbit')).objectFit(ImageFit.Contain).height(200).width(200).transform(this.matrix1)
|
||||
Button("放大").onClick(()=>{
|
||||
|
|
|
@ -63,7 +63,7 @@ export struct UserAvatar {
|
|||
Row() {
|
||||
// Image(this.imageKnifeOption.loadSrc)
|
||||
|
||||
ImageKnifeComponent({ ImageKnifeOption: this.ImageKnifeOption })
|
||||
ImageKnifeComponent({ imageKnifeOption: this.ImageKnifeOption })
|
||||
.borderRadius(this.radius)
|
||||
.clip(true)
|
||||
.width(this.calcImgSize)
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
"pages/SignatureTestPage",
|
||||
"pages/TestPrefetchToFileCache",
|
||||
"pages/TestIsUrlExist",
|
||||
"pages/TestHeader"
|
||||
"pages/TestHeader",
|
||||
"pages/ImageTransformation"
|
||||
]
|
||||
}
|
|
@ -16,6 +16,12 @@ export { ObjectKey } from './src/main/ets/model/ObjectKey'
|
|||
|
||||
export { ImageKnifeData , ReadCacheStrategyType} from "./src/main/ets/model/ImageKnifeData"
|
||||
|
||||
|
||||
export { PixelMapTransformation } from './src/main/ets/transform/PixelMapTransformation'
|
||||
|
||||
export { MultiTransTransformation } from './src/main/ets/transform/MultiTransTransformation'
|
||||
|
||||
export { BrightnessTransformation } from './src/main/ets/transform/BrightnessTransformation'
|
||||
|
||||
export { BlurTransformation } from './src/main/ets/transform/BlurTransformation'
|
||||
|
||||
|
||||
|
|
|
@ -129,7 +129,7 @@ export class ImageKnife {
|
|||
let imageKnifeOption = new ImageKnifeOption()
|
||||
imageKnifeOption.loadSrc = loadSrc
|
||||
let engineKeyImpl: IEngineKey = new DefaultEngineKey()
|
||||
let keys = engineKeyImpl.generateCacheKey(loadSrc)
|
||||
let keys = engineKeyImpl.generateMemoryKey(loadSrc, imageKnifeOption)
|
||||
let cachePath = ImageKnife.getInstance().getFileCache().getFileToPath(keys)
|
||||
if(cachePath == null || cachePath == "" || cachePath == undefined) {
|
||||
let request = new ImageKnifeRequest(
|
||||
|
@ -156,26 +156,33 @@ export class ImageKnife {
|
|||
* @param cacheType 缓存策略
|
||||
* @returns 图片数据
|
||||
*/
|
||||
getCacheImage(loadSrc: string, cacheType: ReadCacheStrategyType = ReadCacheStrategyType.Default):Promise<ImageKnifeData | undefined> {
|
||||
return new Promise((resolve,reject)=>{
|
||||
let engineKeyImpl: IEngineKey = new DefaultEngineKey()
|
||||
if(cacheType == ReadCacheStrategyType.Memory) {
|
||||
resolve(this.ReadMemoryCache(loadSrc,engineKeyImpl))
|
||||
getCacheImage(loadSrc: string,
|
||||
cacheType: ReadCacheStrategyType = ReadCacheStrategyType.Default): Promise<ImageKnifeData | undefined> {
|
||||
let option: ImageKnifeOption = {
|
||||
loadSrc: loadSrc
|
||||
}
|
||||
let engineKeyImpl: IEngineKey = new DefaultEngineKey()
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
if (cacheType == ReadCacheStrategyType.Memory) {
|
||||
resolve(this.readMemoryCache(loadSrc, option, engineKeyImpl))
|
||||
} else if (cacheType == ReadCacheStrategyType.File) {
|
||||
this.ReadFileCache(loadSrc,engineKeyImpl,resolve)
|
||||
this.readFileCache(loadSrc, engineKeyImpl, resolve)
|
||||
} else {
|
||||
let data = this.ReadMemoryCache(loadSrc,engineKeyImpl)
|
||||
data == undefined ? this.ReadFileCache(loadSrc,engineKeyImpl,resolve) : data
|
||||
let data = this.readMemoryCache(loadSrc, option, engineKeyImpl)
|
||||
data == undefined ? this.readFileCache(loadSrc, engineKeyImpl, resolve) : data
|
||||
}
|
||||
})
|
||||
}
|
||||
ReadMemoryCache(loadSrc:string,engineKey:IEngineKey): ImageKnifeData | undefined{
|
||||
let keys = engineKey.generateCacheKey(loadSrc)
|
||||
|
||||
private readMemoryCache(loadSrc: string,option: ImageKnifeOption, engineKey: IEngineKey): ImageKnifeData | undefined {
|
||||
let keys = engineKey.generateMemoryKey(loadSrc,option)
|
||||
return ImageKnife.getInstance()
|
||||
.loadFromMemoryCache(keys)
|
||||
}
|
||||
ReadFileCache(loadSrc:string,engineKey:IEngineKey,onComplete:(data:ImageKnifeData | undefined)=>void){
|
||||
let keys = engineKey.generateCacheKey(loadSrc)
|
||||
|
||||
private readFileCache(loadSrc:string,engineKey:IEngineKey,onComplete:(data:ImageKnifeData | undefined)=>void){
|
||||
let keys = engineKey.generateFileKey(loadSrc)
|
||||
let buffer = ImageKnife.getInstance().loadFromFileCache(keys)
|
||||
if(buffer != undefined) {
|
||||
let fileTypeUtil = new FileTypeUtil();
|
||||
|
|
|
@ -34,6 +34,7 @@ import util from '@ohos.util';
|
|||
import { IEngineKey } from './key/IEngineKey';
|
||||
import { DefaultEngineKey } from './key/DefaultEngineKey';
|
||||
import { HeaderOptions } from './ImageKnifeOption';
|
||||
import { PixelMapTransformation } from './transform/PixelMapTransformation';
|
||||
|
||||
export class ImageKnifeDispatcher {
|
||||
// 最大并发
|
||||
|
@ -47,7 +48,7 @@ export class ImageKnifeDispatcher {
|
|||
|
||||
showFromMemomry(request: ImageKnifeRequest, imageSrc: string | PixelMap | Resource, requestSource: ImageKnifeRequestSource): boolean {
|
||||
let memoryCache: ImageKnifeData | undefined = ImageKnife.getInstance()
|
||||
.loadFromMemoryCache(this.engineKeyImpl.generateCacheKey(imageSrc, request.ImageKnifeOption.signature))
|
||||
.loadFromMemoryCache(this.engineKeyImpl.generateMemoryKey(imageSrc, request.ImageKnifeOption))
|
||||
if (memoryCache !== undefined) {
|
||||
// 画主图
|
||||
if (request.requestState === ImageKnifeRequestState.PROGRESS) {
|
||||
|
@ -96,12 +97,13 @@ export class ImageKnifeDispatcher {
|
|||
* 获取和显示图片
|
||||
*/
|
||||
getAndShowImage(currentRequest: ImageKnifeRequest, imageSrc: string | PixelMap | Resource, requestSource: ImageKnifeRequestSource): void {
|
||||
let key: string = this.engineKeyImpl.generateCacheKey(imageSrc, currentRequest.ImageKnifeOption.signature)
|
||||
let requestList: List<ImageKnifeRequestWithSource> | undefined = this.executingJobMap.get(key)
|
||||
let keyMemory: string = this.engineKeyImpl.generateMemoryKey(imageSrc, currentRequest.ImageKnifeOption)
|
||||
let keyFile: string = this.engineKeyImpl.generateFileKey(imageSrc, currentRequest.ImageKnifeOption.signature)
|
||||
let requestList: List<ImageKnifeRequestWithSource> | undefined = this.executingJobMap.get(keyMemory)
|
||||
if (requestList == undefined) {
|
||||
requestList = new List()
|
||||
requestList.add({ request: currentRequest, source: requestSource })
|
||||
this.executingJobMap.set(key, requestList)
|
||||
this.executingJobMap.set(keyMemory, requestList)
|
||||
} else {
|
||||
requestList.add({ request: currentRequest, source: requestSource })
|
||||
return
|
||||
|
@ -110,11 +112,12 @@ export class ImageKnifeDispatcher {
|
|||
let request: RequestJobRequest = {
|
||||
context: currentRequest.context,
|
||||
src: imageSrc,
|
||||
key: key,
|
||||
key: keyFile,
|
||||
headers:currentRequest.ImageKnifeOption.headerOption,
|
||||
allHeaders:currentRequest.headers,
|
||||
customGetImage: currentRequest.ImageKnifeOption.customGetImage,
|
||||
onlyRetrieveFromCache: currentRequest.ImageKnifeOption.onlyRetrieveFromCache,
|
||||
transformation:currentRequest.ImageKnifeOption.transformation,
|
||||
requestSource
|
||||
}
|
||||
// 启动线程下载和解码主图
|
||||
|
@ -140,15 +143,15 @@ export class ImageKnifeDispatcher {
|
|||
}
|
||||
}
|
||||
});
|
||||
this.executingJobMap.remove(key)
|
||||
this.executingJobMap.remove(keyMemory)
|
||||
}
|
||||
else {
|
||||
LogUtil.log("error: no requestlist need to draw for key = " + key)
|
||||
LogUtil.log("error: no requestlist need to draw for key = " + keyMemory)
|
||||
}
|
||||
}
|
||||
// 保存文件缓存
|
||||
if (requestJobResult.bufferSize > 0 && currentRequest.ImageKnifeOption.writeCacheStrategy !== WriteCacheStrategyType.Memory) {
|
||||
ImageKnife.getInstance().saveWithoutWriteFile(key, requestJobResult.bufferSize)
|
||||
ImageKnife.getInstance().saveWithoutWriteFile(keyFile, requestJobResult.bufferSize)
|
||||
}
|
||||
|
||||
let ImageKnifeData: ImageKnifeData = {
|
||||
|
@ -160,7 +163,7 @@ export class ImageKnifeDispatcher {
|
|||
// 保存内存缓存
|
||||
if(currentRequest.ImageKnifeOption.writeCacheStrategy !== WriteCacheStrategyType.File) {
|
||||
ImageKnife.getInstance()
|
||||
.saveMemoryCache(this.engineKeyImpl.generateCacheKey(imageSrc, currentRequest.ImageKnifeOption.signature),
|
||||
.saveMemoryCache(this.engineKeyImpl.generateMemoryKey(imageSrc, currentRequest.ImageKnifeOption),
|
||||
ImageKnifeData)
|
||||
}
|
||||
if (requestList !== undefined) {
|
||||
|
@ -186,11 +189,11 @@ export class ImageKnifeDispatcher {
|
|||
|
||||
});
|
||||
|
||||
this.executingJobMap.remove(key)
|
||||
this.executingJobMap.remove(keyMemory)
|
||||
this.dispatchNextJob()
|
||||
}
|
||||
else {
|
||||
LogUtil.log("error: no requestlist need to draw for key = " + key)
|
||||
LogUtil.log("error: no requestlist need to draw for key = " + keyMemory)
|
||||
}
|
||||
// })
|
||||
|
||||
|
@ -359,6 +362,11 @@ async function requestJob(request: RequestJobRequest): Promise<RequestJobResult
|
|||
imageSource.release()
|
||||
})
|
||||
|
||||
// 图形变化
|
||||
if (request.requestSource == 0 && request.transformation !== undefined) {
|
||||
resPixelmap = await request.transformation?.transform(request.context, resPixelmap!, 0, 0)
|
||||
}
|
||||
|
||||
return {
|
||||
pixelMap: resPixelmap,
|
||||
bufferSize: bufferSize
|
||||
|
@ -392,4 +400,5 @@ interface RequestJobRequest {
|
|||
customGetImage?: (context: Context, src: string | PixelMap | Resource) => Promise<ArrayBuffer | undefined>,
|
||||
onlyRetrieveFromCache?: boolean
|
||||
requestSource:ImageKnifeRequestSource
|
||||
transformation?: PixelMapTransformation
|
||||
}
|
||||
|
|
|
@ -16,6 +16,8 @@ import taskpool from '@ohos.taskpool';
|
|||
import common from '@ohos.app.ability.common'
|
||||
import { ObjectKey } from './model/ObjectKey';
|
||||
import { WriteCacheStrategyType } from './model/ImageKnifeData';
|
||||
import { PixelMapTransformation } from './transform/PixelMapTransformation';
|
||||
|
||||
export interface HeaderOptions {
|
||||
key: string;
|
||||
value: Object;
|
||||
|
@ -50,6 +52,8 @@ export class ImageKnifeOption {
|
|||
|
||||
progressListener?: (progress: number)=>void;
|
||||
|
||||
transformation?: PixelMapTransformation
|
||||
|
||||
constructor() {
|
||||
|
||||
}
|
||||
|
|
|
@ -17,14 +17,10 @@ import { ImageKnifeRequest, ImageKnifeRequestState } from '../ImageKnifeRequest'
|
|||
import common from '@ohos.app.ability.common';
|
||||
import { ImageKnife } from '../ImageKnife';
|
||||
import { LogUtil } from '../utils/LogUtil';
|
||||
import componentUtils from '@ohos.arkui.componentUtils'
|
||||
import util from '@ohos.util'
|
||||
import inspector from '@ohos.arkui.inspector'
|
||||
import { ImageKnifeData } from '../model/ImageKnifeData'
|
||||
|
||||
@Component
|
||||
export struct ImageKnifeComponent {
|
||||
@Watch('watchImageKnifeOption') @ObjectLink ImageKnifeOption: ImageKnifeOption;
|
||||
@Watch('watchImageKnifeOption') @ObjectLink imageKnifeOption: ImageKnifeOption;
|
||||
@State pixelMap: PixelMap | string | undefined = undefined
|
||||
@State adaptiveWidth: Length = '100%'
|
||||
@State adaptiveHeight: Length = '100%'
|
||||
|
@ -66,10 +62,10 @@ export struct ImageKnifeComponent {
|
|||
|
||||
build() {
|
||||
Image(this.pixelMap)
|
||||
.objectFit(this.ImageKnifeOption.objectFit === undefined ? ImageFit.Contain : this.ImageKnifeOption.objectFit)
|
||||
.objectFit(this.imageKnifeOption.objectFit === undefined ? ImageFit.Contain : this.imageKnifeOption.objectFit)
|
||||
.width(this.adaptiveWidth)
|
||||
.height(this.adaptiveHeight)
|
||||
.border(this.ImageKnifeOption.border)
|
||||
.border(this.imageKnifeOption.border)
|
||||
.onSizeChange((oldValue:SizeOptions, newValue:SizeOptions) => {
|
||||
this.currentWidth = newValue.width as number
|
||||
this.currentHeight = newValue.height as number
|
||||
|
@ -106,8 +102,8 @@ export struct ImageKnifeComponent {
|
|||
getRequest(width: number, height: number): ImageKnifeRequest {
|
||||
if (this.request == undefined) {
|
||||
this.request = new ImageKnifeRequest(
|
||||
this.ImageKnifeOption,
|
||||
this.ImageKnifeOption.context !== undefined ? this.ImageKnifeOption.context : this.getCurrentContext(),
|
||||
this.imageKnifeOption,
|
||||
this.imageKnifeOption.context !== undefined ? this.imageKnifeOption.context : this.getCurrentContext(),
|
||||
width,
|
||||
height,
|
||||
this.componentVersion,
|
||||
|
@ -118,7 +114,7 @@ export struct ImageKnifeComponent {
|
|||
}
|
||||
this.pixelMap = pixelMap
|
||||
if (typeof this.pixelMap !== 'string') {
|
||||
if (this.ImageKnifeOption.objectFit === ImageFit.Auto) {
|
||||
if (this.imageKnifeOption.objectFit === ImageFit.Auto) {
|
||||
let info = await this.pixelMap.getImageInfo()
|
||||
|
||||
this.adaptiveWidth = this.currentWidth
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2021 Huawei Device Co., Ltd.
|
||||
* Copyright (C) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
|
@ -14,34 +14,51 @@
|
|||
*/
|
||||
import util from '@ohos.util';
|
||||
import { SparkMD5 } from '../3rd_party/sparkmd5/spark-md5';
|
||||
import { ObjectKey } from '../model/ObjectKey';
|
||||
import { ImageKnifeOption } from '../ImageKnifeOption';
|
||||
import { IEngineKey } from './IEngineKey';
|
||||
import { ObjectKey } from '../model/ObjectKey';
|
||||
import { PixelMapTransformation } from '../transform/PixelMapTransformation';
|
||||
|
||||
export class DefaultEngineKey implements IEngineKey {
|
||||
private memoryKeyCache: util.LRUCache<string, string> = new util.LRUCache(1024)
|
||||
private fileKeyCache: util.LRUCache<string, string> = new util.LRUCache(1024)
|
||||
|
||||
private keyCache: util.LRUCache<string,string> = new util.LRUCache(1024)
|
||||
|
||||
// 生成内存缓存
|
||||
generateCacheKey(loadSrc: string | PixelMap | Resource, signature?: ObjectKey | undefined): string {
|
||||
let key = "loadSrc=" + this.generateKey(loadSrc) + ";";
|
||||
if (signature) {
|
||||
key += "signature=" + signature.getKey() + ";"
|
||||
// 生成内存缓存key
|
||||
generateMemoryKey(loadSrc: string | PixelMap | Resource, imageKnifeOption: ImageKnifeOption): string {
|
||||
let src = "loadSrc=" + (typeof loadSrc == "string" ? loadSrc : JSON.stringify(loadSrc)) + ";"
|
||||
if (imageKnifeOption.signature) {
|
||||
src += "signature=" + imageKnifeOption.signature.getKey() + ";"
|
||||
}
|
||||
return key;
|
||||
if (imageKnifeOption.transformation) {
|
||||
src += "transformation=" + this.getTransformation(imageKnifeOption.transformation) + ";"
|
||||
}
|
||||
return this.generateKey(src, this.memoryKeyCache)
|
||||
}
|
||||
|
||||
// 生成文件缓存key
|
||||
generateFileKey(loadSrc: string | PixelMap | Resource, signature?: ObjectKey | undefined): string {
|
||||
let src = "loadSrc=" + (typeof loadSrc == "string" ? loadSrc : JSON.stringify(loadSrc)) + ";"
|
||||
if (signature) {
|
||||
src += "signature=" + signature.getKey() + ";"
|
||||
}
|
||||
return this.generateKey(src, this.fileKeyCache)
|
||||
}
|
||||
|
||||
// key缓存策略,避免无意义的 JSON.stringify
|
||||
private generateKey(key: string | PixelMap | Resource): string {
|
||||
let keyCache = typeof key == "string" ? key : JSON.stringify(key)
|
||||
let result = this.keyCache.get(keyCache)
|
||||
private generateKey(keyCache: string, cache: util.LRUCache<string, string>): string {
|
||||
let result = cache.get(keyCache)
|
||||
if (result != undefined) {
|
||||
return result
|
||||
} else {
|
||||
result = SparkMD5.hashBinary(keyCache)
|
||||
this.keyCache.put(keyCache, result)
|
||||
cache.put(keyCache, result)
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
private getTransformation(transformation: PixelMapTransformation): string {
|
||||
return transformation.getName()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2023 Huawei Device Co., Ltd.
|
||||
* Copyright (C) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
|
@ -12,11 +12,15 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { ImageKnifeOption } from '../ImageKnifeOption'
|
||||
import { ObjectKey } from '../model/ObjectKey'
|
||||
|
||||
export interface IEngineKey {
|
||||
// 生成缓存key
|
||||
generateCacheKey(loadSrc: string | PixelMap | Resource, signature?: ObjectKey | undefined): string
|
||||
// 生成内存缓存key
|
||||
generateMemoryKey(loadSrc: string | PixelMap | Resource, imageKnifeOption: ImageKnifeOption): string
|
||||
|
||||
// 生成文件缓存key
|
||||
generateFileKey(loadSrc: string | PixelMap | Resource, signature?: ObjectKey | undefined): string
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* Copyright (C) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* 图片变换接口
|
||||
*/
|
||||
export interface BaseTransformation<T> {
|
||||
|
||||
transform(context: Context, toTransform: T, width: number, height: number): Promise<T>;
|
||||
|
||||
getName(): string
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Copyright (C) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { PixelMapTransformation } from './PixelMapTransformation';
|
||||
import effectKit from '@ohos.effectKit';
|
||||
|
||||
/**
|
||||
* 图片变换:模糊效果
|
||||
*/
|
||||
@Sendable
|
||||
export class BlurTransformation extends PixelMapTransformation {
|
||||
private radius: number // 模糊半径,单位是像素。模糊效果与所设置的值成正比,值越大效果越明显。
|
||||
|
||||
constructor(radius: number) {
|
||||
super()
|
||||
this.radius = radius
|
||||
}
|
||||
|
||||
async transform(context: Context, toTransform: PixelMap, width: number, height: number): Promise<PixelMap> {
|
||||
let headFilter = effectKit.createEffect(toTransform);
|
||||
if (headFilter != null) {
|
||||
return await headFilter.blur(this.radius).getEffectPixelMap()
|
||||
}
|
||||
return toTransform
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Copyright (C) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { PixelMapTransformation } from './PixelMapTransformation';
|
||||
import effectKit from '@ohos.effectKit';
|
||||
|
||||
/**
|
||||
* 图片变换:高亮效果
|
||||
*/
|
||||
@Sendable
|
||||
export class BrightnessTransformation extends PixelMapTransformation {
|
||||
private bright: number // 高亮程度,取值范围在0-1之间,取值为0时图像保持不变。
|
||||
|
||||
constructor(bright: number) {
|
||||
super()
|
||||
this.bright = bright
|
||||
}
|
||||
|
||||
async transform(context: Context, toTransform: PixelMap, width: number, height: number): Promise<PixelMap> {
|
||||
let headFilter = effectKit.createEffect(toTransform);
|
||||
if (headFilter != null) {
|
||||
return await headFilter.brightness(this.bright).getEffectPixelMap()
|
||||
}
|
||||
return toTransform
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Copyright (C) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { PixelMapTransformation } from './PixelMapTransformation';
|
||||
import { collections } from '@kit.ArkTS';
|
||||
|
||||
/**
|
||||
* 多个图片变换
|
||||
*/
|
||||
@Sendable
|
||||
export class MultiTransTransformation extends PixelMapTransformation {
|
||||
private transformations: collections.Array<PixelMapTransformation>
|
||||
|
||||
constructor(transformations: collections.Array<PixelMapTransformation>) {
|
||||
super()
|
||||
this.transformations = transformations
|
||||
}
|
||||
|
||||
async transform(context: Context, toTransform: PixelMap, width: number, height: number): Promise<PixelMap> {
|
||||
let res = toTransform
|
||||
for (let i = 0; i < this.transformations.length; i++) {
|
||||
res = await this.transformations[i].transform(context, res, width, height)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
getName(): string {
|
||||
let res: string = ""
|
||||
this.transformations.forEach((transformation) => {
|
||||
res += transformation.getName() + "&"
|
||||
})
|
||||
return res
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* Copyright (C) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { BaseTransformation } from './BaseTransformation';
|
||||
|
||||
/**
|
||||
* 基于PixelMap的图片变换
|
||||
*/
|
||||
@Sendable
|
||||
export abstract class PixelMapTransformation implements BaseTransformation<PixelMap>{
|
||||
transform(context: Context, toTransform: PixelMap, width: number, height: number): Promise<PixelMap> {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
|
||||
getName(): string {
|
||||
return this.constructor.name
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue