diff --git a/AppScope/app.json5 b/AppScope/app.json5 index 4819fe9..a3ceb20 100644 --- a/AppScope/app.json5 +++ b/AppScope/app.json5 @@ -3,7 +3,7 @@ "bundleName": "com.openharmony.imageknife", "vendor": "example", "versionCode": 1000000, - "versionName": "2.1.2-rc.0", + "versionName": "3.0.0-rc.0", "icon": "$media:app_icon", "label": "$string:app_name", "distributedNotificationEnabled": true diff --git a/AppScope/resources/base/media/app_icon.png b/AppScope/resources/base/media/app_icon.png index ce307a8..cd45acc 100644 Binary files a/AppScope/resources/base/media/app_icon.png and b/AppScope/resources/base/media/app_icon.png differ diff --git a/CHANGELOG.md b/CHANGELOG.md index 843f04d..c6274d3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,25 +1,17 @@ -## 2.1.2-rc.12 -- 新增磁盘预加载返回文件路径接口prefetchToDiskCache - -## 2.1.2-rc.11 -- 修复设置磁盘容量最大值出现闪退 -- 修复概率出现jscrash问题 -- 修复进度条问题 -- 修复单帧gif图片加载失败 -- removeRunning删除running队列log设置开关 -- ImageKnife新增图片宽高自适应功能 -- 修复onlyRetrieveFromCache属性(仅磁盘和内存获取资源)失效 -- 修改拼写错误 -- 新增多线程优先级 -- 修复复用场景下图片闪动以及概率错位 -- 获取组件宽高改为使用CanvasRenderingContext2D对象获取宽高,并修复改变字体大小导致部分图片消失 -- 修复获取不到磁盘缓存文件问题 -- 修复获取不到网络请求错误回调问题 - -## 2.1.2-rc.10 -- 修复部分gif图片识别成静态图 -- 修复同一张图片发送多次请求 -- 复用场景缓存到树aboutToRecycle清理定时器 +## 3.0.0-rc.0 +使用Image组件替换Canvas组件渲染,并重构大部分的实现逻辑,提升渲染性能 +缺失特性 +- gif/webp动图显示与控制 +- 支持自定义key的实现 +- 支持进行图片变换: 支持图像像素源图片变换效果。 +- 使用IDrawLifeCycle自绘Canvas +较2.x版本增强点: +- 使用Image组件渲染,提升渲染性能 +- 支持通过initMemoryCache自定义策略内存缓存策略和大小。 +- 支持option自定义实现图片获取/网络下载 +- 继承Image的能力,支持option传入border,设置边框,圆角 +- 继承Image的能力,支持option传入objectFit设置图片缩放 +- 并发请求数量,支持请求排队队列的优先级 ## 2.1.2-rc.9 - 使用taskpool实现多线程加载图片资源 diff --git a/OAT.xml b/OAT.xml index 10e5eb1..681e878 100644 --- a/OAT.xml +++ b/OAT.xml @@ -10,7 +10,7 @@ - + @@ -20,7 +20,7 @@ - + @@ -34,7 +34,7 @@ - + diff --git a/README.md b/README.md index 327873a..4219c6e 100644 --- a/README.md +++ b/README.md @@ -4,526 +4,116 @@ ## 简介 -本项目基于开源库 [Glide](https://github.com/bumptech/glide) 进行OpenHarmony的自研版本: +本项目参考开源库 [Glide](https://github.com/bumptech/glide) 进行OpenHarmony的自研版本: - 支持内存缓存,使用LRUCache算法,对图片数据进行内存缓存。 -- 支持磁盘缓存,对于下载图片会保存一份至磁盘当中。 -- 支持进行图片变换: 支持图像像素源图片变换效果。 -- 支持用户配置参数使用:( - 例如:配置是否开启一级内存缓存,配置磁盘缓存策略,配置仅使用缓存加载数据,配置图片变换效果,配置占位图,配置加载失败占位图等)。 -- 推荐使用ImageKnifeComponent组件配合ImageKnifeOption参数来实现功能。 -- 支持用户自定义配置实现能力参考ImageKnifeComponent组件中对于入参ImageKnifeOption的处理。 +- 支持通过initMemoryCache自定义策略内存缓存策略和大小。 +- 支持磁盘二级缓存,对于下载图片会保存一份至磁盘当中。 +- 支持option自定义实现图片获取/网络下载 +- 支持监听网络下载回调进度 +- 继承Image的能力,支持option传入border,设置边框,圆角 +- 继承Image的能力,支持option传入objectFit设置图片缩放 +- 支持通过设置transform缩放图片 +- 并发请求数量,支持请求排队队列的优先级 - +待实现特性 +- gif/webp动图显示与控制 +- 内存降采样优化,节约内存的占用 +- 支持自定义图片加载和请求并发数量 +- 支持声明周期已销毁的图片,不再发起请求 +- 支持自定义图片解码 +- 支持自定义key的实现 +- 支持进行图片变换: 支持图像像素源图片变换效果。 + +待确认arkui的能力 +- 精确获取开发者给组件设置的宽和高 +- 动图的显示与控制 ## 下载安装 - ``` ohpm install @ohos/imageknife ``` -## 使用说明 - -### 1.依赖配置 -在entry\src\main\ets\entryability\EntryAbility.ts中做如下配置初始化全局ImageKnife实例: - -```typescript -import UIAbility from '@ohos.app.ability.UIAbility'; -import window from '@ohos.window'; -import { ImageKnife } from '@ohos/imageknife' - -export default class EntryAbility extends UIAbility { - onWindowStageCreate(windowStage: window.WindowStage) { - windowStage.loadContent('pages/Index', (err, data) => { - }); - // 初始化全局ImageKnife - ImageKnife.with(this.context); - // 后续访问ImageKnife请通过:ImageKnifeGlobal.getInstance().getImageKnife()方式 +## 使用说明 +#### 1.显示本地资源图片 +``` +ImageKnifeComponent({ + ImageKnifeOption: { + src: $r("app.media.app_icon"), + placeholderSrc: $r("app.media.loading"), + errorholderSrc: $r("app.media.app_icon"), + objectFit: ImageFit.Auto } -} +}).width(100).height(100) ``` -### 2.加载普通图片 - -接下来我们来写个简单实例看看: - -```extendtypescript -import { ImageKnifeComponent, ImageKnifeOption } from '@ohos/imageknife' - -@Entry -@Component -struct Index { - @State message: string = 'Hello World' - @State option: ImageKnifeOption = { - loadSrc: $r('app.media.icon') +#### 2.显示本地context files下文件 +``` +ImageKnifeComponent({ + ImageKnifeOption: { + src: this.localFile, + placeholderSrc: $r("app.media.loading"), + errorholderSrc: $r("app.media.app_icon"), + objectFit: ImageFit.Auto } +}).width(100).height(100) +``` - build() { - Row() { - Column() { - Text(this.message) - .fontSize(50) - .fontWeight(FontWeight.Bold) - ImageKnifeComponent({ imageKnifeOption: this.option }) - .width(300) - .height(300) - }.width('100%') - }.height('100%') +#### 3.显示网络图片 +``` +ImageKnifeComponent({ + ImageKnifeOption: { + src:"https://www.openharmony.cn/_nuxt/img/logo.dcf95b3.png", + placeholderSrc: $r("app.media.loading"), + errorholderSrc: $r("app.media.app_icon"), + objectFit: ImageFit.Auto } -} +}).width(100).height(100) ``` -非常简单,仅需定义一个ImageKnifeOption数据对象,然后在你需要的UI位置,加入ImageKnifeComponent自定义组件就可以加载出一张图像了。 - -### 3.加载SVG图片 - -加载svg其实和普通流程没有区别,只要将 `loadSrc: $r('app.media.jpgSample'),` `改成一张 loadSrc: $r('app.media.svgSample'),` -svg类型图片即可。 - - -### 4.加载GIF图片 - -加载GIF其实和普通流程也没有区别只要将 `loadSrc: $r('app.media.jpgSample'),` `改成一张 loadSrc: $r('app.media.gifSample'),` -GIF图片即可。 - -### 5.自定义Key -因为通常改变标识符比较困难或者根本不可能,所以ImageKnife也提供了 签名 API 来混合(你可以控制的)额外数据到你的缓存键中。 -签名(signature)适用于媒体内容,也适用于你可以自行维护的一些版本元数据。 - -将签名传入加载请求 -```extendtypescript -imageKnifeOption = { - loadSrc: 'https://aahyhy.oss-cn-beijing.aliyuncs.com/blue.jpg', - signature: new ObjectKey(new Date().getTime().toString()) - } +#### 4.自定义下载图片 ``` -详细样例请参考SignatureTestPage文件 - -代码示例 - -## 进阶使用 - -如果简单的加载一张图像无法满足需求,我们可以看看ImageKnifeOption这个类提供了哪些扩展能力。 - -### ImageKnifeOption参数列表 - -| 参数名称 | 入参内容 | 功能简介 | -| ---------------------------- | ------------------------------------------------------------ |-----------------------------------------------| -| 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 | {
// 返回一周期动画gif消耗的时间
loopFinish?: (loopTime?) => void
// gif播放速率相关
speedFactory?: number
// 直接展示gif第几帧数据
seekTo?: number
} | GIF播放控制能力(可选) | -| transformation | BaseTransform | 单个变换(可选) | -| transformations | Array> | 多个变换,目前仅支持单个变换(可选) | -| allCacheInfoCallback | IAllCacheInfoCallback | 输出缓存相关内容和信息(可选) | -| signature | ObjectKey | 自定key(可选) | -| **drawLifeCycle** | **IDrawLifeCycle** | **用户自定义实现绘制方案(可选)** | -| imageSmoothingEnabled | boolean | 抗锯齿是否开启属性配置,设置为false时,imageSmoothingQuality失效 | -| imageSmoothingQuality | AntiAliasing | 抗锯齿属性配置 | - -其他参数只需要在ImageKnifeOption对象上按需添加即可。 - -这里我们着重讲一下**自定义实现绘制方案**。为了增强绘制扩展能力,目前ImageKnifeComponent使用了Canvas的渲染能力作为基础。在此之上为了抽象组件绘制表达。我将图像的状态使用了 -**IDrawLifeCycle绘制生命周期进行表达**, - -大致流程 展示占位图->展示网络加载进度->展示缩略图->展示主图->展示重试图层->展示失败占位图 - - - -ImageKnifeComponent内部,责任链实现。 用户参数设置->全局参数设置->自定义组件内部设置 - -采用责任链的好处是,用户可以通过自定义绘制,重新绘制图层。如果不想绘制也可以通过预制回调获取绘制流程信息。 - - - -### 场景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'), - // 占位图使用本地资源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) - }; - - build(){ - Scroll() { - Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { - ImageKnifeComponent({ imageKnifeOption: this.imageKnifeOption1 }) - .width(300) - .height(300) - } - } - .width('100%') - .height('100%') - } -} -``` - -`ImageKnifeDrawFactory.createRoundLifeCycle(5,"#ff00ff",30)` -我们深入查看源码可以发现,实际上是对IDrawLifeCycle接口的部分实现,这里我介绍一下IDrawLifeCycle。 - -* -*IDrawLifeCycle的返回值代表事件是否被消费,如果被消费接下来组件内部就不会处理,如果没被消费就会传递到下一个使用者。目前消费流程(用户自定义-> -全局配置定义->组件内部默认定义)** - -所以我们在当数据是一张PixelMap的时候(目前jpg png bmp webp -svg返回的都是PixelMap,gif返回GIFFrame数组),我们返回了true。消费了事件,代表这个绘制流程用户自定义完成。 - - - -由于IDrawLifeCycle实现较为冗长,我们封装了ImageKnifeDrawFactory工厂,提供了网络下载百分比效果、圆角、椭圆添加边框等能力。下面我们就再看看使用工厂封装之后的场景代码。 - -### 场景2: 网络下载百分比效果展示 - -当进行加载网络图片时,可能需要展示网络下载百分比动画。但是默认的动画又不能满足需求,这个时候我们就需要自定义网络下载百分比效果。代码如下: - -```typescript -import UIAbility from '@ohos.app.ability.UIAbility'; -import window from '@ohos.window'; -import { ImageKnifeGlobal,ImageKnife,ImageKnifeDrawFactory,LogUtil } from '@ohos/imageknife' -import abilityAccessCtrl,{Permissions} from '@ohos.abilityAccessCtrl'; -export default class EntryAbility extends UIAbility { - onWindowStageCreate(windowStage: window.WindowStage) { - //.. 删除不必要代码 - windowStage.loadContent('pages/index', (err, data) => { - }); - // 初始化ImageKnifeGlobal和ImageKnife - ImageKnife.with(this.context); - // 全局配置网络加载进度条 使用ImageKnifeGlobal.getInstance().getImageKnife()访问ImageKnife -ImageKnifeGlobal.getInstance().getImageKnife().setDefaultLifeCycle(ImageKnifeDrawFactory.createProgressLifeCycle("#10a5ff", 0.5)) - } -} -``` - -这里大家可能会问,为什么会将这个IDrawLifeCycle放在AbilityStage里面实现? - -这是因为网络下载百分比进度很多时候都是全局通用,如果有需要全局配置的自定义展示方案。推荐在AbilityStage里面,往ImageKnife的setDefaultLifeCycle函数中注入,即可将ImageKnifeComponent中的默认绘制方案替换。 - -在这里我们实现的效果如下图所示。 - - - -## 高级用法 - -以上简单使用和进阶使用都是经过一层自定义组件封装之后形成的,RequestOption封装成了ImageKnifeOption,绘制部分封装成了自定义组件ImageKnifeComponent。 - -如果用户其实并不关心绘制部分,或者说想用自己的通用方案对自定义组件ImageKnifeComponent重构都是可以的。 - -下面我们会着重指导用户如何复用图片加载逻辑,重构自定义组件ImageKnifeComponent。 - -首先我们先看看RequestOption构建的内容,如下所示: - -### 数据加载 - -#### RequestOption构建: - -请查阅下文接口内容:[RequestOption接口方法](#requestoption用户配置参数) - -了解了RequestOption的参数内容后,我们可以参考ImageKnifeComponent组件代码进行分析。 - -**从`imageKnifeExecute()`函数入口,首先我们需要构建一个RequestOption对象,`let request = new RequestOption()`, -接下来就是按需配置request对象的内容,最后使用 `ImageKnifeGlobal.getInstance().getImageKnife()?.call(request)`发送request执行任务即可。** - -是不是很简单,而其实最重要的内容是就是: **按需配置request对象的内容** 为了更好理解,我举例说明一下: - -#### 场景一: 简单加载一张图片 - -``` -let request = new RequestOption(); -// (必传) -request.load("图片url") - // (可选 整个request监听回调) - .addListener({callback:(err:BusinessError|string, data:ImageKnifeData) => { - // data 是ImageKnifeData对象 - if(data.isPixelMap()){ - // 这样就获取到了目标PixelMap - let pixelmap = data.drawPixleMap.imagePixelMap; - } - return false; - }) - - let compSize:Size = { - width: this.currentWidth, - height:this.currentHeight - } - // (必传)这里setImageViewSize函数必传组件大小,因为涉及到图片变换效果都需要适配图像源和组件大小 - request.setImageViewSize(compSize) - // 最后使用ImageKnife的call函数调用request即可 - let imageKnife:ImageKnife|undefined = ImageKnifeGlobal.getInstance().getImageKnife(); - if(imageKnife != undefined){ - imageKnife.call(request) +ImageKnifeComponent({ + ImageKnifeOption: { + src: "https://file.atomgit.com/uploads/user/1704857786989_8994.jpeg", + placeholderSrc: $r("app.media.loading"), + errorholderSrc: $r("app.media.app_icon"), + objectFit: ImageFit.Auto, + customGetImage: custom } +}).width(100).height(100) -``` - -**其他场景,可以按需加载** - -比如我需要配置 **占位图** 只需要 在request对象创建好之后,调用 **placeholder** 函数即可 - -``` -request.placeholder(this.imageKnifeOption.placeholderSrc, (data) => { - console.log('request.placeholder callback') - this.displayPlaceholder(data) -}) -``` - -再比如 我对缓存配置有要求,我要禁用内存缓存,调用 **skipMemoryCache** 函数即可 - -``` -request.skipMemoryCache(true) -``` - -这里只是简单介绍部分使用,更多的内容请参考 **按需加载** 原则,并且可以参考ImageKnifeComponent源码或者根据文档自行探索实现。 - -## 接口说明 - -### RequestOption用户配置参数 - -| 方法名 | 入参 | 接口描述 | -| ------------------------------------------------------------ | ------------------------------------------------------------ | -------------------------------------------------------- | -| load(src: string \| PixelMap \|Resource) | src:string\|PixelMap\|Resource | 用户加载图片源 | -| setImageViewSize(imageSize: { width: number, height: number }) | imageSize:{width: number, height: number } | 传入显示图片组件的大小,变换的时候需要作为参考 | -| diskCacheStrategy(strategy: DiskStrategy) | strategy:DiskStrategy | 配置磁盘缓存策略 NONE SOURCE RESULT ALL AUTOMATIC | -| placeholder(src: PixelMap\|Resource, func?: AsyncSuccess) | src: PixelMap\|Resource, func?: AsyncSuccess | 占位图,占位图回调数据ImageKnifeData | -| errorholder(src: PixelMap\|Resource, func?: AsyncSuccess) | src: PixelMap\|Resource, func?: AsyncSuccess | 错误占位图,错误占位图回调数据ImageKnifeData | -| retryholder(src: PixelMap\|Resource, func?: AsyncSuccess) | src: PixelMap\|Resource, func?: AsyncSuccess | 重试占位图,重试占位图回调数据ImageKnifeData | -| addListener(func: AsyncCallback) | func: AsyncCallback | 配置整个监听回调,数据正常加载返回,加载失败返回错误信息 | -| thumbnail(sizeMultiplier:number, func?: AsyncSuccess) | sizeMultiplier:number, func?: AsyncSuccess | 设置缩略图比例,缩略图返回后,加载并展示缩略图 | -| addProgressListener(func?: AsyncSuccess) | func?: AsyncSuccess | 设置网络下载百分比监听,返回数据加载百分比数值 | -| addAllCacheInfoCallback(func: IAllCacheInfoCallback) | func: IAllCacheInfoCallback | 设置获取所有缓存信息监听 | -| skipMemoryCache(skip: boolean) | skip: boolean | 配置是否跳过内存缓存 | -| retrieveDataFromCache(flag: boolean) | flag: boolean | 配置仅从缓存中加载数据 | -| signature | ObjectKey | 自定义key | - -同时支持[图片变换相关](#图片变换相关)接口。 - -### ImageKnife 启动器/门面类 - -| 方法名 | 入参 | 接口描述 | -| ------------------------------- | ---------------------- | ---------------------------------- | -| call(request: RequestOption) | request: RequestOption | 根据用户配置参数具体执行加载流程 | -| preload(request: RequestOption) | request: RequestOption | 根据用户配置参数具体执行预加载流程 | -| pauseRequests() | | 全局暂停请求 | -| resumeRequests() | | 全局恢复暂停 | - -### 缓存策略相关 - -| 使用方法 | 类型 | 策略描述 | -|--------------------------------------------|-----------|----------------------| -| request.diskCacheStrategy(new ALL()) | ALL | 表示既缓存原始图片,也缓存转换过后的图片 | -| request.diskCacheStrategy(new AUTOMATIC()) | AUTOMATIC | 表示尝试对本地和远程图片使用适合的策略 | -| request.diskCacheStrategy(new DATA()) | DATA | 表示只缓存原始图片 | -| request.diskCacheStrategy(new NONE()) | NONE | 表示不缓存任何内容 | -| request.diskCacheStrategy(new RESOURCE()) | RESOURCE | 表示只缓存转换过后的图片 | - -### AntiAliasing类型展示效果 - -| 使用方法 | 类型 | 策略描述 | -|-------------------------|--------|-------------| -| AntiAliasing.FIT_HIGH | String | 图像抗锯齿设置为高画质 | -| AntiAliasing.FIT_MEDIUM | String | 图像抗锯齿设置为中画质 | -| AntiAliasing.FIT_LOW | String | 图像抗锯齿设置为低画质 | - -### ScaleType类型展示效果 - -| 使用方法 | 类型 | 策略描述 | -|-------------------------|-----|-----------------------------------| -| ScaleType.FIT_START | int | 图像位于用户设置组件左上角显示,图像会缩放至全部展示 | -| ScaleType.FIT_END | int | 图像位于用户设置组件右下角显示,图像会缩放至全部展示 | -| ScaleType.FIT_CENTER | int | 图像位于用户设置组件居中,图像会缩放至全部展示 | -| ScaleType.CENTER | int | 图像居中展示,不缩放 | -| ScaleType.CENTER_CROP | int | 图像的宽高长度,短的部分缩放至组件大小,超出的全部裁剪 | -| ScaleType.FIT_XY | int | 图像拉伸至组件大小 | -| ScaleType.CENTER_INSIDE | int | 如果图像大于组件则执行FIT_CENTER,小于组件则CENTER | -| ScaleType.NONE | int | 如果不想适配,直接展示原图大小 | -| ScaleType.AUTO_HEIGHT | int | 设置宽的时候,图片高度自适应 | -| ScaleType.AUTO_WIDTH | int | 设置高的时候,图片宽度自适应 | -| ScaleType.AUTO | int | 没有设置宽和高,图片按照自身宽高显示 | - -### 图片变换相关 - -| 使用方法 | 类型 | 相关描述 | -|--------------------------------|------------------------------------|--------------------------------| -| request.centerCrop() | CenterCrop | 可以根据图片文件,目标显示大小,进行对应centerCrop | -| request.centerInside() | CenterInside | 可以根据图片文件,目标显示大小,进行对应centerInside | -| request.fitCenter() | FitCenter | 可以根据图片文件,目标显示大小,进行对应fitCenter | -| request.blur() | BlurTransformation | 模糊处理(图片分辨率较大建议传递第二个参数将图片进行缩小) | -| request.brightnessFilter() | BrightnessFilterTransformation | 亮度滤波器 | -| request.contrastFilter() | ContrastFilterTransformation | 对比度滤波器 | -| request.cropCircle() | CropCircleTransformation | 圆形剪裁显示 | -| request.cropCircleWithBorder() | CropCircleWithBorderTransformation | 圆环展示 | -| request.cropSquare() | CropSquareTransformation | 正方形剪裁 | -| request.crop() | CropTransformation | 自定义矩形剪裁 | -| request.grayscale() | GrayscaleTransformation | 灰度级转换 | -| request.invertFilter() | InvertFilterTransformation | 反转滤波器 | -| request.pixelationFilter() | PixelationFilterTransformation | 像素化滤波器 | -| request.rotateImage() | RotateImageTransformation | 图片旋转 | -| request.roundedCorners() | RoundedCornersTransformation | 圆角剪裁 | -| request.sepiaFilter() | SepiaFilterTransformation | 乌墨色滤波器 | -| request.sketchFilter() | SketchFilterTransformation | 素描滤波器 | -| request.mask() | MaskTransformation | 遮罩 | -| request.swirlFilter() | SwirlFilterTransformation | 扭曲滤波器 | -| request.kuwaharaFilter() | KuwaharaFilterTransform | 桑原滤波器 | -| request.toonFilter() | ToonFilterTransform | 动画滤波器 | -| request.vignetteFilter() | VignetteFilterTransform | 装饰滤波器 | - - - -### setLruCacheSize - -setLruCacheSize(size: number,memory:number): void - -设置图片文件缓存的大小上限,size单位为张数,memory单位为字节,提升再次加载同源图片的加载速度,特别是对网络图源会有较明显提升。 -如果不设置则默认为100张,100MB。缓存采用内置的LRU策略。 -size为0则代表不限制缓存张数,memory为0则代表不限制缓存大小。 -建议根据应用实际需求,设置合理缓存上限,数字过大可能导致内存占用过高,可能导致OOM异常。 - -**参数:** - -| 参数名 | 类型 | 必填 | 说明 | -| -------- | -------- | -------- |-------------------------| -| size | number | 是 | 图片文件的缓存张数,单位为张。只支持正整数,0 | -| memory | number | 是 | 图片文件的缓存大小,单位为字节。只支持正数,0 | - -**示例:** -```ts -//EntryAbility.ets -import { InitImageKnife } from '...imageknife' -export default class EntryAbility extends UIAbility { - onWindowStageCreate(windowStage: window.WindowStage) { - InitImageKnife.init(this.context); - let imageKnife: ImageKnife | undefined = ImageKnifeGlobal.getInstance().getImageKnife() - if (imageKnife != undefined) { - //设置全局内存缓存大小张数 - imageKnife.setLruCacheSize(100, 100 * 1204 * 1024) - } - } +// 自定义实现图片获取方法,如自定义网络下载 +@Concurrent +async function custom(context: Context, src: string | PixelMap | Resource): Promise { + console.info("ImageKnife:: custom download:" + src) + // 举例写死从本地文件读取,也可以自己请求网络图片 + return context.resourceManager.getMediaContentSync($r("app.media.bb").id).buffer as ArrayBuffer } ``` +#### 5.监听网络下载进度 +``` +ImageKnifeComponent({ + ImageKnifeOption: { + src:"https://www.openharmony.cn/_nuxt/img/logo.dcf95b3.png", + progressListener:(progress:number)=>{console.info("ImageKinfe:: call back progress = " + progress)} + } +}).width(100).height(100) +``` +#### 6.支持option传入border,设置边框,圆角 +``` +ImageKnifeComponent({ ImageKnifeOption: +{ + src: $r("app.media.rabbit"), + border: {radius:50} + } +}).width(100).height(100) +``` + ## 约束与限制 - -在下述版本验证通过: -DevEco Studio 4.1(4.1.3.520)--SDK:API11( 4.1.0.63) -DevEco Studio 4.1(4.1.3.418)--SDK:API11( 4.1.0.56) -DevEco Studio 4.1(4.1.3.322)--SDK:API11( 4.1.0.36) -DevEco Studio 4.0(4.0.3.700)--SDK:API10( 4.0.10.15) - -HSP场景适配: - -在使用ImageKnifeComponent进行加载图片时, 提供的ImageKnifeOption配置类新增了可选参数context, 在HSP场景下需要传入正确的context, 才能保证三方库后续正确获取Resource资源。 - -在使用RquestOption进行加载图片时, 提供的RquestOption配置类新增了接口`setModuleContext(moduleCtx:common.UIAbilityContext)`, 在HSP场景下需要传入正确的context, 才能保证三方库后续正确获取Resource资源。 - -非HSP场景不影响原功能, ImageKnifeOption配置类新增的可选参数context可以不传, RquestOption配置类新增的接口可以不调用。 - -## 目录结构 - -``` -/library/src/ -- main/ets/components - - cache # 缓存相关内容 - - diskstrategy # 缓存策略 - - key # 缓存key生成策略 - - Base64.ets # Base64算法 - - CustomMap.ets # 自定义Map封装 - - DiskCacheEntry.ets # 磁盘缓存entry - - DiskLruCache.ets # 磁盘LRU缓存策略 - - FileReader.ets # 文件读取相关 - - FileUtils.ets # 文件工具类 - - LruCache.ets # 内存LRU缓存策略 - - Md5.ets # MD5算法 - - - imageknife # imageknife主要内容 - - compress # 压缩相关 - - constants # 常量相关 - - entry # 部分数据结构 - - holder # 占位图相关解析 - - interface # 接口相关 - - networkmanage # 网络相关 - - pngj # pngj相关 - - requestmanage # imageknife请求相关 - - resourcemanage # 本地资源解析相关 - - transform # 图片变换相关 - - utils # 工具类相关 - - ImageKnife.ets # imageknife门面,app持久化类 - - ImageKnifeData.ets # 数据封装 - - ImageKnifeComponent.ets # 自定义控件封装 - - ImageKnifeDrawFactory.ets # IDrawLifeCycle用户自定义实现 - - ImageKnifeOption.ets # 用户传参数封装 - - RequestOption.ets # 用户设置参数封装 - -/entry/src/ -- main/ets - - entryability - - CustomEngineKeyImpl.ets - - EntryAbility.ts - - pages # 测试page页面列表 - - basicTestFeatureAbilityPage.ets # 测试列表加载 - - basicTestFileIOPage.ets # 测试fileio - - basicTestMediaImage.ets # 测试媒体image - - basicTestResourceManagerPage.ets # 测试本地资源解析 - - compressPage.ets # 压缩页面 - - cropImagePage2.ets # 手势裁剪页面 - - frescoImageTestCasePage.ets # 测试属性动画组件切换 - - frescoRetryTestCasePage.ets # 测试ImageKnifeComponent加载失败重试 - - svgTestCasePage.ets # 测试svg解析页面 - - imageknifeTestCaseIndex.ets # 测试用例页面入口 - - index.ets # 程序入口页面 - - loadNetworkTestCasePage.ets # 网络加载测试 - - loadResourceTestCasePage.ets # 本地加载测试 - - showErrorholderTestCasePage.ets # 加载失败占位图测试 - - SignatureTestPage.ets # 自定义key测试 - - storageTestDiskLruCache.ets # 磁盘缓存测试 - - storageTestLruCache.ets # 内存缓存测试 - - testAllCacheInfoPage.ets # 所有缓存信息获取测试 - - testImageKnifeAutoHeightPage.ets # 图片高度自适应测试 - - testImageKnifeAutoWidthPage.ets # 图片宽度自适应测试 - - testImageKnifeAutoPage.ets # 图片宽高自适应测试 - - testImageKnifeOptionChangedPage.ets # 数据切换测试 - - testImageKnifeOptionChangedPage2.ets # 数据切换测试,部分变换 - - testImageKnifeOptionChangedPage3.ets # 数据切换测试,组件动画 - - testImageKnifeOptionChangedPage4.ets # 数据切换测试,内容动画 - - testImageKnifeOptionChangedPage5.ets # 数据切换测试,ImageKnifeDrawFactory封装圆角圆环边框等 - - testPreloadPage.ets # 预加载测试 - - transformPixelMapPage.ets # 所有类型变换测试 - - testSingleFrameGifPage.ets # 单帧gif加载测试 - - - OptionTestPage.ets # 图片缓存测试 - - testManyGifLoadWithPage # 测试gif加载页面 - -workers - - upngWorkerTestCase.ets # png子线程解析 - - upngWorkerDepend.ts # png子线程解析具体执行 -``` +API11 ## 贡献代码 @@ -535,49 +125,5 @@ HSP场景适配: 本项目基于 [Apache License 2.0](https://gitee.com/openharmony-tpc/ImageKnife/blob/master/LICENSE) ,请自由的享受和参与开源。 ## 遗留问题 - -1.目前只支持一种图片变换效果。 - -2.目前svg和gif动图不支持变换效果。 - -## 补充说明 -### SVG标签说明 -使用版本为(SVG)1.1,当前支持的标签列表有: -- a -- circla -- clipPath -- defs -- ellipse -- feBlend -- feColorMatrix -- feComposite -- feDiffuseLighting -- feDisplacementMap -- feDistantLight -- feFlood -- feGaussianBlur -- feImage -- feMorphology -- feOffset -- fePointLight -- feSpecularLighting -- feSpotLight -- feTurbulence -- filter -- g -- image -- line -- linearGradient -- mask -- path -- pattern -- polygon -- polyline -- radialGradient -- rect -- stop -- svg -- text -- textPath -- tspan -- use \ No newline at end of file +- reuse组件错位问题 +- 添加组件闪动问题 \ No newline at end of file diff --git a/build-profile.json5 b/build-profile.json5 index aa57008..d2d4041 100644 --- a/build-profile.json5 +++ b/build-profile.json5 @@ -1,16 +1,20 @@ { "app": { + "signingConfigs": [ + + ], "products": [ { "name": "default", "signingConfig": "default", - "compileSdkVersion": 10, - "compatibleSdkVersion": 10 + "compileSdkVersion": "4.1.0(11)", + "compatibleSdkVersion": "4.1.0(11)", + "runtimeOS": "HarmonyOS", } ], "buildModeSet": [ { - "name": "debug" + "name": "debug", }, { "name": "release" @@ -33,34 +37,6 @@ { "name": "library", "srcPath": "./library" - }, - { - "name": "gpu_transform", - "srcPath": "./gpu_transform" - }, - { - "name": "sharedlibrary", - "srcPath": "./sharedlibrary", - "targets": [ - { - "name": "default", - "applyToProducts": [ - "default" - ] - } - ] - }, - { - "name": "sharedlibrary2", - "srcPath": "./sharedlibrary2", - "targets": [ - { - "name": "default", - "applyToProducts": [ - "default" - ] - } - ] } ] } \ No newline at end of file diff --git a/entry/.gitignore b/entry/.gitignore index f8fba9f..e2713a2 100644 --- a/entry/.gitignore +++ b/entry/.gitignore @@ -1,5 +1,6 @@ /node_modules +/oh_modules /.preview /build -/oh_modules/ -/oh-package-lock.json5 +/.cxx +/.test \ No newline at end of file diff --git a/entry/build-profile.json5 b/entry/build-profile.json5 index e1fd25b..197e83c 100644 --- a/entry/build-profile.json5 +++ b/entry/build-profile.json5 @@ -1,15 +1,28 @@ { - "apiType": 'stageMode', + "apiType": "stageMode", "buildOption": { - "sourceOption": { - "workers": [ - "./src/main/ets/workers/upngWorkerTestCase.ets" - ] + "arkOptions": { + // "apPath": "./modules.ap" /* Profile used for profile-guided optimization (PGO), a compiler optimization technique to improve app runtime performance. */ } }, + "buildOptionSet": [ + { + "name": "release", + "arkOptions": { + "obfuscation": { + "ruleOptions": { + "enable": true, + "files": [ + "./obfuscation-rules.txt" + ] + } + } + } + }, + ], "targets": [ { - "name": "default", + "name": "default" }, { "name": "ohosTest", diff --git a/entry/hvigorfile.js b/entry/hvigorfile.js deleted file mode 100644 index d7720ee..0000000 --- a/entry/hvigorfile.js +++ /dev/null @@ -1,2 +0,0 @@ -// Script for compiling build behavior. It is built in the build plug-in and cannot be modified currently. -module.exports = require('@ohos/hvigor-ohos-plugin').hapTasks diff --git a/entry/hvigorfile.ts b/entry/hvigorfile.ts new file mode 100644 index 0000000..c6edcd9 --- /dev/null +++ b/entry/hvigorfile.ts @@ -0,0 +1,6 @@ +import { hapTasks } from '@ohos/hvigor-ohos-plugin'; + +export default { + system: hapTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ + plugins:[] /* Custom plugin to extend the functionality of Hvigor. */ +} diff --git a/entry/obfuscation-rules.txt b/entry/obfuscation-rules.txt new file mode 100644 index 0000000..985b2ae --- /dev/null +++ b/entry/obfuscation-rules.txt @@ -0,0 +1,18 @@ +# Define project specific obfuscation rules here. +# You can include the obfuscation configuration files in the current module's build-profile.json5. +# +# For more details, see +# https://gitee.com/openharmony/arkcompiler_ets_frontend/blob/master/arkguard/README.md + +# Obfuscation options: +# -disable-obfuscation: disable all obfuscations +# -enable-property-obfuscation: obfuscate the property names +# -enable-toplevel-obfuscation: obfuscate the names in the global scope +# -compact: remove unnecessary blank spaces and all line feeds +# -remove-log: remove all console.* statements +# -print-namecache: print the name cache that contains the mapping from the old names to new names +# -apply-namecache: reuse the given cache file + +# Keep options: +# -keep-property-name: specifies property names that you want to keep +# -keep-global-name: specifies names that you want to keep in the global scope \ No newline at end of file diff --git a/entry/oh-package-lock.json5 b/entry/oh-package-lock.json5 new file mode 100644 index 0000000..2555096 --- /dev/null +++ b/entry/oh-package-lock.json5 @@ -0,0 +1,13 @@ +{ + "lockfileVersion": 3, + "ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.", + "specifiers": { + "@ohos/imageknife@../library": "@ohos/imageknife@../library" + }, + "packages": { + "@ohos/imageknife@../library": { + "mtime": "1711870193874.5308", + "resolved": "../library" + } + } +} \ No newline at end of file diff --git a/entry/oh-package.json5 b/entry/oh-package.json5 index 113d186..62b4158 100644 --- a/entry/oh-package.json5 +++ b/entry/oh-package.json5 @@ -1,14 +1,12 @@ { - "license": "Apache License 2.0", - "devDependencies": {}, "name": "entry", - "description": "example description", - "repository": {}, - "version": "2.1.2-rc.12", + "version": "1.0.0", + "description": "Please describe the basic information.", + "main": "", + "author": "", + "license": "", "dependencies": { - "@ohos/libraryimageknife": "file:../sharedlibrary", - "@ohos/sharedlibrary2": "file:../sharedlibrary2", - "@ohos/disklrucache": "^2.0.2-rc.0", "@ohos/imageknife": "file:../library" } } + diff --git a/entry/src/main/ets/pages/model/Material.ets b/entry/src/main/ets/common/Constants.ets similarity index 70% rename from entry/src/main/ets/pages/model/Material.ets rename to entry/src/main/ets/common/Constants.ets index dc344c5..c157286 100644 --- a/entry/src/main/ets/pages/model/Material.ets +++ b/entry/src/main/ets/common/Constants.ets @@ -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 @@ -7,13 +7,11 @@ * 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, + * 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 Material{ - material_id: string =''; - thumbnail: string = ''; - name: string =''; +export default class Constants { + static readonly TAG: string = "MyImageKnifeTest: " } \ No newline at end of file diff --git a/entry/src/ohosTest/ets/testability/GlobalContext.ets b/entry/src/main/ets/common/GlobalContext.ets similarity index 84% rename from entry/src/ohosTest/ets/testability/GlobalContext.ets rename to entry/src/main/ets/common/GlobalContext.ets index 8671492..97d31a0 100644 --- a/entry/src/ohosTest/ets/testability/GlobalContext.ets +++ b/entry/src/main/ets/common/GlobalContext.ets @@ -1,13 +1,13 @@ /* * Copyright (C) 2024 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); + * 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, + * 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. @@ -20,7 +20,7 @@ export class GlobalContext { private static instance: GlobalContext; private _objects = new Map(); - public static getInstance(): GlobalContext { + public static getContext(): GlobalContext { if (!GlobalContext.instance) { GlobalContext.instance = new GlobalContext(); } diff --git a/entry/src/main/ets/entryability/CustomEngineKeyImpl.ets b/entry/src/main/ets/entryability/CustomEngineKeyImpl.ets deleted file mode 100644 index 81a6863..0000000 --- a/entry/src/main/ets/entryability/CustomEngineKeyImpl.ets +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (C) 2023 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 { EngineKeyFactories, EngineKeyInterface, RequestOption } from '@ohos/libraryimageknife' -import { ObjectKey } from '@ohos/libraryimageknife'; - -export class CustomEngineKeyImpl implements EngineKeyInterface { - redefineUrl: (loadSrc: string) => string; - addOtherInfo: string = "Version=1.0.0;" - - constructor() { - this.redefineUrl = this.urlNeedClearToken; - } - - // request只读 - generateMemoryCacheKey(loadSrc: string, size: string, transformed: string, dontAnimate: boolean, signature: ObjectKey): string { - return EngineKeyFactories.createMemoryCacheKey(loadSrc, size, transformed, dontAnimate, signature, this.redefineUrl, this.addOtherInfo); - } - - generateTransformedDiskCacheKey(loadSrc: string, size: string, transformed: string, dontAnimate: boolean, signature: ObjectKey): string { - return EngineKeyFactories.createTransformedDiskCacheKey(loadSrc, size, transformed, dontAnimate, signature, this.redefineUrl, this.addOtherInfo); - } - - generateOriginalDiskCacheKey(loadSrc: string, signature: ObjectKey): string { - return EngineKeyFactories.createOriginalDiskCacheKey(loadSrc, signature, this.redefineUrl, this.addOtherInfo); - } - - - // 需求场景: 请求图片可能 请求中存在token需要清除, 可以把输入的url清除token后作为key的一部分,这样token发生变化也能命中缓存。 - urlNeedClearToken = (url: string) => { - if (this.isHttpRequest(url)) { - return this.clearToken(url) - } else { - return url; - } - } - - isHttpRequest(loadSrc: string) { - if (typeof loadSrc == "string" && loadSrc.toLowerCase().startsWith("http")) { - return true; - } - return false; - } - - // 清除url里面中携带的token - clearToken(url: string): string { - let retUrl = url.replace(this.findTokenParam(url), "") - return retUrl; - } - - // 网络图片加载 可能因为Token问题导致缓存失效 - findTokenParam(url: string): string { - let tokenParam = ""; - let tokenKeyIndex = url.indexOf("?token=") >= 0 ? url.indexOf("?token=") : url.indexOf("&token="); - if (tokenKeyIndex != -1) { - let nextAndIndex = url.indexOf("&", tokenKeyIndex + 1); - if (nextAndIndex != -1) { - tokenParam = url.substring(tokenKeyIndex + 1, nextAndIndex + 1); - } else { - tokenParam = url.substring(tokenKeyIndex); - } - } - return tokenParam; - } -} diff --git a/entry/src/main/ets/entryability/EntryAbility.ets b/entry/src/main/ets/entryability/EntryAbility.ets index 97ad9c5..3066439 100644 --- a/entry/src/main/ets/entryability/EntryAbility.ets +++ b/entry/src/main/ets/entryability/EntryAbility.ets @@ -1,59 +1,61 @@ /* - * Copyright (C) 2023 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); + * 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, + * 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 UIAbility from '@ohos.app.ability.UIAbility'; +import AbilityConstant from '@ohos.app.ability.AbilityConstant'; import hilog from '@ohos.hilog'; +import UIAbility from '@ohos.app.ability.UIAbility'; +import Want from '@ohos.app.ability.Want'; import window from '@ohos.window'; -import { InitImageKnife, ImageKnifeGlobal, ImageKnife, ImageKnifeDrawFactory, LogUtil } from '@ohos/libraryimageknife' -import { CustomEngineKeyImpl } from './CustomEngineKeyImpl' -import abilityAccessCtrl, { Permissions } from '@ohos.abilityAccessCtrl'; -import { BusinessError } from '@ohos.base' +import { ImageKnife } from '@ohos/imageknife'; export default class EntryAbility extends UIAbility { - onWindowStageCreate(windowStage: window.WindowStage) { + onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate'); + } + + onDestroy(): void { + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onDestroy'); + } + + async onWindowStageCreate(windowStage: window.WindowStage): Promise { // Main window is created, set main page for this ability - let list: Array = ['ohos.permission.MEDIA_LOCATION', 'ohos.permission.READ_MEDIA']; - let permissionRequestResult: Object; - let atManager = abilityAccessCtrl.createAtManager(); - atManager.requestPermissionsFromUser(this.context, list, (err: BusinessError, result: Object) => { - if (err) { + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate'); - } else { - permissionRequestResult = result; + // 初始化ImageKnife的文件缓存 + await ImageKnife.getInstance().initFileCache(this.context, 256, 256 * 1024 * 1024) + windowStage.loadContent('pages/Index', (err, data) => { + if (err.code) { + hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? ''); + return; } - }) - - windowStage.loadContent('pages/index', (err: BusinessError, data: void) => { + hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. Data: %{public}s', JSON.stringify(data) ?? ''); }); + } - InitImageKnife.init(this.context); + onWindowStageDestroy(): void { + // Main window is destroyed, release UI related resources + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageDestroy'); + } - let imageKnife: ImageKnife | undefined = ImageKnifeGlobal.getInstance().getImageKnife() - if (imageKnife != undefined) { - // 全局配置网络加载进度条 - imageKnife - .setDefaultLifeCycle(ImageKnifeDrawFactory.createProgressLifeCycle("#10a5ff", 0.5)) - // 全局配置缓存key - imageKnife.setEngineKeyImpl(new CustomEngineKeyImpl()) - // 设置全局内存缓存大小张数 - imageKnife.setLruCacheSize(100, 100 * 1204 * 1024) - // 全局配置请求头 - imageKnife.addHeader('refer', "http://1.94.37.200:7070/AntiTheftChain/downloadImage"); - imageKnife.deleteHeader('refer'); - } - // 开启ImageKnife所有级别日志开关 - LogUtil.mLogLevel = LogUtil.ALL + onForeground(): void { + // Ability has brought to foreground + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onForeground'); + } + + onBackground(): void { + // Ability has back to background + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onBackground'); } } diff --git a/entry/src/main/ets/pages/CacheRuleChangedPage.ets b/entry/src/main/ets/pages/CacheRuleChangedPage.ets deleted file mode 100644 index ce1ef94..0000000 --- a/entry/src/main/ets/pages/CacheRuleChangedPage.ets +++ /dev/null @@ -1,104 +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, - ImageKnifeOption, - RotateImageTransformation, - RoundedCornersTransformation -} from '@ohos/libraryimageknife' - -@Entry -@Component -struct CacheRuleChangedPage { - @State progresshint: string = "输出加载百分比回调信息" - @State imageKnifeOption1: ImageKnifeOption = - { - loadSrc: "https://thirdwx.qlogo.cn/mmopen/vi_32/DYAIOgq83ericA1Mv66TwicuYOtbDMBcUhv1aa9RJBeAn9uURfcZD0AUGrJebAn1g2AjN0vb2E1XTET7fTuLBNmA/132", - - placeholderSrc: $r('app.media.icon_loading'), - errorholderSrc: $r('app.media.icon_failed'), - displayProgress: true - }; - @State ImageKnifeOption: ImageKnifeOption = - { - loadSrc: "https://hbimg.huabanimg.com/0ef60041445edcfd6b38d20e19024b2cd9281dcc3525a4-Vy8fYO_fw658/format/webp", - - placeholderSrc: $r('app.media.icon_loading'), - errorholderSrc: $r('app.media.icon_failed'), - displayProgress: true - }; - @State imageKnifeOption3: ImageKnifeOption = - { - loadSrc: "https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp", - - placeholderSrc: $r('app.media.icon_loading'), - errorholderSrc: $r('app.media.icon_failed'), - displayProgress: true - }; - @State imageKnifeOption4: ImageKnifeOption = - { - loadSrc: "https://hbimg.huabanimg.com/cc6af25f8d782d3cf3122bef4e61571378271145735e9-vEVggB", - - placeholderSrc: $r('app.media.icon_loading'), - errorholderSrc: $r('app.media.icon_failed'), - displayProgress: true, - }; - @State imageKnifeOption5: ImageKnifeOption = - { - loadSrc: "https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp?mama=sdafsfasdfsdfsdaf&baba=sdfsafsafsd", - - placeholderSrc: $r('app.media.icon_loading'), - errorholderSrc: $r('app.media.icon_failed'), - displayProgress: true, - }; - - build() { - Scroll() { - Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { - - Text('下图默认加载网络图片不带?token=').margin({ top: 20 }) - Button('点击加载网络图片?token=').margin({ top: 5 }).onClick(() => { - - this.imageKnifeOption4 = { - loadSrc: "https://hbimg.huabanimg.com/cc6af25f8d782d3cf3122bef4e61571378271145735e9-vEVggB?token=fsdafsfsafsafsdaf111111", - placeholderSrc: $r('app.media.icon_loading'), - errorholderSrc: $r('app.media.icon_failed'), - displayProgress: true, - } - }) - - ImageKnifeComponent({ imageKnifeOption: this.imageKnifeOption4 }) - .width(300) - .height(300) - - Text('下图默认加载网络图片不带&token=').margin({ top: 20 }) - - Button('点击加载网络图片&token=').margin({ top: 5 }).onClick(() => { - this.imageKnifeOption5 = { - loadSrc: "https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp?mama=sdafsfasdfsdfsdaf&token=fsdafsfsafsafsdaf111111&baba=sdfsafsafsd", - placeholderSrc: $r('app.media.icon_loading'), - errorholderSrc: $r('app.media.icon_failed'), - displayProgress: true, - } - }) - ImageKnifeComponent({ imageKnifeOption: this.imageKnifeOption5 }) - .width(300) - .height(300) - } - } - .width('100%') - .height('100%') - } -} diff --git a/entry/src/main/ets/pages/ListPage.ets b/entry/src/main/ets/pages/ListPage.ets new file mode 100644 index 0000000..d74fbcf --- /dev/null +++ b/entry/src/main/ets/pages/ListPage.ets @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { ImageKnifeComponent, ImageKnifeOption } from '@ohos/imageknife'; + +@Entry +@Component +struct ListPage { + + private datas: string[] = [] + @State ImageKnifeOption: ImageKnifeOption = { loadSrc: $r('app.media.startIcon')} + + + aboutToAppear(): void { + for (let i = 0; i < 1000; i++) { + this.datas.push(i.toString()) + } + } + + build() { + Row() { + List({ space: 10 }) { + ForEach(this.datas, (item: string) => { + ImageKnifeComponent({ ImageKnifeOption: this.ImageKnifeOption }).height(200).width(200) + }, (item: string) => item) + } + .width('100%') + } + .height('100%') + } +} \ No newline at end of file diff --git a/entry/src/main/ets/pages/LongImagePage.ets b/entry/src/main/ets/pages/LongImagePage.ets new file mode 100644 index 0000000..7ad15c1 --- /dev/null +++ b/entry/src/main/ets/pages/LongImagePage.ets @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { ImageKnifeComponent } from '@ohos/imageknife' + +@Entry +@Component +struct LongImagePage { + + build() { + Scroll() { + + // Image("https://wx2.sinaimg.cn/mw690/006HyQKGgy1hnqp08dw09j30u04twu0x.jpg").objectFit(ImageFit.Auto).height(300) + + // Image($r("app.media.aaa")).objectFit(ImageFit.Auto).width(200) + ImageKnifeComponent({ + ImageKnifeOption: { + loadSrc:"https://wx2.sinaimg.cn/mw690/006HyQKGgy1hnqp08dw09j30u04twu0x.jpg", + //src:$r("app.media.aaa"), + // placeholderSrc: $r("app.media.loading"), + // errorholderSrc: $r("app.media.app_icon"), + objectFit: ImageFit.Auto + } + }) + } + .height('100%') .width('100%') + } +} \ No newline at end of file diff --git a/entry/src/main/ets/pages/OptionTestPage.ets b/entry/src/main/ets/pages/OptionTestPage.ets deleted file mode 100644 index 6f7f6e2..0000000 --- a/entry/src/main/ets/pages/OptionTestPage.ets +++ /dev/null @@ -1,79 +0,0 @@ -/* - * 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 { ImageKnifeComponent, ImageKnifeOption,NONE,DiskStrategy } from '@ohos/libraryimageknife' - -@Entry -@Component -struct OptionTestPage { - @State imageKnifeOption1: ImageKnifeOption = - { - loadSrc: $r('app.media.icon'), - placeholderSrc: $r('app.media.icon_loading'), - errorholderSrc: $r('app.media.icon_failed'), - }; - @State imageKnifeOption2: ImageKnifeOption = - { - loadSrc: $r('app.media.icon'), - 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("示例加载图片不进行缓存").fontSize(15) - Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { - Button("加载") - .onClick(() => { - let setting:DiskStrategy = new NONE(); - this.imageKnifeOption1 = { - loadSrc: 'https://img-blog.csdn.net/20140514114029140', - placeholderSrc: $r('app.media.icon_loading'), - errorholderSrc: $r('app.media.icon_failed'), - onlyRetrieveFromCache: false, - isCacheable: false, - strategy: setting - } - }).margin({ top: 5, left: 3 }) - ImageKnifeComponent({ imageKnifeOption: this.imageKnifeOption1 }).width(300).height(300) - }.width('100%').backgroundColor(Color.Pink) - - Text("示例:加载图片进行缓存").fontSize(15) - Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { - Button("加载") - .onClick(() => { - let setting2:DiskStrategy = new NONE(); - this.imageKnifeOption2 = { - loadSrc: 'https://img-blog.csdn.net/20140514114029140', - placeholderSrc: $r('app.media.icon_loading'), - errorholderSrc: $r('app.media.icon_failed'), - onlyRetrieveFromCache: true, - isCacheable: true, - strategy: setting2 - } - }).margin({ top: 5, left: 3 }) - ImageKnifeComponent({ imageKnifeOption: this.imageKnifeOption2 }).width(300).height(300) - }.width('100%').backgroundColor(Color.Pink) - - - } - - }.width('100%') - .height('100%') - - } -} \ No newline at end of file diff --git a/entry/src/main/ets/pages/RequestOptionLoadImage.ets b/entry/src/main/ets/pages/RequestOptionLoadImage.ets deleted file mode 100644 index 66ce87b..0000000 --- a/entry/src/main/ets/pages/RequestOptionLoadImage.ets +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright (C) 2024 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import image from '@ohos.multimedia.image' -import { - ImageKnifeData, - RequestOption, - Size, - ImageKnife, - ImageKnifeGlobal, - ImageKnifeComponent, - ObjectKey -} from '@ohos/libraryimageknife' -import { BusinessError } from '@ohos.base' - -const TAG = "TEST-" -let timeId = -1 - -@Entry -@Component -struct RequestOptionLoadImage { - @State pixelMap: PixelMap | undefined = undefined - - load(src: string | image.PixelMap | Resource) { - clearTimeout(timeId) - let request = new RequestOption() - //*requestOption调用* - request.addHeader('refer', 'http://1.94.37.200:7070/AntiTheftChain/downloadImage'); - //通过时间戳去清除缓存 - request.signature = new ObjectKey(new Date().getTime().toString()) - request.load(src) - .addListener({ callback: (err: BusinessError | string, data: ImageKnifeData) => { - if (data.isPixelMap()) { - if (data.drawPixelMap) { - let pixelmap = data.drawPixelMap.imagePixelMap - if (pixelmap) { - this.pixelMap = pixelmap - } - } - } - if (data.isGIFFrame()) { - let index: number = 0 - if (data.drawGIFFrame) { - if (data.drawGIFFrame.imageGIFFrames) { - let renderGif = () => { - if (data.drawGIFFrame) { - if (data.drawGIFFrame.imageGIFFrames) { - let pixelmap = data.drawGIFFrame.imageGIFFrames[index].drawPixelMap - let delay = data.drawGIFFrame.imageGIFFrames[index].delay - if (pixelmap) { - this.pixelMap = pixelmap - } - index++; - if (index == data.drawGIFFrame.imageGIFFrames.length - 1) { - index = 0 - } - timeId = setTimeout(renderGif, data!.drawGIFFrame!.imageGIFFrames![index].delay) - } - } - } - renderGif() - } - } - } - if (err) { - console.log(TAG + "error:" + JSON.stringify(err)); - } - return false - } - }) - let compSize: Size = { - width: 300, - height: 300 - } - request.setImageViewSize(compSize) - let imageknife: ImageKnife | undefined = ImageKnifeGlobal.getInstance().getImageKnife() - if (imageknife != undefined) { - imageknife.call(request) - } - } - - build() { - Scroll() { - Column() { - Text("RequestOption加载图片").fontSize(25) - Button("加载网络gif").onClick(() => { - this.load("https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658") - }) - Button("加载静态图").onClick(() => { - this.load($r('app.media.pngSample')) - }) - ImageKnifeComponent({ imageKnifeOption: { - loadSrc: this.pixelMap as image.PixelMap - } }).width(300).height(300).borderWidth(3) - } - } - } -} \ No newline at end of file diff --git a/entry/src/main/ets/pages/SignatureTestPage.ets b/entry/src/main/ets/pages/SignatureTestPage.ets deleted file mode 100644 index 5d26d49..0000000 --- a/entry/src/main/ets/pages/SignatureTestPage.ets +++ /dev/null @@ -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 { ImageKnifeComponent, ImageKnifeOption, NONE, DiskStrategy } from '@ohos/libraryimageknife' -import { ObjectKey } from '@ohos/libraryimageknife'; - -@Entry -@Component -struct SignatureTestPage { - @State imageKnifeOption1: ImageKnifeOption = - { - loadSrc: $r('app.media.icon'), - placeholderSrc: $r('app.media.icon_loading'), - errorholderSrc: $r('app.media.icon_failed'), - }; - @State imageKnifeOption2: ImageKnifeOption = - { - loadSrc: $r('app.media.icon'), - 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("Signature固定为 1").fontSize(15) - Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { - Button("加载") - .onClick(() => { - this.imageKnifeOption1 = { - loadSrc: 'https://img-blog.csdn.net/20140514114029140', - placeholderSrc: $r('app.media.icon_loading'), - errorholderSrc: $r('app.media.icon_failed'), - signature: new ObjectKey("1") - } - }).margin({ top: 5, left: 3 }) - ImageKnifeComponent({ imageKnifeOption: this.imageKnifeOption1 }).width(300).height(300) - }.width('100%').backgroundColor(Color.Pink) - - Text("设置Signature,每次为时间戳").fontSize(15) - Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { - Button("加载") - .onClick(() => { - this.imageKnifeOption2 = { - loadSrc: 'https://img-blog.csdn.net/20140514114029140', - placeholderSrc: $r('app.media.icon_loading'), - errorholderSrc: $r('app.media.icon_failed'), - signature: new ObjectKey(new Date().getTime().toString()) - } - }).margin({ top: 5, left: 3 }) - ImageKnifeComponent({ imageKnifeOption: this.imageKnifeOption2 }).width(300).height(300) - }.width('100%').backgroundColor(Color.Pink) - } - - }.width('100%') - .height('100%') - - } - - aboutToAppear() { - console.log("唯一标识页面:" + new ObjectKey(new Date().getTime().toString()).getKey()) - - } -} \ No newline at end of file diff --git a/entry/src/main/ets/pages/SingleImage.ets b/entry/src/main/ets/pages/SingleImage.ets new file mode 100644 index 0000000..5521c0d --- /dev/null +++ b/entry/src/main/ets/pages/SingleImage.ets @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { ImageKnifeComponent } from '@ohos/imageknife'; +import fs from '@ohos.file.fs'; + +@Entry +@Component +struct SingleImage { + scroller: Scroller = new Scroller; + localFile: string = getContext(this).filesDir + "/icon.png" + + aboutToAppear(): void { + // 拷贝本地文件 + let icon: Uint8Array = getContext(this).resourceManager.getMediaContentSync($r("app.media.startIcon")); + let file = fs.openSync(this.localFile, fs.OpenMode.CREATE | fs.OpenMode.READ_WRITE); + fs.writeSync(file.fd, icon.buffer); + fs.fsyncSync(file.fd); + fs.closeSync(file); + } + + build() { + Scroll(this.scroller) { + Column() { + Text("本地资源图片") + .fontSize(30) + .fontWeight(FontWeight.Bold) + ImageKnifeComponent({ + ImageKnifeOption: { + loadSrc: $r("app.media.app_icon"), + placeholderSrc: $r("app.media.loading"), + errorholderSrc: $r("app.media.app_icon"), + objectFit: ImageFit.Contain + } + }).width(100).height(100) + Text("本地context files下文件") + .fontSize(30) + .fontWeight(FontWeight.Bold) + ImageKnifeComponent({ + ImageKnifeOption: { + loadSrc: this.localFile, + placeholderSrc: $r("app.media.loading"), + errorholderSrc: $r("app.media.app_icon"), + objectFit: ImageFit.Contain + } + }).width(100).height(100) + Text("网络图片") + .fontSize(30) + .fontWeight(FontWeight.Bold) + ImageKnifeComponent({ + ImageKnifeOption: { + loadSrc:"https://www.openharmony.cn/_nuxt/img/logo.dcf95b3.png", + placeholderSrc: $r("app.media.loading"), + errorholderSrc: $r("app.media.app_icon"), + objectFit: ImageFit.Contain, + progressListener:(progress:number)=>{console.info("ImageKnife:: call back progress = " + progress)} + } + }).width(100).height(100) + Text("自定义下载") + .fontSize(30) + .fontWeight(FontWeight.Bold) + ImageKnifeComponent({ + 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 + } + }).width(100).height(100) + } + .width('100%') + } + .height('100%') + } +} + +// 自定义下载方法 +@Concurrent +async function custom(context: Context, src: string | PixelMap | Resource): Promise { + console.info("ImageKnife:: custom download:" + src) + // 举例写死从本地文件读取,也可以自己请求网络图片 + return context.resourceManager.getMediaContentSync($r("app.media.startIcon").id).buffer as ArrayBuffer +} + diff --git a/entry/src/main/ets/pages/TransformPage.ets b/entry/src/main/ets/pages/TransformPage.ets new file mode 100644 index 0000000..bda54b2 --- /dev/null +++ b/entry/src/main/ets/pages/TransformPage.ets @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { ImageKnifeComponent, ImageKnifeOption } from "@ohos/imageknife" +import matrix4 from '@ohos.matrix4' + + +@Entry +@Component +struct TransformPage { + private custom_scale:number = 1 + @State matrix1:object = matrix4.identity().scale({ x: 1, y: 1 }) + @State ImageKnifeOption: ImageKnifeOption = { + loadSrc: $r("app.media.rabbit"), + placeholderSrc: $r("app.media.loading"), + errorholderSrc: $r("app.media.app_icon"), + objectFit: ImageFit.Contain, + border: { radius: 50 } + } + + build() { + Column() { + 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(()=>{ + this.custom_scale = this.custom_scale * 2 + this.matrix1 = matrix4.identity().scale({ x: this.custom_scale, y: this.custom_scale }) + }) + + Button("缩小").onClick(()=>{ + this.custom_scale = this.custom_scale / 2 + this.matrix1 = matrix4.identity().scale({ x: this.custom_scale, y: this.custom_scale }) + }) + } + .width('100%') + + .height('100%') + } +} \ No newline at end of file diff --git a/entry/src/main/ets/pages/basicTestFeatureAbilityPage.ets b/entry/src/main/ets/pages/basicTestFeatureAbilityPage.ets deleted file mode 100644 index cc787cc..0000000 --- a/entry/src/main/ets/pages/basicTestFeatureAbilityPage.ets +++ /dev/null @@ -1,82 +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,ImageKnifeComponent} from '@ohos/libraryimageknife' - -@Entry -@Component -struct BasicTestFeatureAbilityPage { - @Watch("watchPathChange") @State filePath: string = "查看featureAbility路径"; - - watchPathChange() { - console.log("watchPathChange") - } - urls:string[]=[ - "http://e.hiphotos.baidu.com/image/pic/item/a1ec08fa513d2697e542494057fbb2fb4316d81e.jpg", - "http://c.hiphotos.baidu.com/image/pic/item/30adcbef76094b36de8a2fe5a1cc7cd98d109d99.jpg", - "http://h.hiphotos.baidu.com/image/pic/item/7c1ed21b0ef41bd5f2c2a9e953da81cb39db3d1d.jpg", - "http://g.hiphotos.baidu.com/image/pic/item/55e736d12f2eb938d5277fd5d0628535e5dd6f4a.jpg", - "http://e.hiphotos.baidu.com/image/pic/item/4e4a20a4462309f7e41f5cfe760e0cf3d6cad6ee.jpg", - "http://b.hiphotos.baidu.com/image/pic/item/9d82d158ccbf6c81b94575cfb93eb13533fa40a2.jpg", - "http://e.hiphotos.baidu.com/image/pic/item/4bed2e738bd4b31c1badd5a685d6277f9e2ff81e.jpg", - "http://g.hiphotos.baidu.com/image/pic/item/0d338744ebf81a4c87a3add4d52a6059252da61e.jpg", - "http://a.hiphotos.baidu.com/image/pic/item/f2deb48f8c5494ee5080c8142ff5e0fe99257e19.jpg", - "http://f.hiphotos.baidu.com/image/pic/item/4034970a304e251f503521f5a586c9177e3e53f9.jpg", - "http://b.hiphotos.baidu.com/image/pic/item/279759ee3d6d55fbb3586c0168224f4a20a4dd7e.jpg", - "http://img2.xkhouse.com/bbs/hfhouse/data/attachment/forum/corebbs/2009-11/2009113011534566298.jpg", - "http://a.hiphotos.baidu.com/image/pic/item/e824b899a9014c087eb617650e7b02087af4f464.jpg", - "http://c.hiphotos.baidu.com/image/pic/item/9c16fdfaaf51f3de1e296fa390eef01f3b29795a.jpg", - "http://d.hiphotos.baidu.com/image/pic/item/b58f8c5494eef01f119945cbe2fe9925bc317d2a.jpg", - "http://h.hiphotos.baidu.com/image/pic/item/902397dda144ad340668b847d4a20cf430ad851e.jpg", - "http://b.hiphotos.baidu.com/image/pic/item/359b033b5bb5c9ea5c0e3c23d139b6003bf3b374.jpg", - "http://a.hiphotos.baidu.com/image/pic/item/8d5494eef01f3a292d2472199d25bc315d607c7c.jpg", - "http://b.hiphotos.baidu.com/image/pic/item/e824b899a9014c08878b2c4c0e7b02087af4f4a3.jpg", - "http://g.hiphotos.baidu.com/image/pic/item/6d81800a19d8bc3e770bd00d868ba61ea9d345f2.jpg", - ] - - @State options:Array = new Array - - aboutToAppear(){ - this.options = this.urls.map((url:string)=>{ - return { - loadSrc:url - } - }) - console.log('this.options length ='+this.options.length) - } - - build() { - Stack({ alignContent: Alignment.TopStart }) { - Column() { - List({ space: 20, initialIndex: 0 }) { - ForEach(this.options, (item:ImageKnifeOption) => { - ListItem() { - ImageKnifeComponent({imageKnifeOption:item}).width(300).height(300) - } - }, (item:ImageKnifeOption )=> item.loadSrc as string) - } - .listDirection(Axis.Vertical) // 排列方向 - .divider({ strokeWidth: 2, color: 0xFFFFFF, startMargin: 20, endMargin: 20 }) // 每行之间的分界线 - .edgeEffect(EdgeEffect.None) // 滑动到边缘无效果 - .chainAnimation(false) // 联动特效关闭 - .onScrollIndex((firstIndex: number, lastIndex: number) => { - console.info('first' + firstIndex) - console.info('last' + lastIndex) - }) - - }.width('100%') - - }.width('100%').height('100%').backgroundColor(0xDCDCDC).padding({ top: 5 }) - } -} diff --git a/entry/src/main/ets/pages/basicTestFileIOPage.ets b/entry/src/main/ets/pages/basicTestFileIOPage.ets deleted file mode 100644 index eb987e2..0000000 --- a/entry/src/main/ets/pages/basicTestFileIOPage.ets +++ /dev/null @@ -1,161 +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 { FileUtils, ImageKnifeGlobal} from '@ohos/libraryimageknife' -import resourceManager from '@ohos.resourceManager'; -import { BusinessError } from '@ohos.base' -import common from '@ohos.app.ability.common'; -@Entry -@Component -struct basicTestFileIOPage { - @State filePath: string = '查看featureAbility路径'; - appFilePath = ''; - appCachePath = ''; - @State imageHint: string = '文字提醒1' - @State imageHint2: string = '文字提醒2' - @State imageFile: string = '' - - @State imageRes: Resource = $r('app.media.pngSample') - @State imagePixelMap?: PixelMap = undefined - @State normalPixelMap: boolean = false; - @State normalResource: boolean = false; - - watchPathChange() { - console.log('watchPathChange'); - } - - build() { - Scroll() { - Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { - Text(this.filePath).fontSize(20) - Button('featureAbility.getContext().getFilesDir()') - .margin({ top: 10 }) - .onClick(() => { - - let data:string = (ImageKnifeGlobal.getInstance().getHapContext() as common.UIAbilityContext).filesDir as string; - console.log('ImageKnife filesPath = ' + data) - this.filePath = data - this.appFilePath = data; - - }) - Button('featureAbility.getContext().getCacheDir()') - .margin({ top: 10 }) - .onClick(() => { - - let data:string = (ImageKnifeGlobal.getInstance().getHapContext() as common.UIAbilityContext).cacheDir as string; - console.log('ImageKnife cachesPath = ' + data) - this.filePath = data - this.appFilePath = data; - - }) - Text(this.imageHint) - Button('files目录创建Folder1和Folder2 验证statSync mkdirSync') - .margin({ top: 10 }) - .onClick(() => { - if(this.appFilePath == '' || this.appFilePath == null){ - this.imageHint = 'appFilePath未取到值,请按顺序从上往下,从左往右依次测试' - return - } - console.log('files目录创建Folder1和Folder2 验证statSync mkdirSync') - try { - FileUtils.getInstance() - .createFolder(this.appFilePath + '/Folder1'); - FileUtils.getInstance() - .createFolder(this.appFilePath + '/Folder2'); - } catch (e) { - console.log('appFilePath未取到值,请按顺序从上往下,从左往右依次测试"'+JSON.stringify(e)); - } - }) - Button('将media资源存入Folder1 验证writeSync mkdirSync createStreamSync') - .margin({ top: 10 }) - .onClick(() => { - console.log('将media资源存入Folder1 验证writeSync mkdirSync createStreamSync') - if(this.appFilePath == '' || this.appFilePath == null){ - this.appFilePath = 'appFilePath未取到值,请按顺序从上往下,从左往右依次测试' - return - } - ((ImageKnifeGlobal.getInstance().getHapContext() as common.UIAbilityContext).resourceManager as resourceManager.ResourceManager) - .getMediaContent($r('app.media.gifSample').id) - .then(data => { - console.log('result.getMedia') - console.log('basicTestFileIOPage - 本地加载资源 解析后数据data length= ' + data.byteLength) - let arrayBuffer = this.typedArrayToBuffer(data); - FileUtils.getInstance().writeFile(this.appFilePath + '/Folder1/jpgSample.gif', arrayBuffer) - this.imageFile = 'file://' + this.appFilePath + '/Folder1/jpgSample.gif' - console.log('Folder1 imaeFile =' + this.imageFile) - }) - .catch((err:BusinessError) => { - console.log('basicTestFileIOPage - 本地加载资源err' + JSON.stringify(err as BusinessError)); - }) - }) - Text(this.imageHint2) - Button('copy:Folder1至Folder2, 验证copyFileSync') - .margin({ top: 10 }) - .onClick(() => { - console.log('copy:Folder1至Folder2, 验证copyFileSync') - if(this.appFilePath == '' || this.appFilePath == null){ - this.imageHint2 = 'appFilePath未取到值,请按顺序从上往下,从左往右依次测试' - return - } - try { - let filePath1 = this.appFilePath + '/Folder1/jpgSample.gif'; - let filePath2 = this.appFilePath + '/Folder2/jpgSample.gif'; - FileUtils.getInstance().createFolder(this.appFilePath + '/Folder1') - FileUtils.getInstance().createFolder(this.appFilePath + '/Folder2') - FileUtils.getInstance().copyFile(filePath1, filePath2); - this.imageFile = 'file://' + this.appFilePath + '/Folder2/jpgSample.gif' - console.log('Folder2 imaeFile =' + this.imageFile) - } catch (e) { - console.log('appFilePath未取到值,请按顺序从上往下,从左往右依次测试:'+JSON.stringify(e)) - } - - }) - Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { - Button('显示空PixelMap') - .margin({ left: 10 }) - .onClick(() => { - this.normalPixelMap = true; - this.normalResource = false; - }) - Button('显示RES') - .margin({ left: 10 }) - .onClick(() => { - this.normalPixelMap = false; - this.normalResource = true; - }) - Button('显示String') - .margin({ left: 10 }) - .onClick(() => { - this.normalPixelMap = false; - this.normalResource = false; - }) - } - - - Image(this.normalPixelMap ? this.imagePixelMap : (this.normalResource ? this.imageRes : this.imageFile)) - .width(200) - .height(200) - .backgroundColor(Color.Pink) - } - .width('100%') - .height('100%') - } - - } - - typedArrayToBuffer(array: Uint8Array): ArrayBuffer { - return array.buffer.slice(array.byteOffset, array.byteLength + array.byteOffset) - } -} diff --git a/entry/src/main/ets/pages/basicTestMediaImage.ets b/entry/src/main/ets/pages/basicTestMediaImage.ets deleted file mode 100644 index e448f79..0000000 --- a/entry/src/main/ets/pages/basicTestMediaImage.ets +++ /dev/null @@ -1,129 +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 featureAbility from '@ohos.ability.featureAbility'; -import { FileUtils } from '@ohos/libraryimageknife' -import { FileTypeUtil } from '@ohos/libraryimageknife' -import resourceManager from '@ohos.resourceManager'; -import { Base64 } from '@ohos/libraryimageknife' -import { ParseImageUtil } from '@ohos/libraryimageknife' -import { ImageKnifeGlobal } from '@ohos/libraryimageknife' -import { BusinessError } from '@ohos.base' -import common from '@ohos.app.ability.common'; -@Entry -@Component -struct BasicTestMediaImage { - @State imagePixelMap?: PixelMap = undefined; - - build() { - Scroll() { - Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { - Flex({ direction: FlexDirection.Row }) { - Button('本地资源jpg') - .onClick(() => { - ((ImageKnifeGlobal.getInstance().getHapContext() as common.UIAbilityContext).resourceManager as resourceManager.ResourceManager) - .getMediaContent($r('app.media.jpgSample').id) - .then(data => { - let arrayBuffer = this.typedArrayToBuffer(data); - let parseImageUtil = new ParseImageUtil(); - parseImageUtil.parseImage(arrayBuffer, (pxielmap) => { - this.imagePixelMap = pxielmap; - }, (err:BusinessError|string|undefined) => { - }) - }) - .catch((err:BusinessError) => { - console.log('basicTestMediaImage - 本地加载资源err' + JSON.stringify(err)); - }) - }).margin({ left: 15 }).backgroundColor(Color.Blue) - Button('本地资源png') - .onClick(() => { - ((ImageKnifeGlobal.getInstance().getHapContext() as common.UIAbilityContext).resourceManager as resourceManager.ResourceManager) - .getMediaContent($r('app.media.pngSample').id) - .then(data => { - let arrayBuffer = this.typedArrayToBuffer(data); - let parseImageUtil = new ParseImageUtil(); - parseImageUtil.parseImage(arrayBuffer, (pxielmap) => { - this.imagePixelMap = pxielmap; - },(err:BusinessError|string|undefined) => { - }) - }) - .catch((err:BusinessError) => { - console.log('basicTestMediaImage - 本地加载资源err' + JSON.stringify(err)); - }) - }).margin({ left: 15 }).backgroundColor(Color.Blue) - Button('本地资源bmp') - .onClick(() => { - ((ImageKnifeGlobal.getInstance().getHapContext() as common.UIAbilityContext).resourceManager as resourceManager.ResourceManager) - .getMediaContent($r('app.media.bmpSample').id) - .then(data => { - let arrayBuffer = this.typedArrayToBuffer(data); - let parseImageUtil = new ParseImageUtil(); - parseImageUtil.parseImage(arrayBuffer, (pxielmap) => { - this.imagePixelMap = pxielmap; - }, (err:BusinessError|string|undefined) => { - }) - }) - .catch((err:BusinessError) => { - console.log('basicTestMediaImage - 本地加载资源err' + JSON.stringify(err)); - }) - }).margin({ left: 15 }).backgroundColor(Color.Blue) - Button('本地资源webp') - .onClick(() => { - ((ImageKnifeGlobal.getInstance().getHapContext() as common.UIAbilityContext).resourceManager as resourceManager.ResourceManager) - .getMediaContent($r('app.media.jpgSample').id) - .then(data => { - let arrayBuffer = this.typedArrayToBuffer(data); - let parseImageUtil = new ParseImageUtil(); - parseImageUtil.parseImage(arrayBuffer, (pxielmap) => { - this.imagePixelMap = pxielmap; - }, (err:BusinessError|string|undefined) => { - }) - }) - .catch((err:BusinessError) => { - console.log('basicTestMediaImage - 本地加载资源err' + JSON.stringify(err)); - }) - }).margin({ left: 15 }).backgroundColor(Color.Blue) - Button('本地资源gif') - .onClick(() => { - ((ImageKnifeGlobal.getInstance().getHapContext() as common.UIAbilityContext).resourceManager as resourceManager.ResourceManager) - .getMediaContent($r('app.media.gifSample').id) - .then(data => { - let arrayBuffer = this.typedArrayToBuffer(data); - let parseImageUtil = new ParseImageUtil(); - parseImageUtil.parseImage(arrayBuffer, (pxielmap) => { - this.imagePixelMap = pxielmap; - }, (err:BusinessError|string|undefined) => { - }) - }) - .catch((err:BusinessError) => { - console.log('basicTestMediaImage - 本地加载资源err' + JSON.stringify(err)); - }) - }).margin({ left: 15 }).backgroundColor(Color.Blue) - } - .margin({ top: 15 }) - - Image(this.imagePixelMap) - .width(300) - .height(300) - .backgroundColor(Color.Pink) - } - } - .width('100%') - .height('100%') - } - - typedArrayToBuffer(array: Uint8Array): ArrayBuffer { - return array.buffer.slice(array.byteOffset, array.byteLength + array.byteOffset) - } -} diff --git a/entry/src/main/ets/pages/basicTestResourceManagerPage.ets b/entry/src/main/ets/pages/basicTestResourceManagerPage.ets deleted file mode 100644 index 95de8fd..0000000 --- a/entry/src/main/ets/pages/basicTestResourceManagerPage.ets +++ /dev/null @@ -1,86 +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 featureAbility from '@ohos.ability.featureAbility'; -import {FileUtils} from '@ohos/libraryimageknife' -import {FileTypeUtil} from '@ohos/libraryimageknife' -import resourceManager from '@ohos.resourceManager'; -import {Base64} from '@ohos/libraryimageknife' -import {ImageKnifeGlobal} from '@ohos/libraryimageknife' -import { BusinessError } from '@ohos.base' -import common from '@ohos.app.ability.common'; -@Entry -@Component -struct BasicTestResourceManagerPage { - @State fileTypeStr: string = '解析后图片类型'; - - build() { - Scroll() { - Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { - Text(this.fileTypeStr).fontSize(20) - .width(300).height(200).backgroundColor(Color.Pink) - Button('getMedia解析一张jpg图片') - .margin({ top: 10 }) - .onClick(() => { - ((ImageKnifeGlobal.getInstance().getHapContext() as common.UIAbilityContext).resourceManager as resourceManager.ResourceManager) - .getMediaContent($r('app.media.jpgSample') - .id) - .then(data => { - console.log('basicTestFileIOPage - 本地加载资源 解析后数据data = ' + data) - let arrayBuffer = this.typedArrayToBuffer(data); - let filetypeUtil = new FileTypeUtil(); - let fileType = filetypeUtil.getFileType(arrayBuffer); - if(fileType != null) { - this.fileTypeStr = fileType; - } - }) - .catch((err:BusinessError) => { - console.log('basicTestFileIOPage - 本地加载资源err' + JSON.stringify(err)); - }) - }) - Button('getMediaBase64解析一张png图片') - .margin({ top: 10 }) - .onClick(() => { - ((ImageKnifeGlobal.getInstance().getHapContext() as common.UIAbilityContext).resourceManager as resourceManager.ResourceManager) - .getMediaContentBase64($r('app.media.pngSample') - .id) - .then(data => { - console.log('ParseResClientBase64 - 本地加载资源 解析后数据data') - let matchReg = ';base64,'; - let firstIndex = data.indexOf(matchReg); - data = data.substring(firstIndex + matchReg.length, data.length) - console.log('ParseResClientBase64 - 本地加载资源 解析后数据剔除非必要数据后data= ' + data) - let arrayBuffer = Base64.getInstance() - .decode(data); - let filetypeUtil = new FileTypeUtil(); - let fileType = filetypeUtil.getFileType(arrayBuffer); - if(fileType != null) { - this.fileTypeStr = fileType; - } - }) - .catch((err:BusinessError) => { - console.log('basicTestFileIOPage - 本地加载资源err' + JSON.stringify(err)); - }) - }) - - } - } - .width('100%') - .height('100%') - } - - typedArrayToBuffer(array: Uint8Array): ArrayBuffer { - return array.buffer.slice(array.byteOffset, array.byteLength + array.byteOffset) - } -} diff --git a/entry/src/main/ets/pages/compressPage.ets b/entry/src/main/ets/pages/compressPage.ets deleted file mode 100644 index 578840a..0000000 --- a/entry/src/main/ets/pages/compressPage.ets +++ /dev/null @@ -1,152 +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 {ImageKnife} from '@ohos/libraryimageknife' -import {OnRenameListener} from '@ohos/libraryimageknife' -import {OnCompressListener} from '@ohos/libraryimageknife' -import {ImageKnifeGlobal} from '@ohos/libraryimageknife' - -@Entry -@Component -struct CompressPage { - @State mRPixelMap?: PixelMap = undefined; - @State mFPixelMap?: PixelMap = undefined; - @State mResultText: string= "压缩回调结果" - @State mResultPath: string= "压缩路径:" - @State mAsyncPath: string= "" - @State mAsyncPathHint: string= "" - - build() { - Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center }) { - - Column() { - Column() { - Text("Resource image compress").fontColor(Color.Gray).fontSize(16); - Button() { - Text("同步压缩").fontSize(13).fontColor(Color.White) - } - .height(35) - .width(120) - .margin({ top: 10 }) - .onClick(() => { - this.compressAsyncRecource(); - }); - Scroll(){ - Text(this.mAsyncPathHint).fontSize(13) - } - .height(55) - .width(350) - - - Image(this.mAsyncPath) - .width(200) - .height(200) - .margin({ top: 10 }) - .backgroundColor(Color.Pink) - - Button() { - Text($r("app.string.resource_image_compress")).fontSize(13).fontColor(Color.White) - } - .height(35) - .width(120) - .margin({ top: 10 }) - .onClick(() => { - this.cropressRecource(); - }); - Image(this.mRPixelMap == undefined?'': this.mRPixelMap!) - .width(200) - .height(200) - .margin({ top: 10 }) - Text(this.mResultText).fontColor(Color.Gray).fontSize(16); - Text(this.mResultPath).fontColor(Color.Gray).fontSize(16); - }.margin({ top: 10 }); - - Column() { - Text("file image compress").fontColor(Color.Gray).fontSize(16); - Button() { - Text($r("app.string.file_image_compress")).fontSize(13).fontColor(Color.White) - } - .height(35) - .width(120) - .margin({ top: 10 }) - .onClick(() => { - }); - Image(this.mFPixelMap == undefined ?'':this.mFPixelMap!) - .width(200) - .height(200) - .margin({ top: 10 }); - }.margin({ top: 10 }).visibility(Visibility.Hidden); - }.margin({ bottom: 30 }); - }.width('100%').height('100%'); - } - private compressAsyncRecource() { - let data = new Array(); - data.push($r('app.media.jpgSample')) - - let imageKnife:ImageKnife|undefined = ImageKnifeGlobal.getInstance().getImageKnife() - if(imageKnife!=undefined) { - imageKnife - .compressBuilder() - .load(data) - .ignoreBy(100) - .get() - .then((path: string) => { - this.mAsyncPathHint = path; - this.mAsyncPath = 'file://' + path; - }); - } - console.info("asasd start compress end") - } - private cropressRecource() { - let data = new Array(); - data.push($r('app.media.jpgSample')) - let rename: OnRenameListener = { - reName() { - return "test_1.jpg"; - } - } - - let listener: OnCompressListener = { - start:()=>{ - this.mResultText = "start" - console.info("asasd start") - }, - onSuccess:(p: PixelMap | null | undefined, path: string)=> { - if(p!=null && p!=undefined) { - let pack = p; - this.mRPixelMap = pack as PixelMap; - console.info("asasd success path:" + this.mRPixelMap) - this.mResultText = "success"; - this.mResultPath = path; - } - }, - onError:(s: string)=>{ - console.info("asasd onError:" + s) - this.mResultText = "fail"; - } - } - console.info("asasd start compress") - let imageKnife:ImageKnife|undefined = ImageKnifeGlobal.getInstance().getImageKnife() - if(imageKnife != undefined) { - imageKnife - .compressBuilder() - .load(data) - .ignoreBy(100) - .setRenameListener(rename) - .setCompressListener(listener) - .launch(); - } - console.info("asasd start compress end") - } -} \ No newline at end of file diff --git a/entry/src/main/ets/pages/cropImagePage2.ets b/entry/src/main/ets/pages/cropImagePage2.ets deleted file mode 100644 index df4ad5d..0000000 --- a/entry/src/main/ets/pages/cropImagePage2.ets +++ /dev/null @@ -1,107 +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/libraryimageknife' -import { CropOptions } from '@ohos/libraryimageknife' -import { Crop } from '@ohos/libraryimageknife' -import { RecourseProvider } from '@ohos/libraryimageknife' -import { PixelMapCrop,Options } from '@ohos/libraryimageknife' -import { CropCallback } from '@ohos/libraryimageknife' -import { FileUtils } from '@ohos/libraryimageknife' -import { ImageKnifeGlobal } from '@ohos/libraryimageknife' -import { BusinessError } from '@ohos.base' -import resourceManager from '@ohos.resourceManager'; -import common from '@ohos.app.ability.common' - -@Entry -@Component -export struct CropImagePage2 { - @State options1: Options = new Options(); - @State cropTap: boolean = false; - - @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() { - Scroll() { - Column() { - Button('点击解析图片') - .onClick(() => { - ((ImageKnifeGlobal.getInstance().getHapContext() as common.UIAbilityContext).resourceManager as resourceManager.ResourceManager) - .getMediaContent($r('app.media.bmpSample').id) - .then((data:Uint8Array) => { - let arrayBuffer = FileUtils.getInstance().uint8ArrayToBuffer(data); - let optionx = new Options(); - optionx.setWidth(800) - .setHeight(800) - .setCropFunction((err:BusinessError|string, pixelmap:PixelMap|null, sx:number, sy:number) => { - console.log('PMC setCropFunction callback') - if (err) { - console.error('PMC crop err =' + err) - } else { - this.width1 = sx * px2vp(1); - this.height1 = sy * px2vp(1); - if(pixelmap != null) { - this.canvasContext.drawImage(pixelmap, 0, 0, this.width1, this.height1) - } - } - }) - optionx.loadBuffer(arrayBuffer, () => { - this.options1 = optionx; - }) - }) - - - }) - - PixelMapCrop({ options: $options1, cropTap: this.cropTap }) - - 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?: GestureEvent) => { - if(event != undefined) { - this._rotate = event.angle; - } - }), PinchGesture({ fingers: 2 }).onActionUpdate((event?: GestureEvent) => { - if(event != undefined) { - this._scale = event.scale; - } - }))) - } - .backgroundColor(Color.Brown) - .width('100%') - } - - } -} \ No newline at end of file diff --git a/entry/src/main/ets/pages/dataShareUriLoadPage.ets b/entry/src/main/ets/pages/dataShareUriLoadPage.ets deleted file mode 100644 index fd3859f..0000000 --- a/entry/src/main/ets/pages/dataShareUriLoadPage.ets +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright (C) 2023 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 mediaLibrary from '@ohos.multimedia.mediaLibrary'; -import { ImageKnifeComponent, ImageKnifeOption, } from '@ohos/libraryimageknife' - - -@Entry -@Component -struct DataShareUriLoadPage { - @State imageKnifeOption1: ImageKnifeOption = - { - loadSrc: $r('app.media.icon'), - - 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("获取媒体图库的uri用ImageKnife展示").fontSize(15) - Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { - Button("点击加载Uri并展示") - .onClick(() => { - // 获取mediaLibrary实例,后续用到此实例均采用此处获取的实例 - const context = getContext(this); - let media = mediaLibrary.getMediaLibrary(context); - - let imageType = mediaLibrary.MediaType.IMAGE; - // 创建文件获取选项,此处参数为获取image类型的文件资源 - let imagesFetchOp:mediaLibrary.MediaFetchOptions = { - selections: mediaLibrary.FileKey.MEDIA_TYPE + '= ?', - selectionArgs: [imageType.toString()], - }; - // 获取文件资源,使用callback方式返回异步结果 - media.getFileAssets(imagesFetchOp, (error, fetchFileResult) => { - // 判断获取的文件资源的检索结果集是否为undefined,若为undefined则接口调用失败 - if (fetchFileResult == undefined) { - console.log('get fetchFileResult failed with error: ' + error); - return; - } - // 获取文件检索结果集中的总数 - const count = fetchFileResult.getCount(); - // 判断结果集中的数量是否小于0,小于0时表示接口调用失败 - if (count < 0) { - console.log('get count from fetchFileResult failed, count: ' + count); - return; - } - // 判断结果集中的数量是否等于0,等于0时表示接口调用成功,但是检索结果集为空,请检查文件获取选项参数配置是否有误和设备中是否存在相应文件 - if (count == 0) { - console.log('The count of fetchFileResult is zero'); - return; - } - console.log('Get fetchFileResult successfully, count: ' + count); - // 获取文件检索结果集中的第一个资源,使用callback方式返回异步结果 - fetchFileResult.getFirstObject((error, fileAsset) => { - // 检查获取的第一个资源是否为undefined,若为undefined则接口调用失败 - if (fileAsset == undefined) { - console.log('get first object failed with error: ' + error); - return; - } - console.log("fileAsset id=" + fileAsset.id + " fileAsset uri=" + fileAsset.uri + " fileAsset displayName=" + fileAsset.displayName) - - // 加载图库第一张图片的uri - this.imageKnifeOption1 = { - loadSrc: fileAsset.uri, - placeholderSrc: $r('app.media.icon_loading'), - errorholderSrc: $r('app.media.icon_failed') - } - // 释放FetchFileResult实例并使其失效。无法调用其他方法 - fetchFileResult.close(); - }); - }); - }).margin({ top: 5, left: 3 }) - ImageKnifeComponent({ imageKnifeOption: this.imageKnifeOption1 }).width(300).height(300) - }.width('100%').backgroundColor(Color.Pink) - - } - } - .width('100%') - .height('100%') - } -} \ No newline at end of file diff --git a/entry/src/main/ets/pages/drawFactoryTestPage.ets b/entry/src/main/ets/pages/drawFactoryTestPage.ets deleted file mode 100644 index 433475b..0000000 --- a/entry/src/main/ets/pages/drawFactoryTestPage.ets +++ /dev/null @@ -1,98 +0,0 @@ -/* - * 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'; -import { - ImageKnifeComponent, - ImageKnifeOption, - ImageKnifeDrawFactory, - ScaleType -} from '@ohos/libraryimageknife' - -@Entry -@Component -struct DrawFactoryTestPage { - - types:Array = [ScaleType.FIT_START,ScaleType.FIT_END,ScaleType.FIT_CENTER,ScaleType.CENTER,ScaleType.CENTER_CROP,ScaleType.FIT_XY,ScaleType.CENTER_INSIDE,ScaleType.NONE] - - - @State msg:string = `当前ScaleType${this.types[0]}` - - @State imageKnifeOption1: ImageKnifeOption = - { - loadSrc:"https://xximg1.meitudata.com/2LqS1vmqv0.png!thumb-w321-webp75", - mainScaleType: this.types[0], - placeholderSrc: $r('app.media.icon_loading'), - errorholderSrc: $r('app.media.icon_failed'), - drawLifeCycle:ImageKnifeDrawFactory.createOvalLifeCycle(15,'#ff000000') - } - @State imageKnifeOption2: ImageKnifeOption = - { - loadSrc:"https://xximg1.meitudata.com/2LqS1vmqv0.png!thumb-w321-webp75", - mainScaleType: this.types[0], - placeholderSrc: $r('app.media.icon_loading'), - errorholderSrc: $r('app.media.icon_failed'), - drawLifeCycle:ImageKnifeDrawFactory.createRoundLifeCycle(10,'#ff000000',30) - } - - count:number = 0; - - - build() { - Scroll() { - Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { - - - Text("用例看护DrawFactory").fontSize(15) - Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { - Button(this.msg) - .onClick(() => { - this.count++; - let index= this.count % this.types.length; - this.msg = `当前ScaleType${this.types[index]}` - - this.imageKnifeOption1 = { - loadSrc:"https://xximg1.meitudata.com/2LqS1vmqv0.png!thumb-w321-webp75", - mainScaleType: this.types[index], - placeholderSrc: $r('app.media.icon_loading'), - errorholderSrc: $r('app.media.icon_failed'), - drawLifeCycle:ImageKnifeDrawFactory.createOvalLifeCycle(15,'#ff000000') - } - - this.imageKnifeOption2 = { - loadSrc:"https://xximg1.meitudata.com/2LqS1vmqv0.png!thumb-w321-webp75", - mainScaleType: this.types[index], - placeholderSrc: $r('app.media.icon_loading'), - errorholderSrc: $r('app.media.icon_failed'), - drawLifeCycle:ImageKnifeDrawFactory.createRoundLifeCycle(10,'#ff000000',30) - } - }).margin({ top: 15, bottom:15 }) - ImageKnifeComponent({ imageKnifeOption: this.imageKnifeOption1 }).width('100%').height(300).backgroundColor(Color.Orange) - ImageKnifeComponent({ imageKnifeOption: this.imageKnifeOption2 }).width('100%').height(300).backgroundColor(Color.Orange) - .margin({ top: 15, bottom:15 }) - } - .width('100%').height('100%').backgroundColor(Color.Pink) - - - - - - - }.width('100%') - } - .width('100%') - .height('100%') - } - -} \ No newline at end of file diff --git a/entry/src/main/ets/pages/frescoRetryTestCasePage.ets b/entry/src/main/ets/pages/frescoRetryTestCasePage.ets deleted file mode 100644 index c6ae9d5..0000000 --- a/entry/src/main/ets/pages/frescoRetryTestCasePage.ets +++ /dev/null @@ -1,78 +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/libraryimageknife' -import {ImageKnifeOption} from '@ohos/libraryimageknife' -import {RotateImageTransformation} from '@ohos/libraryimageknife' -import {RoundedCornersTransformation} from '@ohos/libraryimageknife' - -@Entry -@Component -struct FrescoImageTestCasePage { - @State imageKnifeOption1: ImageKnifeOption = - { - loadSrc: "https://thirdwx.qlogo.cn/mmopen/vi_32/DYAIOgq83ericA1Mv66TwicuYOtbDMBcUhv1aa9RJBeAn9uURfcZD0AUGrJebAn1g2AjN0vb2E1XTET7fTuLBNmA/132", - - placeholderSrc: $r('app.media.icon_loading'), - errorholderSrc: $r('app.media.icon_failed'), - retryholderSrc: $r('app.media.icon_retry'), - displayProgress: true, - canRetryClick:true - }; - @State ImageKnifeOption: ImageKnifeOption = - { - loadSrc: "https://hbimg.huabanimg.com/0ef60041445edcfd6b38d20e19024b2cd9281dcc3525a4-Vy8fYO_fw658/format/webp", - - placeholderSrc: $r('app.media.icon_loading'), - errorholderSrc: $r('app.media.icon_failed'), - retryholderSrc: $r('app.media.icon_retry'), - displayProgress: true, - canRetryClick:true - }; - @State imageKnifeOption3: ImageKnifeOption = - { - loadSrc: "https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp", - - placeholderSrc: $r('app.media.icon_loading'), - errorholderSrc: $r('app.media.icon_failed'), - retryholderSrc: $r('app.media.icon_retry'), - displayProgress: true, - canRetryClick:true - }; - @State imageKnifeOption4: ImageKnifeOption = - { - loadSrc: "https://hbimg.huabanimg.com/testRetryxxxx", - - placeholderSrc: $r('app.media.icon_loading'), - errorholderSrc: $r('app.media.icon_failed'), - retryholderSrc: $r('app.media.icon_retry'), - displayProgress: true, - canRetryClick:true - }; - - build() { - Scroll() { - Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { -// ImageKnifeComponent({ imageKnifeOption: this.imageKnifeOption1 }) -// ImageKnifeComponent({ imageKnifeOption: this.imageKnifeOption }) -// ImageKnifeComponent({ imageKnifeOption: this.imageKnifeOption3 }) - ImageKnifeComponent({ imageKnifeOption: this.imageKnifeOption4 }) - .width(300) - .height(300) - } - } - .width('100%') - .height('100%') - } -} diff --git a/entry/src/main/ets/pages/hspCacheTestPage.ets b/entry/src/main/ets/pages/hspCacheTestPage.ets deleted file mode 100644 index 1d3c2ba..0000000 --- a/entry/src/main/ets/pages/hspCacheTestPage.ets +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (C) 2023 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { ImageKnifeComponent, ImageKnifeOption, FileUtils,ImageKnifeGlobal } from '@ohos/libraryimageknife' -import common from '@ohos.app.ability.common' - -@Entry -@Component -struct Index { - - - @State imageOption1:ImageKnifeOption = { - loadSrc: $r('app.media.icon'), - - } - @State imageOption2:ImageKnifeOption = { - loadSrc: $r('app.media.icon'), - - } - @State imageOption3:ImageKnifeOption = { - loadSrc: $r('app.media.icon'), - - } - - build() { - Scroll() { - Column() { - Button('点击加载网络图片').onClick(()=>{ - this.imageOption2 = { - loadSrc: 'https://hbimg.huabanimg.com/cc6af25f8d782d3cf3122bef4e61571378271145735e9-vEVggB', - } - }) - ImageKnifeComponent({imageKnifeOption:this.imageOption2}).width(300).height(300).backgroundColor(Color.Pink) - - Button('点击加载本地文件').onClick(()=>{ - let ctx:Object|undefined = ImageKnifeGlobal.getInstance().getHapContext(); - if(ctx != undefined){ - let path = (ctx as common.UIAbilityContext).filesDir+"/set.jpeg"; - FileUtils.getInstance().readFilePicAsync(path).then(buffer=>{ - this.imageOption3 = { - loadSrc: path - } - }) - } - - }) - ImageKnifeComponent({imageKnifeOption:this.imageOption3}).width(300).height(300).backgroundColor(Color.Pink) - - - - }.width('100%') - - } - .width('100%') - .height('100%') - } -} \ No newline at end of file diff --git a/entry/src/main/ets/pages/imageknifeTestCaseIndex.ets b/entry/src/main/ets/pages/imageknifeTestCaseIndex.ets deleted file mode 100644 index 4a1563a..0000000 --- a/entry/src/main/ets/pages/imageknifeTestCaseIndex.ets +++ /dev/null @@ -1,372 +0,0 @@ -/* - * 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 '@ohos.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("测试List列表") - router.pushUrl({ url: "pages/basicTestFeatureAbilityPage" }); - }).margin({ top: 5, left: 3 }) - Button("测试文件") - .onClick(() => { - console.log("测试文件子系统") - router.pushUrl({ url: "pages/basicTestFileIOPage" }); - }).margin({ top: 5, left: 3 }) - Button("优先级加载") - .onClick(() => { - console.log("优先级加载") - router.pushUrl({ url: "pages/testPriorityComponent" }); - }).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.pushUrl({ url: "pages/basicTestResourceManagerPage" }); - }).margin({ top: 5, left: 3 }) - Button("测试媒体") - .onClick(() => { - console.log("测试媒体子系统") - router.pushUrl({ url: "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.pushUrl({ url: "pages/testImageKnifeOptionChangedPage" }); - }).margin({ top: 5, left: 3 }) - Button("测试图片高度自适应") - .onClick(() => { - console.log("测试ImageKnifeComponent图片高度自适应") - router.pushUrl({ url: "pages/testImageKnifeAutoHeightPage" }); - }).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("测试ImageKnifeComponent图片宽度自适应") - router.pushUrl({ url: "pages/testImageKnifeAutoWidthPage" }); - }).margin({ top: 5, left: 3 }) - Button("测试图片宽高自适应") - .onClick(() => { - console.log("测试ImageKnifeComponent图片宽高自适应") - router.pushUrl({ url: "pages/testImageKnifeAutoPage" }); - }).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.pushUrl({ url: "pages/testImageKnifeOptionChangedPage2" }); - }).margin({ top: 5, left: 3 }) - Button("测试RequestOption加载图片") - .onClick(() => { - console.log("测试RequestOption加载图片") - router.pushUrl({ url: "pages/RequestOptionLoadImage" }); - }).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.pushUrl({ url: "pages/storageTestLruCache" }); - }).margin({ top: 5, left: 3 }) - Button("测试所有缓存信息输出") - .onClick(() => { - console.log("pages/testAllCacheInfoPage 页面跳转") - router.pushUrl({ url: "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.pushUrl({ url: "pages/testReusePhotoPage" }); - }).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.pushUrl({ url: "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.pushUrl({ url: "pages/testPreloadPage" }); - }).margin({ top: 5, left: 3 }) - Button("测试磁盘预加载返回string") - .onClick(() => { - console.log("测试预加载测试磁盘预加载返回string") - router.pushUrl({ url: "pages/testDiskPreLoadPage" }); - }).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.pushUrl({ url: "pages/transformPixelMapPage" }); - }).margin({ top: 5, left: 3 }) - Button("测试图片压缩") - .onClick(() => { - console.log("测试图片压缩") - router.pushUrl({ url: "pages/compressPage" }); - }).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.pushUrl({ url: "pages/CacheRuleChangedPage" }); - }).margin({ top: 5, left: 3 }) - Button("重试Retry") - .onClick(() => { - console.log("重试Retry") - router.pushUrl({ url: "pages/frescoRetryTestCasePage" }); - }).margin({ top: 5, left: 3 }) - Button("加载媒体库uri") - .onClick(() => { - console.log("加载媒体库uri") - router.pushUrl({ url: "pages/dataShareUriLoadPage" }); - }).margin({ top: 5, left: 3 }) - - }.width('100%').height(60).backgroundColor(Color.Pink) - - Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { - Button("测试Option缓存是否生效") - .onClick(() => { - console.log("测试Option缓存是否生效") - router.pushUrl({ url: "pages/OptionTestPage" }); - }).margin({ top: 5, left: 3 }) - Button("测试Signature自定义缓存") - .onClick(() => { - console.log("测试Signature自定义缓存") - router.pushUrl({ url: "pages/SignatureTestPage" }); - }).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.pushUrl({ url: "pages/pngjTestCasePage" }); - }).margin({ top: 5, left: 3 }) - Button("图片裁剪") - .onClick(() => { - console.log("图片裁剪") - router.pushUrl({ url: "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.pushUrl({ url: "pages/svgTestCasePage" }); - }).margin({ top: 15 }) - - Button("测试gif已转移,不再使用worker") - .onClick(() => { - - }).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.pushUrl({ url: "pages/testImageKnifeOptionChangedPage3" }); - }).margin({ top: 15 }) - - Button("组件内容动画") - .onClick(() => { - console.log("pages/testImageKnifeOptionChangedPage4 页面跳转") - router.pushUrl({ url: "pages/testImageKnifeOptionChangedPage4" }); - }).margin({ top: 15 }) - - Button("自定义圆角椭圆") - .onClick(() => { - console.log("pages/testImageKnifeOptionChangedPage5 页面跳转") - router.pushUrl({ url: "pages/testImageKnifeOptionChangedPage5" }); - }).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/manyPhotoShowPage 页面跳转") - router.pushUrl({ url: "pages/manyPhotoShowPage" }); - }).margin({ top: 15 }) - Button("部分url测试") - .onClick(() => { - console.log("pages/tempUrlTestPage 页面跳转") - router.pushUrl({ url: "pages/tempUrlTestPage" }); - }).margin({ top: 15 }) - Button("测试drawFactory") - .onClick(() => { - console.log("pages/drawFactoryTestPage 页面跳转") - router.pushUrl({ url: "pages/drawFactoryTestPage" }); - }).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/photosPausedResumedPage 页面跳转") - router.pushUrl({ url: "pages/photosPausedResumedPage" }); - }).margin({ top: 15 }) - Button("List滑动暂停和恢复") - .onClick(() => { - console.log("pages/photosPausedResumedPage2 页面跳转") - router.pushUrl({ url: "pages/photosPausedResumedPage2" }); - }).margin({ top: 15 }) - }.width('100%').height(60).backgroundColor(Color.Pink) - - Text("单帧gif测试").fontSize(15) - Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { - Button("单帧gif测试") - .onClick(() => { - router.pushUrl({ url: "pages/testSingleFrameGifPage" }); - }).margin({ top: 5, left: 3 }) - }.width('100%').height(60).backgroundColor(Color.Pink) - - Text("worker测试").fontSize(15) - Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { - Button("gif加载测试已转移,worker不再使用") - .onClick(() => { - - }).margin({ top: 5, left: 3 }) - }.width('100%').height(60).backgroundColor(Color.Pink) - - Text("HSP相关测试").fontSize(15) - Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { - - Button("进入HSP的library共享包") - .onClick(() => { - router.pushUrl({ url: '@bundle:com.openharmony.imageknife/sharedlibrary/ets/pages/Index' }) - .then(() => { - console.log('push page suceess') - }) - }).margin({ top: 15 }) - Button("hsp加载后缓存情况,先点左侧按钮") - .onClick(() => { - console.log("pages/hspCacheTestPage 页面跳转") - router.pushUrl({ url: "pages/hspCacheTestPage" }); - }).margin({ top: 15 }) - Button("不同的hsp资源加载") - .onClick(() => { - console.log("pages/multiHspTestPage 页面跳转") - router.pushUrl({ url: "pages/multiHspTestPage" }); - }) - - }.width('100%').height(60).backgroundColor(Color.Pink) - - Text("测试图片加载稳定").fontSize(15) - Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { - Button("测试多张网络图片加载速度") - .onClick(() => { - router.pushUrl({ url: "pages/testManyNetImageLoadWithPage" }); - }).margin({ top: 5, left: 3 }) - Button("多线程加载大量网络图片加载速度") - .onClick(() => { - router.pushUrl({ url: "pages/testManyNetImageLoadWithPage2" }); - }).margin({ top: 5, left: 3 }) - Button("测试多张gif加载位置") - .onClick(() => { - router.pushUrl({ url: "pages/testManyGifLoadWithPage" }); - }).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(() => { - router.pushUrl({ url: 'pages/testImageAntiAliasingWithPage' }); - }).margin({ top: 5, left: 3 }) - Button('共享转场缩放') - .onClick(() => { - router.pushUrl({ url: 'pages/testImageKnifeRouter1' }); - }).margin({ top: 5, left: 3 }) - }.width('100%').height(60).backgroundColor(Color.Pink) - - Text('测试图片header属性').fontSize(15) - Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { - Button('图片header属性设置') - .onClick(() => { - router.pushUrl({ url: 'pages/testImageKnifeHttpRequestHeader' }); - }).margin({ top: 5, left: 3 }) - }.width('100%').height(60).backgroundColor(Color.Pink) - } - } - .width('100%') - .height('100%') - } - - aboutToAppear() { - } - - onBackPress() { - - } -} \ No newline at end of file diff --git a/entry/src/main/ets/pages/index.ets b/entry/src/main/ets/pages/index.ets index a36d77a..c6d5bf6 100644 --- a/entry/src/main/ets/pages/index.ets +++ b/entry/src/main/ets/pages/index.ets @@ -1,103 +1,54 @@ /* - * Copyright (C) 2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); + * 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, + * 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 '@ohos.router'; -import { - ImageKnifeComponent, - ImageKnifeOption, - ImageKnifeGlobal, - ImageKnife, - HeaderOptions -} from '@ohos/libraryimageknife' +import { ImageKnifeComponent, ImageKnifeOption } from "@ohos/imageknife" -import { ObjectKey } from '@ohos/libraryimageknife'; @Entry @Component -struct IndexFunctionDemo { - @State headerOptions1: HeaderOptions = { - key: "refer", - value: "http://1.94.37.200:7070/AntiTheftChain/downloadImage" - }; - @State imageKnifeOption1: ImageKnifeOption = - { - loadSrc: $r('app.media.icon'), - placeholderSrc: $r('app.media.icon_loading'), - errorholderSrc: $r('app.media.icon_failed'), - headerOption: [this.headerOptions1] - }; - @State imageKnifeOption2: ImageKnifeOption = - { - loadSrc: $r('app.media.icon'), - placeholderSrc: $r('app.media.icon_loading'), - errorholderSrc: $r('app.media.icon_failed'), - headerOption: [this.headerOptions1] - }; +struct Index { + localFile: string = getContext(this).filesDir + "/icon.png" + @State ImageKnifeOption: ImageKnifeOption = { + loadSrc: $r("app.media.rabbit"), + // src:"https://www.openharmony.cn/_nuxt/img/logo.dcf95b3.png", + // src: this.localFile, + placeholderSrc: $r("app.media.loading"), + errorholderSrc: $r("app.media.app_icon"), + objectFit: ImageFit.Contain, + border: { radius: 50 } + } + + aboutToAppear(): void { + // 拷贝本地文件 + // let icon: Uint8Array = getContext(this).resourceManager.getMediaContentSync($r("app.media.startIcon")); + // let file = fs.openSync(this.localFile, fs.OpenMode.CREATE | fs.OpenMode.READ_WRITE); + // fs.writeSync(file.fd, icon.buffer); + // fs.fsyncSync(file.fd); + // fs.closeSync(file); + } build() { - Scroll() { - Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { - Text("简单示例1:加载一张本地png图片").fontSize(15) - Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { - Button("加载PNG") - .onClick(() => { - this.imageKnifeOption1 = { - loadSrc: $r('app.media.pngSample'), - placeholderSrc: $r('app.media.icon_loading'), - errorholderSrc: $r('app.media.icon_failed'), - signature: new ObjectKey('ccccccc') - } - }).margin({ top: 5, left: 3 }) - ImageKnifeComponent({ imageKnifeOption: this.imageKnifeOption1 }).width(300).height(300) - }.width('100%').backgroundColor(Color.Pink) - Text("简单示例2:加载一张网络gif图片").fontSize(15) - Text("gif解析在子线程,请在页面构建后创建worker,注入imageknife").fontSize(15) - Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { - Button("加载GIF") - .onClick(() => { - this.imageKnifeOption2 = { - loadSrc: 'https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658', - placeholderSrc: $r('app.media.icon_loading'), - errorholderSrc: $r('app.media.icon_failed'), - displayProgress:true, - } - }).margin({ top: 5, left: 3 }) - ImageKnifeComponent({ imageKnifeOption: this.imageKnifeOption2 }).width(300).height(300) - }.width('100%').backgroundColor(Color.Pink) + Column() { + ImageKnifeComponent({ ImageKnifeOption: this.ImageKnifeOption }).height(200).width(200) + + // Image($r('app.media.rabbit')).objectFit(ImageFit.Contain).height(200).width(200) + // .border({radius:50}) - Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { - Button("ImageKnife测试目录页面") - .onClick(() => { - console.log("pages/imageknifeTestCaseIndex 页面跳转") - router.pushUrl({ url: "pages/imageknifeTestCaseIndex" }); - }).margin({ top: 15 }) - }.width('100%').height(60).backgroundColor(Color.Pink) - } } .width('100%') + .height('100%') } - - aboutToAppear() { - - } - aboutToDisappear(){ - - } - - onBackPress() { - - } } \ No newline at end of file diff --git a/entry/src/main/ets/pages/manyPhotoShowPage.ets b/entry/src/main/ets/pages/manyPhotoShowPage.ets index dffbb0a..9b2e685 100644 --- a/entry/src/main/ets/pages/manyPhotoShowPage.ets +++ b/entry/src/main/ets/pages/manyPhotoShowPage.ets @@ -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 @@ -12,59 +12,63 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import {ImageKnifeComponent, ScaleType} from '@ohos/libraryimageknife' -import {ImageKnifeOption} from '@ohos/libraryimageknife' -import {ImageKnifeGlobal} from '@ohos/libraryimageknife' -import {RotateImageTransformation} from '@ohos/libraryimageknife' -import {Material} from './model/Material' -import {TestDataSource} from './model/TestDataSource' -import {DiskLruCache} from '@ohos/disklrucache' -import ArkWorker from '@ohos.worker' -import Prompt from '@system.prompt' +import { ImageKnifeComponent } from '@ohos/imageknife'; + + + @Entry @Component struct ManyPhotoShowPage { - private data: TestDataSource = new TestDataSource(); + private data: TestDataSource = new TestDataSource(); - private elementScroller: Scroller = new Scroller() + private elementScroller: Scroller = new Scroller() build() { - Column() { + Column() { - List({ space: 20, scroller: this.elementScroller }) { - LazyForEach(this.data, (item: Material, index) => { - ListItem() { - Column() { - Stack({ alignContent: Alignment.BottomEnd }) { - // 滤镜图片 - ImageKnifeComponent({ imageKnifeOption: { - loadSrc: item.thumbnail, - mainScaleType: ScaleType.FIT_XY, - } }) - } - .width(56).height(56) - //滤镜标题 - Text(item.name) - .fontSize(10) - .maxLines(1) - .fontColor(Color.White) - .textAlign(TextAlign.Center) - .layoutWeight(1) - .width('100%') - .backgroundColor(Color.Orange) - } - .width(56) - .height(72) - .clip(true) - .borderRadius(4) + List({ space: 20, scroller: this.elementScroller }) { + LazyForEach(this.data, (item: Material, index) => { + ListItem() { + Column() { + Stack({ alignContent: Alignment.BottomEnd }) { + // 滤镜图片 + // ImageKnifeComponent({ imageKnifeOption: { + // loadSrc: item.thumbnail, + // mainScaleType: ScaleType.FIT_XY, + // } }) + ImageKnifeComponent({ImageKnifeOption:{ + loadSrc: item.thumbnail, + //src:"https://www.openharmony.cn/_nuxt/img/logo.dcf95b3.png", + // src: this.localFile, + placeholderSrc:$r("app.media.loading"), + errorholderSrc:$r("app.media.app_icon"), + objectFit: ImageFit.Auto, + border: {radius:50} + }}) + } + .width(56).height(56) + //滤镜标题 + Text(item.name) + .fontSize(10) + .maxLines(1) + .fontColor(Color.White) + .textAlign(TextAlign.Center) + .layoutWeight(1) + .width('100%') + .backgroundColor(Color.Orange) + } + .width(56) + .height(72) + .clip(true) + .borderRadius(4) + } + }, (item: Material) => item.material_id) } - }, (item: Material) => item.material_id) - } - .listDirection(Axis.Horizontal) - .width('100%') - .height(72) + .listDirection(Axis.Horizontal) + .width('100%') + .height(72) - } + } } @@ -72,3 +76,2840 @@ struct ManyPhotoShowPage { } +class BasicDataSource implements IDataSource { + private listeners: DataChangeListener[] = []; + + public totalCount(): number { + return 0; + } + + public getData(index: number):T | undefined { + return undefined; + } + + registerDataChangeListener(listener: DataChangeListener): void { + if (this.listeners.indexOf(listener) < 0) { + console.info('add listener'); + this.listeners.push(listener); + } + } + + unregisterDataChangeListener(listener: DataChangeListener): void { + const pos = this.listeners.indexOf(listener); + if (pos >= 0) { + console.info('remove listener'); + this.listeners.splice(pos, 1); + } + } + + notifyDataReload(): void { + this.listeners.forEach(listener => { + listener.onDataReloaded(); + }) + } + + notifyDataAdd(index: number): void { + this.listeners.forEach(listener => { + listener.onDataAdd(index); + }) + } + + notifyDataChange(index: number): void { + this.listeners.forEach(listener => { + listener.onDataChange(index); + }) + } + + notifyDataDelete(index: number): void { + this.listeners.forEach(listener => { + listener.onDataDelete(index); + }) + } + + notifyDataMove(from: number, to: number): void { + this.listeners.forEach(listener => { + listener.onDataMove(from, to); + }) + } +} + +class Material{ + material_id: string =''; + thumbnail: string = ''; + name: string =''; +} + +class TestDataSource extends BasicDataSource { + private dataArray: Material[] = [ + { + name: "测试CBC", + thumbnail: "https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/R9aT7lpEEVxawo4.jpeg!thumb-w321-webp75", + material_id: "5060118818" + }, + { + name: "通用天空1像素测试", + thumbnail: "https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/1V6c63lKLGPlKVo.png!thumb-w321-webp75", + material_id: "506009997" + }, + { + name: "像素测试+bin", + thumbnail: "https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/2NxCo49xAB1L96K.jpeg!thumb-w321-webp75", + material_id: "506009998" + }, + { + name: "像素测试", + thumbnail: "https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/P6gH3pWBGw7L6dD.jpeg!thumb-w321-webp75", + material_id: "506009999" + }, + { + name: "名称一", + thumbnail: "https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/MKosgAWo5VKpo9Z.jpeg!thumb-w321-webp75", + material_id: "50600999" + }, + { + name: "质感", + thumbnail: "https://xximg1.meitudata.com/XepUPNP4WP.png!thumb-w321-webp75", + material_id: "20076061608" + }, + { + name: "抠图批量拼图", + thumbnail: "https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/pA2S9lvNpMY4X3N.jpeg!thumb-w321-webp75", + material_id: "506002368" + }, + { + name: "修改测试", + thumbnail: "https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/69MiA9VxKdkzjWR.png!thumb-w321-webp75", + material_id: "50600229" + }, + { + name: "兰桂坊-艺术", + thumbnail: "https://material-center-pre.meitudata.com/material/image/6228901fd8ddd6350.jpeg!thumb-w321-webp75", + material_id: "50639415" + }, + { + name: "有门槛的我", + thumbnail: "https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/P98i3gdgDw3Rmx5.png!thumb-w321-webp75", + material_id: "506093422" + }, + { + name: "222嗯嗯1", + thumbnail: "https://stage.meitudata.com/public/creator/ed70a3c696c8e7b.jpg!thumb-w321-webp75", + material_id: "50693244" + }, + { + name: "滤镜流程11", + thumbnail: "https://material-center-pre.meitudata.com/material/image/6194a57b5b9ef7678.jpg!thumb-w321-webp75", + material_id: "506017292" + }, + { + name: "hsxTest11.8", + thumbnail: "https://material-center-pre.meitudata.com/material/image/6189f29b48f165954.jpg!thumb-w321-webp75", + material_id: "506530963" + }, + { + name: "旧-美食手绘1", + thumbnail: "https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/0lZCW9BrDgMroLL.jpeg!thumb-w321-webp75", + material_id: "5060002001" + }, + { + name: "Forest", + thumbnail: "https://xximg1.meitudata.com/V2jTkoYa96.jpeg!thumb-w321-webp75", + material_id: "20106191835" + }, + { + name: "春樱", + thumbnail: "https://xximg1.meitudata.com/k5DIOxgJpN.jpeg!thumb-w321-webp75", + material_id: "20076291634" + }, + { + name: "GT G", + thumbnail: "http://xximg2.meitudata.com/Z9DCJpkB2l.jpeg!thumb-w321-webp75", + material_id: "20085081215" + }, + { + name: "测", + thumbnail: "https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/zwdte8R2e5KMMmm.jpeg!thumb-w321-webp75", + material_id: "506000000" + }, + { + name: "五一鱼块", + thumbnail: "https://xximg1.meitudata.com/mlahyxNxjN.jpeg!thumb-w321-webp75", + material_id: "20076292056" + }, + { + name: "青空", + thumbnail: "https://xximg1.meitudata.com/8OkUwBympV.jpeg!thumb-w321-webp75", + material_id: "20106311844" + }, + { + name: "质感", + thumbnail: "https://xximg1.meitudata.com/9nzUydyWeB.png!thumb-w321-webp75", + material_id: "20076061589" + }, + { + name: "测试CBC", + thumbnail: "https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/R9aT7lpEEVxawo4.jpeg!thumb-w321-webp75", + material_id: "5060118818" + }, + { + name: "像素天空抠图测试", + thumbnail: "https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/Ymju0r3deAl7xoJ.jpeg!thumb-w321-webp75", + material_id: "506005680" + }, + { + name: "像素滤镜测试", + thumbnail: "https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/8zPcB0y4vdreG1d.jpeg!thumb-w321-webp75", + material_id: "506019998" + }, + { + name: "通用天空1像素测试", + thumbnail: "https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/1V6c63lKLGPlKVo.png!thumb-w321-webp75", + material_id: "506009997" + }, + { + name: "人像风格化", + thumbnail: "https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/VYwIWp0E52v5vaE.jpeg!thumb-w321-webp75", + material_id: "50600288888" + }, + { + name: "像素+边框测试", + thumbnail: "https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/Z9dtor442OY76KV.jpeg!thumb-w321-webp75", + material_id: "506005678" + }, + { + name: "像素测试+bin", + thumbnail: "https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/2NxCo49xAB1L96K.jpeg!thumb-w321-webp75", + material_id: "506009998" + }, + { + name: "像素测试", + thumbnail: "https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/P6gH3pWBGw7L6dD.jpeg!thumb-w321-webp75", + material_id: "506009999" + }, + { + name: "兰桂坊-艺术", + thumbnail: "https://material-center-pre.meitudata.com/material/image/6228901fd8ddd6350.jpeg!thumb-w321-webp75", + material_id: "50639415" + }, + { + name: "藤黄", + thumbnail: "https://xximg1.meitudata.com/KnJSa8X496.jpeg!thumb-w321-webp75", + material_id: "20076281728" + }, + { + name: "梅幸茶", + thumbnail: "https://xximg1.meitudata.com/GYGcPokEQ3.jpeg!thumb-w321-webp75", + material_id: "20076281771" + }, + { + name: "五一鱼块", + thumbnail: "https://xximg1.meitudata.com/mlahyxNxjN.jpeg!thumb-w321-webp75", + material_id: "20076292056" + }, + { + name: "12.妆容滤镜层级控制", + thumbnail: "https://xxtool-release.zone1.meitudata.com/deRP83dkdlR4.png!thumb-w321-webp75", + material_id: "200720002017" + }, + { + name: "12.妆容滤镜层级控制1", + thumbnail: "https://xxtool-release.zone1.meitudata.com/rPJ1vKjJY6jz.png!thumb-w321-webp75", + material_id: "200720002018" + }, + { + name: "13.3D打光", + thumbnail: "https://xxtool-release.zone1.meitudata.com/z8K3P249ZmVW.png!thumb-w321-webp75", + material_id: "200720002020" + }, + { + name: "14.新bling效果", + thumbnail: "https://xxtool-release.zone1.meitudata.com/e4xlVkl0BzMy.png!thumb-w321-webp75", + material_id: "200720003001" + }, + { + name: "美食手绘效果2", + thumbnail: "https://xxtool-release.zone1.meitudata.com/B6MleZrWeMvj.jpg!thumb-w321-webp75", + material_id: "200720002002" + }, + { + name: "16.美食手绘效果", + thumbnail: "https://xxtool-release.zone1.meitudata.com/xEke61aRK6dg.jpg!thumb-w321-webp75", + material_id: "200720002003" + }, + { + name: "17.素材无人脸规则", + thumbnail: "https://xxtool-release.zone1.meitudata.com/B6MleZ1ae5Ry.jpg!thumb-w321-webp75", + material_id: "200720002010" + }, + { + name: "18.径向色散效果", + thumbnail: "https://xxtool-release.zone1.meitudata.com/EyvzkoPgakDL.jpg!thumb-w321-webp75", + material_id: "200720002012" + }, + { + name: "胶片滤镜2", + thumbnail: "https://xxtool-release.zone1.meitudata.com/3zVRo1E16vZG.png!thumb-w321-webp75", + material_id: "200720002008" + }, + { + name: "20.胶片滤镜", + thumbnail: "https://xxtool-release.zone1.meitudata.com/3zVRo1EdvZ0W.jpg!thumb-w321-webp75", + material_id: "200720002009" + }, + { + name: "21.虚化滤镜", + thumbnail: "https://xxtool-release.zone1.meitudata.com/1mLMv1kd2BLZ.jpg!thumb-w321-webp75", + material_id: "200720002011" + }, + { + name: "22.天空分割滤镜", + thumbnail: "https://xxtool-release.zone1.meitudata.com/8NXRMzE019aB.jpg!thumb-w321-webp75", + material_id: "200720002006" + }, + { + name: "23.妆容滤镜", + thumbnail: "https://xxtool-release.zone1.meitudata.com/0XDRo7xdPkVx.jpg!thumb-w321-webp75", + material_id: "200720002007" + }, + { + name: "1.随机滤镜", + thumbnail: "https://xxtool-release.zone1.meitudata.com/V06dg1RJ8pDr.jpg!thumb-w321-webp75", + material_id: "200720001004" + }, + { + name: "15.实时取色效果", + thumbnail: "https://xxtool-release.zone1.meitudata.com/2p5Ro1VDZvxR.png!thumb-w321-webp75", + material_id: "200720001001" + }, + { + name: "10.不带妆容", + thumbnail: "https://xxtool-release.zone1.meitudata.com/8NXRMz5oypN7.jpeg!thumb-w321-webp75", + material_id: "200720002030" + }, + { + name: "16.美食手绘效果1", + thumbnail: "https://xxtool-release.zone1.meitudata.com/1mLMWyxNVMAe.jpg!thumb-w321-webp75", + material_id: "506088836" + }, + { + name: "素材多比例滤镜", + thumbnail: "https://xxtool-release.zone1.meitudata.com/7d8RoA7DXYB9.jpg!thumb-w321-webp75", + material_id: "200720002013" + }, + { + name: "安德森粉", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/OXOHRLBqVppoxEY.png!thumb-w321-webp75", + material_id: "20079982224" + }, + { + name: "安德森黄", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/bBZcY8dnYDqZE5v.png!thumb-w321-webp75", + material_id: "20079982225" + }, + { + name: "安德森冷", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/x5NF1JLYvqGENkj.png!thumb-w321-webp75", + material_id: "20079982226" + }, + { + name: "安德森暖青", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/KeVUpByXzRp0oPK.png!thumb-w321-webp75", + material_id: "20079982227" + }, + { + name: "高光+100", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/PB2cdnDGN0nqb8q.png!thumb-w321-webp75", + material_id: "20079981113" + }, + { + name: "高光-100", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/XepU5b6OZKW90Yv.png!thumb-w321-webp75", + material_id: "20079981114" + }, + { + name: "阴影+100", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/KeVUp1oQD6W8xg5.png!thumb-w321-webp75", + material_id: "20079981115" + }, + { + name: "阴影-100", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/GPWcJeyweKZR69d.png!thumb-w321-webp75", + material_id: "20079981116" + }, + { + name: "cg无素材", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/LEasj5wg0o10JzO.png!thumb-w321-webp75", + material_id: "20079981112" + }, + { + name: "会员电影胶片", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/8QzFJLZVqLlvj8v.png!thumb-w321-webp75", + material_id: "20079982254" + }, + { + name: "秋1", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/KeVUpByPLRGkgYj.jpeg!thumb-w321-webp75", + material_id: "20079982230" + }, + { + name: "秋2", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/6kQUqeG39YJlEo1.jpeg!thumb-w321-webp75", + material_id: "20079982231" + }, + { + name: "秋3", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/KeVUpByPvxBLldg.jpeg!thumb-w321-webp75", + material_id: "20079982232" + }, + { + name: "秋4", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/3YDh1Dl6xY30nqD.jpeg!thumb-w321-webp75", + material_id: "20079982233" + }, + { + name: "秋5", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/9nzUG9DeeGmn94G.jpeg!thumb-w321-webp75", + material_id: "20079982234" + }, + { + name: "秋6", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/YkpUjYwlPanLVNg.jpeg!thumb-w321-webp75", + material_id: "20079982235" + }, + { + name: "秋7", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/OXOHRLB3YBPbD0o.jpeg!thumb-w321-webp75", + material_id: "20079982236" + }, + { + name: "秋8", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/dWZS0X3P2LjqJ5x.jpeg!thumb-w321-webp75", + material_id: "20079982240" + }, + { + name: "自然灰2", + thumbnail: "https://xximg1.meitudata.com/OXOH0zayv2.png!thumb-w321-webp75", + material_id: "20079981854" + }, + { + name: "自然灰1", + thumbnail: "https://xximg1.meitudata.com/mbeUyRpobN.png!thumb-w321-webp75", + material_id: "20079981853" + }, + { + name: "色散", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/3YDhOe5eO9.png!thumb-w321-webp75", + material_id: "20079981726" + }, + { + name: "毕业季", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/4VQt9N8Pjo.png!thumb-w321-webp75", + material_id: "20079981254" + }, + { + name: "一键美颜质感", + thumbnail: "https://xximg1.meitudata.com/x5NFQPRBWG.png!thumb-w321-webp75", + material_id: "20079982147" + }, + { + name: "相框吸色", + thumbnail: "https://xximg1.meitudata.com/2zmU1vvaPD.png!thumb-w321-webp75", + material_id: "20079982037" + }, + { + name: "美化吸色灰度限制", + thumbnail: "https://xximg1.meitudata.com/EPBcLQoodX.png!thumb-w321-webp75", + material_id: "20079980037" + }, + { + name: "相机吸色测试", + thumbnail: "https://xximg1.meitudata.com/p0LTZqZ2Wm.jpeg!thumb-w321-webp75", + material_id: "20079981873" + }, + { + name: "吸色测试2", + thumbnail: "https://xximg1.meitudata.com/9nzUyoDvEQ.png!thumb-w321-webp75", + material_id: "20079981874" + }, + { + name: "吸色灰度限制0.5", + thumbnail: "https://xximg1.meitudata.com/9nzUyYZ5LZ.png!thumb-w321-webp75", + material_id: "20079981029" + }, + { + name: "foodie锐化", + thumbnail: "https://xximg1.meitudata.com/oJWHn2klo6.png!thumb-w321-webp75", + material_id: "20079982000" + }, + { + name: "自然风光", + thumbnail: "https://xximg1.meitudata.com/N8eUq1aDk1.jpeg!thumb-w321-webp75", + material_id: "20079982003" + }, + { + name: "室内", + thumbnail: "https://xximg1.meitudata.com/LEasJPl8mE.jpeg!thumb-w321-webp75", + material_id: "20079982004" + }, + { + name: "室外", + thumbnail: "https://xximg1.meitudata.com/g5eFOyEePx.jpeg!thumb-w321-webp75", + material_id: "20079982005" + }, + { + name: "老人", + thumbnail: "https://xximg1.meitudata.com/vgzUl2EGV5.jpeg!thumb-w321-webp75", + material_id: "20079982006" + }, + { + name: "街道复用", + thumbnail: "https://xximg1.meitudata.com/QEasmNjL8x.jpeg!thumb-w321-webp75", + material_id: "20079981781" + }, + { + name: "大师1", + thumbnail: "https://xximg1.meitudata.com/wgNU30boQ4.png!thumb-w321-webp75", + material_id: "20079981962" + }, + { + name: "大师2", + thumbnail: "https://xximg1.meitudata.com/YkpU1yPmPa.png!thumb-w321-webp75", + material_id: "20079981963" + }, + { + name: "大师3", + thumbnail: "https://xximg1.meitudata.com/qRdTJOZYn8.png!thumb-w321-webp75", + material_id: "20079981964" + }, + { + name: "大师4", + thumbnail: "https://xximg1.meitudata.com/LEasJoKld4.png!thumb-w321-webp75", + material_id: "20079981965" + }, + { + name: "大师5", + thumbnail: "https://xximg1.meitudata.com/KeVUaQnzez.png!thumb-w321-webp75", + material_id: "20079981966" + }, + { + name: "大师6", + thumbnail: "https://xximg1.meitudata.com/BNGiP6vklD.png!thumb-w321-webp75", + material_id: "20079981967" + }, + { + name: "大师7", + thumbnail: "https://xximg1.meitudata.com/wgNU30boLG.png!thumb-w321-webp75", + material_id: "20079981968" + }, + { + name: "大师8", + thumbnail: "https://xximg1.meitudata.com/j4Gce54yGg.png!thumb-w321-webp75", + material_id: "20079981969" + }, + { + name: "大师9", + thumbnail: "https://xximg1.meitudata.com/g5eFO8dEYO.png!thumb-w321-webp75", + material_id: "20079981970" + }, + { + name: "模糊相机测试", + thumbnail: "https://xximg1.meitudata.com/wgNU3GgL0p.png!thumb-w321-webp75", + material_id: "20079982016" + }, + { + name: "", + thumbnail: "https://xximg1.meitudata.com/g5eFOoOWnK.png!thumb-w321-webp75", + material_id: "20079981872" + }, + { + name: "复古", + thumbnail: "https://xximg1.meitudata.com/x5NFQGlPeD.png!thumb-w321-webp75", + material_id: "20079982026" + }, + { + name: "夜景抠图", + thumbnail: "https://xximg1.meitudata.com/qRdTJOxoK4.png!thumb-w321-webp75", + material_id: "20079981936" + }, + { + name: "我爱中国", + thumbnail: "https://xximg1.meitudata.com/3YDhOJgLgp.png!thumb-w321-webp75", + material_id: "20079981422" + }, + { + name: "", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/oJQiW3WX68vDyaW.jpeg!thumb-w321-webp75", + material_id: "20079992271" + }, + { + name: "桃子奶油", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/lk0HjR5ealbk2Ze.jpeg!thumb-w321-webp75", + material_id: "20079992275" + }, + { + name: "橘粉奶油", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/5JOi8ZVNnqE8w8g.jpeg!thumb-w321-webp75", + material_id: "20079990090" + }, + { + name: "", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/DyOHJnqNb5o8LQg.jpeg!thumb-w321-webp75", + material_id: "20079992277" + }, + { + name: "", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/y59IlX8wQXoNGEK.jpeg!thumb-w321-webp75", + material_id: "20079992276" + }, + { + name: "", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/dWku02V3BpYDylY.jpeg!thumb-w321-webp75", + material_id: "20079990081" + }, + { + name: "", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/p0GcOvOamLXoD3Z.jpeg!thumb-w321-webp75", + material_id: "20079992273" + }, + { + name: "", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/6kOHqmQ3qjPoYQa.jpeg!thumb-w321-webp75", + material_id: "20079992266" + }, + { + name: "", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/RwXHJpZKvlQK2GJ.jpeg!thumb-w321-webp75", + material_id: "20079992267" + }, + { + name: "", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/2zVHE2XGb3d0xgv.jpeg!thumb-w321-webp75", + material_id: "20079990045" + }, + { + name: "炫光", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/dWku0XJZxGgDLO9.jpeg!thumb-w321-webp75", + material_id: "20079992229" + }, + { + name: "CG3", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/JdXHB6LLY8agV8O.jpeg!thumb-w321-webp75", + material_id: "20079992238" + }, + { + name: "CG测试2", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/j4QUVv66nq0P55z.jpeg!thumb-w321-webp75", + material_id: "20079991111" + }, + { + name: "国庆挂历2", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/YkVHj0oP36pmOL1.jpeg!thumb-w321-webp75", + material_id: "20079999999" + }, + { + name: "美化国庆挂历", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/g5yIKQJdqK1aBlQ.jpeg!thumb-w321-webp75", + material_id: "20079998888" + }, + { + name: "在逃公主", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/N8RHzY8o4oKQqEJ.jpeg!thumb-w321-webp75", + material_id: "20079992200" + }, + { + name: "2020美颜默认", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/qR1tRvwgl5mmZDp.jpeg!thumb-w321-webp75", + material_id: "20079990088" + }, + { + name: "复古画册", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/zq9HXROgvWQpXJp.jpeg!thumb-w321-webp75", + material_id: "20079990080" + }, + { + name: "美食1", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/PBXUkeGKl4.jpeg!thumb-w321-webp75", + material_id: "20079990060" + }, + { + name: "美食改", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/8QYIwP5P0x.jpeg!thumb-w321-webp75", + material_id: "20079990059" + }, + { + name: "细细闪", + thumbnail: "https://xximg1.meitudata.com/XeVHPQGmWg.jpeg!thumb-w321-webp75", + material_id: "20079991001" + }, + { + name: "细细闪2", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/qR1tRvRVBLmGaQK.jpeg!thumb-w321-webp75", + material_id: "20079990069" + }, + { + name: "新闪闪1", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/aOWsGzGNdEOkngB.jpeg!thumb-w321-webp75", + material_id: "20079990068" + }, + { + name: "新闪闪3-2", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/qR1tRvbq9BkKZZv.jpeg!thumb-w321-webp75", + material_id: "20079990078" + }, + { + name: "新闪闪5", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/j4QUVwNX4q6LV80.jpeg!thumb-w321-webp75", + material_id: "20079990077" + }, + { + name: "天空闪-橙", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/wgRHvqkwVNgzaQO.jpeg!thumb-w321-webp75", + material_id: "20079990073" + }, + { + name: "新说3", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/6kOHRdweoL.jpeg!thumb-w321-webp75", + material_id: "20079990057" + }, + { + name: "新说2", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/QEXSmQ3JNP.jpeg!thumb-w321-webp75", + material_id: "20079990056" + }, + { + name: "新说", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/nBqUo2nYVw.jpeg!thumb-w321-webp75", + material_id: "20079990055" + }, + { + name: "少女胶片颗粒", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/EPdUL929P1.jpeg!thumb-w321-webp75", + material_id: "20079990053" + }, + { + name: "折纸3", + thumbnail: "https://xximg1.meitudata.com/j4QUeqxb8N.jpeg!thumb-w321-webp75", + material_id: "20079990021" + }, + { + name: "折纸滤镜", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/dWkuagV42R.jpeg!thumb-w321-webp75", + material_id: "20079990050" + }, + { + name: "温柔纹理2", + thumbnail: "https://xximg1.meitudata.com/5JOiDgbOjz.jpeg!thumb-w321-webp75", + material_id: "20079990003" + }, + { + name: "温柔纹理", + thumbnail: "https://xximg1.meitudata.com/mbZHy9Kyd4.jpeg!thumb-w321-webp75", + material_id: "20079990024" + }, + { + name: "油画新说1", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/dWkuaga464.jpeg!thumb-w321-webp75", + material_id: "20079990054" + }, + { + name: "油画新说2", + thumbnail: "https://xximg1.meitudata.com/V2jTkpeb8e.jpeg!thumb-w321-webp75", + material_id: "20079990001" + }, + { + name: "油画新说3", + thumbnail: "https://xximg1.meitudata.com/8QYIw15O85.jpeg!thumb-w321-webp75", + material_id: "20079991994" + }, + { + name: "珍珠2", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/zq9H5VqpGo.jpeg!thumb-w321-webp75", + material_id: "20079990043" + }, + { + name: "珍珠", + thumbnail: "https://xximg1.meitudata.com/dWkua4m2NL.jpeg!thumb-w321-webp75", + material_id: "20079991002" + }, + { + name: "爱心月亮", + thumbnail: "https://xximg1.meitudata.com/LEKSJEmG9L.png!thumb-w321-webp75", + material_id: "20079990041" + }, + { + name: "星星月亮", + thumbnail: "https://xximg1.meitudata.com/3YVfOV8JWX.jpeg!thumb-w321-webp75", + material_id: "20079990040" + }, + { + name: "钢笔淡彩", + thumbnail: "https://xximg1.meitudata.com/6kOHRlg2E8.jpeg!thumb-w321-webp75", + material_id: "20079990039" + }, + { + name: "拯救废片2", + thumbnail: "https://xximg1.meitudata.com/KeEHax9bao.jpeg!thumb-w321-webp75", + material_id: "20079990038" + }, + { + name: "书本感", + thumbnail: "https://xximg1.meitudata.com/WYBfmxXLVz.jpeg!thumb-w321-webp75", + material_id: "20079990036" + }, + { + name: "拯救废片1", + thumbnail: "https://xximg1.meitudata.com/dWkuaGDnaG.jpeg!thumb-w321-webp75", + material_id: "20079990037" + }, + { + name: "夏日4", + thumbnail: "https://xximg1.meitudata.com/j4QUeglDGW.jpeg!thumb-w321-webp75", + material_id: "20079990035" + }, + { + name: "夏日2", + thumbnail: "https://xximg1.meitudata.com/zq9H5obmPq.jpeg!thumb-w321-webp75", + material_id: "20079990034" + }, + { + name: "夏日3", + thumbnail: "https://xximg1.meitudata.com/lk0Hk4z4JE.jpeg!thumb-w321-webp75", + material_id: "20079990033" + }, + { + name: "春日柔光", + thumbnail: "https://xximg1.meitudata.com/oJQinkgLpN.jpeg!thumb-w321-webp75", + material_id: "20079992020" + }, + { + name: "春日日系", + thumbnail: "https://xximg1.meitudata.com/JdXHWgQ588.jpeg!thumb-w321-webp75", + material_id: "20079990022" + }, + { + name: "2020情人节2", + thumbnail: "https://xximg1.meitudata.com/p0GcZg6o2m.jpeg!thumb-w321-webp75", + material_id: "20079990017" + }, + { + name: "11", + thumbnail: "https://xximg1.meitudata.com/j4QUeR0ylz.jpeg!thumb-w321-webp75", + material_id: "20079990014" + }, + { + name: "锐化+颗粒", + thumbnail: "https://xximg1.meitudata.com/nBqUoWm5Eq.jpeg!thumb-w321-webp75", + material_id: "20079990015" + }, + { + name: "22", + thumbnail: "https://xximg1.meitudata.com/EPdULoXbK8.jpeg!thumb-w321-webp75", + material_id: "20079990004" + }, + { + name: "2019圣诞2", + thumbnail: "https://xximg1.meitudata.com/aOWsL0gy9L.jpeg!thumb-w321-webp75", + material_id: "20079990008" + }, + { + name: "bling裸妆", + thumbnail: "https://xximg1.meitudata.com/Z3Vspe2qwl.jpeg!thumb-w321-webp75", + material_id: "20079991976" + }, + { + name: "水雾", + thumbnail: "https://xximg1.meitudata.com/eqOHv8b9Jy.jpeg!thumb-w321-webp75", + material_id: "20079990009" + }, + { + name: "泫雅柔光2", + thumbnail: "https://xximg1.meitudata.com/1zVH1X80BW.jpeg!thumb-w321-webp75", + material_id: "20079990000" + }, + { + name: "无辜妆", + thumbnail: "https://xximg1.meitudata.com/8QYIw5OwzQ.jpeg!thumb-w321-webp75", + material_id: "20079990020" + }, + { + name: "2023", + thumbnail: "https://xximg1.meitudata.com/WYBfmyJ4jO.jpeg!thumb-w321-webp75", + material_id: "20079992023" + }, + { + name: "风格妆22", + thumbnail: "https://xximg1.meitudata.com/y59IbNv8ek.jpeg!thumb-w321-webp75", + material_id: "20079990013" + }, + { + name: "吸色测试", + thumbnail: "https://xximg1.meitudata.com/g5yIOn36zo.jpeg!thumb-w321-webp75", + material_id: "20079991234" + }, + { + name: "爱国", + thumbnail: "https://xximg1.meitudata.com/nBqUonb8dG.jpeg!thumb-w321-webp75", + material_id: "20079991919" + }, + { + name: "春樱改良", + thumbnail: "https://xximg1.meitudata.com/2zVH1mYp8m.jpeg!thumb-w321-webp75", + material_id: "20079991858" + }, + { + name: "爱心阴影", + thumbnail: "https://xximg1.meitudata.com/8QYIw59nPj.jpeg!thumb-w321-webp75", + material_id: "20079991935" + }, + { + name: "无辜妆2", + thumbnail: "https://xximg1.meitudata.com/LEKSJPXj2E.jpeg!thumb-w321-webp75", + material_id: "20079990006" + }, + { + name: "1993", + thumbnail: "https://xximg1.meitudata.com/vgyHlz3kOv.jpeg!thumb-w321-webp75", + material_id: "20079991993" + }, + { + name: "皮肤质感3", + thumbnail: "https://xximg1.meitudata.com/LEKSJooQb8.jpeg!thumb-w321-webp75", + material_id: "20079991113" + }, + { + name: "皮肤质感2", + thumbnail: "https://xximg1.meitudata.com/p0GcZPPXNW.jpeg!thumb-w321-webp75", + material_id: "20079991112" + }, + { + name: "皮肤质感", + thumbnail: "https://xximg1.meitudata.com/WYBfmDvxQK.jpeg!thumb-w321-webp75", + material_id: "20079991884" + }, + { + name: "万圣2", + thumbnail: "https://xximg1.meitudata.com/dWkuap6DpQ.jpeg!thumb-w321-webp75", + material_id: "20079991866" + }, + { + name: "闪闪压缩2", + thumbnail: "https://xximg1.meitudata.com/BNPTP2XB6X.jpeg!thumb-w321-webp75", + material_id: "20079990030" + }, + { + name: "闪闪压缩", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/oJQiWKQQE3VWLKR.jpeg!thumb-w321-webp75", + material_id: "20079990076" + }, + { + name: "复古画册加纸纹", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/QEXSyJENWDbBkna.jpeg!thumb-w321-webp75", + material_id: "20079990079" + }, + { + name: "新闪闪2", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/KeEHpDpzvPgVOqY.jpeg!thumb-w321-webp75", + material_id: "20079990067" + }, + { + name: "新闪闪4", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/mbZHO5dyaXPe91g.jpeg!thumb-w321-webp75", + material_id: "20079990072" + }, + { + name: "天空闪", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/bBLUYpzJY518dqa.jpeg!thumb-w321-webp75", + material_id: "20079990070" + }, + { + name: "美食3改", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/RwXHmlPzDO.jpeg!thumb-w321-webp75", + material_id: "20079990058" + }, + { + name: "质感胶片颗粒", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/1zVH1pkp0o.jpeg!thumb-w321-webp75", + material_id: "20079990052" + }, + { + name: "雀斑", + thumbnail: "https://xximg1.meitudata.com/bBLUvke8mb.jpeg!thumb-w321-webp75", + material_id: "20079991000" + }, + { + name: "春日柔光1", + thumbnail: "https://xximg1.meitudata.com/KeEHa9ZGYO.jpeg!thumb-w321-webp75", + material_id: "20079990031" + }, + { + name: "灰调2", + thumbnail: "https://xximg1.meitudata.com/JdXHW51qgp.jpeg!thumb-w321-webp75", + material_id: "20079990002" + }, + { + name: "移轴虚化2", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/WYBf3WkazQXvlwl.jpeg!thumb-w321-webp75", + material_id: "506000008" + }, + { + name: "", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/6kOHqmdRWjl4BEm.jpeg!thumb-w321-webp75", + material_id: "50600006" + }, + { + name: "微光", + thumbnail: "https://xximg1.meitudata.com/KeEHa4wl8p.jpeg!thumb-w321-webp75", + material_id: "20076251574" + }, + { + name: "微光", + thumbnail: "https://xximg1.meitudata.com/eqZUvNY3YL.png!thumb-w321-webp75", + material_id: "20076251567" + }, + { + name: "微光", + thumbnail: "https://xximg1.meitudata.com/BNPTPoVbeV.jpeg!thumb-w321-webp75", + material_id: "20076251575" + }, + { + name: "微光", + thumbnail: "https://xximg1.meitudata.com/bBZcvmqk8z.png!thumb-w321-webp75", + material_id: "20076251568" + }, + { + name: "微光", + thumbnail: "https://xximg1.meitudata.com/g5yIOPJmZn.jpeg!thumb-w321-webp75", + material_id: "20076251573" + }, + { + name: "微光", + thumbnail: "https://xximg1.meitudata.com/5JeHDVNROj.png!thumb-w321-webp75", + material_id: "20076251569" + }, + { + name: "微光", + thumbnail: "https://xximg1.meitudata.com/wgNU3PJVzR.png!thumb-w321-webp75", + material_id: "20076251577" + }, + { + name: "17.素材无人脸规则", + thumbnail: "https://xxtool-release.zone1.meitudata.com/owv1PzKKkaEz.jpg!thumb-w321-webp75", + material_id: "506088832" + }, + { + name: "22.天空分割滤镜", + thumbnail: "https://xxtool-release.zone1.meitudata.com/laM7B2WRZRve.jpg!thumb-w321-webp75", + material_id: "506088818" + }, + { + name: "11.柔发效果支持", + thumbnail: "https://xxtool-release.zone1.meitudata.com/L24ZJRgYjyw5.png!thumb-w321-webp75", + material_id: "506088812" + }, + { + name: "13.3D打光", + thumbnail: "https://xxtool-release.zone1.meitudata.com/owv1PzXYWoxL.png!thumb-w321-webp75", + material_id: "506088810" + }, + { + name: "(仅日本)10.不带妆容", + thumbnail: "https://xxtool-release.zone1.meitudata.com/y1B45rOXGkBW.jpeg!thumb-w321-webp75", + material_id: "506088811" + }, + { + name: "12.妆容滤镜层级控制1", + thumbnail: "https://xxtool-release.zone1.meitudata.com/e4xlJA94A6Mp.png!thumb-w321-webp75", + material_id: "506088831" + }, + { + name: "6.强制曝光滤镜", + thumbnail: "https://xxtool-release.zone1.meitudata.com/kOo1k0DW9drL.jpg!thumb-w321-webp75", + material_id: "506088835" + }, + { + name: "5.男生、女生滤镜", + thumbnail: "https://xxtool-release.zone1.meitudata.com/OmB4J1oagj0M.jpg!thumb-w321-webp75", + material_id: "506088815" + }, + { + name: "4.带有动效滤镜", + thumbnail: "https://xxtool-release.zone1.meitudata.com/V06dJl3051WA.jpg!thumb-w321-webp75", + material_id: "506088823" + }, + { + name: "12.妆容滤镜层级控制", + thumbnail: "https://xxtool-release.zone1.meitudata.com/kOo1k0Nva6LL.png!thumb-w321-webp75", + material_id: "506088816" + }, + { + name: "3.妆容滤镜", + thumbnail: "https://xxtool-release.zone1.meitudata.com/OmB4J13jO5Dg.jpg!thumb-w321-webp75", + material_id: "506088822" + }, + { + name: "2.bling滤镜", + thumbnail: "https://xxtool-release.zone1.meitudata.com/e4xlJA9WZJoy.jpg!thumb-w321-webp75", + material_id: "506088834" + }, + { + name: "1.随机滤镜", + thumbnail: "https://xxtool-release.zone1.meitudata.com/GYZza015D1LE.jpg!thumb-w321-webp75", + material_id: "506088824" + }, + { + name: "19.素材多比例滤镜", + thumbnail: "https://xxtool-release.zone1.meitudata.com/B6MlzDxYm10N.jpg!thumb-w321-webp75", + material_id: "506088821" + }, + { + name: "16.美食手绘效果", + thumbnail: "https://xxtool-release.zone1.meitudata.com/4JpRm4Em6Y7J.jpg!thumb-w321-webp75", + material_id: "506088833" + }, + { + name: "16.美食手绘效果2", + thumbnail: "https://xxtool-release.zone1.meitudata.com/3zVRNe69zMKM.jpg!thumb-w321-webp75", + material_id: "506088829" + }, + { + name: "23.妆容滤镜", + thumbnail: "https://xxtool-release.zone1.meitudata.com/L24ZJRgjNYWe.jpg!thumb-w321-webp75", + material_id: "506088814" + }, + { + name: "18.径向色散效果", + thumbnail: "https://xxtool-release.zone1.meitudata.com/y1B45rOEZeMP.jpg!thumb-w321-webp75", + material_id: "506088813" + }, + { + name: "14.新bling效果", + thumbnail: "https://xxtool-release.zone1.meitudata.com/y1B45rp8Ky7z.png!thumb-w321-webp75", + material_id: "506088837" + }, + { + name: "绵绵", + thumbnail: "https://xximg1.meitudata.com/EPdUL42bLj.jpeg!thumb-w321-webp75", + material_id: "20076412020" + }, + { + name: "清澈", + thumbnail: "https://xximg1.meitudata.com/nBqUo6pveO.jpeg!thumb-w321-webp75", + material_id: "20076412057" + }, + { + name: "阴雨", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/N3OFzPJbwBgXG6z.jpeg!thumb-w321-webp75", + material_id: "506002342" + }, + { + name: "ar胶片", + thumbnail: "https://xximg1.meitudata.com/lkjUk85p5G.png!thumb-w321-webp75", + material_id: "20108891781" + }, + { + name: "INS", + thumbnail: "https://xximg1.meitudata.com/bBLUv93q2O.jpeg!thumb-w321-webp75", + material_id: "20108890012" + }, + { + name: "高级灰", + thumbnail: "https://xximg1.meitudata.com/jzOIeJz1mK.png!thumb-w321-webp75", + material_id: "20108891777" + }, + { + name: "夜景2", + thumbnail: "https://xximg1.meitudata.com/1zVH1nl3nL.jpeg!thumb-w321-webp75", + material_id: "20108890014" + }, + { + name: "藕色颗粒", + thumbnail: "https://xximg1.meitudata.com/V2jTkoQgO6.jpeg!thumb-w321-webp75", + material_id: "20108890015" + }, + { + name: "胶片1", + thumbnail: "https://xximg1.meitudata.com/KnJSa8gWE4.png!thumb-w321-webp75", + material_id: "20108891783" + }, + { + name: "fuji", + thumbnail: "https://xximg1.meitudata.com/qR1tJbvd5d.jpeg!thumb-w321-webp75", + material_id: "20108890010" + }, + { + name: "咸咸测试", + thumbnail: "https://xximg1.meitudata.com/EPdULqxXOR.jpeg!thumb-w321-webp75", + material_id: "20108899999" + }, + { + name: "古风藕色", + thumbnail: "https://xximg1.meitudata.com/JdXHWjK4o9.jpeg!thumb-w321-webp75", + material_id: "20108891775" + }, + { + name: "natural1", + thumbnail: "https://xximg1.meitudata.com/zq9H5ekDQv.jpeg!thumb-w321-webp75", + material_id: "20108891682" + }, + { + name: "受伤妆", + thumbnail: "https://xximg1.meitudata.com/nBqUoEKnoD.jpeg!thumb-w321-webp75", + material_id: "20108891787" + }, + { + name: "natural2", + thumbnail: "https://xximg1.meitudata.com/j4QUedKlNv.jpeg!thumb-w321-webp75", + material_id: "20108891848" + }, + { + name: "描边2", + thumbnail: "https://xximg1.meitudata.com/4VOC9QOZRd.jpeg!thumb-w321-webp75", + material_id: "20108891835" + }, + { + name: "natural3", + thumbnail: "https://xximg1.meitudata.com/9nOHy6gJOb.jpeg!thumb-w321-webp75", + material_id: "20108890019" + }, + { + name: "宝丽来1", + thumbnail: "https://xximg1.meitudata.com/JdXHW5qp88.jpeg!thumb-w321-webp75", + material_id: "20108891840" + }, + { + name: "日系复古", + thumbnail: "https://xximg1.meitudata.com/6zZIRWym8L.png!thumb-w321-webp75", + material_id: "20108891846" + }, + { + name: "暗调测试", + thumbnail: "https://xximg1.meitudata.com/YkVH1pNvLW.jpeg!thumb-w321-webp75", + material_id: "20108897777" + }, + { + name: "宝丽来2", + thumbnail: "https://xximg1.meitudata.com/6kOHRWaqeJ.jpeg!thumb-w321-webp75", + material_id: "20108891841" + }, + { + name: "海外柔光", + thumbnail: "https://xximg1.meitudata.com/p0GcZyqa5z.jpeg!thumb-w321-webp75", + material_id: "20108891801" + }, + { + name: "绯红", + thumbnail: "https://xximg1.meitudata.com/wgNU340lGP.png!thumb-w321-webp75", + material_id: "20108891770" + }, + { + name: "霜色", + thumbnail: "https://xximg1.meitudata.com/lkjUkL6GXp.png!thumb-w321-webp75", + material_id: "20108891769" + }, + { + name: "梅幸茶", + thumbnail: "https://xximg1.meitudata.com/GPWcPEw1Wj.png!thumb-w321-webp75", + material_id: "20108891771" + }, + { + name: "水墨", + thumbnail: "https://xximg1.meitudata.com/9nzUyjane8.png!thumb-w321-webp75", + material_id: "20108891772" + }, + { + name: "1780", + thumbnail: "https://xximg1.meitudata.com/vgyHlJoLg3.jpeg!thumb-w321-webp75", + material_id: "20108891780" + }, + { + name: "描边3", + thumbnail: "https://xximg1.meitudata.com/nBqUoz0g3y.jpeg!thumb-w321-webp75", + material_id: "20108891837" + }, + { + name: "描边4", + thumbnail: "https://xximg1.meitudata.com/1zVH1XvE4z.jpeg!thumb-w321-webp75", + material_id: "20108891838" + }, + { + name: "描边1", + thumbnail: "https://xximg1.meitudata.com/WYBfmdWOoQ.jpeg!thumb-w321-webp75", + material_id: "20108891834" + }, + { + name: "青空", + thumbnail: "https://xximg1.meitudata.com/8OkUwBympV.jpeg!thumb-w321-webp75", + material_id: "20106311844" + }, + { + name: "暮霭", + thumbnail: "https://xximg1.meitudata.com/9QktyzB0nW.jpeg!thumb-w321-webp75", + material_id: "20106311843" + }, + { + name: "糖果", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/qp4IReJkzbEZD41.jpeg!thumb-w321-webp75", + material_id: "506002348" + }, + { + name: "苏打", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/nplIo2XOm6.jpeg!thumb-w321-webp75", + material_id: "20096442168" + }, + { + name: "淡奶油", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/PVQIkeOx5L.jpeg!thumb-w321-webp75", + material_id: "20096442169" + }, + { + name: "温柔", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/N8RHqBW392.jpeg!thumb-w321-webp75", + material_id: "20096442166" + }, + { + name: "珠光", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/nBqUo2X8lP.jpeg!thumb-w321-webp75", + material_id: "20096442165" + }, + { + name: "丝绸", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/BNPTPWpNRL.jpeg!thumb-w321-webp75", + material_id: "20096442167" + }, + { + name: "黑白", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/OXOHRJnJ5vOXBpY.jpeg!thumb-w321-webp75", + material_id: "20096081095" + }, + { + name: "暗房", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/eqZU6dBdw3EY3d1.jpeg!thumb-w321-webp75", + material_id: "506002307" + }, + { + name: "低反差", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/4VQtnwmwpBL5wDN.jpeg!thumb-w321-webp75", + material_id: "506002309" + }, + { + name: "森山", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/1zXUmEWE4DWbQW2.jpeg!thumb-w321-webp75", + material_id: "506002313" + }, + { + name: "Instant", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/qRdTR9w9ygLqdeb.jpeg!thumb-w321-webp75", + material_id: "506002310" + }, + { + name: "范戴克", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/BNGiqXNXZkljKlb.jpeg!thumb-w321-webp75", + material_id: "506002312" + }, + { + name: "圣诞", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/PVQIdno4bnlEEOq.jpeg!thumb-w321-webp75", + material_id: "20076452266" + }, + { + name: "小梦境", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/2zVHEkJKPj3q5nz.jpeg!thumb-w321-webp75", + material_id: "20076452193" + }, + { + name: "在逃公主", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/lk0HjoJRKlq9E0Z.jpeg!thumb-w321-webp75", + material_id: "20076452200" + }, + { + name: "璀璨", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/DyOHJWjXJGk6Ojl.jpeg!thumb-w321-webp75", + material_id: "20076452189" + }, + { + name: "星河", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/LEKSjB8pREZExxZ.jpeg!thumb-w321-webp75", + material_id: "20076452180" + }, + { + name: "星河II", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/g5yIKQq99XvKZQP.jpeg!thumb-w321-webp75", + material_id: "20076452181" + }, + { + name: "星河III", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/oJQiWKVVJNXe3PB.jpeg!thumb-w321-webp75", + material_id: "20076452184" + }, + { + name: "年味", + thumbnail: "https://xximg1.meitudata.com/EVvILvqjRQ.jpeg!thumb-w321-webp75", + material_id: "20076352017" + }, + { + name: "白日梦 ", + thumbnail: "https://xximg1.meitudata.com/vgyHlzq34j.jpeg!thumb-w321-webp75", + material_id: "20076351989" + }, + { + name: "白桃", + thumbnail: "https://xximg1.meitudata.com/g5eFOnEgJj.png!thumb-w321-webp75", + material_id: "20076351888" + }, + { + name: "Norge", + thumbnail: "https://xximg1.meitudata.com/9nOHylkdjn.jpeg!thumb-w321-webp75", + material_id: "2007635584" + }, + { + name: "冬至", + thumbnail: "https://xximg1.meitudata.com/zqOU5K9Q5m.png!thumb-w321-webp75", + material_id: "20076351887" + }, + { + name: "红杉", + thumbnail: "https://xximg1.meitudata.com/QEasmkjv09.png!thumb-w321-webp75", + material_id: "20076351981" + }, + { + name: "暖暖 ", + thumbnail: "https://xximg1.meitudata.com/y59Ib9kQZw.jpeg!thumb-w321-webp75", + material_id: "20076351988" + }, + { + name: "神仙奶油光", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/XRLI50zwLEBpQ19.jpeg!thumb-w321-webp75", + material_id: "20096472176" + }, + { + name: "神仙奶油光Ⅱ", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/PVQIdB3VbL63GQN.jpeg!thumb-w321-webp75", + material_id: "20096472177" + }, + { + name: "法式油画", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/99ETGwRbEnKn9qd.jpeg!thumb-w321-webp75", + material_id: "20096472178" + }, + { + name: "法式油画Ⅱ", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/wkQsvqJNVn9GaaP.jpeg!thumb-w321-webp75", + material_id: "20096472179" + }, + { + name: "曼哈顿大桥", + thumbnail: "https://xximg1.meitudata.com/bBLUvjadBB.jpeg!thumb-w321-webp75", + material_id: "20106301861" + }, + { + name: "维多利亚港", + thumbnail: "https://xximg1.meitudata.com/wgRH3jVEDg.jpeg!thumb-w321-webp75", + material_id: "20106301862" + }, + { + name: "新宿", + thumbnail: "https://xximg1.meitudata.com/x5eIQyn1bp.jpeg!thumb-w321-webp75", + material_id: "20106301935" + }, + { + name: "那不勒斯", + thumbnail: "https://xximg1.meitudata.com/zqOU5LPDwe.png!thumb-w321-webp75", + material_id: "20106301936" + }, + { + name: "赛博朋克", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/ykGslXOBVOZ1wZm.jpeg!thumb-w321-webp75", + material_id: "20106302217" + }, + { + name: "盐系", + thumbnail: "https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/29gtLmJEWLAadDk.jpeg!thumb-w321-webp75", + material_id: "20096522258" + }, + { + name: "29", + thumbnail: "https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/wOXiNM4O8Jxyv7E.jpeg!thumb-w321-webp75", + material_id: "506030029" + }, + { + name: "28", + thumbnail: "https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/jkEIPyplzRPYXmP.jpeg!thumb-w321-webp75", + material_id: "506030028" + }, + { + name: "27", + thumbnail: "https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/JgpCWo3NL2G81JZ.jpeg!thumb-w321-webp75", + material_id: "506030027" + }, + { + name: "26", + thumbnail: "https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/DpWhZ42RzkXpDgW.jpeg!thumb-w321-webp75", + material_id: "5060230026" + }, + { + name: "25", + thumbnail: "https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/Ng9CWAVaM342ERY.jpeg!thumb-w321-webp75", + material_id: "506030025" + }, + { + name: "24", + thumbnail: "https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/3MLhOxa9x2m49Rp.jpeg!thumb-w321-webp75", + material_id: "506030024" + }, + { + name: "23", + thumbnail: "https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/Ng9CWAVy999Ea27.jpeg!thumb-w321-webp75", + material_id: "506030023" + }, + { + name: "22", + thumbnail: "https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/mjkuw39egW2Lv9V.jpeg!thumb-w321-webp75", + material_id: "506030022" + }, + { + name: "21", + thumbnail: "https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/9L1IrA1E6l7799X.jpeg!thumb-w321-webp75", + material_id: "506030021" + }, + { + name: "20", + thumbnail: "https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/rOwi0AkzJo210E5.jpeg!thumb-w321-webp75", + material_id: "506030020" + }, + { + name: "19", + thumbnail: "https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/ed7IAoW6mr4OVwl.jpeg!thumb-w321-webp75", + material_id: "506030019" + }, + { + name: "18", + thumbnail: "https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/3MLhOx2A2R5GJom.jpeg!thumb-w321-webp75", + material_id: "506030018" + }, + { + name: "17", + thumbnail: "https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/DpWhZ4mE9OZYEv2.jpeg!thumb-w321-webp75", + material_id: "506030017" + }, + { + name: "16", + thumbnail: "https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/lK4H8LpVG7o8ZWo.jpeg!thumb-w321-webp75", + material_id: "506030016" + }, + { + name: "15", + thumbnail: "https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/JgpCWoverVMGlGE.jpeg!thumb-w321-webp75", + material_id: "506030015" + }, + { + name: "14", + thumbnail: "https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/rOwi0Akmj2Wrg8e.jpeg!thumb-w321-webp75", + material_id: "506030014" + }, + { + name: "13", + thumbnail: "https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/ZWdUX61ERRREYx7.jpeg!thumb-w321-webp75", + material_id: "506030013" + }, + { + name: "12", + thumbnail: "https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/Ng9CWAdDvZDZWN0.jpeg!thumb-w321-webp75", + material_id: "506030012" + }, + { + name: "10", + thumbnail: "https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/5O0iJdZB9VKpZYK.jpeg!thumb-w321-webp75", + material_id: "506030006" + }, + { + name: "9", + thumbnail: "https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/AY4T4jpeo29dAJY.jpeg!thumb-w321-webp75", + material_id: "506030005" + }, + { + name: "8", + thumbnail: "https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/EZNHdk171m9Z1Zp.jpeg!thumb-w321-webp75", + material_id: "506030004" + }, + { + name: "7", + thumbnail: "https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/ed7IAorRPGr2DV1.jpeg!thumb-w321-webp75", + material_id: "506030003" + }, + { + name: "测试红点6", + thumbnail: "https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/wOXiNMwZDXGyaOW.jpeg!thumb-w321-webp75", + material_id: "506030002" + }, + { + name: "测试红点5", + thumbnail: "https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/9L1IrAz4yYjKLOp.jpeg!thumb-w321-webp75", + material_id: "506030001" + }, + { + name: "测试红点4", + thumbnail: "https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/EZNHdk1owgyDp9Z.jpeg!thumb-w321-webp75", + material_id: "5060238998" + }, + { + name: "测试红点3", + thumbnail: "https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/3MLhOxDGxyVLwmV.jpeg!thumb-w321-webp75", + material_id: "5060238997" + }, + { + name: "测试红点2", + thumbnail: "https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/jkEIPyVeNwvW4X8.jpeg!thumb-w321-webp75", + material_id: "5060238996" + }, + { + name: "测试红点", + thumbnail: "https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/3MLhOxDGZNlxerJ.jpeg!thumb-w321-webp75", + material_id: "5060238995" + }, + { + name: "123", + thumbnail: "https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/8LxIzOLaGM06Ekx.jpeg!thumb-w321-webp75", + material_id: "5060238991" + }, + { + name: "小草3", + thumbnail: "https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/09mIW9BGz4DdNPK.jpeg!thumb-w321-webp75", + material_id: "5060238990" + }, + { + name: "小草2", + thumbnail: "https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/wOXiNMPBxwoymBv.jpeg!thumb-w321-webp75", + material_id: "5060238989" + }, + { + name: "小草", + thumbnail: "https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/rOwi0AO9BdZzzkv.jpeg!thumb-w321-webp75", + material_id: "5060238988" + }, + { + name: "星星1", + thumbnail: "https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/71zSrY2veyMDEaE.jpeg!thumb-w321-webp75", + material_id: "506010255" + }, + { + name: "小树1", + thumbnail: "https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/4AVSv70z5YzveBy.jpeg!thumb-w321-webp75", + material_id: "506010256" + }, + { + name: "小花4", + thumbnail: "https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/G5wUz1B4zNpRE0P.jpeg!thumb-w321-webp75", + material_id: "506010254" + }, + { + name: "31", + thumbnail: "https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/Kg2CJr4d5PKRP4p.jpeg!thumb-w321-webp75", + material_id: "506030031" + }, + { + name: "西西里", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/yNmTl3VBD1Nz5yE.jpeg!thumb-w321-webp75", + material_id: "506002337" + }, + { + name: "尼斯", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/5JeH8E3e6Vvq8YY.jpeg!thumb-w321-webp75", + material_id: "506002331" + }, + { + name: "布达佩斯", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/lkjUjRxbeV2moG0.jpeg!thumb-w321-webp75", + material_id: "20096082224" + }, + { + name: "月升", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/qRdTRadQlQanwQa.jpeg!thumb-w321-webp75", + material_id: "20096082225" + }, + { + name: "聚会", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/5JeH8ZOg14O3Jq6.jpeg!thumb-w321-webp75", + material_id: "20096082226" + }, + { + name: "法兰西", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/8QzFJz90eZ3lExp.jpeg!thumb-w321-webp75", + material_id: "20096082227" + }, + { + name: "油画", + thumbnail: "https://xximg1.meitudata.com/BNPTPRjbyl.jpeg!thumb-w321-webp75", + material_id: "20096082032" + }, + { + name: "油画Ⅱ", + thumbnail: "https://xximg1.meitudata.com/8QYIw41QVq.jpeg!thumb-w321-webp75", + material_id: "20096082033" + }, + { + name: "安东尼亚", + thumbnail: "https://xximg1.meitudata.com/2LqS1vmqv0.png!thumb-w321-webp75", + material_id: "20096082038" + }, + { + name: "情人节限定", + thumbnail: "https://xximg1.meitudata.com/8QYIwbzm81.jpeg!thumb-w321-webp75", + material_id: "20096082019" + }, + { + name: "勒芒", + thumbnail: "https://xximg1.meitudata.com/ndzuolR3v9.jpeg!thumb-w321-webp75", + material_id: "20096081869" + }, + { + name: "电影", + thumbnail: "https://xximg1.meitudata.com/PBXUkm2yq5.jpeg!thumb-w321-webp75", + material_id: "20096081274" + }, + { + name: "1980", + thumbnail: "http://xximg2.meitudata.com/LEKSJx0N8y.jpeg!thumb-w321-webp75", + material_id: "20096081108" + }, + { + name: "电影", + thumbnail: "http://xximg2.meitudata.com/6kOHRa1OpD.jpeg!thumb-w321-webp75", + material_id: "20096081253" + }, + { + name: "中环码头", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/496TnZaRxddxonY.jpeg!thumb-w321-webp75", + material_id: "2009608530" + }, + { + name: "显影", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/8QYIJLL6NE94K2l.jpeg!thumb-w321-webp75", + material_id: "20086391964" + }, + { + name: "焦点", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/8QYIJLL6o5PVGyv.jpeg!thumb-w321-webp75", + material_id: "20086391965" + }, + { + name: "扫街", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/5JOi8ooNJ25wpg2.jpeg!thumb-w321-webp75", + material_id: "20086391963" + }, + { + name: "Photog", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/OX8iREk4LJ3qgad.jpeg!thumb-w321-webp75", + material_id: "20086391968" + }, + { + name: "超焦距", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/5JOi8ZQeZkvzQQD.jpeg!thumb-w321-webp75", + material_id: "20086391970" + }, + { + name: "影调", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/XeVH5bx1bz4NVdk.jpeg!thumb-w321-webp75", + material_id: "20086391967" + }, + { + name: "名称一", + thumbnail: "https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/MKosgAWo5VKpo9Z.jpeg!thumb-w321-webp75", + material_id: "50600999" + }, + { + name: "修改测试", + thumbnail: "https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/69MiA9VxKdkzjWR.png!thumb-w321-webp75", + material_id: "50600229" + }, + { + name: "有门槛的我", + thumbnail: "https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/P98i3gdgDw3Rmx5.png!thumb-w321-webp75", + material_id: "506093422" + }, + { + name: "222嗯嗯1", + thumbnail: "https://stage.meitudata.com/public/creator/ed70a3c696c8e7b.jpg!thumb-w321-webp75", + material_id: "50693244" + }, + { + name: "抠图批量拼图", + thumbnail: "https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/pA2S9lvNpMY4X3N.jpeg!thumb-w321-webp75", + material_id: "506002368" + }, + { + name: "滤镜流程11", + thumbnail: "https://material-center-pre.meitudata.com/material/image/6194a57b5b9ef7678.jpg!thumb-w321-webp75", + material_id: "506017292" + }, + { + name: "月辉", + thumbnail: "https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/wOXiBYpWgxA7ej5.jpeg!thumb-w321-webp75", + material_id: "5060112313" + }, + { + name: "旧-美食手绘1", + thumbnail: "https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/0lZCW9BrDgMroLL.jpeg!thumb-w321-webp75", + material_id: "5060002001" + }, + { + name: "hsxTest11.8", + thumbnail: "https://material-center-pre.meitudata.com/material/image/6189f29b48f165954.jpg!thumb-w321-webp75", + material_id: "506530963" + }, + { + name: "GT G", + thumbnail: "http://xximg2.meitudata.com/Z9DCJpkB2l.jpeg!thumb-w321-webp75", + material_id: "20085081215" + }, + { + name: "自然", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/j4QUVvP9GPkJ4n3.jpeg!thumb-w321-webp75", + material_id: "20076051317" + }, + { + name: "自然", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/5JOi8o1nKlqXmb2.jpeg!thumb-w321-webp75", + material_id: "20076051233" + }, + { + name: "Room", + thumbnail: "https://xximg1.meitudata.com/WYphm4QnOx.jpeg!thumb-w321-webp75", + material_id: "20076052148" + }, + { + name: "模糊", + thumbnail: "https://xximg1.meitudata.com/qR1tJmaVZg.jpeg!thumb-w321-webp75", + material_id: "20076052016" + }, + { + name: "追光", + thumbnail: "https://xximg1.meitudata.com/mbZHyl6E8Y.jpeg!thumb-w321-webp75", + material_id: "20076051714" + }, + { + name: "春樱", + thumbnail: "https://xximg1.meitudata.com/OX8i0kV1vG.jpeg!thumb-w321-webp75", + material_id: "20076051634" + }, + { + name: "夏橙", + thumbnail: "https://xximg1.meitudata.com/YkVH1doZzv.jpeg!thumb-w321-webp75", + material_id: "20076051635" + }, + { + name: "梨花白", + thumbnail: "https://xximg1.meitudata.com/bBLUvgJmoK.jpeg!thumb-w321-webp75", + material_id: "20076051633" + }, + { + name: "青柠", + thumbnail: "https://xximg1.meitudata.com/gn9SOPYgQ6.jpeg!thumb-w321-webp75", + material_id: "20076051733" + }, + { + name: "西柚", + thumbnail: "https://xximg1.meitudata.com/WXgfmKYZJv.jpeg!thumb-w321-webp75", + material_id: "20076051628" + }, + { + name: "恋人未满", + thumbnail: "https://xximg1.meitudata.com/3YVfO0zBXJ.jpeg!thumb-w321-webp75", + material_id: "20076051075" + }, + { + name: "春樱", + thumbnail: "https://xximg1.meitudata.com/k5DIOxgJpN.jpeg!thumb-w321-webp75", + material_id: "20076291634" + }, + { + name: "自然", + thumbnail: "https://xximg1.meitudata.com/nBqUoGPX5Q.jpeg!thumb-w321-webp75", + material_id: "20076051907" + }, + { + name: "Forest", + thumbnail: "https://xximg1.meitudata.com/V2jTkoYa96.jpeg!thumb-w321-webp75", + material_id: "20106191835" + }, + { + name: "高级灰Ⅱ", + thumbnail: "https://xximg1.meitudata.com/LEKSJO5x8V.jpeg!thumb-w321-webp75", + material_id: "20076051853" + }, + { + name: "晴空", + thumbnail: "https://xximg1.meitudata.com/LEKSJO5VaL.jpeg!thumb-w321-webp75", + material_id: "20076052027" + }, + { + name: "白兔糖", + thumbnail: "https://xximg1.meitudata.com/k5DIOjzV9d.jpeg!thumb-w321-webp75", + material_id: "2007605675" + }, + { + name: "测", + thumbnail: "https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/zwdte8R2e5KMMmm.jpeg!thumb-w321-webp75", + material_id: "506000000" + }, + { + name: "素颜", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/DyOHJNKyxWGbpeg.jpeg!thumb-w321-webp75", + material_id: "20076052222" + }, + { + name: "奶杏", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/3YVf1DOlq5jVlLe.jpeg!thumb-w321-webp75", + material_id: "20076052221" + }, + { + name: "蜜桃", + thumbnail: "https://xximg1.meitudata.com/9QktygQgDn.jpeg!thumb-w321-webp75", + material_id: "20076291732" + }, + { + name: "青柠", + thumbnail: "https://xximg1.meitudata.com/edzuvqDqwJ.jpeg!thumb-w321-webp75", + material_id: "20076291733" + }, + { + name: "西柚", + thumbnail: "https://xximg1.meitudata.com/kGVuOxgxm5.jpeg!thumb-w321-webp75", + material_id: "20076291628" + }, + { + name: "牛油果", + thumbnail: "https://xximg1.meitudata.com/1zXU1zyp3V.jpeg!thumb-w321-webp75", + material_id: "20076292053" + }, + { + name: "胶片字体1", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/wkQsv9BqOlk01j6.jpeg!thumb-w321-webp75", + material_id: "506001241" + }, + { + name: "503cw", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/YadfjNxP2ng3b0v.jpeg!thumb-w321-webp75", + material_id: "506001236" + }, + { + name: "爱心", + thumbnail: "https://xximg1.meitudata.com/8D5Fwm9VLE.jpeg!thumb-w321-webp75", + material_id: "20079971111" + }, + { + name: "", + thumbnail: "https://xximg1.meitudata.com/xkbsQOl9bX.jpeg!thumb-w321-webp75", + material_id: "20079971995" + }, + { + name: "", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/YadfjWvZDeK8Pjb.jpeg!thumb-w321-webp75", + material_id: "200799700078" + }, + { + name: "", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/54Kf8ZNP6YkBdnZ.jpeg!thumb-w321-webp75", + material_id: "200799700077" + }, + { + name: "", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/20dfEzWa33vvbEJ.jpeg!thumb-w321-webp75", + material_id: "200799700076" + }, + { + name: "", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/L3xFj5Y1l5qyO8k.jpeg!thumb-w321-webp75", + material_id: "200799700075" + }, + { + name: "", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/qp4IRaqOvg208Vx.jpeg!thumb-w321-webp75", + material_id: "200799700074" + }, + { + name: "", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/opkIW3BY6gJ6DP8.jpeg!thumb-w321-webp75", + material_id: "200799700073" + }, + { + name: "", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/39nT1zN9v2p5BBy.jpeg!thumb-w321-webp75", + material_id: "200799700072" + }, + { + name: "", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/Kz3fp1lekbGJY52.jpeg!thumb-w321-webp75", + material_id: "200799700071" + }, + { + name: "", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/20dfEz9V3L935WD.jpeg!thumb-w321-webp75", + material_id: "200799700070" + }, + { + name: "", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/R3GFJpZEd0pD5xY.jpeg!thumb-w321-webp75", + material_id: "200799700069" + }, + { + name: "", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/54Kf8o3GlPJgW3Q.jpeg!thumb-w321-webp75", + material_id: "200799700067" + }, + { + name: "", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/DaofJN9Gzxd8O5a.jpeg!thumb-w321-webp75", + material_id: "200799700063" + }, + { + name: "", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/qp4IRN9PaZ1Penl.jpeg!thumb-w321-webp75", + material_id: "200799700055" + }, + { + name: "", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/vkRsK6OxQ60gkJR.jpeg!thumb-w321-webp75", + material_id: "200799700045" + }, + { + name: "", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/1ZLIm5ExEmVpobj.jpeg!thumb-w321-webp75", + material_id: "200799700053" + }, + { + name: "", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/wkQsvL9y9XX1ZL8.jpeg!thumb-w321-webp75", + material_id: "200799700054" + }, + { + name: "", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/BmDFqnXBXod6LKx.jpeg!thumb-w321-webp75", + material_id: "200799700061" + }, + { + name: "", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/39nT1DmnGNQp8Gy.jpeg!thumb-w321-webp75", + material_id: "200799700060" + }, + { + name: "", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/k2ou2a6aPWDR5nX.jpeg!thumb-w321-webp75", + material_id: "200799700058" + }, + { + name: "", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/Q3bFyBOB1DxY6Dx.jpeg!thumb-w321-webp75", + material_id: "200799700059" + }, + { + name: "", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/O3RFRL3v0Jpd0Wk.jpeg!thumb-w321-webp75", + material_id: "200799700057" + }, + { + name: "", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/BmDFqnWadYGzXxP.jpeg!thumb-w321-webp75", + material_id: "20079970049" + }, + { + name: "", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/Q3bFyBQ8JLx2Wvb.jpeg!thumb-w321-webp75", + material_id: "20079970051" + }, + { + name: "", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/vkRsK6eLxeGj9w8.jpeg!thumb-w321-webp75", + material_id: "200799700041" + }, + { + name: "", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/gkmsKBGp36w8wEO.jpeg!thumb-w321-webp75", + material_id: "200799700056" + }, + { + name: "", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/ee9h6Qk4Y1wJpoY.jpeg!thumb-w321-webp75", + material_id: "200799700047" + }, + { + name: "", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/jeyhVvLBDqo64yy.jpeg!thumb-w321-webp75", + material_id: "20079970050" + }, + { + name: "", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/DaofJNY4pKnpQxa.jpeg!thumb-w321-webp75", + material_id: "20079970053" + }, + { + name: "", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/99ETG9z6NzjmBwQ.jpeg!thumb-w321-webp75", + material_id: "200799700046" + }, + { + name: "", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/ee9h6QD4PGmGBGa.jpeg!thumb-w321-webp75", + material_id: "200799700042" + }, + { + name: "", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/BmDFqnwGbGvXPq3.png!thumb-w321-webp75", + material_id: "200799700038" + }, + { + name: "", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/VwJigjRRPoRz8Xl.png!thumb-w321-webp75", + material_id: "200799700039" + }, + { + name: "", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/54Kf8BmB9dyqY2k.jpeg!thumb-w321-webp75", + material_id: "200799700027" + }, + { + name: "", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/ze1hXRywlnq18zj.jpeg!thumb-w321-webp75", + material_id: "200799700025" + }, + { + name: "", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/xkbs1eVvOEB46wE.jpeg!thumb-w321-webp75", + material_id: "200799700032" + }, + { + name: "", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/bxgsY85V4j5W3PY.jpeg!thumb-w321-webp75", + material_id: "200799700034" + }, + { + name: "", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/54Kf8oxaX5kVpN6.jpeg!thumb-w321-webp75", + material_id: "200799700033" + }, + { + name: "", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/EVvIj5VjGJyBNLO.png!thumb-w321-webp75", + material_id: "200799700031" + }, + { + name: "", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/Q3bFyJ2yqXlmJJz.png!thumb-w321-webp75", + material_id: "200799700030" + }, + { + name: "", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/1ZLImgemPooxWqv.jpeg!thumb-w321-webp75", + material_id: "200799700024" + }, + { + name: "", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/8D5FJjdJmO4VRbg.jpeg!thumb-w321-webp75", + material_id: "200799700029" + }, + { + name: "", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/EVvIj595ekZpN3X.jpeg!thumb-w321-webp75", + material_id: "200799700023" + }, + { + name: "", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/vkRsKg3OONyzZLb.png!thumb-w321-webp75", + material_id: "200799700021" + }, + { + name: "", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/496TndEvWqJynwo.png!thumb-w321-webp75", + material_id: "200799700019" + }, + { + name: "", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/8D5FJjkBmkNlpkd.png!thumb-w321-webp75", + material_id: "200799700020" + }, + { + name: "", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/WPWF3ODzRYPzo3K.jpeg!thumb-w321-webp75", + material_id: "200799700018" + }, + { + name: "", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/PVQIdBDb3b998XB.jpeg!thumb-w321-webp75", + material_id: "200799700017" + }, + { + name: "", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/99ETGwpo0Lv8dEZ.jpeg!thumb-w321-webp75", + material_id: "200799700008" + }, + { + name: "", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/gkmsKQKGPVm3j8E.jpeg!thumb-w321-webp75", + material_id: "200799700012" + }, + { + name: "", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/8D5FJjJJ310zYBQ.jpeg!thumb-w321-webp75", + material_id: "200799700010" + }, + { + name: "", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/lpvIjojjEYRbwWL.jpeg!thumb-w321-webp75", + material_id: "200799700011" + }, + { + name: "", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/xkbs1e1ee83wlP0.jpeg!thumb-w321-webp75", + material_id: "200799700014" + }, + { + name: "", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/DaofJWJnxRe3W09.jpeg!thumb-w321-webp75", + material_id: "200799700015" + }, + { + name: "", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/XRLI50Bdlg9joZ2.png!thumb-w321-webp75", + material_id: "200799700009" + }, + { + name: "", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/99ETGwkej4aqVjo.png!thumb-w321-webp75", + material_id: "200799700016" + }, + { + name: "", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/VwJikyzE29.png!thumb-w321-webp75", + material_id: "200799700000" + }, + { + name: "", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/ze1h5O9oKb.jpeg!thumb-w321-webp75", + material_id: "200799700002" + }, + { + name: "", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/a3wFLXLnx2.jpeg!thumb-w321-webp75", + material_id: "200799700001" + }, + { + name: "", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/6DqFRdykvn.png!thumb-w321-webp75", + material_id: "200799700004" + }, + { + name: "", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/1ZLI1pjZgP.jpeg!thumb-w321-webp75", + material_id: "200799700003" + }, + { + name: "", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/opkIn0ZXgW.jpeg!thumb-w321-webp75", + material_id: "200799700006" + }, + { + name: "", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/ze1h5VwNLD.jpeg!thumb-w321-webp75", + material_id: "20079976666" + }, + { + name: "", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/mlahykPGYd.jpeg!thumb-w321-webp75", + material_id: "2007997666" + }, + { + name: "", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/XRLIPQX4qj.jpeg!thumb-w321-webp75", + material_id: "20079972" + }, + { + name: "", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/k2ouOWwP2b.jpeg!thumb-w321-webp75", + material_id: "20079971" + }, + { + name: "", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/xkbsQP2W5z.jpeg!thumb-w321-webp75", + material_id: "20079971234" + }, + { + name: "", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/EVvIjl5B2q1P3Ld.jpeg!thumb-w321-webp75", + material_id: "200799700062" + }, + { + name: "新年静物", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/8D5FJzenN2v99KG.jpeg!thumb-w321-webp75", + material_id: "200799700079" + }, + { + name: "", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/20dfEzd1lndjOwg.jpeg!thumb-w321-webp75", + material_id: "20079972282" + }, + { + name: "", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/nplIyLnnEm9o41W.png!thumb-w321-webp75", + material_id: "200799700022" + }, + { + name: "", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/ze1h5ONoeg.png!thumb-w321-webp75", + material_id: "200799700007" + }, + { + name: "原生", + thumbnail: "https://xximg1.meitudata.com/XeVHPQpbgR.jpeg!thumb-w321-webp75", + material_id: "20079930000" + }, + { + name: "减龄2", + thumbnail: "https://xximg1.meitudata.com/GPoUPW5m8n.jpeg!thumb-w321-webp75", + material_id: "20079930003" + }, + { + name: "质感", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/nBJcyLgw0QZmvB2.png!thumb-w321-webp75", + material_id: "20079932147" + }, + { + name: "眼睑下至", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/1zVH1xKebW.jpeg!thumb-w321-webp75", + material_id: "20079930007" + }, + { + name: "原生2", + thumbnail: "https://xximg1.meitudata.com/aOWsLZ14vp.jpeg!thumb-w321-webp75", + material_id: "20079930001" + }, + { + name: "减龄2优化", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/5JOiDRnL9l.jpeg!thumb-w321-webp75", + material_id: "20079930070" + }, + { + name: "DIOR", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/5JOi8BVv09mRyGK.jpeg!thumb-w321-webp75", + material_id: "20079930075" + }, + { + name: "", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/N3OFqdNzda.jpeg!thumb-w321-webp75", + material_id: "20079932157" + }, + { + name: "bling", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/9nzUy0eQGq.png!thumb-w321-webp75", + material_id: "20079932158" + }, + { + name: "色散光", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/JdaUWkbq92.png!thumb-w321-webp75", + material_id: "20079932154" + }, + { + name: "闪光夏日", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/bBLUvkadVZ.jpeg!thumb-w321-webp75", + material_id: "20079932153" + }, + { + name: "闪光女团", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/qR1tJPGR0j.jpeg!thumb-w321-webp75", + material_id: "20079930053" + }, + { + name: "闪光少女", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/eqOHv3wnlD.jpeg!thumb-w321-webp75", + material_id: "20079932152" + }, + { + name: "bling01", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/EPdULXNn66.jpeg!thumb-w321-webp75", + material_id: "20079930010" + }, + { + name: "bling02", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/6kOHR9OGvP.jpeg!thumb-w321-webp75", + material_id: "20079930011" + }, + { + name: "bling03", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/eqOHv38nPz.jpeg!thumb-w321-webp75", + material_id: "20079930012" + }, + { + name: "Disco6", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/RwXHmzP9Y0.jpeg!thumb-w321-webp75", + material_id: "20079930009" + }, + { + name: "Dream1", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/XeVHPQWGGZ.jpeg!thumb-w321-webp75", + material_id: "20079930013" + }, + { + name: "Hypno1", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/j4QUeORQE4.jpeg!thumb-w321-webp75", + material_id: "20079930014" + }, + { + name: "Stellar2", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/5JOiDpKNRz.jpeg!thumb-w321-webp75", + material_id: "20079930008" + }, + { + name: "光1", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/OX8i06ZB9D.jpeg!thumb-w321-webp75", + material_id: "20079930004" + }, + { + name: "Prisma1", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/JdXHWkgq5D.jpeg!thumb-w321-webp75", + material_id: "20079930017" + }, + { + name: "Plastic1", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/V2jTkWZbP6.jpeg!thumb-w321-webp75", + material_id: "20079930016" + }, + { + name: "莫奈", + thumbnail: "https://xximg1.meitudata.com/9nzUy0bwDV.png!thumb-w321-webp75", + material_id: "20079932086" + }, + { + name: "雾柔水光", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/JdaUWkEplJ.png!thumb-w321-webp75", + material_id: "20079932146" + }, + { + name: "muji", + thumbnail: "https://xximg1.meitudata.com/LEasJNJplP.png!thumb-w321-webp75", + material_id: "20079932148" + }, + { + name: "相机打光测试", + thumbnail: "https://xximg1.meitudata.com/j4QUexO3K5.jpeg!thumb-w321-webp75", + material_id: "20079932054" + }, + { + name: "1222", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/3XwSOKRJjx.jpeg!thumb-w321-webp75", + material_id: "20079931222" + }, + { + name: "1333", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/EQYuL9LqvV.jpeg!thumb-w321-webp75", + material_id: "20079931333" + }, + { + name: "1999", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/VqVfkykO5y.jpeg!thumb-w321-webp75", + material_id: "20079931999" + }, + { + name: "1666", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/1pgI1plVVv.jpeg!thumb-w321-webp75", + material_id: "20079931666" + }, + { + name: "1888", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/OJbF06VvmK.jpeg!thumb-w321-webp75", + material_id: "20079931888" + }, + { + name: "1888", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/ke8UOWwVz6.jpeg!thumb-w321-webp75", + material_id: "20079931777" + }, + { + name: "2057", + thumbnail: "https://xximg1.meitudata.com/3YVfOVKVmm.jpeg!thumb-w321-webp75", + material_id: "20079932057" + }, + { + name: "五一鱼块", + thumbnail: "https://xximg1.meitudata.com/39nTOVegOn.jpeg!thumb-w321-webp75", + material_id: "20079932056" + }, + { + name: "五一", + thumbnail: "https://xximg1.meitudata.com/bBZcvykbxP.png!thumb-w321-webp75", + material_id: "20079932053" + }, + { + name: "bling04", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/OX8i06XB3L.jpeg!thumb-w321-webp75", + material_id: "20079930015" + }, + { + name: "元旦", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/mbZHO6bOgR5YgdB.jpeg!thumb-w321-webp75", + material_id: "20106401993" + }, + { + name: "瞬间", + thumbnail: "https://xximg1.meitudata.com/y59Ib9JKjm.jpeg!thumb-w321-webp75", + material_id: "20106401997" + }, + { + name: "新专辑轰顶", + thumbnail: "https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/BR7fMkae0elL9DK.png!thumb-w321-webp75", + material_id: "506093294" + }, + { + name: "新素材", + thumbnail: "https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/LL8SozrWaMVRP5L.png!thumb-w321-webp75", + material_id: "506093299" + }, + { + name: "素材不在功能页", + thumbnail: "https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/69MiA9JxOErJvvP.png!thumb-w321-webp75", + material_id: "506093238" + }, + { + name: "我被禁用了😄我被禁用了😄", + thumbnail: "https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/D18Iz3ZaAPm0za3.png!thumb-w321-webp75", + material_id: "506093239" + }, + { + name: "低版本不可见", + thumbnail: "https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/757SWMrAkzKAorX.png!thumb-w321-webp75", + material_id: "506093243" + }, + { + name: "3d立体弹窗", + thumbnail: "https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/k4gtA430gyk3Wx9.png!thumb-w321-webp75", + material_id: "506093241" + }, + { + name: "加州", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/RKgUJnKn126zbGG.jpeg!thumb-w321-webp75", + material_id: "50602339" + }, + { + name: "爱心光", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/j4GcVXWgv200k0D.jpeg!thumb-w321-webp75", + material_id: "506002288" + }, + { + name: "2053太空漫游", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/wgNUven5XxgKmG4.jpeg!thumb-w321-webp75", + material_id: "20096492276" + }, + { + name: "CCD", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/XepU5b3WG3BDJNp.jpeg!thumb-w321-webp75", + material_id: "20096492265" + }, + { + name: "IMAX胶片", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/bBZcYlQVDNVde5Y.jpeg!thumb-w321-webp75", + material_id: "20096492254" + }, + { + name: "皮囊之下", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/p0LTO938OKJLV2k.jpeg!thumb-w321-webp75", + material_id: "506002350" + }, + { + name: "号手就位", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/J34FBw2bEwzGbWp.jpeg!thumb-w321-webp75", + material_id: "506002317" + }, + { + name: "海绵3", + thumbnail: "https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/26guLmK1p0M13Zr.jpeg!thumb-w321-webp75", + material_id: "506010277" + }, + { + name: "海绵4", + thumbnail: "https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/KgaiJr4o77waN4d.jpeg!thumb-w321-webp75", + material_id: "506010276" + }, + { + name: "海绵1", + thumbnail: "https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/71MfrYOoEDyKLJA.jpeg!thumb-w321-webp75", + material_id: "506010279" + }, + { + name: "TR2", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/k51F2wNOkqQgBjX.jpeg!thumb-w321-webp75", + material_id: "506002345" + }, + { + name: "TR3", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/JdaUB94WJJqQlwK.jpeg!thumb-w321-webp75", + material_id: "506002344" + }, + { + name: "TR4", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/5JeH8WzDLm1NmPy.jpeg!thumb-w321-webp75", + material_id: "506002347" + }, + { + name: "TR5", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/lkjUjGvk4VORqlR.jpeg!thumb-w321-webp75", + material_id: "506002343" + }, + { + name: "TR6", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/k51F2wNOLjj94dK.jpeg!thumb-w321-webp75", + material_id: "506002346" + }, + { + name: "乌布", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/V2xig11N0vQLpxm.jpeg!thumb-w321-webp75", + material_id: "506002333" + }, + { + name: "微缩世界", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/oJQiWgqo5kodE1B.jpeg!thumb-w321-webp75", + material_id: "506002298" + }, + { + name: "微缩世界Ⅱ", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/N8RHzP6aP44Xex6.jpeg!thumb-w321-webp75", + material_id: "506002299" + }, + { + name: "旅程", + thumbnail: "https://xximg1.meitudata.com/V2jTkEY8Y9.jpeg!thumb-w321-webp75", + material_id: "20086101254" + }, + { + name: "旅程", + thumbnail: "https://xximg1.meitudata.com/GPoUPwOj1b.jpeg!thumb-w321-webp75", + material_id: "20086101315" + }, + { + name: "且听风吟", + thumbnail: "https://xximg1.meitudata.com/Z3VspeGOy3.jpeg!thumb-w321-webp75", + material_id: "2008610635" + }, + { + name: "Sky", + thumbnail: "https://xximg1.meitudata.com/p0GcZPbnV0.jpeg!thumb-w321-webp75", + material_id: "20086101612" + }, + { + name: "清新蓝", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/BbWiqXBp8X869e9.jpeg!thumb-w321-webp75", + material_id: "20086162162" + }, + { + name: "男友力", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/6PocqE9aB8nZgOl.jpeg!thumb-w321-webp75", + material_id: "20086161259" + }, + { + name: "男友力", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/8boiJnm9e69J3GB.jpeg!thumb-w321-webp75", + material_id: "20086161256" + }, + { + name: "男友力", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/oeGiWgmVL06ppzo.jpeg!thumb-w321-webp75", + material_id: "20086161469" + }, + { + name: "chiffon", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/JdXHB6PXY9dzmjl.jpeg!thumb-w321-webp75", + material_id: "2008607975" + }, + { + name: "新年限定", + thumbnail: "https://xximg1.meitudata.com/mlahymLEBk.jpeg!thumb-w321-webp75", + material_id: "20086072015" + }, + { + name: "新春食堂", + thumbnail: "https://xximg1.meitudata.com/dDpFaD19J9.jpeg!thumb-w321-webp75", + material_id: "20086071687" + }, + { + name: "围炉", + thumbnail: "https://xximg1.meitudata.com/jo2UegGjqj.jpeg!thumb-w321-webp75", + material_id: "20086071688" + }, + { + name: "橘子汽水", + thumbnail: "https://xximg1.meitudata.com/voWUlvO8Dd.jpeg!thumb-w321-webp75", + material_id: "2008607571" + }, + { + name: "舒芙蕾", + thumbnail: "https://xximg1.meitudata.com/xmdFQwl5J0.jpeg!thumb-w321-webp75", + material_id: "2008607569" + }, + { + name: "野Ⅰ", + thumbnail: "https://xximg1.meitudata.com/6KwCRlbG6g.jpeg!thumb-w321-webp75", + material_id: "20086070001" + }, + { + name: "野餐Ⅱ", + thumbnail: "https://xximg1.meitudata.com/Nzjuq2XDGQ.jpeg!thumb-w321-webp75", + material_id: "20086070002" + }, + { + name: "食欲", + thumbnail: "https://xximg1.meitudata.com/jo2UegGzVl.jpeg!thumb-w321-webp75", + material_id: "20086071585" + }, + { + name: "食欲", + thumbnail: "https://xximg1.meitudata.com/0J6fWJbYW8.jpeg!thumb-w321-webp75", + material_id: "20086071587" + }, + { + name: "橘子汽水", + thumbnail: "https://xximg1.meitudata.com/bz0uvoO5Po.jpeg!thumb-w321-webp75", + material_id: "20086071908" + }, + { name: "", thumbnail: "https://xximg1.meitudata.com/xmdFQwgNGx.png!thumb-w321-webp75", material_id: "2008607014" }, + { + name: "粉花面包", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/gkmsKBakKNO6ynd.jpeg!thumb-w321-webp75", + material_id: "2008607973" + }, + { name: "", thumbnail: "https://xximg1.meitudata.com/RzLumonEvG.png!thumb-w321-webp75", material_id: "2008607015" }, + { + name: "Brunch", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/V2jTgxyR4xG9k4d.jpeg!thumb-w321-webp75", + material_id: "20086072197" + }, + { + name: "vista200", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/LJwUjvN4awZDWOw.jpeg!thumb-w321-webp75", + material_id: "506002301" + }, + { + name: "胶片时光", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/kBwi28Wm6y698oy.jpeg!thumb-w321-webp75", + material_id: "20086171381" + }, + { + name: "胶片时光", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/8boiJnmYZ8NbvJ6.jpeg!thumb-w321-webp75", + material_id: "20086171339" + }, + { + name: "胶片时光", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/vEdtKOx0n2gEyBg.jpeg!thumb-w321-webp75", + material_id: "20086171336" + }, + { + name: "菲林日记", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/OdpiRJVedvxlR4m.jpeg!thumb-w321-webp75", + material_id: "20096221571" + }, + { + name: "菲林日记", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/kBwi28w05RB11de.jpeg!thumb-w321-webp75", + material_id: "20096221570" + }, + { + name: "菲林日记", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/KBPipZwDElPR1bl.jpeg!thumb-w321-webp75", + material_id: "20096221783" + }, + { + name: "菲林日记", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/2bkiEXqkWmBZzjL.jpeg!thumb-w321-webp75", + material_id: "20096221781" + }, + { + name: "菲林日记", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/PnkTd0zBvKKRYb0.jpeg!thumb-w321-webp75", + material_id: "20096221780" + }, + { + name: "Outdoors", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/NL9HzPdl9WLnlq9.jpeg!thumb-w321-webp75", + material_id: "20086172023" + }, + { + name: "蒸汽波", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/DyjUJpgEgyP8nDL.jpeg!thumb-w321-webp75", + material_id: "506002182" + }, + { + name: "落日", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/V2jTgj1akYWmEvP.jpeg!thumb-w321-webp75", + material_id: "20106112264" + }, + { + name: "音浪", + thumbnail: "http://xximg2.meitudata.com/VXgfk8zEJ3.jpeg!thumb-w321-webp75", + material_id: "20106111100" + }, + { + name: "毕业季", + thumbnail: "https://xxtool-release.zone1.meitudata.com/material/y56Fb5qaXq.jpeg!thumb-w321-webp75", + material_id: "20076121254" + }, + { + name: "游乐园", + thumbnail: "https://xximg1.meitudata.com/N8eUq2XE0E.jpeg!thumb-w321-webp75", + material_id: "20076091595" + }, + { + name: "粉黛", + thumbnail: "https://xximg1.meitudata.com/wgNU3GlNRj.jpeg!thumb-w321-webp75", + material_id: "20076091618" + }, + { + name: "游乐园", + thumbnail: "https://xximg1.meitudata.com/Z3GfpjWOKV.jpeg!thumb-w321-webp75", + material_id: "20076091596" + }, + { + name: "水彩画", + thumbnail: "https://xximg1.meitudata.com/eqOHvqo0ej.jpeg!thumb-w321-webp75", + material_id: "20106041764" + }, + { + name: "钢笔淡彩", + thumbnail: "https://xximg1.meitudata.com/V2jTkopPGQ.jpeg!thumb-w321-webp75", + material_id: "20106041765" + }, + { + name: "质感", + thumbnail: "https://xximg1.meitudata.com/XepUPNP4WP.png!thumb-w321-webp75", + material_id: "20076061608" + }, + { + name: "质感", + thumbnail: "https://xximg1.meitudata.com/9nzUydyWeB.png!thumb-w321-webp75", + material_id: "20076061589" + }, + { + name: "质感", + thumbnail: "http://xximg2.meitudata.com/yObUbokjlb.jpeg!thumb-w321-webp75", + material_id: "20076061609" + }, + { + name: "荼白", + thumbnail: "https://xximg1.meitudata.com/6kOHRW8WGD.jpeg!thumb-w321-webp75", + material_id: "20076061859" + } + ] + + public totalCount(): number { + return this.dataArray.length; + } + + public getData(index: number): Material | undefined { + return this.dataArray[index]; + } + + public addData(index: number, data: Material): void { + this.dataArray.splice(index, 0, data); + this.notifyDataAdd(index); + } + + public pushData(data: Material): void { + this.dataArray.push(data); + this.notifyDataAdd(this.dataArray.length - 1); + } +} diff --git a/entry/src/main/ets/pages/model/BasicDataSource.ets b/entry/src/main/ets/pages/model/BasicDataSource.ets deleted file mode 100644 index cc31787..0000000 --- a/entry/src/main/ets/pages/model/BasicDataSource.ets +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (C) 2023 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 BasicDataSource implements IDataSource { - private listeners: DataChangeListener[] = []; - - public totalCount(): number { - return 0; - } - - public getData(index: number):T | undefined { - return undefined; - } - - registerDataChangeListener(listener: DataChangeListener): void { - if (this.listeners.indexOf(listener) < 0) { - console.info('add listener'); - this.listeners.push(listener); - } - } - - unregisterDataChangeListener(listener: DataChangeListener): void { - const pos = this.listeners.indexOf(listener); - if (pos >= 0) { - console.info('remove listener'); - this.listeners.splice(pos, 1); - } - } - - notifyDataReload(): void { - this.listeners.forEach(listener => { - listener.onDataReloaded(); - }) - } - - notifyDataAdd(index: number): void { - this.listeners.forEach(listener => { - listener.onDataAdd(index); - }) - } - - notifyDataChange(index: number): void { - this.listeners.forEach(listener => { - listener.onDataChange(index); - }) - } - - notifyDataDelete(index: number): void { - this.listeners.forEach(listener => { - listener.onDataDelete(index); - }) - } - - notifyDataMove(from: number, to: number): void { - this.listeners.forEach(listener => { - listener.onDataMove(from, to); - }) - } -} \ No newline at end of file diff --git a/entry/src/main/ets/pages/model/TestDataSource.ets b/entry/src/main/ets/pages/model/TestDataSource.ets deleted file mode 100644 index 587302e..0000000 --- a/entry/src/main/ets/pages/model/TestDataSource.ets +++ /dev/null @@ -1,590 +0,0 @@ -/* - * Copyright (C) 2023 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 {BasicDataSource} from './BasicDataSource' -import { Material } from './Material'; -export class TestDataSource extends BasicDataSource { - private dataArray: Material[] = [ - {name:"测试CBC",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/R9aT7lpEEVxawo4.jpeg!thumb-w321-webp75",material_id:"5060118818"}, - {name:"通用天空1像素测试",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/1V6c63lKLGPlKVo.png!thumb-w321-webp75",material_id:"506009997"}, - {name:"像素测试+bin",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/2NxCo49xAB1L96K.jpeg!thumb-w321-webp75",material_id:"506009998"}, - {name:"像素测试",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/P6gH3pWBGw7L6dD.jpeg!thumb-w321-webp75",material_id:"506009999"}, - {name:"名称一",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/MKosgAWo5VKpo9Z.jpeg!thumb-w321-webp75",material_id:"50600999"}, - {name:"质感",thumbnail:"https://xximg1.meitudata.com/XepUPNP4WP.png!thumb-w321-webp75",material_id:"20076061608"}, - {name:"抠图批量拼图",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/pA2S9lvNpMY4X3N.jpeg!thumb-w321-webp75",material_id:"506002368"}, - {name:"修改测试",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/69MiA9VxKdkzjWR.png!thumb-w321-webp75",material_id:"50600229"}, - {name:"兰桂坊-艺术",thumbnail:"https://material-center-pre.meitudata.com/material/image/6228901fd8ddd6350.jpeg!thumb-w321-webp75",material_id:"50639415"}, - {name:"有门槛的我",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/P98i3gdgDw3Rmx5.png!thumb-w321-webp75",material_id:"506093422"}, - {name:"222嗯嗯1",thumbnail:"https://stage.meitudata.com/public/creator/ed70a3c696c8e7b.jpg!thumb-w321-webp75",material_id:"50693244"}, - {name:"滤镜流程11",thumbnail:"https://material-center-pre.meitudata.com/material/image/6194a57b5b9ef7678.jpg!thumb-w321-webp75",material_id:"506017292"}, - {name:"hsxTest11.8",thumbnail:"https://material-center-pre.meitudata.com/material/image/6189f29b48f165954.jpg!thumb-w321-webp75",material_id:"506530963"}, - {name:"旧-美食手绘1",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/0lZCW9BrDgMroLL.jpeg!thumb-w321-webp75",material_id:"5060002001"}, - {name:"Forest",thumbnail:"https://xximg1.meitudata.com/V2jTkoYa96.jpeg!thumb-w321-webp75",material_id:"20106191835"}, - {name:"春樱",thumbnail:"https://xximg1.meitudata.com/k5DIOxgJpN.jpeg!thumb-w321-webp75",material_id:"20076291634"}, - {name:"GT G",thumbnail:"http://xximg2.meitudata.com/Z9DCJpkB2l.jpeg!thumb-w321-webp75",material_id:"20085081215"}, - {name:"测",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/zwdte8R2e5KMMmm.jpeg!thumb-w321-webp75",material_id:"506000000"}, - {name:"五一鱼块",thumbnail:"https://xximg1.meitudata.com/mlahyxNxjN.jpeg!thumb-w321-webp75",material_id:"20076292056"}, - {name:"青空",thumbnail:"https://xximg1.meitudata.com/8OkUwBympV.jpeg!thumb-w321-webp75",material_id:"20106311844"}, - {name:"质感",thumbnail:"https://xximg1.meitudata.com/9nzUydyWeB.png!thumb-w321-webp75",material_id:"20076061589"}, - {name:"测试CBC",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/R9aT7lpEEVxawo4.jpeg!thumb-w321-webp75",material_id:"5060118818"}, - {name:"像素天空抠图测试",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/Ymju0r3deAl7xoJ.jpeg!thumb-w321-webp75",material_id:"506005680"}, - {name:"像素滤镜测试",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/8zPcB0y4vdreG1d.jpeg!thumb-w321-webp75",material_id:"506019998"}, - {name:"通用天空1像素测试",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/1V6c63lKLGPlKVo.png!thumb-w321-webp75",material_id:"506009997"}, - {name:"人像风格化",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/VYwIWp0E52v5vaE.jpeg!thumb-w321-webp75",material_id:"50600288888"}, - {name:"像素+边框测试",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/Z9dtor442OY76KV.jpeg!thumb-w321-webp75",material_id:"506005678"}, - {name:"像素测试+bin",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/2NxCo49xAB1L96K.jpeg!thumb-w321-webp75",material_id:"506009998"}, - {name:"像素测试",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/P6gH3pWBGw7L6dD.jpeg!thumb-w321-webp75",material_id:"506009999"}, - {name:"兰桂坊-艺术",thumbnail:"https://material-center-pre.meitudata.com/material/image/6228901fd8ddd6350.jpeg!thumb-w321-webp75",material_id:"50639415"}, - {name:"藤黄",thumbnail:"https://xximg1.meitudata.com/KnJSa8X496.jpeg!thumb-w321-webp75",material_id:"20076281728"}, - {name:"梅幸茶",thumbnail:"https://xximg1.meitudata.com/GYGcPokEQ3.jpeg!thumb-w321-webp75",material_id:"20076281771"}, - {name:"五一鱼块",thumbnail:"https://xximg1.meitudata.com/mlahyxNxjN.jpeg!thumb-w321-webp75",material_id:"20076292056"}, - {name:"12.妆容滤镜层级控制",thumbnail:"https://xxtool-release.zone1.meitudata.com/deRP83dkdlR4.png!thumb-w321-webp75",material_id:"200720002017"}, - {name:"12.妆容滤镜层级控制1",thumbnail:"https://xxtool-release.zone1.meitudata.com/rPJ1vKjJY6jz.png!thumb-w321-webp75",material_id:"200720002018"}, - {name:"13.3D打光",thumbnail:"https://xxtool-release.zone1.meitudata.com/z8K3P249ZmVW.png!thumb-w321-webp75",material_id:"200720002020"}, - {name:"14.新bling效果",thumbnail:"https://xxtool-release.zone1.meitudata.com/e4xlVkl0BzMy.png!thumb-w321-webp75",material_id:"200720003001"}, - {name:"美食手绘效果2",thumbnail:"https://xxtool-release.zone1.meitudata.com/B6MleZrWeMvj.jpg!thumb-w321-webp75",material_id:"200720002002"}, - {name:"16.美食手绘效果",thumbnail:"https://xxtool-release.zone1.meitudata.com/xEke61aRK6dg.jpg!thumb-w321-webp75",material_id:"200720002003"}, - {name:"17.素材无人脸规则",thumbnail:"https://xxtool-release.zone1.meitudata.com/B6MleZ1ae5Ry.jpg!thumb-w321-webp75",material_id:"200720002010"}, - {name:"18.径向色散效果",thumbnail:"https://xxtool-release.zone1.meitudata.com/EyvzkoPgakDL.jpg!thumb-w321-webp75",material_id:"200720002012"}, - {name:"胶片滤镜2",thumbnail:"https://xxtool-release.zone1.meitudata.com/3zVRo1E16vZG.png!thumb-w321-webp75",material_id:"200720002008"}, - {name:"20.胶片滤镜",thumbnail:"https://xxtool-release.zone1.meitudata.com/3zVRo1EdvZ0W.jpg!thumb-w321-webp75",material_id:"200720002009"}, - {name:"21.虚化滤镜",thumbnail:"https://xxtool-release.zone1.meitudata.com/1mLMv1kd2BLZ.jpg!thumb-w321-webp75",material_id:"200720002011"}, - {name:"22.天空分割滤镜",thumbnail:"https://xxtool-release.zone1.meitudata.com/8NXRMzE019aB.jpg!thumb-w321-webp75",material_id:"200720002006"}, - {name:"23.妆容滤镜",thumbnail:"https://xxtool-release.zone1.meitudata.com/0XDRo7xdPkVx.jpg!thumb-w321-webp75",material_id:"200720002007"}, - {name:"1.随机滤镜",thumbnail:"https://xxtool-release.zone1.meitudata.com/V06dg1RJ8pDr.jpg!thumb-w321-webp75",material_id:"200720001004"}, - {name:"15.实时取色效果",thumbnail:"https://xxtool-release.zone1.meitudata.com/2p5Ro1VDZvxR.png!thumb-w321-webp75",material_id:"200720001001"}, - {name:"10.不带妆容",thumbnail:"https://xxtool-release.zone1.meitudata.com/8NXRMz5oypN7.jpeg!thumb-w321-webp75",material_id:"200720002030"}, - {name:"16.美食手绘效果1",thumbnail:"https://xxtool-release.zone1.meitudata.com/1mLMWyxNVMAe.jpg!thumb-w321-webp75",material_id:"506088836"}, - {name:"素材多比例滤镜",thumbnail:"https://xxtool-release.zone1.meitudata.com/7d8RoA7DXYB9.jpg!thumb-w321-webp75",material_id:"200720002013"}, - {name:"安德森粉",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/OXOHRLBqVppoxEY.png!thumb-w321-webp75",material_id:"20079982224"}, - {name:"安德森黄",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/bBZcY8dnYDqZE5v.png!thumb-w321-webp75",material_id:"20079982225"}, - {name:"安德森冷",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/x5NF1JLYvqGENkj.png!thumb-w321-webp75",material_id:"20079982226"}, - {name:"安德森暖青",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/KeVUpByXzRp0oPK.png!thumb-w321-webp75",material_id:"20079982227"}, - {name:"高光+100",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/PB2cdnDGN0nqb8q.png!thumb-w321-webp75",material_id:"20079981113"}, - {name:"高光-100",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/XepU5b6OZKW90Yv.png!thumb-w321-webp75",material_id:"20079981114"}, - {name:"阴影+100",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/KeVUp1oQD6W8xg5.png!thumb-w321-webp75",material_id:"20079981115"}, - {name:"阴影-100",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/GPWcJeyweKZR69d.png!thumb-w321-webp75",material_id:"20079981116"}, - {name:"cg无素材",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/LEasj5wg0o10JzO.png!thumb-w321-webp75",material_id:"20079981112"}, - {name:"会员电影胶片",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/8QzFJLZVqLlvj8v.png!thumb-w321-webp75",material_id:"20079982254"}, - {name:"秋1",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/KeVUpByPLRGkgYj.jpeg!thumb-w321-webp75",material_id:"20079982230"}, - {name:"秋2",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/6kQUqeG39YJlEo1.jpeg!thumb-w321-webp75",material_id:"20079982231"}, - {name:"秋3",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/KeVUpByPvxBLldg.jpeg!thumb-w321-webp75",material_id:"20079982232"}, - {name:"秋4",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/3YDh1Dl6xY30nqD.jpeg!thumb-w321-webp75",material_id:"20079982233"}, - {name:"秋5",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/9nzUG9DeeGmn94G.jpeg!thumb-w321-webp75",material_id:"20079982234"}, - {name:"秋6",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/YkpUjYwlPanLVNg.jpeg!thumb-w321-webp75",material_id:"20079982235"}, - {name:"秋7",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/OXOHRLB3YBPbD0o.jpeg!thumb-w321-webp75",material_id:"20079982236"}, - {name:"秋8",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/dWZS0X3P2LjqJ5x.jpeg!thumb-w321-webp75",material_id:"20079982240"}, - {name:"自然灰2",thumbnail:"https://xximg1.meitudata.com/OXOH0zayv2.png!thumb-w321-webp75",material_id:"20079981854"}, - {name:"自然灰1",thumbnail:"https://xximg1.meitudata.com/mbeUyRpobN.png!thumb-w321-webp75",material_id:"20079981853"}, - {name:"色散",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/3YDhOe5eO9.png!thumb-w321-webp75",material_id:"20079981726"}, - {name:"毕业季",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/4VQt9N8Pjo.png!thumb-w321-webp75",material_id:"20079981254"}, - {name:"一键美颜质感",thumbnail:"https://xximg1.meitudata.com/x5NFQPRBWG.png!thumb-w321-webp75",material_id:"20079982147"}, - {name:"相框吸色",thumbnail:"https://xximg1.meitudata.com/2zmU1vvaPD.png!thumb-w321-webp75",material_id:"20079982037"}, - {name:"美化吸色灰度限制",thumbnail:"https://xximg1.meitudata.com/EPBcLQoodX.png!thumb-w321-webp75",material_id:"20079980037"}, - {name:"相机吸色测试",thumbnail:"https://xximg1.meitudata.com/p0LTZqZ2Wm.jpeg!thumb-w321-webp75",material_id:"20079981873"}, - {name:"吸色测试2",thumbnail:"https://xximg1.meitudata.com/9nzUyoDvEQ.png!thumb-w321-webp75",material_id:"20079981874"}, - {name:"吸色灰度限制0.5",thumbnail:"https://xximg1.meitudata.com/9nzUyYZ5LZ.png!thumb-w321-webp75",material_id:"20079981029"}, - {name:"foodie锐化",thumbnail:"https://xximg1.meitudata.com/oJWHn2klo6.png!thumb-w321-webp75",material_id:"20079982000"}, - {name:"自然风光",thumbnail:"https://xximg1.meitudata.com/N8eUq1aDk1.jpeg!thumb-w321-webp75",material_id:"20079982003"}, - {name:"室内",thumbnail:"https://xximg1.meitudata.com/LEasJPl8mE.jpeg!thumb-w321-webp75",material_id:"20079982004"}, - {name:"室外",thumbnail:"https://xximg1.meitudata.com/g5eFOyEePx.jpeg!thumb-w321-webp75",material_id:"20079982005"}, - {name:"老人",thumbnail:"https://xximg1.meitudata.com/vgzUl2EGV5.jpeg!thumb-w321-webp75",material_id:"20079982006"}, - {name:"街道复用",thumbnail:"https://xximg1.meitudata.com/QEasmNjL8x.jpeg!thumb-w321-webp75",material_id:"20079981781"}, - {name:"大师1",thumbnail:"https://xximg1.meitudata.com/wgNU30boQ4.png!thumb-w321-webp75",material_id:"20079981962"}, - {name:"大师2",thumbnail:"https://xximg1.meitudata.com/YkpU1yPmPa.png!thumb-w321-webp75",material_id:"20079981963"}, - {name:"大师3",thumbnail:"https://xximg1.meitudata.com/qRdTJOZYn8.png!thumb-w321-webp75",material_id:"20079981964"}, - {name:"大师4",thumbnail:"https://xximg1.meitudata.com/LEasJoKld4.png!thumb-w321-webp75",material_id:"20079981965"}, - {name:"大师5",thumbnail:"https://xximg1.meitudata.com/KeVUaQnzez.png!thumb-w321-webp75",material_id:"20079981966"}, - {name:"大师6",thumbnail:"https://xximg1.meitudata.com/BNGiP6vklD.png!thumb-w321-webp75",material_id:"20079981967"}, - {name:"大师7",thumbnail:"https://xximg1.meitudata.com/wgNU30boLG.png!thumb-w321-webp75",material_id:"20079981968"}, - {name:"大师8",thumbnail:"https://xximg1.meitudata.com/j4Gce54yGg.png!thumb-w321-webp75",material_id:"20079981969"}, - {name:"大师9",thumbnail:"https://xximg1.meitudata.com/g5eFO8dEYO.png!thumb-w321-webp75",material_id:"20079981970"}, - {name:"模糊相机测试",thumbnail:"https://xximg1.meitudata.com/wgNU3GgL0p.png!thumb-w321-webp75",material_id:"20079982016"}, - {name:"",thumbnail:"https://xximg1.meitudata.com/g5eFOoOWnK.png!thumb-w321-webp75",material_id:"20079981872"}, - {name:"复古",thumbnail:"https://xximg1.meitudata.com/x5NFQGlPeD.png!thumb-w321-webp75",material_id:"20079982026"}, - {name:"夜景抠图",thumbnail:"https://xximg1.meitudata.com/qRdTJOxoK4.png!thumb-w321-webp75",material_id:"20079981936"}, - {name:"我爱中国",thumbnail:"https://xximg1.meitudata.com/3YDhOJgLgp.png!thumb-w321-webp75",material_id:"20079981422"}, - {name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/oJQiW3WX68vDyaW.jpeg!thumb-w321-webp75",material_id:"20079992271"}, - {name:"桃子奶油",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/lk0HjR5ealbk2Ze.jpeg!thumb-w321-webp75",material_id:"20079992275"}, - {name:"橘粉奶油",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/5JOi8ZVNnqE8w8g.jpeg!thumb-w321-webp75",material_id:"20079990090"}, - {name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/DyOHJnqNb5o8LQg.jpeg!thumb-w321-webp75",material_id:"20079992277"}, - {name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/y59IlX8wQXoNGEK.jpeg!thumb-w321-webp75",material_id:"20079992276"}, - {name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/dWku02V3BpYDylY.jpeg!thumb-w321-webp75",material_id:"20079990081"}, - {name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/p0GcOvOamLXoD3Z.jpeg!thumb-w321-webp75",material_id:"20079992273"}, - {name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/6kOHqmQ3qjPoYQa.jpeg!thumb-w321-webp75",material_id:"20079992266"}, - {name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/RwXHJpZKvlQK2GJ.jpeg!thumb-w321-webp75",material_id:"20079992267"}, - {name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/2zVHE2XGb3d0xgv.jpeg!thumb-w321-webp75",material_id:"20079990045"}, - {name:"炫光",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/dWku0XJZxGgDLO9.jpeg!thumb-w321-webp75",material_id:"20079992229"}, - {name:"CG3",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/JdXHB6LLY8agV8O.jpeg!thumb-w321-webp75",material_id:"20079992238"}, - {name:"CG测试2",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/j4QUVv66nq0P55z.jpeg!thumb-w321-webp75",material_id:"20079991111"}, - {name:"国庆挂历2",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/YkVHj0oP36pmOL1.jpeg!thumb-w321-webp75",material_id:"20079999999"}, - {name:"美化国庆挂历",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/g5yIKQJdqK1aBlQ.jpeg!thumb-w321-webp75",material_id:"20079998888"}, - {name:"在逃公主",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/N8RHzY8o4oKQqEJ.jpeg!thumb-w321-webp75",material_id:"20079992200"}, - {name:"2020美颜默认",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/qR1tRvwgl5mmZDp.jpeg!thumb-w321-webp75",material_id:"20079990088"}, - {name:"复古画册",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/zq9HXROgvWQpXJp.jpeg!thumb-w321-webp75",material_id:"20079990080"}, - {name:"美食1",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/PBXUkeGKl4.jpeg!thumb-w321-webp75",material_id:"20079990060"}, - {name:"美食改",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/8QYIwP5P0x.jpeg!thumb-w321-webp75",material_id:"20079990059"}, - {name:"细细闪",thumbnail:"https://xximg1.meitudata.com/XeVHPQGmWg.jpeg!thumb-w321-webp75",material_id:"20079991001"}, - {name:"细细闪2",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/qR1tRvRVBLmGaQK.jpeg!thumb-w321-webp75",material_id:"20079990069"}, - {name:"新闪闪1",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/aOWsGzGNdEOkngB.jpeg!thumb-w321-webp75",material_id:"20079990068"}, - {name:"新闪闪3-2",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/qR1tRvbq9BkKZZv.jpeg!thumb-w321-webp75",material_id:"20079990078"}, - {name:"新闪闪5",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/j4QUVwNX4q6LV80.jpeg!thumb-w321-webp75",material_id:"20079990077"}, - {name:"天空闪-橙",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/wgRHvqkwVNgzaQO.jpeg!thumb-w321-webp75",material_id:"20079990073"}, - {name:"新说3",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/6kOHRdweoL.jpeg!thumb-w321-webp75",material_id:"20079990057"}, - {name:"新说2",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/QEXSmQ3JNP.jpeg!thumb-w321-webp75",material_id:"20079990056"}, - {name:"新说",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/nBqUo2nYVw.jpeg!thumb-w321-webp75",material_id:"20079990055"}, - {name:"少女胶片颗粒",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/EPdUL929P1.jpeg!thumb-w321-webp75",material_id:"20079990053"}, - {name:"折纸3",thumbnail:"https://xximg1.meitudata.com/j4QUeqxb8N.jpeg!thumb-w321-webp75",material_id:"20079990021"}, - {name:"折纸滤镜",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/dWkuagV42R.jpeg!thumb-w321-webp75",material_id:"20079990050"}, - {name:"温柔纹理2",thumbnail:"https://xximg1.meitudata.com/5JOiDgbOjz.jpeg!thumb-w321-webp75",material_id:"20079990003"}, - {name:"温柔纹理",thumbnail:"https://xximg1.meitudata.com/mbZHy9Kyd4.jpeg!thumb-w321-webp75",material_id:"20079990024"}, - {name:"油画新说1",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/dWkuaga464.jpeg!thumb-w321-webp75",material_id:"20079990054"}, - {name:"油画新说2",thumbnail:"https://xximg1.meitudata.com/V2jTkpeb8e.jpeg!thumb-w321-webp75",material_id:"20079990001"}, - {name:"油画新说3",thumbnail:"https://xximg1.meitudata.com/8QYIw15O85.jpeg!thumb-w321-webp75",material_id:"20079991994"}, - {name:"珍珠2",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/zq9H5VqpGo.jpeg!thumb-w321-webp75",material_id:"20079990043"}, - {name:"珍珠",thumbnail:"https://xximg1.meitudata.com/dWkua4m2NL.jpeg!thumb-w321-webp75",material_id:"20079991002"}, - {name:"爱心月亮",thumbnail:"https://xximg1.meitudata.com/LEKSJEmG9L.png!thumb-w321-webp75",material_id:"20079990041"}, - {name:"星星月亮",thumbnail:"https://xximg1.meitudata.com/3YVfOV8JWX.jpeg!thumb-w321-webp75",material_id:"20079990040"}, - {name:"钢笔淡彩",thumbnail:"https://xximg1.meitudata.com/6kOHRlg2E8.jpeg!thumb-w321-webp75",material_id:"20079990039"}, - {name:"拯救废片2",thumbnail:"https://xximg1.meitudata.com/KeEHax9bao.jpeg!thumb-w321-webp75",material_id:"20079990038"}, - {name:"书本感",thumbnail:"https://xximg1.meitudata.com/WYBfmxXLVz.jpeg!thumb-w321-webp75",material_id:"20079990036"}, - {name:"拯救废片1",thumbnail:"https://xximg1.meitudata.com/dWkuaGDnaG.jpeg!thumb-w321-webp75",material_id:"20079990037"}, - {name:"夏日4",thumbnail:"https://xximg1.meitudata.com/j4QUeglDGW.jpeg!thumb-w321-webp75",material_id:"20079990035"}, - {name:"夏日2",thumbnail:"https://xximg1.meitudata.com/zq9H5obmPq.jpeg!thumb-w321-webp75",material_id:"20079990034"}, - {name:"夏日3",thumbnail:"https://xximg1.meitudata.com/lk0Hk4z4JE.jpeg!thumb-w321-webp75",material_id:"20079990033"}, - {name:"春日柔光",thumbnail:"https://xximg1.meitudata.com/oJQinkgLpN.jpeg!thumb-w321-webp75",material_id:"20079992020"}, - {name:"春日日系",thumbnail:"https://xximg1.meitudata.com/JdXHWgQ588.jpeg!thumb-w321-webp75",material_id:"20079990022"}, - {name:"2020情人节2",thumbnail:"https://xximg1.meitudata.com/p0GcZg6o2m.jpeg!thumb-w321-webp75",material_id:"20079990017"}, - {name:"11",thumbnail:"https://xximg1.meitudata.com/j4QUeR0ylz.jpeg!thumb-w321-webp75",material_id:"20079990014"}, - {name:"锐化+颗粒",thumbnail:"https://xximg1.meitudata.com/nBqUoWm5Eq.jpeg!thumb-w321-webp75",material_id:"20079990015"}, - {name:"22",thumbnail:"https://xximg1.meitudata.com/EPdULoXbK8.jpeg!thumb-w321-webp75",material_id:"20079990004"}, - {name:"2019圣诞2",thumbnail:"https://xximg1.meitudata.com/aOWsL0gy9L.jpeg!thumb-w321-webp75",material_id:"20079990008"}, - {name:"bling裸妆",thumbnail:"https://xximg1.meitudata.com/Z3Vspe2qwl.jpeg!thumb-w321-webp75",material_id:"20079991976"}, - {name:"水雾",thumbnail:"https://xximg1.meitudata.com/eqOHv8b9Jy.jpeg!thumb-w321-webp75",material_id:"20079990009"}, - {name:"泫雅柔光2",thumbnail:"https://xximg1.meitudata.com/1zVH1X80BW.jpeg!thumb-w321-webp75",material_id:"20079990000"}, - {name:"无辜妆",thumbnail:"https://xximg1.meitudata.com/8QYIw5OwzQ.jpeg!thumb-w321-webp75",material_id:"20079990020"}, - {name:"2023",thumbnail:"https://xximg1.meitudata.com/WYBfmyJ4jO.jpeg!thumb-w321-webp75",material_id:"20079992023"}, - {name:"风格妆22",thumbnail:"https://xximg1.meitudata.com/y59IbNv8ek.jpeg!thumb-w321-webp75",material_id:"20079990013"}, - {name:"吸色测试",thumbnail:"https://xximg1.meitudata.com/g5yIOn36zo.jpeg!thumb-w321-webp75",material_id:"20079991234"}, - {name:"爱国",thumbnail:"https://xximg1.meitudata.com/nBqUonb8dG.jpeg!thumb-w321-webp75",material_id:"20079991919"}, - {name:"春樱改良",thumbnail:"https://xximg1.meitudata.com/2zVH1mYp8m.jpeg!thumb-w321-webp75",material_id:"20079991858"}, - {name:"爱心阴影",thumbnail:"https://xximg1.meitudata.com/8QYIw59nPj.jpeg!thumb-w321-webp75",material_id:"20079991935"}, - {name:"无辜妆2",thumbnail:"https://xximg1.meitudata.com/LEKSJPXj2E.jpeg!thumb-w321-webp75",material_id:"20079990006"}, - {name:"1993",thumbnail:"https://xximg1.meitudata.com/vgyHlz3kOv.jpeg!thumb-w321-webp75",material_id:"20079991993"}, - {name:"皮肤质感3",thumbnail:"https://xximg1.meitudata.com/LEKSJooQb8.jpeg!thumb-w321-webp75",material_id:"20079991113"}, - {name:"皮肤质感2",thumbnail:"https://xximg1.meitudata.com/p0GcZPPXNW.jpeg!thumb-w321-webp75",material_id:"20079991112"}, - {name:"皮肤质感",thumbnail:"https://xximg1.meitudata.com/WYBfmDvxQK.jpeg!thumb-w321-webp75",material_id:"20079991884"}, - {name:"万圣2",thumbnail:"https://xximg1.meitudata.com/dWkuap6DpQ.jpeg!thumb-w321-webp75",material_id:"20079991866"}, - {name:"闪闪压缩2",thumbnail:"https://xximg1.meitudata.com/BNPTP2XB6X.jpeg!thumb-w321-webp75",material_id:"20079990030"}, - {name:"闪闪压缩",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/oJQiWKQQE3VWLKR.jpeg!thumb-w321-webp75",material_id:"20079990076"}, - {name:"复古画册加纸纹",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/QEXSyJENWDbBkna.jpeg!thumb-w321-webp75",material_id:"20079990079"}, - {name:"新闪闪2",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/KeEHpDpzvPgVOqY.jpeg!thumb-w321-webp75",material_id:"20079990067"}, - {name:"新闪闪4",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/mbZHO5dyaXPe91g.jpeg!thumb-w321-webp75",material_id:"20079990072"}, - {name:"天空闪",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/bBLUYpzJY518dqa.jpeg!thumb-w321-webp75",material_id:"20079990070"}, - {name:"美食3改",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/RwXHmlPzDO.jpeg!thumb-w321-webp75",material_id:"20079990058"}, - {name:"质感胶片颗粒",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/1zVH1pkp0o.jpeg!thumb-w321-webp75",material_id:"20079990052"}, - {name:"雀斑",thumbnail:"https://xximg1.meitudata.com/bBLUvke8mb.jpeg!thumb-w321-webp75",material_id:"20079991000"}, - {name:"春日柔光1",thumbnail:"https://xximg1.meitudata.com/KeEHa9ZGYO.jpeg!thumb-w321-webp75",material_id:"20079990031"}, - {name:"灰调2",thumbnail:"https://xximg1.meitudata.com/JdXHW51qgp.jpeg!thumb-w321-webp75",material_id:"20079990002"}, - {name:"移轴虚化2",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/WYBf3WkazQXvlwl.jpeg!thumb-w321-webp75",material_id:"506000008"}, - {name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/6kOHqmdRWjl4BEm.jpeg!thumb-w321-webp75",material_id:"50600006"}, - {name:"微光",thumbnail:"https://xximg1.meitudata.com/KeEHa4wl8p.jpeg!thumb-w321-webp75",material_id:"20076251574"}, - {name:"微光",thumbnail:"https://xximg1.meitudata.com/eqZUvNY3YL.png!thumb-w321-webp75",material_id:"20076251567"}, - {name:"微光",thumbnail:"https://xximg1.meitudata.com/BNPTPoVbeV.jpeg!thumb-w321-webp75",material_id:"20076251575"}, - {name:"微光",thumbnail:"https://xximg1.meitudata.com/bBZcvmqk8z.png!thumb-w321-webp75",material_id:"20076251568"}, - {name:"微光",thumbnail:"https://xximg1.meitudata.com/g5yIOPJmZn.jpeg!thumb-w321-webp75",material_id:"20076251573"}, - {name:"微光",thumbnail:"https://xximg1.meitudata.com/5JeHDVNROj.png!thumb-w321-webp75",material_id:"20076251569"}, - {name:"微光",thumbnail:"https://xximg1.meitudata.com/wgNU3PJVzR.png!thumb-w321-webp75",material_id:"20076251577"}, - {name:"17.素材无人脸规则",thumbnail:"https://xxtool-release.zone1.meitudata.com/owv1PzKKkaEz.jpg!thumb-w321-webp75",material_id:"506088832"}, - {name:"22.天空分割滤镜",thumbnail:"https://xxtool-release.zone1.meitudata.com/laM7B2WRZRve.jpg!thumb-w321-webp75",material_id:"506088818"}, - {name:"11.柔发效果支持",thumbnail:"https://xxtool-release.zone1.meitudata.com/L24ZJRgYjyw5.png!thumb-w321-webp75",material_id:"506088812"}, - {name:"13.3D打光",thumbnail:"https://xxtool-release.zone1.meitudata.com/owv1PzXYWoxL.png!thumb-w321-webp75",material_id:"506088810"}, - {name:"(仅日本)10.不带妆容",thumbnail:"https://xxtool-release.zone1.meitudata.com/y1B45rOXGkBW.jpeg!thumb-w321-webp75",material_id:"506088811"}, - {name:"12.妆容滤镜层级控制1",thumbnail:"https://xxtool-release.zone1.meitudata.com/e4xlJA94A6Mp.png!thumb-w321-webp75",material_id:"506088831"}, - {name:"6.强制曝光滤镜",thumbnail:"https://xxtool-release.zone1.meitudata.com/kOo1k0DW9drL.jpg!thumb-w321-webp75",material_id:"506088835"}, - {name:"5.男生、女生滤镜",thumbnail:"https://xxtool-release.zone1.meitudata.com/OmB4J1oagj0M.jpg!thumb-w321-webp75",material_id:"506088815"}, - {name:"4.带有动效滤镜",thumbnail:"https://xxtool-release.zone1.meitudata.com/V06dJl3051WA.jpg!thumb-w321-webp75",material_id:"506088823"}, - {name:"12.妆容滤镜层级控制",thumbnail:"https://xxtool-release.zone1.meitudata.com/kOo1k0Nva6LL.png!thumb-w321-webp75",material_id:"506088816"}, - {name:"3.妆容滤镜",thumbnail:"https://xxtool-release.zone1.meitudata.com/OmB4J13jO5Dg.jpg!thumb-w321-webp75",material_id:"506088822"}, - {name:"2.bling滤镜",thumbnail:"https://xxtool-release.zone1.meitudata.com/e4xlJA9WZJoy.jpg!thumb-w321-webp75",material_id:"506088834"}, - {name:"1.随机滤镜",thumbnail:"https://xxtool-release.zone1.meitudata.com/GYZza015D1LE.jpg!thumb-w321-webp75",material_id:"506088824"}, - {name:"19.素材多比例滤镜",thumbnail:"https://xxtool-release.zone1.meitudata.com/B6MlzDxYm10N.jpg!thumb-w321-webp75",material_id:"506088821"}, - {name:"16.美食手绘效果",thumbnail:"https://xxtool-release.zone1.meitudata.com/4JpRm4Em6Y7J.jpg!thumb-w321-webp75",material_id:"506088833"}, - {name:"16.美食手绘效果2",thumbnail:"https://xxtool-release.zone1.meitudata.com/3zVRNe69zMKM.jpg!thumb-w321-webp75",material_id:"506088829"}, - {name:"23.妆容滤镜",thumbnail:"https://xxtool-release.zone1.meitudata.com/L24ZJRgjNYWe.jpg!thumb-w321-webp75",material_id:"506088814"}, - {name:"18.径向色散效果",thumbnail:"https://xxtool-release.zone1.meitudata.com/y1B45rOEZeMP.jpg!thumb-w321-webp75",material_id:"506088813"}, - {name:"14.新bling效果",thumbnail:"https://xxtool-release.zone1.meitudata.com/y1B45rp8Ky7z.png!thumb-w321-webp75",material_id:"506088837"}, - {name:"绵绵",thumbnail:"https://xximg1.meitudata.com/EPdUL42bLj.jpeg!thumb-w321-webp75",material_id:"20076412020"}, - {name:"清澈",thumbnail:"https://xximg1.meitudata.com/nBqUo6pveO.jpeg!thumb-w321-webp75",material_id:"20076412057"}, - {name:"阴雨",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/N3OFzPJbwBgXG6z.jpeg!thumb-w321-webp75",material_id:"506002342"}, - {name:"ar胶片",thumbnail:"https://xximg1.meitudata.com/lkjUk85p5G.png!thumb-w321-webp75",material_id:"20108891781"}, - {name:"INS",thumbnail:"https://xximg1.meitudata.com/bBLUv93q2O.jpeg!thumb-w321-webp75",material_id:"20108890012"}, - {name:"高级灰",thumbnail:"https://xximg1.meitudata.com/jzOIeJz1mK.png!thumb-w321-webp75",material_id:"20108891777"}, - {name:"夜景2",thumbnail:"https://xximg1.meitudata.com/1zVH1nl3nL.jpeg!thumb-w321-webp75",material_id:"20108890014"}, - {name:"藕色颗粒",thumbnail:"https://xximg1.meitudata.com/V2jTkoQgO6.jpeg!thumb-w321-webp75",material_id:"20108890015"}, - {name:"胶片1",thumbnail:"https://xximg1.meitudata.com/KnJSa8gWE4.png!thumb-w321-webp75",material_id:"20108891783"}, - {name:"fuji",thumbnail:"https://xximg1.meitudata.com/qR1tJbvd5d.jpeg!thumb-w321-webp75",material_id:"20108890010"}, - {name:"咸咸测试",thumbnail:"https://xximg1.meitudata.com/EPdULqxXOR.jpeg!thumb-w321-webp75",material_id:"20108899999"}, - {name:"古风藕色",thumbnail:"https://xximg1.meitudata.com/JdXHWjK4o9.jpeg!thumb-w321-webp75",material_id:"20108891775"}, - {name:"natural1",thumbnail:"https://xximg1.meitudata.com/zq9H5ekDQv.jpeg!thumb-w321-webp75",material_id:"20108891682"}, - {name:"受伤妆",thumbnail:"https://xximg1.meitudata.com/nBqUoEKnoD.jpeg!thumb-w321-webp75",material_id:"20108891787"}, - {name:"natural2",thumbnail:"https://xximg1.meitudata.com/j4QUedKlNv.jpeg!thumb-w321-webp75",material_id:"20108891848"}, - {name:"描边2",thumbnail:"https://xximg1.meitudata.com/4VOC9QOZRd.jpeg!thumb-w321-webp75",material_id:"20108891835"}, - {name:"natural3",thumbnail:"https://xximg1.meitudata.com/9nOHy6gJOb.jpeg!thumb-w321-webp75",material_id:"20108890019"}, - {name:"宝丽来1",thumbnail:"https://xximg1.meitudata.com/JdXHW5qp88.jpeg!thumb-w321-webp75",material_id:"20108891840"}, - {name:"日系复古",thumbnail:"https://xximg1.meitudata.com/6zZIRWym8L.png!thumb-w321-webp75",material_id:"20108891846"}, - {name:"暗调测试",thumbnail:"https://xximg1.meitudata.com/YkVH1pNvLW.jpeg!thumb-w321-webp75",material_id:"20108897777"}, - {name:"宝丽来2",thumbnail:"https://xximg1.meitudata.com/6kOHRWaqeJ.jpeg!thumb-w321-webp75",material_id:"20108891841"}, - {name:"海外柔光",thumbnail:"https://xximg1.meitudata.com/p0GcZyqa5z.jpeg!thumb-w321-webp75",material_id:"20108891801"}, - {name:"绯红",thumbnail:"https://xximg1.meitudata.com/wgNU340lGP.png!thumb-w321-webp75",material_id:"20108891770"}, - {name:"霜色",thumbnail:"https://xximg1.meitudata.com/lkjUkL6GXp.png!thumb-w321-webp75",material_id:"20108891769"}, - {name:"梅幸茶",thumbnail:"https://xximg1.meitudata.com/GPWcPEw1Wj.png!thumb-w321-webp75",material_id:"20108891771"}, - {name:"水墨",thumbnail:"https://xximg1.meitudata.com/9nzUyjane8.png!thumb-w321-webp75",material_id:"20108891772"}, - {name:"1780",thumbnail:"https://xximg1.meitudata.com/vgyHlJoLg3.jpeg!thumb-w321-webp75",material_id:"20108891780"}, - {name:"描边3",thumbnail:"https://xximg1.meitudata.com/nBqUoz0g3y.jpeg!thumb-w321-webp75",material_id:"20108891837"}, - {name:"描边4",thumbnail:"https://xximg1.meitudata.com/1zVH1XvE4z.jpeg!thumb-w321-webp75",material_id:"20108891838"}, - {name:"描边1",thumbnail:"https://xximg1.meitudata.com/WYBfmdWOoQ.jpeg!thumb-w321-webp75",material_id:"20108891834"}, - {name:"青空",thumbnail:"https://xximg1.meitudata.com/8OkUwBympV.jpeg!thumb-w321-webp75",material_id:"20106311844"}, - {name:"暮霭",thumbnail:"https://xximg1.meitudata.com/9QktyzB0nW.jpeg!thumb-w321-webp75",material_id:"20106311843"}, - {name:"糖果",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/qp4IReJkzbEZD41.jpeg!thumb-w321-webp75",material_id:"506002348"}, - {name:"苏打",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/nplIo2XOm6.jpeg!thumb-w321-webp75",material_id:"20096442168"}, - {name:"淡奶油",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/PVQIkeOx5L.jpeg!thumb-w321-webp75",material_id:"20096442169"}, - {name:"温柔",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/N8RHqBW392.jpeg!thumb-w321-webp75",material_id:"20096442166"}, - {name:"珠光",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/nBqUo2X8lP.jpeg!thumb-w321-webp75",material_id:"20096442165"}, - {name:"丝绸",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/BNPTPWpNRL.jpeg!thumb-w321-webp75",material_id:"20096442167"}, - {name:"黑白",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/OXOHRJnJ5vOXBpY.jpeg!thumb-w321-webp75",material_id:"20096081095"}, - {name:"暗房",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/eqZU6dBdw3EY3d1.jpeg!thumb-w321-webp75",material_id:"506002307"}, - {name:"低反差",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/4VQtnwmwpBL5wDN.jpeg!thumb-w321-webp75",material_id:"506002309"}, - {name:"森山",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/1zXUmEWE4DWbQW2.jpeg!thumb-w321-webp75",material_id:"506002313"}, - {name:"Instant",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/qRdTR9w9ygLqdeb.jpeg!thumb-w321-webp75",material_id:"506002310"}, - {name:"范戴克",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/BNGiqXNXZkljKlb.jpeg!thumb-w321-webp75",material_id:"506002312"}, - {name:"圣诞",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/PVQIdno4bnlEEOq.jpeg!thumb-w321-webp75",material_id:"20076452266"}, - {name:"小梦境",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/2zVHEkJKPj3q5nz.jpeg!thumb-w321-webp75",material_id:"20076452193"}, - {name:"在逃公主",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/lk0HjoJRKlq9E0Z.jpeg!thumb-w321-webp75",material_id:"20076452200"}, - {name:"璀璨",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/DyOHJWjXJGk6Ojl.jpeg!thumb-w321-webp75",material_id:"20076452189"}, - {name:"星河",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/LEKSjB8pREZExxZ.jpeg!thumb-w321-webp75",material_id:"20076452180"}, - {name:"星河II",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/g5yIKQq99XvKZQP.jpeg!thumb-w321-webp75",material_id:"20076452181"}, - {name:"星河III",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/oJQiWKVVJNXe3PB.jpeg!thumb-w321-webp75",material_id:"20076452184"}, - {name:"年味",thumbnail:"https://xximg1.meitudata.com/EVvILvqjRQ.jpeg!thumb-w321-webp75",material_id:"20076352017"}, - {name:"白日梦 ",thumbnail:"https://xximg1.meitudata.com/vgyHlzq34j.jpeg!thumb-w321-webp75",material_id:"20076351989"}, - {name:"白桃",thumbnail:"https://xximg1.meitudata.com/g5eFOnEgJj.png!thumb-w321-webp75",material_id:"20076351888"}, - {name:"Norge",thumbnail:"https://xximg1.meitudata.com/9nOHylkdjn.jpeg!thumb-w321-webp75",material_id:"2007635584"}, - {name:"冬至",thumbnail:"https://xximg1.meitudata.com/zqOU5K9Q5m.png!thumb-w321-webp75",material_id:"20076351887"}, - {name:"红杉",thumbnail:"https://xximg1.meitudata.com/QEasmkjv09.png!thumb-w321-webp75",material_id:"20076351981"}, - {name:"暖暖 ",thumbnail:"https://xximg1.meitudata.com/y59Ib9kQZw.jpeg!thumb-w321-webp75",material_id:"20076351988"}, - {name:"神仙奶油光",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/XRLI50zwLEBpQ19.jpeg!thumb-w321-webp75",material_id:"20096472176"}, - {name:"神仙奶油光Ⅱ",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/PVQIdB3VbL63GQN.jpeg!thumb-w321-webp75",material_id:"20096472177"}, - {name:"法式油画",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/99ETGwRbEnKn9qd.jpeg!thumb-w321-webp75",material_id:"20096472178"}, - {name:"法式油画Ⅱ",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/wkQsvqJNVn9GaaP.jpeg!thumb-w321-webp75",material_id:"20096472179"}, - {name:"曼哈顿大桥",thumbnail:"https://xximg1.meitudata.com/bBLUvjadBB.jpeg!thumb-w321-webp75",material_id:"20106301861"}, - {name:"维多利亚港",thumbnail:"https://xximg1.meitudata.com/wgRH3jVEDg.jpeg!thumb-w321-webp75",material_id:"20106301862"}, - {name:"新宿",thumbnail:"https://xximg1.meitudata.com/x5eIQyn1bp.jpeg!thumb-w321-webp75",material_id:"20106301935"}, - {name:"那不勒斯",thumbnail:"https://xximg1.meitudata.com/zqOU5LPDwe.png!thumb-w321-webp75",material_id:"20106301936"}, - {name:"赛博朋克",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/ykGslXOBVOZ1wZm.jpeg!thumb-w321-webp75",material_id:"20106302217"}, - {name:"盐系",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/29gtLmJEWLAadDk.jpeg!thumb-w321-webp75",material_id:"20096522258"}, - {name:"29",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/wOXiNM4O8Jxyv7E.jpeg!thumb-w321-webp75",material_id:"506030029"}, - {name:"28",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/jkEIPyplzRPYXmP.jpeg!thumb-w321-webp75",material_id:"506030028"}, - {name:"27",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/JgpCWo3NL2G81JZ.jpeg!thumb-w321-webp75",material_id:"506030027"}, - {name:"26",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/DpWhZ42RzkXpDgW.jpeg!thumb-w321-webp75",material_id:"5060230026"}, - {name:"25",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/Ng9CWAVaM342ERY.jpeg!thumb-w321-webp75",material_id:"506030025"}, - {name:"24",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/3MLhOxa9x2m49Rp.jpeg!thumb-w321-webp75",material_id:"506030024"}, - {name:"23",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/Ng9CWAVy999Ea27.jpeg!thumb-w321-webp75",material_id:"506030023"}, - {name:"22",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/mjkuw39egW2Lv9V.jpeg!thumb-w321-webp75",material_id:"506030022"}, - {name:"21",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/9L1IrA1E6l7799X.jpeg!thumb-w321-webp75",material_id:"506030021"}, - {name:"20",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/rOwi0AkzJo210E5.jpeg!thumb-w321-webp75",material_id:"506030020"}, - {name:"19",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/ed7IAoW6mr4OVwl.jpeg!thumb-w321-webp75",material_id:"506030019"}, - {name:"18",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/3MLhOx2A2R5GJom.jpeg!thumb-w321-webp75",material_id:"506030018"}, - {name:"17",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/DpWhZ4mE9OZYEv2.jpeg!thumb-w321-webp75",material_id:"506030017"}, - {name:"16",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/lK4H8LpVG7o8ZWo.jpeg!thumb-w321-webp75",material_id:"506030016"}, - {name:"15",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/JgpCWoverVMGlGE.jpeg!thumb-w321-webp75",material_id:"506030015"}, - {name:"14",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/rOwi0Akmj2Wrg8e.jpeg!thumb-w321-webp75",material_id:"506030014"}, - {name:"13",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/ZWdUX61ERRREYx7.jpeg!thumb-w321-webp75",material_id:"506030013"}, - {name:"12",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/Ng9CWAdDvZDZWN0.jpeg!thumb-w321-webp75",material_id:"506030012"}, - {name:"10",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/5O0iJdZB9VKpZYK.jpeg!thumb-w321-webp75",material_id:"506030006"}, - {name:"9",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/AY4T4jpeo29dAJY.jpeg!thumb-w321-webp75",material_id:"506030005"}, - {name:"8",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/EZNHdk171m9Z1Zp.jpeg!thumb-w321-webp75",material_id:"506030004"}, - {name:"7",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/ed7IAorRPGr2DV1.jpeg!thumb-w321-webp75",material_id:"506030003"}, - {name:"测试红点6",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/wOXiNMwZDXGyaOW.jpeg!thumb-w321-webp75",material_id:"506030002"}, - {name:"测试红点5",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/9L1IrAz4yYjKLOp.jpeg!thumb-w321-webp75",material_id:"506030001"}, - {name:"测试红点4",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/EZNHdk1owgyDp9Z.jpeg!thumb-w321-webp75",material_id:"5060238998"}, - {name:"测试红点3",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/3MLhOxDGxyVLwmV.jpeg!thumb-w321-webp75",material_id:"5060238997"}, - {name:"测试红点2",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/jkEIPyVeNwvW4X8.jpeg!thumb-w321-webp75",material_id:"5060238996"}, - {name:"测试红点",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/3MLhOxDGZNlxerJ.jpeg!thumb-w321-webp75",material_id:"5060238995"}, - {name:"123",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/8LxIzOLaGM06Ekx.jpeg!thumb-w321-webp75",material_id:"5060238991"}, - {name:"小草3",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/09mIW9BGz4DdNPK.jpeg!thumb-w321-webp75",material_id:"5060238990"}, - {name:"小草2",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/wOXiNMPBxwoymBv.jpeg!thumb-w321-webp75",material_id:"5060238989"}, - {name:"小草",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/rOwi0AO9BdZzzkv.jpeg!thumb-w321-webp75",material_id:"5060238988"}, - {name:"星星1",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/71zSrY2veyMDEaE.jpeg!thumb-w321-webp75",material_id:"506010255"}, - {name:"小树1",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/4AVSv70z5YzveBy.jpeg!thumb-w321-webp75",material_id:"506010256"}, - {name:"小花4",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/G5wUz1B4zNpRE0P.jpeg!thumb-w321-webp75",material_id:"506010254"}, - {name:"31",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/Kg2CJr4d5PKRP4p.jpeg!thumb-w321-webp75",material_id:"506030031"}, - {name:"西西里",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/yNmTl3VBD1Nz5yE.jpeg!thumb-w321-webp75",material_id:"506002337"}, - {name:"尼斯",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/5JeH8E3e6Vvq8YY.jpeg!thumb-w321-webp75",material_id:"506002331"}, - {name:"布达佩斯",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/lkjUjRxbeV2moG0.jpeg!thumb-w321-webp75",material_id:"20096082224"}, - {name:"月升",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/qRdTRadQlQanwQa.jpeg!thumb-w321-webp75",material_id:"20096082225"}, - {name:"聚会",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/5JeH8ZOg14O3Jq6.jpeg!thumb-w321-webp75",material_id:"20096082226"}, - {name:"法兰西",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/8QzFJz90eZ3lExp.jpeg!thumb-w321-webp75",material_id:"20096082227"}, - {name:"油画",thumbnail:"https://xximg1.meitudata.com/BNPTPRjbyl.jpeg!thumb-w321-webp75",material_id:"20096082032"}, - {name:"油画Ⅱ",thumbnail:"https://xximg1.meitudata.com/8QYIw41QVq.jpeg!thumb-w321-webp75",material_id:"20096082033"}, - {name:"安东尼亚",thumbnail:"https://xximg1.meitudata.com/2LqS1vmqv0.png!thumb-w321-webp75",material_id:"20096082038"}, - {name:"情人节限定",thumbnail:"https://xximg1.meitudata.com/8QYIwbzm81.jpeg!thumb-w321-webp75",material_id:"20096082019"}, - {name:"勒芒",thumbnail:"https://xximg1.meitudata.com/ndzuolR3v9.jpeg!thumb-w321-webp75",material_id:"20096081869"}, - {name:"电影",thumbnail:"https://xximg1.meitudata.com/PBXUkm2yq5.jpeg!thumb-w321-webp75",material_id:"20096081274"}, - {name:"1980",thumbnail:"http://xximg2.meitudata.com/LEKSJx0N8y.jpeg!thumb-w321-webp75",material_id:"20096081108"}, - {name:"电影",thumbnail:"http://xximg2.meitudata.com/6kOHRa1OpD.jpeg!thumb-w321-webp75",material_id:"20096081253"}, - {name:"中环码头",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/496TnZaRxddxonY.jpeg!thumb-w321-webp75",material_id:"2009608530"}, - {name:"显影",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/8QYIJLL6NE94K2l.jpeg!thumb-w321-webp75",material_id:"20086391964"}, - {name:"焦点",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/8QYIJLL6o5PVGyv.jpeg!thumb-w321-webp75",material_id:"20086391965"}, - {name:"扫街",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/5JOi8ooNJ25wpg2.jpeg!thumb-w321-webp75",material_id:"20086391963"}, - {name:"Photog",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/OX8iREk4LJ3qgad.jpeg!thumb-w321-webp75",material_id:"20086391968"}, - {name:"超焦距",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/5JOi8ZQeZkvzQQD.jpeg!thumb-w321-webp75",material_id:"20086391970"}, - {name:"影调",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/XeVH5bx1bz4NVdk.jpeg!thumb-w321-webp75",material_id:"20086391967"}, - {name:"名称一",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/MKosgAWo5VKpo9Z.jpeg!thumb-w321-webp75",material_id:"50600999"}, - {name:"修改测试",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/69MiA9VxKdkzjWR.png!thumb-w321-webp75",material_id:"50600229"}, - {name:"有门槛的我",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/P98i3gdgDw3Rmx5.png!thumb-w321-webp75",material_id:"506093422"}, - {name:"222嗯嗯1",thumbnail:"https://stage.meitudata.com/public/creator/ed70a3c696c8e7b.jpg!thumb-w321-webp75",material_id:"50693244"}, - {name:"抠图批量拼图",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/pA2S9lvNpMY4X3N.jpeg!thumb-w321-webp75",material_id:"506002368"}, - {name:"滤镜流程11",thumbnail:"https://material-center-pre.meitudata.com/material/image/6194a57b5b9ef7678.jpg!thumb-w321-webp75",material_id:"506017292"}, - {name:"月辉",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/wOXiBYpWgxA7ej5.jpeg!thumb-w321-webp75",material_id:"5060112313"}, - {name:"旧-美食手绘1",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/0lZCW9BrDgMroLL.jpeg!thumb-w321-webp75",material_id:"5060002001"}, - {name:"hsxTest11.8",thumbnail:"https://material-center-pre.meitudata.com/material/image/6189f29b48f165954.jpg!thumb-w321-webp75",material_id:"506530963"}, - {name:"GT G",thumbnail:"http://xximg2.meitudata.com/Z9DCJpkB2l.jpeg!thumb-w321-webp75",material_id:"20085081215"}, - {name:"自然",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/j4QUVvP9GPkJ4n3.jpeg!thumb-w321-webp75",material_id:"20076051317"}, - {name:"自然",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/5JOi8o1nKlqXmb2.jpeg!thumb-w321-webp75",material_id:"20076051233"}, - {name:"Room",thumbnail:"https://xximg1.meitudata.com/WYphm4QnOx.jpeg!thumb-w321-webp75",material_id:"20076052148"}, - {name:"模糊",thumbnail:"https://xximg1.meitudata.com/qR1tJmaVZg.jpeg!thumb-w321-webp75",material_id:"20076052016"}, - {name:"追光",thumbnail:"https://xximg1.meitudata.com/mbZHyl6E8Y.jpeg!thumb-w321-webp75",material_id:"20076051714"}, - {name:"春樱",thumbnail:"https://xximg1.meitudata.com/OX8i0kV1vG.jpeg!thumb-w321-webp75",material_id:"20076051634"}, - {name:"夏橙",thumbnail:"https://xximg1.meitudata.com/YkVH1doZzv.jpeg!thumb-w321-webp75",material_id:"20076051635"}, - {name:"梨花白",thumbnail:"https://xximg1.meitudata.com/bBLUvgJmoK.jpeg!thumb-w321-webp75",material_id:"20076051633"}, - {name:"青柠",thumbnail:"https://xximg1.meitudata.com/gn9SOPYgQ6.jpeg!thumb-w321-webp75",material_id:"20076051733"}, - {name:"西柚",thumbnail:"https://xximg1.meitudata.com/WXgfmKYZJv.jpeg!thumb-w321-webp75",material_id:"20076051628"}, - {name:"恋人未满",thumbnail:"https://xximg1.meitudata.com/3YVfO0zBXJ.jpeg!thumb-w321-webp75",material_id:"20076051075"}, - {name:"春樱",thumbnail:"https://xximg1.meitudata.com/k5DIOxgJpN.jpeg!thumb-w321-webp75",material_id:"20076291634"}, - {name:"自然",thumbnail:"https://xximg1.meitudata.com/nBqUoGPX5Q.jpeg!thumb-w321-webp75",material_id:"20076051907"}, - {name:"Forest",thumbnail:"https://xximg1.meitudata.com/V2jTkoYa96.jpeg!thumb-w321-webp75",material_id:"20106191835"}, - {name:"高级灰Ⅱ",thumbnail:"https://xximg1.meitudata.com/LEKSJO5x8V.jpeg!thumb-w321-webp75",material_id:"20076051853"}, - {name:"晴空",thumbnail:"https://xximg1.meitudata.com/LEKSJO5VaL.jpeg!thumb-w321-webp75",material_id:"20076052027"}, - {name:"白兔糖",thumbnail:"https://xximg1.meitudata.com/k5DIOjzV9d.jpeg!thumb-w321-webp75",material_id:"2007605675"}, - {name:"测",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/zwdte8R2e5KMMmm.jpeg!thumb-w321-webp75",material_id:"506000000"}, - {name:"素颜",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/DyOHJNKyxWGbpeg.jpeg!thumb-w321-webp75",material_id:"20076052222"}, - {name:"奶杏",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/3YVf1DOlq5jVlLe.jpeg!thumb-w321-webp75",material_id:"20076052221"}, - {name:"蜜桃",thumbnail:"https://xximg1.meitudata.com/9QktygQgDn.jpeg!thumb-w321-webp75",material_id:"20076291732"}, - {name:"青柠",thumbnail:"https://xximg1.meitudata.com/edzuvqDqwJ.jpeg!thumb-w321-webp75",material_id:"20076291733"}, - {name:"西柚",thumbnail:"https://xximg1.meitudata.com/kGVuOxgxm5.jpeg!thumb-w321-webp75",material_id:"20076291628"}, - {name:"牛油果",thumbnail:"https://xximg1.meitudata.com/1zXU1zyp3V.jpeg!thumb-w321-webp75",material_id:"20076292053"}, - {name:"胶片字体1",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/wkQsv9BqOlk01j6.jpeg!thumb-w321-webp75",material_id:"506001241"}, - {name:"503cw",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/YadfjNxP2ng3b0v.jpeg!thumb-w321-webp75",material_id:"506001236"}, - {name:"爱心",thumbnail:"https://xximg1.meitudata.com/8D5Fwm9VLE.jpeg!thumb-w321-webp75",material_id:"20079971111"}, - {name:"",thumbnail:"https://xximg1.meitudata.com/xkbsQOl9bX.jpeg!thumb-w321-webp75",material_id:"20079971995"}, - {name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/YadfjWvZDeK8Pjb.jpeg!thumb-w321-webp75",material_id:"200799700078"}, - {name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/54Kf8ZNP6YkBdnZ.jpeg!thumb-w321-webp75",material_id:"200799700077"}, - {name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/20dfEzWa33vvbEJ.jpeg!thumb-w321-webp75",material_id:"200799700076"}, - {name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/L3xFj5Y1l5qyO8k.jpeg!thumb-w321-webp75",material_id:"200799700075"}, - {name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/qp4IRaqOvg208Vx.jpeg!thumb-w321-webp75",material_id:"200799700074"}, - {name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/opkIW3BY6gJ6DP8.jpeg!thumb-w321-webp75",material_id:"200799700073"}, - {name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/39nT1zN9v2p5BBy.jpeg!thumb-w321-webp75",material_id:"200799700072"}, - {name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/Kz3fp1lekbGJY52.jpeg!thumb-w321-webp75",material_id:"200799700071"}, - {name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/20dfEz9V3L935WD.jpeg!thumb-w321-webp75",material_id:"200799700070"}, - {name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/R3GFJpZEd0pD5xY.jpeg!thumb-w321-webp75",material_id:"200799700069"}, - {name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/54Kf8o3GlPJgW3Q.jpeg!thumb-w321-webp75",material_id:"200799700067"}, - {name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/DaofJN9Gzxd8O5a.jpeg!thumb-w321-webp75",material_id:"200799700063"}, - {name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/qp4IRN9PaZ1Penl.jpeg!thumb-w321-webp75",material_id:"200799700055"}, - {name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/vkRsK6OxQ60gkJR.jpeg!thumb-w321-webp75",material_id:"200799700045"}, - {name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/1ZLIm5ExEmVpobj.jpeg!thumb-w321-webp75",material_id:"200799700053"}, - {name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/wkQsvL9y9XX1ZL8.jpeg!thumb-w321-webp75",material_id:"200799700054"}, - {name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/BmDFqnXBXod6LKx.jpeg!thumb-w321-webp75",material_id:"200799700061"}, - {name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/39nT1DmnGNQp8Gy.jpeg!thumb-w321-webp75",material_id:"200799700060"}, - {name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/k2ou2a6aPWDR5nX.jpeg!thumb-w321-webp75",material_id:"200799700058"}, - {name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/Q3bFyBOB1DxY6Dx.jpeg!thumb-w321-webp75",material_id:"200799700059"}, - {name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/O3RFRL3v0Jpd0Wk.jpeg!thumb-w321-webp75",material_id:"200799700057"}, - {name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/BmDFqnWadYGzXxP.jpeg!thumb-w321-webp75",material_id:"20079970049"}, - {name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/Q3bFyBQ8JLx2Wvb.jpeg!thumb-w321-webp75",material_id:"20079970051"}, - {name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/vkRsK6eLxeGj9w8.jpeg!thumb-w321-webp75",material_id:"200799700041"}, - {name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/gkmsKBGp36w8wEO.jpeg!thumb-w321-webp75",material_id:"200799700056"}, - {name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/ee9h6Qk4Y1wJpoY.jpeg!thumb-w321-webp75",material_id:"200799700047"}, - {name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/jeyhVvLBDqo64yy.jpeg!thumb-w321-webp75",material_id:"20079970050"}, - {name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/DaofJNY4pKnpQxa.jpeg!thumb-w321-webp75",material_id:"20079970053"}, - {name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/99ETG9z6NzjmBwQ.jpeg!thumb-w321-webp75",material_id:"200799700046"}, - {name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/ee9h6QD4PGmGBGa.jpeg!thumb-w321-webp75",material_id:"200799700042"}, - {name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/BmDFqnwGbGvXPq3.png!thumb-w321-webp75",material_id:"200799700038"}, - {name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/VwJigjRRPoRz8Xl.png!thumb-w321-webp75",material_id:"200799700039"}, - {name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/54Kf8BmB9dyqY2k.jpeg!thumb-w321-webp75",material_id:"200799700027"}, - {name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/ze1hXRywlnq18zj.jpeg!thumb-w321-webp75",material_id:"200799700025"}, - {name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/xkbs1eVvOEB46wE.jpeg!thumb-w321-webp75",material_id:"200799700032"}, - {name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/bxgsY85V4j5W3PY.jpeg!thumb-w321-webp75",material_id:"200799700034"}, - {name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/54Kf8oxaX5kVpN6.jpeg!thumb-w321-webp75",material_id:"200799700033"}, - {name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/EVvIj5VjGJyBNLO.png!thumb-w321-webp75",material_id:"200799700031"}, - {name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/Q3bFyJ2yqXlmJJz.png!thumb-w321-webp75",material_id:"200799700030"}, - {name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/1ZLImgemPooxWqv.jpeg!thumb-w321-webp75",material_id:"200799700024"}, - {name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/8D5FJjdJmO4VRbg.jpeg!thumb-w321-webp75",material_id:"200799700029"}, - {name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/EVvIj595ekZpN3X.jpeg!thumb-w321-webp75",material_id:"200799700023"}, - {name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/vkRsKg3OONyzZLb.png!thumb-w321-webp75",material_id:"200799700021"}, - {name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/496TndEvWqJynwo.png!thumb-w321-webp75",material_id:"200799700019"}, - {name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/8D5FJjkBmkNlpkd.png!thumb-w321-webp75",material_id:"200799700020"}, - {name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/WPWF3ODzRYPzo3K.jpeg!thumb-w321-webp75",material_id:"200799700018"}, - {name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/PVQIdBDb3b998XB.jpeg!thumb-w321-webp75",material_id:"200799700017"}, - {name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/99ETGwpo0Lv8dEZ.jpeg!thumb-w321-webp75",material_id:"200799700008"}, - {name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/gkmsKQKGPVm3j8E.jpeg!thumb-w321-webp75",material_id:"200799700012"}, - {name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/8D5FJjJJ310zYBQ.jpeg!thumb-w321-webp75",material_id:"200799700010"}, - {name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/lpvIjojjEYRbwWL.jpeg!thumb-w321-webp75",material_id:"200799700011"}, - {name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/xkbs1e1ee83wlP0.jpeg!thumb-w321-webp75",material_id:"200799700014"}, - {name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/DaofJWJnxRe3W09.jpeg!thumb-w321-webp75",material_id:"200799700015"}, - {name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/XRLI50Bdlg9joZ2.png!thumb-w321-webp75",material_id:"200799700009"}, - {name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/99ETGwkej4aqVjo.png!thumb-w321-webp75",material_id:"200799700016"}, - {name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/VwJikyzE29.png!thumb-w321-webp75",material_id:"200799700000"}, - {name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/ze1h5O9oKb.jpeg!thumb-w321-webp75",material_id:"200799700002"}, - {name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/a3wFLXLnx2.jpeg!thumb-w321-webp75",material_id:"200799700001"}, - {name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/6DqFRdykvn.png!thumb-w321-webp75",material_id:"200799700004"}, - {name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/1ZLI1pjZgP.jpeg!thumb-w321-webp75",material_id:"200799700003"}, - {name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/opkIn0ZXgW.jpeg!thumb-w321-webp75",material_id:"200799700006"}, - {name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/ze1h5VwNLD.jpeg!thumb-w321-webp75",material_id:"20079976666"}, - {name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/mlahykPGYd.jpeg!thumb-w321-webp75",material_id:"2007997666"}, - {name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/XRLIPQX4qj.jpeg!thumb-w321-webp75",material_id:"20079972"}, - {name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/k2ouOWwP2b.jpeg!thumb-w321-webp75",material_id:"20079971"}, - {name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/xkbsQP2W5z.jpeg!thumb-w321-webp75",material_id:"20079971234"}, - {name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/EVvIjl5B2q1P3Ld.jpeg!thumb-w321-webp75",material_id:"200799700062"}, - {name:"新年静物",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/8D5FJzenN2v99KG.jpeg!thumb-w321-webp75",material_id:"200799700079"}, - {name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/20dfEzd1lndjOwg.jpeg!thumb-w321-webp75",material_id:"20079972282"}, - {name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/nplIyLnnEm9o41W.png!thumb-w321-webp75",material_id:"200799700022"}, - {name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/ze1h5ONoeg.png!thumb-w321-webp75",material_id:"200799700007"}, - {name:"原生",thumbnail:"https://xximg1.meitudata.com/XeVHPQpbgR.jpeg!thumb-w321-webp75",material_id:"20079930000"}, - {name:"减龄2",thumbnail:"https://xximg1.meitudata.com/GPoUPW5m8n.jpeg!thumb-w321-webp75",material_id:"20079930003"}, - {name:"质感",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/nBJcyLgw0QZmvB2.png!thumb-w321-webp75",material_id:"20079932147"}, - {name:"眼睑下至",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/1zVH1xKebW.jpeg!thumb-w321-webp75",material_id:"20079930007"}, - {name:"原生2",thumbnail:"https://xximg1.meitudata.com/aOWsLZ14vp.jpeg!thumb-w321-webp75",material_id:"20079930001"}, - {name:"减龄2优化",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/5JOiDRnL9l.jpeg!thumb-w321-webp75",material_id:"20079930070"}, - {name:"DIOR",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/5JOi8BVv09mRyGK.jpeg!thumb-w321-webp75",material_id:"20079930075"}, - {name:"",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/N3OFqdNzda.jpeg!thumb-w321-webp75",material_id:"20079932157"}, - {name:"bling",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/9nzUy0eQGq.png!thumb-w321-webp75",material_id:"20079932158"}, - {name:"色散光",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/JdaUWkbq92.png!thumb-w321-webp75",material_id:"20079932154"}, - {name:"闪光夏日",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/bBLUvkadVZ.jpeg!thumb-w321-webp75",material_id:"20079932153"}, - {name:"闪光女团",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/qR1tJPGR0j.jpeg!thumb-w321-webp75",material_id:"20079930053"}, - {name:"闪光少女",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/eqOHv3wnlD.jpeg!thumb-w321-webp75",material_id:"20079932152"}, - {name:"bling01",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/EPdULXNn66.jpeg!thumb-w321-webp75",material_id:"20079930010"}, - {name:"bling02",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/6kOHR9OGvP.jpeg!thumb-w321-webp75",material_id:"20079930011"}, - {name:"bling03",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/eqOHv38nPz.jpeg!thumb-w321-webp75",material_id:"20079930012"}, - {name:"Disco6",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/RwXHmzP9Y0.jpeg!thumb-w321-webp75",material_id:"20079930009"}, - {name:"Dream1",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/XeVHPQWGGZ.jpeg!thumb-w321-webp75",material_id:"20079930013"}, - {name:"Hypno1",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/j4QUeORQE4.jpeg!thumb-w321-webp75",material_id:"20079930014"}, - {name:"Stellar2",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/5JOiDpKNRz.jpeg!thumb-w321-webp75",material_id:"20079930008"}, - {name:"光1",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/OX8i06ZB9D.jpeg!thumb-w321-webp75",material_id:"20079930004"}, - {name:"Prisma1",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/JdXHWkgq5D.jpeg!thumb-w321-webp75",material_id:"20079930017"}, - {name:"Plastic1",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/V2jTkWZbP6.jpeg!thumb-w321-webp75",material_id:"20079930016"}, - {name:"莫奈",thumbnail:"https://xximg1.meitudata.com/9nzUy0bwDV.png!thumb-w321-webp75",material_id:"20079932086"}, - {name:"雾柔水光",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/JdaUWkEplJ.png!thumb-w321-webp75",material_id:"20079932146"}, - {name:"muji",thumbnail:"https://xximg1.meitudata.com/LEasJNJplP.png!thumb-w321-webp75",material_id:"20079932148"}, - {name:"相机打光测试",thumbnail:"https://xximg1.meitudata.com/j4QUexO3K5.jpeg!thumb-w321-webp75",material_id:"20079932054"}, - {name:"1222",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/3XwSOKRJjx.jpeg!thumb-w321-webp75",material_id:"20079931222"}, - {name:"1333",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/EQYuL9LqvV.jpeg!thumb-w321-webp75",material_id:"20079931333"}, - {name:"1999",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/VqVfkykO5y.jpeg!thumb-w321-webp75",material_id:"20079931999"}, - {name:"1666",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/1pgI1plVVv.jpeg!thumb-w321-webp75",material_id:"20079931666"}, - {name:"1888",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/OJbF06VvmK.jpeg!thumb-w321-webp75",material_id:"20079931888"}, - {name:"1888",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/ke8UOWwVz6.jpeg!thumb-w321-webp75",material_id:"20079931777"}, - {name:"2057",thumbnail:"https://xximg1.meitudata.com/3YVfOVKVmm.jpeg!thumb-w321-webp75",material_id:"20079932057"}, - {name:"五一鱼块",thumbnail:"https://xximg1.meitudata.com/39nTOVegOn.jpeg!thumb-w321-webp75",material_id:"20079932056"}, - {name:"五一",thumbnail:"https://xximg1.meitudata.com/bBZcvykbxP.png!thumb-w321-webp75",material_id:"20079932053"}, - {name:"bling04",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/OX8i06XB3L.jpeg!thumb-w321-webp75",material_id:"20079930015"}, - {name:"元旦",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/mbZHO6bOgR5YgdB.jpeg!thumb-w321-webp75",material_id:"20106401993"}, - {name:"瞬间",thumbnail:"https://xximg1.meitudata.com/y59Ib9JKjm.jpeg!thumb-w321-webp75",material_id:"20106401997"}, - {name:"新专辑轰顶",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/BR7fMkae0elL9DK.png!thumb-w321-webp75",material_id:"506093294"}, - {name:"新素材",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/LL8SozrWaMVRP5L.png!thumb-w321-webp75",material_id:"506093299"}, - {name:"素材不在功能页",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/69MiA9JxOErJvvP.png!thumb-w321-webp75",material_id:"506093238"}, - {name:"我被禁用了😄我被禁用了😄",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/D18Iz3ZaAPm0za3.png!thumb-w321-webp75",material_id:"506093239"}, - {name:"低版本不可见",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/757SWMrAkzKAorX.png!thumb-w321-webp75",material_id:"506093243"}, - {name:"3d立体弹窗",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/k4gtA430gyk3Wx9.png!thumb-w321-webp75",material_id:"506093241"}, - {name:"加州",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/RKgUJnKn126zbGG.jpeg!thumb-w321-webp75",material_id:"50602339"}, - {name:"爱心光",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/j4GcVXWgv200k0D.jpeg!thumb-w321-webp75",material_id:"506002288"}, - {name:"2053太空漫游",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/wgNUven5XxgKmG4.jpeg!thumb-w321-webp75",material_id:"20096492276"}, - {name:"CCD",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/XepU5b3WG3BDJNp.jpeg!thumb-w321-webp75",material_id:"20096492265"}, - {name:"IMAX胶片",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/bBZcYlQVDNVde5Y.jpeg!thumb-w321-webp75",material_id:"20096492254"}, - {name:"皮囊之下",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/p0LTO938OKJLV2k.jpeg!thumb-w321-webp75",material_id:"506002350"}, - {name:"号手就位",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/J34FBw2bEwzGbWp.jpeg!thumb-w321-webp75",material_id:"506002317"}, - {name:"海绵3",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/26guLmK1p0M13Zr.jpeg!thumb-w321-webp75",material_id:"506010277"}, - {name:"海绵4",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/KgaiJr4o77waN4d.jpeg!thumb-w321-webp75",material_id:"506010276"}, - {name:"海绵1",thumbnail:"https://xxtool-release.zone1.meitudata.com/xxtool-pre/material/71MfrYOoEDyKLJA.jpeg!thumb-w321-webp75",material_id:"506010279"}, - {name:"TR2",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/k51F2wNOkqQgBjX.jpeg!thumb-w321-webp75",material_id:"506002345"}, - {name:"TR3",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/JdaUB94WJJqQlwK.jpeg!thumb-w321-webp75",material_id:"506002344"}, - {name:"TR4",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/5JeH8WzDLm1NmPy.jpeg!thumb-w321-webp75",material_id:"506002347"}, - {name:"TR5",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/lkjUjGvk4VORqlR.jpeg!thumb-w321-webp75",material_id:"506002343"}, - {name:"TR6",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/k51F2wNOLjj94dK.jpeg!thumb-w321-webp75",material_id:"506002346"}, - {name:"乌布",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/V2xig11N0vQLpxm.jpeg!thumb-w321-webp75",material_id:"506002333"}, - {name:"微缩世界",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/oJQiWgqo5kodE1B.jpeg!thumb-w321-webp75",material_id:"506002298"}, - {name:"微缩世界Ⅱ",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/N8RHzP6aP44Xex6.jpeg!thumb-w321-webp75",material_id:"506002299"}, - {name:"旅程",thumbnail:"https://xximg1.meitudata.com/V2jTkEY8Y9.jpeg!thumb-w321-webp75",material_id:"20086101254"}, - {name:"旅程",thumbnail:"https://xximg1.meitudata.com/GPoUPwOj1b.jpeg!thumb-w321-webp75",material_id:"20086101315"}, - {name:"且听风吟",thumbnail:"https://xximg1.meitudata.com/Z3VspeGOy3.jpeg!thumb-w321-webp75",material_id:"2008610635"}, - {name:"Sky",thumbnail:"https://xximg1.meitudata.com/p0GcZPbnV0.jpeg!thumb-w321-webp75",material_id:"20086101612"}, - {name:"清新蓝",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/BbWiqXBp8X869e9.jpeg!thumb-w321-webp75",material_id:"20086162162"}, - {name:"男友力",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/6PocqE9aB8nZgOl.jpeg!thumb-w321-webp75",material_id:"20086161259"}, - {name:"男友力",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/8boiJnm9e69J3GB.jpeg!thumb-w321-webp75",material_id:"20086161256"}, - {name:"男友力",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/oeGiWgmVL06ppzo.jpeg!thumb-w321-webp75",material_id:"20086161469"}, - {name:"chiffon",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/JdXHB6PXY9dzmjl.jpeg!thumb-w321-webp75",material_id:"2008607975"}, - {name:"新年限定",thumbnail:"https://xximg1.meitudata.com/mlahymLEBk.jpeg!thumb-w321-webp75",material_id:"20086072015"}, - {name:"新春食堂",thumbnail:"https://xximg1.meitudata.com/dDpFaD19J9.jpeg!thumb-w321-webp75",material_id:"20086071687"}, - {name:"围炉",thumbnail:"https://xximg1.meitudata.com/jo2UegGjqj.jpeg!thumb-w321-webp75",material_id:"20086071688"}, - {name:"橘子汽水",thumbnail:"https://xximg1.meitudata.com/voWUlvO8Dd.jpeg!thumb-w321-webp75",material_id:"2008607571"}, - {name:"舒芙蕾",thumbnail:"https://xximg1.meitudata.com/xmdFQwl5J0.jpeg!thumb-w321-webp75",material_id:"2008607569"}, - {name:"野Ⅰ",thumbnail:"https://xximg1.meitudata.com/6KwCRlbG6g.jpeg!thumb-w321-webp75",material_id:"20086070001"}, - {name:"野餐Ⅱ",thumbnail:"https://xximg1.meitudata.com/Nzjuq2XDGQ.jpeg!thumb-w321-webp75",material_id:"20086070002"}, - {name:"食欲",thumbnail:"https://xximg1.meitudata.com/jo2UegGzVl.jpeg!thumb-w321-webp75",material_id:"20086071585"}, - {name:"食欲",thumbnail:"https://xximg1.meitudata.com/0J6fWJbYW8.jpeg!thumb-w321-webp75",material_id:"20086071587"}, - {name:"橘子汽水",thumbnail:"https://xximg1.meitudata.com/bz0uvoO5Po.jpeg!thumb-w321-webp75",material_id:"20086071908"}, - {name:"",thumbnail:"https://xximg1.meitudata.com/xmdFQwgNGx.png!thumb-w321-webp75",material_id:"2008607014"}, - {name:"粉花面包",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/gkmsKBakKNO6ynd.jpeg!thumb-w321-webp75",material_id:"2008607973"}, - {name:"",thumbnail:"https://xximg1.meitudata.com/RzLumonEvG.png!thumb-w321-webp75",material_id:"2008607015"}, - {name:"Brunch",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/V2jTgxyR4xG9k4d.jpeg!thumb-w321-webp75",material_id:"20086072197"}, - {name:"vista200",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/LJwUjvN4awZDWOw.jpeg!thumb-w321-webp75",material_id:"506002301"}, - {name:"胶片时光",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/kBwi28Wm6y698oy.jpeg!thumb-w321-webp75",material_id:"20086171381"}, - {name:"胶片时光",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/8boiJnmYZ8NbvJ6.jpeg!thumb-w321-webp75",material_id:"20086171339"}, - {name:"胶片时光",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/vEdtKOx0n2gEyBg.jpeg!thumb-w321-webp75",material_id:"20086171336"}, - {name:"菲林日记",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/OdpiRJVedvxlR4m.jpeg!thumb-w321-webp75",material_id:"20096221571"}, - {name:"菲林日记",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/kBwi28w05RB11de.jpeg!thumb-w321-webp75",material_id:"20096221570"}, - {name:"菲林日记",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/KBPipZwDElPR1bl.jpeg!thumb-w321-webp75",material_id:"20096221783"}, - {name:"菲林日记",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/2bkiEXqkWmBZzjL.jpeg!thumb-w321-webp75",material_id:"20096221781"}, - {name:"菲林日记",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/PnkTd0zBvKKRYb0.jpeg!thumb-w321-webp75",material_id:"20096221780"}, - {name:"Outdoors",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/NL9HzPdl9WLnlq9.jpeg!thumb-w321-webp75",material_id:"20086172023"}, - {name:"蒸汽波",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/DyjUJpgEgyP8nDL.jpeg!thumb-w321-webp75",material_id:"506002182"}, - {name:"落日",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/V2jTgj1akYWmEvP.jpeg!thumb-w321-webp75",material_id:"20106112264"}, - {name:"音浪",thumbnail:"http://xximg2.meitudata.com/VXgfk8zEJ3.jpeg!thumb-w321-webp75",material_id:"20106111100"}, - {name:"毕业季",thumbnail:"https://xxtool-release.zone1.meitudata.com/material/y56Fb5qaXq.jpeg!thumb-w321-webp75",material_id:"20076121254"}, - {name:"游乐园",thumbnail:"https://xximg1.meitudata.com/N8eUq2XE0E.jpeg!thumb-w321-webp75",material_id:"20076091595"}, - {name:"粉黛",thumbnail:"https://xximg1.meitudata.com/wgNU3GlNRj.jpeg!thumb-w321-webp75",material_id:"20076091618"}, - {name:"游乐园",thumbnail:"https://xximg1.meitudata.com/Z3GfpjWOKV.jpeg!thumb-w321-webp75",material_id:"20076091596"}, - {name:"水彩画",thumbnail:"https://xximg1.meitudata.com/eqOHvqo0ej.jpeg!thumb-w321-webp75",material_id:"20106041764"}, - {name:"钢笔淡彩",thumbnail:"https://xximg1.meitudata.com/V2jTkopPGQ.jpeg!thumb-w321-webp75",material_id:"20106041765"}, - {name:"质感",thumbnail:"https://xximg1.meitudata.com/XepUPNP4WP.png!thumb-w321-webp75",material_id:"20076061608"}, - {name:"质感",thumbnail:"https://xximg1.meitudata.com/9nzUydyWeB.png!thumb-w321-webp75",material_id:"20076061589"}, - {name:"质感",thumbnail:"http://xximg2.meitudata.com/yObUbokjlb.jpeg!thumb-w321-webp75",material_id:"20076061609"}, - {name:"荼白",thumbnail:"https://xximg1.meitudata.com/6kOHRW8WGD.jpeg!thumb-w321-webp75",material_id:"20076061859"} - ] - - public totalCount(): number { - return this.dataArray.length; - } - - public getData(index: number): Material | undefined { - return this.dataArray[index]; - } - - public addData(index: number, data: Material): void { - this.dataArray.splice(index, 0, data); - this.notifyDataAdd(index); - } - - public pushData(data: Material): void { - this.dataArray.push(data); - this.notifyDataAdd(this.dataArray.length - 1); - } -} \ No newline at end of file diff --git a/entry/src/main/ets/pages/multiHspTestPage.ets b/entry/src/main/ets/pages/multiHspTestPage.ets deleted file mode 100644 index c142ef9..0000000 --- a/entry/src/main/ets/pages/multiHspTestPage.ets +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (C) 2023 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { ImageKnifeComponent, ImageKnifeOption, FileUtils, ImageKnifeGlobal, GetRes1 } from '@ohos/libraryimageknife' -import common from '@ohos.app.ability.common' -import { GetRes2 } from '@ohos/sharedlibrary2' - -@Entry -@Component -struct Index { - @State imageOption1: ImageKnifeOption = { - loadSrc: $r('app.media.icon'), - } - @State imageOption2: ImageKnifeOption = { - loadSrc: $r('app.media.icon'), - } - - build() { - Scroll() { - Column() { - Button('点击HSP1主图,HSP2占位,无context').onClick(() => { - let mainRes = GetRes1.getSample1(); - let placeholderRes = GetRes2.getSample2(); - this.imageOption1 = { - loadSrc:mainRes, - placeholderSrc:placeholderRes - } - }) - ImageKnifeComponent({ imageKnifeOption: this.imageOption1 }).width(300).height(300).backgroundColor(Color.Pink) - Button('点击HSP1主图,HSP2占位,有context ').onClick(() => { - let mainRes = GetRes1.getSample1(); - let placeholderRes = GetRes2.getSample2(); - this.imageOption2 = { - loadSrc:mainRes, - placeholderSrc:placeholderRes, - context:getContext(this) as common.UIAbilityContext - } - }) - ImageKnifeComponent({ imageKnifeOption: this.imageOption2 }).width(300).height(300).backgroundColor(Color.Pink) - - - }.width('100%') - - } - .width('100%') - .height('100%') - } -} \ No newline at end of file diff --git a/entry/src/main/ets/pages/photosPausedResumedPage.ets b/entry/src/main/ets/pages/photosPausedResumedPage.ets deleted file mode 100644 index d82f1fd..0000000 --- a/entry/src/main/ets/pages/photosPausedResumedPage.ets +++ /dev/null @@ -1,92 +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, ScaleType,ImageKnife} from '@ohos/libraryimageknife' -import {ImageKnifeOption} from '@ohos/libraryimageknife' -import {ImageKnifeGlobal} from '@ohos/libraryimageknife' -import {RotateImageTransformation} from '@ohos/libraryimageknife' -import {Material} from './model/Material' -import {TestDataSource} from './model/TestDataSource' - - -@Entry -@Component -struct photosPausedResumedPage { - private data: TestDataSource = new TestDataSource(); - - private elementScroller: Scroller = new Scroller() - - build() { - Column() { - - Button('点击暂停加载') - .margin({top:10,bottom:5}) - .onClick(()=>{ - let imageKnife:ImageKnife|undefined = ImageKnifeGlobal.getInstance().getImageKnife(); - if(imageKnife!= undefined){ - imageKnife.pauseRequests() - } - }) - - Button('点击重新加载') - .margin({top:10,bottom:5}) - .onClick(()=>{ - let imageKnife:ImageKnife|undefined = ImageKnifeGlobal.getInstance().getImageKnife(); - if(imageKnife!= undefined){ - imageKnife.resumeRequests() - } - }) - - - List({ space: 20, scroller: this.elementScroller }) { - LazyForEach(this.data, (item: Material, index) => { - ListItem() { - Column() { - Stack({ alignContent: Alignment.BottomEnd }) { - // 滤镜图片 - ImageKnifeComponent({ imageKnifeOption: { - loadSrc: item.thumbnail, - mainScaleType: ScaleType.FIT_XY, - } }) - } - .width(56).height(56) - //滤镜标题 - Text(item.name) - .fontSize(10) - .maxLines(1) - .fontColor(Color.White) - .textAlign(TextAlign.Center) - .layoutWeight(1) - .width('100%') - .backgroundColor(Color.Orange) - } - .width(56) - .height(72) - .clip(true) - .borderRadius(4) - } - }, (item: Material) => item.material_id) - } - .listDirection(Axis.Horizontal) - .width('100%') - .height(72) - - } - } - - - -} - - diff --git a/entry/src/main/ets/pages/photosPausedResumedPage2.ets b/entry/src/main/ets/pages/photosPausedResumedPage2.ets deleted file mode 100644 index 6b043df..0000000 --- a/entry/src/main/ets/pages/photosPausedResumedPage2.ets +++ /dev/null @@ -1,104 +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, ScaleType,ImageKnife} from '@ohos/libraryimageknife' -import {ImageKnifeOption} from '@ohos/libraryimageknife' -import {ImageKnifeGlobal} from '@ohos/libraryimageknife' -import {RotateImageTransformation} from '@ohos/libraryimageknife' -import {Material} from './model/Material' -import {TestDataSource} from './model/TestDataSource' -import {DiskLruCache} from '@ohos/disklrucache' -import ArkWorker from '@ohos.worker' -import Prompt from '@system.prompt' -@Entry -@Component -struct photosPausedResumedPage { - private data: TestDataSource = new TestDataSource(); - - private elementScroller: Scroller = new Scroller() - - build() { - Column() { - - Button('这个List通过监听: 开始滑动,停止加载图片;滑动结束,恢复加载图片') - .margin({top:10,bottom:5}) - .onClick(()=>{ - - }) - - - - - List({ space: 20, scroller: this.elementScroller }) { - LazyForEach(this.data, (item: Material, index) => { - ListItem() { - Column() { - Stack({ alignContent: Alignment.BottomEnd }) { - // 滤镜图片 - ImageKnifeComponent({ imageKnifeOption: { - loadSrc: item.thumbnail, - mainScaleType: ScaleType.FIT_XY, - } }) - } - .width(56).height(56) - //滤镜标题 - Text(item.name) - .fontSize(10) - .maxLines(1) - .fontColor(Color.White) - .textAlign(TextAlign.Center) - .layoutWeight(1) - .width('100%') - .backgroundColor(Color.Orange) - } - .width(56) - .height(72) - .clip(true) - .borderRadius(4) - } - }, (item: Material) => item.material_id) - } - .onScrollStart(()=>{ - let imageKnife:ImageKnife|undefined = ImageKnifeGlobal.getInstance().getImageKnife(); - if(imageKnife!= undefined){ - imageKnife.pauseRequests() - } - }) - .onScrollStop(()=>{ - let imageKnife:ImageKnife|undefined = ImageKnifeGlobal.getInstance().getImageKnife(); - if(imageKnife!= undefined){ - imageKnife.resumeRequests() - } - }) - .listDirection(Axis.Horizontal) - .width('100%') - .height(72) - - } - } - - - aboutToDisappear(){ - // 如果用户滑动过程中就退出了页面我们需要恢复图片加载能力 - let imageKnife:ImageKnife|undefined = ImageKnifeGlobal.getInstance().getImageKnife(); - if(imageKnife!= undefined){ - imageKnife.resumeRequests() - } - } - - - -} - - diff --git a/entry/src/main/ets/pages/pngjTestCasePage.ets b/entry/src/main/ets/pages/pngjTestCasePage.ets deleted file mode 100644 index 3969de7..0000000 --- a/entry/src/main/ets/pages/pngjTestCasePage.ets +++ /dev/null @@ -1,257 +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 { Pngj } from '@ohos/libraryimageknife' -import resourceManager from '@ohos.resourceManager'; -import { FileUtils,ImageKnifeGlobal } from '@ohos/libraryimageknife' -import { BusinessError } from '@ohos.base' -import common from '@ohos.app.ability.common'; -interface WorkerType { - type: string - name: string -} -@Entry -@Component -struct PngjTestCasePage { - pngSource1?: ArrayBuffer = undefined; - pngSource2?: ArrayBuffer = undefined; - pngSource3?: ArrayBuffer = undefined; - pngSource4?: ArrayBuffer = undefined; - pngdecodeRun1: boolean = false; - pngdecodeRun2: boolean = false; - pngdecodeRun3: boolean = false; - pngdecodeRun4: boolean = false; - rootFolder: string = ''; - @State hint1: string = 'readPngImageInfo内容展示' - @State hint2: string = 'readPngImage内容展示' - @State hint3: string = 'writePngWithString内容展示' - @State hint4: string = 'writePngWithString内容展示' - @State hint5: string = '测试readMetadata' - @State hint6: string = '测试writeMetadata' - @State hint7: string = '首先点击获取PNG图片buffer' - @State hint8: string = '首先点击获取PNG图片buffer' - @State hint9: string = '首先点击获取PNG图片buffer' - @State hint10: string = '首先点击获取PNG图片buffer' - - build() { - Scroll() { - Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { - Text('pngj接口测试列表').fontSize(20) - - Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { - - Button(this.hint7).fontSize(30) - .onClick(() => { - this.rootFolder = (ImageKnifeGlobal.getInstance().getHapContext() as common.UIAbilityContext).filesDir as string; - ((ImageKnifeGlobal.getInstance().getHapContext() as common.UIAbilityContext) - .resourceManager as resourceManager.ResourceManager) - .getMediaContent($r('app.media.pngSample').id) - .then(data => { - this.pngSource1 = FileUtils.getInstance().uint8ArrayToBuffer(data); - this.hint7 = '获取buffer成功,可以测试' - }) - .catch( (err:BusinessError) => { - console.log('点击获取Png图片buffer err=' + err) - }) - }) - Button('测试readPng') - .onClick(() => { - - if (this.pngSource1!=undefined) { - if (!this.pngdecodeRun1) { - this.pngdecodeRun1 = true; - let pngj = new Pngj(); - pngj.readPngImageInfo(this.pngSource1,{pngCallback: (sender, value) => { - this.hint1 = JSON.stringify(value); - this.pngdecodeRun1 = false; - }}) - - } else { - this.hint7 = '已经在执行了,请稍等' - } - } else { - this.hint7 = '请先点击此处获取buffer' - } - }).margin({ top: 5, left: 10 }) - - - }.width('100%') - .height(60).backgroundColor(Color.Pink) - - Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { - Button(this.hint8).fontSize(30) - .onClick(() => { - - - - this.rootFolder = (ImageKnifeGlobal.getInstance().getHapContext() as common.UIAbilityContext).filesDir as string; - ((ImageKnifeGlobal.getInstance().getHapContext() as common.UIAbilityContext) - .resourceManager as resourceManager.ResourceManager) - .getMediaContent($r('app.media.pngSample').id) - - .then(data => { - this.pngSource2 = FileUtils.getInstance().uint8ArrayToBuffer(data); - this.hint8 = '获取buffer成功,可以测试' - }) - .catch((err:BusinessError) => { - console.log('点击获取Png图片buffer err=' + err) - }) - }) - Button('readPngAsync') - .onClick(() => { - - if (this.pngSource2!=undefined) { - if (!this.pngdecodeRun2) { - this.pngdecodeRun2 = true; - let pngj = new Pngj(); - let png_worker: WorkerType = { - type: 'classic', - name: 'readPngImageAsync' - } - pngj.readPngImageAsync(png_worker, this.pngSource2!, (value:ESObject) => { - this.hint8 = '重新获取buffer才能测试' - this.hint2 = 'img with=' + value.width + ' img height=' + value.height - + ' img depth=' + value.depth + ' img ctype=' + value.ctype - this.pngdecodeRun2 = false; - }) - - } else { - this.hint8 = '已经在执行了,请稍等' - } - } else { - this.hint8 = '请先点击此处获取buffer' - } - - }).margin({ top: 5, left: 10 }) - - }.width('100%') - .height(60).backgroundColor(Color.Pink) - - Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { - Button(this.hint9).fontSize(30) - .onClick(() => { - this.rootFolder = (ImageKnifeGlobal.getInstance().getHapContext() as common.UIAbilityContext).filesDir as string; - ((ImageKnifeGlobal.getInstance().getHapContext() as common.UIAbilityContext) - .resourceManager as resourceManager.ResourceManager) - .getMediaContent($r('app.media.pngSample').id) - .then(data => { - this.pngSource3 = FileUtils.getInstance().uint8ArrayToBuffer(data); - this.hint9 = '获取buffer成功,可以测试' - }) - .catch((err:BusinessError) => { - console.log('点击获取Png图片buffer err=' + err) - }) - }) - Button('测试writePngWithString') - .onClick(() => { - - if (this.pngSource3 != undefined) { - if (!this.pngdecodeRun3) { - this.pngdecodeRun3 = true; - let pngj = new Pngj(); - let png_worker: WorkerType = { - type: 'classic', - name: 'writePngWithStringAsync' - } - pngj.writePngWithStringAsync(png_worker, this.pngSource3, ( value:ESObject) => { - 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进制查看数据是否新增' - this.pngdecodeRun3 = false; - },'hello world') - } else { - this.hint9 = '已经在执行了,请稍等' - } - } else { - this.hint9 = '请先点击此处获取buffer' - } - - }).margin({ top: 5, left: 10 }) - - }.width('100%') - .height(60).backgroundColor(Color.Pink) - - - Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { - - Button(this.hint10).fontSize(30) - .onClick(() => { - this.rootFolder = (ImageKnifeGlobal.getInstance().getHapContext() as common.UIAbilityContext).filesDir as string; - ((ImageKnifeGlobal.getInstance().getHapContext() as common.UIAbilityContext) - .resourceManager as resourceManager.ResourceManager) - .getMediaContent($r('app.media.pngSample').id) - .then(data => { - this.pngSource4 = FileUtils.getInstance().uint8ArrayToBuffer(data); - this.hint10 = '获取buffer成功,可以测试' - }) - .catch((err:BusinessError) => { - console.log('点击获取Png图片buffer err=' + err) - }) - }) - Button('writePng') - .onClick(()=>{ - if (this.pngSource4 != undefined) { - if (!this.pngdecodeRun4) { - this.pngdecodeRun4 = true; - let pngj = new Pngj(); - let png_worker: WorkerType = { - type: 'classic', - name: 'writePngAsync' - } - pngj.writePngAsync(png_worker, this.pngSource4, ( value:ESObject) => { - 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进制查看数据是否新增' - this.pngdecodeRun4 = false; - }) - } else { - this.hint10 = '已经在执行了,请稍等' - } - } else { - this.hint10 = '请先点击此处获取buffer' - } - }) - .margin({ top: 5, left: 10 }) - }.width('100%') - .height(60).backgroundColor(Color.Pink) - - - Text(this.hint1) - .width('100%') - .height(120) - Text(this.hint2) - .width('100%') - .height(120) - Text(this.hint3) - .width('100%') - .height(120) - Text(this.hint4) - .width('100%') - .height(120) - } - .width('100%') - .height('100%') - } - } - - typedArrayToBuffer(array: Uint8Array): ArrayBuffer { - return array.buffer.slice(array.byteOffset, array.byteLength + array.byteOffset) - } -} diff --git a/entry/src/main/ets/pages/showErrorholderTestCasePage.ets b/entry/src/main/ets/pages/showErrorholderTestCasePage.ets deleted file mode 100644 index 15ea013..0000000 --- a/entry/src/main/ets/pages/showErrorholderTestCasePage.ets +++ /dev/null @@ -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/libraryimageknife' -import {ImageKnifeOption} from '@ohos/libraryimageknife' -import {RotateImageTransformation} from '@ohos/libraryimageknife' -import {RoundedCornersTransformation} from '@ohos/libraryimageknife' - -@Entry -@Component -struct ShowErrorholderTestCasePage { - @State imageKnifeOption1: ImageKnifeOption = - { - loadSrc: "https://thirdwx.qlogo.cn/mmopen/xxxxx", - - placeholderSrc: $r('app.media.icon_loading'), - errorholderSrc: $r('app.media.icon_failed'), - }; - @State imageKnifeOption: ImageKnifeOption = - { - loadSrc: "https://hbimg.huabanimg.com/xxxxx", - - placeholderSrc: $r('app.media.icon_loading'), - errorholderSrc: $r('app.media.icon_failed'), - }; - @State imageKnifeOption3: ImageKnifeOption = - { - loadSrc: "https://hbimg.huabanimg.com/xxxxx", - - placeholderSrc: $r('app.media.icon_loading'), - errorholderSrc: $r('app.media.icon_failed'), - }; - @State imageKnifeOption4: ImageKnifeOption = - { - loadSrc: "https://hbimg.huabanimg.com/xxxxx", - - 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: this.imageKnifeOption1 }).width(300).height(300) - ImageKnifeComponent({ imageKnifeOption: this.imageKnifeOption }).width(300).height(300) - ImageKnifeComponent({ imageKnifeOption: this.imageKnifeOption3 }).width(300).height(300) - ImageKnifeComponent({ imageKnifeOption: this.imageKnifeOption4 }).width(300).height(300) - } - } - .width('100%') - .height('100%') - } -} diff --git a/entry/src/main/ets/pages/storageTestLruCache.ets b/entry/src/main/ets/pages/storageTestLruCache.ets deleted file mode 100644 index 018c002..0000000 --- a/entry/src/main/ets/pages/storageTestLruCache.ets +++ /dev/null @@ -1,55 +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 {LruCache} from '@ohos/libraryimageknife' - -function getRandomInt(min:number, max:number):number { - min = Math.ceil(min); - max = Math.floor(max); - return Math.floor(Math.random() * (max - min)) + min; //不含最大值,含最小值 -} - -@Entry -@Component -struct StorageTestLruCache { - @State logText:string = "打印日志结果"; - @State nowNumText:string = "显示输入的数据"; - mLruCache:LruCache = new LruCache(5); - build() { - Scroll() { - Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { - Text("默认创建一个容量为5的LruCache") - .backgroundColor(Color.Blue) - Button("随机存入一个数字0-9") - .onClick(()=>{ - let randomNum = getRandomInt(0,10); - this.nowNumText = ''+randomNum; - this.mLruCache.put(randomNum+"",randomNum+"") - this.logText = "日志结果:"+this.mLruCache.print(); - }) .margin({top:20}) - - Button(this.nowNumText) - .margin({top:20}) - - Scroll() { - Text(this.logText).fontSize(15) - }.width(300).height(200).margin({top:20}).backgroundColor(Color.Pink) - - } - .width('100%') - .height('100%') - } - } -} diff --git a/entry/src/main/ets/pages/svgTestCasePage.ets b/entry/src/main/ets/pages/svgTestCasePage.ets deleted file mode 100644 index 7e6b772..0000000 --- a/entry/src/main/ets/pages/svgTestCasePage.ets +++ /dev/null @@ -1,81 +0,0 @@ -/* - * 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/libraryimageknife' -import { ImageKnifeComponent } from '@ohos/libraryimageknife' -import resourceManager from '@ohos.resourceManager'; -import {BusinessError} from '@ohos.base' -import common from '@ohos.app.ability.common'; -@Entry -@Component -struct svgTestCasePage { - - @State svgSamplePixelMap?: Resource = undefined - @State svgIconPixelMap?: Resource = undefined - - build() { - Scroll() { - Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { - Flex({direction:FlexDirection.Row}){ - Button("加载SVG图片") - .onClick(()=>{ - this.svgSamplePixelMap = $r('app.media.svgSample') - }).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:{ - loadSrc:this.svgSamplePixelMap as Resource - }}) - .width(400) - .height(400) - .backgroundColor(Color.Pink) - }.width(400).height(400).margin({top:10}).backgroundColor(Color.Pink) - - Flex({direction:FlexDirection.Row}){ - Button("加载SVG图片") - .onClick(()=>{ - this.svgIconPixelMap = $r('app.media.iconsvg') - }).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:{ - loadSrc:this.svgIconPixelMap as Resource - }}) - .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) - } -} - - diff --git a/entry/src/main/ets/pages/tempUrlTestPage.ets b/entry/src/main/ets/pages/tempUrlTestPage.ets deleted file mode 100644 index 9261dbe..0000000 --- a/entry/src/main/ets/pages/tempUrlTestPage.ets +++ /dev/null @@ -1,98 +0,0 @@ -/* - * 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 { - ImageKnifeComponent, - ImageKnifeOption, - ImageKnifeGlobal, - ImageKnife, - ImageKnifeDrawFactory, - ScaleType -} from '@ohos/libraryimageknife' -import worker from '@ohos.worker'; -@Entry -@Component -struct tempUrlTestPage { - - @State imageKnifeOption1: ImageKnifeOption = - { - loadSrc: $r('app.media.icon'), - - placeholderSrc: $r('app.media.icon_loading'), - errorholderSrc: $r('app.media.icon_failed') - }; - - @State imageKnifeOption2: ImageKnifeOption = - { - loadSrc: $r('app.media.icon'), - - 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("简单示例1:加载一张本地png图片").fontSize(15) - Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { - Button("加载PNG") - .onClick(() => { - this.imageKnifeOption1 = { - // loadSrc:"https://res.vmallres.com/cmscdn/CN/2023-03/a11790b9335a4d598d59f14795368e14.png.75.webp", - loadSrc:"https://xximg1.meitudata.com/2LqS1vmqv0.png!thumb-w321-webp75", - mainScaleType: ScaleType.FIT_XY, - placeholderSrc: $r('app.media.icon_loading'), - errorholderSrc: $r('app.media.icon_failed'), - drawLifeCycle:ImageKnifeDrawFactory.createRoundLifeCycle(0,'#00000000',30) - } - }).margin({ top: 5, left: 3 }) - ImageKnifeComponent({ imageKnifeOption: this.imageKnifeOption1 }).width('100%').height(300).backgroundColor(Color.Orange) - } - .width('100%').height(400).backgroundColor(Color.Pink) - - Text("简单示例2:加载一张网络gif图片").fontSize(15) - Text("gif解析在子线程,请在页面构建后创建worker,注入imageknife").fontSize(15) - Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { - Button("加载GIF") - .onClick(() => { - this.imageKnifeOption2 = { - loadSrc: 'https://res.vmallres.com/cmscdn/CN/2023-03/7052a601ac3e428c84c9415ad9734735.gif', - - placeholderSrc: $r('app.media.icon_loading'), - errorholderSrc: $r('app.media.icon_failed'), - displayProgress:true, - } - }).margin({ top: 5, left: 3 }) - ImageKnifeComponent({ imageKnifeOption: this.imageKnifeOption2 }).width(300).height(300) - }.width('100%').backgroundColor(Color.Pink) - - - }.width('100%') - } - .width('100%') - .height('100%') - } - - aboutToAppear() { - - } - aboutToDisappear(){ - - } - - onBackPress() { - - } -} \ No newline at end of file diff --git a/entry/src/main/ets/pages/testAllCacheInfoPage.ets b/entry/src/main/ets/pages/testAllCacheInfoPage.ets deleted file mode 100644 index f39920a..0000000 --- a/entry/src/main/ets/pages/testAllCacheInfoPage.ets +++ /dev/null @@ -1,209 +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/libraryimageknife' -import {ImageKnifeData} from '@ohos/libraryimageknife' -import {AllCacheInfo,IAllCacheInfoCallback} from '@ohos/libraryimageknife' -import {ImageKnifeComponent} from '@ohos/libraryimageknife' -import {TransformType} from '@ohos/libraryimageknife' -import {ImageKnifeOption} from '@ohos/libraryimageknife' -import {ImageKnifeGlobal} from '@ohos/libraryimageknife' -import {RotateImageTransformation} from '@ohos/libraryimageknife' -import {BusinessError} from '@ohos.base' -@Entry -@Component -struct TestAllCacheInfoPage { - @State nativePixelMap?: PixelMap = undefined; - @State networkPixelMap?: PixelMap = undefined; - allCacheInfoCallback1:IAllCacheInfoCallback ={callback:(allCacheInfo:AllCacheInfo)=>{ - let info = allCacheInfo as AllCacheInfo; - console.log("AllCacheInfoCallback imageknifecomponent1 memory ="+JSON.stringify(info.memoryCacheInfo)) - console.log("AllCacheInfoCallback imageknifecomponent1 resource ="+JSON.stringify(info.resourceCacheInfo)) - console.log("AllCacheInfoCallback imageknifecomponent1 data ="+JSON.stringify(info.dataCacheInfo)) - this.cacheinfo3 = "memory="+JSON.stringify(info.memoryCacheInfo)+ - "\n resource ="+JSON.stringify(info.resourceCacheInfo)+ - "\n data ="+JSON.stringify(info.dataCacheInfo) - }} - allCacheInfoCallback2:IAllCacheInfoCallback ={callback:(allCacheInfo:AllCacheInfo)=>{ - let info = allCacheInfo as AllCacheInfo; - 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) - }} - @State imageKnifeOption1: ImageKnifeOption = - { - loadSrc: $r('app.media.pngSample'), - - placeholderSrc: $r('app.media.icon_loading'), - errorholderSrc: $r('app.media.icon_failed'), - - transform: { - transformType:TransformType.RotateImageTransformation, - rotateImage:180 - }, - allCacheInfoCallback:this.allCacheInfoCallback1 - }; - @State imageKnifeOption: ImageKnifeOption = - { - loadSrc: "https://thirdwx.qlogo.cn/mmopen/vi_32/DYAIOgq83ericA1Mv66TwicuYOtbDMBcUhv1aa9RJBeAn9uURfcZD0AUGrJebAn1g2AjN0vb2E1XTET7fTuLBNmA/132", - - placeholderSrc: $r('app.media.icon_loading'), - errorholderSrc: $r('app.media.icon_failed'), - - transform: { - transformType:TransformType.RotateImageTransformation, - rotateImage:180 - }, - allCacheInfoCallback:this.allCacheInfoCallback2 - }; - imageKnifeComponentAngle:number = 90; - - @State cacheinfo1:string = "观察本地资源获取缓存信息输出" - @State cacheinfo2:string = "观察网络资源获取缓存信息输出" - @State cacheinfo3:string = "观察ImageKnifeComponent本地缓存输出" - @State cacheinfo4:string = "观察ImageKnifeComponent网络缓存输出" - - build() { - Scroll() { - Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { - Button("加载本地资源获取缓存信息") - .width(300).height(25) - .onClick(() => { - this.testAllCacheInfoNative(); - }).margin({ top: 15 }) - Scroll() { - Text(this.cacheinfo1).fontSize(15) - }.width(300).height(200) - Image(this.nativePixelMap == undefined ? '':this.nativePixelMap!) - .width(300) - .height(300) - .objectFit(ImageFit.Contain) - .backgroundColor(Color.Green) - .margin({ top: 15 }) - Button("加载网络资源获取缓存信息").width(300).height(25) - .onClick(() => { - this.testAllCacheInfoNetwork(); - }).margin({ top: 15 }) - Scroll() { - Text(this.cacheinfo2).fontSize(15) - }.width(300).height(200) - Image(this.networkPixelMap==undefined?'':this.networkPixelMap! ) - .width(300) - .height(300) - .objectFit(ImageFit.Contain) - .backgroundColor(Color.Green) - .margin({ top: 15 }) - - Button("ImageKnifeComponent加载本地资源获取缓存信息").width(300).height(25) - .onClick(() => { - this.imageKnifeComponentAngle = this.imageKnifeComponentAngle + 45; - this.imageKnifeOption1 = - { - loadSrc: $r('app.media.pngSample'), - - placeholderSrc: $r('app.media.icon_loading'), - errorholderSrc: $r('app.media.icon_failed'), - - transform: { - transformType:TransformType.RotateImageTransformation, - rotateImage:this.imageKnifeComponentAngle - }, - allCacheInfoCallback:this.allCacheInfoCallback1 - }; - }).margin({ top: 15 }) - Scroll() { - Text(this.cacheinfo3).fontSize(15) - }.width(300).height(200) - ImageKnifeComponent({ imageKnifeOption: this.imageKnifeOption1 }) - - Button("ImageKnifeComponent加载网络资源获取缓存信息").width(300).height(25) - .onClick(() => { - this.imageKnifeComponentAngle = this.imageKnifeComponentAngle + 45; - this.imageKnifeOption = - { - loadSrc: "https://thirdwx.qlogo.cn/mmopen/vi_32/DYAIOgq83ericA1Mv66TwicuYOtbDMBcUhv1aa9RJBeAn9uURfcZD0AUGrJebAn1g2AjN0vb2E1XTET7fTuLBNmA/132", - - placeholderSrc: $r('app.media.icon_loading'), - errorholderSrc: $r('app.media.icon_failed'), - - transform: { - transformType:TransformType.RotateImageTransformation, - rotateImage:this.imageKnifeComponentAngle - }, - allCacheInfoCallback:this.allCacheInfoCallback2 - }; - }) - Scroll() { - Text(this.cacheinfo4).fontSize(15) - }.width(300).height(200) - ImageKnifeComponent({ imageKnifeOption: this.imageKnifeOption }).width(300).height(300) - - } - } - .width('100%') - .height('100%') - } - - aboutToAppear() { - - } - - private testAllCacheInfoNative() { - let imageKnifeOption = new RequestOption(); - imageKnifeOption.load($r('app.media.pngSample')) - .setImageViewSize({width:300,height:300}) - .addListener({callback:(err:BusinessError|string, data:ImageKnifeData) => { - let pack = data.drawPixelMap?.imagePixelMap as PixelMap;; - this.nativePixelMap = pack; - return false; - }}).addAllCacheInfoCallback({callback:(allCacheInfo:AllCacheInfo)=>{ - let info = allCacheInfo as AllCacheInfo; - console.log("AllCacheInfoCallback memory ="+JSON.stringify(info.memoryCacheInfo)) - console.log("AllCacheInfoCallback resource ="+JSON.stringify(info.resourceCacheInfo)) - console.log("AllCacheInfoCallback data ="+JSON.stringify(info.dataCacheInfo)) - this.cacheinfo1 = "memory="+JSON.stringify(info.memoryCacheInfo)+ - "\n resource ="+JSON.stringify(info.resourceCacheInfo)+ - "\n data ="+JSON.stringify(info.dataCacheInfo) - }}) - ImageKnife?.call(imageKnifeOption); - } - - private testAllCacheInfoNetwork() { - let ImageKnifeOption = new RequestOption(); - ImageKnifeOption.load("https://hbimg.huabanimg.com/0ef60041445edcfd6b38d20e19024b2cd9281dcc3525a4-Vy8fYO_fw658/format/webp") - .addListener({callback:(err:BusinessError|string, data:ImageKnifeData) => { - let pack = data.drawPixelMap?.imagePixelMap as PixelMap; - this.networkPixelMap = pack; - console.log("imageknife2 图片2 赋值!") - return false; - }}).addAllCacheInfoCallback({callback:(allCacheInfo:AllCacheInfo)=>{ - let info = allCacheInfo as AllCacheInfo; - console.log("AllCacheInfoCallback memory ="+JSON.stringify(info.memoryCacheInfo)) - console.log("AllCacheInfoCallback resource ="+JSON.stringify(info.resourceCacheInfo)) - console.log("AllCacheInfoCallback data ="+JSON.stringify(info.dataCacheInfo)) - this.cacheinfo2 = "memory="+JSON.stringify(info.memoryCacheInfo)+ - "\n resource ="+JSON.stringify(info.resourceCacheInfo)+ - "\n data ="+JSON.stringify(info.dataCacheInfo) - }}) - .setImageViewSize({width:300,height:300}) - .rotateImage(180) - ImageKnife?.call(ImageKnifeOption); - } -} - - -let ImageKnife = (ImageKnifeGlobal.getInstance().getImageKnife()) \ No newline at end of file diff --git a/entry/src/main/ets/pages/testDiskPreLoadPage.ets b/entry/src/main/ets/pages/testDiskPreLoadPage.ets deleted file mode 100644 index fb52d2d..0000000 --- a/entry/src/main/ets/pages/testDiskPreLoadPage.ets +++ /dev/null @@ -1,61 +0,0 @@ -/* - * 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 { ImageKnife,ImageKnifeGlobal,ImageKnifeOption,ImageKnifeComponent} from '@ohos/libraryimageknife' - -@Entry -@Component -struct DiskPreLoadPage { - - @State imageKnifeOption2: ImageKnifeOption = - { - loadSrc: $r('app.media.icon'), - placeholderSrc: $r('app.media.icon_loading'), - errorholderSrc: $r('app.media.icon_failed'), - }; - - build() { - Row() { - Column() { - Button("预加载图片").onClick(()=>{ - let imageKnife: ImageKnife | undefined = ImageKnifeGlobal.getInstance().getImageKnife(); - if(imageKnife != undefined){ - imageKnife.prefetchToDiskCache("https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658") - .then((resolve)=>{ - console.log("成功回调 : " + resolve) - }) - .catch((reject: ESObject) => { - console.log("失败回调 : " + reject) - }) - } - }) - Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { - Button("加载GIF") - .onClick(() => { - this.imageKnifeOption2 = { - loadSrc: 'https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658', - placeholderSrc: $r('app.media.icon_loading'), - errorholderSrc: $r('app.media.icon_failed'), - displayProgress:true, - } - }).margin({ top: 5, left: 3 }) - ImageKnifeComponent({ imageKnifeOption: this.imageKnifeOption2 }).width(300).height(300) - }.width('100%').backgroundColor(Color.Pink) - } - .width('100%') - } - .height('100%') - } -} \ No newline at end of file diff --git a/entry/src/main/ets/pages/testImageAntiAliasingWithPage.ets b/entry/src/main/ets/pages/testImageAntiAliasingWithPage.ets deleted file mode 100644 index 182dd1e..0000000 --- a/entry/src/main/ets/pages/testImageAntiAliasingWithPage.ets +++ /dev/null @@ -1,62 +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,AntiAliasing } from '@ohos/libraryimageknife' -import { ImageKnifeOption } from '@ohos/libraryimageknife' -import { RotateImageTransformation } from '@ohos/libraryimageknife' -import { RoundedCornersTransformation } from '@ohos/libraryimageknife' - -@Entry -@Component -struct TestImageAntiAliasingWithPage { - @State imageKnifeOption1: ImageKnifeOption = - { - loadSrc: $r('app.media.icon_failed'), - }; - - build() { - Scroll() { - Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { - Text("ImageKnife开启抗锯齿").fontSize(15) - ImageKnifeComponent({ imageKnifeOption: this.imageKnifeOption1,imageSmoothingQuality: AntiAliasing.FIT_HIGH }).width(600).height(600) - Text("Image开启抗锯齿").fontSize(15) - Image($r('app.media.icon_failed')) - .width(600) - .height(600) - .margin(15) - .overlay('png', { align: Alignment.Bottom, offset: { x: 0, y: 20 } }) - .interpolation(ImageInterpolation.High) - Text("ImageKnife开启抗锯齿且设置为中等").fontSize(15) - ImageKnifeComponent({ imageKnifeOption: this.imageKnifeOption1,imageSmoothingQuality: AntiAliasing.FIT_MEDIUM }).width(600).height(600) - Text("Image开启抗锯齿且设置为中等").fontSize(15) - Image($r('app.media.icon_failed')) - .width(600) - .height(600) - .margin(15) - .overlay('png', { align: Alignment.Bottom, offset: { x: 0, y: 20 } }) - .interpolation(ImageInterpolation.Medium) - Text("ImageKnife未开启抗锯齿").fontSize(15) - ImageKnifeComponent({ imageKnifeOption: this.imageKnifeOption1,imageSmoothingEnabled: false }).width(600).height(600) - Text("Image未开启抗锯齿").fontSize(15) - Image($r('app.media.icon_failed')) - .width(600) - .height(600) - .margin(15) - .overlay('png', { align: Alignment.Bottom, offset: { x: 0, y: 20 } }) - } - } - .width('100%') - .height('100%') - } -} \ No newline at end of file diff --git a/entry/src/main/ets/pages/testImageKnifeAutoHeightPage.ets b/entry/src/main/ets/pages/testImageKnifeAutoHeightPage.ets deleted file mode 100644 index 701b868..0000000 --- a/entry/src/main/ets/pages/testImageKnifeAutoHeightPage.ets +++ /dev/null @@ -1,71 +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 { ComponentUtils } from '@ohos.arkui.UIContext' -import display from '@ohos.display'; -import { ImageKnifeComponent, - ScaleType } from '@ohos/libraryimageknife' -import componentUtils from '@ohos.arkui.componentUtils'; - -@Entry -@Component - -struct testImageKnifeAutoHeightPage { - - - private currentWidth: number =0 - private currentHeight: number =0 - - @State value : componentUtils.ComponentInfo = componentUtils.getRectangleById("ImageKnifeCanvas"); - - aboutToAppear(){ - let displayClas : ESObject =null - try { - displayClas = display.getDefaultDisplaySync() - console.info('........width'+ displayClas.width) - console.info('........height'+ displayClas.height) - - }catch (e){ - - console.error('error' + e) - } - - - } - build(){ - Scroll(){ - Column(){ - ImageKnifeComponent({ - imageKnifeOption:{ - loadSrc :$r('app.media.pngSample'), - mainScaleType:ScaleType.AUTO_HEIGHT, - } - }) - .width("100%") - Button(){ - Text('getRectangleById').fontSize(40).fontWeight(FontWeight.Bold); - } - .onClick(()=> { - this.value = componentUtils.getRectangleById("ImageKnifeCanvas") - this.currentWidth = px2vp(this.value.size.width) - this.currentHeight = px2vp(this.value.size.height) - console.log('currentWidth'+this.currentWidth) - console.log('currentHeight'+this.currentHeight) - }) - } - } - - } -} \ No newline at end of file diff --git a/entry/src/main/ets/pages/testImageKnifeAutoPage.ets b/entry/src/main/ets/pages/testImageKnifeAutoPage.ets deleted file mode 100644 index 1251d76..0000000 --- a/entry/src/main/ets/pages/testImageKnifeAutoPage.ets +++ /dev/null @@ -1,71 +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 { ComponentUtils } from '@ohos.arkui.UIContext' -import display from '@ohos.display'; -import { ImageKnifeComponent, - ScaleType } from '@ohos/libraryimageknife' -import componentUtils from '@ohos.arkui.componentUtils'; - -@Entry -@Component - -struct testImageKnifeAutoPage { - - - private currentWidth: number =0 - private currentHeight: number =0 - - @State value : componentUtils.ComponentInfo = componentUtils.getRectangleById("ImageKnifeCanvas"); - - aboutToAppear(){ - let displayClas : ESObject =null - try { - displayClas = display.getDefaultDisplaySync() - console.info('........width'+ displayClas.width) - console.info('........height'+ displayClas.height) - - }catch (e){ - - console.error('error' + e) - } - - - } - build(){ - Scroll(){ - Column(){ - ImageKnifeComponent({ - imageKnifeOption:{ - loadSrc :$r('app.media.pngSample'), - mainScaleType:ScaleType.AUTO, - } - }) - - Button(){ - Text('getRectangleById').fontSize(40).fontWeight(FontWeight.Bold); - } - .onClick(()=> { - this.value = componentUtils.getRectangleById("ImageKnifeCanvas") - this.currentWidth = px2vp(this.value.size.width) - this.currentHeight = px2vp(this.value.size.height) - console.log('currentWidth'+this.currentWidth) - console.log('currentHeight'+this.currentHeight) - }) - } - } - - } -} \ No newline at end of file diff --git a/entry/src/main/ets/pages/testImageKnifeAutoWidthPage.ets b/entry/src/main/ets/pages/testImageKnifeAutoWidthPage.ets deleted file mode 100644 index 256f29c..0000000 --- a/entry/src/main/ets/pages/testImageKnifeAutoWidthPage.ets +++ /dev/null @@ -1,72 +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 { ComponentUtils } from '@ohos.arkui.UIContext' -import display from '@ohos.display'; -import { ImageKnifeComponent, - ScaleType } from '@ohos/libraryimageknife' -import componentUtils from '@ohos.arkui.componentUtils'; - -@Entry -@Component - -struct testImageKnifeAutoWidthPage { - - - private currentWidth: number =0 - private currentHeight: number =0 - - @State value : componentUtils.ComponentInfo = componentUtils.getRectangleById("ImageKnifeCanvas"); - - aboutToAppear(){ - let displayClas : ESObject =null - try { - displayClas = display.getDefaultDisplaySync() - console.info('........width'+ displayClas.width) - console.info('........height'+ displayClas.height) - - }catch (e){ - - console.error('error' + e) - } - - - } - build(){ - Scroll(){ - Column(){ - ImageKnifeComponent({ - imageKnifeOption:{ - loadSrc :$r('app.media.pngSample'), - mainScaleType:ScaleType.AUTO_WIDTH, - } - }) - .height(400) - - Button(){ - Text('getRectangleById').fontSize(40).fontWeight(FontWeight.Bold); - } - .onClick(()=> { - this.value = componentUtils.getRectangleById("ImageKnifeCanvas") - this.currentWidth = px2vp(this.value.size.width) - this.currentHeight = px2vp(this.value.size.height) - console.log('currentWidth'+this.currentWidth) - console.log('currentHeight'+this.currentHeight) - }) - } - } - - } -} \ No newline at end of file diff --git a/entry/src/main/ets/pages/testImageKnifeHttpRequestHeader.ets b/entry/src/main/ets/pages/testImageKnifeHttpRequestHeader.ets deleted file mode 100644 index 411a411..0000000 --- a/entry/src/main/ets/pages/testImageKnifeHttpRequestHeader.ets +++ /dev/null @@ -1,256 +0,0 @@ -/* - * Copyright (C) 2024 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { - HeaderOptions,ImageKnife,ImageKnifeComponent,ImageKnifeData,ImageKnifeGlobal,RequestOption,ImageKnifeOption,ObjectKey -} from '@ohos/libraryimageknife' -import image from '@ohos.multimedia.image' -import { BusinessError } from '@ohos.base' - -const TAG = "TEST-" -let timeId = -1 - -@Entry -@Component -struct testImageKnifeHttpRequestHeader { - @State pixelMap: PixelMap | undefined = undefined; - @State pixelMap1: PixelMap | undefined = undefined; - @State pixelMap2: PixelMap | undefined = undefined; - @State pixelMap3: PixelMap | undefined = undefined; - @State domeType1: boolean = false; - @State domeType2: boolean = false; - @State domeType3: boolean = false; - @State domeType4: boolean = false; - @State domeType5: boolean = false; - @State domeType6: boolean = false; - @State successHeader: string = "requestOption调用成功"; - @State errorHeader: string = "requestOption调用失败"; - @State successHeader1: string = "全局调用imageKnife成功"; - @State errorHeader1: string = "全局调用imageKnife失败"; - @State successHeader2: string = "单个imageKnife组件调用成功"; - @State errorHeader2: string = "单个imageKnife组件调用失败"; - - @State message: string = "图片header属性测试"; - @State headerOptions1: HeaderOptions = { - key: "refer", - value: "http://1.94.37.200:7070/AntiTheftChain/downloadImage" - }; - @State headerOptions2: HeaderOptions = { - key: "xx", - value: "http://1.94.37.200:7070/AntiTheftChain/downloadImage" - }; - @State imageKnifeOption1: ImageKnifeOption = - { - loadSrc: 'http://1.94.37.200:7070/AntiTheftChain/downloadImage', - placeholderSrc: $r('app.media.icon_loading'), - errorholderSrc: $r('app.media.icon_failed'), - headerOption: [this.headerOptions1] - }; - @State imageKnifeOption2: ImageKnifeOption = - { - loadSrc: 'http://1.94.37.200:7070/AntiTheftChain/downloadImage', - placeholderSrc: $r('app.media.icon_loading'), - errorholderSrc: $r('app.media.icon_failed'), - headerOption: [this.headerOptions2] - }; - - // RequestOption调用 - load(src: string | image.PixelMap | Resource, type: string, num: number) { - clearTimeout(timeId) - let request = new RequestOption() - if (type == 'error') { - request.addHeader('xx', src) - } else { - request.addHeader('refer', src) - } - //清理缓存 - request.signature = new ObjectKey(new Date().getTime().toString()) - request.load(src) - .addListener({ callback: (err: BusinessError | string, data: ImageKnifeData) => { - if (data.isPixelMap()) { - if (data.drawPixelMap) { - let pixelmap = data.drawPixelMap.imagePixelMap - if (pixelmap) { - if (num == 1) { - this.pixelMap = pixelmap - } else if (num == 2) { - this.pixelMap1 = pixelmap - } else if (num == 3) { - this.pixelMap2 = pixelmap - } else if (num == 4) { - this.pixelMap3 = pixelmap - } - } - } - } - if (data.isGIFFrame()) { - let index: number = 0 - if (data.drawGIFFrame) { - if (data.drawGIFFrame.imageGIFFrames) { - let renderGif = () => { - if (data.drawGIFFrame) { - if (data.drawGIFFrame.imageGIFFrames) { - let pixelmap = data.drawGIFFrame.imageGIFFrames[index].drawPixelMap - let delay = data.drawGIFFrame.imageGIFFrames[index].delay - if (pixelmap) { - if (num == 1) { - this.pixelMap = pixelmap - } else if (num == 2) { - this.pixelMap1 = pixelmap - } else if (num == 3) { - this.pixelMap2 = pixelmap - } else if (num == 4) { - this.pixelMap3 = pixelmap - } - } - index++; - if (index == data.drawGIFFrame.imageGIFFrames.length - 1) { - index = 0 - } - timeId = setTimeout(renderGif, data!.drawGIFFrame!.imageGIFFrames![index].delay) - } - } - } - renderGif() - } - } - } - if (err) { - console.log(TAG + "error:" + JSON.stringify(err)); - } - return false - } - }) - let imageknife: ImageKnife | undefined = ImageKnifeGlobal.getInstance().getImageKnife() - if (imageknife != undefined) { - imageknife.call(request) - } - } - - @Builder - setHeader() { - ImageKnifeComponent({ - imageKnifeOption: { - loadSrc: this.pixelMap as image.PixelMap - } - }).width(200).height(200).borderWidth(1) - } - @Builder - setHeader3() { - ImageKnifeComponent({ - imageKnifeOption: { - loadSrc: this.pixelMap1 as image.PixelMap - } - }).width(200).height(200).borderWidth(1) - } - @Builder - setHeader1() { - ImageKnifeComponent({ - imageKnifeOption: { - loadSrc: this.pixelMap2 as image.PixelMap - } - }).width(200).height(200).borderWidth(1) - } - @Builder - setHeader4() { - ImageKnifeComponent({ - imageKnifeOption: { - loadSrc: this.pixelMap3 as image.PixelMap - } - }).width(200).height(200).borderWidth(1) - } - @Builder - setHeader2() { - ImageKnifeComponent({ imageKnifeOption: this.imageKnifeOption1 }) - .margin(16) - .width(200) - .height(200) - } - @Builder - setHeader5() { - ImageKnifeComponent({ imageKnifeOption: this.imageKnifeOption2 }) - .margin(16) - .width(200) - .height(200) - } - - build() { - Scroll() { - Column() { - Text(`${this.message}`) - .width("300vp") - .height("60vp") - .textAlign(TextAlign.Center) - .fontSize("30fp") - .fontWeight(FontWeight.Bold) - Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Start }) { - Button(this.successHeader) - .margin(16) - .onClick(() => { - this.domeType1 = !this.domeType1 - this.load('http://1.94.37.200:7070/AntiTheftChain/downloadImage', 'success', 1) - }) - if (this.domeType1) { - this.setHeader() - } - Button(this.errorHeader) - .margin(16) - .onClick(() => { - this.domeType2 = !this.domeType2 - this.load('http://1.94.37.200:7070/AntiTheftChain/downloadImage', 'error', 2) - }) - if (this.domeType2) { - this.setHeader3() - } - Button(this.successHeader1) - .margin(16) - .onClick(() => { - this.domeType3 = !this.domeType3 - this.load('http://1.94.37.200:7070/AntiTheftChain/downloadImage', 'success', 3) - }) - if (this.domeType3) { - this.setHeader1() - } - Button(this.errorHeader1) - .margin(16) - .onClick(() => { - this.domeType4 = !this.domeType4 - this.load('http://1.94.37.200:7070/AntiTheftChain/downloadImage', 'error', 4) - }) - if (this.domeType4) { - this.setHeader4() - } - Button(this.successHeader2) - .margin(16) - .onClick(() => { - this.domeType5 = !this.domeType5 - }) - if (this.domeType5) { - this.setHeader2() - } - Button(this.errorHeader2) - .margin(16) - .onClick(() => { - this.domeType6 = !this.domeType6 - }) - if (this.domeType6) { - this.setHeader5() - } - } - }.width("100%") - .justifyContent(FlexAlign.Start) - } - } -} diff --git a/entry/src/main/ets/pages/testImageKnifeOptionChangedPage.ets b/entry/src/main/ets/pages/testImageKnifeOptionChangedPage.ets deleted file mode 100644 index dc95841..0000000 --- a/entry/src/main/ets/pages/testImageKnifeOptionChangedPage.ets +++ /dev/null @@ -1,214 +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/libraryimageknife' -import {ImageKnifeOption} from '@ohos/libraryimageknife' -import {ImageKnifeGlobal} from '@ohos/libraryimageknife' -import {ImageKnife} from '@ohos/libraryimageknife' -import {RotateImageTransformation} from '@ohos/libraryimageknife' -import ArkWorker from '@ohos.worker' -import worker from '@ohos.worker' -@Entry -@Component -struct TestImageKnifeOptionChangedPage { - - svgUrl:string = '' - @State imageKnifeOption1: ImageKnifeOption = - { - loadSrc: $r('app.media.jpgSample'), - - 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'), - - placeholderSrc: $r('app.media.icon_loading'), - errorholderSrc: $r('app.media.icon_failed'), - - }; - - }).margin({left:5}).backgroundColor(Color.Blue) - Button('png') - .onClick(()=>{ - this.imageKnifeOption1 = { - loadSrc: $r('app.media.pngSample'), - - placeholderSrc: $r('app.media.icon_loading'), - errorholderSrc: $r('app.media.icon_failed'), - - }; - - }).margin({left:5}).backgroundColor(Color.Blue) - Button('bmp') - .onClick(()=>{ - this.imageKnifeOption1 = { - loadSrc: $r('app.media.bmpSample'), - - placeholderSrc: $r('app.media.icon_loading'), - errorholderSrc: $r('app.media.icon_failed'), - - }; - - }).margin({left:5}).backgroundColor(Color.Blue) - Button('webp') - .onClick(()=>{ - this.imageKnifeOption1 = { - loadSrc: $r('app.media.jpgSample'), - - placeholderSrc: $r('app.media.icon_loading'), - errorholderSrc: $r('app.media.icon_failed') - }; - - }).margin({left:5}).backgroundColor(Color.Blue) - Button('svg') - .onClick(()=>{ - this.imageKnifeOption1 = { - loadSrc: $r('app.media.svgSample'), - - placeholderSrc: $r('app.media.icon_loading'), - errorholderSrc: $r('app.media.icon_failed') - }; - - }).margin({left:5}).backgroundColor(Color.Blue) - Button('gif') - .onClick(()=>{ - this.imageKnifeOption1 = { - loadSrc: $r('app.media.gifSample'), - - placeholderSrc: $r('app.media.icon_loading'), - errorholderSrc: $r('app.media.icon_failed') - }; - - }).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', - - placeholderSrc: $r('app.media.icon_loading'), - errorholderSrc: $r('app.media.icon_failed') - }; - }).margin({left:5}).backgroundColor(Color.Blue) - Button('png') - .onClick(()=>{ - this.imageKnifeOption1 = { - loadSrc: 'https://img-blog.csdnimg.cn/20191215043500229.png', - - placeholderSrc: $r('app.media.icon_loading'), - errorholderSrc: $r('app.media.icon_failed') - }; - }).margin({left:5}).backgroundColor(Color.Blue) - Button('bmp') - .onClick(()=>{ - this.imageKnifeOption1 = { - loadSrc: 'https://img-blog.csdn.net/20140514114029140', - - placeholderSrc: $r('app.media.icon_loading'), - errorholderSrc: $r('app.media.icon_failed') - }; - }).margin({left:5}).backgroundColor(Color.Blue) - Button('webp') - .onClick(()=>{ - this.imageKnifeOption1 = { - loadSrc: 'https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp', - - placeholderSrc: $r('app.media.icon_loading'), - errorholderSrc: $r('app.media.icon_failed') - }; - }).margin({left:5}).backgroundColor(Color.Blue) - - Text("请先设置SVG图片的url地址") - TextArea({ placeholder: '请输入SVG图片的url地址' }) - .placeholderColor("rgb(0,0,35)") - .placeholderFont({ size: 20, weight: 100, family: 'cursive', style: FontStyle.Italic }) - .textAlign(TextAlign.Center) - .caretColor(Color.Blue) - .height(40) - .width(400) - .fontSize(20) - .fontWeight(FontWeight.Bold) - .fontFamily("sans-serif") - .fontStyle(FontStyle.Normal) - .fontColor(Color.Red) - .onChange((value: string) => { - this.svgUrl = value - }) - - Button('svg') - .onClick(()=>{ - this.imageKnifeOption1 = { - loadSrc: this.svgUrl, - - placeholderSrc: $r('app.media.icon_loading'), - errorholderSrc: $r('app.media.icon_failed') - }; - }).margin({left:5}).backgroundColor(Color.Blue) - Button('gif') - .onClick(()=>{ - this.imageKnifeOption1 = { - loadSrc: 'https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658', - - placeholderSrc: $r('app.media.icon_loading'), - errorholderSrc: $r('app.media.icon_failed') - }; - }).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", - - placeholderSrc: $r('app.media.icon_loading'), - errorholderSrc: $r('app.media.icon_failed') - }; - }).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: this.imageKnifeOption1 }) - .width(300) - .height(300) - }.width(400).height(400).margin({top:10}).backgroundColor(Color.Pink) - - - } - } - .width('100%') - .height('100%') - } - - aboutToAppear() { - - } - aboutToDisappear(){ - - } -} - - diff --git a/entry/src/main/ets/pages/testImageKnifeOptionChangedPage2.ets b/entry/src/main/ets/pages/testImageKnifeOptionChangedPage2.ets deleted file mode 100644 index 44c646f..0000000 --- a/entry/src/main/ets/pages/testImageKnifeOptionChangedPage2.ets +++ /dev/null @@ -1,110 +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/libraryimageknife' -import {ImageKnifeOption} from '@ohos/libraryimageknife' -import {BaseTransform} from '@ohos/libraryimageknife' -import {RotateImageTransformation} from '@ohos/libraryimageknife' -import {GrayscaleTransformation} from '@ohos/libraryimageknife' -import {SketchFilterTransformation} from '@ohos/libraryimageknife' -import image from '@ohos.multimedia.image' - -@Entry -@Component -struct TestImageKnifeOptionChangedPage2 { - @State imageKnifeOption1: ImageKnifeOption = - { - loadSrc: $r('app.media.jpgSample'), - - placeholderSrc: $r('app.media.icon_loading'), - errorholderSrc: $r('app.media.icon_failed'), - - thumbSizeMultiplier:0.1 - }; - - - build() { - Scroll() { - Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { - Flex({direction:FlexDirection.Row}){ - Button("网络jpg") - .onClick(()=>{ - let rotateTrans:BaseTransform = new RotateImageTransformation(180) - this.imageKnifeOption1 = { - loadSrc: "https://hbimg.huabanimg.com/cc6af25f8d782d3cf3122bef4e61571378271145735e9-vEVggB", - - placeholderSrc: $r('app.media.icon_loading'), - errorholderSrc: $r('app.media.icon_failed'), - - thumbSizeMultiplier:0.1, - transformation:rotateTrans - }; - }).margin({left:5}).backgroundColor(Color.Blue) - Button("png") - .onClick(()=>{ - this.imageKnifeOption1 = { - loadSrc: "https://img-blog.csdnimg.cn/20191215043500229.png", - - placeholderSrc: $r('app.media.icon_loading'), - errorholderSrc: $r('app.media.icon_failed'), - - thumbSizeMultiplier:0.1, - transformations:[new RotateImageTransformation(180)] - }; - }).margin({left:5}).backgroundColor(Color.Blue) - Button("bmp") - .onClick(()=>{ - this.imageKnifeOption1 = { - loadSrc: "https://img-blog.csdn.net/20140514114029140", - - placeholderSrc: $r('app.media.icon_loading'), - errorholderSrc: $r('app.media.icon_failed'), - - thumbSizeMultiplier:0.1, - transformations:[new GrayscaleTransformation()] - }; - }).margin({left:5}).backgroundColor(Color.Blue) - Button("webp") - .onClick(()=>{ - this.imageKnifeOption1 = { - loadSrc: "https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp", - - placeholderSrc: $r('app.media.icon_loading'), - errorholderSrc: $r('app.media.icon_failed'), - - thumbSizeMultiplier:0.1, - transformations:[new SketchFilterTransformation()] - }; - }).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: this.imageKnifeOption1 }).width(300).height(300) - }.width(400).height(400).margin({top:10}).backgroundColor(Color.Pink) - - - } - } - .width('100%') - .height('100%') - } - - aboutToAppear() { - console.log("aboutToAppear()") - } -} - - diff --git a/entry/src/main/ets/pages/testImageKnifeOptionChangedPage3.ets b/entry/src/main/ets/pages/testImageKnifeOptionChangedPage3.ets deleted file mode 100644 index 7c988c2..0000000 --- a/entry/src/main/ets/pages/testImageKnifeOptionChangedPage3.ets +++ /dev/null @@ -1,167 +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/libraryimageknife' -import {ImageKnifeOption} from '@ohos/libraryimageknife' -import {ImageKnifeGlobal} from '@ohos/libraryimageknife' -import {ImageKnife} from '@ohos/libraryimageknife' -import {ScaleType} from '@ohos/libraryimageknife' -import {RotateImageTransformation} from '@ohos/libraryimageknife' -import {GrayscaleTransformation} from '@ohos/libraryimageknife' -import {SketchFilterTransformation} from '@ohos/libraryimageknife' -import ArkWorker from '@ohos.worker' -import worker from '@ohos.worker' -import {BaseTransform} from '@ohos/libraryimageknife' -import image from '@ohos.multimedia.image' -@Entry -@Component -struct TestImageKnifeOptionChangedPage3 { - - @State imageKnifeOption1: ImageKnifeOption = - { - loadSrc: $r('app.media.jpgSample'), - mainScaleType: ScaleType.FIT_CENTER, - placeholderSrc: $r('app.media.icon_loading'), - errorholderSrc: $r('app.media.icon_failed'), - }; - @State compWidht:number = 300 - @State compHeight:number = 300 - - - build() { - Scroll() { - Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { - Flex({direction:FlexDirection.Row}){ - Button("本地jpg") - .onClick(()=>{ - let rotateTrans:BaseTransform = new RotateImageTransformation(180) - this.imageKnifeOption1 = { - loadSrc: $r('app.media.jpgSample'), - mainScaleType: ScaleType.FIT_CENTER, - placeholderSrc: $r('app.media.icon_loading'), - errorholderSrc: $r('app.media.icon_failed'), - thumbSizeMultiplier:0.1, - transformation:rotateTrans, - }; - - }).margin({left:5}).backgroundColor(Color.Blue) - Button("本地png") - .onClick(()=>{ - - let rotateTrans:BaseTransform = new RotateImageTransformation(180) - this.imageKnifeOption1 = { - loadSrc: $r('app.media.pngSample'), - mainScaleType: ScaleType.FIT_CENTER, - placeholderSrc: $r('app.media.icon_loading'), - errorholderSrc: $r('app.media.icon_failed'), - thumbSizeMultiplier:0.1, - transformation:rotateTrans, - }; - - }).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, - placeholderSrc: $r('app.media.icon_loading'), - errorholderSrc: $r('app.media.icon_failed'), - thumbSizeMultiplier:0.1, - transformations:[new GrayscaleTransformation()], - }; - - }).margin({left:5}).backgroundColor(Color.Blue) - Button("本地webp") - .onClick(()=>{ - this.imageKnifeOption1 = { - loadSrc: $r('app.media.webpSample'), - mainScaleType: ScaleType.FIT_CENTER, - placeholderSrc: $r('app.media.icon_loading'), - errorholderSrc: $r('app.media.icon_failed'), - thumbSizeMultiplier:0.1, - transformations:[new SketchFilterTransformation()], - }; - - }).margin({left:5}).backgroundColor(Color.Blue) - }.margin({top:15}) - Flex({direction:FlexDirection.Row}){ - Button("网络jpg") - .onClick(()=>{ - let rotateTrans:BaseTransform = new RotateImageTransformation(180) - this.imageKnifeOption1 = { - loadSrc: "https://hbimg.huabanimg.com/cc6af25f8d782d3cf3122bef4e61571378271145735e9-vEVggB", - placeholderSrc: $r('app.media.icon_loading'), - errorholderSrc: $r('app.media.icon_failed'), - displayProgress:true, - thumbSizeMultiplier:0.1, - transformation:rotateTrans - }; - }).margin({left:5}).backgroundColor(Color.Blue) - Button("网络png") - .onClick(()=>{ - this.imageKnifeOption1 = { - loadSrc: "https://img-blog.csdnimg.cn/20191215043500229.png", - placeholderSrc: $r('app.media.icon_loading'), - errorholderSrc: $r('app.media.icon_failed'), - displayProgress:true, - thumbSizeMultiplier:0.1, - 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", - placeholderSrc: $r('app.media.icon_loading'), - errorholderSrc: $r('app.media.icon_failed'), - displayProgress:true, - thumbSizeMultiplier:0.1, - transformations:[new GrayscaleTransformation()] - }; - }).margin({left:5}).backgroundColor(Color.Blue) - Button("网络webp") - .onClick(()=>{ - this.imageKnifeOption1 = { - loadSrc: "https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp", - placeholderSrc: $r('app.media.icon_loading'), - errorholderSrc: $r('app.media.icon_failed'), - displayProgress:true, - thumbSizeMultiplier:0.1, - }; - }).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: this.imageKnifeOption1 }).width(this.compWidht).height(this.compHeight) - }.width(400).height(400).margin({top:10}).backgroundColor(Color.Pink) - - - } - } - .width('100%') - .height('100%') - } - aboutToAppear() { - - } - aboutToDisappear(){ - } -} - - diff --git a/entry/src/main/ets/pages/testImageKnifeOptionChangedPage4.ets b/entry/src/main/ets/pages/testImageKnifeOptionChangedPage4.ets deleted file mode 100644 index 441c02b..0000000 --- a/entry/src/main/ets/pages/testImageKnifeOptionChangedPage4.ets +++ /dev/null @@ -1,277 +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 { - GrayscaleTransformation, - ImageKnifeComponent, - ImageKnifeData, - ImageKnifeOption, - RotateImageTransformation, - SketchFilterTransformation, - ScaleTypeHelper, - IDrawLifeCycle, - ScaleType, - ImageKnifeGlobal, - BaseTransform -} from '@ohos/libraryimageknife' -import ArkWorker from '@ohos.worker' -import worker from '@ohos.worker'; -import image from '@ohos.multimedia.image'; - -@Entry -@Component -struct TestImageKnifeOptionChangedPage4 { - - @State imageKnifeOption1: ImageKnifeOption = - { - loadSrc: $r('app.media.jpgSample'), - - placeholderSrc: $r('app.media.icon_loading'), - errorholderSrc: $r('app.media.icon_failed'), - - 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(() => { - let rotateTrans: BaseTransform = new RotateImageTransformation(180) - this.imageKnifeOption1 = { - loadSrc: "https://hbimg.huabanimg.com/cc6af25f8d782d3cf3122bef4e61571378271145735e9-vEVggB", - - placeholderSrc: $r('app.media.icon_loading'), - errorholderSrc: $r('app.media.icon_failed'), - - thumbSizeMultiplier: 0.1, - transformation: rotateTrans, - drawLifeCycle: this.createViewLifeCycle() - }; - }).margin({ left: 5 }).backgroundColor(Color.Blue) - Button("网络png") - .onClick(() => { - this.imageKnifeOption1 = { - loadSrc: "https://img-blog.csdnimg.cn/20191215043500229.png", - - placeholderSrc: $r('app.media.icon_loading'), - errorholderSrc: $r('app.media.icon_failed'), - - 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", - - placeholderSrc: $r('app.media.icon_loading'), - errorholderSrc: $r('app.media.icon_failed'), - - 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", - - placeholderSrc: $r('app.media.icon_loading'), - errorholderSrc: $r('app.media.icon_failed'), - - 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: this.imageKnifeOption1 }).width(300).height(300) - }.width(400).height(400).margin({ top: 10 }).backgroundColor(Color.Pink) - - } - } - .width('100%') - .height('100%') - } - - aboutToAppear() { - - } - - aboutToDisappear() { - - } - - drawMainAnimate_index: number = 0; - drawMainAnimate_context?: CanvasRenderingContext2D = undefined; - drawMainAnimate_scaleType: ScaleType = ScaleType.FIT_CENTER; - drawMainAnimate_imagePixelMap?: PixelMap = undefined; - drawMainAnimate_widthPixel: number = 0; - drawMainAnimate_heightPixel: number = 0; - drawMainAnimate_compWidth: number = 0; - drawMainAnimate_compHeight: number = 0; - drawMainAnimate = () => { - console.log('drawMainAnimate index = ' + this.drawMainAnimate_index) - - let clipScale = (this.drawMainAnimate_index / 30.0) - this.drawMainAnimate_context?.save() - this.drawMainAnimate_context?.beginPath(); - let path2d = new Path2D() - let maxRadius = Math.sqrt(this.drawMainAnimate_compWidth / 2 * this.drawMainAnimate_compWidth / 2 + this.drawMainAnimate_compHeight / 2 * this.drawMainAnimate_compHeight / 2) - path2d.arc(this.drawMainAnimate_compWidth / 2, this.drawMainAnimate_compHeight / 2, maxRadius * clipScale, 0, Math.PI * 2) - this.drawMainAnimate_context?.clip(path2d) - this.drawMainAnimate_context?.save() - ScaleTypeHelper.drawImageWithScaleType(this.drawMainAnimate_context!, this.drawMainAnimate_scaleType, this.drawMainAnimate_imagePixelMap, px2vp(this.drawMainAnimate_widthPixel), px2vp(this.drawMainAnimate_heightPixel), this.drawMainAnimate_compWidth, this.drawMainAnimate_compHeight, 0, 0) - this.drawMainAnimate_context?.restore(); - this.drawMainAnimate_context?.restore(); - if (this.drawMainAnimate_index < 30) { - this.drawMainAnimate_index++ - let nextFunc = this.drawMainAnimate - - 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) => { - - this.stopAnimate() - return false; - }, - // 展示加载进度 - displayProgress: (context: CanvasRenderingContext2D, progress: number, imageKnifeOption: ImageKnifeOption, compWidth: number, compHeight: number, setGifTimeId?: (timeId: number) => void) => { - - 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) => { - - this.stopAnimate() - return false; - }, - - // 展示主图 - displayMainSource: (context: CanvasRenderingContext2D, data: ImageKnifeData, imageKnifeOption: ImageKnifeOption, compWidth: number, compHeight: number, setGifTimeId?: (timeId: number) => void) => { - this.stopAnimate() - if (data.isPixelMap()) { - - 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) - - - this.drawMainAnimate_index = 0; - this.drawMainAnimate_context = context; - this.drawMainAnimate_scaleType = scaleType - this.drawMainAnimate_imagePixelMap = data.drawPixelMap?.imagePixelMap - this.drawMainAnimate_widthPixel = imageInfo.size.width - this.drawMainAnimate_heightPixel = imageInfo.size.height - this.drawMainAnimate_compWidth = compWidth - this.drawMainAnimate_compHeight = compHeight - - let func = this.drawMainAnimate - - 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) => { - - this.stopAnimate() - return false; - }, - - // 展示失败占位图 - displayErrorholder: (context: CanvasRenderingContext2D, data: ImageKnifeData, imageKnifeOption: ImageKnifeOption, compWidth: number, compHeight: number, setGifTimeId?: (timeId: number) => void) => { - - this.stopAnimate() - return false; - } - } - return viewLifeCycle; - } -} - - diff --git a/entry/src/main/ets/pages/testImageKnifeOptionChangedPage5.ets b/entry/src/main/ets/pages/testImageKnifeOptionChangedPage5.ets deleted file mode 100644 index 47c1119..0000000 --- a/entry/src/main/ets/pages/testImageKnifeOptionChangedPage5.ets +++ /dev/null @@ -1,177 +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 { - GrayscaleTransformation, - ImageKnifeComponent, - ImageKnifeData, - ImageKnifeGlobal, - ImageKnifeOption, - ImageKnife, - RotateImageTransformation, - SketchFilterTransformation, - ScaleTypeHelper, - IDrawLifeCycle, - ScaleType, - ImageKnifeDrawFactory -} from '@ohos/libraryimageknife' -import worker from '@ohos.worker'; -@Entry -@Component -struct TestImageKnifeOptionChangedPage5 { - - @State imageKnifeOption1: ImageKnifeOption = - { - loadSrc: $r('app.media.jpgSample'), - placeholderSrc: $r('app.media.icon_loading'), - errorholderSrc: $r('app.media.icon_failed'), - drawLifeCycle:this.choiceViewLifeCycle(DrawType.Oval) - }; - - - 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", - 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", - 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", - 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", - 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: this.imageKnifeOption1 }).width(300).height(300) - }.width(400).height(400).margin({ top: 10 }).backgroundColor(Color.Pink) - - } - } - .width('100%') - .height('100%') - } - - aboutToAppear() { - - } - aboutToDisappear(){ - - } - - private choiceViewLifeCycle(type:DrawType): IDrawLifeCycle { - let viewLifeCycle:IDrawLifeCycle|undefined = 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) => { - - 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) => { - - return false; - }, - - // 展示主图 - displayMainSource: (context: CanvasRenderingContext2D, data: ImageKnifeData, imageKnifeOption: ImageKnifeOption, compWidth: number, compHeight: number, setGifTimeId?: (timeId: number) => void) => { - if (data.isPixelMap()) { - - 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 - -} - diff --git a/entry/src/main/ets/pages/testImageKnifeRouter1.ets b/entry/src/main/ets/pages/testImageKnifeRouter1.ets deleted file mode 100644 index aa27ca7..0000000 --- a/entry/src/main/ets/pages/testImageKnifeRouter1.ets +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (C) 2023 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import { ImageKnifeComponent } from '@ohos/libraryimageknife' -import router from '@ohos.router' - -@Entry -@Component -struct TestImageKnifeRouter { - @State array: Array = [ - "https://hbimg.huabanimg.com/cc6af25f8d782d3cf3122bef4e61571378271145735e9-vEVggB", - 'https://img-blog.csdnimg.cn/20191215043500229.png', - 'https://img-blog.csdn.net/20140514114029140', - 'https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp' - ] - - build() { - Column() { - Grid() { - ForEach(this.array, (item: string, index: number) => { - GridItem() { - ImageKnifeComponent({ - imageKnifeOption: { - loadSrc: item, - placeholderSrc: $r('app.media.icon_loading'), - errorholderSrc: $r('app.media.icon_failed'), - onClick: () => { - router.pushUrl({ url: "pages/testImageKnifeRouter2", params: { url: this.array[index] } }) - } - } - }).width(150).height(150) - .sharedTransition(this.array[index], { - duration: 500, - curve: Curve.Linear, - type: SharedTransitionEffectType.Exchange - }) - } - }) - }.columnsTemplate('1fr 1fr') - .rowsTemplate('1fr 1fr') - }.width("100%").height("100%") - } - - pageTransition() { - PageTransitionEnter({ duration: 0 }) - PageTransitionExit({ duration: 0 }) - } -} \ No newline at end of file diff --git a/entry/src/main/ets/pages/testImageKnifeRouter2.ets b/entry/src/main/ets/pages/testImageKnifeRouter2.ets deleted file mode 100644 index 1a9ab31..0000000 --- a/entry/src/main/ets/pages/testImageKnifeRouter2.ets +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (C) 2023 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import { ImageKnifeComponent } from '@ohos/libraryimageknife' -import router from '@ohos.router' - -interface ParamsType { - url: string -} - -@Entry -@Component -struct TestImageKnifeRouter { - @State url: string = "" - - aboutToAppear() { - this.url = (router.getParams() as ParamsType).url - } - - build() { - Column() { - ImageKnifeComponent({ - imageKnifeOption: { - loadSrc: this.url, - placeholderSrc: $r('app.media.icon_loading'), - errorholderSrc: $r('app.media.icon_failed'), - onClick: () => { - router.back() - } - } - }).width("100%").height(600) - .sharedTransition(this.url, { - duration: 500, - curve: Curve.Linear, - type: SharedTransitionEffectType.Exchange - }) - }.width("100%").height("100%") - } - - pageTransition() { - PageTransitionEnter({ duration: 0 }) - PageTransitionExit({ duration: 0 }) - } -} \ No newline at end of file diff --git a/entry/src/main/ets/pages/testManyGifLoadWithPage.ets b/entry/src/main/ets/pages/testManyGifLoadWithPage.ets deleted file mode 100644 index 11f9819..0000000 --- a/entry/src/main/ets/pages/testManyGifLoadWithPage.ets +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (C) 2023 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import { ImageKnife, ImageKnifeComponent, ImageKnifeGlobal, ImageKnifeOption } from "@ohos/libraryimageknife" -import worker from '@ohos.worker'; - -let gifUrl = "https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658" - -let data: string[] = [ - 'https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658', - 'https://hbimg.huabanimg.com/cc6af25f8d782d3cf3122bef4e61571378271145735e9-vEVggB', - 'https://pic.ibaotu.com/gif/18/17/16/51u888piCtqj.gif!fwpaa70/fw/700', - 'https://img-blog.csdnimg.cn/20191215043500229.png', - 'https://res.vmallres.com/cmscdn/CN/2023-03/7052a601ac3e428c84c9415ad9734735.gif', - 'https://img-blog.csdn.net/20140514114029140' -] - -@Entry -@Component -struct TestManyGifLoadWithPage { - - @State p1: PixelMap | undefined = undefined - @State p2: PixelMap | undefined = undefined - @State workerOption: ImageKnifeOption = { - loadSrc: $r('app.media.icon'), - placeholderSrc: $r('app.media.icon_loading'), - errorholderSrc: $r('app.media.icon_failed') - }; - - build() { - Column() { - Text('gif Demo').align(Alignment.Center).fontSize(25).margin(10).fontWeight(FontWeight.Bolder) - Row() { - Column() { - Button('use Origin Image').align(Alignment.Center).fontSize(10).margin(2) - Image(gifUrl).width('100%').height(100).backgroundColor(Color.Blue).objectFit(ImageFit.Contain) - }.width('50%').backgroundColor(Color.Orange) - - Column() { - Button('use ImageKnifeComponent').align(Alignment.Center).fontSize(10).margin(2) - ImageKnifeComponent({ imageKnifeOption: { loadSrc: gifUrl } }) - .width('100%') - .height(100) - .backgroundColor(Color.Orange) - }.width('50%').backgroundColor(Color.Blue) - } - - Grid() { - ForEach(data, (url: string) => { - GridItem(){ - ImageKnifeComponent({imageKnifeOption:{ - loadSrc:url - }}).backgroundColor(0x38393D).width(150).height(100) - } - }) - }.rowsGap(2) - .columnsGap(2) - }.width('100%').height('100%').backgroundColor(0xF1F3F5) - } - aboutToAppear(){ - - } - aboutToDisappear(){ - - } -} \ No newline at end of file diff --git a/entry/src/main/ets/pages/testManyNetImageLoadWithPage.ets b/entry/src/main/ets/pages/testManyNetImageLoadWithPage.ets deleted file mode 100644 index e90357a..0000000 --- a/entry/src/main/ets/pages/testManyNetImageLoadWithPage.ets +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright (C) 2023 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 { ScaleType, ImageKnifeComponent } from "@ohos/libraryimageknife" - -class CommonDataSource implements IDataSource { - private dataArray: T[] = [] - private listeners: DataChangeListener[] = [] - - constructor(element: []) { - this.dataArray = element - } - - public getData(index: number) { - return this.dataArray[index] - } - - public totalCount(): number { - return this.dataArray.length - } - - public addData(index: number, data: T[]): void { - this.dataArray = this.dataArray.concat(data) - this.notifyDataAdd(index) - } - - unregisterDataChangeListener(listener: DataChangeListener): void { - const pos = this.listeners.indexOf(listener); - if (pos >= 0) { - this.listeners.splice(pos, 1); - } - } - - registerDataChangeListener(listener: DataChangeListener): void { - if (this.listeners.indexOf(listener) < 0) { - this.listeners.push(listener) - } - } - - notifyDataAdd(index: number): void { - this.listeners.forEach((listener: DataChangeListener) => { - listener.onDataAdd(index) - }) - } -} - -@Entry -@Component -struct TestManyNetImageLoadWithPage { - @State hotCommendList:CommonDataSource = new CommonDataSource([]) - private data:Array = [ - "http://e.hiphotos.baidu.com/image/pic/item/a1ec08fa513d2697e542494057fbb2fb4316d81e.jpg", - "http://c.hiphotos.baidu.com/image/pic/item/30adcbef76094b36de8a2fe5a1cc7cd98d109d99.jpg", - "http://h.hiphotos.baidu.com/image/pic/item/7c1ed21b0ef41bd5f2c2a9e953da81cb39db3d1d.jpg", - "http://g.hiphotos.baidu.com/image/pic/item/55e736d12f2eb938d5277fd5d0628535e5dd6f4a.jpg", - "http://e.hiphotos.baidu.com/image/pic/item/4e4a20a4462309f7e41f5cfe760e0cf3d6cad6ee.jpg", - "http://b.hiphotos.baidu.com/image/pic/item/9d82d158ccbf6c81b94575cfb93eb13533fa40a2.jpg", - "http://e.hiphotos.baidu.com/image/pic/item/4bed2e738bd4b31c1badd5a685d6277f9e2ff81e.jpg", - "http://g.hiphotos.baidu.com/image/pic/item/0d338744ebf81a4c87a3add4d52a6059252da61e.jpg", - "http://a.hiphotos.baidu.com/image/pic/item/f2deb48f8c5494ee5080c8142ff5e0fe99257e19.jpg", - "http://f.hiphotos.baidu.com/image/pic/item/4034970a304e251f503521f5a586c9177e3e53f9.jpg", - "http://b.hiphotos.baidu.com/image/pic/item/279759ee3d6d55fbb3586c0168224f4a20a4dd7e.jpg", - "http://img2.xkhouse.com/bbs/hfhouse/data/attachment/forum/corebbs/2009-11/2009113011534566298.jpg", - "http://a.hiphotos.baidu.com/image/pic/item/e824b899a9014c087eb617650e7b02087af4f464.jpg", - "http://c.hiphotos.baidu.com/image/pic/item/9c16fdfaaf51f3de1e296fa390eef01f3b29795a.jpg", - "http://d.hiphotos.baidu.com/image/pic/item/b58f8c5494eef01f119945cbe2fe9925bc317d2a.jpg", - "http://h.hiphotos.baidu.com/image/pic/item/902397dda144ad340668b847d4a20cf430ad851e.jpg", - "http://b.hiphotos.baidu.com/image/pic/item/359b033b5bb5c9ea5c0e3c23d139b6003bf3b374.jpg", - "http://a.hiphotos.baidu.com/image/pic/item/8d5494eef01f3a292d2472199d25bc315d607c7c.jpg", - "http://b.hiphotos.baidu.com/image/pic/item/e824b899a9014c08878b2c4c0e7b02087af4f4a3.jpg", - "http://g.hiphotos.baidu.com/image/pic/item/6d81800a19d8bc3e770bd00d868ba61ea9d345f2.jpg", - ] - aboutToAppear() { - this.hotCommendList.addData(this.hotCommendList.totalCount(),this.data) - } - - build() { - Scroll() { - Column() { - Grid() { - LazyForEach(this.hotCommendList, (item: string) => { - GridItem() { - ImageKnifeComponent({ - imageKnifeOption: { - loadSrc: item, - placeholderSrc: $r('app.media.icon_loading'), - mainScaleType: ScaleType.CENTER_CROP, - placeholderScaleType: ScaleType.CENTER_CROP - } - }).width('100%').height('100%') - }.width('45%').height(200) - }, (item: string) => JSON.stringify(item)) - } - .columnsTemplate('1fr 1fr') - .columnsGap(8) - .rowsGap(10) - .width('100%') - .hitTestBehavior(HitTestMode.None) - .maxCount(10) - }.margin({ top: 5 }) - } - } -} \ No newline at end of file diff --git a/entry/src/main/ets/pages/testManyNetImageLoadWithPage2.ets b/entry/src/main/ets/pages/testManyNetImageLoadWithPage2.ets deleted file mode 100644 index ee0c3d0..0000000 --- a/entry/src/main/ets/pages/testManyNetImageLoadWithPage2.ets +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (C) 2023 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 { ScaleType, ImageKnifeComponent, NONE, DiskStrategy } from "@ohos/libraryimageknife" -import { Material } from './model/Material'; -import { TestDataSource } from './model/TestDataSource'; - - -@Entry -@Component -struct TestManyNetImageLoadWithPage2 { - private data: TestDataSource = new TestDataSource(); - private setting: DiskStrategy = new NONE(); - private scroller: Scroller = new Scroller() - - build() { - Scroll() { - Column() { - Grid(this.scroller) { - LazyForEach(this.data, (item: Material, index) => { - GridItem() { - Stack({ alignContent: Alignment.BottomEnd }) { - ImageKnifeComponent({ - imageKnifeOption: { - loadSrc: item.thumbnail, - placeholderSrc: $r('app.media.icon_loading'), - mainScaleType: ScaleType.CENTER_CROP, - placeholderScaleType: ScaleType.CENTER_CROP, - isCacheable: false, - strategy: this.setting - } - }).width('100%').height('100%') - Text(index + "." + item.name) - .fontSize(10) - .maxLines(1) - .fontColor(Color.White) - .textAlign(TextAlign.Center) - .layoutWeight(1) - .width('100%') - .backgroundColor(Color.Orange) - } - }.width('45%').height(200) - }, (item: Material) => item.material_id) - } - .columnsTemplate('1fr 1fr') - .columnsGap(8) - .rowsGap(10) - .width('100%') - .cachedCount(1) - .height('100%') - }.margin({ top: 5 }) - } - } -} \ No newline at end of file diff --git a/entry/src/main/ets/pages/testPreloadPage.ets b/entry/src/main/ets/pages/testPreloadPage.ets deleted file mode 100644 index acb3f61..0000000 --- a/entry/src/main/ets/pages/testPreloadPage.ets +++ /dev/null @@ -1,642 +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/libraryimageknife' -import {ImageKnifeData} from '@ohos/libraryimageknife' -import {ImageKnifeOption} from '@ohos/libraryimageknife' -import {RequestOption} from '@ohos/libraryimageknife' -import {ImageKnifeGlobal } from '@ohos/libraryimageknife' -import worker from '@ohos.worker' -import { BusinessError } from '@ohos.base' - -@Entry -@Component -struct TestPreloadPage { - svgUrl:string = '' - @State imageKnifeOption1: ImageKnifeOption = - { - loadSrc: $r('app.media.jpgSample'), - - placeholderSrc: $r('app.media.icon_loading'), - errorholderSrc: $r('app.media.icon_failed'), - - }; - @State imageKnifeOption: ImageKnifeOption = - { - loadSrc: $r('app.media.jpgSample'), - - placeholderSrc: $r('app.media.icon_loading'), - errorholderSrc: $r('app.media.icon_failed'), - - }; - @State imageKnifeOption3: ImageKnifeOption = - { - loadSrc: $r('app.media.jpgSample'), - - placeholderSrc: $r('app.media.icon_loading'), - errorholderSrc: $r('app.media.icon_failed'), - - }; - - @State imageKnifeOption4: ImageKnifeOption = - { - loadSrc: $r('app.media.jpgSample'), - - placeholderSrc: $r('app.media.icon_loading'), - errorholderSrc: $r('app.media.icon_failed'), - - }; - @State imageKnifeOption5: ImageKnifeOption = - { - loadSrc: $r('app.media.jpgSample'), - - placeholderSrc: $r('app.media.icon_loading'), - errorholderSrc: $r('app.media.icon_failed'), - - }; - @State imageKnifeOption6: ImageKnifeOption = - { - loadSrc: $r('app.media.jpgSample'), - - placeholderSrc: $r('app.media.icon_loading'), - errorholderSrc: $r('app.media.icon_failed'), - - }; - - build() { - Scroll() { - Column() { - Column() { - Flex({ direction: FlexDirection.Row }) { - Button('预加载本地资源gif') - .onClick(() => { - let request = new RequestOption(); - request.load($r('app.media.gifSample')) - .setImageViewSize({ width: 300, height: 300 }) - .addListener({callback:(err:BusinessError|string, data:ImageKnifeData) => { - if (err) { - console.log('预加载本地资源gif 出现错误! err=' + err) - } else { - console.log('预加载本地资源gif成功! imageKnifedata=' + JSON.stringify(data)) - } - return false; - }}) - ImageKnifeGlobal.getInstance().getImageKnife()?.preload(request); - }) - .margin({ left: 15 }) - .backgroundColor(Color.Grey) - - - Button('本地资源gif') - .onClick(() => { - this.imageKnifeOption1 = { - loadSrc: $r('app.media.gifSample'), - - placeholderSrc: $r('app.media.icon_loading'), - errorholderSrc: $r('app.media.icon_failed'), - - } - - }) - .margin({ left: 15 }) - .backgroundColor(Color.Grey) - - Button('预加载本地资源gif静态') - .onClick(() => { - let request = new RequestOption(); - request.load($r('app.media.gifSample')) - .setImageViewSize({ width: 300, height: 300 }) - .dontAnimate() - .addListener({callback:(err:BusinessError|string, data:ImageKnifeData) => { - if (err ) { - console.log('预加载本地资源gif静态 出现错误! err=' + err) - } else { - console.log('预加载本地资源gif静态成功! imageKnifedata=' + JSON.stringify(data)) - } - return false; - }}) - ImageKnifeGlobal.getInstance().getImageKnife()?.preload(request); - }) - .margin({ left: 15 }) - .backgroundColor(Color.Grey) - - Button('本地资源gif静态') - .onClick(() => { - this.imageKnifeOption1 = { - loadSrc: $r('app.media.gifSample'), - placeholderSrc: $r('app.media.icon_loading'), - errorholderSrc: $r('app.media.icon_failed'), - dontAnimateFlag: true - } - - }) - .margin({ left: 15 }) - .backgroundColor(Color.Grey) - } - .margin({ top: 15 }) - - Flex({ direction: FlexDirection.Row }) { - - Button('预加载网络资源gif') - .onClick(() => { - let request = new RequestOption(); - request.load('https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658') - .setImageViewSize({ width: 300, height: 300 }) - .addListener({callback:(err:BusinessError|string, data:ImageKnifeData) => { - if (err) { - console.log('预加载网络资源gif 出现错误! err=' + err) - } else { - console.log('预加载网络资源gif成功! imageKnifedata=' + JSON.stringify(data)) - } - return false; - }}) - ImageKnifeGlobal.getInstance().getImageKnife()?.preload(request); - }) - .margin({ left: 15 }) - .backgroundColor(Color.Grey) - - Button('网络资源gif') - .onClick(() => { - this.imageKnifeOption1 = { - loadSrc: 'https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658', - - placeholderSrc: $r('app.media.icon_loading'), - errorholderSrc: $r('app.media.icon_failed'), - - }; - }) - .margin({ left: 15 }) - .backgroundColor(Color.Grey) - - Button('预加载网络资源gif静态') - .onClick(() => { - let request = new RequestOption(); - request.load('https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658') - .setImageViewSize({ width: 300, height: 300 }) - .dontAnimate() - .addListener({callback:(err:BusinessError|string, data:ImageKnifeData) => { - if (err) { - console.log('预加载网络资源gif静态 出现错误! err=' + err) - } else { - console.log('预加载网络资源gif静态成功! imageKnifedata=' + JSON.stringify(data)) - } - return false; - }}) - ImageKnifeGlobal.getInstance().getImageKnife()?.preload(request); - }) - .margin({ left: 15 }) - .backgroundColor(Color.Grey) - - Button('网络资源gif静态') - .onClick(() => { - this.imageKnifeOption1 = { - loadSrc: 'https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658', - - placeholderSrc: $r('app.media.icon_loading'), - errorholderSrc: $r('app.media.icon_failed'), - dontAnimateFlag: true - }; - }) - .margin({ left: 15 }) - .backgroundColor(Color.Grey) - } - .margin({ top: 15 }) - - ImageKnifeComponent({ imageKnifeOption: this.imageKnifeOption1 }).width(200).height(200) - - } - - Column() { - Flex({ direction: FlexDirection.Row }) { - Button('预加载本地资源svg') - .onClick(() => { - let request = new RequestOption(); - request.load($r('app.media.svgSample')) - .setImageViewSize({ width: 300, height: 300 }) - .addListener({callback:(err:BusinessError|string, data:ImageKnifeData) => { - if (err ) { - console.log('预加载本地资源svg 出现错误! err=' + err) - } else { - console.log('预加载本地资源svg成功! imageKnifedata=' + JSON.stringify(data)) - } - return false; - }}) - ImageKnifeGlobal.getInstance().getImageKnife()?.preload(request); - }) - .margin({ left: 15 }) - .backgroundColor(Color.Grey) - - - Button('本地资源svg') - .onClick(() => { - this.imageKnifeOption = { - loadSrc: $r('app.media.svgSample'), - - placeholderSrc: $r('app.media.icon_loading'), - errorholderSrc: $r('app.media.icon_failed'), - - } - - }) - .margin({ left: 15 }) - .backgroundColor(Color.Grey) - - - } - .margin({ top: 15 }) - Text("请先设置SVG图片的url地址") - TextArea({ placeholder: '请输入SVG图片的url地址' }) - .placeholderColor("rgb(0,0,35)") - .placeholderFont({ size: 20, weight: 100, family: 'cursive', style: FontStyle.Italic }) - .textAlign(TextAlign.Center) - .caretColor(Color.Blue) - .height(40) - .width(400) - .fontSize(20) - .fontWeight(FontWeight.Bold) - .fontFamily("sans-serif") - .fontStyle(FontStyle.Normal) - .fontColor(Color.Red) - .onChange((value: string) => { - this.svgUrl = value - }) - Flex({ direction: FlexDirection.Row }) { - - Button('预加载网络资源svg') - .onClick(() => { - let request = new RequestOption(); - request.load(this.svgUrl) - .setImageViewSize({ width: 300, height: 300 }) - .addListener({callback:(err:BusinessError|string, data:ImageKnifeData) => { - if (err) { - console.log('预加载网络资源gif 出现错误! err=' + err) - } else { - console.log('预加载网络资源gif成功! imageKnifedata=' + JSON.stringify(data)) - } - return false; - }}) - ImageKnifeGlobal.getInstance().getImageKnife()?.preload(request); - }) - .margin({ left: 15 }) - .backgroundColor(Color.Grey) - - Button('网络资源svg') - .onClick(() => { - this.imageKnifeOption = { - loadSrc: this.svgUrl, - - placeholderSrc: $r('app.media.icon_loading'), - errorholderSrc: $r('app.media.icon_failed'), - - }; - }) - .margin({ left: 15 }) - .backgroundColor(Color.Grey) - - - } - .margin({ top: 15 }) - - ImageKnifeComponent({ imageKnifeOption: this.imageKnifeOption }).width(200).height(200) - - } - - Column() { - Flex({ direction: FlexDirection.Row }) { - Button('预加载本地资源webp') - .onClick(() => { - let request = new RequestOption(); - request.load($r('app.media.jpgSample')) - .setImageViewSize({ width: 300, height: 300 }) - .addListener({callback:(err:BusinessError|string, data:ImageKnifeData) => { - if (err) { - console.log('预加载本地资源webp 出现错误! err=' + err) - } else { - console.log('预加载本地资源webp成功! imageKnifedata=' + JSON.stringify(data)) - } - return false; - }}) - ImageKnifeGlobal.getInstance().getImageKnife()?.preload(request); - }) - .margin({ left: 15 }) - .backgroundColor(Color.Grey) - - - Button('本地资源webp') - .onClick(() => { - this.imageKnifeOption3 = { - loadSrc: $r('app.media.jpgSample'), - - placeholderSrc: $r('app.media.icon_loading'), - errorholderSrc: $r('app.media.icon_failed'), - - } - - }) - .margin({ left: 15 }) - .backgroundColor(Color.Grey) - - - } - .margin({ top: 15 }) - - Flex({ direction: FlexDirection.Row }) { - - Button('预加载网络资源webp') - .onClick(() => { - let request = new RequestOption(); - request.load('https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp') - .setImageViewSize({ width: 300, height: 300 }) - .addListener({callback:(err:BusinessError|string, data:ImageKnifeData) => { - if (err) { - console.log('预加载网络资源webp 出现错误! err=' + err) - } else { - console.log('预加载网络资源webp成功! imageKnifedata=' + JSON.stringify(data)) - } - return false; - }}) - ImageKnifeGlobal.getInstance().getImageKnife()?.preload(request); - }) - .margin({ left: 15 }) - .backgroundColor(Color.Grey) - - Button('网络资源webp') - .onClick(() => { - this.imageKnifeOption3 = { - loadSrc: 'https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp', - - placeholderSrc: $r('app.media.icon_loading'), - errorholderSrc: $r('app.media.icon_failed'), - - }; - }) - .margin({ left: 15 }) - .backgroundColor(Color.Grey) - } - .margin({ top: 15 }) - - ImageKnifeComponent({ imageKnifeOption: this.imageKnifeOption3 }).width(200).height(200) - - } - - Column() { - Flex({ direction: FlexDirection.Row }) { - Button('预加载本地资源bmp') - .onClick(() => { - let request = new RequestOption(); - request.load($r('app.media.bmpSample')) - .setImageViewSize({ width: 300, height: 300 }) - .addListener({callback:(err:BusinessError|string, data:ImageKnifeData) => { - if (err) { - console.log('预加载本地资源bmp 出现错误! err=' + err) - } else { - console.log('预加载本地资源bmp成功! imageKnifedata=' + JSON.stringify(data)) - } - return false; - }}) - ImageKnifeGlobal.getInstance().getImageKnife()?.preload(request); - }) - .margin({ left: 15 }) - .backgroundColor(Color.Grey) - - - Button('本地资源bmp') - .onClick(() => { - this.imageKnifeOption4 = { - loadSrc: $r('app.media.bmpSample'), - - placeholderSrc: $r('app.media.icon_loading'), - errorholderSrc: $r('app.media.icon_failed'), - - } - - }) - .margin({ left: 15 }) - .backgroundColor(Color.Grey) - - - } - .margin({ top: 15 }) - - Flex({ direction: FlexDirection.Row }) { - - Button('预加载网络资源bmp') - .onClick(() => { - let request = new RequestOption(); - request.load('https://img-blog.csdn.net/20140514114029140') - .setImageViewSize({ width: 300, height: 300 }) - .addListener({callback:(err:BusinessError|string, data:ImageKnifeData) => { - if (err) { - console.log('预加载网络资源bmp 出现错误! err=' + err) - } else { - console.log('预加载网络资源bmp成功! imageKnifedata=' + JSON.stringify(data)) - } - return false; - }}) - ImageKnifeGlobal.getInstance().getImageKnife()?.preload(request); - }) - .margin({ left: 15 }) - .backgroundColor(Color.Grey) - - Button('网络资源bmp') - .onClick(() => { - this.imageKnifeOption4 = { - loadSrc: 'https://img-blog.csdn.net/20140514114029140', - - placeholderSrc: $r('app.media.icon_loading'), - errorholderSrc: $r('app.media.icon_failed'), - - }; - }) - .margin({ left: 15 }) - .backgroundColor(Color.Grey) - } - .margin({ top: 15 }) - - ImageKnifeComponent({ imageKnifeOption: this.imageKnifeOption4 }).width(200).height(200) - - } - - Column() { - Flex({ direction: FlexDirection.Row }) { - Button('预加载本地资源png') - .onClick(() => { - let request = new RequestOption(); - request.load($r('app.media.pngSample')) - .setImageViewSize({ width: 300, height: 300 }) - .addListener({callback:(err:BusinessError|string, data:ImageKnifeData) => { - if (err) { - console.log('预加载本地资源png 出现错误! err=' + err) - } else { - console.log('预加载本地资源png成功! imageKnifedata=' + JSON.stringify(data)) - } - return false; - }}) - ImageKnifeGlobal.getInstance().getImageKnife()?.preload(request); - }) - .margin({ left: 15 }) - .backgroundColor(Color.Grey) - - - Button('本地资源png') - .onClick(() => { - this.imageKnifeOption5 = { - loadSrc: $r('app.media.pngSample'), - - placeholderSrc: $r('app.media.icon_loading'), - errorholderSrc: $r('app.media.icon_failed'), - - } - - }) - .margin({ left: 15 }) - .backgroundColor(Color.Grey) - - - } - .margin({ top: 15 }) - - Flex({ direction: FlexDirection.Row }) { - - Button('预加载网络资源png') - .onClick(() => { - let request = new RequestOption(); - request.load('https://img-blog.csdnimg.cn/20191215043500229.png') - .setImageViewSize({ width: 300, height: 300 }) - .addListener({callback:(err:BusinessError|string, data:ImageKnifeData) => { - if (err) { - console.log('预加载网络资源bmp 出现错误! err=' + err) - } else { - console.log('预加载网络资源bmp成功! imageKnifedata=' + JSON.stringify(data)) - } - return false; - }}) - ImageKnifeGlobal.getInstance().getImageKnife()?.preload(request); - }) - .margin({ left: 15 }) - .backgroundColor(Color.Grey) - - Button('网络资源png') - .onClick(() => { - this.imageKnifeOption5 = { - loadSrc: 'https://img-blog.csdnimg.cn/20191215043500229.png', - - placeholderSrc: $r('app.media.icon_loading'), - errorholderSrc: $r('app.media.icon_failed'), - - }; - }) - .margin({ left: 15 }) - .backgroundColor(Color.Grey) - } - .margin({ top: 15 }) - - ImageKnifeComponent({ imageKnifeOption: this.imageKnifeOption5 }).width(200).height(200) - - } - - Column() { - Flex({ direction: FlexDirection.Row }) { - Button('预加载本地资源jpg') - .onClick(() => { - let request = new RequestOption(); - request.load($r('app.media.jpgSample')) - .setImageViewSize({ width: 300, height: 300 }) - .addListener({callback:(err:BusinessError|string, data:ImageKnifeData) => { - if (err) { - console.log('预加载本地资源jpg 出现错误! err=' + err) - } else { - console.log('预加载本地资源jpg成功! imageKnifedata=' + JSON.stringify(data)) - } - return false; - }}) - ImageKnifeGlobal.getInstance().getImageKnife()?.preload(request); - }) - .margin({ left: 15 }) - .backgroundColor(Color.Grey) - - - Button('本地资源jpg') - .onClick(() => { - this.imageKnifeOption6 = { - loadSrc: $r('app.media.jpgSample'), - - placeholderSrc: $r('app.media.icon_loading'), - errorholderSrc: $r('app.media.icon_failed'), - - } - - }) - .margin({ left: 15 }) - .backgroundColor(Color.Grey) - - - } - .margin({ top: 15 }) - - Flex({ direction: FlexDirection.Row }) { - - Button('预加载网络资源jpg') - .onClick(() => { - let request = new RequestOption(); - request.load('https://hbimg.huabanimg.com/cc6af25f8d782d3cf3122bef4e61571378271145735e9-vEVggB') - .setImageViewSize({ width: 300, height: 300 }) - .addListener({callback:(err:BusinessError|string, data:ImageKnifeData) => { - if (err) { - console.log('预加载网络资源jpg 出现错误! err=' + err) - } else { - console.log('预加载网络资源jpg成功! imageknifedata=' + JSON.stringify(data)) - } - return false; - }}) - ImageKnifeGlobal.getInstance().getImageKnife()?.preload(request); - }) - .margin({ left: 15 }) - .backgroundColor(Color.Grey) - - Button('网络资源jpg') - .onClick(() => { - this.imageKnifeOption6 = { - loadSrc: 'https://hbimg.huabanimg.com/cc6af25f8d782d3cf3122bef4e61571378271145735e9-vEVggB', - - placeholderSrc: $r('app.media.icon_loading'), - errorholderSrc: $r('app.media.icon_failed'), - - }; - }) - .margin({ left: 15 }) - .backgroundColor(Color.Grey) - } - .margin({ top: 15 }) - - ImageKnifeComponent({ imageKnifeOption: this.imageKnifeOption6 }).width(200).height(200) - - } - } - - } - .width('100%') - .height('100%') - - } - - aboutToAppear() { - - } - aboutToDisappear(){ - - } -} - - diff --git a/entry/src/main/ets/pages/testPriorityComponent.ets b/entry/src/main/ets/pages/testPriorityComponent.ets deleted file mode 100644 index 5630f3c..0000000 --- a/entry/src/main/ets/pages/testPriorityComponent.ets +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (C) 2024 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import { ImageKnifeComponent , Priority , NONE } from '@ohos/libraryimageknife' - -@Entry -@Component -struct TestPriorityComponent { - private data: string[] = [ - "http://e.hiphotos.baidu.com/image/pic/item/a1ec08fa513d2697e542494057fbb2fb4316d81e.jpg", - "http://c.hiphotos.baidu.com/image/pic/item/30adcbef76094b36de8a2fe5a1cc7cd98d109d99.jpg", - "http://h.hiphotos.baidu.com/image/pic/item/7c1ed21b0ef41bd5f2c2a9e953da81cb39db3d1d.jpg", - "http://g.hiphotos.baidu.com/image/pic/item/55e736d12f2eb938d5277fd5d0628535e5dd6f4a.jpg", - "http://e.hiphotos.baidu.com/image/pic/item/4e4a20a4462309f7e41f5cfe760e0cf3d6cad6ee.jpg", - "http://b.hiphotos.baidu.com/image/pic/item/9d82d158ccbf6c81b94575cfb93eb13533fa40a2.jpg", - "http://e.hiphotos.baidu.com/image/pic/item/4bed2e738bd4b31c1badd5a685d6277f9e2ff81e.jpg", - "http://g.hiphotos.baidu.com/image/pic/item/0d338744ebf81a4c87a3add4d52a6059252da61e.jpg", - "http://a.hiphotos.baidu.com/image/pic/item/f2deb48f8c5494ee5080c8142ff5e0fe99257e19.jpg", - "http://f.hiphotos.baidu.com/image/pic/item/4034970a304e251f503521f5a586c9177e3e53f9.jpg", - "http://b.hiphotos.baidu.com/image/pic/item/279759ee3d6d55fbb3586c0168224f4a20a4dd7e.jpg", - "http://img2.xkhouse.com/bbs/hfhouse/data/attachment/forum/corebbs/2009-11/2009113011534566298.jpg", - "http://a.hiphotos.baidu.com/image/pic/item/e824b899a9014c087eb617650e7b02087af4f464.jpg", - "http://c.hiphotos.baidu.com/image/pic/item/9c16fdfaaf51f3de1e296fa390eef01f3b29795a.jpg", - "http://d.hiphotos.baidu.com/image/pic/item/b58f8c5494eef01f119945cbe2fe9925bc317d2a.jpg", - "http://h.hiphotos.baidu.com/image/pic/item/902397dda144ad340668b847d4a20cf430ad851e.jpg", - "http://b.hiphotos.baidu.com/image/pic/item/359b033b5bb5c9ea5c0e3c23d139b6003bf3b374.jpg", - "http://a.hiphotos.baidu.com/image/pic/item/8d5494eef01f3a292d2472199d25bc315d607c7c.jpg", - "http://b.hiphotos.baidu.com/image/pic/item/e824b899a9014c08878b2c4c0e7b02087af4f4a3.jpg", - "http://g.hiphotos.baidu.com/image/pic/item/6d81800a19d8bc3e770bd00d868ba61ea9d345f2.jpg", - "https://hbimg.huabanimg.com/cc6af25f8d782d3cf3122bef4e61571378271145735e9-vEVggB", - 'https://img-blog.csdnimg.cn/20191215043500229.png', - 'https://img-blog.csdn.net/20140514114029140', - 'https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp' - ] - - build(){ - Column(){ - Grid(){ - ForEach(this.data,(item:string,index:number)=>{ - GridItem(){ - if(index % 2 == 0){ - ImageKnifeComponent({ - imageKnifeOption:{ - loadSrc:item, - placeholderSrc:$r('app.media.icon_loading'), - strategy:new NONE(), - isCacheable:false, - priority:Priority.LOW - } - }) - } else if (index % 3 == 0) { - ImageKnifeComponent({ - imageKnifeOption:{ - loadSrc:item, - placeholderSrc:$r('app.media.icon_loading'), - strategy:new NONE(), - isCacheable:false, - priority:Priority.MEDIUM - } - }) - } else { - ImageKnifeComponent({ - imageKnifeOption:{ - loadSrc:item, - placeholderSrc:$r('app.media.icon_loading'), - strategy:new NONE(), - isCacheable:false, - priority:Priority.HIGH - } - }) - } - } - }) - } - .width("100%") - .height("100%") - .columnsTemplate("1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr") - .rowsTemplate("1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr") - .columnsGap(10) - .backgroundColor(0xFAEEE0) - }.width("100%").height("100%").backgroundColor(Color.Pink) - } -} \ No newline at end of file diff --git a/entry/src/main/ets/pages/testReusePhotoPage.ets b/entry/src/main/ets/pages/testReusePhotoPage.ets deleted file mode 100644 index 52abc1e..0000000 --- a/entry/src/main/ets/pages/testReusePhotoPage.ets +++ /dev/null @@ -1,203 +0,0 @@ -/* - * Copyright (C) 2024 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import { ImageKnifeComponent, ImageKnifeOption, ScaleType } from '@ohos/libraryimageknife' - -class CommonDataSource implements IDataSource { - private dataArray: T[] = [] - private listeners: DataChangeListener[] = [] - - constructor(element: []) { - this.dataArray = element - } - - public getData(index: number) { - return this.dataArray[index] - } - - public totalCount(): number { - return this.dataArray.length - } - - public addData(index: number, data: T[]): void { - this.dataArray = this.dataArray.concat(data) - this.notifyDataAdd(index) - } - - unregisterDataChangeListener(listener: DataChangeListener): void { - const pos = this.listeners.indexOf(listener); - if (pos >= 0) { - this.listeners.splice(pos, 1); - } - } - - registerDataChangeListener(listener: DataChangeListener): void { - if (this.listeners.indexOf(listener) < 0) { - this.listeners.push(listener) - } - } - - notifyDataAdd(index: number): void { - this.listeners.forEach((listener: DataChangeListener) => { - listener.onDataAdd(index) - }) - } -} - -@Entry -@Component -struct TestReusePhotoPage { - @State hotCommendList: CommonDataSource = new CommonDataSource([]) - private data: Array = [ - "http://e.hiphotos.baidu.com/image/pic/item/a1ec08fa513d2697e542494057fbb2fb4316d81e.jpg", - "http://c.hiphotos.baidu.com/image/pic/item/30adcbef76094b36de8a2fe5a1cc7cd98d109d99.jpg", - "http://h.hiphotos.baidu.com/image/pic/item/7c1ed21b0ef41bd5f2c2a9e953da81cb39db3d1d.jpg", - "http://g.hiphotos.baidu.com/image/pic/item/55e736d12f2eb938d5277fd5d0628535e5dd6f4a.jpg", - "http://e.hiphotos.baidu.com/image/pic/item/4e4a20a4462309f7e41f5cfe760e0cf3d6cad6ee.jpg", - "http://b.hiphotos.baidu.com/image/pic/item/9d82d158ccbf6c81b94575cfb93eb13533fa40a2.jpg", - "http://e.hiphotos.baidu.com/image/pic/item/4bed2e738bd4b31c1badd5a685d6277f9e2ff81e.jpg", - "http://g.hiphotos.baidu.com/image/pic/item/0d338744ebf81a4c87a3add4d52a6059252da61e.jpg", - "http://a.hiphotos.baidu.com/image/pic/item/f2deb48f8c5494ee5080c8142ff5e0fe99257e19.jpg", - "http://f.hiphotos.baidu.com/image/pic/item/4034970a304e251f503521f5a586c9177e3e53f9.jpg", - "http://b.hiphotos.baidu.com/image/pic/item/279759ee3d6d55fbb3586c0168224f4a20a4dd7e.jpg", - "http://img2.xkhouse.com/bbs/hfhouse/data/attachment/forum/corebbs/2009-11/2009113011534566298.jpg", - "http://a.hiphotos.baidu.com/image/pic/item/e824b899a9014c087eb617650e7b02087af4f464.jpg", - "http://c.hiphotos.baidu.com/image/pic/item/9c16fdfaaf51f3de1e296fa390eef01f3b29795a.jpg", - "http://d.hiphotos.baidu.com/image/pic/item/b58f8c5494eef01f119945cbe2fe9925bc317d2a.jpg", - "http://h.hiphotos.baidu.com/image/pic/item/902397dda144ad340668b847d4a20cf430ad851e.jpg", - "http://b.hiphotos.baidu.com/image/pic/item/359b033b5bb5c9ea5c0e3c23d139b6003bf3b374.jpg", - "http://a.hiphotos.baidu.com/image/pic/item/8d5494eef01f3a292d2472199d25bc315d607c7c.jpg", - "http://b.hiphotos.baidu.com/image/pic/item/e824b899a9014c08878b2c4c0e7b02087af4f4a3.jpg", - "http://g.hiphotos.baidu.com/image/pic/item/6d81800a19d8bc3e770bd00d868ba61ea9d345f2.jpg", - "https://hbimg.huabanimg.com/cc6af25f8d782d3cf3122bef4e61571378271145735e9-vEVggB", - 'https://img-blog.csdnimg.cn/20191215043500229.png', - 'https://img-blog.csdn.net/20140514114029140', - 'https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp' - ] - - aboutToAppear() { - this.hotCommendList.addData(this.hotCommendList.totalCount(), this.data) - AppStorage.set("image_size",1) - } - - build() { - Column() { - Button("up").onClick(()=>{ - AppStorage.set("image_size",1.6) - }) - Button("down").onClick(()=>{ - AppStorage.set("image_size",0.9) - }) - List() { - LazyForEach(this.hotCommendList, (item: string) => { - ListItem() { - ReuseComponent({ url: item }).width("100%").height("100%") - }.width(200).height(200).backgroundColor(Color.Orange) - }) - } - .width("100%") - .height("100%") - .backgroundColor(0xFAEEE0) - }.width("100%").height("100%") - } -} - -@Reusable -@Component -struct ReuseComponent { - @Prop url: string = "" - imgSize: number = 100 - @StorageProp("image_size") @Watch("updateImageSize") image_size: number = 0 - scaleAble: boolean = true - @State calcImgSize: number = 100 - aboutToReuse(params: Record) { - this.url = params.url - } - aboutToAppear(){ - this.setImageSize() - } - updateImageSize() { - this.setImageSize() - } - - setImageSize() { - if (!this.scaleAble) { - this.calcImgSize = this.imgSize - } else if (this.image_size < 0.9) { - this.calcImgSize = this.imgSize * 0.9 - } else if (this.image_size > 1.6) { - this.calcImgSize = this.imgSize * 1.6 - } else { - this.calcImgSize = this.imgSize * this.image_size - } - } - - build() { - Column() { - ImageKnifeComponent({ - imageKnifeOption:{ - loadSrc: this.url, - mainScaleType: ScaleType.FIT_XY, - placeholderSrc: $r('app.media.icon_loading'), - placeholderScaleType: ScaleType.FIT_XY, - errorholderSrc: $r('app.media.icon_failed'), - errorholderSrcScaleType: ScaleType.FIT_XY - } - }).width(this.calcImgSize).height(this.calcImgSize) - }.width("100%").height("100%") - } -} - -@Component -struct PhotoComponent { - @Watch("updateTheUrl") @Prop url: string = "" - imgSize: number = 100 - @State imageKnifeOption: ImageKnifeOption = new ImageKnifeOption() - @StorageProp("image_size") @Watch("updateImageSize") image_size: number = 0 - scaleAble: boolean = true - @State calcImgSize: number = 100 - - updateImageSize() { - this.setImageSize() - } - - setImageSize() { - if (!this.scaleAble) { - this.calcImgSize = this.imgSize - } else if (this.image_size < 0.9) { - this.calcImgSize = this.imgSize * 0.9 - } else if (this.image_size > 1.6) { - this.calcImgSize = this.imgSize * 1.6 - } else { - this.calcImgSize = this.imgSize * this.image_size - } - } - - updateTheUrl() { - this.imageKnifeOption = { - loadSrc: this.url, - mainScaleType: ScaleType.FIT_XY, - placeholderSrc: $r('app.media.icon_loading'), - placeholderScaleType: ScaleType.FIT_XY, - errorholderSrc: $r('app.media.icon_failed'), - errorholderSrcScaleType: ScaleType.FIT_XY - } - } - - build() { - Column() { - ImageKnifeComponent({ imageKnifeOption: this.imageKnifeOption }) - }.width(this.calcImgSize).height(this.calcImgSize) - } -} \ No newline at end of file diff --git a/entry/src/main/ets/pages/testSingleFrameGifPage.ets b/entry/src/main/ets/pages/testSingleFrameGifPage.ets deleted file mode 100644 index 7e7a8f7..0000000 --- a/entry/src/main/ets/pages/testSingleFrameGifPage.ets +++ /dev/null @@ -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/libraryimageknife' -import { ImageKnifeOption } from '@ohos/libraryimageknife' - -@Entry -@Component -struct TestSingleFrameGifPage { - @State message: string = '单帧gif测试' - @State options: ImageKnifeOption = { - loadSrc: $r('app.media.app_icon') - } - - build() { - Column() { - Column() { - Text(`${this.message}`) - .width("300vp") - .height("60vp") - .textAlign(TextAlign.Center) - .fontSize("50fp") - .fontWeight(FontWeight.Bold) - Button("加载单帧gif") - .margin(16) - .onClick(() => { - console.log("加载单帧gif") - this.options = { - loadSrc: $r('app.media.gifSample_single_frame'), - placeholderSrc:$r('app.media.icon_loading') - } - }) - Button("加载多帧gif") - .margin(16) - .onClick(() => { - console.log("加载多帧gif") - this.options = { - loadSrc: $r('app.media.gifSample'), - placeholderSrc:$r('app.media.icon_loading') - } - }) - ImageKnifeComponent({ imageKnifeOption: this.options }) - .margin(16) - .width(200) - .height(200) - } - .width("100%") - .height("100%") - .justifyContent(FlexAlign.Center) - } - .width("100%") - .height("100%") - } -} \ No newline at end of file diff --git a/entry/src/main/ets/pages/transformPixelMapPage.ets b/entry/src/main/ets/pages/transformPixelMapPage.ets deleted file mode 100644 index 152ea0e..0000000 --- a/entry/src/main/ets/pages/transformPixelMapPage.ets +++ /dev/null @@ -1,995 +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,ImageKnifeGlobal} from '@ohos/libraryimageknife' -import { CropCircleTransformation } from '@ohos/libraryimageknife' -import { RoundedCornersTransformation } from '@ohos/libraryimageknife' -import { - rgbColor,CropCircleWithBorderTransformation -} from '@ohos/libraryimageknife' -import { RotateImageTransformation } from '@ohos/libraryimageknife' -import { CropSquareTransformation } from '@ohos/libraryimageknife' -import { CropTransformation } from '@ohos/libraryimageknife' -import { CropType } from '@ohos/libraryimageknife' -import { GrayscaleTransformation } from '@ohos/libraryimageknife' -import { BrightnessFilterTransformation } from '@ohos/libraryimageknife' -import { ContrastFilterTransformation } from '@ohos/libraryimageknife' -import { InvertFilterTransformation } from '@ohos/libraryimageknife' -import { SepiaFilterTransformation } from '@ohos/libraryimageknife' -import { SketchFilterTransformation } from '@ohos/libraryimageknife' -import { BlurTransformation } from '@ohos/libraryimageknife' -import { PixelationFilterTransformation } from '@ohos/libraryimageknife' -import { MaskTransformation } from '@ohos/libraryimageknife' -import { SwirlFilterTransformation } from '@ohos/libraryimageknife' -import { BusinessError } from '@ohos.base' -import {ImageKnifeData} from '@ohos/libraryimageknife' -/** - * PixelMap transform 示例 - */ -let mRotate: number = 0; -//let mUrl = "https://hbimg.huabanimg.com/cc6af25f8d782d3cf3122bef4e61571378271145735e9-vEVggB" -let mUrl = $r('app.media.pngSample'); - -@Entry -@Component -struct TransformPixelMapPage { - @State url: string = ""; - @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; - @State mKuwaharaPixelMap?: PixelMap = undefined; - @State mToonPixelMap?: PixelMap = undefined; - @State mVignettePixelMap?: PixelMap = undefined; - - build() { - Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center }) { - Scroll() { - Column() { - Column() { - Text("基础变换").fontColor(Color.Gray).fontSize(16); - Row({ space: 1 }) { - Button() { - Text("CenterCrop").fontSize(13).fontColor(Color.White) - } - .height(35) - .width(100) - .onClick(() => { - this.centerCrop(); - }); - Button() { - Text("CenterInside").fontSize(13).fontColor(Color.White) - } - .height(35) - .width(100) - .onClick(() => { - this.centerInside(); - }); - Button() { - Text("fitCenter").fontSize(13).fontColor(Color.White) - } - .height(35) - .width(100) - .onClick(() => { - this.fitCenter(); - }); - }.margin({ top: 10 }) - - Image(this.mCropPixelMap == undefined ? '':this.mCropPixelMap!) - .objectFit(ImageFit.None) - .width(100) - .height(100) - .backgroundColor("#23d1de") - .margin({ top: 10 }) - - }.margin({ top: 10 }); - - Column() { - Text("RoundedCornersTransformation").fontColor(Color.Gray).fontSize(16); - Row({ space: 1 }) { - Button() { - Text($r("app.string.left_top_corner")).fontSize(13).fontColor(Color.White) - } - .height(35) - .width(72) - .onClick(() => { - this.roundedCornersTransformation(10, 0, 0, 0); - }); - Button() { - Text($r("app.string.r_top_corner")).fontSize(13).fontColor(Color.White) - } - .height(35) - .width(72) - .onClick(() => { - this.roundedCornersTransformation(0, 0, 10, 0); - }); - Button() { - Text($r("app.string.left_bottom_corner")).fontSize(13).fontColor(Color.White) - } - .height(35) - .width(72) - .onClick(() => { - this.roundedCornersTransformation(0, 10, 0, 0); - }); - Button() { - Text($r("app.string.r_bottom_corner")).fontSize(13).fontColor(Color.White) - } - .height(35) - .width(72) - .onClick(() => { - this.roundedCornersTransformation(0, 0, 0, 10); - }); - Button("All") - .fontSize(13) - .height(35) - .width(72) - .onClick(() => { - this.roundedCornersTransformation(10, 10, 10, 10); - }); - }.margin({ top: 10 }) - - Image(this.mRoundPixelMap == undefined ? '': this.mRoundPixelMap!) - .objectFit(ImageFit.Fill) - .width(100) - .height(100) - .margin({ top: 10 }) - - }.margin({ top: 10 }); - - Column() { - Text("CropCircleTransformation").fontColor(Color.Gray).fontSize(16); - Button() { - Text($r("app.string.trans_circle")).fontSize(13).fontColor(Color.White) - } - .height(35) - .width(120) - .margin({ top: 10 }) - .onClick(() => { - this.circleTransformation(); - }); - Image(this.mCirclePixelMap == undefined ? '':this.mCirclePixelMap!) - .width(200) - .height(200) - .margin({ top: 10 }) - - }.margin({ top: 10 }); - - Column() { - Text("CropCircleWithBorderTransformation").fontColor(Color.Gray).fontSize(16); - Button() { - Text($r("app.string.trans_circle_border")).fontSize(13).fontColor(Color.White) - } - .height(35) - .width(120) - .margin({ top: 10 }) - .onClick(() => { - this.circleBorderTransformation(5); - }); - Image(this.mCircleBorderPixelMap == undefined ? '':this.mCircleBorderPixelMap!) - .width(200) - .height(200) - .margin({ top: 10 }) - - }.margin({ top: 10 }); - - Column() { - Text("RotateImageTransformation").fontColor(Color.Gray).fontSize(16); - Button() { - Text($r("app.string.trans_rotate")).fontSize(13).fontColor(Color.White) - } - .height(35) - .width(120) - .margin({ top: 10 }) - .onClick(() => { - mRotate += 45; - if (mRotate > 360) { - mRotate = 0; - } - this.transformRotate(mRotate); - }); - Image(this.mRotatePixelMap == undefined ? '':this.mRotatePixelMap!) - .width(200) - .height(200) - .margin({ top: 10 }) - - }.margin({ top: 10 }); - - Column() { - Text("CropSquareTransformation").fontColor(Color.Gray).fontSize(16); - Button() { - Text($r("app.string.trans_square")).fontSize(13).fontColor(Color.White) - } - .height(35) - .width(120) - .margin({ top: 10 }) - .onClick(() => { - this.transformSquare(); - }); - Image(this.mSquarePixelMap == undefined ? '' : this.mSquarePixelMap!) - .objectFit(ImageFit.Fill) - .width(200) - .height(200) - .margin({ top: 10 }) - - }.margin({ top: 10 }); - - Column() { - Text("CropTransformation").fontColor(Color.Gray).fontSize(16); - Row({ space: 1 }) { - Button() { - Text($r("app.string.trans_clip_top")).fontSize(13).fontColor(Color.White) - } - .height(35) - .width(72) - .onClick(() => { - this.clipPixelMap(25, 25, CropType.TOP); - }); - Button() { - Text($r("app.string.trans_clip_center")).fontSize(13).fontColor(Color.White) - } - .height(35) - .width(72) - .onClick(() => { - this.clipPixelMap(25, 25, CropType.CENTER); - }); - Button() { - Text($r("app.string.trans_clip_bottom")).fontSize(13).fontColor(Color.White) - } - .height(35) - .width(72) - .onClick(() => { - this.clipPixelMap(25, 25, CropType.BOTTOM); - }); - }.margin({ top: 10 }) - - Row({ space: 1 }) { - Image(this.mClipTopPixelMap == undefined ? '':this.mClipTopPixelMap!) - .objectFit(ImageFit.Fill) - .width(100) - .height(100) - .margin({ top: 10 }) - Image(this.mClipCenterPixelMap == undefined ? '':this.mClipCenterPixelMap!) - .objectFit(ImageFit.Fill) - .width(100) - .height(100) - .margin({ top: 10 }) - Image(this.mClipBottomPixelMap == undefined ? '':this.mClipBottomPixelMap!) - .objectFit(ImageFit.Fill) - .width(100) - .height(100) - .margin({ top: 10 }) - } - }.margin({ top: 10 }); - - Column() { - Text("GrayscaleTransformation").fontColor(Color.Gray).fontSize(16); - Button() { - Text($r("app.string.image_grayscale")).fontSize(13).fontColor(Color.White) - } - .height(35) - .width(120) - .margin({ top: 10 }) - .onClick(() => { - this.grayscalePixelMap(); - }); - Image(this.mGrayscalePixelMap == undefined ? '': this.mGrayscalePixelMap!) - .objectFit(ImageFit.Fill) - .width(200) - .height(200) - .margin({ top: 10 }) - - }.margin({ top: 10 }); - Column() { - Text("BrightnessFilterTransformation").fontColor(Color.Gray).fontSize(16); - Button() { - Text($r("app.string.image_Brightness")).fontSize(13).fontColor(Color.White) - } - .height(35) - .width(120) - .margin({ top: 10 }) - .onClick(() => { - this.brightnessPixelMap(0.8); - }); - Image(this.mBrightnessPixelMap == undefined?'':this.mBrightnessPixelMap!) - .objectFit(ImageFit.Fill) - .width(200) - .height(200) - .margin({ top: 10 }) - - }.margin({ top: 10 }); - Column() { - Text("ContrastFilterTransformation").fontColor(Color.Gray).fontSize(16); - Button() { - Text($r("app.string.image_Contrast")).fontSize(13).fontColor(Color.White) - } - .height(35) - .width(120) - .margin({ top: 10 }) - .onClick(() => { - this.contrastPixelMap(4); - }); - Image(this.mContrastPixelMap == undefined?'':this.mContrastPixelMap!) - .objectFit(ImageFit.Fill) - .width(200) - .height(200) - .margin({ top: 10 }) - - }.margin({ top: 10 }); - Column() { - Text("InvertFilterTransformation").fontColor(Color.Gray).fontSize(16); - Button() { - Text($r("app.string.image_Invert")).fontSize(13).fontColor(Color.White) - } - .height(35) - .width(120) - .margin({ top: 10 }) - .onClick(() => { - this.invertPixelMap(); - }); - Image(this.mInvertPixelMap == undefined ? '':this.mInvertPixelMap!) - .objectFit(ImageFit.Fill) - .width(200) - .height(200) - .margin({ top: 10 }) - - }.margin({ top: 10 }); - - Column() { - Text("SepiaFilterTransformation").fontColor(Color.Gray).fontSize(16); - Button() { - Text($r("app.string.image_Sepia")).fontSize(13).fontColor(Color.White) - } - .height(35) - .width(120) - .margin({ top: 10 }) - .onClick(() => { - this.sepiaPixelMap(); - }); - Image(this.mSepiaPixelMap == undefined ? '':this.mSepiaPixelMap!) - .objectFit(ImageFit.Fill) - .width(200) - .height(200) - .margin({ top: 10 }) - - }.margin({ top: 10 }); - Column() { - Text("SketchFilterTransformation").fontColor(Color.Gray).fontSize(16); - Button() { - Text($r("app.string.image_Sketch")).fontSize(13).fontColor(Color.White) - } - .height(35) - .width(120) - .margin({ top: 10 }) - .onClick(() => { - this.sketchPixelMap(); - }); - Image(this.mSketchPixelMap == undefined ? '':this.mSketchPixelMap!) - .objectFit(ImageFit.Fill) - .width(200) - .height(200) - .margin({ top: 10 }) - - }.margin({ top: 10 }); - - Column() { - Text("BlurTransformation").fontColor(Color.Gray).fontSize(16); - Button() { - Text($r("app.string.image_blur")).fontSize(13).fontColor(Color.White) - } - .height(35) - .width(120) - .margin({ top: 10 }) - .onClick(() => { - this.blurHandlePixelMap(20,3); - }); - Image(this.mBlurPixelMap==undefined?'':this.mBlurPixelMap!) - .objectFit(ImageFit.Fill) - .width(200) - .height(200) - .margin({ top: 10 }) - - }.margin({ top: 10 }); - - - Column() { - Text("PixelationFilterTransformation").fontColor(Color.Gray).fontSize(16); - Button() { - Text($r("app.string.image_pixel")).fontSize(13).fontColor(Color.White) - } - .height(35) - .width(120) - .margin({ top: 10 }) - .onClick(() => { - this.pixelHandlePixelMap(20); - }); - Image(this.mPixelPixelMap == undefined ? '':this.mPixelPixelMap!) - .objectFit(ImageFit.Fill) - .width(200) - .height(200) - .margin({ top: 10 }) - - }.margin({ top: 10 }); - - Column() { - Text("SwirlFilterTransformation").fontColor(Color.Gray).fontSize(16); - Button() { - Text("图片Swirl").fontSize(13).fontColor(Color.White) - } - .height(35) - .width(120) - .margin({ top: 10 }) - .onClick(() => { - this.swirlHandlePixelMap(); - }); - Image(this.mSwirlPixelMap == undefined ? '':this.mSwirlPixelMap!) - .objectFit(ImageFit.Fill) - .width(200) - .height(200) - .margin({ top: 10 }) - - }.margin({ top: 10 }); - - Column() { - Text("MaskTransformation").fontColor(Color.Gray).fontSize(16); - Button() { - Text("图片mask").fontSize(13).fontColor(Color.White) - } - .height(35) - .width(120) - .margin({ top: 10 }) - .onClick(() => { - this.maskHandlePixelMap($r('app.media.mask_starfish')); - }); - Image(this.mMaskPixelMap == undefined ? '':this.mMaskPixelMap!) - .objectFit(ImageFit.Fill) - .width(200) - .height(200) - .margin({ top: 10 }) - - }.margin({ top: 10 }); - - Column() { - Text("KuwaharaFilterTransform").fontColor(Color.Gray).fontSize(16); - Button() { - Text("图片kuwahara").fontSize(13).fontColor(Color.White) - } - .height(35) - .width(120) - .margin({ top: 10 }) - .onClick(() => { - this.kuwaharaHandlePixelMap(); - }); - Image(this.mKuwaharaPixelMap == undefined? '':this.mKuwaharaPixelMap!) - .objectFit(ImageFit.Fill) - .width(200) - .height(200) - .margin({ top: 10 }) - - }.margin({ top: 10 }); - - Column() { - Text("ToonFilterTransform").fontColor(Color.Gray).fontSize(16); - Button() { - Text("图片toon").fontSize(13).fontColor(Color.White) - } - .height(35) - .width(120) - .margin({ top: 10 }) - .onClick(() => { - this.toonHandlePixelMap(); - }); - Image(this.mToonPixelMap == undefined?'':this.mToonPixelMap!) - .objectFit(ImageFit.Fill) - .width(200) - .height(200) - .margin({ top: 10 }) - - }.margin({ top: 10 }); - - Column() { - Text("VignetteFilterTransform").fontColor(Color.Gray).fontSize(16); - Button() { - Text("图片vignette").fontSize(13).fontColor(Color.White) - } - .height(35) - .width(120) - .margin({ top: 10 }) - .onClick(() => { - this.vignetteHandlePixelMap(); - }); - Image(this.mVignettePixelMap == undefined ? '':this.mVignettePixelMap) - .objectFit(ImageFit.Fill) - .width(200) - .height(200) - .margin({ top: 10 }) - - }.margin({ top: 10 }); - - }.margin({ bottom: 30 }); - - } - }.width('100%').height('100%'); - } - - aboutToAppear() { - - } - - /** - * centerCrop - */ - centerCrop() { - let imageKnifeOption = new RequestOption(); - imageKnifeOption.load($r('app.media.jpgSample')) - // imageKnifeOption.load(mUrl) - .addListener({callback:(err:BusinessError|string, data:ImageKnifeData) => { - this.mCropPixelMap = data.drawPixelMap?.imagePixelMap as PixelMap; - return false; - }}) - .setImageViewSize({ width: vp2px(100), height: vp2px(100) }) - .skipMemoryCache(true) - .centerCrop(); - ImageKnife?.call(imageKnifeOption); - } - - /** - * centerInside - */ - centerInside() { - let imageKnifeOption = new RequestOption(); - imageKnifeOption.load($r('app.media.Back')) - .addListener({callback:(err:BusinessError|string, data:ImageKnifeData) => { - this.mCropPixelMap = data.drawPixelMap?.imagePixelMap as PixelMap; - return false; - }}) - .setImageViewSize({ width: vp2px(100), height: vp2px(100) }) - .skipMemoryCache(true) - .centerInside(); - ImageKnife?.call(imageKnifeOption); - } - - /** - * centerInside - */ - fitCenter() { - let imageKnifeOption = new RequestOption() - imageKnifeOption.load($r('app.media.Back')) - .addListener({callback:(err:BusinessError|string, data:ImageKnifeData) => { - this.mCropPixelMap = data.drawPixelMap?.imagePixelMap as PixelMap; - return false; - }}) - .setImageViewSize({ width: vp2px(100), height: vp2px(100) }) - .skipMemoryCache(true) - .fitCenter(); - ImageKnife?.call(imageKnifeOption); - } - /** - * 圆角设置 - */ - roundedCornersTransformation(top_left: number, - bottom_left: number, top_right: number, bottom_right: number) { - - let imageKnifeOption = new RequestOption(); - imageKnifeOption.load(mUrl) - .addListener({callback:(err:BusinessError|string, data:ImageKnifeData) => { - this.mRoundPixelMap = data.drawPixelMap?.imagePixelMap as PixelMap; - return false; - }}) - .setImageViewSize({ width: vp2px(100), height: vp2px(100) }) - .skipMemoryCache(true) - .roundedCorners({ - top_left: top_left, - top_right: top_right, - bottom_left: bottom_left, - bottom_right: bottom_right - }) - ImageKnife?.call(imageKnifeOption); - } - - /** - * 裁剪圆 - */ - circleTransformation() { - let imageKnifeOption = new RequestOption(); - imageKnifeOption.load(mUrl) - .addListener({callback:(err:BusinessError|string, data:ImageKnifeData) => { - - this.mCirclePixelMap = data.drawPixelMap?.imagePixelMap as PixelMap; - - return false; - }}) - .setImageViewSize({ width: vp2px(200), height: vp2px(200) }) - .skipMemoryCache(true) - .cropCircle() - ImageKnife?.call(imageKnifeOption); - } - - /** - * 圆环裁剪 - */ - circleBorderTransformation(border: number) { - let imageKnifeOption = new RequestOption(); - let color:rgbColor = { r_color: 255, g_color: 204, b_color: 204 } - let circleTransformation = new CropCircleWithBorderTransformation(border, - color); - imageKnifeOption.load(mUrl) - .addListener({callback:(err:BusinessError|string, data:ImageKnifeData) => { - - this.mCircleBorderPixelMap = data.drawPixelMap?.imagePixelMap as PixelMap; - - return false; - }}) - .setImageViewSize({ width: vp2px(200), height: vp2px(200) }) - .skipMemoryCache(true) - .cropCircleWithBorder(border, - { r_color: 255, g_color: 204, b_color: 204 }) - ImageKnife?.call(imageKnifeOption); - } - - /** - * 旋转 - */ - transformRotate(angled: number) { - let imageKnifeOption = new RequestOption(); - let transformation = new RotateImageTransformation(angled); - imageKnifeOption.load(mUrl) - .addListener({callback:(err:BusinessError|string, data:ImageKnifeData) => { - - this.mRotatePixelMap = data.drawPixelMap?.imagePixelMap as PixelMap; - - return false; - }}) - .setImageViewSize({ width: vp2px(200), height: vp2px(200) }) - .skipMemoryCache(true) - .rotateImage(angled) - ImageKnife?.call(imageKnifeOption); - } - - /** - * 正方形裁剪 - */ - transformSquare() { - let imageKnifeOption = new RequestOption(); - let transformation = new CropSquareTransformation(); - imageKnifeOption.load(mUrl) - .addListener({callback:(err:BusinessError|string, data:ImageKnifeData) => { - - this.mSquarePixelMap = data.drawPixelMap?.imagePixelMap as PixelMap; - - return false; - }}) - .setImageViewSize({ width: vp2px(200), height: vp2px(200) }) - .skipMemoryCache(true) - .cropSquare() - ImageKnife?.call(imageKnifeOption); - } - - /** - * 区域裁剪 - */ - clipPixelMap(width: number, height: number, cropType: CropType) { - let imageKnifeOption = new RequestOption(); - let transformation = new CropTransformation(width, height, cropType); - imageKnifeOption.load(mUrl) - .addListener({callback:(err:BusinessError|string, data:ImageKnifeData) => { - let result:PixelMap|undefined = undefined; - if (cropType == CropType.TOP) { - result = data.drawPixelMap?.imagePixelMap as PixelMap; - this.mClipTopPixelMap = result; - } else if (cropType == CropType.CENTER) { - result = data.drawPixelMap?.imagePixelMap as PixelMap; - this.mClipCenterPixelMap = result; - } else if (cropType == CropType.BOTTOM) { - result = data.drawPixelMap?.imagePixelMap as PixelMap; - this.mClipBottomPixelMap = result; - } - return false; - }}) - .setImageViewSize({ width: width, height: height }) - .skipMemoryCache(true) - .crop(width, height, cropType) - ImageKnife?.call(imageKnifeOption); - - } - - /** - * 灰度 - */ - grayscalePixelMap() { - let imageKnifeOption = new RequestOption(); - let transformation = new GrayscaleTransformation(); - imageKnifeOption.load(mUrl) - .addListener({callback:(err:BusinessError|string, data:ImageKnifeData) => { - - this.mGrayscalePixelMap = data.drawPixelMap?.imagePixelMap as PixelMap; - - return false; - }}) - .setImageViewSize({ width: vp2px(200), height: vp2px(200) }) - .skipMemoryCache(true) - .enableGPU() - .grayscale() - ImageKnife?.call(imageKnifeOption); - - } - - /** - *亮度b - */ - brightnessPixelMap(brightness: number) { - let imageKnifeOption = new RequestOption(); - let transformation = new BrightnessFilterTransformation(brightness); - imageKnifeOption.load(mUrl) - .addListener({callback:(err:BusinessError|string, data:ImageKnifeData) => { - - this.mBrightnessPixelMap = data.drawPixelMap?.imagePixelMap as PixelMap; - - return false; - }}) - .setImageViewSize({ width: vp2px(200), height: vp2px(200) }) - .skipMemoryCache(true) - .enableGPU() - .brightnessFilter(brightness) - ImageKnife?.call(imageKnifeOption); - - } - - /** - *对比度 - */ - contrastPixelMap(contrast: number) { - let imageKnifeOption = new RequestOption(); - let transformation = new ContrastFilterTransformation(contrast); - imageKnifeOption.load(mUrl) - .addListener({callback:(err:BusinessError|string, data:ImageKnifeData) => { - - this.mContrastPixelMap = data.drawPixelMap?.imagePixelMap as PixelMap; - - return false; - }}) - .setImageViewSize({ width: vp2px(200), height: vp2px(200) }) - .skipMemoryCache(true) - .enableGPU() - .contrastFilter(contrast) - ImageKnife?.call(imageKnifeOption); - - } - - /** - *反转处理 - */ - invertPixelMap() { - let imageKnifeOption = new RequestOption(); - let transformation = new InvertFilterTransformation(); - imageKnifeOption.load(mUrl) - .addListener({callback:(err:BusinessError|string, data:ImageKnifeData) => { - - this.mInvertPixelMap = data.drawPixelMap?.imagePixelMap as PixelMap; - - return false; - }}) - .setImageViewSize({ width: vp2px(200), height: vp2px(200) }) - .skipMemoryCache(true) - .enableGPU() - .invertFilter() - ImageKnife?.call(imageKnifeOption); - - } - - /** - *照片老旧出来(黑褐色) - */ - sepiaPixelMap() { - let imageKnifeOption = new RequestOption(); - let transformation = new SepiaFilterTransformation(); - imageKnifeOption.load(mUrl) - .addListener({callback:(err:BusinessError|string, data:ImageKnifeData) => { - - this.mSepiaPixelMap = data.drawPixelMap?.imagePixelMap as PixelMap; - - return false; - }}) - .setImageViewSize({ width: vp2px(200), height: vp2px(200) }) - .skipMemoryCache(true) - .enableGPU() - .sepiaFilter() - ImageKnife?.call(imageKnifeOption); - - } - - /** - *素描 - */ - sketchPixelMap() { - let imageKnifeOption = new RequestOption(); - let transformation = new SketchFilterTransformation(); - imageKnifeOption.load(mUrl) - .addListener({callback:(err:BusinessError|string, data:ImageKnifeData) => { - - this.mSketchPixelMap = data.drawPixelMap?.imagePixelMap as PixelMap; - - return false; - }}) - .setImageViewSize({ width: vp2px(200), height: vp2px(200) }) - .skipMemoryCache(true) - .enableGPU() - .sketchFilter() - ImageKnife?.call(imageKnifeOption); - - } - - /** - *模糊 - */ - blurHandlePixelMap(radius: number,sampling: number) { - let imageKnifeOption = new RequestOption(); - let transformation = new BlurTransformation(radius,sampling); - imageKnifeOption.load(mUrl) - .addListener({callback:(err:BusinessError|string, data:ImageKnifeData) => { - - this.mBlurPixelMap = data.drawPixelMap?.imagePixelMap as PixelMap; - - return false; - }}) - .setImageViewSize({ width: vp2px(200), height: vp2px(200) }) - .skipMemoryCache(true) - .enableGPU() - .blur(radius,sampling) - ImageKnife?.call(imageKnifeOption); - - } - /** - *马赛克 - */ - pixelHandlePixelMap(pixel: number) { - let imageKnifeOption = new RequestOption(); - let transformation = new PixelationFilterTransformation(pixel); - imageKnifeOption.load(mUrl) - .addListener({callback:(err:BusinessError|string, data:ImageKnifeData) => { - - this.mPixelPixelMap = data.drawPixelMap?.imagePixelMap as PixelMap; - - return false; - }}) - .setImageViewSize({ width: vp2px(200), height: vp2px(200) }) - .skipMemoryCache(true) - .enableGPU() - .pixelationFilter(pixel) - ImageKnife?.call(imageKnifeOption); - - } - - /** - *扭曲 - */ - swirlHandlePixelMap() { - let imageKnifeOption = new RequestOption(); - let transformation = new SwirlFilterTransformation(80); - imageKnifeOption.load(mUrl) - .addListener({callback:(err:BusinessError|string, data:ImageKnifeData) => { - - this.mSwirlPixelMap = data.drawPixelMap?.imagePixelMap as PixelMap; - - return false; - }}) - .setImageViewSize({ width: vp2px(200), height: vp2px(200) }) - .skipMemoryCache(true) - .enableGPU() - .swirlFilter(80) - // .diskCacheStrategy(new NONE()) - ImageKnife?.call(imageKnifeOption); - - } - /** - *遮罩 - */ - maskHandlePixelMap(maskResource: Resource) { - let imageKnifeOption = new RequestOption(); - let transformation = new MaskTransformation(maskResource); - // imageKnifeOption.load($r('app.media.photo6')) - imageKnifeOption.load(mUrl) - .addListener({callback:(err:BusinessError|string, data:ImageKnifeData) => { - - this.mMaskPixelMap = data.drawPixelMap?.imagePixelMap as PixelMap; - - return false; - }}) - .setImageViewSize({ width: vp2px(200), height: vp2px(200) }) - .skipMemoryCache(true) - .mask(maskResource) - // .diskCacheStrategy(new NONE()) - ImageKnife?.call(imageKnifeOption); - - } - - /** - *kuwahara - */ - kuwaharaHandlePixelMap() { - let imageKnifeOption = new RequestOption(); - imageKnifeOption.load(mUrl) - .addListener({callback:(err:BusinessError|string, data:ImageKnifeData) => { - - this.mKuwaharaPixelMap = data.drawPixelMap?.imagePixelMap as PixelMap; - - return false; - }}) - .setImageViewSize({ width: vp2px(200), height: vp2px(200) }) - .skipMemoryCache(true) - .enableGPU() - .kuwaharaFilter(20.0) - // .diskCacheStrategy(new NONE()) - ImageKnife?.call(imageKnifeOption); - - } - - /** - *toon - */ - toonHandlePixelMap() { - let imageKnifeOption = new RequestOption(); - imageKnifeOption.load(mUrl) - .addListener({callback:(err:BusinessError|string, data:ImageKnifeData) => { - - this.mToonPixelMap = data.drawPixelMap?.imagePixelMap as PixelMap; - - return false; - }}) - .setImageViewSize({ width: vp2px(200), height: vp2px(200) }) - .skipMemoryCache(true) - .enableGPU() - .toonFilter(0.2, 50.0); - // .diskCacheStrategy(new NONE()) - ImageKnife?.call(imageKnifeOption); - - } - - /** - *vignette - */ - vignetteHandlePixelMap() { - let imageKnifeOption = new RequestOption(); - imageKnifeOption.load(mUrl) - .addListener({callback:(err:BusinessError|string, data:ImageKnifeData) => { - - this.mVignettePixelMap = data.drawPixelMap?.imagePixelMap as PixelMap; - - return false; - }}) - .setImageViewSize({ width: vp2px(200), height: vp2px(200) }) - .skipMemoryCache(true) - .enableGPU() - .vignetteFilter([0.5, 0.5], [0.0, 0.0, 0.0], [0.3, 0.5]) - // .diskCacheStrategy(new NONE()) - ImageKnife?.call(imageKnifeOption); - - } -} - -let ImageKnife = ImageKnifeGlobal.getInstance().getImageKnife(); \ No newline at end of file diff --git a/entry/src/main/ets/workers/upngWorkerDepend.ts b/entry/src/main/ets/workers/upngWorkerDepend.ts deleted file mode 100644 index 74f75bb..0000000 --- a/entry/src/main/ets/workers/upngWorkerDepend.ts +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (C) 2023 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 worker, { ThreadWorkerGlobalScope, MessageEvents, ErrorEvent } from '@ohos.worker'; - -export function resolvePngWorker (workerPort,UPNG, e: MessageEvents) { - - let data = e.data; - - switch (data.type) { - - case 'readPngImageAsync': - - let 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 } - - workerPort.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 } - - workerPort.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 } - - workerPort.postMessage(dataObj3, [newPng3, data.data]); - - break; - - default: - - break - } -} \ No newline at end of file diff --git a/entry/src/main/ets/workers/upngWorkerTestCase.ets b/entry/src/main/ets/workers/upngWorkerTestCase.ets deleted file mode 100644 index 6b3e8fc..0000000 --- a/entry/src/main/ets/workers/upngWorkerTestCase.ets +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (C) 2023 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 worker, { ThreadWorkerGlobalScope, MessageEvents, ErrorEvent } from '@ohos.worker'; -import { UPNG } from '@ohos/libraryimageknife' -import {resolvePngWorker} from './upngWorkerDepend' -const workerPort: ThreadWorkerGlobalScope = worker.workerPort; - -workerPort.onmessage = (e: MessageEvents)=> { - - resolvePngWorker(workerPort,UPNG,e) - -} \ No newline at end of file diff --git a/entry/src/main/module.json5 b/entry/src/main/module.json5 index e33f091..54cf03a 100644 --- a/entry/src/main/module.json5 +++ b/entry/src/main/module.json5 @@ -2,33 +2,26 @@ "module": { "name": "entry", "type": "entry", - - "description": "$string:entry_desc", - "mainElement": "MainAbility", + "description": "$string:module_desc", + "mainElement": "EntryAbility", "deviceTypes": [ - "default", - "tablet" + "phone", + "tablet", + "2in1" ], "deliveryWithInstall": true, "installationFree": false, "pages": "$profile:main_pages", - "metadata": [ - { - "name": "ArkTSPartialUpdate", - "value": "true" - } - ], - "uiSyntax": "ets", "abilities": [ { - "name": "MainAbility", - "srcEntrance": "./ets/entryability/EntryAbility.ets", - "description": "$string:MainAbility_desc", + "name": "EntryAbility", + "srcEntry": "./ets/entryability/EntryAbility.ets", + "description": "$string:EntryAbility_desc", "icon": "$media:icon", - "label": "$string:MainAbility_label", - "startWindowIcon": "$media:icon", - "startWindowBackground": "$color:test_color", - "visible": true, + "label": "$string:EntryAbility_label", + "startWindowIcon": "$media:startIcon", + "startWindowBackground": "$color:start_window_background", + "exported": true, "skills": [ { "entities": [ @@ -53,7 +46,6 @@ }, { "name": "ohos.permission.MEDIA_LOCATION", - "reason": "$string:app_permission_MEDIA_LOCATION", "usedScene": { "abilities": [ "EntryAbility" @@ -63,7 +55,6 @@ }, { "name": "ohos.permission.READ_MEDIA", - "reason": "$string:app_permission_READ_MEDIA", "usedScene": { "abilities": [ "EntryAbility" diff --git a/entry/src/main/resources/base/element/color.json b/entry/src/main/resources/base/element/color.json index 6146fec..3c71296 100644 --- a/entry/src/main/resources/base/element/color.json +++ b/entry/src/main/resources/base/element/color.json @@ -1,8 +1,8 @@ { "color": [ { - "name": "test_color", - "value": "#3d2564" + "name": "start_window_background", + "value": "#FFFFFF" } ] } \ No newline at end of file diff --git a/entry/src/main/resources/base/element/string.json b/entry/src/main/resources/base/element/string.json index c1c0806..f945955 100644 --- a/entry/src/main/resources/base/element/string.json +++ b/entry/src/main/resources/base/element/string.json @@ -1,125 +1,16 @@ { "string": [ { - "name": "entry_desc", + "name": "module_desc", + "value": "module description" + }, + { + "name": "EntryAbility_desc", "value": "description" }, { - "name": "MainAbility_desc", - "value": "description" - }, - { - "name": "MainAbility_label", - "value": "ImageKnife" - }, - - { - "name": "ImageKnife_OHOS", - "value": "ImageKnife_OHOS" - }, - { - "name": "mainability_description", - "value": "ETS_Empty Ability" - }, - { - "name": "left_top_corner", - "value": "左上角" - }, - { - "name": "r_top_corner", - "value": "右上角" - }, - { - "name": "left_bottom_corner", - "value": "左下角" - }, - { - "name": "r_bottom_corner", - "value": "右下角" - }, - { - "name": "trans_circle", - "value": "裁剪-圆" - }, - { - "name": "trans_circle_border", - "value": "裁剪-圆环" - }, - { - "name": "trans_rotate", - "value": "旋转" - }, - { - "name": "trans_square", - "value": "正方形裁剪" - }, - { - "name": "trans_clip_top", - "value": "上方裁剪" - }, - { - "name": "trans_clip_center", - "value": "中间裁剪" - }, - { - "name": "trans_clip_bottom", - "value": "底下裁剪" - }, - { - "name": "resource_image_compress", - "value": "资源图片压缩" - }, - { - "name": "file_image_compress", - "value": "本地文件图片压缩" - }, - { - "name": "image_transform", - "value": "图片变换" - }, - { - "name": "image_compress", - "value": "图片压缩" - }, - { - "name": "image_grayscale", - "value": "灰度处理" - }, - { - "name": "image_Brightness", - "value": "亮度处理" - }, - { - "name": "image_Contrast", - "value": "对比度处理" - }, - { - "name": "image_Invert", - "value": "反转处理" - }, - { - "name": "image_Sepia", - "value": "黑褐色处理" - }, - { - "name": "image_Sketch", - "value": "素描处理" - }, - { - "name": "image_blur", - "value": "模糊处理" - }, - { - "name": "image_pixel", - "value": "马赛克处理" - }, - { - "name": "app_permission_MEDIA_LOCATION", - "value": "获取媒体图片" - }, - { - "name": "app_permission_READ_MEDIA", - "value": "读媒体图片" + "name": "EntryAbility_label", + "value": "label" } ] } \ No newline at end of file diff --git a/entry/src/main/resources/base/media/Back.png b/entry/src/main/resources/base/media/Back.png deleted file mode 100644 index e4d200e..0000000 Binary files a/entry/src/main/resources/base/media/Back.png and /dev/null differ diff --git a/entry/src/main/resources/base/media/aaa.jpg b/entry/src/main/resources/base/media/aaa.jpg new file mode 100644 index 0000000..b4212c2 Binary files /dev/null and b/entry/src/main/resources/base/media/aaa.jpg differ diff --git a/entry/src/main/resources/base/media/bmpSample.bmp b/entry/src/main/resources/base/media/bmpSample.bmp deleted file mode 100644 index 4cbb7ee..0000000 Binary files a/entry/src/main/resources/base/media/bmpSample.bmp and /dev/null differ diff --git a/entry/src/main/resources/base/media/dpgSample.dpg b/entry/src/main/resources/base/media/dpgSample.dpg deleted file mode 100644 index 313d892..0000000 Binary files a/entry/src/main/resources/base/media/dpgSample.dpg and /dev/null differ diff --git a/entry/src/main/resources/base/media/gifSample.gif b/entry/src/main/resources/base/media/gifSample.gif deleted file mode 100644 index 11a454c..0000000 Binary files a/entry/src/main/resources/base/media/gifSample.gif and /dev/null differ diff --git a/entry/src/main/resources/base/media/gifSample_single_frame.gif b/entry/src/main/resources/base/media/gifSample_single_frame.gif deleted file mode 100644 index 94ce8e1..0000000 Binary files a/entry/src/main/resources/base/media/gifSample_single_frame.gif and /dev/null differ diff --git a/entry/src/main/resources/base/media/icon.png b/entry/src/main/resources/base/media/icon.png index ce307a8..cd45acc 100644 Binary files a/entry/src/main/resources/base/media/icon.png and b/entry/src/main/resources/base/media/icon.png differ diff --git a/entry/src/main/resources/base/media/icon_failed.png b/entry/src/main/resources/base/media/icon_failed.png deleted file mode 100644 index 94c63eb..0000000 Binary files a/entry/src/main/resources/base/media/icon_failed.png and /dev/null differ diff --git a/entry/src/main/resources/base/media/icon_loading.png b/entry/src/main/resources/base/media/icon_loading.png deleted file mode 100644 index 592d50b..0000000 Binary files a/entry/src/main/resources/base/media/icon_loading.png and /dev/null differ diff --git a/entry/src/main/resources/base/media/icon_retry.png b/entry/src/main/resources/base/media/icon_retry.png deleted file mode 100644 index e671aa8..0000000 Binary files a/entry/src/main/resources/base/media/icon_retry.png and /dev/null differ diff --git a/entry/src/main/resources/base/media/iconsvg.svg b/entry/src/main/resources/base/media/iconsvg.svg deleted file mode 100644 index f2fb75b..0000000 --- a/entry/src/main/resources/base/media/iconsvg.svg +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/entry/src/main/resources/base/media/jpgSample.jpg b/entry/src/main/resources/base/media/jpgSample.jpg deleted file mode 100644 index c67ad12..0000000 Binary files a/entry/src/main/resources/base/media/jpgSample.jpg and /dev/null differ diff --git a/entry/src/main/resources/base/media/loading.png b/entry/src/main/resources/base/media/loading.png new file mode 100644 index 0000000..e7ddd2e Binary files /dev/null and b/entry/src/main/resources/base/media/loading.png differ diff --git a/entry/src/main/resources/base/media/mask_starfish.png b/entry/src/main/resources/base/media/mask_starfish.png deleted file mode 100644 index 34f4a7f..0000000 Binary files a/entry/src/main/resources/base/media/mask_starfish.png and /dev/null differ diff --git a/entry/src/main/resources/base/media/pngSample.png b/entry/src/main/resources/base/media/pngSample.png deleted file mode 100644 index ebe1711..0000000 Binary files a/entry/src/main/resources/base/media/pngSample.png and /dev/null differ diff --git a/entry/src/main/resources/base/media/startIcon.png b/entry/src/main/resources/base/media/startIcon.png new file mode 100644 index 0000000..366f764 Binary files /dev/null and b/entry/src/main/resources/base/media/startIcon.png differ diff --git a/entry/src/main/resources/base/media/svgSample.svg b/entry/src/main/resources/base/media/svgSample.svg deleted file mode 100644 index dab8c8e..0000000 --- a/entry/src/main/resources/base/media/svgSample.svg +++ /dev/null @@ -1,48 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/entry/src/main/resources/base/media/test.gif b/entry/src/main/resources/base/media/test.gif deleted file mode 100644 index fceab16..0000000 Binary files a/entry/src/main/resources/base/media/test.gif and /dev/null differ diff --git a/entry/src/main/resources/base/media/user.txt b/entry/src/main/resources/base/media/user.txt deleted file mode 100644 index 710e1c6..0000000 --- a/entry/src/main/resources/base/media/user.txt +++ /dev/null @@ -1,9 +0,0 @@ -syntax = "proto3"; -package User; - -message UserLoginResponse{ - string sessionId = 1; - string userPrivilege = 2; - int64 servTimesTemp = 3; - string formatTimestamp = 4; -} \ No newline at end of file diff --git a/entry/src/main/resources/base/media/webpSample.webp b/entry/src/main/resources/base/media/webpSample.webp deleted file mode 100644 index c799b82..0000000 Binary files a/entry/src/main/resources/base/media/webpSample.webp and /dev/null differ diff --git a/entry/src/main/resources/base/profile/main_pages.json b/entry/src/main/resources/base/profile/main_pages.json index 12657f6..e87dd6a 100644 --- a/entry/src/main/resources/base/profile/main_pages.json +++ b/entry/src/main/resources/base/profile/main_pages.json @@ -1,51 +1,10 @@ { "src": [ - "pages/index", - "pages/CacheRuleChangedPage", - "pages/frescoRetryTestCasePage", - "pages/basicTestFeatureAbilityPage", - "pages/basicTestFileIOPage", - "pages/basicTestMediaImage", - "pages/basicTestResourceManagerPage", - "pages/storageTestLruCache", - "pages/pngjTestCasePage", - "pages/showErrorholderTestCasePage", - "pages/transformPixelMapPage", - "pages/testPreloadPage", - "pages/testDiskPreLoadPage", - "pages/testImageKnifeOptionChangedPage", - "pages/testImageKnifeOptionChangedPage2", - "pages/testImageKnifeOptionChangedPage3", - "pages/testImageKnifeOptionChangedPage4", - "pages/testImageKnifeOptionChangedPage5", - "pages/compressPage", - "pages/testAllCacheInfoPage", - "pages/cropImagePage2", - "pages/svgTestCasePage", - "pages/imageknifeTestCaseIndex", - "pages/dataShareUriLoadPage", - "pages/manyPhotoShowPage", - "pages/photosPausedResumedPage", - "pages/photosPausedResumedPage2", - "pages/tempUrlTestPage", - "pages/drawFactoryTestPage", - "pages/testSingleFrameGifPage", - "pages/OptionTestPage", - "pages/SignatureTestPage", - "pages/hspCacheTestPage", - "pages/multiHspTestPage", - "pages/testManyNetImageLoadWithPage", - "pages/testManyNetImageLoadWithPage2", - "pages/testManyGifLoadWithPage", - "pages/testImageAntiAliasingWithPage", - "pages/testImageKnifeRouter1", - "pages/testImageKnifeRouter2", - "pages/RequestOptionLoadImage", - "pages/testImageKnifeHttpRequestHeader", - "pages/testImageKnifeAutoPage", - "pages/testImageKnifeAutoWidthPage", - "pages/testImageKnifeAutoHeightPage", - "pages/testPriorityComponent", - "pages/testReusePhotoPage" + "pages/Index", + "pages/ListPage", + "pages/SingleImage", + "pages/ManyPhotoShowPage", + "pages/LongImagePage", + "pages/TransformPage" ] } \ No newline at end of file diff --git a/entry/src/main/resources/en_US/element/string.json b/entry/src/main/resources/en_US/element/string.json new file mode 100644 index 0000000..f945955 --- /dev/null +++ b/entry/src/main/resources/en_US/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "module description" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "label" + } + ] +} \ No newline at end of file diff --git a/entry/src/main/resources/zh_CN/element/string.json b/entry/src/main/resources/zh_CN/element/string.json new file mode 100644 index 0000000..597ecf9 --- /dev/null +++ b/entry/src/main/resources/zh_CN/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "模块描述" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "label" + } + ] +} \ No newline at end of file diff --git a/entry/src/ohosTest/ets/test/DefaultJobQueueTest.test.ets b/entry/src/ohosTest/ets/test/DefaultJobQueueTest.test.ets new file mode 100644 index 0000000..8aeb9b6 --- /dev/null +++ b/entry/src/ohosTest/ets/test/DefaultJobQueueTest.test.ets @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'; +import { ImageKnifeOption, ImageKnifeRequest } from '@ohos/imageknife/Index'; +import { DefaultJobQueue } from '@ohos/imageknife/src/main/ets/utils/DefaultJobQueue'; +import { IJobQueue } from '@ohos/imageknife/src/main/ets/utils/IJobQueue'; +import taskpool from '@ohos.taskpool'; +import common from '@ohos.app.ability.common'; + + +export default function DefaultJobQueueTest() { + + describe('DefaultJobQueueTest', () => { + // Defines a test suite. Two parameters are supported: test suite name and test suite function. + beforeAll(() => { + // Presets an action, which is performed only once before all test cases of the test suite start. + // This API supports only one parameter: preset action function. + }); + beforeEach(() => { + // Presets an action, which is performed before each unit test case starts. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: preset action function. + }); + afterEach(() => { + // Presets a clear action, which is performed after each unit test case ends. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: clear action function. + }); + afterAll(() => { + // Presets a clear action, which is performed after all test cases of the test suite end. + // This API supports only one parameter: clear action function. + }); + + it('testJob', 0, async () => { + let job: IJobQueue = new DefaultJobQueue() + job.add(makeRequest("medium1", getContext() as common.UIAbilityContext)) + job.add(makeRequest("medium2", getContext() as common.UIAbilityContext, taskpool.Priority.MEDIUM)) + job.add(makeRequest("medium3", getContext() as common.UIAbilityContext)) + job.add(makeRequest("low1", getContext() as common.UIAbilityContext, taskpool.Priority.LOW)) + job.add(makeRequest("high1", getContext() as common.UIAbilityContext, taskpool.Priority.HIGH)) + job.add(makeRequest("low2", getContext() as common.UIAbilityContext, taskpool.Priority.LOW)) + job.add(makeRequest("medium4", getContext() as common.UIAbilityContext)) + + expect(job.getQueueLength()).assertEqual(7) + expect(job.pop()!.ImageKnifeOption.loadSrc).assertEqual("high1") + expect(job.pop()!.ImageKnifeOption.loadSrc).assertEqual("medium1") + expect(job.pop()!.ImageKnifeOption.loadSrc).assertEqual("medium2") + expect(job.pop()!.ImageKnifeOption.loadSrc).assertEqual("medium3") + expect(job.pop()!.ImageKnifeOption.loadSrc).assertEqual("medium4") + expect(job.pop()!.ImageKnifeOption.loadSrc).assertEqual("low1") + expect(job.pop()!.ImageKnifeOption.loadSrc).assertEqual("low2") + expect(job.pop()).assertEqual(undefined) + expect(job.getQueueLength()).assertEqual(0) + + }); + + }); +} + +function makeRequest(src: string, context: common.UIAbilityContext, priority?: taskpool.Priority): ImageKnifeRequest { + let option: ImageKnifeOption = { + loadSrc: src, + priority: priority + } + return new ImageKnifeRequest( + option, + context, + 0, + 0, + 0, + { + showPixelMap: async (version: number,pixelMap: PixelMap | string) => { + } + }) +} diff --git a/entry/src/ohosTest/ets/test/FileLruCache.test.ets b/entry/src/ohosTest/ets/test/FileLruCache.test.ets new file mode 100644 index 0000000..00ddc29 --- /dev/null +++ b/entry/src/ohosTest/ets/test/FileLruCache.test.ets @@ -0,0 +1,172 @@ +/* + * Copyright (C) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'; + +import Constants from '../../../main/ets/common/Constants'; +import taskpool from '@ohos.taskpool'; +import { GlobalContext } from '../../../main/ets/common/GlobalContext'; +import { FileCache } from '@ohos/imageknife/src/main/ets/utils/FileCache'; + + +export default function FileLruCacheTest() { + + describe('FileLruCacheTest', () => { + // Defines a test suite. Two parameters are supported: test suite name and test suite function. + beforeAll(() => { + // Presets an action, which is performed only once before all test cases of the test suite start. + // This API supports only one parameter: preset action function. + }); + beforeEach(() => { + // Presets an action, which is performed before each unit test case starts. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: preset action function. + }); + afterEach(() => { + // Presets a clear action, which is performed after each unit test case ends. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: clear action function. + }); + afterAll(() => { + // Presets a clear action, which is performed after all test cases of the test suite end. + // This API supports only one parameter: clear action function. + }); + + // 测试基础put,get以及size功能 + it('assertFileSizeAllInMainThread', 0, async () => { + const buf: ArrayBuffer = new ArrayBuffer(1024 * 1024); + console.info(Constants.TAG + buf.byteLength) + console.info(Constants.TAG + GlobalContext.getContext().getObject("cacheDir")) + + let fileCache: FileCache = new FileCache(GlobalContext.getContext() + .getObject("context") as Context, 5, 3 * 1024 * 1024) + await fileCache.initFileCache() + + fileCache.put("aaa", buf) + await sleep(1000) + fileCache.put("bbb", buf) + await sleep(1000) + fileCache.put("ccc", buf) + expect(fileCache.size()).assertEqual(3) + console.info(Constants.TAG + fileCache.currentMemory + "") + fileCache.get("aaa") + await sleep(1000) + fileCache.put("ddd", buf) + await sleep(1000) + console.info(Constants.TAG + fileCache.currentMemory + "") + expect(fileCache.size()).assertEqual(3) + console.info(Constants.TAG + fileCache.get("aaa")?.byteLength) + expect(fileCache.get("ddd")?.byteLength).assertEqual(buf.byteLength) + await sleep(1000) + expect(fileCache.get("aaa")?.byteLength).assertEqual(buf.byteLength) + await sleep(1000) + expect(fileCache.get("ccc")?.byteLength).assertEqual(buf.byteLength) + await sleep(1000) + expect(fileCache.get("bbb")).assertUndefined() + + + // 模拟第二次启动后重新加载缓存 + let fileCache2: FileCache = new FileCache(GlobalContext.getContext() + .getObject("context") as Context, 5, 3 * 1024 * 1024) + await fileCache2.initFileCache() + expect(fileCache2.size()).assertEqual(3) + expect(fileCache2.get("ddd")?.byteLength).assertEqual(buf.byteLength) + expect(fileCache2.get("aaa")?.byteLength).assertEqual(buf.byteLength) + expect(fileCache2.get("ccc")?.byteLength).assertEqual(buf.byteLength) + + }); + + it('assertFileSizeAllInSubThread', 0, async () => { + const buf: ArrayBuffer = new ArrayBuffer(1024 * 1024); + console.info(Constants.TAG + buf.byteLength) + console.info(Constants.TAG + GlobalContext.getContext().getObject("cacheDir")) + + let fileCache: FileCache = new FileCache(GlobalContext.getContext() + .getObject("context") as Context, 5, 3 * 1024 * 1024) + await fileCache.initFileCache() + + fileCache.put("aaa", buf) + + let task: taskpool.Task = new taskpool.Task(getFile, "bbb", GlobalContext.getContext() + .getObject("context") as Context); + let res: ArrayBuffer | undefined = await taskpool.execute(task) as (ArrayBuffer | undefined) + if (res !== undefined) { + fileCache.putWithoutWriteFile("bbb", res) + } + + task = new taskpool.Task(getFile, "aaa", GlobalContext.getContext() + .getObject("context") as Context); + res = await taskpool.execute(task) as (ArrayBuffer | undefined) + if (res !== undefined) { + fileCache.putWithoutWriteFile("aaa", res) + } + + fileCache.put("ddd", buf) + expect(fileCache.size()).assertEqual(3) + expect(fileCache.currentMemory).assertEqual(3 * 1024 * 1024) + expect(fileCache.get("bbb")?.byteLength).assertEqual(1024 * 1024) + expect(fileCache.get("aaa")?.byteLength).assertEqual(1024 * 1024) + expect(fileCache.get("ddd")?.byteLength).assertEqual(1024 * 1024) + + + task = new taskpool.Task(getFile, "eee", GlobalContext.getContext() + .getObject("context") as Context); + + res = await taskpool.execute(task) as (ArrayBuffer | undefined) + if (res !== undefined) { + fileCache.putWithoutWriteFile("eee", res) + } + expect(fileCache.size()).assertEqual(3) + expect(fileCache.currentMemory).assertEqual(3 * 1024 * 1024) + expect(fileCache.get("bbb")).assertEqual(undefined) + expect(fileCache.get("aaa")?.byteLength).assertEqual(1024 * 1024) + expect(fileCache.get("ddd")?.byteLength).assertEqual(1024 * 1024) + + }); + + + it('test', 0, async () => { + const buf: ArrayBuffer = new ArrayBuffer(1024 * 1024); + console.info(Constants.TAG + buf.byteLength) + console.info(Constants.TAG + GlobalContext.getContext().getObject("cacheDir")) + + let fileCache: FileCache = new FileCache(GlobalContext.getContext() + .getObject("context") as Context, 5, 3 * 1024 * 1024) + await fileCache.initFileCache() + + console.info(Constants.TAG + JSON.stringify("xxxxx")) + fileCache.put(JSON.stringify("xxxxx"),buf) + expect(fileCache.get(JSON.stringify("xxxxx"))?.byteLength).assertEqual(1024 * 1024) + }); + }); +} + +function sleep(ms: number): Promise { + return new Promise(resolve => setTimeout(resolve, ms)); +} + +@Concurrent +async function getFile(key: string, context: Context): Promise { + // 读取文件缓存 + let buf = FileCache.getFileCacheByFile(context, key) + + if (buf !== undefined) { + return buf + } + + buf = new ArrayBuffer(1024 * 1024) + // 写文件缓存 + FileCache.saveFileCacheOnlyFile(context, key, buf) + return buf; +} \ No newline at end of file diff --git a/entry/src/ohosTest/ets/test/List.test.ets b/entry/src/ohosTest/ets/test/List.test.ets index 489b341..878bde1 100644 --- a/entry/src/ohosTest/ets/test/List.test.ets +++ b/entry/src/ohosTest/ets/test/List.test.ets @@ -1,31 +1,23 @@ /* - * Copyright (C) 2023 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); + * 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, + * 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 abilityTest from './Ability.test' -import lruCacheTest from './lrucache.test' -import LogUtilTest from './logutil.test' -import Transfrom from './transfrom.test' -import RequestOptionTest from './requestoption.test' -import ImageKnifeTest from './imageknife.test' -import DiskLruCacheTest from './diskLruCache.test' +import DefaultJobQueueTest from './DefaultJobQueueTest.test'; +import FileLruCacheTest from './FileLruCache.test'; +import MemoryLruCacheTest from './MemoryLruCache.test'; export default function testsuite() { - abilityTest() - lruCacheTest() - DiskLruCacheTest() - LogUtilTest() - Transfrom() - RequestOptionTest() - ImageKnifeTest(); + MemoryLruCacheTest(); + FileLruCacheTest(); + DefaultJobQueueTest(); } \ No newline at end of file diff --git a/entry/src/ohosTest/ets/test/MemoryLruCache.test.ets b/entry/src/ohosTest/ets/test/MemoryLruCache.test.ets new file mode 100644 index 0000000..1139992 --- /dev/null +++ b/entry/src/ohosTest/ets/test/MemoryLruCache.test.ets @@ -0,0 +1,135 @@ +/* + * Copyright (C) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'; +import image from '@ohos.multimedia.image'; + + +import Constants from '../../../main/ets/common/Constants'; +import { MemoryLruCache } from '@ohos/imageknife/src/main/ets/utils/MemoryLruCache'; +import { ImageKnifeData } from '@ohos/imageknife/src/main/ets/model/ImageKnifeData'; + + +export default function MemoryLruCacheTest() { + + describe('MemoryLruCacheTest', () => { + // Defines a test suite. Two parameters are supported: test suite name and test suite function. + beforeAll(() => { + // Presets an action, which is performed only once before all test cases of the test suite start. + // This API supports only one parameter: preset action function. + }); + beforeEach(() => { + // Presets an action, which is performed before each unit test case starts. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: preset action function. + }); + afterEach(() => { + // Presets a clear action, which is performed after each unit test case ends. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: clear action function. + }); + afterAll(() => { + // Presets a clear action, which is performed after all test cases of the test suite end. + // This API supports only one parameter: clear action function. + }); + + // 测试基础put,get以及size功能 + it('assertBasicFunction', 0, async () => { + let memoryCache: MemoryLruCache = new MemoryLruCache(3, 3 * 1024 * 1024); + + let data: ImageKnifeData = await getNewImageKnifeData() + memoryCache.put("aaa", data) + memoryCache.put("bbb", data) + memoryCache.put("ccc", data) + expect(memoryCache.size()).assertEqual(3) + expect(memoryCache.get("aaa")).assertEqual(data) + expect(memoryCache.get("bbb")).assertEqual(data) + expect(memoryCache.get("ccc")).assertEqual(data) + expect(memoryCache.size()).assertEqual(3) + + memoryCache.remove("ccc") + memoryCache.remove("ddd") + expect(memoryCache.size()).assertEqual(2) + + memoryCache.removeAll() + expect(memoryCache.size()).assertEqual(0) + }); + + + // 测试内存缓存size的lru功能 + it('assertSizeLruFuction', 0, async () => { + let memoryCache: MemoryLruCache = new MemoryLruCache(3, 3 * 1024 * 1024); + + let data: ImageKnifeData = await getNewImageKnifeData() + memoryCache.put("aaa", data) + memoryCache.put("bbb", data) + memoryCache.put("ccc", data) + memoryCache.put("ddd", data) + + expect(memoryCache.get("aaa")).assertUndefined() + expect(memoryCache.get("bbb")).assertEqual(data) + memoryCache.put("eee", data) + expect(memoryCache.get("ccc")).assertUndefined() + expect(memoryCache.get("bbb")).assertEqual(data) + expect(memoryCache.get("ddd")).assertEqual(data) + expect(memoryCache.get("eee")).assertEqual(data) + }); + + // 测试内存缓存memorySize的lru功能 + it('assertMemorySizeLruFuction', 0, async () => { + let memoryCache: MemoryLruCache = new MemoryLruCache(3, 2 * 1024 * 1024); + + const color: ArrayBuffer = new ArrayBuffer(1024 * 1024); //96为需要创建的像素buffer大小,取值为:height * width *4 + let opts: image.InitializationOptions = { + editable: true, pixelFormat: 3, size: { + height: 512, width: 512 + } + } + let pixelmap: PixelMap = await image.createPixelMap(color, opts) + console.info(Constants.TAG + pixelmap.getPixelBytesNumber()) + let data: ImageKnifeData = { + source: pixelmap, + imageWidth: 5, + imageHeight: 5 + } + + memoryCache.put("aaa", data) + memoryCache.put("bbb", data) + memoryCache.get("aaa") + memoryCache.put("ccc", data) + expect(memoryCache.size()).assertEqual(2) + expect(memoryCache.get("bbb")).assertUndefined() + expect(memoryCache.get("aaa")).assertEqual(data) + expect(memoryCache.get("ccc")).assertEqual(data) + }); + + }); +} + +async function getNewImageKnifeData(): Promise { + const color: ArrayBuffer = new ArrayBuffer(96); //96为需要创建的像素buffer大小,取值为:height * width *4 + let opts: image.InitializationOptions = { + editable: true, pixelFormat: 3, size: { + height: 4, width: 6 + } + } + let pixelmap: PixelMap = await image.createPixelMap(color, opts) + + let data: ImageKnifeData = { + source: pixelmap, + imageWidth: 5, + imageHeight: 5 + } + return data +} \ No newline at end of file diff --git a/entry/src/ohosTest/ets/test/diskLruCache.test.ets b/entry/src/ohosTest/ets/test/diskLruCache.test.ets deleted file mode 100644 index a4b5fb4..0000000 --- a/entry/src/ohosTest/ets/test/diskLruCache.test.ets +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Copyright (C) 2024 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium' -import { DiskLruCache, DiskCacheEntry } from '@ohos/imageknife' -import { common } from '@kit.AbilityKit'; -import fs from '@ohos.file.fs'; -import { GlobalContext } from '../testability/GlobalContext' - -const BASE_COUNT: number = 2000; - -export default function DiskLruCacheTest() { - - describe('DiskLruCacheTest', () => { - // Defines a test suite. Two parameters are supported: test suite name and test suite function. - beforeAll(() => { - //ImageKnife.with(this.context.createModuleContext("entry_test")); - // Presets an action, which is performed only once before all test cases of the test suite start. - // This API supports only one parameter: preset action function. - }) - beforeEach(() => { - - // Presets an action, which is performed before each unit test case starts. - // The number of execution times is the same as the number of test cases defined by **it**. - // This API supports only one parameter: preset action function. - }) - afterEach(() => { - // Presets a clear action, which is performed after each unit test case ends. - // The number of execution times is the same as the number of test cases defined by **it**. - // This API supports only one parameter: clear action function. - }) - afterAll(() => { - // Presets a clear action, which is performed after all test cases of the test suite end. - // This API supports only one parameter: clear action function. - }) - it('testSetCahe', 0, () => { - let context: object | undefined = GlobalContext.getInstance().getObject("hapContext"); - let disLruCache: DiskLruCache = DiskLruCache.create(context as common.UIAbilityContext, 1024); - let startTime = new Date().getTime(); - disLruCache.set('test', "Hello World Simple Example."); - disLruCache.set('testABC', "Hello World ABC"); - disLruCache.set('testDE', "Hello World Simple DE"); - expect(String.fromCharCode(...new Uint8Array(disLruCache.get('test') as ArrayBufferLike)) == "Hello World Simple Example.") - .assertTrue() - expect(String.fromCharCode(...new Uint8Array(disLruCache.get('testABC') as ArrayBufferLike)) == "Hello World ABC") - .assertTrue() - expect(String.fromCharCode(...new Uint8Array(disLruCache.get('testDE') as ArrayBufferLike)) == "Hello World Simple DE") - .assertTrue() - let str: string = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'; - for (let index = 0; index < 100; index++) { - str += index; - disLruCache.set('test' + index, str); - } - expect(disLruCache.getSize() <= 1024).assertTrue() - endTime(startTime, 'testSetCahe'); - disLruCache.cleanCacheData(); - - }) - it('testGetCacheAsync', 1, () => { - let context: object | undefined = GlobalContext.getInstance().getObject("hapContext"); - let filesDir: object | undefined = GlobalContext.getInstance().getObject("filesDir"); - let cache: DiskLruCache = DiskLruCache.create(context as common.UIAbilityContext, 1024); - let startTime = new Date().getTime(); - let path = filesDir + '/testFile.txt'; - let file = fs.openSync(path, 0o102); - fs.writeSync(file.fd, "hello, world!"); - let length = fs.statSync(path).size; - let dataArr = new ArrayBuffer(length); - fs.readSync(file.fd, dataArr); - cache.set('testFile', dataArr); - expect(cache.get('testFile')?.byteLength == 13).assertTrue() - endTime(startTime, 'testGetCacheAsync'); - cache.cleanCacheData(); - }) - it('testDeleteCacheDataByKey', 2, () => { - let context: object | undefined = GlobalContext.getInstance().getObject("hapContext"); - let cache: DiskLruCache = DiskLruCache.create(context as common.UIAbilityContext, 1024); - let startTime = new Date().getTime(); - cache.set('test', "Hello World Simple Example."); - cache.set('testABC', "Hello World ABC"); - expect(String.fromCharCode(...new Uint8Array(cache.get('test') as ArrayBufferLike))) - .assertEqual("Hello World Simple Example."); - expect(String.fromCharCode(...new Uint8Array(cache.get('testABC') as ArrayBufferLike))) - .assertEqual("Hello World ABC"); - cache.deleteCacheDataByKey('test'); - cache.deleteCacheDataByKey('testABC'); - expect(String.fromCharCode(...new Uint8Array(cache.get('test') as ArrayBufferLike))).assertEqual(''); - expect(String.fromCharCode(...new Uint8Array(cache.get('testABC') as ArrayBufferLike))).assertEqual(''); - endTime(startTime, 'testDeleteCacheDataByKey'); - cache.cleanCacheData(); - }) - it('testGetPath', 3, () => { - let context: object | undefined = GlobalContext.getInstance().getObject("hapContext"); - let cache: DiskLruCache = DiskLruCache.create(context as common.UIAbilityContext, 1024); - let startTime = new Date().getTime(); - cache.set('test', "Hello World Simple Example."); - let path: string = cache.getFileToPath('test'); - expect(String.fromCharCode(...new Uint8Array(cache.get('test') as ArrayBufferLike)) == "Hello World Simple Example.") - .assertTrue() - expect(cache.getFileToPath('test') == path).assertTrue() - expect(cache.getPath() + cache.getCacheMap().getFirstKey() == path).assertTrue() - endTime(startTime, 'testGetPath'); - cache.cleanCacheData(); - }) - it('testGetCacheMap', 6, () => { - let context: object | undefined = GlobalContext.getInstance().getObject("hapContext"); - let cache: DiskLruCache = DiskLruCache.create(context as common.UIAbilityContext, 1024); - let startTime = new Date().getTime(); - cache.set('test', "Hello World Simple Example."); - expect(cache.getCacheMap().getFirstKey() == '098f6bcd4621d373cade4e832627b4f6').assertTrue() - expect(cache.getCacheMap().hasKey('098f6bcd4621d373cade4e832627b4f6') == true).assertTrue() - endTime(startTime, 'testGetCacheMap'); - cache.cleanCacheData(); - - }) - - it('testGetSize', 7, () => { - let context: object | undefined = GlobalContext.getInstance().getObject("hapContext"); - let cache: DiskLruCache = DiskLruCache.create(context as common.UIAbilityContext, 1024); - let startTime = new Date().getTime(); - cache.set('test', "Hello World Simple Example."); - expect(String.fromCharCode(...new Uint8Array(cache.get('test') as ArrayBufferLike)) == "Hello World Simple Example.") - .assertTrue() - expect(cache.getSize() == 27).assertTrue() - endTime(startTime, 'testGetSize'); - cache.cleanCacheData(); - - }) - - it('testDiskCacheEntry', 8, () => { - let startTime = new Date().getTime(); - let dentry = new DiskCacheEntry('test', 30 * 1024 * 1024) - expect(dentry.getKey() == 'test').assertTrue() - dentry.setKey('newtest') - expect(dentry.getKey() == 'newtest').assertTrue() - expect(dentry.getLength() == 30 * 1024 * 1024).assertTrue() - dentry.setLength(12 * 1024 * 1024) - expect(dentry.getLength() == 12 * 1024 * 1024).assertTrue() - expect(dentry.toString() == dentry.getKey() + ' - ' + dentry.getLength()).assertTrue() - endTime(startTime, 'testDiskCacheEntry'); - }) - }) -} - -function endTime(startTime: number, tag: string) { - let endTime: number = new Date().getTime(); - let averageTime = ((endTime - startTime) * 1000 / BASE_COUNT) - console.info(tag + " startTime: " + endTime) - console.info(tag + " endTime: " + endTime) - console.log(tag + " averageTime: " + averageTime + "μs"); -} \ No newline at end of file diff --git a/entry/src/ohosTest/ets/test/imageknife.test.ets b/entry/src/ohosTest/ets/test/imageknife.test.ets deleted file mode 100644 index ad85441..0000000 --- a/entry/src/ohosTest/ets/test/imageknife.test.ets +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (C) 2023 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 hilog from '@ohos.hilog'; -import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium' -import {ImageKnife,ImageKnifeDrawFactory,ImageKnifeGlobal} from '@ohos/imageknife' - -const BASE_COUNT: number = 2000; - -export default function ImageKnifeTest() { - describe('ImageKnifeTest', ()=> { - // Defines a test suite. Two parameters are supported: test suite name and test suite function. - beforeAll( ()=> { - // Presets an action, which is performed only once before all test cases of the test suite start. - // This API supports only one parameter: preset action function. - }) - beforeEach( ()=> { - // Presets an action, which is performed before each unit test case starts. - // The number of execution times is the same as the number of test cases defined by **it**. - // This API supports only one parameter: preset action function. - }) - afterEach( ()=> { - // Presets a clear action, which is performed after each unit test case ends. - // The number of execution times is the same as the number of test cases defined by **it**. - // This API supports only one parameter: clear action function. - }) - afterAll( ()=> { - // Presets a clear action, which is performed after all test cases of the test suite end. - // This API supports only one parameter: clear action function. - }) - - - it('TestGlobalImageKnife',0, ()=> { - let context:Object|undefined = ImageKnifeGlobal.getInstance().getHapContext(); - if(context != undefined) { - let startTime = new Date().getTime(); - for (let index = 0; index < BASE_COUNT; index++) { - ImageKnife.with(context); - } - endTime(startTime, 'TestGlobalImageKnife'); - let global: ImageKnifeGlobal = ImageKnife.with(context) - expect(global.getImageKnife()).not().assertUndefined() - } - }) - - - it('TestGlobalDefaultLifeCycle',1, ()=> { - let imageKnife:ImageKnife|undefined = ImageKnifeGlobal.getInstance().getImageKnife() - if(imageKnife != undefined){ - let startTime = new Date().getTime(); - for (let index = 0; index < BASE_COUNT; index++) { - imageKnife.setDefaultLifeCycle(ImageKnifeDrawFactory.createProgressLifeCycle("#10a5ff", 0.5)) - } - endTime(startTime, 'setDefaultLifeCycle'); - let startTime1 = new Date().getTime(); - for (let index = 0; index < BASE_COUNT; index++) { - imageKnife.getDefaultLifeCycle(); - } - endTime(startTime1, 'getDefaultLifeCycle'); - imageKnife.setDefaultLifeCycle(ImageKnifeDrawFactory.createProgressLifeCycle("#10a5ff", 0.5)) - let globalLifeCycle = imageKnife.getDefaultLifeCycle(); - expect(globalLifeCycle).not().assertUndefined() - } - - }) - }) -} - -function endTime(startTime: number, tag: string) { - let endTime: number = new Date().getTime(); - let averageTime = ((endTime - startTime) * 1000 / BASE_COUNT) - console.info(tag + " startTime: " + endTime) - console.info(tag + " endTime: " + endTime) - console.log(tag + " averageTime: " + averageTime + "μs"); -} \ No newline at end of file diff --git a/entry/src/ohosTest/ets/test/logutil.test.ets b/entry/src/ohosTest/ets/test/logutil.test.ets deleted file mode 100644 index 3981923..0000000 --- a/entry/src/ohosTest/ets/test/logutil.test.ets +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (C) 2023 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 hilog from '@ohos.hilog'; -import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium' -import {LogUtil} from '@ohos/imageknife' - -export default function LogUtilTest() { - describe('LogUtilTest', ()=> { - // Defines a test suite. Two parameters are supported: test suite name and test suite function. - beforeAll( ()=> { - // Presets an action, which is performed only once before all test cases of the test suite start. - // This API supports only one parameter: preset action function. - }) - beforeEach( ()=> { - // Presets an action, which is performed before each unit test case starts. - // The number of execution times is the same as the number of test cases defined by **it**. - // This API supports only one parameter: preset action function. - }) - afterEach( ()=> { - // Presets a clear action, which is performed after each unit test case ends. - // The number of execution times is the same as the number of test cases defined by **it**. - // This API supports only one parameter: clear action function. - }) - afterAll( ()=> { - // Presets a clear action, which is performed after all test cases of the test suite end. - // This API supports only one parameter: clear action function. - }) - it('TestLogUtilLevel',0, ()=> { - - - LogUtil.mLogLevel = LogUtil.OFF; - expect(LogUtil.mLogLevel).assertEqual(LogUtil.OFF); - - LogUtil.debug("你好! 第一条消息看不到!") - LogUtil.mLogLevel = LogUtil.DEBUG; - expect(LogUtil.mLogLevel).assertEqual(LogUtil.DEBUG) - LogUtil.debug("你好! 第二条消息可以查看!") - }) - }) -} \ No newline at end of file diff --git a/entry/src/ohosTest/ets/test/lrucache.test.ets b/entry/src/ohosTest/ets/test/lrucache.test.ets deleted file mode 100644 index ee73564..0000000 --- a/entry/src/ohosTest/ets/test/lrucache.test.ets +++ /dev/null @@ -1,188 +0,0 @@ -/* - * Copyright (C) 2023 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 hilog from '@ohos.hilog'; -import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium' -import {LruCache} from '@ohos/imageknife' // DiskLruCache用例由DiskLruCache三方库提供 - -const BASE_COUNT: number = 2000; - -export default function lruCacheTest() { - describe('lruCacheTest', ()=> { - // Defines a test suite. Two parameters are supported: test suite name and test suite function. - beforeAll( ()=> { - // Presets an action, which is performed only once before all test cases of the test suite start. - // This API supports only one parameter: preset action function. - }) - beforeEach( ()=> { - // Presets an action, which is performed before each unit test case starts. - // The number of execution times is the same as the number of test cases defined by **it**. - // This API supports only one parameter: preset action function. - }) - afterEach( ()=> { - // Presets a clear action, which is performed after each unit test case ends. - // The number of execution times is the same as the number of test cases defined by **it**. - // This API supports only one parameter: clear action function. - }) - afterAll( ()=> { - // Presets a clear action, which is performed after all test cases of the test suite end. - // This API supports only one parameter: clear action function. - }) - it('testLruCacheSize',0, ()=> { - // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. - let startTime = new Date().getTime(); - for (let index = 0; index < BASE_COUNT; index++) { - new LruCache(100); - } - endTime(startTime, 'testLruCacheSize'); - let memoryCache = new LruCache(100); - expect(memoryCache.size).assertEqual(0); - expect(memoryCache.maxsize).assertEqual(100) - }) - it('testLruCachePut',1, ()=> { - // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. - let memoryCache = new LruCache(5); - memoryCache.put("1","1"); - memoryCache.put("2","2"); - memoryCache.put("3","3"); - memoryCache.put("4","4"); - memoryCache.put("5","5"); - memoryCache.put("6","6"); - let startTime = new Date().getTime(); - for (let index = 0; index < BASE_COUNT; index++) { - memoryCache.put("7","7"); - } - endTime(startTime, 'testLruCachePut'); - - expect(memoryCache.maxsize).assertEqual(5) - let result = memoryCache.get("1") - expect(result).assertEqual(undefined) - }) - it('testLruCacheGet',2, ()=> { - // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. - let memoryCache = new LruCache(5); - memoryCache.put("1","1"); - memoryCache.put("2","2"); - memoryCache.put("3","3"); - memoryCache.put("4","4"); - memoryCache.put("5","5"); - memoryCache.put("6","6"); - - expect(memoryCache.maxsize).assertEqual(5) - let startTime = new Date().getTime(); - for (let index = 0; index < BASE_COUNT; index++) { - memoryCache.get("2"); - } - endTime(startTime, 'testLruCacheGet'); - let result = memoryCache.get("2") - expect(result).assertEqual("2") - }) - it('testLruCacheAlgorithm',3, ()=> { - // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. - let memoryCache = new LruCache(5); - memoryCache.put("1","1"); - memoryCache.put("2","2"); - memoryCache.put("3","3"); - memoryCache.put("4","4"); - memoryCache.put("5","5"); - - memoryCache.get("1"); - memoryCache.get("2"); - let count:number = 1 - let callback =(key:string,value:string)=>{ - if(count == 5){ - expect(key).assertEqual("2") - expect(value).assertEqual("2") - } - - count++; - } - memoryCache.foreachLruCache( (value:string, key:string, map:Map)=> { - callback(key,value) - }) - let startTime = new Date().getTime(); - for (let index = 0; index < BASE_COUNT; index++) { - memoryCache.foreachLruCache( (value:string, key:string, map:Map)=> { - callback(key,value) - }) - } - endTime(startTime, 'testLruCacheAlgorithm'); - expect(memoryCache.size).assertEqual(5) - - }) - it('testLruCacheRemove',4, ()=> { - // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. - let memoryCache = new LruCache(5); - memoryCache.put("1","1"); - memoryCache.put("2","2"); - memoryCache.put("3","3"); - memoryCache.put("4","4"); - memoryCache.put("5","5"); - - memoryCache.get("1"); - memoryCache.get("2"); - - memoryCache.remove("2"); - let startTime = new Date().getTime(); - for (let index = 0; index < BASE_COUNT; index++) { - memoryCache.remove("2"); - } - endTime(startTime, 'testLruCacheRemove'); - let count:number = 1 - let callback =(key:string,value:string)=>{ - if(count == 4){ - expect(key).assertEqual("1") - expect(value).assertEqual("1") - } - - count++; - } - memoryCache.foreachLruCache( (value:string, key:string, map:Map)=> { - callback(key,value) - }) - expect(memoryCache.size).assertEqual(4) - }) - it('testLruCacheResize',5, ()=> { - // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. - let memoryCache = new LruCache(5); - memoryCache.put("1","1"); - memoryCache.put("2","2"); - memoryCache.put("3","3"); - memoryCache.put("4","4"); - memoryCache.put("5","5"); - - memoryCache.resize(4); - - let startTime = new Date().getTime(); - for (let index = 0; index < BASE_COUNT; index++) { - memoryCache.resize(4); - } - endTime(startTime, 'testLruCacheResize'); - - let result1 = memoryCache.get("1"); - expect(result1).assertEqual(undefined); - let result2 = memoryCache.get("2"); - expect(result2).assertEqual("2"); - - }) - }) -} - -function endTime(startTime: number, tag: string) { - let endTime: number = new Date().getTime(); - let averageTime = ((endTime - startTime) * 1000 / BASE_COUNT) - console.info(tag + " startTime: " + endTime) - console.info(tag + " endTime: " + endTime) - console.log(tag + " averageTime: " + averageTime + "μs"); -} \ No newline at end of file diff --git a/entry/src/ohosTest/ets/test/requestoption.test.ets b/entry/src/ohosTest/ets/test/requestoption.test.ets deleted file mode 100644 index 52becb3..0000000 --- a/entry/src/ohosTest/ets/test/requestoption.test.ets +++ /dev/null @@ -1,103 +0,0 @@ - -/* - * Copyright (C) 2023 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 hilog from '@ohos.hilog'; -import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium' -import {RequestOption,Size} from '@ohos/imageknife' - -const BASE_COUNT: number = 2000; - -export default function RequestOptionTest() { - describe('RequestOptionTest', ()=> { - // Defines a test suite. Two parameters are supported: test suite name and test suite function. - beforeAll( ()=> { - // Presets an action, which is performed only once before all test cases of the test suite start. - // This API supports only one parameter: preset action function. - }) - beforeEach( ()=> { - // Presets an action, which is performed before each unit test case starts. - // The number of execution times is the same as the number of test cases defined by **it**. - // This API supports only one parameter: preset action function. - }) - afterEach( ()=> { - // Presets a clear action, which is performed after each unit test case ends. - // The number of execution times is the same as the number of test cases defined by **it**. - // This API supports only one parameter: clear action function. - }) - afterAll( ()=> { - // Presets a clear action, which is performed after all test cases of the test suite end. - // This API supports only one parameter: clear action function. - }) - it('TestRequestOption',0, ()=> { - let startTime = new Date().getTime(); - for (let index = 0; index < BASE_COUNT; index++) { - new RequestOption(); - } - endTime(startTime, 'TestRequestOption'); - let option = new RequestOption(); - if(option.requestListeners != undefined) { - expect(option.requestListeners.length == 0).assertTrue() - } - }) - it('TestConfigLoadSrc',1, ()=> { - let option = new RequestOption(); - expect(option.loadSrc).assertEqual('') - option.loadSrc = $r('app.media.icon') - let startTime = new Date().getTime(); - for (let index = 0; index < BASE_COUNT; index++) { - option.loadSrc = $r('app.media.icon'); - } - endTime(startTime, 'TestConfigLoadSrc'); - expect(JSON.stringify(option.loadSrc)).assertEqual(JSON.stringify($r('app.media.icon'))) - }) - it('TestConfigViewSize',2, ()=> { - let option = new RequestOption(); - option.loadSrc = '' - let size:Size = {width:100,height:100} - option.setImageViewSize(size) - let startTime = new Date().getTime(); - for (let index = 0; index < BASE_COUNT; index++) { - option.setImageViewSize(size); - } - endTime(startTime, 'TestConfigViewSize'); - expect(JSON.stringify(option.size)).assertEqual(JSON.stringify(size)) - }) - it('TestNormalConfigInfo',3, ()=>{ - let option = new RequestOption(); - expect(option.strategy.getName()).assertEqual('AUTOMATIC') - - expect(option.dontAnimateFlag).assertFalse() - - expect(option.onlyRetrieveFromCache).assertFalse() - - expect(option.isCacheable).assertTrue() - - expect(option.gpuEnabled).assertFalse() - expect(option.loadMainReady).assertFalse() - expect(option.loadErrorReady).assertFalse() - expect(option.loadRetryReady).assertFalse() - expect(option.loadThumbnailReady).assertFalse() - - }) - }) -} - -function endTime(startTime: number, tag: string) { - let endTime: number = new Date().getTime(); - let averageTime = ((endTime - startTime) * 1000 / BASE_COUNT) - console.info(tag + " startTime: " + endTime) - console.info(tag + " endTime: " + endTime) - console.log(tag + " averageTime: " + averageTime + "μs"); -} \ No newline at end of file diff --git a/entry/src/ohosTest/ets/test/transfrom.test.ets b/entry/src/ohosTest/ets/test/transfrom.test.ets deleted file mode 100644 index a029651..0000000 --- a/entry/src/ohosTest/ets/test/transfrom.test.ets +++ /dev/null @@ -1,261 +0,0 @@ -/* - * Copyright (C) 2023 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 hilog from '@ohos.hilog'; -import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium' -import { - BlurTransformation, - BrightnessFilterTransformation, - ContrastFilterTransformation, - CropCircleTransformation, - CropCircleWithBorderTransformation, - CropSquareTransformation, - CropTransformation, - CropType, - GrayscaleTransformation, - InvertFilterTransformation, - PixelationFilterTransformation, - RotateImageTransformation, - RoundedCornersTransformation, - SepiaFilterTransformation, - SketchFilterTransformation, - MaskTransformation, - SwirlFilterTransformation, - KuwaharaFilterTransform, - ToonFilterTransform, - VignetteFilterTransform, - -} from '@ohos/imageknife' - -const BASE_COUNT: number = 2000; - -export default function Transform() { - describe('Transform', ()=>{ - // Defines a test suite. Two parameters are supported: test suite name and test suite function. - beforeAll(()=>{ - // Presets an action, which is performed only once before all test cases of the test suite start. - // This API supports only one parameter: preset action function. - }) - beforeEach(()=>{ - // Presets an action, which is performed before each unit test case starts. - // The number of execution times is the same as the number of test cases defined by **it**. - // This API supports only one parameter: preset action function. - }) - afterEach(()=>{ - // Presets a clear action, which is performed after each unit test case ends. - // The number of execution times is the same as the number of test cases defined by **it**. - // This API supports only one parameter: clear action function. - }) - afterAll(()=>{ - // Presets a clear action, which is performed after all test cases of the test suite end. - // This API supports only one parameter: clear action function. - }) - it('TestBlurTransformation', 0, ()=>{ - let startTime = new Date().getTime(); - for (let index = 0; index < BASE_COUNT; index++) { - new BlurTransformation(15,3); - } - endTime(startTime, 'TestBlurTransformation'); - let blur = new BlurTransformation(15,3); - expect(blur.getName()).assertEqual('BlurTransformation _mRadius:15==BlurTransformation sampling:3') - }) - it('TestBrightnessFilterTransformation', 1, ()=>{ - let startTime = new Date().getTime(); - for (let index = 0; index < BASE_COUNT; index++) { - new BrightnessFilterTransformation(20); - } - endTime(startTime, 'TestBrightnessFilterTransformation'); - let bright = new BrightnessFilterTransformation(20); - expect(bright.getName()).assertEqual("BrightnessFilterTransformation:20") - }) - it('TestContrastFilterTransformation', 2, ()=>{ - let startTime = new Date().getTime(); - for (let index = 0; index < BASE_COUNT; index++) { - new ContrastFilterTransformation(30); - } - endTime(startTime, 'TestContrastFilterTransformation'); - let contrast = new ContrastFilterTransformation(30); - expect(contrast.getName()).assertEqual("ContrastFilterTransformation:30") - }) - it('TestCropCircleTransformation', 3, ()=>{ - let startTime = new Date().getTime(); - for (let index = 0; index < BASE_COUNT; index++) { - new CropCircleTransformation(); - } - endTime(startTime, 'TestCropCircleTransformation'); - let cropCircle = new CropCircleTransformation(); - expect(cropCircle.getName()).assertContain("CropCircleTransformation") - expect(cropCircle.getName()).assertContain(";mCenterX:") - expect(cropCircle.getName()).assertContain(";mCenterY:") - expect(cropCircle.getName()).assertContain(";mRadius:") - }) - it('TestCropCircleWithBorderTransformation', 4, ()=>{ - let startTime = new Date().getTime(); - for (let index = 0; index < BASE_COUNT; index++) { - new CropCircleWithBorderTransformation(10,{r_color:100,g_color:100,b_color:100 }); - } - endTime(startTime, 'TestCropCircleWithBorderTransformation'); - let CropCircleWithBorder = new CropCircleWithBorderTransformation(10,{r_color:100,g_color:100,b_color:100 }); - expect(CropCircleWithBorder.getName()).assertContain("CropCircleTransformation") - expect(CropCircleWithBorder.getName()).assertContain(";mCenterX:") - expect(CropCircleWithBorder.getName()).assertContain(";mCenterY:") - expect(CropCircleWithBorder.getName()).assertContain(";mRadius:") - expect(CropCircleWithBorder.getName()).assertContain(";mBorderSize:") - expect(CropCircleWithBorder.getName()).assertContain(";mRColor:") - expect(CropCircleWithBorder.getName()).assertContain(";mGColor:") - expect(CropCircleWithBorder.getName()).assertContain(";mBColor:") - }) - it('TestCropSquareTransformation', 5, ()=>{ - let startTime = new Date().getTime(); - for (let index = 0; index < BASE_COUNT; index++) { - new CropSquareTransformation(); - } - endTime(startTime, 'TestCropSquareTransformation'); - let CropSquare = new CropSquareTransformation(); - expect(CropSquare.getName()).assertContain("CropSquareTransformation") - }) - it('TestCropTransformation', 6, ()=>{ - let startTime = new Date().getTime(); - for (let index = 0; index < BASE_COUNT; index++) { - new CropTransformation(10,10,CropType.CENTER); - } - endTime(startTime, 'TestCropTransformation'); - let crop = new CropTransformation(10,10,CropType.CENTER); - expect(crop.getName()).assertContain("CropCircleTransformation"+ ";mWidth:10" + ";mHeight:10" + ";mCropType:1" ) - }) - it('TestGrayscaleTransformation', 7, ()=>{ - let startTime = new Date().getTime(); - for (let index = 0; index < BASE_COUNT; index++) { - new GrayscaleTransformation(); - } - endTime(startTime, 'TestGrayscaleTransformation'); - let grayscale = new GrayscaleTransformation(); - expect(grayscale.getName()).assertContain("GrayscaleTransformation" ) - }) - it('TestInvertFilterTransformation', 8, ()=>{ - let startTime = new Date().getTime(); - for (let index = 0; index < BASE_COUNT; index++) { - new InvertFilterTransformation(); - } - endTime(startTime, 'TestInvertFilterTransformation'); - let invert = new InvertFilterTransformation(); - expect(invert.getName()).assertContain("InvertFilterTransformation" ) - }) - it('TestPixelationFilterTransformation', 9, ()=>{ - let startTime = new Date().getTime(); - for (let index = 0; index < BASE_COUNT; index++) { - new PixelationFilterTransformation(); - } - endTime(startTime, 'TestPixelationFilterTransformation'); - let pixelation = new PixelationFilterTransformation(); - expect(pixelation.getName()).assertContain("PixelationFilterTransformation" ) - }) - it('TestRotateImageTransformation', 10, ()=>{ - let startTime = new Date().getTime(); - for (let index = 0; index < BASE_COUNT; index++) { - new RotateImageTransformation(180); - } - endTime(startTime, 'TestRotateImageTransformation'); - let rotateImage = new RotateImageTransformation(180); - expect(rotateImage.getName()).assertContain("RotateImageTransformation" + ";degreesToRotate:180") - }) - it('TestRoundedCornersTransformation', 11, ()=>{ - let startTime = new Date().getTime(); - for (let index = 0; index < BASE_COUNT; index++) { - new RoundedCornersTransformation({top_left:5,bottom_left:5,top_right:5,bottom_right:5}); - } - endTime(startTime, 'TestRoundedCornersTransformation'); - let roundConer = new RoundedCornersTransformation({top_left:5,bottom_left:5,top_right:5,bottom_right:5}); - expect(roundConer.getName()).assertContain("RoundedCornersTransformation" + ";mTop_left:" + 5 - + ";mTop_right:" + 5 - + ";mBottom_left:" + 5 - + ";mBottom_right:" + 5) - }) - it('TestSepiaFilterTransformation', 12, ()=>{ - let startTime = new Date().getTime(); - for (let index = 0; index < BASE_COUNT; index++) { - new SepiaFilterTransformation(); - } - endTime(startTime, 'TestSepiaFilterTransformation'); - let speia = new SepiaFilterTransformation(); - expect(speia.getName()).assertContain("SepiaFilterTransformation") - }) - it('TestSketchFilterTransformation', 13, ()=>{ - let startTime = new Date().getTime(); - for (let index = 0; index < BASE_COUNT; index++) { - new SketchFilterTransformation(); - } - endTime(startTime, 'TestSketchFilterTransformation'); - let Sketch = new SketchFilterTransformation(); - expect(Sketch.getName()).assertContain("SketchFilterTransformation") - }) - it('TestMaskTransformation', 14, ()=>{ - let startTime = new Date().getTime(); - for (let index = 0; index < BASE_COUNT; index++) { - new MaskTransformation($r('app.media.icon')); - } - endTime(startTime, 'TestMaskTransformation'); - let mask = new MaskTransformation($r('app.media.icon')); - expect(mask.getName()).assertContain("MaskTransformation") - }) - it('TestSwirlFilterTransformation', 15, ()=>{ - let startTime = new Date().getTime(); - for (let index = 0; index < BASE_COUNT; index++) { - new SwirlFilterTransformation(10,180,[10,10]); - } - endTime(startTime, 'TestSwirlFilterTransformation'); - let swirl = new SwirlFilterTransformation(10,180,[10,10]); - expect(swirl.getName()).assertContain("SwirlFilterTransformation") - }) - it('TestKuwaharaFilterTransform', 16, ()=>{ - let startTime = new Date().getTime(); - for (let index = 0; index < BASE_COUNT; index++) { - new KuwaharaFilterTransform(10); - } - endTime(startTime, 'TestKuwaharaFilterTransform'); - let kuwahara = new KuwaharaFilterTransform(10); - expect(kuwahara.getName()).assertContain("KuwaharaFilterTransform _mRadius:10") - }) - it('TestToonFilterTransform', 17, ()=>{ - let startTime = new Date().getTime(); - for (let index = 0; index < BASE_COUNT; index++) { - new ToonFilterTransform(10); - } - endTime(startTime, 'TestToonFilterTransform'); - let toon = new ToonFilterTransform(10); - expect(toon.getName()).assertContain("ToonFilterTransform threshold:") - expect(toon.getName()).assertContain(";quantizationLevels:") - }) - it('TestVignetteFilterTransform', 18, ()=>{ - let startTime = new Date().getTime(); - for (let index = 0; index < BASE_COUNT; index++) { - new VignetteFilterTransform([0.5, 0.5],[0.0, 0.0, 0.0],[0.3, 0.75]); - } - endTime(startTime, 'TestVignetteFilterTransform'); - let vignette = new VignetteFilterTransform([0.5, 0.5],[0.0, 0.0, 0.0],[0.3, 0.75]); - expect(vignette.getName()).assertContain("VignetteFilterTransform centerPoint:") - expect(vignette.getName()).assertContain(";vignetteColor:") - expect(vignette.getName()).assertContain(";vignetteSpace:") - }) - - }) -} - -function endTime(startTime: number, tag: string) { - let endTime: number = new Date().getTime(); - let averageTime = ((endTime - startTime) * 1000 / BASE_COUNT) - console.info(tag + " startTime: " + endTime) - console.info(tag + " endTime: " + endTime) - console.log(tag + " averageTime: " + averageTime + "μs"); -} \ No newline at end of file diff --git a/entry/src/ohosTest/ets/testability/TestAbility.ets b/entry/src/ohosTest/ets/testability/TestAbility.ets index 1860105..628af01 100644 --- a/entry/src/ohosTest/ets/testability/TestAbility.ets +++ b/entry/src/ohosTest/ets/testability/TestAbility.ets @@ -1,13 +1,13 @@ /* - * Copyright (C) 2023 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); + * 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, + * 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. @@ -18,46 +18,50 @@ import hilog from '@ohos.hilog'; import { Hypium } from '@ohos/hypium'; import testsuite from '../test/List.test'; import window from '@ohos.window'; -import {ImageKnife,ImageKnifeDrawFactory,ImageKnifeGlobal} from '@ohos/libraryimageknife' -import AbilityConstant from '@ohos.app.ability.AbilityConstant'; import Want from '@ohos.app.ability.Want'; -import { BusinessError } from '@ohos.base' -import {GlobalContext } from './GlobalContext' +import AbilityConstant from '@ohos.app.ability.AbilityConstant'; +import { GlobalContext } from '../../../main/ets/common/GlobalContext'; + export default class TestAbility extends UIAbility { - onCreate(want: Want, param: AbilityConstant.LaunchParam) { + onCreate(want: Want, launchParam: AbilityConstant.LaunchParam) { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onCreate'); + hilog.info(0x0000, 'testTag', '%{public}s', 'want param:' + JSON.stringify(want) ?? ''); + hilog.info(0x0000, 'testTag', '%{public}s', 'launchParam:' + JSON.stringify(launchParam) ?? ''); + let abilityDelegator: AbilityDelegatorRegistry.AbilityDelegator; + abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator(); + let abilityDelegatorArguments: AbilityDelegatorRegistry.AbilityDelegatorArgs; + abilityDelegatorArguments = AbilityDelegatorRegistry.getArguments(); + hilog.info(0x0000, 'testTag', '%{public}s', 'start run testcase!!!'); + Hypium.hypiumTest(abilityDelegator, abilityDelegatorArguments, testsuite); + } - let abilityDelegator: AbilityDelegatorRegistry.AbilityDelegator - abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator() - let abilityDelegatorArguments: AbilityDelegatorRegistry.AbilityDelegatorArgs - abilityDelegatorArguments = AbilityDelegatorRegistry.getArguments() + onDestroy() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onDestroy'); + } - Hypium.hypiumTest(abilityDelegator, abilityDelegatorArguments, testsuite) - // 初始化xts的ImageKnife - ImageKnife.with(this.context.createModuleContext("entry_test")); - GlobalContext.getInstance().setObject("hapContext",this.context.createModuleContext("entry_test")); - GlobalContext.getInstance().setObject("filesDir",this.context.createModuleContext("entry_test").filesDir); - } + onWindowStageCreate(windowStage: window.WindowStage) { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onWindowStageCreate'); + GlobalContext.getContext().setObject("context", this.context); + GlobalContext.getContext().setObject("cacheDir", this.context.cacheDir); + windowStage.loadContent('testability/pages/Index', (err, data) => { + if (err.code) { + hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? ''); + return; + } + hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. Data: %{public}s', + JSON.stringify(data) ?? ''); + }); + } - onDestroy() { + onWindowStageDestroy() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onWindowStageDestroy'); + } - } + onForeground() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onForeground'); + } - onWindowStageCreate(windowStage: window.WindowStage) { - - windowStage.loadContent('testability/pages/Index', (err:BusinessError, data:void) => { - - }); - } - - onWindowStageDestroy() { - hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onWindowStageDestroy'); - } - - onForeground() { - hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onForeground'); - } - - onBackground() { - hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onBackground'); - } + onBackground() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onBackground'); + } } \ No newline at end of file diff --git a/entry/src/ohosTest/ets/testability/pages/Index.ets b/entry/src/ohosTest/ets/testability/pages/Index.ets index 19ddc97..98be4ce 100644 --- a/entry/src/ohosTest/ets/testability/pages/Index.ets +++ b/entry/src/ohosTest/ets/testability/pages/Index.ets @@ -1,50 +1,31 @@ /* - * Copyright (C) 2023 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); + * 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, + * 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 hilog from '@ohos.hilog'; - @Entry @Component struct Index { + @State message: string = 'Hello World'; - aboutToAppear() { - hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility index aboutToAppear'); + build() { + Row() { + Column() { + Text(this.message) + .fontSize(50) + .fontWeight(FontWeight.Bold) + } + .width('100%') + } + .height('100%') } - - @State message: string = 'Hello World' - build() { - Row() { - Column() { - Text(this.message) - .fontSize(50) - .fontWeight(FontWeight.Bold) - Button() { - Text('next page') - .fontSize(20) - .fontWeight(FontWeight.Bold) - }.type(ButtonType.Capsule) - .margin({ - top: 20 - }) - .backgroundColor('#0D9FFB') - .width('35%') - .height('5%') - .onClick(()=>{ - }) - } - .width('100%') - } - .height('100%') - } - } \ No newline at end of file +} \ No newline at end of file diff --git a/entry/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ets b/entry/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ets new file mode 100644 index 0000000..9d981ea --- /dev/null +++ b/entry/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ets @@ -0,0 +1,64 @@ +/* + * 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 hilog from '@ohos.hilog'; +import TestRunner from '@ohos.application.testRunner'; +import AbilityDelegatorRegistry from '@ohos.app.ability.abilityDelegatorRegistry'; +import Want from '@ohos.app.ability.Want'; + +let abilityDelegator: AbilityDelegatorRegistry.AbilityDelegator | undefined = undefined +let abilityDelegatorArguments: AbilityDelegatorRegistry.AbilityDelegatorArgs | undefined = undefined + +async function onAbilityCreateCallback() { + hilog.info(0x0000, 'testTag', '%{public}s', 'onAbilityCreateCallback'); +} + +async function addAbilityMonitorCallback(err : Error) { + hilog.info(0x0000, 'testTag', 'addAbilityMonitorCallback : %{public}s', JSON.stringify(err) ?? ''); +} + +export default class OpenHarmonyTestRunner implements TestRunner { + constructor() { + } + + onPrepare() { + hilog.info(0x0000, 'testTag', '%{public}s', 'OpenHarmonyTestRunner OnPrepare '); + } + + async onRun() { + hilog.info(0x0000, 'testTag', '%{public}s', 'OpenHarmonyTestRunner onRun run'); + abilityDelegatorArguments = AbilityDelegatorRegistry.getArguments() + abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator() + const bundleName = abilityDelegatorArguments.bundleName; + const testAbilityName = 'TestAbility'; + const moduleName = abilityDelegatorArguments.parameters['-m']; + let lMonitor: AbilityDelegatorRegistry.AbilityMonitor = { + abilityName: testAbilityName, + onAbilityCreate: onAbilityCreateCallback, + moduleName: moduleName + }; + abilityDelegator.addAbilityMonitor(lMonitor, addAbilityMonitorCallback) + const want: Want = { + bundleName: bundleName, + abilityName: testAbilityName, + moduleName: moduleName + }; + abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator(); + abilityDelegator.startAbility(want, (err, data) => { + hilog.info(0x0000, 'testTag', 'startAbility : err : %{public}s', JSON.stringify(err) ?? ''); + hilog.info(0x0000, 'testTag', 'startAbility : data : %{public}s',JSON.stringify(data) ?? ''); + }) + hilog.info(0x0000, 'testTag', '%{public}s', 'OpenHarmonyTestRunner onRun end'); + } +} \ No newline at end of file diff --git a/entry/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ts b/entry/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ts deleted file mode 100644 index 063887c..0000000 --- a/entry/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ts +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (C) 2023 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 hilog from '@ohos.hilog'; -import TestRunner from '@ohos.application.testRunner'; -import AbilityDelegatorRegistry from '@ohos.app.ability.abilityDelegatorRegistry'; - -var abilityDelegator = undefined -var abilityDelegatorArguments = undefined - -async function onAbilityCreateCallback() { - hilog.info(0x0000, 'testTag', '%{public}s', 'onAbilityCreateCallback'); -} - -async function addAbilityMonitorCallback(err: any) { - hilog.info(0x0000, 'testTag', 'addAbilityMonitorCallback : %{public}s', JSON.stringify(err) ?? ''); -} - -export default class OpenHarmonyTestRunner implements TestRunner { - constructor() { - } - - onPrepare() { - hilog.info(0x0000, 'testTag', '%{public}s', 'OpenHarmonyTestRunner OnPrepare '); - } - - async onRun() { - hilog.info(0x0000, 'testTag', '%{public}s', 'OpenHarmonyTestRunner onRun run'); - abilityDelegatorArguments = AbilityDelegatorRegistry.getArguments() - abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator() - var testAbilityName = abilityDelegatorArguments.bundleName + '.TestAbility' - let lMonitor = { - abilityName: testAbilityName, - onAbilityCreate: onAbilityCreateCallback, - }; - abilityDelegator.addAbilityMonitor(lMonitor, addAbilityMonitorCallback) - var cmd = 'aa start -d 0 -a TestAbility' + ' -b ' + abilityDelegatorArguments.bundleName - var debug = abilityDelegatorArguments.parameters['-D'] - if (debug == 'true') - { - cmd += ' -D' - } - hilog.info(0x0000, 'testTag', 'cmd : %{public}s', cmd); - abilityDelegator.executeShellCommand(cmd, - (err: any, d: any) => { - hilog.info(0x0000, 'testTag', 'executeShellCommand : err : %{public}s', JSON.stringify(err) ?? ''); - hilog.info(0x0000, 'testTag', 'executeShellCommand : data : %{public}s', d.stdResult ?? ''); - hilog.info(0x0000, 'testTag', 'executeShellCommand : data : %{public}s', d.exitCode ?? ''); - }) - hilog.info(0x0000, 'testTag', '%{public}s', 'OpenHarmonyTestRunner onRun end'); - } -} \ No newline at end of file diff --git a/entry/src/ohosTest/module.json5 b/entry/src/ohosTest/module.json5 index cf29076..d0dc5d5 100644 --- a/entry/src/ohosTest/module.json5 +++ b/entry/src/ohosTest/module.json5 @@ -2,19 +2,16 @@ "module": { "name": "entry_test", "type": "feature", - "srcEntrance": "./ets/testability/TestAbility.ets", "description": "$string:module_test_desc", "mainElement": "TestAbility", - "deviceTypes": ["default"], + "deviceTypes": [ + "phone", + "tablet", + "2in1" + ], "deliveryWithInstall": true, "installationFree": false, "pages": "$profile:test_pages", - "metadata": [ - { - "name": "ArkTSPartialUpdate", - "value": "true" - } - ], "abilities": [ { "name": "TestAbility", diff --git a/entry/src/ohosTest/resources/base/media/icon.png b/entry/src/ohosTest/resources/base/media/icon.png index ce307a8..cd45acc 100644 Binary files a/entry/src/ohosTest/resources/base/media/icon.png and b/entry/src/ohosTest/resources/base/media/icon.png differ diff --git a/entry/src/ohosTest/resources/base/profile/test_pages.json b/entry/src/ohosTest/resources/base/profile/test_pages.json index 2d90c65..b7e7343 100644 --- a/entry/src/ohosTest/resources/base/profile/test_pages.json +++ b/entry/src/ohosTest/resources/base/profile/test_pages.json @@ -1,5 +1,5 @@ { "src": [ - "testability/pages/index" + "testability/pages/Index" ] } diff --git a/entry/src/test/List.test.ets b/entry/src/test/List.test.ets new file mode 100644 index 0000000..7a855c1 --- /dev/null +++ b/entry/src/test/List.test.ets @@ -0,0 +1,5 @@ +import MemoryLruCacheTest from './MemoryLruCache.test'; + +export default function testsuite() { + MemoryLruCacheTest(); +} \ No newline at end of file diff --git a/entry/src/test/MemoryLruCache.test.ets b/entry/src/test/MemoryLruCache.test.ets new file mode 100644 index 0000000..848438b --- /dev/null +++ b/entry/src/test/MemoryLruCache.test.ets @@ -0,0 +1,98 @@ +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'; +import image from '@ohos.multimedia.image'; + +import { ImageKnifeData } from '@ohos/imageword/src/main/ets/model/ImageKnifeData'; +import { MemoryLruCache } from '@ohos/imageword/src/main/ets/utils/MemoryLruCache'; + +export default function MemoryLruCacheTest() { + describe('MemoryLruCacheTest',() => { + // Defines a test suite. Two parameters are supported: test suite name and test suite function. + beforeAll(() => { + // Presets an action, which is performed only once before all test cases of the test suite start. + // This API supports only one parameter: preset action function. + }); + beforeEach(() => { + // Presets an action, which is performed before each unit test case starts. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: preset action function. + }); + afterEach(() => { + // Presets a clear action, which is performed after each unit test case ends. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: clear action function. + }); + afterAll(() => { + // Presets a clear action, which is performed after all test cases of the test suite end. + // This API supports only one parameter: clear action function. + }); + + // 测试基础put,get以及size功能 + it('assertBasicFunction', 0, async () => { + let memoryCache: MemoryLruCache = new MemoryLruCache(3, 3 * 1024 * 1024); + + let data: ImageKnifeData = await getNewImageKnifeData() + memoryCache.put("aaa", data) + memoryCache.put("bbb", data) + memoryCache.put("ccc", data) + + console.info(JSON.stringify(memoryCache.get("aaa"))) + console.info(memoryCache.size() + "") + // expect(memoryCache.size()).assertEqual(3) + console.info("1111111") + // expect(memoryCache.get("aaa")).assertEqual(data) + // expect(memoryCache.get("bbb")).assertEqual(data) + // expect(memoryCache.get("ccc")).assertEqual(data) + // expect(memoryCache.size()).assertEqual(3) + // + // memoryCache.remove("ccc") + // memoryCache.remove("ddd") + // expect(memoryCache.size()).assertEqual(2) + // + // memoryCache.removeAll() + // expect(memoryCache.size()).assertEqual(0) + }); + + // it('assertSizeLruFuction', 0, async () => { + // let memoryCache: MemoryLruCache = new MemoryLruCache(3, 3 * 1024 * 1024); + // + // let data: ImageKnifeData = await getNewImageKnifeData() + // memoryCache.put("aaa", data) + // memoryCache.put("bbb", data) + // memoryCache.put("ccc", data) + // memoryCache.put("ddd", data) + // + // expect(memoryCache.get("aaa")).assertUndefined() + // expect(memoryCache.get("bbb")).assertEqual(data) + // memoryCache.put("eee", data) + // expect(memoryCache.get("ccc")).assertUndefined() + // expect(memoryCache.get("bbb")).assertEqual(data) + // expect(memoryCache.get("ddd")).assertEqual(data) + // expect(memoryCache.get("eee")).assertEqual(data) + // }); + // + // it('assertMemorySizeLruFuction', 0, () => { + // // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. + // let a = 'abc'; + // let b = 'b'; + // // Defines a variety of assertion methods, which are used to declare expected boolean conditions. + // expect(a).assertContain(b); + // expect(a).assertEqual(a); + // }); + }); +} + +async function getNewImageKnifeData(): Promise { + const color: ArrayBuffer = new ArrayBuffer(96); //96为需要创建的像素buffer大小,取值为:height * width *4 + let opts: image.InitializationOptions = { + editable: true, pixelFormat: 3, size: { + height: 4, width: 6 + } + } + let pixelmap: PixelMap = await image.createPixelMap(color, opts) + let data: ImageKnifeData = { + source: pixelmap, + imageWidth: 5, + imageHeight: 5 + } + return data +} \ No newline at end of file diff --git a/hvigor/hvigor-config.json5 b/hvigor/hvigor-config.json5 index 122677b..efe6aee 100644 --- a/hvigor/hvigor-config.json5 +++ b/hvigor/hvigor-config.json5 @@ -1,6 +1,22 @@ { - "hvigorVersion": "3.0.9", + "hvigorVersion": "4.0.2", "dependencies": { - "@ohos/hvigor-ohos-plugin": "3.0.9" + "@ohos/hvigor-ohos-plugin": "4.0.2" + }, + "execution": { + // "analyze": "default", /* Define the build analyze mode. Value: [ "default" | "verbose" | false ]. Default: "default" */ + // "daemon": true, /* Enable daemon compilation. Value: [ true | false ]. Default: true */ + // "incremental": true, /* Enable incremental compilation. Value: [ true | false ]. Default: true */ + // "parallel": true, /* Enable parallel compilation. Value: [ true | false ]. Default: true */ + // "typeCheck": false, /* Enable typeCheck. Value: [ true | false ]. Default: false */ + }, + "logging": { + // "level": "info" /* Define the log level. Value: [ "debug" | "info" | "warn" | "error" ]. Default: "info" */ + }, + "debugging": { + // "stacktrace": false /* Disable stacktrace compilation. Value: [ true | false ]. Default: false */ + }, + "nodeOptions": { + // "maxOldSpaceSize": 4096 /* Enable nodeOptions maxOldSpaceSize compilation. Unit M. Used for the daemon process */ } } \ No newline at end of file diff --git a/hvigor/hvigor-wrapper.js b/hvigor/hvigor-wrapper.js index 994f229..372eae8 100644 --- a/hvigor/hvigor-wrapper.js +++ b/hvigor/hvigor-wrapper.js @@ -1,2 +1 @@ -"use strict";var e=require("fs"),t=require("path"),n=require("os"),r=require("crypto"),u=require("child_process"),o=require("constants"),i=require("stream"),s=require("util"),c=require("assert"),a=require("tty"),l=require("zlib"),f=require("net");function d(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var D=d(e),p=d(t),E=d(n),m=d(r),h=d(u),y=d(o),C=d(i),F=d(s),g=d(c),A=d(a),v=d(l),S=d(f),w="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{},O={},b={},_={},B=w&&w.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(_,"__esModule",{value:!0}),_.isMac=_.isLinux=_.isWindows=void 0;const P=B(E.default),k="Windows_NT",x="Linux",N="Darwin";_.isWindows=function(){return P.default.type()===k},_.isLinux=function(){return P.default.type()===x},_.isMac=function(){return P.default.type()===N};var I={},T=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),R=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),M=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&T(t,e,n);return R(t,e),t};Object.defineProperty(I,"__esModule",{value:!0}),I.hash=void 0;const L=M(m.default);I.hash=function(e,t="md5"){return L.createHash(t).update(e,"utf-8").digest("hex")},function(e){var t=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),n=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),r=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var r={};if(null!=e)for(var u in e)"default"!==u&&Object.prototype.hasOwnProperty.call(e,u)&&t(r,e,u);return n(r,e),r};Object.defineProperty(e,"__esModule",{value:!0}),e.HVIGOR_BOOT_JS_FILE_PATH=e.HVIGOR_PROJECT_DEPENDENCY_PACKAGE_JSON_PATH=e.HVIGOR_PROJECT_DEPENDENCIES_HOME=e.HVIGOR_PROJECT_WRAPPER_HOME=e.HVIGOR_PROJECT_NAME=e.HVIGOR_PROJECT_ROOT_DIR=e.HVIGOR_PROJECT_CACHES_HOME=e.HVIGOR_PNPM_STORE_PATH=e.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH=e.HVIGOR_WRAPPER_TOOLS_HOME=e.HVIGOR_USER_HOME=e.DEFAULT_PACKAGE_JSON=e.DEFAULT_HVIGOR_CONFIG_JSON_FILE_NAME=e.PNPM=e.HVIGOR=e.NPM_TOOL=e.PNPM_TOOL=e.HVIGOR_ENGINE_PACKAGE_NAME=void 0;const u=r(p.default),o=r(E.default),i=_,s=I;e.HVIGOR_ENGINE_PACKAGE_NAME="@ohos/hvigor",e.PNPM_TOOL=(0,i.isWindows)()?"pnpm.cmd":"pnpm",e.NPM_TOOL=(0,i.isWindows)()?"npm.cmd":"npm",e.HVIGOR="hvigor",e.PNPM="pnpm",e.DEFAULT_HVIGOR_CONFIG_JSON_FILE_NAME="hvigor-config.json5",e.DEFAULT_PACKAGE_JSON="package.json",e.HVIGOR_USER_HOME=u.resolve(o.homedir(),".hvigor"),e.HVIGOR_WRAPPER_TOOLS_HOME=u.resolve(e.HVIGOR_USER_HOME,"wrapper","tools"),e.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH=u.resolve(e.HVIGOR_WRAPPER_TOOLS_HOME,"node_modules",".bin",e.PNPM_TOOL),e.HVIGOR_PNPM_STORE_PATH=u.resolve(e.HVIGOR_USER_HOME,"caches"),e.HVIGOR_PROJECT_CACHES_HOME=u.resolve(e.HVIGOR_USER_HOME,"project_caches"),e.HVIGOR_PROJECT_ROOT_DIR=process.cwd(),e.HVIGOR_PROJECT_NAME=u.basename((0,s.hash)(e.HVIGOR_PROJECT_ROOT_DIR)),e.HVIGOR_PROJECT_WRAPPER_HOME=u.resolve(e.HVIGOR_PROJECT_ROOT_DIR,e.HVIGOR),e.HVIGOR_PROJECT_DEPENDENCIES_HOME=u.resolve(e.HVIGOR_PROJECT_CACHES_HOME,e.HVIGOR_PROJECT_NAME,"workspace"),e.HVIGOR_PROJECT_DEPENDENCY_PACKAGE_JSON_PATH=u.resolve(e.HVIGOR_PROJECT_DEPENDENCIES_HOME,e.DEFAULT_PACKAGE_JSON),e.HVIGOR_BOOT_JS_FILE_PATH=u.resolve(e.HVIGOR_PROJECT_DEPENDENCIES_HOME,"node_modules","@ohos","hvigor","bin","hvigor.js")}(b);var j={},$={};Object.defineProperty($,"__esModule",{value:!0}),$.logInfoPrintConsole=$.logErrorAndExit=void 0,$.logErrorAndExit=function(e){e instanceof Error?console.error(e.message):console.error(e),process.exit(-1)},$.logInfoPrintConsole=function(e){console.log(e)};var H=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),J=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),G=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&H(t,e,n);return J(t,e),t},V=w&&w.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(j,"__esModule",{value:!0}),j.isFileExists=j.offlinePluginConversion=j.executeCommand=j.getNpmPath=j.hasNpmPackInPaths=void 0;const U=h.default,W=G(p.default),z=b,K=$,q=V(D.default);j.hasNpmPackInPaths=function(e,t){try{return require.resolve(e,{paths:[...t]}),!0}catch(e){return!1}},j.getNpmPath=function(){const e=process.execPath;return W.join(W.dirname(e),z.NPM_TOOL)},j.executeCommand=function(e,t,n){0!==(0,U.spawnSync)(e,t,n).status&&(0,K.logErrorAndExit)(`Error: ${e} ${t} execute failed.See above for details.`)},j.offlinePluginConversion=function(e,t){return t.startsWith("file:")||t.endsWith(".tgz")?W.resolve(e,z.HVIGOR,t.replace("file:","")):t},j.isFileExists=function(e){return q.default.existsSync(e)&&q.default.statSync(e).isFile()},function(e){var t=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),n=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),r=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var r={};if(null!=e)for(var u in e)"default"!==u&&Object.prototype.hasOwnProperty.call(e,u)&&t(r,e,u);return n(r,e),r},u=w&&w.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(e,"__esModule",{value:!0}),e.executeInstallPnpm=e.isPnpmAvailable=e.environmentHandler=e.checkNpmConifg=e.PNPM_VERSION=void 0;const o=r(D.default),i=b,s=j,c=r(p.default),a=$,l=h.default,f=u(E.default);e.PNPM_VERSION="7.30.0",e.checkNpmConifg=function(){const e=c.resolve(i.HVIGOR_PROJECT_ROOT_DIR,".npmrc"),t=c.resolve(f.default.homedir(),".npmrc");if((0,s.isFileExists)(e)||(0,s.isFileExists)(t))return;const n=(0,s.getNpmPath)(),r=(0,l.spawnSync)(n,["config","get","prefix"],{cwd:i.HVIGOR_PROJECT_ROOT_DIR});if(0!==r.status||!r.stdout)return void(0,a.logErrorAndExit)("Error: The hvigor depends on the npmrc file. Configure the npmrc file first.");const u=c.resolve(`${r.stdout}`.replace(/[\r\n]/gi,""),".npmrc");(0,s.isFileExists)(u)||(0,a.logErrorAndExit)("Error: The hvigor depends on the npmrc file. Configure the npmrc file first.")},e.environmentHandler=function(){process.env["npm_config_update-notifier"]="false"},e.isPnpmAvailable=function(){return!!o.existsSync(i.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH)&&(0,s.hasNpmPackInPaths)("pnpm",[i.HVIGOR_WRAPPER_TOOLS_HOME])},e.executeInstallPnpm=function(){(0,a.logInfoPrintConsole)(`Installing pnpm@${e.PNPM_VERSION}...`);const t=(0,s.getNpmPath)();!function(){const t=c.resolve(i.HVIGOR_WRAPPER_TOOLS_HOME,i.DEFAULT_PACKAGE_JSON);try{o.existsSync(i.HVIGOR_WRAPPER_TOOLS_HOME)||o.mkdirSync(i.HVIGOR_WRAPPER_TOOLS_HOME,{recursive:!0});const n={dependencies:{}};n.dependencies[i.PNPM]=e.PNPM_VERSION,o.writeFileSync(t,JSON.stringify(n))}catch(e){(0,a.logErrorAndExit)(`Error: EPERM: operation not permitted,create ${t} failed.`)}}(),(0,s.executeCommand)(t,["install","pnpm"],{cwd:i.HVIGOR_WRAPPER_TOOLS_HOME,stdio:["inherit","inherit","inherit"],env:process.env}),(0,a.logInfoPrintConsole)("Pnpm install success.")}}(O);var Y={},X={},Z={},Q={};Object.defineProperty(Q,"__esModule",{value:!0}),Q.Unicode=void 0;class ee{}Q.Unicode=ee,ee.Space_Separator=/[\u1680\u2000-\u200A\u202F\u205F\u3000]/,ee.ID_Start=/[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u0860-\u086A\u08A0-\u08B4\u08B6-\u08BD\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u09FC\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0AF9\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C60\u0C61\u0C80\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D54-\u0D56\u0D5F-\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u1884\u1887-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1C80-\u1C88\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312E\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FEA\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AE\uA7B0-\uA7B7\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA8FD\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDE80-\uDE9C\uDEA0-\uDED0\uDF00-\uDF1F\uDF2D-\uDF4A\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE4\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC03-\uDC37\uDC83-\uDCAF\uDCD0-\uDCE8\uDD03-\uDD26\uDD50-\uDD72\uDD76\uDD83-\uDDB2\uDDC1-\uDDC4\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE2B\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEDE\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF50\uDF5D-\uDF61]|\uD805[\uDC00-\uDC34\uDC47-\uDC4A\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDD80-\uDDAE\uDDD8-\uDDDB\uDE00-\uDE2F\uDE44\uDE80-\uDEAA\uDF00-\uDF19]|\uD806[\uDCA0-\uDCDF\uDCFF\uDE00\uDE0B-\uDE32\uDE3A\uDE50\uDE5C-\uDE83\uDE86-\uDE89\uDEC0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC2E\uDC40\uDC72-\uDC8F\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD30\uDD46]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD81C-\uD820\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDED0-\uDEED\uDF00-\uDF2F\uDF40-\uDF43\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50\uDF93-\uDF9F\uDFE0\uDFE1]|\uD821[\uDC00-\uDFEC]|\uD822[\uDC00-\uDEF2]|\uD82C[\uDC00-\uDD1E\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB]|\uD83A[\uDC00-\uDCC4\uDD00-\uDD43]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]/,ee.ID_Continue=/[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0300-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u0483-\u0487\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u05D0-\u05EA\u05F0-\u05F2\u0610-\u061A\u0620-\u0669\u066E-\u06D3\u06D5-\u06DC\u06DF-\u06E8\u06EA-\u06FC\u06FF\u0710-\u074A\u074D-\u07B1\u07C0-\u07F5\u07FA\u0800-\u082D\u0840-\u085B\u0860-\u086A\u08A0-\u08B4\u08B6-\u08BD\u08D4-\u08E1\u08E3-\u0963\u0966-\u096F\u0971-\u0983\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BC-\u09C4\u09C7\u09C8\u09CB-\u09CE\u09D7\u09DC\u09DD\u09DF-\u09E3\u09E6-\u09F1\u09FC\u0A01-\u0A03\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A59-\u0A5C\u0A5E\u0A66-\u0A75\u0A81-\u0A83\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABC-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AD0\u0AE0-\u0AE3\u0AE6-\u0AEF\u0AF9-\u0AFF\u0B01-\u0B03\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3C-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B5C\u0B5D\u0B5F-\u0B63\u0B66-\u0B6F\u0B71\u0B82\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD0\u0BD7\u0BE6-\u0BEF\u0C00-\u0C03\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C58-\u0C5A\u0C60-\u0C63\u0C66-\u0C6F\u0C80-\u0C83\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBC-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CDE\u0CE0-\u0CE3\u0CE6-\u0CEF\u0CF1\u0CF2\u0D00-\u0D03\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D44\u0D46-\u0D48\u0D4A-\u0D4E\u0D54-\u0D57\u0D5F-\u0D63\u0D66-\u0D6F\u0D7A-\u0D7F\u0D82\u0D83\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DE6-\u0DEF\u0DF2\u0DF3\u0E01-\u0E3A\u0E40-\u0E4E\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB9\u0EBB-\u0EBD\u0EC0-\u0EC4\u0EC6\u0EC8-\u0ECD\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F18\u0F19\u0F20-\u0F29\u0F35\u0F37\u0F39\u0F3E-\u0F47\u0F49-\u0F6C\u0F71-\u0F84\u0F86-\u0F97\u0F99-\u0FBC\u0FC6\u1000-\u1049\u1050-\u109D\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u135D-\u135F\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1714\u1720-\u1734\u1740-\u1753\u1760-\u176C\u176E-\u1770\u1772\u1773\u1780-\u17D3\u17D7\u17DC\u17DD\u17E0-\u17E9\u180B-\u180D\u1810-\u1819\u1820-\u1877\u1880-\u18AA\u18B0-\u18F5\u1900-\u191E\u1920-\u192B\u1930-\u193B\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19D9\u1A00-\u1A1B\u1A20-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AA7\u1AB0-\u1ABD\u1B00-\u1B4B\u1B50-\u1B59\u1B6B-\u1B73\u1B80-\u1BF3\u1C00-\u1C37\u1C40-\u1C49\u1C4D-\u1C7D\u1C80-\u1C88\u1CD0-\u1CD2\u1CD4-\u1CF9\u1D00-\u1DF9\u1DFB-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u203F\u2040\u2054\u2071\u207F\u2090-\u209C\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D7F-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2DE0-\u2DFF\u2E2F\u3005-\u3007\u3021-\u302F\u3031-\u3035\u3038-\u303C\u3041-\u3096\u3099\u309A\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312E\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FEA\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66F\uA674-\uA67D\uA67F-\uA6F1\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AE\uA7B0-\uA7B7\uA7F7-\uA827\uA840-\uA873\uA880-\uA8C5\uA8D0-\uA8D9\uA8E0-\uA8F7\uA8FB\uA8FD\uA900-\uA92D\uA930-\uA953\uA960-\uA97C\uA980-\uA9C0\uA9CF-\uA9D9\uA9E0-\uA9FE\uAA00-\uAA36\uAA40-\uAA4D\uAA50-\uAA59\uAA60-\uAA76\uAA7A-\uAAC2\uAADB-\uAADD\uAAE0-\uAAEF\uAAF2-\uAAF6\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABEA\uABEC\uABED\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE00-\uFE0F\uFE20-\uFE2F\uFE33\uFE34\uFE4D-\uFE4F\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF3F\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDDFD\uDE80-\uDE9C\uDEA0-\uDED0\uDEE0\uDF00-\uDF1F\uDF2D-\uDF4A\uDF50-\uDF7A\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCA0-\uDCA9\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00-\uDE03\uDE05\uDE06\uDE0C-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE38-\uDE3A\uDE3F\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE6\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC00-\uDC46\uDC66-\uDC6F\uDC7F-\uDCBA\uDCD0-\uDCE8\uDCF0-\uDCF9\uDD00-\uDD34\uDD36-\uDD3F\uDD50-\uDD73\uDD76\uDD80-\uDDC4\uDDCA-\uDDCC\uDDD0-\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE37\uDE3E\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEEA\uDEF0-\uDEF9\uDF00-\uDF03\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3C-\uDF44\uDF47\uDF48\uDF4B-\uDF4D\uDF50\uDF57\uDF5D-\uDF63\uDF66-\uDF6C\uDF70-\uDF74]|\uD805[\uDC00-\uDC4A\uDC50-\uDC59\uDC80-\uDCC5\uDCC7\uDCD0-\uDCD9\uDD80-\uDDB5\uDDB8-\uDDC0\uDDD8-\uDDDD\uDE00-\uDE40\uDE44\uDE50-\uDE59\uDE80-\uDEB7\uDEC0-\uDEC9\uDF00-\uDF19\uDF1D-\uDF2B\uDF30-\uDF39]|\uD806[\uDCA0-\uDCE9\uDCFF\uDE00-\uDE3E\uDE47\uDE50-\uDE83\uDE86-\uDE99\uDEC0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC36\uDC38-\uDC40\uDC50-\uDC59\uDC72-\uDC8F\uDC92-\uDCA7\uDCA9-\uDCB6\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD36\uDD3A\uDD3C\uDD3D\uDD3F-\uDD47\uDD50-\uDD59]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD81C-\uD820\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDE60-\uDE69\uDED0-\uDEED\uDEF0-\uDEF4\uDF00-\uDF36\uDF40-\uDF43\uDF50-\uDF59\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50-\uDF7E\uDF8F-\uDF9F\uDFE0\uDFE1]|\uD821[\uDC00-\uDFEC]|\uD822[\uDC00-\uDEF2]|\uD82C[\uDC00-\uDD1E\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99\uDC9D\uDC9E]|\uD834[\uDD65-\uDD69\uDD6D-\uDD72\uDD7B-\uDD82\uDD85-\uDD8B\uDDAA-\uDDAD\uDE42-\uDE44]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB\uDFCE-\uDFFF]|\uD836[\uDE00-\uDE36\uDE3B-\uDE6C\uDE75\uDE84\uDE9B-\uDE9F\uDEA1-\uDEAF]|\uD838[\uDC00-\uDC06\uDC08-\uDC18\uDC1B-\uDC21\uDC23\uDC24\uDC26-\uDC2A]|\uD83A[\uDC00-\uDCC4\uDCD0-\uDCD6\uDD00-\uDD4A\uDD50-\uDD59]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]|\uDB40[\uDD00-\uDDEF]/,Object.defineProperty(Z,"__esModule",{value:!0}),Z.JudgeUtil=void 0;const te=Q;Z.JudgeUtil=class{static isIgnoreChar(e){return"string"==typeof e&&("\t"===e||"\v"===e||"\f"===e||" "===e||" "===e||"\ufeff"===e||"\n"===e||"\r"===e||"\u2028"===e||"\u2029"===e)}static isSpaceSeparator(e){return"string"==typeof e&&te.Unicode.Space_Separator.test(e)}static isIdStartChar(e){return"string"==typeof e&&(e>="a"&&e<="z"||e>="A"&&e<="Z"||"$"===e||"_"===e||te.Unicode.ID_Start.test(e))}static isIdContinueChar(e){return"string"==typeof e&&(e>="a"&&e<="z"||e>="A"&&e<="Z"||e>="0"&&e<="9"||"$"===e||"_"===e||"‌"===e||"‍"===e||te.Unicode.ID_Continue.test(e))}static isDigitWithoutZero(e){return/[1-9]/.test(e)}static isDigit(e){return"string"==typeof e&&/[0-9]/.test(e)}static isHexDigit(e){return"string"==typeof e&&/[0-9A-Fa-f]/.test(e)}};var ne={},re={fromCallback:function(e){return Object.defineProperty((function(...t){if("function"!=typeof t[t.length-1])return new Promise(((n,r)=>{e.call(this,...t,((e,t)=>null!=e?r(e):n(t)))}));e.apply(this,t)}),"name",{value:e.name})},fromPromise:function(e){return Object.defineProperty((function(...t){const n=t[t.length-1];if("function"!=typeof n)return e.apply(this,t);e.apply(this,t.slice(0,-1)).then((e=>n(null,e)),n)}),"name",{value:e.name})}},ue=y.default,oe=process.cwd,ie=null,se=process.env.GRACEFUL_FS_PLATFORM||process.platform;process.cwd=function(){return ie||(ie=oe.call(process)),ie};try{process.cwd()}catch(e){}if("function"==typeof process.chdir){var ce=process.chdir;process.chdir=function(e){ie=null,ce.call(process,e)},Object.setPrototypeOf&&Object.setPrototypeOf(process.chdir,ce)}var ae=function(e){ue.hasOwnProperty("O_SYMLINK")&&process.version.match(/^v0\.6\.[0-2]|^v0\.5\./)&&function(e){e.lchmod=function(t,n,r){e.open(t,ue.O_WRONLY|ue.O_SYMLINK,n,(function(t,u){t?r&&r(t):e.fchmod(u,n,(function(t){e.close(u,(function(e){r&&r(t||e)}))}))}))},e.lchmodSync=function(t,n){var r,u=e.openSync(t,ue.O_WRONLY|ue.O_SYMLINK,n),o=!0;try{r=e.fchmodSync(u,n),o=!1}finally{if(o)try{e.closeSync(u)}catch(e){}else e.closeSync(u)}return r}}(e);e.lutimes||function(e){ue.hasOwnProperty("O_SYMLINK")&&e.futimes?(e.lutimes=function(t,n,r,u){e.open(t,ue.O_SYMLINK,(function(t,o){t?u&&u(t):e.futimes(o,n,r,(function(t){e.close(o,(function(e){u&&u(t||e)}))}))}))},e.lutimesSync=function(t,n,r){var u,o=e.openSync(t,ue.O_SYMLINK),i=!0;try{u=e.futimesSync(o,n,r),i=!1}finally{if(i)try{e.closeSync(o)}catch(e){}else e.closeSync(o)}return u}):e.futimes&&(e.lutimes=function(e,t,n,r){r&&process.nextTick(r)},e.lutimesSync=function(){})}(e);e.chown=r(e.chown),e.fchown=r(e.fchown),e.lchown=r(e.lchown),e.chmod=t(e.chmod),e.fchmod=t(e.fchmod),e.lchmod=t(e.lchmod),e.chownSync=u(e.chownSync),e.fchownSync=u(e.fchownSync),e.lchownSync=u(e.lchownSync),e.chmodSync=n(e.chmodSync),e.fchmodSync=n(e.fchmodSync),e.lchmodSync=n(e.lchmodSync),e.stat=o(e.stat),e.fstat=o(e.fstat),e.lstat=o(e.lstat),e.statSync=i(e.statSync),e.fstatSync=i(e.fstatSync),e.lstatSync=i(e.lstatSync),e.chmod&&!e.lchmod&&(e.lchmod=function(e,t,n){n&&process.nextTick(n)},e.lchmodSync=function(){});e.chown&&!e.lchown&&(e.lchown=function(e,t,n,r){r&&process.nextTick(r)},e.lchownSync=function(){});"win32"===se&&(e.rename="function"!=typeof e.rename?e.rename:function(t){function n(n,r,u){var o=Date.now(),i=0;t(n,r,(function s(c){if(c&&("EACCES"===c.code||"EPERM"===c.code||"EBUSY"===c.code)&&Date.now()-o<6e4)return setTimeout((function(){e.stat(r,(function(e,o){e&&"ENOENT"===e.code?t(n,r,s):u(c)}))}),i),void(i<100&&(i+=10));u&&u(c)}))}return Object.setPrototypeOf&&Object.setPrototypeOf(n,t),n}(e.rename));function t(t){return t?function(n,r,u){return t.call(e,n,r,(function(e){s(e)&&(e=null),u&&u.apply(this,arguments)}))}:t}function n(t){return t?function(n,r){try{return t.call(e,n,r)}catch(e){if(!s(e))throw e}}:t}function r(t){return t?function(n,r,u,o){return t.call(e,n,r,u,(function(e){s(e)&&(e=null),o&&o.apply(this,arguments)}))}:t}function u(t){return t?function(n,r,u){try{return t.call(e,n,r,u)}catch(e){if(!s(e))throw e}}:t}function o(t){return t?function(n,r,u){function o(e,t){t&&(t.uid<0&&(t.uid+=4294967296),t.gid<0&&(t.gid+=4294967296)),u&&u.apply(this,arguments)}return"function"==typeof r&&(u=r,r=null),r?t.call(e,n,r,o):t.call(e,n,o)}:t}function i(t){return t?function(n,r){var u=r?t.call(e,n,r):t.call(e,n);return u&&(u.uid<0&&(u.uid+=4294967296),u.gid<0&&(u.gid+=4294967296)),u}:t}function s(e){return!e||("ENOSYS"===e.code||!(process.getuid&&0===process.getuid()||"EINVAL"!==e.code&&"EPERM"!==e.code))}e.read="function"!=typeof e.read?e.read:function(t){function n(n,r,u,o,i,s){var c;if(s&&"function"==typeof s){var a=0;c=function(l,f,d){if(l&&"EAGAIN"===l.code&&a<10)return a++,t.call(e,n,r,u,o,i,c);s.apply(this,arguments)}}return t.call(e,n,r,u,o,i,c)}return Object.setPrototypeOf&&Object.setPrototypeOf(n,t),n}(e.read),e.readSync="function"!=typeof e.readSync?e.readSync:(c=e.readSync,function(t,n,r,u,o){for(var i=0;;)try{return c.call(e,t,n,r,u,o)}catch(e){if("EAGAIN"===e.code&&i<10){i++;continue}throw e}});var c};var le=C.default.Stream,fe=function(e){return{ReadStream:function t(n,r){if(!(this instanceof t))return new t(n,r);le.call(this);var u=this;this.path=n,this.fd=null,this.readable=!0,this.paused=!1,this.flags="r",this.mode=438,this.bufferSize=65536,r=r||{};for(var o=Object.keys(r),i=0,s=o.length;ithis.end)throw new Error("start must be <= end");this.pos=this.start}if(null!==this.fd)return void process.nextTick((function(){u._read()}));e.open(this.path,this.flags,this.mode,(function(e,t){if(e)return u.emit("error",e),void(u.readable=!1);u.fd=t,u.emit("open",t),u._read()}))},WriteStream:function t(n,r){if(!(this instanceof t))return new t(n,r);le.call(this),this.path=n,this.fd=null,this.writable=!0,this.flags="w",this.encoding="binary",this.mode=438,this.bytesWritten=0,r=r||{};for(var u=Object.keys(r),o=0,i=u.length;o= zero");this.pos=this.start}this.busy=!1,this._queue=[],null===this.fd&&(this._open=e.open,this._queue.push([this._open,this.path,this.flags,this.mode,void 0]),this.flush())}}};var de=function(e){if(null===e||"object"!=typeof e)return e;if(e instanceof Object)var t={__proto__:De(e)};else t=Object.create(null);return Object.getOwnPropertyNames(e).forEach((function(n){Object.defineProperty(t,n,Object.getOwnPropertyDescriptor(e,n))})),t},De=Object.getPrototypeOf||function(e){return e.__proto__};var pe,Ee,me=D.default,he=ae,ye=fe,Ce=de,Fe=F.default;function ge(e,t){Object.defineProperty(e,pe,{get:function(){return t}})}"function"==typeof Symbol&&"function"==typeof Symbol.for?(pe=Symbol.for("graceful-fs.queue"),Ee=Symbol.for("graceful-fs.previous")):(pe="___graceful-fs.queue",Ee="___graceful-fs.previous");var Ae=function(){};if(Fe.debuglog?Ae=Fe.debuglog("gfs4"):/\bgfs4\b/i.test(process.env.NODE_DEBUG||"")&&(Ae=function(){var e=Fe.format.apply(Fe,arguments);e="GFS4: "+e.split(/\n/).join("\nGFS4: "),console.error(e)}),!me[pe]){var ve=w[pe]||[];ge(me,ve),me.close=function(e){function t(t,n){return e.call(me,t,(function(e){e||_e(),"function"==typeof n&&n.apply(this,arguments)}))}return Object.defineProperty(t,Ee,{value:e}),t}(me.close),me.closeSync=function(e){function t(t){e.apply(me,arguments),_e()}return Object.defineProperty(t,Ee,{value:e}),t}(me.closeSync),/\bgfs4\b/i.test(process.env.NODE_DEBUG||"")&&process.on("exit",(function(){Ae(me[pe]),g.default.equal(me[pe].length,0)}))}w[pe]||ge(w,me[pe]);var Se,we=Oe(Ce(me));function Oe(e){he(e),e.gracefulify=Oe,e.createReadStream=function(t,n){return new e.ReadStream(t,n)},e.createWriteStream=function(t,n){return new e.WriteStream(t,n)};var t=e.readFile;e.readFile=function(e,n,r){"function"==typeof n&&(r=n,n=null);return function e(n,r,u,o){return t(n,r,(function(t){!t||"EMFILE"!==t.code&&"ENFILE"!==t.code?"function"==typeof u&&u.apply(this,arguments):be([e,[n,r,u],t,o||Date.now(),Date.now()])}))}(e,n,r)};var n=e.writeFile;e.writeFile=function(e,t,r,u){"function"==typeof r&&(u=r,r=null);return function e(t,r,u,o,i){return n(t,r,u,(function(n){!n||"EMFILE"!==n.code&&"ENFILE"!==n.code?"function"==typeof o&&o.apply(this,arguments):be([e,[t,r,u,o],n,i||Date.now(),Date.now()])}))}(e,t,r,u)};var r=e.appendFile;r&&(e.appendFile=function(e,t,n,u){"function"==typeof n&&(u=n,n=null);return function e(t,n,u,o,i){return r(t,n,u,(function(r){!r||"EMFILE"!==r.code&&"ENFILE"!==r.code?"function"==typeof o&&o.apply(this,arguments):be([e,[t,n,u,o],r,i||Date.now(),Date.now()])}))}(e,t,n,u)});var u=e.copyFile;u&&(e.copyFile=function(e,t,n,r){"function"==typeof n&&(r=n,n=0);return function e(t,n,r,o,i){return u(t,n,r,(function(u){!u||"EMFILE"!==u.code&&"ENFILE"!==u.code?"function"==typeof o&&o.apply(this,arguments):be([e,[t,n,r,o],u,i||Date.now(),Date.now()])}))}(e,t,n,r)});var o=e.readdir;e.readdir=function(e,t,n){"function"==typeof t&&(n=t,t=null);var r=i.test(process.version)?function(e,t,n,r){return o(e,u(e,t,n,r))}:function(e,t,n,r){return o(e,t,u(e,t,n,r))};return r(e,t,n);function u(e,t,n,u){return function(o,i){!o||"EMFILE"!==o.code&&"ENFILE"!==o.code?(i&&i.sort&&i.sort(),"function"==typeof n&&n.call(this,o,i)):be([r,[e,t,n],o,u||Date.now(),Date.now()])}}};var i=/^v[0-5]\./;if("v0.8"===process.version.substr(0,4)){var s=ye(e);d=s.ReadStream,D=s.WriteStream}var c=e.ReadStream;c&&(d.prototype=Object.create(c.prototype),d.prototype.open=function(){var e=this;E(e.path,e.flags,e.mode,(function(t,n){t?(e.autoClose&&e.destroy(),e.emit("error",t)):(e.fd=n,e.emit("open",n),e.read())}))});var a=e.WriteStream;a&&(D.prototype=Object.create(a.prototype),D.prototype.open=function(){var e=this;E(e.path,e.flags,e.mode,(function(t,n){t?(e.destroy(),e.emit("error",t)):(e.fd=n,e.emit("open",n))}))}),Object.defineProperty(e,"ReadStream",{get:function(){return d},set:function(e){d=e},enumerable:!0,configurable:!0}),Object.defineProperty(e,"WriteStream",{get:function(){return D},set:function(e){D=e},enumerable:!0,configurable:!0});var l=d;Object.defineProperty(e,"FileReadStream",{get:function(){return l},set:function(e){l=e},enumerable:!0,configurable:!0});var f=D;function d(e,t){return this instanceof d?(c.apply(this,arguments),this):d.apply(Object.create(d.prototype),arguments)}function D(e,t){return this instanceof D?(a.apply(this,arguments),this):D.apply(Object.create(D.prototype),arguments)}Object.defineProperty(e,"FileWriteStream",{get:function(){return f},set:function(e){f=e},enumerable:!0,configurable:!0});var p=e.open;function E(e,t,n,r){return"function"==typeof n&&(r=n,n=null),function e(t,n,r,u,o){return p(t,n,r,(function(i,s){!i||"EMFILE"!==i.code&&"ENFILE"!==i.code?"function"==typeof u&&u.apply(this,arguments):be([e,[t,n,r,u],i,o||Date.now(),Date.now()])}))}(e,t,n,r)}return e.open=E,e}function be(e){Ae("ENQUEUE",e[0].name,e[1]),me[pe].push(e),Be()}function _e(){for(var e=Date.now(),t=0;t2&&(me[pe][t][3]=e,me[pe][t][4]=e);Be()}function Be(){if(clearTimeout(Se),Se=void 0,0!==me[pe].length){var e=me[pe].shift(),t=e[0],n=e[1],r=e[2],u=e[3],o=e[4];if(void 0===u)Ae("RETRY",t.name,n),t.apply(null,n);else if(Date.now()-u>=6e4){Ae("TIMEOUT",t.name,n);var i=n.pop();"function"==typeof i&&i.call(null,r)}else{var s=Date.now()-o,c=Math.max(o-u,1);s>=Math.min(1.2*c,100)?(Ae("RETRY",t.name,n),t.apply(null,n.concat([u]))):me[pe].push(e)}void 0===Se&&(Se=setTimeout(Be,0))}}process.env.TEST_GRACEFUL_FS_GLOBAL_PATCH&&!me.__patched&&(we=Oe(me),me.__patched=!0),function(e){const t=re.fromCallback,n=we,r=["access","appendFile","chmod","chown","close","copyFile","fchmod","fchown","fdatasync","fstat","fsync","ftruncate","futimes","lchmod","lchown","link","lstat","mkdir","mkdtemp","open","opendir","readdir","readFile","readlink","realpath","rename","rm","rmdir","stat","symlink","truncate","unlink","utimes","writeFile"].filter((e=>"function"==typeof n[e]));Object.assign(e,n),r.forEach((r=>{e[r]=t(n[r])})),e.realpath.native=t(n.realpath.native),e.exists=function(e,t){return"function"==typeof t?n.exists(e,t):new Promise((t=>n.exists(e,t)))},e.read=function(e,t,r,u,o,i){return"function"==typeof i?n.read(e,t,r,u,o,i):new Promise(((i,s)=>{n.read(e,t,r,u,o,((e,t,n)=>{if(e)return s(e);i({bytesRead:t,buffer:n})}))}))},e.write=function(e,t,...r){return"function"==typeof r[r.length-1]?n.write(e,t,...r):new Promise(((u,o)=>{n.write(e,t,...r,((e,t,n)=>{if(e)return o(e);u({bytesWritten:t,buffer:n})}))}))},"function"==typeof n.writev&&(e.writev=function(e,t,...r){return"function"==typeof r[r.length-1]?n.writev(e,t,...r):new Promise(((u,o)=>{n.writev(e,t,...r,((e,t,n)=>{if(e)return o(e);u({bytesWritten:t,buffers:n})}))}))})}(ne);var Pe={},ke={};const xe=p.default;ke.checkPath=function(e){if("win32"===process.platform){if(/[<>:"|?*]/.test(e.replace(xe.parse(e).root,""))){const t=new Error(`Path contains invalid characters: ${e}`);throw t.code="EINVAL",t}}};const Ne=ne,{checkPath:Ie}=ke,Te=e=>"number"==typeof e?e:{mode:511,...e}.mode;Pe.makeDir=async(e,t)=>(Ie(e),Ne.mkdir(e,{mode:Te(t),recursive:!0})),Pe.makeDirSync=(e,t)=>(Ie(e),Ne.mkdirSync(e,{mode:Te(t),recursive:!0}));const Re=re.fromPromise,{makeDir:Me,makeDirSync:Le}=Pe,je=Re(Me);var $e={mkdirs:je,mkdirsSync:Le,mkdirp:je,mkdirpSync:Le,ensureDir:je,ensureDirSync:Le};const He=re.fromPromise,Je=ne;var Ge={pathExists:He((function(e){return Je.access(e).then((()=>!0)).catch((()=>!1))})),pathExistsSync:Je.existsSync};const Ve=we;var Ue=function(e,t,n,r){Ve.open(e,"r+",((e,u)=>{if(e)return r(e);Ve.futimes(u,t,n,(e=>{Ve.close(u,(t=>{r&&r(e||t)}))}))}))},We=function(e,t,n){const r=Ve.openSync(e,"r+");return Ve.futimesSync(r,t,n),Ve.closeSync(r)};const ze=ne,Ke=p.default,qe=F.default;function Ye(e,t,n){const r=n.dereference?e=>ze.stat(e,{bigint:!0}):e=>ze.lstat(e,{bigint:!0});return Promise.all([r(e),r(t).catch((e=>{if("ENOENT"===e.code)return null;throw e}))]).then((([e,t])=>({srcStat:e,destStat:t})))}function Xe(e,t){return t.ino&&t.dev&&t.ino===e.ino&&t.dev===e.dev}function Ze(e,t){const n=Ke.resolve(e).split(Ke.sep).filter((e=>e)),r=Ke.resolve(t).split(Ke.sep).filter((e=>e));return n.reduce(((e,t,n)=>e&&r[n]===t),!0)}function Qe(e,t,n){return`Cannot ${n} '${e}' to a subdirectory of itself, '${t}'.`}var et={checkPaths:function(e,t,n,r,u){qe.callbackify(Ye)(e,t,r,((r,o)=>{if(r)return u(r);const{srcStat:i,destStat:s}=o;if(s){if(Xe(i,s)){const r=Ke.basename(e),o=Ke.basename(t);return"move"===n&&r!==o&&r.toLowerCase()===o.toLowerCase()?u(null,{srcStat:i,destStat:s,isChangingCase:!0}):u(new Error("Source and destination must not be the same."))}if(i.isDirectory()&&!s.isDirectory())return u(new Error(`Cannot overwrite non-directory '${t}' with directory '${e}'.`));if(!i.isDirectory()&&s.isDirectory())return u(new Error(`Cannot overwrite directory '${t}' with non-directory '${e}'.`))}return i.isDirectory()&&Ze(e,t)?u(new Error(Qe(e,t,n))):u(null,{srcStat:i,destStat:s})}))},checkPathsSync:function(e,t,n,r){const{srcStat:u,destStat:o}=function(e,t,n){let r;const u=n.dereference?e=>ze.statSync(e,{bigint:!0}):e=>ze.lstatSync(e,{bigint:!0}),o=u(e);try{r=u(t)}catch(e){if("ENOENT"===e.code)return{srcStat:o,destStat:null};throw e}return{srcStat:o,destStat:r}}(e,t,r);if(o){if(Xe(u,o)){const r=Ke.basename(e),i=Ke.basename(t);if("move"===n&&r!==i&&r.toLowerCase()===i.toLowerCase())return{srcStat:u,destStat:o,isChangingCase:!0};throw new Error("Source and destination must not be the same.")}if(u.isDirectory()&&!o.isDirectory())throw new Error(`Cannot overwrite non-directory '${t}' with directory '${e}'.`);if(!u.isDirectory()&&o.isDirectory())throw new Error(`Cannot overwrite directory '${t}' with non-directory '${e}'.`)}if(u.isDirectory()&&Ze(e,t))throw new Error(Qe(e,t,n));return{srcStat:u,destStat:o}},checkParentPaths:function e(t,n,r,u,o){const i=Ke.resolve(Ke.dirname(t)),s=Ke.resolve(Ke.dirname(r));if(s===i||s===Ke.parse(s).root)return o();ze.stat(s,{bigint:!0},((i,c)=>i?"ENOENT"===i.code?o():o(i):Xe(n,c)?o(new Error(Qe(t,r,u))):e(t,n,s,u,o)))},checkParentPathsSync:function e(t,n,r,u){const o=Ke.resolve(Ke.dirname(t)),i=Ke.resolve(Ke.dirname(r));if(i===o||i===Ke.parse(i).root)return;let s;try{s=ze.statSync(i,{bigint:!0})}catch(e){if("ENOENT"===e.code)return;throw e}if(Xe(n,s))throw new Error(Qe(t,r,u));return e(t,n,i,u)},isSrcSubdir:Ze,areIdentical:Xe};const tt=we,nt=p.default,rt=$e.mkdirs,ut=Ge.pathExists,ot=Ue,it=et;function st(e,t,n,r,u){const o=nt.dirname(n);ut(o,((i,s)=>i?u(i):s?at(e,t,n,r,u):void rt(o,(o=>o?u(o):at(e,t,n,r,u)))))}function ct(e,t,n,r,u,o){Promise.resolve(u.filter(n,r)).then((i=>i?e(t,n,r,u,o):o()),(e=>o(e)))}function at(e,t,n,r,u){(r.dereference?tt.stat:tt.lstat)(t,((o,i)=>o?u(o):i.isDirectory()?function(e,t,n,r,u,o){return t?Dt(n,r,u,o):function(e,t,n,r,u){tt.mkdir(n,(o=>{if(o)return u(o);Dt(t,n,r,(t=>t?u(t):dt(n,e,u)))}))}(e.mode,n,r,u,o)}(i,e,t,n,r,u):i.isFile()||i.isCharacterDevice()||i.isBlockDevice()?function(e,t,n,r,u,o){return t?function(e,t,n,r,u){if(!r.overwrite)return r.errorOnExist?u(new Error(`'${n}' already exists`)):u();tt.unlink(n,(o=>o?u(o):lt(e,t,n,r,u)))}(e,n,r,u,o):lt(e,n,r,u,o)}(i,e,t,n,r,u):i.isSymbolicLink()?function(e,t,n,r,u){tt.readlink(t,((t,o)=>t?u(t):(r.dereference&&(o=nt.resolve(process.cwd(),o)),e?void tt.readlink(n,((t,i)=>t?"EINVAL"===t.code||"UNKNOWN"===t.code?tt.symlink(o,n,u):u(t):(r.dereference&&(i=nt.resolve(process.cwd(),i)),it.isSrcSubdir(o,i)?u(new Error(`Cannot copy '${o}' to a subdirectory of itself, '${i}'.`)):e.isDirectory()&&it.isSrcSubdir(i,o)?u(new Error(`Cannot overwrite '${i}' with '${o}'.`)):function(e,t,n){tt.unlink(t,(r=>r?n(r):tt.symlink(e,t,n)))}(o,n,u)))):tt.symlink(o,n,u))))}(e,t,n,r,u):i.isSocket()?u(new Error(`Cannot copy a socket file: ${t}`)):i.isFIFO()?u(new Error(`Cannot copy a FIFO pipe: ${t}`)):u(new Error(`Unknown file: ${t}`))))}function lt(e,t,n,r,u){tt.copyFile(t,n,(o=>o?u(o):r.preserveTimestamps?function(e,t,n,r){if(function(e){return 0==(128&e)}(e))return function(e,t,n){return dt(e,128|t,n)}(n,e,(u=>u?r(u):ft(e,t,n,r)));return ft(e,t,n,r)}(e.mode,t,n,u):dt(n,e.mode,u)))}function ft(e,t,n,r){!function(e,t,n){tt.stat(e,((e,r)=>e?n(e):ot(t,r.atime,r.mtime,n)))}(t,n,(t=>t?r(t):dt(n,e,r)))}function dt(e,t,n){return tt.chmod(e,t,n)}function Dt(e,t,n,r){tt.readdir(e,((u,o)=>u?r(u):pt(o,e,t,n,r)))}function pt(e,t,n,r,u){const o=e.pop();return o?function(e,t,n,r,u,o){const i=nt.join(n,t),s=nt.join(r,t);it.checkPaths(i,s,"copy",u,((t,c)=>{if(t)return o(t);const{destStat:a}=c;!function(e,t,n,r,u){r.filter?ct(at,e,t,n,r,u):at(e,t,n,r,u)}(a,i,s,u,(t=>t?o(t):pt(e,n,r,u,o)))}))}(e,o,t,n,r,u):u()}var Et=function(e,t,n,r){"function"!=typeof n||r?"function"==typeof n&&(n={filter:n}):(r=n,n={}),r=r||function(){},(n=n||{}).clobber=!("clobber"in n)||!!n.clobber,n.overwrite="overwrite"in n?!!n.overwrite:n.clobber,n.preserveTimestamps&&"ia32"===process.arch&&console.warn("fs-extra: Using the preserveTimestamps option in 32-bit node is not recommended;\n\n see https://github.com/jprichardson/node-fs-extra/issues/269"),it.checkPaths(e,t,"copy",n,((u,o)=>{if(u)return r(u);const{srcStat:i,destStat:s}=o;it.checkParentPaths(e,i,t,"copy",(u=>u?r(u):n.filter?ct(st,s,e,t,n,r):st(s,e,t,n,r)))}))};const mt=we,ht=p.default,yt=$e.mkdirsSync,Ct=We,Ft=et;function gt(e,t,n,r){const u=(r.dereference?mt.statSync:mt.lstatSync)(t);if(u.isDirectory())return function(e,t,n,r,u){return t?St(n,r,u):function(e,t,n,r){return mt.mkdirSync(n),St(t,n,r),vt(n,e)}(e.mode,n,r,u)}(u,e,t,n,r);if(u.isFile()||u.isCharacterDevice()||u.isBlockDevice())return function(e,t,n,r,u){return t?function(e,t,n,r){if(r.overwrite)return mt.unlinkSync(n),At(e,t,n,r);if(r.errorOnExist)throw new Error(`'${n}' already exists`)}(e,n,r,u):At(e,n,r,u)}(u,e,t,n,r);if(u.isSymbolicLink())return function(e,t,n,r){let u=mt.readlinkSync(t);r.dereference&&(u=ht.resolve(process.cwd(),u));if(e){let e;try{e=mt.readlinkSync(n)}catch(e){if("EINVAL"===e.code||"UNKNOWN"===e.code)return mt.symlinkSync(u,n);throw e}if(r.dereference&&(e=ht.resolve(process.cwd(),e)),Ft.isSrcSubdir(u,e))throw new Error(`Cannot copy '${u}' to a subdirectory of itself, '${e}'.`);if(mt.statSync(n).isDirectory()&&Ft.isSrcSubdir(e,u))throw new Error(`Cannot overwrite '${e}' with '${u}'.`);return function(e,t){return mt.unlinkSync(t),mt.symlinkSync(e,t)}(u,n)}return mt.symlinkSync(u,n)}(e,t,n,r);if(u.isSocket())throw new Error(`Cannot copy a socket file: ${t}`);if(u.isFIFO())throw new Error(`Cannot copy a FIFO pipe: ${t}`);throw new Error(`Unknown file: ${t}`)}function At(e,t,n,r){return mt.copyFileSync(t,n),r.preserveTimestamps&&function(e,t,n){(function(e){return 0==(128&e)})(e)&&function(e,t){vt(e,128|t)}(n,e);(function(e,t){const n=mt.statSync(e);Ct(t,n.atime,n.mtime)})(t,n)}(e.mode,t,n),vt(n,e.mode)}function vt(e,t){return mt.chmodSync(e,t)}function St(e,t,n){mt.readdirSync(e).forEach((r=>function(e,t,n,r){const u=ht.join(t,e),o=ht.join(n,e),{destStat:i}=Ft.checkPathsSync(u,o,"copy",r);return function(e,t,n,r){if(!r.filter||r.filter(t,n))return gt(e,t,n,r)}(i,u,o,r)}(r,e,t,n)))}var wt=function(e,t,n){"function"==typeof n&&(n={filter:n}),(n=n||{}).clobber=!("clobber"in n)||!!n.clobber,n.overwrite="overwrite"in n?!!n.overwrite:n.clobber,n.preserveTimestamps&&"ia32"===process.arch&&console.warn("fs-extra: Using the preserveTimestamps option in 32-bit node is not recommended;\n\n see https://github.com/jprichardson/node-fs-extra/issues/269");const{srcStat:r,destStat:u}=Ft.checkPathsSync(e,t,"copy",n);return Ft.checkParentPathsSync(e,r,t,"copy"),function(e,t,n,r){if(r.filter&&!r.filter(t,n))return;const u=ht.dirname(n);mt.existsSync(u)||yt(u);return gt(e,t,n,r)}(u,e,t,n)};var Ot={copy:(0,re.fromCallback)(Et),copySync:wt};const bt=we,_t=p.default,Bt=g.default,Pt="win32"===process.platform;function kt(e){["unlink","chmod","stat","lstat","rmdir","readdir"].forEach((t=>{e[t]=e[t]||bt[t],e[t+="Sync"]=e[t]||bt[t]})),e.maxBusyTries=e.maxBusyTries||3}function xt(e,t,n){let r=0;"function"==typeof t&&(n=t,t={}),Bt(e,"rimraf: missing path"),Bt.strictEqual(typeof e,"string","rimraf: path should be a string"),Bt.strictEqual(typeof n,"function","rimraf: callback function required"),Bt(t,"rimraf: invalid options argument provided"),Bt.strictEqual(typeof t,"object","rimraf: options should be object"),kt(t),Nt(e,t,(function u(o){if(o){if(("EBUSY"===o.code||"ENOTEMPTY"===o.code||"EPERM"===o.code)&&rNt(e,t,u)),100*r)}"ENOENT"===o.code&&(o=null)}n(o)}))}function Nt(e,t,n){Bt(e),Bt(t),Bt("function"==typeof n),t.lstat(e,((r,u)=>r&&"ENOENT"===r.code?n(null):r&&"EPERM"===r.code&&Pt?It(e,t,r,n):u&&u.isDirectory()?Rt(e,t,r,n):void t.unlink(e,(r=>{if(r){if("ENOENT"===r.code)return n(null);if("EPERM"===r.code)return Pt?It(e,t,r,n):Rt(e,t,r,n);if("EISDIR"===r.code)return Rt(e,t,r,n)}return n(r)}))))}function It(e,t,n,r){Bt(e),Bt(t),Bt("function"==typeof r),t.chmod(e,438,(u=>{u?r("ENOENT"===u.code?null:n):t.stat(e,((u,o)=>{u?r("ENOENT"===u.code?null:n):o.isDirectory()?Rt(e,t,n,r):t.unlink(e,r)}))}))}function Tt(e,t,n){let r;Bt(e),Bt(t);try{t.chmodSync(e,438)}catch(e){if("ENOENT"===e.code)return;throw n}try{r=t.statSync(e)}catch(e){if("ENOENT"===e.code)return;throw n}r.isDirectory()?Lt(e,t,n):t.unlinkSync(e)}function Rt(e,t,n,r){Bt(e),Bt(t),Bt("function"==typeof r),t.rmdir(e,(u=>{!u||"ENOTEMPTY"!==u.code&&"EEXIST"!==u.code&&"EPERM"!==u.code?u&&"ENOTDIR"===u.code?r(n):r(u):function(e,t,n){Bt(e),Bt(t),Bt("function"==typeof n),t.readdir(e,((r,u)=>{if(r)return n(r);let o,i=u.length;if(0===i)return t.rmdir(e,n);u.forEach((r=>{xt(_t.join(e,r),t,(r=>{if(!o)return r?n(o=r):void(0==--i&&t.rmdir(e,n))}))}))}))}(e,t,r)}))}function Mt(e,t){let n;kt(t=t||{}),Bt(e,"rimraf: missing path"),Bt.strictEqual(typeof e,"string","rimraf: path should be a string"),Bt(t,"rimraf: missing options"),Bt.strictEqual(typeof t,"object","rimraf: options should be object");try{n=t.lstatSync(e)}catch(n){if("ENOENT"===n.code)return;"EPERM"===n.code&&Pt&&Tt(e,t,n)}try{n&&n.isDirectory()?Lt(e,t,null):t.unlinkSync(e)}catch(n){if("ENOENT"===n.code)return;if("EPERM"===n.code)return Pt?Tt(e,t,n):Lt(e,t,n);if("EISDIR"!==n.code)throw n;Lt(e,t,n)}}function Lt(e,t,n){Bt(e),Bt(t);try{t.rmdirSync(e)}catch(r){if("ENOTDIR"===r.code)throw n;if("ENOTEMPTY"===r.code||"EEXIST"===r.code||"EPERM"===r.code)!function(e,t){if(Bt(e),Bt(t),t.readdirSync(e).forEach((n=>Mt(_t.join(e,n),t))),!Pt){return t.rmdirSync(e,t)}{const n=Date.now();do{try{return t.rmdirSync(e,t)}catch{}}while(Date.now()-n<500)}}(e,t);else if("ENOENT"!==r.code)throw r}}var jt=xt;xt.sync=Mt;const $t=we,Ht=re.fromCallback,Jt=jt;var Gt={remove:Ht((function(e,t){if($t.rm)return $t.rm(e,{recursive:!0,force:!0},t);Jt(e,t)})),removeSync:function(e){if($t.rmSync)return $t.rmSync(e,{recursive:!0,force:!0});Jt.sync(e)}};const Vt=re.fromPromise,Ut=ne,Wt=p.default,zt=$e,Kt=Gt,qt=Vt((async function(e){let t;try{t=await Ut.readdir(e)}catch{return zt.mkdirs(e)}return Promise.all(t.map((t=>Kt.remove(Wt.join(e,t)))))}));function Yt(e){let t;try{t=Ut.readdirSync(e)}catch{return zt.mkdirsSync(e)}t.forEach((t=>{t=Wt.join(e,t),Kt.removeSync(t)}))}var Xt={emptyDirSync:Yt,emptydirSync:Yt,emptyDir:qt,emptydir:qt};const Zt=re.fromCallback,Qt=p.default,en=we,tn=$e;var nn={createFile:Zt((function(e,t){function n(){en.writeFile(e,"",(e=>{if(e)return t(e);t()}))}en.stat(e,((r,u)=>{if(!r&&u.isFile())return t();const o=Qt.dirname(e);en.stat(o,((e,r)=>{if(e)return"ENOENT"===e.code?tn.mkdirs(o,(e=>{if(e)return t(e);n()})):t(e);r.isDirectory()?n():en.readdir(o,(e=>{if(e)return t(e)}))}))}))})),createFileSync:function(e){let t;try{t=en.statSync(e)}catch{}if(t&&t.isFile())return;const n=Qt.dirname(e);try{en.statSync(n).isDirectory()||en.readdirSync(n)}catch(e){if(!e||"ENOENT"!==e.code)throw e;tn.mkdirsSync(n)}en.writeFileSync(e,"")}};const rn=re.fromCallback,un=p.default,on=we,sn=$e,cn=Ge.pathExists,{areIdentical:an}=et;var ln={createLink:rn((function(e,t,n){function r(e,t){on.link(e,t,(e=>{if(e)return n(e);n(null)}))}on.lstat(t,((u,o)=>{on.lstat(e,((u,i)=>{if(u)return u.message=u.message.replace("lstat","ensureLink"),n(u);if(o&&an(i,o))return n(null);const s=un.dirname(t);cn(s,((u,o)=>u?n(u):o?r(e,t):void sn.mkdirs(s,(u=>{if(u)return n(u);r(e,t)}))))}))}))})),createLinkSync:function(e,t){let n;try{n=on.lstatSync(t)}catch{}try{const t=on.lstatSync(e);if(n&&an(t,n))return}catch(e){throw e.message=e.message.replace("lstat","ensureLink"),e}const r=un.dirname(t);return on.existsSync(r)||sn.mkdirsSync(r),on.linkSync(e,t)}};const fn=p.default,dn=we,Dn=Ge.pathExists;var pn={symlinkPaths:function(e,t,n){if(fn.isAbsolute(e))return dn.lstat(e,(t=>t?(t.message=t.message.replace("lstat","ensureSymlink"),n(t)):n(null,{toCwd:e,toDst:e})));{const r=fn.dirname(t),u=fn.join(r,e);return Dn(u,((t,o)=>t?n(t):o?n(null,{toCwd:u,toDst:e}):dn.lstat(e,(t=>t?(t.message=t.message.replace("lstat","ensureSymlink"),n(t)):n(null,{toCwd:e,toDst:fn.relative(r,e)})))))}},symlinkPathsSync:function(e,t){let n;if(fn.isAbsolute(e)){if(n=dn.existsSync(e),!n)throw new Error("absolute srcpath does not exist");return{toCwd:e,toDst:e}}{const r=fn.dirname(t),u=fn.join(r,e);if(n=dn.existsSync(u),n)return{toCwd:u,toDst:e};if(n=dn.existsSync(e),!n)throw new Error("relative srcpath does not exist");return{toCwd:e,toDst:fn.relative(r,e)}}}};const En=we;var mn={symlinkType:function(e,t,n){if(n="function"==typeof t?t:n,t="function"!=typeof t&&t)return n(null,t);En.lstat(e,((e,r)=>{if(e)return n(null,"file");t=r&&r.isDirectory()?"dir":"file",n(null,t)}))},symlinkTypeSync:function(e,t){let n;if(t)return t;try{n=En.lstatSync(e)}catch{return"file"}return n&&n.isDirectory()?"dir":"file"}};const hn=re.fromCallback,yn=p.default,Cn=ne,Fn=$e.mkdirs,gn=$e.mkdirsSync,An=pn.symlinkPaths,vn=pn.symlinkPathsSync,Sn=mn.symlinkType,wn=mn.symlinkTypeSync,On=Ge.pathExists,{areIdentical:bn}=et;function _n(e,t,n,r){An(e,t,((u,o)=>{if(u)return r(u);e=o.toDst,Sn(o.toCwd,n,((n,u)=>{if(n)return r(n);const o=yn.dirname(t);On(o,((n,i)=>n?r(n):i?Cn.symlink(e,t,u,r):void Fn(o,(n=>{if(n)return r(n);Cn.symlink(e,t,u,r)}))))}))}))}var Bn={createSymlink:hn((function(e,t,n,r){r="function"==typeof n?n:r,n="function"!=typeof n&&n,Cn.lstat(t,((u,o)=>{!u&&o.isSymbolicLink()?Promise.all([Cn.stat(e),Cn.stat(t)]).then((([u,o])=>{if(bn(u,o))return r(null);_n(e,t,n,r)})):_n(e,t,n,r)}))})),createSymlinkSync:function(e,t,n){let r;try{r=Cn.lstatSync(t)}catch{}if(r&&r.isSymbolicLink()){const n=Cn.statSync(e),r=Cn.statSync(t);if(bn(n,r))return}const u=vn(e,t);e=u.toDst,n=wn(u.toCwd,n);const o=yn.dirname(t);return Cn.existsSync(o)||gn(o),Cn.symlinkSync(e,t,n)}};const{createFile:Pn,createFileSync:kn}=nn,{createLink:xn,createLinkSync:Nn}=ln,{createSymlink:In,createSymlinkSync:Tn}=Bn;var Rn={createFile:Pn,createFileSync:kn,ensureFile:Pn,ensureFileSync:kn,createLink:xn,createLinkSync:Nn,ensureLink:xn,ensureLinkSync:Nn,createSymlink:In,createSymlinkSync:Tn,ensureSymlink:In,ensureSymlinkSync:Tn};var Mn={stringify:function(e,{EOL:t="\n",finalEOL:n=!0,replacer:r=null,spaces:u}={}){const o=n?t:"";return JSON.stringify(e,r,u).replace(/\n/g,t)+o},stripBom:function(e){return Buffer.isBuffer(e)&&(e=e.toString("utf8")),e.replace(/^\uFEFF/,"")}};let Ln;try{Ln=we}catch(e){Ln=D.default}const jn=re,{stringify:$n,stripBom:Hn}=Mn;const Jn=jn.fromPromise((async function(e,t={}){"string"==typeof t&&(t={encoding:t});const n=t.fs||Ln,r=!("throws"in t)||t.throws;let u,o=await jn.fromCallback(n.readFile)(e,t);o=Hn(o);try{u=JSON.parse(o,t?t.reviver:null)}catch(t){if(r)throw t.message=`${e}: ${t.message}`,t;return null}return u}));const Gn=jn.fromPromise((async function(e,t,n={}){const r=n.fs||Ln,u=$n(t,n);await jn.fromCallback(r.writeFile)(e,u,n)}));const Vn={readFile:Jn,readFileSync:function(e,t={}){"string"==typeof t&&(t={encoding:t});const n=t.fs||Ln,r=!("throws"in t)||t.throws;try{let r=n.readFileSync(e,t);return r=Hn(r),JSON.parse(r,t.reviver)}catch(t){if(r)throw t.message=`${e}: ${t.message}`,t;return null}},writeFile:Gn,writeFileSync:function(e,t,n={}){const r=n.fs||Ln,u=$n(t,n);return r.writeFileSync(e,u,n)}};var Un={readJson:Vn.readFile,readJsonSync:Vn.readFileSync,writeJson:Vn.writeFile,writeJsonSync:Vn.writeFileSync};const Wn=re.fromCallback,zn=we,Kn=p.default,qn=$e,Yn=Ge.pathExists;var Xn={outputFile:Wn((function(e,t,n,r){"function"==typeof n&&(r=n,n="utf8");const u=Kn.dirname(e);Yn(u,((o,i)=>o?r(o):i?zn.writeFile(e,t,n,r):void qn.mkdirs(u,(u=>{if(u)return r(u);zn.writeFile(e,t,n,r)}))))})),outputFileSync:function(e,...t){const n=Kn.dirname(e);if(zn.existsSync(n))return zn.writeFileSync(e,...t);qn.mkdirsSync(n),zn.writeFileSync(e,...t)}};const{stringify:Zn}=Mn,{outputFile:Qn}=Xn;var er=async function(e,t,n={}){const r=Zn(t,n);await Qn(e,r,n)};const{stringify:tr}=Mn,{outputFileSync:nr}=Xn;var rr=function(e,t,n){const r=tr(t,n);nr(e,r,n)};const ur=re.fromPromise,or=Un;or.outputJson=ur(er),or.outputJsonSync=rr,or.outputJSON=or.outputJson,or.outputJSONSync=or.outputJsonSync,or.writeJSON=or.writeJson,or.writeJSONSync=or.writeJsonSync,or.readJSON=or.readJson,or.readJSONSync=or.readJsonSync;var ir=or;const sr=we,cr=p.default,ar=Ot.copy,lr=Gt.remove,fr=$e.mkdirp,dr=Ge.pathExists,Dr=et;function pr(e,t,n,r,u){return r?Er(e,t,n,u):n?lr(t,(r=>r?u(r):Er(e,t,n,u))):void dr(t,((r,o)=>r?u(r):o?u(new Error("dest already exists.")):Er(e,t,n,u)))}function Er(e,t,n,r){sr.rename(e,t,(u=>u?"EXDEV"!==u.code?r(u):function(e,t,n,r){const u={overwrite:n,errorOnExist:!0};ar(e,t,u,(t=>t?r(t):lr(e,r)))}(e,t,n,r):r()))}var mr=function(e,t,n,r){"function"==typeof n&&(r=n,n={});const u=n.overwrite||n.clobber||!1;Dr.checkPaths(e,t,"move",n,((n,o)=>{if(n)return r(n);const{srcStat:i,isChangingCase:s=!1}=o;Dr.checkParentPaths(e,i,t,"move",(n=>n?r(n):function(e){const t=cr.dirname(e);return cr.parse(t).root===t}(t)?pr(e,t,u,s,r):void fr(cr.dirname(t),(n=>n?r(n):pr(e,t,u,s,r)))))}))};const hr=we,yr=p.default,Cr=Ot.copySync,Fr=Gt.removeSync,gr=$e.mkdirpSync,Ar=et;function vr(e,t,n){try{hr.renameSync(e,t)}catch(r){if("EXDEV"!==r.code)throw r;return function(e,t,n){const r={overwrite:n,errorOnExist:!0};return Cr(e,t,r),Fr(e)}(e,t,n)}}var Sr=function(e,t,n){const r=(n=n||{}).overwrite||n.clobber||!1,{srcStat:u,isChangingCase:o=!1}=Ar.checkPathsSync(e,t,"move",n);return Ar.checkParentPathsSync(e,u,t,"move"),function(e){const t=yr.dirname(e);return yr.parse(t).root===t}(t)||gr(yr.dirname(t)),function(e,t,n,r){if(r)return vr(e,t,n);if(n)return Fr(t),vr(e,t,n);if(hr.existsSync(t))throw new Error("dest already exists.");return vr(e,t,n)}(e,t,r,o)};var wr,Or,br,_r,Br,Pr={move:(0,re.fromCallback)(mr),moveSync:Sr},kr={...ne,...Ot,...Xt,...Rn,...ir,...$e,...Pr,...Xn,...Ge,...Gt},xr={},Nr={exports:{}},Ir={exports:{}};function Tr(){if(Or)return wr;Or=1;var e=1e3,t=60*e,n=60*t,r=24*n,u=7*r,o=365.25*r;function i(e,t,n,r){var u=t>=1.5*n;return Math.round(e/n)+" "+r+(u?"s":"")}return wr=function(s,c){c=c||{};var a=typeof s;if("string"===a&&s.length>0)return function(i){if((i=String(i)).length>100)return;var s=/^(-?(?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec(i);if(!s)return;var c=parseFloat(s[1]);switch((s[2]||"ms").toLowerCase()){case"years":case"year":case"yrs":case"yr":case"y":return c*o;case"weeks":case"week":case"w":return c*u;case"days":case"day":case"d":return c*r;case"hours":case"hour":case"hrs":case"hr":case"h":return c*n;case"minutes":case"minute":case"mins":case"min":case"m":return c*t;case"seconds":case"second":case"secs":case"sec":case"s":return c*e;case"milliseconds":case"millisecond":case"msecs":case"msec":case"ms":return c;default:return}}(s);if("number"===a&&isFinite(s))return c.long?function(u){var o=Math.abs(u);if(o>=r)return i(u,o,r,"day");if(o>=n)return i(u,o,n,"hour");if(o>=t)return i(u,o,t,"minute");if(o>=e)return i(u,o,e,"second");return u+" ms"}(s):function(u){var o=Math.abs(u);if(o>=r)return Math.round(u/r)+"d";if(o>=n)return Math.round(u/n)+"h";if(o>=t)return Math.round(u/t)+"m";if(o>=e)return Math.round(u/e)+"s";return u+"ms"}(s);throw new Error("val is not a non-empty string or a valid number. val="+JSON.stringify(s))}}function Rr(){if(_r)return br;return _r=1,br=function(e){function t(e){let r,u,o,i=null;function s(...e){if(!s.enabled)return;const n=s,u=Number(new Date),o=u-(r||u);n.diff=o,n.prev=r,n.curr=u,r=u,e[0]=t.coerce(e[0]),"string"!=typeof e[0]&&e.unshift("%O");let i=0;e[0]=e[0].replace(/%([a-zA-Z%])/g,((r,u)=>{if("%%"===r)return"%";i++;const o=t.formatters[u];if("function"==typeof o){const t=e[i];r=o.call(n,t),e.splice(i,1),i--}return r})),t.formatArgs.call(n,e);(n.log||t.log).apply(n,e)}return s.namespace=e,s.useColors=t.useColors(),s.color=t.selectColor(e),s.extend=n,s.destroy=t.destroy,Object.defineProperty(s,"enabled",{enumerable:!0,configurable:!1,get:()=>null!==i?i:(u!==t.namespaces&&(u=t.namespaces,o=t.enabled(e)),o),set:e=>{i=e}}),"function"==typeof t.init&&t.init(s),s}function n(e,n){const r=t(this.namespace+(void 0===n?":":n)+e);return r.log=this.log,r}function r(e){return e.toString().substring(2,e.toString().length-2).replace(/\.\*\?$/,"*")}return t.debug=t,t.default=t,t.coerce=function(e){if(e instanceof Error)return e.stack||e.message;return e},t.disable=function(){const e=[...t.names.map(r),...t.skips.map(r).map((e=>"-"+e))].join(",");return t.enable(""),e},t.enable=function(e){let n;t.save(e),t.namespaces=e,t.names=[],t.skips=[];const r=("string"==typeof e?e:"").split(/[\s,]+/),u=r.length;for(n=0;n{t[n]=e[n]})),t.names=[],t.skips=[],t.formatters={},t.selectColor=function(e){let n=0;for(let t=0;t{const n=e.startsWith("-")?"":1===e.length?"-":"--",r=t.indexOf(n+e),u=t.indexOf("--");return-1!==r&&(-1===u||r{}),"Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`."),t.colors=[6,2,3,4,5,1];try{const e=function(){if($r)return jr;$r=1;const e=E.default,t=A.default,n=Vr(),{env:r}=process;let u;function o(e){return 0!==e&&{level:e,hasBasic:!0,has256:e>=2,has16m:e>=3}}function i(t,o){if(0===u)return 0;if(n("color=16m")||n("color=full")||n("color=truecolor"))return 3;if(n("color=256"))return 2;if(t&&!o&&void 0===u)return 0;const i=u||0;if("dumb"===r.TERM)return i;if("win32"===process.platform){const t=e.release().split(".");return Number(t[0])>=10&&Number(t[2])>=10586?Number(t[2])>=14931?3:2:1}if("CI"in r)return["TRAVIS","CIRCLECI","APPVEYOR","GITLAB_CI","GITHUB_ACTIONS","BUILDKITE"].some((e=>e in r))||"codeship"===r.CI_NAME?1:i;if("TEAMCITY_VERSION"in r)return/^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(r.TEAMCITY_VERSION)?1:0;if("truecolor"===r.COLORTERM)return 3;if("TERM_PROGRAM"in r){const e=parseInt((r.TERM_PROGRAM_VERSION||"").split(".")[0],10);switch(r.TERM_PROGRAM){case"iTerm.app":return e>=3?3:2;case"Apple_Terminal":return 2}}return/-256(color)?$/i.test(r.TERM)?2:/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(r.TERM)||"COLORTERM"in r?1:i}return n("no-color")||n("no-colors")||n("color=false")||n("color=never")?u=0:(n("color")||n("colors")||n("color=true")||n("color=always"))&&(u=1),"FORCE_COLOR"in r&&(u="true"===r.FORCE_COLOR?1:"false"===r.FORCE_COLOR?0:0===r.FORCE_COLOR.length?1:Math.min(parseInt(r.FORCE_COLOR,10),3)),jr={supportsColor:function(e){return o(i(e,e&&e.isTTY))},stdout:o(i(!0,t.isatty(1))),stderr:o(i(!0,t.isatty(2)))}}();e&&(e.stderr||e).level>=2&&(t.colors=[20,21,26,27,32,33,38,39,40,41,42,43,44,45,56,57,62,63,68,69,74,75,76,77,78,79,80,81,92,93,98,99,112,113,128,129,134,135,148,149,160,161,162,163,164,165,166,167,168,169,170,171,172,173,178,179,184,185,196,197,198,199,200,201,202,203,204,205,206,207,208,209,214,215,220,221])}catch(e){}t.inspectOpts=Object.keys(process.env).filter((e=>/^debug_/i.test(e))).reduce(((e,t)=>{const n=t.substring(6).toLowerCase().replace(/_([a-z])/g,((e,t)=>t.toUpperCase()));let r=process.env[t];return r=!!/^(yes|on|true|enabled)$/i.test(r)||!/^(no|off|false|disabled)$/i.test(r)&&("null"===r?null:Number(r)),e[n]=r,e}),{}),e.exports=Rr()(t);const{formatters:u}=e.exports;u.o=function(e){return this.inspectOpts.colors=this.useColors,r.inspect(e,this.inspectOpts).split("\n").map((e=>e.trim())).join(" ")},u.O=function(e){return this.inspectOpts.colors=this.useColors,r.inspect(e,this.inspectOpts)}}(Gr,Gr.exports)),Gr.exports}Jr=Nr,"undefined"==typeof process||"renderer"===process.type||!0===process.browser||process.__nwjs?Jr.exports=(Br||(Br=1,function(e,t){t.formatArgs=function(t){if(t[0]=(this.useColors?"%c":"")+this.namespace+(this.useColors?" %c":" ")+t[0]+(this.useColors?"%c ":" ")+"+"+e.exports.humanize(this.diff),!this.useColors)return;const n="color: "+this.color;t.splice(1,0,n,"color: inherit");let r=0,u=0;t[0].replace(/%[a-zA-Z%]/g,(e=>{"%%"!==e&&(r++,"%c"===e&&(u=r))})),t.splice(u,0,n)},t.save=function(e){try{e?t.storage.setItem("debug",e):t.storage.removeItem("debug")}catch(e){}},t.load=function(){let e;try{e=t.storage.getItem("debug")}catch(e){}return!e&&"undefined"!=typeof process&&"env"in process&&(e=process.env.DEBUG),e},t.useColors=function(){return!("undefined"==typeof window||!window.process||"renderer"!==window.process.type&&!window.process.__nwjs)||("undefined"==typeof navigator||!navigator.userAgent||!navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/))&&("undefined"!=typeof document&&document.documentElement&&document.documentElement.style&&document.documentElement.style.WebkitAppearance||"undefined"!=typeof window&&window.console&&(window.console.firebug||window.console.exception&&window.console.table)||"undefined"!=typeof navigator&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/)&&parseInt(RegExp.$1,10)>=31||"undefined"!=typeof navigator&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/))},t.storage=function(){try{return localStorage}catch(e){}}(),t.destroy=(()=>{let e=!1;return()=>{e||(e=!0,console.warn("Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`."))}})(),t.colors=["#0000CC","#0000FF","#0033CC","#0033FF","#0066CC","#0066FF","#0099CC","#0099FF","#00CC00","#00CC33","#00CC66","#00CC99","#00CCCC","#00CCFF","#3300CC","#3300FF","#3333CC","#3333FF","#3366CC","#3366FF","#3399CC","#3399FF","#33CC00","#33CC33","#33CC66","#33CC99","#33CCCC","#33CCFF","#6600CC","#6600FF","#6633CC","#6633FF","#66CC00","#66CC33","#9900CC","#9900FF","#9933CC","#9933FF","#99CC00","#99CC33","#CC0000","#CC0033","#CC0066","#CC0099","#CC00CC","#CC00FF","#CC3300","#CC3333","#CC3366","#CC3399","#CC33CC","#CC33FF","#CC6600","#CC6633","#CC9900","#CC9933","#CCCC00","#CCCC33","#FF0000","#FF0033","#FF0066","#FF0099","#FF00CC","#FF00FF","#FF3300","#FF3333","#FF3366","#FF3399","#FF33CC","#FF33FF","#FF6600","#FF6633","#FF9900","#FF9933","#FFCC00","#FFCC33"],t.log=console.debug||console.log||(()=>{}),e.exports=Rr()(t);const{formatters:n}=e.exports;n.j=function(e){try{return JSON.stringify(e)}catch(e){return"[UnexpectedJSONParseError]: "+e.message}}}(Ir,Ir.exports)),Ir.exports):Jr.exports=Ur();var Wr=function(e){return(e=e||{}).circles?function(e){var t=[],n=[];return e.proto?function e(u){if("object"!=typeof u||null===u)return u;if(u instanceof Date)return new Date(u);if(Array.isArray(u))return r(u,e);if(u instanceof Map)return new Map(r(Array.from(u),e));if(u instanceof Set)return new Set(r(Array.from(u),e));var o={};for(var i in t.push(u),n.push(o),u){var s=u[i];if("object"!=typeof s||null===s)o[i]=s;else if(s instanceof Date)o[i]=new Date(s);else if(s instanceof Map)o[i]=new Map(r(Array.from(s),e));else if(s instanceof Set)o[i]=new Set(r(Array.from(s),e));else if(ArrayBuffer.isView(s))o[i]=zr(s);else{var c=t.indexOf(s);o[i]=-1!==c?n[c]:e(s)}}return t.pop(),n.pop(),o}:function e(u){if("object"!=typeof u||null===u)return u;if(u instanceof Date)return new Date(u);if(Array.isArray(u))return r(u,e);if(u instanceof Map)return new Map(r(Array.from(u),e));if(u instanceof Set)return new Set(r(Array.from(u),e));var o={};for(var i in t.push(u),n.push(o),u)if(!1!==Object.hasOwnProperty.call(u,i)){var s=u[i];if("object"!=typeof s||null===s)o[i]=s;else if(s instanceof Date)o[i]=new Date(s);else if(s instanceof Map)o[i]=new Map(r(Array.from(s),e));else if(s instanceof Set)o[i]=new Set(r(Array.from(s),e));else if(ArrayBuffer.isView(s))o[i]=zr(s);else{var c=t.indexOf(s);o[i]=-1!==c?n[c]:e(s)}}return t.pop(),n.pop(),o};function r(e,r){for(var u=Object.keys(e),o=new Array(u.length),i=0;i!e,Qr=e=>e&&"object"==typeof e&&!Array.isArray(e),eu=(e,t,n)=>{(Array.isArray(t)?t:[t]).forEach((t=>{if(t)throw new Error(`Problem with log4js configuration: (${Kr.inspect(e,{depth:5})}) - ${n}`)}))};var tu={configure:e=>{qr("New configuration to be validated: ",e),eu(e,Zr(Qr(e)),"must be an object."),qr(`Calling pre-processing listeners (${Yr.length})`),Yr.forEach((t=>t(e))),qr("Configuration pre-processing finished."),qr(`Calling configuration listeners (${Xr.length})`),Xr.forEach((t=>t(e))),qr("Configuration finished.")},addListener:e=>{Xr.push(e),qr(`Added listener, now ${Xr.length} listeners`)},addPreProcessingListener:e=>{Yr.push(e),qr(`Added pre-processing listener, now ${Yr.length} listeners`)},throwExceptionIf:eu,anObject:Qr,anInteger:e=>e&&"number"==typeof e&&Number.isInteger(e),validIdentifier:e=>/^[A-Za-z][A-Za-z0-9_]*$/g.test(e),not:Zr},nu={exports:{}};!function(e){function t(e,t){for(var n=e.toString();n.length-1?s:c,l=n(u.getHours()),f=n(u.getMinutes()),d=n(u.getSeconds()),D=t(u.getMilliseconds(),3),p=function(e){var t=Math.abs(e),n=String(Math.floor(t/60)),r=String(t%60);return n=("0"+n).slice(-2),r=("0"+r).slice(-2),0===e?"Z":(e<0?"+":"-")+n+":"+r}(u.getTimezoneOffset());return r.replace(/dd/g,o).replace(/MM/g,i).replace(/y{1,4}/g,a).replace(/hh/g,l).replace(/mm/g,f).replace(/ss/g,d).replace(/SSS/g,D).replace(/O/g,p)}function u(e,t,n,r){e["set"+(r?"":"UTC")+t](n)}e.exports=r,e.exports.asString=r,e.exports.parse=function(t,n,r){if(!t)throw new Error("pattern must be supplied");return function(t,n,r){var o=t.indexOf("O")<0,i=!1,s=[{pattern:/y{1,4}/,regexp:"\\d{1,4}",fn:function(e,t){u(e,"FullYear",t,o)}},{pattern:/MM/,regexp:"\\d{1,2}",fn:function(e,t){u(e,"Month",t-1,o),e.getMonth()!==t-1&&(i=!0)}},{pattern:/dd/,regexp:"\\d{1,2}",fn:function(e,t){i&&u(e,"Month",e.getMonth()-1,o),u(e,"Date",t,o)}},{pattern:/hh/,regexp:"\\d{1,2}",fn:function(e,t){u(e,"Hours",t,o)}},{pattern:/mm/,regexp:"\\d\\d",fn:function(e,t){u(e,"Minutes",t,o)}},{pattern:/ss/,regexp:"\\d\\d",fn:function(e,t){u(e,"Seconds",t,o)}},{pattern:/SSS/,regexp:"\\d\\d\\d",fn:function(e,t){u(e,"Milliseconds",t,o)}},{pattern:/O/,regexp:"[+-]\\d{1,2}:?\\d{2}?|Z",fn:function(e,t){t="Z"===t?0:t.replace(":","");var n=Math.abs(t),r=(t>0?-1:1)*(n%100+60*Math.floor(n/100));e.setUTCMinutes(e.getUTCMinutes()+r)}}],c=s.reduce((function(e,t){return t.pattern.test(e.regexp)?(t.index=e.regexp.match(t.pattern).index,e.regexp=e.regexp.replace(t.pattern,"("+t.regexp+")")):t.index=-1,e}),{regexp:t,index:[]}),a=s.filter((function(e){return e.index>-1}));a.sort((function(e,t){return e.index-t.index}));var l=new RegExp(c.regexp).exec(n);if(l){var f=r||e.exports.now();return a.forEach((function(e,t){e.fn(f,l[t+1])})),f}throw new Error("String '"+n+"' could not be parsed as '"+t+"'")}(t,n,r)},e.exports.now=function(){return new Date},e.exports.ISO8601_FORMAT="yyyy-MM-ddThh:mm:ss.SSS",e.exports.ISO8601_WITH_TZ_OFFSET_FORMAT="yyyy-MM-ddThh:mm:ss.SSSO",e.exports.DATETIME_FORMAT="dd MM yyyy hh:mm:ss.SSS",e.exports.ABSOLUTETIME_FORMAT="hh:mm:ss.SSS"}(nu);const ru=nu.exports,uu=E.default,ou=F.default,iu=p.default,su={bold:[1,22],italic:[3,23],underline:[4,24],inverse:[7,27],white:[37,39],grey:[90,39],black:[90,39],blue:[34,39],cyan:[36,39],green:[32,39],magenta:[35,39],red:[91,39],yellow:[33,39]};function cu(e){return e?`[${su[e][0]}m`:""}function au(e){return e?`[${su[e][1]}m`:""}function lu(e,t){return n=ou.format("[%s] [%s] %s - ",ru.asString(e.startTime),e.level.toString(),e.categoryName),cu(r=t)+n+au(r);var n,r}function fu(e){return lu(e)+ou.format(...e.data)}function du(e){return lu(e,e.level.colour)+ou.format(...e.data)}function Du(e){return ou.format(...e.data)}function pu(e){return e.data[0]}function Eu(e,t){const n=/%(-?[0-9]+)?(\.?-?[0-9]+)?([[\]cdhmnprzxXyflos%])(\{([^}]+)\})?|([^%]+)/;function r(e){return e&&e.pid?e.pid.toString():process.pid.toString()}e=e||"%r %p %c - %m%n";const u={c:function(e,t){let n=e.categoryName;if(t){const e=parseInt(t,10),r=n.split(".");ee&&(n=r.slice(-e).join(iu.sep))}return n},l:function(e){return e.lineNumber?`${e.lineNumber}`:""},o:function(e){return e.columnNumber?`${e.columnNumber}`:""},s:function(e){return e.callStack||""}};function o(e,t,n){return u[e](t,n)}function i(e,t,n){let r=e;return r=function(e,t){let n;return e?(n=parseInt(e.substr(1),10),n>0?t.slice(0,n):t.slice(n)):t}(t,r),r=function(e,t){let n;if(e)if("-"===e.charAt(0))for(n=parseInt(e.substr(1),10);t.lengthDu,basic:()=>fu,colored:()=>du,coloured:()=>du,pattern:e=>Eu(e&&e.pattern,e&&e.tokens),dummy:()=>pu};var hu={basicLayout:fu,messagePassThroughLayout:Du,patternLayout:Eu,colouredLayout:du,coloredLayout:du,dummyLayout:pu,addLayout(e,t){mu[e]=t},layout:(e,t)=>mu[e]&&mu[e](t)};const yu=tu,Cu=["white","grey","black","blue","cyan","green","magenta","red","yellow"];class Fu{constructor(e,t,n){this.level=e,this.levelStr=t,this.colour=n}toString(){return this.levelStr}static getLevel(e,t){return e?e instanceof Fu?e:(e instanceof Object&&e.levelStr&&(e=e.levelStr),Fu[e.toString().toUpperCase()]||t):t}static addLevels(e){if(e){Object.keys(e).forEach((t=>{const n=t.toUpperCase();Fu[n]=new Fu(e[t].value,n,e[t].colour);const r=Fu.levels.findIndex((e=>e.levelStr===n));r>-1?Fu.levels[r]=Fu[n]:Fu.levels.push(Fu[n])})),Fu.levels.sort(((e,t)=>e.level-t.level))}}isLessThanOrEqualTo(e){return"string"==typeof e&&(e=Fu.getLevel(e)),this.level<=e.level}isGreaterThanOrEqualTo(e){return"string"==typeof e&&(e=Fu.getLevel(e)),this.level>=e.level}isEqualTo(e){return"string"==typeof e&&(e=Fu.getLevel(e)),this.level===e.level}}Fu.levels=[],Fu.addLevels({ALL:{value:Number.MIN_VALUE,colour:"grey"},TRACE:{value:5e3,colour:"blue"},DEBUG:{value:1e4,colour:"cyan"},INFO:{value:2e4,colour:"green"},WARN:{value:3e4,colour:"yellow"},ERROR:{value:4e4,colour:"red"},FATAL:{value:5e4,colour:"magenta"},MARK:{value:9007199254740992,colour:"grey"},OFF:{value:Number.MAX_VALUE,colour:"grey"}}),yu.addListener((e=>{const t=e.levels;if(t){yu.throwExceptionIf(e,yu.not(yu.anObject(t)),"levels must be an object");Object.keys(t).forEach((n=>{yu.throwExceptionIf(e,yu.not(yu.validIdentifier(n)),`level name "${n}" is not a valid identifier (must start with a letter, only contain A-Z,a-z,0-9,_)`),yu.throwExceptionIf(e,yu.not(yu.anObject(t[n])),`level "${n}" must be an object`),yu.throwExceptionIf(e,yu.not(t[n].value),`level "${n}" must have a 'value' property`),yu.throwExceptionIf(e,yu.not(yu.anInteger(t[n].value)),`level "${n}".value must have an integer value`),yu.throwExceptionIf(e,yu.not(t[n].colour),`level "${n}" must have a 'colour' property`),yu.throwExceptionIf(e,yu.not(Cu.indexOf(t[n].colour)>-1),`level "${n}".colour must be one of ${Cu.join(", ")}`)}))}})),yu.addListener((e=>{Fu.addLevels(e.levels)}));var gu=Fu,Au={exports:{}},vu={};/*! (c) 2020 Andrea Giammarchi */ -const{parse:Su,stringify:wu}=JSON,{keys:Ou}=Object,bu=String,_u="string",Bu={},Pu="object",ku=(e,t)=>t,xu=e=>e instanceof bu?bu(e):e,Nu=(e,t)=>typeof t===_u?new bu(t):t,Iu=(e,t,n,r)=>{const u=[];for(let o=Ou(n),{length:i}=o,s=0;s{const r=bu(t.push(n)-1);return e.set(n,r),r},Ru=(e,t)=>{const n=Su(e,Nu).map(xu),r=n[0],u=t||ku,o=typeof r===Pu&&r?Iu(n,new Set,r,u):r;return u.call({"":o},"",o)};vu.parse=Ru;const Mu=(e,t,n)=>{const r=t&&typeof t===Pu?(e,n)=>""===e||-1Su(Mu(e));vu.fromJSON=e=>Ru(wu(e));const Lu=vu,ju=gu;class $u{constructor(e,t,n,r,u){this.startTime=new Date,this.categoryName=e,this.data=n,this.level=t,this.context=Object.assign({},r),this.pid=process.pid,u&&(this.functionName=u.functionName,this.fileName=u.fileName,this.lineNumber=u.lineNumber,this.columnNumber=u.columnNumber,this.callStack=u.callStack)}serialise(){const e=this.data.map((e=>(e&&e.message&&e.stack&&(e=Object.assign({message:e.message,stack:e.stack},e)),e)));return this.data=e,Lu.stringify(this)}static deserialise(e){let t;try{const n=Lu.parse(e);n.data=n.data.map((e=>{if(e&&e.message&&e.stack){const t=new Error(e);Object.keys(e).forEach((n=>{t[n]=e[n]})),e=t}return e})),t=new $u(n.categoryName,ju.getLevel(n.level.levelStr),n.data,n.context),t.startTime=new Date(n.startTime),t.pid=n.pid,t.cluster=n.cluster}catch(n){t=new $u("log4js",ju.ERROR,["Unable to parse log:",e,"because: ",n])}return t}}var Hu=$u;const Ju=Nr.exports("log4js:clustering"),Gu=Hu,Vu=tu;let Uu=!1,Wu=null;try{Wu=require("cluster")}catch(e){Ju("cluster module not present"),Uu=!0}const zu=[];let Ku=!1,qu="NODE_APP_INSTANCE";const Yu=()=>Ku&&"0"===process.env[qu],Xu=()=>Uu||Wu.isMaster||Yu(),Zu=e=>{zu.forEach((t=>t(e)))},Qu=(e,t)=>{if(Ju("cluster message received from worker ",e,": ",t),e.topic&&e.data&&(t=e,e=void 0),t&&t.topic&&"log4js:message"===t.topic){Ju("received message: ",t.data);const e=Gu.deserialise(t.data);Zu(e)}};Uu||Vu.addListener((e=>{zu.length=0,({pm2:Ku,disableClustering:Uu,pm2InstanceVar:qu="NODE_APP_INSTANCE"}=e),Ju(`clustering disabled ? ${Uu}`),Ju(`cluster.isMaster ? ${Wu&&Wu.isMaster}`),Ju(`pm2 enabled ? ${Ku}`),Ju(`pm2InstanceVar = ${qu}`),Ju(`process.env[${qu}] = ${process.env[qu]}`),Ku&&process.removeListener("message",Qu),Wu&&Wu.removeListener&&Wu.removeListener("message",Qu),Uu||e.disableClustering?Ju("Not listening for cluster messages, because clustering disabled."):Yu()?(Ju("listening for PM2 broadcast messages"),process.on("message",Qu)):Wu.isMaster?(Ju("listening for cluster messages"),Wu.on("message",Qu)):Ju("not listening for messages, because we are not a master process")}));var eo={onlyOnMaster:(e,t)=>Xu()?e():t,isMaster:Xu,send:e=>{Xu()?Zu(e):(Ku||(e.cluster={workerId:Wu.worker.id,worker:process.pid}),process.send({topic:"log4js:message",data:e.serialise()}))},onMessage:e=>{zu.push(e)}},to={};function no(e){if("number"==typeof e&&Number.isInteger(e))return e;const t={K:1024,M:1048576,G:1073741824},n=Object.keys(t),r=e.substr(e.length-1).toLocaleUpperCase(),u=e.substring(0,e.length-1).trim();if(n.indexOf(r)<0||!Number.isInteger(Number(u)))throw Error(`maxLogSize: "${e}" is invalid`);return u*t[r]}function ro(e){return function(e,t){const n=Object.assign({},t);return Object.keys(e).forEach((r=>{n[r]&&(n[r]=e[r](t[r]))})),n}({maxLogSize:no},e)}const uo={file:ro,fileSync:ro};to.modifyConfig=e=>uo[e.type]?uo[e.type](e):e;var oo={};const io=console.log.bind(console);oo.configure=function(e,t){let n=t.colouredLayout;return e.layout&&(n=t.layout(e.layout.type,e.layout)),function(e,t){return n=>{io(e(n,t))}}(n,e.timezoneOffset)};var so={};so.configure=function(e,t){let n=t.colouredLayout;return e.layout&&(n=t.layout(e.layout.type,e.layout)),function(e,t){return n=>{process.stdout.write(`${e(n,t)}\n`)}}(n,e.timezoneOffset)};var co={};co.configure=function(e,t){let n=t.colouredLayout;return e.layout&&(n=t.layout(e.layout.type,e.layout)),function(e,t){return n=>{process.stderr.write(`${e(n,t)}\n`)}}(n,e.timezoneOffset)};var ao={};ao.configure=function(e,t,n,r){const u=n(e.appender);return function(e,t,n,r){const u=r.getLevel(e),o=r.getLevel(t,r.FATAL);return e=>{const t=e.level;t.isGreaterThanOrEqualTo(u)&&t.isLessThanOrEqualTo(o)&&n(e)}}(e.level,e.maxLevel,u,r)};var lo={};const fo=Nr.exports("log4js:categoryFilter");lo.configure=function(e,t,n){const r=n(e.appender);return function(e,t){return"string"==typeof e&&(e=[e]),n=>{fo(`Checking ${n.categoryName} against ${e}`),-1===e.indexOf(n.categoryName)&&(fo("Not excluded, sending to appender"),t(n))}}(e.exclude,r)};var Do={};const po=Nr.exports("log4js:noLogFilter");Do.configure=function(e,t,n){const r=n(e.appender);return function(e,t){return n=>{po(`Checking data: ${n.data} against filters: ${e}`),"string"==typeof e&&(e=[e]),e=e.filter((e=>null!=e&&""!==e));const r=new RegExp(e.join("|"),"i");(0===e.length||n.data.findIndex((e=>r.test(e)))<0)&&(po("Not excluded, sending to appender"),t(n))}}(e.exclude,r)};var Eo={},mo={exports:{}},ho={},yo={fromCallback:function(e){return Object.defineProperty((function(){if("function"!=typeof arguments[arguments.length-1])return new Promise(((t,n)=>{arguments[arguments.length]=(e,r)=>{if(e)return n(e);t(r)},arguments.length++,e.apply(this,arguments)}));e.apply(this,arguments)}),"name",{value:e.name})},fromPromise:function(e){return Object.defineProperty((function(){const t=arguments[arguments.length-1];if("function"!=typeof t)return e.apply(this,arguments);e.apply(this,arguments).then((e=>t(null,e)),t)}),"name",{value:e.name})}};!function(e){const t=yo.fromCallback,n=we,r=["access","appendFile","chmod","chown","close","copyFile","fchmod","fchown","fdatasync","fstat","fsync","ftruncate","futimes","lchown","lchmod","link","lstat","mkdir","mkdtemp","open","readFile","readdir","readlink","realpath","rename","rmdir","stat","symlink","truncate","unlink","utimes","writeFile"].filter((e=>"function"==typeof n[e]));Object.keys(n).forEach((t=>{"promises"!==t&&(e[t]=n[t])})),r.forEach((r=>{e[r]=t(n[r])})),e.exists=function(e,t){return"function"==typeof t?n.exists(e,t):new Promise((t=>n.exists(e,t)))},e.read=function(e,t,r,u,o,i){return"function"==typeof i?n.read(e,t,r,u,o,i):new Promise(((i,s)=>{n.read(e,t,r,u,o,((e,t,n)=>{if(e)return s(e);i({bytesRead:t,buffer:n})}))}))},e.write=function(e,t,...r){return"function"==typeof r[r.length-1]?n.write(e,t,...r):new Promise(((u,o)=>{n.write(e,t,...r,((e,t,n)=>{if(e)return o(e);u({bytesWritten:t,buffer:n})}))}))},"function"==typeof n.realpath.native&&(e.realpath.native=t(n.realpath.native))}(ho);const Co=p.default;function Fo(e){return(e=Co.normalize(Co.resolve(e)).split(Co.sep)).length>0?e[0]:null}const go=/[<>:"|?*]/;var Ao=function(e){const t=Fo(e);return e=e.replace(t,""),go.test(e)};const vo=we,So=p.default,wo=Ao,Oo=parseInt("0777",8);var bo=function e(t,n,r,u){if("function"==typeof n?(r=n,n={}):n&&"object"==typeof n||(n={mode:n}),"win32"===process.platform&&wo(t)){const e=new Error(t+" contains invalid WIN32 path characters.");return e.code="EINVAL",r(e)}let o=n.mode;const i=n.fs||vo;void 0===o&&(o=Oo&~process.umask()),u||(u=null),r=r||function(){},t=So.resolve(t),i.mkdir(t,o,(o=>{if(!o)return r(null,u=u||t);if("ENOENT"===o.code){if(So.dirname(t)===t)return r(o);e(So.dirname(t),n,((u,o)=>{u?r(u,o):e(t,n,r,o)}))}else i.stat(t,((e,t)=>{e||!t.isDirectory()?r(o,u):r(null,u)}))}))};const _o=we,Bo=p.default,Po=Ao,ko=parseInt("0777",8);var xo=function e(t,n,r){n&&"object"==typeof n||(n={mode:n});let u=n.mode;const o=n.fs||_o;if("win32"===process.platform&&Po(t)){const e=new Error(t+" contains invalid WIN32 path characters.");throw e.code="EINVAL",e}void 0===u&&(u=ko&~process.umask()),r||(r=null),t=Bo.resolve(t);try{o.mkdirSync(t,u),r=r||t}catch(u){if("ENOENT"===u.code){if(Bo.dirname(t)===t)throw u;r=e(Bo.dirname(t),n,r),e(t,n,r)}else{let e;try{e=o.statSync(t)}catch(e){throw u}if(!e.isDirectory())throw u}}return r};const No=(0,yo.fromCallback)(bo);var Io={mkdirs:No,mkdirsSync:xo,mkdirp:No,mkdirpSync:xo,ensureDir:No,ensureDirSync:xo};const To=we;E.default,p.default;var Ro=function(e,t,n,r){To.open(e,"r+",((e,u)=>{if(e)return r(e);To.futimes(u,t,n,(e=>{To.close(u,(t=>{r&&r(e||t)}))}))}))},Mo=function(e,t,n){const r=To.openSync(e,"r+");return To.futimesSync(r,t,n),To.closeSync(r)};const Lo=we,jo=p.default,$o=10,Ho=5,Jo=0,Go=process.versions.node.split("."),Vo=Number.parseInt(Go[0],10),Uo=Number.parseInt(Go[1],10),Wo=Number.parseInt(Go[2],10);function zo(){if(Vo>$o)return!0;if(Vo===$o){if(Uo>Ho)return!0;if(Uo===Ho&&Wo>=Jo)return!0}return!1}function Ko(e,t){const n=jo.resolve(e).split(jo.sep).filter((e=>e)),r=jo.resolve(t).split(jo.sep).filter((e=>e));return n.reduce(((e,t,n)=>e&&r[n]===t),!0)}function qo(e,t,n){return`Cannot ${n} '${e}' to a subdirectory of itself, '${t}'.`}var Yo,Xo,Zo={checkPaths:function(e,t,n,r){!function(e,t,n){zo()?Lo.stat(e,{bigint:!0},((e,r)=>{if(e)return n(e);Lo.stat(t,{bigint:!0},((e,t)=>e?"ENOENT"===e.code?n(null,{srcStat:r,destStat:null}):n(e):n(null,{srcStat:r,destStat:t})))})):Lo.stat(e,((e,r)=>{if(e)return n(e);Lo.stat(t,((e,t)=>e?"ENOENT"===e.code?n(null,{srcStat:r,destStat:null}):n(e):n(null,{srcStat:r,destStat:t})))}))}(e,t,((u,o)=>{if(u)return r(u);const{srcStat:i,destStat:s}=o;return s&&s.ino&&s.dev&&s.ino===i.ino&&s.dev===i.dev?r(new Error("Source and destination must not be the same.")):i.isDirectory()&&Ko(e,t)?r(new Error(qo(e,t,n))):r(null,{srcStat:i,destStat:s})}))},checkPathsSync:function(e,t,n){const{srcStat:r,destStat:u}=function(e,t){let n,r;n=zo()?Lo.statSync(e,{bigint:!0}):Lo.statSync(e);try{r=zo()?Lo.statSync(t,{bigint:!0}):Lo.statSync(t)}catch(e){if("ENOENT"===e.code)return{srcStat:n,destStat:null};throw e}return{srcStat:n,destStat:r}}(e,t);if(u&&u.ino&&u.dev&&u.ino===r.ino&&u.dev===r.dev)throw new Error("Source and destination must not be the same.");if(r.isDirectory()&&Ko(e,t))throw new Error(qo(e,t,n));return{srcStat:r,destStat:u}},checkParentPaths:function e(t,n,r,u,o){const i=jo.resolve(jo.dirname(t)),s=jo.resolve(jo.dirname(r));if(s===i||s===jo.parse(s).root)return o();zo()?Lo.stat(s,{bigint:!0},((i,c)=>i?"ENOENT"===i.code?o():o(i):c.ino&&c.dev&&c.ino===n.ino&&c.dev===n.dev?o(new Error(qo(t,r,u))):e(t,n,s,u,o))):Lo.stat(s,((i,c)=>i?"ENOENT"===i.code?o():o(i):c.ino&&c.dev&&c.ino===n.ino&&c.dev===n.dev?o(new Error(qo(t,r,u))):e(t,n,s,u,o)))},checkParentPathsSync:function e(t,n,r,u){const o=jo.resolve(jo.dirname(t)),i=jo.resolve(jo.dirname(r));if(i===o||i===jo.parse(i).root)return;let s;try{s=zo()?Lo.statSync(i,{bigint:!0}):Lo.statSync(i)}catch(e){if("ENOENT"===e.code)return;throw e}if(s.ino&&s.dev&&s.ino===n.ino&&s.dev===n.dev)throw new Error(qo(t,r,u));return e(t,n,i,u)},isSrcSubdir:Ko};const Qo=we,ei=p.default,ti=Io.mkdirsSync,ni=Mo,ri=Zo;function ui(e,t,n,r){if(!r.filter||r.filter(t,n))return function(e,t,n,r){const u=r.dereference?Qo.statSync:Qo.lstatSync,o=u(t);if(o.isDirectory())return function(e,t,n,r,u){if(!t)return function(e,t,n,r){return Qo.mkdirSync(n),ii(t,n,r),Qo.chmodSync(n,e.mode)}(e,n,r,u);if(t&&!t.isDirectory())throw new Error(`Cannot overwrite non-directory '${r}' with directory '${n}'.`);return ii(n,r,u)}(o,e,t,n,r);if(o.isFile()||o.isCharacterDevice()||o.isBlockDevice())return function(e,t,n,r,u){return t?function(e,t,n,r){if(r.overwrite)return Qo.unlinkSync(n),oi(e,t,n,r);if(r.errorOnExist)throw new Error(`'${n}' already exists`)}(e,n,r,u):oi(e,n,r,u)}(o,e,t,n,r);if(o.isSymbolicLink())return function(e,t,n,r){let u=Qo.readlinkSync(t);r.dereference&&(u=ei.resolve(process.cwd(),u));if(e){let e;try{e=Qo.readlinkSync(n)}catch(e){if("EINVAL"===e.code||"UNKNOWN"===e.code)return Qo.symlinkSync(u,n);throw e}if(r.dereference&&(e=ei.resolve(process.cwd(),e)),ri.isSrcSubdir(u,e))throw new Error(`Cannot copy '${u}' to a subdirectory of itself, '${e}'.`);if(Qo.statSync(n).isDirectory()&&ri.isSrcSubdir(e,u))throw new Error(`Cannot overwrite '${e}' with '${u}'.`);return function(e,t){return Qo.unlinkSync(t),Qo.symlinkSync(e,t)}(u,n)}return Qo.symlinkSync(u,n)}(e,t,n,r)}(e,t,n,r)}function oi(e,t,n,r){return"function"==typeof Qo.copyFileSync?(Qo.copyFileSync(t,n),Qo.chmodSync(n,e.mode),r.preserveTimestamps?ni(n,e.atime,e.mtime):void 0):function(e,t,n,r){const u=65536,o=(Xo?Yo:(Xo=1,Yo=function(e){if("function"==typeof Buffer.allocUnsafe)try{return Buffer.allocUnsafe(e)}catch(t){return new Buffer(e)}return new Buffer(e)}))(u),i=Qo.openSync(t,"r"),s=Qo.openSync(n,"w",e.mode);let c=0;for(;cfunction(e,t,n,r){const u=ei.join(t,e),o=ei.join(n,e),{destStat:i}=ri.checkPathsSync(u,o,"copy");return ui(i,u,o,r)}(r,e,t,n)))}var si=function(e,t,n){"function"==typeof n&&(n={filter:n}),(n=n||{}).clobber=!("clobber"in n)||!!n.clobber,n.overwrite="overwrite"in n?!!n.overwrite:n.clobber,n.preserveTimestamps&&"ia32"===process.arch&&console.warn("fs-extra: Using the preserveTimestamps option in 32-bit node is not recommended;\n\n see https://github.com/jprichardson/node-fs-extra/issues/269");const{srcStat:r,destStat:u}=ri.checkPathsSync(e,t,"copy");return ri.checkParentPathsSync(e,r,t,"copy"),function(e,t,n,r){if(r.filter&&!r.filter(t,n))return;const u=ei.dirname(n);Qo.existsSync(u)||ti(u);return ui(e,t,n,r)}(u,e,t,n)},ci={copySync:si};const ai=yo.fromPromise,li=ho;var fi={pathExists:ai((function(e){return li.access(e).then((()=>!0)).catch((()=>!1))})),pathExistsSync:li.existsSync};const di=we,Di=p.default,pi=Io.mkdirs,Ei=fi.pathExists,mi=Ro,hi=Zo;function yi(e,t,n,r,u){const o=Di.dirname(n);Ei(o,((i,s)=>i?u(i):s?Fi(e,t,n,r,u):void pi(o,(o=>o?u(o):Fi(e,t,n,r,u)))))}function Ci(e,t,n,r,u,o){Promise.resolve(u.filter(n,r)).then((i=>i?e(t,n,r,u,o):o()),(e=>o(e)))}function Fi(e,t,n,r,u){return r.filter?Ci(gi,e,t,n,r,u):gi(e,t,n,r,u)}function gi(e,t,n,r,u){(r.dereference?di.stat:di.lstat)(t,((o,i)=>o?u(o):i.isDirectory()?function(e,t,n,r,u,o){if(!t)return function(e,t,n,r,u){di.mkdir(n,(o=>{if(o)return u(o);Si(t,n,r,(t=>t?u(t):di.chmod(n,e.mode,u)))}))}(e,n,r,u,o);if(t&&!t.isDirectory())return o(new Error(`Cannot overwrite non-directory '${r}' with directory '${n}'.`));return Si(n,r,u,o)}(i,e,t,n,r,u):i.isFile()||i.isCharacterDevice()||i.isBlockDevice()?function(e,t,n,r,u,o){return t?function(e,t,n,r,u){if(!r.overwrite)return r.errorOnExist?u(new Error(`'${n}' already exists`)):u();di.unlink(n,(o=>o?u(o):Ai(e,t,n,r,u)))}(e,n,r,u,o):Ai(e,n,r,u,o)}(i,e,t,n,r,u):i.isSymbolicLink()?function(e,t,n,r,u){di.readlink(t,((t,o)=>t?u(t):(r.dereference&&(o=Di.resolve(process.cwd(),o)),e?void di.readlink(n,((t,i)=>t?"EINVAL"===t.code||"UNKNOWN"===t.code?di.symlink(o,n,u):u(t):(r.dereference&&(i=Di.resolve(process.cwd(),i)),hi.isSrcSubdir(o,i)?u(new Error(`Cannot copy '${o}' to a subdirectory of itself, '${i}'.`)):e.isDirectory()&&hi.isSrcSubdir(i,o)?u(new Error(`Cannot overwrite '${i}' with '${o}'.`)):function(e,t,n){di.unlink(t,(r=>r?n(r):di.symlink(e,t,n)))}(o,n,u)))):di.symlink(o,n,u))))}(e,t,n,r,u):void 0))}function Ai(e,t,n,r,u){return"function"==typeof di.copyFile?di.copyFile(t,n,(t=>t?u(t):vi(e,n,r,u))):function(e,t,n,r,u){const o=di.createReadStream(t);o.on("error",(e=>u(e))).once("open",(()=>{const t=di.createWriteStream(n,{mode:e.mode});t.on("error",(e=>u(e))).on("open",(()=>o.pipe(t))).once("close",(()=>vi(e,n,r,u)))}))}(e,t,n,r,u)}function vi(e,t,n,r){di.chmod(t,e.mode,(u=>u?r(u):n.preserveTimestamps?mi(t,e.atime,e.mtime,r):r()))}function Si(e,t,n,r){di.readdir(e,((u,o)=>u?r(u):wi(o,e,t,n,r)))}function wi(e,t,n,r,u){const o=e.pop();return o?function(e,t,n,r,u,o){const i=Di.join(n,t),s=Di.join(r,t);hi.checkPaths(i,s,"copy",((t,c)=>{if(t)return o(t);const{destStat:a}=c;Fi(a,i,s,u,(t=>t?o(t):wi(e,n,r,u,o)))}))}(e,o,t,n,r,u):u()}var Oi=function(e,t,n,r){"function"!=typeof n||r?"function"==typeof n&&(n={filter:n}):(r=n,n={}),r=r||function(){},(n=n||{}).clobber=!("clobber"in n)||!!n.clobber,n.overwrite="overwrite"in n?!!n.overwrite:n.clobber,n.preserveTimestamps&&"ia32"===process.arch&&console.warn("fs-extra: Using the preserveTimestamps option in 32-bit node is not recommended;\n\n see https://github.com/jprichardson/node-fs-extra/issues/269"),hi.checkPaths(e,t,"copy",((u,o)=>{if(u)return r(u);const{srcStat:i,destStat:s}=o;hi.checkParentPaths(e,i,t,"copy",(u=>u?r(u):n.filter?Ci(yi,s,e,t,n,r):yi(s,e,t,n,r)))}))};var bi={copy:(0,yo.fromCallback)(Oi)};const _i=we,Bi=p.default,Pi=g.default,ki="win32"===process.platform;function xi(e){["unlink","chmod","stat","lstat","rmdir","readdir"].forEach((t=>{e[t]=e[t]||_i[t],e[t+="Sync"]=e[t]||_i[t]})),e.maxBusyTries=e.maxBusyTries||3}function Ni(e,t,n){let r=0;"function"==typeof t&&(n=t,t={}),Pi(e,"rimraf: missing path"),Pi.strictEqual(typeof e,"string","rimraf: path should be a string"),Pi.strictEqual(typeof n,"function","rimraf: callback function required"),Pi(t,"rimraf: invalid options argument provided"),Pi.strictEqual(typeof t,"object","rimraf: options should be object"),xi(t),Ii(e,t,(function u(o){if(o){if(("EBUSY"===o.code||"ENOTEMPTY"===o.code||"EPERM"===o.code)&&rIi(e,t,u)),100*r)}"ENOENT"===o.code&&(o=null)}n(o)}))}function Ii(e,t,n){Pi(e),Pi(t),Pi("function"==typeof n),t.lstat(e,((r,u)=>r&&"ENOENT"===r.code?n(null):r&&"EPERM"===r.code&&ki?Ti(e,t,r,n):u&&u.isDirectory()?Mi(e,t,r,n):void t.unlink(e,(r=>{if(r){if("ENOENT"===r.code)return n(null);if("EPERM"===r.code)return ki?Ti(e,t,r,n):Mi(e,t,r,n);if("EISDIR"===r.code)return Mi(e,t,r,n)}return n(r)}))))}function Ti(e,t,n,r){Pi(e),Pi(t),Pi("function"==typeof r),n&&Pi(n instanceof Error),t.chmod(e,438,(u=>{u?r("ENOENT"===u.code?null:n):t.stat(e,((u,o)=>{u?r("ENOENT"===u.code?null:n):o.isDirectory()?Mi(e,t,n,r):t.unlink(e,r)}))}))}function Ri(e,t,n){let r;Pi(e),Pi(t),n&&Pi(n instanceof Error);try{t.chmodSync(e,438)}catch(e){if("ENOENT"===e.code)return;throw n}try{r=t.statSync(e)}catch(e){if("ENOENT"===e.code)return;throw n}r.isDirectory()?ji(e,t,n):t.unlinkSync(e)}function Mi(e,t,n,r){Pi(e),Pi(t),n&&Pi(n instanceof Error),Pi("function"==typeof r),t.rmdir(e,(u=>{!u||"ENOTEMPTY"!==u.code&&"EEXIST"!==u.code&&"EPERM"!==u.code?u&&"ENOTDIR"===u.code?r(n):r(u):function(e,t,n){Pi(e),Pi(t),Pi("function"==typeof n),t.readdir(e,((r,u)=>{if(r)return n(r);let o,i=u.length;if(0===i)return t.rmdir(e,n);u.forEach((r=>{Ni(Bi.join(e,r),t,(r=>{if(!o)return r?n(o=r):void(0==--i&&t.rmdir(e,n))}))}))}))}(e,t,r)}))}function Li(e,t){let n;xi(t=t||{}),Pi(e,"rimraf: missing path"),Pi.strictEqual(typeof e,"string","rimraf: path should be a string"),Pi(t,"rimraf: missing options"),Pi.strictEqual(typeof t,"object","rimraf: options should be object");try{n=t.lstatSync(e)}catch(n){if("ENOENT"===n.code)return;"EPERM"===n.code&&ki&&Ri(e,t,n)}try{n&&n.isDirectory()?ji(e,t,null):t.unlinkSync(e)}catch(n){if("ENOENT"===n.code)return;if("EPERM"===n.code)return ki?Ri(e,t,n):ji(e,t,n);if("EISDIR"!==n.code)throw n;ji(e,t,n)}}function ji(e,t,n){Pi(e),Pi(t),n&&Pi(n instanceof Error);try{t.rmdirSync(e)}catch(r){if("ENOTDIR"===r.code)throw n;if("ENOTEMPTY"===r.code||"EEXIST"===r.code||"EPERM"===r.code)!function(e,t){if(Pi(e),Pi(t),t.readdirSync(e).forEach((n=>Li(Bi.join(e,n),t))),!ki){return t.rmdirSync(e,t)}{const n=Date.now();do{try{return t.rmdirSync(e,t)}catch(e){}}while(Date.now()-n<500)}}(e,t);else if("ENOENT"!==r.code)throw r}}var $i=Ni;Ni.sync=Li;const Hi=$i;var Ji={remove:(0,yo.fromCallback)(Hi),removeSync:Hi.sync};const Gi=yo.fromCallback,Vi=we,Ui=p.default,Wi=Io,zi=Ji,Ki=Gi((function(e,t){t=t||function(){},Vi.readdir(e,((n,r)=>{if(n)return Wi.mkdirs(e,t);r=r.map((t=>Ui.join(e,t))),function e(){const n=r.pop();if(!n)return t();zi.remove(n,(n=>{if(n)return t(n);e()}))}()}))}));function qi(e){let t;try{t=Vi.readdirSync(e)}catch(t){return Wi.mkdirsSync(e)}t.forEach((t=>{t=Ui.join(e,t),zi.removeSync(t)}))}var Yi={emptyDirSync:qi,emptydirSync:qi,emptyDir:Ki,emptydir:Ki};const Xi=yo.fromCallback,Zi=p.default,Qi=we,es=Io,ts=fi.pathExists;var ns={createFile:Xi((function(e,t){function n(){Qi.writeFile(e,"",(e=>{if(e)return t(e);t()}))}Qi.stat(e,((r,u)=>{if(!r&&u.isFile())return t();const o=Zi.dirname(e);ts(o,((e,r)=>e?t(e):r?n():void es.mkdirs(o,(e=>{if(e)return t(e);n()}))))}))})),createFileSync:function(e){let t;try{t=Qi.statSync(e)}catch(e){}if(t&&t.isFile())return;const n=Zi.dirname(e);Qi.existsSync(n)||es.mkdirsSync(n),Qi.writeFileSync(e,"")}};const rs=yo.fromCallback,us=p.default,os=we,is=Io,ss=fi.pathExists;var cs={createLink:rs((function(e,t,n){function r(e,t){os.link(e,t,(e=>{if(e)return n(e);n(null)}))}ss(t,((u,o)=>u?n(u):o?n(null):void os.lstat(e,(u=>{if(u)return u.message=u.message.replace("lstat","ensureLink"),n(u);const o=us.dirname(t);ss(o,((u,i)=>u?n(u):i?r(e,t):void is.mkdirs(o,(u=>{if(u)return n(u);r(e,t)}))))}))))})),createLinkSync:function(e,t){if(os.existsSync(t))return;try{os.lstatSync(e)}catch(e){throw e.message=e.message.replace("lstat","ensureLink"),e}const n=us.dirname(t);return os.existsSync(n)||is.mkdirsSync(n),os.linkSync(e,t)}};const as=p.default,ls=we,fs=fi.pathExists;var ds={symlinkPaths:function(e,t,n){if(as.isAbsolute(e))return ls.lstat(e,(t=>t?(t.message=t.message.replace("lstat","ensureSymlink"),n(t)):n(null,{toCwd:e,toDst:e})));{const r=as.dirname(t),u=as.join(r,e);return fs(u,((t,o)=>t?n(t):o?n(null,{toCwd:u,toDst:e}):ls.lstat(e,(t=>t?(t.message=t.message.replace("lstat","ensureSymlink"),n(t)):n(null,{toCwd:e,toDst:as.relative(r,e)})))))}},symlinkPathsSync:function(e,t){let n;if(as.isAbsolute(e)){if(n=ls.existsSync(e),!n)throw new Error("absolute srcpath does not exist");return{toCwd:e,toDst:e}}{const r=as.dirname(t),u=as.join(r,e);if(n=ls.existsSync(u),n)return{toCwd:u,toDst:e};if(n=ls.existsSync(e),!n)throw new Error("relative srcpath does not exist");return{toCwd:e,toDst:as.relative(r,e)}}}};const Ds=we;var ps={symlinkType:function(e,t,n){if(n="function"==typeof t?t:n,t="function"!=typeof t&&t)return n(null,t);Ds.lstat(e,((e,r)=>{if(e)return n(null,"file");t=r&&r.isDirectory()?"dir":"file",n(null,t)}))},symlinkTypeSync:function(e,t){let n;if(t)return t;try{n=Ds.lstatSync(e)}catch(e){return"file"}return n&&n.isDirectory()?"dir":"file"}};const Es=yo.fromCallback,ms=p.default,hs=we,ys=Io.mkdirs,Cs=Io.mkdirsSync,Fs=ds.symlinkPaths,gs=ds.symlinkPathsSync,As=ps.symlinkType,vs=ps.symlinkTypeSync,Ss=fi.pathExists;var ws={createSymlink:Es((function(e,t,n,r){r="function"==typeof n?n:r,n="function"!=typeof n&&n,Ss(t,((u,o)=>u?r(u):o?r(null):void Fs(e,t,((u,o)=>{if(u)return r(u);e=o.toDst,As(o.toCwd,n,((n,u)=>{if(n)return r(n);const o=ms.dirname(t);Ss(o,((n,i)=>n?r(n):i?hs.symlink(e,t,u,r):void ys(o,(n=>{if(n)return r(n);hs.symlink(e,t,u,r)}))))}))}))))})),createSymlinkSync:function(e,t,n){if(hs.existsSync(t))return;const r=gs(e,t);e=r.toDst,n=vs(r.toCwd,n);const u=ms.dirname(t);return hs.existsSync(u)||Cs(u),hs.symlinkSync(e,t,n)}};var Os,bs={createFile:ns.createFile,createFileSync:ns.createFileSync,ensureFile:ns.createFile,ensureFileSync:ns.createFileSync,createLink:cs.createLink,createLinkSync:cs.createLinkSync,ensureLink:cs.createLink,ensureLinkSync:cs.createLinkSync,createSymlink:ws.createSymlink,createSymlinkSync:ws.createSymlinkSync,ensureSymlink:ws.createSymlink,ensureSymlinkSync:ws.createSymlinkSync};try{Os=we}catch(e){Os=D.default}function _s(e,t){var n,r="\n";return"object"==typeof t&&null!==t&&(t.spaces&&(n=t.spaces),t.EOL&&(r=t.EOL)),JSON.stringify(e,t?t.replacer:null,n).replace(/\n/g,r)+r}function Bs(e){return Buffer.isBuffer(e)&&(e=e.toString("utf8")),e=e.replace(/^\uFEFF/,"")}var Ps={readFile:function(e,t,n){null==n&&(n=t,t={}),"string"==typeof t&&(t={encoding:t});var r=(t=t||{}).fs||Os,u=!0;"throws"in t&&(u=t.throws),r.readFile(e,t,(function(r,o){if(r)return n(r);var i;o=Bs(o);try{i=JSON.parse(o,t?t.reviver:null)}catch(t){return u?(t.message=e+": "+t.message,n(t)):n(null,null)}n(null,i)}))},readFileSync:function(e,t){"string"==typeof(t=t||{})&&(t={encoding:t});var n=t.fs||Os,r=!0;"throws"in t&&(r=t.throws);try{var u=n.readFileSync(e,t);return u=Bs(u),JSON.parse(u,t.reviver)}catch(t){if(r)throw t.message=e+": "+t.message,t;return null}},writeFile:function(e,t,n,r){null==r&&(r=n,n={});var u=(n=n||{}).fs||Os,o="";try{o=_s(t,n)}catch(e){return void(r&&r(e,null))}u.writeFile(e,o,n,r)},writeFileSync:function(e,t,n){var r=(n=n||{}).fs||Os,u=_s(t,n);return r.writeFileSync(e,u,n)}},ks=Ps;const xs=yo.fromCallback,Ns=ks;var Is={readJson:xs(Ns.readFile),readJsonSync:Ns.readFileSync,writeJson:xs(Ns.writeFile),writeJsonSync:Ns.writeFileSync};const Ts=p.default,Rs=Io,Ms=fi.pathExists,Ls=Is;var js=function(e,t,n,r){"function"==typeof n&&(r=n,n={});const u=Ts.dirname(e);Ms(u,((o,i)=>o?r(o):i?Ls.writeJson(e,t,n,r):void Rs.mkdirs(u,(u=>{if(u)return r(u);Ls.writeJson(e,t,n,r)}))))};const $s=we,Hs=p.default,Js=Io,Gs=Is;var Vs=function(e,t,n){const r=Hs.dirname(e);$s.existsSync(r)||Js.mkdirsSync(r),Gs.writeJsonSync(e,t,n)};const Us=yo.fromCallback,Ws=Is;Ws.outputJson=Us(js),Ws.outputJsonSync=Vs,Ws.outputJSON=Ws.outputJson,Ws.outputJSONSync=Ws.outputJsonSync,Ws.writeJSON=Ws.writeJson,Ws.writeJSONSync=Ws.writeJsonSync,Ws.readJSON=Ws.readJson,Ws.readJSONSync=Ws.readJsonSync;var zs=Ws;const Ks=we,qs=p.default,Ys=ci.copySync,Xs=Ji.removeSync,Zs=Io.mkdirpSync,Qs=Zo;function ec(e,t,n){try{Ks.renameSync(e,t)}catch(r){if("EXDEV"!==r.code)throw r;return function(e,t,n){const r={overwrite:n,errorOnExist:!0};return Ys(e,t,r),Xs(e)}(e,t,n)}}var tc=function(e,t,n){const r=(n=n||{}).overwrite||n.clobber||!1,{srcStat:u}=Qs.checkPathsSync(e,t,"move");return Qs.checkParentPathsSync(e,u,t,"move"),Zs(qs.dirname(t)),function(e,t,n){if(n)return Xs(t),ec(e,t,n);if(Ks.existsSync(t))throw new Error("dest already exists.");return ec(e,t,n)}(e,t,r)},nc={moveSync:tc};const rc=we,uc=p.default,oc=bi.copy,ic=Ji.remove,sc=Io.mkdirp,cc=fi.pathExists,ac=Zo;function lc(e,t,n,r){rc.rename(e,t,(u=>u?"EXDEV"!==u.code?r(u):function(e,t,n,r){const u={overwrite:n,errorOnExist:!0};oc(e,t,u,(t=>t?r(t):ic(e,r)))}(e,t,n,r):r()))}var fc=function(e,t,n,r){"function"==typeof n&&(r=n,n={});const u=n.overwrite||n.clobber||!1;ac.checkPaths(e,t,"move",((n,o)=>{if(n)return r(n);const{srcStat:i}=o;ac.checkParentPaths(e,i,t,"move",(n=>{if(n)return r(n);sc(uc.dirname(t),(n=>n?r(n):function(e,t,n,r){if(n)return ic(t,(u=>u?r(u):lc(e,t,n,r)));cc(t,((u,o)=>u?r(u):o?r(new Error("dest already exists.")):lc(e,t,n,r)))}(e,t,u,r)))}))}))};var dc={move:(0,yo.fromCallback)(fc)};const Dc=yo.fromCallback,pc=we,Ec=p.default,mc=Io,hc=fi.pathExists;var yc={outputFile:Dc((function(e,t,n,r){"function"==typeof n&&(r=n,n="utf8");const u=Ec.dirname(e);hc(u,((o,i)=>o?r(o):i?pc.writeFile(e,t,n,r):void mc.mkdirs(u,(u=>{if(u)return r(u);pc.writeFile(e,t,n,r)}))))})),outputFileSync:function(e,...t){const n=Ec.dirname(e);if(pc.existsSync(n))return pc.writeFileSync(e,...t);mc.mkdirsSync(n),pc.writeFileSync(e,...t)}};!function(e){e.exports=Object.assign({},ho,ci,bi,Yi,bs,zs,Io,nc,dc,yc,fi,Ji);const t=D.default;Object.getOwnPropertyDescriptor(t,"promises")&&Object.defineProperty(e.exports,"promises",{get:()=>t.promises})}(mo);const Cc=Nr.exports("streamroller:fileNameFormatter"),Fc=p.default;const gc=Nr.exports("streamroller:fileNameParser"),Ac=nu.exports;const vc=Nr.exports("streamroller:moveAndMaybeCompressFile"),Sc=mo.exports,wc=v.default;var Oc=async(e,t,n)=>{if(n=function(e){const t={mode:parseInt("0600",8),compress:!1},n=Object.assign({},t,e);return vc(`_parseOption: moveAndMaybeCompressFile called with option=${JSON.stringify(n)}`),n}(n),e!==t){if(await Sc.pathExists(e))if(vc(`moveAndMaybeCompressFile: moving file from ${e} to ${t} ${n.compress?"with":"without"} compress`),n.compress)await new Promise(((r,u)=>{let o=!1;const i=Sc.createWriteStream(t,{mode:n.mode,flags:"wx"}).on("open",(()=>{o=!0;const t=Sc.createReadStream(e).on("open",(()=>{t.pipe(wc.createGzip()).pipe(i)})).on("error",(t=>{vc(`moveAndMaybeCompressFile: error reading ${e}`,t),i.destroy(t)}))})).on("finish",(()=>{vc(`moveAndMaybeCompressFile: finished compressing ${t}, deleting ${e}`),Sc.unlink(e).then(r).catch((t=>{vc(`moveAndMaybeCompressFile: error deleting ${e}, truncating instead`,t),Sc.truncate(e).then(r).catch((t=>{vc(`moveAndMaybeCompressFile: error truncating ${e}`,t),u(t)}))}))})).on("error",(e=>{o?(vc(`moveAndMaybeCompressFile: error writing ${t}, deleting`,e),Sc.unlink(t).then((()=>{u(e)})).catch((e=>{vc(`moveAndMaybeCompressFile: error deleting ${t}`,e),u(e)}))):(vc(`moveAndMaybeCompressFile: error creating ${t}`,e),u(e))}))})).catch((()=>{}));else{vc(`moveAndMaybeCompressFile: renaming ${e} to ${t}`);try{await Sc.move(e,t,{overwrite:!0})}catch(n){if(vc(`moveAndMaybeCompressFile: error renaming ${e} to ${t}`,n),"ENOENT"!==n.code){vc("moveAndMaybeCompressFile: trying copy+truncate instead");try{await Sc.copy(e,t,{overwrite:!0}),await Sc.truncate(e)}catch(e){vc("moveAndMaybeCompressFile: error copy+truncate",e)}}}}}else vc("moveAndMaybeCompressFile: source and target are the same, not doing anything")};const bc=Nr.exports("streamroller:RollingFileWriteStream"),_c=mo.exports,Bc=p.default,Pc=E.default,kc=()=>new Date,xc=nu.exports,{Writable:Nc}=C.default,Ic=({file:e,keepFileExt:t,needsIndex:n,alwaysIncludeDate:r,compress:u,fileNameSep:o})=>{let i=o||".";const s=Fc.join(e.dir,e.name),c=t=>t+e.ext,a=(e,t,r)=>!n&&r||!t?e:e+i+t,l=(e,t,n)=>(t>0||r)&&n?e+i+n:e,f=(e,t)=>t&&u?e+".gz":e,d=t?[l,a,c,f]:[c,l,a,f];return({date:e,index:t})=>(Cc(`_formatFileName: date=${e}, index=${t}`),d.reduce(((n,r)=>r(n,t,e)),s))},Tc=({file:e,keepFileExt:t,pattern:n,fileNameSep:r})=>{let u=r||".";const o="__NOT_MATCHING__";let i=[(e,t)=>e.endsWith(".gz")?(gc("it is gzipped"),t.isCompressed=!0,e.slice(0,-1*".gz".length)):e,t?t=>t.startsWith(e.name)&&t.endsWith(e.ext)?(gc("it starts and ends with the right things"),t.slice(e.name.length+1,-1*e.ext.length)):o:t=>t.startsWith(e.base)?(gc("it starts with the right things"),t.slice(e.base.length+1)):o,n?(e,t)=>{const r=e.split(u);let o=r[r.length-1];gc("items: ",r,", indexStr: ",o);let i=e;void 0!==o&&o.match(/^\d+$/)?(i=e.slice(0,-1*(o.length+1)),gc(`dateStr is ${i}`),n&&!i&&(i=o,o="0")):o="0";try{const r=Ac.parse(n,i,new Date(0,0));return Ac.asString(n,r)!==i?e:(t.index=parseInt(o,10),t.date=i,t.timestamp=r.getTime(),"")}catch(t){return gc(`Problem parsing ${i} as ${n}, error was: `,t),e}}:(e,t)=>e.match(/^\d+$/)?(gc("it has an index"),t.index=parseInt(e,10),""):e];return e=>{let t={filename:e,index:0,isCompressed:!1};return i.reduce(((e,n)=>n(e,t)),e)?null:t}},Rc=Oc;var Mc=class extends Nc{constructor(e,t){if(bc(`constructor: creating RollingFileWriteStream. path=${e}`),"string"!=typeof e||0===e.length)throw new Error(`Invalid filename: ${e}`);if(e.endsWith(Bc.sep))throw new Error(`Filename is a directory: ${e}`);0===e.indexOf(`~${Bc.sep}`)&&(e=e.replace("~",Pc.homedir())),super(t),this.options=this._parseOption(t),this.fileObject=Bc.parse(e),""===this.fileObject.dir&&(this.fileObject=Bc.parse(Bc.join(process.cwd(),e))),this.fileFormatter=Ic({file:this.fileObject,alwaysIncludeDate:this.options.alwaysIncludePattern,needsIndex:this.options.maxSize 0`)}else delete n.maxSize;if(n.numBackups||0===n.numBackups){if(n.numBackups<0)throw new Error(`options.numBackups (${n.numBackups}) should be >= 0`);if(n.numBackups>=Number.MAX_SAFE_INTEGER)throw new Error(`options.numBackups (${n.numBackups}) should be < Number.MAX_SAFE_INTEGER`);n.numToKeep=n.numBackups+1}else if(n.numToKeep<=0)throw new Error(`options.numToKeep (${n.numToKeep}) should be > 0`);return bc(`_parseOption: creating stream with option=${JSON.stringify(n)}`),n}_final(e){this.currentFileStream.end("",this.options.encoding,e)}_write(e,t,n){this._shouldRoll().then((()=>{bc(`_write: writing chunk. file=${this.currentFileStream.path} state=${JSON.stringify(this.state)} chunk=${e}`),this.currentFileStream.write(e,t,(t=>{this.state.currentSize+=e.length,n(t)}))}))}async _shouldRoll(){(this._dateChanged()||this._tooBig())&&(bc(`_shouldRoll: rolling because dateChanged? ${this._dateChanged()} or tooBig? ${this._tooBig()}`),await this._roll())}_dateChanged(){return this.state.currentDate&&this.state.currentDate!==xc(this.options.pattern,kc())}_tooBig(){return this.state.currentSize>=this.options.maxSize}_roll(){return bc("_roll: closing the current stream"),new Promise(((e,t)=>{this.currentFileStream.end("",this.options.encoding,(()=>{this._moveOldFiles().then(e).catch(t)}))}))}async _moveOldFiles(){const e=await this._getExistingFiles();for(let t=(this.state.currentDate?e.filter((e=>e.date===this.state.currentDate)):e).length;t>=0;t--){bc(`_moveOldFiles: i = ${t}`);const e=this.fileFormatter({date:this.state.currentDate,index:t}),n=this.fileFormatter({date:this.state.currentDate,index:t+1}),r={compress:this.options.compress&&0===t,mode:this.options.mode};await Rc(e,n,r)}this.state.currentSize=0,this.state.currentDate=this.state.currentDate?xc(this.options.pattern,kc()):null,bc(`_moveOldFiles: finished rolling files. state=${JSON.stringify(this.state)}`),this._renewWriteStream(),await new Promise(((e,t)=>{this.currentFileStream.write("","utf8",(()=>{this._clean().then(e).catch(t)}))}))}async _getExistingFiles(){const e=await _c.readdir(this.fileObject.dir).catch((()=>[]));bc(`_getExistingFiles: files=${e}`);const t=e.map((e=>this.fileNameParser(e))).filter((e=>e)),n=e=>(e.timestamp?e.timestamp:kc().getTime())-e.index;return t.sort(((e,t)=>n(e)-n(t))),t}_renewWriteStream(){const e=this.fileFormatter({date:this.state.currentDate,index:0}),t=e=>{try{return _c.mkdirSync(e,{recursive:!0})}catch(n){if("ENOENT"===n.code)return t(Bc.dirname(e)),t(e);if("EEXIST"!==n.code&&"EROFS"!==n.code)throw n;try{if(_c.statSync(e).isDirectory())return e;throw n}catch(e){throw n}}};t(this.fileObject.dir);const n={flags:this.options.flags,encoding:this.options.encoding,mode:this.options.mode};var r,u;_c.appendFileSync(e,"",(r={...n},u="flags",r["flag"]=r[u],delete r[u],r)),this.currentFileStream=_c.createWriteStream(e,n),this.currentFileStream.on("error",(e=>{this.emit("error",e)}))}async _clean(){const e=await this._getExistingFiles();if(bc(`_clean: numToKeep = ${this.options.numToKeep}, existingFiles = ${e.length}`),bc("_clean: existing files are: ",e),this._tooManyFiles(e.length)){const n=e.slice(0,e.length-this.options.numToKeep).map((e=>Bc.format({dir:this.fileObject.dir,base:e.filename})));await(t=n,bc(`deleteFiles: files to delete: ${t}`),Promise.all(t.map((e=>_c.unlink(e).catch((t=>{bc(`deleteFiles: error when unlinking ${e}, ignoring. Error was ${t}`)}))))))}var t}_tooManyFiles(e){return this.options.numToKeep>0&&e>this.options.numToKeep}};const Lc=Mc;var jc=class extends Lc{constructor(e,t,n,r){r||(r={}),t&&(r.maxSize=t),r.numBackups||0===r.numBackups||(n||0===n||(n=1),r.numBackups=n),super(e,r),this.backups=r.numBackups,this.size=this.options.maxSize}get theStream(){return this.currentFileStream}};const $c=Mc;var Hc={RollingFileWriteStream:Mc,RollingFileStream:jc,DateRollingFileStream:class extends $c{constructor(e,t,n){t&&"object"==typeof t&&(n=t,t=null),n||(n={}),t||(t="yyyy-MM-dd"),n.pattern=t,n.numBackups||0===n.numBackups?n.daysToKeep=n.numBackups:(n.daysToKeep||0===n.daysToKeep?process.emitWarning("options.daysToKeep is deprecated due to the confusion it causes when used together with file size rolling. Please use options.numBackups instead.","DeprecationWarning","streamroller-DEP0001"):n.daysToKeep=1,n.numBackups=n.daysToKeep),super(e,n),this.mode=this.options.mode}get theStream(){return this.currentFileStream}}};const Jc=Nr.exports("log4js:file"),Gc=p.default,Vc=Hc,Uc=E.default.EOL;let Wc=!1;const zc=new Set;function Kc(){zc.forEach((e=>{e.sighupHandler()}))}function qc(e,t,n,r){const u=new Vc.RollingFileStream(e,t,n,r);return u.on("error",(t=>{console.error("log4js.fileAppender - Writing to file %s, error happened ",e,t)})),u.on("drain",(()=>{process.emit("log4js:pause",!1)})),u}Eo.configure=function(e,t){let n=t.basicLayout;return e.layout&&(n=t.layout(e.layout.type,e.layout)),e.mode=e.mode||384,function(e,t,n,r,u,o){e=Gc.normalize(e),Jc("Creating file appender (",e,", ",n,", ",r=r||0===r?r:5,", ",u,", ",o,")");let i=qc(e,n,r,u);const s=function(e){if(i.writable){if(!0===u.removeColor){const t=/\x1b[[0-9;]*m/g;e.data=e.data.map((e=>"string"==typeof e?e.replace(t,""):e))}i.write(t(e,o)+Uc,"utf8")||process.emit("log4js:pause",!0)}};return s.reopen=function(){i.end((()=>{i=qc(e,n,r,u)}))},s.sighupHandler=function(){Jc("SIGHUP handler called."),s.reopen()},s.shutdown=function(e){zc.delete(s),0===zc.size&&Wc&&(process.removeListener("SIGHUP",Kc),Wc=!1),i.end("","utf-8",e)},zc.add(s),Wc||(process.on("SIGHUP",Kc),Wc=!0),s}(e.filename,n,e.maxLogSize,e.backups,e,e.timezoneOffset)};var Yc={};const Xc=Hc,Zc=E.default.EOL;function Qc(e,t,n,r,u){r.maxSize=r.maxLogSize;const o=function(e,t,n){const r=new Xc.DateRollingFileStream(e,t,n);return r.on("error",(t=>{console.error("log4js.dateFileAppender - Writing to file %s, error happened ",e,t)})),r.on("drain",(()=>{process.emit("log4js:pause",!1)})),r}(e,t,r),i=function(e){o.writable&&(o.write(n(e,u)+Zc,"utf8")||process.emit("log4js:pause",!0))};return i.shutdown=function(e){o.end("","utf-8",e)},i}Yc.configure=function(e,t){let n=t.basicLayout;return e.layout&&(n=t.layout(e.layout.type,e.layout)),e.alwaysIncludePattern||(e.alwaysIncludePattern=!1),e.mode=e.mode||384,Qc(e.filename,e.pattern,n,e,e.timezoneOffset)};var ea={};const ta=Nr.exports("log4js:fileSync"),na=p.default,ra=D.default,ua=E.default.EOL||"\n";function oa(e,t){if(ra.existsSync(e))return;const n=ra.openSync(e,t.flags,t.mode);ra.closeSync(n)}class ia{constructor(e,t,n,r){ta("In RollingFileStream"),function(){if(!e||!t||t<=0)throw new Error("You must specify a filename and file size")}(),this.filename=e,this.size=t,this.backups=n,this.options=r,this.currentSize=0,this.currentSize=function(e){let t=0;try{t=ra.statSync(e).size}catch(t){oa(e,r)}return t}(this.filename)}shouldRoll(){return ta("should roll with current size %d, and max size %d",this.currentSize,this.size),this.currentSize>=this.size}roll(e){const t=this,n=new RegExp(`^${na.basename(e)}`);function r(e){return n.test(e)}function u(t){return parseInt(t.substring(`${na.basename(e)}.`.length),10)||0}function o(e,t){return u(e)>u(t)?1:u(e) ${e}.${r+1}`),ra.renameSync(na.join(na.dirname(e),n),`${e}.${r+1}`)}}ta("Rolling, rolling, rolling"),ta("Renaming the old files"),ra.readdirSync(na.dirname(e)).filter(r).sort(o).reverse().forEach(i)}write(e,t){const n=this;ta("in write"),this.shouldRoll()&&(this.currentSize=0,this.roll(this.filename)),ta("writing the chunk to the file"),n.currentSize+=e.length,ra.appendFileSync(n.filename,e)}}ea.configure=function(e,t){let n=t.basicLayout;e.layout&&(n=t.layout(e.layout.type,e.layout));const r={flags:e.flags||"a",encoding:e.encoding||"utf8",mode:e.mode||384};return function(e,t,n,r,u,o){ta("fileSync appender created");const i=function(e,t,n){let r;var u;return t?r=new ia(e,t,n,o):(oa(u=e,o),r={write(e){ra.appendFileSync(u,e)}}),r}(e=na.normalize(e),n,r=r||0===r?r:5);return e=>{i.write(t(e,u)+ua)}}(e.filename,n,e.maxLogSize,e.backups,e.timezoneOffset,r)};var sa={};const ca=Nr.exports("log4js:tcp"),aa=S.default;sa.configure=function(e,t){ca(`configure with config = ${e}`);let n=function(e){return e.serialise()};return e.layout&&(n=t.layout(e.layout.type,e.layout)),function(e,t){let n=!1;const r=[];let u,o=3,i="__LOG4JS__";function s(e){ca("Writing log event to socket"),n=u.write(`${t(e)}${i}`,"utf8")}function c(){let e;for(ca("emptying buffer");e=r.shift();)s(e)}function a(e){n?s(e):(ca("buffering log event because it cannot write at the moment"),r.push(e))}return function t(){ca(`appender creating socket to ${e.host||"localhost"}:${e.port||5e3}`),i=`${e.endMsg||"__LOG4JS__"}`,u=aa.createConnection(e.port||5e3,e.host||"localhost"),u.on("connect",(()=>{ca("socket connected"),c(),n=!0})),u.on("drain",(()=>{ca("drain event received, emptying buffer"),n=!0,c()})),u.on("timeout",u.end.bind(u)),u.on("error",(e=>{ca("connection error",e),n=!1,c()})),u.on("close",t)}(),a.shutdown=function(e){ca("shutdown called"),r.length&&o?(ca("buffer has items, waiting 100ms to empty"),o-=1,setTimeout((()=>{a.shutdown(e)}),100)):(u.removeAllListeners("close"),u.end(e))},a}(e,n)};const la=p.default,fa=Nr.exports("log4js:appenders"),da=tu,Da=eo,pa=gu,Ea=hu,ma=to,ha=new Map;ha.set("console",oo),ha.set("stdout",so),ha.set("stderr",co),ha.set("logLevelFilter",ao),ha.set("categoryFilter",lo),ha.set("noLogFilter",Do),ha.set("file",Eo),ha.set("dateFile",Yc),ha.set("fileSync",ea),ha.set("tcp",sa);const ya=new Map,Ca=(e,t)=>{fa("Loading module from ",e);try{return require(e)}catch(n){return void da.throwExceptionIf(t,"MODULE_NOT_FOUND"!==n.code,`appender "${e}" could not be loaded (error was: ${n})`)}},Fa=new Set,ga=(e,t)=>{if(ya.has(e))return ya.get(e);if(!t.appenders[e])return!1;if(Fa.has(e))throw new Error(`Dependency loop detected for appender ${e}.`);Fa.add(e),fa(`Creating appender ${e}`);const n=Aa(e,t);return Fa.delete(e),ya.set(e,n),n},Aa=(e,t)=>{const n=t.appenders[e],r=n.type.configure?n.type:((e,t)=>ha.get(e)||Ca(`./${e}`,t)||Ca(e,t)||require.main&&Ca(la.join(la.dirname(require.main.filename),e),t)||Ca(la.join(process.cwd(),e),t))(n.type,t);return da.throwExceptionIf(t,da.not(r),`appender "${e}" is not valid (type "${n.type}" could not be found)`),r.appender&&fa(`DEPRECATION: Appender ${n.type} exports an appender function.`),r.shutdown&&fa(`DEPRECATION: Appender ${n.type} exports a shutdown function.`),fa(`${e}: clustering.isMaster ? ${Da.isMaster()}`),fa(`${e}: appenderModule is ${F.default.inspect(r)}`),Da.onlyOnMaster((()=>(fa(`calling appenderModule.configure for ${e} / ${n.type}`),r.configure(ma.modifyConfig(n),Ea,(e=>ga(e,t)),pa))),(()=>{}))},va=e=>{ya.clear(),Fa.clear();const t=[];Object.values(e.categories).forEach((e=>{t.push(...e.appenders)})),Object.keys(e.appenders).forEach((n=>{(t.includes(n)||"tcp-server"===e.appenders[n].type)&&ga(n,e)}))},Sa=()=>{va({appenders:{out:{type:"stdout"}},categories:{default:{appenders:["out"],level:"trace"}}})};Sa(),da.addListener((e=>{da.throwExceptionIf(e,da.not(da.anObject(e.appenders)),'must have a property "appenders" of type object.');const t=Object.keys(e.appenders);da.throwExceptionIf(e,da.not(t.length),"must define at least one appender."),t.forEach((t=>{da.throwExceptionIf(e,da.not(e.appenders[t].type),`appender "${t}" is not valid (must be an object with property "type")`)}))})),da.addListener(va),Au.exports=ya,Au.exports.init=Sa;var wa={exports:{}};!function(e){const t=Nr.exports("log4js:categories"),n=tu,r=gu,u=Au.exports,o=new Map;function i(e,t,n){if(!1===t.inherit)return;const r=n.lastIndexOf(".");if(r<0)return;const u=n.substring(0,r);let o=e.categories[u];o||(o={inherit:!0,appenders:[]}),i(e,o,u),!e.categories[u]&&o.appenders&&o.appenders.length&&o.level&&(e.categories[u]=o),t.appenders=t.appenders||[],t.level=t.level||o.level,o.appenders.forEach((e=>{t.appenders.includes(e)||t.appenders.push(e)})),t.parent=o}function s(e){if(!e.categories)return;Object.keys(e.categories).forEach((t=>{const n=e.categories[t];i(e,n,t)}))}n.addPreProcessingListener((e=>s(e))),n.addListener((e=>{n.throwExceptionIf(e,n.not(n.anObject(e.categories)),'must have a property "categories" of type object.');const t=Object.keys(e.categories);n.throwExceptionIf(e,n.not(t.length),"must define at least one category."),t.forEach((t=>{const o=e.categories[t];n.throwExceptionIf(e,[n.not(o.appenders),n.not(o.level)],`category "${t}" is not valid (must be an object with properties "appenders" and "level")`),n.throwExceptionIf(e,n.not(Array.isArray(o.appenders)),`category "${t}" is not valid (appenders must be an array of appender names)`),n.throwExceptionIf(e,n.not(o.appenders.length),`category "${t}" is not valid (appenders must contain at least one appender name)`),Object.prototype.hasOwnProperty.call(o,"enableCallStack")&&n.throwExceptionIf(e,"boolean"!=typeof o.enableCallStack,`category "${t}" is not valid (enableCallStack must be boolean type)`),o.appenders.forEach((r=>{n.throwExceptionIf(e,n.not(u.get(r)),`category "${t}" is not valid (appender "${r}" is not defined)`)})),n.throwExceptionIf(e,n.not(r.getLevel(o.level)),`category "${t}" is not valid (level "${o.level}" not recognised; valid levels are ${r.levels.join(", ")})`)})),n.throwExceptionIf(e,n.not(e.categories.default),'must define a "default" category.')}));const c=e=>{o.clear();Object.keys(e.categories).forEach((n=>{const i=e.categories[n],s=[];i.appenders.forEach((e=>{s.push(u.get(e)),t(`Creating category ${n}`),o.set(n,{appenders:s,level:r.getLevel(i.level),enableCallStack:i.enableCallStack||!1})}))}))},a=()=>{c({categories:{default:{appenders:["out"],level:"OFF"}}})};a(),n.addListener(c);const l=e=>(t(`configForCategory: searching for config for ${e}`),o.has(e)?(t(`configForCategory: ${e} exists in config, returning it`),o.get(e)):e.indexOf(".")>0?(t(`configForCategory: ${e} has hierarchy, searching for parents`),l(e.substring(0,e.lastIndexOf(".")))):(t("configForCategory: returning config for default category"),l("default")));e.exports=o,e.exports=Object.assign(e.exports,{appendersForCategory:e=>l(e).appenders,getLevelForCategory:e=>l(e).level,setLevelForCategory:(e,n)=>{let r=o.get(e);if(t(`setLevelForCategory: found ${r} for ${e}`),!r){const n=l(e);t(`setLevelForCategory: no config found for category, found ${n} for parents of ${e}`),r={appenders:n.appenders}}r.level=n,o.set(e,r)},getEnableCallStackForCategory:e=>!0===l(e).enableCallStack,setEnableCallStackForCategory:(e,t)=>{l(e).enableCallStack=t},init:a})}(wa);const Oa=Nr.exports("log4js:logger"),ba=Hu,_a=gu,Ba=eo,Pa=wa.exports,ka=tu,xa=/at (?:(.+)\s+\()?(?:(.+?):(\d+)(?::(\d+))?|([^)]+))\)?/;function Na(e,t=4){const n=e.stack.split("\n").slice(t),r=xa.exec(n[0]);return r&&6===r.length?{functionName:r[1],fileName:r[2],lineNumber:parseInt(r[3],10),columnNumber:parseInt(r[4],10),callStack:n.join("\n")}:null}class Ia{constructor(e){if(!e)throw new Error("No category provided.");this.category=e,this.context={},this.parseCallStack=Na,Oa(`Logger created (${this.category}, ${this.level})`)}get level(){return _a.getLevel(Pa.getLevelForCategory(this.category),_a.TRACE)}set level(e){Pa.setLevelForCategory(this.category,_a.getLevel(e,this.level))}get useCallStack(){return Pa.getEnableCallStackForCategory(this.category)}set useCallStack(e){Pa.setEnableCallStackForCategory(this.category,!0===e)}log(e,...t){let n=_a.getLevel(e);n||(this._log(_a.WARN,"log4js:logger.log: invalid value for log-level as first parameter given: ",e),n=_a.INFO),this.isLevelEnabled(n)&&this._log(n,t)}isLevelEnabled(e){return this.level.isLessThanOrEqualTo(e)}_log(e,t){Oa(`sending log data (${e}) to appenders`);const n=new ba(this.category,e,t,this.context,this.useCallStack&&this.parseCallStack(new Error));Ba.send(n)}addContext(e,t){this.context[e]=t}removeContext(e){delete this.context[e]}clearContext(){this.context={}}setParseCallStackFunction(e){this.parseCallStack=e}}function Ta(e){const t=_a.getLevel(e),n=t.toString().toLowerCase().replace(/_([a-z])/g,(e=>e[1].toUpperCase())),r=n[0].toUpperCase()+n.slice(1);Ia.prototype[`is${r}Enabled`]=function(){return this.isLevelEnabled(t)},Ia.prototype[n]=function(...e){this.log(t,...e)}}_a.levels.forEach(Ta),ka.addListener((()=>{_a.levels.forEach(Ta)}));var Ra=Ia;const Ma=gu;function La(e){return e.originalUrl||e.url}function ja(e,t){for(let n=0;ne.source?e.source:e));t=new RegExp(n.join("|"))}return t}(t.nolog);return(e,i,s)=>{if(e._logging)return s();if(o&&o.test(e.originalUrl))return s();if(n.isLevelEnabled(r)||"auto"===t.level){const o=new Date,{writeHead:s}=i;e._logging=!0,i.writeHead=(e,t)=>{i.writeHead=s,i.writeHead(e,t),i.__statusCode=e,i.__headers=t||{}},i.on("finish",(()=>{i.responseTime=new Date-o,i.statusCode&&"auto"===t.level&&(r=Ma.INFO,i.statusCode>=300&&(r=Ma.WARN),i.statusCode>=400&&(r=Ma.ERROR)),r=function(e,t,n){let r=t;if(n){const t=n.find((t=>{let n=!1;return n=t.from&&t.to?e>=t.from&&e<=t.to:-1!==t.codes.indexOf(e),n}));t&&(r=Ma.getLevel(t.level,r))}return r}(i.statusCode,r,t.statusRules);const s=function(e,t,n){const r=[];return r.push({token:":url",replacement:La(e)}),r.push({token:":protocol",replacement:e.protocol}),r.push({token:":hostname",replacement:e.hostname}),r.push({token:":method",replacement:e.method}),r.push({token:":status",replacement:t.__statusCode||t.statusCode}),r.push({token:":response-time",replacement:t.responseTime}),r.push({token:":date",replacement:(new Date).toUTCString()}),r.push({token:":referrer",replacement:e.headers.referer||e.headers.referrer||""}),r.push({token:":http-version",replacement:`${e.httpVersionMajor}.${e.httpVersionMinor}`}),r.push({token:":remote-addr",replacement:e.headers["x-forwarded-for"]||e.ip||e._remoteAddress||e.socket&&(e.socket.remoteAddress||e.socket.socket&&e.socket.socket.remoteAddress)}),r.push({token:":user-agent",replacement:e.headers["user-agent"]}),r.push({token:":content-length",replacement:t.getHeader("content-length")||t.__headers&&t.__headers["Content-Length"]||"-"}),r.push({token:/:req\[([^\]]+)]/g,replacement:(t,n)=>e.headers[n.toLowerCase()]}),r.push({token:/:res\[([^\]]+)]/g,replacement:(e,n)=>t.getHeader(n.toLowerCase())||t.__headers&&t.__headers[n]}),(e=>{const t=e.concat();for(let e=0;eja(e,s)));t&&n.log(r,t)}else n.log(r,ja(u,s));t.context&&n.removeContext("res")}))}return s()}},nl=Va;let rl=!1;function ul(e){if(!rl)return;Ua("Received log event ",e);Za.appendersForCategory(e.categoryName).forEach((t=>{t(e)}))}function ol(e){rl&&il();let t=e;return"string"==typeof t&&(t=function(e){Ua(`Loading configuration from ${e}`);try{return JSON.parse(Wa.readFileSync(e,"utf8"))}catch(t){throw new Error(`Problem reading config from file "${e}". Error was ${t.message}`,t)}}(e)),Ua(`Configuration is ${t}`),Ka.configure(za(t)),el.onMessage(ul),rl=!0,sl}function il(e){Ua("Shutdown called. Disabling all log writing."),rl=!1;const t=Array.from(Xa.values());Xa.init(),Za.init();const n=t.reduceRight(((e,t)=>t.shutdown?e+1:e),0);if(0===n)return Ua("No appenders with shutdown functions found."),void 0!==e&&e();let r,u=0;function o(t){r=r||t,u+=1,Ua(`Appender shutdowns complete: ${u} / ${n}`),u>=n&&(Ua("All shutdown functions completed."),e&&e(r))}return Ua(`Found ${n} appenders with shutdown functions.`),t.filter((e=>e.shutdown)).forEach((e=>e.shutdown(o))),null}const sl={getLogger:function(e){return rl||ol(process.env.LOG4JS_CONFIG||{appenders:{out:{type:"stdout"}},categories:{default:{appenders:["out"],level:"OFF"}}}),new Qa(e||"default")},configure:ol,shutdown:il,connectLogger:tl,levels:Ya,addLayout:qa.addLayout,recording:function(){return nl}};var cl=sl,al={};Object.defineProperty(al,"__esModule",{value:!0}),al.levelMap=al.getLevel=al.setCategoriesLevel=al.getConfiguration=al.setConfiguration=void 0;const ll=cl;let fl={appenders:{debug:{type:"stdout",layout:{type:"pattern",pattern:"[%d] > hvigor %p %c %[%m%]"}},info:{type:"stdout",layout:{type:"pattern",pattern:"[%d] > hvigor %[%m%]"}},"no-pattern-info":{type:"stdout",layout:{type:"pattern",pattern:"%m"}},wrong:{type:"stderr",layout:{type:"pattern",pattern:"[%d] > hvigor %[%p: %m%]"}},"just-debug":{type:"logLevelFilter",appender:"debug",level:"debug",maxLevel:"debug"},"just-info":{type:"logLevelFilter",appender:"info",level:"info",maxLevel:"info"},"just-wrong":{type:"logLevelFilter",appender:"wrong",level:"warn",maxLevel:"error"}},categories:{default:{appenders:["just-debug","just-info","just-wrong"],level:"debug"},"no-pattern-info":{appenders:["no-pattern-info"],level:"info"}}};al.setConfiguration=e=>{fl=e};al.getConfiguration=()=>fl;let dl=ll.levels.DEBUG;al.setCategoriesLevel=(e,t)=>{dl=e;const n=fl.categories;for(const r in n)(null==t?void 0:t.includes(r))||Object.prototype.hasOwnProperty.call(n,r)&&(n[r].level=e.levelStr)};al.getLevel=()=>dl,al.levelMap=new Map([["ALL",ll.levels.ALL],["MARK",ll.levels.MARK],["TRACE",ll.levels.TRACE],["DEBUG",ll.levels.DEBUG],["INFO",ll.levels.INFO],["WARN",ll.levels.WARN],["ERROR",ll.levels.ERROR],["FATAL",ll.levels.FATAL],["OFF",ll.levels.OFF]]);var Dl=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),pl=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),El=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&Dl(t,e,n);return pl(t,e),t};Object.defineProperty(xr,"__esModule",{value:!0}),xr.evaluateLogLevel=xr.HvigorLogger=void 0;const ml=El(cl),hl=cl,yl=El(F.default),Cl=al;class Fl{constructor(e){ml.configure((0,Cl.getConfiguration)()),this._logger=ml.getLogger(e),this._logger.level=(0,Cl.getLevel)()}static getLogger(e){return new Fl(e)}log(e,...t){this._logger.log(e,...t)}debug(e,...t){this._logger.debug(e,...t)}info(e,...t){this._logger.info(e,...t)}warn(e,...t){void 0!==e&&""!==e&&this._logger.warn(e,...t)}error(e,...t){this._logger.error(e,...t)}_printTaskExecuteInfo(e,t){this.info(`Finished :${e}... after ${t}`)}_printFailedTaskInfo(e){this.error(`Failed :${e}... `)}_printDisabledTaskInfo(e){this.info(`Disabled :${e}... `)}_printUpToDateTaskInfo(e){this.info(`UP-TO-DATE :${e}... `)}errorMessageExit(e,...t){throw new Error(yl.format(e,...t))}errorExit(e,t,...n){t&&this._logger.error(t,n),this._logger.error(e.stack)}setLevel(e,t){(0,Cl.setCategoriesLevel)(e,t),ml.shutdown(),ml.configure((0,Cl.getConfiguration)())}getLevel(){return this._logger.level}configure(e){const t=(0,Cl.getConfiguration)(),n={appenders:{...t.appenders,...e.appenders},categories:{...t.categories,...e.categories}};(0,Cl.setConfiguration)(n),ml.shutdown(),ml.configure(n)}}xr.HvigorLogger=Fl,xr.evaluateLogLevel=function(e,t){t.debug?e.setLevel(hl.levels.DEBUG):t.warn?e.setLevel(hl.levels.WARN):t.error?e.setLevel(hl.levels.ERROR):e.setLevel(hl.levels.INFO)};var gl=w&&w.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(X,"__esModule",{value:!0}),X.parseJsonText=X.parseJsonFile=void 0;const Al=Z,vl=gl(kr),Sl=gl(p.default),wl=gl(E.default),Ol=xr.HvigorLogger.getLogger("parse-json-util");var bl;!function(e){e[e.Char=0]="Char",e[e.EOF=1]="EOF",e[e.Identifier=2]="Identifier"}(bl||(bl={}));let _l,Bl,Pl,kl,xl,Nl,Il="start",Tl=[],Rl=0,Ml=1,Ll=0,jl=!1,$l="default",Hl="'",Jl=1;function Gl(e,t=!1){Bl=String(e),Il="start",Tl=[],Rl=0,Ml=1,Ll=0,kl=void 0,jl=t;do{_l=Vl(),Xl[Il]()}while("eof"!==_l.type);return kl}function Vl(){for($l="default",xl="",Hl="'",Jl=1;;){Nl=Ul();const e=zl[$l]();if(e)return e}}function Ul(){if(Bl[Rl])return String.fromCodePoint(Bl.codePointAt(Rl))}function Wl(){const e=Ul();return"\n"===e?(Ml++,Ll=0):e?Ll+=e.length:Ll++,e&&(Rl+=e.length),e}X.parseJsonFile=function(e,t=!1,n="utf-8"){const r=vl.default.readFileSync(Sl.default.resolve(e),{encoding:n});try{return Gl(r,t)}catch(t){if(t instanceof SyntaxError){const n=t.message.split("at");2===n.length&&Ol.errorMessageExit(`${n[0].trim()}${wl.default.EOL}\t at ${e}:${n[1].trim()}`)}Ol.errorMessageExit(`${e} is not in valid JSON/JSON5 format.`)}},X.parseJsonText=Gl;const zl={default(){switch(Nl){case"/":return Wl(),void($l="comment");case void 0:return Wl(),Kl("eof")}if(!Al.JudgeUtil.isIgnoreChar(Nl)&&!Al.JudgeUtil.isSpaceSeparator(Nl))return zl[Il]();Wl()},start(){$l="value"},beforePropertyName(){switch(Nl){case"$":case"_":return xl=Wl(),void($l="identifierName");case"\\":return Wl(),void($l="identifierNameStartEscape");case"}":return Kl("punctuator",Wl());case'"':case"'":return Hl=Nl,Wl(),void($l="string")}if(Al.JudgeUtil.isIdStartChar(Nl))return xl+=Wl(),void($l="identifierName");throw tf(bl.Char,Wl())},afterPropertyName(){if(":"===Nl)return Kl("punctuator",Wl());throw tf(bl.Char,Wl())},beforePropertyValue(){$l="value"},afterPropertyValue(){switch(Nl){case",":case"}":return Kl("punctuator",Wl())}throw tf(bl.Char,Wl())},beforeArrayValue(){if("]"===Nl)return Kl("punctuator",Wl());$l="value"},afterArrayValue(){switch(Nl){case",":case"]":return Kl("punctuator",Wl())}throw tf(bl.Char,Wl())},end(){throw tf(bl.Char,Wl())},comment(){switch(Nl){case"*":return Wl(),void($l="multiLineComment");case"/":return Wl(),void($l="singleLineComment")}throw tf(bl.Char,Wl())},multiLineComment(){switch(Nl){case"*":return Wl(),void($l="multiLineCommentAsterisk");case void 0:throw tf(bl.Char,Wl())}Wl()},multiLineCommentAsterisk(){switch(Nl){case"*":return void Wl();case"/":return Wl(),void($l="default");case void 0:throw tf(bl.Char,Wl())}Wl(),$l="multiLineComment"},singleLineComment(){switch(Nl){case"\n":case"\r":case"\u2028":case"\u2029":return Wl(),void($l="default");case void 0:return Wl(),Kl("eof")}Wl()},value(){switch(Nl){case"{":case"[":return Kl("punctuator",Wl());case"n":return Wl(),ql("ull"),Kl("null",null);case"t":return Wl(),ql("rue"),Kl("boolean",!0);case"f":return Wl(),ql("alse"),Kl("boolean",!1);case"-":case"+":return"-"===Wl()&&(Jl=-1),void($l="numerical");case".":case"0":case"I":case"N":return void($l="numerical");case'"':case"'":return Hl=Nl,Wl(),xl="",void($l="string")}if(void 0===Nl||!Al.JudgeUtil.isDigitWithoutZero(Nl))throw tf(bl.Char,Wl());$l="numerical"},numerical(){switch(Nl){case".":return xl=Wl(),void($l="decimalPointLeading");case"0":return xl=Wl(),void($l="zero");case"I":return Wl(),ql("nfinity"),Kl("numeric",Jl*(1/0));case"N":return Wl(),ql("aN"),Kl("numeric",NaN)}if(void 0!==Nl&&Al.JudgeUtil.isDigitWithoutZero(Nl))return xl=Wl(),void($l="decimalInteger");throw tf(bl.Char,Wl())},zero(){switch(Nl){case".":case"e":case"E":return void($l="decimal");case"x":case"X":return xl+=Wl(),void($l="hexadecimal")}return Kl("numeric",0)},decimalInteger(){switch(Nl){case".":case"e":case"E":return void($l="decimal")}if(!Al.JudgeUtil.isDigit(Nl))return Kl("numeric",Jl*Number(xl));xl+=Wl()},decimal(){switch(Nl){case".":xl+=Wl(),$l="decimalFraction";break;case"e":case"E":xl+=Wl(),$l="decimalExponent"}},decimalPointLeading(){if(Al.JudgeUtil.isDigit(Nl))return xl+=Wl(),void($l="decimalFraction");throw tf(bl.Char,Wl())},decimalFraction(){switch(Nl){case"e":case"E":return xl+=Wl(),void($l="decimalExponent")}if(!Al.JudgeUtil.isDigit(Nl))return Kl("numeric",Jl*Number(xl));xl+=Wl()},decimalExponent(){switch(Nl){case"+":case"-":return xl+=Wl(),void($l="decimalExponentSign")}if(Al.JudgeUtil.isDigit(Nl))return xl+=Wl(),void($l="decimalExponentInteger");throw tf(bl.Char,Wl())},decimalExponentSign(){if(Al.JudgeUtil.isDigit(Nl))return xl+=Wl(),void($l="decimalExponentInteger");throw tf(bl.Char,Wl())},decimalExponentInteger(){if(!Al.JudgeUtil.isDigit(Nl))return Kl("numeric",Jl*Number(xl));xl+=Wl()},hexadecimal(){if(Al.JudgeUtil.isHexDigit(Nl))return xl+=Wl(),void($l="hexadecimalInteger");throw tf(bl.Char,Wl())},hexadecimalInteger(){if(!Al.JudgeUtil.isHexDigit(Nl))return Kl("numeric",Jl*Number(xl));xl+=Wl()},identifierNameStartEscape(){if("u"!==Nl)throw tf(bl.Char,Wl());Wl();const e=Yl();switch(e){case"$":case"_":break;default:if(!Al.JudgeUtil.isIdStartChar(e))throw tf(bl.Identifier)}xl+=e,$l="identifierName"},identifierName(){switch(Nl){case"$":case"_":case"‌":case"‍":return void(xl+=Wl());case"\\":return Wl(),void($l="identifierNameEscape")}if(!Al.JudgeUtil.isIdContinueChar(Nl))return Kl("identifier",xl);xl+=Wl()},identifierNameEscape(){if("u"!==Nl)throw tf(bl.Char,Wl());Wl();const e=Yl();switch(e){case"$":case"_":case"‌":case"‍":break;default:if(!Al.JudgeUtil.isIdContinueChar(e))throw tf(bl.Identifier)}xl+=e,$l="identifierName"},string(){switch(Nl){case"\\":return Wl(),void(xl+=function(){const e=Ul(),t=function(){switch(Ul()){case"b":return Wl(),"\b";case"f":return Wl(),"\f";case"n":return Wl(),"\n";case"r":return Wl(),"\r";case"t":return Wl(),"\t";case"v":return Wl(),"\v"}return}();if(t)return t;switch(e){case"0":if(Wl(),Al.JudgeUtil.isDigit(Ul()))throw tf(bl.Char,Wl());return"\0";case"x":return Wl(),function(){let e="",t=Ul();if(!Al.JudgeUtil.isHexDigit(t))throw tf(bl.Char,Wl());if(e+=Wl(),t=Ul(),!Al.JudgeUtil.isHexDigit(t))throw tf(bl.Char,Wl());return e+=Wl(),String.fromCodePoint(parseInt(e,16))}();case"u":return Wl(),Yl();case"\n":case"\u2028":case"\u2029":return Wl(),"";case"\r":return Wl(),"\n"===Ul()&&Wl(),""}if(void 0===e||Al.JudgeUtil.isDigitWithoutZero(e))throw tf(bl.Char,Wl());return Wl()}());case'"':case"'":if(Nl===Hl){const e=Kl("string",xl);return Wl(),e}return void(xl+=Wl());case"\n":case"\r":case void 0:throw tf(bl.Char,Wl());case"\u2028":case"\u2029":!function(e){Ol.warn(`JSON5: '${ef(e)}' in strings is not valid ECMAScript; consider escaping.`)}(Nl)}xl+=Wl()}};function Kl(e,t){return{type:e,value:t,line:Ml,column:Ll}}function ql(e){for(const t of e){if(Ul()!==t)throw tf(bl.Char,Wl());Wl()}}function Yl(){let e="",t=4;for(;t-- >0;){const t=Ul();if(!Al.JudgeUtil.isHexDigit(t))throw tf(bl.Char,Wl());e+=Wl()}return String.fromCodePoint(parseInt(e,16))}const Xl={start(){if("eof"===_l.type)throw tf(bl.EOF);Zl()},beforePropertyName(){switch(_l.type){case"identifier":case"string":return Pl=_l.value,void(Il="afterPropertyName");case"punctuator":return void Ql();case"eof":throw tf(bl.EOF)}},afterPropertyName(){if("eof"===_l.type)throw tf(bl.EOF);Il="beforePropertyValue"},beforePropertyValue(){if("eof"===_l.type)throw tf(bl.EOF);Zl()},afterPropertyValue(){if("eof"===_l.type)throw tf(bl.EOF);switch(_l.value){case",":return void(Il="beforePropertyName");case"}":Ql()}},beforeArrayValue(){if("eof"===_l.type)throw tf(bl.EOF);"punctuator"!==_l.type||"]"!==_l.value?Zl():Ql()},afterArrayValue(){if("eof"===_l.type)throw tf(bl.EOF);switch(_l.value){case",":return void(Il="beforeArrayValue");case"]":Ql()}},end(){}};function Zl(){const e=function(){let e;switch(_l.type){case"punctuator":switch(_l.value){case"{":e={};break;case"[":e=[]}break;case"null":case"boolean":case"numeric":case"string":e=_l.value}return e}();if(jl&&"object"==typeof e&&(e._line=Ml,e._column=Ll),void 0===kl)kl=e;else{const t=Tl[Tl.length-1];Array.isArray(t)?jl&&"object"!=typeof e?t.push({value:e,_line:Ml,_column:Ll}):t.push(e):t[Pl]=jl&&"object"!=typeof e?{value:e,_line:Ml,_column:Ll}:e}!function(e){if(e&&"object"==typeof e)Tl.push(e),Il=Array.isArray(e)?"beforeArrayValue":"beforePropertyName";else{const e=Tl[Tl.length-1];Il=e?Array.isArray(e)?"afterArrayValue":"afterPropertyValue":"end"}}(e)}function Ql(){Tl.pop();const e=Tl[Tl.length-1];Il=e?Array.isArray(e)?"afterArrayValue":"afterPropertyValue":"end"}function ef(e){const t={"'":"\\'",'"':'\\"',"\\":"\\\\","\b":"\\b","\f":"\\f","\n":"\\n","\r":"\\r","\t":"\\t","\v":"\\v","\0":"\\0","\u2028":"\\u2028","\u2029":"\\u2029"};if(t[e])return t[e];if(e<" "){const t=e.charCodeAt(0).toString(16);return`\\x${`00${t}`.substring(t.length)}`}return e}function tf(e,t){let n="";switch(e){case bl.Char:n=void 0===t?`JSON5: invalid end of input at ${Ml}:${Ll}`:`JSON5: invalid character '${ef(t)}' at ${Ml}:${Ll}`;break;case bl.EOF:n=`JSON5: invalid end of input at ${Ml}:${Ll}`;break;case bl.Identifier:Ll-=5,n=`JSON5: invalid identifier character at ${Ml}:${Ll}`}const r=new nf(n);return r.lineNumber=Ml,r.columnNumber=Ll,r}class nf extends SyntaxError{}var rf=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),uf=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),of=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&rf(t,e,n);return uf(t,e),t};Object.defineProperty(Y,"__esModule",{value:!0});var sf=Y.cleanWorkSpace=Ff=Y.executeInstallHvigor=yf=Y.isHvigorInstalled=mf=Y.isAllDependenciesInstalled=void 0;const cf=of(D.default),af=of(p.default),lf=b,ff=j,df=$,Df=X;let pf,Ef;var mf=Y.isAllDependenciesInstalled=function(){function e(e){const t=null==e?void 0:e.dependencies;return void 0===t?0:Object.getOwnPropertyNames(t).length}if(pf=gf(),Ef=Af(),e(pf)+1!==e(Ef))return!1;for(const e in null==pf?void 0:pf.dependencies)if(!(0,ff.hasNpmPackInPaths)(e,[lf.HVIGOR_PROJECT_DEPENDENCIES_HOME])||!hf(e,pf,Ef))return!1;return!0};function hf(e,t,n){return void 0!==n.dependencies&&(0,ff.offlinePluginConversion)(lf.HVIGOR_PROJECT_ROOT_DIR,t.dependencies[e])===n.dependencies[e]}var yf=Y.isHvigorInstalled=function(){return pf=gf(),Ef=Af(),(0,ff.hasNpmPackInPaths)(lf.HVIGOR_ENGINE_PACKAGE_NAME,[lf.HVIGOR_PROJECT_DEPENDENCIES_HOME])&&(0,ff.offlinePluginConversion)(lf.HVIGOR_PROJECT_ROOT_DIR,pf.hvigorVersion)===Ef.dependencies[lf.HVIGOR_ENGINE_PACKAGE_NAME]};const Cf={cwd:lf.HVIGOR_PROJECT_DEPENDENCIES_HOME,stdio:["inherit","inherit","inherit"]};var Ff=Y.executeInstallHvigor=function(){(0,df.logInfoPrintConsole)("Hvigor installing...");const e={dependencies:{}};e.dependencies[lf.HVIGOR_ENGINE_PACKAGE_NAME]=(0,ff.offlinePluginConversion)(lf.HVIGOR_PROJECT_ROOT_DIR,pf.hvigorVersion);try{cf.mkdirSync(lf.HVIGOR_PROJECT_DEPENDENCIES_HOME,{recursive:!0});const t=af.resolve(lf.HVIGOR_PROJECT_DEPENDENCIES_HOME,lf.DEFAULT_PACKAGE_JSON);cf.writeFileSync(t,JSON.stringify(e))}catch(e){(0,df.logErrorAndExit)(e)}!function(){const e=["config","set","store-dir",lf.HVIGOR_PNPM_STORE_PATH];(0,ff.executeCommand)(lf.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH,e,Cf)}(),(0,ff.executeCommand)(lf.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH,["install"],Cf)};function gf(){const e=af.resolve(lf.HVIGOR_PROJECT_WRAPPER_HOME,lf.DEFAULT_HVIGOR_CONFIG_JSON_FILE_NAME);return cf.existsSync(e)||(0,df.logErrorAndExit)(`Error: Hvigor config file ${e} does not exist.`),(0,Df.parseJsonFile)(e)}function Af(){return cf.existsSync(lf.HVIGOR_PROJECT_DEPENDENCY_PACKAGE_JSON_PATH)?(0,Df.parseJsonFile)(lf.HVIGOR_PROJECT_DEPENDENCY_PACKAGE_JSON_PATH):{dependencies:{}}}sf=Y.cleanWorkSpace=function(){if((0,df.logInfoPrintConsole)("Hvigor cleaning..."),!cf.existsSync(lf.HVIGOR_PROJECT_DEPENDENCIES_HOME))return;const e=cf.readdirSync(lf.HVIGOR_PROJECT_DEPENDENCIES_HOME);if(e&&0!==e.length){cf.existsSync(lf.HVIGOR_BOOT_JS_FILE_PATH)&&(0,ff.executeCommand)(process.argv[0],[lf.HVIGOR_BOOT_JS_FILE_PATH,"--stop-daemon"],{});try{e.forEach((e=>{cf.rmSync(af.resolve(lf.HVIGOR_PROJECT_DEPENDENCIES_HOME,e),{recursive:!0})}))}catch(e){(0,df.logErrorAndExit)(`The hvigor build tool cannot be installed. Please manually clear the workspace directory and synchronize the project again.\n\n Workspace Path: ${lf.HVIGOR_PROJECT_DEPENDENCIES_HOME}.`)}}};var vf={},Sf=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),wf=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),Of=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&Sf(t,e,n);return wf(t,e),t};Object.defineProperty(vf,"__esModule",{value:!0});var bf=vf.executeBuild=void 0;const _f=b,Bf=Of(D.default),Pf=Of(p.default),kf=$;bf=vf.executeBuild=function(){const e=Pf.resolve(_f.HVIGOR_PROJECT_DEPENDENCIES_HOME,"node_modules","@ohos","hvigor","bin","hvigor.js");try{const t=Bf.realpathSync(e);require(t)}catch(t){(0,kf.logErrorAndExit)(`Error: ENOENT: no such file ${e},delete ${_f.HVIGOR_PROJECT_DEPENDENCIES_HOME} and retry.`)}},function(){if(O.checkNpmConifg(),O.environmentHandler(),O.isPnpmAvailable()||O.executeInstallPnpm(),yf()&&mf())bf();else{sf();try{Ff()}catch(e){return void sf()}bf()}}(); \ No newline at end of file +"use strict";var u=require("path"),D=require("os"),e=require("fs"),t=require("crypto"),r=require("child_process"),n="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{},i={},C={},F=n&&n.__importDefault||function(u){return u&&u.__esModule?u:{default:u}};Object.defineProperty(C,"__esModule",{value:!0}),C.maxPathLength=C.isMac=C.isLinux=C.isWindows=void 0;const E=F(D),A="Windows_NT",o="Darwin";function a(){return E.default.type()===A}function c(){return E.default.type()===o}C.isWindows=a,C.isLinux=function(){return"Linux"===E.default.type()},C.isMac=c,C.maxPathLength=function(){return c()?1016:a()?259:4095},function(e){var t=n&&n.__createBinding||(Object.create?function(u,D,e,t){void 0===t&&(t=e);var r=Object.getOwnPropertyDescriptor(D,e);r&&!("get"in r?!D.__esModule:r.writable||r.configurable)||(r={enumerable:!0,get:function(){return D[e]}}),Object.defineProperty(u,t,r)}:function(u,D,e,t){void 0===t&&(t=e),u[t]=D[e]}),r=n&&n.__setModuleDefault||(Object.create?function(u,D){Object.defineProperty(u,"default",{enumerable:!0,value:D})}:function(u,D){u.default=D}),i=n&&n.__importStar||function(u){if(u&&u.__esModule)return u;var D={};if(null!=u)for(var e in u)"default"!==e&&Object.prototype.hasOwnProperty.call(u,e)&&t(D,u,e);return r(D,u),D};Object.defineProperty(e,"__esModule",{value:!0}),e.WORK_SPACE=e.HVIGOR_PROJECT_WRAPPER_HOME=e.HVIGOR_PROJECT_ROOT_DIR=e.HVIGOR_PROJECT_CACHES_HOME=e.HVIGOR_PNPM_STORE_PATH=e.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH=e.PROJECT_CACHES=e.HVIGOR_WRAPPER_TOOLS_HOME=e.HVIGOR_USER_HOME=e.DEFAULT_PACKAGE_JSON=e.DEFAULT_HVIGOR_CONFIG_JSON_FILE_NAME=e.PNPM=e.HVIGOR=e.NPM_TOOL=e.PNPM_TOOL=e.HVIGOR_ENGINE_PACKAGE_NAME=void 0;const F=i(D),E=i(u),A=C;e.HVIGOR_ENGINE_PACKAGE_NAME="@ohos/hvigor",e.PNPM_TOOL=(0,A.isWindows)()?"pnpm.cmd":"pnpm",e.NPM_TOOL=(0,A.isWindows)()?"npm.cmd":"npm",e.HVIGOR="hvigor",e.PNPM="pnpm",e.DEFAULT_HVIGOR_CONFIG_JSON_FILE_NAME="hvigor-config.json5",e.DEFAULT_PACKAGE_JSON="package.json",e.HVIGOR_USER_HOME=E.resolve(F.homedir(),".hvigor"),e.HVIGOR_WRAPPER_TOOLS_HOME=E.resolve(e.HVIGOR_USER_HOME,"wrapper","tools"),e.PROJECT_CACHES="project_caches",e.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH=E.resolve(e.HVIGOR_WRAPPER_TOOLS_HOME,"node_modules",".bin",e.PNPM_TOOL),e.HVIGOR_PNPM_STORE_PATH=E.resolve(e.HVIGOR_USER_HOME,"caches"),e.HVIGOR_PROJECT_CACHES_HOME=E.resolve(e.HVIGOR_USER_HOME,e.PROJECT_CACHES),e.HVIGOR_PROJECT_ROOT_DIR=process.cwd(),e.HVIGOR_PROJECT_WRAPPER_HOME=E.resolve(e.HVIGOR_PROJECT_ROOT_DIR,e.HVIGOR),e.WORK_SPACE="workspace"}(i);var s={},l={};Object.defineProperty(l,"__esModule",{value:!0}),l.logInfoPrintConsole=l.logErrorAndExit=void 0,l.logErrorAndExit=function(u){u instanceof Error?console.error(u.message):console.error(u),process.exit(-1)},l.logInfoPrintConsole=function(u){console.log(u)};var B=n&&n.__createBinding||(Object.create?function(u,D,e,t){void 0===t&&(t=e);var r=Object.getOwnPropertyDescriptor(D,e);r&&!("get"in r?!D.__esModule:r.writable||r.configurable)||(r={enumerable:!0,get:function(){return D[e]}}),Object.defineProperty(u,t,r)}:function(u,D,e,t){void 0===t&&(t=e),u[t]=D[e]}),d=n&&n.__setModuleDefault||(Object.create?function(u,D){Object.defineProperty(u,"default",{enumerable:!0,value:D})}:function(u,D){u.default=D}),f=n&&n.__importStar||function(u){if(u&&u.__esModule)return u;var D={};if(null!=u)for(var e in u)"default"!==e&&Object.prototype.hasOwnProperty.call(u,e)&&B(D,u,e);return d(D,u),D};Object.defineProperty(s,"__esModule",{value:!0});var _=s.executeBuild=void 0;const p=f(e),O=f(u),h=l;_=s.executeBuild=function(u){const D=O.resolve(u,"node_modules","@ohos","hvigor","bin","hvigor.js");try{const u=p.realpathSync(D);require(u)}catch(e){(0,h.logErrorAndExit)(`Error: ENOENT: no such file ${D},delete ${u} and retry.`)}};var P={},v={};!function(u){var D=n&&n.__importDefault||function(u){return u&&u.__esModule?u:{default:u}};Object.defineProperty(u,"__esModule",{value:!0}),u.hashFile=u.hash=u.createHash=void 0;const r=D(t),i=D(e);u.createHash=(u="MD5")=>r.default.createHash(u);u.hash=(D,e)=>(0,u.createHash)(e).update(D).digest("hex");u.hashFile=(D,e)=>{if(i.default.existsSync(D))return(0,u.hash)(i.default.readFileSync(D,"utf-8"),e)}}(v);var g={},m={},R={};Object.defineProperty(R,"__esModule",{value:!0}),R.Unicode=void 0;class y{}R.Unicode=y,y.SPACE_SEPARATOR=/[\u1680\u2000-\u200A\u202F\u205F\u3000]/,y.ID_START=/[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u0860-\u086A\u08A0-\u08B4\u08B6-\u08BD\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u09FC\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0AF9\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C60\u0C61\u0C80\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D54-\u0D56\u0D5F-\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u1884\u1887-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1C80-\u1C88\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312E\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FEA\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AE\uA7B0-\uA7B7\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA8FD\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDE80-\uDE9C\uDEA0-\uDED0\uDF00-\uDF1F\uDF2D-\uDF4A\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE4\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC03-\uDC37\uDC83-\uDCAF\uDCD0-\uDCE8\uDD03-\uDD26\uDD50-\uDD72\uDD76\uDD83-\uDDB2\uDDC1-\uDDC4\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE2B\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEDE\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF50\uDF5D-\uDF61]|\uD805[\uDC00-\uDC34\uDC47-\uDC4A\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDD80-\uDDAE\uDDD8-\uDDDB\uDE00-\uDE2F\uDE44\uDE80-\uDEAA\uDF00-\uDF19]|\uD806[\uDCA0-\uDCDF\uDCFF\uDE00\uDE0B-\uDE32\uDE3A\uDE50\uDE5C-\uDE83\uDE86-\uDE89\uDEC0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC2E\uDC40\uDC72-\uDC8F\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD30\uDD46]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD81C-\uD820\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDED0-\uDEED\uDF00-\uDF2F\uDF40-\uDF43\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50\uDF93-\uDF9F\uDFE0\uDFE1]|\uD821[\uDC00-\uDFEC]|\uD822[\uDC00-\uDEF2]|\uD82C[\uDC00-\uDD1E\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB]|\uD83A[\uDC00-\uDCC4\uDD00-\uDD43]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]/,y.ID_CONTINUE=/[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0300-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u0483-\u0487\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u05D0-\u05EA\u05F0-\u05F2\u0610-\u061A\u0620-\u0669\u066E-\u06D3\u06D5-\u06DC\u06DF-\u06E8\u06EA-\u06FC\u06FF\u0710-\u074A\u074D-\u07B1\u07C0-\u07F5\u07FA\u0800-\u082D\u0840-\u085B\u0860-\u086A\u08A0-\u08B4\u08B6-\u08BD\u08D4-\u08E1\u08E3-\u0963\u0966-\u096F\u0971-\u0983\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BC-\u09C4\u09C7\u09C8\u09CB-\u09CE\u09D7\u09DC\u09DD\u09DF-\u09E3\u09E6-\u09F1\u09FC\u0A01-\u0A03\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A59-\u0A5C\u0A5E\u0A66-\u0A75\u0A81-\u0A83\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABC-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AD0\u0AE0-\u0AE3\u0AE6-\u0AEF\u0AF9-\u0AFF\u0B01-\u0B03\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3C-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B5C\u0B5D\u0B5F-\u0B63\u0B66-\u0B6F\u0B71\u0B82\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD0\u0BD7\u0BE6-\u0BEF\u0C00-\u0C03\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C58-\u0C5A\u0C60-\u0C63\u0C66-\u0C6F\u0C80-\u0C83\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBC-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CDE\u0CE0-\u0CE3\u0CE6-\u0CEF\u0CF1\u0CF2\u0D00-\u0D03\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D44\u0D46-\u0D48\u0D4A-\u0D4E\u0D54-\u0D57\u0D5F-\u0D63\u0D66-\u0D6F\u0D7A-\u0D7F\u0D82\u0D83\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DE6-\u0DEF\u0DF2\u0DF3\u0E01-\u0E3A\u0E40-\u0E4E\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB9\u0EBB-\u0EBD\u0EC0-\u0EC4\u0EC6\u0EC8-\u0ECD\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F18\u0F19\u0F20-\u0F29\u0F35\u0F37\u0F39\u0F3E-\u0F47\u0F49-\u0F6C\u0F71-\u0F84\u0F86-\u0F97\u0F99-\u0FBC\u0FC6\u1000-\u1049\u1050-\u109D\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u135D-\u135F\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1714\u1720-\u1734\u1740-\u1753\u1760-\u176C\u176E-\u1770\u1772\u1773\u1780-\u17D3\u17D7\u17DC\u17DD\u17E0-\u17E9\u180B-\u180D\u1810-\u1819\u1820-\u1877\u1880-\u18AA\u18B0-\u18F5\u1900-\u191E\u1920-\u192B\u1930-\u193B\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19D9\u1A00-\u1A1B\u1A20-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AA7\u1AB0-\u1ABD\u1B00-\u1B4B\u1B50-\u1B59\u1B6B-\u1B73\u1B80-\u1BF3\u1C00-\u1C37\u1C40-\u1C49\u1C4D-\u1C7D\u1C80-\u1C88\u1CD0-\u1CD2\u1CD4-\u1CF9\u1D00-\u1DF9\u1DFB-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u203F\u2040\u2054\u2071\u207F\u2090-\u209C\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D7F-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2DE0-\u2DFF\u2E2F\u3005-\u3007\u3021-\u302F\u3031-\u3035\u3038-\u303C\u3041-\u3096\u3099\u309A\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312E\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FEA\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66F\uA674-\uA67D\uA67F-\uA6F1\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AE\uA7B0-\uA7B7\uA7F7-\uA827\uA840-\uA873\uA880-\uA8C5\uA8D0-\uA8D9\uA8E0-\uA8F7\uA8FB\uA8FD\uA900-\uA92D\uA930-\uA953\uA960-\uA97C\uA980-\uA9C0\uA9CF-\uA9D9\uA9E0-\uA9FE\uAA00-\uAA36\uAA40-\uAA4D\uAA50-\uAA59\uAA60-\uAA76\uAA7A-\uAAC2\uAADB-\uAADD\uAAE0-\uAAEF\uAAF2-\uAAF6\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABEA\uABEC\uABED\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE00-\uFE0F\uFE20-\uFE2F\uFE33\uFE34\uFE4D-\uFE4F\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF3F\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDDFD\uDE80-\uDE9C\uDEA0-\uDED0\uDEE0\uDF00-\uDF1F\uDF2D-\uDF4A\uDF50-\uDF7A\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCA0-\uDCA9\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00-\uDE03\uDE05\uDE06\uDE0C-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE38-\uDE3A\uDE3F\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE6\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC00-\uDC46\uDC66-\uDC6F\uDC7F-\uDCBA\uDCD0-\uDCE8\uDCF0-\uDCF9\uDD00-\uDD34\uDD36-\uDD3F\uDD50-\uDD73\uDD76\uDD80-\uDDC4\uDDCA-\uDDCC\uDDD0-\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE37\uDE3E\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEEA\uDEF0-\uDEF9\uDF00-\uDF03\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3C-\uDF44\uDF47\uDF48\uDF4B-\uDF4D\uDF50\uDF57\uDF5D-\uDF63\uDF66-\uDF6C\uDF70-\uDF74]|\uD805[\uDC00-\uDC4A\uDC50-\uDC59\uDC80-\uDCC5\uDCC7\uDCD0-\uDCD9\uDD80-\uDDB5\uDDB8-\uDDC0\uDDD8-\uDDDD\uDE00-\uDE40\uDE44\uDE50-\uDE59\uDE80-\uDEB7\uDEC0-\uDEC9\uDF00-\uDF19\uDF1D-\uDF2B\uDF30-\uDF39]|\uD806[\uDCA0-\uDCE9\uDCFF\uDE00-\uDE3E\uDE47\uDE50-\uDE83\uDE86-\uDE99\uDEC0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC36\uDC38-\uDC40\uDC50-\uDC59\uDC72-\uDC8F\uDC92-\uDCA7\uDCA9-\uDCB6\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD36\uDD3A\uDD3C\uDD3D\uDD3F-\uDD47\uDD50-\uDD59]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD81C-\uD820\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDE60-\uDE69\uDED0-\uDEED\uDEF0-\uDEF4\uDF00-\uDF36\uDF40-\uDF43\uDF50-\uDF59\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50-\uDF7E\uDF8F-\uDF9F\uDFE0\uDFE1]|\uD821[\uDC00-\uDFEC]|\uD822[\uDC00-\uDEF2]|\uD82C[\uDC00-\uDD1E\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99\uDC9D\uDC9E]|\uD834[\uDD65-\uDD69\uDD6D-\uDD72\uDD7B-\uDD82\uDD85-\uDD8B\uDDAA-\uDDAD\uDE42-\uDE44]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB\uDFCE-\uDFFF]|\uD836[\uDE00-\uDE36\uDE3B-\uDE6C\uDE75\uDE84\uDE9B-\uDE9F\uDEA1-\uDEAF]|\uD838[\uDC00-\uDC06\uDC08-\uDC18\uDC1B-\uDC21\uDC23\uDC24\uDC26-\uDC2A]|\uD83A[\uDC00-\uDCC4\uDCD0-\uDCD6\uDD00-\uDD4A\uDD50-\uDD59]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]|\uDB40[\uDD00-\uDDEF]/,Object.defineProperty(m,"__esModule",{value:!0}),m.JudgeUtil=void 0;const I=R;m.JudgeUtil=class{static isIgnoreChar(u){return"string"==typeof u&&("\t"===u||"\v"===u||"\f"===u||" "===u||" "===u||"\ufeff"===u||"\n"===u||"\r"===u||"\u2028"===u||"\u2029"===u)}static isSpaceSeparator(u){return"string"==typeof u&&I.Unicode.SPACE_SEPARATOR.test(u)}static isIdStartChar(u){return"string"==typeof u&&(u>="a"&&u<="z"||u>="A"&&u<="Z"||"$"===u||"_"===u||I.Unicode.ID_START.test(u))}static isIdContinueChar(u){return"string"==typeof u&&(u>="a"&&u<="z"||u>="A"&&u<="Z"||u>="0"&&u<="9"||"$"===u||"_"===u||"‌"===u||"‍"===u||I.Unicode.ID_CONTINUE.test(u))}static isDigitWithoutZero(u){return/[1-9]/.test(u)}static isDigit(u){return"string"==typeof u&&/[0-9]/.test(u)}static isHexDigit(u){return"string"==typeof u&&/[0-9A-Fa-f]/.test(u)}};var N=n&&n.__importDefault||function(u){return u&&u.__esModule?u:{default:u}};Object.defineProperty(g,"__esModule",{value:!0}),g.parseJsonText=g.parseJsonFile=void 0;const b=N(e),S=N(D),w=N(u),H=m;var x;!function(u){u[u.Char=0]="Char",u[u.EOF=1]="EOF",u[u.Identifier=2]="Identifier"}(x||(x={}));let M,T,V,G,j,J,W="start",U=[],L=0,$=1,k=0,K=!1,z="default",q="'",Z=1;function X(u,D=!1){T=String(u),W="start",U=[],L=0,$=1,k=0,G=void 0,K=D;do{M=Q(),nu[W]()}while("eof"!==M.type);return G}function Q(){for(z="default",j="",q="'",Z=1;;){J=Y();const u=Du[z]();if(u)return u}}function Y(){if(T[L])return String.fromCodePoint(T.codePointAt(L))}function uu(){const u=Y();return"\n"===u?($++,k=0):u?k+=u.length:k++,u&&(L+=u.length),u}g.parseJsonFile=function(u,D=!1,e="utf-8"){const t=b.default.readFileSync(w.default.resolve(u),{encoding:e});try{return X(t,D)}catch(D){if(D instanceof SyntaxError){const e=D.message.split("at");if(2===e.length)throw new Error(`${e[0].trim()}${S.default.EOL}\t at ${u}:${e[1].trim()}`)}throw new Error(`${u} is not in valid JSON/JSON5 format.`)}},g.parseJsonText=X;const Du={default(){switch(J){case"/":return uu(),void(z="comment");case void 0:return uu(),eu("eof")}if(!H.JudgeUtil.isIgnoreChar(J)&&!H.JudgeUtil.isSpaceSeparator(J))return Du[W]();uu()},start(){z="value"},beforePropertyName(){switch(J){case"$":case"_":return j=uu(),void(z="identifierName");case"\\":return uu(),void(z="identifierNameStartEscape");case"}":return eu("punctuator",uu());case'"':case"'":return q=J,uu(),void(z="string")}if(H.JudgeUtil.isIdStartChar(J))return j+=uu(),void(z="identifierName");throw Eu(x.Char,uu())},afterPropertyName(){if(":"===J)return eu("punctuator",uu());throw Eu(x.Char,uu())},beforePropertyValue(){z="value"},afterPropertyValue(){switch(J){case",":case"}":return eu("punctuator",uu())}throw Eu(x.Char,uu())},beforeArrayValue(){if("]"===J)return eu("punctuator",uu());z="value"},afterArrayValue(){switch(J){case",":case"]":return eu("punctuator",uu())}throw Eu(x.Char,uu())},end(){throw Eu(x.Char,uu())},comment(){switch(J){case"*":return uu(),void(z="multiLineComment");case"/":return uu(),void(z="singleLineComment")}throw Eu(x.Char,uu())},multiLineComment(){switch(J){case"*":return uu(),void(z="multiLineCommentAsterisk");case void 0:throw Eu(x.Char,uu())}uu()},multiLineCommentAsterisk(){switch(J){case"*":return void uu();case"/":return uu(),void(z="default");case void 0:throw Eu(x.Char,uu())}uu(),z="multiLineComment"},singleLineComment(){switch(J){case"\n":case"\r":case"\u2028":case"\u2029":return uu(),void(z="default");case void 0:return uu(),eu("eof")}uu()},value(){switch(J){case"{":case"[":return eu("punctuator",uu());case"n":return uu(),tu("ull"),eu("null",null);case"t":return uu(),tu("rue"),eu("boolean",!0);case"f":return uu(),tu("alse"),eu("boolean",!1);case"-":case"+":return"-"===uu()&&(Z=-1),void(z="numerical");case".":case"0":case"I":case"N":return void(z="numerical");case'"':case"'":return q=J,uu(),j="",void(z="string")}if(void 0===J||!H.JudgeUtil.isDigitWithoutZero(J))throw Eu(x.Char,uu());z="numerical"},numerical(){switch(J){case".":return j=uu(),void(z="decimalPointLeading");case"0":return j=uu(),void(z="zero");case"I":return uu(),tu("nfinity"),eu("numeric",Z*(1/0));case"N":return uu(),tu("aN"),eu("numeric",NaN)}if(void 0!==J&&H.JudgeUtil.isDigitWithoutZero(J))return j=uu(),void(z="decimalInteger");throw Eu(x.Char,uu())},zero(){switch(J){case".":case"e":case"E":return void(z="decimal");case"x":case"X":return j+=uu(),void(z="hexadecimal")}return eu("numeric",0)},decimalInteger(){switch(J){case".":case"e":case"E":return void(z="decimal")}if(!H.JudgeUtil.isDigit(J))return eu("numeric",Z*Number(j));j+=uu()},decimal(){switch(J){case".":j+=uu(),z="decimalFraction";break;case"e":case"E":j+=uu(),z="decimalExponent"}},decimalPointLeading(){if(H.JudgeUtil.isDigit(J))return j+=uu(),void(z="decimalFraction");throw Eu(x.Char,uu())},decimalFraction(){switch(J){case"e":case"E":return j+=uu(),void(z="decimalExponent")}if(!H.JudgeUtil.isDigit(J))return eu("numeric",Z*Number(j));j+=uu()},decimalExponent(){switch(J){case"+":case"-":return j+=uu(),void(z="decimalExponentSign")}if(H.JudgeUtil.isDigit(J))return j+=uu(),void(z="decimalExponentInteger");throw Eu(x.Char,uu())},decimalExponentSign(){if(H.JudgeUtil.isDigit(J))return j+=uu(),void(z="decimalExponentInteger");throw Eu(x.Char,uu())},decimalExponentInteger(){if(!H.JudgeUtil.isDigit(J))return eu("numeric",Z*Number(j));j+=uu()},hexadecimal(){if(H.JudgeUtil.isHexDigit(J))return j+=uu(),void(z="hexadecimalInteger");throw Eu(x.Char,uu())},hexadecimalInteger(){if(!H.JudgeUtil.isHexDigit(J))return eu("numeric",Z*Number(j));j+=uu()},identifierNameStartEscape(){if("u"!==J)throw Eu(x.Char,uu());uu();const u=ru();switch(u){case"$":case"_":break;default:if(!H.JudgeUtil.isIdStartChar(u))throw Eu(x.Identifier)}j+=u,z="identifierName"},identifierName(){switch(J){case"$":case"_":case"‌":case"‍":return void(j+=uu());case"\\":return uu(),void(z="identifierNameEscape")}if(!H.JudgeUtil.isIdContinueChar(J))return eu("identifier",j);j+=uu()},identifierNameEscape(){if("u"!==J)throw Eu(x.Char,uu());uu();const u=ru();switch(u){case"$":case"_":case"‌":case"‍":break;default:if(!H.JudgeUtil.isIdContinueChar(u))throw Eu(x.Identifier)}j+=u,z="identifierName"},string(){switch(J){case"\\":return uu(),void(j+=function(){const u=Y(),D=function(){switch(Y()){case"b":return uu(),"\b";case"f":return uu(),"\f";case"n":return uu(),"\n";case"r":return uu(),"\r";case"t":return uu(),"\t";case"v":return uu(),"\v"}return}();if(D)return D;switch(u){case"0":if(uu(),H.JudgeUtil.isDigit(Y()))throw Eu(x.Char,uu());return"\0";case"x":return uu(),function(){let u="",D=Y();if(!H.JudgeUtil.isHexDigit(D))throw Eu(x.Char,uu());if(u+=uu(),D=Y(),!H.JudgeUtil.isHexDigit(D))throw Eu(x.Char,uu());return u+=uu(),String.fromCodePoint(parseInt(u,16))}();case"u":return uu(),ru();case"\n":case"\u2028":case"\u2029":return uu(),"";case"\r":return uu(),"\n"===Y()&&uu(),""}if(void 0===u||H.JudgeUtil.isDigitWithoutZero(u))throw Eu(x.Char,uu());return uu()}());case'"':case"'":if(J===q){const u=eu("string",j);return uu(),u}return void(j+=uu());case"\n":case"\r":case void 0:throw Eu(x.Char,uu());case"\u2028":case"\u2029":!function(u){console.warn(`JSON5: '${Fu(u)}' in strings is not valid ECMAScript; consider escaping.`)}(J)}j+=uu()}};function eu(u,D){return{type:u,value:D,line:$,column:k}}function tu(u){for(const D of u){if(Y()!==D)throw Eu(x.Char,uu());uu()}}function ru(){let u="",D=4;for(;D-- >0;){const D=Y();if(!H.JudgeUtil.isHexDigit(D))throw Eu(x.Char,uu());u+=uu()}return String.fromCodePoint(parseInt(u,16))}const nu={start(){if("eof"===M.type)throw Eu(x.EOF);iu()},beforePropertyName(){switch(M.type){case"identifier":case"string":return V=M.value,void(W="afterPropertyName");case"punctuator":return void Cu();case"eof":throw Eu(x.EOF)}},afterPropertyName(){if("eof"===M.type)throw Eu(x.EOF);W="beforePropertyValue"},beforePropertyValue(){if("eof"===M.type)throw Eu(x.EOF);iu()},afterPropertyValue(){if("eof"===M.type)throw Eu(x.EOF);switch(M.value){case",":return void(W="beforePropertyName");case"}":Cu()}},beforeArrayValue(){if("eof"===M.type)throw Eu(x.EOF);"punctuator"!==M.type||"]"!==M.value?iu():Cu()},afterArrayValue(){if("eof"===M.type)throw Eu(x.EOF);switch(M.value){case",":return void(W="beforeArrayValue");case"]":Cu()}},end(){}};function iu(){const u=function(){let u;switch(M.type){case"punctuator":switch(M.value){case"{":u={};break;case"[":u=[]}break;case"null":case"boolean":case"numeric":case"string":u=M.value}return u}();if(K&&"object"==typeof u&&(u._line=$,u._column=k),void 0===G)G=u;else{const D=U[U.length-1];Array.isArray(D)?K&&"object"!=typeof u?D.push({value:u,_line:$,_column:k}):D.push(u):D[V]=K&&"object"!=typeof u?{value:u,_line:$,_column:k}:u}!function(u){if(u&&"object"==typeof u)U.push(u),W=Array.isArray(u)?"beforeArrayValue":"beforePropertyName";else{const u=U[U.length-1];W=u?Array.isArray(u)?"afterArrayValue":"afterPropertyValue":"end"}}(u)}function Cu(){U.pop();const u=U[U.length-1];W=u?Array.isArray(u)?"afterArrayValue":"afterPropertyValue":"end"}function Fu(u){const D={"'":"\\'",'"':'\\"',"\\":"\\\\","\b":"\\b","\f":"\\f","\n":"\\n","\r":"\\r","\t":"\\t","\v":"\\v","\0":"\\0","\u2028":"\\u2028","\u2029":"\\u2029"};if(D[u])return D[u];if(u<" "){const D=u.charCodeAt(0).toString(16);return`\\x${`00${D}`.substring(D.length)}`}return u}function Eu(u,D){let e="";switch(u){case x.Char:e=void 0===D?`JSON5: invalid end of input at ${$}:${k}`:`JSON5: invalid character '${Fu(D)}' at ${$}:${k}`;break;case x.EOF:e=`JSON5: invalid end of input at ${$}:${k}`;break;case x.Identifier:k-=5,e=`JSON5: invalid identifier character at ${$}:${k}`}const t=new Au(e);return t.lineNumber=$,t.columnNumber=k,t}class Au extends SyntaxError{}var ou={},au=n&&n.__createBinding||(Object.create?function(u,D,e,t){void 0===t&&(t=e);var r=Object.getOwnPropertyDescriptor(D,e);r&&!("get"in r?!D.__esModule:r.writable||r.configurable)||(r={enumerable:!0,get:function(){return D[e]}}),Object.defineProperty(u,t,r)}:function(u,D,e,t){void 0===t&&(t=e),u[t]=D[e]}),cu=n&&n.__setModuleDefault||(Object.create?function(u,D){Object.defineProperty(u,"default",{enumerable:!0,value:D})}:function(u,D){u.default=D}),su=n&&n.__importStar||function(u){if(u&&u.__esModule)return u;var D={};if(null!=u)for(var e in u)"default"!==e&&Object.prototype.hasOwnProperty.call(u,e)&&au(D,u,e);return cu(D,u),D},lu=n&&n.__importDefault||function(u){return u&&u.__esModule?u:{default:u}};Object.defineProperty(ou,"__esModule",{value:!0}),ou.isFileExists=ou.offlinePluginConversion=ou.executeCommand=ou.getNpmPath=ou.hasNpmPackInPaths=void 0;const Bu=r,du=lu(e),fu=su(u),_u=i,pu=l;ou.hasNpmPackInPaths=function(u,D){try{return require.resolve(u,{paths:[...D]}),!0}catch(u){return!1}},ou.getNpmPath=function(){const u=process.execPath;return fu.join(fu.dirname(u),_u.NPM_TOOL)},ou.executeCommand=function(u,D,e){0!==(0,Bu.spawnSync)(u,D,e).status&&(0,pu.logErrorAndExit)(`Error: ${u} ${D} execute failed.See above for details.`)},ou.offlinePluginConversion=function(u,D){return D.startsWith("file:")||D.endsWith(".tgz")?fu.resolve(u,_u.HVIGOR,D.replace("file:","")):D},ou.isFileExists=function(u){return du.default.existsSync(u)&&du.default.statSync(u).isFile()};var Ou=n&&n.__createBinding||(Object.create?function(u,D,e,t){void 0===t&&(t=e);var r=Object.getOwnPropertyDescriptor(D,e);r&&!("get"in r?!D.__esModule:r.writable||r.configurable)||(r={enumerable:!0,get:function(){return D[e]}}),Object.defineProperty(u,t,r)}:function(u,D,e,t){void 0===t&&(t=e),u[t]=D[e]}),hu=n&&n.__setModuleDefault||(Object.create?function(u,D){Object.defineProperty(u,"default",{enumerable:!0,value:D})}:function(u,D){u.default=D}),Pu=n&&n.__importStar||function(u){if(u&&u.__esModule)return u;var D={};if(null!=u)for(var e in u)"default"!==e&&Object.prototype.hasOwnProperty.call(u,e)&&Ou(D,u,e);return hu(D,u),D},vu=n&&n.__importDefault||function(u){return u&&u.__esModule?u:{default:u}};Object.defineProperty(P,"__esModule",{value:!0});var gu=P.initProjectWorkSpace=void 0;const mu=Pu(e),Ru=vu(D),yu=Pu(u),Iu=v,Nu=i,bu=g,Su=l,wu=ou;let Hu,xu,Mu;function Tu(u,D,e){return void 0!==e.dependencies&&(0,wu.offlinePluginConversion)(Nu.HVIGOR_PROJECT_ROOT_DIR,D.dependencies[u])===yu.normalize(e.dependencies[u])}function Vu(){const u=yu.join(Mu,Nu.WORK_SPACE);if((0,Su.logInfoPrintConsole)("Hvigor cleaning..."),!mu.existsSync(u))return;const D=mu.readdirSync(u);if(!D||0===D.length)return;const e=yu.resolve(Mu,"node_modules","@ohos","hvigor","bin","hvigor.js");mu.existsSync(e)&&(0,wu.executeCommand)(process.argv[0],[e,"--stop-daemon"],{});try{D.forEach((D=>{mu.rmSync(yu.resolve(u,D),{recursive:!0})}))}catch(D){(0,Su.logErrorAndExit)(`The hvigor build tool cannot be installed. Please manually clear the workspace directory and synchronize the project again.\n\n Workspace Path: ${u}.`)}}gu=P.initProjectWorkSpace=function(){if(Hu=function(){const u=yu.resolve(Nu.HVIGOR_PROJECT_WRAPPER_HOME,Nu.DEFAULT_HVIGOR_CONFIG_JSON_FILE_NAME);mu.existsSync(u)||(0,Su.logErrorAndExit)(`Error: Hvigor config file ${u} does not exist.`);return(0,bu.parseJsonFile)(u)}(),Mu=function(u){let D;D=function(u){let D=u.hvigorVersion;if(D.startsWith("file:")||D.endsWith(".tgz"))return!1;const e=u.dependencies,t=Object.getOwnPropertyNames(e);for(const u of t){const D=e[u];if(D.startsWith("file:")||D.endsWith(".tgz"))return!1}if(1===t.length&&"@ohos/hvigor-ohos-plugin"===t[0])return D>"2.5.0";return!1}(u)?function(u){let D=`${Nu.HVIGOR_ENGINE_PACKAGE_NAME}@${u.hvigorVersion}`;const e=u.dependencies;if(e){Object.getOwnPropertyNames(e).sort().forEach((u=>{D+=`,${u}@${e[u]}`}))}return(0,Iu.hash)(D)}(u):(0,Iu.hash)(process.cwd());return yu.resolve(Ru.default.homedir(),".hvigor","project_caches",D)}(Hu),xu=function(){const u=yu.resolve(Mu,Nu.WORK_SPACE,Nu.DEFAULT_PACKAGE_JSON);return mu.existsSync(u)?(0,bu.parseJsonFile)(u):{dependencies:{}}}(),!(0,wu.hasNpmPackInPaths)(Nu.HVIGOR_ENGINE_PACKAGE_NAME,[yu.join(Mu,Nu.WORK_SPACE)])||(0,wu.offlinePluginConversion)(Nu.HVIGOR_PROJECT_ROOT_DIR,Hu.hvigorVersion)!==xu.dependencies[Nu.HVIGOR_ENGINE_PACKAGE_NAME]||!function(){function u(u){const D=null==u?void 0:u.dependencies;return void 0===D?0:Object.getOwnPropertyNames(D).length}const D=u(Hu),e=u(xu);if(D+1!==e)return!1;for(const u in null==Hu?void 0:Hu.dependencies)if(!(0,wu.hasNpmPackInPaths)(u,[yu.join(Mu,Nu.WORK_SPACE)])||!Tu(u,Hu,xu))return!1;return!0}()){Vu();try{!function(){(0,Su.logInfoPrintConsole)("Hvigor installing...");for(const u in Hu.dependencies)Hu.dependencies[u]&&(Hu.dependencies[u]=(0,wu.offlinePluginConversion)(Nu.HVIGOR_PROJECT_ROOT_DIR,Hu.dependencies[u]));const u={dependencies:{...Hu.dependencies}};u.dependencies[Nu.HVIGOR_ENGINE_PACKAGE_NAME]=(0,wu.offlinePluginConversion)(Nu.HVIGOR_PROJECT_ROOT_DIR,Hu.hvigorVersion);const D=yu.join(Mu,Nu.WORK_SPACE);try{mu.mkdirSync(D,{recursive:!0});const e=yu.resolve(D,Nu.DEFAULT_PACKAGE_JSON);mu.writeFileSync(e,JSON.stringify(u))}catch(u){(0,Su.logErrorAndExit)(u)}(function(){const u=["config","set","store-dir",Nu.HVIGOR_PNPM_STORE_PATH],D={cwd:yu.join(Mu,Nu.WORK_SPACE),stdio:["inherit","inherit","inherit"]};(0,wu.executeCommand)(Nu.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH,u,D)})(),function(){const u=["install"],D={cwd:yu.join(Mu,Nu.WORK_SPACE),stdio:["inherit","inherit","inherit"]};(0,wu.executeCommand)(Nu.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH,u,D)}(),(0,Su.logInfoPrintConsole)("Hvigor install success.")}()}catch(u){Vu()}}return Mu};var Gu={};!function(t){var C=n&&n.__createBinding||(Object.create?function(u,D,e,t){void 0===t&&(t=e);var r=Object.getOwnPropertyDescriptor(D,e);r&&!("get"in r?!D.__esModule:r.writable||r.configurable)||(r={enumerable:!0,get:function(){return D[e]}}),Object.defineProperty(u,t,r)}:function(u,D,e,t){void 0===t&&(t=e),u[t]=D[e]}),F=n&&n.__setModuleDefault||(Object.create?function(u,D){Object.defineProperty(u,"default",{enumerable:!0,value:D})}:function(u,D){u.default=D}),E=n&&n.__importStar||function(u){if(u&&u.__esModule)return u;var D={};if(null!=u)for(var e in u)"default"!==e&&Object.prototype.hasOwnProperty.call(u,e)&&C(D,u,e);return F(D,u),D},A=n&&n.__importDefault||function(u){return u&&u.__esModule?u:{default:u}};Object.defineProperty(t,"__esModule",{value:!0}),t.executeInstallPnpm=t.isPnpmInstalled=t.environmentHandler=t.checkNpmConifg=t.PNPM_VERSION=void 0;const o=r,a=E(e),c=A(D),s=E(u),B=i,d=l,f=ou;t.PNPM_VERSION="7.30.0",t.checkNpmConifg=function(){const u=s.resolve(B.HVIGOR_PROJECT_ROOT_DIR,".npmrc"),D=s.resolve(c.default.homedir(),".npmrc");if((0,f.isFileExists)(u)||(0,f.isFileExists)(D))return;const e=(0,f.getNpmPath)(),t=(0,o.spawnSync)(e,["config","get","prefix"],{cwd:B.HVIGOR_PROJECT_ROOT_DIR});if(0!==t.status||!t.stdout)return void(0,d.logErrorAndExit)("Error: The hvigor depends on the npmrc file. Configure the npmrc file first.");const r=s.resolve(`${t.stdout}`.replace(/[\r\n]/gi,""),".npmrc");(0,f.isFileExists)(r)||(0,d.logErrorAndExit)("Error: The hvigor depends on the npmrc file. Configure the npmrc file first.")},t.environmentHandler=function(){process.env["npm_config_update-notifier"]="false"},t.isPnpmInstalled=function(){return!!a.existsSync(B.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH)&&(0,f.hasNpmPackInPaths)("pnpm",[B.HVIGOR_WRAPPER_TOOLS_HOME])},t.executeInstallPnpm=function(){(0,d.logInfoPrintConsole)(`Installing pnpm@${t.PNPM_VERSION}...`);const u=(0,f.getNpmPath)();!function(){const u=s.resolve(B.HVIGOR_WRAPPER_TOOLS_HOME,B.DEFAULT_PACKAGE_JSON);try{a.existsSync(B.HVIGOR_WRAPPER_TOOLS_HOME)||a.mkdirSync(B.HVIGOR_WRAPPER_TOOLS_HOME,{recursive:!0});const D={dependencies:{}};D.dependencies[B.PNPM]=t.PNPM_VERSION,a.writeFileSync(u,JSON.stringify(D))}catch(D){(0,d.logErrorAndExit)(`Error: EPERM: operation not permitted,create ${u} failed.`)}}(),(0,f.executeCommand)(u,["install","pnpm"],{cwd:B.HVIGOR_WRAPPER_TOOLS_HOME,stdio:["inherit","inherit","inherit"],env:process.env}),(0,d.logInfoPrintConsole)("Pnpm install success.")}}(Gu),function(){Gu.checkNpmConifg(),Gu.environmentHandler(),Gu.isPnpmInstalled()||Gu.executeInstallPnpm();const D=gu();_(u.join(D,i.WORK_SPACE))}(); \ No newline at end of file diff --git a/hvigorfile.js b/hvigorfile.js deleted file mode 100644 index 5f2735e..0000000 --- a/hvigorfile.js +++ /dev/null @@ -1,2 +0,0 @@ -// Script for compiling build behavior. It is built in the build plug-in and cannot be modified currently. -module.exports = require('@ohos/hvigor-ohos-plugin').appTasks \ No newline at end of file diff --git a/hvigorfile.ts b/hvigorfile.ts new file mode 100644 index 0000000..f3cb9f1 --- /dev/null +++ b/hvigorfile.ts @@ -0,0 +1,6 @@ +import { appTasks } from '@ohos/hvigor-ohos-plugin'; + +export default { + system: appTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ + plugins:[] /* Custom plugin to extend the functionality of Hvigor. */ +} diff --git a/hvigorw b/hvigorw index 54aadd2..4f0aa94 100644 --- a/hvigorw +++ b/hvigorw @@ -2,47 +2,53 @@ # ---------------------------------------------------------------------------- # Hvigor startup script, version 1.0.0 -# +# # Required ENV vars: # ------------------ # NODE_HOME - location of a Node home dir -# or +# or # Add /usr/local/nodejs/bin to the PATH environment variable # ---------------------------------------------------------------------------- -HVIGOR_APP_HOME=$(dirname $(readlink -f $0)) +HVIGOR_APP_HOME="`pwd -P`" HVIGOR_WRAPPER_SCRIPT=${HVIGOR_APP_HOME}/hvigor/hvigor-wrapper.js -warn() { - echo "" - echo -e "\033[1;33m`date '+[%Y-%m-%d %H:%M:%S]'`$@\033[0m" -} - -error() { - echo "" - echo -e "\033[1;31m`date '+[%Y-%m-%d %H:%M:%S]'`$@\033[0m" -} +#NODE_OPTS="--max-old-space-size=4096" fail() { - error "$@" - exit 1 + echo "$*" + exit 1 +} + +set_executable_node() { + EXECUTABLE_NODE="${NODE_HOME}/bin/node" + if [ -x "$EXECUTABLE_NODE" ]; then + return + fi + + EXECUTABLE_NODE="${NODE_HOME}/node" + if [ -x "$EXECUTABLE_NODE" ]; then + return + fi + fail "ERROR: NODE_HOME is set to an invalid directory,check $NODE_HOME\n\nPlease set NODE_HOME in your environment to the location where your nodejs installed" } # Determine node to start hvigor wrapper script -if [ -n "${NODE_HOME}" ];then - EXECUTABLE_NODE="${NODE_HOME}/bin/node" - if [ ! -x "$EXECUTABLE_NODE" ];then - fail "ERROR: NODE_HOME is set to an invalid directory,check $NODE_HOME\n\nPlease set NODE_HOME in your environment to the location where your nodejs installed" - fi +if [ -n "${NODE_HOME}" ]; then + set_executable_node else - EXECUTABLE_NODE="node" - which ${EXECUTABLE_NODE} > /dev/null 2>&1 || fail "ERROR: NODE_HOME is not set and not 'node' command found in your path" + EXECUTABLE_NODE="node" + command -v ${EXECUTABLE_NODE} &> /dev/null || fail "ERROR: NODE_HOME not set and 'node' command not found" fi # Check hvigor wrapper script -if [ ! -r "$HVIGOR_WRAPPER_SCRIPT" ];then - fail "ERROR: Couldn't find hvigor/hvigor-wrapper.js in ${HVIGOR_APP_HOME}" +if [ ! -r "$HVIGOR_WRAPPER_SCRIPT" ]; then + fail "ERROR: Couldn't find hvigor/hvigor-wrapper.js in ${HVIGOR_APP_HOME}" +fi + +if [ -z "${NODE_OPTS}" ]; then + NODE_OPTS="--" fi # start hvigor-wrapper script -exec "${EXECUTABLE_NODE}" \ - "${HVIGOR_WRAPPER_SCRIPT}" "$@" +exec "${EXECUTABLE_NODE}" "${NODE_OPTS}" \ + "${HVIGOR_WRAPPER_SCRIPT}" "$@" diff --git a/hvigorw.bat b/hvigorw.bat index 29196b4..b5eecf5 100644 --- a/hvigorw.bat +++ b/hvigorw.bat @@ -1,9 +1,15 @@ -@if "%DEBUG%" == "" @echo off -@rem ########################################################################## @rem -@rem Hvigor startup script for Windows +@rem ---------------------------------------------------------------------------- +@rem Hvigor startup script for Windows, version 1.0.0 @rem -@rem ########################################################################## +@rem Required ENV vars: +@rem ------------------ +@rem NODE_HOME - location of a Node home dir +@rem or +@rem Add %NODE_HOME%/bin to the PATH environment variable +@rem ---------------------------------------------------------------------------- +@rem +@echo off @rem Set local scope for the variables with windows NT shell if "%OS%"=="Windows_NT" setlocal @@ -13,45 +19,36 @@ if "%DIRNAME%" == "" set DIRNAME=. set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% +set WRAPPER_MODULE_PATH=%APP_HOME%\hvigor\hvigor-wrapper.js +set NODE_EXE=node.exe +@rem set NODE_OPTS="--max-old-space-size=4096" + @rem Resolve any "." and ".." in APP_HOME to make it shorter. for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi -set WRAPPER_MODULE_PATH=%APP_HOME%\hvigor\hvigor-wrapper.js -set NODE_EXE=node.exe +if not defined NODE_OPTS set NODE_OPTS="--" -goto start - -:start @rem Find node.exe -if defined NODE_HOME goto findNodeFromNodeHome +if defined NODE_HOME ( + set NODE_HOME=%NODE_HOME:"=% + set NODE_EXE_PATH=%NODE_HOME%/%NODE_EXE% +) %NODE_EXE% --version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto execute +if "%ERRORLEVEL%" == "0" ( + "%NODE_EXE%" "%NODE_OPTS%" "%WRAPPER_MODULE_PATH%" %* +) else if exist "%NODE_EXE_PATH%" ( + "%NODE_EXE%" "%NODE_OPTS%" "%WRAPPER_MODULE_PATH%" %* +) else ( + echo. + echo ERROR: NODE_HOME is not set and no 'node' command could be found in your PATH. + echo. + echo Please set the NODE_HOME variable in your environment to match the + echo location of your NodeJs installation. +) -echo. -echo ERROR: NODE_HOME is not set and no 'node' command could be found in your PATH. -echo. -echo Please set the NODE_HOME variable in your environment to match the -echo location of your NodeJs installation. - -goto fail - -:findNodeFromNodeHome -set NODE_HOME=%NODE_HOME:"=% -set NODE_EXE_PATH=%NODE_HOME%/%NODE_EXE% - -if exist "%NODE_EXE_PATH%" goto execute -echo. -echo ERROR: NODE_HOME is not set and no 'node' command could be found in your PATH. -echo. -echo Please set the NODE_HOME variable in your environment to match the -echo location of your NodeJs installation. - -goto fail - -:execute -@rem Execute hvigor -"%NODE_EXE%" %WRAPPER_MODULE_PATH% %* - -:fail -exit /b 1 +if "%ERRORLEVEL%" == "0" ( + if "%OS%" == "Windows_NT" endlocal +) else ( + exit /b %ERRORLEVEL% +) \ No newline at end of file diff --git a/library/.gitignore b/library/.gitignore index f8fba9f..e2713a2 100644 --- a/library/.gitignore +++ b/library/.gitignore @@ -1,5 +1,6 @@ /node_modules +/oh_modules /.preview /build -/oh_modules/ -/oh-package-lock.json5 +/.cxx +/.test \ No newline at end of file diff --git a/library/BuildProfile.ets b/library/BuildProfile.ets new file mode 100644 index 0000000..56a40f4 --- /dev/null +++ b/library/BuildProfile.ets @@ -0,0 +1,5 @@ +export default class BuildProfile { + static readonly HAR_VERSION = '3.0.0-rc.0'; + static readonly BUILD_MODE_NAME = 'debug'; + static readonly DEBUG = true; +} \ No newline at end of file diff --git a/library/PngWork.ets b/library/PngWork.ets deleted file mode 100644 index d6492b8..0000000 --- a/library/PngWork.ets +++ /dev/null @@ -1,61 +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 taskpool from '@ohos.taskpool'; -import { UPNG } from './src/main/ets/components/3rd_party/upng/UPNG' -import { WorkerType } from "./src/main/ets/components/imageknife/pngj/PngCallback" - -export function handler(e: WorkerType, source: ArrayBuffer, pngCallback: (value:ESObject) => void, info?: string) { - let task: taskpool.Task | undefined = undefined - if (info == undefined) { - task = new taskpool.Task(printArgs, e) - } else { - task = new taskpool.Task(printArgs, e, source) - } - let val1: ESObject = taskpool.execute(task) - pngCallback(val1) - try { - taskpool.cancel(task) - } catch (e) { - console.error("taskpool.cancel occur error:" + e) - } -} - -@Concurrent -function printArgs(e: WorkerType, pngSource: ArrayBuffer, info?: string): Object | ArrayBufferLike | void { - let a: Object | ArrayBufferLike | undefined = undefined - let png = UPNG.decode(pngSource) - switch (e.name) { - case 'readPngImageAsync': - let array: Uint8Array = png.data; - let arrayData = array.buffer.slice(array.byteOffset, array.byteLength + array.byteOffset) - png.data = arrayData; - a = png - break; - case 'writePngWithStringAsync': - let addInfo: string | undefined = info; - let newPng = UPNG.encodeWithString(addInfo, UPNG.toRGBA8(png), png.width, png.height, 0) - a = newPng - break; - case 'writePngAsync': - let newPng3 = UPNG.encode(UPNG.toRGBA8(png), png.width, png.height, 0) - a = newPng3 - break; - default: - break - } - if(a != undefined) { return a } -} - - diff --git a/library/build-profile.json5 b/library/build-profile.json5 index 35dff6d..312d38e 100644 --- a/library/build-profile.json5 +++ b/library/build-profile.json5 @@ -1,5 +1,28 @@ { "apiType": "stageMode", "buildOption": { - } + }, + "buildOptionSet": [ + { + "name": "release", + "arkOptions": { + "obfuscation": { + "ruleOptions": { + "enable": true, + "files": [ + "./obfuscation-rules.txt" + ] + }, + "consumerFiles": [ + "./consumer-rules.txt" + ] + } + }, + }, + ], + "targets": [ + { + "name": "default" + } + ] } diff --git a/library/consumer-rules.txt b/library/consumer-rules.txt new file mode 100644 index 0000000..e69de29 diff --git a/library/hvigorfile.ts b/library/hvigorfile.ts index 42ed4b4..4218707 100644 --- a/library/hvigorfile.ts +++ b/library/hvigorfile.ts @@ -1,3 +1,6 @@ -// Script for compiling build behavior. It is built in the build plug-in and cannot be modified currently. -module.exports = require('@ohos/hvigor-ohos-plugin').harTasks +import { harTasks } from '@ohos/hvigor-ohos-plugin'; +export default { + system: harTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ + plugins:[] /* Custom plugin to extend the functionality of Hvigor. */ +} diff --git a/library/index.ets b/library/index.ets index 061b4db..7a3fa16 100644 --- a/library/index.ets +++ b/library/index.ets @@ -1,130 +1,11 @@ -/* - * 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. - */ +export { ImageKnifeComponent } from './src/main/ets/components/ImageKnifeComponent' + +export { ImageKnife } from './src/main/ets/ImageKnife' + +export { ImageKnifeOption } from './src/main/ets/ImageKnifeOption' + +export { ImageKnifeRequest } from './src/main/ets/ImageKnifeRequest' + +export { FileUtils } from './src/main/ets/utils/FileUtils' -/** - * cache - */ - -export { FileUtils } from './src/main/ets/components/cache/FileUtils' -export { Base64 } from './src/main/ets/components/cache/Base64' -export { LruCache } from './src/main/ets/components/cache/LruCache' -export { DiskLruCache } from './src/main/ets/components/cache/DiskLruCache' -export { DiskCacheEntry } from './src/main/ets/components/cache/DiskCacheEntry' -export { DiskStrategy } from './src/main/ets/components/cache/diskstrategy/DiskStrategy' -export { ALL } from './src/main/ets/components/cache/diskstrategy/enum/ALL' -export { AUTOMATIC } from './src/main/ets/components/cache/diskstrategy/enum/AUTOMATIC' -export { DATA } from './src/main/ets/components/cache/diskstrategy/enum/DATA' -export { NONE } from './src/main/ets/components/cache/diskstrategy/enum/NONE' -export { RESOURCE } from './src/main/ets/components/cache/diskstrategy/enum/RESOURCE' -export { EngineKeyInterface } from './src/main/ets/components/cache/key/EngineKeyInterface' -export { EngineKeyFactories } from './src/main/ets/components/cache/key/EngineKeyFactories' - -/** - * compress - */ -export { CompressBuilder } from './src/main/ets/components/imageknife/compress/CompressBuilder' -export { OnCompressListener } from './src/main/ets/components/imageknife/compress/listener/OnCompressListener' -export { OnRenameListener } from './src/main/ets/components/imageknife/compress/listener/OnRenameListener' -export { CompressDataListener } from './src/main/ets/components/imageknife/compress/listener/CompressDataListener' -export { CompressionPredicate } from './src/main/ets/components/imageknife/compress/listener/CompressionPredicate' -export { CompressAdapter } from './src/main/ets/components/imageknife/compress/provider/CompressAdapter' -export { CompressProvider } from './src/main/ets/components/imageknife/compress/provider/CompressProvider' -export { DataStringPathProvider } from './src/main/ets/components/imageknife/compress/provider/DataStringPathProvider' -export { RecourseProvider } from './src/main/ets/components/imageknife/compress/provider/RecourseProvider' - -/** - * crop - */ - -export { CropImage } from './src/main/ets/components/imageknife/crop/CropImage' -export { CropOptions } from './src/main/ets/components/imageknife/crop/CropOptions' -export { PixelMapCrop,Options } from './src/main/ets/components/imageknife/crop/PixelMapCrop' -export { CropCallback } from './src/main/ets/components/imageknife/crop/CropCallback' - -/** - * transform - */ -export { BaseTransform } from './src/main/ets/components/imageknife/transform/BaseTransform' -export { BlurTransformation } from './src/main/ets/components/imageknife/transform/BlurTransformation' -export { BrightnessFilterTransformation } from './src/main/ets/components/imageknife/transform/BrightnessFilterTransformation' -export { ContrastFilterTransformation } from './src/main/ets/components/imageknife/transform/ContrastFilterTransformation' -export { CropCircleTransformation } from './src/main/ets/components/imageknife/transform/CropCircleTransformation' -export { CropCircleWithBorderTransformation,rgbColor } from './src/main/ets/components/imageknife/transform/CropCircleWithBorderTransformation' -export { CropSquareTransformation } from './src/main/ets/components/imageknife/transform/CropSquareTransformation' -export { CropTransformation,CropType } from './src/main/ets/components/imageknife/transform/CropTransformation' -export { GrayscaleTransformation } from './src/main/ets/components/imageknife/transform/GrayscaleTransformation' -export { InvertFilterTransformation } from './src/main/ets/components/imageknife/transform/InvertFilterTransformation' -export { PixelationFilterTransformation } from './src/main/ets/components/imageknife/transform/PixelationFilterTransformation' -export { RotateImageTransformation } from './src/main/ets/components/imageknife/transform/RotateImageTransformation' -export { RoundedCornersTransformation,RoundCorner } from './src/main/ets/components/imageknife/transform/RoundedCornersTransformation' -export { SepiaFilterTransformation } from './src/main/ets/components/imageknife/transform/SepiaFilterTransformation' -export { SketchFilterTransformation } from './src/main/ets/components/imageknife/transform/SketchFilterTransformation' -export { MaskTransformation } from './src/main/ets/components/imageknife/transform/MaskTransformation' -export { SwirlFilterTransformation } from './src/main/ets/components/imageknife/transform/SwirlFilterTransformation' -export { KuwaharaFilterTransform } from './src/main/ets/components/imageknife/transform/KuwaharaFilterTransform' -export { ToonFilterTransform } from './src/main/ets/components/imageknife/transform/ToonFilterTransform' -export { VignetteFilterTransform } from './src/main/ets/components/imageknife/transform/VignetteFilterTransform' -export { TransformUtils } from './src/main/ets/components/imageknife/transform/TransformUtils' -export { TransformType } from './src/main/ets/components/imageknife/transform/TransformType' -export { CenterCrop } from './src/main/ets/components/imageknife/transform/pixelmap/CenterCrop' -export { CenterInside } from './src/main/ets/components/imageknife/transform/pixelmap/CenterInside' -export { FitCenter } from './src/main/ets/components/imageknife/transform/pixelmap/FitCenter' - -/** - * pngj - */ -export { Pngj } from './src/main/ets/components/imageknife/pngj/Pngj' -export {handler} from './PngWork' -export { UPNG } from './src/main/ets/components/3rd_party/upng/UPNG' - - - -/** - * ImageKnife - */ -export { ImageKnife } from './src/main/ets/components/imageknife/ImageKnife' -export { ImageKnifeGlobal } from './src/main/ets/components/imageknife/ImageKnifeGlobal' -export { ObjectKey } from './src/main/ets/components/imageknife/ObjectKey' -export {RequestOption,Size,DetachFromLayout,Priority} from './src/main/ets/components/imageknife/RequestOption' -export { ImageKnifeComponent, ScaleType, ScaleTypeHelper, AntiAliasing} from './src/main/ets/components/imageknife/ImageKnifeComponent' -export { ImageKnifeDrawFactory } from './src/main/ets/components/imageknife/ImageKnifeDrawFactory' -export {ImageKnifeOption,CropCircleWithBorder,Crop,GifOptions,TransformOptions,HeaderOptions} from './src/main/ets/components/imageknife/ImageKnifeOption' -export { ImageKnifeData } from './src/main/ets/components/imageknife/ImageKnifeData' -export {IAllCacheInfoCallback,AllCacheInfo,ResourceCacheInfo,MemoryCacheInfo,DataCacheInfo} from './src/main/ets/components/imageknife/interface/IAllCacheInfoCallback' -export {IParseImage} from './src/main/ets/components/imageknife/interface/IParseImage' -export {IDataFetch} from './src/main/ets/components/imageknife/networkmanage/IDataFetch' -export {ICache} from './src/main/ets/components/imageknife/requestmanage/ICache' -export { FileTypeUtil } from './src/main/ets/components/imageknife/utils/FileTypeUtil' -export { ParseImageUtil } from './src/main/ets/components/imageknife/utils/ParseImageUtil' - -/** - * svg parse - */ -export { SVGParseImpl } from './src/main/ets/components/imageknife/utils/svg/SVGParseImpl' - -/** - * gif parse - */ -export { GIFParseImpl } from './src/main/ets/components/imageknife/utils/gif/GIFParseImpl' -export { GIFFrame } from './src/main/ets/components/imageknife/utils/gif/GIFFrame' - - -// 自定义组件新增 -// 自定义组件绘制生命周期 -export { IDrawLifeCycle } from './src/main/ets/components/imageknife/interface/IDrawLifeCycle' - -// 日志管理 -export { LogUtil } from './src/main/ets/components/imageknife/utils/LogUtil' \ No newline at end of file diff --git a/library/obfuscation-rules.txt b/library/obfuscation-rules.txt new file mode 100644 index 0000000..985b2ae --- /dev/null +++ b/library/obfuscation-rules.txt @@ -0,0 +1,18 @@ +# Define project specific obfuscation rules here. +# You can include the obfuscation configuration files in the current module's build-profile.json5. +# +# For more details, see +# https://gitee.com/openharmony/arkcompiler_ets_frontend/blob/master/arkguard/README.md + +# Obfuscation options: +# -disable-obfuscation: disable all obfuscations +# -enable-property-obfuscation: obfuscate the property names +# -enable-toplevel-obfuscation: obfuscate the names in the global scope +# -compact: remove unnecessary blank spaces and all line feeds +# -remove-log: remove all console.* statements +# -print-namecache: print the name cache that contains the mapping from the old names to new names +# -apply-namecache: reuse the given cache file + +# Keep options: +# -keep-property-name: specifies property names that you want to keep +# -keep-global-name: specifies names that you want to keep in the global scope \ No newline at end of file diff --git a/library/oh-package-lock.json5 b/library/oh-package-lock.json5 new file mode 100644 index 0000000..3245bae --- /dev/null +++ b/library/oh-package-lock.json5 @@ -0,0 +1,6 @@ +{ + "lockfileVersion": 3, + "ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.", + "specifiers": {}, + "packages": {} +} \ No newline at end of file diff --git a/library/oh-package.json5 b/library/oh-package.json5 index 1b8fc01..0b53565 100644 --- a/library/oh-package.json5 +++ b/library/oh-package.json5 @@ -14,10 +14,9 @@ "main": "index.ets", "repository": "https://gitee.com/openharmony-tpc/ImageKnife", "type": "module", - "version": "2.1.2-rc.12", + "version": "3.0.0-rc.0", "dependencies": { - "pako": "^2.1.0", - "@ohos/gpu_transform": "^1.0.0" + }, "tags": [ "ImageCache", diff --git a/library/src/main/ets/components/3rd_party/sparkmd5/spark-md5.js b/library/src/main/ets/3rd_party/sparkmd5/spark-md5.js similarity index 100% rename from library/src/main/ets/components/3rd_party/sparkmd5/spark-md5.js rename to library/src/main/ets/3rd_party/sparkmd5/spark-md5.js diff --git a/library/src/main/ets/ImageKnife.ets b/library/src/main/ets/ImageKnife.ets new file mode 100644 index 0000000..c529d4b --- /dev/null +++ b/library/src/main/ets/ImageKnife.ets @@ -0,0 +1,123 @@ +/* + * 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 { ImageKnifeRequest } from './ImageKnifeRequest'; +import { ImageKnifeData } from './model/ImageKnifeData'; +import { MemoryLruCache } from './utils/MemoryLruCache'; +import { IMemoryCache } from './utils/IMemoryCache' +import { FileCache } from './utils/FileCache'; +import { ImageKnifeDispatcher } from './ImageKnifeDispatcher'; + + +export class ImageKnife { + private static instance: ImageKnife; + // 内存缓存 + private memoryCache: IMemoryCache = new MemoryLruCache(256, 128 * 1024 * 1024); + // 文件缓存 + private fileCache?: FileCache + private dispatcher: ImageKnifeDispatcher = new ImageKnifeDispatcher() + + public static getInstance(): ImageKnife { + if (!ImageKnife.instance) { + ImageKnife.instance = new ImageKnife(); + } + return ImageKnife.instance; + } + + private constructor() { + } + + /** + * 初始化文件缓存 + * @param context 上下文 + * @param size 缓存数量 + * @param memory 内存大小 + */ + async initFileCache(context: Context, size: number, memory: number) { + this.fileCache = new FileCache(context, size, memory) + this.fileCache.initFileCache() + } + + /** + * 设置自定义的内存缓存 + * @param newMemoryCache 自定义内存缓存 + */ + initMemoryCache(newMemoryCache: IMemoryCache): void { + this.memoryCache + } + + /** + * 清除所有内存缓存 + */ + removeAllMemoryCache(): void { + this.memoryCache.removeAll() + } + + loadFromMemoryCache(key: string): ImageKnifeData | undefined { + if (key !== "") { + return this.memoryCache.get(key) + } + return undefined + } + + saveMemoryCache(key: string, data: ImageKnifeData): void { + if (key !== "") { + this.memoryCache.put(key, data) + } + } + + loadFromFileCache(key: string): ArrayBuffer | undefined { + return this.fileCache?.get(key) + } + + saveFileCache(key: string, data: ArrayBuffer): void { + this.fileCache?.put(key, data) + } + + /** + * 清除所有文件缓存 + * @returns + */ + async removeAllFileCache(): Promise { + if (this.fileCache !== undefined) { + await this.fileCache.removeAll() + } + } + + saveWithoutWriteFile(key: string, bufferSize: number): void { + this.fileCache?.putWithoutWriteFile(key, bufferSize) + } + + saveFileCacheOnlyFile(context: Context, key: string, value: ArrayBuffer): boolean { + if (this.fileCache !== undefined) { + return FileCache.saveFileCacheOnlyFile(context, key, value) + } + return false + } + + getFileCacheByFile(context: Context, key: string): ArrayBuffer | undefined { + if (this.fileCache !== undefined) { + return FileCache.getFileCacheByFile(context, key) + } + return undefined + } + + async execute(request: ImageKnifeRequest): Promise { + this.dispatcher.enqueue(request) + } + + setMaxRequests(concurrency: number): void { + this.dispatcher.setMaxRequests(concurrency) + } +} \ No newline at end of file diff --git a/library/src/main/ets/ImageKnifeDispatcher.ets b/library/src/main/ets/ImageKnifeDispatcher.ets new file mode 100644 index 0000000..f24864f --- /dev/null +++ b/library/src/main/ets/ImageKnifeDispatcher.ets @@ -0,0 +1,330 @@ +/* + * 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 { ImageKnifeRequest, ImageKnifeRequestState } from './ImageKnifeRequest' +import { DefaultJobQueue } from './utils/DefaultJobQueue' +import { IJobQueue } from './utils/IJobQueue' +import List from '@ohos.util.List'; +import LightWeightMap from '@ohos.util.LightWeightMap'; +import { LogUtil } from './utils/LogUtil'; +import buffer from '@ohos.buffer'; +import common from '@ohos.app.ability.common'; +import { FileCache } from './utils/FileCache'; +import fs from '@ohos.file.fs'; +import { ImageKnife } from './ImageKnife'; +import { ImageKnifeData } from './model/ImageKnifeData'; +import http from '@ohos.net.http'; +import image from '@ohos.multimedia.image'; +import emitter from '@ohos.events.emitter'; +import { Constants } from './utils/Constants'; +import taskpool from '@ohos.taskpool'; +import { FileTypeUtil } from './utils/FileTypeUtil'; +import util from '@ohos.util'; + +export class ImageKnifeDispatcher { + // 最大并发 + private maxRequests: number = 64 + // 排队队列 + private jobQueue: IJobQueue = new DefaultJobQueue() + // 执行中的请求 + executingJobMap: LightWeightMap> = new LightWeightMap(); + + enqueue(request: ImageKnifeRequest): void { + + //1.内存有的话直接渲染 + if (request.showFromMemomry()) { + return + } + + //2.判断是否要排队 + if (this.executingJobMap.length > this.maxRequests) { + this.jobQueue.add(request) + } + this.executeJob(request) + } + + executeJob(request: ImageKnifeRequest): void { + // 加载占位符 + if (request.ImageKnifeOption.placeholderSrc !== undefined) { + this.getAndShowImage(request, request.ImageKnifeOption.placeholderSrc, ImageKnifeRequestSource.PLACE_HOLDER) + } + + // 加载主图 + this.getAndShowImage(request, request.ImageKnifeOption.loadSrc, ImageKnifeRequestSource.SRC) + } + + /** + * 获取和显示图片 + */ + getAndShowImage(currentRequest: ImageKnifeRequest, imageSrc: string | PixelMap | Resource, requestSource: ImageKnifeRequestSource): void { + let key: string = currentRequest.generateKey(imageSrc) + let requestList: List | undefined = this.executingJobMap.get(key) + if (requestList == undefined) { + requestList = new List() + requestList.add({ request: currentRequest, source: requestSource }) + this.executingJobMap.set(key, requestList) + } else { + requestList.add({ request: currentRequest, source: requestSource }) + return + } + + let request: RequestJobRequest = { + context: currentRequest.context, + src: imageSrc, + key: key, + customGetImage: currentRequest.ImageKnifeOption.customGetImage + } + // 启动线程下载和解码主图 + let task = new taskpool.Task(requestJob, request) + // 监听网络回调事件 + if (currentRequest.ImageKnifeOption.progressListener !== undefined && requestSource === ImageKnifeRequestSource.SRC) { + let progressCallBack = currentRequest.ImageKnifeOption.progressListener + emitter.on(Constants.PROGRESS_EMITTER, (data) => { + progressCallBack(data?.data?.value as number) + }); + } + + taskpool.execute(task).then((res: Object) => { + let requestJobResult = res as RequestJobResult + let pixelmap = requestJobResult === undefined ? undefined : requestJobResult.pixelMap + if (pixelmap === undefined) { + if (requestList !== undefined) { + requestList.forEach((requestWithSource: ImageKnifeRequestWithSource) => { + if (requestWithSource.source === ImageKnifeRequestSource.SRC && currentRequest.ImageKnifeOption.errorholderSrc !== undefined) { + this.getAndShowImage(currentRequest, currentRequest.ImageKnifeOption.errorholderSrc, ImageKnifeRequestSource.ERROR_HOLDER) + } + }); + this.executingJobMap.remove(key) + } + else { + LogUtil.log("error: no requestlist need to draw for key = " + key) + } + } + // 保存文件缓存 + if (requestJobResult.bufferSize > 0) { + ImageKnife.getInstance().saveWithoutWriteFile(key, requestJobResult.bufferSize) + } + + let ImageKnifeData: ImageKnifeData = { + source: pixelmap!, + imageWidth: 0, + imageHeight: 0 + } + + // 保存内存缓存 + ImageKnife.getInstance().saveMemoryCache(key, ImageKnifeData) + + if (requestList !== undefined) { + + // todo 判断request生命周期,已销毁的不需要再绘制 + // key相同的request,一起绘制 + requestList.forEach((requestWithSource: ImageKnifeRequestWithSource) => { + // 画主图 + if (requestWithSource.source === ImageKnifeRequestSource.SRC || requestWithSource.source === ImageKnifeRequestSource.ERROR_HOLDER + || (requestWithSource.source === ImageKnifeRequestSource.PLACE_HOLDER && requestWithSource.request.requestState === ImageKnifeRequestState.PROGRESS)) { + + requestWithSource.request.ImageKnifeRequestCallback.showPixelMap(requestWithSource.request.componentVersion , ImageKnifeData.source) + } + + if (requestWithSource.source == ImageKnifeRequestSource.SRC) { + requestWithSource.request.requestState = ImageKnifeRequestState.COMPLETE + } else if (requestWithSource.source == ImageKnifeRequestSource.ERROR_HOLDER) { + requestWithSource.request.requestState = ImageKnifeRequestState.ERROR + } + + }); + + this.executingJobMap.remove(key) + this.dispatchNextJob() + } + else { + LogUtil.log("error: no requestlist need to draw for key = " + key) + } + // }) + + }); + } + + dispatchNextJob() { + let request = this.jobQueue.pop() + if (request !== undefined) { + this.executeJob(request) + } + } + + setMaxRequests(concurrency: number): void { + if (concurrency > 0) { + this.maxRequests = concurrency + } + } +} + +/** + * 通过taskpool 二级缓存,下载/读取本地文件,编解码 + * @param context + * @param src + * @returns + */ +@Concurrent +async function requestJob(request: RequestJobRequest): Promise { + let resBuf: ArrayBuffer | undefined + let bufferSize: number = 0 + + class RequestData { + receiveSize: number = 2000 + totalSize: number = 2000 + } + + // 判断自定义下载 + if (request.customGetImage !== undefined && typeof request.src === 'string' && (request.src.indexOf("http://") == 0 || request.src.indexOf("https://") == 0)) { + // 先从文件缓存获取 + resBuf = FileCache.getFileCacheByFile(request.context, request.key) + if (resBuf === undefined) { + LogUtil.log("customGetImage customGetImage"); + resBuf = await request.customGetImage(request.context, request.src) + // 保存文件缓存 + if (resBuf !== undefined) { + let copyBuf = buffer.concat([buffer.from(resBuf)]).buffer; // IDE有bug,不能直接获取resBuf.byteLength + bufferSize = copyBuf.byteLength + FileCache.saveFileCacheOnlyFile(request.context, request.key, resBuf) + } + } + } + else { + if (typeof request.src === 'string') { + if (request.src.indexOf("http://") == 0 || request.src.indexOf("https://") == 0) { //从网络下载 + // 先从文件缓存获取 + resBuf = FileCache.getFileCacheByFile(request.context, request.key) + if (resBuf === undefined) { + // // 模拟耗时验证 + // let start = (new Date()).getTime(); + // while ((new Date()).getTime() - start < 5000) { + // continue; + // } + let httpRequest = http.createHttp(); + let progress: number = 0 + let promise = httpRequest.requestInStream(request.src, { + method: http.RequestMethod.GET, + connectTimeout: 6000, + readTimeout: 6000, + // header: new Header('application/json') + }); + + httpRequest.on("dataReceive", (data: ArrayBuffer) => { + if (resBuf == undefined) { + resBuf = data + } else { + resBuf = buffer.concat([buffer.from(resBuf), buffer.from(data)]).buffer; + } + }); + + httpRequest.on('dataReceiveProgress', (data: RequestData) => { + // 下载进度 + if (data != undefined && (typeof data.receiveSize == 'number') && (typeof data.totalSize == 'number')) { + let percent = Math.round(((data.receiveSize * 1.0) / (data.totalSize * 1.0)) * 100) + if (progress !== percent) { + progress = percent + emitter.emit(Constants.PROGRESS_EMITTER, { data: { "value": progress } }) + } + } + }) + + await promise.then((data: number) => { + }).catch((err: Error) => { + LogUtil.error("requestInStream ERROR : err = " + JSON.stringify(err)); + }); + + // 保存文件缓存 + if (resBuf !== undefined) { + let copyBuf = buffer.concat([buffer.from(resBuf)]).buffer; // IDE有bug,不能直接获取resBuf.byteLength + bufferSize = copyBuf.byteLength + FileCache.saveFileCacheOnlyFile(request.context, request.key, resBuf) + } + } + else { + LogUtil.log("success get image from filecache for key = " + request.key); + } + } else { //从本地文件获取 + let stat = fs.statSync(request.src); + if (stat.size > 0) { + let file = fs.openSync(request.src, fs.OpenMode.READ_ONLY); + resBuf = new ArrayBuffer(stat.size); + fs.readSync(file.fd, resBuf); + fs.closeSync(file); + } + } + } else if ((request.src as Resource).id !== undefined) { //从资源文件获取 + resBuf = request.context.resourceManager.getMediaContentSync((request.src as Resource).id).buffer as ArrayBuffer + } + } + + + if (resBuf == undefined) { + return undefined + } + + let fileTypeUtil = new FileTypeUtil(); + let typeValue = fileTypeUtil.getFileType(resBuf); + if (typeValue === 'gif' || typeValue === 'webp') { + let base64Help = new util.Base64Helper() + + let base64str = "data:image/" + typeValue + ";base64," + base64Help.encodeToStringSync(new Uint8Array(resBuf)) + return { + pixelMap: base64str, + bufferSize: bufferSize + }; + } + + let imageSource: image.ImageSource = image.createImageSource(resBuf); + let decodingOptions: image.DecodingOptions = { + editable: true, + } + + let resPixelmap: PixelMap | undefined = undefined + await imageSource.createPixelMap(decodingOptions) + .then((pixelmap: PixelMap) => { + resPixelmap = pixelmap + imageSource.release() + }) + + return { + pixelMap: resPixelmap, + bufferSize: bufferSize + }; +} + + +export enum ImageKnifeRequestSource { + SRC, + PLACE_HOLDER, + ERROR_HOLDER +} + + +export interface ImageKnifeRequestWithSource { + request: ImageKnifeRequest + source: ImageKnifeRequestSource +} + +interface RequestJobResult { + pixelMap: PixelMap | string | undefined + bufferSize: number +} + +interface RequestJobRequest { + context: common.UIAbilityContext, + src: string | PixelMap | Resource, + key: string, + customGetImage?: (context: Context, src: string | PixelMap | Resource) => Promise +} diff --git a/library/src/main/ets/ImageKnifeOption.ets b/library/src/main/ets/ImageKnifeOption.ets new file mode 100644 index 0000000..ddae520 --- /dev/null +++ b/library/src/main/ets/ImageKnifeOption.ets @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import taskpool from '@ohos.taskpool'; +import common from '@ohos.app.ability.common' + +@Observed +export class ImageKnifeOption { + // 主图资源 + loadSrc: string | PixelMap | Resource = ""; + // 占位图 + placeholderSrc?: PixelMap | Resource; + // 失败占位图 + errorholderSrc?: PixelMap | Resource; + + objectFit?: ImageFit + + customGetImage?: (context: Context, src: string | PixelMap | Resource) => Promise + + border?: BorderOptions + + priority? : taskpool.Priority = taskpool.Priority.LOW + + context?: common.UIAbilityContext; + + progressListener?: (progress: number)=>void; + + constructor() { + + } +} \ No newline at end of file diff --git a/library/src/main/ets/ImageKnifeRequest.ets b/library/src/main/ets/ImageKnifeRequest.ets new file mode 100644 index 0000000..53a0f1e --- /dev/null +++ b/library/src/main/ets/ImageKnifeRequest.ets @@ -0,0 +1,77 @@ +/* + * 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 { ImageKnifeOption } from './ImageKnifeOption'; +import { ImageKnifeData } from './model/ImageKnifeData'; +import { ImageKnife } from './ImageKnife' +import common from '@ohos.app.ability.common'; +import { SparkMD5 } from './3rd_party/sparkmd5/spark-md5' +import { LogUtil } from './utils/LogUtil' + + +export class ImageKnifeRequest { + requestState: ImageKnifeRequestState = ImageKnifeRequestState.PROGRESS + componentWidth: number = 0 + componentHeight: number = 0 + ImageKnifeOption: ImageKnifeOption + context: common.UIAbilityContext + ImageKnifeRequestCallback: ImageKnifeRequestCallback + componentVersion: number = 0 + + constructor(option: ImageKnifeOption, + uIAbilityContext: common.UIAbilityContext, + width: number, + height: number, + version:number, + ImageKnifeRequestCallback: ImageKnifeRequestCallback) { + this.ImageKnifeOption = option + this.context = uIAbilityContext + this.componentWidth = width + this.componentHeight = height + this.componentVersion = version + this.ImageKnifeRequestCallback = ImageKnifeRequestCallback + } + + showFromMemomry(): boolean { + let memoryCache: ImageKnifeData | undefined = ImageKnife.getInstance() + .loadFromMemoryCache(this.generateKey(this.ImageKnifeOption.loadSrc)) + if (memoryCache !== undefined) { + LogUtil.log("load from memory cache for key = " + this.generateKey(this.ImageKnifeOption.loadSrc)) + // 画主图 + if (this.requestState === ImageKnifeRequestState.PROGRESS) { + this.ImageKnifeRequestCallback?.showPixelMap(this.componentVersion , memoryCache.source) + } + return true + } + return false + } + + // 生成唯一的key + generateKey(key: string | PixelMap | Resource): string { + // todo 补充变换 + return SparkMD5.hashBinary(JSON.stringify(key)) as string + } +} + +export enum ImageKnifeRequestState { + PROGRESS, + COMPLETE, + ERROR, + DESTROY +} + + +export interface ImageKnifeRequestCallback { + showPixelMap: (version: number, pixelMap: PixelMap | string) => void; +} diff --git a/library/src/main/ets/components/3rd_party/upng/UPNG.js b/library/src/main/ets/components/3rd_party/upng/UPNG.js deleted file mode 100644 index acb04a0..0000000 --- a/library/src/main/ets/components/3rd_party/upng/UPNG.js +++ /dev/null @@ -1,1907 +0,0 @@ -/** -* 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.*/ -import pako from 'pako' -const UZIP = null; - -export { - UPNG -} - -var UPNG = {}; - - -UPNG.toRGBA8 = function (out) { - var w = out.width, h = out.height; - if (out.tabs.acTL == null) return [UPNG.toRGBA8.decodeImage(out.data, w, h, out).buffer]; - - var frms = []; - if (out.frames[0].data == null) out.frames[0].data = out.data; - - var len = w * h * 4, img = new Uint8Array(len), empty = new Uint8Array(len), prev = new Uint8Array(len); - for (var i = 0; i < out.frames.length; i++) { - var frm = out.frames[i]; - var fx = frm.rect.x, fy = frm.rect.y, fw = frm.rect.width, fh = frm.rect.height; - var fdata = UPNG.toRGBA8.decodeImage(frm.data, fw, fh, out); - - if (i != 0) for (var j = 0; j < len; j++) prev[j] = img[j]; - - if (frm.blend == 0) UPNG._copyTile(fdata, fw, fh, img, w, h, fx, fy, 0); - else if (frm.blend == 1) UPNG._copyTile(fdata, fw, fh, img, w, h, fx, fy, 1); - - frms.push(img.buffer.slice(0)); - - if (frm.dispose == 0) { - } - else if (frm.dispose == 1) UPNG._copyTile(empty, fw, fh, img, w, h, fx, fy, 0); - else if (frm.dispose == 2) for (var j = 0; j < len; j++) img[j] = prev[j]; - } - return frms; -} -UPNG.toRGBA8.decodeImage = function (data, w, h, out) { - var area = w * h, bpp = UPNG.decode._getBPP(out); - var bpl = Math.ceil(w * bpp / 8); // bytes per line - - var bf = new Uint8Array(area * 4), bf32 = new Uint32Array(bf.buffer); - var ctype = out.ctype, depth = out.depth; - var rs = UPNG._bin.readUshort; - - var time = Date.now(); - - if (ctype == 6) { // RGB + alpha - var qarea = area << 2; - if (depth == 8) for (var i = 0; i < qarea; i += 4) { - bf[i] = data[i]; - bf[i+1] = data[i+1]; - bf[i+2] = data[i+2]; - bf[i+3] = data[i+3]; - } - if (depth == 16) for (var i = 0; i < qarea; i++) { - bf[i] = data[i<<1]; - } - } - else if (ctype == 2) { // RGB - var ts = out.tabs['tRNS']; - if (ts == null) { - if (depth == 8) for (var i = 0; i < area; i++) { - var ti = i * 3; - bf32[i] = (255 << 24) | (data[ti+2] << 16) | (data[ti+1] << 8) | data[ti]; - } - if (depth == 16) for (var i = 0; i < area; i++) { - var ti = i * 6; - bf32[i] = (255 << 24) | (data[ti+4] << 16) | (data[ti+2] << 8) | data[ti]; - } - } - else { - var tr = ts[0], tg = ts[1], tb = ts[2]; - if (depth == 8) for (var i = 0; i < area; i++) { - var qi = i << 2, ti = i * 3; - bf32[i] = (255 << 24) | (data[ti+2] << 16) | (data[ti+1] << 8) | data[ti]; - if (data[ti] == tr && data[ti+1] == tg && data[ti+2] == tb) bf[qi+3] = 0; - } - if (depth == 16) for (var i = 0; i < area; i++) { - var qi = i << 2, ti = i * 6; - bf32[i] = (255 << 24) | (data[ti+4] << 16) | (data[ti+2] << 8) | data[ti]; - if (rs(data, ti) == tr && rs(data, ti + 2) == tg && rs(data, ti + 4) == tb) bf[qi+3] = 0; - } - } - } - else if (ctype == 3) { // palette - var p = out.tabs['PLTE'], ap = out.tabs['tRNS'], tl = ap ? ap.length : 0; - if (depth == 1) for (var y = 0; y < h; y++) { - var s0 = y * bpl, t0 = y * w; - for (var i = 0; i < w; i++) { - var qi = (t0 + i) << 2, j = ((data[s0+(i >> 3)] >> (7 - ((i & 7) << 0))) & 1), cj = 3 * j; - bf[qi] = p[cj]; - bf[qi+1] = p[cj+1]; - bf[qi+2] = p[cj+2]; - bf[qi+3] = (j < tl) ? ap[j] : 255; - } - } - if (depth == 2) for (var y = 0; y < h; y++) { - var s0 = y * bpl, t0 = y * w; - for (var i = 0; i < w; i++) { - var qi = (t0 + i) << 2, j = ((data[s0+(i >> 2)] >> (6 - ((i & 3) << 1))) & 3), cj = 3 * j; - bf[qi] = p[cj]; - bf[qi+1] = p[cj+1]; - bf[qi+2] = p[cj+2]; - bf[qi+3] = (j < tl) ? ap[j] : 255; - } - } - if (depth == 4) for (var y = 0; y < h; y++) { - var s0 = y * bpl, t0 = y * w; - for (var i = 0; i < w; i++) { - var qi = (t0 + i) << 2, j = ((data[s0+(i >> 1)] >> (4 - ((i & 1) << 2))) & 15), cj = 3 * j; - bf[qi] = p[cj]; - bf[qi+1] = p[cj+1]; - bf[qi+2] = p[cj+2]; - bf[qi+3] = (j < tl) ? ap[j] : 255; - } - } - if (depth == 8) for (var i = 0; i < area; i++) { - var qi = i << 2, j = data[i], cj = 3 * j; - bf[qi] = p[cj]; - bf[qi+1] = p[cj+1]; - bf[qi+2] = p[cj+2]; - bf[qi+3] = (j < tl) ? ap[j] : 255; - } - } - else if (ctype == 4) { // gray + alpha - if (depth == 8) for (var i = 0; i < area; i++) { - var qi = i << 2, di = i << 1, gr = data[di]; - bf[qi] = gr; - bf[qi+1] = gr; - bf[qi+2] = gr; - bf[qi+3] = data[di+1]; - } - if (depth == 16) for (var i = 0; i < area; i++) { - var qi = i << 2, di = i << 2, gr = data[di]; - bf[qi] = gr; - bf[qi+1] = gr; - bf[qi+2] = gr; - bf[qi+3] = data[di+2]; - } - } - else if (ctype == 0) { // gray - var tr = out.tabs['tRNS'] ? out.tabs['tRNS'] : -1; - for (var y = 0; y < h; y++) { - var off = y * bpl, to = y * w; - if (depth == 1) for (var x = 0; x < w; x++) { - var gr = 255 * ((data[off+(x >>> 3)] >>> (7 - ((x & 7)))) & 1), al = (gr == tr * 255) ? 0 : 255; - bf32[to+x] = (al << 24) | (gr << 16) | (gr << 8) | gr; - } - else if (depth == 2) for (var x = 0; x < w; x++) { - var gr = 85 * ((data[off+(x >>> 2)] >>> (6 - ((x & 3) << 1))) & 3), al = (gr == tr * 85) ? 0 : 255; - bf32[to+x] = (al << 24) | (gr << 16) | (gr << 8) | gr; - } - else if (depth == 4) for (var x = 0; x < w; x++) { - var gr = 17 * ((data[off+(x >>> 1)] >>> (4 - ((x & 1) << 2))) & 15), al = (gr == tr * 17) ? 0 : 255; - bf32[to+x] = (al << 24) | (gr << 16) | (gr << 8) | gr; - } - else if (depth == 8) for (var x = 0; x < w; x++) { - var gr = data[off+ x], al = (gr == tr) ? 0 : 255; - bf32[to+x] = (al << 24) | (gr << 16) | (gr << 8) | gr; - } - else if (depth == 16) for (var x = 0; x < w; x++) { - var gr = data[off+(x << 1)], al = (rs(data, off + (x << 1)) == tr) ? 0 : 255; - bf32[to+x] = (al << 24) | (gr << 16) | (gr << 8) | gr; - } - } - } - - return bf; -} - - -UPNG.decode = function (buff) { - var data = new Uint8Array(buff), offset = 8, bin = UPNG._bin, rUs = bin.readUshort, rUi = bin.readUint; - var out = { tabs: {}, frames: [] }; - var dd = new Uint8Array(data.length), doff = 0; // put all IDAT data into it - var fd, foff = 0; // frames - - var mgck = [0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]; - for (var i = 0; i < 8; i++) if (data[i] != mgck[i]) throw 'The input is not a PNG file!'; - - while (offset < data.length) { - var len = bin.readUint(data, offset); - offset += 4; - var type = bin.readASCII(data, offset, 4); - offset += 4; - - - if (type == 'IHDR') { - UPNG.decode._IHDR(data, offset, out); - } - else if (type == 'CgBI') { - out.tabs[type] = data.slice(offset, offset + 4); - } - else if (type == 'IDAT') { - for (var i = 0; i < len; i++) dd[doff+i] = data[offset+i]; - doff += len; - } - else if (type == 'acTL') { - out.tabs[type] = { num_frames: rUi(data, offset), num_plays: rUi(data, offset + 4) }; - fd = new Uint8Array(data.length); - } - else if (type == 'fcTL') { - if (foff != 0) { - var fr = out.frames[out.frames.length-1]; - fr.data = UPNG.decode._decompress(out, fd.slice(0, foff), fr.rect.width, fr.rect.height); - foff = 0; - } - var rct = { - x: rUi(data, offset + 12), - y: rUi(data, offset + 16), - width: rUi(data, offset + 4), - height: rUi(data, offset + 8) - }; - var del = rUs(data, offset + 22); - del = rUs(data, offset + 20) / (del == 0 ? 100 : del); - var frm = { rect: rct, delay: Math.round(del * 1000), dispose: data[offset+24], blend: data[offset+25] }; - - out.frames.push(frm); - } - else if (type == 'fdAT') { - for (var i = 0; i < len - 4; i++) fd[foff+i] = data[offset + i+4]; - foff += len - 4; - } - else if (type == 'pHYs') { - out.tabs[type] = [bin.readUint(data, offset), bin.readUint(data, offset + 4), data[offset+8]]; - } - else if (type == 'cHRM') { - out.tabs[type] = []; - for (var i = 0; i < 8; i++) out.tabs[type].push(bin.readUint(data, offset + i * 4)); - } - else if (type == 'tEXt' || type == 'zTXt') { - if (out.tabs[type] == null) out.tabs[type] = {}; - var nz = bin.nextZero(data, offset); - var keyw = bin.readASCII(data, offset, nz - offset); - var text, tl = offset + len - nz - 1; - if (type == 'tEXt') text = bin.readASCII(data, nz + 1, tl); - else { - var bfr = UPNG.decode._inflate(data.slice(nz + 2, nz + 2 + tl)); - text = bin.readUTF8(bfr, 0, bfr.length); - } - out.tabs[type][keyw] = text; - } - else if (type == 'iTXt') { - if (out.tabs[type] == null) out.tabs[type] = {}; - var nz = 0, off = offset; - nz = bin.nextZero(data, off); - var keyw = bin.readASCII(data, off, nz - off); - off = nz + 1; - var cflag = data[off], cmeth = data[off+1]; - off += 2; - nz = bin.nextZero(data, off); - var ltag = bin.readASCII(data, off, nz - off); - off = nz + 1; - nz = bin.nextZero(data, off); - var tkeyw = bin.readUTF8(data, off, nz - off); - off = nz + 1; - var text, tl = len - (off - offset); - if (cflag == 0) text = bin.readUTF8(data, off, tl); - else { - var bfr = UPNG.decode._inflate(data.slice(off, off + tl)); - text = bin.readUTF8(bfr, 0, bfr.length); - } - out.tabs[type][keyw] = text; - } - else if (type == 'PLTE') { - out.tabs[type] = bin.readBytes(data, offset, len); - } - else if (type == 'hIST') { - var pl = out.tabs['PLTE'].length / 3; - out.tabs[type] = []; - for (var i = 0; i < pl; i++) out.tabs[type].push(rUs(data, offset + i * 2)); - } - else if (type == 'tRNS') { - if (out.ctype == 3) out.tabs[type] = bin.readBytes(data, offset, len); - else if (out.ctype == 0) out.tabs[type] = rUs(data, offset); - else if (out.ctype == 2) out.tabs[type] = [rUs(data, offset), rUs(data, offset + 2), rUs(data, offset + 4)]; - - } - else if (type == 'gAMA') out.tabs[type] = bin.readUint(data, offset) / 100000; - else if (type == 'sRGB') out.tabs[type] = data[offset]; - else if (type == 'bKGD') { - if (out.ctype == 0 || out.ctype == 4) out.tabs[type] = [rUs(data, offset)]; - else if (out.ctype == 2 || out.ctype == 6) out.tabs[type] = [rUs(data, offset), rUs(data, offset + 2), rUs(data, offset + 4)]; - else if (out.ctype == 3) out.tabs[type] = data[offset]; - } - else if (type == 'IEND') { - break; - } - - offset += len; - var crc = bin.readUint(data, offset); - offset += 4; - } - if (foff != 0) { - var fr = out.frames[out.frames.length-1]; - fr.data = UPNG.decode._decompress(out, fd.slice(0, foff), fr.rect.width, fr.rect.height); - } - out.data = UPNG.decode._decompress(out, dd, out.width, out.height); - - delete out.compress; - delete out.interlace; - delete out.filter; - return out; -} - -UPNG.decode._decompress = function (out, dd, w, h) { - var time = Date.now(); - var bpp = UPNG.decode._getBPP(out), bpl = Math.ceil(w * bpp / 8), - buff = new Uint8Array((bpl + 1 + out.interlace) * h); - if (out.tabs['CgBI']) dd = UPNG.inflateRaw(dd, buff); - else dd = UPNG.decode._inflate(dd, buff); - - - var time = Date.now(); - if (out.interlace == 0) dd = UPNG.decode._filterZero(dd, out, 0, w, h); - else if (out.interlace == 1) dd = UPNG.decode._readInterlace(dd, out); - - return dd; -} - -UPNG.decode._inflate = function (data, buff) { - var out = UPNG['inflateRaw'](new Uint8Array(data.buffer, 2, data.length - 6), buff); - return out; -} -UPNG.inflateRaw = function(){ - var H = {}; - H.H = {}; - H.H.N = function (N, W) { - var R = Uint8Array, i = 0, m = 0, J = 0, h = 0, Q = 0, X = 0, u = 0, w = 0, d = 0, v, C; - if (N[0] == 3 && N[1] == 0)return W ? W : new R(0); - var V = H.H, n = V.b, A = V.e, l = V.R, M = V.n, I = V.A, e = V.Z, b = V.m, Z = W == null; - if (Z)W = new R(N.length >>> 2 << 5); - while (i == 0) { - i = n(N, d, 1); - m = n(N, d + 1, 2); - d += 3; - if (m == 0) { - if ((d & 7) != 0)d += 8 - (d & 7); - var D = (d >>> 3) + 4, q = N[D-4] | N[D-3] << 8; - if (Z)W = H.H.W(W, w + q); - W.set(new R(N.buffer, N.byteOffset + D, q), w); - d = D + q << 3; - w += q; - continue - } - if (Z)W = H.H.W(W, w + (1 << 17)); - if (m == 1) { - v = b.J; - C = b.h; - X = (1 << 9) - 1; - u = (1 << 5) - 1 - } - if (m == 2) { - J = A(N, d, 5) + 257; - h = A(N, d + 5, 5) + 1; - Q = A(N, d + 10, 4) + 4; - d += 14; - var E = d, j = 1; - for (var c = 0;c < 38; c += 2) { - b.Q[c] = 0; - b.Q[c+1] = 0 - } - for (var c = 0; c < Q; c++) { - var K = A(N, d + c * 3, 3); - b.Q[(b.X[c] << 1)+1] = K; - if (K > j)j = K - } - d += 3 * Q; - M(b.Q, j); - I(b.Q, j, b.u); - v = b.w; - C = b.d; - d = l(b.u, (1 << j) - 1, J + h, N, d, b.v); - var r = V.V(b.v, 0, J, b.C); - X = (1 << r) - 1; - var S = V.V(b.v, J, h, b.D); - u = (1 << S) - 1; - M(b.C, r); - I(b.C, r, v); - M(b.D, S); - I(b.D, S, C) - } - while (!0) { - var T = v[e(N, d)&X]; - d += T & 15; - var p = T >>> 4; - if (p >>> 8 == 0) { - W[w++] = p - } else if (p == 256) { - break - } else { - var z = w + p - 254; - if (p > 264) { - var _ = b.q[p-257]; - z = w + (_ >>> 3) + A(N, d, _ & 7); - d += _ & 7 - } - var $ = C[e(N, d)&u]; - d += $ & 15; - var s = $ >>> 4, Y = b.c[s], a = (Y >>> 4) + n(N, d, Y & 15); - d += Y & 15; - while (w < z) { - W[w] = W[w++-a]; - W[w] = W[w++-a]; - W[w] = W[w++-a]; - W[w] = W[w++-a] - } - w = z - } - } - } - return W.length == w ? W : W.slice(0, w) - }; - H.H.W = function (N, W) { - var R = N.length; - if (W <= R)return N; - var V = new Uint8Array(R << 1); - V.set(N, 0); - return V - }; - H.H.R = function (N, W, R, V, n, A) { - var l = H.H.e, M = H.H.Z, I = 0; - while (I < R) { - var e = N[M(V, n)&W]; - n += e & 15; - var b = e >>> 4; - if (b <= 15) { - A[I] = b; - I++ - } else { - var Z = 0, m = 0; - if (b == 16) { - m = 3 + l(V, n, 2); - n += 2; - Z = A[I-1] - } else if (b == 17) { - m = 3 + l(V, n, 3); - n += 3 - } else if (b == 18) { - m = 11 + l(V, n, 7); - n += 7 - } - var J = I + m; - while (I < J) { - A[I] = Z; - I++ - } - } - } - return n - }; - H.H.V = function (N, W, R, V) { - var n = 0, A = 0, l = V.length >>> 1; - while (A < R) { - var M = N[A+W]; - V[A<<1] = 0; - V[(A << 1)+1] = M; - if (M > n)n = M; - A++ - } - while (A < l) { - V[A<<1] = 0; - V[(A << 1)+1] = 0; - A++ - } - return n - }; - H.H.n = function (N, W) { - var R = H.H.m, V = N.length, n, A, l, M, I, e = R.j; - for (var M = 0;M <= W; M++)e[M] = 0; - for (M = 1; M < V; M += 2)e[N[M]]++; - var b = R.K; - n = 0; - e[0] = 0; - for (A = 1; A <= W; A++) { - n = n + e[A-1] << 1; - b[A] = n - } - for (l = 0; l < V; l += 2) { - I = N[l+1]; - if (I != 0) { - N[l] = b[I]; - b[I]++ - } - } - }; - H.H.A = function (N, W, R) { - var V = N.length, n = H.H.m, A = n.r; - for (var l = 0;l < V; l += 2)if (N[l+1] != 0) { - var M = l >> 1, I = N[l+1], e = M << 4 | I, b = W - I, Z = N[l] << b, m = Z + (1 << b); - while (Z != m) { - var J = A[Z] >>> 15 - W; - R[J] = e; - Z++ - } - } - }; - H.H.l = function (N, W) { - var R = H.H.m.r, V = 15 - W; - for (var n = 0;n < N.length; - n += 2) { - var A = N[n] << W - N[n+1]; - N[n] = R[A] >>> V - } - }; - H.H.M = function (N, W, R) { - R = R << (W & 7); - var V = W >>> 3; - N[V] |= R; - N[V+1] |= R >>> 8 - }; - H.H.I = function (N, W, R) { - R = R << (W & 7); - var V = W >>> 3; - N[V] |= R; - N[V+1] |= R >>> 8; - N[V+2] |= R >>> 16 - }; - H.H.e = function (N, W, R) { - return (N[W>>>3] | N[(W >>> 3)+1] << 8) >>> (W & 7) & (1 << R) - 1 - }; - H.H.b = function (N, W, R) { - return (N[W>>>3] | N[(W >>> 3)+1] << 8 | N[(W >>> 3)+2] << 16) >>> (W & 7) & (1 << R) - 1 - }; - H.H.Z = function (N, W) { - return (N[W>>>3] | N[(W >>> 3)+1] << 8 | N[(W >>> 3)+2] << 16) >>> (W & 7) - }; - H.H.i = function (N, W) { - return (N[W>>>3] | N[(W >>> 3)+1] << 8 | N[(W >>> 3)+2] << 16 | N[(W >>> 3)+3] << 24) >>> (W & 7) - }; - H.H.m = function(){ - var N = Uint16Array, W = Uint32Array; - return { - K: new N(16), - j: new N(16), - X: [16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15], - S: [3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 999, 999, 999], - T: [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 0, 0, 0], - q: new N(32), - p: [1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577, 65535, 65535], - z: [0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 0, 0], - c: new W(32), - J: new N(512), - _: [], - h: new N(32), - $: [], - w: new N(32768), - C: [], - v: [], - d: new N(32768), - D: [], - u: new N(512), - Q: [], - r: new N(1 << 15), - s: new W(286), - Y: new W(30), - a: new W(19), - t: new W(15e3), - k: new N(1 << 16), - g: new N(1 << 15) - } - }(); - (function(){ - var N = H.H.m, W = 1 << 15; - for (var R = 0;R < W; R++) { - var V = R; - V = (V & 2863311530) >>> 1 | (V & 1431655765) << 1; - V = (V & 3435973836) >>> 2 | (V & 858993459) << 2; - V = (V & 4042322160) >>> 4 | (V & 252645135) << 4; - V = (V & 4278255360) >>> 8 | (V & 16711935) << 8; - N.r[R] = (V >>> 16 | V << 16) >>> 17 - } - - function n(A, l, M) { - while (l-- != 0)A.push(0, M) - } - - for (var R = 0;R < 32; R++) { - N.q[R] = N.S[R] << 3 | N.T[R]; - N.c[R] = N.p[R] << 4 | N.z[R] - } - n(N._, 144, 8); - n(N._, 255 - 143, 9); - n(N._, 279 - 255, 7); - n(N._, 287 - 279, 8); - H.H.n(N._, 9); - H.H.A(N._, 9, N.J); - H.H.l(N._, 9); - n(N.$, 32, 5); - H.H.n(N.$, 5); - H.H.A(N.$, 5, N.h); - H.H.l(N.$, 5); - n(N.Q, 19, 0); - n(N.C, 286, 0); - n(N.D, 30, 0); - n(N.v, 320, 0) - }()); - return H.H.N -}() - - -UPNG.decode._readInterlace = function (data, out) { - var w = out.width, h = out.height; - var bpp = UPNG.decode._getBPP(out), cbpp = bpp >> 3, bpl = Math.ceil(w * bpp / 8); - var img = new Uint8Array(h * bpl); - var di = 0; - - var starting_row = [0, 0, 4, 0, 2, 0, 1]; - var starting_col = [0, 4, 0, 2, 0, 1, 0]; - var row_increment = [8, 8, 8, 4, 4, 2, 2]; - var col_increment = [8, 8, 4, 4, 2, 2, 1]; - - var pass = 0; - while (pass < 7) { - var ri = row_increment[pass], ci = col_increment[pass]; - var sw = 0, sh = 0; - var cr = starting_row[pass]; - while (cr < h) { - cr += ri; - sh++; - } - var cc = starting_col[pass]; - while (cc < w) { - cc += ci; - sw++; - } - var bpll = Math.ceil(sw * bpp / 8); - UPNG.decode._filterZero(data, out, di, sw, sh); - - var y = 0, row = starting_row[pass]; - while (row < h) { - var col = starting_col[pass]; - var cdi = (di + y * bpll) << 3; - - while (col < w) { - if (bpp == 1) { - var val = data[cdi>>3]; - val = (val >> (7 - (cdi & 7))) & 1; - img[row * bpl + (col >> 3)] |= (val << (7 - ((col & 7) << 0))); - } - if (bpp == 2) { - var val = data[cdi>>3]; - val = (val >> (6 - (cdi & 7))) & 3; - img[row * bpl + (col >> 2)] |= (val << (6 - ((col & 3) << 1))); - } - if (bpp == 4) { - var val = data[cdi>>3]; - val = (val >> (4 - (cdi & 7))) & 15; - img[row * bpl + (col >> 1)] |= (val << (4 - ((col & 1) << 2))); - } - if (bpp >= 8) { - var ii = row * bpl + col * cbpp; - for (var j = 0; j < cbpp; j++) img[ii+j] = data[(cdi >> 3)+j]; - } - cdi += bpp; - col += ci; - } - y++; - row += ri; - } - if (sw * sh != 0) di += sh * (1 + bpll); - pass = pass + 1; - } - return img; -} - -UPNG.decode._getBPP = function (out) { - var noc = [1, null, 3, 1, 2, null, 4][out.ctype]; - return noc * out.depth; -} - -UPNG.decode._filterZero = function (data, out, off, w, h) { - var bpp = UPNG.decode._getBPP(out), bpl = Math.ceil(w * bpp / 8), paeth = UPNG.decode._paeth; - bpp = Math.ceil(bpp / 8); - - var i, di, type = data[off], x = 0; - - if (type > 1) data[off] = [0, 0, 1][type-2]; - if (type == 3) for (x = bpp; x < bpl; x++) data[x+1] = (data[x+1] + (data[x + 1-bpp] >>> 1)) & 255; - - for (var y = 0; y < h; y++) { - i = off + y * bpl; - di = i + y + 1; - type = data[di-1]; - x = 0; - - if (type == 0) for (; x < bpl; x++) data[i+x] = data[di+x]; - else if (type == 1) { - for (; x < bpp; x++) data[i+x] = data[di+x]; - for (; x < bpl; x++) data[i+x] = (data[di+x] + data[i + x-bpp]); - } - else if (type == 2) { - for (; x < bpl; x++) data[i+x] = (data[di+x] + data[i + x-bpl]); - } - else if (type == 3) { - for (; x < bpp; x++) data[i+x] = (data[di+x] + (data[i + x-bpl] >>> 1)); - for (; x < bpl; x++) data[i+x] = (data[di+x] + ((data[i + x-bpl] + data[i + x-bpp]) >>> 1)); - } - else { - for (; x < bpp; x++) data[i+x] = (data[di+x] + paeth(0, data[i + x-bpl], 0)); - for (; x < bpl; x++) data[i+x] = (data[di+x] + paeth(data[i + x-bpp], data[i + x-bpl], data[i + x - bpp-bpl])); - } - } - return data; -} - -UPNG.decode._paeth = function (a, b, c) { - var p = a + b - c, pa = (p - a), pb = (p - b), pc = (p - c); - if (pa * pa <= pb * pb && pa * pa <= pc * pc) return a; - else if (pb * pb <= pc * pc) return b; - return c; -} - -UPNG.decode._IHDR = function (data, offset, out) { - var bin = UPNG._bin; - out.width = bin.readUint(data, offset); - offset += 4; - out.height = bin.readUint(data, offset); - offset += 4; - out.depth = data[offset]; - offset++; - out.ctype = data[offset]; - offset++; - out.compress = data[offset]; - offset++; - out.filter = data[offset]; - offset++; - out.interlace = data[offset]; - offset++; -} - -UPNG._bin = { - nextZero: function (data, p) { - while (data[p] != 0) p++; - return p; - }, - readUshort: function (buff, p) { - return (buff[p] << 8) | buff[p+1]; - }, - writeUshort: function (buff, p, n) { - buff[p] = (n >> 8) & 255; - buff[p+1] = n & 255; - }, - readUint: function (buff, p) { - return (buff[p] * (256 * 256 * 256)) + ((buff[p+1] << 16) | (buff[p+2] << 8) | buff[p+3]); - }, - writeUint: function (buff, p, n) { - buff[p] = (n >> 24) & 255; - buff[p+1] = (n >> 16) & 255; - buff[p+2] = (n >> 8) & 255; - buff[p+3] = n & 255; - }, - readASCII: function (buff, p, l) { - var s = ''; - for (var i = 0; i < l; i++) s += String.fromCharCode(buff[p+i]); - return s; - }, - writeASCII: function (data, p, s) { - for (var i = 0; i < s.length; i++) data[p+i] = s.charCodeAt(i); - }, - readBytes: function (buff, p, l) { - var arr = []; - for (var i = 0; i < l; i++) arr.push(buff[p+i]); - return arr; - }, - pad: function (n) { - return n.length < 2 ? '0' + n : n; - }, - readUTF8: function (buff, p, l) { - var s = '', ns; - for (var i = 0; i < l; i++) s += '%' + UPNG._bin.pad(buff[p+i].toString(16)); - try { - ns = decodeURIComponent(s); - } - catch (e) { - return UPNG._bin.readASCII(buff, p, l); - } - return ns; - } -} -UPNG._copyTile = function (sb, sw, sh, tb, tw, th, xoff, yoff, mode) { - var w = Math.min(sw, tw), h = Math.min(sh, th); - var si = 0, ti = 0; - for (var y = 0; y < h; y++) - for (var x = 0; x < w; x++) { - if (xoff >= 0 && yoff >= 0) { - si = (y * sw + x) << 2; - ti = ((yoff + y) * tw + xoff + x) << 2; - } - else { - si = ((-yoff + y) * sw - xoff + x) << 2; - ti = (y * tw + x) << 2; - } - - if (mode == 0) { - tb[ti] = sb[si]; - tb[ti+1] = sb[si+1]; - tb[ti+2] = sb[si+2]; - tb[ti+3] = sb[si+3]; - } - else if (mode == 1) { - var fa = sb[si+3] * (1 / 255), fr = sb[si] * fa, fg = sb[si+1] * fa, fb = sb[si+2] * fa; - var ba = tb[ti+3] * (1 / 255), br = tb[ti] * ba, bg = tb[ti+1] * ba, bb = tb[ti+2] * ba; - - var ifa = 1 - fa, oa = fa + ba * ifa, ioa = (oa == 0 ? 0 : 1 / oa); - tb[ti+3] = 255 * oa; - tb[ti+0] = (fr + br * ifa) * ioa; - tb[ti+1] = (fg + bg * ifa) * ioa; - tb[ti+2] = (fb + bb * ifa) * ioa; - } - else if (mode == 2) { // copy only differences, otherwise zero - var fa = sb[si+3], fr = sb[si], fg = sb[si+1], fb = sb[si+2]; - var ba = tb[ti+3], br = tb[ti], bg = tb[ti+1], bb = tb[ti+2]; - if (fa == ba && fr == br && fg == bg && fb == bb) { - tb[ti] = 0; - tb[ti+1] = 0; - tb[ti+2] = 0; - tb[ti+3] = 0; - } - else { - tb[ti] = fr; - tb[ti+1] = fg; - tb[ti+2] = fb; - tb[ti+3] = fa; - } - } - else if (mode == 3) { // check if can be blended - var fa = sb[si+3], fr = sb[si], fg = sb[si+1], fb = sb[si+2]; - var ba = tb[ti+3], br = tb[ti], bg = tb[ti+1], bb = tb[ti+2]; - if (fa == ba && fr == br && fg == bg && fb == bb) continue; - - if (fa < 220 && ba > 20) return false; - } - } - return true; - } - - -UPNG.encode = function (bufs, w, h, ps, dels, tabs, forbidPlte) { - if (ps == null) ps = 0; - if (forbidPlte == null) forbidPlte = false; - - var nimg = UPNG.encode.compress(bufs, w, h, ps, [false, false, false, 0, forbidPlte, false]); - UPNG.encode.compressPNG(nimg, -1); - - return UPNG.encode._main(nimg, w, h, dels, tabs); -} -UPNG.encodeWithString = function (writeString, bufs, w, h, ps, dels, tabs, forbidPlte) { - if (ps == null) ps = 0; - if (forbidPlte == null) forbidPlte = false; - - var nimg = UPNG.encode.compress(bufs, w, h, ps, [false, false, false, 0, forbidPlte, false]); - UPNG.encode.compressPNG(nimg, -1); - - return UPNG.encode._mainWithString(writeString, nimg, w, h, dels, tabs); -} - -UPNG.encodeLL = function (bufs, w, h, cc, ac, depth, dels, tabs) { - var nimg = { ctype: 0 + (cc == 1 ? 0 : 2) + (ac == 0 ? 0 : 4), depth: depth, frames: [] }; - - var time = Date.now(); - var bipp = (cc + ac) * depth, bipl = bipp * w; - for (var i = 0; i < bufs.length; i++) - nimg.frames.push({ - rect: { x: 0, y: 0, width: w, height: h }, - img: new Uint8Array(bufs[i]), - blend: 0, - dispose: 1, - bpp: Math.ceil(bipp / 8), - bpl: Math.ceil(bipl / 8) - }); - - UPNG.encode.compressPNG(nimg, 0, true); - - var out = UPNG.encode._main(nimg, w, h, dels, tabs); - return out; -} - -UPNG.encode._main = function (nimg, w, h, dels, tabs) { - try { - if (tabs == null) tabs = {}; - var crc = UPNG.crc.crc, wUi = UPNG._bin.writeUint, wUs = UPNG._bin.writeUshort, wAs = UPNG._bin.writeASCII; - var offset = 8, anim = nimg.frames.length > 1, pltAlpha = false; - - var leng = 8 + (16 + 5 + 4) /*+ (9+4)*/ - + (anim ? 20 : 0); - if (tabs['sRGB'] != null) leng += 8 + 1 + 4; - if (tabs['pHYs'] != null) leng += 8 + 9 + 4; - if (nimg.ctype == 3) { - var dl = nimg.plte.length; - for (var i = 0; i < dl; i++) if ((nimg.plte[i] >>> 24) != 255) pltAlpha = true; - leng += (8 + dl * 3 + 4) + (pltAlpha ? (8 + dl * 1 + 4) : 0); - } - for (var j = 0; j < nimg.frames.length; j++) { - var fr = nimg.frames[j]; - if (anim) leng += 38; - leng += fr.cimg.length + 12; - if (j != 0) leng += 4; - } - leng += 12; - - var data = new Uint8Array(leng); - var wr = [0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]; - for (var i = 0; i < 8; i++) data[i] = wr[i]; - - wUi(data, offset, 13); - offset += 4; - wAs(data, offset, 'IHDR'); - offset += 4; - wUi(data, offset, w); - offset += 4; - wUi(data, offset, h); - offset += 4; - data[offset] = nimg.depth; - offset++; // depth - data[offset] = nimg.ctype; - offset++; // ctype - data[offset] = 0; - offset++; // compress - data[offset] = 0; - offset++; // filter - data[offset] = 0; - offset++; // interlace - wUi(data, offset, crc(data, offset - 17, 17)); - offset += 4; // crc - - // 13 bytes to say, that it is sRGB - if (tabs['sRGB'] != null) { - wUi(data, offset, 1); - offset += 4; - wAs(data, offset, 'sRGB'); - offset += 4; - data[offset] = tabs['sRGB']; - offset++; - wUi(data, offset, crc(data, offset - 5, 5)); - offset += 4; // crc - } - if (tabs['pHYs'] != null) { - wUi(data, offset, 9); - offset += 4; - wAs(data, offset, 'pHYs'); - offset += 4; - wUi(data, offset, tabs['pHYs'][0]); - offset += 4; - wUi(data, offset, tabs['pHYs'][1]); - offset += 4; - data[offset] = tabs['pHYs'][2]; - offset++; - wUi(data, offset, crc(data, offset - 13, 13)); - offset += 4; // crc - } - - if (anim) { - wUi(data, offset, 8); - offset += 4; - wAs(data, offset, 'acTL'); - offset += 4; - wUi(data, offset, nimg.frames.length); - offset += 4; - wUi(data, offset, tabs['loop'] != null ? tabs['loop'] : 0); - offset += 4; - wUi(data, offset, crc(data, offset - 12, 12)); - offset += 4; // crc - } - - if (nimg.ctype == 3) { - var dl = nimg.plte.length; - wUi(data, offset, dl * 3); - offset += 4; - wAs(data, offset, 'PLTE'); - offset += 4; - for (var i = 0; i < dl; i++) { - var ti = i * 3, c = nimg.plte[i], r = (c) & 255, g = (c >>> 8) & 255, b = (c >>> 16) & 255; - data[offset + ti+0] = r; - data[offset + ti+1] = g; - data[offset + ti+2] = b; - } - offset += dl * 3; - wUi(data, offset, crc(data, offset - dl * 3 - 4, dl * 3 + 4)); - offset += 4; // crc - - if (pltAlpha) { - wUi(data, offset, dl); - offset += 4; - wAs(data, offset, 'tRNS'); - offset += 4; - for (var i = 0; i < dl; i++) data[offset+i] = (nimg.plte[i] >>> 24) & 255; - offset += dl; - wUi(data, offset, crc(data, offset - dl - 4, dl + 4)); - offset += 4; // crc - } - } - - var fi = 0; - for (var j = 0; j < nimg.frames.length; j++) { - var fr = nimg.frames[j]; - if (anim) { - wUi(data, offset, 26); - offset += 4; - wAs(data, offset, 'fcTL'); - offset += 4; - wUi(data, offset, fi++); - offset += 4; - wUi(data, offset, fr.rect.width); - offset += 4; - wUi(data, offset, fr.rect.height); - offset += 4; - wUi(data, offset, fr.rect.x); - offset += 4; - wUi(data, offset, fr.rect.y); - offset += 4; - wUs(data, offset, dels[j]); - offset += 2; - wUs(data, offset, 1000); - offset += 2; - data[offset] = fr.dispose; - offset++; // dispose - data[offset] = fr.blend; - offset++; // blend - wUi(data, offset, crc(data, offset - 30, 30)); - offset += 4; // crc - } - - var imgd = fr.cimg, dl = imgd.length; - wUi(data, offset, dl + (j == 0 ? 0 : 4)); - offset += 4; - var ioff = offset; - wAs(data, offset, (j == 0) ? 'IDAT' : 'fdAT'); - offset += 4; - if (j != 0) { - wUi(data, offset, fi++); - offset += 4; - } - data.set(imgd, offset); - offset += dl; - wUi(data, offset, crc(data, ioff, offset - ioff)); - offset += 4; // crc - } - - wUi(data, offset, 0); - offset += 4; - wAs(data, offset, 'IEND'); - offset += 4; - wUi(data, offset, crc(data, offset - 4, 4)); - offset += 4; // crc - return data.buffer; - } - catch (err) { - } -} -UPNG.encode._mainWithString = function (writeString, nimg, w, h, dels, tabs) { - if (tabs == null) tabs = {}; - var crc = UPNG.crc.crc, wUi = UPNG._bin.writeUint, wUs = UPNG._bin.writeUshort, wAs = UPNG._bin.writeASCII; - var offset = 8, anim = nimg.frames.length > 1, pltAlpha = false; - - var leng = 8 + (16 + 5 + 4) /*+ (9+4)*/ - + (anim ? 20 : 0); - if (tabs['sRGB'] != null) leng += 8 + 1 + 4; - if (tabs['pHYs'] != null) leng += 8 + 9 + 4; - if (nimg.ctype == 3) { - var dl = nimg.plte.length; - for (var i = 0; i < dl; i++) if ((nimg.plte[i] >>> 24) != 255) pltAlpha = true; - leng += (8 + dl * 3 + 4) + (pltAlpha ? (8 + dl * 1 + 4) : 0); - } - for (var j = 0; j < nimg.frames.length; j++) { - var fr = nimg.frames[j]; - if (anim) leng += 38; - leng += fr.cimg.length + 12; - if (j != 0) leng += 4; - } - - // 由于IEND数据块永远是 00 00 00 00 49 45 4E 44 AE 42 60 82 - // 其中 IEND 是 49 45 4E 44 因此CRC码也总是 AE 42 60 82 - - let writeUint8 = UPNG.encode._strToUint8Array(writeString); - - leng += 12 + writeUint8.byteLength; - - - var data = new Uint8Array(leng); - var wr = [0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]; - for (var i = 0; i < 8; i++) data[i] = wr[i]; - - wUi(data, offset, 13); - offset += 4; - wAs(data, offset, 'IHDR'); - offset += 4; - wUi(data, offset, w); - offset += 4; - wUi(data, offset, h); - offset += 4; - data[offset] = nimg.depth; - offset++; // depth - data[offset] = nimg.ctype; - offset++; // ctype - data[offset] = 0; - offset++; // compress - data[offset] = 0; - offset++; // filter - data[offset] = 0; - offset++; // interlace - wUi(data, offset, crc(data, offset - 17, 17)); - offset += 4; // crc - - // 13 bytes to say, that it is sRGB - if (tabs['sRGB'] != null) { - wUi(data, offset, 1); - offset += 4; - wAs(data, offset, 'sRGB'); - offset += 4; - data[offset] = tabs['sRGB']; - offset++; - wUi(data, offset, crc(data, offset - 5, 5)); - offset += 4; // crc - } - if (tabs['pHYs'] != null) { - wUi(data, offset, 9); - offset += 4; - wAs(data, offset, 'pHYs'); - offset += 4; - wUi(data, offset, tabs['pHYs'][0]); - offset += 4; - wUi(data, offset, tabs['pHYs'][1]); - offset += 4; - data[offset] = tabs['pHYs'][2]; - offset++; - wUi(data, offset, crc(data, offset - 13, 13)); - offset += 4; // crc - } - - if (anim) { - wUi(data, offset, 8); - offset += 4; - wAs(data, offset, 'acTL'); - offset += 4; - wUi(data, offset, nimg.frames.length); - offset += 4; - wUi(data, offset, tabs['loop'] != null ? tabs['loop'] : 0); - offset += 4; - wUi(data, offset, crc(data, offset - 12, 12)); - offset += 4; // crc - } - - if (nimg.ctype == 3) { - var dl = nimg.plte.length; - wUi(data, offset, dl * 3); - offset += 4; - wAs(data, offset, 'PLTE'); - offset += 4; - for (var i = 0; i < dl; i++) { - var ti = i * 3, c = nimg.plte[i], r = (c) & 255, g = (c >>> 8) & 255, b = (c >>> 16) & 255; - data[offset + ti+0] = r; - data[offset + ti+1] = g; - data[offset + ti+2] = b; - } - offset += dl * 3; - wUi(data, offset, crc(data, offset - dl * 3 - 4, dl * 3 + 4)); - offset += 4; // crc - - if (pltAlpha) { - wUi(data, offset, dl); - offset += 4; - wAs(data, offset, 'tRNS'); - offset += 4; - for (var i = 0; i < dl; i++) data[offset+i] = (nimg.plte[i] >>> 24) & 255; - offset += dl; - wUi(data, offset, crc(data, offset - dl - 4, dl + 4)); - offset += 4; // crc - } - } - - var fi = 0; - for (var j = 0; j < nimg.frames.length; j++) { - var fr = nimg.frames[j]; - if (anim) { - wUi(data, offset, 26); - offset += 4; - wAs(data, offset, 'fcTL'); - offset += 4; - wUi(data, offset, fi++); - offset += 4; - wUi(data, offset, fr.rect.width); - offset += 4; - wUi(data, offset, fr.rect.height); - offset += 4; - wUi(data, offset, fr.rect.x); - offset += 4; - wUi(data, offset, fr.rect.y); - offset += 4; - wUs(data, offset, dels[j]); - offset += 2; - wUs(data, offset, 1000); - offset += 2; - data[offset] = fr.dispose; - offset++; // dispose - data[offset] = fr.blend; - offset++; // blend - wUi(data, offset, crc(data, offset - 30, 30)); - offset += 4; // crc - } - - var imgd = fr.cimg, dl = imgd.length; - wUi(data, offset, dl + (j == 0 ? 0 : 4)); - offset += 4; - var ioff = offset; - wAs(data, offset, (j == 0) ? 'IDAT' : 'fdAT'); - offset += 4; - if (j != 0) { - wUi(data, offset, fi++); - offset += 4; - } - data.set(imgd, offset); - offset += dl; - wUi(data, offset, crc(data, ioff, offset - ioff)); - offset += 4; // crc - } - - wUi(data, offset, 0); - offset += 4; - - wAs(data, offset, 'IEND'); - offset += 4; - wUi(data, offset, crc(data, offset - (4), 4)); - offset += 4; // crc - wAs(data, offset, writeString); - offset += writeUint8.byteLength; - return data.buffer; -} - -UPNG.encode.compressPNG = function (out, filter, levelZero) { - try { - for (var i = 0; i < out.frames.length; i++) { - var frm = out.frames[i], nw = frm.rect.width, nh = frm.rect.height; - var fdata = new Uint8Array(nh * frm.bpl + nh); - frm.cimg = UPNG.encode._filterZero(frm.img, nh, frm.bpp, frm.bpl, fdata, filter, levelZero); - } - } catch (err) { - } -} - - -UPNG.encode.compress = function (bufs, w, h, ps, prms) // prms: onlyBlend, minBits, forbidPlte -{ - try { - - var onlyBlend = prms[0], evenCrd = prms[1], forbidPrev = prms[2], minBits = prms[3], forbidPlte = prms[4], - dither = prms[5]; - - var ctype = 6, depth = 8, alphaAnd = 255 - - for (var j = 0; j < bufs.length; j++) { // when not quantized, other frames can contain colors, that are not in an initial frame - var img = new Uint8Array(bufs[j]), ilen = img.length; - for (var i = 0; i < ilen; i += 4) alphaAnd &= img[i+3]; - } - var gotAlpha = (alphaAnd != 255); - - var frms = UPNG.encode.framize(bufs, w, h, onlyBlend, evenCrd, forbidPrev); - - var cmap = {}, plte = [], inds = []; - - if (ps != 0) { - var nbufs = []; - for (var i = 0; i < frms.length; i++) nbufs.push(frms[i].img.buffer); - - var abuf = UPNG.encode.concatRGBA(nbufs), qres = UPNG.quantize(abuf, ps); - - for (var i = 0; i < qres.plte.length; i++) plte.push(qres.plte[i].est.rgba); - - var cof = 0; - for (var i = 0; i < frms.length; i++) { - var frm = frms[i], bln = frm.img.length, ind = new Uint8Array(qres.inds.buffer, cof >> 2, bln >> 2); - inds.push(ind); - var bb = new Uint8Array(qres.abuf, cof, bln); - - if (dither) UPNG.encode.dither(frm.img, frm.rect.width, frm.rect.height, plte, bb, ind); - - frm.img.set(bb); - cof += bln; - } - } - else { - // what if ps==0, but there are <=256 colors? we still need to detect, if the palette could be used - for (var j = 0; j < frms.length; j++) { // when not quantized, other frames can contain colors, that are not in an initial frame - var frm = frms[j], img32 = new Uint32Array(frm.img.buffer), nw = frm.rect.width, ilen = img32.length; - var ind = new Uint8Array(ilen); - inds.push(ind); - for (var i = 0; i < ilen; i++) { - var c = img32[i]; - if (i != 0 && c == img32[i- 1]) ind[i] = ind[i-1]; - else if (i > nw && c == img32[i-nw]) ind[i] = ind[i-nw]; - else { - var cmc = cmap[c]; - if (cmc == null) { - cmap[c] = cmc = plte.length; - plte.push(c); - if (plte.length >= 300) break; - } - ind[i] = cmc; - } - } - } - } - - var cc = plte.length; - if (cc <= 256 && forbidPlte == false) { - if (cc <= 2) depth = 1; else if (cc <= 4) depth = 2; else if (cc <= 16) depth = 4; else depth = 8; - depth = Math.max(depth, minBits); - } - - for (var j = 0; j < frms.length; j++) { - var frm = frms[j], nx = frm.rect.x, ny = frm.rect.y, nw = frm.rect.width, nh = frm.rect.height; - var cimg = frm.img, cimg32 = new Uint32Array(cimg.buffer); - var bpl = 4 * nw, bpp = 4; - if (cc <= 256 && forbidPlte == false) { - bpl = Math.ceil(depth * nw / 8); - var nimg = new Uint8Array(bpl * nh); - var inj = inds[j]; - for (var y = 0; y < nh; y++) { - var i = y * bpl, ii = y * nw; - if (depth == 8) for (var x = 0; x < nw; x++) nimg[i+(x)] = (inj[ii+x]); - else if (depth == 4) for (var x = 0; x < nw; x++) nimg[i+(x >> 1)] |= (inj[ii+x] << (4 - (x & 1) * 4)); - else if (depth == 2) for (var x = 0; x < nw; x++) nimg[i+(x >> 2)] |= (inj[ii+x] << (6 - (x & 3) * 2)); - else if (depth == 1) for (var x = 0; x < nw; x++) nimg[i+(x >> 3)] |= (inj[ii+x] << (7 - (x & 7) * 1)); - } - cimg = nimg; - ctype = 3; - bpp = 1; - } - else if (gotAlpha == false && frms.length == 1) { // some next 'reduced' frames may contain alpha for blending - var nimg = new Uint8Array(nw * nh * 3), area = nw * nh; - for (var i = 0; i < area; i++) { - var ti = i * 3, qi = i * 4; - nimg[ti] = cimg[qi]; - nimg[ti+1] = cimg[qi+1]; - nimg[ti+2] = cimg[qi+2]; - } - cimg = nimg; - ctype = 2; - bpp = 3; - bpl = 3 * nw; - } - frm.img = cimg; - frm.bpl = bpl; - frm.bpp = bpp; - } - return { ctype: ctype, depth: depth, plte: plte, frames: frms }; - } catch (err) { - } -} -UPNG.encode.framize = function (bufs, w, h, alwaysBlend, evenCrd, forbidPrev) { - - try { - var frms = []; - for (var j = 0; j < bufs.length; j++) { - var cimg = new Uint8Array(bufs[j]), cimg32 = new Uint32Array(cimg.buffer); - var nimg; - - var nx = 0, ny = 0, nw = w, nh = h, blend = alwaysBlend ? 1 : 0; - if (j != 0) { - var tlim = (forbidPrev || alwaysBlend || j == 1 || frms[j-2].dispose != 0) ? 1 : 2, tstp = 0, - tarea = 1e9; - for (var it = 0; it < tlim; it++) { - var pimg = new Uint8Array(bufs[j - 1-it]), p32 = new Uint32Array(bufs[j - 1-it]); - var mix = w, miy = h, max = -1, may = -1; - for (var y = 0; y < h; y++) for (var x = 0; x < w; x++) { - var i = y * w + x; - if (cimg32[i] != p32[i]) { - if (x < mix) mix = x; - if (x > max) max = x; - if (y < miy) miy = y; - if (y > may) may = y; - } - } - if (max == -1) mix = miy = max = may = 0; - if (evenCrd) { - if ((mix & 1) == 1)mix--; - if ((miy & 1) == 1)miy--; - } - var sarea = (max - mix + 1) * (may - miy + 1); - if (sarea < tarea) { - tarea = sarea; - tstp = it; - nx = mix; - ny = miy; - nw = max - mix + 1; - nh = may - miy + 1; - } - } - - // alwaysBlend: pokud zjistím, že blendit nelze, nastavím předchozímu snímku dispose=1. Zajistím, aby obsahoval můj obdélník. - var pimg = new Uint8Array(bufs[j - 1-tstp]); - if (tstp == 1) frms[j-1].dispose = 2; - - nimg = new Uint8Array(nw * nh * 4); - UPNG._copyTile(pimg, w, h, nimg, nw, nh, -nx, -ny, 0); - - blend = UPNG._copyTile(cimg, w, h, nimg, nw, nh, -nx, -ny, 3) ? 1 : 0; - if (blend == 1) UPNG.encode._prepareDiff(cimg, w, h, nimg, { x: nx, y: ny, width: nw, height: nh }); - else UPNG._copyTile(cimg, w, h, nimg, nw, nh, -nx, -ny, 0); - } - else nimg = cimg.slice(0); // img may be rewritten further ... don't rewrite input - - frms.push({ rect: { x: nx, y: ny, width: nw, height: nh }, img: nimg, blend: blend, dispose: 0 }); - } - - if (alwaysBlend) for (var j = 0; j < frms.length; j++) { - var frm = frms[j]; - if (frm.blend == 1) continue; - var r0 = frm.rect, r1 = frms[j-1].rect - var miX = Math.min(r0.x, r1.x), miY = Math.min(r0.y, r1.y); - var maX = Math.max(r0.x + r0.width, r1.x + r1.width), maY = Math.max(r0.y + r0.height, r1.y + r1.height); - var r = { x: miX, y: miY, width: maX - miX, height: maY - miY }; - - frms[j-1].dispose = 1; - if (j - 1 != 0) - UPNG.encode._updateFrame(bufs, w, h, frms, j - 1, r, evenCrd); - UPNG.encode._updateFrame(bufs, w, h, frms, j, r, evenCrd); - } - var area = 0; - if (bufs.length != 1) for (var i = 0; i < frms.length; i++) { - var frm = frms[i]; - area += frm.rect.width * frm.rect.height; - } - return frms; - } catch (err) { - } -} -UPNG.encode._updateFrame = function (bufs, w, h, frms, i, r, evenCrd) { - var U8 = Uint8Array, U32 = Uint32Array; - var pimg = new U8(bufs[i-1]), pimg32 = new U32(bufs[i-1]), nimg = i + 1 < bufs.length ? new U8(bufs[i+1]) : null; - var cimg = new U8(bufs[i]), cimg32 = new U32(cimg.buffer); - - var mix = w, miy = h, max = -1, may = -1; - for (var y = 0; y < r.height; y++) for (var x = 0; x < r.width; x++) { - var cx = r.x + x, cy = r.y + y; - var j = cy * w + cx, cc = cimg32[j]; - // no need to draw transparency, or to dispose it. Or, if writing the same color and the next one does not need transparency. - if (cc == 0 || (frms[i-1].dispose == 0 && pimg32[j] == cc && (nimg == null || nimg[j * 4+3] != 0)) /**/ - ) { - } - else { - if (cx < mix) mix = cx; - if (cx > max) max = cx; - if (cy < miy) miy = cy; - if (cy > may) may = cy; - } - } - if (max == -1) mix = miy = max = may = 0; - if (evenCrd) { - if ((mix & 1) == 1)mix--; - if ((miy & 1) == 1)miy--; - } - r = { x: mix, y: miy, width: max - mix + 1, height: may - miy + 1 }; - - var fr = frms[i]; - fr.rect = r; - fr.blend = 1; - fr.img = new Uint8Array(r.width * r.height * 4); - if (frms[i-1].dispose == 0) { - UPNG._copyTile(pimg, w, h, fr.img, r.width, r.height, -r.x, -r.y, 0); - UPNG.encode._prepareDiff(cimg, w, h, fr.img, r); - } - else - UPNG._copyTile(cimg, w, h, fr.img, r.width, r.height, -r.x, -r.y, 0); -} -UPNG.encode._prepareDiff = function (cimg, w, h, nimg, rec) { - UPNG._copyTile(cimg, w, h, nimg, rec.width, rec.height, -rec.x, -rec.y, 2); -} - -UPNG.encode._filterZero = function (img, h, bpp, bpl, data, filter, levelZero) { - var fls = [], ftry = [0, 1, 2, 3, 4]; - if (filter != -1) ftry = [filter]; - else if (h * bpl > 500000 || bpp == 1) ftry = [0]; - var opts; - if (levelZero) opts = { level: 0 }; - - - var CMPR = (data.length > 10e6 && UZIP != null) ? UZIP : pako; - - console.log("dodo pako is null ="+(pako == null) + "CMPR['deflate']="+CMPR['deflate']) - - var time = Date.now(); - for (var i = 0; i < ftry.length; i++) { - for (var y = 0; y < h; y++) UPNG.encode._filterLine(data, img, y, bpl, bpp, ftry[i]); - fls.push(CMPR['deflate'](data, opts)); - } - - var ti, tsize = 1e9; - for (var i = 0; i < fls.length; i++) if (fls[i].length < tsize) { - ti = i; - tsize = fls[i].length; - } - return fls[ti]; -} -UPNG.encode._filterLine = function (data, img, y, bpl, bpp, type) { - var i = y * bpl, di = i + y, paeth = UPNG.decode._paeth - data[di] = type; - di++; - - if (type == 0) { - if (bpl < 500) for (var x = 0; x < bpl; x++) data[di+x] = img[i+x]; - else data.set(new Uint8Array(img.buffer, i, bpl), di); - } - else if (type == 1) { - for (var x = 0; x < bpp; x++) data[di+x] = img[i+x]; - for (var x = bpp; x < bpl; x++) data[di+x] = (img[i+x] - img[i + x-bpp] + 256) & 255; - } - else if (y == 0) { - for (var x = 0; x < bpp; x++) data[di+x] = img[i+x]; - - if (type == 2) for (var x = bpp; x < bpl; x++) data[di+x] = img[i+x]; - if (type == 3) for (var x = bpp; x < bpl; x++) data[di+x] = (img[i+x] - (img[i + x-bpp] >> 1) + 256) & 255; - if (type == 4) for (var x = bpp; x < bpl; x++) data[di+x] = (img[i+x] - paeth(img[i + x-bpp], 0, 0) + 256) & 255; - } - else { - if (type == 2) { - for (var x = 0; x < bpl; x++) data[di+x] = (img[i+x] + 256 - img[i + x-bpl]) & 255; - } - if (type == 3) { - for (var x = 0; x < bpp; x++) data[di+x] = (img[i+x] + 256 - (img[i + x-bpl] >> 1)) & 255; - for (var x = bpp; x < bpl; x++) data[di+x] = (img[i+x] + 256 - ((img[i + x-bpl] + img[i + x-bpp]) >> 1)) & 255; - } - if (type == 4) { - for (var x = 0; x < bpp; x++) data[di+x] = (img[i+x] + 256 - paeth(0, img[i + x-bpl], 0)) & 255; - for (var x = bpp; x < bpl; x++) data[di+x] = (img[i+x] + 256 - paeth(img[i + x-bpp], img[i + x-bpl], img[i + x - bpp-bpl])) & 255; - } - } -} - -UPNG.crc = { - table: (function () { - var tab = new Uint32Array(256); - for (var n = 0; n < 256; n++) { - var c = n; - for (var k = 0; k < 8; k++) { - if (c & 1) c = 0xedb88320 ^ (c >>> 1); - else c = c >>> 1; - } - tab[n] = c; - } - return tab; - })(), - update: function (c, buf, off, len) { - for (var i = 0; i < len; i++) c = UPNG.crc.table[(c ^ buf[off+i]) & 0xff] ^ (c >>> 8); - return c; - }, - crc: function (b, o, l) { - return UPNG.crc.update(0xffffffff, b, o, l) ^ 0xffffffff; - } -} - - -UPNG.quantize = function (abuf, ps) { - var sb = new Uint8Array(abuf), tb = sb.slice(0), tb32 = new Uint32Array(tb.buffer); - - var KD = UPNG.quantize.getKDtree(tb, ps); - var root = KD[0], leafs = KD[1]; - - var planeDst = UPNG.quantize.planeDst; - var len = sb.length; - - var inds = new Uint8Array(len >> 2), nd; - if (sb.length < 20e6) // precise, but slow :( - for (var i = 0; i < len; i += 4) { - var r = sb[i] * (1 / 255), g = sb[i+1] * (1 / 255), b = sb[i+2] * (1 / 255), a = sb[i+3] * (1 / 255); - - nd = UPNG.quantize.getNearest(root, r, g, b, a); - inds[i>>2] = nd.ind; - tb32[i>>2] = nd.est.rgba; - } - else - for (var i = 0; i < len; i += 4) { - var r = sb[i] * (1 / 255), g = sb[i+1] * (1 / 255), b = sb[i+2] * (1 / 255), a = sb[i+3] * (1 / 255); - - nd = root; - while (nd.left) nd = (planeDst(nd.est, r, g, b, a) <= 0) ? nd.left : nd.right; - inds[i>>2] = nd.ind; - tb32[i>>2] = nd.est.rgba; - } - return { abuf: tb.buffer, inds: inds, plte: leafs }; -} - -UPNG.quantize.getKDtree = function (nimg, ps, err) { - if (err == null) err = 0.0001; - var nimg32 = new Uint32Array(nimg.buffer); - - var root = { - i0: 0, - i1: nimg.length, - bst: null, - est: null, - tdst: 0, - left: null, - right: null - }; // basic statistic, extra statistic - root.bst = UPNG.quantize.stats(nimg, root.i0, root.i1); - root.est = UPNG.quantize.estats(root.bst); - var leafs = [root]; - - while (leafs.length < ps) { - var maxL = 0, mi = 0; - for (var i = 0; i < leafs.length; i++) if (leafs[i].est.L > maxL) { - maxL = leafs[i].est.L; - mi = i; - } - if (maxL < err) break; - var node = leafs[mi]; - - var s0 = UPNG.quantize.splitPixels(nimg, nimg32, node.i0, node.i1, node.est.e, node.est.eMq255); - var s0wrong = (node.i0 >= s0 || node.i1 <= s0); - if (s0wrong) { - node.est.L = 0; - continue; - } - - var ln = { - i0: node.i0, - i1: s0, - bst: null, - est: null, - tdst: 0, - left: null, - right: null - }; - ln.bst = UPNG.quantize.stats(nimg, ln.i0, ln.i1); - ln.est = UPNG.quantize.estats(ln.bst); - var rn = { - i0: s0, - i1: node.i1, - bst: null, - est: null, - tdst: 0, - left: null, - right: null - }; - rn.bst = { R: [], m: [], N: node.bst.N - ln.bst.N }; - for (var i = 0; i < 16; i++) rn.bst.R[i] = node.bst.R[i] - ln.bst.R[i]; - for (var i = 0; i < 4; i++) rn.bst.m[i] = node.bst.m[i] - ln.bst.m[i]; - rn.est = UPNG.quantize.estats(rn.bst); - - node.left = ln; - node.right = rn; - leafs[mi] = ln; - leafs.push(rn); - } - leafs.sort(function (a, b) { - return b.bst.N - a.bst.N; - }); - for (var i = 0; i < leafs.length; i++) leafs[i].ind = i; - return [root, leafs]; -} - -UPNG.quantize.getNearest = function (nd, r, g, b, a) { - if (nd.left == null) { - nd.tdst = UPNG.quantize.dist(nd.est.q, r, g, b, a); - return nd; - } - var planeDst = UPNG.quantize.planeDst(nd.est, r, g, b, a); - - var node0 = nd.left, node1 = nd.right; - if (planeDst > 0) { - node0 = nd.right; - node1 = nd.left; - } - - var ln = UPNG.quantize.getNearest(node0, r, g, b, a); - if (ln.tdst <= planeDst * planeDst) return ln; - var rn = UPNG.quantize.getNearest(node1, r, g, b, a); - return rn.tdst < ln.tdst ? rn : ln; -} -UPNG.quantize.planeDst = function (est, r, g, b, a) { - var e = est.e; - return e[0] * r + e[1] * g + e[2] * b + e[3] * a - est.eMq; -} -UPNG.quantize.dist = function (q, r, g, b, a) { - var d0 = r - q[0], d1 = g - q[1], d2 = b - q[2], d3 = a - q[3]; - return d0 * d0 + d1 * d1 + d2 * d2 + d3 * d3; -} - -UPNG.quantize.splitPixels = function (nimg, nimg32, i0, i1, e, eMq) { - var vecDot = UPNG.quantize.vecDot; - i1 -= 4; - var shfs = 0; - while (i0 < i1) { - while (vecDot(nimg, i0, e) <= eMq) i0 += 4; - while (vecDot(nimg, i1, e) > eMq) i1 -= 4; - if (i0 >= i1) break; - - var t = nimg32[i0>>2]; - nimg32[i0>>2] = nimg32[i1>>2]; - nimg32[i1>>2] = t; - - i0 += 4; - i1 -= 4; - } - while (vecDot(nimg, i0, e) > eMq) i0 -= 4; - return i0 + 4; -} -UPNG.quantize.vecDot = function (nimg, i, e) { - return nimg[i] * e[0] + nimg[i+1] * e[1] + nimg[i+2] * e[2] + nimg[i+3] * e[3]; -} -UPNG.quantize.stats = function (nimg, i0, i1) { - var R = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; - var m = [0, 0, 0, 0]; - var N = (i1 - i0) >> 2; - for (var i = i0; i < i1; i += 4) { - var r = nimg[i] * (1 / 255), g = nimg[i+1] * (1 / 255), b = nimg[i+2] * (1 / 255), a = nimg[i+3] * (1 / 255); - m[0] += r; - m[1] += g; - m[2] += b; - m[3] += a; - - R[0] += r * r; - R[1] += r * g; - R[2] += r * b; - R[3] += r * a; - R[5] += g * g; - R[6] += g * b; - R[7] += g * a; - R[10] += b * b; - R[11] += b * a; - R[15] += a * a; - } - R[4] = R[1]; - R[8] = R[2]; - R[9] = R[6]; - R[12] = R[3]; - R[13] = R[7]; - R[14] = R[11]; - - return { R: R, m: m, N: N }; -} -UPNG.quantize.estats = function (stats) { - var R = stats.R, m = stats.m, N = stats.N; - - // when all samples are equal, but N is large (millions), the Rj can be non-zero ( 0.0003.... - precission error) - var m0 = m[0], m1 = m[1], m2 = m[2], m3 = m[3], iN = (N == 0 ? 0 : 1 / N); - var Rj = [ - R[0] - m0 * m0 * iN, R[1] - m0 * m1 * iN, R[2] - m0 * m2 * iN, R[3] - m0 * m3 * iN, - R[4] - m1 * m0 * iN, R[5] - m1 * m1 * iN, R[6] - m1 * m2 * iN, R[7] - m1 * m3 * iN, - R[8] - m2 * m0 * iN, R[9] - m2 * m1 * iN, R[10] - m2 * m2 * iN, R[11] - m2 * m3 * iN, - R[12] - m3 * m0 * iN, R[13] - m3 * m1 * iN, R[14] - m3 * m2 * iN, R[15] - m3 * m3 * iN - ]; - - var A = Rj, M = UPNG.M4; - var b = [Math.random(), Math.random(), Math.random(), Math.random()], mi = 0, tmi = 0; - - if (N != 0) - for (var i = 0; i < 16; i++) { - b = M.multVec(A, b); - tmi = Math.sqrt(M.dot(b, b)); - b = M.sml(1 / tmi, b); - if (i != 0 && Math.abs(tmi - mi) < 1e-9) break; - mi = tmi; - } - var q = [m0 * iN, m1 * iN, m2 * iN, m3 * iN]; - var eMq255 = M.dot(M.sml(255, q), b); - - return { - Cov: Rj, - q: q, - e: b, - L: mi, - eMq255: eMq255, - eMq: M.dot(b, q), - rgba: (((Math.round(255 * q[3]) << 24) | (Math.round(255 * q[2]) << 16) | (Math.round(255 * q[1]) << 8) | (Math.round(255 * q[0]) << 0)) >>> 0) - }; -} -UPNG.M4 = { - multVec: function (m, v) { - return [ - m[0] * v[0] + m[1] * v[1] + m[2] * v[2] + m[3] * v[3], - m[4] * v[0] + m[5] * v[1] + m[6] * v[2] + m[7] * v[3], - m[8] * v[0] + m[9] * v[1] + m[10] * v[2] + m[11] * v[3], - m[12] * v[0] + m[13] * v[1] + m[14] * v[2] + m[15] * v[3] - ]; - }, - dot: function (x, y) { - return x[0] * y[0] + x[1] * y[1] + x[2] * y[2] + x[3] * y[3]; - }, - sml: function (a, y) { - return [a * y[0], a * y[1], a * y[2], a * y[3]]; - } -} - -UPNG.encode.concatRGBA = function (bufs) { - var tlen = 0; - for (var i = 0; i < bufs.length; i++) tlen += bufs[i].byteLength; - var nimg = new Uint8Array(tlen), noff = 0; - for (var i = 0; i < bufs.length; i++) { - var img = new Uint8Array(bufs[i]), il = img.length; - for (var j = 0; j < il; j += 4) { - var r = img[j], g = img[j+1], b = img[j+2], a = img[j+3]; - if (a == 0) r = g = b = 0; - nimg[noff+j] = r; - nimg[noff + j+1] = g; - nimg[noff + j+2] = b; - nimg[noff + j+3] = a; - } - noff += il; - } - return nimg.buffer; -} - -UPNG.encode.dither = function (sb, w, h, plte, tb, oind) { - - function addErr(er, tg, ti, f) { - tg[ti] += (er[0] * f) >> 4; - tg[ti+1] += (er[1] * f) >> 4; - tg[ti+2] += (er[2] * f) >> 4; - tg[ti+3] += (er[3] * f) >> 4; - } - - function N(x) { - return Math.max(0, Math.min(255, x)); - } - - function D(a, b) { - var dr = a[0] - b[0], dg = a[1] - b[1], db = a[2] - b[2], da = a[3] - b[3]; - return (dr * dr + dg * dg + db * db + da * da); - } - - - var pc = plte.length, nplt = [], rads = []; - for (var i = 0; i < pc; i++) { - var c = plte[i]; - nplt.push([((c >>> 0) & 255), ((c >>> 8) & 255), ((c >>> 16) & 255), ((c >>> 24) & 255)]); - } - for (var i = 0; i < pc; i++) { - var ne = 0xffffffff, ni = 0; - for (var j = 0; j < pc; j++) { - var ce = D(nplt[i], nplt[j]); - if (j != i && ce < ne) { - ne = ce; - ni = j; - } - } - var hd = Math.sqrt(ne) / 2; - rads[i] = ~~(hd * hd); - } - - var tb32 = new Uint32Array(tb.buffer); - var err = new Int16Array(w * h * 4); - - for (var y = 0; y < h; y++) { - for (var x = 0; x < w; x++) { - var i = (y * w + x) * 4; - - var cc = [N(sb[i] + err[i]), N(sb[i+1] + err[i+1]), N(sb[i+2] + err[i+2]), N(sb[i+3] + err[i+3])]; - - var ni = 0, nd = 0xffffff; - for (var j = 0; j < pc; j++) { - var cd = D(cc, nplt[j]); - if (cd < nd) { - nd = cd; - ni = j; - } - } - - var nc = nplt[ni]; - var er = [cc[0] - nc[0], cc[1] - nc[1], cc[2] - nc[2], cc[3] - nc[3]]; - - if (x != w - 1) addErr(er, err, i + 4, 7); - if (y != h - 1) { - if (x != 0) addErr(er, err, i + 4 * w - 4, 3); - addErr(er, err, i + 4 * w, 5); - if (x != w - 1) addErr(er, err, i + 4 * w + 4, 1); //*/ - } - - oind[i>>2] = ni; - tb32[i>>2] = plte[ni]; - } - } -} - -UPNG.encode._strToUint8Array = function (str) { - - var arr = []; - for (var i = 0, j = str.length; i < j; ++i) { - arr.push(str.charCodeAt(i)); - } - var tmpUint8Array = new Uint8Array(arr); - return tmpUint8Array -} \ No newline at end of file diff --git a/library/src/main/ets/components/ImageKnifeComponent.ets b/library/src/main/ets/components/ImageKnifeComponent.ets new file mode 100644 index 0000000..03fad35 --- /dev/null +++ b/library/src/main/ets/components/ImageKnifeComponent.ets @@ -0,0 +1,143 @@ +/* + * 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 { ImageKnifeOption } from '../ImageKnifeOption'; +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' + +@Component +export struct ImageKnifeComponent { + @Watch('watchImageKnifeOption') @ObjectLink ImageKnifeOption: ImageKnifeOption; + @State pixelMap: PixelMap | string | undefined = undefined + @State adaptiveWidth: Length = '100%' + @State adaptiveHeight: Length = '100%' + private request: ImageKnifeRequest | undefined + private lastWidth: number = 0 + private lastHeight: number = 0 + private currentWidth: number = 0 + private currentHeight: number = 0 + private lastSrc: string | PixelMap | Resource = ""; + private componentVersion: number = 0 + @State keyCanvas: KeyCanvas = { + keyId: util.generateRandomUUID() + } + private listener: inspector.ComponentObserver = inspector.createComponentObserver(this.keyCanvas.keyId) + + aboutToAppear(): void { + this.listener.on("layout", this.onLayoutComplete) + } + + aboutToDisappear(): void { + if (this.request !== undefined) { + this.request.requestState = ImageKnifeRequestState.DESTROY + this.request = undefined + } + this.listener.off("layout", this.onLayoutComplete) + } + + aboutToReuse(params: Record): void { + if (this.request !== undefined) { + this.request.requestState = ImageKnifeRequestState.DESTROY + this.lastWidth = 0 + this.lastHeight = 0 + this.request = undefined + this.lastSrc = "" + this.componentVersion ++ + } + } + + build() { + Image(this.pixelMap) + .objectFit(this.ImageKnifeOption.objectFit === undefined ? ImageFit.Contain : this.ImageKnifeOption.objectFit) + .width(this.adaptiveWidth) + .height(this.adaptiveHeight) + .key(this.keyCanvas.keyId) + .border(this.ImageKnifeOption.border) + } + + watchImageKnifeOption() { + if (this.lastSrc !== this.ImageKnifeOption.loadSrc) { + this.request = undefined + ImageKnife.getInstance().execute(this.getRequest(this.currentWidth, this.currentHeight)) + } + } + + getRequest(width: number, height: number): ImageKnifeRequest { + if (this.request == undefined) { + this.lastSrc = this.ImageKnifeOption.loadSrc + this.request = new ImageKnifeRequest( + this.ImageKnifeOption, + this.ImageKnifeOption.context !== undefined ? this.ImageKnifeOption.context : getContext(this) as common.UIAbilityContext, + width, + height, + this.componentVersion, + { + showPixelMap: async (version: number, pixelMap: PixelMap | string) => { + if (version !== this.componentVersion){ + return //针对reuse场景,不显示历史图片 + } + this.pixelMap = pixelMap + //console.info("KKKKKKKKKKK:11111111" + typeof this.pixelMap) + if (typeof this.pixelMap !== 'string') { + if (this.ImageKnifeOption.objectFit === ImageFit.Auto) { + let info = await this.pixelMap.getImageInfo() + + this.adaptiveWidth = this.currentWidth + this.adaptiveHeight = info.size.height * this.currentWidth / info.size.width + + // if (this.currentWidth / this.currentHeight > info.size.width / info.size.height) { + // this.adaptiveWidth = this.currentWidth + // this.adaptiveHeight = info.size.height * this.currentWidth / this.currentHeight + // } + // else { + // this.adaptiveWidth = info.size.width * this.currentWidth / this.currentHeight + // this.adaptiveHeight = this.currentHeight + // } + } + } else { + //console.info("KKKKKKKKKKK:" + pixelMap) + } + } + }) + } + + return this.request + } + + onLayoutComplete: () => void = (): void => { + let value: componentUtils.ComponentInfo = componentUtils.getRectangleById(this.keyCanvas.keyId); + this.currentWidth = px2vp(value.size.width) + this.currentHeight = px2vp(value.size.height) + if (this.currentWidth <= 0 || this.currentHeight <= 0) { + // 存在宽或者高为0,此次重回无意义,无需进行request请求 + } else { + // 前提:宽高值均有效,值>0. 条件1:当前宽高与上一次宽高不同 条件2:当前是第一次绘制 + if (this.currentHeight != this.lastHeight || this.currentWidth != this.lastWidth) { + this.lastWidth = this.currentWidth + this.lastHeight = this.currentHeight + LogUtil.log("execute request:width=" + this.currentWidth + " height= " + this.currentHeight) + ImageKnife.getInstance().execute(this.getRequest(this.currentWidth, this.currentHeight)) + } + } + } +} + +interface KeyCanvas { + keyId: string +} \ No newline at end of file diff --git a/library/src/main/ets/components/cache/Base64.ets b/library/src/main/ets/components/cache/Base64.ets deleted file mode 100644 index b71b6fe..0000000 --- a/library/src/main/ets/components/cache/Base64.ets +++ /dev/null @@ -1,86 +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. - */ -export class Base64 { - lookup: Uint8Array = new Uint8Array(256) - chars: string = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' - private static sInstance: Base64; - - public static getInstance(): Base64{ - if (!Base64.sInstance) { - Base64.sInstance = new Base64(); - } - return Base64.sInstance; - } - - private constructor() { - console.log("Base64 - constructor init!") - for (let index = 0; index < this.chars.length; index++) { - this.lookup[this.chars.charCodeAt(index)] = index; - } - } - - encode(arraybuffer: ArrayBuffer): string { - let bytes = new Uint8Array(arraybuffer), - len = bytes.length, - base64 = ''; - let i:number = 0 - for (i = 0; i < len; i += 3) { - base64 += this.chars[bytes[i] >> 2]; - base64 += this.chars[((bytes[i] & 3) << 4) | (bytes[i + 1] >> 4)]; - base64 += this.chars[((bytes[i + 1] & 15) << 2) | (bytes[i + 2] >> 6)]; - base64 += this.chars[bytes[i + 2] & 63]; - } - if (len % 3 === 2) { - base64 = base64.substring(0, base64.length - 1) + '='; - } else if (len % 3 === 1) { - base64 = base64.substring(0, base64.length - 2) + '=='; - } - return base64; - } - - decode(base64: string): ArrayBuffer{ - let bufferLength = base64.length * 0.75, - len = base64.length, - p = 0; - let i:number = 0; - let encoded1:number = 0; - let encoded2:number = 0; - let encoded3:number = 0; - let encoded4:number = 0; - - if (base64[base64.length - 1] === '=') { - bufferLength--; - if (base64[base64.length - 2] === '=') { - bufferLength--; - } - } - - const arraybuffer = new ArrayBuffer(bufferLength), - bytes = new Uint8Array(arraybuffer); - - for (i = 0; i < len; i += 4) { - encoded1 = this.lookup[base64.charCodeAt(i)]; - encoded2 = this.lookup[base64.charCodeAt(i + 1)]; - encoded3 = this.lookup[base64.charCodeAt(i + 2)]; - encoded4 = this.lookup[base64.charCodeAt(i + 3)]; - - bytes[p++] = (encoded1 << 2) | (encoded2 >> 4); - bytes[p++] = ((encoded2 & 15) << 4) | (encoded3 >> 2); - bytes[p++] = ((encoded3 & 3) << 6) | (encoded4 & 63); - } - - return arraybuffer; - } -} \ No newline at end of file diff --git a/library/src/main/ets/components/cache/CustomMap.ets b/library/src/main/ets/components/cache/CustomMap.ets deleted file mode 100644 index 0baca69..0000000 --- a/library/src/main/ets/components/cache/CustomMap.ets +++ /dev/null @@ -1,84 +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. - */ -export class CustomMap { - map: Map = new Map() - - // 获取键对应的值 - get(key: K): V | undefined{ - if (key == null) { - throw new Error('key is null,checking the parameter'); - } - return this.map.get(key) - } - - /** - * 是否含有key的缓存 - */ - hasKey(key: K) { - if (key == null) { - throw new Error('key is null,checking the parameter'); - } - return this.map.has(key) - } - - // 添加键值对 - put(key: K, value: V): V | undefined{ - if (key == null || value == null) { - throw new Error('key or value is invalid,checking the parameter'); - } - let pre = this.map.get(key) - if (this.hasKey(key)) { - this.map.delete(key) - } - this.map.set(key, value); - return pre - } - - // 去除键值,(去除键数据中的键名及对应的值) - remove(key: K): boolean { - if (key == null) { - throw new Error('key is null,checking the parameter'); - } - return this.map.delete(key) - } - - /** - * 获取最先存储的数据的key - */ - getFirstKey(): K{ // keys()可以遍历后需要优化put()方法,暂时仅获取index=0的key - return this.map.keys().next().value - } - - // 判断键值元素是否为空 - isEmpty(): boolean{ - return this.map.size == 0; - } - // 获取键值元素大小 - size(): number{ - return this.map.size; - } - // 遍历Map,执行处理函数. 回调函数 function(key,value,index){..} - each(fn: (value: V, key: K, map: Map) => void) { - this.map.forEach(fn) - } - // 清除键值对 - clear() { - this.map.clear() - } - // 遍历key - keys(): IterableIterator{ - return this.map.keys() - } -} \ No newline at end of file diff --git a/library/src/main/ets/components/cache/DiskCacheEntry.ets b/library/src/main/ets/components/cache/DiskCacheEntry.ets deleted file mode 100644 index 959f12f..0000000 --- a/library/src/main/ets/components/cache/DiskCacheEntry.ets +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (C) 2024 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -export class DiskCacheEntry { - // 缓存的key - key: string = '' - - // 缓存文件大小 - length: number = 0 - - constructor(key: string, length?: number) { - this.key = key - this.length = length as number - } - - setKey(key: string) { - this.key = key - } - - getKey(): string { - return this.key - } - - setLength(length: number) { - this.length = length - } - - getLength(): number { - return this.length - } - - toString(): string { - return this.key + ' - ' + this.length - } -} \ No newline at end of file diff --git a/library/src/main/ets/components/cache/DiskLruCache.ets b/library/src/main/ets/components/cache/DiskLruCache.ets deleted file mode 100644 index 1b84789..0000000 --- a/library/src/main/ets/components/cache/DiskLruCache.ets +++ /dev/null @@ -1,496 +0,0 @@ -/* - * Copyright (C) 2024 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import fileio from '@ohos.fileio' -import { CustomMap } from './CustomMap' -import { FileUtils } from './FileUtils' -import { FileReader } from './FileReader' -import { DiskCacheEntry } from './DiskCacheEntry' -import { SparkMD5 } from '../3rd_party/sparkmd5/spark-md5' -import { Context } from '@ohos.abilityAccessCtrl' -import common from '@ohos.app.ability.common' - -export class DiskLruCache { - // 默认缓存数据最大值 - private static readonly DEFAULT_MAX_SIZE: number = 300 * 1024 * 1024 - // 默认缓存文件名 - private static readonly DEFAULT_NAME: string = 'diskLruCache' - // 缓存journal文件名称 - private static readonly journal: string = 'journal' - // 缓存journal备份文件名称 - private static readonly journalTemp: string = 'journal_temp' - // 备份文件save标识符 - private static readonly SAVE: string = 'save' - // 备份文件read标识符 - private static readonly READ: string = 'read' - // 备份文件remove标识符 - private static readonly REMOVE: string = 'remove' - // 缓存文件路径地址 - private path: string = '' - // 缓存journal文件路径 - private journalPath: string = '' - // 缓存journal备份文件路径 - private journalPathTemp: string = '' - // 缓存数据最大值 - private maxSize: number = DiskLruCache.DEFAULT_MAX_SIZE - // 当前缓存数据值 - private size: number = 0 - // 缓存数据集合 - private cacheMap: CustomMap = new CustomMap() - - constructor(path: string, maxSize: number) { - this.path = path - this.maxSize = maxSize - this.journalPath = path + DiskLruCache.journal - this.journalPathTemp = path + DiskLruCache.journalTemp - } - - /** - * 打开context获取的cache路径中的缓存,如果不存在缓存,则创建新缓存 - * - * @param context 上下文 - * @param maxSize 缓存数据最大值,默认值为300M - */ - public static create(context: common.UIAbilityContext, maxSize?: number): DiskLruCache { - if (!!!context) { - throw new Error('DiskLruCache create context is empty, checking the parameter'); - } - if (!!!maxSize) { - maxSize = DiskLruCache.DEFAULT_MAX_SIZE - } - if (maxSize <= 0) { - throw new Error("DiskLruCache create maxSize <= 0, checking the parameter"); - } - - // 使用默认应用在内部存储上的缓存路径,作为存储地址 - let path = context.cacheDir + FileUtils.SEPARATOR + DiskLruCache.DEFAULT_NAME - if (!FileUtils.getInstance().existFolder(path)) { - FileUtils.getInstance().createFolder(path) - } - if (path.endsWith(FileUtils.SEPARATOR)) { - path = path - } else { - path = path + FileUtils.SEPARATOR - } - let journalPath = path + DiskLruCache.journal - let journalPathTemp = path + DiskLruCache.journalTemp - - // 判断日志文件是否存在,如果没有初始化创建 - if (FileUtils.getInstance().exist(journalPath)) { - let stat = fileio.statSync(journalPath) - if (stat.size > 0) { - FileUtils.getInstance().createFile(journalPathTemp) - FileUtils.getInstance().copyFile(journalPath, journalPathTemp) - let diskLruCache: DiskLruCache = new DiskLruCache(path, maxSize) - diskLruCache.readJournal(journalPathTemp) - diskLruCache.resetJournalFile() - return diskLruCache - } else { - return new DiskLruCache(path, maxSize) - } - } else { - FileUtils.getInstance().createFile(journalPath) - return new DiskLruCache(path, maxSize) - } - } - - /** - * 设置disk缓存最大数据值 - * - * @param max 缓存数据最大值 - */ - setMaxSize(max: number) { - if (max <= 0 || max > DiskLruCache.DEFAULT_MAX_SIZE) { - throw new Error('setMaxSize error, checking the parameter'); - } - this.maxSize = max - this.trimToSize() - } - - /** - * 存储disk缓存数据 - * - * @param key 键值 - * @param content 文件内容 - */ - set(key: string, content: ArrayBuffer | string) { - if (!!!key) { - throw new Error('key is null, checking the parameter') - } - let fileSize = 0; - if (content instanceof ArrayBuffer) { - if (content == null || content.byteLength == 0) { - throw new Error('content is null. checking the parameter') - } - fileSize = content.byteLength - } else { - if (!!!content) { - throw new Error('content is null, checking the parameter') - } - fileSize = content.length; - } - if (this.fileSizeMoreThenMaxSize(fileSize)) { - throw new Error('content must be less then DiskLruCache Size, checking the parameter') - return - } - key = SparkMD5.hashBinary(key) - this.size = this.size + fileSize - this.putCacheMap(key, fileSize) - FileUtils.getInstance().writeData(this.journalPath, DiskLruCache.SAVE + ' ' + key + FileReader.LF) - this.trimToSize() - let tempPath = this.path + key - FileUtils.getInstance().writeNewFile(tempPath, content) - } - - /** - * 异步存储disk缓存数据 - * - * @param key 键值 - * @param content 文件内容 - */ - async setAsync(key: string, content: ArrayBuffer | string): Promise { - if (!!!key) { - throw new Error('key is null, checking the parameter') - } - let fileSize = 0; - if (content instanceof ArrayBuffer) { - if (content == null || content.byteLength == 0) { - throw new Error('content is null. checking the parameter') - } - fileSize = content.byteLength - } else { - if (!!!content) { - throw new Error('content is null, checking the parameter') - } - fileSize = content.length; - } - if (this.fileSizeMoreThenMaxSize(fileSize)) { - throw new Error('content must be less then DiskLruCache Size, checking the parameter') - return - } - key = SparkMD5.hashBinary(key) - this.size = this.size + fileSize - this.putCacheMap(key, fileSize) - await FileUtils.getInstance().writeDataAsync(this.journalPath, DiskLruCache.SAVE + ' ' + key + FileReader.LF) - this.trimToSize() - let tempPath = this.path + key - await FileUtils.getInstance().writeNewFileAsync(tempPath, content) - } - - /** - * 获取key缓存数据 - * - * @param key key 键值 - */ - get(key: string): ArrayBuffer | undefined { - if (!!!key) { - throw new Error('key is null,checking the parameter'); - } - key = SparkMD5.hashBinary(key) - let path = this.path + key; - if (FileUtils.getInstance().exist(path)) { - let ab: ArrayBuffer = FileUtils.getInstance().readFile(path) - this.putCacheMap(key, ab.byteLength) - FileUtils.getInstance().writeData(this.journalPath, DiskLruCache.READ + ' ' + key + FileReader.LF) - return ab - } else { - return undefined; - } - } - - /** - * 异步获取key缓存数据 - * - * @param key 键值 - */ - async getAsync(key: string): Promise { - if (!!!key) { - throw new Error('key is null,checking the parameter'); - } - key = SparkMD5.hashBinary(key) - let path = this.path + key; - if (FileUtils.getInstance().exist(path)) { - let ab: ArrayBuffer = await FileUtils.getInstance().readFileAsync(path) - this.putCacheMap(key, ab.byteLength) - await FileUtils.getInstance().writeDataAsync(this.journalPath, DiskLruCache.READ + ' ' + key + FileReader.LF) - return ab - } else { - return undefined; - } - } - - /** - * 获取key缓存数据绝对路径 - * - * @param key 键值 - */ - getFileToPath(key: string): string { - if (!!!key) { - throw new Error('key is null,checking the parameter'); - } - key = SparkMD5.hashBinary(key); - let path = this.path + key; - if (FileUtils.getInstance().exist(path)) { - FileUtils.getInstance().writeData(this.journalPath, DiskLruCache.READ + ' ' + key + FileReader.LF); - return path - } else { - return ""; - } - } - - /** - * 异步获取key缓存数据绝对路径 - * - * @param key 键值 - */ - async getFileToPathAsync(key: string): Promise { - if (!!!key) { - throw new Error('key is null,checking the parameter'); - } - key = SparkMD5.hashBinary(key); - let path = this.path + key; - if (FileUtils.getInstance().exist(path)) { - await FileUtils.getInstance().writeDataAsync(this.journalPath, DiskLruCache.READ + ' ' + key + FileReader.LF); - return path - } else { - return "" - } - } - - /** - * 获取缓存路径 - */ - getPath(): string { - return this.path; - } - - /** - * 删除key缓存数据 - * - * @param key 键值 - */ - deleteCacheDataByKey(key: string): DiskCacheEntry { - if (!!!key) { - throw new Error('key is null,checking the parameter'); - } - key = SparkMD5.hashBinary(key) - let path = this.path + key; - if (FileUtils.getInstance().exist(path)) { - let ab = FileUtils.getInstance().readFile(path) - this.size = this.size - ab.byteLength - this.cacheMap.remove(key) - FileUtils.getInstance().writeData(this.journalPath, DiskLruCache.REMOVE + ' ' + key + FileReader.LF) - FileUtils.getInstance().deleteFile(path) - } - return this.cacheMap.get(key) as DiskCacheEntry; - } - - /** - *遍历当前的磁盘缓存数据 - * - * @param fn 遍历后方法回调 - */ - foreachDiskLruCache(fn: Function) { - this.cacheMap.each(fn()) - } - - /** - * 清除所有disk缓存数据 - */ - cleanCacheData() { - this.cacheMap.each((value, key) => { - FileUtils.getInstance().deleteFile(this.path + key) - }) - FileUtils.getInstance().deleteFile(this.journalPath) - this.cacheMap.clear() - this.size = 0 - } - - getCacheMap() { - return this.cacheMap; - } - - /** - * 返回当前DiskLruCache的size大小 - */ - getSize() { - return this.size; - } - - /** - * 处理journal文件数据 - * - * @param line 日志行字符串 - */ - private dealWithJournal(line: string) { - let filePath = '' - try { - let lineData = line.split(' ') - if (lineData.length > 1) { - if (lineData[0] != DiskLruCache.REMOVE) { - filePath = this.path + lineData[1] - let fileStat = fileio.statSync(filePath) - if (fileStat.isFile() && fileStat.size > 0) { - this.size = this.size + fileStat.size - FileUtils.getInstance().writeData(this.journalPath, line + FileReader.LF) - this.putCacheMap(lineData[1], fileStat.size) - } - } else { - if (this.cacheMap.hasKey(lineData[1])) { - let cacheEntry: DiskCacheEntry = this.cacheMap.get(lineData[1]) as DiskCacheEntry; - this.size = this.size - cacheEntry.getLength() - this.cacheMap.remove(lineData[1]) - } - } - } - } catch (e) { - console.error('DiskLruCache - dealWithJournal e ' + e) - } - } - - /** - * 重置journal文件数据 - */ - private resetJournalFile() { - FileUtils.getInstance().clearFile(this.journalPath) - for (let key of this.cacheMap.keys()) { - FileUtils.getInstance().writeData(this.journalPath, DiskLruCache.SAVE + ' ' + key + FileReader.LF) - } - } - - /** - * 读取journal文件的缓存数据 - * - * @param path 日志缓存文件路径地址 - */ - private readJournal(path: string) { - let fileReader = new FileReader(path) - let line: string = '' - while (!fileReader.isEnd()) { - line = fileReader.readLine() - line = line.replace(FileReader.LF, '').replace(FileReader.CR, '') - this.dealWithJournal(line) - } - fileReader.close() - FileUtils.getInstance().deleteFile(this.journalPathTemp) - this.trimToSize() - } - - /** - * 缓存数据map集合 - * - * @param key 键值 - * @param length 缓存文件大小 - */ - private putCacheMap(key: string, length?: number) { - if (length && length > 0) { - this.cacheMap.put(key, new DiskCacheEntry(key, length)) - } else { - this.cacheMap.put(key, new DiskCacheEntry(key)) - } - } - - /** - * 根据LRU算法删除多余缓存数据 - */ - private trimToSize() { - while (this.size > this.maxSize) { - let tempKey: string = this.cacheMap.getFirstKey() - let fileSize = FileUtils.getInstance().getFileSize(this.path + tempKey) - if (fileSize > 0) { - this.size = this.size - fileSize - } - FileUtils.getInstance().deleteFile(this.path + tempKey) - this.cacheMap.remove(tempKey) - FileUtils.getInstance().writeData(this.journalPath, DiskLruCache.REMOVE + ' ' + tempKey + FileReader.LF) - } - } - - /** - * 图片文件过大 直接超过DiskLruCache上限 - */ - private fileSizeMoreThenMaxSize(fileSize: number): boolean { - if (fileSize > this.maxSize) { - return true; - } - return false; - } - - /** - * 子线程里只写入缓存文件 - * @param context - * @param key - * @param value - */ - static saveFileCacheOnlyFile(path: string, key: string, value: ArrayBuffer): boolean { - // 写文件 - if (!!!key) { - throw new Error('key is null, checking the parameter') - } - key = SparkMD5.hashBinary(key); - FileUtils.getInstance() - .writeData(path + DiskLruCache.journal, DiskLruCache.SAVE + ' ' + key + FileReader.LF); - FileUtils.getInstance().writeNewFile(path + key, value); - return true - } - - /** - * 子线程中,通过文件名,直接查找是否有文件缓存 - * @param context - * @param key - * @returns - */ - static getFileCacheByFile(path: string, key: string): ArrayBuffer | undefined { - // 从文件获取查看是否有缓存 - if (!!!key) { - throw new Error('key is null,checking the parameter'); - } - key = SparkMD5.hashBinary(key) - let filepath = path + key; - if (FileUtils.getInstance().exist(filepath)) { - let ab: ArrayBuffer = FileUtils.getInstance().readFile(filepath) - FileUtils.getInstance().writeData(path + DiskLruCache.journal, DiskLruCache.READ + ' ' + key + FileReader.LF) - return ab - } else { - return undefined; - } - } - - // 添加缓存键值对,但不写文件(用于子线程已经写文件的场景) - setCacheMapAndSize(key: string, content: ArrayBuffer | string): void { - if (!!!key) { - throw new Error('key is null, checking the parameter') - } - let fileSize = 0; - if (content instanceof ArrayBuffer) { - if (content == null || content.byteLength == 0) { - throw new Error('content is null. checking the parameter') - } - fileSize = content.byteLength - } else { - if (!!!content) { - throw new Error('content is null, checking the parameter') - } - fileSize = content.length; - } - if (this.fileSizeMoreThenMaxSize(fileSize)) { - throw new Error('content must be less then DiskLruCache Size, checking the parameter') - return - } - key = SparkMD5.hashBinary(key); - this.size = this.size + fileSize; - this.putCacheMap(key, fileSize); - this.trimToSize(); - } -} \ No newline at end of file diff --git a/library/src/main/ets/components/cache/FileReader.ets b/library/src/main/ets/components/cache/FileReader.ets deleted file mode 100644 index 5c00198..0000000 --- a/library/src/main/ets/components/cache/FileReader.ets +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (C) 2024 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import fs from '@ohos.file.fs'; -import { RequestOption } from '../imageknife/RequestOption'; - -export class FileReader { - // 换行符 - static readonly LF: string = '\n' - // CR符 - static readonly CR: string = '\r' - // 文件大小 - fileLength: number = 0 - // 读取的长度 - length: number = 0 - // 读写stream - stream: fs.Stream - // 缓存buf - buf: ArrayBuffer = new ArrayBuffer(1) - - /** - * 读取文件行 - * - * @param path 文件路径 - */ - constructor(path: string) { - if (!!!path) { - throw new Error('FileReader constructor path is null, checking the parameter') - return; - } - this.stream = fs.createStreamSync(path, 'r+'); - let stat = fs.statSync(path) - this.fileLength = stat.size - } - - /** - * 循环读取文件数据 - */ - readLine(): string { - let line = '' - while (this.stream && this.length < this.fileLength) { - this.stream?.readSync(this.buf, { offset: this.length }) - this.length++ - let temp = String.fromCharCode(...new Uint8Array(this.buf)); - line = line + temp - // check CRLF - if (temp == FileReader.CR) { - // 边界判断 首先拿到下一个字符判断是否是LF 如果是CRLF需要再向后挪一位 - if (this.length < this.fileLength) { - let nextBuf = new ArrayBuffer(1) - this.stream?.readSync(nextBuf, { offset: this.length }) - let nextTemp = String.fromCharCode(...new Uint8Array(nextBuf)); - // 如果是CRLF 需要给当前length+1 向后挪一位 - if (nextTemp == FileReader.LF) { - this.length++ - } - } - // 如果不是CRLF 只有一个CR结尾length不用变 - return line; - } else { - // 判断LF情况 - if (temp == FileReader.LF) { - return line - } - } - } - return line - } - - /** - * 判断文件是否结束 - */ - isEnd() { - return this.fileLength <= 0 || this.length == this.fileLength - } - - /** - * 关闭stream - */ - close() { - this.stream?.closeSync() - } -} \ No newline at end of file diff --git a/library/src/main/ets/components/cache/FileUtils.ets b/library/src/main/ets/components/cache/FileUtils.ets deleted file mode 100644 index 8e9d926..0000000 --- a/library/src/main/ets/components/cache/FileUtils.ets +++ /dev/null @@ -1,414 +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 fs from '@ohos.file.fs'; -import { BusinessError } from '@ohos.base' -export class FileUtils { - static readonly SEPARATOR: string = '/' - base64Str: string = '' - private static sInstance: FileUtils; - - public static getInstance(): FileUtils { - if (!FileUtils.sInstance) { - FileUtils.sInstance = new FileUtils(); - } - return FileUtils.sInstance; - } - - private constructor() { - console.log("FileUtils - FileUtils constructor") - } - - /** - * 新建文件 - * - * @param path 文件绝对路径及文件名 - * @return number 文件句柄id - */ - createFile(path: string): number { - let num = -1; - try { - num = fs.openSync(path, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE).fd - } catch (e) { - console.log("createFile err :" + e) - } - return num; - } - - - /** - * 删除文件 - * @param path 文件绝对路径及文件名 - */ - deleteFile(path: string): void { - try { - let fileExist = fs.accessSync(path); - if (fileExist) { - fs.unlinkSync(path); - } - } catch (err) { - console.log("FileUtils deleteFile Method has error, err msg=" + (err as BusinessError).message + " err code=" + (err as BusinessError).code); - } - } - /** - * 异步删除文件 - * @param path 文件绝对路径及文件名 - */ - deleteFileAsync(path: string): Promise { - return new Promise((resolve,reject)=>{ - fs.access(path).then(fileExist =>{ - if (fileExist) { - fs.unlink(path).then(()=>{ - resolve(); - }).catch( (err:BusinessError)=>{ - reject(err) - }) - } - }).catch((err:BusinessError)=>{ - reject(err); - }) - }) - } - - - - /** - * 同步删除文件目录 必须保证文件夹里面没有文件 - * @param path 待删除目录的绝对路径 - */ - deleteFolderSync(path: string): void { - if (this.existFolder(path)) { - fs.rmdirSync(path); - } - } - - /** - * 异步删除文件目录 必须保证文件夹里面没有文件 - * @param path 待删除目录的绝对路径 - */ - deleteFolderAsync(path: string, deleteComplete:(value: void) => void | PromiseLike, deleteError:(reason: Object) => PromiseLike) { - if (this.existFolder(path)) { - fs.rmdir(path) - .then(deleteComplete).catch(deleteError); - } - } - - /** - * 拷贝文件 - * @param path 文件绝对路径及文件名 - */ - copyFile(oriPath: string, newPath: string) { - fs.copyFileSync(oriPath, newPath); - } - - /** - * 清空已有文件数据 - */ - clearFile(path: string): number { - return fs.openSync(path, fs.OpenMode.TRUNC).fd - } - - /** - * 向path写入content数据,覆盖旧数据 - */ - writeFile(path: string, content: ArrayBuffer | string) { - try { - let fd = fs.openSync(path, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE).fd - fs.truncateSync(fd) - fs.writeSync(fd, content) - fs.fsyncSync(fd) - fs.closeSync(fd) - } catch (e) { - console.log("FileUtils - Failed to writeFile for " + e) - } - } - - /** - * 向path写入数据 - */ - writeData(path: string, content: ArrayBuffer | string) { - try { - let fd = fs.openSync(path, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE).fd - let stat = fs.statSync(path) - console.info("FileUtils - writeData size = " + stat.size + " path=" + path); - fs.writeSync(fd, content, { offset: stat.size }) - fs.closeSync(fd) - } catch (e) { - console.log("FileUtils - Failed to writeData for " + e) - } - } - - /** - * 判断path文件是否存在 - * - * @param path 文件绝对路径 - */ - exist(path: string): boolean { - try { - if (fs.accessSync(path)) { - let stat = fs.statSync(path) - return stat.isFile() - } - } catch (error) { - let err: BusinessError = error as BusinessError; - console.error("accessSync failed with error message: " + err.message + ", error code: " + err.code); - } - return false - } - - /** - * 向path写入数据 - */ - writePic(path: string, picData: ArrayBuffer) { - console.info("FileUtils - writepic 1") - this.createFile(path) - this.writeFile(path, picData) - console.info("FileUtils - writepic 3") - } - - /** - * 获取path的文件大小 - */ - getFileSize(path: string): number { - try { - let stat = fs.statSync(path) - return stat.size - } catch (e) { - console.error("FileUtils - FileUtils getFileSize e " + e) - return -1 - } - } - - /** - * 同步读取路径path的文件 - */ - readFilePic(path: string): ArrayBuffer { - try { - let stat = fs.statSync(path) - let fd = fs.openSync(path, fs.OpenMode.READ_ONLY).fd; - let length = stat.size - let buf = new ArrayBuffer(length); - fs.readSync(fd, buf) - fs.closeSync(fd) - return buf - } catch (e) { - console.log("FileUtils - readFilePicSync " + e) - return new ArrayBuffer(0) - } - } - /** - * 异步读取路径path的文件 - */ - readFilePicAsync(path: string): Promise { - return new Promise((resolve,reject)=>{ - fs.open(path, fs.OpenMode.READ_ONLY).then((file) => { - let stat = fs.statSync(path) - let fd = file.fd; - let length = stat.size; - let buf = new ArrayBuffer(length); - fs.read(fd,buf).then((readLen)=>{ - // 关闭文件 - fs.closeSync(file); - resolve(buf); - }).catch((err:BusinessError)=>{ - reject(err); - }) - }).catch((err:BusinessError)=>{ - reject(err); - }) - - - }) - - } - - - - - /** - * stream式读取 - */ - readStream(path: string): string { - try { - let stat = fs.statSync(path) - let length = stat.size - let buf = new ArrayBuffer(length); - let ss = fs.createStreamSync(path, "r+"); - ss.readSync(buf) - ss.closeSync(); - let u8:Uint8Array = new Uint8Array(buf); - let array:Array = Array.from(u8) - return String.fromCharCode(...array) - } catch (e) { - console.log("FileUtils - readFilePic " + e) - return "" - } - } - - /** - * stream式写入 - */ - writeStream(path: string, tempArray: ArrayBuffer) { - try { - console.error("FileUtils - writeStream =1 ") - this.createFile(path) - console.error("FileUtils - writeStream 2 ") - let ss = fs.createStreamSync(path, "r+"); - console.error("FileUtils - writeStream 3 " + tempArray.byteLength) - let num = ss.writeSync(tempArray, { - encoding: 'utf-8' - }); - console.error("FileUtils - write num = " + num) - ss.flushSync(); - ss.closeSync(); - } catch (e) { - console.log("FileUtils - Failed to writeStream for " + e) - } - } - - /** - * 创建文件夹 - * @param 文件夹绝对路径 - */ - createFolder(path: string) { - // 创建文件夹 - if (!this.existFolder(path)) { - fs.mkdirSync(path) - } - } - - /** - * 判断文件夹是否存在 - * @param 文件夹绝对路径 - */ - existFolder(path: string): boolean { - try { - let stat = fs.statSync(path) - return stat.isDirectory() - } catch (e) { - console.debug("fileutils folder exist error=" + e) - return false - } - } - - /** - * 如果文件夹不存在则创建一个文件夹 然后在其中创建文件 并且将数据写入进文件 - * @param folder 文件夹绝对路径 - * @param file 文件绝对路径 - * @param content 文件内容数据 - */ - createFileProcess(folder: string, file: string, content: ArrayBuffer | string) { - // 创建文件夹 - this.createFolder(folder); - // 创建文件 - this.createFile(file); - // 写入数据 - this.writeFile(file, content) - } - - /** - * string 转 Uint8Array - * @param str 输入String - */ - stringToUint8Array(str:string): Uint8Array { - let arr:Array = new Array(); - for (let i = 0, j = str.length; i < j; ++i) { - arr.push(str.charCodeAt(i)); - } - let tmpUint8Array = new Uint8Array(arr); - return tmpUint8Array - } - - /** - * 异步向path写入数据 - * - * @param path 文件绝对路径 - * @param content 文件内容 - */ - async writeDataAsync(path: string, content: ArrayBuffer | string): Promise { - let fd = (await fs.open(path, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE)).fd - let stat = await fs.stat(path) - await fs.write(fd, content, { offset: stat.size }) - await fs.close(fd) - } - - /** - * 异步拷贝文件 - * - * @param src 文件绝对路径及文件名 - * @param dest 拷贝到对应的路径 - */ - async copyFileAsync(src: string, dest: string): Promise { - await fs.copyFile(src, dest); - } - - /** - * 读取路径path的文件 - * - * @param path 文件绝对路径 - */ - async readFileAsync(path: string): Promise { - let stat = await fs.stat(path); - let fd = (await fs.open(path, fs.OpenMode.READ_WRITE)).fd; - let length = stat.size; - let buf = new ArrayBuffer(length); - await fs.read(fd, buf); - return buf - } - - /** - * 向path写入数据 - * - * @param path 文件绝对路径 - * @param data 文件内容 - */ - async writeNewFileAsync(path: string, data: ArrayBuffer | string): Promise { - let fd = (await fs.open(path, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE)).fd - await fs.truncate(fd) - await fs.write(fd, data) - await fs.fsync(fd) - await fs.close(fd) - } - - - uint8ArrayToBuffer(array: Uint8Array): ArrayBuffer { - return array.buffer.slice(array.byteOffset, array.byteLength + array.byteOffset) - } - - /** - * 向path写入数据 - * - * @param path 文件绝对路径 - * @param data 文件内容 - */ - writeNewFile(path: string, data: ArrayBuffer | string) { - this.createFile(path) - this.writeFile(path, data) - } - - /** - * 读取路径path的文件 - * - * @param path 文件绝对路径 - */ - readFile(path: string): ArrayBuffer { - let fd = fs.openSync(path, fs.OpenMode.READ_WRITE).fd; - let length = fs.statSync(path).size - let buf = new ArrayBuffer(length); - fs.readSync(fd, buf) - return buf - } - -} diff --git a/library/src/main/ets/components/cache/LruCache.ets b/library/src/main/ets/components/cache/LruCache.ets deleted file mode 100644 index ef27540..0000000 --- a/library/src/main/ets/components/cache/LruCache.ets +++ /dev/null @@ -1,143 +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 { CustomMap } from './CustomMap' - -export class LruCache { - maxsize: number = 0 - size: number = 0; - map: CustomMap = new CustomMap(); - - constructor(maxsize: number) { - this.trimToSize(-1) - this.maxsize = maxsize - this.size = 0; - } - - // 添加缓存键值对 - put(key: K, value: V) { - if (key == null || value == null) { - throw new Error('key or value is invalid '); - } - let pre = this.map.get(key) - if (pre == null) { - this.size++ - } - this.entryRemoved(key, pre, value) - this.trimToSize(this.maxsize) - } - - // 移除键为key的缓存 - remove(key: K): V | undefined { - if (key == null) { - throw new Error('key is null,checking the parameter'); - } - let preValue = this.map.get(key) - if (this.map.remove(key)) { - this.size-- - } - return preValue - } - - // 获取键为key的value - get(key: K): V | undefined { - if (key == null) { - throw new Error('key is null,checking the parameter'); - } - let preValue = this.map.get(key) - if (preValue != null) { - this.entryRemoved(key, preValue, preValue) - } - return preValue - } - - // 是否存在key - has(key: K): boolean { - return this.map.hasKey(key); - } - - /* - * 替换或删除对应key键的数据 - * evicted:是否删除 - * key:对应的键值key - * preValue 对应key键的旧value值 - * value 对应key键的新value值 - */ - entryRemoved(key: K, preValue: V | undefined, value: V | undefined) { - if (preValue != null) { - this.map.remove(key) - } - if (value != null) { - this.map.put(key, value) - } - } - - // 移除较少使用的缓存数据 - trimToSize(tempsize: number) { - while (true) { - if (tempsize < 0) { - this.map.clear() - this.size = 0 - break - } - if (this.size <= tempsize || this.map.isEmpty()) { - break - } - let delkey = this.map.getFirstKey() - this.map.remove(delkey) - this.size-- - } - } - - // 缓存数据数量 - sizeLength(): number { - return this.size - } - - // 缓存数据最大值 - maxSize(): number { - return this.maxsize - } - - // 设置缓存数据量最大值 - resize(maxsize: number) { - if (maxsize < 0) { - throw new Error('maxsize <0 & maxsize invalid'); - } - this.maxsize = maxsize - this.trimToSize(maxsize) - } - - // 清除缓存 - evicAll() { - this.trimToSize(-1) - } - - print(): string { - let printResult = ''; - if (this.map.isEmpty()) { - return printResult; - } - - - this.map.each((value, key, index) => { - printResult += 'LruCache:key=' + key + 'value= ' + value; - }) - return printResult; - } - - foreachLruCache(fn: (value: V, key: K, map: Map) => void) { - this.map.each(fn); - } -} \ No newline at end of file diff --git a/library/src/main/ets/components/cache/MemoryLruCache.ets b/library/src/main/ets/components/cache/MemoryLruCache.ets deleted file mode 100644 index 7eeb9f1..0000000 --- a/library/src/main/ets/components/cache/MemoryLruCache.ets +++ /dev/null @@ -1,123 +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 { ImageKnife } from '../imageknife/ImageKnife'; -import { ImageKnifeData } from '../imageknife/ImageKnifeData'; -import { LogUtil } from '../imageknife/utils/LogUtil'; -import { LruCache } from './LruCache'; - -export class MemoryLruCache extends LruCache { - maxMemory: number = 0 - memorySize: number = 0 - - constructor(maxsize: number, maxMemory: number) { - super(maxsize); - this.removeAll(); - this.maxMemory = maxMemory - this.memorySize = 0; - } - - // 添加缓存键值对 - put(key: string, value: ImageKnifeData) { - if (key == null || value == null) { - throw new Error('key or value is invalid '); - } - let pre = this.map.get(key) - if (pre == null ) { - this.size++ - this.addMemorySize(value) - } - this.entryRemoved(key, pre, value); - this.trimToSize(); - } - - // 移除键为key的缓存 - remove(key: string): ImageKnifeData | undefined { - if (key == null) { - throw new Error('key is null,checking the parameter'); - } - let preValue = this.map.get(key) - if (this.map.remove(key)) { - this.size-- - if (preValue != undefined) { - this.removeMemorySize(preValue) - } - } - return preValue - } - - removeAll() { - this.map.clear() - this.size = 0 - this.memorySize = 0; - } - - // 移除较少使用的缓存数据 - trimToSize() { - LogUtil.info("MemoryLruCache maxSize:" + this.maxsize + " maxMemory: " + this.maxMemory) - if (this.maxMemory == 0 || this.maxsize == 0 ){ - return; - } - while (true) { - if (this.size <= this.maxsize && this.memorySize <= this.maxMemory || this.map.isEmpty()) { - break - } - let delkey = this.map.getFirstKey() - let data: ImageKnifeData | undefined = this.map.get(delkey) - this.size-- - if (data != undefined) { - this.removeMemorySize(data) - data.release() - } - this.map.remove(delkey) - } - } - - private removeMemorySize(value: ImageKnifeData): void { - if (value.drawPixelMap != undefined) { - LogUtil.info("MemoryLruCache removeMemorySize---- top drawPixelMap memorySize:" + this.memorySize) - if (value.drawPixelMap.imagePixelMap != undefined) { - this.memorySize -= value.drawPixelMap.imagePixelMap.getPixelBytesNumber(); - } - LogUtil.info("MemoryLruCache removeMemorySize---- end drawPixelMap memorySize:" + this.memorySize) - } - if (value.drawGIFFrame != undefined) { - LogUtil.info("MemoryLruCache removeMemorySize---- top drawGIFFrame memorySize:" + this.memorySize) - if (value.drawGIFFrame != undefined) { - this.memorySize -= value.drawGIFFrame.getGIFFramesBytesNumber(); - } - LogUtil.info("MemoryLruCache removeMemorySize---- end drawGIFFrame memorySize:" + this.memorySize) - } - LogUtil.info("MemoryLruCache removeMemorySize---- end mapSize:" + this.map.size()) - } - - private addMemorySize(value: ImageKnifeData): void { - if (value.drawPixelMap != undefined) { - LogUtil.info("MemoryLruCache addMemorySize---- top drawPixelMap memorySize:" + this.memorySize) - if (value.drawPixelMap.imagePixelMap != undefined) { - this.memorySize += value.drawPixelMap.imagePixelMap.getPixelBytesNumber(); - } - LogUtil.info("MemoryLruCache addMemorySize---- end drawPixelMap memorySize:" + this.memorySize) - } - if (value.drawGIFFrame != undefined) { - LogUtil.info("MemoryLruCache addMemorySize---- top drawGIFFrame memorySize:" + this.memorySize) - if (value.drawGIFFrame != undefined) { - this.memorySize += value.drawGIFFrame.getGIFFramesBytesNumber(); - } - LogUtil.info("MemoryLruCache addMemorySize---- end drawGIFFrame memorySize:" + this.memorySize) - } - LogUtil.info("MemoryLruCache addMemorySize---- end mapSize:" + this.map.size()) - } - -} \ No newline at end of file diff --git a/library/src/main/ets/components/cache/diskstrategy/DataSrc.ets b/library/src/main/ets/components/cache/diskstrategy/DataSrc.ets deleted file mode 100644 index 60ad54b..0000000 --- a/library/src/main/ets/components/cache/diskstrategy/DataSrc.ets +++ /dev/null @@ -1,41 +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. - */ -/** Indicates the origin of some retrieved data. */ - -export enum DataSrc { - - /** - * Indicates data was probably retrieved locally from the device, although it may have been - * obtained through a content provider that may have obtained the data from a remote source. - */ - - LOCAL, - - /** Indicates data was retrieved from a remote source other than the device. */ - - REMOTE, - - /** Indicates data was retrieved unmodified from the on device cache. */ - - DATA_DISK_CACHE, - - /** Indicates data was retrieved from modified content in the on device cache. */ - - RESOURCE_DISK_CACHE, - - /** Indicates data was retrieved from the in memory cache. */ - - MEMORY_CACHE, -} diff --git a/library/src/main/ets/components/cache/diskstrategy/DiskStrategy.ets b/library/src/main/ets/components/cache/diskstrategy/DiskStrategy.ets deleted file mode 100644 index b5b4606..0000000 --- a/library/src/main/ets/components/cache/diskstrategy/DiskStrategy.ets +++ /dev/null @@ -1,31 +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{DataSrc} from "../diskstrategy/DataSrc" -import{EncodeStrategy} from "../diskstrategy/EncodeStrategy" - -export interface DiskStrategy { - - isDataCacheable(dataSource: DataSrc): boolean - - isResourceCacheable(isFromAlternateCacheKey: boolean, dataSource: DataSrc, encodeStrategy: EncodeStrategy): boolean; - - decodeCachedResource(): boolean; - - decodeCachedData(): boolean; - - getName(): string; -} - - diff --git a/library/src/main/ets/components/cache/diskstrategy/EncodeStrategy.ets b/library/src/main/ets/components/cache/diskstrategy/EncodeStrategy.ets deleted file mode 100644 index 780c9ec..0000000 --- a/library/src/main/ets/components/cache/diskstrategy/EncodeStrategy.ets +++ /dev/null @@ -1,33 +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. - */ - - -export enum EncodeStrategy { - - /** - * Writes the original unmodified data for the resource to disk, not include downsampling or - * transformations. - */ - - SOURCE, - - /** Writes the decoded, downsampled and transformed data for the resource to disk. */ - - TRANSFORMED, - - /** Will write no data. */ - - NONE, -} \ No newline at end of file diff --git a/library/src/main/ets/components/cache/diskstrategy/enum/ALL.ets b/library/src/main/ets/components/cache/diskstrategy/enum/ALL.ets deleted file mode 100644 index ca7b950..0000000 --- a/library/src/main/ets/components/cache/diskstrategy/enum/ALL.ets +++ /dev/null @@ -1,42 +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 { DiskStrategy } from '../../diskstrategy/DiskStrategy' -import { DataSrc } from '../../diskstrategy/DataSrc' -import { EncodeStrategy } from '../../diskstrategy/EncodeStrategy' - -export class ALL implements DiskStrategy { - getName(): string{ - return 'ALL'; - } - - isDataCacheable(dataSource: DataSrc): boolean { - return dataSource == DataSrc.REMOTE; - } - - isResourceCacheable( - isFromAlternateCacheKey: boolean, dataSource: DataSrc, encodeStrategy: EncodeStrategy): boolean { - return ((isFromAlternateCacheKey && dataSource == DataSrc.DATA_DISK_CACHE) - || dataSource == DataSrc.LOCAL) - && encodeStrategy == EncodeStrategy.TRANSFORMED; - } - - decodeCachedResource(): boolean { - return true; - } - - decodeCachedData(): boolean{ - return true; - } -} \ No newline at end of file diff --git a/library/src/main/ets/components/cache/diskstrategy/enum/AUTOMATIC.ets b/library/src/main/ets/components/cache/diskstrategy/enum/AUTOMATIC.ets deleted file mode 100644 index a1c4305..0000000 --- a/library/src/main/ets/components/cache/diskstrategy/enum/AUTOMATIC.ets +++ /dev/null @@ -1,42 +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{DiskStrategy} from '../../diskstrategy/DiskStrategy' -import{DataSrc} from '../../diskstrategy/DataSrc' -import{EncodeStrategy} from '../../diskstrategy/EncodeStrategy' - -export class AUTOMATIC implements DiskStrategy { - getName(): string{ - return 'AUTOMATIC'; - } - - isDataCacheable(dataSource: DataSrc): boolean { - return dataSource == DataSrc.REMOTE; - } - - isResourceCacheable( - isFromAlternateCacheKey: boolean, dataSource: DataSrc, encodeStrategy: EncodeStrategy): boolean { - return ((isFromAlternateCacheKey && dataSource == DataSrc.DATA_DISK_CACHE) - || dataSource == DataSrc.LOCAL) - && encodeStrategy == EncodeStrategy.TRANSFORMED; - } - - decodeCachedResource(): boolean { - return true; - } - - decodeCachedData(): boolean{ - return true; - } -} \ No newline at end of file diff --git a/library/src/main/ets/components/cache/diskstrategy/enum/DATA.ets b/library/src/main/ets/components/cache/diskstrategy/enum/DATA.ets deleted file mode 100644 index 9e86616..0000000 --- a/library/src/main/ets/components/cache/diskstrategy/enum/DATA.ets +++ /dev/null @@ -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{DiskStrategy} from '../../diskstrategy/DiskStrategy' -import{DataSrc} from '../../diskstrategy/DataSrc' -import{EncodeStrategy} from '../../diskstrategy/EncodeStrategy' - -export class DATA implements DiskStrategy { - getName(): string{ - return 'DATA'; - } - - isDataCacheable(dataSource: DataSrc): boolean { - return dataSource != DataSrc.DATA_DISK_CACHE && dataSource != DataSrc.MEMORY_CACHE; - } - - isResourceCacheable( - isFromAlternateCacheKey: boolean, dataSource: DataSrc, encodeStrategy: EncodeStrategy): boolean { - return false; - } - - decodeCachedResource(): boolean { - return false; - } - - decodeCachedData(): boolean{ - return true; - } -} \ No newline at end of file diff --git a/library/src/main/ets/components/cache/diskstrategy/enum/NONE.ets b/library/src/main/ets/components/cache/diskstrategy/enum/NONE.ets deleted file mode 100644 index 25e6757..0000000 --- a/library/src/main/ets/components/cache/diskstrategy/enum/NONE.ets +++ /dev/null @@ -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{DiskStrategy} from '../../diskstrategy/DiskStrategy' -import{DataSrc} from '../../diskstrategy/DataSrc' -import{EncodeStrategy} from '../../diskstrategy/EncodeStrategy' - -export class NONE implements DiskStrategy { - getName(): string{ - return 'NONE'; - } - - isDataCacheable(dataSource: DataSrc): boolean { - return false; - } - - isResourceCacheable( - isFromAlternateCacheKey: boolean, dataSource: DataSrc, encodeStrategy: EncodeStrategy): boolean { - return false; - } - - decodeCachedResource(): boolean { - return false; - } - - decodeCachedData(): boolean{ - return false; - } -} \ No newline at end of file diff --git a/library/src/main/ets/components/cache/diskstrategy/enum/RESOURCE.ets b/library/src/main/ets/components/cache/diskstrategy/enum/RESOURCE.ets deleted file mode 100644 index 928a029..0000000 --- a/library/src/main/ets/components/cache/diskstrategy/enum/RESOURCE.ets +++ /dev/null @@ -1,41 +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{DiskStrategy} from '../../diskstrategy/DiskStrategy' -import{DataSrc} from '../../diskstrategy/DataSrc' -import{EncodeStrategy} from '../../diskstrategy/EncodeStrategy' - -export class RESOURCE implements DiskStrategy { - getName(): string{ - return 'RESOURCE'; - } - - isDataCacheable(dataSource: DataSrc): boolean { - return false; - } - - isResourceCacheable( - isFromAlternateCacheKey: boolean, dataSource: DataSrc, encodeStrategy: EncodeStrategy): boolean { - return dataSource != DataSrc.RESOURCE_DISK_CACHE - && dataSource != DataSrc.MEMORY_CACHE; - } - - decodeCachedResource(): boolean { - return true; - } - - decodeCachedData(): boolean{ - return false; - } -} \ No newline at end of file diff --git a/library/src/main/ets/components/cache/key/EngineKey.ets b/library/src/main/ets/components/cache/key/EngineKey.ets deleted file mode 100644 index a8d34bc..0000000 --- a/library/src/main/ets/components/cache/key/EngineKey.ets +++ /dev/null @@ -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 { Key } from "../key/Key" -import { RequestOption } from '../../imageknife/RequestOption' -import { BaseTransform } from '../../imageknife/transform/BaseTransform' -import { ObjectKey } from '../../imageknife/ObjectKey'; - -export class EngineKey implements Key { - // 内存缓存 缓存生成规则:是否会影响图片内容,不影响则通用(strategy onlyRetrieveFromCache isCacheable)为通用项目 - // 生成规则 加载数据原 各类参数(排除监听 排除 占位图 失败占位图) - public static generateMemoryCacheKey(loadSrc: string, size: string, transformed: string, dontAnimate: boolean,signature?: ObjectKey, redefine?: (loadSrc: string) => string, otherInfo?: string): string { - - if (redefine) { - loadSrc = redefine(loadSrc); - } - - let key = "loadSrc=" + loadSrc + ";" + - "size=" + size + ";" + - "transformations=" + transformed + ";" + - "dontAnimateFlag=" + dontAnimate + ";" - if (signature) { - key += "signature=" + signature.getKey() + ";" - } - if (otherInfo) { - key += otherInfo; - } - return key; - } - - // 磁盘缓存 缓存生成规则:是否会影响图片内容,不影响则通用(strategy onlyRetrieveFromCache isCacheable)为通用项目 - // 生成规则 加载数据原 各类参数(排除监听 排除 占位图 失败占位图) - public static generateTransformedDiskCacheKey(loadSrc: string, size: string, transformed: string, dontAnimate: boolean, signature?: ObjectKey, redefine?: (loadSrc: string) => string, otherInfo?: string): string { - if (redefine) { - loadSrc = redefine(loadSrc); - } - let key = "loadSrc=" + loadSrc + ";" + - "size=" + size + ";" + - "transformations=" + transformed + ";" + - "dontAnimateFlag=" + dontAnimate + ";" - if (signature) { - key += "signature=" + signature.getKey() + ";" - } - if (otherInfo) { - key += otherInfo; - } - return key; - } - - // 磁盘缓存 - // 生成网络加载数据 原始数据存于磁盘的key - public static generateOriginalDiskCacheKey(loadSrc: string,signature?: ObjectKey, redefine?: (loadSrc: string) => string, otherInfo?: string): string { - if (redefine) { - loadSrc = redefine(loadSrc); - } - let key = "loadSrc=" + loadSrc + ";" - if (signature) { - key += "signature=" + signature.getKey() + ";" - } - if (otherInfo) { - key += otherInfo; - } - return key; - } - - updateDiskCacheKey(info: Object) { - - } -} diff --git a/library/src/main/ets/components/cache/key/EngineKeyFactories.ets b/library/src/main/ets/components/cache/key/EngineKeyFactories.ets deleted file mode 100644 index 65cfee2..0000000 --- a/library/src/main/ets/components/cache/key/EngineKeyFactories.ets +++ /dev/null @@ -1,53 +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 {EngineKey} from '../key/EngineKey' -import {EngineKeyInterface} from '../key/EngineKeyInterface' -import {RequestOption} from '../../imageknife/RequestOption' -import { ObjectKey } from '../../imageknife/ObjectKey'; - -export class EngineKeyFactories implements EngineKeyInterface { - // 生成内存缓存 - generateMemoryCacheKey(loadSrc:string,size:string,transformed:string,dontAnimate:boolean,signature: ObjectKey) { - return EngineKey.generateMemoryCacheKey(loadSrc,size,transformed,dontAnimate); - } - // 生成原图变换后的图片的磁盘缓存 - generateTransformedDiskCacheKey(loadSrc:string,size:string,transformed:string,dontAnimate:boolean,signature: ObjectKey) { - return EngineKey.generateTransformedDiskCacheKey(loadSrc,size,transformed,dontAnimate); - } - // 生成原图的磁盘缓存 - generateOriginalDiskCacheKey(loadSrc:string,signature: ObjectKey) { - return EngineKey.generateOriginalDiskCacheKey(loadSrc); - } - - public static createMemoryCacheKey(loadSrc:string,size:string,transformed:string,dontAnimate:boolean,signature: ObjectKey, redefineUrl?:(loadSrc:string)=>string, addOtherInfo?:string):string{ - return EngineKey.generateMemoryCacheKey(loadSrc,size,transformed,dontAnimate,signature,redefineUrl,addOtherInfo); - } - - - public static createTransformedDiskCacheKey(loadSrc:string,size:string,transformed:string,dontAnimate:boolean,signature: ObjectKey, redefineUrl?:(loadSrc:string)=>string, addOtherInfo?:string):string { - return EngineKey.generateTransformedDiskCacheKey(loadSrc,size,transformed,dontAnimate,signature,redefineUrl,addOtherInfo); - } - - public static createOriginalDiskCacheKey(loadSrc:string,signature: ObjectKey, redefineUrl?:(loadSrc:string)=>string, addOtherInfo?:string):string { - return EngineKey.generateOriginalDiskCacheKey(loadSrc,signature,redefineUrl,addOtherInfo); - } - - - - -} - - - diff --git a/library/src/main/ets/components/cache/key/EngineKeyInterface.ets b/library/src/main/ets/components/cache/key/EngineKeyInterface.ets deleted file mode 100644 index 90985a0..0000000 --- a/library/src/main/ets/components/cache/key/EngineKeyInterface.ets +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (C) 2023 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 { ObjectKey } from '../../imageknife/ObjectKey' -import { RequestOption } from '../../imageknife/RequestOption' - -export interface EngineKeyInterface { - // 生成内存缓存 - generateMemoryCacheKey(loadSrc: string, size: string, transformed: string, dontAnimate: boolean, signature: ObjectKey | undefined): string - // 生成原图变换后的图片的磁盘缓存 - generateTransformedDiskCacheKey(loadSrc: string, size: string, transformed: string, dontAnimate: boolean, signature: ObjectKey | undefined): string - // 生成原图的磁盘缓存 - generateOriginalDiskCacheKey(loadSrc: string, signature: ObjectKey | undefined): string -} - - - diff --git a/library/src/main/ets/components/cache/key/Key.ets b/library/src/main/ets/components/cache/key/Key.ets deleted file mode 100644 index 58b6adc..0000000 --- a/library/src/main/ets/components/cache/key/Key.ets +++ /dev/null @@ -1,26 +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. - */ -export interface Key { - - /** - * Adds all uniquely identifying information to the given digest. - * - *

Note - Using {@link MessageDigest#reset()} inside of this method will result - * in undefined behavior. - * @param messageDigest - */ - updateDiskCacheKey(info: Object):void; - -} \ No newline at end of file diff --git a/library/src/main/ets/components/imageknife/ImageKnife.ets b/library/src/main/ets/components/imageknife/ImageKnife.ets deleted file mode 100644 index 30eb5be..0000000 --- a/library/src/main/ets/components/imageknife/ImageKnife.ets +++ /dev/null @@ -1,842 +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 { DiskLruCache } from "../cache/DiskLruCache" -import { EngineKeyFactories } from "../cache/key/EngineKeyFactories" -import { EngineKeyInterface } from "../cache/key/EngineKeyInterface" -import { RequestOption, Size } 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/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, ImageKnifeType } from '../imageknife/ImageKnifeData' -import { ImageKnifeGlobal } from '../imageknife/ImageKnifeGlobal' -import image from "@ohos.multimedia.image" -import { CompressBuilder } from "../imageknife/compress/CompressBuilder" -import { IDrawLifeCycle } from '../imageknife/interface/IDrawLifeCycle' -import { LogUtil } from '../imageknife/utils/LogUtil' -import { EasyLinkedHashMap } from './utils/base/EasyLinkedHashMap' -import { MethodMutex } from './utils/base/MethodMutex' -import worker from '@ohos.worker' -import common from '@ohos.app.ability.common' -import { MemoryLruCache } from '../cache/MemoryLruCache' -import { BusinessError } from '@ohos.base' -import taskpool from '@ohos.taskpool' -import { GIFFrame } from './utils/gif/GIFFrame' -import emitter from '@ohos.events.emitter'; - -import { MemoryCacheProxy } from './requestmanage/MemoryCacheProxy' -import { ObjectKey } from './ObjectKey' -import { TaskParams } from './TaskParams' -import { Constants } from './constants/Constants' -import { TransformUtils } from './transform/TransformUtils' - -export class ImageKnife { - static readonly SEPARATOR: string = '/' - memoryCache: MemoryLruCache; - dataFetch: IDataFetch; - resourceFetch: IResourceFetch; - filesPath: string = ""; // data/data/包名/files目录 - diskMemoryCache: DiskLruCache; - memoryCacheProxy: MemoryCacheProxy = new MemoryCacheProxy(new MemoryLruCache(100, 100 * 1024 * 1024)); - headerMap: Map = new Map(); //定义全局map - placeholderCache: string = "placeholderCache" - runningMaps: EasyLinkedHashMap; - pendingMaps: EasyLinkedHashMap; - pausedMaps: EasyLinkedHashMap; - isPaused: boolean = false; - mutex: MethodMutex = new MethodMutex(); - fileTypeUtil: FileTypeUtil; // 通用文件格式辨别 - diskCacheFolder: string = "ImageKnifeDiskCache" - defaultListener: AsyncCallback = { - callback: (err: string, data: ImageKnifeData) => { - return false - } - }; // 全局监听器 - - // gifWorker - gifWorker: worker.ThreadWorker | undefined = undefined; - defaultLifeCycle: IDrawLifeCycle | undefined = undefined; - // 开发者可配置全局缓存 - engineKeyImpl: EngineKeyInterface; - - private constructor() { - - this.runningMaps = new EasyLinkedHashMap(); - this.pendingMaps = new EasyLinkedHashMap(); - this.pausedMaps = new EasyLinkedHashMap(); - - // 构造方法传入size 为保存文件个数 - this.memoryCache = new MemoryLruCache(100, 100 * 1024 * 1024); - - // 创建网络下载能力 - this.dataFetch = new DownloadClient(); - - // 创建本地数据解析能力 - this.resourceFetch = new ParseResClient(); - - // 初始化本地 文件保存 - this.filesPath = (ImageKnifeGlobal.getInstance().getHapContext() as common.UIAbilityContext).filesDir as string; - - this.diskMemoryCache = DiskLruCache.create(ImageKnifeGlobal.getInstance() - .getHapContext() as common.UIAbilityContext); - - // 通用文件格式识别初始化 - this.fileTypeUtil = new FileTypeUtil(); - - this.engineKeyImpl = new EngineKeyFactories(); - - } - - //全局设置请求头调用方法 - addHeader(key: string, value: Object) { - this.headerMap.set(key, value); - } - - deleteHeader(key: string) { - this.headerMap.delete(key); - } - - getMemoryCache(): MemoryLruCache { - return this.memoryCache; - } - - getMemoryCacheProxy(): MemoryCacheProxy { - return this.memoryCacheProxy; - } - - public static with(context: Object): ImageKnifeGlobal { - // 存入hapContext; - let global: ImageKnifeGlobal = ImageKnifeGlobal.getInstance(); - global.setHapContext(context) - - // 初始化ImageKnife - if (!ImageKnife.sInstance) { - ImageKnife.sInstance = new ImageKnife(); - } - - // 存入ImageKnife - global.setImageKnife(ImageKnife.sInstance) - - return global; - } - - getDiskMemoryCache(): DiskLruCache { - return this.diskMemoryCache; - }; - - setDiskMemoryCache(diskLruCache: DiskLruCache) { - this.diskMemoryCache = diskLruCache; - }; - - getFileTypeUtil(): FileTypeUtil { - return this.fileTypeUtil; - } - - getImageKnifeContext() { - return ImageKnifeGlobal.getInstance().getHapContext(); - } - - setMemoryCache(lrucache: MemoryLruCache) { - this.memoryCache = lrucache; - } - - getDefaultListener() { - return this.defaultListener; - } - - setGifWorker(worker: worker.ThreadWorker) { - this.gifWorker = worker - } - - getGifWorker() { - return this.gifWorker; - } - - getDefaultLifeCycle() { - return this.defaultLifeCycle; - } - - setDefaultLifeCycle(viewLifeCycle: IDrawLifeCycle) { - this.defaultLifeCycle = viewLifeCycle; - } - - setEngineKeyImpl(impl: EngineKeyInterface) { - this.engineKeyImpl = impl; - } - - private static sInstance: ImageKnife; - - setDefaultListener(newDefaultListener: AsyncCallback) { - this.defaultListener = newDefaultListener; - } - - public compressBuilder(): CompressBuilder { - return new CompressBuilder(); - } - - - // 设置缓存张数,缓存大小,单位字节 - public setLruCacheSize(size: number, memory: number) { - if (this.memoryCache.map.size() <= 0) { - this.memoryCache = new MemoryLruCache(size, memory); - } else { - let newLruCache = new MemoryLruCache(size, memory); - this.memoryCache.foreachLruCache((value: ImageKnifeData, key: string, map: Object) => { - newLruCache.put(key, value); - }) - this.memoryCache = newLruCache; - } - } - - public replaceDataFetch(fetch: IDataFetch) { - this.dataFetch = fetch; - } - - - // 替代原来的DiskLruCache - public replaceDiskLruCache(size: number) { - this.diskMemoryCache.setMaxSize(size) - // if (this.diskMemoryCache.getCacheMap().size() <= 0) { - // this.diskMemoryCache = DiskLruCache.create(ImageKnifeGlobal.getInstance().getHapContext(), size); - // } else { - // let newDiskLruCache = DiskLruCache.create(ImageKnifeGlobal.getInstance().getHapContext(), size); - // this.diskMemoryCache.foreachDiskLruCache((value: string | ArrayBuffer, key: string, map: Object) => { - // newDiskLruCache.set(key, value); - // }) - // this.diskMemoryCache = newDiskLruCache; - // } - } - - // 预加载 resource资源一级缓存,string资源实现二级缓存 - preload(request: RequestOption): void { - // 每个request 公共信息补充 - request.setFilesPath(this.filesPath); - return this.parseSource(request); - } - - // 暂停所有请求 - async pauseRequests(): Promise { - await this.mutex.lock(async () => { - this.isPaused = true; - - // 将未删除的所有request [run pend] 放入 [pause] - LogUtil.log('dodo pauseRequests start1 pausedMaps size=' + this.pausedMaps.size() + ' runMaps Size=' + this.runningMaps.size() + ' pendMaps Size=' + this.pendingMaps.size()) - - // 将run存入pause - let runNode = this.runningMaps.getHead(); - while (runNode) { - let request = runNode.value; - this.pausedMaps.put(request.uuid, request) - runNode = runNode.next; - } - this.runningMaps.clear(); - LogUtil.log('dodo pauseRequests start2 pausedMaps size=' + this.pausedMaps.size() + ' runMaps Size=' + this.runningMaps.size() + ' pendMaps Size=' + this.pendingMaps.size()) - - let pendNode = this.pendingMaps.getHead(); - while (pendNode) { - let request = pendNode.value; - this.pausedMaps.put(request.uuid, request) - pendNode = pendNode.next - } - this.pendingMaps.clear() - LogUtil.log('dodo pauseRequests start3 pausedMaps size=' + this.pausedMaps.size() + ' runMaps Size=' + this.runningMaps.size() + ' pendMaps Size=' + this.pendingMaps.size()) - }) - } - - // 恢复所有被暂停的请求 - async resumeRequests(): Promise { - await this.mutex.lock(async () => { - this.isPaused = false; - LogUtil.log('dodo resumeRequest start1 pausedMaps size=' + this.pausedMaps.size() + ' runMaps Size=' + this.runningMaps.size() + ' pendMaps Size=' + this.pendingMaps.size()) - // 重启了之后需要把paused 里面的所有request重新发送 - let headNode = this.pausedMaps.getHead(); - while (headNode) { - let request = headNode.value - this.loadCacheManager(request) - headNode = headNode.next - } - this.pausedMaps.clear() - LogUtil.log('dodo resumeRequest start1 pausedMaps size=' + this.pausedMaps.size() + ' runMaps Size=' + this.runningMaps.size() + ' pendMaps Size=' + this.pendingMaps.size()) - }) - } - - // 删除 请求 - remove(uuid: string) { - if (this.isPaused) { - this.pausedMaps.remove(uuid) - } else { - // TODO 哪些请求可以删除 - this.pendingMaps.remove(uuid) - this.runningMaps.remove(uuid) - } - } - - // 正常加载 - call(request: RequestOption): void { - // 添加全局监听 - if (this.defaultListener) { - request.addListener(this.defaultListener) - } - - // 每个request 公共信息补充 - request.setFilesPath(this.filesPath); - - if (this.headerMap.size > 0) { - request.addHeaderMap(this.headerMap) - } - - this.generateDataCacheKey(request) - // 首先执行占位图 解析任务 - if (request.placeholderSrc) { - this.taskpoolLoadResource(request, Constants.PLACE_HOLDER); - } - // 其次执行重试占位图 解析任务 - if (request.retryholderSrc) { - this.taskpoolLoadResource(request, Constants.RETRY_HOLDER); - } - - // 最后解析错误占位图 - if (request.errorholderSrc) { - this.taskpoolLoadResource(request, Constants.ERROR_HOLDER); - } - return this.parseSource(request); - } - - generateDataCacheKey(request: RequestOption) { - let factories: EngineKeyInterface; - let cacheKey: string; - let transferKey: string; - let dataKey: string; - //设置全局缓存key - if (this.engineKeyImpl) { - factories = this.engineKeyImpl; - } else { - factories = new EngineKeyFactories(); - } - // 生成内存缓存key 内存 变换后磁盘 - - let loadKey = ''; - if (typeof request.loadSrc == 'string') { - loadKey = request.loadSrc; - } else { - loadKey = JSON.stringify(request.loadSrc); - } - - let size = JSON.stringify(request.size); - - let transformed = ''; - if (request && request.transformations) { - for (let i = 0; i < request.transformations.length; i++) { - if (i == request.transformations.length - 1) { - transformed += request.transformations[i].getName() + ""; - } else { - transformed += request.transformations[i].getName() + ","; - } - } - } - - let dontAnimateFlag = request.dontAnimateFlag; - - let signature = request.signature; - - cacheKey = factories.generateMemoryCacheKey(loadKey, size, transformed, dontAnimateFlag, signature); - - // 生成磁盘缓存变换后数据key 变换后数据保存在磁盘 - transferKey = factories.generateTransformedDiskCacheKey(loadKey, size, transformed, dontAnimateFlag, signature); - - // 生成磁盘缓存源数据key 原始数据保存在磁盘 - dataKey = factories.generateOriginalDiskCacheKey(loadKey, signature); - if (request.placeholderSrc) { - let placeholderLoadKey = ''; - if (typeof request.placeholderSrc == 'string') { - placeholderLoadKey = request.placeholderSrc; - } else { - placeholderLoadKey = JSON.stringify(request.placeholderSrc); - } - request.placeholderCacheKey = this.generateCacheKey(placeholderLoadKey, size, dontAnimateFlag, signature) - } - if (request.retryholderSrc) { - let retryholderLoadKey = ''; - if (typeof request.retryholderSrc == 'string') { - retryholderLoadKey = request.retryholderSrc; - } else { - retryholderLoadKey = JSON.stringify(request.retryholderSrc); - } - request.retryholderCacheKey = this.generateCacheKey(retryholderLoadKey, size, dontAnimateFlag, signature) - } - if (request.errorholderSrc) { - let errorholderLoadKey = ''; - if (typeof request.errorholderSrc == 'string') { - errorholderLoadKey = request.errorholderSrc; - } else { - errorholderLoadKey = JSON.stringify(request.errorholderSrc); - } - request.errorholderCacheKey = this.generateCacheKey(errorholderLoadKey, size, dontAnimateFlag, signature) - } - request.generateCacheKey = cacheKey; - request.generateResourceKey = transferKey; - request.generateDataKey = dataKey; - } - - private generateCacheKey(loadkey: string, size: string, dontAnimateFlag: boolean, signature?: ObjectKey) { - let factories: EngineKeyInterface; - - //设置全局缓存key - if (this.engineKeyImpl) { - factories = this.engineKeyImpl; - } else { - factories = new EngineKeyFactories(); - } - return factories.generateMemoryCacheKey(loadkey, size, '', dontAnimateFlag, signature); - } - - // 删除执行结束的running - removeRunning(request: RequestOption) { - if (this.isPaused) { - - } else { - this.runningMaps.remove(request.uuid); - LogUtil.log('dodo runningMaps length =' + this.runningMaps.size()) - let previousRequest = request; - this.loadNextPending(previousRequest); - } - } - - // 执行相同key的pending队列请求 - private keyEqualPendingToRun(nextPending: RequestOption) { - - - this.pendingMaps.remove(nextPending.uuid) - this.runningMaps.put(nextPending.uuid, nextPending); - - // RequestManager.execute((nextPending as RequestOption), this.memoryCache, this.diskMemoryCache, this.dataFetch, this.resourceFetch) - this.taskpoolLoadResource(nextPending, Constants.MAIN_HOLDER); - - } - - private searchNextKeyToRun() { - // 其次则寻找pending中第一个和running不重复的requestOrKey - let pendingTailNode = this.pendingMaps.getTail(); - while (pendingTailNode) { - let pendingRequest = pendingTailNode.value; - let hasEqual = false; - let runningTailNode = this.runningMaps.getTail(); - while (runningTailNode) { - let runningRequest = runningTailNode.value; - if (this.requestOrKeyEqual(pendingRequest, runningRequest)) { - hasEqual = true; - break - } - runningTailNode = runningTailNode.prev; - } - - if (!hasEqual) { - break; - } - pendingTailNode = pendingTailNode.prev; - } - - if (pendingTailNode != null && pendingTailNode.value != null) { - let nextPending = pendingTailNode.value; - this.runningMaps.put(nextPending.uuid, nextPending) - this.pendingMaps.remove(nextPending.uuid) - //RequestManager.execute((nextPending as RequestOption), this.memoryCache, this.diskMemoryCache, this.dataFetch, this.resourceFetch) - this.taskpoolLoadResource(nextPending, Constants.MAIN_HOLDER); - } - } - - - // 加载下一个key的请求 - private loadNextPending(request: RequestOption) { - let hasEqualRunning = false; - let tailNode = this.pendingMaps.getTail(); - while (tailNode) { - if (this.requestOrKeyEqual(request, tailNode.value)) { - hasEqualRunning = true; - break; - } - tailNode = tailNode.prev; - } - - if (hasEqualRunning) { - if (tailNode != null && tailNode.value != null) { - this.keyEqualPendingToRun(tailNode.value); - } - } else { - this.searchNextKeyToRun(); - } - } - - // 启动新线程 去磁盘取 去网络取 - private loadCacheManager(request: RequestOption) { - if (this.isPaused) { - // 将当前request存入pausedMaps - this.pausedMaps.put(request.uuid, request); - } else { - // 正常逻辑 - if (this.keyNotEmpty(request)) { - let hasRunningRequest = false; - // 遍历双向链表 从尾巴到头 - let tailNode = this.runningMaps.getTail(); - while (tailNode) { - if (this.requestOrKeyEqual(request, tailNode.value)) { - hasRunningRequest = true; - break; - } - tailNode = tailNode.prev - } - - if (hasRunningRequest) { - this.pendingMaps.put(request.uuid, request); - - - } else { - this.runningMaps.put(request.uuid, request) - - this.taskpoolLoadResource(request, Constants.MAIN_HOLDER); - } - } - else { - LogUtil.log("key没有生成无法进入存取!") - } - } - } - - //组装任务参数 - private assembleTaskParams(request: RequestOption, usageType: string) { - //图片变换方法无法直接传递到子线程,这里先把对象名和构造参数传递到子线程,然后在子线程中实例化变换方法 - let transformations: string [][] = []; - if (usageType == Constants.MAIN_HOLDER) { - for (let i = 0; i < request.transformations.length; i++) { - transformations.push([request.transformations[i].getClassName(), request.transformations[i].getConstructorParams()]) - } - } - let displayProgress = request.progressFunc ? true : false; - //將要传递到子线程的参数,放在一个json对象上,避免方法参数过多 - let taskParams: TaskParams = { - headers: request.headers, - moduleContext: request.moduleContext, - transformations: transformations, - usageType: usageType, - displayProgress: displayProgress, - uuid: request.uuid, - dontAnimateFlag: request.dontAnimateFlag, - priority: request.priority, - generateCacheKey: request.generateCacheKey, - generateResourceKey: request.generateResourceKey, - generateDataKey: request.generateDataKey, - thumbSizeMultiplier: request.thumbSizeMultiplier, - thumbDelayTime: request.thumbDelayTime, - size: request.size, - onlyRetrieveFromCache: request.onlyRetrieveFromCache, - gpuEnabled: request.gpuEnabled, - signature: request.signature, - isCacheable: request.isCacheable, - diskMemoryCachePath: this.diskMemoryCache.getPath() - } - return taskParams; - } - - //多线程请求加载资源 - private taskpoolLoadResource(request: RequestOption, usageType: string) { - let mainCache = this.memoryCacheProxy.loadMemoryCache(request.generateCacheKey, request.isCacheable); - let placeholderCache = this.memoryCacheProxy.loadMemoryCache(request.placeholderCacheKey, request.isCacheable); - let retryholderCache = this.memoryCacheProxy.loadMemoryCache(request.retryholderCacheKey, request.isCacheable); - let errorholderCacheKey = this.memoryCacheProxy.loadMemoryCache(request.errorholderCacheKey, request.isCacheable); - - if (usageType == Constants.PLACE_HOLDER && placeholderCache && !mainCache && !retryholderCache && !errorholderCacheKey) { - LogUtil.info("imageknife load placeholder from MemoryCache") - request.placeholderOnComplete(placeholderCache); - return; - } else if (usageType == Constants.RETRY_HOLDER && retryholderCache && !mainCache && !errorholderCacheKey) { - LogUtil.info("imageknife load retryholder from MemoryCache") - request.retryholderOnComplete(retryholderCache); - return; - } else if (usageType == Constants.ERROR_HOLDER && errorholderCacheKey && !mainCache) { - LogUtil.info("imageknife load errorholder from MemoryCache") - request.errorholderOnComplete(errorholderCacheKey); - return; - } else if (usageType == Constants.MAIN_HOLDER && mainCache) { - LogUtil.info("imageknife load mainsource from MemoryCache") - mainCache.waitSaveDisk = false; - request.loadComplete(mainCache); - return; - } - - let taskParams: TaskParams = this.assembleTaskParams(request, usageType); - let loadSrcJson = JSON.stringify({ - loadSrc: request.loadSrc, - placeholderSrc: request.placeholderSrc, - errorholderSrc: request.errorholderSrc, - retryholderSrc: request.retryholderSrc, - }); - //使用taskpool多线程执行资源下载 - let task: ESObject = new taskpool.Task(taskExecute, taskParams, loadSrcJson) - task.setTransferList([]) - - emitter.on(Constants.PROGRESS_EMITTER as ESObject, (data: ESObject) => { - if (request.progressFunc && data?.data?.value) { - let percent = data.data.value as number; - request.progressFunc.asyncSuccess(percent); - } - }); - taskpool.execute(task).then((data: ESObject) => { - if (usageType == Constants.PLACE_HOLDER) { - if ((typeof (data as PixelMap).isEditable) == 'boolean') { - let imageKnifeData = ImageKnifeData.createImagePixelMap(ImageKnifeType.PIXELMAP, data as PixelMap); - request.placeholderOnComplete(imageKnifeData) - this.memoryCacheProxy.putValue(request.placeholderCacheKey,imageKnifeData) - } else { - request.placeholderOnError("request placeholder error") - } - } else if (usageType == Constants.RETRY_HOLDER) { - if ((typeof (data as PixelMap).isEditable) == 'boolean') { - let imageKnifeData = ImageKnifeData.createImagePixelMap(ImageKnifeType.PIXELMAP, data as PixelMap); - request.retryholderOnComplete(imageKnifeData) - this.memoryCacheProxy.putValue(request.retryholderCacheKey,imageKnifeData) - } else { - request.retryholderOnError("request retryholder error") - } - } else if (usageType == Constants.ERROR_HOLDER) { - if ((typeof (data as PixelMap).isEditable) == 'boolean') { - let imageKnifeData = ImageKnifeData.createImagePixelMap(ImageKnifeType.PIXELMAP, data as PixelMap); - request.errorholderOnComplete(imageKnifeData) - this.memoryCacheProxy.putValue(request.errorholderCacheKey,imageKnifeData) - } else { - request.errorholderOnError("request errorholder error") - } - } else { - if ((typeof (data as PixelMap).isEditable) == 'boolean') { - let imageKnifeData = ImageKnifeData.createImagePixelMap(ImageKnifeType.PIXELMAP, data as PixelMap); - imageKnifeData.needSaveDisk = true; - request.loadComplete(imageKnifeData) - this.memoryCacheProxy.putValue(request.generateCacheKey,imageKnifeData) - this.setDiskCache(request) - } else if ((data as GIFFrame[]).length > 0) { - let imageKnifeData = ImageKnifeData.createImageGIFFrame(ImageKnifeType.GIFFRAME, data as GIFFrame[]); - imageKnifeData.needSaveDisk = true; - request.loadComplete(imageKnifeData) - this.memoryCacheProxy.putValue(request.generateCacheKey,imageKnifeData) - this.setDiskCache(request) - } else { - request.loadError("request resources error") - } - } - }).catch((err: BusinessError | string) => { - request.loadError(err) - }) - - } - - private setDiskCache(request: RequestOption):void{ - try { - // let diskMemoryCache = ImageKnifeGlobal.getInstance().getImageKnife()?.getDiskMemoryCache(); - let dataArraybuffer: ArrayBuffer = DiskLruCache.getFileCacheByFile(this.diskMemoryCache.getPath() as string, request.generateDataKey) as ArrayBuffer; - //缓存原图片 - if (dataArraybuffer) { - this.diskMemoryCache.setCacheMapAndSize(request.generateDataKey, dataArraybuffer); - } - //缓存变换后图片 - let resourceArraybuffer: ArrayBuffer = DiskLruCache.getFileCacheByFile(this.diskMemoryCache.getPath() as string, request.generateResourceKey) as ArrayBuffer; - if (resourceArraybuffer) { - this.diskMemoryCache.setCacheMapAndSize(request.generateResourceKey, resourceArraybuffer); - } - - } catch (e) { - LogUtil.error("imageknife DiskMemoryCache setDiskCache error :" + e.message); - } - } - - private keyNotEmpty(request: RequestOption): boolean { - if ( - request.generateCacheKey != null && request.generateCacheKey.length > 0 && - request.generateDataKey != null && request.generateDataKey.length > 0 && - request.generateResourceKey != null && request.generateResourceKey.length > 0 - ) { - return true; - } - return false; - } - - private keyEqual(request1: RequestOption, request2: RequestOption): boolean { - // key 完全相等的情况 - if ( - request1.generateCacheKey == request2.generateCacheKey && - request1.generateResourceKey == request2.generateResourceKey && - request1.generateDataKey == request2.generateDataKey - ) { - return true; - } - - return false; - } - - // 非严格校验模式,如果所有key相等我们认为一定相等, 如果请求类型是string 网络请求url或者uri相等 我们也认为该请求应该只发送一个即可,后续请求会去缓存或者磁盘读取 - private requestOrKeyEqual(request1: RequestOption, request2: RequestOption): boolean { - // key 完全相等的情况 - if ( - request1.generateCacheKey == request2.generateCacheKey && - request1.generateResourceKey == request2.generateResourceKey && - request1.generateDataKey == request2.generateDataKey - ) { - return true; - } - - // 如果加载的是网络url或者是本地文件uri读取,那么loadSrc相同就认为是同一个请求 - if ( - typeof request1.loadSrc == 'string' && typeof request2.loadSrc == 'string' && request1.loadSrc == request2.loadSrc - ) { - return true; - } - - return false; - } - - private parseSource(request: RequestOption): void { - if ((typeof (request.loadSrc as image.PixelMap).isEditable) == 'boolean') { - let imageKnifeData = ImageKnifeData.createImagePixelMap(ImageKnifeType.PIXELMAP, request.loadSrc as PixelMap) - request.loadComplete(imageKnifeData); - } else if (typeof request.loadSrc == 'string') { - // 进入三级缓存模型 - return this.loadCacheManager(request); - } else { - let res = request.loadSrc as Resource; - if (typeof res.id != 'undefined' && typeof res.type != 'undefined') { - // 进入三级缓存模型 本地资源不参与磁盘缓存 - let none = new NONE(); - request.diskCacheStrategy(none); - this.loadCacheManager(request); - } else { - LogUtil.error("输入参数有问题!") - } - } - } - - prefetchToDiskCache(url: string): Promise { - return new Promise((resolve, reject) => { - let key = this.engineKeyImpl.generateOriginalDiskCacheKey(url, undefined); - let cachedPath = this.getDiskMemoryCache().getFileToPath(key); - if (cachedPath == null || cachedPath == "" || cachedPath == undefined) { - let request = new RequestOption(); - request.load(url) - .addListener({ callback: (err: BusinessError | string, data: ImageKnifeData) => { - if (err) { - reject(err) - } else { - let cachedPath = this.getDiskMemoryCache().getFileToPath(key); - resolve(cachedPath); - } - return false; - } - }) - this.call(request); - } else { - resolve(cachedPath); - } - - }) - } -} - - -/** - * 加载资源子线程包含流程:网络请求资源->下载资源到本地->解码成ixelMap | GIFFrame[]->缓存到内存和磁盘 - * @param taskParams:任务参数,JSON字符串类型 - * @param headers:请求头 - * @param moduleContext:模块上下文 - * @returns - */ -@Concurrent -async function taskExecute(taskParams: TaskParams, loadSrcJson: string): Promise { - - let emitProgressPercent = (percentValue: number) => { - let eventData: emitter.EventData = { - data: { - "value": percentValue, - } - }; - emitter.emit(Constants.PROGRESS_EMITTER as ESObject, eventData) - } - - let transformations = taskParams.transformations; - let usageType = taskParams.usageType; - let displayProgress = taskParams.displayProgress; - //子线程构造RequestOption对象 - let newRequestOption = new RequestOption(); - let loadSrcObj: object = JSON.parse(loadSrcJson); - newRequestOption.priority = taskParams.priority - newRequestOption.uuid = taskParams.uuid; - newRequestOption.loadSrc = loadSrcObj["loadSrc"] as string | PixelMap | Resource; - newRequestOption.dontAnimateFlag = taskParams.dontAnimateFlag; - newRequestOption.generateCacheKey = taskParams.generateCacheKey; - newRequestOption.generateResourceKey = taskParams.generateResourceKey; - newRequestOption.generateDataKey = taskParams.generateDataKey; - newRequestOption.thumbSizeMultiplier = taskParams.thumbSizeMultiplier; - newRequestOption.thumbDelayTime = taskParams.thumbDelayTime; - newRequestOption.size = taskParams.size; - newRequestOption.diskMemoryCachePath = taskParams.diskMemoryCachePath; - newRequestOption.placeholderSrc = loadSrcObj["placeholderSrc"] as PixelMap | Resource | undefined; - newRequestOption.errorholderSrc = loadSrcObj["errorholderSrc"] as PixelMap | Resource | undefined; - newRequestOption.retryholderSrc = loadSrcObj["retryholderSrc"] as PixelMap | Resource | undefined; - newRequestOption.onlyRetrieveFromCache = taskParams.onlyRetrieveFromCache; - newRequestOption.gpuEnabled = taskParams.gpuEnabled; - newRequestOption.headers = taskParams.headers; - newRequestOption.signature = taskParams.signature; - ImageKnifeGlobal.getInstance().setHapContext(taskParams.moduleContext as common.UIAbilityContext); - newRequestOption.moduleContext = taskParams.moduleContext; - newRequestOption.isCacheable = taskParams.isCacheable; - - if (displayProgress) { - newRequestOption.addProgressListener({ - asyncSuccess: (percentValue: number) => { - // 如果进度条百分比 未展示大小,展示其动画 - emitProgressPercent(percentValue) - } - }) - } - //如果是本地图片不作磁盘缓存 - if (typeof newRequestOption.loadSrc !== 'string') { - let none = new NONE(); - newRequestOption.diskCacheStrategy(none); - } - - if (usageType == Constants.PLACE_HOLDER) { - let manager = new PlaceHolderManager(newRequestOption); - return await new Promise(manager.process); - } else if (usageType == Constants.RETRY_HOLDER) { - let manager = new RetryHolderManager(newRequestOption); - return await new Promise(manager.process); - } else if (usageType == Constants.ERROR_HOLDER) { - let manager = new ErrorHolderManager(newRequestOption); - return await new Promise(manager.process); - } else { - if (transformations) { - newRequestOption.setTransformations(TransformUtils.addTransformations(transformations)) - } - let newDataFetch = new DownloadClient(); - let newResourceFetch = new ParseResClient(); - let manager = new RequestManager(newRequestOption, newDataFetch, newResourceFetch); - return await new Promise(manager.process); - } -} - diff --git a/library/src/main/ets/components/imageknife/ImageKnifeComponent.ets b/library/src/main/ets/components/imageknife/ImageKnifeComponent.ets deleted file mode 100644 index 2aa6803..0000000 --- a/library/src/main/ets/components/imageknife/ImageKnifeComponent.ets +++ /dev/null @@ -1,1069 +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 '../imageknife/ImageKnifeOption' -import { ImageKnifeGlobal } from '../imageknife/ImageKnifeGlobal' -import { TransformType } from '../imageknife/transform/TransformType' -import { DetachFromLayout, RequestOption, Size } from '../imageknife/RequestOption' -import { ImageKnifeData } from '../imageknife/ImageKnifeData' -import { GIFFrame } from '../imageknife/utils/gif/GIFFrame' -import { IDrawLifeCycle } from '../imageknife/interface/IDrawLifeCycle' -import { LogUtil } from '../imageknife/utils/LogUtil' -import { BusinessError } from '@ohos.base' -import common from '@ohos.app.ability.common' -import { ObjectKey } from './ObjectKey' -import componentUtils from '@ohos.arkui.componentUtils' -import inspector from '@ohos.arkui.inspector' -import util from '@ohos.util' - -interface KeyCanvas { - keyId:string -} -@Component -export struct ImageKnifeComponent { - @Watch('watchImageKnifeOption') @ObjectLink imageKnifeOption: ImageKnifeOption; - autoPlay: boolean = true - private settings: RenderingContextSettings = new RenderingContextSettings(true) - private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings) - private hasDisplayRetryholder = false; - private lastWidth: number = 0 - private lastHeight: number = 0 - // 定时器id - private gifTimerId: number = -1 - // 完整gif播放时间 - private gifLoopDuration: number = 0 - private startGifLoopTime: number = 0 - private endGifLoopTime: number = 0 - // 抗锯齿属性 - private imageSmoothingQuality: ImageSmoothingQuality = 'low'; - private imageSmoothingEnabled: boolean = true; - // 是否是gif图片 - private isGif: boolean = false - @State keyCanvas: KeyCanvas = { - keyId: util.generateRandomUUID() - } - defaultLifeCycle: IDrawLifeCycle = { - - // 展示占位图 - 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; - } - - } - private canvasHasReady: boolean = false; - private firstDrawFlag: boolean = false; - private onReadyNext?: (data:ImageKnifeData|number|undefined) => void = undefined - private onReadyNextData:ImageKnifeData|number|undefined = undefined - - private detachFromLayout:DetachFromLayout|undefined = undefined; - - private detachFromLayoutGIF :DetachFromLayout|undefined = undefined; - - private detachFromLayoutPixelMap :DetachFromLayout|undefined = undefined; - private lastSrc: string | Resource | PixelMap = "" - listener: inspector.ComponentObserver = inspector.createComponentObserver(this.keyCanvas.keyId) - - @State currentSize : Size = { - width: 0.01, - height: 0.01 - } - - build() { - Canvas(this.context) - .key(this.keyCanvas.keyId) - .width((this.imageKnifeOption!=undefined && this.imageKnifeOption.mainScaleType!= undefined && this.imageKnifeOption.mainScaleType == ScaleType.AUTO_WIDTH )? this.currentSize.width:'100%') - .height((this.imageKnifeOption!=undefined && this.imageKnifeOption.mainScaleType!= undefined && this.imageKnifeOption.mainScaleType == ScaleType.AUTO_HEIGHT )? this.currentSize.height:'100%') - .renderFit(RenderFit.RESIZE_FILL) - .onReady(() => { - let ctx = this.context; - ctx.imageSmoothingEnabled = this.imageSmoothingEnabled; - ctx.imageSmoothingQuality = this.imageSmoothingQuality; - this.canvasHasReady = true; - if (this.onReadyNext) { - LogUtil.log('ImageKnifeComponent onReadyNext is running!') - this.onReadyNext(this.onReadyNextData) - this.onReadyNext = undefined; - this.onReadyNextData = undefined - } - }) - .onClick((event?: ClickEvent) => { - // 需要将点击事件回传 - if (this.imageKnifeOption.onClick) { - this.imageKnifeOption.onClick(event) - } - if (this.imageKnifeOption.canRetryClick && this.hasDisplayRetryholder) { - this.retryClick() - } - }) - } - onLayoutComplete:()=>void = ():void=>{ - if (this.context.width <= 0 || this.context.height <= 0) { - // 存在宽或者高为0,此次重回无意义,无需进行request请求 - } else { - // 前提:宽高值均有效,值>0. 条件1:当前宽高与上一次宽高不同 条件2:当前是第一次绘制 - if ((this.context.height != this.lastHeight || this.context.width != this.lastWidth) || this.firstDrawFlag) { - this.firstDrawFlag = false; - LogUtil.log('ImageKnifeComponent onAreaChange And Next To Execute. Canvas currentWidth =' + this.context.width + ' currentHeight=' + this.context.height) - this.lastWidth = this.context.width - this.lastHeight = this.context.height - this.imageKnifeExecute() - } - } - } - - watchImageKnifeOption() { - LogUtil.log('ImageKnifeComponent watchImageKnifeOption is happened!') - this.lastSrc = this.imageKnifeOption.loadSrc - this.whetherWaitSize(); - } - - /** - * 判断当前是否有宽高,有直接重绘,没有则等待onAreaChange回调,当出现aboutToAppear第一次绘制的时候 - * 给firstDrawFlag置为true,保证size即使没有变化也要进入 请求绘制流程 - * @param drawFirst 是否是aboutToAppear第一次绘制 - */ - whetherWaitSize(drawFirst?: boolean) { - if (this.context.height <= 0 || this.context.width <= 0) { - // 宽或者高没有高度,需要等待canvas组件初始化完成 - if (drawFirst) { - this.firstDrawFlag = true; - } - } else { - LogUtil.log('ImageKnifeComponent whetherWaitSize 宽高有效 直接发送请求') - this.imageKnifeExecute() - } - } - - retryClick() { - this.hasDisplayRetryholder = false; - this.imageKnifeExecute(); - } - - /** - * 为了保证执行方法在canvas的onReay之后 - * 如果onReady未初始化,则将最新的绘制生命周期绑定到onReadNext上 - * 待onReady执行的时候执行 - * @param nextFunction 下一个方法 - */ - runNextFunction(nextFunction: (data:ImageKnifeData|number|undefined) => void,data:ImageKnifeData|number|undefined) { - if (!this.canvasHasReady) { - // canvas未初始化完成 - this.onReadyNext = nextFunction; - this.onReadyNextData = data; - } else { - nextFunction(data); - } - } - - configNecessary(request: RequestOption) { - request.load(this.imageKnifeOption.loadSrc) - .addListener({ callback: (err:BusinessError|string, data:ImageKnifeData) => { - LogUtil.log('ImageKnifeComponent request.load callback') - if(data.isGIFFrame()) { - this.isGif = true - } else { - this.isGif = false - } - if(this.lastSrc !== request.loadSrc && this.lastSrc !== ""){} - else { - this.runNextFunction(this.displayMainSource,data); - } - return false; - } - }) - - let realSize:Size = { - width: this.context.width, - height: this.context.height - } - request.setImageViewSize(realSize) - } - - configCacheStrategy(request: RequestOption) { - if (this.imageKnifeOption.onlyRetrieveFromCache != null && this.imageKnifeOption.onlyRetrieveFromCache != undefined) { - request.retrieveDataFromCache(this.imageKnifeOption.onlyRetrieveFromCache) - } - - if (this.imageKnifeOption.isCacheable != null && this.imageKnifeOption.isCacheable != undefined) { - request.skipMemoryCache(!this.imageKnifeOption.isCacheable) - } - - - if (this.imageKnifeOption.strategy != null && this.imageKnifeOption.strategy != undefined) { - request.diskCacheStrategy(this.imageKnifeOption.strategy) - } - if (this.imageKnifeOption.allCacheInfoCallback != null && this.imageKnifeOption.allCacheInfoCallback != undefined) { - request.addAllCacheInfoCallback(this.imageKnifeOption.allCacheInfoCallback) - } - if (this.imageKnifeOption.signature) { - request.signature = this.imageKnifeOption.signature; - } - } - - configDisplay(request: RequestOption) { - //单个image组件多个请求头调用 - if (this.imageKnifeOption.headerOption != undefined && this.imageKnifeOption.headerOption?.length > 0) { - for (let i = 0; i < this.imageKnifeOption.headerOption.length; i++) { - let headerOptions = this.imageKnifeOption.headerOption[i]; - request.addHeader(headerOptions.key, headerOptions.value); - request.signature = new ObjectKey(new Date().getTime().toString()) - } - } - if( this.imageKnifeOption.priority != undefined) { - request.setPriority(this.imageKnifeOption.priority) - } - if (this.imageKnifeOption.placeholderSrc) { - request.placeholder(this.imageKnifeOption.placeholderSrc, {asyncSuccess:(data:ImageKnifeData) => { - LogUtil.log('ImageKnife ImageKnifeComponent request.placeholder callback') - this.runNextFunction(this.displayPlaceholder,data) - } - }) - } - if (this.imageKnifeOption.thumbSizeMultiplier) { - request.thumbnail(this.imageKnifeOption.thumbSizeMultiplier, {asyncSuccess:(data:ImageKnifeData) => { - LogUtil.log('ImageKnife ImageKnifeComponent request.thumbnail callback') - this.runNextFunction(this.displayThumbSizeMultiplier,data) - }}, this.imageKnifeOption.thumbSizeDelay) - } - if (this.imageKnifeOption.errorholderSrc) { - request.errorholder(this.imageKnifeOption.errorholderSrc, {asyncSuccess:(data:ImageKnifeData) => { - LogUtil.log('ImageKnife ImageKnifeComponent request.errorholder callback') - this.runNextFunction(this.displayErrorholder,data) - }}) - } - - if (this.imageKnifeOption.transform) { - this.requestAddTransform(request) - } - if (this.imageKnifeOption.transformation) { - request.transform(this.imageKnifeOption.transformation) - } - if (this.imageKnifeOption.transformations) { - request.transforms(this.imageKnifeOption.transformations) - } - if (this.imageKnifeOption.dontAnimateFlag) { - request.dontAnimate() - } - - - if (this.imageKnifeOption.displayProgress) { - request.addProgressListener({asyncSuccess:(percentValue: number) => { - // 如果进度条百分比 未展示大小,展示其动画 - LogUtil.log('ImageKnife ImageKnifeComponent request.addProgressListener callback') - this.runNextFunction(this.displayProgress,percentValue) - }}) - } - - if (this.imageKnifeOption.retryholderSrc) { - request.retryholder(this.imageKnifeOption.retryholderSrc,{asyncSuccess: (data:ImageKnifeData) => { - LogUtil.log('ImageKnife ImageKnifeComponent request.retryholder callback') - this.hasDisplayRetryholder = true - this.runNextFunction(this.displayRetryholder,data) - }}) - } - } - - configHspContext(request: RequestOption){ - if(this.imageKnifeOption.context != undefined){ - request.setModuleContext(this.imageKnifeOption.context) - }else{ - request.setModuleContext(getContext(this) as common.UIAbilityContext) - } - } - - configRenderGpu(request: RequestOption) { - if (this.imageKnifeOption.enableGpu) { - request.enableGPU() - } else { - // 如果enableGpu未设置则不启动GPU渲染 - } - } - - // imageknife 第一次启动和数据刷新后重新发送请求 - imageKnifeExecute() { - if (this.imageKnifeOption == null || this.imageKnifeOption.loadSrc == null) { - // 如果数据是null或者undefined,清空图片内容和gif循环,并且不进入图片请求流程 - this.resetGifData() - if (this.canvasHasReady) { - // 如果canvas已经初始化好了,清空原有的canvas内容 - this.context.clearRect(0, 0, this.context.width, this.context.height) - } - return - } - this.resetGifData() - let request = new RequestOption(); - this.detachFromLayout = request.detachFromLayout; - this.configNecessary(request); - this.configCacheStrategy(request); - this.configDisplay(request); - this.configHspContext(request); - this.configRenderGpu(request); - if(ImageKnifeGlobal.getInstance().getImageKnife()!=undefined) { - ImageKnifeGlobal.getInstance().getImageKnife()?.call(request); - } - } - - displayPlaceholder = (data: ImageKnifeData|number|undefined)=> { - if(data == undefined || typeof data == 'number'){ - return - } - if (!this.drawLifeCycleHasConsumed( 'displayPlaceholder', this.context, data, this.imageKnifeOption, - this.context.width, this.context.height, (gifTimeId) => { - this.setGifTimeId(gifTimeId) - },this.imageKnifeOption.drawLifeCycle)) { - if (!this.drawLifeCycleHasConsumed( 'displayPlaceholder', this.context, data, this.imageKnifeOption, - this.context.width, this.context.height, (gifTimeId) => { - this.setGifTimeId(gifTimeId) - },(ImageKnifeGlobal.getInstance().getImageKnife())?.getDefaultLifeCycle())) { - if(this.defaultLifeCycle.displayPlaceholder != undefined) { - this.defaultLifeCycle.displayPlaceholder(this.context, data, this.imageKnifeOption, this.context.width, this.context.height, (gifTimeId) => { - this.setGifTimeId(gifTimeId) - }) - } - } - } - - - } - - displayProgress = (percent: ImageKnifeData|number|undefined)=> { - if(typeof percent != 'number'){ - return - } - if (!this.drawLifeCycleHasConsumed( 'displayProgress', this.context, percent, this.imageKnifeOption, - this.context.width, this.context.height, (gifTimeId) => { - this.setGifTimeId(gifTimeId) - },this.imageKnifeOption.drawLifeCycle)) { - if (!this.drawLifeCycleHasConsumed( 'displayProgress', this.context, percent, this.imageKnifeOption, - this.context.width, this.context.height, (gifTimeId) => { - this.setGifTimeId(gifTimeId) - },(ImageKnifeGlobal.getInstance().getImageKnife())?.getDefaultLifeCycle())) { - if(this.defaultLifeCycle.displayProgress != undefined) { - this.defaultLifeCycle.displayProgress(this.context, percent, this.imageKnifeOption, this.context.width, this.context.height, (gifTimeId) => { - this.setGifTimeId(gifTimeId) - }) - } - } - } - - - } - - displayThumbSizeMultiplier = (data: ImageKnifeData|number|undefined)=> { - if(data == undefined || typeof data == 'number'){ - return - } - if (!this.drawLifeCycleHasConsumed( 'displayThumbSizeMultiplier', this.context, data, this.imageKnifeOption, - this.context.width, this.context.height, (gifTimeId) => { - this.setGifTimeId(gifTimeId) - },this.imageKnifeOption.drawLifeCycle)) { - if (!this.drawLifeCycleHasConsumed( 'displayThumbSizeMultiplier', this.context, data, this.imageKnifeOption, - this.context.width, this.context.height, (gifTimeId) => { - this.setGifTimeId(gifTimeId) - },(ImageKnifeGlobal.getInstance().getImageKnife())?.getDefaultLifeCycle())) { - if(this.defaultLifeCycle.displayThumbSizeMultiplier != undefined) { - this.defaultLifeCycle.displayThumbSizeMultiplier(this.context, data, this.imageKnifeOption, this.context.width, this.context.height, (gifTimeId) => { - this.setGifTimeId(gifTimeId) - }) - } - } - } - } - - displayMainSource = (data: ImageKnifeData|number|undefined)=> { - if(data == undefined || typeof data == 'number'){ - return - } - if (!this.drawLifeCycleHasConsumed( 'displayMainSource', this.context, data, this.imageKnifeOption, - this.context.width, this.context.height, (gifTimeId) => { - this.setGifTimeId(gifTimeId) - },this.imageKnifeOption.drawLifeCycle)) { - if (!this.drawLifeCycleHasConsumed( 'displayMainSource', this.context, data, this.imageKnifeOption, - this.context.width, this.context.height, (gifTimeId) => { - this.setGifTimeId(gifTimeId) - },(ImageKnifeGlobal.getInstance().getImageKnife())?.getDefaultLifeCycle())) { - if(this.defaultLifeCycle.displayMainSource != undefined) { - this.defaultLifeCycle.displayMainSource(this.context, data, this.imageKnifeOption, this.context.width, this.context.height, (gifTimeId) => { - this.setGifTimeId(gifTimeId) - }) - } - } - } - - - } - - displayRetryholder = (data: ImageKnifeData|number|undefined)=> { - if(data == undefined || typeof data == 'number'){ - return - } - if (!this.drawLifeCycleHasConsumed( 'displayRetryholder', this.context, data, this.imageKnifeOption, - this.context.width, this.context.height, (gifTimeId) => { - this.setGifTimeId(gifTimeId) - },this.imageKnifeOption.drawLifeCycle)) { - if (!this.drawLifeCycleHasConsumed( 'displayRetryholder', this.context, data, this.imageKnifeOption, - this.context.width, this.context.height, (gifTimeId) => { - this.setGifTimeId(gifTimeId) - },(ImageKnifeGlobal.getInstance().getImageKnife())?.getDefaultLifeCycle())) { - if( this.defaultLifeCycle.displayRetryholder != undefined) { - this.defaultLifeCycle.displayRetryholder(this.context, data, this.imageKnifeOption, this.context.width, this.context.height, (gifTimeId) => { - this.setGifTimeId(gifTimeId) - }) - } - } - } - - } - - displayErrorholder = (data: ImageKnifeData|number|undefined)=> { - if(data == undefined || typeof data == 'number'){ - return - } - if (!this.drawLifeCycleHasConsumed( 'displayErrorholder', this.context, data, this.imageKnifeOption, - this.context.width, this.context.height, (gifTimeId) => { - this.setGifTimeId(gifTimeId) - },this.imageKnifeOption.drawLifeCycle)) { - if (!this.drawLifeCycleHasConsumed( 'displayErrorholder', this.context, data, this.imageKnifeOption, - this.context.width, this.context.height, (gifTimeId) => { - this.setGifTimeId(gifTimeId) - },(ImageKnifeGlobal.getInstance().getImageKnife())?.getDefaultLifeCycle())) { - if(this.defaultLifeCycle.displayErrorholder != undefined) { - this.defaultLifeCycle.displayErrorholder(this.context, data, this.imageKnifeOption, this.context.width, this.context.height, (gifTimeId) => { - this.setGifTimeId(gifTimeId) - }) - } - } - } - - - } - - drawPlaceholder(context: CanvasRenderingContext2D, data: ImageKnifeData, imageKnifeOption: ImageKnifeOption, compWidth: number, compHeight: number, setGifTimeId?: (timeId: number) => void) { - LogUtil.log('ImageKnifeComponent default drawPlaceholder start!') - // API12 getImageInfoSync同步 - // if(data.drawPixelMap?.imagePixelMap != undefined) { - // let imageInfo = data.drawPixelMap?.imagePixelMap.getImageInfoSync() - // LogUtil.log('ImageKnifeComponent imageinfo width =' + 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(); - // LogUtil.log('ImageKnifeComponent default drawPlaceholder end!') - // } - // getImageInfo异步 - data.drawPixelMap?.imagePixelMap?.getImageInfo().then((imageInfo) => { - LogUtil.log('ImageKnifeComponent imageinfo width =' + 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(); - LogUtil.log('ImageKnifeComponent 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) { - LogUtil.log('ImageKnifeComponent default drawThumbSizeMultiplier start!') - // API12 getImageInfoSync同步 - // if(data.drawPixelMap?.imagePixelMap != undefined) { - // let imageInfo = data.drawPixelMap?.imagePixelMap.getImageInfoSync() - // LogUtil.log('ImageKnifeComponent imageinfo width =' + 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(); - // LogUtil.log('ImageKnifeComponent default drawThumbSizeMultiplier end!') - // } - // getImageInfo异步 - data.drawPixelMap?.imagePixelMap?.getImageInfo().then((imageInfo) => { - LogUtil.log('ImageKnifeComponent imageinfo width =' + 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(); - LogUtil.log('ImageKnifeComponent default drawThumbSizeMultiplier end!') - }) - } - - drawMainSource(context: CanvasRenderingContext2D, data: ImageKnifeData, imageKnifeOption: ImageKnifeOption, compWidth: number, compHeight: number, setGifTimeId?: (timeId: number) => void) { - LogUtil.log('ImageKnifeComponent default drawMainSource start!') - if (data.isPixelMap()) { - // API12 getImageInfoSync同步 - // if(data.drawPixelMap?.imagePixelMap != undefined) { - // let imageInfo = data.drawPixelMap?.imagePixelMap.getImageInfoSync() - // let scaleType = (typeof imageKnifeOption.mainScaleType == 'number') ? imageKnifeOption.mainScaleType : ScaleType.FIT_CENTER - // LogUtil.log('ImageKnifeComponent 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(); - // LogUtil.log('ImageKnifeComponent default drawMainSource end!') - // } - // getImageInfo异步 - data.drawPixelMap?.imagePixelMap?.getImageInfo().then((imageInfo) => { - let scaleType = (typeof imageKnifeOption.mainScaleType == 'number') ? imageKnifeOption.mainScaleType : ScaleType.FIT_CENTER - LogUtil.log('ImageKnifeComponent imageinfo width =' + imageInfo.size.width + ' height=' + imageInfo.size.height + 'scaleType=' + scaleType) - context.save(); - context.clearRect(0, 0, compWidth, compHeight) - let scaleHeight = imageInfo.size.height/imageInfo.size.width - let scaleWidth = imageInfo.size.width/imageInfo.size.height - if (this.imageKnifeOption.mainScaleType == ScaleType.AUTO_WIDTH){ - this.currentSize.width=this.context.height*scaleWidth - }else if (this.imageKnifeOption.mainScaleType == ScaleType.AUTO_HEIGHT){ - this.currentSize.height=this.context.width*scaleHeight - }else if (this.imageKnifeOption.mainScaleType == ScaleType.AUTO){ - this.currentSize.height=imageInfo.size.height - this.currentSize.width =imageInfo.size.width - } - ScaleTypeHelper.drawImageWithScaleType(context, scaleType, data.drawPixelMap?.imagePixelMap, px2vp(imageInfo.size.width), px2vp(imageInfo.size.height), compWidth, compHeight, 0, 0) - context.restore(); - LogUtil.log('ImageKnifeComponent default drawMainSource end!') - }) - if (data.drawPixelMap != undefined) { - data.drawPixelMap.isShowOnComponent = true; - this.detachFromLayoutPixelMap = data.drawPixelMap.detachFromLayoutPixelMap; - } - } else if (data.isGIFFrame()) { - if(data.drawGIFFrame != undefined) { - data.drawGIFFrame.isShowOnComponent = true - this.detachFromLayoutGIF = data.drawGIFFrame.detachFromLayoutGIF - this.drawGIFFrame(context, data, imageKnifeOption, compWidth, compHeight, setGifTimeId) - } - } - } - - drawRetryholder(context: CanvasRenderingContext2D, data: ImageKnifeData, imageKnifeOption: ImageKnifeOption, compWidth: number, compHeight: number, setGifTimeId?: (timeId: number) => void) { - LogUtil.log('ImageKnifeComponent default drawRetryholder start!') - // API12 getImageInfoSync同步 - // if(data.drawPixelMap?.imagePixelMap != undefined) { - // let imageInfo = data.drawPixelMap?.imagePixelMap.getImageInfoSync() - // LogUtil.log('ImageKnifeComponent 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(); - // LogUtil.log('ImageKnifeComponent default drawRetryholder end!') - // } - // getImageInfo异步 - data.drawPixelMap?.imagePixelMap?.getImageInfo().then((imageInfo) => { - LogUtil.log('ImageKnifeComponent 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(); - LogUtil.log('ImageKnifeComponent default drawRetryholder end!') - }) - } - - drawErrorholder(context: CanvasRenderingContext2D, data: ImageKnifeData, imageKnifeOption: ImageKnifeOption, compWidth: number, compHeight: number, setGifTimeId?: (timeId: number) => void) { - LogUtil.log('ImageKnifeComponent default drawErrorholder start!') - // API12 getImageInfoSync同步 - // if(data.drawPixelMap?.imagePixelMap != undefined) { - // let imageInfo = data.drawPixelMap?.imagePixelMap.getImageInfoSync() - // LogUtil.log('ImageKnifeComponent imageinfo width =' + 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(); - // LogUtil.log('ImageKnifeComponent default drawErrorholder end!') - // } - // getImageInfo异步 - data.drawPixelMap?.imagePixelMap?.getImageInfo().then((imageInfo) => { - LogUtil.log('ImageKnifeComponent imageinfo width =' + 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(); - LogUtil.log('ImageKnifeComponent default drawErrorholder end!') - }) - } - - requestAddTransform(request: RequestOption) { - if (TransformType.BlurTransformation == this.imageKnifeOption.transform?.transformType) { - request.blur(this.imageKnifeOption.transform?.blur?.radius,this.imageKnifeOption.transform?.blur?.sampling) - } else if (TransformType.BrightnessFilterTransformation == this.imageKnifeOption.transform?.transformType) { - request.brightnessFilter(this.imageKnifeOption.transform?.brightnessFilter) - } else if (TransformType.ContrastFilterTransformation == this.imageKnifeOption.transform?.transformType) { - request.contrastFilter(this.imageKnifeOption.transform?.contrastFilter) - } else if (TransformType.CropCircleTransformation == this.imageKnifeOption.transform?.transformType) { - request.cropCircle() - } 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) { - 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) { - request.grayscale() - } else if (TransformType.InvertFilterTransformation == this.imageKnifeOption.transform?.transformType) { - request.invertFilter() - } else if (TransformType.MaskTransformation == this.imageKnifeOption.transform?.transformType) { - request.mask(this.imageKnifeOption.transform?.mask) - } else if (TransformType.PixelationFilterTransformation == this.imageKnifeOption.transform?.transformType) { - request.pixelationFilter(this.imageKnifeOption.transform?.pixelationFilter) - } else if (TransformType.RotateImageTransformation == this.imageKnifeOption.transform?.transformType) { - request.rotateImage(this.imageKnifeOption.transform?.rotateImage) - } else if (TransformType.RoundedCornersTransformation == this.imageKnifeOption.transform?.transformType) { - request.roundedCorners(this.imageKnifeOption.transform?.roundedCorners) - } else if (TransformType.SepiaFilterTransformation == this.imageKnifeOption.transform?.transformType) { - request.sepiaFilter() - } else if (TransformType.SketchFilterTransformation == this.imageKnifeOption.transform?.transformType) { - request.sketchFilter() - } else if (TransformType.SwirlFilterTransformation == this.imageKnifeOption.transform?.transformType) { - request.swirlFilter(this.imageKnifeOption.transform?.swirlFilter) - } else if (TransformType.CenterCrop == this.imageKnifeOption.transform?.transformType) { - request.centerCrop() - } else if (TransformType.CenterInside == this.imageKnifeOption.transform?.transformType) { - request.centerInside() - } else if (TransformType.FitCenter == this.imageKnifeOption.transform?.transformType) { - request.fitCenter() - } - } - aboutToRecycle(){ - this.resetGifData() - } - aboutToAppear() { - LogUtil.log('ImageKnifeComponent aboutToAppear happened!') - this.canvasHasReady = false; - this.whetherWaitSize(true); - - this.listener.on("layout",this.onLayoutComplete) - } - - aboutToDisappear() { - LogUtil.log('ImageKnifeComponent aboutToDisappear happened!') - if(this.detachFromLayout != undefined){ - this.detachFromLayout.detach(); - } - if(this.detachFromLayoutGIF != undefined){ - this.detachFromLayoutGIF.detach(); - } - if (this.detachFromLayoutPixelMap != undefined) { - this.detachFromLayoutPixelMap.detach(); - } - if(this.isGif){ - this.resetGifData(); - } - this.listener.off("layout",this.onLayoutComplete) - } - - onPageShow() { - } - - onPageHide() { - } - - onBackPress() { - } - - setGifTimeId(timeId: number) { - this.gifTimerId = timeId; - } - - private drawLifeCycleHasConsumed( methodName: string, - context: CanvasRenderingContext2D, data: K, imageKnifeOption: T, compWidth: number, compHeight: number, setGifTimeId?: (timeId: number) => void,drawLifeCycle?: IDrawLifeCycle - ):boolean { - if (drawLifeCycle && (drawLifeCycle as Record)[methodName]) { - return (drawLifeCycle as Record)[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[] - LogUtil.log('ImageKnifeComponent 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_frames = frames - this.renderFrames_index = 0 - this.renderFrames_context = context - this.renderFrames_compWidth = compWidth - this.renderFrames_compHeight = compHeight - - this.renderFrames() - } - } - - 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) { - if(this.imageKnifeOption.gif != undefined && this.imageKnifeOption.gif.seekTo != undefined) { - for (let i = 0; i < this.imageKnifeOption.gif.seekTo; i++) { - this.drawFrame(frames, i, context, compWidth, compHeight); - } - } - } - - renderFrames_frames: GIFFrame[] | undefined = undefined - renderFrames_index: number = 0; - renderFrames_context: CanvasRenderingContext2D | undefined = undefined; - renderFrames_compWidth: number = 0; - renderFrames_compHeight: number = 0 - - renderFrames:()=>void = ()=> { - LogUtil.log('ImageKnifeComponent renderFrames frames length =' + this.renderFrames_frames?.length) - let start = new Date().getTime(); - if (this.renderFrames_index === 0) { - // 如果是第一帧,我们只从开始渲染前记录时间 - this.startGifLoopTime = start; - } - // draw Frame - this.drawFrame(this.renderFrames_frames, this.renderFrames_index, this.renderFrames_context, this.renderFrames_compWidth, this.renderFrames_compHeight); - //如果gif动图只有一帧的情况下,不进行后面代码的逐帧绘制循环 - if (this.renderFrames_frames != undefined && this.renderFrames_frames.length <= 1) { - return - } - - // 记录渲染结束时间点 - let end = new Date().getTime(); - let diff = end - start - - if (this.autoPlay) { - - // 理论上该帧在屏幕上保留的时间 - let stayTime:number= 0 - if(this.renderFrames_frames != undefined) { - stayTime = this.renderFrames_frames[this.renderFrames_index].delay; - } - if (this.imageKnifeOption.gif && this.imageKnifeOption.gif.speedFactory) { - stayTime = stayTime / (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 (this.renderFrames_frames != undefined && this.renderFrames_index === (this.renderFrames_frames.length - 1) && this.imageKnifeOption.gif != undefined && this.imageKnifeOption.gif?.loopFinish) { - this.imageKnifeOption.gif.loopFinish(this.gifLoopDuration) - this.gifLoopDuration = 0; - } - // update the frame index - this.renderFrames_index++ - if (this.renderFrames_frames != undefined && this.renderFrames_index >= this.renderFrames_frames.length) { - this.renderFrames_index = 0; - } - this.gifTimerId = setTimeout(this.renderFrames, delayTime) - } - } - - private drawFrame(frames: GIFFrame[]|undefined, index: number, context: CanvasRenderingContext2D|undefined, compWidth: number, compHeight: number) { - if(frames == undefined){ - return - } - // 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) { - LogUtil.log('ImageKnifeComponent canvasDrawPixelMap index=' + index) - let frame = frames[index]; - let pixelmap = frame['drawPixelMap'] - 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(); - LogUtil.log('ImageKnifeComponent canvasDrawPixelMap 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 AntiAliasing { - // 抗锯齿设置为高画质 - FIT_HIGH = 'high', - // 抗锯齿设置为中画质 - FIT_MEDIUM = 'medium', - // 抗锯齿设置为低画质 - FIT_LOW = 'low' -} - -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, - // 设置宽的时候,图片高度自适应 - AUTO_HEIGHT =9, - // 设置高的时候,图片宽度自适应 - AUTO_WIDTH =10, - //没有设置宽和高,图片按照自身宽高显示 - AUTO =11 -} - - -export class ScaleTypeHelper { - static drawImageWithScaleType(context: CanvasRenderingContext2D, scaleType: ScaleType, source: PixelMap | undefined, 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.drawFitCenter(context, source, minScale, imageWidth, imageHeight, compWidth, compHeight, imageOffsetX, imageOffsetY) - break - } - - } - - static drawFitStart(context: CanvasRenderingContext2D, source: PixelMap | undefined, minScale: number, imageWidth: number, imageHeight: number, imageOffsetX?: number, imageOffsetY?: number) { - context.setTransform(minScale, 0, 0, minScale, 0, 0) - let dx:number = 0 - let dy:number = 0 - let dw:number = imageWidth; - let dh:number = imageHeight; - if(source!= undefined) { - context.drawImage(source, dx + (imageOffsetX != undefined ? imageOffsetX : 0), dy + (imageOffsetY != undefined ? imageOffsetY : 0)) - } - } - - static drawFitEnd(context: CanvasRenderingContext2D, source: PixelMap | undefined, minScale: number, imageWidth: number, imageHeight: number, compWidth: number, compHeight: number, imageOffsetX?: number, imageOffsetY?: number) { - context.setTransform(minScale, 0, 0, minScale, 0, 0) - - let dx:number = (compWidth - imageWidth * minScale) / (minScale * 1.0); - let dy:number = (compHeight - imageHeight * minScale) / (minScale * 1.0); - let dw:number = imageWidth; - let dh:number = imageHeight; - if(source!= undefined) { - context.drawImage(source, dx + (imageOffsetX != undefined ? imageOffsetX : 0), dy + (imageOffsetY != undefined ? imageOffsetY : 0)) - } - } - - static drawFitCenter(context: CanvasRenderingContext2D, source: PixelMap | undefined, minScale: number, imageWidth: number, imageHeight: number, compWidth: number, compHeight: number, imageOffsetX?: number, imageOffsetY?: number) { - context.setTransform(minScale, 0, 0, minScale, 0, 0) - let dx:number = (compWidth - imageWidth * minScale) / (minScale * 2.0); - let dy:number = (compHeight - imageHeight * minScale) / (minScale * 2.0); - let dw:number = imageWidth; - let dh:number = imageHeight; - if(source!= undefined) { - context.drawImage(source, dx + (imageOffsetX != undefined ? imageOffsetX : 0), dy + (imageOffsetY != undefined ? imageOffsetY : 0)) - } - } - - static drawCenter(context: CanvasRenderingContext2D, source: PixelMap | undefined, imageWidth: number, imageHeight: number, compWidth: number, compHeight: number, imageOffsetX?: number, imageOffsetY?: number) { - let dx:number = (compWidth - imageWidth) / 2.0; - let dy:number = (compHeight - imageHeight) / 2.0; - let dw:number = imageWidth; - let dh:number = imageHeight; - if(source!= undefined) { - context.drawImage(source, dx + (imageOffsetX != undefined ? imageOffsetX : 0), dy + (imageOffsetY != undefined ? imageOffsetY : 0)) - } - } - - static drawCenterCrop(context: CanvasRenderingContext2D, source: PixelMap | undefined, maxScale: number, imageWidth: number, imageHeight: number, compWidth: number, compHeight: number, imageOffsetX?: number, imageOffsetY?: number) { - context.setTransform(maxScale, 0, 0, maxScale, 0, 0) - let dx:number = (compWidth - imageWidth * maxScale) / (maxScale * 2.0); - let dy:number = (compHeight - imageHeight * maxScale) / (maxScale * 2.0); - let dw:number = imageWidth; - let dh:number = imageHeight; - if(source!= undefined) { - context.drawImage(source, dx + (imageOffsetX != undefined ? imageOffsetX : 0), dy + (imageOffsetY != undefined ? imageOffsetY : 0)) - } - } - - static drawFitXY(context: CanvasRenderingContext2D, source: PixelMap | undefined, scaleW: number, scaleH: number, imageWidth: number, imageHeight: number, imageOffsetX?: number, imageOffsetY?: number) { - context.setTransform(scaleW, 0, 0, scaleH, 0, 0) - let dx:number = 0; - let dy:number = 0; - let dw:number = imageWidth; - let dh:number = imageHeight; - if(source!= undefined) { - context.drawImage(source, dx + (imageOffsetX != undefined ? imageOffsetX : 0), dy + (imageOffsetY != undefined ? imageOffsetY : 0)) - } - } - - static drawCenterInside(context: CanvasRenderingContext2D, source: PixelMap | undefined, 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 | undefined, imageWidth: number, imageHeight: number, imageOffsetX?: number, imageOffsetY?: number) { - let dx:number = 0; - let dy:number = 0; - let dw:number = imageWidth; - let dh:number = imageHeight; - if(source!= undefined) { - context.drawImage(source, dx + (imageOffsetX != undefined ? imageOffsetX : 0), dy + (imageOffsetY != undefined ? imageOffsetY : 0)) - } - } -} - - - - - diff --git a/library/src/main/ets/components/imageknife/ImageKnifeData.ets b/library/src/main/ets/components/imageknife/ImageKnifeData.ets deleted file mode 100644 index 2b17d4c..0000000 --- a/library/src/main/ets/components/imageknife/ImageKnifeData.ets +++ /dev/null @@ -1,203 +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 { GIFFrame } from './utils/gif/GIFFrame' -import { DetachFromLayout } from './RequestOption' -import { LogUtil } from './utils/LogUtil' - -export enum ImageKnifeType { - PIXELMAP = 'PixelMap', - STRING = 'String', - RESOURCE = 'Resource', - GIFFRAME = 'GIFFrame' -} - -export class DrawPixelMap { - imagePixelMap: PixelMap | undefined = undefined - isShowOnComponent: boolean = false; // gif是否显示在组件上 true:显示在组件上 false:不显示在组件上 - isLruCacheRelease: boolean = false; // 当前lru是否释放gif资源,true的就释放了gif资源 false就是没有释放 - - detachFromLayoutPixelMap: DetachFromLayout = { - detach: () => { - this.isShowOnComponent = false - if (this.isLruCacheRelease) { - let pixelMap = this.imagePixelMap; - if (pixelMap != undefined) { - pixelMap.release(); - } - this.imagePixelMap = undefined; - } - } - } -} - -export class DrawString { - imageString: string | undefined = undefined -} - -export class DrawResource { - imageResource: Resource | undefined = undefined -} - -export class DrawGIFFrame { - imageGIFFrames: GIFFrame[] | undefined = undefined - isShowOnComponent: boolean = false; //gif是否显示在组件上 true:显示在组件上 false:不显示在组件上 - isLruCacheRelease: boolean = false; //当前lru是否释放gif资源,true的就释放了gif资源 false就是没有释放 - - detachFromLayoutGIF: DetachFromLayout = { - detach: () => { - this.isShowOnComponent = false - if (this.isLruCacheRelease) { - let gifFrames = this.imageGIFFrames; - if (gifFrames != undefined) { - for (let i = 0; i < gifFrames.length; i++) { - let tempFrame = gifFrames[i]; - if (tempFrame.drawPixelMap != undefined) { - tempFrame.drawPixelMap.release() - } - } - } - this.imageGIFFrames = undefined; - } - } - }; - - getGIFFramesBytesNumber(): number { - let pixelMapBytes: number = 0; - if (this.imageGIFFrames != undefined) { - for (let index = 0; index < this.imageGIFFrames.length; index++) { - let drawPixelMap = this.imageGIFFrames[index].drawPixelMap; - if (drawPixelMap != undefined) { - pixelMapBytes += drawPixelMap.getPixelBytesNumber(); - LogUtil.info("getGIFFramesBytesNumber gif总大小为:" + pixelMapBytes); - } - } - } - return pixelMapBytes; - } -} - -export class ImageKnifeData { - static SVG = 'svg'; - static GIF = 'gif'; - static JPG = 'jpg'; - static PNG = 'png'; - static BMP = 'bmp'; - static WEBP = 'webp'; - waitSaveDisk = false; - needSaveDisk = false; - imageKnifeType: ImageKnifeType | undefined = undefined; - drawPixelMap: DrawPixelMap | undefined = undefined; - drawGIFFrame: DrawGIFFrame | undefined = undefined; - drawResource: DrawResource | undefined = undefined; - drawString: DrawString | undefined = undefined; - - static createImagePixelMap(type: ImageKnifeType, value: PixelMap) { - let data = new ImageKnifeData(); - data.imageKnifeType = type; - data.drawPixelMap = new DrawPixelMap(); - data.drawPixelMap.imagePixelMap = value; - data.drawPixelMap.isShowOnComponent = true; - return data; - } - - static createImageGIFFrame(type: ImageKnifeType, value: GIFFrame[]) { - let data = new ImageKnifeData(); - data.imageKnifeType = type; - data.drawGIFFrame = new DrawGIFFrame(); - data.drawGIFFrame.imageGIFFrames = value; - data.drawGIFFrame.isShowOnComponent = true; - return data; - } - - isPixelMap(): boolean { - return ImageKnifeType.PIXELMAP == this.imageKnifeType; - } - - isGIFFrame(): boolean { - return ImageKnifeType.GIFFRAME == this.imageKnifeType; - } - - isString(): boolean { - return ImageKnifeType.STRING == this.imageKnifeType; - } - - isResource(): boolean { - return ImageKnifeType.RESOURCE == this.imageKnifeType; - } - - release() { - let promise = new Promise((resolve) => { - resolve() - }) - if (this.isPixelMap()) { - if (this.drawPixelMap != undefined && this.drawPixelMap.imagePixelMap != undefined) { - this.drawPixelMap.isLruCacheRelease = true; - if (this.drawPixelMap.isShowOnComponent) { - return; - } else { - promise.then(() => { - if (this.drawPixelMap != undefined && this.drawPixelMap.imagePixelMap != undefined) { - this.drawPixelMap.imagePixelMap.release(() => { - if (this.drawPixelMap != undefined && this.drawPixelMap.imagePixelMap != undefined) { - this.drawPixelMap.imagePixelMap = undefined - } - }) - } - }) - } - LogUtil.info("MemoryLruCache removeMemorySize---- end 释放普通图片:") - } - } - if (this.isGIFFrame()) { - if (this.drawGIFFrame != undefined) { - this.drawGIFFrame.isLruCacheRelease = true; - - if (this.drawGIFFrame.isShowOnComponent) { - return; - } else { - let gifFrames = this.drawGIFFrame.imageGIFFrames; - if (gifFrames != undefined) { - for (let i = 0; i < gifFrames.length; i++) { - let tempFrame = gifFrames[i]; - if (tempFrame.drawPixelMap != undefined) { - promise.then(() => { - if (tempFrame.drawPixelMap != undefined) { - tempFrame.drawPixelMap.release() - } - }) - } - } - LogUtil.info("MemoryLruCache removeMemorySize---- end 释放GIF图片:") - this.drawGIFFrame.imageGIFFrames = undefined - } - this.drawGIFFrame.imageGIFFrames = undefined - } - } - } - - if (this.isString()) { - if (this.drawString != undefined && this.drawString.imageString != undefined) { - this.drawString.imageString = undefined - } - } - - if (this.isResource()) { - if (this.drawResource != undefined && this.drawResource.imageResource != undefined) { - this.drawResource.imageResource = undefined - } - } - - } -} \ No newline at end of file diff --git a/library/src/main/ets/components/imageknife/ImageKnifeDrawFactory.ets b/library/src/main/ets/components/imageknife/ImageKnifeDrawFactory.ets deleted file mode 100644 index f67bfad..0000000 --- a/library/src/main/ets/components/imageknife/ImageKnifeDrawFactory.ets +++ /dev/null @@ -1,480 +0,0 @@ -/* - * 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:IDrawLifeCycle = { - // 展示占位图 - displayPlaceholder: (context: CanvasRenderingContext2D, data: ImageKnifeData, imageKnifeOption: ImageKnifeOption, compWidth: number, compHeight: number, setGifTimeId?: (timeId: number) => void) => { - - 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) => { - - return false; - }, - - // 展示主图 - displayMainSource: (context: CanvasRenderingContext2D, data: ImageKnifeData, imageKnifeOption: ImageKnifeOption, compWidth: number, compHeight: number, setGifTimeId?: (timeId: number) => void) => { - if (data.isPixelMap()) { - - 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(); - ImageKnifeDrawFactory.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(); - ImageKnifeDrawFactory.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 | undefined, 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 = imageHeight * 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 = compHeight / 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 = compHeight / 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:IDrawLifeCycle = { - // 展示占位图 - displayPlaceholder: (context: CanvasRenderingContext2D, data: ImageKnifeData, imageKnifeOption: ImageKnifeOption, compWidth: number, compHeight: number, setGifTimeId?: (timeId: number) => void) => { - - 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) => { - - return false; - }, - - // 展示主图 - displayMainSource: (context: CanvasRenderingContext2D, data: ImageKnifeData, imageKnifeOption: ImageKnifeOption, compWidth: number, compHeight: number, setGifTimeId?: (timeId: number) => void) => { - if (data.isPixelMap()) { - - 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' - ImageKnifeDrawFactory.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' - ImageKnifeDrawFactory.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(); - }) - 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 | undefined, 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 = compHeight - borderWidth; - switch (scaleType) { - case ScaleType.FIT_START: - x1 = borderWidth/2 - y1 = borderWidth/2 - w1 = imageWidth * minScale - borderWidth; - h1 = imageHeight * minScale - borderWidth; - ImageKnifeDrawFactory.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; - ImageKnifeDrawFactory.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 - ImageKnifeDrawFactory.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; - - ImageKnifeDrawFactory.roundRect(context, x1, y1, w1, h1, cornerRadius) - break - case ScaleType.CENTER_CROP: - x1 = borderWidth/2 - y1 = borderWidth/2 - - w1 = compWidth - borderWidth; - h1 = compHeight - borderWidth; - ImageKnifeDrawFactory.roundRect(context, x1, y1, w1, h1, cornerRadius) - break - case ScaleType.FIT_XY: - x1 = borderWidth/2 - y1 = borderWidth/2 - - w1 = compWidth - borderWidth; - h1 = compHeight - borderWidth; - ImageKnifeDrawFactory.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 - ImageKnifeDrawFactory.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; - - ImageKnifeDrawFactory.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; - - ImageKnifeDrawFactory.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) => { - - return false; - }, - // 展示加载进度 - displayProgress: (context: CanvasRenderingContext2D, progress: number, imageKnifeOption: ImageKnifeOption, compWidth: number, compHeight: number, setGifTimeId?: (timeId: number) => void) => { - - ImageKnifeDrawFactory.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) => { - - return false; - }, - - // 展示主图 - displayMainSource: (context: CanvasRenderingContext2D, data: ImageKnifeData, imageKnifeOption: ImageKnifeOption, compWidth: number, compHeight: number, setGifTimeId?: (timeId: number) => void) => { - - 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 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(); - } - - -} \ No newline at end of file diff --git a/library/src/main/ets/components/imageknife/ImageKnifeGlobal.ets b/library/src/main/ets/components/imageknife/ImageKnifeGlobal.ets deleted file mode 100644 index 1672a8f..0000000 --- a/library/src/main/ets/components/imageknife/ImageKnifeGlobal.ets +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (C) 2023 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the 'License'); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an 'AS IS' BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import { ImageKnife } from './ImageKnife'; -import { LogUtil } from './utils/LogUtil'; -export enum GlobalEnum{ - // 主hap的context对象key - HAP_CONTEXT_KEY = 'HAP_CONTEXT_KEY', - // ImageKnife的对象key - IMAGE_KNIFE_KEY = 'IMAGE_KNIFE_KEY' -} - -// 构造单例对象 -export class ImageKnifeGlobal { - private constructor() {} - private static instance: ImageKnifeGlobal; - private _objects = new Map(); - - - public static getInstance(): ImageKnifeGlobal { - if (!ImageKnifeGlobal.instance) { - ImageKnifeGlobal.instance = new ImageKnifeGlobal(); - } - return ImageKnifeGlobal.instance; - } - - getObject(value: string): Object | undefined { - return this._objects.get(value); - } - - setObject(key: string, objectClass: Object): void { - this._objects.set(key, objectClass); - } - - getImageKnife():ImageKnife | undefined{ - let imageKnifeObj:Object | undefined = this._objects.get(GlobalEnum.IMAGE_KNIFE_KEY); - if(imageKnifeObj == undefined){ - LogUtil.error('ImageKnifeGlobal imageKnifeObj is undefined, you need to initialize before using') - return undefined - }else{ - return (imageKnifeObj as ImageKnife) - } - } - - setImageKnife(imageKnife:Object):void{ - this._objects.set(GlobalEnum.IMAGE_KNIFE_KEY, imageKnife); - } - - getHapContext():Object | undefined{ - let hapContext:Object | undefined = this._objects.get(GlobalEnum.HAP_CONTEXT_KEY); - if(hapContext == undefined){ - LogUtil.error('ImageKnifeGlobal hapContext is undefined, you need to initialize before using') - return undefined - }else{ - return hapContext - } - } - - setHapContext(hapContext:Object):void{ - this._objects.set(GlobalEnum.HAP_CONTEXT_KEY, hapContext); - } - - -} \ No newline at end of file diff --git a/library/src/main/ets/components/imageknife/ImageKnifeOption.ets b/library/src/main/ets/components/imageknife/ImageKnifeOption.ets deleted file mode 100644 index 12816a1..0000000 --- a/library/src/main/ets/components/imageknife/ImageKnifeOption.ets +++ /dev/null @@ -1,146 +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 { 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' -import { rgbColor } from './transform/CropCircleWithBorderTransformation' -import { RoundCorner } from './transform/RoundedCornersTransformation' -import { ObjectKey } from './ObjectKey' -import common from '@ohos.app.ability.common' -import { Priority } from './RequestOption' - -export interface CropCircleWithBorder{ - border: number, - obj: rgbColor -} - -export interface Crop{ - width: number, - height: number, - cropType: CropType -} -export interface BlurType { - radius: number, - sampling: number -} -export interface GifOptions{ - loopFinish?: (loopTime?:number) => void - speedFactory?: number - seekTo?: number -} -export interface TransformOptions{ - transformType: number, - blur?: BlurType, - roundedCorners?: RoundCorner - cropCircleWithBorder?: CropCircleWithBorder - crop?:Crop - brightnessFilter?: number, - contrastFilter?: number, - pixelationFilter?: number, - swirlFilter?: number, - mask?: Resource, - rotateImage?: number -} - -export interface HeaderOptions { - key: string; - value: string; -} - -@Observed -export class ImageKnifeOption { - // header请求列表 - headerOption?: Array; - // 主图资源 - loadSrc: string | PixelMap | Resource = ''; - mainScaleType?: ScaleType = ScaleType.FIT_CENTER - // 优先级 - priority?: Priority = Priority.MEDIUM - enableGpu?:boolean = true; - - // 磁盘缓存策略 - strategy?: DiskStrategy = new AUTOMATIC(); - - // gif加载展示一帧 - dontAnimateFlag? = false; - - // 占位图 - 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; - - - // 自定义缓存关键字 - signature?: ObjectKey; - - // 重试图层 可点击 - canRetryClick?: boolean; - - // 仅使用缓存加载数据 - onlyRetrieveFromCache?: boolean = false; - - // 是否开启一级内存缓存 - isCacheable?: boolean = true; - - - // 用户自定义实现 绘制方案 - drawLifeCycle?: IDrawLifeCycle; - - // 设置点击事件回调 - onClick?:(event?: ClickEvent) => void - - gif?: GifOptions = undefined; - - - // 变换相关 不推荐使用该接口 建议直接使用transformation transformations这2个接口实现 - transform?:TransformOptions = undefined - transformation?: BaseTransform; - transformations?: Array>; - - // 输出缓存相关内容和信息 - allCacheInfoCallback?: IAllCacheInfoCallback; - - - context?: common.UIAbilityContext; -// sizeAnimate?: AnimateParam 由业务自定义不再支持 - - constructor() { - - } -} \ No newline at end of file diff --git a/library/src/main/ets/components/imageknife/ObjectKey.ets b/library/src/main/ets/components/imageknife/ObjectKey.ets deleted file mode 100644 index 9a121ae..0000000 --- a/library/src/main/ets/components/imageknife/ObjectKey.ets +++ /dev/null @@ -1,28 +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. - */ -export class ObjectKey{ - - private objectKey: string; - - constructor(objectKey: string) { - this.objectKey = objectKey; - } - - getKey(): string{ - return this.objectKey; - } - - -} \ No newline at end of file diff --git a/library/src/main/ets/components/imageknife/RequestOption.ets b/library/src/main/ets/components/imageknife/RequestOption.ets deleted file mode 100644 index 001d464..0000000 --- a/library/src/main/ets/components/imageknife/RequestOption.ets +++ /dev/null @@ -1,631 +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 { ImageKnife } from './ImageKnife' -import { DiskStrategy } from "../cache/diskstrategy/DiskStrategy" -import { AsyncCallback } from "../imageknife/interface/AsyncCallback" -import { AsyncSuccess } from "../imageknife/interface/AsyncSuccess" -import { AllCacheInfo, IAllCacheInfoCallback } from "../imageknife/interface/IAllCacheInfoCallback" -import { AUTOMATIC } from "../cache/diskstrategy/enum/AUTOMATIC" -import { BaseTransform } from "../imageknife/transform/BaseTransform" -import { RotateImageTransformation } from "../imageknife/transform/RotateImageTransformation" -import { ImageKnifeData, ImageKnifeType } from "../imageknife/ImageKnifeData" -import { CenterCrop } from '../imageknife/transform/pixelmap/CenterCrop' -import { CenterInside } from '../imageknife/transform/pixelmap/CenterInside' -import { FitCenter } from '../imageknife/transform/pixelmap/FitCenter' -import { RoundedCornersTransformation, RoundCorner } from '../imageknife/transform/RoundedCornersTransformation' - -import { CropCircleTransformation } from '../imageknife/transform/CropCircleTransformation' - -import { - CropCircleWithBorderTransformation, - rgbColor -} from '../imageknife/transform/CropCircleWithBorderTransformation' -import { CropSquareTransformation } from '../imageknife/transform/CropSquareTransformation' -import { CropTransformation } from '../imageknife/transform/CropTransformation' -import { CropType } from '../imageknife/transform/CropTransformation' -import { GrayscaleTransformation } from '../imageknife/transform/GrayscaleTransformation' -import { BrightnessFilterTransformation } from '../imageknife/transform/BrightnessFilterTransformation' -import { ContrastFilterTransformation } from '../imageknife/transform/ContrastFilterTransformation' -import { InvertFilterTransformation } from '../imageknife/transform/InvertFilterTransformation' -import { SepiaFilterTransformation } from '../imageknife/transform/SepiaFilterTransformation' -import { SketchFilterTransformation } from '../imageknife/transform/SketchFilterTransformation' -import { BlurTransformation } from '../imageknife/transform/BlurTransformation' -import { PixelationFilterTransformation } from '../imageknife/transform/PixelationFilterTransformation' -import { MaskTransformation } from '../imageknife/transform/MaskTransformation' -import { SwirlFilterTransformation } from '../imageknife/transform/SwirlFilterTransformation' -import { KuwaharaFilterTransform } from '../imageknife/transform/KuwaharaFilterTransform' -import { ToonFilterTransform } from '../imageknife/transform/ToonFilterTransform' -import { VignetteFilterTransform } from '../imageknife/transform/VignetteFilterTransform' -import { LogUtil } from '../imageknife/utils/LogUtil' -import { ImageKnifeGlobal } from './ImageKnifeGlobal' -import { BusinessError } from '@ohos.base' -import { ObjectKey } from './ObjectKey' -import common from '@ohos.app.ability.common' -import { GIFFrame } from './utils/gif/GIFFrame' -import { DiskCacheProxy } from './requestmanage/DiskCacheProxy' -import { DiskLruCache } from '../cache/DiskLruCache' -import { SparkMD5 } from '../3rd_party/sparkmd5/spark-md5' -import { FileUtils } from '../cache/FileUtils' - -export interface Size { - width: number, - height: number -} - -export interface DetachFromLayout { - detach: () => void -} -export enum Priority { - HIGH = 0, - MEDIUM = 1, - LOW = 2 -} -export class RequestOption { - // 遍历添加图片http请求头 - headers: Map = new Map(); - - // RequestOption调用header对于的方法 - addHeader(key: string, value: Object) { - this.headers.set(key, value); - } - - // 全局调用header对应的方法,包含RequestOption的形式 - addHeaderMap(map: Map) { - this.headers = map; - } - // 优先级 - priority: Priority = Priority.MEDIUM; - uuid: string = '' // 唯一标识 - loadSrc: string | PixelMap | Resource = ''; - strategy: DiskStrategy = new AUTOMATIC(); - dontAnimateFlag = false; - placeholderSrc: PixelMap | Resource | undefined = undefined; - placeholderFunc: AsyncSuccess | undefined = undefined; - errorholderSrc: PixelMap | Resource | undefined = undefined; - errorholderFunc: AsyncSuccess | undefined = undefined; - errorholderData: ImageKnifeData | undefined = undefined; - thumbSizeMultiplier: number = 0; - // 如果存在缩略图,则主图延时1s加载 - thumbDelayTime: number = 1000 - thumbHolderFunc: AsyncSuccess | undefined = undefined; - requestListeners: Array> | undefined = undefined; - // 进度条 - progressFunc: AsyncSuccess | undefined = undefined; - // 重试图层 - retryholderSrc: PixelMap | Resource | undefined = undefined; - retryholderFunc: AsyncSuccess | undefined = undefined; - retryholderData: ImageKnifeData | undefined = undefined; - size: Size = { width: -1, height: -1 }; - // 网络下载数据回调 - allCacheInfoCallback: IAllCacheInfoCallback | undefined = undefined; - onlyRetrieveFromCache: boolean = false; - isCacheable: boolean = true; - // 开启GPU变换绘制 - gpuEnabled: boolean = false; - // 变换相关 - transformations: Array> = new Array(); - generateCacheKey: string = ""; - generateResourceKey: string = ""; - generateDataKey: string = ""; - filesPath: string = ""; // data/data/包名/files目录 - cachesPath: string = ""; // 网络下载默认存储在data/data/包名/cache/ImageKnifeNetworkFolder/目标md5.img下面 - placeholderCacheKey: string = ""; - retryholderCacheKey: string = ""; - errorholderCacheKey: string = ""; - // 自定义缓存关键字 - signature?: ObjectKey; - // 下载原始文件地址 - downloadFilePath: string = ""; - //磁盘缓存文件路径 - diskMemoryCachePath: string =""; - // 网络文件下载统一存放 - networkCacheFolder: string = "ImageKnifeNetworkFolder" - // 主线图片 状态变化 是否加载完成 - // 主图未加载成功 显示占位图 主图加载成功不展示占位图 - loadMainReady = false; - // 失败占位图展示状态 当true 表示主图加载失败需要展示失败占位图 - loadErrorReady = false; - // 重试占位图展示状态 当true 表示主图加载失败需要展示失败占位图 - loadRetryReady = false; - // 缩略图展示 - loadThumbnailReady = false; - detachFromLayout: DetachFromLayout = { - detach: () => { - let imageKnife: ImageKnife | undefined = ImageKnifeGlobal.getInstance().getImageKnife(); - if (imageKnife != undefined) { - imageKnife.remove(this.uuid); - } - } - } - // module资源的需要当前的module context - moduleContext?: common.UIAbilityContext = undefined; - - constructor() { - // 初始化全局监听 - this.requestListeners = new Array(); - // 初始化唯一标识,可以用这个标识找到ImageKnife中的对象 - this.uuid = this.generateUUID(); - - - let ctx = ImageKnifeGlobal.getInstance().getHapContext() as common.UIAbilityContext - if (ctx != undefined) { - this.moduleContext = ctx; - } - } - setPriority(priority: Priority) { - this.priority = priority - } - setTransformations( array:Array>){ - this.transformations = array; - } - generateUUID(): string { - let d = new Date().getTime(); - const uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(new RegExp("[xy]", "g"), (c) => { - const r = (d + Math.random() * 16) % 16 | 0; - d = Math.floor(d / 16); - return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16); - }); - return uuid; - } - - setModuleContext(moduleCtx: common.UIAbilityContext) { - this.moduleContext = moduleCtx; - } - - getModuleContext(): common.UIAbilityContext | undefined { - return this.moduleContext; - } - - /** - * set image Component size - */ - setImageViewSize(imageSize: Size) { - this.size.width = imageSize.width; - this.size.height = imageSize.height; - return this; - } - - getFilesPath() { - return this.filesPath; - } - - setFilesPath(path: string) { - this.filesPath = path; - } - - getCachesPath() { - return this.cachesPath; - } - - setCachesPath(path: string) { - this.cachesPath = path; - } - - load(src: string | PixelMap | Resource) { - this.loadSrc = src; - return this; - } - - diskCacheStrategy(strategy: DiskStrategy) { - this.strategy = strategy; - return this; - } - - dontAnimate() { - this.dontAnimateFlag = true; - return this; - } - - // 仅支持 本地图片 - placeholder(src: PixelMap | Resource, func?: AsyncSuccess) { - this.placeholderSrc = src; - this.placeholderFunc = func; - return this; - } - - errorholder(src: PixelMap | Resource, func?: AsyncSuccess) { - this.errorholderSrc = src; - this.errorholderFunc = func; - return this; - } - - retryholder(src: PixelMap | Resource, func?: AsyncSuccess) { - this.retryholderSrc = src; - this.retryholderFunc = func; - return this; - } - - thumbnail(sizeMultiplier: number, func?: AsyncSuccess, displayTime?: number) { - this.thumbSizeMultiplier = sizeMultiplier; - this.thumbHolderFunc = func; - if (displayTime) { - this.thumbDelayTime = displayTime; - } - return this; - } - - addProgressListener(func?: AsyncSuccess) { - this.progressFunc = func; - return this; - } - - addListener(func: AsyncCallback) { - if (this.requestListeners != undefined) { - this.requestListeners?.push(func); - } - return this; - } - - addAllCacheInfoCallback(func: IAllCacheInfoCallback) { - this.allCacheInfoCallback = func; - return this; - } - - skipMemoryCache(skip: boolean) { - this.isCacheable = !skip; - return this; - } - - retrieveDataFromCache(flag: boolean) { - this.onlyRetrieveFromCache = flag; - } - - rotateImage(degreesToRotate: number | undefined) { - if (degreesToRotate == undefined) { - return - } - let rotateImage = new RotateImageTransformation(degreesToRotate); - this.transformations.push(rotateImage); - return this; - } - - centerCrop() { - this.transformations.push(new CenterCrop()); - return this; - } - - centerInside() { - this.transformations.push(new CenterInside()); - return this; - } - - fitCenter() { - this.transformations.push(new FitCenter()); - return this; - } - - roundedCorners(obj: RoundCorner | undefined) { - if (obj == undefined) { - return - } - let transformation = new RoundedCornersTransformation({ - top_left: obj.top_left, - top_right: obj.top_right, - bottom_left: obj.bottom_left, - bottom_right: obj.bottom_right - }) - this.transformations.push(transformation); - return this; - } - - cropCircle() { - let transformation = new CropCircleTransformation() - this.transformations.push(transformation); - return this; - } - - cropCircleWithBorder(border: number | undefined, obj: rgbColor | undefined) { - if (border == undefined || obj == undefined) { - return - } - let transformation = new CropCircleWithBorderTransformation(border, obj) - this.transformations.push(transformation); - return this; - } - - cropSquare() { - let transformation = new CropSquareTransformation() - this.transformations.push(transformation); - return this; - } - - crop(width: number | undefined, height: number | undefined, cropType: CropType | undefined) { - if (width == undefined || height == undefined || cropType == undefined) { - return - } - let transformation = new CropTransformation(width, height, cropType) - this.transformations.push(transformation); - return this; - } - - grayscale() { - let transformation = new GrayscaleTransformation() - this.transformations.push(transformation); - return this; - } - - brightnessFilter(brightness: number | undefined) { - if (brightness == undefined) { - return - } - let transformation = new BrightnessFilterTransformation(brightness) - this.transformations.push(transformation); - return this; - } - - contrastFilter(contrast: number | undefined) { - if (contrast == undefined) { - return - } - let transformation = new ContrastFilterTransformation(contrast) - this.transformations.push(transformation); - return this; - } - - invertFilter() { - let transformation = new InvertFilterTransformation() - this.transformations.push(transformation); - return this; - } - - sepiaFilter() { - let transformation = new SepiaFilterTransformation() - this.transformations.push(transformation); - return this; - } - - sketchFilter() { - let transformation = new SketchFilterTransformation() - this.transformations.push(transformation); - return this; - } - - blur(radius: number | undefined, sampling?: number) { - if (radius == undefined) { - return - } - if (sampling == undefined) { - let transformation = new BlurTransformation(radius) - this.transformations.push(transformation); - } else { - let transformation = new BlurTransformation(radius, sampling) - this.transformations.push(transformation); - } - return this; - } - - pixelationFilter(pixel: number | undefined) { - if (pixel == undefined) { - return - } - let transformation = new PixelationFilterTransformation(pixel) - this.transformations.push(transformation); - return this; - } - - swirlFilter(degree: number | undefined) { - if (degree == undefined) { - return - } - let transformation = new SwirlFilterTransformation(degree) - this.transformations.push(transformation); - return this; - } - - mask(maskResource: Resource | undefined) { - if (maskResource == undefined) { - return - } - let transformation = new MaskTransformation(maskResource) - this.transformations.push(transformation); - return this; - } - - kuwaharaFilter(radius: number | undefined) { - if (radius == undefined) { - return - } - let transformation = new KuwaharaFilterTransform(radius); - this.transformations.push(transformation); - return this; - } - - toonFilter(threshold: number | undefined, quantizationLevels: number | undefined) { - if (threshold == undefined || quantizationLevels == undefined) { - return - } - let transformation = new ToonFilterTransform(threshold, quantizationLevels); - this.transformations.push(transformation); - return this; - } - - vignetteFilter(centerPoint: Array | undefined, vignetteColor: Array | undefined, vignetteSpace: Array | undefined) { - if (centerPoint == undefined || vignetteColor == undefined || vignetteSpace == undefined) { - return - } - let transformation = new VignetteFilterTransform(centerPoint, vignetteColor, vignetteSpace); - this.transformations.push(transformation); - return this; - } - - transform(input: BaseTransform) { - this.transformations.push(input); - return this; - } - - transforms(inputs: BaseTransform[]) { - this.transformations = inputs; - return this; - } - - // 开启GPU变换绘制 - enableGPU() { - this.gpuEnabled = true; - return this; - } - - // 占位图解析成功 - placeholderOnComplete = (imageKnifeData:ImageKnifeData) => { - LogUtil.log("placeholderOnComplete has called!"); - LogUtil.log("Main Image is Ready:" + this.loadMainReady); - if (!this.loadMainReady && !(this.loadErrorReady || this.loadRetryReady) && !this.loadThumbnailReady) { - // 主图未加载成功,并且未加载失败 显示占位图 主图加载成功或者加载失败后=>不展示占位图 - if (this.placeholderSrc != undefined) { - this.placeholderFunc?.asyncSuccess(imageKnifeData) - } - } - } - // 占位图解析失败 - placeholderOnError = (error: BusinessError | string) => { - LogUtil.log("占位图解析失败 error =" + error) - } - // 缩略图解析成功 - thumbholderOnComplete = (value: PixelMap | GIFFrame[]) => { - let imageKnifeData = new ImageKnifeData(); - if ((typeof (value as PixelMap).isEditable) == 'boolean') { - imageKnifeData = ImageKnifeData.createImagePixelMap(ImageKnifeType.PIXELMAP, value as PixelMap); - } else { - imageKnifeData = ImageKnifeData.createImageGIFFrame(ImageKnifeType.GIFFRAME, value as GIFFrame[]); - } - if (!this.loadMainReady && !(this.loadErrorReady || this.loadRetryReady)) { - // 主图未加载成功,并且未加载失败 显示占位图 主图加载成功或者加载失败后=>不展示占位图 - if (this.thumbHolderFunc != undefined) { - this.thumbHolderFunc?.asyncSuccess(imageKnifeData) - } - } - } - // 缩略图解析失败 - thumbholderOnError = (error?: BusinessError | string) => { - LogUtil.log("缩略图解析失败 error =" + error) - } - // 加载失败 占位图解析成功 - errorholderOnComplete = (imageKnifeData:ImageKnifeData) => { - // 如果有错误占位图 先解析并保存在RequestOption中 等到加载失败时候进行调用 - this.errorholderData = imageKnifeData; - if (this.loadErrorReady) { - if (this.errorholderFunc != undefined) { - this.errorholderFunc.asyncSuccess(imageKnifeData) - } - } - } - // 加载失败 占位图解析失败 - errorholderOnError = (error: BusinessError | string) => { - LogUtil.log("失败占位图解析失败 error =" + error) - } - retryholderOnComplete = (imageKnifeData:ImageKnifeData) => { - this.retryholderData = imageKnifeData; - if (this.loadRetryReady) { - if (this.retryholderFunc != undefined) { - this.retryholderFunc?.asyncSuccess(imageKnifeData) - } - } - } - retryholderOnError = (error: BusinessError | string) => { - LogUtil.log("重试占位图解析失败 error =" + error) - } - - loadComplete = (imageKnifeData: ImageKnifeData) => { - this.loadMainReady = true; - // 三级缓存数据加载成功 - if (this.requestListeners != undefined) { - for (let i = 0; i < this.requestListeners.length; i++) { - let requestListener = this.requestListeners[i]; - let boolInterception = requestListener.callback("", imageKnifeData); - if (boolInterception) { - break; - } - } - } - //输出缓存相关内容和信息 - if (this.allCacheInfoCallback) { - // 内存缓存 - let allCacheInfo: AllCacheInfo = { - memoryCacheInfo: { key: '', data: new ImageKnifeData() }, - resourceCacheInfo: { key: '', path: '' }, - dataCacheInfo: { key: '', path: '' } - }; - allCacheInfo.memoryCacheInfo = { - key: this.generateCacheKey, - data: imageKnifeData - } - let mDiskCacheProxy = new DiskCacheProxy(DiskLruCache.create(ImageKnifeGlobal.getInstance() - .getHapContext() as common.UIAbilityContext)) - // 变换后缓存 - allCacheInfo.resourceCacheInfo = { - key: SparkMD5.hashBinary(this.generateResourceKey) as string, - path: (mDiskCacheProxy.getCachePath() + SparkMD5.hashBinary(this.generateResourceKey)) as string - }; - - // 原图缓存 - allCacheInfo.dataCacheInfo = { - key: SparkMD5.hashBinary(this.generateDataKey) as string, - path: (mDiskCacheProxy.getCachePath() + SparkMD5.hashBinary(this.generateDataKey)) as string - } - this.allCacheInfoCallback.callback(allCacheInfo); - } - - if (imageKnifeData.waitSaveDisk) { - // 等落盘结束后主动调用#removeCurrentAndSearchNext方法 - } else { - // 非落盘情况,直接进行寻找下一个加载 - let imageKnife: ImageKnife | undefined = ImageKnifeGlobal.getInstance().getImageKnife(); - if (imageKnife != undefined) { - imageKnife.removeRunning(this); - } - } - } - - // 图片文件落盘之后会自动去寻找下一个数据加载 - removeCurrentAndSearchNext = () => { - if (ImageKnifeGlobal.getInstance().getImageKnife() != undefined) { - (ImageKnifeGlobal.getInstance().getImageKnife())?.removeRunning(this); - } - } - loadError = (err: BusinessError | string) => { - LogUtil.log("loadError:" + err); - // 失败占位图展示规则 - if (this.retryholderFunc) { - // 重试图层优先于加载失败展示 - this.loadRetryReady = true; - if (this.retryholderData != null) { - this.retryholderFunc.asyncSuccess(this.retryholderData) - } - } else { - // 失败图层标记,如果已经有数据直接展示失败图层 - this.loadErrorReady = true; - if (this.errorholderData != null) { - if (this.errorholderFunc != undefined) { - this.errorholderFunc.asyncSuccess(this.errorholderData) - } - } - } - - if (this.requestListeners != undefined) { - for (let i = 0; i < this.requestListeners.length; i++) { - let requestListener = this.requestListeners[i]; - let boolInterception = requestListener.callback(err as string, new ImageKnifeData()); - if (boolInterception) { - break; - } - } - } - // 加载失败之后 - if (ImageKnifeGlobal.getInstance().getImageKnife() != undefined) { - (ImageKnifeGlobal.getInstance().getImageKnife())?.removeRunning(this); - } - } -} - - diff --git a/library/src/main/ets/components/imageknife/TaskParams.ets b/library/src/main/ets/components/imageknife/TaskParams.ets deleted file mode 100644 index 4820288..0000000 --- a/library/src/main/ets/components/imageknife/TaskParams.ets +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (C) 2024 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the 'License'); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an 'AS IS' BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import { ObjectKey } from './ObjectKey'; -import { Priority, Size } from '../imageknife/RequestOption' -import common from '@ohos.app.ability.common' - -export class TaskParams { - headers: Map = new Map(); - moduleContext?: common.UIAbilityContext = undefined; - transformations: string [][] = [] - usageType: string = '' - displayProgress: boolean = false - priority: Priority = Priority.MEDIUM // 优先级 - uuid: string = '' // 唯一标识 - dontAnimateFlag: boolean = false; - thumbSizeMultiplier: number = 0; - thumbDelayTime: number = 1000; - size: Size = { width: -1, height: -1 }; - onlyRetrieveFromCache: boolean = false; - isCacheable: boolean = true; - gpuEnabled: boolean = false; - generateCacheKey: string = ""; - generateResourceKey: string = ""; - generateDataKey: string = ""; - signature?: ObjectKey; - diskMemoryCachePath: string = ""; -} \ No newline at end of file diff --git a/library/src/main/ets/components/imageknife/compress/CompressBuilder.ets b/library/src/main/ets/components/imageknife/compress/CompressBuilder.ets deleted file mode 100644 index dbfa5e7..0000000 --- a/library/src/main/ets/components/imageknife/compress/CompressBuilder.ets +++ /dev/null @@ -1,217 +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 {OnRenameListener} from '../compress/listener/OnRenameListener' -import {OnCompressListener} from '../compress/listener/OnCompressListener' -import {CompressionPredicate} from '../compress/listener/CompressionPredicate' -import fileio from '@ohos.fileio'; -import {CompressAdapter} from '../compress/provider/CompressAdapter' -import {DataStringPathProvider} from '../compress/provider/DataStringPathProvider' -import {RecourseProvider} from '../compress/provider/RecourseProvider' -import { Engine } from '../compress/Engine' -import { ImageKnife } from '../ImageKnife' -import { ImageKnifeGlobal } from '../ImageKnifeGlobal'; -import common from '@ohos.app.ability.common'; - -export class CompressBuilder { - private _mTargetDir: string = ''; - private _mLeastCompressSize: number= 100; // KB - private _mRenameListener: OnRenameListener = {reName:()=>{return ''}}; - private _mCompressListener: OnCompressListener={ - start:()=> {}, - onSuccess:(p: PixelMap|null|undefined, path: string)=> {}, - onError:(s: string)=> {} - }; - private _mCompressionPredicate: CompressionPredicate ={ - apply:(path: string)=> { return false } -} - private _mStreamProviders: Array = new Array(); - private _mFocusAlpha: boolean = false; - private _outFilePath: string = ''; - constructor() { - this._mStreamProviders = new Array(); - } - - public setRenameListener(listener: OnRenameListener): CompressBuilder { - this._mRenameListener = listener; - return this; - } - - public setCompressListener(listener: OnCompressListener): CompressBuilder { - this._mCompressListener = listener; - return this; - } - - public filter(compressionPredicate: CompressionPredicate): CompressBuilder { - this._mCompressionPredicate = compressionPredicate; - return this; - } - - public setTargetDir(targetDir: string): CompressBuilder { - this._mTargetDir = targetDir; - if (this._mTargetDir) { - let timestamp = (new Date()).valueOf(); - this._outFilePath = this._mTargetDir + "/" + timestamp + (Math.random() * 100).toFixed(0) + ".jpg"; - } - return this; - } - - public load(list: Array): CompressBuilder { - for (let i = 0; i < list.length; i++) { - let element = list[i]; - if (typeof element === "string") { - this.loadString(element); - } else { - this.loadRecourse(element) - } - } - return this; - } - - /** - * load string file path; - */ - private loadString(path: string) { - this._mStreamProviders.push(new DataStringPathProvider(path)); - } - - /** - * load resource; - */ - private loadRecourse(data: Resource) { - this._mStreamProviders.push(new RecourseProvider(data)); - } - - public setFocusAlpha(focusAlpha: boolean): CompressBuilder { - this._mFocusAlpha = focusAlpha; - return this; - } - - public ignoreBy(size: number): CompressBuilder { - this._mLeastCompressSize = size; - return this; - } - - public launch() { - if (!this._mTargetDir) { - this.getImageCacheFile(); - } else { - this.startCompress(); - } - } - - public async get():Promise { - if (!this._mTargetDir) { - let context= (ImageKnifeGlobal.getInstance().getHapContext() as common.UIAbilityContext); - let path = context.filesDir; - let timestamp = (new Date()).valueOf(); - this._outFilePath = path + "/compress/" + timestamp + (Math.random() * 100).toFixed(0) + ".jpg"; - let result = await this.startAsyncCompress(); - return result; - } else { - let result =await this.startAsyncCompress(); - return result; - } - } - - private async startAsyncCompress():Promise { - let compressPromise:Promise = new Promise((resolve, reject) => { - - let compressListener: OnCompressListener = { - start:()=>{ - }, - onSuccess:(p: PixelMap|undefined|null, path: string)=> { - resolve(path); - }, - onError:(s: string)=> { - } - } - - compressListener.start(); - - if (this._mStreamProviders == null || this._mStreamProviders.length == 0) { - compressListener.onError("this compress path is empty"); - return; - } - - for (let i = 0; i < this._mStreamProviders.length; i++) { - let element = this._mStreamProviders[i]; - let isOpenfilter = false; - if (this._mCompressionPredicate) { - isOpenfilter = this._mCompressionPredicate.apply(element.getRecoursePath()); - } - - - if (!isOpenfilter) { - new Engine(element, this._outFilePath, this._mFocusAlpha, this._mLeastCompressSize, - compressListener, this._mCompressionPredicate).compress(); - } else { - resolve(element.getRecoursePath()); - } - } - - }) - let result = await compressPromise - return (result as string) - } - - - /** - * start compress - */ - private startCompress() { - if (this._mStreamProviders == null || this._mStreamProviders.length == 0) { - if (this._mCompressListener) { - this._mCompressListener.onError("this compress path is empty"); - } - return; - } - if (this._mRenameListener) { - let name = this._mRenameListener.reName(); - if (this._outFilePath && name) { - let start = this._outFilePath.lastIndexOf("/") + 1 - let end = this._outFilePath.length; - let replaceStr = this._outFilePath.substring(start, end); - this._outFilePath = this._outFilePath.replace(replaceStr, name); - } - } - if (this._mCompressListener) { - this._mCompressListener.start(); - } - - for (let i = 0; i < this._mStreamProviders.length; i++) { - let element = this._mStreamProviders[i]; - let isOpenfilter = false; - if (this._mCompressionPredicate) { - isOpenfilter = this._mCompressionPredicate.apply(element.getRecoursePath()); - } - if (!isOpenfilter) { - new Engine(element, this._outFilePath, this._mFocusAlpha, this._mLeastCompressSize, - this._mCompressListener, this._mCompressionPredicate).compress(); - } else { - if (this._mCompressListener) { - this._mCompressListener.onSuccess(null, element.getRecoursePath()); - } - } - } - } - - private getImageCacheFile() { - let context = (ImageKnifeGlobal.getInstance().getHapContext() as common.UIAbilityContext) - let timestamp = (new Date()).valueOf(); - this._outFilePath = context.filesDir + "/compress/" + timestamp + (Math.random() * 100).toFixed(0) + ".jpg"; - this.startCompress(); - } -} \ No newline at end of file diff --git a/library/src/main/ets/components/imageknife/compress/Engine.ets b/library/src/main/ets/components/imageknife/compress/Engine.ets deleted file mode 100644 index e3827d3..0000000 --- a/library/src/main/ets/components/imageknife/compress/Engine.ets +++ /dev/null @@ -1,203 +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 { OnCompressListener } from '../compress/listener/OnCompressListener' -import { CompressionPredicate } from '../compress/listener/CompressionPredicate' -import { CompressAdapter } from "../compress/provider/CompressAdapter" -import { DataStringPathProvider } from '../compress/provider/DataStringPathProvider' -import { RecourseProvider } from '../compress/provider/RecourseProvider' -import { FileUtils } from '../../cache/FileUtils' -import image from "@ohos.multimedia.image" -import fs from '@ohos.file.fs'; -import { BusinessError } from '@ohos.base' - -export class Engine { - private mFocusAlpha: boolean; - private mCompressListener: OnCompressListener - private mPredicate: CompressionPredicate - private mCompressAdapter: CompressAdapter - private mPath: string - private _mLeastCompressSize: number; // KB - - constructor(compressAdapter: CompressAdapter, - outPath: string, - focusAlpha: boolean, - leastSize: number, - compressListener: OnCompressListener, - predicate: CompressionPredicate) { - this.mCompressAdapter = compressAdapter; - this.mPath = outPath; - this.mFocusAlpha = focusAlpha; - this.mCompressListener = compressListener; - this.mPredicate = predicate; - this._mLeastCompressSize = leastSize; - } - - private computeSize(srcWidth: number, srcHeight: number): number { - srcWidth = srcWidth % 2 == 1 ? srcWidth + 1 : srcWidth; - srcHeight = srcHeight % 2 == 1 ? srcHeight + 1 : srcHeight; - - let longSide = Math.max(srcWidth, srcHeight); - let shortSide = Math.min(srcWidth, srcHeight); - - let scale = shortSide / longSide; - if (scale <= 1 && scale > 0.5625) { - if (longSide < 1664) { - return 1; - } else if (longSide < 4990) { - return 2; - } else if (longSide > 4990 && longSide < 10240) { - return 4; - } else { - return longSide / 1280 == 0 ? 1 : longSide / 1280; - } - } else if (scale <= 0.5625 && scale > 0.5) { - return longSide / 1280 == 0 ? 1 : longSide / 1280; - } else { - return Math.ceil(longSide / (1280.0 / scale)); - } - } - - compress() { - if (this.mCompressAdapter instanceof DataStringPathProvider) { - // file - this.mCompressAdapter.openInternal({ compressDataListener: (buffer: ArrayBuffer) => { - if (!buffer) { - if (this.mCompressListener) { - this.mCompressListener.onError("file read fail,and date is empty") - } - return; - } - if (!this.checkNeedCompress(buffer)) { - return; - } - - let imageResource: image.ImageSource = image.createImageSource(buffer); - imageResource.getImageInfo() - .then(info => { - let height = info.size.height; - let width = info.size.width; - let computeSize = this.computeSize(width, height); - console.info("Engine compress computeSize:" + computeSize); - let options: image.DecodingOptions = { - editable: true, - sampleSize: computeSize, - desiredPixelFormat: image.PixelMapFormat.RGB_565, - } - imageResource.createPixelMap(options) - .then(bitmap => { - imageResource.release() - }) - .catch((error: BusinessError) => { - this.mCompressListener.onError("ptah createPixelMap fail,because error:" + JSON.stringify(error as BusinessError)) - imageResource.release() - }) - - - }) - .catch((error: BusinessError) => { - this.mCompressListener.onError("ptah getImageInfo fail,because error:" + JSON.stringify(error as BusinessError)) - }) - - } }) - } else if (this.mCompressAdapter instanceof RecourseProvider) { - // resource - this.mCompressAdapter.openInternal({ compressDataListener: (buffer: ArrayBuffer) => { - if (!buffer) { - if (this.mCompressListener) { - this.mCompressListener.onError("resource read fail,and date is empty") - } - return; - } - if (!this.checkNeedCompress(buffer)) { - return; - } - let imageResource: image.ImageSource = image.createImageSource(buffer); - imageResource.getImageInfo() - .then(info => { - let height = info.size.height; - let width = info.size.width; - let computeSize = this.computeSize(width, height); - let packer: image.PackingOption = { - format: "image/jpeg", - quality: computeSize, - } - let imagePacker: image.ImagePacker = image.createImagePacker(); - imagePacker.packing(imageResource, packer, (err, compressBuffer) => { - if (err) { - this.mCompressListener.onError("resource packing fail,because error:" + err); - } - - console.log("compressBuffer is null =" + (compressBuffer == null)); - console.log("compressBuffer is undefined =" + (compressBuffer == undefined)); - let dirPath = this.mPath.substring(0, this.mPath.lastIndexOf("/") + 1); - let isDirectory = this.checkDirExist(dirPath); - if (isDirectory) { - this.saveFile(this.mPath, compressBuffer); - this.handResult(compressBuffer, this.mPath); - } else { - fs.mkdir(dirPath) - .then(() => { - this.saveFile(this.mPath, compressBuffer); - this.handResult(compressBuffer, this.mPath); - }); - } - }) - - - }) - } }) - - - } - } - - private handResult(buffer: ArrayBuffer, path: string) { - let imageRes:image.ImageSource = image.createImageSource(buffer); - let a:image.DecodingOptions = { - editable: true, - } - imageRes.createPixelMap(a) - .then(bitmap => { - if (this.mCompressListener) { - this.mCompressListener.onSuccess(bitmap, path); - } - imageRes.release() - }) - .catch((error:BusinessError) => { - if (this.mCompressListener) { - this.mCompressListener.onError("buffer generated pixelMap fail,because error:" + JSON.stringify(error as BusinessError)) - } - imageRes.release() - }) - } - - private checkNeedCompress(buf: ArrayBuffer): boolean { - if (!buf) { - return false; - } - let length = buf.byteLength / 1024; - return length > this._mLeastCompressSize; - } - - private saveFile(path: string, content: ArrayBuffer) { - FileUtils.getInstance().writeFile(path, content); - } - - private checkDirExist(dirPath: string): boolean { - let isExist:boolean = fs.accessSync(dirPath); - return isExist; - } -} \ No newline at end of file diff --git a/library/src/main/ets/components/imageknife/compress/listener/CompressDataListener.ets b/library/src/main/ets/components/imageknife/compress/listener/CompressDataListener.ets deleted file mode 100644 index 63e1a86..0000000 --- a/library/src/main/ets/components/imageknife/compress/listener/CompressDataListener.ets +++ /dev/null @@ -1,18 +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. - */ - -export interface CompressDataListener { - compressDataListener:(t: T)=>void; -} \ No newline at end of file diff --git a/library/src/main/ets/components/imageknife/compress/listener/CompressionPredicate.ets b/library/src/main/ets/components/imageknife/compress/listener/CompressionPredicate.ets deleted file mode 100644 index ad29877..0000000 --- a/library/src/main/ets/components/imageknife/compress/listener/CompressionPredicate.ets +++ /dev/null @@ -1,21 +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. - */ - -/** - * filter out unsupported - */ -export interface CompressionPredicate { - apply:(path: string)=>boolean; -} \ No newline at end of file diff --git a/library/src/main/ets/components/imageknife/compress/listener/OnCompressListener.ets b/library/src/main/ets/components/imageknife/compress/listener/OnCompressListener.ets deleted file mode 100644 index 96a9a76..0000000 --- a/library/src/main/ets/components/imageknife/compress/listener/OnCompressListener.ets +++ /dev/null @@ -1,31 +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. - */ -/** - * compress listener - */ -export interface OnCompressListener { - /** - * compress start - */ - start:()=>void; - /** - * compress success - */ - onSuccess:(p: PixelMap|undefined|null, path: string)=>void; - /** - * compress fail - */ - onError:(s: string)=>void; -} \ No newline at end of file diff --git a/library/src/main/ets/components/imageknife/compress/listener/OnRenameListener.ets b/library/src/main/ets/components/imageknife/compress/listener/OnRenameListener.ets deleted file mode 100644 index 811a4bf..0000000 --- a/library/src/main/ets/components/imageknife/compress/listener/OnRenameListener.ets +++ /dev/null @@ -1,21 +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. - */ - -/** - * rename listener - */ -export interface OnRenameListener { - reName:()=>string; -} \ No newline at end of file diff --git a/library/src/main/ets/components/imageknife/compress/provider/CompressAdapter.ets b/library/src/main/ets/components/imageknife/compress/provider/CompressAdapter.ets deleted file mode 100644 index 31b2ff1..0000000 --- a/library/src/main/ets/components/imageknife/compress/provider/CompressAdapter.ets +++ /dev/null @@ -1,71 +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 {CompressProvider} from "../provider/CompressProvider" -import {CompressDataListener} from "../listener/CompressDataListener" - -export abstract class CompressAdapter implements CompressProvider { - mData: ArrayBuffer = new ArrayBuffer(0); - mPath: string = ''; - - close() { - } - - openData(): ArrayBuffer{ - return this.mData; - } - - getPath(): string{ - return this.mPath; - }; - - abstract openInternal(callback: CompressDataListener); - - abstract getRecoursePath(): string; - - abstract getPixelMapFormat(): PixelMapFormat | undefined; - - getFormat(s: string): PixelMapFormat | undefined{ - if (!s) { - return undefined; - } - if (s == "jpg" || s == "JPG") { - return PixelMapFormat.JPG; - } else if (s == "png" || s == "PNG") { - return PixelMapFormat.PNG; - } else if (s == "jpeg" || s == "JPEG") { - return PixelMapFormat.JPEG; - } else if (s == "gif" || s == "GIF") { - return PixelMapFormat.GIF; - } else if (s == "webp" || s == "WEBP" || s == "WebP") { - return PixelMapFormat.WEBP; - } else if (s == "bmg" || s == "BMG") { - return PixelMapFormat.BMG; - } else { - return PixelMapFormat.NONE; - } - } -} - -export enum PixelMapFormat { - JPG, - PNG, - JPEG, - WEBP, - BMG, - GIF, - NONE -} - diff --git a/library/src/main/ets/components/imageknife/compress/provider/CompressProvider.ets b/library/src/main/ets/components/imageknife/compress/provider/CompressProvider.ets deleted file mode 100644 index 3283c70..0000000 --- a/library/src/main/ets/components/imageknife/compress/provider/CompressProvider.ets +++ /dev/null @@ -1,23 +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. - */ - -export interface CompressProvider { - close():void; - - openData():ArrayBuffer; - - getPath(): string; - -} \ No newline at end of file diff --git a/library/src/main/ets/components/imageknife/compress/provider/DataStringPathProvider.ets b/library/src/main/ets/components/imageknife/compress/provider/DataStringPathProvider.ets deleted file mode 100644 index 8bf3554..0000000 --- a/library/src/main/ets/components/imageknife/compress/provider/DataStringPathProvider.ets +++ /dev/null @@ -1,49 +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 {CompressAdapter, PixelMapFormat} from '../provider/CompressAdapter' -import {CompressDataListener} from '../listener/CompressDataListener' -import {FileUtils} from '../../../cache/FileUtils' - -export class DataStringPathProvider extends CompressAdapter { - constructor(s: string) { - super() - this.mPath = s; - } - - getRecoursePath(): string{ - return this.mPath; - } - - openInternal(callback: CompressDataListener) { - if (!this.mPath) { - throw new Error('DataStringPathProvider error path is empty'); - } - let buffer = FileUtils.getInstance().readFilePic(this.mPath); - this.mData = buffer; - if (callback) { - callback.compressDataListener(buffer); - } - } - - getPixelMapFormat(): PixelMapFormat|undefined{ - if (!this.mPath) { - return PixelMapFormat.NONE; - } - let lastIndex = this.mPath.lastIndexOf('/') - let s = this.mPath.substring(lastIndex + 1, this.mPath.length); - return this.getFormat(s); - } -} \ No newline at end of file diff --git a/library/src/main/ets/components/imageknife/compress/provider/RecourseProvider.ets b/library/src/main/ets/components/imageknife/compress/provider/RecourseProvider.ets deleted file mode 100644 index aac034f..0000000 --- a/library/src/main/ets/components/imageknife/compress/provider/RecourseProvider.ets +++ /dev/null @@ -1,121 +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 { CompressAdapter, PixelMapFormat } from "../provider/CompressAdapter" -import { CompressDataListener } from "../listener/CompressDataListener" -import { FileTypeUtil } from '../../../imageknife/utils/FileTypeUtil' -import { ImageKnifeGlobal } from '../../ImageKnifeGlobal'; -import resourceManager from '@ohos.resourceManager'; -import { BusinessError } from '@ohos.base' -import common from '@ohos.app.ability.common'; -import { ContextCacheProxy } from '../../requestmanage/ContextCacheProxy'; - -export class RecourseProvider extends CompressAdapter { - private static CHARS: string = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; - private static DEFAULT_RESOURCE_PATH: string = "Resource" - private _mLookup: Uint8Array = new Uint8Array(256); - private _mResourceData?: Resource = undefined; - private _mPixelMapHeader: string = ''; - - constructor(s: Resource) { - super() - this._mResourceData = s; - this.mPath = RecourseProvider.DEFAULT_RESOURCE_PATH; - for (let index = 0; index < RecourseProvider.CHARS.length; index++) { - this._mLookup[RecourseProvider.CHARS.charCodeAt(index)] = index; - } - } - - getRecoursePath(): string { - return this.mPath; - } - - openInternal(callback: CompressDataListener) { - console.info("asasd compress openInternal _mData"); - if (!this._mResourceData) { - throw Error("compress resource is empty"); - } - let context = ContextCacheProxy.getInstance() - .contextGetValue(this._mResourceData.moduleName, - ImageKnifeGlobal.getInstance().getHapContext() as common.UIAbilityContext); - if (context != undefined) { - (context.resourceManager as resourceManager.ResourceManager) - .getMediaContent(this._mResourceData.id) - .then(data => { - let buffer = this.uint8ArrayToBuffer(data); - let fileTypeUtil = new FileTypeUtil() - let fileType = fileTypeUtil.getFileType(buffer); - if (fileType != null) { - this._mPixelMapHeader = fileType; - } - callback.compressDataListener(buffer); - }) - .catch((err: BusinessError) => { - console.log("RecourseProvider openInternal err" + JSON.stringify(err as BusinessError)); - }) - } - } - - getPixelMapFormat(): PixelMapFormat | undefined { - if (!this._mPixelMapHeader) { - return PixelMapFormat.NONE; - } - return this.getFormat(this._mPixelMapHeader); - } - - /** - * data decode - */ - decode(base64: string, callback: CompressDataListener) { - let bufferLength: number = base64.length; - let len: number = base64.length; - let i: number = 0; - let p: number = 0; - let encoded1: number = 0; - let encoded2: number = 0; - let encoded3: number = 0; - let encoded4: number = 0; - - if (base64[base64.length - 1] === '=') { - bufferLength--; - if (base64[base64.length - 2] === '=') { - bufferLength--; - } - } - - const arraybuffer = new ArrayBuffer(bufferLength), - bytes = new Uint8Array(arraybuffer); - - for (i = 0; i < len; i += 4) { - encoded1 = this._mLookup[base64.charCodeAt(i)]; - encoded2 = this._mLookup[base64.charCodeAt(i + 1)]; - encoded3 = this._mLookup[base64.charCodeAt(i + 2)]; - encoded4 = this._mLookup[base64.charCodeAt(i + 3)]; - - bytes[p++] = (encoded1 << 2) | (encoded2 >> 4); - bytes[p++] = ((encoded2 & 15) << 4) | (encoded3 >> 2); - bytes[p++] = ((encoded3 & 3) << 6) | (encoded4 & 63); - - } - this.mData = arraybuffer; - if (callback) { - callback.compressDataListener(arraybuffer); - } - } - - uint8ArrayToBuffer(array: Uint8Array): ArrayBuffer { - return array.buffer.slice(array.byteOffset, array.byteLength + array.byteOffset) - } -} \ No newline at end of file diff --git a/library/src/main/ets/components/imageknife/constants/Constants.ets b/library/src/main/ets/components/imageknife/constants/Constants.ets deleted file mode 100644 index 4a2d98a..0000000 --- a/library/src/main/ets/components/imageknife/constants/Constants.ets +++ /dev/null @@ -1,23 +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. - */ - -export class Constants { - public static PROJECT_TAG: string = "ImageKnife_js" - public static PROGRESS_EMITTER: string = "progressEmitter" - public static PLACE_HOLDER: string = "placeholder" - public static RETRY_HOLDER: string = "retryholder" - public static ERROR_HOLDER: string = "errorholder" - public static MAIN_HOLDER: string = "main" -} \ No newline at end of file diff --git a/library/src/main/ets/components/imageknife/constants/ResourceTypeEts.ets b/library/src/main/ets/components/imageknife/constants/ResourceTypeEts.ets deleted file mode 100644 index 5c3fdee..0000000 --- a/library/src/main/ets/components/imageknife/constants/ResourceTypeEts.ets +++ /dev/null @@ -1,28 +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. - */ - -export enum ResourceTypeEts { - COLOR = 10001, - FLOAT, - STRING, - PLURAL, - BOOLEAN, - INTARRAY, - INTEGER, - PATTERN, - STRARRAY, - MEDIA = 20000, - RAWFILE = 30000 -} \ No newline at end of file diff --git a/library/src/main/ets/components/imageknife/crop/Crop.ets b/library/src/main/ets/components/imageknife/crop/Crop.ets deleted file mode 100644 index da7ded7..0000000 --- a/library/src/main/ets/components/imageknife/crop/Crop.ets +++ /dev/null @@ -1,118 +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 { CropCallback } from './CropCallback' -import image from "@ohos.multimedia.image" -import { BusinessError } from '@ohos.base' -export namespace Crop { - - export interface CropSize{ - width:number, - height:number - } - - export function crop(buf: ArrayBuffer, x: number, y: number, cropWidth: number, cropHeight: number, func?: CropCallback, colorRatio?: number) { - if (!buf || buf.byteLength <= 0) { - console.log("Crop buf is empty"); - if (func) { - func.cropCallback("Crop buf is empty", null); - } - return; - } - let imageSource:image.ImageSource = image.createImageSource(buf); - let crop:CropCallback = { cropCallback: (error:BusinessError|string, size: CropSize|null) => { - if (!size) { - func?.cropCallback(error, null) - return; - } - let pixelMapWidth = size.width; - let pixelMapHeight = size.height; - if (x < 0 || x > pixelMapWidth) { - func?.cropCallback("Crop error x must be less than pixelMapWidth ", null) - return; - } - if (y < 0 || y > pixelMapHeight) { - func?.cropCallback("Crop error x must be less than pixelMapHeight ", null) - return; - } - let options: image.DecodingOptions = { - editable: true, - rotate: 0, - desiredSize: { - width: pixelMapWidth, - height: pixelMapHeight - }, - desiredRegion: { size: { width: cropWidth, height: cropHeight }, - x: x, - y: y, - }, - } - imageSource.createPixelMap(options) - .then((data:PixelMap) => { - if (colorRatio && colorRatio <= 1) { - colorRatioPixelMap(data, pixelMapWidth, pixelMapHeight, colorRatio, func); - } else { - func?.cropCallback("", data); - } - imageSource.release() - }) - .catch((e:BusinessError) => { - func?.cropCallback(e, null); - imageSource.release() - }) - } - } - getPixelMapSize(imageSource, crop) - } - - let colorRatioPixelMap = async (data: PixelMap, width: number, height: number, colorRatio: number, func?: CropCallback)=> { - if (!data) { - func?.cropCallback("colorRatio pixelMap is null", null); - return; - } - if (colorRatio > 1) { - throw new Error("the colorRatio must be <= 1"); - } - let buffer = new ArrayBuffer(width * height * 5); - let bytes = new Uint8Array(buffer); - let buffer1B = new ArrayBuffer(width * height * 5); - let bytes1B = new Uint8Array(buffer1B); - - let readPromise:Promise = data.readPixelsToBuffer(buffer) - await readPromise; - for (let i = 0;i < bytes.length; i++) { - bytes1B[i] = bytes[i] * colorRatio; - } - let writePromise:Promise = data.writeBufferToPixels(buffer1B) - await writePromise; - func?.cropCallback("", data); - } - - - let getPixelMapSize = (imageSource: image.ImageSource, func: CropCallback)=> { - if (!imageSource) { - return; - } - imageSource.getImageInfo((err, value) => { - if (err) { - func.cropCallback(err, null) - return; - } - let pWidth = value.size.width; - let pHeight = value.size.height; - func.cropCallback('', { width: pWidth, height: pHeight }); - }) - } -} \ No newline at end of file diff --git a/library/src/main/ets/components/imageknife/crop/CropCallback.ets b/library/src/main/ets/components/imageknife/crop/CropCallback.ets deleted file mode 100644 index 04b3a70..0000000 --- a/library/src/main/ets/components/imageknife/crop/CropCallback.ets +++ /dev/null @@ -1,18 +0,0 @@ -/* - * 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 { BusinessError } from '@ohos.base' -export interface CropCallback { - cropCallback:(err:BusinessError|string, data: T)=>void -} \ No newline at end of file diff --git a/library/src/main/ets/components/imageknife/crop/CropImage.ets b/library/src/main/ets/components/imageknife/crop/CropImage.ets deleted file mode 100644 index 578d5c4..0000000 --- a/library/src/main/ets/components/imageknife/crop/CropImage.ets +++ /dev/null @@ -1,54 +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 {CropOptions,Size} from "../crop/CropOptions"; - -@Component -export struct CropImage { - @Link _mOptions: CropOptions; - @State _rotate: number= 0; - @State _scale: number= 1; - - build() { - Stack() { - Image(this._mOptions.src) - .width(this._mOptions.size.width) - .height(this._mOptions.size.height) - .objectFit(ImageFit.None) - .rotate({ - z: 1, - centerX: this._mOptions.size.width / 2, - centerY: this._mOptions.size.height / 2, - angle: this._rotate - }) - .scale({ x: this._scale, y: this._scale, z: 1.0 }) - .gesture(GestureGroup(GestureMode.Parallel, - RotationGesture({ fingers: 1 }).onActionUpdate((event?: GestureEvent) => { - if(event != undefined) { - this._rotate = event.angle; - } - }), PinchGesture({ fingers: 2 }).onActionUpdate((event?: GestureEvent) => { - if(event != undefined) { - this._scale = event.scale; - } - - }) - ).onCancel(() => { - console.log("CropImage gesture cancel"); - }) - ) - }.width(this._mOptions.size.width).height(this._mOptions.size.height); - } -} diff --git a/library/src/main/ets/components/imageknife/crop/CropOptions.ets b/library/src/main/ets/components/imageknife/crop/CropOptions.ets deleted file mode 100644 index 6840094..0000000 --- a/library/src/main/ets/components/imageknife/crop/CropOptions.ets +++ /dev/null @@ -1,23 +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. - */ -export interface Size{ - width: number, - height: number; -} - -export interface CropOptions { - src: string | PixelMap | Resource; - size: Size -} \ No newline at end of file diff --git a/library/src/main/ets/components/imageknife/crop/PixelMapCrop.ets b/library/src/main/ets/components/imageknife/crop/PixelMapCrop.ets deleted file mode 100644 index a319dac..0000000 --- a/library/src/main/ets/components/imageknife/crop/PixelMapCrop.ets +++ /dev/null @@ -1,905 +0,0 @@ -/* - * 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 image from "@ohos.multimedia.image" -import { Crop } from './Crop' -import { CropCallback } from './CropCallback' -import { BusinessError } from '@ohos.base' -@Component -export struct PixelMapCrop { - @Watch('watchOptions') @Link options: Options; - @Watch('watchCropTap') @Prop cropTap: boolean = false; - @State bWidth: number = 0; - @State bHeight: number = 0; - @State cWidth: number = 0; - @State cHeight: number = 0; - downX: number = 0; - downY: number = 0; - moveX: number = 0; - moveY: number = 0; - lastMoveX: number = 0; - lastMoveY: number = 0; - // 裁剪4个角区域 下标0和1左上点 下标2和3右下点 - leftTopArea: number[] = [0, 0, 0, 0] - leftBottomArea: number[] = [0, 0, 0, 0] - rightTopArea: number[] = [0, 0, 0, 0] - rightBottomArea: number[] = [0, 0, 0, 0] - // 4个边框区域 - leftLineArea: number[] = [0, 0, 0, 0] - topLineArea: number[] = [0, 0, 0, 0] - rightLineArea: number[] = [0, 0, 0, 0] - bottomLineArea: number[] = [0, 0, 0, 0] - //四个角的点 - topLeftPoint: number[] = [0, 0] - topRightPoint: number[] = [0, 0] - bottomLeftPoint: number[] = [0, 0] - bottomRightPoint: number[] = [0, 0] - //角宽 - connerWidth: number = 4 - //边框线宽 - lineWidth: number = 2 - //内部预览细线 - gridLineWidth: number = 1 - MIN_LENGTH = this.connerWidth * 2 * 4 - isValidTouch = false; - isTopLeftAreaTouch = false; - isTopRightAreaTouch = false; - isBottomLeftAreaTouch = false; - isBottomRightAreaTouch = false; - isTopLineAreaTouch = false; - isLeftLineAreaTouch = false; - isRightLineAreaTouch = false; - isBottomLineAreaTouch = false; - isMoveTouch = false; - private settings: RenderingContextSettings = new RenderingContextSettings(true) - private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings) - private contextGesture: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings) - - watchOptions() { - this.readyCrop(); - } - - watchCropTap() { - console.log('PMC watchCropTap callback') - if (this.options.cropAction) { - console.log('PMC cropAction start') - this.options.cropAction(this.topLeftPoint, this.bottomRightPoint, this.options.pixelScale); - } - } - - readyCrop() { - if (!this.options.width || !this.options.height || !this.options.pixelBuffer || !this.options.pixelMap) { - throw new Error('PixelMapCrop Options width must not be null & height must not be null & pixelMap must not be null & pixelBuffer must not be null ') - return - } - - this.bWidth = px2vp(this.options.width); - this.bHeight = px2vp(this.options.height); - - this.cWidth = px2vp(this.options.pixelWidth) - this.cHeight = px2vp(this.options.pixelHeight) - - - this.context.drawImage(this.options.pixelMap, 0, 0) - - - this.cropDefault(); - - this.buildCropBoxConnerArea() - - this.buildCropBoxLineArea() - - - this.drawCropBox(); - } - - - //获取裁剪 初始位置 - cropDefault() { - // 左上角 初始坐标 - this.topLeftPoint = [this.cWidth / 4.0 - this.connerWidth / 2.0, this.cHeight / 4.0 - this.connerWidth / 2.0] - - // 右上角 初始坐标 - this.topRightPoint = [this.cWidth / 4.0 * 3.0 + this.connerWidth / 2.0, this.cHeight / 4.0 - this.connerWidth / 2.0] - - // 左下角 初始坐标 - this.bottomLeftPoint = [this.cWidth / 4.0 - this.connerWidth / 2.0, this.cHeight / 4.0 * 3.0 + this.connerWidth / 2.0] - - // 右下角 初始坐标 - this.bottomRightPoint = [this.cWidth / 4.0 * 3.0 + this.connerWidth / 2.0, this.cHeight / 4.0 * 3.0 + this.connerWidth / 2.0] - } - - buildCropBoxConnerArea() { - // 左上角 初始区域 - this.leftTopArea = [this.topLeftPoint[0], this.topLeftPoint[1], this.topLeftPoint[0] + this.MIN_LENGTH / 2, this.topLeftPoint[1] + this.MIN_LENGTH / 2] - // 右上角 初始区域 - this.rightTopArea = [this.topRightPoint[0] - this.MIN_LENGTH / 2, this.topRightPoint[1], this.topRightPoint[0], this.topRightPoint[1] + this.MIN_LENGTH / 2] - // 左下角 初始区域 - this.leftBottomArea = [this.bottomLeftPoint[0], this.bottomLeftPoint[1] - this.MIN_LENGTH / 2, this.bottomLeftPoint[0] + this.MIN_LENGTH / 2, this.bottomLeftPoint[1]] - // 右下角 初始区域 - this.rightBottomArea = [this.bottomRightPoint[0] - this.MIN_LENGTH / 2, this.bottomRightPoint[1] - this.MIN_LENGTH / 2, this.bottomRightPoint[0], this.bottomRightPoint[1]] - } - - buildCropBoxLineArea() { - // 左线 - this.leftLineArea = [this.topLeftPoint[0], this.topLeftPoint[1] + this.MIN_LENGTH / 2, this.bottomLeftPoint[0] + this.MIN_LENGTH / 2, this.bottomLeftPoint[1] - this.MIN_LENGTH / 2] - // 上线 - this.topLineArea = [this.topLeftPoint[0] + this.MIN_LENGTH / 2, this.topLeftPoint[1], this.topRightPoint[0] - this.MIN_LENGTH / 2, this.topRightPoint[1] + this.MIN_LENGTH / 2] - // 右线 - this.rightLineArea = [this.topRightPoint[0] - this.MIN_LENGTH / 2, this.topRightPoint[1] + this.MIN_LENGTH / 2, this.bottomRightPoint[0], this.bottomRightPoint[1] - this.MIN_LENGTH / 2] - // 下线 - this.bottomLineArea = [this.bottomLeftPoint[0] + this.MIN_LENGTH / 2, this.bottomLeftPoint[1] - this.MIN_LENGTH / 2, this.bottomRightPoint[0] - this.MIN_LENGTH / 2, this.bottomRightPoint[1]] - } - - - // 绘制裁剪框 - drawCropBox() { - this.contextGesture.clearRect(0, 0, this.cWidth, this.cHeight) - // 绘制 裁剪框内部 透明底色 外部非透明底色 - this.drawTransparentBackground(); - // 绘制网格线 - if (this.options.hasGuideLine) { - this.drawGridLine() - } - // 绘制裁剪框边框线 - this.drawConnerLine() - // 绘制裁剪框边框 - this.drawConner() - } - - drawTransparentBackground() { - - this.contextGesture.fillStyle = 'rgba(0,0,0,0.8)' - this.contextGesture.moveTo(this.topLeftPoint[0], this.topLeftPoint[1]) - this.contextGesture.lineTo(this.topRightPoint[0], this.topRightPoint[1]) - this.contextGesture.lineTo(this.bottomRightPoint[0], this.bottomRightPoint[1]) - this.contextGesture.lineTo(this.bottomLeftPoint[0], this.bottomLeftPoint[1]) - this.contextGesture.closePath(); - - this.contextGesture.moveTo(0, 0) - this.contextGesture.lineTo(0, this.cHeight) - this.contextGesture.lineTo(this.cWidth, this.cHeight) - this.contextGesture.lineTo(this.cWidth, 0) - this.contextGesture.closePath(); - - this.contextGesture.fill(); - } - - drawGridLine() { - - this.contextGesture.lineWidth = this.gridLineWidth * px2vp(1) - this.contextGesture.lineCap = 'square' - this.contextGesture.strokeStyle = '#ffffff' - - let contentW = this.topRightPoint[0] - this.topLeftPoint[0] - let stepW = contentW / 3.0; - - let contentH = this.bottomLeftPoint[1] - this.topLeftPoint[1] - let stepH = contentH / 3.0; - - // 竖线1 - this.contextGesture.beginPath() - this.contextGesture.moveTo(this.topLeftPoint[0] + stepW * 1.0, this.topLeftPoint[1]) - this.contextGesture.lineTo(this.bottomLeftPoint[0] + stepW * 1.0, this.bottomLeftPoint[1]) - this.contextGesture.stroke() - - // 竖线2 - this.contextGesture.beginPath() - this.contextGesture.moveTo(this.topLeftPoint[0] + stepW * 2.0, this.topLeftPoint[1]) - this.contextGesture.lineTo(this.bottomLeftPoint[0] + stepW * 2.0, this.bottomLeftPoint[1]) - this.contextGesture.stroke() - - //横线1 - this.contextGesture.beginPath() - this.contextGesture.moveTo(this.topLeftPoint[0], this.topLeftPoint[1] + stepH * 1.0) - this.contextGesture.lineTo(this.topRightPoint[0], this.topRightPoint[1] + stepH * 1.0) - this.contextGesture.stroke() - //横线2 - this.contextGesture.beginPath() - this.contextGesture.moveTo(this.topLeftPoint[0], this.topLeftPoint[1] + stepH * 2.0) - this.contextGesture.lineTo(this.topRightPoint[0], this.topRightPoint[1] + stepH * 2.0) - this.contextGesture.stroke() - } - - // 边框 - drawConnerLine() { - this.contextGesture.lineWidth = this.lineWidth - this.contextGesture.lineCap = 'square' - this.contextGesture.strokeStyle = '#aaaaaa' - // 上框 - this.contextGesture.beginPath() - this.contextGesture.moveTo(this.topLeftPoint[0], this.topLeftPoint[1]) - this.contextGesture.lineTo(this.topRightPoint[0], this.topRightPoint[1]) - this.contextGesture.stroke() - // 左框 - this.contextGesture.beginPath() - this.contextGesture.moveTo(this.topLeftPoint[0], this.topLeftPoint[1]) - this.contextGesture.lineTo(this.bottomLeftPoint[0], this.bottomLeftPoint[1]) - this.contextGesture.stroke() - // 右框 - console.log('PMC this.topRightPoint=' + this.topRightPoint + ' this.bottomRightPoint=' + this.bottomRightPoint) - this.contextGesture.beginPath() - this.contextGesture.moveTo(this.topRightPoint[0], this.topRightPoint[1]) - this.contextGesture.lineTo(this.bottomRightPoint[0], this.bottomRightPoint[1]) - this.contextGesture.stroke() - // 下框 - this.contextGesture.beginPath() - this.contextGesture.moveTo(this.bottomLeftPoint[0], this.bottomLeftPoint[1]) - this.contextGesture.lineTo(this.bottomRightPoint[0], this.bottomRightPoint[1]) - this.contextGesture.stroke() - } - // 边框角 - drawConner() { - this.contextGesture.lineWidth = this.connerWidth - this.contextGesture.lineCap = 'square' - this.contextGesture.strokeStyle = '#ffffff' - - // 左上角 - this.contextGesture.beginPath() - this.contextGesture.moveTo(this.topLeftPoint[0], this.topLeftPoint[1]) - this.contextGesture.lineTo(this.topLeftPoint[0], this.topLeftPoint[1] + this.MIN_LENGTH / 2.0) - this.contextGesture.stroke() - - this.contextGesture.beginPath() - this.contextGesture.moveTo(this.topLeftPoint[0], this.topLeftPoint[1]) - this.contextGesture.lineTo(this.topLeftPoint[0] + this.MIN_LENGTH / 2.0, this.topLeftPoint[1]) - this.contextGesture.stroke() - - // 右上角 - this.contextGesture.beginPath() - this.contextGesture.moveTo(this.topRightPoint[0], this.topRightPoint[1]) - this.contextGesture.lineTo(this.topRightPoint[0], this.topRightPoint[1] + this.MIN_LENGTH / 2.0) - this.contextGesture.stroke() - - this.contextGesture.beginPath() - this.contextGesture.moveTo(this.topRightPoint[0], this.topRightPoint[1]) - this.contextGesture.lineTo(this.topRightPoint[0] - this.MIN_LENGTH / 2.0, this.topRightPoint[1]) - this.contextGesture.stroke() - - // 左下角 - this.contextGesture.beginPath() - this.contextGesture.moveTo(this.bottomLeftPoint[0], this.bottomLeftPoint[1]) - this.contextGesture.lineTo(this.bottomLeftPoint[0], this.bottomLeftPoint[1] - this.MIN_LENGTH / 2.0) - this.contextGesture.stroke() - - this.contextGesture.beginPath() - this.contextGesture.moveTo(this.bottomLeftPoint[0], this.bottomLeftPoint[1]) - this.contextGesture.lineTo(this.bottomLeftPoint[0] + this.MIN_LENGTH / 2.0, this.bottomLeftPoint[1]) - this.contextGesture.stroke() - - - // 右下角 - this.contextGesture.beginPath() - this.contextGesture.moveTo(this.bottomRightPoint[0], this.bottomRightPoint[1]) - this.contextGesture.lineTo(this.bottomRightPoint[0], this.bottomRightPoint[1] - this.MIN_LENGTH / 2.0) - this.contextGesture.stroke() - - this.contextGesture.beginPath() - this.contextGesture.moveTo(this.bottomRightPoint[0], this.bottomRightPoint[1]) - this.contextGesture.lineTo(this.bottomRightPoint[0] - this.MIN_LENGTH / 2.0, this.bottomRightPoint[1]) - this.contextGesture.stroke() - } - - build() { - Stack() { - Canvas(this.context) - .width(this.cWidth) - .height(this.cHeight) - .onReady(() => { - }).backgroundColor(Color.Yellow) - - Canvas(this.contextGesture) - .width(this.cWidth) - .height(this.cHeight) - // .backgroundColor('#33000000') - .onReady(() => { - }) - .onTouch((event?: TouchEvent) => { - if(event != undefined) { - if (event.type === TouchType.Down) { - // 手指按下 - this.downX = event.touches[0].x; - this.downY = event.touches[0].y; - - this.lastMoveX = event.touches[0].x; - this.lastMoveY = event.touches[0].y; - - this.belongRegion() - - } - if (event.type === TouchType.Up) { - // 手指放开 - this.downX = 0; - this.downY = 0; - - this.moveX = 0; - this.moveY = 0; - - this.resetTouch(); - - } - if (event.type === TouchType.Move) { - // 手指移动 - this.moveX = event.touches[0].x; - this.moveY = event.touches[0].y; - // 每次移动的delta数据 - let dx = this.moveX - this.lastMoveX; - let dy = this.moveY - this.lastMoveY; - - console.log('PMC this.isTopLeftAreaTouch =' + this.isTopLeftAreaTouch + ' this.isTopRightAreaTouch =' + this.isTopRightAreaTouch - + ' this.isBottomLeftAreaTouch=' + this.isBottomLeftAreaTouch + ' isBottomRightAreaTouch' + this.isBottomRightAreaTouch - + ' dx =' + dx + ' dy =' + dy) - - this.touchLeftTopArea(dx, dy) - this.touchRightTopArea(dx, dy) - this.touchLeftBottomArea(dx, dy) - this.touchRightBottomArea(dx, dy) - - - this.touchTopLineArea(dx, dy) - this.touchLeftLineArea(dx, dy) - this.touchRightLineArea(dx, dy) - this.touchBottomLineArea(dx, dy) - - this.touchMoveCropBox(dx, dy); - - this.lastMoveX = event.touches[0].x - this.lastMoveY = event.touches[0].y - - } - } - }) - - } - .width(this.bWidth) - .height(this.bHeight) - .padding({ - left: (this.bWidth - this.cWidth) / 2.0, - top: (this.bHeight - this.cHeight) / 2.0, - right: (this.bWidth - this.cWidth) / 2.0, - bottom: (this.bHeight - this.cHeight) / 2.0 - }) - .backgroundColor(Color.Pink) - } - - touchLeftTopArea(dx: number, dy: number) { - if (this.isTopLeftAreaTouch) { - let boarderLeft = this.topLeftPoint[0] + dx - - if (boarderLeft < 0) { - dx = 0 - this.topLeftPoint[0]; - } - - let boarderTop = this.topLeftPoint[1] + dy - if (boarderTop < 0) { - dy = 0 - this.topLeftPoint[1] - } - - let boarderRight = this.topLeftPoint[0] + dx - if (boarderRight > this.topRightPoint[0] - this.MIN_LENGTH) { - dx = this.topRightPoint[0] - this.MIN_LENGTH - this.topLeftPoint[0] - } - - let boarderBottom = this.topLeftPoint[1] + dy - if (boarderBottom > this.bottomLeftPoint[1] - this.MIN_LENGTH) { - dy = this.bottomLeftPoint[1] - this.MIN_LENGTH - this.topLeftPoint[1] - } - - - this.topLeftPoint[0] = this.topLeftPoint[0] + dx; - this.topLeftPoint[1] = this.topLeftPoint[1] + dy; - - this.topRightPoint[1] = this.topRightPoint[1] + dy; - - this.bottomLeftPoint[0] = this.bottomLeftPoint[0] + dx; - - this.buildCropBoxConnerArea(); - this.buildCropBoxLineArea(); - this.drawCropBox(); - - } - } - - touchRightTopArea(dx: number, dy: number) { - if (this.isTopRightAreaTouch) { - let boarderLeft = this.topRightPoint[0] + dx - - if (boarderLeft < this.topLeftPoint[0] + this.MIN_LENGTH) { - dx = this.topLeftPoint[0] + this.MIN_LENGTH - this.topRightPoint[0]; - } - - let boarderTop = this.topRightPoint[1] + dy - if (boarderTop < 0) { - dy = 0 - this.topRightPoint[1] - } - - let boarderRight = this.topRightPoint[0] + dx - if (boarderRight > this.cWidth) { - dx = this.cWidth - this.topRightPoint[0] - } - - let boarderBottom = this.topRightPoint[1] + dy - if (boarderBottom > this.bottomRightPoint[1] - this.MIN_LENGTH) { - dy = this.bottomRightPoint[1] - this.MIN_LENGTH - this.topLeftPoint[1] - } - - - this.topRightPoint[0] = this.topRightPoint[0] + dx; - this.topRightPoint[1] = this.topRightPoint[1] + dy; - - this.topLeftPoint[1] = this.topLeftPoint[1] + dy; - this.bottomRightPoint[0] = this.bottomRightPoint[0] + dx; - - this.buildCropBoxConnerArea(); - this.buildCropBoxLineArea(); - this.drawCropBox(); - - } - } - - touchLeftBottomArea(dx: number, dy: number) { - if (this.isBottomLeftAreaTouch) { - let boarderLeft = this.bottomLeftPoint[0] + dx - - if (boarderLeft < 0) { - dx = 0 - this.bottomLeftPoint[0]; - } - - let boarderTop = this.bottomLeftPoint[1] + dy - if (boarderTop < this.topLeftPoint[1] + this.MIN_LENGTH) { - dy = this.topLeftPoint[1] + this.MIN_LENGTH - this.bottomLeftPoint[1] - } - - let boarderRight = this.bottomLeftPoint[0] + dx - if (boarderRight > this.bottomRightPoint[0] - this.MIN_LENGTH) { - dx = this.bottomRightPoint[0] - this.MIN_LENGTH - this.bottomLeftPoint[0] - } - - let boarderBottom = this.bottomLeftPoint[1] + dy - if (boarderBottom > this.cHeight) { - dy = this.cHeight - this.bottomLeftPoint[1] - } - - - this.bottomLeftPoint[0] = this.bottomLeftPoint[0] + dx; - this.bottomLeftPoint[1] = this.bottomLeftPoint[1] + dy; - - this.topLeftPoint[0] = this.topLeftPoint[0] + dx; - this.bottomRightPoint[1] = this.bottomRightPoint[1] + dy; - - this.buildCropBoxConnerArea(); - this.buildCropBoxLineArea(); - this.drawCropBox(); - - } - } - - touchRightBottomArea(dx: number, dy: number) { - if (this.isBottomRightAreaTouch) { - let boarderLeft = this.bottomRightPoint[0] + dx - - if (boarderLeft < this.bottomLeftPoint[0] + this.MIN_LENGTH) { - dx = this.bottomLeftPoint[0] + this.MIN_LENGTH - this.bottomRightPoint[0]; - } - - let boarderTop = this.bottomRightPoint[1] + dy - if (boarderTop < this.topRightPoint[1] + this.MIN_LENGTH) { - dy = this.topRightPoint[1] + this.MIN_LENGTH - this.bottomRightPoint[1] - } - - let boarderRight = this.bottomRightPoint[0] + dx - if (boarderRight > this.cWidth) { - dx = this.cWidth - this.bottomRightPoint[0] - } - - let boarderBottom = this.bottomRightPoint[1] + dy - if (boarderBottom > this.cHeight) { - dy = this.cHeight - this.bottomRightPoint[1] - } - - - this.bottomRightPoint[0] = this.bottomRightPoint[0] + dx; - this.bottomRightPoint[1] = this.bottomRightPoint[1] + dy; - - this.bottomLeftPoint[1] = this.bottomLeftPoint[1] + dy; - this.topRightPoint[0] = this.topRightPoint[0] + dx; - - this.buildCropBoxConnerArea(); - this.buildCropBoxLineArea(); - this.drawCropBox(); - - } - } - - touchTopLineArea(dx: number, dy: number) { - - if (this.isTopLineAreaTouch) { - - - let boarderTop = this.topLeftPoint[1] + dy - if (boarderTop < 0) { - dy = 0 - this.topLeftPoint[1] - } - - let boarderBottom = this.topLeftPoint[1] + dy - if (boarderBottom > this.bottomLeftPoint[1] - this.MIN_LENGTH) { - dy = this.bottomLeftPoint[1] - this.MIN_LENGTH - this.topLeftPoint[1] - } - - - this.topLeftPoint[1] = this.topLeftPoint[1] + dy; - - this.topRightPoint[1] = this.topRightPoint[1] + dy; - - - this.buildCropBoxConnerArea(); - this.buildCropBoxLineArea(); - this.drawCropBox(); - - } - } - - touchBottomLineArea(dx: number, dy: number) { - - if (this.isBottomLineAreaTouch) { - - let boarderTop = this.bottomLeftPoint[1] + dy - if (boarderTop < this.topLeftPoint[1] + this.MIN_LENGTH) { - dy = this.topLeftPoint[1] + this.MIN_LENGTH - this.bottomLeftPoint[1] - } - - let boarderBottom = this.bottomLeftPoint[1] + dy - if (boarderBottom > this.cHeight) { - dy = this.cHeight - this.bottomLeftPoint[1] - } - - this.bottomLeftPoint[1] = this.bottomLeftPoint[1] + dy; - this.bottomRightPoint[1] = this.bottomRightPoint[1] + dy; - - this.buildCropBoxConnerArea(); - this.buildCropBoxLineArea(); - this.drawCropBox(); - - } - } - - touchLeftLineArea(dx: number, dy: number) { - - if (this.isLeftLineAreaTouch) { - let boarderLeft = this.topLeftPoint[0] + dx - if (boarderLeft < 0) { - dx = 0 - this.topLeftPoint[0]; - } - - let boarderRight = this.topLeftPoint[0] + dx - if (boarderRight > this.topRightPoint[0] - this.MIN_LENGTH) { - dx = this.topRightPoint[0] - this.MIN_LENGTH - this.topLeftPoint[0] - } - - this.topLeftPoint[0] = this.topLeftPoint[0] + dx; - this.bottomLeftPoint[0] = this.bottomLeftPoint[0] + dx; - - - this.buildCropBoxConnerArea(); - this.buildCropBoxLineArea(); - this.drawCropBox(); - } - } - - touchRightLineArea(dx: number, dy: number) { - if (this.isRightLineAreaTouch) { - - let boarderLeft = this.topRightPoint[0] + dx - if (boarderLeft < this.topLeftPoint[0] + this.MIN_LENGTH) { - dx = this.topLeftPoint[0] + this.MIN_LENGTH - this.topRightPoint[0]; - } - - let boarderRight = this.topRightPoint[0] + dx - if (boarderRight > this.cWidth) { - dx = this.cWidth - this.topRightPoint[0] - } - - this.topRightPoint[0] = this.topRightPoint[0] + dx; - this.bottomRightPoint[0] = this.bottomRightPoint[0] + dx; - - this.buildCropBoxConnerArea(); - this.buildCropBoxLineArea(); - this.drawCropBox(); - } - } - - touchMoveCropBox(dx: number, dy: number) { - if (this.isMoveTouch) { - let boarderLeft = this.topLeftPoint[0] + dx - if (boarderLeft < 0) { - dx = 0 - this.topLeftPoint[0]; - } - - let boarderTop = this.topLeftPoint[1] + dy - if (boarderTop < 0) { - dy = 0 - this.topLeftPoint[1] - } - - let boarderRight = this.bottomRightPoint[0] + dx - if (boarderRight > this.cWidth) { - dx = this.cWidth - this.bottomRightPoint[0] - } - - let boarderBottom = this.bottomRightPoint[1] + dy - if (boarderBottom > this.cHeight) { - dy = this.cHeight - this.bottomRightPoint[1] - } - - this.topLeftPoint[0] = this.topLeftPoint[0] + dx; - this.topLeftPoint[1] = this.topLeftPoint[1] + dy; - - this.topRightPoint[0] = this.topRightPoint[0] + dx; - this.topRightPoint[1] = this.topRightPoint[1] + dy; - - this.bottomLeftPoint[0] = this.bottomLeftPoint[0] + dx; - this.bottomLeftPoint[1] = this.bottomLeftPoint[1] + dy; - - this.bottomRightPoint[0] = this.bottomRightPoint[0] + dx; - this.bottomRightPoint[1] = this.bottomRightPoint[1] + dy; - - - this.buildCropBoxConnerArea(); - this.buildCropBoxLineArea(); - this.drawCropBox(); - - } - } - - - // 判断用户手指按下的点的位置 - belongRegion() { - this.resetTouch(); - // 首先判断是否落在裁剪框默认范围内 - this.isBelongCropBox(); - console.log('PMC this.isValidTouch=' + this.isValidTouch) - console.log('PMC downx =' + this.downX + ' downy =' + this.downY + 'this.leftTopArea =' + this.leftTopArea + ' this.leftBottomArea=' + this.leftBottomArea - + ' this.rightTopArea=' + this.rightTopArea + ' this.rightBottomArea=' + this.rightBottomArea); - // 其次判断是否落在裁剪框4个角位置范围 - if (this.isValidTouch) { - console.log('PMC C1') - this.isTopLeftAreaTouch = this.connerBelonged(this.leftTopArea) - console.log('PMC C2') - this.isBottomLeftAreaTouch = this.connerBelonged(this.leftBottomArea) - console.log('PMC C3') - this.isTopRightAreaTouch = this.connerBelonged(this.rightTopArea) - console.log('PMC C4') - this.isBottomRightAreaTouch = this.connerBelonged(this.rightBottomArea) - console.log('PMC result this.isTopLeftAreaTouch =' + this.isTopLeftAreaTouch + ' this.isTopRightAreaTouch =' + this.isTopRightAreaTouch - + ' this.isBottomLeftAreaTouch=' + this.isBottomLeftAreaTouch + ' isBottomRightAreaTouch' + this.isBottomRightAreaTouch) - - // 再判断是否落在裁剪框4个边框范围 - if (!this.isTopLeftAreaTouch && !this.isBottomLeftAreaTouch && !this.isTopRightAreaTouch && !this.isBottomRightAreaTouch) { - console.log('PMC L1') - this.isTopLineAreaTouch = this.lineBelonged(this.topLineArea) - console.log('PMC L2') - this.isLeftLineAreaTouch = this.lineBelonged(this.leftLineArea) - console.log('PMC L3') - this.isRightLineAreaTouch = this.lineBelonged(this.rightLineArea) - console.log('PMC L4') - this.isBottomLineAreaTouch = this.lineBelonged(this.bottomLineArea) - - console.log('PMC result this.isTopLineAreaTouch =' + this.isTopLineAreaTouch + ' this.isLeftLineAreaTouch =' + this.isLeftLineAreaTouch - + ' this.isRightLineAreaTouch=' + this.isRightLineAreaTouch + ' isBottomLineAreaTouch' + this.isBottomLineAreaTouch) - - } - if (!this.isTopLeftAreaTouch && !this.isBottomLeftAreaTouch && !this.isTopRightAreaTouch && !this.isBottomRightAreaTouch - && !this.isTopLineAreaTouch && !this.isLeftLineAreaTouch && !this.isRightLineAreaTouch && !this.isBottomLineAreaTouch - ) { - this.belongMoveTouch(); - } - } - - // 最后的其他位置都是整体平移整个裁剪框 - } - - resetTouch() { - this.isValidTouch = false; - - this.isTopLeftAreaTouch = false; - this.isTopRightAreaTouch = false; - this.isBottomLeftAreaTouch = false; - this.isBottomRightAreaTouch = false; - - this.isTopLineAreaTouch = false; - this.isLeftLineAreaTouch = false; - this.isRightLineAreaTouch = false; - this.isBottomLineAreaTouch = false; - - this.isMoveTouch = false; - } - - isBelongCropBox() { - - let x0 = this.topLeftPoint[0]; - let y0 = this.topLeftPoint[1]; - - let x1 = this.bottomRightPoint[0]; - let y1 = this.bottomRightPoint[1]; - - if (this.downX >= x0 && this.downX <= x1 && this.downY >= y0 && this.downY <= y1) { - this.isValidTouch = true; - } else { - this.isValidTouch = false; - } - - } - - belongMoveTouch() { - - let x0 = this.topLeftPoint[0] + this.MIN_LENGTH / 2; - let y0 = this.topLeftPoint[1] + this.MIN_LENGTH / 2; - - let x1 = this.bottomRightPoint[0] - this.MIN_LENGTH / 2; - let y1 = this.bottomRightPoint[1] - this.MIN_LENGTH / 2; - - if (this.downX > x0 && this.downX < x1 && this.downY > y0 && this.downY < y1) { - this.isMoveTouch = true; - } else { - this.isMoveTouch = false; - } - - } - - lineBelonged(area: number[]) { - - let x0 = area[0]; - let y0 = area[1]; - - let x1 = area[2]; - let y1 = area[3]; - - if (this.downX > x0 && this.downX < x1 && this.downY > y0 && this.downY < y1) { - return true; - } - return false; - } - - connerBelonged(area: number[]): boolean { - - let x0 = area[0]; - let y0 = area[1]; - - let x1 = area[2]; - let y1 = area[3]; - console.log('PMC downx=' + this.downX + ' downY' + this.downY + ' x0=' + x0 + ' y0=' + y0 + ' x1=' + x1 + ' y1=' + y1) - if (this.downX >= x0 && this.downX <= x1 && this.downY >= y0 && this.downY <= y1) { - console.log('PMC conner is belonged!') - return true - } - return false; - } -} - -export class Options { - width: number = 0; - height: number = 0; - pixelMap?: PixelMap = undefined; - - // 是否需要绘制线 - hasGuideLine: boolean = false; - pixelBuffer: ArrayBuffer = new ArrayBuffer(0); - // 展示pixel宽度 - pixelWidth: number = 0; - // 展示pixel高度 - pixelHeight: number = 0; - // 缩放scale:center-inside类型缩放的比例 - pixelScale: number = 1; - - // 用户裁剪后的回调 - cropFunction: (error:BusinessError|string, pixelmap:PixelMap|null, sx:number, sy:number) => void = (error:BusinessError|string, pixelmap:PixelMap|null, sx:number, sy:number)=>{}; - - // 本地裁剪框 回调 - cropAction: (topLeftPoint:number[], bottomRightPoint:number[], scaleInside:number) =>void = (topLeftPoint:number[], bottomRightPoint:number[], scaleInside:number)=>{}; - - constructor() { - - } - - // 裁剪动作 - setCropFunction(crop: (error:BusinessError|string, pixelmap:PixelMap|null, sx:number, sy:number) => void) { - this.cropFunction = crop; - - this.cropAction = (topLeftPoint:number[], bottomRightPoint:number[], scaleInside:number) => { - let dx:number = vp2px(1) * topLeftPoint[0] * 1.0 / scaleInside; - let dy:number = vp2px(1) * topLeftPoint[1] * 1.0 / scaleInside; - let sx:number = vp2px(1) * (bottomRightPoint[0] - topLeftPoint[0]) * 1.0 / scaleInside; - let sy:number = vp2px(1) * (bottomRightPoint[1] - topLeftPoint[1]) * 1.0 / scaleInside; - Crop.crop(this.pixelBuffer, dx, dy, sx, sy, { - cropCallback: (error: BusinessError | string, pixelmap: PixelMap | null) => { - this.cropFunction(error, pixelmap, sx, sy) - } - }, 1); - - } - - return this; - } - - setWidth(imageWidth: number) { - this.width = imageWidth; - return this; - } - - setHeight(imageHeight: number) { - this.height = imageHeight; - return this; - } - - setGuideLine(guideLine: boolean) { - this.hasGuideLine = guideLine; - } - - getGuideLine() { - return this.hasGuideLine; - } - - async loadBuffer(buffer: ArrayBuffer, readyCrop: Function) { - if (!buffer || buffer.byteLength <= 0) { - console.log('PixelMapCrop "loadBuffer" method buf is empty'); - return; - } - - //数据赋值 - this.pixelBuffer = buffer; - - let imageSource:image.ImageSource = image.createImageSource(buffer); - imageSource.getImageInfo().then((imageInfo) => { - //获取宽高 - - let scaleInside = 1; - - if (this.width && this.height) { - //center_inside 模式判断 - let scaleW = imageInfo.size.width / (this.width * 1.0) - let scaleH = imageInfo.size.height / (this.height * 1.0) - if (scaleH > 1 || scaleW > 1) { - scaleInside = 1.0 / Math.max(scaleW, scaleH) - } - - } else { - this.width = imageInfo.size.width; - this.height = imageInfo.size.height; - } - this.pixelScale = scaleInside; - this.pixelWidth = imageInfo.size.width * scaleInside; - this.pixelHeight = imageInfo.size.height * scaleInside; - - let options:image.DecodingOptions = { - editable: true, - rotate: 0, - desiredSize: { - width: imageInfo.size.width * scaleInside, - height: imageInfo.size.height * scaleInside, - } - } - imageSource.createPixelMap(options).then((pixelmap:PixelMap) => { - this.pixelMap = pixelmap; - if (readyCrop) { - readyCrop(); - } - imageSource.release() - }) - - }); - - } - } - - - diff --git a/library/src/main/ets/components/imageknife/entry/ArcPoint.ets b/library/src/main/ets/components/imageknife/entry/ArcPoint.ets deleted file mode 100644 index a94c90c..0000000 --- a/library/src/main/ets/components/imageknife/entry/ArcPoint.ets +++ /dev/null @@ -1,32 +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. - */ - -export class ArcPoint { - private x: number = 0; - private y: number = 0; - - constructor(x: number, y: number) { - this.y = y; - this.x = x; - } - - getX(): number{ - return this.x; - } - - getY(): number{ - return this.y - } -} diff --git a/library/src/main/ets/components/imageknife/entry/PixelEntry.ets b/library/src/main/ets/components/imageknife/entry/PixelEntry.ets deleted file mode 100644 index 1f2f871..0000000 --- a/library/src/main/ets/components/imageknife/entry/PixelEntry.ets +++ /dev/null @@ -1,26 +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. - */ -export class PixelEntry { - a: number = 0; - b: number = 0; - r: number = 0; - g: number = 0; - f: number = 0; - pixel: number = 0; - - public toString(): string { - return "PixelEntry a:" + this.a + ";b:" + this.b + ";r:" + this.r + ";g:" + this.g + ";f:" + this.f; - } -} \ No newline at end of file diff --git a/library/src/main/ets/components/imageknife/holder/ErrorHolderManager.ets b/library/src/main/ets/components/imageknife/holder/ErrorHolderManager.ets deleted file mode 100644 index 6b460aa..0000000 --- a/library/src/main/ets/components/imageknife/holder/ErrorHolderManager.ets +++ /dev/null @@ -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 { RequestOption,Size } 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 {LogUtil} from '../../imageknife/utils/LogUtil' -import image from '@ohos.multimedia.image' -import { BusinessError } from '@ohos.base' - -export class ErrorHolderManager { - private options: RequestOption; - - constructor(option: RequestOption) { - this.options = option; - } - - process = (onComplete:(value:PixelMap)=>void|PromiseLike, onError:(reason?:BusinessError|string)=>void)=>{ - this.displayErrorholder(onComplete, onError); - } - - private displayErrorholder(onComplete:(value:PixelMap)=>void|PromiseLike, onError:(reason?:BusinessError|string)=>void) { - LogUtil.log("displayErrorholder") - if ((typeof (this.options.errorholderSrc as image.PixelMap).isEditable) == 'boolean') { - let imageKnifeData = ImageKnifeData.createImagePixelMap(ImageKnifeType.PIXELMAP, this.options.errorholderSrc as PixelMap) - onComplete(imageKnifeData?.drawPixelMap?.imagePixelMap as PixelMap); - } else if (typeof this.options.errorholderSrc == 'string') { - - } else { - let res = this.options.errorholderSrc as Resource; - if (typeof res.id != 'undefined' && typeof res.id != 'undefined') { - let resourceFetch = new ParseResClient(); - let suc = (arraybuffer:ArrayBuffer) => { - let fileTypeUtil: FileTypeUtil = new FileTypeUtil(); - - let typeValue: string | null = fileTypeUtil.getFileType(arraybuffer); - if (typeValue != null) { - 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; - } - }else{ - onError("ErrorHolderManager 文件类型为null,请检查数据源arraybuffer") - } - } - let ctx = this.options.getModuleContext(); - if(ctx != undefined){ - resourceFetch.loadResource(ctx,res, suc, onError) - }else{ - onError("ErrorHolderManager moduleContext is undefined,please check it!") - } - } else { - onError("ErrorHolderManager 输入参数有问题!") - } - } - } - - private svgProcess(onComplete:(value:PixelMap)=>void|PromiseLike, onError:(reason?:BusinessError|string)=>void, arraybuffer:ArrayBuffer, typeValue:string) { - let svgParseImpl:SVGParseImpl = new SVGParseImpl() - svgParseImpl.parseSvg(this.options,arraybuffer, onComplete,onError); - } - - private mediaImageProcess(onComplete:(value:PixelMap)=>void|PromiseLike, onError:(reason?:BusinessError|string)=>void, arraybuffer:ArrayBuffer, typeValue:string) { - let parseImageUtil = new ParseImageUtil() - let success = (value: PixelMap) => { - let imageKnifeData = ImageKnifeData.createImagePixelMap(ImageKnifeType.PIXELMAP, value) - onComplete(imageKnifeData?.drawPixelMap?.imagePixelMap as PixelMap) - } - parseImageUtil.parseImage(arraybuffer, success, onError) - } -} \ No newline at end of file diff --git a/library/src/main/ets/components/imageknife/holder/PlaceHolderManager.ets b/library/src/main/ets/components/imageknife/holder/PlaceHolderManager.ets deleted file mode 100644 index 651fec1..0000000 --- a/library/src/main/ets/components/imageknife/holder/PlaceHolderManager.ets +++ /dev/null @@ -1,100 +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,Size} 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 {LogUtil} from '../../imageknife/utils/LogUtil' -import resourceManager from '@ohos.resourceManager'; -import image from "@ohos.multimedia.image" -import { BusinessError } from '@ohos.base' -import { GIFFrame } from '../utils/gif/GIFFrame' - -export class PlaceHolderManager { - private options: RequestOption; - - constructor(option: RequestOption) { - this.options = option; - } - - - process = (onComplete:(value:PixelMap)=>void|PromiseLike, onError:(reason?:BusinessError|string)=>void)=>{ - this.displayPlaceholder(onComplete, onError); - } - - private displayPlaceholder(onComplete:(value:PixelMap)=>void|PromiseLike, onError:(reason?:BusinessError|string)=>void){ - LogUtil.log("ImageKnife displayPlaceholder") - if ((typeof (this.options.placeholderSrc as image.PixelMap).isEditable) == 'boolean') { - let imageKnifeData = ImageKnifeData.createImagePixelMap(ImageKnifeType.PIXELMAP, this.options.placeholderSrc as PixelMap) - onComplete(imageKnifeData?.drawPixelMap?.imagePixelMap as PixelMap); - } else if (typeof this.options.placeholderSrc == 'string') { - - } else { - let res = this.options.placeholderSrc as Resource; - if (typeof res.id != 'undefined' && typeof res.id != 'undefined') { - let resourceFetch = new ParseResClient(); - let suc = (arraybuffer: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; - } - } - let ctx = this.options.getModuleContext(); - if(ctx != undefined){ - resourceFetch.loadResource(ctx,res, suc, onError) - }else{ - onError("PlaceHolderManager moduleContext is undefined,please check it!") - } - } else { - onError("PlaceHolderManager 输入参数有问题!") - } - } - } - - - - private svgProcess(onComplete:(value:PixelMap)=>void|PromiseLike, onError:(reason?:BusinessError|string)=>void, arraybuffer:ArrayBuffer, typeValue:string) { - let svgParseImpl:SVGParseImpl = new SVGParseImpl() - svgParseImpl.parseSvg(this.options,arraybuffer, onComplete,onError); - } - - private mediaImageProcess(onComplete:(value:PixelMap)=>void|PromiseLike, onError:(reason?:BusinessError|string)=>void, arraybuffer:ArrayBuffer, typeValue:string) { - let parseImageUtil:ParseImageUtil = new ParseImageUtil() - let success = (value: PixelMap) => { - let imageKnifeData = ImageKnifeData.createImagePixelMap(ImageKnifeType.PIXELMAP, value) - onComplete(imageKnifeData?.drawPixelMap?.imagePixelMap as PixelMap) - } - parseImageUtil.parseImage(arraybuffer, success, onError) - } -} \ No newline at end of file diff --git a/library/src/main/ets/components/imageknife/holder/RetryHolderManager.ets b/library/src/main/ets/components/imageknife/holder/RetryHolderManager.ets deleted file mode 100644 index 8acfc20..0000000 --- a/library/src/main/ets/components/imageknife/holder/RetryHolderManager.ets +++ /dev/null @@ -1,97 +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,Size} 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 {LogUtil} from '../../imageknife/utils/LogUtil' -import resourceManager from '@ohos.resourceManager'; -import image from "@ohos.multimedia.image" -import { BusinessError } from '@ohos.base' -export class RetryHolderManager { - private options: RequestOption; - - constructor(option: RequestOption) { - this.options = option; - } - - process = (onComplete:(value:PixelMap)=>void|PromiseLike, onError:(reason?:BusinessError|string)=>void)=>{ - this.displayRetryholder(onComplete, onError); - } - - private displayRetryholder(onComplete:(value:PixelMap)=>void|PromiseLike, onError:(reason?:BusinessError|string)=>void){ - LogUtil.log("ImageKnife displayRetryholder") - if ((typeof (this.options.retryholderSrc as image.PixelMap).isEditable) == 'boolean') { - let imageKnifeData = ImageKnifeData.createImagePixelMap(ImageKnifeType.PIXELMAP, this.options.placeholderSrc as PixelMap) - onComplete(imageKnifeData?.drawPixelMap?.imagePixelMap as PixelMap); - } 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: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; - } - } - let ctx = this.options.getModuleContext(); - if(ctx != undefined){ - resourceFetch.loadResource(ctx,res, suc, onError) - }else{ - onError("RetryHolderManager moduleContext is undefined,please check it!") - } - } else { - onError("RetryHolderManager 输入参数有问题!") - } - } - } - - - - private svgProcess(onComplete:(value:PixelMap)=>void|PromiseLike, onError:(reason?:BusinessError|string)=>void, arraybuffer:ArrayBuffer, typeValue:string) { - let svgParseImpl = new SVGParseImpl() - svgParseImpl.parseSvg(this.options,arraybuffer, onComplete,onError); - } - - private mediaImageProcess(onComplete:(value:PixelMap)=>void|PromiseLike, onError:(reason?:BusinessError|string)=>void, arraybuffer:ArrayBuffer, typeValue:string) { - let parseImageUtil = new ParseImageUtil() - let success = (value: PixelMap) => { - let imageKnifeData = ImageKnifeData.createImagePixelMap(ImageKnifeType.PIXELMAP, value) - onComplete(imageKnifeData?.drawPixelMap?.imagePixelMap as PixelMap) - } - parseImageUtil.parseImage(arraybuffer, success, onError) - } -} \ No newline at end of file diff --git a/library/src/main/ets/components/imageknife/interface/AsyncSuccess.ets b/library/src/main/ets/components/imageknife/interface/AsyncSuccess.ets deleted file mode 100644 index 3bb8d34..0000000 --- a/library/src/main/ets/components/imageknife/interface/AsyncSuccess.ets +++ /dev/null @@ -1,18 +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. - */ - -export interface AsyncSuccess { - asyncSuccess:(data: T)=>void; -} diff --git a/library/src/main/ets/components/imageknife/interface/IAllCacheInfoCallback.ets b/library/src/main/ets/components/imageknife/interface/IAllCacheInfoCallback.ets deleted file mode 100644 index 38e62ef..0000000 --- a/library/src/main/ets/components/imageknife/interface/IAllCacheInfoCallback.ets +++ /dev/null @@ -1,37 +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 {ImageKnifeData} from "../../imageknife/ImageKnifeData" -export interface MemoryCacheInfo{ - key: string, - data: ImageKnifeData | undefined -} -export interface ResourceCacheInfo{ - path: string, - key: string -} -export interface DataCacheInfo{ - path: string, - key: string -} -export interface AllCacheInfo { - memoryCacheInfo: MemoryCacheInfo | undefined - resourceCacheInfo: ResourceCacheInfo | undefined - dataCacheInfo: DataCacheInfo | undefined -} - -export interface IAllCacheInfoCallback { - callback :(cacheInfo: AllCacheInfo)=>void; -} \ No newline at end of file diff --git a/library/src/main/ets/components/imageknife/interface/IDrawLifeCycle.ets b/library/src/main/ets/components/imageknife/interface/IDrawLifeCycle.ets deleted file mode 100644 index db472ad..0000000 --- a/library/src/main/ets/components/imageknife/interface/IDrawLifeCycle.ets +++ /dev/null @@ -1,37 +0,0 @@ -/* - * 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 - -} \ No newline at end of file diff --git a/library/src/main/ets/components/imageknife/interface/IParseImage.ets b/library/src/main/ets/components/imageknife/interface/IParseImage.ets deleted file mode 100644 index 9713810..0000000 --- a/library/src/main/ets/components/imageknife/interface/IParseImage.ets +++ /dev/null @@ -1,20 +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 { BusinessError } from '@ohos.base' -export interface IParseImage { - parseImage:(imageinfo:ArrayBuffer, onCompleteFunction:(value:T)=>void | PromiseLike, onErrorFunction:(reason?:BusinessError|string)=>void)=>void; - parseImageThumbnail:(scale:number, imageinfo:ArrayBuffer, onCompleteFunction:(value:T)=>void | PromiseLike, - onErrorFunction:(reason?:BusinessError|string)=>void)=>void; -} \ No newline at end of file diff --git a/library/src/main/ets/components/imageknife/networkmanage/DownloadClient.ets b/library/src/main/ets/components/imageknife/networkmanage/DownloadClient.ets deleted file mode 100644 index 94d2092..0000000 --- a/library/src/main/ets/components/imageknife/networkmanage/DownloadClient.ets +++ /dev/null @@ -1,51 +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 { IDataFetch } from '../networkmanage/IDataFetch' -import { RequestOption } from '../RequestOption' - -import { HttpDownloadClient } from './HttpDownloadClient' -import { LoadLocalFileClient } from './LoadLocalFileClient' -import { LoadDataShareFileClient } from './LoadDataShareFileClient' -import loadRequest from '@ohos.request'; -import { ImageKnifeGlobal } from '../ImageKnifeGlobal' -import common from '@ohos.app.ability.common' -import { NetworkDownloadClient } from './NetworkDownloadClient' - -// 数据加载器 -export class DownloadClient implements IDataFetch { - private networkDownloadClient = new NetworkDownloadClient(); - private httpDownloadClient = new HttpDownloadClient(); - private localFileClient = new LoadLocalFileClient(); - private dataShareFileClient = new LoadDataShareFileClient(); - - loadData(request: RequestOption, onCompleteFunction:(img: ArrayBuffer) => void, onErrorFunction: (err: string) => void) { - if (typeof request.loadSrc == 'string') { - let fileDir:string = (ImageKnifeGlobal.getInstance().getHapContext() as common.UIAbilityContext).filesDir as string; - let cacheDir:string = (ImageKnifeGlobal.getInstance().getHapContext() as common.UIAbilityContext).cacheDir as string - - if (request.loadSrc.startsWith(fileDir) || - request.loadSrc.startsWith(cacheDir)) { - // 本地沙盒 - this.localFileClient.loadData(request, onCompleteFunction, onErrorFunction) - } else if (request.loadSrc.startsWith('datashare://') || request.loadSrc.startsWith('file://')) { - this.dataShareFileClient.loadData(request, onCompleteFunction, onErrorFunction) - } else { - // 网络下载 - this.httpDownloadClient.loadData(request, onCompleteFunction, onErrorFunction) - } - } - } -} \ No newline at end of file diff --git a/library/src/main/ets/components/imageknife/networkmanage/HttpDownloadClient.ets b/library/src/main/ets/components/imageknife/networkmanage/HttpDownloadClient.ets deleted file mode 100644 index fc07368..0000000 --- a/library/src/main/ets/components/imageknife/networkmanage/HttpDownloadClient.ets +++ /dev/null @@ -1,107 +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 { IDataFetch } from '../networkmanage/IDataFetch' -import { RequestOption } from '../RequestOption' -import http from '@ohos.net.http' - -// 数据加载器 -class RequestData { - receiveSize: number = 2000 - totalSize: number = 2000 -} - -export class HttpDownloadClient implements IDataFetch { - async loadData(request: RequestOption, onComplete: (img: ArrayBuffer) => void, onError: (err: string) => void) { - try { - let httpRequest = http.createHttp() - let arrayBuffers = new Array(); - httpRequest.on('headersReceive', (header: Object) => { - // 跟服务器连接成功准备下载 - if (request.progressFunc) { - // 进度条为0 - request.progressFunc.asyncSuccess(0) - } - }) - httpRequest.on('dataReceive', (data: ArrayBuffer) => { - // 下载数据流多次返回 - arrayBuffers.push(data); - }) - httpRequest.on('dataReceiveProgress', (data: RequestData) => { - // 下载进度 - if (data != undefined && (typeof data.receiveSize == 'number') && (typeof data.totalSize == 'number')) { - let percent = Math.round(((data.receiveSize * 1.0) / (data.totalSize * 1.0)) * 100) - if (request.progressFunc) { - request.progressFunc.asyncSuccess(percent) - } - } - }) - httpRequest.on('dataEnd', () => { - // 下载完毕 - let combineArray = this.combineArrayBuffers(arrayBuffers); - onComplete(combineArray) - }) - - const headerObj: Record = {} - request.headers.forEach((value, key) => { - headerObj[key] = value - }) - let promise = httpRequest.requestInStream(request.loadSrc as string, { - header: headerObj, - method: http.RequestMethod.GET, - expectDataType: http.HttpDataType.ARRAY_BUFFER, - connectTimeout: 60000, // 可选 默认60000ms - readTimeout: 0, // 可选, 默认为60000ms - usingProtocol: http.HttpProtocol.HTTP1_1, // 可选,协议类型默认值由系统自动指定 - usingCache: false - }); - await promise.then((data) => { - if (data == 200) { - - } else { - onError(`HttpDownloadClient has error, http code = ` + JSON.stringify(data)) - } - }).catch((err: Error) => { - onError(`HttpDownloadClient has error, http code = ` + JSON.stringify(err)) - }) - } catch (err) { - onError('HttpDownloadClient catch err request uuid =' + request.uuid) - } - } - - combineArrayBuffers(arrayBuffers: ArrayBuffer[]): ArrayBuffer { - // 计算多个ArrayBuffer的总字节大小 - let totalByteLength = 0; - for (const arrayBuffer of arrayBuffers) { - totalByteLength += arrayBuffer.byteLength; - } - - // 创建一个新的ArrayBuffer - const combinedArrayBuffer = new ArrayBuffer(totalByteLength); - - // 创建一个Uint8Array来操作新的ArrayBuffer - const combinedUint8Array = new Uint8Array(combinedArrayBuffer); - - // 依次复制每个ArrayBuffer的内容到新的ArrayBuffer中 - let offset = 0; - for (const arrayBuffer of arrayBuffers) { - const sourceUint8Array = new Uint8Array(arrayBuffer); - combinedUint8Array.set(sourceUint8Array, offset); - offset += sourceUint8Array.length; - } - - return combinedArrayBuffer; - } -} \ No newline at end of file diff --git a/library/src/main/ets/components/imageknife/networkmanage/IDataFetch.ets b/library/src/main/ets/components/imageknife/networkmanage/IDataFetch.ets deleted file mode 100644 index 1fafeb0..0000000 --- a/library/src/main/ets/components/imageknife/networkmanage/IDataFetch.ets +++ /dev/null @@ -1,21 +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 '../RequestOption' - -// 资源加载接口 -export interface IDataFetch { - loadData:(request: RequestOption, onComplete: (img: ArrayBuffer) => void, onError: (err: string) => void)=>void; -} \ No newline at end of file diff --git a/library/src/main/ets/components/imageknife/networkmanage/LoadDataShareFileClient.ets b/library/src/main/ets/components/imageknife/networkmanage/LoadDataShareFileClient.ets deleted file mode 100644 index e080a67..0000000 --- a/library/src/main/ets/components/imageknife/networkmanage/LoadDataShareFileClient.ets +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (C) 2023 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 { IDataFetch } from '../networkmanage/IDataFetch' -import { RequestOption } from '../RequestOption' -import fs from '@ohos.file.fs'; -import { BusinessError } from '@ohos.base' - -export class LoadDataShareFileClient implements IDataFetch { - loadData(request: RequestOption, onComplete: (img: ArrayBuffer) => void, onError: (err: string) => void) { - if (typeof request.loadSrc == 'string') { - fs.open(request.loadSrc, fs.OpenMode.READ_ONLY).then((file) => { - fs.stat(file.fd).then(stat =>{ - let buf = new ArrayBuffer(stat.size); - fs.read(file.fd, buf).then((readLen) => { - onComplete(buf); - fs.close(file.fd); - }).catch((err:BusinessError) => { - onError('LoadDataShareFileClient fs.read err happened uri=' + request.loadSrc + " err.msg=" + err?.message + " err.code=" + err?.code) - }) - }).catch((err:BusinessError) => { - onError('LoadDataShareFileClient fs.stat err happened uri=' + request.loadSrc + " err.msg=" + err?.message + " err.code=" + err?.code) - }) - }).catch((err:BusinessError) => { - onError('LoadDataShareFileClient fs.open err happened uri=' + request.loadSrc + " err.msg=" + err?.message + " err.code=" + err?.code) - }) - } - } -} \ No newline at end of file diff --git a/library/src/main/ets/components/imageknife/networkmanage/LoadLocalFileClient.ets b/library/src/main/ets/components/imageknife/networkmanage/LoadLocalFileClient.ets deleted file mode 100644 index 89240af..0000000 --- a/library/src/main/ets/components/imageknife/networkmanage/LoadLocalFileClient.ets +++ /dev/null @@ -1,35 +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 { IDataFetch } from '../networkmanage/IDataFetch' -import { RequestOption } from '../RequestOption' -import { FileUtils } from '../../cache/FileUtils' -import { BusinessError } from '@ohos.base' -export class LoadLocalFileClient implements IDataFetch { - loadData(request: RequestOption, onComplete: (img: ArrayBuffer) => void, onError: (err: string) => void) { - if (typeof request.loadSrc == 'string') { - FileUtils.getInstance().readFilePicAsync(request.loadSrc).then(fileBuffer=>{ - if (fileBuffer == null || fileBuffer.byteLength <= 0) { - onError('LoadLocalFileClient loadLocalFileData The File Does Not Exist!Check The File!') - } else { - onComplete(fileBuffer); - } - }).catch((err:BusinessError)=>{ - onError('LoadLocalFileClient loadLocalFileData Error Msg ='+err?.message) - }) - - } - } -} \ No newline at end of file diff --git a/library/src/main/ets/components/imageknife/networkmanage/NetworkDownloadClient.ets b/library/src/main/ets/components/imageknife/networkmanage/NetworkDownloadClient.ets deleted file mode 100644 index ae7d9c5..0000000 --- a/library/src/main/ets/components/imageknife/networkmanage/NetworkDownloadClient.ets +++ /dev/null @@ -1,114 +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 { IDataFetch } from '../networkmanage/IDataFetch' -import { RequestOption } from '../RequestOption' -import { SparkMD5 } from '../../3rd_party/sparkmd5/spark-md5' -import { FileUtils } from '../../cache/FileUtils' -import loadRequest from '@ohos.request'; -import { LogUtil } from '../utils/LogUtil' -import { ImageKnifeGlobal } from '../ImageKnifeGlobal' -import common from '@ohos.app.ability.common' -import { BusinessError } from '@ohos.base' -// 数据加载器 -export class NetworkDownloadClient implements IDataFetch { - loadData(request: RequestOption, onComplete: (img: ArrayBuffer) => void, onError: (err: string) => void) { - let filename:string = SparkMD5.hashBinary(request.generateDataKey); - let downloadFolder = request.getFilesPath() + "/" + request.networkCacheFolder; - let allpath = request.getFilesPath() + "/" + request.networkCacheFolder + "/" + filename + ".img"; - if (!FileUtils.getInstance().existFolder(downloadFolder)) { - FileUtils.getInstance().createFolder(downloadFolder) - } - - // 理论上来讲不会进入这里来删除文件,但是如果存在文件,则需要同步删除保证后续文件下载没问题。 - if (FileUtils.getInstance().exist(allpath)) { - FileUtils.getInstance().deleteFile(allpath) - } - let downloadConfig:loadRequest.DownloadConfig = { - url: (request.loadSrc as string), - filePath: allpath, - // 允许计费流量下载 - enableMetered: true, - }; - - loadRequest.downloadFile( (request.getModuleContext() as common.BaseContext ), downloadConfig).then((downloadTask:loadRequest.DownloadTask) => { - if (downloadTask) { - let loadTask:loadRequest.DownloadTask | null = downloadTask; - - loadTask.on('progress', (receivedSize, totalSize) => { - if (totalSize > 0) { - // 并不是所有服务器都会返回totalSize 当没有文件大小的时候,下载进度没有百分比回调,只能知道目前下载了多少数据量 - let percent = Math.round(((receivedSize * 1.0) / (totalSize * 1.0)) * 100) - if (request.progressFunc) { - request.progressFunc.asyncSuccess(percent); - } - } - }); - - loadTask.on('complete', () => { - let downloadPath = allpath; - request.downloadFilePath = downloadPath; - FileUtils.getInstance().readFilePicAsync(downloadPath).then(arraybuffer=>{ - onComplete(arraybuffer); - FileUtils.getInstance().deleteFileAsync(downloadPath).then(()=>{ - LogUtil.log('文件名:'+downloadPath+" 文件删除成功!") - }).catch((err:BusinessError)=>{ - LogUtil.log('文件名:'+downloadPath+" 文件删除失败!") - }); - }).catch((err:BusinessError)=>{ - onError('NetworkDownloadClient Read File Async Error Msg='+ (err as BusinessError)?.message) - }) - - if(loadTask != null) { - loadTask.off('complete', () => {}) - loadTask.off('pause', () => {}) - loadTask.off('remove', () => {}) - loadTask.off('progress', () => {}) - loadTask.off('fail', () => {}) - loadTask = null; - } - }) - - loadTask.on('pause', () => {}) - - loadTask.on('remove', () => {}) - - loadTask.on('fail', (err) => { - onError('NetworkDownloadClient Download task fail err =' + err) - if (loadTask!=null) { - loadTask.delete().then(result => { - if(loadTask != undefined) { - loadTask.off('complete', () => {}) - loadTask.off('pause', () => {}) - loadTask.off('remove', () => {}) - loadTask.off('progress', () => {}) - loadTask.off('fail', () => {}) - loadTask = null - } - }).catch((err:BusinessError) => { - loadTask = null; - console.log('NetworkDownloadClient Download task fail err =' + err); - }) - } - }) - } else { - onError('NetworkDownloadClient downloadTask dismiss!') - } - }) - .catch((err:BusinessError)=> { - onError("下载子系统download错误捕获,error=" + err.message); - }) - } -} \ No newline at end of file diff --git a/library/src/main/ets/components/imageknife/pngj/PngCallback.ts b/library/src/main/ets/components/imageknife/pngj/PngCallback.ts deleted file mode 100644 index 394b6bb..0000000 --- a/library/src/main/ets/components/imageknife/pngj/PngCallback.ts +++ /dev/null @@ -1,23 +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. - */ - -export interface PngCallback{ - pngCallback: (sender:R, receover:T)=>void -} - -export interface WorkerType { - type: string - name: string -} \ No newline at end of file diff --git a/library/src/main/ets/components/imageknife/pngj/PngReader.ets b/library/src/main/ets/components/imageknife/pngj/PngReader.ets deleted file mode 100644 index 45592fd..0000000 --- a/library/src/main/ets/components/imageknife/pngj/PngReader.ets +++ /dev/null @@ -1,32 +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 {Closeable} from "./io/Closeable" -import {ImageInfo} from "./entry/ImageInfo" - -export class PngReader implements Closeable { - private static LOG_TAG: string= "PngReader"; - private static MAX_TOTAL_BYTES_READ_DEFAULT: number= 901001001; - private static MAX_BYTES_METADATA_DEFAULT: number= 5024024; - private static MAX_CHUNK_SIZE_SKIP: number= 2024024; - public imgInfo: ImageInfo = new ImageInfo(0,0,0,false,false,false); - public interlaced: boolean = false; - - constructor(shouldCloseStream: boolean) { - - } - - close(): void { - } -} \ No newline at end of file diff --git a/library/src/main/ets/components/imageknife/pngj/Pngj.ets b/library/src/main/ets/components/imageknife/pngj/Pngj.ets deleted file mode 100644 index 860ed48..0000000 --- a/library/src/main/ets/components/imageknife/pngj/Pngj.ets +++ /dev/null @@ -1,123 +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 { UPNG } from '../../3rd_party/upng/UPNG'; -import { PngCallback, WorkerType } from './PngCallback'; -import image from '@ohos.multimedia.image'; -import taskpool from '@ohos.taskpool'; -import { BusinessError } from '@ohos.base' - -export class Pngj { - readPngImageInfo(arraybuffer: ArrayBuffer, callback: PngCallback) { - let imageSource: image.ImageSource = image.createImageSource(arraybuffer); - if (imageSource != undefined) { - imageSource.getImageInfo((err: BusinessError, value: image.ImageInfo) => { - if (err) { - return; - } - callback.pngCallback(arraybuffer, value); - }); - } - - } - - /** - * - * @param pngBuffer ArrayBuffer containing the PNG file - * @param callback - * returns an image object with following properties: - * width: the width of the image - * height: the height of the image - * depth: number of bits per channel - * ctype: color type of the file (Truecolor, Grayscale, Palette ...) - * frames: additional info about frames (frame delays etc.) - * tabs: additional chunks of the PNG file - * data: pixel data of the image - */ - readPngImage(pngBuffer: ArrayBuffer, callback: PngCallback) { - let png = UPNG.decode(pngBuffer); - callback.pngCallback(pngBuffer, png) - } - - writePngWithString(addInfo: string, pngBuffer: ArrayBuffer, callback: PngCallback) { - let pngDecode = UPNG.decode(pngBuffer); - let newPng = UPNG.encodeWithString(addInfo, UPNG.toRGBA8(pngDecode), pngDecode.width, pngDecode.height, 0) - callback.pngCallback(pngBuffer, newPng); - } - - writePng(pngBuffer: ArrayBuffer, callback: PngCallback) { - let pngDecode = UPNG.decode(pngBuffer); - let newPng = UPNG.encode(UPNG.toRGBA8(pngDecode), pngDecode.width, pngDecode.height, 0) - callback.pngCallback(pngBuffer, newPng); - } - - async readPngImageAsync(e: WorkerType, source: ArrayBuffer, pngCallback: (value: ESObject) => void) { - let task = new taskpool.Task(taskPngImage, e, source) - let val1: ESObject = await taskpool.execute(task) - pngCallback(val1) - try { - taskpool.cancel(task) - } catch (e) { - console.error("taskpool.cancel occur error:" + e) - } - } - - async writePngWithStringAsync(e: WorkerType, source: ArrayBuffer, pngCallback: (value: ESObject) => void, info: string) { - let task = new taskpool.Task(taskPngImage, e, source, info) - let val1: ESObject = await taskpool.execute(task) - pngCallback(val1) - try { - taskpool.cancel(task) - } catch (e) { - console.error("taskpool.cancel occur error:" + e) - } - } - - async writePngAsync(e: WorkerType, source: ArrayBuffer, pngCallback: (value: ESObject) => void) { - let task = new taskpool.Task(taskPngImage, e, source) - let val1: ESObject = await taskpool.execute(task) - pngCallback(val1) - try { - taskpool.cancel(task) - } catch (e) { - console.error("taskpool.cancel occur error:" + e) - } - } -} - -@Concurrent -function taskPngImage(e: WorkerType, pngSource: ArrayBuffer, info?: string): Object | ArrayBufferLike | void { - let a: Object | ArrayBufferLike | undefined = undefined - let png = UPNG.decode(pngSource) - switch (e.name) { - case 'readPngImageAsync': - let array: Uint8Array = png.data; - let arrayData = array.buffer.slice(array.byteOffset, array.byteLength + array.byteOffset) - png.data = arrayData; - a = png - break; - case 'writePngWithStringAsync': - let addInfo: string | undefined = info; - let newPng = UPNG.encodeWithString(addInfo, UPNG.toRGBA8(png), png.width, png.height, 0) - a = newPng - break; - case 'writePngAsync': - let newPng3 = UPNG.encode(UPNG.toRGBA8(png), png.width, png.height, 0) - a = newPng3 - break; - default: - break - } - if(a != undefined) { return a } -} \ No newline at end of file diff --git a/library/src/main/ets/components/imageknife/pngj/PngjException.ets b/library/src/main/ets/components/imageknife/pngj/PngjException.ets deleted file mode 100644 index d35951c..0000000 --- a/library/src/main/ets/components/imageknife/pngj/PngjException.ets +++ /dev/null @@ -1,19 +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. - */ -export class PngjException extends Error { - constructor(s: string) { - super(s) - } -} \ No newline at end of file diff --git a/library/src/main/ets/components/imageknife/pngj/entry/ImageInfo.ets b/library/src/main/ets/components/imageknife/pngj/entry/ImageInfo.ets deleted file mode 100644 index a6bf73b..0000000 --- a/library/src/main/ets/components/imageknife/pngj/entry/ImageInfo.ets +++ /dev/null @@ -1,180 +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 {PngjException} from "../PngjException" - -export class ImageInfo { - private static MAX_COLS_ROW: number= 16777216; - private cols: number; - private rows: number; - private bitDepth: number; - private channels: number; - private alpha: boolean; - private greyscale: boolean; - private indexed: boolean; - private packed: boolean; - private bitspPixel: number; - private bytesPixel: number; - private bytesPerRow: number; - private samplesPerRow: number; - private samplesPerRowPacked: number ; - private totalPixels: number= -1; - private totalRawBytes: number= -1; - - /** - * Full constructor - * - * @param cols - * Width in pixels - * @param rows - * Height in pixels - * @param bitdepth - * Bits per sample, in the buffer : 8-16 for RGB true color and - * greyscale - * @param alpha - * Flag: has an alpha channel (RGBA or GA) - * @param grayscale - * Flag: is gray scale (any bitdepth, with or without alpha) - * @param indexed - * Flag: has palette - */ - constructor(cols: number, rows: number, bitdepth: number - , alpha: boolean, grayscale: boolean, indexed: boolean) { - this.cols = cols; - this.rows = rows; - this.alpha = alpha; - this.indexed = indexed; - this.greyscale = grayscale; - - if (grayscale && indexed) { - throw new PngjException("palette and greyscale are mutually exclusive"); - } - this.channels = (grayscale || indexed) ? (alpha ? 2 : 1) : (alpha ? 4 : 3); - this.bitDepth = bitdepth; - this.packed = bitdepth < 8; - this.bitspPixel = (this.channels * this.bitDepth); - this.bytesPixel = (this.bitspPixel + 7) / 8; - this.bytesPerRow = (this.bitspPixel * cols + 7) / 8; - this.samplesPerRow = this.channels * this.cols; - this.samplesPerRowPacked = this.packed ? this.bytesPerRow : this.samplesPerRow; - - switch (this.bitDepth) { - case 1: - case 2: - case 4: - if (!(this.indexed || this.greyscale)) - throw new PngjException("only indexed or grayscale can have bitdepth=" + this.bitDepth); - break; - case 8: - break; - case 16: - if (this.indexed) { - throw new PngjException("indexed can't have bitdepth=" + this.bitDepth); - } - break; - default: - throw new PngjException("invalid bitdepth=" + this.bitDepth); - } - if (cols < 1 || cols > ImageInfo.MAX_COLS_ROW) { - throw new PngjException("invalid cols=" + cols + " ???"); - } - - if (rows < 1 || rows > ImageInfo.MAX_COLS_ROW) { - throw new PngjException("invalid rows=" + rows + " ???"); - } - if (this.samplesPerRow < 1) { - throw new PngjException("invalid image parameters (overflow?)"); - } - } - - /** - * returns a copy with different size - * - * @param cols - * if non-positive, the original is used - * @param rows - * if non-positive, the original is used - * @return a new copy with the specified size and same properties - */ - public withSize(cols: number, rows: number): ImageInfo { - return new ImageInfo(cols > 0 ? cols : this.cols, rows > 0 ? rows : this.rows, this.bitDepth, this.alpha, - this.greyscale, this.indexed); - } - - public getTotalPixels(): number { - if (this.totalPixels < 0) - this.totalPixels = this.cols * this.rows; - return this.totalPixels; - } - - public getTotalRawBytes(): number { - if (this.totalRawBytes < 0) - this.totalRawBytes = (this.bytesPerRow + 1) * this.rows; - return this.totalRawBytes; - } - - public toString(): string{ - return "ImageInfo [cols=" + this.cols + ", rows=" + this.rows + ", bitDepth=" - + this.bitDepth + ", channels=" + this.channels - + ", alpha=" + this.alpha + ", greyscale=" - + this.greyscale + ", indexed=" + this.indexed + "]"; - } - - public toStringBrief(): string{ - return this.cols + "x" + this.rows + (this.bitDepth != 8 ? ("d" + this.bitDepth) : "") + (this.alpha ? "a" : "") - + (this.indexed ? "p" : "") + (this.greyscale ? "g" : ""); - } - - public toStringDetail(): string{ - return "ImageInfo [cols=" + this.cols + ", rows=" + this.rows + ", bitDepth=" - + this.bitDepth + ", channels=" + this.channels + ", bitspPixel=" + this.bitspPixel - + ", bytesPixel=" + this.bytesPixel + ", bytesPerRow=" + this.bytesPerRow - + ", samplesPerRow=" + this.samplesPerRow + ", samplesPerRowP=" + this.samplesPerRowPacked - + ", alpha=" + this.alpha + ", greyscale=" + this.greyscale + ", indexed=" + this.indexed - + ", packed=" + this.packed + "]"; - } - - public hashCode(): number { - const prime: number = 31; - let result: number = 1; - result = prime * result + (this.alpha ? 1231 : 1237); - result = prime * result + this.bitDepth; - result = prime * result + this.cols; - result = prime * result + (this.greyscale ? 1231 : 1237); - result = prime * result + (this.indexed ? 1231 : 1237); - result = prime * result + this.rows; - return result; - } - - public equals(obj: ImageInfo): boolean { - if (this == obj) - return true; - if (obj == null) - return false; - let other = obj; - if (this.alpha != other.alpha) - return false; - if (this.bitDepth != other.bitDepth) - return false; - if (this.cols != other.cols) - return false; - if (this.greyscale != other.greyscale) - return false; - if (this.indexed != other.indexed) - return false; - if (this.rows != other.rows) - return false; - return true; - } -} \ No newline at end of file diff --git a/library/src/main/ets/components/imageknife/pngj/interface/IBytesConsumer.ets b/library/src/main/ets/components/imageknife/pngj/interface/IBytesConsumer.ets deleted file mode 100644 index 5607f29..0000000 --- a/library/src/main/ets/components/imageknife/pngj/interface/IBytesConsumer.ets +++ /dev/null @@ -1,19 +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. - */ -export interface IBytesConsumer { - isDone(): boolean; - - consume(buf: ArrayBuffer, offset: number, len: number): number; -} \ No newline at end of file diff --git a/library/src/main/ets/components/imageknife/pngj/io/Closeable.ets b/library/src/main/ets/components/imageknife/pngj/io/Closeable.ets deleted file mode 100644 index 0ba92ac..0000000 --- a/library/src/main/ets/components/imageknife/pngj/io/Closeable.ets +++ /dev/null @@ -1,17 +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. - */ -export interface Closeable { - close(): void; -} \ No newline at end of file diff --git a/library/src/main/ets/components/imageknife/pngj/misc/Sandbox.ets b/library/src/main/ets/components/imageknife/pngj/misc/Sandbox.ets deleted file mode 100644 index b294cf9..0000000 --- a/library/src/main/ets/components/imageknife/pngj/misc/Sandbox.ets +++ /dev/null @@ -1,21 +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. - */ -export class Sandbox { - - - public static convert(origFileName: string, destFileName: string) { - - } -} \ No newline at end of file diff --git a/library/src/main/ets/components/imageknife/requestmanage/ContextCacheProxy.ets b/library/src/main/ets/components/imageknife/requestmanage/ContextCacheProxy.ets deleted file mode 100644 index 0903059..0000000 --- a/library/src/main/ets/components/imageknife/requestmanage/ContextCacheProxy.ets +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (C) 2024 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { ICache } from "../requestmanage/ICache" -import { LruCache } from "../../cache/LruCache" - -export class ContextCacheProxy implements ICache { - private mLruCache: LruCache; - private static cache: ContextCacheProxy = new ContextCacheProxy(new LruCache(5)); - - private constructor(lruCache: LruCache) { - this.mLruCache = lruCache; - } - - public static getInstance(): ContextCacheProxy { - return ContextCacheProxy.cache; - } - - - // 缓存类型 - getName() { - return "ContextCacheProxy" - } - - contextGetValue(key: string, context: Context): Context | undefined{ - if (this.hasValue(key)) { - return this.getValue(key); - } else { - let moduleContext = context.createModuleContext(key); - this.putValue(key, moduleContext) - return moduleContext; - } - } - - getValue(key: string): Context | undefined { - return this.mLruCache.get(key); - } - - hasValue(key: string): boolean { - return this.mLruCache.has(key); - } - - putValue(key: string, value: Context) { - this.mLruCache.put(key, value); - } - - removeValue(key: string): Context | undefined { - return this.mLruCache.remove(key); - } - - clear() { - this.mLruCache.evicAll(); - } - - - // 外界调用 - loadMemoryCache(key: string, isMemoryCacheable: boolean): Context | null { - // 是否开启内存缓存 - if (!isMemoryCacheable) { - return null; - } - let cached = this.getValue(key) - if (cached != null) { - return cached; - } - return null; - } -} \ No newline at end of file diff --git a/library/src/main/ets/components/imageknife/requestmanage/DiskCacheProxy.ets b/library/src/main/ets/components/imageknife/requestmanage/DiskCacheProxy.ets deleted file mode 100644 index 552d607..0000000 --- a/library/src/main/ets/components/imageknife/requestmanage/DiskCacheProxy.ets +++ /dev/null @@ -1,56 +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 { ICache } from "../requestmanage/ICache" -import { DiskLruCache } from "../../cache/DiskLruCache" - -export class DiskCacheProxy implements ICache { - private mDiskLruCache: DiskLruCache; - - constructor(diskLruCache: DiskLruCache) { - this.mDiskLruCache = diskLruCache; - } - - // 缓存类型 - getName(): string{ - return "Level2DiskCache"; - } - - getCachePath():string{ - let folderPath:string = this.mDiskLruCache.getPath(); - if (folderPath.endsWith('/')) { - return folderPath; - } else { - return folderPath + '/' - } - } - - getValue(key: string): ArrayBuffer{ - return this.mDiskLruCache.get(key) as ArrayBuffer; - } - - putValue(key: string, value: ArrayBuffer) { - this.mDiskLruCache.set(key, value) - } - - removeValue(key: string): ArrayBuffer{ - // Disk暂无实现 - return new ArrayBuffer(0); - } - - clear() { - this.mDiskLruCache.cleanCacheData(); - } -} \ No newline at end of file diff --git a/library/src/main/ets/components/imageknife/requestmanage/ICache.ets b/library/src/main/ets/components/imageknife/requestmanage/ICache.ets deleted file mode 100644 index 9c86eb0..0000000 --- a/library/src/main/ets/components/imageknife/requestmanage/ICache.ets +++ /dev/null @@ -1,30 +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. - */ - -export interface ICache { - - // 缓存类型 - getName(): string - - getValue(key: K): V|undefined; - - putValue(key: K, value: V):void; - - removeValue(key: K): V|undefined; - - clear():void; - - -} \ No newline at end of file diff --git a/library/src/main/ets/components/imageknife/requestmanage/MemoryCacheProxy.ets b/library/src/main/ets/components/imageknife/requestmanage/MemoryCacheProxy.ets deleted file mode 100644 index bacefa7..0000000 --- a/library/src/main/ets/components/imageknife/requestmanage/MemoryCacheProxy.ets +++ /dev/null @@ -1,60 +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 {ICache} from "../requestmanage/ICache" -import {LruCache} from "../../cache/LruCache" - -export class MemoryCacheProxy implements ICache { - private mLruCache: LruCache; - - constructor(lruCache: LruCache) { - this.mLruCache = lruCache; - } - - // 缓存类型 - getName() { - return "Level1MemoryCache" - } - - getValue(key: K): V|undefined{ - return this.mLruCache.get(key); - } - - putValue(key: K, value: V) { - this.mLruCache.put(key, value); - } - - removeValue(key: K): V|undefined{ - return this.mLruCache.remove(key); - } - - clear() { - this.mLruCache.evicAll(); - } - - - // 外界调用 - loadMemoryCache(key: K, isMemoryCacheable: boolean): V | null{ - // 是否开启内存缓存 - if (!isMemoryCacheable) { - return null; - } - let cached = this.getValue(key) - if (cached != null) { - return cached; - } - return null; - } -} \ No newline at end of file diff --git a/library/src/main/ets/components/imageknife/requestmanage/RequestManager.ets b/library/src/main/ets/components/imageknife/requestmanage/RequestManager.ets deleted file mode 100644 index 69c4ea5..0000000 --- a/library/src/main/ets/components/imageknife/requestmanage/RequestManager.ets +++ /dev/null @@ -1,552 +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, Size } from '../../imageknife/RequestOption' -import { DiskLruCache } from "../../cache/DiskLruCache" -import { LruCache } from '../../cache/LruCache' -import { SparkMD5 } from '../../3rd_party/sparkmd5/spark-md5' -import { MemoryCacheProxy } from '../requestmanage/MemoryCacheProxy' -import { DiskCacheProxy } from '../requestmanage/DiskCacheProxy' -import { FileTypeUtil } from '../utils/FileTypeUtil' -import { IDataFetch } from '../../imageknife/networkmanage/IDataFetch' -import { IResourceFetch } from '../../imageknife/resourcemanage/IResourceFetch' -import { ImageKnifeData, ImageKnifeType } from '../ImageKnifeData' -import { AllCacheInfo } 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' -import { LogUtil } from '../../imageknife/utils/LogUtil' -import { BusinessError } from '@ohos.base' -import taskpool from '@ohos.taskpool'; - - -export enum Stage { - - INITIALIZE, - - RESOURCE_CACHE, - - DATA_CACHE, - - SOURCE, - - ENCODE, - - FINISHED, -} - - -export enum RunReason { - - INITIALIZE, - - SWITCH_TO_SOURCE_SERVICE, - - DECODE_DATA, -} - -export class RequestManager { - private TAG: string = "RequestManager"; - private options: RequestOption; - private mIDataFetch: IDataFetch; - private mIResourceFetch: IResourceFetch; - private mParseImageUtil: IParseImage; - - constructor(option: RequestOption, dataFetch: IDataFetch, resourceFetch: IResourceFetch) { - this.options = option; - - // 网络下载能力 - this.mIDataFetch = dataFetch; - - // 本地数据解析能力 - this.mIResourceFetch = resourceFetch; - - // 解析image能力 - this.mParseImageUtil = new ParseImageUtil(); - } - - // DecodeJob work - private mStage: Stage = Stage.INITIALIZE; - private mRunReason: RunReason = RunReason.INITIALIZE; - process = (onComplete: (value: PixelMap | GIFFrame[]) => void | PromiseLike, onError: (reason?: BusinessError | string) => void) => { - LogUtil.log("ImageKnife RequestManager process !"); - this.loadLeve1MemoryCache(onComplete, onError) - } - - private runWrapped(request: RequestOption, runReason: RunReason, onComplete: (value: PixelMap | GIFFrame[]) => void | PromiseLike, onError: (reason?: BusinessError | string) => void) { - LogUtil.log("ImageKnife RequestManager runWrapped") - if (runReason == RunReason.INITIALIZE) { - this.mStage = this.getNextStage(request, this.mStage); - this.searchLoadFrom(this.options, this.mStage, onComplete, onError); - } else { - throw new Error("Unrecognized run reason: " + runReason) - } - } - - private getNextStage(request: RequestOption, current: Stage): Stage { - if (current == Stage.INITIALIZE) { - return request.strategy.decodeCachedResource() - ? Stage.RESOURCE_CACHE - : this.getNextStage(request, Stage.RESOURCE_CACHE); - } else if (current == Stage.RESOURCE_CACHE) { - return request.strategy.decodeCachedData() - ? Stage.DATA_CACHE - : this.getNextStage(request, Stage.DATA_CACHE); - } else if (current == Stage.DATA_CACHE) { - return request.onlyRetrieveFromCache ? Stage.FINISHED : Stage.SOURCE; - } else if (current == Stage.SOURCE) { - return Stage.FINISHED; - } else if (current == Stage.FINISHED) { - return Stage.FINISHED; - } else { - throw new Error("ImageKnife Unrecognized stage: " + current); - } - } - - // 究竟从哪里加载数据 - private searchLoadFrom(request: RequestOption, current: Stage, onComplete: (value: PixelMap | GIFFrame[]) => void | PromiseLike, onError: (reason?: BusinessError | string) => void) { - LogUtil.log("ImageKnife RequestManager searchLoadFrom") - if (current == Stage.RESOURCE_CACHE) { - this.loadDiskFromTransform(request, onComplete, onError); - } else if (current == Stage.DATA_CACHE) { - this.loadDiskFromSource(request, onComplete, onError); - } else if (current == Stage.SOURCE) { - this.parseSource(request, onComplete, onError) - } else if (current == Stage.FINISHED) { - onError("在仅从缓存获取数据中,未获取到数据!") - } else { - throw new Error("Unrecognized stage: " + current); - } - } - - // 加载网络资源 - private loadSourceFromNetwork(request: RequestOption, onComplete: (value: PixelMap | GIFFrame[]) => void | PromiseLike, onError: (reason?: BusinessError | string) => void) { - try { - LogUtil.log("ImageKnife RequestManager loadSourceFromNetwork") - let success = (arraybuffer: ArrayBuffer) => { - this.downloadSuccess(request, arraybuffer, onComplete, onError) - } - let error = (errorMsg: string) => { - onError(errorMsg) - } - this.mIDataFetch.loadData(request, success, error); - } catch (e) { - LogUtil.error("ImageKnife RequestManager loadSourceFromNetwork error") - } - } - - // 加载本地资源 - private loadSourceFormNative(request: RequestOption, onComplete: (value: PixelMap | GIFFrame[]) => void | PromiseLike, onError: (reason?: BusinessError | string) => void) { - LogUtil.log("ImageKnife RequestManager loadSourceFormNative") - // 本地解析后进行一级缓存 - let success = (arrayBuffer: ArrayBuffer) => { - // 使用媒体子系统 ImageSource解析文件 获取PixelMap - let fileTypeUtil = new FileTypeUtil(); - let typeValue = fileTypeUtil.getFileType(arrayBuffer) - LogUtil.log("ImageKnife RequestManager - 文件类型为= " + typeValue) - // gif处理 - if (ImageKnifeData.GIF == typeValue && !request.dontAnimateFlag) { - // 处理gif - this.gifProcess(onComplete, onError, arrayBuffer, typeValue) - } else if (ImageKnifeData.SVG == typeValue) { - // 处理svg - this.svgProcess(request, onComplete, onError, arrayBuffer, typeValue) - } else { - if (request.transformations[0]) { - request.transformations[0].transform(arrayBuffer, request, { - asyncTransform: (error: BusinessError | string, pixelMap: PixelMap | null) => { - // 输出给Image - if (pixelMap) { - onComplete(pixelMap); - } else { - onError(error); - } - } - }) - } - else { - let success = (value: PixelMap) => { - onComplete(value); - } - this.mParseImageUtil.parseImage(arrayBuffer, success, onError) - } - } - } - let ctx = request.getModuleContext(); - if (ctx != undefined) { - this.mIResourceFetch.loadResource(ctx, request.loadSrc as Resource, success, onError); - } else { - onError('ImageKnife RequestManager loadSourceFormNative moduleContext is undefined! please check it') - } - - } - - // 加载磁盘缓存 原图 - private loadDiskFromSource(request: RequestOption, onComplete: (value: PixelMap | GIFFrame[]) => void | PromiseLike, onError: (reason?: BusinessError | string) => void) { - LogUtil.log("ImageKnife RequestManager loadDiskFromSource") - let cached = DiskLruCache.getFileCacheByFile(request.diskMemoryCachePath, request.generateDataKey); - if (cached != null && cached.byteLength > 0) { - LogUtil.log("ImageKnife loadDiskFromSource load resource from DiskLruCache") - this.parseDiskFile2PixelMap(request, cached, onComplete, onError) - } else { - this.mStage = Stage.SOURCE; - this.mStage = request.onlyRetrieveFromCache? Stage.FINISHED : Stage.SOURCE - this.searchLoadFrom(this.options, this.mStage, onComplete, onError); - } - } - - // 加载磁盘缓存 变换后图片 - private loadDiskFromTransform(request: RequestOption, onComplete: (value: PixelMap | GIFFrame[]) => void | PromiseLike, onError: (reason?: BusinessError | string) => void) { - LogUtil.log("ImageKnife RequestManager loadDiskFromTransform") - let cached = DiskLruCache.getFileCacheByFile(request.diskMemoryCachePath, request.generateResourceKey); - if (cached != null) { - LogUtil.log("ImageKnife loadDiskFromTransform load resource from DiskLruCache") - this.parseDiskTransformFile2PixelMap(request, cached, onComplete, onError) - } else { - this.mStage = Stage.DATA_CACHE; - this.searchLoadFrom(this.options, this.mStage, onComplete, onError); - } - } - - parseSource(request: RequestOption, onComplete: (value: PixelMap | GIFFrame[]) => void | PromiseLike, onError: (reason?: BusinessError | string) => void) { - LogUtil.log("ImageKnife RequestManager parseSource") - try { - if ((typeof (request.loadSrc as image.PixelMap).isEditable) == 'boolean') { - // PixelMap 外层捕获效率更高,不会进入这里 - } else if (typeof request.loadSrc == 'string') { - this.loadSourceFromNetwork(request, onComplete, onError); - } else { - let res = request.loadSrc as Resource; - if (typeof res.id != 'undefined') { - this.loadSourceFormNative(request, onComplete, onError) - } else { - LogUtil.log("输入参数有问题!") - } - } - } catch (e) { - LogUtil.error("ImageKnife RequestManager parseSource error") - } - - } - - private loadLeve1MemoryCache(onComplete: (value: PixelMap | GIFFrame[]) => void | PromiseLike, onError: (reason?: BusinessError | string) => void) { - try { - this.runWrapped(this.options, this.mRunReason, onComplete, onError) - } catch (e) { - LogUtil.error("ImageKnife loadLeve1MemoryCache error") - } - } - - // 解析磁盘文件变成PixeMap - private parseDiskFile2PixelMap(request: RequestOption, source: ArrayBuffer, onComplete: (value: PixelMap | GIFFrame[]) => void | PromiseLike, onError: (reason?: BusinessError | string) => void) { - LogUtil.log("ImageKnife RequestManager parseDiskFile2PixelMap") - // 步骤一:文件转为pixelMap 然后变换 给Image组件 - let fileTypeUtil = new FileTypeUtil(); - let typeValue = fileTypeUtil.getFileType(source); - // 解析磁盘文件 gif 和 svg - if (ImageKnifeData.GIF == typeValue && !request.dontAnimateFlag) { - // 处理gif - this.gifProcess(onComplete, onError, source, typeValue) - } else if (ImageKnifeData.SVG == typeValue) { - this.svgProcess(request, onComplete, onError, source, typeValue) - } else { - if (this.options.transformations[0]) { - if (this.options.thumbSizeMultiplier) { - let thumbOption: RequestOption = new RequestOption(); - thumbOption.setImageViewSize({ - width: Math.round(this.options.thumbSizeMultiplier * this.options.size.width), - height: Math.round(this.options.thumbSizeMultiplier * this.options.size.height) - }) - let ctx = this.options.getModuleContext() - if (ctx != undefined) { - thumbOption.setModuleContext(ctx) - } else { - onError('RequestManager parseDiskFile2PixelMap moduleContext is undefined, please check it!') - return - } - let thumbCallback = this.options.thumbholderOnComplete; - let thumbError = this.options.thumbholderOnError; - this.options.transformations[0].transform(source, thumbOption, { - asyncTransform: (error: BusinessError | string, pixelMap: PixelMap | null) => { - if (pixelMap) { - thumbCallback(pixelMap); - } else { - thumbError(error); - } - } - }) - setTimeout(() => { - this.options.transformations[0].transform(source, request, { - asyncTransform: (error: BusinessError | string, pixelMap: PixelMap | null) => { - if (pixelMap) { - onComplete(pixelMap); - } else { - onError(error); - } - } - }) - }, this.options.thumbDelayTime); - } - else { - this.options.transformations[0].transform(source, request, { - asyncTransform: (error: BusinessError | string, pixelMap: PixelMap | null) => { - if (pixelMap) { - onComplete(pixelMap); - } else { - onError(error); - } - } - }) - } - } else { - // thumbnail 缩略图部分 - if (request.thumbSizeMultiplier) { - let thumbCallback = this.options.thumbholderOnComplete - let thumbError = this.options.thumbholderOnError - let thumbSuccess = (value: PixelMap) => { - thumbCallback(value); - } - this.mParseImageUtil.parseImageThumbnail(request.thumbSizeMultiplier, source, thumbSuccess, thumbError); - setTimeout(() => { - let success = (value: PixelMap) => { - onComplete(value); - } - this.mParseImageUtil.parseImage(source, success, onError) - }, this.options.thumbDelayTime) - } else { - let success = (value: PixelMap) => { - onComplete(value); - } - this.mParseImageUtil.parseImage(source, success, onError) - } - } - } - } - - // 解析磁盘变换后文件变成PixeMap - private parseDiskTransformFile2PixelMap(request: RequestOption, source: ArrayBuffer, onComplete: (value: PixelMap) => void | PromiseLike, onError: (reason?: BusinessError | string) => void) { - LogUtil.log("ImageKnife RequestManager parseDiskTransformFile2PixelMap") - let fileTypeUtil = new FileTypeUtil(); - let typeValue = fileTypeUtil.getFileType(source); - // thumbnail 缩略图部分 - if (request.thumbSizeMultiplier) { - let thumbCallback = this.options.thumbholderOnComplete - let thumbError = this.options.thumbholderOnError - let thumbSuccess = (value: PixelMap) => { - thumbCallback(value); - } - this.mParseImageUtil.parseImageThumbnail(request.thumbSizeMultiplier, source, thumbSuccess, thumbError); - setTimeout(() => { - let success = (value: PixelMap) => { - onComplete(value); - } - this.mParseImageUtil.parseImage(source, success, onError) - }, this.options.thumbDelayTime) - } else { - let success = (value: PixelMap) => { - onComplete(value); - } - this.mParseImageUtil.parseImage(source, success, onError) - } - } - - private downloadSuccess(request: RequestOption, source: ArrayBuffer, onComplete: (value: PixelMap | GIFFrame[]) => void | PromiseLike, onError: (reason?: BusinessError | string) => void) { - - if (source == null || source == undefined || source.byteLength <= 0) { - onError('ImageKnife Download task completed. but download file is empty!') - return - } - - // 下载成功之后 去data/data/包名/唯一路径/文件名 读取数据 - // 步骤一:文件转为pixelMap 然后变换 给Image组件 - // 步骤二: 文件名保存一份全局 - // 步骤三:查看文件是否支持 非支持类型直接返回 - let fileTypeUtil = new FileTypeUtil(); - let filetype: string | null = fileTypeUtil.getFileType(source); - if (filetype == null) { - onError("下载文件解析后类型为null,请检查数据源!"); - return; - } - - if (!fileTypeUtil.isImage(source)) { - onError("暂不支持 下载文件类型!类型=" + filetype); - return; - } - - // 解析磁盘文件 gif 和 svg - if (ImageKnifeData.GIF == filetype && !this.options.dontAnimateFlag) { - // 处理gif - this.gifProcess(onComplete, onError, source, filetype) - - // 保存二级磁盘缓存 - Promise.resolve(source) - .then((arraybuffer: ArrayBuffer) => { - DiskLruCache.saveFileCacheOnlyFile(this.options.diskMemoryCachePath, this.options.generateDataKey,arraybuffer); - }) - .catch((err: BusinessError) => { - LogUtil.log('download file is =' + ImageKnifeData.GIF + 'and save diskLruCache error =' + (err as BusinessError)) - }) - } else if (ImageKnifeData.SVG == filetype) { - // 处理svg - this.svgProcess(request, onComplete, onError, source, filetype) - - // 保存二级磁盘缓存 - Promise.resolve(source) - .then((arraybuffer: ArrayBuffer) => { - DiskLruCache.saveFileCacheOnlyFile(this.options.diskMemoryCachePath, this.options.generateDataKey,arraybuffer); - }) - .catch((err: BusinessError) => { - LogUtil.log('download file is =' + ImageKnifeData.SVG + 'and save diskLruCache error =' + (err as BusinessError)) - }) - } else { - // 进行变换 - if (this.options.transformations[0]) { - // thumbnail 缩略图部分 - if (this.options.thumbSizeMultiplier) { - if (filetype != null) { - this.thumbnailProcess(source, filetype, onComplete, onError); - } - } else { - this.options.transformations[0].transform(source, this.options, { - asyncTransform: (error: BusinessError | string, pixelMap: PixelMap | null) => { - if (pixelMap) { - if (filetype != null) { - this.saveCacheAndDisk(pixelMap, filetype, onComplete, source); - } - } else { - onError(error); - } - } - }) - } - } else { - // thumbnail 缩略图部分 - if (this.options.thumbSizeMultiplier) { - let thumbCallback = this.options.thumbholderOnComplete - let thumbError = this.options.thumbholderOnError - let thumbSuccess = (value: PixelMap) => { - thumbCallback(value); - } - this.mParseImageUtil.parseImageThumbnail(this.options.thumbSizeMultiplier, source, thumbSuccess, thumbError); - setTimeout(() => { - let success = (value: PixelMap) => { - if (filetype != null) { - this.saveCacheAndDisk(value, filetype, onComplete, source); - } - } - this.mParseImageUtil.parseImage(source, success, onError) - }, this.options.thumbDelayTime) - } else { - let success = (value: PixelMap) => { - if (filetype != null) { - this.saveCacheAndDisk(value, filetype, onComplete, source); - } - } - this.mParseImageUtil.parseImage(source, success, onError) - } - } - } - } - - createImagePixelMap(imageKnifeType: ImageKnifeType, imageKnifeValue: PixelMap): ImageKnifeData { - return ImageKnifeData.createImagePixelMap(imageKnifeType, imageKnifeValue); - } - - createImageGIFFrame(imageKnifeType: ImageKnifeType, imageKnifeValue: GIFFrame[]): ImageKnifeData { - return ImageKnifeData.createImageGIFFrame(imageKnifeType, imageKnifeValue); - } - - - private async saveCacheAndDisk(value: PixelMap, filetype: string, onComplete: (value: PixelMap) => void | PromiseLike, source: ArrayBuffer) { - let save2DiskCache = (arraybuffer: ArrayBuffer) => { - DiskLruCache.saveFileCacheOnlyFile(this.options.diskMemoryCachePath, this.options.generateDataKey,arraybuffer); - // 落盘之后需要主动移除当前request并且调用下一个加载 - let removeCurrentAndSearchNextRun = this.options.removeCurrentAndSearchNext; - removeCurrentAndSearchNextRun(); - } - let runSave2Disk = (resolve: (value: ArrayBuffer) => void | PromiseLike, reject: (reason?: BusinessError | string) => void) => { - resolve(source); - } - let promise = new Promise(runSave2Disk); - await promise.then(save2DiskCache); - onComplete(value); - } - - thumbnailProcess(source: ArrayBuffer, filetype: string, onComplete: (value: PixelMap) => void | PromiseLike, onError: (reason?: BusinessError | string) => void) { - let thumbOption = new RequestOption(); - let ctx = this.options.getModuleContext() - if (ctx != undefined) { - thumbOption.setModuleContext(ctx) - } else { - onError('RequestManager thumbnailProcess moduleContext is undefined, please check it!') - return - } - thumbOption.setImageViewSize({ - width: Math.round(this.options.thumbSizeMultiplier * this.options.size.width), - height: Math.round(this.options.thumbSizeMultiplier * this.options.size.height) - }) - let thumbCallback = this.options.thumbholderOnComplete - let thumbError = this.options.thumbholderOnError - this.options.transformations[0].transform(source, thumbOption, { - asyncTransform: (error: BusinessError | string, pixelMap: PixelMap | null) => { - if (pixelMap) { - thumbCallback(pixelMap); - } else { - thumbError(error); - } - } - }) - setTimeout(() => { - this.options.transformations[0].transform(source, this.options, { - asyncTransform: (error: BusinessError | string, pixelMap: PixelMap | null) => { - if (pixelMap) { - this.saveCacheAndDisk(pixelMap, filetype, onComplete, source); - } else { - onError(error); - } - } - }) - }, this.options.thumbDelayTime) - } - - private svgProcess(option: RequestOption, onComplete: (value: PixelMap) => void | PromiseLike, onError: (reason?: BusinessError | string) => void, arraybuffer: ArrayBuffer, typeValue: string, cacheStrategy?: (cacheData: ImageKnifeData) => void) { - let svgParseImpl = new SVGParseImpl() - svgParseImpl.parseSvg(option, arraybuffer, onComplete, onError) - } - - private gifProcess(onComplete: (value: PixelMap | GIFFrame[]) => void | PromiseLike, onError: (reason?: BusinessError | string) => void, arraybuffer: ArrayBuffer, typeValue: string, cacheStrategy?: (cacheData: ImageKnifeData) => void) { - let gifParseImpl = new GIFParseImpl() - gifParseImpl.parseGifs(arraybuffer, (data?: GIFFrame[], err?: BusinessError | string) => { - if (err) { - onError(err) - } - LogUtil.log("gifProcess data is null:" + (data == null)); - if (!!data) { - // let imageKnifeData = this.createImageGIFFrame(ImageKnifeType.GIFFRAME, data) - // LogUtil.log('gifProcess 生成gif 返回数据类型') - // if (cacheStrategy) { - // LogUtil.log('gifProcess 生成gif并且存入了缓存策略') - // cacheStrategy(imageKnifeData) - // } - onComplete(data) - } else { - onError('Parse GIF callback data is null, you need check callback data!') - } - }) - } -} diff --git a/library/src/main/ets/components/imageknife/resourcemanage/IResourceFetch.ets b/library/src/main/ets/components/imageknife/resourcemanage/IResourceFetch.ets deleted file mode 100644 index 0d77865..0000000 --- a/library/src/main/ets/components/imageknife/resourcemanage/IResourceFetch.ets +++ /dev/null @@ -1,23 +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 { BusinessError } from '@ohos.base' -import common from '@ohos.app.ability.common'; - -// 本地资源解析抽象接口 -export interface IResourceFetch { - loadResource:(context:common.UIAbilityContext ,res: Resource, onCompleteFunction:(value:T)=>void | PromiseLike, - onErrorFunction:(reason?:BusinessError|string)=>void)=>void; -} \ No newline at end of file diff --git a/library/src/main/ets/components/imageknife/resourcemanage/ParseResClient.ets b/library/src/main/ets/components/imageknife/resourcemanage/ParseResClient.ets deleted file mode 100644 index 7839571..0000000 --- a/library/src/main/ets/components/imageknife/resourcemanage/ParseResClient.ets +++ /dev/null @@ -1,54 +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 { IResourceFetch } from '../resourcemanage/IResourceFetch' -import { ResourceTypeEts } from '../../imageknife/constants/ResourceTypeEts' -import resourceManager from '@ohos.resourceManager'; -import { ImageKnifeGlobal } from '../ImageKnifeGlobal'; -import { BusinessError } from '@ohos.base' -import common from '@ohos.app.ability.common'; -import { ContextCacheProxy } from '../requestmanage/ContextCacheProxy'; - -export class ParseResClient implements IResourceFetch { - loadResource(context: common.UIAbilityContext, res: Resource, onCompleteFunction: (value: ArrayBuffer) => void | PromiseLike, onErrorFunction: (reason?: BusinessError | string) => void) { - let resId = res.id; - let resType = res.type; - if (resType == ResourceTypeEts.MEDIA) { - let moduleContext = ContextCacheProxy.getInstance() - .contextGetValue(res.moduleName, context); - if (moduleContext != undefined) { - (moduleContext.resourceManager as resourceManager.ResourceManager) - .getMediaContent(resId) - .then(data => { - let arrayBuffer = this.typedArrayToBuffer(data); - onCompleteFunction(arrayBuffer) - }) - .catch((err: BusinessError) => { - onErrorFunction(err) - }) - } - - } - else if (resType == ResourceTypeEts.RAWFILE) { - onErrorFunction('ParseResClient 本地资源是rawfile暂时无法解析出错') - } else { - onErrorFunction('ParseResClient 本地资源不是media也不是rawfile无法解析出错') - } - } - - typedArrayToBuffer(array: Uint8Array): ArrayBuffer { - return array.buffer.slice(array.byteOffset, array.byteLength + array.byteOffset) - } -} \ No newline at end of file diff --git a/library/src/main/ets/components/imageknife/resourcemanage/ParseResClientBase64.ets b/library/src/main/ets/components/imageknife/resourcemanage/ParseResClientBase64.ets deleted file mode 100644 index 2f8510f..0000000 --- a/library/src/main/ets/components/imageknife/resourcemanage/ParseResClientBase64.ets +++ /dev/null @@ -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 { IResourceFetch } from '../resourcemanage/IResourceFetch' -import { ResourceTypeEts } from '../../imageknife/constants/ResourceTypeEts' -import { Base64 } from '../../cache/Base64' -import { BusinessError } from '@ohos.base' -import resourceManager from '@ohos.resourceManager'; -import { ImageKnifeGlobal } from '../ImageKnifeGlobal'; -import common from '@ohos.app.ability.common' -import { ContextCacheProxy } from '../requestmanage/ContextCacheProxy' - -export class ParseResClientBase64 implements IResourceFetch { - loadResource(context: common.UIAbilityContext, res: Resource, onCompleteFunction: (value: ArrayBuffer) => void | PromiseLike, onErrorFunction: (reason?: BusinessError | string) => void) { - let resId = res.id; - let resType = res.type; - if (resType == ResourceTypeEts.MEDIA) { - let moduleContext = ContextCacheProxy.getInstance() - .contextGetValue(res.moduleName, context); - (moduleContext.resourceManager as resourceManager.ResourceManager) - .getMediaContentBase64(resId) - .then(data => { - let matchReg = ';base64,'; - let firstIndex = data.indexOf(matchReg) - data = data.substring(firstIndex + matchReg.length, data.length) - let arrayBuffer = Base64.getInstance() - .decode(data); - onCompleteFunction(arrayBuffer) - }) - .catch((err: BusinessError) => { - onErrorFunction(err) - }) - } - else if (resType == ResourceTypeEts.RAWFILE) { - onErrorFunction('ParseResClientBase64 本地资源是rawfile暂时无法解析出错') - } else { - onErrorFunction('ParseResClientBase64 本地资源不是media也不是rawfile无法解析出错') - } - } -} \ No newline at end of file diff --git a/library/src/main/ets/components/imageknife/transform/AsyncTransform.ets b/library/src/main/ets/components/imageknife/transform/AsyncTransform.ets deleted file mode 100644 index d267bc4..0000000 --- a/library/src/main/ets/components/imageknife/transform/AsyncTransform.ets +++ /dev/null @@ -1,18 +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 { BusinessError } from '@ohos.base' -export interface AsyncTransform { - asyncTransform:(err:BusinessError|string, data: T | null)=>void -} diff --git a/library/src/main/ets/components/imageknife/transform/BaseTransform.ets b/library/src/main/ets/components/imageknife/transform/BaseTransform.ets deleted file mode 100644 index e0a7f1c..0000000 --- a/library/src/main/ets/components/imageknife/transform/BaseTransform.ets +++ /dev/null @@ -1,28 +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 {AsyncTransform} from "../transform/AsyncTransform" -import {RequestOption} from "../../imageknife/RequestOption" - -export interface BaseTransform { - // 实现类 返回作为key生成的一部分 - getName(): string; - - getClassName():string; - - getConstructorParams():string; - - transform(value: ArrayBuffer, request: RequestOption, func: AsyncTransform):void; -} \ No newline at end of file diff --git a/library/src/main/ets/components/imageknife/transform/BlurTransformation.ets b/library/src/main/ets/components/imageknife/transform/BlurTransformation.ets deleted file mode 100644 index 3cd6547..0000000 --- a/library/src/main/ets/components/imageknife/transform/BlurTransformation.ets +++ /dev/null @@ -1,100 +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 { BaseTransform } from "../transform/BaseTransform" -import { AsyncTransform } from "../transform/AsyncTransform" -import { Constants } from "../constants/Constants" -import { RequestOption } from "../../imageknife/RequestOption" -import { TransformUtils } from "../transform/TransformUtils" -import image from "@ohos.multimedia.image" -import { fastBlur } from "../utils/FastBlur" -import {LogUtil} from '../../imageknife/utils/LogUtil' -import { BusinessError } from '@ohos.base' -import {Size} from '../../imageknife/RequestOption' - -export class BlurTransformation implements BaseTransform { - private _mRadius: number; - private sampling: number - - constructor(radius: number,sampling?:number) { - this._mRadius = radius; - if(sampling == undefined){ - this.sampling = 1 - } else { - this.sampling = sampling - } - } - - getClassName() { - return "BlurTransformation"; - } - - getConstructorParams() { - return JSON.stringify([this._mRadius,this.sampling]); - } - - getName() { - return "BlurTransformation _mRadius:" + this._mRadius +"==BlurTransformation sampling:"+ this.sampling; - } - - transform(buf: ArrayBuffer, request: RequestOption, func?: AsyncTransform) { - if (!buf || buf.byteLength <= 0) { - LogUtil.log(Constants.PROJECT_TAG + ";BlurTransformation buf is empty"); - if (func) { - func?.asyncTransform(Constants.PROJECT_TAG + ";BlurTransformation buf is empty", null); - } - return; - } - let imageSource:image.ImageSource = image.createImageSource(buf); - TransformUtils.getPixelMapSize(imageSource, {asyncTransform:(error:BusinessError|string, size: Size|null) => { - if (!size) { - func?.asyncTransform(error, null) - return; - } - let pixelMapWidth = size.width; - let pixelMapHeight = size.height; - let targetWidth = request.size.width; - let targetHeight = request.size.height; - if (pixelMapWidth < targetWidth) { - targetWidth = pixelMapWidth; - } - if (pixelMapHeight < targetHeight) { - targetHeight = pixelMapHeight; - } - - let options:image.DecodingOptions = { - editable: true, - desiredSize: { - width: pixelMapWidth / this.sampling, - height: pixelMapHeight / this.sampling - } - } - imageSource.createPixelMap(options) - .then((data) => { - if (request.gpuEnabled) { - fastBlur.blurGPU(data, this._mRadius, true, func); - } else { - fastBlur.blur(data, this._mRadius, true, func); - } - imageSource.release() - }) - .catch((e:BusinessError) => { - LogUtil.log(Constants.PROJECT_TAG + ";error:" + e); - imageSource.release() - func?.asyncTransform(e, null); - }) - }}) - } -} \ No newline at end of file diff --git a/library/src/main/ets/components/imageknife/transform/BrightnessFilterTransformation.ets b/library/src/main/ets/components/imageknife/transform/BrightnessFilterTransformation.ets deleted file mode 100644 index cd9d884..0000000 --- a/library/src/main/ets/components/imageknife/transform/BrightnessFilterTransformation.ets +++ /dev/null @@ -1,128 +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 { BaseTransform } from "../transform/BaseTransform" -import { AsyncTransform } from "../transform/AsyncTransform" -import { Constants } from "../constants/Constants" -import { RequestOption } from "../../imageknife/RequestOption" -import { LogUtil } from '../../imageknife/utils/LogUtil' -import image from "@ohos.multimedia.image" -import { GPUImageBrightnessFilter } from '@ohos/gpu_transform' -import { BusinessError } from '@ohos.base' -import {Size} from '../../imageknife/RequestOption' - -/** - * brightness value ranges from -1.0 to 1.0, with 0.0 as the normal level - */ -export class BrightnessFilterTransformation implements BaseTransform { - private _mBrightness: number = 0.0; - - constructor(brightness: number) { - this._mBrightness = brightness; - } - - getClassName(){ - return "BrightnessFilterTransformation"; - } - - getConstructorParams(){ - return JSON.stringify([this._mBrightness]); - } - - getName() { - return "BrightnessFilterTransformation:" + this._mBrightness; - } - - async transform(buf: ArrayBuffer, request: RequestOption, func?: AsyncTransform) { - if (!buf || buf.byteLength <= 0) { - LogUtil.log(Constants.PROJECT_TAG + ";GrayscaleTransformation buf is empty"); - if (func != undefined) { - func?.asyncTransform(Constants.PROJECT_TAG + ";GrayscaleTransformation buf is empty", null); - } - return; - } - let imageSource:image.ImageSource = image.createImageSource(buf); - - let imageInfo:image.ImageInfo = await imageSource.getImageInfo(); - let size:Size = { - width: imageInfo.size.width, - height: imageInfo.size.height - } - - if (!size) { - func?.asyncTransform("GrayscaleTransformation The image size does not exist.", null) - return; - } - let pixelMapWidth:number = size.width; - let pixelMapHeight:number = size.height; - let targetWidth:number = request.size.width; - let targetHeight:number = request.size.height; - if (pixelMapWidth < targetWidth) { - targetWidth = pixelMapWidth; - } - if (pixelMapHeight < targetHeight) { - targetHeight = pixelMapHeight; - } - - let options:image.DecodingOptions = { - editable: true, - desiredSize: { - width: targetWidth, - height: targetHeight - } - } - let data = await imageSource.createPixelMap(options); - imageSource.release() - let bufferData = new ArrayBuffer(data.getPixelBytesNumber()); - await data.readPixelsToBuffer(bufferData); - - if (request.gpuEnabled) { - let filter:GPUImageBrightnessFilter = new GPUImageBrightnessFilter(); - filter.setImageData(bufferData, targetWidth, targetHeight); - filter.setBrightness(this._mBrightness); - let buf = await filter.getPixelMapBuf(0, 0, targetWidth, targetHeight); - data.writeBufferToPixels(buf); - if (func) { - func?.asyncTransform("success", data); - } - return; - } - - let dataArray = new Uint8Array(bufferData); - - for (let index = 0; index < dataArray.length; index += 4) { - dataArray[index] = this.checkVisAble(dataArray[index] * this._mBrightness + dataArray[index]); - dataArray[index+1] = this.checkVisAble(dataArray[index+1] * this._mBrightness + dataArray[index+1]); - dataArray[index+2] = this.checkVisAble(dataArray[index+2] * this._mBrightness + dataArray[index+2]); - dataArray[index+3] = this.checkVisAble(dataArray[index+3] * this._mBrightness + dataArray[index+3]); - } - - await data.writeBufferToPixels(bufferData); - - if (func) { - func?.asyncTransform("", data); - } - } - - private checkVisAble(input: number) { - if (input > 255) { - input = 255; - } - if (input <= 0) { - input = 0; - } - return input; - } -} \ No newline at end of file diff --git a/library/src/main/ets/components/imageknife/transform/ContrastFilterTransformation.ets b/library/src/main/ets/components/imageknife/transform/ContrastFilterTransformation.ets deleted file mode 100644 index 6454511..0000000 --- a/library/src/main/ets/components/imageknife/transform/ContrastFilterTransformation.ets +++ /dev/null @@ -1,142 +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 { BaseTransform } from "../transform/BaseTransform" -import { AsyncTransform } from "../transform/AsyncTransform" -import { Constants } from "../constants/Constants" -import { RequestOption } from "../../imageknife/RequestOption" -import { LogUtil } from '../../imageknife/utils/LogUtil' -import image from "@ohos.multimedia.image" -import { GPUImageContrastFilter } from '@ohos/gpu_transform' -import { BusinessError } from '@ohos.base' -import {Size} from '../../imageknife/RequestOption' - -/** - * 以24位色图像为例子,每种色彩都可以用0-255, - * 一共256种深度来表示。如果我们把它画在一个二维坐标上, - * 正好是一条直线。比如我们将像素的色深作为横坐标,输出色深作为纵坐标的画,正好是一条经过原点(0,0)的45度斜线 - * 那么很容易就可以写出它的直线方程:Out = In * 1 ,系数1就是对比度的概念.如果把条直线加上一个偏移量变成B,那么它的直线方程就成为: - * Out = In * 1 + (ab)偏移量(ab)就是亮度的增量。 - *只要有初中的代数知识就很容易看出它满足一条直线方程:Y= A * X + B。但是,我们这里要处理的情况稍微有些不同,在图像处理中,对比度和亮度要分别对待。不能因为改变而改变亮度,因为我们习惯上把灰色(127,127)这一点作为中心点。 - * - *直线公式修改成:Y=( X - 127 ) * A + B。A表示对比度,B表示亮度增量。 - * 只要亮度增量 B=0,无论怎么改变对比度 A,该直线始终通过中心点(127,127),也就是说改变对比度的同时,亮度没有改变 - * - *_mContrast value ranges from 0.0 to 4.0, with 1.0 as the normal level - * - * - */ -export class ContrastFilterTransformation implements BaseTransform { - private _mContrast: number; - - constructor(contrast: number) { - this._mContrast = contrast; - } - - getClassName(){ - return "ContrastFilterTransformation"; - } - - getConstructorParams(){ - return JSON.stringify([this._mContrast]); - } - - - getName() { - return "ContrastFilterTransformation:" + this._mContrast; - } - - async transform(buf: ArrayBuffer, request: RequestOption, func?: AsyncTransform) { - if (!buf || buf.byteLength <= 0) { - LogUtil.log(Constants.PROJECT_TAG + ";ContrastFilterTransformation buf is empty"); - if (func!=undefined) { - func?.asyncTransform(Constants.PROJECT_TAG + ";ContrastFilterTransformation buf is empty", null); - } - return; - } - let imageSource:image.ImageSource = image.createImageSource(buf); - - let imageInfo:image.ImageInfo = await imageSource.getImageInfo(); - let size:Size = { - width: imageInfo.size.width, - height: imageInfo.size.height - } - - if (!size) { - func?.asyncTransform("ContrastFilterTransformation The image size does not exist.", null) - return; - } - let pixelMapWidth:number = size.width; - let pixelMapHeight:number = size.height; - let targetWidth:number = request.size.width; - let targetHeight:number = request.size.height; - if (pixelMapWidth < targetWidth) { - targetWidth = pixelMapWidth; - } - if (pixelMapHeight < targetHeight) { - targetHeight = pixelMapHeight; - } - - let options:image.DecodingOptions = { - editable: true, - desiredSize: { - width: targetWidth, - height: targetHeight - } - } - - let data = await imageSource.createPixelMap(options); - imageSource.release() - let bufferData = new ArrayBuffer(data.getPixelBytesNumber()); - await data.readPixelsToBuffer(bufferData); - - if (request.gpuEnabled) { - let filter = new GPUImageContrastFilter(); - filter.setImageData(bufferData, targetWidth, targetHeight); - filter.setContrast(this._mContrast) - let buf = await filter.getPixelMapBuf(0, 0, targetWidth, targetHeight); - data.writeBufferToPixels(buf); - if (func != undefined) { - func?.asyncTransform("success", data); - } - return; - } - - let dataArray = new Uint8Array(bufferData); - - let brightness = 0; // 亮度的偏移量,可以默认0 - for (let index = 0; index < dataArray.length; index += 4) { - dataArray[index] = this.checkVisAble((dataArray[index] - 127) * this._mContrast + brightness + 127); - dataArray[index+1] = this.checkVisAble((dataArray[index+1] - 127) * this._mContrast + brightness + 127); - dataArray[index+2] = this.checkVisAble((dataArray[index+2] - 127) * this._mContrast + brightness + 127); - dataArray[index+3] = this.checkVisAble((dataArray[index+3] - 127) * this._mContrast + brightness + 127); - } - - await data.writeBufferToPixels(bufferData); - if (func != undefined) { - func?.asyncTransform("", data); - } - } - - private checkVisAble(input: number) { - if (input > 255) { - input = 255; - } - if (input <= 0) { - input = 0; - } - return input; - } -} \ No newline at end of file diff --git a/library/src/main/ets/components/imageknife/transform/CropCircleTransformation.ets b/library/src/main/ets/components/imageknife/transform/CropCircleTransformation.ets deleted file mode 100644 index 14a2d02..0000000 --- a/library/src/main/ets/components/imageknife/transform/CropCircleTransformation.ets +++ /dev/null @@ -1,149 +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 { BaseTransform } from "../transform/BaseTransform" -import { AsyncTransform } from "../transform/AsyncTransform" -import { Constants } from "../constants/Constants" -import { RequestOption } from "../../imageknife/RequestOption" -import { TransformUtils } from "../transform/TransformUtils" -import {LogUtil} from '../../imageknife/utils/LogUtil' -import image from "@ohos.multimedia.image" -import { BusinessError } from '@ohos.base' -import {Size} from '../../imageknife/RequestOption' - -export class CropCircleTransformation implements BaseTransform { - private static TAG: string = "CropCircleTransformation"; - private mCenterX: number = 0; - private mCenterY: number = 0; - private mRadius: number = 0; - - getClassName(){ - return "CropCircleTransformation"; - } - - getConstructorParams(){ - return "[]"; - } - - getName() { - return CropCircleTransformation.TAG + ";mCenterX:" + this.mCenterX - + ";mCenterY:" + this.mCenterY - + ";mRadius:" + this.mRadius; - } - - transform(buf: ArrayBuffer, request: RequestOption, func?: AsyncTransform) { - if (!buf || buf.byteLength <= 0) { - LogUtil.log(Constants.PROJECT_TAG + CropCircleTransformation.TAG + " buf is empty"); - if (func!=undefined) { - func?.asyncTransform(Constants.PROJECT_TAG + CropCircleTransformation.TAG + " buf is empty", null); - } - return; - } - let imageSource:image.ImageSource = image.createImageSource(buf); - - TransformUtils.getPixelMapSize(imageSource, {asyncTransform:(error:BusinessError|string, size: Size | null) => { - if (!size) { - func?.asyncTransform(error, null) - return; - } - let pixelMapWidth:number = size.width; - let pixelMapHeight:number = size.height; - let targetWidth:number = request.size.width; - let targetHeight:number = request.size.height; - if (pixelMapWidth < targetWidth) { - targetWidth = pixelMapWidth; - } - if (pixelMapHeight < targetHeight) { - targetHeight = pixelMapHeight; - } - this.updatePixelMapSize(imageSource, targetWidth, targetHeight, func); - }}) - } - - private updatePixelMapSize(imageSource: image.ImageSource, outWith: number, outHeight: number, func?: AsyncTransform) { - let options:image.DecodingOptions = { - editable: true, - desiredSize: { - width: outWith, - height: outHeight - } - } - imageSource.createPixelMap(options) - .then((p:PixelMap) => { - this.transformCircle(p, func); - imageSource.release() - }) - .catch((e:BusinessError) => { - LogUtil.log(Constants.PROJECT_TAG + CropCircleTransformation.TAG + " transform e:" + e); - if (func!=undefined) { - func?.asyncTransform(Constants.PROJECT_TAG + CropCircleTransformation.TAG + "e" + e, null); - } - imageSource.release() - }) - } - - private async transformCircle(data: PixelMap, func?: AsyncTransform) { - let imageInfo:image.ImageInfo = await data.getImageInfo(); - let size:Size = { - width: imageInfo.size.width, - height: imageInfo.size.height - } - - if (!size) { - func?.asyncTransform("CropCircleTransformation The image size does not exist.", null) - return; - } - let height:number = size.height; - let width:number = size.width; - this.mRadius = 0; - if (width > height) { - this.mRadius = height / 2; - } else { - this.mRadius = width / 2; - } - this.mCenterX = width / 2; - this.mCenterY = height / 2; - - let bufferData:ArrayBuffer = new ArrayBuffer(data.getPixelBytesNumber()); - await data.readPixelsToBuffer(bufferData); - - let dataArray = new Uint8Array(bufferData); - - for (let h = 0;h <= height; h++) { - for (let w = 0;w <= width; w++) { - if (this.isContainsCircle(w, h)) { - continue; - } - // 针对的点 - let index = (h * width + w) * 4; - dataArray[index] = 0; - dataArray[index+1] = 0; - dataArray[index+2] = 0; - dataArray[index+3] = 0; - } - } - await data.writeBufferToPixels(bufferData); - if (func != undefined) { - func?.asyncTransform("", data); - } - } - - isContainsCircle(x: number, y: number): boolean { - let a = Math.pow((this.mCenterX - x), 2); - let b = Math.pow((this.mCenterY - y), 2); - let c = Math.sqrt((a + b)); - return c <= this.mRadius; - } -} \ No newline at end of file diff --git a/library/src/main/ets/components/imageknife/transform/CropCircleWithBorderTransformation.ets b/library/src/main/ets/components/imageknife/transform/CropCircleWithBorderTransformation.ets deleted file mode 100644 index 582cb40..0000000 --- a/library/src/main/ets/components/imageknife/transform/CropCircleWithBorderTransformation.ets +++ /dev/null @@ -1,185 +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 { BaseTransform } from "../transform/BaseTransform" -import { AsyncTransform } from "../transform/AsyncTransform" -import { Constants } from "../constants/Constants" -import { RequestOption } from "../../imageknife/RequestOption" -import { TransformUtils } from "../transform/TransformUtils" -import { LogUtil } from '../../imageknife/utils/LogUtil' -import image from "@ohos.multimedia.image" -import { BusinessError } from '@ohos.base' -import { Size } from '../../imageknife/RequestOption' - -export interface rgbColor { - r_color: number, - g_color: number, - b_color: number, -} - -export class CropCircleWithBorderTransformation implements BaseTransform { - private static TAG: string = "CropCircleTransformation"; - private mBorderSize: number = 5; - private mCenterX: number = 0; - private mCenterY: number = 0; - private mRadius: number = 0; - private mRColor: number = 0; - private mGColor: number = 0; - private mBColor: number = 0; - - constructor(border_size: number, value: rgbColor) { - this.mRColor = value.g_color; - this.mGColor = value.g_color; - this.mBColor = value.b_color; - this.mBorderSize = border_size; - } - - getClassName() { - return "CropCircleWithBorderTransformation"; - } - - getConstructorParams() { - return JSON.stringify([this.mBorderSize, { - r_color: this.mRColor, - g_color: this.mGColor, - b_color: this.mBColor - }]); - } - - getName() { - return CropCircleWithBorderTransformation.TAG + ";mBorderSize:" + this.mBorderSize - + ";mCenterX:" + this.mCenterX - + ";mCenterY:" + this.mCenterY - + ";mRadius:" + this.mRadius - + ";mRColor:" + this.mRColor - + ";mGColor:" + this.mGColor - + ";mBColor:" + this.mBColor; - } - - transform(buf: ArrayBuffer, request: RequestOption, func?: AsyncTransform) { - if (!buf || buf.byteLength <= 0) { - LogUtil.log(Constants.PROJECT_TAG + ";CropCircleWithBorderTransformation buf is empty"); - if (func != undefined) { - func?.asyncTransform(Constants.PROJECT_TAG + ";CropCircleWithBorderTransformation buf is empty", null); - } - return; - } - let imageSource: image.ImageSource = image.createImageSource(buf); - TransformUtils.getPixelMapSize(imageSource, { - asyncTransform: (error: BusinessError | string, size: Size | null) => { - if (!size) { - func?.asyncTransform(error, null) - return; - } - let pixelMapWidth = size.width; - let pixelMapHeight = size.height; - let targetWidth = request.size.width; - let targetHeight = request.size.height; - if (pixelMapWidth < targetWidth) { - targetWidth = pixelMapWidth; - } - if (pixelMapHeight < targetHeight) { - targetHeight = pixelMapHeight; - } - this.updatePixelMapSize(imageSource, targetWidth, targetHeight, func); - } - }) - } - - private updatePixelMapSize(imageSource: image.ImageSource, outWith: number, outHeight: number, func?: AsyncTransform) { - let options: image.DecodingOptions = { - editable: true, - desiredSize: { - width: outWith, - height: outHeight - } - } - imageSource.createPixelMap(options) - .then((pixelMap: PixelMap) => { - this.transformPixelMap(pixelMap, outWith, outHeight, func); - imageSource.release() - }) - .catch((e: BusinessError) => { - LogUtil.log(Constants.PROJECT_TAG + ";CropCircleWithBorderTransformation e:" + e); - if (func != undefined) { - func?.asyncTransform(Constants.PROJECT_TAG + ";CropCircleWithBorderTransformation e:" + e, null); - } - imageSource.release() - }) - } - - private async transformPixelMap(pixelMap: PixelMap, width: number, height: number, func?: AsyncTransform) { - this.mRadius = 0; - if (width > height) { - this.mRadius = height / 2; - } else { - this.mRadius = width / 2; - } - this.mCenterX = width / 2; - this.mCenterY = height / 2; - - - let bufferData = new ArrayBuffer(pixelMap.getPixelBytesNumber()); - await pixelMap.readPixelsToBuffer(bufferData); - - let dataArray = new Uint8Array(bufferData); - - for (let h = 0; h <= height; h++) { - for (let w = 0; w <= width; w++) { - // 不在大圆之内的设置透明 - // 在大圆与小圆之间的 设置rgb值 - // 小圆之内的不变 - let isSmallCircle: boolean = this.isContainsSmallCircle(w, h); - let isBigCircle: boolean = this.isContainsCircle(w, h); - if (isSmallCircle) { - continue; - } - - let index = (h * width + w) * 4; - if (!isBigCircle) { - // 设置透明 - dataArray[index] = 0; - dataArray[index+1] = 0; - dataArray[index+2] = 0; - dataArray[index+3] = 0; - } else { - // 设置broke - dataArray[index] = this.mRColor; - dataArray[index+1] = this.mGColor; - dataArray[index+2] = this.mBColor; - } - } - } - - await pixelMap.writeBufferToPixels(bufferData); - if (func != undefined) { - func?.asyncTransform("", pixelMap); - } - } - - isContainsCircle(x: number, y: number): boolean { - let a: number = Math.pow((this.mCenterX - x), 2); - let b: number = Math.pow((this.mCenterY - y), 2); - let c: number = Math.sqrt((a + b)); - return c <= this.mRadius; - } - - isContainsSmallCircle(x: number, y: number): boolean { - let a: number = Math.pow((this.mCenterX - x), 2); - let b: number = Math.pow((this.mCenterY - y), 2); - let c: number = Math.sqrt((a + b)); - return c <= (this.mRadius - this.mBorderSize); - } -} \ No newline at end of file diff --git a/library/src/main/ets/components/imageknife/transform/CropSquareTransformation.ets b/library/src/main/ets/components/imageknife/transform/CropSquareTransformation.ets deleted file mode 100644 index 5ac287c..0000000 --- a/library/src/main/ets/components/imageknife/transform/CropSquareTransformation.ets +++ /dev/null @@ -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 { BaseTransform } from "../transform/BaseTransform" -import { AsyncTransform } from "../transform/AsyncTransform" -import { Constants } from "../constants/Constants" -import { RequestOption } from "../../imageknife/RequestOption" -import {LogUtil} from '../../imageknife/utils/LogUtil' -import { BusinessError } from '@ohos.base' -import {Size} from '../../imageknife/RequestOption' - -import image from "@ohos.multimedia.image" - -export class CropSquareTransformation implements BaseTransform { - private static TAG: string = "CropSquareTransformation"; - - getClassName(){ - return "CropSquareTransformation"; - } - - getConstructorParams(){ - return '[]'; - } - - getName() { - return CropSquareTransformation.TAG; - } - - transform(buf: ArrayBuffer, request: RequestOption, func?: AsyncTransform) { - if (!buf || buf.byteLength <= 0) { - LogUtil.log(Constants.PROJECT_TAG + ";CropSquareTransformation buf is empty"); - if (func != undefined) { - func?.asyncTransform(Constants.PROJECT_TAG + ";CropSquareTransformation buf is empty", null); - } - return; - } - this.squareCrop(buf, request, func); - } - - squareCrop(buf: ArrayBuffer, request: RequestOption, func?: AsyncTransform) { - let imageSource:image.ImageSource = image.createImageSource(buf); - imageSource.getImageInfo() - .then((p:image.ImageInfo) => { - let pw:number = p.size.width; - let ph:number = p.size.height; - let outWidth:number = request.size.width; - let outHeight:number = request.size.height; - if (pw < outWidth) { - outWidth = pw; - } - if (ph < outHeight) { - outHeight = ph; - } - let targetSize:number = outWidth > outHeight ? outHeight : outWidth; - let options:image.DecodingOptions = { - editable: true, - rotate: 0, - desiredSize: { - width: pw, - height: ph - }, - desiredRegion: { size: { width: targetSize, height: targetSize }, - x: pw / 2 - targetSize / 2, - y: ph / 2 - targetSize / 2, - }, - } - imageSource.createPixelMap(options) - .then(data => { - if (func != undefined) { - func?.asyncTransform("", data); - } - imageSource.release() - }) - .catch((e:BusinessError) => { - if (func != undefined) { - func?.asyncTransform(Constants.PROJECT_TAG + ";CropSquareTransformation e:" + e, null); - } - imageSource.release() - }) - }) - .catch((error:BusinessError) => { - if (func != undefined) { - func?.asyncTransform(Constants.PROJECT_TAG + ";CropSquareTransformation error:" + error, null); - } - }) - } -} \ No newline at end of file diff --git a/library/src/main/ets/components/imageknife/transform/CropTransformation.ets b/library/src/main/ets/components/imageknife/transform/CropTransformation.ets deleted file mode 100644 index 9cf40b2..0000000 --- a/library/src/main/ets/components/imageknife/transform/CropTransformation.ets +++ /dev/null @@ -1,122 +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 { BaseTransform } from "../transform/BaseTransform" -import { AsyncTransform } from "../transform/AsyncTransform" -import { Constants } from "../constants/Constants" -import { RequestOption } from "../../imageknife/RequestOption" -import { TransformUtils } from "../transform/TransformUtils" -import {LogUtil} from '../../imageknife/utils/LogUtil' -import image from "@ohos.multimedia.image" -import { BusinessError } from '@ohos.base' -import {Size} from '../../imageknife/RequestOption' - -export class CropTransformation implements BaseTransform { - private static TAG: string = "CropCircleTransformation"; - private mWidth: number = 0; - private mHeight: number = 0; - private mCropType: CropType = CropType.CENTER; - - constructor(width: number, height: number, cropType: CropType) { - this.mWidth = width; - this.mHeight = height; - this.mCropType = cropType; - } - - getClassName(){ - return "CropTransformation"; - } - - getConstructorParams(){ - return JSON.stringify([this.mWidth,this.mHeight ,this.mCropType]); - } - - getName() { - return CropTransformation.TAG + ";mWidth:" + this.mWidth - + ";mHeight:" + this.mHeight - + ";mCropType:" + this.mCropType; - } - - transform(buf: ArrayBuffer, request: RequestOption, func?: AsyncTransform) { - if (!buf || buf.byteLength <= 0) { - LogUtil.log(Constants.PROJECT_TAG + ";CropTransformation buf is empty"); - if (func != undefined) { - func?.asyncTransform(Constants.PROJECT_TAG + ";CropTransformation buf is empty", null); - } - return; - } - let imageSource:image.ImageSource = image.createImageSource(buf); - TransformUtils.getPixelMapSize(imageSource, {asyncTransform:(error:BusinessError|string, size: Size|null) => { - if (!size) { - func?.asyncTransform(error, null) - return; - } - let pixelMapWidth:number = size.width; - let pixelMapHeight:number = size.height; - - this.mWidth = this.mWidth == 0 ? pixelMapWidth : this.mWidth; - this.mHeight = this.mHeight == 0 ? pixelMapHeight : this.mHeight; - - let scaleX:number = this.mWidth / pixelMapWidth; - let scaleY:number = this.mHeight / pixelMapHeight; - let scale:number = Math.max(scaleX, scaleY); - - let scaledWidth:number = scale * pixelMapWidth; - let scaledHeight:number = scale * pixelMapHeight; - let left:number = (this.mWidth - scaledWidth) / 2; - let top:number = Math.abs(this.getTop(pixelMapHeight)); - let options:image.DecodingOptions = { - editable: true, - desiredRegion: { - size: { - width: scaledWidth > pixelMapWidth ? pixelMapWidth : scaledWidth, - height: scaledHeight > pixelMapHeight ? pixelMapHeight : scaledHeight - }, - x: left < 0 ? 0 : left, - y: top < 0 ? 0 : top, - }, - } - imageSource.createPixelMap(options) - .then((data:PixelMap) => { - func?.asyncTransform("", data); - imageSource.release() - }) - .catch((e:BusinessError) => { - LogUtil.log(Constants.PROJECT_TAG + ";error:" + e); - imageSource.release() - func?.asyncTransform(e, null); - }) - }}) - } - - private getTop(scaledHeight: number): number{ - switch (this.mCropType) { - case CropType.TOP: - return 0; - case CropType.CENTER: - return (this.mHeight - scaledHeight) / 2; - case CropType.BOTTOM: - return this.mHeight - scaledHeight; - default: - return 0; - } - } -} - -export enum CropType { - TOP = 0, - CENTER = 1, - BOTTOM = 2 -} \ No newline at end of file diff --git a/library/src/main/ets/components/imageknife/transform/GrayscaleTransformation.ets b/library/src/main/ets/components/imageknife/transform/GrayscaleTransformation.ets deleted file mode 100644 index bc6771d..0000000 --- a/library/src/main/ets/components/imageknife/transform/GrayscaleTransformation.ets +++ /dev/null @@ -1,123 +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 { BaseTransform } from "../transform/BaseTransform" -import { AsyncTransform } from "../transform/AsyncTransform" -import { Constants } from "../constants/Constants" -import { RequestOption } from "../../imageknife/RequestOption" -import { TransformUtils } from "../transform/TransformUtils" -import {LogUtil} from '../../imageknife/utils/LogUtil' -import image from "@ohos.multimedia.image" -import { GPUImageGrayscaleFilter } from '@ohos/gpu_transform' -import { BusinessError } from '@ohos.base' -import {Size} from '../../imageknife/RequestOption' - -export class GrayscaleTransformation implements BaseTransform { - getName() { - return "GrayscaleTransformation"; - } - - getClassName(){ - return "GrayscaleTransformation"; - } - - getConstructorParams(){ - return '[]'; - } - - async transform(buf: ArrayBuffer, request: RequestOption, func?: AsyncTransform) { - if (!buf || buf.byteLength <= 0) { - LogUtil.log(Constants.PROJECT_TAG + ";GrayscaleTransformation buf is empty"); - if (func != undefined) { - func?.asyncTransform(Constants.PROJECT_TAG + ";GrayscaleTransformation buf is empty", null); - } - return; - } - let imageSource:image.ImageSource = image.createImageSource(buf); - - let imageInfo = await imageSource.getImageInfo(); - let size:Size = { - width: imageInfo.size.width, - height: imageInfo.size.height - } - - if (!size) { - func?.asyncTransform("GrayscaleTransformation The image size does not exist.", null) - return; - } - let pixelMapWidth:number = size.width; - let pixelMapHeight:number = size.height; - let targetWidth:number = request.size.width; - let targetHeight:number = request.size.height; - if (pixelMapWidth < targetWidth) { - targetWidth = pixelMapWidth; - } - if (pixelMapHeight < targetHeight) { - targetHeight = pixelMapHeight; - } - - let options:image.DecodingOptions = { - editable: true, - desiredSize: { - width: targetWidth, - height: targetHeight - } - } - let data:PixelMap= await imageSource.createPixelMap(options); - imageSource.release() - let bufferData = new ArrayBuffer(data.getPixelBytesNumber()); - let bufferNewData = new ArrayBuffer(data.getPixelBytesNumber()); - await data.readPixelsToBuffer(bufferData); - - if (request.gpuEnabled) { - let filter = new GPUImageGrayscaleFilter(); - filter.setImageData(bufferData, targetWidth, targetHeight); - let buf = await filter.getPixelMapBuf(0, 0, targetWidth, targetHeight); - data.writeBufferToPixels(buf); - if (func != undefined) { - func?.asyncTransform("success", data); - } - return; - } - - - let dataArray = new Uint8Array(bufferData); - let dataNewArray = new Uint8Array(bufferNewData); - - for (let index = 0; index < dataArray.length; index += 4) { - const r = dataArray[index]; - const g = dataArray[index+1]; - const b = dataArray[index+2]; - const f = dataArray[index+3]; - // b g r - dataNewArray[index] = this.grayscale(r, g, b); - dataNewArray[index+1] = this.grayscale(r, g, b); - dataNewArray[index+2] = this.grayscale(r, g, b); - dataNewArray[index+3] = f; - } - - await data.writeBufferToPixels(bufferNewData); - if (func != undefined) { - func?.asyncTransform('', data); - } - } - - /** - * 将读取的像素点的rgb值,全部灰度化,得到灰度图片(黑白图片)加权平均法 - */ - private grayscale(r: number, g: number, b: number): number{ - return (r * 28 + g * 151 + b * 77) >> 8; - } -} \ No newline at end of file diff --git a/library/src/main/ets/components/imageknife/transform/InvertFilterTransformation.ets b/library/src/main/ets/components/imageknife/transform/InvertFilterTransformation.ets deleted file mode 100644 index 7373ae8..0000000 --- a/library/src/main/ets/components/imageknife/transform/InvertFilterTransformation.ets +++ /dev/null @@ -1,126 +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 { BaseTransform } from "../transform/BaseTransform" -import { AsyncTransform } from "../transform/AsyncTransform" -import { Constants } from "../constants/Constants" -import { RequestOption } from "../../imageknife/RequestOption" -import {LogUtil} from '../../imageknife/utils/LogUtil' -import image from "@ohos.multimedia.image" -import { GPUImageColorInvertFilter } from '@ohos/gpu_transform' -import { BusinessError } from '@ohos.base' -import {Size} from '../../imageknife/RequestOption' - -/** - ** Image inversion is particularly useful for enhancing white or gray detail in - * dark areas of an embedded image, especially when black areas dominate in size.The formula for image inversion is as follows: - * Reverse Formula - * s=L-l-r; - * Where, s is the gray level value of a point in the inverted target image, r is the gray level value of the corresponding point in the original image, and L is the number of gray levels. - */ - -export class InvertFilterTransformation implements BaseTransform { - getName() { - return "InvertFilterTransformation"; - } - - getClassName(){ - return "InvertFilterTransformation"; - } - - getConstructorParams(){ - return '[]'; - } - - async transform(buf: ArrayBuffer, request: RequestOption, func?: AsyncTransform) { - if (!buf || buf.byteLength <= 0) { - LogUtil.log(Constants.PROJECT_TAG + ";InvertFilterTransformation buf is empty"); - if (func != undefined) { - func?.asyncTransform(Constants.PROJECT_TAG + ";InvertFilterTransformation buf is empty", null); - } - return; - } - let imageSource:image.ImageSource = image.createImageSource(buf); - - let imageInfo:image.ImageInfo = await imageSource.getImageInfo(); - let size:Size = { - width: imageInfo.size.width, - height: imageInfo.size.height - } - - if (!size) { - func?.asyncTransform("InvertFilterTransformation The image size does not exist.", null) - return; - } - - let pixelMapWidth:number = size.width; - let pixelMapHeight:number = size.height; - let targetWidth:number = request.size.width; - let targetHeight:number = request.size.height; - if (pixelMapWidth < targetWidth) { - targetWidth = pixelMapWidth; - } - if (pixelMapHeight < targetHeight) { - targetHeight = pixelMapHeight; - } - - let options:image.DecodingOptions = { - editable: true, - desiredSize: { - width: targetWidth, - height: targetHeight - } - } - - let data:PixelMap = await imageSource.createPixelMap(options); - imageSource.release() - let bufferData = new ArrayBuffer(data.getPixelBytesNumber()); - await data.readPixelsToBuffer(bufferData); - - if (request.gpuEnabled) { - let filter = new GPUImageColorInvertFilter(); - filter.setImageData(bufferData, targetWidth, targetHeight); - let buf = await filter.getPixelMapBuf(0, 0, targetWidth, targetHeight); - data.writeBufferToPixels(buf); - if (func != undefined) { - func?.asyncTransform("success", data); - } - return; - } - - - let dataArray = new Uint8Array(bufferData); - - for (let index = 0; index < dataArray.length; index += 4) { - dataArray[index] = this.checkVisAble(255 - dataArray[index]); - dataArray[index+1] = this.checkVisAble(255 - dataArray[index+1]); - dataArray[index+2] = this.checkVisAble(255 - dataArray[index+2]); - } - await data.writeBufferToPixels(bufferData); - if (func != undefined) { - func?.asyncTransform('', data); - } - } - - private checkVisAble(input: number) { - if (input > 255) { - input = 255; - } - if (input <= 0) { - input = 0; - } - return input; - } -} \ No newline at end of file diff --git a/library/src/main/ets/components/imageknife/transform/KuwaharaFilterTransform.ets b/library/src/main/ets/components/imageknife/transform/KuwaharaFilterTransform.ets deleted file mode 100644 index 9b87c41..0000000 --- a/library/src/main/ets/components/imageknife/transform/KuwaharaFilterTransform.ets +++ /dev/null @@ -1,112 +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 { BaseTransform } from "../transform/BaseTransform" -import { AsyncTransform } from "../transform/AsyncTransform" -import { Constants } from "../constants/Constants" -import { RequestOption } from "../../imageknife/RequestOption" -import { TransformUtils } from "../transform/TransformUtils" -import image from "@ohos.multimedia.image" -import { LogUtil } from '../../imageknife/utils/LogUtil' -import { GPUImageKuwaharaFilter } from '@ohos/gpu_transform' -import { BusinessError } from '@ohos.base' -import {Size} from '../../imageknife/RequestOption' - - -export class KuwaharaFilterTransform implements BaseTransform { - private _mRadius: number = 0; - - constructor(radius: number) { - this._mRadius = radius; - } - - getClassName(){ - return "KuwaharaFilterTransform"; - } - - getConstructorParams(){ - return JSON.stringify([this._mRadius]); - } - - getName() { - return "KuwaharaFilterTransform _mRadius:" + this._mRadius; - } - - transform(buf: ArrayBuffer, request: RequestOption, func?: AsyncTransform) { - if (!buf || buf.byteLength <= 0) { - LogUtil.log(Constants.PROJECT_TAG + ";KuwaharaFilterTransform buf is empty"); - if (func != undefined) { - func?.asyncTransform(Constants.PROJECT_TAG + ";KuwaharaFilterTransform buf is empty", null); - } - return; - } - if (!request.gpuEnabled) { - LogUtil.error(Constants.PROJECT_TAG + ";the KuwaharaFilterTransform supported only in GPU mode"); - if (func) { - func?.asyncTransform(Constants.PROJECT_TAG + ";;the KuwaharaFilterTransform supported only in GPU mode", null); - } - return; - } - - let imageSource:image.ImageSource = image.createImageSource(buf); - TransformUtils.getPixelMapSize(imageSource, {asyncTransform:(error:BusinessError|string, size: Size|null) => { - if (!size) { - func?.asyncTransform(error, null) - return; - } - let pixelMapWidth:number = size.width; - let pixelMapHeight:number = size.height; - let targetWidth:number = request.size.width; - let targetHeight:number = request.size.height; - if (pixelMapWidth < targetWidth) { - targetWidth = pixelMapWidth; - } - if (pixelMapHeight < targetHeight) { - targetHeight = pixelMapHeight; - } - - let options:image.DecodingOptions = { - editable: true, - desiredSize: { - width: targetWidth, - height: targetHeight - } - } - imageSource.createPixelMap(options) - .then((data) => { - this.kuwahara(data, targetWidth, targetHeight, func); - imageSource.release() - }) - .catch((e:BusinessError) => { - LogUtil.log(Constants.PROJECT_TAG + ";error:" + e); - func?.asyncTransform(e, null); - imageSource.release() - }) - }}) - } - - private async kuwahara(bitmap: image.PixelMap, targetWidth: number, targetHeight: number, func?: AsyncTransform) { - let bufferData = new ArrayBuffer(bitmap.getPixelBytesNumber()); - await bitmap.readPixelsToBuffer(bufferData); - let filter = new GPUImageKuwaharaFilter(); - filter.setImageData(bufferData, targetWidth, targetHeight); - filter.setRadius(this._mRadius); - let buf = await filter.getPixelMapBuf(0, 0, targetWidth, targetHeight) - bitmap.writeBufferToPixels(buf); - if (func != undefined) { - func?.asyncTransform("success", bitmap); - } - } -} \ No newline at end of file diff --git a/library/src/main/ets/components/imageknife/transform/MaskTransformation.ets b/library/src/main/ets/components/imageknife/transform/MaskTransformation.ets deleted file mode 100644 index 8a73ce7..0000000 --- a/library/src/main/ets/components/imageknife/transform/MaskTransformation.ets +++ /dev/null @@ -1,137 +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 { BaseTransform } from "../transform/BaseTransform" -import { AsyncTransform } from "../transform/AsyncTransform" -import { Constants } from "../constants/Constants" -import { RequestOption } from "../../imageknife/RequestOption" -import { MaskUtils } from "../utils/MaskUtils" -import {LogUtil} from '../../imageknife/utils/LogUtil' -import image from "@ohos.multimedia.image" -import resmgr from "@ohos.resourceManager" -import { ImageKnifeGlobal } from '../ImageKnifeGlobal' -import resourceManager from '@ohos.resourceManager' -import { BusinessError } from '@ohos.base' -import {Size} from '../../imageknife/RequestOption' -import common from '@ohos.app.ability.common' -import { ContextCacheProxy } from '../requestmanage/ContextCacheProxy' - -export class MaskTransformation implements BaseTransform { - private _mResourceData:Resource|undefined = undefined; - - constructor(maskBitmap: Resource) { - this._mResourceData = maskBitmap; - } - - getClassName(){ - return "MaskTransformation"; - } - - getConstructorParams(){ - return JSON.stringify([this._mResourceData]); - } - - getName() { - return "MaskTransformation:" + this._mResourceData; - } - - async transform(buf: ArrayBuffer, request: RequestOption, func?: AsyncTransform) { - if (!buf || buf.byteLength <= 0) { - LogUtil.log(Constants.PROJECT_TAG + ";MaskTransformation buf is empty"); - if (func != undefined) { - func?.asyncTransform(Constants.PROJECT_TAG + ";MaskTransformation buf is empty", null); - } - return; - } - let imageSource:image.ImageSource = image.createImageSource(buf); - - let imageInfo = await imageSource.getImageInfo(); - let size:Size = { - width: imageInfo.size.width, - height: imageInfo.size.height - } - - if (!size) { - func?.asyncTransform("MaskTransformation The image size does not exist.", null) - return; - } - let pixelMapWidth:number = size.width; - let pixelMapHeight:number = size.height; - let targetWidth:number = request.size.width; - let targetHeight:number = request.size.height; - if (pixelMapWidth < targetWidth) { - targetWidth = pixelMapWidth; - } - if (pixelMapHeight < targetHeight) { - targetHeight = pixelMapHeight; - } - - let options:image.DecodingOptions = { - editable: true, - desiredSize: { - width: targetWidth, - height: targetHeight - } - } - imageSource.createPixelMap(options) - .then(data => { - this.openInternal(request, data, targetWidth, targetHeight, func) - imageSource.release() - }) - .catch((e:BusinessError )=> { - func?.asyncTransform(e, null); - imageSource.release() - }) - } - - private openInternal(request: RequestOption,bitmap: PixelMap, width: number, height: number, func?: AsyncTransform) { - if (!this._mResourceData) { - if(func != undefined){ - func.asyncTransform("MaskTransformation resource is empty", null) - } - } - let context = (request.getModuleContext() as common.UIAbilityContext) - if(context != undefined){ - if(this._mResourceData != undefined){ - let moduleContext = ContextCacheProxy.getInstance() - .contextGetValue(this._mResourceData.moduleName, context); - if (moduleContext != undefined) { - let resourceManager = moduleContext.resourceManager as resourceManager.ResourceManager - if(resourceManager != undefined && this._mResourceData != undefined) - resourceManager.getMediaContent(this._mResourceData?.id) - .then(array => { - let buffer = array.buffer.slice(array.byteOffset, array.byteLength + array.byteOffset); - let imageSource:image.ImageSource = image.createImageSource(buffer); - let options:image.DecodingOptions = { - editable: true, - desiredSize: { - width: width, - height: height - } - } - imageSource.createPixelMap(options) - .then(maskBitmap => { - MaskUtils.mask(bitmap, maskBitmap, func) - }) - }) - .catch((err:BusinessError) => { - func?.asyncTransform("MaskTransformation openInternal error" + err, null); - }) - } - - } - } - } -} \ No newline at end of file diff --git a/library/src/main/ets/components/imageknife/transform/PixelationFilterTransformation.ets b/library/src/main/ets/components/imageknife/transform/PixelationFilterTransformation.ets deleted file mode 100644 index 341b42a..0000000 --- a/library/src/main/ets/components/imageknife/transform/PixelationFilterTransformation.ets +++ /dev/null @@ -1,100 +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 { BaseTransform } from "../transform/BaseTransform" -import { AsyncTransform } from "../transform/AsyncTransform" -import { Constants } from "../constants/Constants" -import { RequestOption } from "../../imageknife/RequestOption" -import { TransformUtils } from "../transform/TransformUtils" -import { LogUtil } from '../../imageknife/utils/LogUtil' -import image from "@ohos.multimedia.image" -import { pixelUtils } from "../utils/PixelUtils" -import { BusinessError } from '@ohos.base' -import {Size} from '../../imageknife/RequestOption' - -/** - * Applies a Pixelation effect to the image. - * The pixel with a default of 10.0. - */ -export class PixelationFilterTransformation implements BaseTransform { - private _mPixel: number = 10.0; - - constructor(pixel?: number) { - if (pixel) { - this._mPixel = pixel; - } - } - - getClassName(){ - return "PixelationFilterTransformation"; - } - - getConstructorParams(){ - return JSON.stringify([this._mPixel]); - } - - getName() { - return "PixelationFilterTransformation" + this._mPixel; - } - - transform(buf: ArrayBuffer, request: RequestOption, func?: AsyncTransform) { - if (!buf || buf.byteLength <= 0) { - LogUtil.log(Constants.PROJECT_TAG + ";PixelationFilterTransformation buf is empty"); - if (func != undefined) { - func?.asyncTransform(Constants.PROJECT_TAG + ";PixelationFilterTransformation buf is empty", null); - } - return; - } - let imageSource:image.ImageSource = image.createImageSource(buf); - TransformUtils.getPixelMapSize(imageSource, {asyncTransform:(error:BusinessError|string, size:Size|null) => { - if (!size) { - func?.asyncTransform(error, null) - return; - } - let pixelMapWidth:number = size.width; - let pixelMapHeight:number = size.height; - let targetWidth:number = request.size.width; - let targetHeight:number = request.size.height; - if (pixelMapWidth < targetWidth) { - targetWidth = pixelMapWidth; - } - if (pixelMapHeight < targetHeight) { - targetHeight = pixelMapHeight; - } - - let options:image.DecodingOptions = { - editable: true, - desiredSize: { - width: targetWidth, - height: targetHeight - } - } - imageSource.createPixelMap(options) - .then((data) => { - if (request.gpuEnabled) { - pixelUtils.pixelGPU(data, this._mPixel, func); - } else { - pixelUtils.pixel(data, this._mPixel, func); - } - imageSource.release() - }) - .catch((e:BusinessError) => { - LogUtil.log(Constants.PROJECT_TAG + ";error:" + e); - imageSource.release(); - func?.asyncTransform(e, null); - }) - }}) - } -} \ No newline at end of file diff --git a/library/src/main/ets/components/imageknife/transform/RotateImageTransformation.ets b/library/src/main/ets/components/imageknife/transform/RotateImageTransformation.ets deleted file mode 100644 index 3cc9656..0000000 --- a/library/src/main/ets/components/imageknife/transform/RotateImageTransformation.ets +++ /dev/null @@ -1,90 +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 { BaseTransform } from "../transform/BaseTransform" -import { AsyncTransform } from "../transform/AsyncTransform" -import { Constants } from "../constants/Constants" -import { RequestOption } from "../../imageknife/RequestOption" -import { TransformUtils } from "../transform/TransformUtils" -import {LogUtil} from '../../imageknife/utils/LogUtil' -import { BusinessError } from '@ohos.base' -import {Size} from '../../imageknife/RequestOption' - -import image from "@ohos.multimedia.image" - -export class RotateImageTransformation implements BaseTransform { - private mDegreesToRotate: number = 0; - - constructor(degreesToRotate: number) { - this.mDegreesToRotate = degreesToRotate; - } - - getName() { - return "RotateImageTransformation" + ";degreesToRotate:" + this.mDegreesToRotate; - } - - getClassName(){ - return "RotateImageTransformation"; - } - - getConstructorParams(){ - return JSON.stringify([this.mDegreesToRotate]); - } - - transform(buf: ArrayBuffer, request: RequestOption, func?: AsyncTransform) { - if (!buf || buf.byteLength <= 0) { - LogUtil.log(Constants.PROJECT_TAG + ";RotateImageTransformation buf is empty"); - if (func != undefined) { - func?.asyncTransform(Constants.PROJECT_TAG + ";RotateImageTransformation buf is empty", null); - } - return; - } - let imageSource:image.ImageSource = image.createImageSource(buf); - TransformUtils.getPixelMapSize(imageSource, {asyncTransform:(error:BusinessError|string, size: Size|null) => { - if (!size) { - func?.asyncTransform(error, null) - return; - } - let pixelMapWidth:number = size.width; - let pixelMapHeight:number = size.height; - let targetWidth:number = request.size.width; - let targetHeight:number = request.size.height; - if (pixelMapWidth < targetWidth) { - targetWidth = pixelMapWidth; - } - if (pixelMapHeight < targetHeight) { - targetHeight = pixelMapHeight; - } - - let options:image.DecodingOptions = { - editable: true, - rotate: this.mDegreesToRotate%360, - desiredSize: { - width: targetWidth, - height: targetHeight - } - } - imageSource.createPixelMap(options) - .then((data) => { - func?.asyncTransform("", data); - imageSource.release() - }) - .catch((e:BusinessError) => { - LogUtil.log(Constants.PROJECT_TAG + ";error:" + e); - imageSource.release() - func?.asyncTransform(e, null); - }) - }}) - } -} \ No newline at end of file diff --git a/library/src/main/ets/components/imageknife/transform/RoundedCornersTransformation.ets b/library/src/main/ets/components/imageknife/transform/RoundedCornersTransformation.ets deleted file mode 100644 index 2fdebef..0000000 --- a/library/src/main/ets/components/imageknife/transform/RoundedCornersTransformation.ets +++ /dev/null @@ -1,245 +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 { BaseTransform } from "../transform/BaseTransform" -import { AsyncTransform } from "../transform/AsyncTransform" -import { ArcPoint } from "../entry/ArcPoint" -import { Constants } from "../constants/Constants" -import { RequestOption } from "../../imageknife/RequestOption" -import { TransformUtils } from "../transform/TransformUtils" -import {LogUtil} from '../../imageknife/utils/LogUtil' -import { BusinessError } from '@ohos.base' -import {Size} from '../../imageknife/RequestOption' - -import image from "@ohos.multimedia.image" - -export interface RoundCorner{ - top_left: number, - top_right: number, - bottom_left: number, - bottom_right: number -} - -export class RoundedCornersTransformation implements BaseTransform { - private mTop_left: number = 0; - private mTop_right: number = 0; - private mBottom_left: number = 0; - private mBottom_right: number = 0; - private mTransform_pixelMap: PixelMap|undefined = undefined; - private mPoint: ArcPoint[] = new Array(); - - constructor(value:RoundCorner) { - this.mTop_left = value.top_left; - this.mTop_right = value.top_right; - this.mBottom_left = value.bottom_left; - this.mBottom_right = value.bottom_right; - } - - getClassName(){ - return "RoundedCornersTransformation"; - } - - getConstructorParams(){ - return JSON.stringify([{ - top_left: this.mTop_left, - top_right: this.mTop_right, - bottom_left: this.mBottom_left, - bottom_right: this.mBottom_right - }]); - } - - getName() { - return "RoundedCornersTransformation" + ";mTop_left:" + this.mTop_left - + ";mTop_right:" + this.mTop_right - + ";mBottom_left:" + this.mBottom_left - + ";mBottom_right:" + this.mBottom_right - } - - transform(buf: ArrayBuffer, request: RequestOption, func?: AsyncTransform) { - LogUtil.log('RoundedCornersTransformation = '+ this.getName() - + 'buf is null ='+ (buf == null)); - if (!buf || buf.byteLength <= 0) { - LogUtil.log(Constants.PROJECT_TAG + ";RoundedCornersTransformation buf is empty"); - if (func != undefined) { - func?.asyncTransform(Constants.PROJECT_TAG + ";RoundedCornersTransformation buf is empty", null); - } - return; - } - let imageSource:image.ImageSource = image.createImageSource(buf); - TransformUtils.getPixelMapSize(imageSource, {asyncTransform:(error:BusinessError|string, size: Size|null) => { - if (!size) { - func?.asyncTransform(error, null) - return; - } - let pixelMapWidth:number = size.width; - let pixelMapHeight:number = size.height; - let targetWidth:number = request.size.width; - let targetHeight:number = request.size.height; - if (pixelMapWidth < targetWidth) { - targetWidth = pixelMapWidth; - } - if (pixelMapHeight < targetHeight) { - targetHeight = pixelMapHeight; - } - this.transformPixelMap(imageSource, pixelMapWidth, pixelMapHeight, func); - }}) - } - - private transformPixelMap(imageSource: image.ImageSource, outWith: number, outHeight: number, func?: AsyncTransform) { - let options:image.DecodingOptions = { - editable: true, - desiredSize: { - width: outWith, - height: outHeight - } - } - imageSource.createPixelMap(options) - .then((pixelMap) => { - this.mTransform_pixelMap = pixelMap; - this.mTransform_pixelMap.getImageInfo() - .then((data) => { - let width:number = data.size.width; - let height:number = data.size.height; - if (this.mTop_left > 0) { - this.top_left_corners(); - } - if (this.mTop_right > 0) { - this.top_right_corners(width); - } - if (this.mBottom_left > 0) { - this.bottom_left_corners(width, height); - } - if (this.mBottom_right > 0) { - this.bottom_right_corners(width, height); - } - if (func != undefined && this.mTransform_pixelMap != undefined) { - func?.asyncTransform("", this.mTransform_pixelMap); - } - imageSource.release() - }) - .catch((error:BusinessError) => { - imageSource.release() - LogUtil.log(Constants.PROJECT_TAG + "RoundedCornersTransformation error:" + error); - }); - }) - .catch((e:BusinessError) => { - LogUtil.log(Constants.PROJECT_TAG + ";error:" + e); - if (func != undefined) { - func?.asyncTransform(e, null); - } - }) - - } - - private top_left_corners() { - this.mPoint = new Array(); - for (let time = 180; time < 270; time++) { - let hudu:number = (2 * Math.PI / 360) * time; - let x:number= this.mTop_left + Math.sin(hudu) * this.mTop_left; - let y:number = this.mTop_left + Math.cos(hudu) * this.mTop_left; - this.mPoint.push(new ArcPoint(x, y)); - } - this.hand_pixel_point(this.mPoint); - } - - private top_right_corners(width: number) { - this.mPoint = new Array(); - for (let time = 0; time < 90; time++) { - let hudu:number = (2 * Math.PI / 360) * time; - let x:number = (width - this.mTop_right) + Math.cos(hudu) * this.mTop_right; - let y:number = this.mTop_right - Math.sin(hudu) * this.mTop_right; - this.mPoint.push(new ArcPoint(x, y)); - } - - this.hand_right_pixel_point(this.mPoint, width); - } - - private bottom_left_corners(width: number, height: number) { - this.mPoint = new Array(); - for (let time = 90; time < 180; time++) { - let hudu = (2 * Math.PI / 360) * time; - let x = this.mBottom_left + Math.cos(hudu) * this.mBottom_left; - let y = height - this.mBottom_left + Math.sin(hudu) * this.mBottom_left; - this.mPoint.push(new ArcPoint(x, y)); - } - this.hand_pixel_point(this.mPoint); - } - - private bottom_right_corners(width: number, height: number) { - this.mPoint = new Array(); - for (let time = 0; time < 90; time++) { - let hudu = (2 * Math.PI / 360) * time; - let x = width - this.mBottom_right + Math.cos(hudu) * this.mBottom_right; - let y = height - this.mBottom_right + Math.sin(hudu) * this.mBottom_right; - this.mPoint.push(new ArcPoint(x, y)); - } - this.hand_right_pixel_point(this.mPoint, width); - } - - private hand_pixel_point(points: ArcPoint[]) { - for (let index = 0; index < points.length; index++) { - const element = points[index]; - let x = element.getX(); - let y = element.getY(); - - for (let i = 0; i <= x; i++) { - let buffer1 = new ArrayBuffer(5); - let bytes1 = new Uint8Array(buffer1); - let writePositionRen:image.PositionArea = { - pixels: buffer1, - offset: 1, - stride: 1024, - region: { size: { width: 1, height: 1 }, - x: i, - y: y - } - } - for (let j = 0;j < 5; j++) { - bytes1[j] = 0; - } - if(this.mTransform_pixelMap != undefined) { - this.mTransform_pixelMap.writePixels(writePositionRen); - } - } - } - } - - private hand_right_pixel_point(points: ArcPoint[], width: number) { - for (let index = 0; index < points.length; index++) { - const element = points[index]; - let x = element.getX(); - let y = element.getY(); - - for (let i = x; i <= width; i++) { - let buffer1 = new ArrayBuffer(5); - let bytes1 = new Uint8Array(buffer1); - let writePositionRen:image.PositionArea = { - pixels: buffer1, - offset: 0, - stride: 4, - region: { size: { width: 1, height: 1 }, - x: i, - y: y - } - } - for (let j = 0;j < 5; j++) { - bytes1[j] = 0; - } - if(this.mTransform_pixelMap != undefined) { - this.mTransform_pixelMap.writePixels(writePositionRen); - } - } - } - } -} \ No newline at end of file diff --git a/library/src/main/ets/components/imageknife/transform/SepiaFilterTransformation.ets b/library/src/main/ets/components/imageknife/transform/SepiaFilterTransformation.ets deleted file mode 100644 index ab4e99f..0000000 --- a/library/src/main/ets/components/imageknife/transform/SepiaFilterTransformation.ets +++ /dev/null @@ -1,144 +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 { BaseTransform } from "../transform/BaseTransform" -import { AsyncTransform } from "../transform/AsyncTransform" -import { Constants } from "../constants/Constants" -import { RequestOption } from "../../imageknife/RequestOption" -import { LogUtil } from '../../imageknife/utils/LogUtil' -import image from "@ohos.multimedia.image" -import { GPUImageSepiaToneFilter } from '@ohos/gpu_transform' -import { BusinessError } from '@ohos.base' -import {Size} from '../../imageknife/RequestOption' - -/** - * Applies a simple sepia effect. - *

- * The intensity with a default of 1.0. - */ -export class SepiaFilterTransformation implements BaseTransform { - getName() { - return "SepiaFilterTransformation"; - } - - getClassName(){ - return "SepiaFilterTransformation"; - } - - getConstructorParams(){ - return '[]'; - } - - async transform(buf: ArrayBuffer, request: RequestOption, func?: AsyncTransform) { - if (!buf || buf.byteLength <= 0) { - LogUtil.log(Constants.PROJECT_TAG + ";SepiaFilterTransformation buf is empty"); - if (func!=undefined) { - func?.asyncTransform(Constants.PROJECT_TAG + ";SepiaFilterTransformation buf is empty", null); - } - return; - } - let imageSource:image.ImageSource = image.createImageSource(buf); - - let imageInfo:image.ImageInfo = await imageSource.getImageInfo(); - let size:Size = { - width: imageInfo.size.width, - height: imageInfo.size.height - } - - if (!size) { - func?.asyncTransform("SepiaFilterTransformation The image size does not exist.", null) - return; - } - - let pixelMapWidth:number = size.width; - let pixelMapHeight:number = size.height; - let targetWidth:number = request.size.width; - let targetHeight:number = request.size.height; - if (pixelMapWidth < targetWidth) { - targetWidth = pixelMapWidth; - } - if (pixelMapHeight < targetHeight) { - targetHeight = pixelMapHeight; - } - - let options:image.DecodingOptions = { - editable: true, - desiredSize: { - width: targetWidth, - height: targetHeight - } - } - let data:PixelMap = await imageSource.createPixelMap(options); - imageSource.release(); - let bufferData = new ArrayBuffer(data.getPixelBytesNumber()); - await data.readPixelsToBuffer(bufferData); - - if (request.gpuEnabled) { - let filter = new GPUImageSepiaToneFilter(); - filter.setImageData(bufferData, targetWidth, targetHeight); - let buf = await filter.getPixelMapBuf(0, 0, targetWidth, targetHeight); - data.writeBufferToPixels(buf); - if (func != undefined) { - func?.asyncTransform("success", data); - } - return; - } - - let bufferNewData = new ArrayBuffer(data.getPixelBytesNumber()); - let dataArray = new Uint8Array(bufferData); - let dataNewArray = new Uint8Array(bufferNewData); - - for (let index = 0; index < dataArray.length; index += 4) { - const r:number = dataArray[index]; - const g:number = dataArray[index+1]; - const b:number = dataArray[index+2]; - const f:number = dataArray[index+3]; - - dataNewArray[index+2] = this.checkVisAble(this.colorBlend(this.noise() - , (r * 0.272) + (g * 0.534) + (b * 0.131) - , b)); - dataNewArray[index+1] = this.checkVisAble(this.colorBlend(this.noise() - , (r * 0.349) + (g * 0.686) + (b * 0.168) - , g)); - dataNewArray[index] = this.checkVisAble(this.colorBlend(this.noise() - , (r * 0.393) + (g * 0.769) + (b * 0.189) - , r)); - dataNewArray[index+3] = f; - } - - await data.writeBufferToPixels(bufferNewData); - if (func != undefined) { - func?.asyncTransform("", data); - } - } - - private checkVisAble(input: number) { - if (input > 255) { - input = 255; - } - if (input <= 0) { - input = 0; - } - return input; - } - - private colorBlend(scale: number, dest: number, src: number): number { - return (scale * dest + (1.0 - scale) * src); - } - - private noise(): number { - return Math.random() * 0.5 + 0.5; - } -} \ No newline at end of file diff --git a/library/src/main/ets/components/imageknife/transform/SketchFilterTransformation.ets b/library/src/main/ets/components/imageknife/transform/SketchFilterTransformation.ets deleted file mode 100644 index 1092912..0000000 --- a/library/src/main/ets/components/imageknife/transform/SketchFilterTransformation.ets +++ /dev/null @@ -1,86 +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 { BaseTransform } from '../transform/BaseTransform' -import { AsyncTransform } from '../transform/AsyncTransform' -import { Constants } from '../constants/Constants' -import { RequestOption } from '../../imageknife/RequestOption' -import { TransformUtils } from '../transform/TransformUtils' -import image from '@ohos.multimedia.image' -import { CalculatePixelUtils } from '../utils/CalculatePixelUtils' -import { BusinessError } from '@ohos.base' -import {Size} from '../../imageknife/RequestOption' - -export class SketchFilterTransformation implements BaseTransform { - - getClassName(){ - return "SketchFilterTransformation"; - } - - getConstructorParams(){ - return '[]'; - } - - getName() { - return 'SketchFilterTransformation'; - } - - transform(buf: ArrayBuffer, request: RequestOption, func?: AsyncTransform) { - if (!buf || buf.byteLength <= 0) { - if (func != undefined) { - func?.asyncTransform(Constants.PROJECT_TAG + ';SketchFilterTransformation buf is empty', null); - } - return; - } - let imageSource:image.ImageSource = image.createImageSource(buf); - TransformUtils.getPixelMapSize(imageSource, {asyncTransform:(error:BusinessError|string, size: Size|null) => { - if (!size) { - func?.asyncTransform(error, null) - return; - } - let pixelMapWidth: number = size.width; - let pixelMapHeight: number = size.height; - let targetWidth: number = request.size.width; - let targetHeight: number = request.size.height; - if (pixelMapWidth < targetWidth) { - targetWidth = pixelMapWidth; - } - if (pixelMapHeight < targetHeight) { - targetHeight = pixelMapHeight; - } - - let options: image.DecodingOptions = { - editable: true, - desiredSize: { - width: targetWidth, - height: targetHeight - } - } - imageSource.createPixelMap(options) - .then((data) => { - if (request.gpuEnabled) { - CalculatePixelUtils.sketchGpu(data, func); - } else { - CalculatePixelUtils.sketch(data, func); - } - imageSource.release() - }) - .catch((e:BusinessError) => { - func?.asyncTransform(e, null); - imageSource.release() - }) - }}) - } -} \ No newline at end of file diff --git a/library/src/main/ets/components/imageknife/transform/SwirlFilterTransformation.ets b/library/src/main/ets/components/imageknife/transform/SwirlFilterTransformation.ets deleted file mode 100644 index 76c5a14..0000000 --- a/library/src/main/ets/components/imageknife/transform/SwirlFilterTransformation.ets +++ /dev/null @@ -1,216 +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 { BaseTransform } from '../transform/BaseTransform' -import { AsyncTransform } from '../transform/AsyncTransform' -import { Constants } from '../constants/Constants' -import { RequestOption } from '../../imageknife/RequestOption' -import { TransformUtils } from '../transform/TransformUtils' -import image from '@ohos.multimedia.image' -import { PixelEntry } from '../entry/PixelEntry' -import { ColorUtils } from '../utils/ColorUtils' -import { CalculatePixelUtils } from '../utils/CalculatePixelUtils' -import { GPUImageSwirlFilter } from '@ohos/gpu_transform' -import { BusinessError } from '@ohos.base' -import {Size} from '../../imageknife/RequestOption' - -export class SwirlFilterTransformation implements BaseTransform { - private radius: number = 0; - private _angle: number = 0.9; - private _xCenter: number = 0.5; - private _yCenter: number = 0.5; - - constructor(radius: number, angle?: number, centerPoint?: Array) { - this.radius = radius; - if (angle) { - this._angle = angle; - } - if (centerPoint && centerPoint.length === 2) { - this._xCenter = centerPoint[0]; - this._yCenter = centerPoint[1]; - } - } - - getClassName(){ - return "SwirlFilterTransformation"; - } - - getConstructorParams(){ - return JSON.stringify([this.radius,this._angle,[this._xCenter,this._yCenter]]); - } - - getName() { - return 'SwirlFilterTransformation' + this.radius; - } - - transform(buf: ArrayBuffer, request: RequestOption, func?: AsyncTransform) { - if (!buf || buf.byteLength <= 0) { - if (func != undefined) { - func?.asyncTransform(Constants.PROJECT_TAG + ';SwirlFilterTransformation buf is empty', null); - } - return; - } - let imageSource:image.ImageSource = image.createImageSource(buf); - TransformUtils.getPixelMapSize(imageSource,{asyncTransform: (error:BusinessError|string, size:Size|null) => { - if (!size) { - func?.asyncTransform(error, null) - return; - } - let pixelMapWidth:number = size.width; - let pixelMapHeight:number = size.height; - let targetWidth:number = request.size.width; - let targetHeight:number = request.size.height; - if (pixelMapWidth < targetWidth) { - targetWidth = pixelMapWidth; - } - if (pixelMapHeight < targetHeight) { - targetHeight = pixelMapHeight; - } - - let options:image.DecodingOptions = { - editable: true, - desiredSize: { - width: targetWidth, - height: targetHeight - } - } - imageSource.createPixelMap(options) - .then((data) => { - this.swirl(data, this.radius, request, func); - imageSource.release(); - }) - .catch((e:BusinessError) => { - imageSource.release(); - func?.asyncTransform(e, null); - }) - }}) - } - - private async swirl(bitmap: image.PixelMap, degree: number, request: RequestOption, func?: AsyncTransform) { - let imageInfo:image.ImageInfo = await bitmap.getImageInfo(); - let size:Size = { - width: imageInfo.size.width, - height: imageInfo.size.height - } - if (!size) { - return; - } - let width:number = size.width; - let height:number = size.height; - - - let bufferData = new ArrayBuffer(bitmap.getPixelBytesNumber()); - await bitmap.readPixelsToBuffer(bufferData); - if (request.gpuEnabled) { - let filter = new GPUImageSwirlFilter(); - filter.setImageData(bufferData, width, height); - filter.setRadius(degree); - filter.setAngle(this._angle) - filter.setCenter(this._xCenter, this._yCenter) - let buf = await filter.getPixelMapBuf(0, 0, width, height); - bitmap.writeBufferToPixels(buf); - if (func != undefined) { - func?.asyncTransform("success", bitmap); - } - return; - } - - let pixEntry: Array = new Array(); - - let rgbData = CalculatePixelUtils.createInt2DArray(height, width); - - let dataArray = new Uint8Array(bufferData); - - let ph:number = 0; - let pw:number = 0; - for (let index = 0; index < dataArray.length; index += 4) { - const r:number = dataArray[index]; - const g:number = dataArray[index+1]; - const b:number = dataArray[index+2]; - const f:number = dataArray[index+3]; - - let entry = new PixelEntry(); - entry.a = 0; - entry.b = b; - entry.g = g; - entry.r = r; - entry.f = f; - entry.pixel = ColorUtils.rgb(entry.r, entry.g, entry.b); - pixEntry.push(entry); - rgbData[ph][pw] = ColorUtils.rgb(entry.r, entry.g, entry.b); - if (pw == width - 1) { - pw = 0; - ph++; - } else { - pw++; - } - } - - let k = degree / 3600; - let cenX = width / 2; - let cenY = height / 2; - - let radius = 0; - for (let h = 0;h < height; h++) { - for (let w = 0; w < width; w++) { - - let offerX = w - cenX; - let offerY = h - cenY; - let radian = Math.atan2(offerY, offerX) - radius = Math.floor(Math.sqrt(offerX * offerX + offerY * offerY)); - - let newX = Math.floor(radius * Math.cos(radian + k * radius)) + cenX; - let newY = Math.floor(radius * Math.sin(radian + k * radius)) + cenY; - - newX = Math.floor(Math.min(width - 1, Math.max(0, newX))); - newY = Math.floor(Math.min(height - 1, Math.max(0, newY))); - - rgbData[h][w] = rgbData[newY][newX]; - } - } - - - let bufferNewData = new ArrayBuffer(bitmap.getPixelBytesNumber()); - let dataNewArray = new Uint8Array(bufferNewData); - let index = 0; - let mh = 0; - let nw = 0; - - for (let i = 0; i < dataNewArray.length; i += 4) { - let pixel_1 = rgbData[mh][nw]; - - if (nw == width - 1) { - nw = 0; - mh++; - } else { - nw++; - } - - let p_r = ColorUtils.red(pixel_1); - let p_g = ColorUtils.green(pixel_1); - let p_b = ColorUtils.blue(pixel_1); - - dataNewArray[i] = p_r; - dataNewArray[i+1] = p_g; - dataNewArray[i+2] = p_b; - dataNewArray[i+3] = pixEntry[index].f; - index++; - } - await bitmap.writeBufferToPixels(bufferNewData); - if (func != undefined) { - func?.asyncTransform("", bitmap); - } - } -} \ No newline at end of file diff --git a/library/src/main/ets/components/imageknife/transform/ToonFilterTransform.ets b/library/src/main/ets/components/imageknife/transform/ToonFilterTransform.ets deleted file mode 100644 index 3b5dcde..0000000 --- a/library/src/main/ets/components/imageknife/transform/ToonFilterTransform.ets +++ /dev/null @@ -1,118 +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 { BaseTransform } from "../transform/BaseTransform" -import { AsyncTransform } from "../transform/AsyncTransform" -import { Constants } from "../constants/Constants" -import { RequestOption } from "../../imageknife/RequestOption" -import { TransformUtils } from "../transform/TransformUtils" -import image from "@ohos.multimedia.image" -import { LogUtil } from '../../imageknife/utils/LogUtil' -import { GPUImageToonFilter } from '@ohos/gpu_transform' -import { BusinessError } from '@ohos.base' -import {Size} from '../../imageknife/RequestOption' - -export class ToonFilterTransform implements BaseTransform { - private threshold: number = 0.2; - private quantizationLevels: number = 10.0; - - constructor(threshold?: number, quantizationLevels?: number) { - if (threshold) { - this.threshold = threshold; - } - if (quantizationLevels) { - this.quantizationLevels = quantizationLevels; - } - } - - getClassName(){ - return "ToonFilterTransform"; - } - - getConstructorParams(){ - return JSON.stringify([this.threshold,this.quantizationLevels]); - } - - getName() { - return "ToonFilterTransform threshold:" + this.threshold + ";quantizationLevels:" + this.quantizationLevels; - } - - transform(buf: ArrayBuffer, request: RequestOption, func?: AsyncTransform) { - if (!buf || buf.byteLength <= 0) { - LogUtil.log(Constants.PROJECT_TAG + ";ToonFilterTransform buf is empty"); - if (func != undefined) { - func?.asyncTransform(Constants.PROJECT_TAG + ";ToonFilterTransform buf is empty", null); - } - return; - } - if (!request.gpuEnabled) { - LogUtil.error(Constants.PROJECT_TAG + ";the ToonFilterTransform supported only in GPU mode"); - if (func) { - func?.asyncTransform(Constants.PROJECT_TAG + ";the ToonFilterTransform supported only in GPU mode", null); - } - return; - } - - let imageSource:image.ImageSource = image.createImageSource(buf); - TransformUtils.getPixelMapSize(imageSource, {asyncTransform:(error:BusinessError|string, size: Size|null) => { - if (!size) { - func?.asyncTransform(error, null) - return; - } - let pixelMapWidth:number = size.width; - let pixelMapHeight:number = size.height; - let targetWidth:number = request.size.width; - let targetHeight:number = request.size.height; - if (pixelMapWidth < targetWidth) { - targetWidth = pixelMapWidth; - } - if (pixelMapHeight < targetHeight) { - targetHeight = pixelMapHeight; - } - - let options:image.DecodingOptions = { - editable: true, - desiredSize: { - width: targetWidth, - height: targetHeight - } - } - imageSource.createPixelMap(options) - .then((data) => { - imageSource.release() - this.toon(data, targetWidth, targetHeight, func); - }) - .catch((e:BusinessError) => { - imageSource.release() - LogUtil.log(Constants.PROJECT_TAG + ";error:" + e); - func?.asyncTransform(e, null); - }) - }}) - } - - private async toon(bitmap: image.PixelMap, targetWidth: number, targetHeight: number, func?: AsyncTransform) { - let bufferData = new ArrayBuffer(bitmap.getPixelBytesNumber()); - await bitmap.readPixelsToBuffer(bufferData); - let filter = new GPUImageToonFilter(); - filter.setImageData(bufferData, targetWidth, targetHeight); - filter.setThreshold(this.threshold); - filter.setQuantizationLevels(this.quantizationLevels); - let buf = await filter.getPixelMapBuf(0, 0, targetWidth, targetHeight) - bitmap.writeBufferToPixels(buf); - if (func != undefined) { - func?.asyncTransform("success", bitmap); - } - } -} \ No newline at end of file diff --git a/library/src/main/ets/components/imageknife/transform/TransformType.ets b/library/src/main/ets/components/imageknife/transform/TransformType.ets deleted file mode 100644 index bde5ccc..0000000 --- a/library/src/main/ets/components/imageknife/transform/TransformType.ets +++ /dev/null @@ -1,35 +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. - */ -export enum TransformType { - BlurTransformation, - BrightnessFilterTransformation, - ContrastFilterTransformation, - CropCircleTransformation, - CropCircleWithBorderTransformation, - CropSquareTransformation, - CropTransformation, - GrayscaleTransformation, - InvertFilterTransformation, - MaskTransformation, - PixelationFilterTransformation, - RotateImageTransformation, - RoundedCornersTransformation, - SepiaFilterTransformation, - SketchFilterTransformation, - SwirlFilterTransformation, - CenterCrop, - CenterInside, - FitCenter -} \ No newline at end of file diff --git a/library/src/main/ets/components/imageknife/transform/TransformUtils.ets b/library/src/main/ets/components/imageknife/transform/TransformUtils.ets deleted file mode 100644 index 8f5ea50..0000000 --- a/library/src/main/ets/components/imageknife/transform/TransformUtils.ets +++ /dev/null @@ -1,277 +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 { AsyncTransform } from '../transform/AsyncTransform' -import image from '@ohos.multimedia.image' -import { Size } from '../../imageknife/RequestOption' -import { BusinessError } from '@ohos.base' -import { Constants } from '../constants/Constants' -import { BaseTransform } from './BaseTransform' -import { BlurTransformation } from './BlurTransformation' -import { BrightnessFilterTransformation } from './BrightnessFilterTransformation' -import { RotateImageTransformation } from './RotateImageTransformation' -import { GrayscaleTransformation } from './GrayscaleTransformation' -import { ContrastFilterTransformation } from './ContrastFilterTransformation' -import { CropCircleTransformation } from './CropCircleTransformation' -import { CropCircleWithBorderTransformation, rgbColor } from './CropCircleWithBorderTransformation' -import { CropSquareTransformation } from './CropSquareTransformation' -import { InvertFilterTransformation } from './InvertFilterTransformation' -import { KuwaharaFilterTransform } from './KuwaharaFilterTransform' -import { MaskTransformation } from './MaskTransformation' -import { PixelationFilterTransformation } from './PixelationFilterTransformation' -import { RoundCorner, RoundedCornersTransformation } from './RoundedCornersTransformation' -import { SketchFilterTransformation } from './SketchFilterTransformation' -import { SepiaFilterTransformation } from './SepiaFilterTransformation' -import { SwirlFilterTransformation } from './SwirlFilterTransformation' -import { ToonFilterTransform } from './ToonFilterTransform' -import { VignetteFilterTransform } from './VignetteFilterTransform' -import { CenterCrop } from './pixelmap/CenterCrop' -import { CenterInside } from './pixelmap/CenterInside' -import { FitCenter } from './pixelmap/FitCenter' -import { CropTransformation, CropType } from './CropTransformation' - -export class TransformUtils { - static centerCrop(buf: ArrayBuffer, outWidth: number, outHeihgt: number, - callback?: AsyncTransform>) { - let imageSource: image.ImageSource = image.createImageSource(buf); - imageSource.getImageInfo() - .then((p) => { - let sw: number = 0; - let sh: number = 0; - let scale: number = 1; - let pw: number = p.size.width; - let ph: number = p.size.height; - if (pw == outWidth && ph == outHeihgt) { - sw = outWidth; - sh = outHeihgt; - } else { - if (pw * outHeihgt > outWidth * ph) { - scale = outHeihgt / ph; - } else { - scale = outWidth / pw; - } - sw = pw * scale; - sh = ph * scale; - } - let options: image.DecodingOptions = { - editable: true, - rotate: 0, - desiredRegion: { size: { width: sw, height: sh }, - x: pw / 2 - sw / 2, - y: ph / 2 - sh / 2, - }, - } - if (callback) { - callback.asyncTransform('', imageSource.createPixelMap(options)); - } - }) - .catch((error: BusinessError) => { - callback?.asyncTransform(error, null); - }) - - } - - static rotateImage(buf: ArrayBuffer, degreesToRotate: number): Promise { - let imageSource: image.ImageSource = image.createImageSource(buf); - let options: image.DecodingOptions = { - editable: true, - rotate: degreesToRotate - } - let promise: Promise = imageSource.createPixelMap(options); - imageSource.release() - return promise; - } - - static centerInside(buf: ArrayBuffer, outWidth: number, outHeihgt: number, - callback?: AsyncTransform) { - let imageSource: image.ImageSource = image.createImageSource(buf); - imageSource.getImageInfo() - .then((p: image.ImageInfo) => { - let pw = p.size.width; - let ph = p.size.height; - if (pw <= outWidth && ph <= outHeihgt) { - imageSource.createPixelMap() - .then(p => { - callback?.asyncTransform('', p); - imageSource.release() - }).catch((e: BusinessError) => { - callback?.asyncTransform(Constants.PROJECT_TAG + ';CenterInside error:' + e, null); - imageSource.release() - }) - } else { - TransformUtils.fitCenter(buf, outWidth, outHeihgt, callback); - } - }) - .catch((error: BusinessError) => { - callback?.asyncTransform(error, null); - }) - - } - - static fitCenter(buf: ArrayBuffer, outWidth: number, outHeihgt: number - , callback?: AsyncTransform) { - let imageSource: image.ImageSource = image.createImageSource(buf); - imageSource.getImageInfo() - .then((p: image.ImageInfo) => { - let pw: number = p.size.width; - let ph: number = p.size.height; - let widthPercentage: number = outWidth / pw; - let heightPercentage: number = outHeihgt / ph; - let minPercentage: number = Math.min(widthPercentage, heightPercentage); - - let targetWidth: number = Math.round(minPercentage * pw); - let targetHeight: number = Math.round(minPercentage * ph); - - if (pw == targetWidth && ph == targetHeight) { - targetWidth = pw; - targetHeight = ph; - } else { - targetWidth = minPercentage * pw; - targetHeight = minPercentage * ph; - } - let options: image.DecodingOptions = { - editable: true, - rotate: 0, - desiredSize: { width: targetWidth, height: targetHeight } - } - if (callback != undefined) { - imageSource.createPixelMap(options) - .then(p => { - callback?.asyncTransform('', p); - imageSource.release(); - }) - .catch((e: BusinessError) => { - callback?.asyncTransform(Constants.PROJECT_TAG + ';FitCenter error:' + e, null); - imageSource.release(); - }) - } - }) - .catch((e: BusinessError) => { - if (callback) { - callback.asyncTransform(e, null); - } - }) - } - - static getPixelMapSize(imageSource: image.ImageSource, func: AsyncTransform) { - if (!imageSource) { - return; - } - imageSource.getImageInfo((err: BusinessError, value: image.ImageInfo) => { - if (err) { - func?.asyncTransform(err, null) - return; - } - let pWidth: number = value.size.width; - let pHeight: number = value.size.height; - func?.asyncTransform('', { width: pWidth, height: pHeight }); - }) - } - - static addTransformations (data: string [][]) { - let transformations: Array> = new Array(); - for (let i = 0; i < data.length; i++) { - let className = data[i][0] as string; - let params = data[i][1] as string; - switch (className) { - case "BlurTransformation": - let paramList: number [] = JSON.parse(params); - transformations.push(new BlurTransformation(paramList[0], paramList[1])); - break; - case "BrightnessFilterTransformation": - let paramList1: number [] = JSON.parse(params); - transformations.push(new BrightnessFilterTransformation(paramList1[0])); - break; - case "RotateImageTransformation": - let paramList2: number [] = JSON.parse(params); - transformations.push(new RotateImageTransformation(paramList2[0])); - break; - case "GrayscaleTransformation": - transformations.push(new GrayscaleTransformation()); - break; - case "BlurTransformation": - let paramList3: number [] = JSON.parse(params); - transformations.push(new BlurTransformation(paramList3[0])); - break; - case "ContrastFilterTransformation": - let paramList4: number [] = JSON.parse(params); - transformations.push(new ContrastFilterTransformation(paramList4[0])); - break; - case "CropCircleTransformation": - transformations.push(new CropCircleTransformation()); - break; - case "CropCircleWithBorderTransformation": - let paramList5: (number | rgbColor) [] = JSON.parse(params); - transformations.push(new CropCircleWithBorderTransformation(paramList5[0] as number, paramList5[1] as rgbColor)); - break; - case "CropSquareTransformation": - transformations.push(new CropSquareTransformation()); - break; - case "InvertFilterTransformation": - transformations.push(new InvertFilterTransformation()); - break; - case "KuwaharaFilterTransform": - let paramList7: number [] = JSON.parse(params); - transformations.push(new KuwaharaFilterTransform(paramList7[0] as number)); - break; - case "MaskTransformation": - let paramList8: Resource [] = JSON.parse(params); - transformations.push(new MaskTransformation(paramList8[0] as Resource)); - break; - case "PixelationFilterTransformation": - let paramList9: number [] = JSON.parse(params); - transformations.push(new PixelationFilterTransformation(paramList9[0] as number)); - break; - case "RoundedCornersTransformation": - let paramList10: RoundCorner [] = JSON.parse(params); - transformations.push(new RoundedCornersTransformation(paramList10[0] as RoundCorner)); - break; - case "SepiaFilterTransformation": - transformations.push(new SepiaFilterTransformation()); - break; - case "SketchFilterTransformation": - transformations.push(new SketchFilterTransformation()); - break; - case "SwirlFilterTransformation": - let paramList11: (number | Array) [] = JSON.parse(params); - transformations.push(new SwirlFilterTransformation(paramList11[0] as number, paramList11[1] as number, paramList11[2] as Array)); - break; - case "ToonFilterTransform": - let paramList14: number [] = JSON.parse(params); - transformations.push(new ToonFilterTransform(paramList14[0], paramList14[1])); - break; - case "VignetteFilterTransform": - let paramList12: Array [] = JSON.parse(params); - transformations.push(new VignetteFilterTransform(paramList12[0], paramList12[1], paramList12[2])); - break; - case "CenterCrop": - transformations.push(new CenterCrop()); - break; - case "CenterInside": - transformations.push(new CenterInside()); - break; - case "FitCenter": - transformations.push(new FitCenter()); - break; - case "CropTransformation": - let paramList13: (number | CropType) [] = JSON.parse(params); - transformations.push(new CropTransformation(paramList13[0] as number, paramList13[1] as number, paramList13[2] as CropType)); - break; - default: - break - } - } - return transformations; - } -} \ No newline at end of file diff --git a/library/src/main/ets/components/imageknife/transform/VignetteFilterTransform.ets b/library/src/main/ets/components/imageknife/transform/VignetteFilterTransform.ets deleted file mode 100644 index c612c4d..0000000 --- a/library/src/main/ets/components/imageknife/transform/VignetteFilterTransform.ets +++ /dev/null @@ -1,124 +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 { BaseTransform } from "../transform/BaseTransform" -import { AsyncTransform } from "../transform/AsyncTransform" -import { Constants } from "../constants/Constants" -import { RequestOption } from "../../imageknife/RequestOption" -import { TransformUtils } from "../transform/TransformUtils" -import image from "@ohos.multimedia.image" -import { LogUtil } from '../../imageknife/utils/LogUtil' -import { GPUImageVignetterFilter } from '@ohos/gpu_transform' -import { BusinessError } from '@ohos.base' -import {Size} from '../../imageknife/RequestOption' - - -export class VignetteFilterTransform implements BaseTransform { - private centerPoint: Array = [0.5, 0.5]; - private vignetteColor: Array = [0.0, 0.0, 0.0]; - private vignetteSpace: Array = [0.3, 0.75]; - - constructor(centerPoint: Array, vignetteColor: Array, vignetteSpace: Array) { - if (centerPoint.length === 2) { - this.centerPoint = centerPoint; - } - if (vignetteColor.length === 3) { - this.vignetteColor = vignetteColor; - } - if (vignetteSpace.length === 2) { - this.vignetteSpace = vignetteSpace; - } - } - - getClassName(){ - return "VignetteFilterTransform"; - } - - getConstructorParams(){ - return JSON.stringify([this.centerPoint,this.vignetteColor,this.vignetteSpace]); - } - - getName() { - return "VignetteFilterTransform centerPoint:" + this.centerPoint + ";vignetteColor:" + this.vignetteColor + ";vignetteSpace:" + this.vignetteSpace; - } - - transform(buf: ArrayBuffer, request: RequestOption, func?: AsyncTransform) { - if (!buf || buf.byteLength <= 0) { - LogUtil.log(Constants.PROJECT_TAG + ";VignetteFilterTransform buf is empty"); - if (func != undefined) { - func?.asyncTransform(Constants.PROJECT_TAG + ";VignetteFilterTransform buf is empty", null); - } - return; - } - if (!request.gpuEnabled) { - LogUtil.error(Constants.PROJECT_TAG + ";the VignetteFilterTransform supported only in GPU mode"); - if (func != undefined) { - func?.asyncTransform(Constants.PROJECT_TAG + ";the VignetteFilterTransform supported only in GPU mode", null); - } - return; - } - let imageSource:image.ImageSource = image.createImageSource(buf); - TransformUtils.getPixelMapSize(imageSource, {asyncTransform:(error:BusinessError|string, size: Size|null) => { - if (!size) { - func?.asyncTransform(error, null) - return; - } - let pixelMapWidth:number = size.width; - let pixelMapHeight:number = size.height; - let targetWidth:number = request.size.width; - let targetHeight:number = request.size.height; - if (pixelMapWidth < targetWidth) { - targetWidth = pixelMapWidth; - } - if (pixelMapHeight < targetHeight) { - targetHeight = pixelMapHeight; - } - - let options:image.DecodingOptions = { - editable: true, - desiredSize: { - width: targetWidth, - height: targetHeight - } - } - imageSource.createPixelMap(options) - .then((data) => { - this.vignette(data, targetWidth, targetHeight, func); - imageSource.release(); - }) - .catch((e:BusinessError) => { - imageSource.release() - LogUtil.log(Constants.PROJECT_TAG + ";error:" + e); - func?.asyncTransform(e, null); - }) - }}) - } - - private async vignette(bitmap: image.PixelMap, targetWidth: number, targetHeight: number, func?: AsyncTransform) { - let bufferData = new ArrayBuffer(bitmap.getPixelBytesNumber()); - await bitmap.readPixelsToBuffer(bufferData); - let filter = new GPUImageVignetterFilter(); - filter.setImageData(bufferData, targetWidth, targetHeight); - filter.setVignetteCenter(this.centerPoint); - filter.setVignetteColor(this.vignetteColor); - filter.setVignetteStart(this.vignetteSpace[0]); - filter.setVignetteEnd(this.vignetteSpace[1]); - let buf = await filter.getPixelMapBuf(0, 0, targetWidth, targetHeight) - bitmap.writeBufferToPixels(buf); - if (func != undefined) { - func?.asyncTransform("success", bitmap); - } - } -} \ No newline at end of file diff --git a/library/src/main/ets/components/imageknife/transform/pixelmap/CenterCrop.ets b/library/src/main/ets/components/imageknife/transform/pixelmap/CenterCrop.ets deleted file mode 100644 index 0c23002..0000000 --- a/library/src/main/ets/components/imageknife/transform/pixelmap/CenterCrop.ets +++ /dev/null @@ -1,51 +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 {BaseTransform} from '../BaseTransform' -import {AsyncTransform} from '../AsyncTransform' -import {Constants} from '../../constants/Constants' -import {TransformUtils} from '../TransformUtils' -import {RequestOption} from '../../../imageknife/RequestOption' -import { BusinessError } from '@ohos.base' -export class CenterCrop implements BaseTransform { - - getClassName(){ - return "CenterCrop"; - } - - getConstructorParams(){ - return '[]'; - } - - getName() { - return 'CenterCrop:' + this; - } - - transform(buf: ArrayBuffer, request: RequestOption, func?: AsyncTransform) { - if (!buf || buf.byteLength <= 0) { - if (func != undefined) { - func?.asyncTransform(Constants.PROJECT_TAG + ';CenterCrop buf is empty', null); - } - return; - } - TransformUtils.centerCrop(buf, request.size.width, request.size.height, {asyncTransform:(error:BusinessError|string, data:Promise|null) => { - data?.then(p => { - func?.asyncTransform('', p); - }).catch((e:BusinessError) => { - func?.asyncTransform(Constants.PROJECT_TAG + ';CenterCrop error:' + e, null); - }) - }}) - } -} \ No newline at end of file diff --git a/library/src/main/ets/components/imageknife/transform/pixelmap/CenterInside.ets b/library/src/main/ets/components/imageknife/transform/pixelmap/CenterInside.ets deleted file mode 100644 index 68264ae..0000000 --- a/library/src/main/ets/components/imageknife/transform/pixelmap/CenterInside.ets +++ /dev/null @@ -1,43 +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 {BaseTransform} from '../BaseTransform' -import {AsyncTransform} from '../AsyncTransform' -import {Constants} from '../../constants/Constants' -import {TransformUtils} from '../TransformUtils' -import {RequestOption} from '../../../imageknife/RequestOption' -import { BusinessError } from '@ohos.base' -export class CenterInside implements BaseTransform { - getName() { - return 'CenterInside:' + this; - } - getClassName(){ - return "CenterInside"; - } - - getConstructorParams(){ - return '[]'; - } - - transform(buf: ArrayBuffer, request: RequestOption, func?: AsyncTransform) { - if (!buf || buf.byteLength <= 0) { - if (func != undefined) { - func?.asyncTransform(Constants.PROJECT_TAG + ';CenterInside buf is empty', null); - } - return; - } - TransformUtils.centerInside(buf, request.size.width, request.size.height, func) - } -} \ No newline at end of file diff --git a/library/src/main/ets/components/imageknife/transform/pixelmap/FitCenter.ets b/library/src/main/ets/components/imageknife/transform/pixelmap/FitCenter.ets deleted file mode 100644 index 907d828..0000000 --- a/library/src/main/ets/components/imageknife/transform/pixelmap/FitCenter.ets +++ /dev/null @@ -1,43 +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 {BaseTransform} from '../BaseTransform' -import {AsyncTransform} from '../AsyncTransform' -import {Constants} from '../../constants/Constants' -import {TransformUtils} from '../TransformUtils' -import {RequestOption} from '../../../imageknife/RequestOption' -import { BusinessError } from '@ohos.base' -export class FitCenter implements BaseTransform { - getName() { - return 'FitCenter:' + this; - } - getClassName(){ - return "FitCenter"; - } - - getConstructorParams(){ - return '[]'; - } - - transform(buf: ArrayBuffer, request: RequestOption, func?: AsyncTransform) { - if (!buf || buf.byteLength <= 0) { - if (func != undefined) { - func?.asyncTransform(Constants.PROJECT_TAG + ';FitCenter buf is empty', null); - } - return; - } - TransformUtils.fitCenter(buf, request.size.width, request.size.height, func) - } -} \ No newline at end of file diff --git a/library/src/main/ets/components/imageknife/utils/CalculatePixelUtils.ets b/library/src/main/ets/components/imageknife/utils/CalculatePixelUtils.ets deleted file mode 100644 index 85aa52d..0000000 --- a/library/src/main/ets/components/imageknife/utils/CalculatePixelUtils.ets +++ /dev/null @@ -1,361 +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 { PixelEntry } from "../entry/PixelEntry" -import { AsyncTransform } from "../transform/AsyncTransform" -import { ColorUtils } from "./ColorUtils" -import { GPUImageSketchFilter } from '@ohos/gpu_transform' -import image from '@ohos.multimedia.image' -import { Size } from '../RequestOption' - -export namespace CalculatePixelUtils { - export async function sketch(p: PixelMap, func?: AsyncTransform) { - let imageInfo = await p.getImageInfo(); - let size:Size = { - width: imageInfo.size.width, - height: imageInfo.size.height - } - if (!size) { - func?.asyncTransform("sketch The image size does not exist.", null) - return; - } - - let pos: number = 0 - let row: number = 0 - let col: number = 0 - let clr: number = 0 - let width: number = size.width; - let height: number = size.height; - let pixEntry: Array = new Array() - let pixSrc: Array = new Array() - let pixNvt: Array = new Array() - - let bufferData = new ArrayBuffer(p.getPixelBytesNumber()); - await p.readPixelsToBuffer(bufferData); - let dataArray = new Uint8Array(bufferData); - - for (let index = 0; index < dataArray.length; index += 4) { - const r = dataArray[index]; - const g = dataArray[index+1]; - const b = dataArray[index+2]; - const f = dataArray[index+3]; - - let entry = new PixelEntry(); - entry.a = 0; - entry.b = b; - entry.g = g; - entry.r = r; - entry.f = f; - entry.pixel = ColorUtils.rgb(entry.r, entry.g, entry.b); - pixEntry.push(entry); - pixSrc.push(ColorUtils.rgb(entry.r, entry.g, entry.b)); - pixNvt.push(0); - } - - for (row = 0; row < height; row++) { - for (col = 0; col < width; col++) { - pos = row * width + col; - pixSrc[pos] = (pixEntry[pos].r + pixEntry[pos].g + pixEntry[pos].b) / 3; - pixNvt[pos] = 255 - pixSrc[pos]; - } - } - // 对取反的像素进行高斯模糊, 强度可以设置,暂定为5.0 - gaussGray(pixNvt, 5.0, 5.0, width, height); - // 灰度颜色和模糊后像素进行差值运算 - for (row = 0; row < height; row++) { - for (col = 0; col < width; col++) { - pos = row * width + col; - clr = pixSrc[pos] << 8; - clr /= 256 - pixNvt[pos]; - clr = Math.min(clr, 255); - pixSrc[pos] = ColorUtils.rgb(clr, clr, clr); - } - } - - let bufferNewData = new ArrayBuffer(p.getPixelBytesNumber()); - let dataNewArray = new Uint8Array(bufferNewData); - let index = 0; - - for (let i = 0; i < dataNewArray.length; i += 4) { - dataNewArray[i] = ColorUtils.red(pixSrc[index]); - dataNewArray[i+1] = ColorUtils.green(pixSrc[index]); - dataNewArray[i+2] = ColorUtils.blue(pixSrc[index]); - dataNewArray[i+3] = pixEntry[index].f; - index++; - } - await p.writeBufferToPixels(bufferNewData); - - if (func != undefined) { - func.asyncTransform("success", p); - } - } - - let gaussGray = (psrc: Array, horz: number, vert: number, - width: number, height: number): number => { - let dst: Array; - let src: Array; - let n_p: Array; - let n_m: Array; - let d_p: Array; - let d_m: Array; - let bd_p: Array; - let bd_m: Array; - let val_p: Array; - let val_m: Array; - let initial_p: Array; - let initial_m: Array; - let i: number; - let j: number; - let t: number; - let k: number; - let row: number; - let col: number; - let terms: number; - let std_dev: number; - let sp_p_idx: number; - let sp_m_idx: number; - let vp_idx: number; - let vm_idx: number; - let row_stride = width; - let max_len = Math.max(width, height); - val_p = createIntArray(max_len); - val_m = createIntArray(max_len); - n_p = createIntArray(5); - n_m = createIntArray(5); - d_p = createIntArray(5); - d_m = createIntArray(5); - bd_p = createIntArray(5); - bd_m = createIntArray(5); - src = createIntArray(max_len); - dst = createIntArray(max_len); - initial_p = createIntArray(4); - initial_m = createIntArray(4); - // 垂直方向 - if (vert > 0.0) { - vert = Math.abs(vert) + 1.0; - std_dev = Math.sqrt(-(vert * vert) / (2 * Math.log(1.0 / 255.0))); - // 初试化常量 - findConstants(n_p, n_m, d_p, d_m, bd_p, bd_m, std_dev); - for (col = 0; col < width; col++) { - for (k = 0; k < max_len; k++) { - val_m[k] = val_p[k] = 0; - } - for (t = 0; t < height; t++) { - src[t] = psrc[t * row_stride + col]; - } - sp_p_idx = 0; - sp_m_idx = height - 1; - vp_idx = 0; - vm_idx = height - 1; - initial_p[0] = src[0]; - initial_m[0] = src[height - 1]; - for (row = 0; row < height; row++) { - terms = (row < 4) ? row : 4; - for (i = 0; i <= terms; i++) { - val_p[vp_idx] += n_p[i] * src[sp_p_idx - i] - d_p[i] - * val_p[vp_idx - i]; - val_m[vm_idx] += n_m[i] * src[sp_m_idx + i] - d_m[i] - * val_m[vm_idx + i]; - } - for (j = i; j <= 4; j++) { - val_p[vp_idx] += (n_p[j] - bd_p[j]) * initial_p[0]; - val_m[vm_idx] += (n_m[j] - bd_m[j]) * initial_m[0]; - } - sp_p_idx++; - sp_m_idx--; - vp_idx++; - vm_idx--; - } - transferGaussPixels(val_p, val_m, dst, 1, height); - for (t = 0; t < height; t++) { - psrc[t * row_stride + col] = dst[t]; - } - } - } - // 水平方向 - if (horz > 0.0) { - horz = Math.abs(horz) + 1.0; - if (horz != vert) { - std_dev = Math.sqrt(-(horz * horz) - / (2 * Math.log(1.0 / 255.0))); - // 初试化常量 - findConstants(n_p, n_m, d_p, d_m, bd_p, bd_m, std_dev); - } - for (row = 0; row < height; row++) { - for (k = 0; k < max_len; k++) { - val_m[k] = val_p[k] = 0; - } - for (t = 0; t < width; t++) { - src[t] = psrc[row * row_stride + t]; - } - sp_p_idx = 0; - sp_m_idx = width - 1; - vp_idx = 0; - vm_idx = width - 1; - initial_p[0] = src[0]; - initial_m[0] = src[width - 1]; - for (col = 0; col < width; col++) { - terms = (col < 4) ? col : 4; - for (i = 0; i <= terms; i++) { - val_p[vp_idx] += n_p[i] * src[sp_p_idx - i] - d_p[i] - * val_p[vp_idx - i]; - val_m[vm_idx] += n_m[i] * src[sp_m_idx + i] - d_m[i] - * val_m[vm_idx + i]; - } - for (j = i; j <= 4; j++) { - val_p[vp_idx] += (n_p[j] - bd_p[j]) * initial_p[0]; - val_m[vm_idx] += (n_m[j] - bd_m[j]) * initial_m[0]; - } - sp_p_idx++; - sp_m_idx--; - vp_idx++; - vm_idx--; - } - transferGaussPixels(val_p, val_m, dst, 1, width); - for (t = 0; t < width; t++) { - psrc[row * row_stride + t] = dst[t]; - } - } - } - return 0; - } - - let findConstants = (n_p: Array, n_m: Array, d_p: Array, - d_m: Array, bd_p: Array - , bd_m: Array, std_dev: number) => { - let div = Math.sqrt(2 * 3.141593) * std_dev; - let x0 = -1.783 / std_dev; - let x1 = -1.723 / std_dev; - let x2 = 0.6318 / std_dev; - let x3 = 1.997 / std_dev; - let x4 = 1.6803 / div; - let x5 = 3.735 / div; - let x6 = -0.6803 / div; - let x7 = -0.2598 / div; - let i: number; - n_p[0] = x4 + x6; - n_p[1] = (Math.exp(x1) - * (x7 * Math.sin(x3) - (x6 + 2 * x4) * Math.cos(x3)) + Math - .exp(x0) * (x5 * Math.sin(x2) - (2 * x6 + x4) * Math.cos(x2))); - n_p[2] = (2 - * Math.exp(x0 + x1) - * ((x4 + x6) * Math.cos(x3) * Math.cos(x2) - x5 * Math.cos(x3) - * Math.sin(x2) - x7 * Math.cos(x2) * Math.sin(x3)) + x6 - * Math.exp(2 * x0) + x4 * Math.exp(2 * x1)); - n_p[3] = (Math.exp(x1 + 2 * x0) - * (x7 * Math.sin(x3) - x6 * Math.cos(x3)) + Math.exp(x0 + 2 - * x1) - * (x5 * Math.sin(x2) - x4 * Math.cos(x2))); - n_p[4] = 0.0; - d_p[0] = 0.0; - d_p[1] = -2 * Math.exp(x1) * Math.cos(x3) - 2 * Math.exp(x0) - * Math.cos(x2); - d_p[2] = 4 * Math.cos(x3) * Math.cos(x2) * Math.exp(x0 + x1) - + Math.exp(2 * x1) + Math.exp(2 * x0); - d_p[3] = -2 * Math.cos(x2) * Math.exp(x0 + 2 * x1) - 2 * Math.cos(x3) - * Math.exp(x1 + 2 * x0); - d_p[4] = Math.exp(2 * x0 + 2 * x1); - for (i = 0; i <= 4; i++) { - d_m[i] = d_p[i]; - } - n_m[0] = 0.0; - for (i = 1; i <= 4; i++) { - n_m[i] = n_p[i] - d_p[i] * n_p[0]; - } - let sum_n_p: number; - let sum_n_m: number; - let sum_d: number; - let a: number; - let b: number; - sum_n_p = 0.0; - sum_n_m = 0.0; - sum_d = 0.0; - for (i = 0; i <= 4; i++) { - sum_n_p += n_p[i]; - sum_n_m += n_m[i]; - sum_d += d_p[i]; - } - a = sum_n_p / (1.0 + sum_d); - b = sum_n_m / (1.0 + sum_d); - for (i = 0; i <= 4; i++) { - bd_p[i] = d_p[i] * a; - bd_m[i] = d_m[i] * b; - } - } - - let transferGaussPixels = (src1: Array, src2: Array, - dest: Array, bytes: number, width: number) => { - let i: number; - let j: number; - let k: number; - let b: number; - let sum: number; - let bend = bytes * width; - i = j = k = 0; - for (b = 0; b < bend; b++) { - sum = src1[i++] + src2[j++]; - if (sum > 255) - sum = 255; - else if (sum < 0) - sum = 0; - dest[k++] = sum; - } - } - - export function createIntArray(len: number): Array { - let array = new Array(); - for (let index = 0; index < len; index++) { - array.push(0); - } - return array; - } - - export function createInt2DArray(first_len: number, second_len: number): Array> { - let array = new Array>(); - for (let f = 0; f < first_len; f++) { - let s1 = new Array(); - for (let s = 0; s < second_len; s++) { - s1.push(0); - } - array.push(s1); - } - return array; - } - - export async function sketchGpu(p: PixelMap, func?: AsyncTransform) { - let imageInfo: image.ImageInfo = await p.getImageInfo(); - let size:Size = { - width: imageInfo.size.width, - height: imageInfo.size.height - } - if (!size) { - func?.asyncTransform("sketch The image size does not exist.", null) - return; - } - - let w = size.width; - let h = size.height; - - let bufferData = new ArrayBuffer(p.getPixelBytesNumber()); - await p.readPixelsToBuffer(bufferData); - let filter = new GPUImageSketchFilter(); - filter.setImageData(bufferData, w, h); - filter.getPixelMapBuf(0, 0, w, h).then((buf) => { - p.writeBufferToPixels(buf); - if (func != undefined) { - func.asyncTransform("success", p); - } - }) - } -} \ No newline at end of file diff --git a/library/src/main/ets/components/imageknife/utils/ColorUtils.ets b/library/src/main/ets/components/imageknife/utils/ColorUtils.ets deleted file mode 100644 index ea62c11..0000000 --- a/library/src/main/ets/components/imageknife/utils/ColorUtils.ets +++ /dev/null @@ -1,61 +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 resourceManager from '@ohos.resourceManager'; -import common from '@ohos.app.ability.common'; -import { ImageKnifeGlobal } from '../ImageKnifeGlobal'; -import {DataCallBack} from "../interface/DataCallBack" - -export namespace ColorUtils { - -/** - * 本地颜色值解析 - * ColorUtils.parseColor("color_name",callback) - */ - export function parseColor(c: string, callback: DataCallBack) { - - let reColor = 'sys.color.' + c; - ((ImageKnifeGlobal.getInstance().getHapContext() as common.UIAbilityContext).resourceManager as resourceManager.ResourceManager).getString($r(reColor) - .id, (err, color) => { - if (!err) { - let cos = JSON.stringify(color); - callback.callback(cos) - } else { - callback.callback(err.message) - } - }); - - - } - - export function red(color: number): number { - return (color >> 16) & 0xFF; - } - - export function green(color: number): number { - return (color >> 8) & 0xFF; - } - - export function blue(color: number): number { - return color & 0xFF; - } - - export function alpha(color: number): number { - return color >>> 24; - } - - export function rgb(red: number, green: number, blue: number): number { - return 0xff000000 | (red << 16) | (green << 8) | blue; - } -} \ No newline at end of file diff --git a/library/src/main/ets/components/imageknife/utils/FastBlur.ets b/library/src/main/ets/components/imageknife/utils/FastBlur.ets deleted file mode 100644 index 86961fe..0000000 --- a/library/src/main/ets/components/imageknife/utils/FastBlur.ets +++ /dev/null @@ -1,345 +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 {CalculatePixelUtils} from "./CalculatePixelUtils" -import {PixelEntry} from "../entry/PixelEntry" -import {AsyncTransform} from "../transform/AsyncTransform" -import {ColorUtils} from "./ColorUtils" -import { GPUImageBlurFilter } from '@ohos/gpu_transform' -import {Size} from '../../imageknife/RequestOption' -import image from '@ohos.multimedia.image'; -export namespace fastBlur { - - - export async function blur(bitmap: PixelMap, radius: number, canReuseInBitmap: boolean, func?: AsyncTransform) { - - -// http://www.quasimondo.com/StackBlurForCanvas/StackBlurDemo.html -// -// Java Author: Mario Klingemann -// http://incubator.quasimondo.com -// created February 29, 2004 -// port : Yahel Bouaziz -// 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?.asyncTransform("error,radius must be greater than 1 ", null); - return; - } - - let imageInfo = await bitmap.getImageInfo(); - let size:Size = { - width: imageInfo.size.width, - height: imageInfo.size.height - } - - if (!size) { - func?.asyncTransform("fastBlur The image size does not exist.", null) - return; - } - - let w = size.width; - let h = size.height; - let pixEntry: Array = new Array() - let pix: Array = new Array() - - - let bufferData = new ArrayBuffer(bitmap.getPixelBytesNumber()); - await bitmap.readPixelsToBuffer(bufferData); - let dataArray = new Uint8Array(bufferData); - - for (let index = 0; index < dataArray.length; index+=4) { - const r = dataArray[index]; - const g = dataArray[index+1]; - const b = dataArray[index+2]; - const f = dataArray[index+3]; - - let entry = new PixelEntry(); - entry.a = 0; - entry.b = b; - entry.g = g; - entry.r = r; - entry.f = f; - entry.pixel = ColorUtils.rgb(entry.r, entry.g, entry.b); - pixEntry.push(entry); - pix.push(ColorUtils.rgb(entry.r, entry.g, entry.b)); - } - - let wm = w - 1; - let hm = h - 1; - let wh = w * h; - let div = radius + radius + 1; - - let r = CalculatePixelUtils.createIntArray(wh); - let g = CalculatePixelUtils.createIntArray(wh); - let b = CalculatePixelUtils.createIntArray(wh); - - let rsum:number = 0; - let gsum:number = 0; - let bsum:number = 0; - let x:number = 0; - let y:number = 0; - let i:number = 0; - let p:number = 0; - let yp:number = 0; - let yi:number = 0; - let yw: number = 0; - - let vmin = CalculatePixelUtils.createIntArray(Math.max(w, h)); - - let divsum = (div + 1) >> 1; - divsum *= divsum; - let dv = CalculatePixelUtils.createIntArray(256 * divsum); - for (i = 0; i < 256 * divsum; i++) { - dv[i] = (i / divsum); - } - - yw = yi = 0; - let stack = CalculatePixelUtils.createInt2DArray(div, 3); - let stackpointer:number=0; - let stackstart:number=0; - let rbs:number=0; - let routsum:number=0; - let goutsum:number=0; - let boutsum:number=0; - let rinsum:number=0; - let ginsum:number=0; - let binsum:number=0; - let sir: Array; - let r1 = radius + 1; - for (y = 0; y < h; y++) { - rinsum = ginsum = binsum = routsum = goutsum = boutsum = rsum = gsum = bsum = 0; - for (i = -radius; i <= radius; i++) { - p = pix[yi + Math.min(wm, Math.max(i, 0))]; - sir = stack[i + radius]; - sir[0] = (p & 0xff0000) >> 16; - sir[1] = (p & 0x00ff00) >> 8; - sir[2] = (p & 0x0000ff); - rbs = r1 - Math.abs(i); - rsum += sir[0] * rbs; - gsum += sir[1] * rbs; - bsum += sir[2] * rbs; - if (i > 0) { - rinsum += sir[0]; - ginsum += sir[1]; - binsum += sir[2]; - } else { - routsum += sir[0]; - goutsum += sir[1]; - boutsum += sir[2]; - } - } - stackpointer = radius; - - for (x = 0; x < w; x++) { - - r[yi] = dv[rsum]; - g[yi] = dv[gsum]; - b[yi] = dv[bsum]; - - rsum -= routsum; - gsum -= goutsum; - bsum -= boutsum; - - stackstart = stackpointer - radius + div; - sir = stack[stackstart % div]; - - routsum -= sir[0]; - goutsum -= sir[1]; - boutsum -= sir[2]; - - if (y == 0) { - vmin[x] = Math.min(x + radius + 1, wm); - } - p = pix[yw + vmin[x]]; - - sir[0] = (p & 0xff0000) >> 16; - sir[1] = (p & 0x00ff00) >> 8; - sir[2] = (p & 0x0000ff); - - rinsum += sir[0]; - ginsum += sir[1]; - binsum += sir[2]; - - rsum += rinsum; - gsum += ginsum; - bsum += binsum; - - stackpointer = (stackpointer + 1) % div; - sir = stack[(stackpointer) % div]; - - routsum += sir[0]; - goutsum += sir[1]; - boutsum += sir[2]; - - rinsum -= sir[0]; - ginsum -= sir[1]; - binsum -= sir[2]; - - yi++; - } - yw += w; - } - for (x = 0; x < w; x++) { - rinsum = ginsum = binsum = routsum = goutsum = boutsum = rsum = gsum = bsum = 0; - yp = -radius * w; - for (i = -radius; i <= radius; i++) { - yi = Math.max(0, yp) + x; - - sir = stack[i + radius]; - - sir[0] = r[yi]; - sir[1] = g[yi]; - sir[2] = b[yi]; - - rbs = r1 - Math.abs(i); - - rsum += r[yi] * rbs; - gsum += g[yi] * rbs; - bsum += b[yi] * rbs; - - if (i > 0) { - rinsum += sir[0]; - ginsum += sir[1]; - binsum += sir[2]; - } else { - routsum += sir[0]; - goutsum += sir[1]; - boutsum += sir[2]; - } - - if (i < hm) { - yp += w; - } - } - yi = x; - stackpointer = radius; - for (y = 0; y < h; y++) { - // Preserve alpha channel: ( 0xff000000 & pix[yi] ) - pix[yi] = (0xff000000 & pix[Math.round(yi)]) | (dv[Math.round(rsum)] << 16) | (dv[ - Math.round(gsum)] << 8) | dv[Math.round(bsum)]; - - rsum -= routsum; - gsum -= goutsum; - bsum -= boutsum; - - stackstart = stackpointer - radius + div; - sir = stack[stackstart % div]; - - routsum -= sir[0]; - goutsum -= sir[1]; - boutsum -= sir[2]; - - if (x == 0) { - vmin[y] = Math.min(y + r1, hm) * w; - } - p = x + vmin[y]; - - sir[0] = r[p]; - sir[1] = g[p]; - sir[2] = b[p]; - - rinsum += sir[0]; - ginsum += sir[1]; - binsum += sir[2]; - - rsum += rinsum; - gsum += ginsum; - bsum += binsum; - - stackpointer = (stackpointer + 1) % div; - sir = stack[stackpointer]; - - routsum += sir[0]; - goutsum += sir[1]; - boutsum += sir[2]; - - rinsum -= sir[0]; - ginsum -= sir[1]; - binsum -= sir[2]; - - yi += w; - } - } - - - let bufferNewData = new ArrayBuffer(bitmap.getPixelBytesNumber()); - let dataNewArray = new Uint8Array(bufferNewData); - let index = 0; - - for (let i = 0; i < dataNewArray.length; i += 4) { - dataNewArray[i] = ColorUtils.red(pix[index]); - dataNewArray[i+1] = ColorUtils.green(pix[index]); - dataNewArray[i+2] = ColorUtils.blue(pix[index]); - dataNewArray[i+3] = pixEntry[index].f; - index++; - } - await bitmap.writeBufferToPixels(bufferNewData); - if (func != undefined) { - func?.asyncTransform("success", bitmap); - } - } - export async function blurGPU(bitmap: PixelMap, radius: number, canReuseInBitmap: boolean, func?: AsyncTransform) { - if (radius < 1) { - func?.asyncTransform("error,radius must be greater than 1 ", null); - return; - } - - let imageInfo:image.ImageInfo = await bitmap.getImageInfo(); - let size:Size = { - width: imageInfo.size.width, - height: imageInfo.size.height - } - - if (!size) { - func?.asyncTransform("fastBlur The image size does not exist.", null) - return; - } - - let w:number = size.width; - let h:number = size.height; - - let bufferData = new ArrayBuffer(bitmap.getPixelBytesNumber()); - await bitmap.readPixelsToBuffer(bufferData); - let filter = new GPUImageBlurFilter(); - filter.setImageData(bufferData, w, h); - filter.setBlurRadius(radius); - filter.setBlurOffset([1.0, 1.0]) - filter.getPixelMapBuf(0, 0, w, h).then((buf) => { - bitmap.writeBufferToPixels(buf); - if (func != undefined) { - func?.asyncTransform("success", bitmap); - } - }) - } -} diff --git a/library/src/main/ets/components/imageknife/utils/K2DArray.ets b/library/src/main/ets/components/imageknife/utils/K2DArray.ets deleted file mode 100644 index 334d999..0000000 --- a/library/src/main/ets/components/imageknife/utils/K2DArray.ets +++ /dev/null @@ -1,86 +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. - */ -/** - * 定义一个二维数组 - */ -export class K2DArray { - private _2dArray: Array> = new Array>(); - private rows: number; - private columns: number; - - public constructor(r: number, c: number, value: number) { - this.rows = r; - this.columns = c; - this.initRows(r); - this.initColumns(c, value); - } - - private initRows(row: number) { - if (row < 1) { - return; - } - for (let i = 0; i < row; i++) { - this._2dArray.push(new Array()) - } - } - - private initColumns(c: number, value: number) { - if (c < 1) { - return; - } - for (let i = 0; i < this._2dArray.length; i++) { - for (let j = 0; j < c; j++) { - this._2dArray[i].push(value); - } - } - } - - /** - * 获取数组 - */ - public getArray(): Array>{ - return this._2dArray; - } - - /** - * 获取数组 - */ - public getColumnsArray(r: number): Array|null{ - if (r < 0 || r >= this.rows) { - return null; - } - return this._2dArray[r]; - } - - /** - * 获取值 - */ - public getValue(r: number, c: number): number|undefined{ - if (r < 0 || c < 0 || r >= this.rows || c >= this.columns) { - return undefined; - } - return this._2dArray[r][c]; - } - - /** - * 设置值 - */ - public setValye(r: number, c: number, value: number) { - if (r < 0 || c < 0 || r >= this.rows || c >= this.columns) { - return; - } - this._2dArray[r][c] = value; - } -} \ No newline at end of file diff --git a/library/src/main/ets/components/imageknife/utils/MaskUtils.ets b/library/src/main/ets/components/imageknife/utils/MaskUtils.ets deleted file mode 100644 index c8a9a78..0000000 --- a/library/src/main/ets/components/imageknife/utils/MaskUtils.ets +++ /dev/null @@ -1,145 +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 {PixelEntry} from "../entry/PixelEntry" -import {AsyncTransform} from "../transform/AsyncTransform" -import {ColorUtils} from "./ColorUtils" -import {CalculatePixelUtils} from "./CalculatePixelUtils" -import {Size} from '../RequestOption' - -export class MaskUtils { - static async mask(bitmap: PixelMap, maskBitmap: PixelMap, func?: AsyncTransform) { - let imageInfo = await bitmap.getImageInfo(); - let size:Size = { - width: imageInfo.size.width, - height: imageInfo.size.height - } - if (!size) { - return; - } - let width = size.width; - let height = size.height; - - let rgbData = CalculatePixelUtils.createInt2DArray(height, width); - - let bufferData = new ArrayBuffer(bitmap.getPixelBytesNumber()); - await bitmap.readPixelsToBuffer(bufferData); - let dataArray = new Uint8Array(bufferData); - - let ph = 0; - let pw = 0; - for (let index = 0; index < dataArray.length; index += 4) { - const r = dataArray[index]; - const g = dataArray[index+1]; - const b = dataArray[index+2]; - const f = dataArray[index+3]; - - let entry = new PixelEntry(); - entry.a = 0; - entry.b = b; - entry.g = g; - entry.r = r; - entry.f = f; - entry.pixel = ColorUtils.rgb(entry.r, entry.g, entry.b); - rgbData[ph][pw] = ColorUtils.rgb(entry.r, entry.g, entry.b); - if (pw == width - 1) { - pw = 0; - ph++; - } else { - pw++; - } - } - - - let imageInfoMask = await maskBitmap.getImageInfo(); - let sizeMask:Size = { - width: imageInfoMask.size.width, - height: imageInfoMask.size.height - } - if (!sizeMask) { - return; - } - let widthMask = sizeMask.width; - let heightMask = sizeMask.height; - let rgbDataMask = CalculatePixelUtils.createInt2DArray(heightMask, widthMask); - let pixEntry: Array = new Array(); - - let bufferDataM = new ArrayBuffer(maskBitmap.getPixelBytesNumber()); - await maskBitmap.readPixelsToBuffer(bufferDataM); - let dataArrayM = new Uint8Array(bufferDataM); - - let phM = 0; - let pwM = 0; - - 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; - entry.b = b; - entry.g = g; - entry.r = r; - entry.f = f; - entry.pixel = ColorUtils.rgb(entry.r, entry.g, entry.b); - pixEntry.push(entry); - if (entry.r == 0 && entry.g == 0 && entry.b == 0) { - rgbDataMask[phM][pwM] = rgbData[phM][pwM]; - } else { - rgbDataMask[phM][pwM] = ColorUtils.rgb(entry.r, entry.g, entry.b); - } - - if (pwM == widthMask - 1) { - pwM = 0; - phM++; - } else { - pwM++; - } - } - - - let bufferNewData = new ArrayBuffer(maskBitmap.getPixelBytesNumber()); - let dataNewArray = new Uint8Array(bufferNewData); - let index = 0; - let mh = 0; - let nw = 0; - - for (let i = 0; i < dataNewArray.length; i += 4) { - let pixel1 = rgbDataMask[mh][nw]; - - if (nw == widthMask - 1) { - nw = 0; - mh++; - } else { - nw++; - } - - let pR = ColorUtils.red(pixel1); - let pG = ColorUtils.green(pixel1); - let pB = ColorUtils.blue(pixel1); - - dataNewArray[i] = pR; - dataNewArray[i+1] = pG; - dataNewArray[i+2] = pB; - dataNewArray[i+3] = pixEntry[index].f; - index++; - } - await maskBitmap.writeBufferToPixels(bufferNewData); - if (func != undefined) { - func?.asyncTransform("", maskBitmap); - } - } -} \ No newline at end of file diff --git a/library/src/main/ets/components/imageknife/utils/ParseImageUtil.ets b/library/src/main/ets/components/imageknife/utils/ParseImageUtil.ets deleted file mode 100644 index fd3cb98..0000000 --- a/library/src/main/ets/components/imageknife/utils/ParseImageUtil.ets +++ /dev/null @@ -1,55 +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 { IParseImage } from '../interface/IParseImage' -import image from '@ohos.multimedia.image'; -import { BusinessError } from '@ohos.base' -import taskpool from '@ohos.taskpool'; -import { LogUtil } from './LogUtil'; - -export class ParseImageUtil implements IParseImage { - parseImage(imageinfo: ArrayBuffer, onCompleteFunction: (value: PixelMap) => void | PromiseLike, onErrorFunction: (reason?: BusinessError | string) => void) { - this.parseImageThumbnail(1, imageinfo, onCompleteFunction, onErrorFunction) - } - - parseImageThumbnail(scale: number, imageinfo: ArrayBuffer, onCompleteFunction: (value: PixelMap) => void | PromiseLike, onErrorFunction: (reason?: BusinessError | string) => void) { - - let imageSource: image.ImageSource = image.createImageSource(imageinfo); // 步骤一:文件转为pixelMap 然后变换 给Image组件 - imageSource.getImageInfo().then((value) => { - let hValue = Math.round(value.size.height * scale); - let wValue = Math.round(value.size.width * scale); - let defaultSize: image.Size = { - height: hValue, - width: wValue - }; - let opts: image.DecodingOptions = { - editable: true, - desiredSize: defaultSize - }; - - imageSource.createPixelMap(opts).then((pixelMap: image.PixelMap) => { - onCompleteFunction(pixelMap); - imageSource.release() - }).catch((err: string) => { - onErrorFunction(err); - imageSource.release() - }) - - }).catch((err: string) => { - onErrorFunction(err); - imageSource.release() - }) - } -} \ No newline at end of file diff --git a/library/src/main/ets/components/imageknife/utils/PixelUtils.ets b/library/src/main/ets/components/imageknife/utils/PixelUtils.ets deleted file mode 100644 index ce61142..0000000 --- a/library/src/main/ets/components/imageknife/utils/PixelUtils.ets +++ /dev/null @@ -1,161 +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 {CalculatePixelUtils} from "./CalculatePixelUtils" -import {PixelEntry} from "../entry/PixelEntry" -import {AsyncTransform} from "../transform/AsyncTransform" -import {ColorUtils} from "./ColorUtils" -import {Size} from "../../imageknife/RequestOption" -import {GPUImagePixelationFilter} from '@ohos/gpu_transform' -import image from '@ohos.multimedia.image'; - -export namespace pixelUtils { - - export async function pixel(bitmap: PixelMap, pixel: number, func?: AsyncTransform) { - - let imageInfo:image.ImageInfo= await bitmap.getImageInfo(); - let size:Size = { - width: imageInfo.size.width, - height: imageInfo.size.height - } - if (!size) { - func?.asyncTransform("GrayscaleTransformation The image size does not exist.", null) - return; - } - let targetWidth:number = size.width; - let targetHeight:number = size.height; - - let pixEntry: Array = new Array() - let inPixels: Array> = CalculatePixelUtils.createInt2DArray(targetHeight, targetWidth); - - let bufferData = new ArrayBuffer(bitmap.getPixelBytesNumber()); - await bitmap.readPixelsToBuffer(bufferData); - let dataArray = new Uint8Array(bufferData); - - let ph:number = 0; - let pw:number = 0; - - - for (let index = 0; index < dataArray.length; index += 4) { - const r = dataArray[index]; - const g = dataArray[index+1]; - const b = dataArray[index+2]; - const f = dataArray[index+3]; - - let entry = new PixelEntry(); - entry.a = 0; - entry.b = b; - entry.g = g; - entry.r = r; - entry.f = f; - entry.pixel = ColorUtils.rgb(entry.r, entry.g, entry.b); - pixEntry.push(entry); - inPixels[ph][pw] = ColorUtils.rgb(entry.r, entry.g, entry.b); - if (pw == targetWidth - 1) { - pw = 0; - ph++; - } else { - pw++; - } - } - - let realPixel_W = pixel > targetWidth ? targetWidth : pixel; - let realPixel_H = pixel > targetHeight ? targetHeight : pixel; - - // 横排的正方形个数 - let x_index = Math.floor(targetWidth / realPixel_W); - // 纵排的正方形个数 - let y_index = Math.floor(targetHeight / realPixel_H); - - for (let ch = 0; ch < y_index; ch++) { - for (let cw = 0; cw < x_index; cw++) { - - let max_x = (cw + 1) * realPixel_W > targetWidth ? targetWidth : (cw + 1) * realPixel_W; - let max_y = (ch + 1) * realPixel_H > targetHeight ? targetHeight : (ch + 1) * realPixel_H; - - - let min_x = cw * realPixel_W; - let min_y = ch * realPixel_H; - - // 取左上角的像素值 - let center_p = inPixels[min_y+1][min_x+1]; - // 设置该正方形里的像素统一 - for (let zh = min_y; zh < max_y; zh++) { - for (let zw = min_x; zw < max_x; zw++) { - inPixels[zh][zw] = center_p; - } - } - } - } - - - let bufferNewData = new ArrayBuffer(bitmap.getPixelBytesNumber()); - let dataNewArray = new Uint8Array(bufferNewData); - let index = 0; - let mh = 0; - let nw = 0; - - for (let i = 0; i < dataNewArray.length; i += 4) { - let pixel_1 = inPixels[mh][nw]; - - if (nw == targetWidth - 1) { - nw = 0; - mh++; - } else { - nw++; - } - - let p_r = ColorUtils.red(pixel_1); - let p_g = ColorUtils.green(pixel_1); - let p_b = ColorUtils.blue(pixel_1); - - dataNewArray[i] = p_r; - dataNewArray[i+1] = p_g; - dataNewArray[i+2] = p_b; - dataNewArray[i+3] = pixEntry[index].f; - index++; - } - await bitmap.writeBufferToPixels(bufferNewData); - if (func) { - func?.asyncTransform("success", bitmap); - } - } - export async function pixelGPU(bitmap: PixelMap, pixel: number, func?: AsyncTransform) { - - let imageInfo:image.ImageInfo = await bitmap.getImageInfo(); - let size:Size = { - width: imageInfo.size.width, - height: imageInfo.size.height - } - if (!size) { - func?.asyncTransform("GrayscaleTransformation The image size does not exist.", null) - return; - } - let w = size.width; - let h = size.height; - - let bufferData = new ArrayBuffer(bitmap.getPixelBytesNumber()); - await bitmap.readPixelsToBuffer(bufferData); - let filter = new GPUImagePixelationFilter(); - filter.setImageData(bufferData, w, h); - filter.setPixel(pixel) - filter.getPixelMapBuf(0, 0, w, h).then((buf) => { - bitmap.writeBufferToPixels(buf); - if (func!=undefined) { - func?.asyncTransform("success", bitmap); - } - }) - } -} \ No newline at end of file diff --git a/library/src/main/ets/components/imageknife/utils/base/EasyLinkedHashMap.ets b/library/src/main/ets/components/imageknife/utils/base/EasyLinkedHashMap.ets deleted file mode 100644 index cd427ec..0000000 --- a/library/src/main/ets/components/imageknife/utils/base/EasyLinkedHashMap.ets +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright (C) 2023 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. - */ - - -class Node { - key: K; - value: V; - next: Node | null; - prev: Node | null; - - constructor(key: K, value: V) { - this.key = key; - this.value = value; - this.next = null; - this.prev = null; - } -} -// 链表的tail是最近访问,head是最晚访问,对顺序有要求需要访问tail -export class EasyLinkedHashMap { - private map: Map>; // 存储键值对的哈希映射 - private head: Node | null; // 链表头节点 - private tail: Node | null; // 链表尾节点 - - constructor() { - this.map = new Map>(); - this.head = null; - this.tail = null; - } - - // 添加键值对到映射中,并在链表尾部添加新节点 - put(key: K, value: V) { - if (this.map.has(key)) { - // 如果键已存在,则更新对应的值 - const node = this.map.get(key)!; - node.value = value; - this.moveToTail(node); - } else { - // 创建新节点并加入链表尾部 - const newNode = new Node(key, value); - this.map.set(key, newNode); - if (this.tail) { - this.tail.next = newNode; - newNode.prev = this.tail; - this.tail = newNode; - } else { - this.head = newNode; - this.tail = newNode; - } - } - } - - // 从映射中移除键值对,并从链表中删除对应节点 - remove(key: K) { - if (this.map.has(key)) { - const node = this.map.get(key)!; - this.map.delete(key); - this.removeNode(node); - } - } - - // 获取键对应的值,并将对应节点移到链表尾部(表示最近访问) - get(key: K): V | undefined { - if (this.map.has(key)) { - const node = this.map.get(key)!; - this.moveToTail(node); - return node.value; - } - return undefined; - } - - // 将节点移动到链表尾部 - private moveToTail(node: Node) { - if (node === this.tail) { - return; // 节点已在链表尾部,无需移动 - } - - if (node === this.head) { - this.head = node.next; - } else { - node.prev!.next = node.next; - } - - node.next!.prev = node.prev; - this.tail!.next = node; - node.prev = this.tail; - node.next = null; - this.tail = node; - } - - // 从链表中删除节点 - private removeNode(node: Node) { - if (node === this.head) { - this.head = node.next; - } else { - node.prev!.next = node.next; - } - - if (node === this.tail) { - this.tail = node.prev; - } else { - node.next!.prev = node.prev; - } - } - - // 返回映射中的键值对数量 - size(): number { - return this.map.size; - } - // 返回顺序双向链表 - getTail(){ - return this.tail; - } - - getHead(){ - return this.head; - } - clear(){ - this.map.clear() - this.head = null; - this.tail=null; - } -} \ No newline at end of file diff --git a/library/src/main/ets/components/imageknife/utils/base/MethodMutex.ets b/library/src/main/ets/components/imageknife/utils/base/MethodMutex.ets deleted file mode 100644 index e3165d8..0000000 --- a/library/src/main/ets/components/imageknife/utils/base/MethodMutex.ets +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (C) 2023 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 MethodMutex { - private mutex: Promise; - private release: () => void; - - constructor() { - this.mutex = Promise.resolve(); - this.release = () => {}; - } - - async lock(fn: () => Promise): Promise { - await this.mutex; - let result: T; - - try { - this.mutex = new Promise((resolve) => { - this.release = resolve; - }); - result = await fn(); - } finally { - this.release(); - } - - return result; - } -} \ No newline at end of file diff --git a/library/src/main/ets/components/imageknife/utils/gif/GIFFrame.ts b/library/src/main/ets/components/imageknife/utils/gif/GIFFrame.ts deleted file mode 100644 index 394c313..0000000 --- a/library/src/main/ets/components/imageknife/utils/gif/GIFFrame.ts +++ /dev/null @@ -1,47 +0,0 @@ -/* - * 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 image from '@ohos.multimedia.image'; -export interface Dims{ - width: number; - height: number; - top: number; - left: number -} -export class GIFFrame { - - // 显示帧 width 宽 height 高 top上边距 left左边距 - dims: Dims - - // 当前帧的像素数据指向的颜色数组 只为了生成patch,非必要 - colorTable?: [number, number, number][] - - // 当前帧到下一帧的间隔时长 - delay: number - - // 当前帧绘制要求 0保留 1在上一帧绘制此帧 2恢复画布背景 3.将画布恢复到绘制当前图像之前的先前状态 - disposalType: number - - // Uint8CampedArray颜色转换后的补片信息用于绘制 必要 - patch?: Uint8ClampedArray - - // drawPixelMap 如果像素转换为PixelMap后使用PixelMap展示, patch和drawPixelMap 2选1 - drawPixelMap?:image.PixelMap - - // 当前帧每个像素的颜色表查找索引 只为了生成patch,非必要 - pixels?: number[] - - // 表示透明度的可选颜色索引 - transparentIndex: number -} \ No newline at end of file diff --git a/library/src/main/ets/components/imageknife/utils/gif/GIFParseImpl.ets b/library/src/main/ets/components/imageknife/utils/gif/GIFParseImpl.ets deleted file mode 100644 index abe1a37..0000000 --- a/library/src/main/ets/components/imageknife/utils/gif/GIFParseImpl.ets +++ /dev/null @@ -1,79 +0,0 @@ -/* - * 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 { Dims, GIFFrame } from './GIFFrame' -import image from '@ohos.multimedia.image' -import { BusinessError } from '@ohos.base' -import worker, { ErrorEvent, MessageEvents } from '@ohos.worker'; -import taskpool from '@ohos.taskpool' -import { LogUtil } from '../LogUtil' - -export interface senderData { - type: string, - data: ArrayBuffer; -} - -export interface gifBackData { - dims: Dims[], - delay: number[], - disposalType: number[], - patch: Uint8ClampedArray[], - transparentIndex: number[] -} - -export class GIFParseImpl implements IParseGif { - parseGifs(imageinfo: ArrayBuffer, callback: (data?: GIFFrame[], err?: BusinessError | string) => void) { - // 硬解码流程 - let imageSource = image.createImageSource(imageinfo); - let decodeOpts: image.DecodingOptions = { - sampleSize: 1, - editable: true, - rotate: 0 - } - let data:GIFFrame[] = []; - imageSource.createPixelMapList(decodeOpts).then((pixelList: Array) => { - //sdk的api接口发生变更:从.getDelayTime() 变为.getDelayTimeList() - imageSource.getDelayTimeList().then(delayTimes => { - if (pixelList.length > 0) { - let pixelmap1 = pixelList[0]; - pixelmap1.getImageInfo().then(imageInfo => { - for (let i = 0; i < pixelList.length; i++) { - let frame = new GIFFrame(); - frame.drawPixelMap = pixelList[i]; - frame.dims = { width: imageInfo.size.width, height: imageInfo.size.height, top: 0, left: 0 } - if (i < delayTimes.length) { - frame.delay = delayTimes[i]; - } else { - frame.delay = delayTimes[delayTimes.length - 1] - } - data.push(frame) - } - callback(data,undefined) - imageSource.release(); - }).catch((err: string) => { - imageSource.release(); - callback(undefined,err) - }) - } - }).catch((err: string) => { - imageSource.release(); - callback(undefined,err) - }) - }).catch((err: string) => { - imageSource.release(); - callback(undefined,err) - }) - } -} \ No newline at end of file diff --git a/library/src/main/ets/components/imageknife/utils/gif/IParseGif.ets b/library/src/main/ets/components/imageknife/utils/gif/IParseGif.ets deleted file mode 100644 index d80f388..0000000 --- a/library/src/main/ets/components/imageknife/utils/gif/IParseGif.ets +++ /dev/null @@ -1,21 +0,0 @@ -/* - * 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 { BusinessError } from '@ohos.base' -import { GIFFrame } from './GIFFrame' -import worker from '@ohos.worker'; -export interface IParseGif{ - // gif解析 - parseGifs:(imageinfo: ArrayBuffer, callback: (data?:GIFFrame[], err?:BusinessError|string) => void, worker?:worker.ThreadWorker,runMainThread?:boolean)=>void -} \ No newline at end of file diff --git a/library/src/main/ets/components/imageknife/utils/svg/IParseSvg.ets b/library/src/main/ets/components/imageknife/utils/svg/IParseSvg.ets deleted file mode 100644 index bf7c72e..0000000 --- a/library/src/main/ets/components/imageknife/utils/svg/IParseSvg.ets +++ /dev/null @@ -1,24 +0,0 @@ -/* - * 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 { RequestOption } from '../../RequestOption' -import { BusinessError } from '@ohos.base' -import { ImageKnifeData } from '../../ImageKnifeData' - -export interface IParseSvg { - // 解析svg - parseSvg:(option: RequestOption, imageInfo: ArrayBuffer | ArrayBufferLike, - onComplete: (value: PixelMap) => void | PromiseLike, - onErrorFunction: (reason?: BusinessError | string) => void)=> void -} \ No newline at end of file diff --git a/library/src/main/ets/components/imageknife/utils/svg/SVGParseImpl.ets b/library/src/main/ets/components/imageknife/utils/svg/SVGParseImpl.ets deleted file mode 100644 index 557214a..0000000 --- a/library/src/main/ets/components/imageknife/utils/svg/SVGParseImpl.ets +++ /dev/null @@ -1,46 +0,0 @@ -/* - * 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 { RequestOption } from '../../RequestOption' -import { BusinessError } from '@ohos.base' -import { ImageKnifeData, ImageKnifeType } from '../../ImageKnifeData' -import image from '@ohos.multimedia.image' - -export class SVGParseImpl implements IParseSvg { - parseSvg(option: RequestOption, imageInfo: ArrayBuffer, - onComplete: (value: PixelMap) => void | PromiseLike, - onErrorFunction: (reason?: BusinessError | string) => void) { - - let imageSource: image.ImageSource = image.createImageSource(imageInfo); // 步骤一:文件转为pixelMap 然后变换 给Image组件 - let hValue = Math.round(option.size.height); - let wValue = Math.round(option.size.width); - let defaultSize: image.Size = { - height: hValue, - width: wValue - }; - let opts: image.DecodingOptions = { - editable: true, - desiredSize: defaultSize - }; - imageSource.createPixelMap(opts).then((pixelMap: image.PixelMap) => { - let imageKnifeData = ImageKnifeData.createImagePixelMap(ImageKnifeType.PIXELMAP, pixelMap) - onComplete(imageKnifeData?.drawPixelMap?.imagePixelMap as PixelMap); - imageSource.release() - }).catch((err: string) => { - onErrorFunction(err); - imageSource.release() - }) - } -} \ No newline at end of file diff --git a/library/src/main/ets/components/imageknife/interface/AsyncCallback.ets b/library/src/main/ets/model/ImageKnifeData.ets similarity index 60% rename from library/src/main/ets/components/imageknife/interface/AsyncCallback.ets rename to library/src/main/ets/model/ImageKnifeData.ets index be30df4..eece771 100644 --- a/library/src/main/ets/components/imageknife/interface/AsyncCallback.ets +++ b/library/src/main/ets/model/ImageKnifeData.ets @@ -1,18 +1,20 @@ /* - * Copyright (C) 2021 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); + * 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, + * 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 AsyncCallback { - callback:(err: string, data: T)=>boolean; +export interface ImageKnifeData { + source: PixelMap | string, + imageWidth: number, + imageHeight: number } + diff --git a/library/src/main/ets/components/imageknife/interface/DataCallBack.ets b/library/src/main/ets/utils/Constants.ets similarity index 62% rename from library/src/main/ets/components/imageknife/interface/DataCallBack.ets rename to library/src/main/ets/utils/Constants.ets index 5fee466..d187451 100644 --- a/library/src/main/ets/components/imageknife/interface/DataCallBack.ets +++ b/library/src/main/ets/utils/Constants.ets @@ -1,18 +1,17 @@ /* - * Copyright (C) 2021 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); + * 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, + * 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 DataCallBack { - callback:(data: T)=>void; +export class Constants { + public static PROGRESS_EMITTER: string = "progressEmitter" } \ No newline at end of file diff --git a/library/src/main/ets/utils/DefaultJobQueue.ets b/library/src/main/ets/utils/DefaultJobQueue.ets new file mode 100644 index 0000000..c6aafe0 --- /dev/null +++ b/library/src/main/ets/utils/DefaultJobQueue.ets @@ -0,0 +1,48 @@ +/* + * 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 { ImageKnifeRequest } from '../ImageKnifeRequest'; +import { IJobQueue } from './IJobQueue' +import Queue from '@ohos.util.Queue'; +import { taskpool } from '@kit.ArkTS'; + +export class DefaultJobQueue implements IJobQueue { + highQueue: Queue = new Queue(); + normalQueue: Queue = new Queue(); + lowQueue: Queue = new Queue(); + + getQueueLength(): number { + return this.highQueue.length + this.normalQueue.length + this.lowQueue.length + } + + add(request: ImageKnifeRequest): void { + if (request.ImageKnifeOption.priority === undefined || request.ImageKnifeOption.priority === taskpool.Priority.MEDIUM) { + this.normalQueue.add(request) + } else if (request.ImageKnifeOption.priority === taskpool.Priority.HIGH) { + this.highQueue.add(request) + } else { + this.lowQueue.add(request) + } + } + + pop(): ImageKnifeRequest | undefined { + if (this.highQueue.length > 0) { + return this.highQueue.pop() + } else if (this.normalQueue.length > 0) { + return this.normalQueue.pop() + } else { + return this.lowQueue.pop() + } + } +} \ No newline at end of file diff --git a/library/src/main/ets/utils/FileCache.ets b/library/src/main/ets/utils/FileCache.ets new file mode 100644 index 0000000..cbfb3aa --- /dev/null +++ b/library/src/main/ets/utils/FileCache.ets @@ -0,0 +1,264 @@ +/* + * 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 util from '@ohos.util'; +import { FileUtils } from './FileUtils'; +import fs from '@ohos.file.fs'; +import { LogUtil } from './LogUtil'; + + +/** + * 二级文件缓存 + * 主线程通过lruCache管理缓存大小 + * 子线程直接读写文件 + */ +export class FileCache { + static readonly CACHE_FOLDER: string = "ImageKnife" // context cacheDir 的缓存文件目录 + maxMemory: number = 0 + currentMemory: number = 0 + maxSize: number = 0 + path: string = "" + private lruCache: util.LRUCache + private isInited: boolean = false + private context?: Context + readonly defaultMaxSize: number = 512; + readonly defaultSize: number = 128; + readonly defaultMaxMemorySize: number = 512 * 1024 * 1024; + readonly defaultMemorySize: number = 128 * 1024 * 1024; + + constructor(context: Context, size: number, memory: number) { + if (size <= 0 || size > this.defaultMaxSize) { + size = this.defaultSize + } + if (memory <= 0 || memory > this.defaultMaxMemorySize) { + memory = this.defaultMemorySize + } + + this.lruCache = new util.LRUCache(size); + this.maxMemory = memory + this.currentMemory = 0; + this.maxSize = size + this.context = context + } + + /** + * 遍历缓存文件目录,初始化缓存 + */ + public async initFileCache() { + if (this.isInited) { + return + } + + this.path = this.context?.cacheDir + FileUtils.SEPARATOR + FileCache.CACHE_FOLDER + FileUtils.SEPARATOR + await FileUtils.getInstance().createFolder(this.path) + // 遍历缓存目录下的文件,按照时间顺序加入缓存 + let filenames: string[] = await FileUtils.getInstance().ListFile(this.path) + + interface CacheFileInfo { + file: string; + ctime: number; + } + + // 按照上次访问该文件的时间排序 + let cachefiles: CacheFileInfo[] = [] + for (let i = 0; i < filenames.length; i++) { + let stat: fs.Stat | undefined = await FileUtils.getInstance().Stat(this.path + filenames[i]) + cachefiles.push({ + file: filenames[i], + ctime: stat === undefined ? 0 : stat.ctime + }) + } + let sortedCachefiles: CacheFileInfo[] = cachefiles.sort((a, b) => a.ctime - b.ctime) + + for (let i = 0; i < sortedCachefiles.length; i++) { + let buf: ArrayBuffer | undefined = await FileUtils.getInstance().readFile(this.path + sortedCachefiles[i].file) + if (buf !== undefined) { + // 处理数量超过size的场景,移除即将排除的文件 + if (this.lruCache.length == this.maxSize && !this.lruCache.contains(sortedCachefiles[i].file)) { + let remove: string | undefined = this.lruCache.remove(this.lruCache.keys()[0]) + if (remove !== undefined) { + let buf: ArrayBuffer | undefined = FileUtils.getInstance().readFileSync(this.path + this.lruCache.keys()[0]) + if (buf !== undefined) { + FileUtils.getInstance().deleteFile(this.path + this.lruCache.keys()[0]) + this.removeMemorySize(buf) + } + } + } + + this.lruCache.put(sortedCachefiles[i].file, "") + this.addMemorySize(buf) + } + } + + this.trimToSize(); + this.isInited = true + } + + // 添加缓存键值对,同时写文件 + put(key: string, value: ArrayBuffer): void { + if (key == null || value == null) { + throw new Error('key or value is invalid '); + } + if (!this.isInited) { + return + } + + // 如果size满了的话,需要按照LRU的方式删除第一个 + if (this.lruCache.length == this.maxSize && !this.lruCache.contains(key)) { + this.remove(this.lruCache.keys()[0]) + } else if (this.lruCache.contains(key)) { + this.remove(key) + } + + let pre = this.lruCache.put(key, "") + FileUtils.getInstance().writeDataSync(this.path + key, value) + if (pre !== undefined) { + this.addMemorySize(value) + } + this.trimToSize() + } + + // 添加缓存键值对,但不写文件(用于子线程已经写文件的场景) + putWithoutWriteFile(key: string, value: ArrayBuffer | number): void { + if (key == null || value == null) { + throw new Error('key or value is invalid '); + } + if (!this.isInited) { + return + } + + // 如果size满了的话,需要按照LRU的方式删除第一个 + if (this.lruCache.length == this.maxSize && !this.lruCache.contains(key)) { + this.remove(this.lruCache.keys()[0]) + } else if (this.lruCache.contains(key)) { + this.lruCache.remove(key) + this.lruCache.put(key, "") + return + } + + this.lruCache.put(key, "") + this.addMemorySize(value) + this.trimToSize() + } + + get(key: string): ArrayBuffer | undefined { + if (!this.isInited) { + return + } + + if (this.lruCache.get(key) !== undefined) { + // TODO 如何才能修改文件访问时间呢 + return FileUtils.getInstance().readFileSync(this.path + key) + } + return undefined + } + + // 移除键为key的缓存 + remove(key: string): void { + if (key == null) { + throw new Error('key is null,checking the parameter'); + } + if (!this.isInited) { + return + } + + let remove: string | undefined = this.lruCache.remove(key) + if (remove !== undefined) { + let buf: ArrayBuffer | undefined = FileUtils.getInstance().readFileSync(this.path + key) + if (buf !== undefined) { + FileUtils.getInstance().deleteFile(this.path + key) + this.removeMemorySize(buf) + } + } + } + + async removeAll(): Promise { + if (!this.isInited) { + return + } + this.isInited = false + this.lruCache.clear() + this.currentMemory = 0; + + let filenames: string[] = await FileUtils.getInstance().ListFile(this.path) + for (let i = 0; i < filenames.length; i++) { + await FileUtils.getInstance().deleteFile(this.path + filenames[i]) + } + + this.isInited = true + } + + size(): number { + return this.lruCache.length + } + + // 移除较少使用的缓存数据 + trimToSize(): void { + while (true) { + if (this.currentMemory <= this.maxMemory || this.lruCache.isEmpty()) { + break + } + let delkey = this.lruCache.keys()[0] + let data: ArrayBuffer | undefined = FileUtils.getInstance().readFileSync(this.path + delkey) + if (data !== undefined) { + FileUtils.getInstance().deleteFileSync(this.path + delkey) + this.removeMemorySize(data) + } + this.lruCache.remove(delkey) + } + } + + private removeMemorySize(value: ArrayBuffer): void { + if (value != undefined) { + this.currentMemory -= value.byteLength + LogUtil.info("FileCache removeMemorySize: " + value.byteLength + " currentMemory:" + this.currentMemory) + } + } + + private addMemorySize(value: ArrayBuffer | number): void { + if (typeof value == "number") { + this.currentMemory += value + LogUtil.info("FileCache addMemorySize: " + value + " currentMemory:" + this.currentMemory) + } + else if (value != undefined) { + this.currentMemory += value.byteLength + LogUtil.info("FileCache addMemorySize: " + value.byteLength + " currentMemory:" + this.currentMemory) + } + } + + /** + * 子线程里只写入缓存文件 + * @param context + * @param key + * @param value + */ + static saveFileCacheOnlyFile(context: Context, key: string, value: ArrayBuffer): boolean { + // 写文件 + FileUtils.getInstance() + .writeFileSync(context.cacheDir + FileUtils.SEPARATOR + FileCache.CACHE_FOLDER + FileUtils.SEPARATOR + key, value) + return true + } + + /** + * 子线程中,通过文件名,直接查找是否有文件缓存 + * @param context + * @param key + * @returns + */ + static getFileCacheByFile(context: Context, key: string): ArrayBuffer | undefined { + // 从文件获取查看是否有缓存 + return FileUtils.getInstance() + .readFileSync(context.cacheDir + FileUtils.SEPARATOR + FileCache.CACHE_FOLDER + FileUtils.SEPARATOR + key) + } +} \ No newline at end of file diff --git a/library/src/main/ets/components/imageknife/utils/FileTypeUtil.ets b/library/src/main/ets/utils/FileTypeUtil.ets similarity index 93% rename from library/src/main/ets/components/imageknife/utils/FileTypeUtil.ets rename to library/src/main/ets/utils/FileTypeUtil.ets index 44e2b54..c87c939 100644 --- a/library/src/main/ets/components/imageknife/utils/FileTypeUtil.ets +++ b/library/src/main/ets/utils/FileTypeUtil.ets @@ -1,18 +1,17 @@ /* - * Copyright (C) 2021 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); + * 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, + * 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 { LogUtil } from '../../imageknife/utils/LogUtil' export class FileTypeUtil { diff --git a/library/src/main/ets/utils/FileUtils.ets b/library/src/main/ets/utils/FileUtils.ets new file mode 100644 index 0000000..1b8e94b --- /dev/null +++ b/library/src/main/ets/utils/FileUtils.ets @@ -0,0 +1,305 @@ +/* + * 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 fs from '@ohos.file.fs'; +import { BusinessError } from '@ohos.base'; +import { LogUtil } from './LogUtil' + + +export class FileUtils { + static readonly SEPARATOR: string = '/' + private static sInstance: FileUtils + + private constructor() { + } + + /** + * 单例实现FileUtils类 + */ + public static getInstance(): FileUtils { + if (!FileUtils.sInstance) { + FileUtils.sInstance = new FileUtils(); + } + return FileUtils.sInstance; + } + + /** + * 删除文件 + * + * @param path 文件绝对路径及文件名 + */ + deleteFileSync(path: string): boolean { + try { + let fileExist = fs.accessSync(path); + if (fileExist) { + fs.unlinkSync(path); + } + return true + } catch (err) { + LogUtil.error("FileUtils deleteFileSync failed: err msg=" + err.message + " err code=" + err.code); + return false + } + } + + /** + * 异步删除文件 + * @param path + * @returns + */ + async deleteFile(path: string): Promise { + const isExist: boolean = await fs.access(path) + if (isExist) { + try { + await fs.unlink(path) + } + catch (err) { + LogUtil.error("FileUtils deleteFile failed: err msg=" + err.message + " err code=" + err.code); + return false + } + } + return true + } + + /** + * 向path写入数据 + * + * @param path 文件绝对路径 + * @param content 文件内容 + */ + writeDataSync(path: string, content: ArrayBuffer | string): boolean { + try { + let fd = fs.openSync(path, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE | fs.OpenMode.TRUNC).fd + let stat = fs.statSync(path) + fs.writeSync(fd, content, { offset: stat.size }) + fs.closeSync(fd) + return true + } + catch (err) { + LogUtil.error("FileUtils writeDataSync failed: err msg=" + err.message + " err code=" + err.code); + return false + } + } + + /** + * 异步向path写入数据 + * + * @param path 文件绝对路径 + * @param content 文件内容 + */ + async writeData(path: string, content: ArrayBuffer | string): Promise { + try { + let fd = (await fs.open(path, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE)).fd + let stat = await fs.stat(path) + await fs.write(fd, content, { offset: stat.size }) + await fs.close(fd) + return true + } + catch (err) { + LogUtil.error("FileUtils writeData failed: err msg=" + err.message + " err code=" + err.code); + return false + } + } + + /** + * 判断path文件是否存在 + * + * @param path 文件绝对路径 + */ + exist(path: string): boolean { + try { + if (fs.accessSync(path)) { + let stat = fs.statSync(path) + return stat.isFile() + } else { + return false + } + } catch (error) { + let err: BusinessError = error as BusinessError; + LogUtil.error("FileUtils exist failed with error message: " + err.message + ", error code: " + err.code); + } + return false + } + + /** + * 获取path的文件大小 + * + * @param path 文件绝对路径 + */ + getFileSizeSync(path: string): number { + try { + let stat = fs.statSync(path) + return stat.size + } catch (e) { + LogUtil.error("FileUtils getFileSize e " + e) + return -1 + } + } + + /** + * 读取路径path的文件 + * + * @param path 文件绝对路径 + */ + readFileSync(path: string): ArrayBuffer | undefined { + try { + if (fs.accessSync(path)) { + let fd = fs.openSync(path, fs.OpenMode.READ_ONLY).fd; + let length = fs.statSync(path).size + let buf = new ArrayBuffer(length); + fs.readSync(fd, buf) + fs.closeSync(fd) + return buf + } + } catch (error) { + let err: BusinessError = error as BusinessError; + LogUtil.error("FileUtils readFileSync failed with error message: " + err.message + ", error code: " + err.code); + } + return undefined + } + + /** + * 读取路径path的文件 + * + * @param path 文件绝对路径 + */ + async readFile(path: string): Promise { + try { + let stat = await fs.stat(path); + let fd = (await fs.open(path, fs.OpenMode.READ_ONLY)).fd; + let length = stat.size; + let buf = new ArrayBuffer(length); + await fs.read(fd, buf); + return buf + } catch (error) { + let err: BusinessError = error as BusinessError; + LogUtil.error("FileUtils readFile failed with error message: " + err.message + ", error code: " + err.code); + } + return undefined + } + + /** + * 创建文件夹 + * + * @param path 文件夹绝对路径,只有是权限范围内的路径,可以生成 + * @param recursive + */ + createFolderSync(path: string, recursive?: boolean) { + try { + if (recursive) { + if (!this.existFolder(path)) { + let lastInterval = path.lastIndexOf(FileUtils.SEPARATOR) + if (lastInterval == 0) { + return + } + let newPath = path.substring(0, lastInterval) + this.createFolderSync(newPath, true) + if (!this.existFolder(path)) { + fs.mkdirSync(path) + } + } + } else { + if (!this.existFolder(path)) { + fs.mkdirSync(path) + } + } + } catch (e) { + LogUtil.log("FileUtils createFolder err : " + e) + } + } + + async createFolder(path: string): Promise { + try { + let isExist: boolean = await fs.access(path) + if (!isExist) { + await fs.mkdir(path) + + } + return true + } catch (error) { + let err: BusinessError = error as BusinessError; + LogUtil.error("FileUtils createFolder failed with error message: " + err.message + ", error code: " + err.code); + } + return false + } + + /** + * 判断文件夹是否存在 + * + * @param path 文件夹绝对路径 + */ + existFolder(path: string): boolean { + try { + if (fs.accessSync(path)) { + let stat = fs.statSync(path) + return stat.isDirectory() + } else { + return false + } + } + catch (error) { + let err: BusinessError = error as BusinessError; + LogUtil.error("FileUtils existFolder failed with error message: " + err.message + ", error code: " + err.code); + } + return false + } + + writeFileSync(path: string, content: ArrayBuffer | string): boolean { + try { + let fd = fs.openSync(path, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE).fd + fs.truncateSync(fd) + fs.writeSync(fd, content) + fs.closeSync(fd) + return true + } catch (err) { + LogUtil.error("FileUtils writeFileSync failed with error message: " + err.message + ", error code: " + err.code); + } + return false + } + + ListFileSync(path: string): string[] { + try { + return fs.listFileSync(path) + } catch (err) { + LogUtil.error("FileUtils ListFileSync failed with error message: " + err.message + ", error code: " + err.code); + } + return [] + } + + async ListFile(path: string): Promise { + try { + return fs.listFile(path) + } catch (err) { + LogUtil.error("FileUtils ListFile failed with error message: " + err.message + ", error code: " + err.code); + } + return [] + } + + StatSync(path: string): fs.Stat | undefined { + try { + return fs.statSync(path) + } catch (err) { + LogUtil.error("FileUtils StatSync failed with error message: " + err.message + ", error code: " + err.code); + } + return undefined + } + + async Stat(path: string): Promise { + try { + return fs.stat(path) + } catch (err) { + LogUtil.error("FileUtils Stat failed with error message: " + err.message + ", error code: " + err.code); + } + return undefined + } +} \ No newline at end of file diff --git a/library/src/main/ets/utils/IJobQueue.ets b/library/src/main/ets/utils/IJobQueue.ets new file mode 100644 index 0000000..0a51ff0 --- /dev/null +++ b/library/src/main/ets/utils/IJobQueue.ets @@ -0,0 +1,37 @@ +/* + * 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 { ImageKnifeRequest } from '../ImageKnifeRequest' + +export interface IJobQueue { + + /** + * 获取队列长度 + * @returns + */ + getQueueLength(): number + + /** + * 往队列中添加元素 + * @param request + */ + add(request: ImageKnifeRequest): void + + + /** + * 移除并返回队列头部的元素 + * @returns + */ + pop(): ImageKnifeRequest | undefined +} \ No newline at end of file diff --git a/library/src/main/ets/utils/IMemoryCache.ets b/library/src/main/ets/utils/IMemoryCache.ets new file mode 100644 index 0000000..8e35c62 --- /dev/null +++ b/library/src/main/ets/utils/IMemoryCache.ets @@ -0,0 +1,28 @@ +/* + * 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 { ImageKnifeData } from '../model/ImageKnifeData' + +export interface IMemoryCache { + + put(key: string, value: ImageKnifeData): void + + get(key: string): ImageKnifeData | undefined + + remove(key: string): ImageKnifeData | undefined + + removeAll(): void + + size(): number +} \ No newline at end of file diff --git a/library/src/main/ets/components/imageknife/utils/LogUtil.ets b/library/src/main/ets/utils/LogUtil.ets similarity index 68% rename from library/src/main/ets/components/imageknife/utils/LogUtil.ets rename to library/src/main/ets/utils/LogUtil.ets index cf7e066..11a3645 100644 --- a/library/src/main/ets/components/imageknife/utils/LogUtil.ets +++ b/library/src/main/ets/utils/LogUtil.ets @@ -1,13 +1,13 @@ /* - * Copyright (C) 2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); + * 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, + * 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. @@ -20,36 +20,36 @@ export class LogUtil { public static WARN: number = 5 public static ERROR: number = 6 public static ALL: number = 7 - public static mLogLevel:number = LogUtil.OFF; + public static mLogLevel: number = LogUtil.ALL; + public static TAG: string = "ImageKnife:: "; public static debug(message: string, ...args: Object[]) { if (LogUtil.mLogLevel >= LogUtil.DEBUG) { - console.debug(message, args) + console.debug(LogUtil.TAG + message, args) } } public static info(message: string, ...args: Object[]) { if (LogUtil.mLogLevel >= LogUtil.INFO) { - console.info(message, args) + console.info(LogUtil.TAG + message, args) } } public static log(message: string, ...args: Object[]) { if (LogUtil.mLogLevel >= LogUtil.LOG) { - console.log(message, args) + console.log(LogUtil.TAG + message, args) } } public static warn(message: string, ...args: Object[]) { if (LogUtil.mLogLevel >= LogUtil.WARN) { - console.warn(message, args) + console.warn(LogUtil.TAG + message, args) } } - // error 不做拦截 public static error(message: string, ...args: Object[]) { - if(LogUtil.mLogLevel >= LogUtil.ERROR) { - console.error(message, args) + if (LogUtil.mLogLevel >= LogUtil.ERROR) { + console.error(LogUtil.TAG + message, args) } } } \ No newline at end of file diff --git a/library/src/main/ets/utils/MemoryLruCache.ets b/library/src/main/ets/utils/MemoryLruCache.ets new file mode 100644 index 0000000..fa0d513 --- /dev/null +++ b/library/src/main/ets/utils/MemoryLruCache.ets @@ -0,0 +1,126 @@ +/* + * 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 { ImageKnifeData } from '../model/ImageKnifeData'; +import util from '@ohos.util'; +import { IMemoryCache } from './IMemoryCache'; + +export class MemoryLruCache implements IMemoryCache { + maxMemory: number = 0 + currentMemory: number = 0 + maxSize: number = 0 + private lruCache: util.LRUCache + readonly defaultMaxSize: number = 4096 + readonly defaultSize: number = 512 + readonly defaultMaxMemorySize: number = 1024 * 1024 * 1024 + readonly defaultMemorySize: number = 128 * 1024 * 1024 + + constructor(size: number, memory: number) { + if (size <= 0 || size > this.defaultMaxSize) { + size = this.defaultSize + } + if (memory <= 0 || memory > this.defaultMaxMemorySize) { + memory = this.defaultMemorySize + } + + this.lruCache = new util.LRUCache(size); + this.maxMemory = memory + this.maxSize = size + this.currentMemory = 0 + } + + // 添加缓存键值对 + put(key: string, value: ImageKnifeData): void { + if (key == null || value == null) { + throw new Error('key or value is invalid '); + } + + // 如果size满了的话,需要按照LRU的方式删除第一个 + if (this.lruCache.length == this.maxSize && !this.lruCache.contains(key)) { + this.remove(this.lruCache.keys()[0]) + } else if (this.lruCache.contains(key)) { + this.remove(key) + } + + let pre: ImageKnifeData = this.lruCache.put(key, value) + this.addMemorySize(value) + // if (pre !== undefined) { // 当前返回不是key的之前value + // this.removeMemorySize(pre) + // } + this.trimToSize(); + } + + get(key: string): ImageKnifeData | undefined { + return this.lruCache.get(key) + } + + // 移除键为key的缓存 + remove(key: string): ImageKnifeData | undefined { + if (key == null) { + throw new Error('key is null,checking the parameter'); + } + + let remove: ImageKnifeData | undefined = this.lruCache.remove(key) + if (remove !== undefined) { + this.removeMemorySize(remove) + } + return remove + } + + removeAll(): void { + this.lruCache.clear() + this.currentMemory = 0; + } + + size(): number { + return this.lruCache.length + } + + // 移除较少使用的缓存数据 + trimToSize(): void { + while (true) { + if (this.currentMemory <= this.maxMemory || this.lruCache.isEmpty()) { + break + } + let delkey = this.lruCache.keys()[0] + let data: ImageKnifeData | undefined = this.lruCache.get(delkey) + if (data != undefined) { + this.removeMemorySize(data) + } + this.lruCache.remove(delkey) + } + } + + private removeMemorySize(value: ImageKnifeData): void { + if (value.source != undefined) { + if (typeof value.source === 'string') { + this.currentMemory -= value.source.length + } else { + this.currentMemory -= value.source.getPixelBytesNumber(); + } + // LogUtil.info("MemoryCache removeMemorySize: " + value.source.getPixelBytesNumber() + " currentMemory:" + this.currentMemory) + } + } + + private addMemorySize(value: ImageKnifeData): void { + if (value.source != undefined) { + if (typeof value.source === 'string') { + this.currentMemory += value.source.length + } else { + this.currentMemory += value.source.getPixelBytesNumber(); + } + //LogUtil.log("MemoryCache addMemorySize: " + value.source.getPixelBytesNumber() + " currentMemory:" + this.currentMemory) + } + } +} \ No newline at end of file diff --git a/library/src/main/module.json5 b/library/src/main/module.json5 index 7274415..dd30f8e 100644 --- a/library/src/main/module.json5 +++ b/library/src/main/module.json5 @@ -4,8 +4,8 @@ "type": "har", "deviceTypes": [ "default", - "tablet" - ], - "uiSyntax": "ets" + "tablet", + "2in1" + ] } -} \ No newline at end of file +} diff --git a/library/src/main/resources/base/element/string.json b/library/src/main/resources/base/element/string.json index 1e76de0..f51a9c8 100644 --- a/library/src/main/resources/base/element/string.json +++ b/library/src/main/resources/base/element/string.json @@ -2,7 +2,7 @@ "string": [ { "name": "page_show", - "value": "page from npm package" + "value": "page from package" } ] } diff --git a/library/src/main/resources/base/media/rabbit.gif b/library/src/main/resources/base/media/rabbit.gif new file mode 100644 index 0000000..c2c1402 Binary files /dev/null and b/library/src/main/resources/base/media/rabbit.gif differ diff --git a/library/src/main/resources/base/media/startIcon.png b/library/src/main/resources/base/media/startIcon.png new file mode 100644 index 0000000..366f764 Binary files /dev/null and b/library/src/main/resources/base/media/startIcon.png differ diff --git a/library/src/main/resources/en_US/element/string.json b/library/src/main/resources/en_US/element/string.json new file mode 100644 index 0000000..f51a9c8 --- /dev/null +++ b/library/src/main/resources/en_US/element/string.json @@ -0,0 +1,8 @@ +{ + "string": [ + { + "name": "page_show", + "value": "page from package" + } + ] +} diff --git a/library/src/main/resources/zh_CN/element/string.json b/library/src/main/resources/zh_CN/element/string.json new file mode 100644 index 0000000..f51a9c8 --- /dev/null +++ b/library/src/main/resources/zh_CN/element/string.json @@ -0,0 +1,8 @@ +{ + "string": [ + { + "name": "page_show", + "value": "page from package" + } + ] +} diff --git a/library/src/test/List.test.ets b/library/src/test/List.test.ets new file mode 100644 index 0000000..bb5b5c3 --- /dev/null +++ b/library/src/test/List.test.ets @@ -0,0 +1,5 @@ +import localUnitTest from './LocalUnit.test'; + +export default function testsuite() { + localUnitTest(); +} \ No newline at end of file diff --git a/entry/src/ohosTest/ets/test/Ability.test.ets b/library/src/test/LocalUnit.test.ets similarity index 53% rename from entry/src/ohosTest/ets/test/Ability.test.ets rename to library/src/test/LocalUnit.test.ets index 91d458b..ed22d4d 100644 --- a/entry/src/ohosTest/ets/test/Ability.test.ets +++ b/library/src/test/LocalUnit.test.ets @@ -1,50 +1,33 @@ -/* - * Copyright (C) 2023 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 hilog from '@ohos.hilog'; -import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium' +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'; - -export default function abilityTest() { - describe('ActsAbilityTest', ()=> { +export default function localUnitTest() { + describe('localUnitTest',() => { // Defines a test suite. Two parameters are supported: test suite name and test suite function. - beforeAll( ()=> { + beforeAll(() => { // Presets an action, which is performed only once before all test cases of the test suite start. // This API supports only one parameter: preset action function. - }) - beforeEach( ()=> { + }); + beforeEach(() => { // Presets an action, which is performed before each unit test case starts. // The number of execution times is the same as the number of test cases defined by **it**. // This API supports only one parameter: preset action function. - }) - afterEach( ()=> { + }); + afterEach(() => { // Presets a clear action, which is performed after each unit test case ends. // The number of execution times is the same as the number of test cases defined by **it**. // This API supports only one parameter: clear action function. - }) - afterAll( ()=> { + }); + afterAll(() => { // Presets a clear action, which is performed after all test cases of the test suite end. // This API supports only one parameter: clear action function. - }) - it('assertContain',0, ()=> { + }); + it('assertContain', 0, () => { // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. - hilog.info(0x0000, 'testTag', '%{public}s', 'it begin'); - let a = 'abc' - let b = 'b' + let a = 'abc'; + let b = 'b'; // Defines a variety of assertion methods, which are used to declare expected boolean conditions. - expect(a).assertContain(b) - expect(a).assertEqual(a) - }) - }) + expect(a).assertContain(b); + expect(a).assertEqual(a); + }); + }); } \ No newline at end of file diff --git a/oh-package.json5 b/oh-package.json5 index 9e9498e..5d45532 100644 --- a/oh-package.json5 +++ b/oh-package.json5 @@ -1,11 +1,13 @@ { - "license": "ISC", - "devDependencies": { - "@ohos/hypium": "1.0.6" - }, "name": "imageknife", - "description": "example description", - "repository": {}, - "version": "2.1.2-rc.12", - "dependencies": {} + "version": "1.0.0", + "description": "Please describe the basic information.", + "main": "", + "author": "", + "license": "", + "dependencies": { + }, + "devDependencies": { + "@ohos/hypium": "1.0.13" + } } diff --git a/screenshot/gif1.gif b/screenshot/gif1.gif deleted file mode 100644 index bbd0991..0000000 Binary files a/screenshot/gif1.gif and /dev/null differ diff --git a/screenshot/gif2.gif b/screenshot/gif2.gif deleted file mode 100644 index cbfc95e..0000000 Binary files a/screenshot/gif2.gif and /dev/null differ diff --git a/screenshot/gif3.gif b/screenshot/gif3.gif deleted file mode 100644 index 214cbb9..0000000 Binary files a/screenshot/gif3.gif and /dev/null differ diff --git a/screenshot/gif4.gif b/screenshot/gif4.gif deleted file mode 100644 index e188563..0000000 Binary files a/screenshot/gif4.gif and /dev/null differ diff --git a/screenshot/jpg1.jpg b/screenshot/jpg1.jpg deleted file mode 100644 index 18d3d6a..0000000 Binary files a/screenshot/jpg1.jpg and /dev/null differ diff --git a/screenshot/jpg2.jpg b/screenshot/jpg2.jpg deleted file mode 100644 index 360b1a1..0000000 Binary files a/screenshot/jpg2.jpg and /dev/null differ diff --git a/screenshot/png1.png b/screenshot/png1.png deleted file mode 100644 index d3f25dd..0000000 Binary files a/screenshot/png1.png and /dev/null differ diff --git a/screenshot/png2.png b/screenshot/png2.png deleted file mode 100644 index bff16f3..0000000 Binary files a/screenshot/png2.png and /dev/null differ diff --git a/screenshot/worker1.png b/screenshot/worker1.png deleted file mode 100644 index 8769b21..0000000 Binary files a/screenshot/worker1.png and /dev/null differ diff --git a/screenshot/worker2.png b/screenshot/worker2.png deleted file mode 100644 index db52375..0000000 Binary files a/screenshot/worker2.png and /dev/null differ diff --git a/screenshot/worker3.png b/screenshot/worker3.png deleted file mode 100644 index f8cc1e0..0000000 Binary files a/screenshot/worker3.png and /dev/null differ diff --git a/screenshot/worker4.png b/screenshot/worker4.png deleted file mode 100644 index f4c62d3..0000000 Binary files a/screenshot/worker4.png and /dev/null differ diff --git a/sharedlibrary/.gitignore b/sharedlibrary/.gitignore deleted file mode 100644 index e2713a2..0000000 --- a/sharedlibrary/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -/node_modules -/oh_modules -/.preview -/build -/.cxx -/.test \ No newline at end of file diff --git a/sharedlibrary/build-profile.json5 b/sharedlibrary/build-profile.json5 deleted file mode 100644 index befa101..0000000 --- a/sharedlibrary/build-profile.json5 +++ /dev/null @@ -1,10 +0,0 @@ -{ - "apiType": 'stageMode', - "buildOption": { - }, - "targets": [ - { - "name": "default" - } - ] -} \ No newline at end of file diff --git a/sharedlibrary/hvigorfile.ts b/sharedlibrary/hvigorfile.ts deleted file mode 100644 index 0e65ea8..0000000 --- a/sharedlibrary/hvigorfile.ts +++ /dev/null @@ -1,2 +0,0 @@ -// Script for compiling build behavior. It is built in the build plug-in and cannot be modified currently. -module.exports = require('@ohos/hvigor-ohos-plugin').hspTasks diff --git a/sharedlibrary/oh-package.json5 b/sharedlibrary/oh-package.json5 deleted file mode 100644 index 1d879aa..0000000 --- a/sharedlibrary/oh-package.json5 +++ /dev/null @@ -1,12 +0,0 @@ -{ - "license": "Apache-2.0", - "devDependencies": {}, - "author": "", - "name": "sharedlibrary", - "description": "Please describe the basic information.", - "main": "./src/main/ets/Index.ets", - "version": "1.0.0", - "dependencies": { - "@ohos/imageknife": "file:../library" - } -} diff --git a/sharedlibrary/src/main/ets/Index.ets b/sharedlibrary/src/main/ets/Index.ets deleted file mode 100644 index 28c8d80..0000000 --- a/sharedlibrary/src/main/ets/Index.ets +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright (C) 2023 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. - */ - - -// ImageKnife 对外暴露的接口由library提供 - -/** - * cache - */ - -export { FileUtils } from '@ohos/imageknife' -export { Base64 } from '@ohos/imageknife' -export { LruCache } from '@ohos/imageknife' -export { DiskStrategy } from '@ohos/imageknife' -export { ALL } from '@ohos/imageknife' -export { AUTOMATIC } from '@ohos/imageknife' -export { DATA } from '@ohos/imageknife' -export { NONE } from '@ohos/imageknife' -export { RESOURCE } from '@ohos/imageknife' -export { EngineKeyInterface } from '@ohos/imageknife' -export { EngineKeyFactories } from '@ohos/imageknife' - -/** - * compress - */ -export { CompressBuilder } from '@ohos/imageknife' -export { OnCompressListener } from '@ohos/imageknife' -export { OnRenameListener } from '@ohos/imageknife' -export { CompressDataListener } from '@ohos/imageknife' -export { CompressionPredicate } from '@ohos/imageknife' -export { CompressAdapter } from '@ohos/imageknife' -export { CompressProvider } from '@ohos/imageknife' -export { DataStringPathProvider } from '@ohos/imageknife' -export { RecourseProvider } from '@ohos/imageknife' - -/** - * crop - */ - -export { CropImage } from '@ohos/imageknife' -export { CropOptions } from '@ohos/imageknife' -export { PixelMapCrop,Options } from '@ohos/imageknife' -export { CropCallback } from '@ohos/imageknife' - -/** - * transform - */ -export { BaseTransform } from '@ohos/imageknife' -export { BlurTransformation } from '@ohos/imageknife' -export { BrightnessFilterTransformation } from '@ohos/imageknife' -export { ContrastFilterTransformation } from '@ohos/imageknife' -export { CropCircleTransformation } from '@ohos/imageknife' -export { CropCircleWithBorderTransformation,rgbColor } from '@ohos/imageknife' -export { CropSquareTransformation } from '@ohos/imageknife' -export { CropTransformation,CropType } from '@ohos/imageknife' -export { GrayscaleTransformation } from '@ohos/imageknife' -export { InvertFilterTransformation } from '@ohos/imageknife' -export { PixelationFilterTransformation } from '@ohos/imageknife' -export { RotateImageTransformation } from '@ohos/imageknife' -export { RoundedCornersTransformation,RoundCorner } from '@ohos/imageknife' -export { SepiaFilterTransformation } from '@ohos/imageknife' -export { SketchFilterTransformation } from '@ohos/imageknife' -export { MaskTransformation } from '@ohos/imageknife' -export { SwirlFilterTransformation } from '@ohos/imageknife' -export { KuwaharaFilterTransform } from '@ohos/imageknife' -export { ToonFilterTransform } from '@ohos/imageknife' -export { VignetteFilterTransform } from '@ohos/imageknife' -export { TransformUtils } from '@ohos/imageknife' -export { TransformType } from '@ohos/imageknife' -export { CenterCrop } from '@ohos/imageknife' -export { CenterInside } from '@ohos/imageknife' -export { FitCenter } from '@ohos/imageknife' - -/** - * pngj - */ -export { Pngj } from '@ohos/imageknife' -export {handler} from '@ohos/imageknife' -export { UPNG } from '@ohos/imageknife' - - - -/** - * ImageKnife - */ -export { ImageKnife } from '@ohos/imageknife' -export { ImageKnifeGlobal } from '@ohos/imageknife' -export {RequestOption,Size} from '@ohos/imageknife' -export {ObjectKey} from '@ohos/imageknife' -export { ImageKnifeComponent, ScaleType, ScaleTypeHelper, AntiAliasing, Priority} from '@ohos/imageknife' -export { ImageKnifeDrawFactory } from '@ohos/imageknife' -export {ImageKnifeOption,CropCircleWithBorder,Crop,GifOptions,TransformOptions,HeaderOptions} from '@ohos/imageknife' -export { ImageKnifeData } from '@ohos/imageknife' -export {IAllCacheInfoCallback,AllCacheInfo,ResourceCacheInfo,MemoryCacheInfo,DataCacheInfo} from '@ohos/imageknife' -export {IParseImage} from '@ohos/imageknife' -export {IDataFetch} from '@ohos/imageknife' -export {ICache} from '@ohos/imageknife' -export { FileTypeUtil } from '@ohos/imageknife' -export { ParseImageUtil } from '@ohos/imageknife' - -/** - * svg parse - */ -export { SVGParseImpl } from '@ohos/imageknife' - -/** - * gif parse - */ -export { GIFParseImpl } from '@ohos/imageknife' -export { GIFFrame } from '@ohos/imageknife' - - -// 自定义组件新增 -// 自定义组件绘制生命周期 -export { IDrawLifeCycle } from '@ohos/imageknife' - -// 日志管理 -export { LogUtil } from '@ohos/imageknife' - -// 额外开放初始化ImageKnife的方法 -export {InitImageKnife} from '../ets/pages/InitImageKnife' - -export {GetRes1} from '../ets/pages/GetRes1' \ No newline at end of file diff --git a/sharedlibrary/src/main/ets/pages/GetRes1.ets b/sharedlibrary/src/main/ets/pages/GetRes1.ets deleted file mode 100644 index 6a02910..0000000 --- a/sharedlibrary/src/main/ets/pages/GetRes1.ets +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright (C) 2023 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 common from '@ohos.app.ability.common' - -export class GetRes1{ - static getSample1():Resource { - return $r('app.media.setting'); - } -} \ No newline at end of file diff --git a/sharedlibrary/src/main/ets/pages/Index.ets b/sharedlibrary/src/main/ets/pages/Index.ets deleted file mode 100644 index b34810d..0000000 --- a/sharedlibrary/src/main/ets/pages/Index.ets +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (C) 2023 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 {ImageKnifeGlobal, ImageKnifeComponent, ImageKnifeOption, FileUtils } from '@ohos/imageknife' -import common from '@ohos.app.ability.common' - -@Entry -@Component -struct Index { - - - @State imageOption1:ImageKnifeOption = { - loadSrc: $r('app.media.icon'), - context: getContext(this).createModuleContext('sharedlibrary') as common.UIAbilityContext - } - @State imageOption2:ImageKnifeOption = { - loadSrc: $r('app.media.icon'), - context: getContext(this).createModuleContext('sharedlibrary') as common.UIAbilityContext - } - @State imageOption3:ImageKnifeOption = { - loadSrc: $r('app.media.icon'), - context: getContext(this).createModuleContext('sharedlibrary') as common.UIAbilityContext - } - - build() { - Scroll() { - Column() { - Button('点击加载Resource').onClick(()=>{ - this.imageOption1 = { - loadSrc: $r('app.media.setting'), - // 只要涉及resource加载 在HSP中都要带上context属性 - context: getContext(this).createModuleContext('sharedlibrary') as common.UIAbilityContext - } - }) - ImageKnifeComponent({imageKnifeOption:this.imageOption1}).width(300).height(300).backgroundColor(Color.Pink) - Button('点击加载网络图片').onClick(()=>{ - this.imageOption2 = { - loadSrc: 'https://hbimg.huabanimg.com/cc6af25f8d782d3cf3122bef4e61571378271145735e9-vEVggB', - context: getContext(this).createModuleContext('sharedlibrary') as common.UIAbilityContext - } - }) - ImageKnifeComponent({imageKnifeOption:this.imageOption2}).width(300).height(300).backgroundColor(Color.Pink) - - Button('点击加载本地文件').onClick(()=>{ - getContext(this).createModuleContext('sharedlibrary').resourceManager.getMediaContent($r('app.media.setting').id).then((data:Uint8Array)=>{ - let ctx = ImageKnifeGlobal.getInstance().getHapContext() as common.UIAbilityContext; - let path = ctx.filesDir+"/set.jpeg"; - FileUtils.getInstance().writeFile(path,data.buffer) - FileUtils.getInstance().readFilePicAsync(path).then(buffer=>{ - this.imageOption3 = { - loadSrc: path, - context: getContext(this).createModuleContext('sharedlibrary') as common.UIAbilityContext - } - }) - }) - - }) - ImageKnifeComponent({imageKnifeOption:this.imageOption3}).width(300).height(300).backgroundColor(Color.Pink) - - - - }.width('100%') - - } - .width('100%') - .height('100%') - } -} \ No newline at end of file diff --git a/sharedlibrary/src/main/ets/pages/InitImageKnife.ets b/sharedlibrary/src/main/ets/pages/InitImageKnife.ets deleted file mode 100644 index 05fc782..0000000 --- a/sharedlibrary/src/main/ets/pages/InitImageKnife.ets +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (C) 2023 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 common from '@ohos.app.ability.common' -import { ImageKnifeComponent, ImageKnifeOption, FileUtils } from '@ohos/imageknife' -import { ImageKnifeGlobal,ImageKnife,ImageKnifeDrawFactory,LogUtil } from '@ohos/imageknife' -export class InitImageKnife{ - static init(entryContext:common.UIAbilityContext){ - ImageKnife.with(entryContext); - } -} \ No newline at end of file diff --git a/sharedlibrary/src/main/module.json5 b/sharedlibrary/src/main/module.json5 deleted file mode 100644 index 7e37699..0000000 --- a/sharedlibrary/src/main/module.json5 +++ /dev/null @@ -1,13 +0,0 @@ -{ - "module": { - "name": "sharedlibrary", - "type": "shared", - "description": "$string:shared_desc", - "deviceTypes": [ - "default", - "tablet" - ], - "deliveryWithInstall": true, - "pages": "$profile:main_pages" - } -} \ No newline at end of file diff --git a/sharedlibrary/src/main/resources/base/element/color.json b/sharedlibrary/src/main/resources/base/element/color.json deleted file mode 100644 index 1bbc9aa..0000000 --- a/sharedlibrary/src/main/resources/base/element/color.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "color": [ - { - "name": "white", - "value": "#FFFFFF" - } - ] -} \ No newline at end of file diff --git a/sharedlibrary/src/main/resources/base/element/string.json b/sharedlibrary/src/main/resources/base/element/string.json deleted file mode 100644 index 98e1d8a..0000000 --- a/sharedlibrary/src/main/resources/base/element/string.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "string": [ - { - "name": "shared_desc", - "value": "description" - } - ] -} \ No newline at end of file diff --git a/sharedlibrary/src/main/resources/base/media/icon.png b/sharedlibrary/src/main/resources/base/media/icon.png deleted file mode 100644 index ce307a8..0000000 Binary files a/sharedlibrary/src/main/resources/base/media/icon.png and /dev/null differ diff --git a/sharedlibrary/src/main/resources/base/media/setting.jpeg b/sharedlibrary/src/main/resources/base/media/setting.jpeg deleted file mode 100644 index 57e67dd..0000000 Binary files a/sharedlibrary/src/main/resources/base/media/setting.jpeg and /dev/null differ diff --git a/sharedlibrary/src/main/resources/base/profile/main_pages.json b/sharedlibrary/src/main/resources/base/profile/main_pages.json deleted file mode 100644 index 1898d94..0000000 --- a/sharedlibrary/src/main/resources/base/profile/main_pages.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "src": [ - "pages/Index" - ] -} diff --git a/sharedlibrary2/.gitignore b/sharedlibrary2/.gitignore deleted file mode 100644 index e2713a2..0000000 --- a/sharedlibrary2/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -/node_modules -/oh_modules -/.preview -/build -/.cxx -/.test \ No newline at end of file diff --git a/sharedlibrary2/build-profile.json5 b/sharedlibrary2/build-profile.json5 deleted file mode 100644 index befa101..0000000 --- a/sharedlibrary2/build-profile.json5 +++ /dev/null @@ -1,10 +0,0 @@ -{ - "apiType": 'stageMode', - "buildOption": { - }, - "targets": [ - { - "name": "default" - } - ] -} \ No newline at end of file diff --git a/sharedlibrary2/hvigorfile.ts b/sharedlibrary2/hvigorfile.ts deleted file mode 100644 index 0e65ea8..0000000 --- a/sharedlibrary2/hvigorfile.ts +++ /dev/null @@ -1,2 +0,0 @@ -// Script for compiling build behavior. It is built in the build plug-in and cannot be modified currently. -module.exports = require('@ohos/hvigor-ohos-plugin').hspTasks diff --git a/sharedlibrary2/oh-package.json5 b/sharedlibrary2/oh-package.json5 deleted file mode 100644 index f6d8e3a..0000000 --- a/sharedlibrary2/oh-package.json5 +++ /dev/null @@ -1,11 +0,0 @@ -{ - "license": "Apache-2.0", - "devDependencies": {}, - "author": "", - "name": "sharedlibrary2", - "description": "Please describe the basic information.", - "main": "./src/main/ets/Index.ets", - "version": "1.0.0", - "dependencies": { - } -} diff --git a/sharedlibrary2/src/main/ets/Index.ets b/sharedlibrary2/src/main/ets/Index.ets deleted file mode 100644 index aeba7a3..0000000 --- a/sharedlibrary2/src/main/ets/Index.ets +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (C) 2023 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 {GetRes2} from '../ets/pages/GetRes2' \ No newline at end of file diff --git a/sharedlibrary2/src/main/ets/pages/GetRes2.ets b/sharedlibrary2/src/main/ets/pages/GetRes2.ets deleted file mode 100644 index 36bfdef..0000000 --- a/sharedlibrary2/src/main/ets/pages/GetRes2.ets +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright (C) 2023 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 common from '@ohos.app.ability.common' - -export class GetRes2{ - static getSample2():Resource { - return $r('app.media.icon_loading'); - } -} \ No newline at end of file diff --git a/sharedlibrary2/src/main/ets/pages/Index.ets b/sharedlibrary2/src/main/ets/pages/Index.ets deleted file mode 100644 index f2894ad..0000000 --- a/sharedlibrary2/src/main/ets/pages/Index.ets +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (C) 2023 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. - */ - - -@Entry -@Component -struct Index { - - - build() { - Column(){ - Text('Hello world') - } - } -} \ No newline at end of file diff --git a/sharedlibrary2/src/main/module.json5 b/sharedlibrary2/src/main/module.json5 deleted file mode 100644 index ff37b1a..0000000 --- a/sharedlibrary2/src/main/module.json5 +++ /dev/null @@ -1,13 +0,0 @@ -{ - "module": { - "name": "sharedlibrary2", - "type": "shared", - "description": "$string:shared_desc", - "deviceTypes": [ - "default", - "tablet" - ], - "deliveryWithInstall": true, - "pages": "$profile:main_pages" - } -} \ No newline at end of file diff --git a/sharedlibrary2/src/main/resources/base/element/color.json b/sharedlibrary2/src/main/resources/base/element/color.json deleted file mode 100644 index 1bbc9aa..0000000 --- a/sharedlibrary2/src/main/resources/base/element/color.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "color": [ - { - "name": "white", - "value": "#FFFFFF" - } - ] -} \ No newline at end of file diff --git a/sharedlibrary2/src/main/resources/base/element/string.json b/sharedlibrary2/src/main/resources/base/element/string.json deleted file mode 100644 index 98e1d8a..0000000 --- a/sharedlibrary2/src/main/resources/base/element/string.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "string": [ - { - "name": "shared_desc", - "value": "description" - } - ] -} \ No newline at end of file diff --git a/sharedlibrary2/src/main/resources/base/media/icon_loading.png b/sharedlibrary2/src/main/resources/base/media/icon_loading.png deleted file mode 100644 index 592d50b..0000000 Binary files a/sharedlibrary2/src/main/resources/base/media/icon_loading.png and /dev/null differ diff --git a/sharedlibrary2/src/main/resources/base/profile/main_pages.json b/sharedlibrary2/src/main/resources/base/profile/main_pages.json deleted file mode 100644 index 1898d94..0000000 --- a/sharedlibrary2/src/main/resources/base/profile/main_pages.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "src": [ - "pages/Index" - ] -}