1.Deleting All Files of the Gradle Project
Signed-off-by: zhoulisheng <635547767@qq.com>
This commit is contained in:
parent
fc4545d384
commit
2615ce1d33
|
@ -1,17 +0,0 @@
|
||||||
*.iml
|
|
||||||
.gradle
|
|
||||||
/local.properties
|
|
||||||
/.idea/caches
|
|
||||||
/.idea/libraries
|
|
||||||
/.idea/modules.xml
|
|
||||||
/.idea/workspace.xml
|
|
||||||
/.idea/navEditor.xml
|
|
||||||
/.idea/assetWizardSettings.xml
|
|
||||||
.DS_Store
|
|
||||||
/build
|
|
||||||
/captures
|
|
||||||
.externalNativeBuild
|
|
||||||
/entry/.preview
|
|
||||||
.cxx
|
|
||||||
/node_modules
|
|
||||||
.idea
|
|
201
LICENSE
201
LICENSE
|
@ -1,201 +0,0 @@
|
||||||
Apache License
|
|
||||||
Version 2.0, January 2004
|
|
||||||
http://www.apache.org/licenses/
|
|
||||||
|
|
||||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
||||||
|
|
||||||
1. Definitions.
|
|
||||||
|
|
||||||
"License" shall mean the terms and conditions for use, reproduction,
|
|
||||||
and distribution as defined by Sections 1 through 9 of this document.
|
|
||||||
|
|
||||||
"Licensor" shall mean the copyright owner or entity authorized by
|
|
||||||
the copyright owner that is granting the License.
|
|
||||||
|
|
||||||
"Legal Entity" shall mean the union of the acting entity and all
|
|
||||||
other entities that control, are controlled by, or are under common
|
|
||||||
control with that entity. For the purposes of this definition,
|
|
||||||
"control" means (i) the power, direct or indirect, to cause the
|
|
||||||
direction or management of such entity, whether by contract or
|
|
||||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
||||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
||||||
|
|
||||||
"You" (or "Your") shall mean an individual or Legal Entity
|
|
||||||
exercising permissions granted by this License.
|
|
||||||
|
|
||||||
"Source" form shall mean the preferred form for making modifications,
|
|
||||||
including but not limited to software source code, documentation
|
|
||||||
source, and configuration files.
|
|
||||||
|
|
||||||
"Object" form shall mean any form resulting from mechanical
|
|
||||||
transformation or translation of a Source form, including but
|
|
||||||
not limited to compiled object code, generated documentation,
|
|
||||||
and conversions to other media types.
|
|
||||||
|
|
||||||
"Work" shall mean the work of authorship, whether in Source or
|
|
||||||
Object form, made available under the License, as indicated by a
|
|
||||||
copyright notice that is included in or attached to the work
|
|
||||||
(an example is provided in the Appendix below).
|
|
||||||
|
|
||||||
"Derivative Works" shall mean any work, whether in Source or Object
|
|
||||||
form, that is based on (or derived from) the Work and for which the
|
|
||||||
editorial revisions, annotations, elaborations, or other modifications
|
|
||||||
represent, as a whole, an original work of authorship. For the purposes
|
|
||||||
of this License, Derivative Works shall not include works that remain
|
|
||||||
separable from, or merely link (or bind by name) to the interfaces of,
|
|
||||||
the Work and Derivative Works thereof.
|
|
||||||
|
|
||||||
"Contribution" shall mean any work of authorship, including
|
|
||||||
the original version of the Work and any modifications or additions
|
|
||||||
to that Work or Derivative Works thereof, that is intentionally
|
|
||||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
|
||||||
or by an individual or Legal Entity authorized to submit on behalf of
|
|
||||||
the copyright owner. For the purposes of this definition, "submitted"
|
|
||||||
means any form of electronic, verbal, or written communication sent
|
|
||||||
to the Licensor or its representatives, including but not limited to
|
|
||||||
communication on electronic mailing lists, source code control systems,
|
|
||||||
and issue tracking systems that are managed by, or on behalf of, the
|
|
||||||
Licensor for the purpose of discussing and improving the Work, but
|
|
||||||
excluding communication that is conspicuously marked or otherwise
|
|
||||||
designated in writing by the copyright owner as "Not a Contribution."
|
|
||||||
|
|
||||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
|
||||||
on behalf of whom a Contribution has been received by Licensor and
|
|
||||||
subsequently incorporated within the Work.
|
|
||||||
|
|
||||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
||||||
this License, each Contributor hereby grants to You a perpetual,
|
|
||||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
||||||
copyright license to reproduce, prepare Derivative Works of,
|
|
||||||
publicly display, publicly perform, sublicense, and distribute the
|
|
||||||
Work and such Derivative Works in Source or Object form.
|
|
||||||
|
|
||||||
3. Grant of Patent License. Subject to the terms and conditions of
|
|
||||||
this License, each Contributor hereby grants to You a perpetual,
|
|
||||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
||||||
(except as stated in this section) patent license to make, have made,
|
|
||||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
|
||||||
where such license applies only to those patent claims licensable
|
|
||||||
by such Contributor that are necessarily infringed by their
|
|
||||||
Contribution(s) alone or by combination of their Contribution(s)
|
|
||||||
with the Work to which such Contribution(s) was submitted. If You
|
|
||||||
institute patent litigation against any entity (including a
|
|
||||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
|
||||||
or a Contribution incorporated within the Work constitutes direct
|
|
||||||
or contributory patent infringement, then any patent licenses
|
|
||||||
granted to You under this License for that Work shall terminate
|
|
||||||
as of the date such litigation is filed.
|
|
||||||
|
|
||||||
4. Redistribution. You may reproduce and distribute copies of the
|
|
||||||
Work or Derivative Works thereof in any medium, with or without
|
|
||||||
modifications, and in Source or Object form, provided that You
|
|
||||||
meet the following conditions:
|
|
||||||
|
|
||||||
(a) You must give any other recipients of the Work or
|
|
||||||
Derivative Works a copy of this License; and
|
|
||||||
|
|
||||||
(b) You must cause any modified files to carry prominent notices
|
|
||||||
stating that You changed the files; and
|
|
||||||
|
|
||||||
(c) You must retain, in the Source form of any Derivative Works
|
|
||||||
that You distribute, all copyright, patent, trademark, and
|
|
||||||
attribution notices from the Source form of the Work,
|
|
||||||
excluding those notices that do not pertain to any part of
|
|
||||||
the Derivative Works; and
|
|
||||||
|
|
||||||
(d) If the Work includes a "NOTICE" text file as part of its
|
|
||||||
distribution, then any Derivative Works that You distribute must
|
|
||||||
include a readable copy of the attribution notices contained
|
|
||||||
within such NOTICE file, excluding those notices that do not
|
|
||||||
pertain to any part of the Derivative Works, in at least one
|
|
||||||
of the following places: within a NOTICE text file distributed
|
|
||||||
as part of the Derivative Works; within the Source form or
|
|
||||||
documentation, if provided along with the Derivative Works; or,
|
|
||||||
within a display generated by the Derivative Works, if and
|
|
||||||
wherever such third-party notices normally appear. The contents
|
|
||||||
of the NOTICE file are for informational purposes only and
|
|
||||||
do not modify the License. You may add Your own attribution
|
|
||||||
notices within Derivative Works that You distribute, alongside
|
|
||||||
or as an addendum to the NOTICE text from the Work, provided
|
|
||||||
that such additional attribution notices cannot be construed
|
|
||||||
as modifying the License.
|
|
||||||
|
|
||||||
You may add Your own copyright statement to Your modifications and
|
|
||||||
may provide additional or different license terms and conditions
|
|
||||||
for use, reproduction, or distribution of Your modifications, or
|
|
||||||
for any such Derivative Works as a whole, provided Your use,
|
|
||||||
reproduction, and distribution of the Work otherwise complies with
|
|
||||||
the conditions stated in this License.
|
|
||||||
|
|
||||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
|
||||||
any Contribution intentionally submitted for inclusion in the Work
|
|
||||||
by You to the Licensor shall be under the terms and conditions of
|
|
||||||
this License, without any additional terms or conditions.
|
|
||||||
Notwithstanding the above, nothing herein shall supersede or modify
|
|
||||||
the terms of any separate license agreement you may have executed
|
|
||||||
with Licensor regarding such Contributions.
|
|
||||||
|
|
||||||
6. Trademarks. This License does not grant permission to use the trade
|
|
||||||
names, trademarks, service marks, or product names of the Licensor,
|
|
||||||
except as required for reasonable and customary use in describing the
|
|
||||||
origin of the Work and reproducing the content of the NOTICE file.
|
|
||||||
|
|
||||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
|
||||||
agreed to in writing, Licensor provides the Work (and each
|
|
||||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
||||||
implied, including, without limitation, any warranties or conditions
|
|
||||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
|
||||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
|
||||||
appropriateness of using or redistributing the Work and assume any
|
|
||||||
risks associated with Your exercise of permissions under this License.
|
|
||||||
|
|
||||||
8. Limitation of Liability. In no event and under no legal theory,
|
|
||||||
whether in tort (including negligence), contract, or otherwise,
|
|
||||||
unless required by applicable law (such as deliberate and grossly
|
|
||||||
negligent acts) or agreed to in writing, shall any Contributor be
|
|
||||||
liable to You for damages, including any direct, indirect, special,
|
|
||||||
incidental, or consequential damages of any character arising as a
|
|
||||||
result of this License or out of the use or inability to use the
|
|
||||||
Work (including but not limited to damages for loss of goodwill,
|
|
||||||
work stoppage, computer failure or malfunction, or any and all
|
|
||||||
other commercial damages or losses), even if such Contributor
|
|
||||||
has been advised of the possibility of such damages.
|
|
||||||
|
|
||||||
9. Accepting Warranty or Additional Liability. While redistributing
|
|
||||||
the Work or Derivative Works thereof, You may choose to offer,
|
|
||||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
|
||||||
or other liability obligations and/or rights consistent with this
|
|
||||||
License. However, in accepting such obligations, You may act only
|
|
||||||
on Your own behalf and on Your sole responsibility, not on behalf
|
|
||||||
of any other Contributor, and only if You agree to indemnify,
|
|
||||||
defend, and hold each Contributor harmless for any liability
|
|
||||||
incurred by, or claims asserted against, such Contributor by reason
|
|
||||||
of your accepting any such warranty or additional liability.
|
|
||||||
|
|
||||||
END OF TERMS AND CONDITIONS
|
|
||||||
|
|
||||||
APPENDIX: How to apply the Apache License to your work.
|
|
||||||
|
|
||||||
To apply the Apache License to your work, attach the following
|
|
||||||
boilerplate notice, with the fields enclosed by brackets "{}"
|
|
||||||
replaced with your own identifying information. (Don't include
|
|
||||||
the brackets!) The text should be enclosed in the appropriate
|
|
||||||
comment syntax for the file format. We also recommend that a
|
|
||||||
file or class name and description of purpose be included on the
|
|
||||||
same "printed page" as the copyright notice for easier
|
|
||||||
identification within third-party archives.
|
|
||||||
|
|
||||||
Copyright {yyyy} {name of copyright owner}
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-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.
|
|
|
@ -1,62 +0,0 @@
|
||||||
[
|
|
||||||
{
|
|
||||||
"Name": "glide",
|
|
||||||
"License": "under one or more license",
|
|
||||||
"License File": "https://github.com/bumptech/glide/blob/master/LICENSE",
|
|
||||||
"Version Number": "4.13.1",
|
|
||||||
"Owner" : "bumptech"
|
|
||||||
"Upstream URL": "https://github.com/bumptech/glide",
|
|
||||||
"Description": "An image loading and caching library for Android focused on smooth scrolling"
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
"Name": "glide-transformations",
|
|
||||||
"License": "Apache License 2.0",
|
|
||||||
"License File": "https://github.com/wasabeef/glide-transformations/blob/main/LICENSE",
|
|
||||||
"Version Number": "4.3.0",
|
|
||||||
"Owner" : "wasabeef"
|
|
||||||
"Upstream URL": "https://github.com/wasabeef/glide-transformations",
|
|
||||||
"Description": " An Android transformation library providing a variety of image transformations for Glide. "
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
"Name": "fresco",
|
|
||||||
"License": "MIT License",
|
|
||||||
"License File": "https://github.com/facebook/fresco/blob/main/LICENSE",
|
|
||||||
"Version Number": "2.6.0",
|
|
||||||
"Owner" : "facebook"
|
|
||||||
"Upstream URL": "https://github.com/facebook/fresco",
|
|
||||||
"Description": " An Android library for managing images and the memory they use. "
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
"Name": "UPNG.js",
|
|
||||||
"License": "MIT License",
|
|
||||||
"License File": "https://github.com/photopea/UPNG.js/blob/master/LICENSE",
|
|
||||||
"Version Number": "1.0.0",
|
|
||||||
"Owner" : "photopea"
|
|
||||||
"Upstream URL": "https://github.com/photopea/UPNG.js",
|
|
||||||
"Description": " Fast and advanced PNG (APNG) decoder and encoder (lossy / lossless) "
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
"Name": "Luban",
|
|
||||||
"License": "Apache License 2.0",
|
|
||||||
"License File": "https://github.com/Curzibn/Luban/blob/master/LICENSE",
|
|
||||||
"Version Number": "1.1.8",
|
|
||||||
"Owner" : " Curzibn"
|
|
||||||
"Upstream URL": "https://github.com/Curzibn/Luban",
|
|
||||||
"Description": " Luban(鲁班)—Image compression with efficiency very close to WeChat Moments/可能是最接近微信朋友圈的图片压缩算法 "
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
"Name": "uCrop",
|
|
||||||
"License": "Apache License 2.0",
|
|
||||||
"License File": "https://github.com/Yalantis/uCrop/blob/develop/README.md",
|
|
||||||
"Version Number": "2.2.8",
|
|
||||||
"Owner" : " Yalantis"
|
|
||||||
"Upstream URL": "https://github.com/Yalantis/uCrop",
|
|
||||||
"Description": " Image Cropping Library for Android "
|
|
||||||
}
|
|
||||||
|
|
||||||
]
|
|
331
README.md
331
README.md
|
@ -1,331 +0,0 @@
|
||||||
# ImageKnife
|
|
||||||
|
|
||||||
**专门为OpenHarmony打造的一款图像加载缓存库,致力于更高效、更轻便、更简单**
|
|
||||||
|
|
||||||
## 简介
|
|
||||||
|
|
||||||
本项目基于Android开源库 [Glide](https://github.com/bumptech/glide) 进行OpenHarmony的自研版本
|
|
||||||
|
|
||||||
- 支持内存缓存,使用LRUCache算法,对图片数据进行内存缓存
|
|
||||||
- 支持磁盘缓存,对于下载图片会保存一份至磁盘当中
|
|
||||||
- 支持进行图片变换
|
|
||||||
- 支持用户配置参数使用:(例如:配置是否开启第一级内存缓存,配置磁盘缓存策略,配置仅使用缓存加载数据,配置图片变换效果,配置占位图,配置加载失败占位图等)
|
|
||||||
- 推荐使用GlideImage组件配合GlideOption参数来实现功能
|
|
||||||
- 支持用户自定义配置实现能力参考GlideImage组件中对于入参GlideOption的处理
|
|
||||||
|
|
||||||
## 下载
|
|
||||||
|
|
||||||
1.配置npm仓库地址:@ohos:registry=https://repo.harmonyos.com/npm/
|
|
||||||
|
|
||||||
2.命令行执行:
|
|
||||||
|
|
||||||
npm install @ohos/imageknife
|
|
||||||
|
|
||||||
DevEco Studio 下载:
|
|
||||||
|
|
||||||
https://developer.harmonyos.com/cn/develop/deveco-studio
|
|
||||||
|
|
||||||
## 使用说明
|
|
||||||
|
|
||||||
[跳转至代码示例](##'代码示例')
|
|
||||||
|
|
||||||
## 目录
|
|
||||||
|
|
||||||
```
|
|
||||||
/entry/src/
|
|
||||||
- main/ets/MainAbility
|
|
||||||
- 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算法
|
|
||||||
|
|
||||||
- glide # glide主要内容
|
|
||||||
- compress # 压缩相关
|
|
||||||
- constants # 常量相关
|
|
||||||
- entry # 部分数据结构
|
|
||||||
- holder # 占位图相关解析
|
|
||||||
- interface # 接口相关
|
|
||||||
- networkmanage # 网络相关
|
|
||||||
- pngj # pngj相关
|
|
||||||
- requestmanage # Glide请求相关
|
|
||||||
- resourcemanage # 本地资源解析相关
|
|
||||||
- transform # 图片变换相关
|
|
||||||
- utils # 工具类相关
|
|
||||||
- Glide.ets # Glide门面,app持久化类
|
|
||||||
- GlideData.ets # 数据封装
|
|
||||||
- GlideImage.ets # 自定义控件封装
|
|
||||||
- GlideOption.ets # 用户传参数封装
|
|
||||||
- PixelMapPack.ets # PixelMap封装
|
|
||||||
- RequestOption.ets # 用户设置参数封装
|
|
||||||
|
|
||||||
- pages # 测试page页面列表
|
|
||||||
- basicTestFeatureAbilityPage.ets # 测试元能力
|
|
||||||
- basicTestFileIOPage.ets # 测试fileio
|
|
||||||
- basicTestMediaImage.ets # 测试媒体image
|
|
||||||
- basicTestResourceManagerPage.ets # 测试本地资源解析
|
|
||||||
- CompressPage.ets # 压缩页面
|
|
||||||
- frescoImageTestCasePage.ets # 测试属性动画组件切换
|
|
||||||
- frescoLayerTestCasePage.ets # 测试GlideImage组件切换配合属性动画
|
|
||||||
- frescoRetryTestCasePage.ets # 测试GlideImage加载失败重试
|
|
||||||
- index.ets # 测试页面入口
|
|
||||||
- indexFresco.ets # 二级测试页面入口
|
|
||||||
- loadNetworkTestCasePage.ets # 网络加载测试
|
|
||||||
- loadResourceTestCasePage.ets # 本地加载测试
|
|
||||||
- showErrorholderTestCasePage.ets # 加载失败占位图测试
|
|
||||||
- storageTestDiskLruCache.ets # 磁盘缓存测试
|
|
||||||
- storageTestLruCache.ets # 内存缓存测试
|
|
||||||
- testAllCacheInfoPage.ets # 所有缓存信息获取测试
|
|
||||||
- testAllTypeGlideImagePage.ets # 所有类型图片加载测试
|
|
||||||
- testAllTypeNativeImagePage.ets # 所有类型本地图片加载测试
|
|
||||||
- testGifDontAnimatePage.ets # gif加载静态图片测试
|
|
||||||
- testGlideOptionChangedPage.ets # GlideOption数据切换测试
|
|
||||||
- testGlideOptionChangedPage2.ets # GlideOption数据切换测试
|
|
||||||
- testMultiThreadWorkerPage2.ets # 多线程测试
|
|
||||||
- testPlaceholderPage.ets # 加载占位图测试
|
|
||||||
- testPreloadPage.ets # 预加载测试
|
|
||||||
- testResourceManagerPage.ets # 解析本地资源测试
|
|
||||||
- TransformPixelMapPage.ets # 所有类型变换测试
|
|
||||||
- transformTestCasePage.ets # 所有类型变换配合GlideImage测试
|
|
||||||
|
|
||||||
- workers # 测试worker多线程
|
|
||||||
- worker1.js # worker多线程测试
|
|
||||||
```
|
|
||||||
|
|
||||||
## 接口说明
|
|
||||||
|
|
||||||
### RequestOpton 用户配置参数
|
|
||||||
|
|
||||||
| 方法名 | 入参 | 接口描述 |
|
|
||||||
| ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ |
|
|
||||||
| load(src: string \| PixelMap \| Resource) | string \| PixelMap \| Resource | 待加载图片的资源 |
|
|
||||||
| setImageViewSize(imageSize: { width: number, height: number }) | { width: number, height: number } | 传入显示图片组件的大小,变换的时候需要作为参考 |
|
|
||||||
| diskCacheStrategy(strategy: DiskStrategy) | DiskStrategy | 配置磁盘缓存策略 NONE SOURCE RESULT ALL AUTOMATIC |
|
|
||||||
| placeholder(src: PixelMap \| Resource, func?: AsyncSuccess<PixelMap>) | src: PixelMap \| Resource, func?: AsyncSuccess<PixelMap> | 配置占位图,其中func为数据回调函数 |
|
|
||||||
| errorholder(src: PixelMap \| Resource, func?: AsyncSuccess<PixelMap>) | src: PixelMap \| Resource, func?: AsyncSuccess<PixelMap> | 配置加载失败占位图,其中func为数据回调函数 |
|
|
||||||
| addListener(func: AsyncCallback<PixelMap>) | func: AsyncCallback<PixelMap> | 配置整个监听回调,数据正常加载返回,加载失败返回错误信息 |
|
|
||||||
| thumbnail(sizeMultiplier:number, func?: AsyncSuccess<GlideData>) | sizeMultiplier:number, func?: AsyncSuccess<GlideData> | 设置缩略图比例,缩略图返回后,加载并展示缩略图 |
|
|
||||||
| addProgressListener(func?: AsyncSuccess<string>){ this.progressFunc = func; return this; } | func?: AsyncSuccess<string> | 设置网络下载百分比监听,返回数据加载百分比数值 |
|
|
||||||
| addRetryListener(func?: AsyncSuccess<any>){ this.retryFunc = func; return this; } | func?: AsyncSuccess<any> | 设置重试监听 |
|
|
||||||
| addAllCacheInfoCallback(func: IAllCacheInfoCallback) | func: IAllCacheInfoCallback | 设置获取所有缓存信息监听 |
|
|
||||||
| skipMemoryCache(skip: boolean) | skip: boolean | 配置是否跳过内存缓存 |
|
|
||||||
| retrieveDataFromCache(flag: boolean) | flag: boolean | 配置仅从缓存中加载数据 |
|
|
||||||
| transform(transform: BaseTransform<PixelMap>) | transform: BaseTransform<PixelMap> | 配置自定义变换类型 |
|
|
||||||
| centerCrop(fd: number, out_width: number, out_height: number, callback?: AsyncTransform<Promise<PixelMap>>) | fd: number, out_width: number, out_height: number, callback?: AsyncTransform<Promise<PixelMap>> | 静态方法可以根据图片文件,目标显示大小,进行对应centerCrop |
|
|
||||||
| rotateImage(fd: number, degreesToRotate: number) | fd: number, degreesToRotate: number | 静态方法可以根据图片文件,和旋转角度,进行对应rotateImaroge |
|
|
||||||
| centerInside(fd: number, out_width: number, out_height: number, callback?: AsyncTransform<Promise<PixelMap>>) | fd: number, out_width: number, out_height: number, callback?: AsyncTransform<Promise<PixelMap>> | 静态方法可以根据图片文件,目标显示大小,进行对应centerInside |
|
|
||||||
| fitCenter(fd: number, out_width: number, out_height: number , callback?: AsyncTransform<Promise<PixelMap>>) | fd: number, out_width: number, out_height: number , callback?: AsyncTransform<Promise<PixelMap>> | 静态方法可以根据图片文件,目标显示大小,进行对应fitCenter |
|
|
||||||
|
|
||||||
### Glide 启动器/门面类
|
|
||||||
|
|
||||||
| 方法名 | 入参 | 接口描述 |
|
|
||||||
| ------------------------------- | ---------------------- | ---------------------------------- |
|
|
||||||
| call(request: RequestOption) | request: RequestOption | 根据用户配置参数具体执行加载流程 |
|
|
||||||
| preload(request: RequestOption) | request: RequestOption | 根据用户配置参数具体执行预加载流程 |
|
|
||||||
|
|
||||||
### 缓存策略相关
|
|
||||||
|
|
||||||
| 使用方法 | 类型 | 策略描述 |
|
|
||||||
| ------------------------------------------ | --------- | ---------------------------------------- |
|
|
||||||
| 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 | 表示只缓存转换过后的图片 |
|
|
||||||
|
|
||||||
### 图片变换相关
|
|
||||||
|
|
||||||
| 使用方法 | 类型 | 相关描述 |
|
|
||||||
| ------------------------------------------------------------ | ---------------------------------- | -------------- |
|
|
||||||
| request.transforms(new BlurTransformation()) | BlurTransformation | 模糊处理 |
|
|
||||||
| request.transforms(new BrightnessFilterTransformation()) | BrightnessFilterTransformation | 亮度滤波器 |
|
|
||||||
| request.transforms(new ContrastFilterTransformation()) | ContrastFilterTransformation | 对比度滤波器 |
|
|
||||||
| request.transforms(new CropCircleTransformation()) | CropCircleTransformation | 圆形剪裁显示 |
|
|
||||||
| request.transforms(new CropCircleWithBorderTransformation()) | CropCircleWithBorderTransformation | 圆环展示 |
|
|
||||||
| request.transforms(new CropSquareTransformation()) | CropSquareTransformation | 正方形剪裁 |
|
|
||||||
| request.transforms(new CropTransformation()) | CropTransformation | 自定义矩形剪裁 |
|
|
||||||
| request.transforms(new GrayscaleTransformation()) | GrayscaleTransformation | 灰度级转换 |
|
|
||||||
| request.transforms(new InvertFilterTransformation()) | InvertFilterTransformation | 反转滤波器 |
|
|
||||||
| request.transforms(new PixelationFilterTransformation()) | PixelationFilterTransformation | 像素化滤波器 |
|
|
||||||
| request.transforms(new RotateImageTransformation()) | RotateImageTransformation | 图片旋转 |
|
|
||||||
| request.transforms(new RoundedCornersTransformation()) | RoundedCornersTransformation | 圆角剪裁 |
|
|
||||||
| request.transforms(new SepiaFilterTransformation()) | SepiaFilterTransformation | 乌墨色滤波器 |
|
|
||||||
| request.transforms(new SketchFilterTransformation()) | SketchFilterTransformation | 素描滤波器 |
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## 代码示例
|
|
||||||
|
|
||||||
1.首先初始化全局Glide实例,在app.ets中调用Glide.with()进行初始化
|
|
||||||
|
|
||||||
```
|
|
||||||
import {Glide} from './glide/Glide.ets'
|
|
||||||
export default {
|
|
||||||
data: {
|
|
||||||
glide: {} // Glide全局占位符
|
|
||||||
},
|
|
||||||
onCreate() {
|
|
||||||
this.data.glide = Glide.with();// Glide占位符全局初始化赋值
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
2.在页面index.ets中使用Glide
|
|
||||||
|
|
||||||
```
|
|
||||||
@Entry
|
|
||||||
@Component
|
|
||||||
struct Index {
|
|
||||||
build() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// 页面初始化完成,生命周期回调函数中 进行调用Glide
|
|
||||||
aboutToAppear() {
|
|
||||||
let requestOption = new RequestOption();
|
|
||||||
requestOptin.load($r('app.media.IceCream'))
|
|
||||||
.addListener((err,data) => {
|
|
||||||
//加载成功/失败回调监听
|
|
||||||
})
|
|
||||||
...
|
|
||||||
Glide.call(requestOption)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var Glide;
|
|
||||||
var defaultTemp = globalThis.exports.default
|
|
||||||
if (defaultTemp != undefined) {
|
|
||||||
Glide = defaultTemp.data.glide;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#### 推荐使用:
|
|
||||||
|
|
||||||
使用GlideOption作为入参,配合自定义组件GlideImage使用。
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
@Entry
|
|
||||||
@Component
|
|
||||||
struct Index {
|
|
||||||
@State glideOption1: GlideOption =
|
|
||||||
{
|
|
||||||
loadSrc: "https://thirdwx.qlogo.cn/mmopen/vi_32/DYAIOgq83ericA1Mv66TwicuYOtbDMBcUhv1aa9RJBeAn9uURfcZD0AUGrJebAn1g2AjN0vb2E1XTET7fTuLBNmA/132",
|
|
||||||
size: { width: 300, height: 300 },
|
|
||||||
placeholderSrc: $r('app.media.icon_loading'),
|
|
||||||
errorholderSrc: $r('app.media.icon_failed'),
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
build() {
|
|
||||||
Scroll() {
|
|
||||||
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
|
||||||
GlideImage({ glideOption: $glideOption1 })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.width('100%')
|
|
||||||
.height('100%')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 自定义实现:
|
|
||||||
|
|
||||||
使用原生Image组件,配合用户配置参数实现。
|
|
||||||
|
|
||||||
##### 步骤1:
|
|
||||||
|
|
||||||
定义自定义类
|
|
||||||
export default class PixelMapPack{
|
|
||||||
|
|
||||||
pixelMap:PixelMap;
|
|
||||||
|
|
||||||
}
|
|
||||||
使用@State关联PixelMapPack
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
@State glidePixelMapPack:PixelMapPack = new PixelMapPack();
|
|
||||||
width:number = 200;
|
|
||||||
height:number = 200;
|
|
||||||
```
|
|
||||||
|
|
||||||
##### 步骤2:
|
|
||||||
|
|
||||||
在你的component组件中,写下一个Image组件,将基础参数(入参PixelMap,组件的宽、高)配置好
|
|
||||||
|
|
||||||
```
|
|
||||||
Image(this.glidePixelMapPack.pixelMap)
|
|
||||||
.backgroundColor(Color.Grey)
|
|
||||||
.objectFit(ImageFit.Contain)
|
|
||||||
.width(this.width)
|
|
||||||
.height(this.height)
|
|
||||||
```
|
|
||||||
|
|
||||||
##### 步骤3:
|
|
||||||
|
|
||||||
在aboutToAppear() 函数中调用加载流程
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
//配置参数
|
|
||||||
let requestOptin = new RequestOption();
|
|
||||||
//加载本地图片
|
|
||||||
requestOptin.load($r('app.media.IceCream'))
|
|
||||||
.addListener((err,data) => {
|
|
||||||
//加载成功/失败回调监听
|
|
||||||
})
|
|
||||||
.placeholder( $r('app.media.icon_loading'), (data)=>{
|
|
||||||
// 占位图回调监听
|
|
||||||
})
|
|
||||||
.errorholder(this.glideOption.errorholderSrc, (data)=>{
|
|
||||||
// 失败占位图回调监听
|
|
||||||
})
|
|
||||||
.thumbnail(this.glideOption.thumbSizeMultiplier, (data) => {
|
|
||||||
// 缩略图加载成功回调
|
|
||||||
})
|
|
||||||
// 一定要把控件大小传给RequestOption,图片变换必须
|
|
||||||
.setImageViewSize({width:this.width, height:this.height})
|
|
||||||
// 设置缓存策略
|
|
||||||
.diskCacheStrategy(new Strategy())
|
|
||||||
.addProgressListener((percentValue: string) => {
|
|
||||||
// 图片网络加载进度条百分比回调
|
|
||||||
})
|
|
||||||
.addRetryListener((error: any) => {
|
|
||||||
// 加载失败重试监听 图片加载失败时优先展示重试图层,点击重试图层,会重新进行一次加载流程
|
|
||||||
})
|
|
||||||
.transforms(new RoundedCornersTransformation({top:10}))
|
|
||||||
// 启动加载流程,执行结果将会返回到上面的回调接口中
|
|
||||||
Glide.call(requestOptin);
|
|
||||||
```
|
|
||||||
|
|
||||||
##### 步骤4:
|
|
||||||
|
|
||||||
更多细节设置请参考自定义Component的GlideImage实现
|
|
||||||
|
|
||||||
## 演示
|
|
||||||
|
|
||||||
<img src="screenshot/g3.gif" width="50%"/>
|
|
||||||
|
|
||||||
<img src="screenshot/g1.gif" width="50%"/><img src="screenshot/g2.gif" width="50%"/>
|
|
||||||
|
|
||||||
## 兼容性
|
|
||||||
|
|
||||||
支持OpenHarmony API version 8 及以上版本
|
|
||||||
|
|
||||||
## 开源协议
|
|
||||||
|
|
||||||
[协议详见](https://gitee.com/openharmony-tpc/ImageKnife/blob/master/LICENSE)
|
|
||||||
|
|
||||||
## 贡献代码
|
|
||||||
|
|
||||||
使用过程中发现任何问题都可以提[issue](https://gitee.com/openharmony-tpc/ImageKnife/issues)给我们,当然,我们也非常欢迎你给我们发[PR](https://gitee.com/openharmony-tpc/ImageKnife/issues)
|
|
||||||
|
|
||||||
## 遗留问题
|
|
||||||
|
|
||||||
1.图片变换缓慢(待优化)
|
|
35
build.gradle
35
build.gradle
|
@ -1,35 +0,0 @@
|
||||||
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
|
||||||
apply plugin: 'com.huawei.ohos.app'
|
|
||||||
|
|
||||||
//For instructions on signature configuration, see https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ide_debug_device-0000001053822404#section1112183053510
|
|
||||||
ohos {
|
|
||||||
compileSdkVersion 8
|
|
||||||
supportSystem "standard"
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
buildscript {
|
|
||||||
repositories {
|
|
||||||
maven {
|
|
||||||
url 'https://repo.huaweicloud.com/repository/maven/'
|
|
||||||
}
|
|
||||||
maven {
|
|
||||||
url 'https://developer.huawei.com/repo/'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dependencies {
|
|
||||||
classpath 'com.huawei.ohos:hap:3.0.5.2'
|
|
||||||
classpath 'com.huawei.ohos:decctest:1.2.7.2'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
allprojects {
|
|
||||||
repositories {
|
|
||||||
maven {
|
|
||||||
url 'https://repo.huaweicloud.com/repository/maven/'
|
|
||||||
}
|
|
||||||
maven {
|
|
||||||
url 'https://developer.huawei.com/repo/'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,2 +0,0 @@
|
||||||
/build
|
|
||||||
/node_modules
|
|
|
@ -1,21 +0,0 @@
|
||||||
apply plugin: 'com.huawei.ohos.hap'
|
|
||||||
//For instructions on signature configuration, see https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ide_debug_device-0000001053822404#section1112183053510
|
|
||||||
ohos {
|
|
||||||
compileSdkVersion 8
|
|
||||||
defaultConfig {
|
|
||||||
compatibleSdkVersion 8
|
|
||||||
}
|
|
||||||
buildTypes {
|
|
||||||
release {
|
|
||||||
proguardOpt {
|
|
||||||
proguardEnabled false
|
|
||||||
rulesFiles 'proguard-rules.pro'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
implementation fileTree(dir: 'libs', include: ['*.jar', '*.har'])
|
|
||||||
testImplementation 'junit:junit:4.13.1'
|
|
||||||
}
|
|
|
@ -1 +0,0 @@
|
||||||
# config module specific ProGuard rules here.
|
|
|
@ -1,141 +0,0 @@
|
||||||
{
|
|
||||||
"app": {
|
|
||||||
"bundleName": "com.huawei.mydemoall",
|
|
||||||
"vendor": "huawei",
|
|
||||||
"version": {
|
|
||||||
"code": 1000000,
|
|
||||||
"name": "1.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"deviceConfig": {
|
|
||||||
"default": {
|
|
||||||
"network": {
|
|
||||||
"cleartextTraffic": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"module": {
|
|
||||||
"package": "com.bumptech.glidejs_ohos",
|
|
||||||
"name": ".MyApplication",
|
|
||||||
"mainAbility": ".MainAbility",
|
|
||||||
"srcPath": "",
|
|
||||||
"deviceType": [
|
|
||||||
"phone",
|
|
||||||
"tablet",
|
|
||||||
"default"
|
|
||||||
],
|
|
||||||
"distro": {
|
|
||||||
"deliveryWithInstall": true,
|
|
||||||
"moduleName": "entry",
|
|
||||||
"moduleType": "entry",
|
|
||||||
"installationFree": false
|
|
||||||
},
|
|
||||||
"abilities": [
|
|
||||||
{
|
|
||||||
"skills": [
|
|
||||||
{
|
|
||||||
"entities": [
|
|
||||||
"entity.system.home"
|
|
||||||
],
|
|
||||||
"actions": [
|
|
||||||
"action.system.home"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"orientation": "unspecified",
|
|
||||||
"visible": true,
|
|
||||||
"srcPath": "MainAbility",
|
|
||||||
"name": ".MainAbility",
|
|
||||||
"srcLanguage": "ets",
|
|
||||||
"icon": "$media:icon",
|
|
||||||
"description": "$string:mainability_description",
|
|
||||||
"formsEnabled": false,
|
|
||||||
"label": "$string:GlideJS_OHOS",
|
|
||||||
"type": "page",
|
|
||||||
"launchType": "standard"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"reqPermissions": [
|
|
||||||
{
|
|
||||||
"name": "ohos.permission.READ_USER_STORAGE"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "ohos.permission.INTERNET",
|
|
||||||
"reason": "Api call",
|
|
||||||
"usedScene": {
|
|
||||||
"ability": [
|
|
||||||
"com.zls.glidejscache.MainAbility"
|
|
||||||
],
|
|
||||||
"when": "always"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "ohos.permission.KEEP_BACKGROUND_RUNNING"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "ohos.permission.READ_MEDIA",
|
|
||||||
"reason": "location background",
|
|
||||||
"usedScene": {
|
|
||||||
"when": "always",
|
|
||||||
"ability": [
|
|
||||||
"com.zls.glidejscache.MainAbility"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "ohos.permission.WRITE_MEDIA",
|
|
||||||
"reason": "location background",
|
|
||||||
"usedScene": {
|
|
||||||
"when": "always",
|
|
||||||
"ability": [
|
|
||||||
"com.zls.glidejscache.MainAbility"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"js": [
|
|
||||||
{
|
|
||||||
"mode": {
|
|
||||||
"syntax": "ets",
|
|
||||||
"type": "pageAbility"
|
|
||||||
},
|
|
||||||
"pages": [
|
|
||||||
"pages/index",
|
|
||||||
"pages/indexFresco",
|
|
||||||
"pages/frescoLayerTestCasePage",
|
|
||||||
"pages/frescoImageTestCasePage",
|
|
||||||
"pages/frescoRetryTestCasePage",
|
|
||||||
"pages/basicTestFeatureAbilityPage",
|
|
||||||
"pages/basicTestFileIOPage",
|
|
||||||
"pages/basicTestMediaImage",
|
|
||||||
"pages/basicTestResourceManagerPage",
|
|
||||||
"pages/storageTestLruCache",
|
|
||||||
"pages/storageTestDiskLruCache",
|
|
||||||
"pages/transformTestCasePage",
|
|
||||||
"pages/pngjTestCasePage",
|
|
||||||
"pages/testAllTypeGlideImagePage",
|
|
||||||
"pages/testAllTypeNativeImagePage",
|
|
||||||
"pages/loadResourceTestCasePage",
|
|
||||||
"pages/loadNetworkTestCasePage",
|
|
||||||
"pages/showErrorholderTestCasePage",
|
|
||||||
"pages/TransformPixelMapPage",
|
|
||||||
"pages/testGifDontAnimatePage",
|
|
||||||
"pages/testPreloadPage",
|
|
||||||
"pages/testGlideOptionChangedPage",
|
|
||||||
"pages/testGlideOptionChangedPage2",
|
|
||||||
"pages/CompressPage",
|
|
||||||
"pages/testAllCacheInfoPage",
|
|
||||||
"pages/testResourceManagerPage",
|
|
||||||
"pages/testMultiThreadWorkerPage2",
|
|
||||||
"pages/testGlideOptionChangedPage",
|
|
||||||
"pages/CropImagePage"
|
|
||||||
],
|
|
||||||
"name": ".MainAbility",
|
|
||||||
"window": {
|
|
||||||
"designWidth": 720,
|
|
||||||
"autoDesignWidth": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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 app from '@system.app';
|
|
||||||
|
|
||||||
import {Glide} from './glide/Glide'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
data: {
|
|
||||||
glide: {} // Glide
|
|
||||||
},
|
|
||||||
onCreate() {
|
|
||||||
this.data.glide = Glide.with();
|
|
||||||
app.setImageCacheCount(100);
|
|
||||||
app.setImageRawDataCacheSize(104857600)
|
|
||||||
app.setImageFileCacheSize(209715200)
|
|
||||||
},
|
|
||||||
onDestroy() {
|
|
||||||
|
|
||||||
},
|
|
||||||
}
|
|
|
@ -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 (!this.sInstance) {
|
|
||||||
this.sInstance = new Base64();
|
|
||||||
}
|
|
||||||
return this.sInstance;
|
|
||||||
}
|
|
||||||
|
|
||||||
private constructor() {
|
|
||||||
console.log("Base64 - constructor init!")
|
|
||||||
for (var index = 0; index < this.chars.length; index++) {
|
|
||||||
this.lookup[this.chars.charCodeAt(index)] = index;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
encode(arraybuffer: ArrayBuffer): string {
|
|
||||||
let bytes = new Uint8Array(arraybuffer),
|
|
||||||
i,
|
|
||||||
len = bytes.length,
|
|
||||||
base64 = '';
|
|
||||||
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,
|
|
||||||
i,
|
|
||||||
p = 0,
|
|
||||||
encoded1,
|
|
||||||
encoded2,
|
|
||||||
encoded3,
|
|
||||||
encoded4;
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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 <K, V> {
|
|
||||||
map: Map<K, V> = new Map<K, V>()
|
|
||||||
|
|
||||||
// 获取键对应的值
|
|
||||||
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');
|
|
||||||
}
|
|
||||||
var 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) {
|
|
||||||
this.map.forEach(fn)
|
|
||||||
}
|
|
||||||
// 清除键值对
|
|
||||||
clear() {
|
|
||||||
this.map.clear()
|
|
||||||
}
|
|
||||||
// 遍历key
|
|
||||||
keys(): IterableIterator<K>{
|
|
||||||
return this.map.keys()
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,47 +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 DiskCacheEntry {
|
|
||||||
|
|
||||||
// 缓存的key
|
|
||||||
key: string= ''
|
|
||||||
|
|
||||||
// 缓存文件大小
|
|
||||||
length: number= 0
|
|
||||||
|
|
||||||
constructor(key: string, length?: number) {
|
|
||||||
this.key = key
|
|
||||||
this.length = length
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,317 +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'
|
|
||||||
import {FileUtils} from './FileUtils'
|
|
||||||
import {FileReader} from './FileReader'
|
|
||||||
import {DiskCacheEntry} from './DiskCacheEntry'
|
|
||||||
import fileio from '@ohos.fileio';
|
|
||||||
import featureability from '@ohos.ability.featureAbility'
|
|
||||||
import {Md5} from './Md5'
|
|
||||||
|
|
||||||
export class DiskLruCache {
|
|
||||||
|
|
||||||
// 缓存数据集合
|
|
||||||
cacheMap: CustomMap<string, DiskCacheEntry> = new CustomMap<string, DiskCacheEntry>()
|
|
||||||
fileUtils: FileUtils = FileUtils.getInstance()
|
|
||||||
diskCacheFolder: string = 'GlideDiskCache'
|
|
||||||
|
|
||||||
// 缓存文件路劲地址
|
|
||||||
dirPath: string= ''
|
|
||||||
|
|
||||||
// 缓存数据最大值
|
|
||||||
maxSize: number = 30 * 1024 * 1024
|
|
||||||
|
|
||||||
// 当前缓存数据值
|
|
||||||
size: number = 0
|
|
||||||
|
|
||||||
// 缓存journal文件名称
|
|
||||||
|
|
||||||
journal: string = 'journal'
|
|
||||||
|
|
||||||
// 缓存journal备份文件名称
|
|
||||||
journalTemp: string = 'journal_temp'
|
|
||||||
|
|
||||||
// 缓存journal文件路径
|
|
||||||
journalPath: string = ''
|
|
||||||
|
|
||||||
// 缓存journal备份文件路径
|
|
||||||
journalPathTemp: string = ''
|
|
||||||
|
|
||||||
constructor(maxSize: number, direction?: string) {
|
|
||||||
if (maxSize > 0) {
|
|
||||||
this.maxSize = maxSize
|
|
||||||
}
|
|
||||||
if (!this.isNull(direction)) {
|
|
||||||
if (direction.endsWith('/')) {
|
|
||||||
this.dirPath = direction
|
|
||||||
} else {
|
|
||||||
this.dirPath = direction + '/'
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
featureability.getContext()
|
|
||||||
.getFilesDir()
|
|
||||||
.then((data) => {
|
|
||||||
console.log('DiskLruCache - FileDir= ' + data)
|
|
||||||
let dirPathFolder = data + '/' + this.diskCacheFolder
|
|
||||||
this.dirPath = dirPathFolder;
|
|
||||||
FileUtils.getInstance()
|
|
||||||
.createFolder(dirPathFolder)
|
|
||||||
this.init()
|
|
||||||
})
|
|
||||||
.catch((error) => {
|
|
||||||
console.log('DiskLruCache FileDir Error Cause:' + error.message);
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 初始化缓存文件
|
|
||||||
*/
|
|
||||||
private init() {
|
|
||||||
if (this.dirPath.endsWith('/')) {
|
|
||||||
this.dirPath = this.dirPath
|
|
||||||
} else {
|
|
||||||
this.dirPath = this.dirPath + '/'
|
|
||||||
}
|
|
||||||
this.journalPath = this.dirPath + this.journal
|
|
||||||
this.journalPathTemp = this.dirPath + this.journalTemp
|
|
||||||
try {
|
|
||||||
var stat = fileio.statSync(this.journalPath)
|
|
||||||
if (stat.isFile() && stat.size > 0) {
|
|
||||||
this.fileUtils.createFile(this.journalPathTemp)
|
|
||||||
this.fileUtils.copyFile(this.journalPath, this.journalPathTemp)
|
|
||||||
this.readJournal(this.journalPathTemp)
|
|
||||||
this.resetJournalFile()
|
|
||||||
} else {
|
|
||||||
this.fileUtils.createFile(this.journalPath)
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
console.log('DiskLruCache - init e ' + e)
|
|
||||||
this.fileUtils.createFile(this.journalPath)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 重置journal文件数据
|
|
||||||
*/
|
|
||||||
resetJournalFile(){
|
|
||||||
this.fileUtils.clearFile(this.journalPath)
|
|
||||||
for(let key of this.cacheMap.keys()){
|
|
||||||
this.fileUtils.writeData(this.journalPath, 'save ' + key + '\n')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 读取journal文件的缓存数据
|
|
||||||
*/
|
|
||||||
readJournal(path: string) {
|
|
||||||
var fileReader = new FileReader(path)
|
|
||||||
var line: string = ''
|
|
||||||
while (!fileReader.isEnd()) {
|
|
||||||
line = fileReader.readLine()
|
|
||||||
line = line.replace('\n', '').replace('\r', '')
|
|
||||||
this.dealwithJournal(line)
|
|
||||||
}
|
|
||||||
this.fileUtils.deleteFile(this.journalPathTemp)
|
|
||||||
this.trimToSize()
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 处理journal文件数据
|
|
||||||
*/
|
|
||||||
dealwithJournal(line: string) {
|
|
||||||
var picPath = ''
|
|
||||||
try {
|
|
||||||
var datas = line.split(' ')
|
|
||||||
if (datas.length > 1) {
|
|
||||||
if (datas[0] != 'remove') {
|
|
||||||
picPath = this.dirPath + datas[1]
|
|
||||||
var picstat = fileio.statSync(picPath)
|
|
||||||
if (picstat.isFile() && picstat.size > 0) {
|
|
||||||
this.size = this.size + picstat.size
|
|
||||||
this.fileUtils.writeData(this.journalPath, line + '\n')
|
|
||||||
this.putCacheMap(datas[1], picstat.size)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (this.cacheMap.hasKey(datas[1])) {
|
|
||||||
var cacheEntry: DiskCacheEntry = this.cacheMap.get(datas[1])
|
|
||||||
this.size = this.size - cacheEntry.getLength()
|
|
||||||
this.cacheMap.remove(datas[1])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
console.log('DiskLruCache - dealwithJournal e = ' + e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 设置disk缓存最大数据值
|
|
||||||
*/
|
|
||||||
setMaxSize(max: number) {
|
|
||||||
this.maxSize = max
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 缓存数据map集合
|
|
||||||
*/
|
|
||||||
private putCacheMap(key: string, length?: number) {
|
|
||||||
if (this.cacheMap.hasKey(key)) {
|
|
||||||
this.cacheMap.remove(key)
|
|
||||||
}
|
|
||||||
if (length > 0) {
|
|
||||||
this.cacheMap.put(key, new DiskCacheEntry(key, length))
|
|
||||||
} else {
|
|
||||||
this.cacheMap.put(key, new DiskCacheEntry(key))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 存储disk缓存数据
|
|
||||||
*/
|
|
||||||
putCacheData(key: string, content?: ArrayBuffer, path?: string) {
|
|
||||||
if (key == null) {
|
|
||||||
throw new Error('key is null,checking the parameter');
|
|
||||||
}
|
|
||||||
var fileSize = 0
|
|
||||||
var isvalid: boolean = false
|
|
||||||
key = Md5.hashStr(key)
|
|
||||||
if (content != null && content.byteLength > 0) {
|
|
||||||
isvalid = true
|
|
||||||
var tempPath = this.dirPath + key
|
|
||||||
fileSize = content.byteLength
|
|
||||||
this.fileUtils.writePic(tempPath, content)
|
|
||||||
}
|
|
||||||
if (!this.isNull(path) && this.fileUtils.exist(path)) {
|
|
||||||
isvalid = true
|
|
||||||
fileSize = this.fileUtils.getFileSize(path)
|
|
||||||
this.fileUtils.copyFile(path, this.dirPath + key)
|
|
||||||
}
|
|
||||||
if (isvalid) {
|
|
||||||
this.size = this.size + fileSize
|
|
||||||
this.putCacheMap(key, fileSize)
|
|
||||||
this.fileUtils.writeData(this.journalPath, 'save ' + key + '\n')
|
|
||||||
this.trimToSize()
|
|
||||||
} else {
|
|
||||||
throw ('putCacheData() key or content or path is invalid')
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 根据LRU算法删除多余缓存数据
|
|
||||||
*/
|
|
||||||
private trimToSize() {
|
|
||||||
while (this.size > this.maxSize) {
|
|
||||||
var tempkey: string = this.cacheMap.getFirstKey()
|
|
||||||
var fileSize = this.fileUtils.getFileSize(this.dirPath + tempkey)
|
|
||||||
if (fileSize > 0) {
|
|
||||||
this.size = this.size - fileSize
|
|
||||||
}
|
|
||||||
this.fileUtils.deleteFile(this.dirPath + tempkey)
|
|
||||||
this.cacheMap.remove(tempkey)
|
|
||||||
this.fileUtils.writeData(this.journalPath, 'remove ' + tempkey + '\n')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取key缓存数据
|
|
||||||
*/
|
|
||||||
getCacheDataByKey(key: string): ArrayBuffer{
|
|
||||||
if (key == null) {
|
|
||||||
throw new Error('key is null,checking the parameter');
|
|
||||||
}
|
|
||||||
key = Md5.hashStr(key)
|
|
||||||
var path = this.dirPath + key;
|
|
||||||
if (this.fileUtils.exist(path)) {
|
|
||||||
var ab: ArrayBuffer = this.fileUtils.readFilePic(path)
|
|
||||||
this.putCacheMap(key, ab.byteLength)
|
|
||||||
this.fileUtils.writeData(path, 'read ' + key + '\n')
|
|
||||||
return ab
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取key缓存数据绝对路径
|
|
||||||
*/
|
|
||||||
getCacheFileByKey(key: string): string{
|
|
||||||
if (key == null) {
|
|
||||||
throw new Error('key is null,checking the parameter');
|
|
||||||
}
|
|
||||||
key = Md5.hashStr(key)
|
|
||||||
if (this.dirPath.endsWith('/')) {
|
|
||||||
this.dirPath = this.dirPath
|
|
||||||
} else {
|
|
||||||
this.dirPath = this.dirPath + '/'
|
|
||||||
}
|
|
||||||
var path = this.dirPath + key;
|
|
||||||
if (this.fileUtils.exist(path)) {
|
|
||||||
this.fileUtils.writeData(path, 'read ' + key + '\n')
|
|
||||||
return path
|
|
||||||
} else {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 删除key缓存数据
|
|
||||||
*/
|
|
||||||
deleteCacheDataBykey(key: string): DiskCacheEntry{
|
|
||||||
if (key == null) {
|
|
||||||
throw new Error('key is null,checking the parameter');
|
|
||||||
}
|
|
||||||
key = Md5.hashStr(key)
|
|
||||||
var path = this.dirPath + key;
|
|
||||||
if (this.fileUtils.exist(path)) {
|
|
||||||
var ab = this.fileUtils.readFilePic(path)
|
|
||||||
this.size = this.size - ab.byteLength
|
|
||||||
this.cacheMap.remove(key)
|
|
||||||
this.fileUtils.writeData(this.journalPath, 'remove ' + key + '\n')
|
|
||||||
this.fileUtils.deleteFile(path)
|
|
||||||
}
|
|
||||||
return this.cacheMap.get(key)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 清除所有disk缓存数据
|
|
||||||
*/
|
|
||||||
cleanCacheData() {
|
|
||||||
var length = this.cacheMap.size()
|
|
||||||
for (var index = 0; index < length; index++) {
|
|
||||||
this.fileUtils.deleteFile(this.dirPath + this.cacheMap[index])
|
|
||||||
}
|
|
||||||
this.fileUtils.deleteFile(this.journalPath)
|
|
||||||
this.cacheMap.clear()
|
|
||||||
this.size = 0
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 空字符串判断
|
|
||||||
*/
|
|
||||||
private isNull(str: string): boolean{
|
|
||||||
if (!str || Object.keys(str).length == 0) {
|
|
||||||
return true
|
|
||||||
} else {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
foreachDiskLruCache(fn){
|
|
||||||
this.cacheMap.each(fn)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -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 fileio from '@ohos.fileio';
|
|
||||||
|
|
||||||
export class FileReader {
|
|
||||||
|
|
||||||
// 文件大小
|
|
||||||
fileLength: number = 0
|
|
||||||
|
|
||||||
// 读取的长度
|
|
||||||
length: number = 0
|
|
||||||
|
|
||||||
// 读写stream
|
|
||||||
stream: any = null
|
|
||||||
// 缓存buf
|
|
||||||
buf: ArrayBuffer = new ArrayBuffer(1)
|
|
||||||
|
|
||||||
constructor(path: string) {
|
|
||||||
if (!path || Object.keys(path).length == 0) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
this.stream = fileio.createStreamSync(path, 'r+');
|
|
||||||
var stat = fileio.statSync(path)
|
|
||||||
this.fileLength = stat.size
|
|
||||||
} catch (e) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 循环读取文件数据
|
|
||||||
*/
|
|
||||||
readLine(): string{
|
|
||||||
var line = ''
|
|
||||||
while (this.length <= this.fileLength) {
|
|
||||||
this.stream.readSync(this.buf, { position: this.length })
|
|
||||||
this.length++
|
|
||||||
var temp = String.fromCharCode.apply(null, new Uint8Array(this.buf));
|
|
||||||
line = line + temp
|
|
||||||
if (temp == '\n' || temp == '\r') {
|
|
||||||
return line
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return line
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 判断文件是否结束
|
|
||||||
*/
|
|
||||||
isEnd() {
|
|
||||||
return this.fileLength <= 0 || this.length == this.fileLength
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 关闭stream
|
|
||||||
*/
|
|
||||||
close() {
|
|
||||||
this.stream.closeSync()
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,316 +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 resmgr from '@ohos.resourceManager'
|
|
||||||
import fileio from '@ohos.fileio';
|
|
||||||
|
|
||||||
export class FileUtils {
|
|
||||||
base64Str: string= ''
|
|
||||||
|
|
||||||
private static sInstance: FileUtils;
|
|
||||||
|
|
||||||
public static getInstance(): FileUtils{
|
|
||||||
if (!this.sInstance) {
|
|
||||||
this.sInstance = new FileUtils();
|
|
||||||
}
|
|
||||||
return this.sInstance;
|
|
||||||
}
|
|
||||||
|
|
||||||
private constructor() {
|
|
||||||
console.error("FileUtils - FileUtils constructor")
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 新建文件
|
|
||||||
* @param path 文件绝对路径及文件名
|
|
||||||
* @return number 文件句柄id
|
|
||||||
*/
|
|
||||||
createFile(path: string): number{
|
|
||||||
return fileio.openSync(path, 0o100, 0o666)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 删除文件
|
|
||||||
* @param path 文件绝对路径及文件名
|
|
||||||
*/
|
|
||||||
deleteFile(path: string):void {
|
|
||||||
fileio.unlinkSync(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 同步删除文件目录 必须保证文件夹里面没有文件
|
|
||||||
* @param path 待删除目录的绝对路径
|
|
||||||
*/
|
|
||||||
deleteFolderSync(path: string):void {
|
|
||||||
if (this.existFolder(path)) {
|
|
||||||
fileio.rmdirSync(path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 异步删除文件目录 必须保证文件夹里面没有文件
|
|
||||||
* @param path 待删除目录的绝对路径
|
|
||||||
*/
|
|
||||||
deleteFolderAsync(path: string, deleteComplete, deleteError) {
|
|
||||||
if (this.existFolder(path)) {
|
|
||||||
fileio.rmdir(path)
|
|
||||||
.then(deleteComplete).catch(deleteError);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 拷贝文件
|
|
||||||
* @param path 文件绝对路径及文件名
|
|
||||||
*/
|
|
||||||
copyFile(oriPath: string, newPath: string) {
|
|
||||||
fileio.copyFileSync(oriPath, newPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 清空已有文件数据
|
|
||||||
*/
|
|
||||||
clearFile(path: string):number {
|
|
||||||
return fileio.openSync(path, 0o1000)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 向path写入content数据,覆盖旧数据
|
|
||||||
*/
|
|
||||||
writeFile(path: string, content: ArrayBuffer | string) {
|
|
||||||
try {
|
|
||||||
let fd = fileio.openSync(path, 0o102, 0o666)
|
|
||||||
fileio.ftruncateSync(fd)
|
|
||||||
fileio.writeSync(fd, content)
|
|
||||||
fileio.fsyncSync(fd)
|
|
||||||
fileio.closeSync(fd)
|
|
||||||
} catch (e) {
|
|
||||||
console.log("FileUtils - Failed to writeFile for " + e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 向path写入数据
|
|
||||||
*/
|
|
||||||
writeData(path: string, content: ArrayBuffer | string) {
|
|
||||||
try {
|
|
||||||
console.info("FileUtils - writeData size 1= " + path)
|
|
||||||
let fd = fileio.openSync(path, 0o102, 0o666)
|
|
||||||
console.info("FileUtils - writeData size 2= ")
|
|
||||||
let stat = fileio.statSync(path)
|
|
||||||
console.info("FileUtils - writeData size = " + stat.size)
|
|
||||||
fileio.writeSync(fd, content, { position: stat.size })
|
|
||||||
let length = 0
|
|
||||||
if (content instanceof ArrayBuffer) {
|
|
||||||
length = content.byteLength
|
|
||||||
} else {
|
|
||||||
length = content.length
|
|
||||||
}
|
|
||||||
fileio.closeSync(fd)
|
|
||||||
} catch (e) {
|
|
||||||
console.log("FileUtils - Failed to writeData for " + e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 判断path文件是否存在
|
|
||||||
*/
|
|
||||||
exist(path: string): boolean{
|
|
||||||
try {
|
|
||||||
let stat = fileio.statSync(path)
|
|
||||||
return stat.isFile()
|
|
||||||
} catch (e) {
|
|
||||||
console.debug("FileUtils - fileutils exsit e" + e)
|
|
||||||
console.log("path=>" + path)
|
|
||||||
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 = fileio.statSync(path)
|
|
||||||
return stat.size
|
|
||||||
} catch (e) {
|
|
||||||
console.error("FileUtils - FileUtils getFileSize e " + e)
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 读取路径path的文件
|
|
||||||
*/
|
|
||||||
readFilePic(path: string): ArrayBuffer {
|
|
||||||
try {
|
|
||||||
let stat = fileio.statSync(path)
|
|
||||||
console.info("FileUtils - readFilePic 1")
|
|
||||||
let fd = fileio.openSync(path, 0o2);
|
|
||||||
let length = fileio.statSync(path).size
|
|
||||||
console.info("FileUtils - readFilePic 2 length = " + length)
|
|
||||||
let buf = new ArrayBuffer(length);
|
|
||||||
console.info("FileUtils - readFilePic 3")
|
|
||||||
fileio.readSync(fd, buf)
|
|
||||||
return buf
|
|
||||||
} catch (e) {
|
|
||||||
console.log("FileUtils - readFilePic " + e)
|
|
||||||
return new ArrayBuffer(0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 读取media的资源文件
|
|
||||||
*/
|
|
||||||
readMediaPic() {
|
|
||||||
resmgr.getResourceManager()
|
|
||||||
.then(result => {
|
|
||||||
result.getMediaBase64($r('app.media.icon')
|
|
||||||
.id)
|
|
||||||
.then(data => {
|
|
||||||
console.error("FileUtils - readPic data = " + data)
|
|
||||||
data = data.replace("data:image/png;base64,", "")
|
|
||||||
console.error("FileUtils - readPic this.data = " + data)
|
|
||||||
this.base64Str = data
|
|
||||||
console.error("FileUtils - readPic this.base64Str = " + this.base64Str)
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
console.log("FileUtils - readPic err" + JSON.stringify(err));
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* stream式读取
|
|
||||||
*/
|
|
||||||
readStream(path: string): string {
|
|
||||||
try {
|
|
||||||
let stat = fileio.statSync(path)
|
|
||||||
let length = stat.size
|
|
||||||
let buf = new ArrayBuffer(length);
|
|
||||||
let ss = fileio.createStreamSync(path, "r+");
|
|
||||||
ss.readSync(buf)
|
|
||||||
ss.closeSync();
|
|
||||||
return String.fromCharCode.apply(null, new Uint8Array(buf))
|
|
||||||
} 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 = fileio.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)) {
|
|
||||||
fileio.mkdirSync(path)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 判断文件夹是否存在
|
|
||||||
* @param 文件夹绝对路径
|
|
||||||
*/
|
|
||||||
existFolder(path: string): boolean{
|
|
||||||
try {
|
|
||||||
let stat = fileio.statSync(path)
|
|
||||||
return stat.isDirectory()
|
|
||||||
} catch (e) {
|
|
||||||
console.debug("fileutils folder exsit 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): Uint8Array{
|
|
||||||
var arr = [];
|
|
||||||
for (var i = 0, j = str.length; i < j; ++i) {
|
|
||||||
arr.push(str.charCodeAt(i));
|
|
||||||
}
|
|
||||||
var tmpUint8Array = new Uint8Array(arr);
|
|
||||||
return tmpUint8Array
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* int 转 byte[]
|
|
||||||
* @param n 输入int
|
|
||||||
*/
|
|
||||||
intTobytes2(n) {
|
|
||||||
var bytes = [];
|
|
||||||
for (var i = 0; i < 2; i++) {
|
|
||||||
bytes[i] = n >> (8 - i * 8);
|
|
||||||
}
|
|
||||||
return bytes;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
uint8ArrayToBuffer(array: Uint8Array): ArrayBuffer {
|
|
||||||
return array.buffer.slice(array.byteOffset, array.byteLength + array.byteOffset)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface AsyncCallback<T> {
|
|
||||||
(err: string, data: T): void;
|
|
||||||
}
|
|
|
@ -1,139 +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 <K, V> {
|
|
||||||
maxsize: number = 0
|
|
||||||
size: number = 0;
|
|
||||||
map: CustomMap<K, V> = new CustomMap<K, V>();
|
|
||||||
|
|
||||||
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 ');
|
|
||||||
}
|
|
||||||
var 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');
|
|
||||||
}
|
|
||||||
var preValue = this.map.get(key)
|
|
||||||
if (this.map.remove(key)) {
|
|
||||||
this.size--
|
|
||||||
}
|
|
||||||
return preValue
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取键为key的value
|
|
||||||
get(key: K): V {
|
|
||||||
if (key == null) {
|
|
||||||
throw new Error('key is null,checking the parameter');
|
|
||||||
}
|
|
||||||
var preValue = this.map.get(key)
|
|
||||||
if (preValue != null) {
|
|
||||||
this.entryRemoved(key, preValue, preValue)
|
|
||||||
}
|
|
||||||
return preValue
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 替换或删除对应key键的数据
|
|
||||||
* evicted:是否删除
|
|
||||||
* key:对应的键值key
|
|
||||||
* preValue 对应key键的旧value值
|
|
||||||
* value 对应key键的新value值
|
|
||||||
*/
|
|
||||||
entryRemoved(key: K, preValue: V, value: V) {
|
|
||||||
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
|
|
||||||
}
|
|
||||||
var 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(function (value, key, index) {
|
|
||||||
printResult +='LruCache:key=' + key + 'value= ' + value;
|
|
||||||
})
|
|
||||||
return printResult;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreachLruCache(fn){
|
|
||||||
this.map.each(fn);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,392 +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 Md5 {
|
|
||||||
|
|
||||||
// One time hashing functions
|
|
||||||
public static hashStr(str: string, raw?: false): string
|
|
||||||
|
|
||||||
public static hashStr(str: string, raw: true): Int32Array
|
|
||||||
|
|
||||||
public static hashStr(str: string, raw: boolean = false) {
|
|
||||||
return this.onePassHasher
|
|
||||||
.start()
|
|
||||||
.appendStr(str)
|
|
||||||
.end(raw);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static hashAsciiStr(str: string, raw?: false): string
|
|
||||||
|
|
||||||
public static hashAsciiStr(str: string, raw: true): Int32Array
|
|
||||||
|
|
||||||
public static hashAsciiStr(str: string, raw: boolean = false) {
|
|
||||||
return this.onePassHasher
|
|
||||||
.start()
|
|
||||||
.appendAsciiStr(str)
|
|
||||||
.end(raw);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Private Static Variables
|
|
||||||
private static stateIdentity = new Int32Array([1732584193, -271733879, -1732584194, 271733878]);
|
|
||||||
private static buffer32Identity = new Int32Array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
|
|
||||||
private static hexChars = '0123456789abcdef';
|
|
||||||
private static hexOut: string[] = [];
|
|
||||||
|
|
||||||
// Permanent instance is to use for one-call hashing
|
|
||||||
private static onePassHasher = new Md5();
|
|
||||||
|
|
||||||
private static _hex(x: any): string {
|
|
||||||
const hc = Md5.hexChars;
|
|
||||||
const ho = Md5.hexOut;
|
|
||||||
let n;
|
|
||||||
let offset;
|
|
||||||
let j;
|
|
||||||
let i;
|
|
||||||
|
|
||||||
for (i = 0; i < 4; i += 1) {
|
|
||||||
offset = i * 8;
|
|
||||||
n = x[i];
|
|
||||||
for (j = 0; j < 8; j += 2) {
|
|
||||||
ho[offset + 1 + j] = hc.charAt(n & 0x0F);
|
|
||||||
n >>>= 4;
|
|
||||||
ho[offset + 0 + j] = hc.charAt(n & 0x0F);
|
|
||||||
n >>>= 4;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ho.join('');
|
|
||||||
}
|
|
||||||
|
|
||||||
private static _md5cycle(x: Int32Array | Uint32Array, k: Int32Array | Uint32Array) {
|
|
||||||
let a = x[0];
|
|
||||||
let b = x[1];
|
|
||||||
let c = x[2];
|
|
||||||
let d = x[3];
|
|
||||||
// ff()
|
|
||||||
a += (b & c | ~b & d) + k[0] - 680876936 | 0;
|
|
||||||
a = (a << 7 | a >>> 25) + b | 0;
|
|
||||||
d += (a & b | ~a & c) + k[1] - 389564586 | 0;
|
|
||||||
d = (d << 12 | d >>> 20) + a | 0;
|
|
||||||
c += (d & a | ~d & b) + k[2] + 606105819 | 0;
|
|
||||||
c = (c << 17 | c >>> 15) + d | 0;
|
|
||||||
b += (c & d | ~c & a) + k[3] - 1044525330 | 0;
|
|
||||||
b = (b << 22 | b >>> 10) + c | 0;
|
|
||||||
a += (b & c | ~b & d) + k[4] - 176418897 | 0;
|
|
||||||
a = (a << 7 | a >>> 25) + b | 0;
|
|
||||||
d += (a & b | ~a & c) + k[5] + 1200080426 | 0;
|
|
||||||
d = (d << 12 | d >>> 20) + a | 0;
|
|
||||||
c += (d & a | ~d & b) + k[6] - 1473231341 | 0;
|
|
||||||
c = (c << 17 | c >>> 15) + d | 0;
|
|
||||||
b += (c & d | ~c & a) + k[7] - 45705983 | 0;
|
|
||||||
b = (b << 22 | b >>> 10) + c | 0;
|
|
||||||
a += (b & c | ~b & d) + k[8] + 1770035416 | 0;
|
|
||||||
a = (a << 7 | a >>> 25) + b | 0;
|
|
||||||
d += (a & b | ~a & c) + k[9] - 1958414417 | 0;
|
|
||||||
d = (d << 12 | d >>> 20) + a | 0;
|
|
||||||
c += (d & a | ~d & b) + k[10] - 42063 | 0;
|
|
||||||
c = (c << 17 | c >>> 15) + d | 0;
|
|
||||||
b += (c & d | ~c & a) + k[11] - 1990404162 | 0;
|
|
||||||
b = (b << 22 | b >>> 10) + c | 0;
|
|
||||||
a += (b & c | ~b & d) + k[12] + 1804603682 | 0;
|
|
||||||
a = (a << 7 | a >>> 25) + b | 0;
|
|
||||||
d += (a & b | ~a & c) + k[13] - 40341101 | 0;
|
|
||||||
d = (d << 12 | d >>> 20) + a | 0;
|
|
||||||
c += (d & a | ~d & b) + k[14] - 1502002290 | 0;
|
|
||||||
c = (c << 17 | c >>> 15) + d | 0;
|
|
||||||
b += (c & d | ~c & a) + k[15] + 1236535329 | 0;
|
|
||||||
b = (b << 22 | b >>> 10) + c | 0;
|
|
||||||
// gg()
|
|
||||||
a += (b & d | c & ~d) + k[1] - 165796510 | 0;
|
|
||||||
a = (a << 5 | a >>> 27) + b | 0;
|
|
||||||
d += (a & c | b & ~c) + k[6] - 1069501632 | 0;
|
|
||||||
d = (d << 9 | d >>> 23) + a | 0;
|
|
||||||
c += (d & b | a & ~b) + k[11] + 643717713 | 0;
|
|
||||||
c = (c << 14 | c >>> 18) + d | 0;
|
|
||||||
b += (c & a | d & ~a) + k[0] - 373897302 | 0;
|
|
||||||
b = (b << 20 | b >>> 12) + c | 0;
|
|
||||||
a += (b & d | c & ~d) + k[5] - 701558691 | 0;
|
|
||||||
a = (a << 5 | a >>> 27) + b | 0;
|
|
||||||
d += (a & c | b & ~c) + k[10] + 38016083 | 0;
|
|
||||||
d = (d << 9 | d >>> 23) + a | 0;
|
|
||||||
c += (d & b | a & ~b) + k[15] - 660478335 | 0;
|
|
||||||
c = (c << 14 | c >>> 18) + d | 0;
|
|
||||||
b += (c & a | d & ~a) + k[4] - 405537848 | 0;
|
|
||||||
b = (b << 20 | b >>> 12) + c | 0;
|
|
||||||
a += (b & d | c & ~d) + k[9] + 568446438 | 0;
|
|
||||||
a = (a << 5 | a >>> 27) + b | 0;
|
|
||||||
d += (a & c | b & ~c) + k[14] - 1019803690 | 0;
|
|
||||||
d = (d << 9 | d >>> 23) + a | 0;
|
|
||||||
c += (d & b | a & ~b) + k[3] - 187363961 | 0;
|
|
||||||
c = (c << 14 | c >>> 18) + d | 0;
|
|
||||||
b += (c & a | d & ~a) + k[8] + 1163531501 | 0;
|
|
||||||
b = (b << 20 | b >>> 12) + c | 0;
|
|
||||||
a += (b & d | c & ~d) + k[13] - 1444681467 | 0;
|
|
||||||
a = (a << 5 | a >>> 27) + b | 0;
|
|
||||||
d += (a & c | b & ~c) + k[2] - 51403784 | 0;
|
|
||||||
d = (d << 9 | d >>> 23) + a | 0;
|
|
||||||
c += (d & b | a & ~b) + k[7] + 1735328473 | 0;
|
|
||||||
c = (c << 14 | c >>> 18) + d | 0;
|
|
||||||
b += (c & a | d & ~a) + k[12] - 1926607734 | 0;
|
|
||||||
b = (b << 20 | b >>> 12) + c | 0;
|
|
||||||
// hh()
|
|
||||||
a += (b ^ c ^ d) + k[5] - 378558 | 0;
|
|
||||||
a = (a << 4 | a >>> 28) + b | 0;
|
|
||||||
d += (a ^ b ^ c) + k[8] - 2022574463 | 0;
|
|
||||||
d = (d << 11 | d >>> 21) + a | 0;
|
|
||||||
c += (d ^ a ^ b) + k[11] + 1839030562 | 0;
|
|
||||||
c = (c << 16 | c >>> 16) + d | 0;
|
|
||||||
b += (c ^ d ^ a) + k[14] - 35309556 | 0;
|
|
||||||
b = (b << 23 | b >>> 9) + c | 0;
|
|
||||||
a += (b ^ c ^ d) + k[1] - 1530992060 | 0;
|
|
||||||
a = (a << 4 | a >>> 28) + b | 0;
|
|
||||||
d += (a ^ b ^ c) + k[4] + 1272893353 | 0;
|
|
||||||
d = (d << 11 | d >>> 21) + a | 0;
|
|
||||||
c += (d ^ a ^ b) + k[7] - 155497632 | 0;
|
|
||||||
c = (c << 16 | c >>> 16) + d | 0;
|
|
||||||
b += (c ^ d ^ a) + k[10] - 1094730640 | 0;
|
|
||||||
b = (b << 23 | b >>> 9) + c | 0;
|
|
||||||
a += (b ^ c ^ d) + k[13] + 681279174 | 0;
|
|
||||||
a = (a << 4 | a >>> 28) + b | 0;
|
|
||||||
d += (a ^ b ^ c) + k[0] - 358537222 | 0;
|
|
||||||
d = (d << 11 | d >>> 21) + a | 0;
|
|
||||||
c += (d ^ a ^ b) + k[3] - 722521979 | 0;
|
|
||||||
c = (c << 16 | c >>> 16) + d | 0;
|
|
||||||
b += (c ^ d ^ a) + k[6] + 76029189 | 0;
|
|
||||||
b = (b << 23 | b >>> 9) + c | 0;
|
|
||||||
a += (b ^ c ^ d) + k[9] - 640364487 | 0;
|
|
||||||
a = (a << 4 | a >>> 28) + b | 0;
|
|
||||||
d += (a ^ b ^ c) + k[12] - 421815835 | 0;
|
|
||||||
d = (d << 11 | d >>> 21) + a | 0;
|
|
||||||
c += (d ^ a ^ b) + k[15] + 530742520 | 0;
|
|
||||||
c = (c << 16 | c >>> 16) + d | 0;
|
|
||||||
b += (c ^ d ^ a) + k[2] - 995338651 | 0;
|
|
||||||
b = (b << 23 | b >>> 9) + c | 0;
|
|
||||||
// ii()
|
|
||||||
a += (c ^ (b | ~d)) + k[0] - 198630844 | 0;
|
|
||||||
a = (a << 6 | a >>> 26) + b | 0;
|
|
||||||
d += (b ^ (a | ~c)) + k[7] + 1126891415 | 0;
|
|
||||||
d = (d << 10 | d >>> 22) + a | 0;
|
|
||||||
c += (a ^ (d | ~b)) + k[14] - 1416354905 | 0;
|
|
||||||
c = (c << 15 | c >>> 17) + d | 0;
|
|
||||||
b += (d ^ (c | ~a)) + k[5] - 57434055 | 0;
|
|
||||||
b = (b << 21 | b >>> 11) + c | 0;
|
|
||||||
a += (c ^ (b | ~d)) + k[12] + 1700485571 | 0;
|
|
||||||
a = (a << 6 | a >>> 26) + b | 0;
|
|
||||||
d += (b ^ (a | ~c)) + k[3] - 1894986606 | 0;
|
|
||||||
d = (d << 10 | d >>> 22) + a | 0;
|
|
||||||
c += (a ^ (d | ~b)) + k[10] - 1051523 | 0;
|
|
||||||
c = (c << 15 | c >>> 17) + d | 0;
|
|
||||||
b += (d ^ (c | ~a)) + k[1] - 2054922799 | 0;
|
|
||||||
b = (b << 21 | b >>> 11) + c | 0;
|
|
||||||
a += (c ^ (b | ~d)) + k[8] + 1873313359 | 0;
|
|
||||||
a = (a << 6 | a >>> 26) + b | 0;
|
|
||||||
d += (b ^ (a | ~c)) + k[15] - 30611744 | 0;
|
|
||||||
d = (d << 10 | d >>> 22) + a | 0;
|
|
||||||
c += (a ^ (d | ~b)) + k[6] - 1560198380 | 0;
|
|
||||||
c = (c << 15 | c >>> 17) + d | 0;
|
|
||||||
b += (d ^ (c | ~a)) + k[13] + 1309151649 | 0;
|
|
||||||
b = (b << 21 | b >>> 11) + c | 0;
|
|
||||||
a += (c ^ (b | ~d)) + k[4] - 145523070 | 0;
|
|
||||||
a = (a << 6 | a >>> 26) + b | 0;
|
|
||||||
d += (b ^ (a | ~c)) + k[11] - 1120210379 | 0;
|
|
||||||
d = (d << 10 | d >>> 22) + a | 0;
|
|
||||||
c += (a ^ (d | ~b)) + k[2] + 718787259 | 0;
|
|
||||||
c = (c << 15 | c >>> 17) + d | 0;
|
|
||||||
b += (d ^ (c | ~a)) + k[9] - 343485551 | 0;
|
|
||||||
b = (b << 21 | b >>> 11) + c | 0;
|
|
||||||
|
|
||||||
x[0] = a + x[0] | 0;
|
|
||||||
x[1] = b + x[1] | 0;
|
|
||||||
x[2] = c + x[2] | 0;
|
|
||||||
x[3] = d + x[3] | 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
private _dataLength: number;
|
|
||||||
private _bufferLength: number;
|
|
||||||
private _state: Int32Array = new Int32Array(4);
|
|
||||||
private _buffer: ArrayBuffer = new ArrayBuffer(68);
|
|
||||||
private _buffer8: Uint8Array;
|
|
||||||
private _buffer32: Uint32Array;
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
this._buffer8 = new Uint8Array(this._buffer, 0, 68);
|
|
||||||
this._buffer32 = new Uint32Array(this._buffer, 0, 17);
|
|
||||||
this.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
public start() {
|
|
||||||
this._dataLength = 0;
|
|
||||||
this._bufferLength = 0;
|
|
||||||
this._state.set(Md5.stateIdentity);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Char to code point to to array conversion:
|
|
||||||
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/charCodeAt
|
|
||||||
// #Example.3A_Fixing_charCodeAt_to_handle_non-Basic-Multilingual-Plane_characters_if_their_presence_earlier_in_the_string_is_unknown
|
|
||||||
public appendStr(str: string) {
|
|
||||||
const buf8 = this._buffer8;
|
|
||||||
const buf32 = this._buffer32;
|
|
||||||
let bufLen = this._bufferLength;
|
|
||||||
let code;
|
|
||||||
let i;
|
|
||||||
|
|
||||||
for (i = 0; i < str.length; i += 1) {
|
|
||||||
code = str.charCodeAt(i);
|
|
||||||
if (code < 128) {
|
|
||||||
buf8[bufLen++] = code;
|
|
||||||
} else if (code < 0x800) {
|
|
||||||
buf8[bufLen++] = (code >>> 6) + 0xC0;
|
|
||||||
buf8[bufLen++] = code & 0x3F | 0x80;
|
|
||||||
} else if (code < 0xD800 || code > 0xDBFF) {
|
|
||||||
buf8[bufLen++] = (code >>> 12) + 0xE0;
|
|
||||||
buf8[bufLen++] = (code >>> 6 & 0x3F) | 0x80;
|
|
||||||
buf8[bufLen++] = (code & 0x3F) | 0x80;
|
|
||||||
} else {
|
|
||||||
code = ((code - 0xD800) * 0x400) + (str.charCodeAt(++i) - 0xDC00) + 0x10000;
|
|
||||||
if (code > 0x10FFFF) {
|
|
||||||
throw new Error('Unicode standard supports code points up to U+10FFFF');
|
|
||||||
}
|
|
||||||
buf8[bufLen++] = (code >>> 18) + 0xF0;
|
|
||||||
buf8[bufLen++] = (code >>> 12 & 0x3F) | 0x80;
|
|
||||||
buf8[bufLen++] = (code >>> 6 & 0x3F) | 0x80;
|
|
||||||
buf8[bufLen++] = (code & 0x3F) | 0x80;
|
|
||||||
}
|
|
||||||
if (bufLen >= 64) {
|
|
||||||
this._dataLength += 64;
|
|
||||||
Md5._md5cycle(this._state, buf32);
|
|
||||||
bufLen -= 64;
|
|
||||||
buf32[0] = buf32[16];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this._bufferLength = bufLen;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public appendAsciiStr(str: string) {
|
|
||||||
const buf8 = this._buffer8;
|
|
||||||
const buf32 = this._buffer32;
|
|
||||||
let bufLen = this._bufferLength;
|
|
||||||
let i;
|
|
||||||
let j = 0;
|
|
||||||
|
|
||||||
for (;; ) {
|
|
||||||
i = Math.min(str.length - j, 64 - bufLen);
|
|
||||||
while (i--) {
|
|
||||||
buf8[bufLen++] = str.charCodeAt(j++);
|
|
||||||
}
|
|
||||||
if (bufLen < 64) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
this._dataLength += 64;
|
|
||||||
Md5._md5cycle(this._state, buf32);
|
|
||||||
bufLen = 0;
|
|
||||||
}
|
|
||||||
this._bufferLength = bufLen;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public appendByteArray(input: Uint8Array) {
|
|
||||||
const buf8 = this._buffer8;
|
|
||||||
const buf32 = this._buffer32;
|
|
||||||
let bufLen = this._bufferLength;
|
|
||||||
let i;
|
|
||||||
let j = 0;
|
|
||||||
|
|
||||||
for (;; ) {
|
|
||||||
i = Math.min(input.length - j, 64 - bufLen);
|
|
||||||
while (i--) {
|
|
||||||
buf8[bufLen++] = input[j++];
|
|
||||||
}
|
|
||||||
if (bufLen < 64) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
this._dataLength += 64;
|
|
||||||
Md5._md5cycle(this._state, buf32);
|
|
||||||
bufLen = 0;
|
|
||||||
}
|
|
||||||
this._bufferLength = bufLen;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public getState() {
|
|
||||||
const self = this;
|
|
||||||
const s = self._state;
|
|
||||||
|
|
||||||
return {
|
|
||||||
buffer: String.fromCharCode.apply(null, self._buffer8),
|
|
||||||
buflen: self._bufferLength,
|
|
||||||
length: self._dataLength,
|
|
||||||
state: [s[0], s[1], s[2], s[3]]
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public setState(state: any) {
|
|
||||||
const buf = state.buffer;
|
|
||||||
const x = state.state;
|
|
||||||
const s = this._state;
|
|
||||||
let i;
|
|
||||||
|
|
||||||
this._dataLength = state.length;
|
|
||||||
this._bufferLength = state.buflen;
|
|
||||||
s[0] = x[0];
|
|
||||||
s[1] = x[1];
|
|
||||||
s[2] = x[2];
|
|
||||||
s[3] = x[3];
|
|
||||||
|
|
||||||
for (i = 0; i < buf.length; i += 1) {
|
|
||||||
this._buffer8[i] = buf.charCodeAt(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public end(raw: boolean = false) {
|
|
||||||
const bufLen = this._bufferLength;
|
|
||||||
const buf8 = this._buffer8;
|
|
||||||
const buf32 = this._buffer32;
|
|
||||||
const i = (bufLen >> 2) + 1;
|
|
||||||
let dataBitsLen;
|
|
||||||
|
|
||||||
this._dataLength += bufLen;
|
|
||||||
|
|
||||||
buf8[bufLen] = 0x80;
|
|
||||||
buf8[bufLen + 1] = buf8[bufLen + 2] = buf8[bufLen + 3] = 0;
|
|
||||||
buf32.set(Md5.buffer32Identity.subarray(i), i);
|
|
||||||
|
|
||||||
if (bufLen > 55) {
|
|
||||||
Md5._md5cycle(this._state, buf32);
|
|
||||||
buf32.set(Md5.buffer32Identity);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Do the final computation based on the tail and length
|
|
||||||
// Beware that the final length may not fit in 32 bits so we take care of that
|
|
||||||
dataBitsLen = this._dataLength * 8;
|
|
||||||
if (dataBitsLen <= 0xFFFFFFFF) {
|
|
||||||
buf32[14] = dataBitsLen;
|
|
||||||
} else {
|
|
||||||
const matches = dataBitsLen.toString(16).match(/(.*?)(.{0,8})$/);
|
|
||||||
if (matches === null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const lo = parseInt(matches[2], 16);
|
|
||||||
const hi = parseInt(matches[1], 16) || 0;
|
|
||||||
|
|
||||||
buf32[14] = lo;
|
|
||||||
buf32[15] = hi;
|
|
||||||
}
|
|
||||||
|
|
||||||
Md5._md5cycle(this._state, buf32);
|
|
||||||
|
|
||||||
return raw ? this._state : Md5._hex(this._state);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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,
|
|
||||||
}
|
|
|
@ -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{DataSrc} from "../diskstrategy/DataSrc"
|
|
||||||
import{EncodeStrategy} from "../diskstrategy/EncodeStrategy"
|
|
||||||
|
|
||||||
export interface DiskStrategy {
|
|
||||||
/**
|
|
||||||
* Returns true if this request should cache the original unmodified data.
|
|
||||||
*
|
|
||||||
* @param dataSource Indicates where the data was originally retrieved.
|
|
||||||
* @return boolean
|
|
||||||
*/
|
|
||||||
isDataCacheable(dataSource: DataSrc): boolean
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns true if this request should cache the final transformed resource.
|
|
||||||
*
|
|
||||||
* @param isFromAlternateCacheKey {@code true} if the resource we've decoded was loaded using an
|
|
||||||
* alternative, rather than the primary, cache key.
|
|
||||||
* @param dataSource Indicates where the data used to decode the resource was originally
|
|
||||||
* retrieved.
|
|
||||||
* @param encodeStrategy The {@link EncodeStrategy} the {@link
|
|
||||||
* com.bumptech.glide.load.ResourceEncoder} will use to encode the resource.
|
|
||||||
* @return boolean
|
|
||||||
*/
|
|
||||||
isResourceCacheable(isFromAlternateCacheKey: boolean, dataSource: DataSrc, encodeStrategy: EncodeStrategy): boolean;
|
|
||||||
|
|
||||||
/** Returns true if this request should attempt to decode cached resource data.
|
|
||||||
* @return boolean
|
|
||||||
*/
|
|
||||||
decodeCachedResource(): boolean;
|
|
||||||
|
|
||||||
/** Returns true if this request should attempt to decode cached source data.
|
|
||||||
* @return boolean
|
|
||||||
*/
|
|
||||||
decodeCachedData(): boolean;
|
|
||||||
|
|
||||||
getName(): string;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -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,
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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 {Key} from "../key/Key"
|
|
||||||
import {RequestOption} from '../../glide/RequestOption'
|
|
||||||
|
|
||||||
export class EngineKey implements Key {
|
|
||||||
private request: RequestOption;
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
request
|
|
||||||
) {
|
|
||||||
this.request = request;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 内存缓存 缓存生成规则:是否会影响图片内容,不影响则通用(strategy onlyRetrieveFromCache isCacheable)为通用项目
|
|
||||||
// 生成规则 加载数据原 各类参数(排除监听 排除 占位图 失败占位图)
|
|
||||||
generateCacheKey(): string{
|
|
||||||
let loadSrc = JSON.stringify(this.request.loadSrc);
|
|
||||||
let size = JSON.stringify(this.request.size);
|
|
||||||
|
|
||||||
let transformations;
|
|
||||||
for (let i = 0; i < this.request.transformtions.length; i++) {
|
|
||||||
if (i == 0) {
|
|
||||||
transformations = this.request.transformtions[i].getName() + ",";
|
|
||||||
} else if (i == this.request.transformtions.length - 1) {
|
|
||||||
transformations += this.request.transformtions[i].getName() + "";
|
|
||||||
} else {
|
|
||||||
transformations += this.request.transformtions[i].getName() + ",";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let dontAnimateFlag = JSON.stringify(this.request.dontAnimateFlag);
|
|
||||||
let key = "loadSrc=" + loadSrc + ";" +
|
|
||||||
"size=" + size + ";" +
|
|
||||||
"transformations=" + transformations + ";" +
|
|
||||||
"dontAnimateFlag=" + dontAnimateFlag + ";"
|
|
||||||
return key;
|
|
||||||
}
|
|
||||||
// 磁盘缓存 缓存生成规则:是否会影响图片内容,不影响则通用(strategy onlyRetrieveFromCache isCacheable)为通用项目
|
|
||||||
// 生成规则 加载数据原 各类参数(排除监听 排除 占位图 失败占位图)
|
|
||||||
generateResourceKey(): string{
|
|
||||||
let loadSrc = JSON.stringify(this.request.loadSrc);
|
|
||||||
let size = JSON.stringify(this.request.size);
|
|
||||||
|
|
||||||
let transformations;
|
|
||||||
for (let i = 0; i < this.request.transformtions.length; i++) {
|
|
||||||
if (i == this.request.transformtions.length - 1) {
|
|
||||||
transformations += this.request.transformtions[i].getName() + "";
|
|
||||||
} else {
|
|
||||||
transformations += this.request.transformtions[i].getName() + ",";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let dontAnimateFlag = JSON.stringify(this.request.dontAnimateFlag);
|
|
||||||
let key = "loadSrc=" + loadSrc + ";" +
|
|
||||||
"size=" + size + ";" +
|
|
||||||
"transformations=" + transformations + ";" +
|
|
||||||
"dontAnimateFlag=" + dontAnimateFlag + ";"
|
|
||||||
|
|
||||||
return key;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 磁盘缓存
|
|
||||||
// 生成网络加载数据 原始数据存于磁盘的key
|
|
||||||
generateDataKey(): string{
|
|
||||||
let loadSrc = JSON.stringify(this.request.loadSrc);
|
|
||||||
let key = "loadSrc=" + loadSrc + ";"
|
|
||||||
return key;
|
|
||||||
}
|
|
||||||
|
|
||||||
updateDiskCacheKey(info: Object) {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,38 +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'
|
|
||||||
|
|
||||||
export class EngineKeyFactories {
|
|
||||||
buildCacheKey(
|
|
||||||
request) {
|
|
||||||
return new EngineKey(
|
|
||||||
request).generateCacheKey();
|
|
||||||
}
|
|
||||||
|
|
||||||
buildDataKey(
|
|
||||||
request
|
|
||||||
) {
|
|
||||||
return new EngineKey(request).generateDataKey()
|
|
||||||
}
|
|
||||||
|
|
||||||
buildResourceKey(
|
|
||||||
request
|
|
||||||
) {
|
|
||||||
return new EngineKey(request).generateResourceKey()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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.
|
|
||||||
*
|
|
||||||
* <p>Note - Using {@link MessageDigest#reset()} inside of this method will result
|
|
||||||
* in undefined behavior.
|
|
||||||
* @param messageDigest
|
|
||||||
*/
|
|
||||||
updateDiskCacheKey(info: Object);
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,407 +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 {LruCache} from "../cache/LruCache"
|
|
||||||
import {EngineKey} from "../cache/key/EngineKey"
|
|
||||||
import {EngineKeyFactories} from "../cache/key/EngineKeyFactories"
|
|
||||||
import {DiskStrategy} from "../cache/diskstrategy/DiskStrategy"
|
|
||||||
import {ResourceTypeEts} from "../glide/constants/ResourceTypeEts"
|
|
||||||
import {RequestOption} from "../glide/RequestOption"
|
|
||||||
import {AsyncCallback} from "../glide/interface/asynccallback"
|
|
||||||
import {PlaceHolderManager} from "../glide/holder/PlaceHolderManager"
|
|
||||||
import {ErrorHolderManager} from "../glide/holder/ErrorHolderManager"
|
|
||||||
import {RequestManager} from "../glide/requestmanage/RequstManager"
|
|
||||||
import {NONE} from "../cache/diskstrategy/enum/NONE"
|
|
||||||
import {FileTypeUtil} from '../glide/utils/FileTypeUtil'
|
|
||||||
import {DownloadClient} from '../glide/networkmanage/DownloadClient'
|
|
||||||
import {IDataFetch} from '../glide/networkmanage/IDataFetch'
|
|
||||||
import {ParseResClient} from '../glide/resourcemanage/ParseResClient'
|
|
||||||
import {IResourceFetch} from '../glide/resourcemanage/IResourceFetch'
|
|
||||||
import {GlideData} from '../glide/GlideData'
|
|
||||||
import {FileUtils} from '../cache/FileUtils'
|
|
||||||
import {FileReader} from '../cache/FileReader'
|
|
||||||
import {GlideOption} from '../glide/GlideOption'
|
|
||||||
import image from "@ohos.multimedia.image"
|
|
||||||
import featureAbility from '@ohos.ability.featureAbility';
|
|
||||||
import {CompressBuilder} from "../glide/compress/CompressBuilder"
|
|
||||||
|
|
||||||
export class Glide {
|
|
||||||
private memoryCache: LruCache<string, any>;
|
|
||||||
private diskMemoryCache: DiskLruCache;
|
|
||||||
private dataFetch: IDataFetch;
|
|
||||||
private resourceFetch: IResourceFetch;
|
|
||||||
private filesPath: string = ""; // data/data/包名/files目录
|
|
||||||
|
|
||||||
|
|
||||||
private placeholderCache: string = "placeholderCache"
|
|
||||||
private runningRequest: Array<RequestOption>;
|
|
||||||
private pendingRequest: Array<RequestOption>;
|
|
||||||
private fileTypeUtil: FileTypeUtil; // 通用文件格式辨别
|
|
||||||
private svgAndGifFolder: string = "svgAndGifFolder"; // svg和gif的文件路径地址
|
|
||||||
private svgAndGifCommitFile: string = "svgAndGifCommitFile" // svg和gif提交记录
|
|
||||||
|
|
||||||
private defaultListener:AsyncCallback<GlideData>; // 全局监听器
|
|
||||||
|
|
||||||
getMemoryCache(): LruCache<string, any>{
|
|
||||||
return this.memoryCache;
|
|
||||||
}
|
|
||||||
|
|
||||||
setMemoryCache(lrucache: LruCache<string, any>){
|
|
||||||
this.memoryCache = lrucache;
|
|
||||||
}
|
|
||||||
|
|
||||||
getDiskMemoryCache(): DiskLruCache{
|
|
||||||
return this.diskMemoryCache;
|
|
||||||
};
|
|
||||||
|
|
||||||
setDiskMemoryCache(diskLruCache: DiskLruCache) {
|
|
||||||
this.diskMemoryCache = diskLruCache;
|
|
||||||
};
|
|
||||||
|
|
||||||
getFileTypeUtil(): FileTypeUtil{
|
|
||||||
return this.fileTypeUtil;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
getSvgAndGifFolder(): string{
|
|
||||||
return this.svgAndGifFolder;
|
|
||||||
}
|
|
||||||
|
|
||||||
setSvgAndGifFolder(folderPath: string){
|
|
||||||
this.svgAndGifFolder = folderPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
getDefaultListener(){
|
|
||||||
return this.defaultListener;
|
|
||||||
}
|
|
||||||
|
|
||||||
setDefaultListener(newDefaultListener:AsyncCallback<GlideData>){
|
|
||||||
this.defaultListener = newDefaultListener;
|
|
||||||
}
|
|
||||||
|
|
||||||
private constructor() {
|
|
||||||
|
|
||||||
// 构造方法传入size 为保存文件个数
|
|
||||||
this.memoryCache = new LruCache<string, any>(100);
|
|
||||||
|
|
||||||
// 创建disk缓存 传入的size 为多少比特 比如20KB 传入20*1024
|
|
||||||
this.diskMemoryCache = new DiskLruCache(30 * 1024 * 1024);
|
|
||||||
|
|
||||||
// 创建网络下载能力
|
|
||||||
this.dataFetch = new DownloadClient();
|
|
||||||
|
|
||||||
// 创建本地数据解析能力
|
|
||||||
this.resourceFetch = new ParseResClient();
|
|
||||||
|
|
||||||
// 初始化本地 文件保存
|
|
||||||
featureAbility.getContext()
|
|
||||||
.getFilesDir()
|
|
||||||
.then((data) => {
|
|
||||||
this.filesPath = data
|
|
||||||
this.initSvgAndGifEnvironment();
|
|
||||||
})
|
|
||||||
.catch((error) => {
|
|
||||||
console.error('Glide Failed to obtain the filesPath directory. Cause:' + error.message);
|
|
||||||
})
|
|
||||||
|
|
||||||
this.runningRequest = new Array();
|
|
||||||
this.pendingRequest = new Array();
|
|
||||||
|
|
||||||
// 通用文件格式识别初始化
|
|
||||||
this.fileTypeUtil = new FileTypeUtil();
|
|
||||||
}
|
|
||||||
|
|
||||||
private initSvgAndGifEnvironment() {
|
|
||||||
let folderExist = FileUtils.getInstance().existFolder(this.filesPath + "/" + this.svgAndGifFolder)
|
|
||||||
let fileExist =
|
|
||||||
FileUtils.getInstance()
|
|
||||||
.exist(this.filesPath + "/" + this.svgAndGifFolder + "/" + this.svgAndGifCommitFile)
|
|
||||||
if (folderExist && fileExist) {
|
|
||||||
// 创建完成,需要删除上次使用的文件
|
|
||||||
var fileReader = new FileReader(this.filesPath + "/" + this.svgAndGifFolder + "/" + this.svgAndGifCommitFile)
|
|
||||||
var line: string = ''
|
|
||||||
while (!fileReader.isEnd()) {
|
|
||||||
line = fileReader.readLine()
|
|
||||||
line = line.replace('\n', "").replace('\r', "")
|
|
||||||
FileUtils.getInstance().deleteFile(this.filesPath + "/" + this.svgAndGifFolder + "/" + line)
|
|
||||||
}
|
|
||||||
FileUtils.getInstance().clearFile(this.filesPath + "/" + this.svgAndGifFolder + "/" + this.svgAndGifCommitFile)
|
|
||||||
} else {
|
|
||||||
if (!folderExist) {
|
|
||||||
FileUtils.getInstance().createFolder(this.filesPath + "/" + this.svgAndGifFolder);
|
|
||||||
}
|
|
||||||
if (!fileExist) {
|
|
||||||
FileUtils.getInstance().createFile(this.filesPath + "/" + this.svgAndGifFolder + "/" + this.svgAndGifCommitFile)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private static sInstance: Glide;
|
|
||||||
|
|
||||||
public static with(): Glide{
|
|
||||||
if (!this.sInstance) {
|
|
||||||
this.sInstance = new Glide();
|
|
||||||
}
|
|
||||||
return this.sInstance;
|
|
||||||
}
|
|
||||||
|
|
||||||
public compressBuilder(): CompressBuilder{
|
|
||||||
return new CompressBuilder();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 替代原来的LruCache
|
|
||||||
public replaceLruCache(size:number){
|
|
||||||
if(this.memoryCache.map.size() <= 0) {
|
|
||||||
this.memoryCache = new LruCache<string, any>(size);
|
|
||||||
}else{
|
|
||||||
let newLruCache = new LruCache<string, any>(size);
|
|
||||||
this.memoryCache.foreachLruCache(function (value, key, map) {
|
|
||||||
newLruCache.put(key, value);
|
|
||||||
})
|
|
||||||
this.memoryCache = newLruCache;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public replaceDataFetch(fetch:IDataFetch){
|
|
||||||
this.dataFetch = fetch;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 替代原来的DiskLruCache
|
|
||||||
public replaceDiskLruCache(size:number){
|
|
||||||
this.diskMemoryCache = new DiskLruCache(size);
|
|
||||||
|
|
||||||
if(this.diskMemoryCache.cacheMap.size() <= 0) {
|
|
||||||
this.diskMemoryCache = new DiskLruCache(size);
|
|
||||||
}else{
|
|
||||||
let newDiskLruCache = new DiskLruCache(size);
|
|
||||||
this.diskMemoryCache.foreachDiskLruCache(function (value, key, map) {
|
|
||||||
newDiskLruCache.putCacheData(key, value, null);
|
|
||||||
})
|
|
||||||
this.diskMemoryCache = newDiskLruCache;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 预加载 resource资源一级缓存,string资源实现二级缓存
|
|
||||||
preload(request: RequestOption) {
|
|
||||||
// 每个request 公共信息补充
|
|
||||||
request.setFilesPath(this.filesPath);
|
|
||||||
// svg特殊处理
|
|
||||||
request._svgAndGifFolder = this.svgAndGifFolder;
|
|
||||||
request._svgAndGifCommitFile = this.svgAndGifCommitFile;
|
|
||||||
return this.parseSource(request);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 正常加载
|
|
||||||
call(request: RequestOption) {
|
|
||||||
console.log("Glide call")
|
|
||||||
// 添加全局监听
|
|
||||||
if(this.defaultListener) {
|
|
||||||
request.addListener(this.defaultListener)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 每个request 公共信息补充
|
|
||||||
request.setFilesPath(this.filesPath);
|
|
||||||
|
|
||||||
// svg特殊处理
|
|
||||||
request._svgAndGifFolder = this.svgAndGifFolder;
|
|
||||||
request._svgAndGifCommitFile = this.svgAndGifCommitFile;
|
|
||||||
|
|
||||||
// 首先执行占位图 解析任务
|
|
||||||
if (request.placeholderSrc) {
|
|
||||||
PlaceHolderManager.execute(request)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 其次解析错误占位图
|
|
||||||
if (request.errorholderSrc) {
|
|
||||||
ErrorHolderManager.execute(request)
|
|
||||||
}
|
|
||||||
return this.parseSource(request);
|
|
||||||
}
|
|
||||||
|
|
||||||
loadResources(request: RequestOption) {
|
|
||||||
console.log("Glide loadResources")
|
|
||||||
let factories = new EngineKeyFactories();
|
|
||||||
|
|
||||||
// 生成内存缓存key 内存 变换后磁盘
|
|
||||||
let cacheKey = factories.buildCacheKey(request);
|
|
||||||
|
|
||||||
// 生成磁盘缓存变换后数据key 变换后数据保存在磁盘
|
|
||||||
let transfromKey = factories.buildResourceKey(request);
|
|
||||||
|
|
||||||
// 生成磁盘缓存源数据key 原始数据保存在磁盘
|
|
||||||
let dataKey = factories.buildDataKey(request);
|
|
||||||
|
|
||||||
request.generateCacheKey = cacheKey;
|
|
||||||
request.generateResourceKey = transfromKey;
|
|
||||||
request.generateDataKey = dataKey;
|
|
||||||
this.loadCacheManager(request);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 删除执行结束的running
|
|
||||||
removeRunning(request: RequestOption) {
|
|
||||||
let index = -1;
|
|
||||||
for (let i = 0; i < this.runningRequest.length; i++) {
|
|
||||||
let tempRunning = this.runningRequest[i];
|
|
||||||
if (this.keyEqual(request, tempRunning)) {
|
|
||||||
// 如果key相同 说明目前有任务正在执行,我们记录下当前request 放入pendingRunning
|
|
||||||
index = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (index >= 0) {
|
|
||||||
let request = this.runningRequest.splice(index, 1)[0];
|
|
||||||
this.loadNextPennding(request);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
keyEqualPendingToRun(index:number){
|
|
||||||
let nextPending = this.pendingRequest.splice(index, 1)[0];
|
|
||||||
this.runningRequest.push(nextPending)
|
|
||||||
RequestManager.execute((nextPending as RequestOption), this.memoryCache, this.diskMemoryCache, this.dataFetch, this.resourceFetch)
|
|
||||||
}
|
|
||||||
|
|
||||||
searchNextKeyToRun(){
|
|
||||||
// 其次则寻找pending中第一个和running不重复的key
|
|
||||||
let index2 = -1;
|
|
||||||
for (let i = 0; i < this.pendingRequest.length; i++) {
|
|
||||||
let temppending = this.pendingRequest[i];
|
|
||||||
let hasKeyEqual = false;
|
|
||||||
for (let j = 0; j < this.runningRequest.length; j++) {
|
|
||||||
let temprunning = this.runningRequest[j];
|
|
||||||
if (this.keyEqual(temppending, temprunning)) {
|
|
||||||
hasKeyEqual = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!hasKeyEqual) {
|
|
||||||
index2 = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (index2 >= 0) {
|
|
||||||
let nextPending = this.pendingRequest.splice(index2, 1)[0];
|
|
||||||
this.runningRequest.push(nextPending)
|
|
||||||
RequestManager.execute((nextPending as RequestOption), this.memoryCache, this.diskMemoryCache, this.dataFetch, this.resourceFetch)
|
|
||||||
} else {
|
|
||||||
// 不执行
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// 加载下一个key的请求
|
|
||||||
loadNextPennding(request) {
|
|
||||||
// 首先寻找被移除key相同的request
|
|
||||||
let index = -1;
|
|
||||||
for (let i = 0; i < this.pendingRequest.length; i++) {
|
|
||||||
let temppending = this.pendingRequest[i];
|
|
||||||
if (this.keyEqual(request, temppending)) {
|
|
||||||
// 如果key相同 说明目前有任务正在执行,我们记录下当前request 放入pendingRunning
|
|
||||||
index = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (index >= 0) {
|
|
||||||
this.keyEqualPendingToRun(index);
|
|
||||||
} else {
|
|
||||||
this.searchNextKeyToRun();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 启动新线程 去磁盘取 去网络取
|
|
||||||
loadCacheManager(request: RequestOption) {
|
|
||||||
console.log("Glide loadCacheManager")
|
|
||||||
if (this.keyNotEmpty(request)) {
|
|
||||||
let hasRunningRequest = false;
|
|
||||||
for (let i = 0; i < this.runningRequest.length; i++) {
|
|
||||||
let tempRunning = this.runningRequest[i];
|
|
||||||
if (this.keyEqual(request, tempRunning)) {
|
|
||||||
|
|
||||||
// 如果key相同 说明目前有任务正在执行,我们记录下当前request 放入pendingRunning
|
|
||||||
hasRunningRequest = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (hasRunningRequest) {
|
|
||||||
this.pendingRequest.push(request);
|
|
||||||
} else {
|
|
||||||
this.runningRequest.push(request);
|
|
||||||
|
|
||||||
// 不存在相同key的 任务可以并行
|
|
||||||
RequestManager.execute(request, this.memoryCache, this.diskMemoryCache, this.dataFetch, this.resourceFetch)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
console.log("key没有生成无法进入存取!")
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
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{
|
|
||||||
if (
|
|
||||||
request1.generateCacheKey == request2.generateCacheKey &&
|
|
||||||
request1.generateResourceKey == request2.generateResourceKey &&
|
|
||||||
request1.generateDataKey == request2.generateDataKey
|
|
||||||
) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
parseSource(request: RequestOption) {
|
|
||||||
console.log("Glide parseSource")
|
|
||||||
console.log("Glide request ="+JSON.stringify(request))
|
|
||||||
if (request.loadSrc instanceof image.PixelMap) {
|
|
||||||
console.log("Glide parseSource PixelMap")
|
|
||||||
let glidedata = new GlideData();
|
|
||||||
glidedata.glideType = GlideData.PIXELMAP
|
|
||||||
glidedata.glideValue = request.loadSrc as PixelMap
|
|
||||||
request.loadComplete(glidedata);
|
|
||||||
} else
|
|
||||||
if (typeof request.loadSrc == 'string') {
|
|
||||||
// 进入三级缓存模型
|
|
||||||
console.log("Glide parseSource string")
|
|
||||||
return this.loadResources(request);
|
|
||||||
} else {
|
|
||||||
console.log("Glide parseSource Resource")
|
|
||||||
let res = request.loadSrc as Resource;
|
|
||||||
console.log("Glide parseSource res="+JSON.stringify(res))
|
|
||||||
if (typeof res.id != 'undefined' && typeof res.type != 'undefined') {
|
|
||||||
//进入三级缓存模型 本地资源不参与磁盘缓存
|
|
||||||
let none = new NONE();
|
|
||||||
request.diskCacheStrategy(none);
|
|
||||||
this.loadResources(request);
|
|
||||||
} else {
|
|
||||||
console.error("输入参数有问题!")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,74 +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 GlideData {
|
|
||||||
|
|
||||||
static PIXELMAP = 'PixelMap'
|
|
||||||
static STRING = 'string'
|
|
||||||
static RESOURCE ='Resource'
|
|
||||||
|
|
||||||
static SVG = 'svg';
|
|
||||||
static GIF = 'gif';
|
|
||||||
static JPG = 'jpg';
|
|
||||||
static PNG = 'png';
|
|
||||||
static BMP = 'bmp';
|
|
||||||
static WEBP = 'webp';
|
|
||||||
|
|
||||||
|
|
||||||
glideType:string = '';
|
|
||||||
glideValue:PixelMap|string|Resource;
|
|
||||||
glideSourceType:string = ''
|
|
||||||
|
|
||||||
isSvg():boolean{
|
|
||||||
return GlideData.SVG == this.glideSourceType;
|
|
||||||
}
|
|
||||||
|
|
||||||
isGif():boolean{
|
|
||||||
return GlideData.GIF == this.glideSourceType;
|
|
||||||
}
|
|
||||||
|
|
||||||
isJpg():boolean{
|
|
||||||
return GlideData.JPG == this.glideSourceType;
|
|
||||||
}
|
|
||||||
|
|
||||||
isPng():boolean{
|
|
||||||
return GlideData.PNG == this.glideSourceType;
|
|
||||||
}
|
|
||||||
|
|
||||||
isBmp():boolean{
|
|
||||||
return GlideData.BMP == this.glideSourceType;
|
|
||||||
}
|
|
||||||
|
|
||||||
isWebp():boolean{
|
|
||||||
return GlideData.WEBP == this.glideSourceType;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
isString():boolean{
|
|
||||||
return GlideData.STRING == this.glideType;
|
|
||||||
}
|
|
||||||
isPixelMap():boolean{
|
|
||||||
return GlideData.PIXELMAP == this.glideType;
|
|
||||||
}
|
|
||||||
isResource():boolean{
|
|
||||||
return GlideData.RESOURCE == this.glideType;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
can2PixelMap(){ // 可以转换为PixelMap的数据源
|
|
||||||
return this.isPixelMap() || this.isBmp() || this.isJpg() || this.isWebp() || this.isPng();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,301 +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 {GlideOption} from '../glide/GlideOption'
|
|
||||||
import {RequestOption} from '../glide/RequestOption'
|
|
||||||
import {GlideData} from '../glide/GlideData'
|
|
||||||
import {PixelMapPack} from '../glide/PixelMapPack'
|
|
||||||
import {Base64} from '../cache/Base64'
|
|
||||||
import resourceManager from '@ohos.resourceManager';
|
|
||||||
import image from '@ohos.multimedia.image';
|
|
||||||
|
|
||||||
@Component
|
|
||||||
export struct GlideImage {
|
|
||||||
@Watch('watchGlideOption') @Link glideOption: GlideOption;
|
|
||||||
@State glidePixelMapPack: PixelMapPack = new PixelMapPack();
|
|
||||||
@State glideResource: Resource = $r('app.media.icon_loading')
|
|
||||||
@State glideString: string = ''
|
|
||||||
@State normalPixelMap: boolean = true;
|
|
||||||
@State normalResource: boolean = true;
|
|
||||||
previousData: GlideData = null;
|
|
||||||
nowData: GlideData = null;
|
|
||||||
@State percentVisible: Visibility = Visibility.Visible
|
|
||||||
@State retryVisible: Visibility = Visibility.Visible
|
|
||||||
@State imageVisible: Visibility = Visibility.Visible
|
|
||||||
@State percent: string = '0%'
|
|
||||||
@State percentWidth: string = '0%';
|
|
||||||
@State percentHeight: string = '0%';
|
|
||||||
@State retryWidth: string = '0%';
|
|
||||||
@State retryHeight: string = '0%';
|
|
||||||
@State imageWidth: string = '100%';
|
|
||||||
@State imageHeight: string = '100%';
|
|
||||||
|
|
||||||
hasRetry:boolean = false;
|
|
||||||
|
|
||||||
build() {
|
|
||||||
Stack() {
|
|
||||||
|
|
||||||
Text(this.percent)
|
|
||||||
.fontSize(this.glideOption.size ? Math.min(this.glideOption.size.height, this.glideOption.size.width) / 2 : 24)
|
|
||||||
.fontWeight(FontWeight.Bold)
|
|
||||||
.visibility(this.retryVisible)
|
|
||||||
.width(this.percentWidth)
|
|
||||||
.height(this.percentHeight)
|
|
||||||
|
|
||||||
Image($r('app.media.icon_retry'))
|
|
||||||
.onClick(()=>{
|
|
||||||
this.retryClick();
|
|
||||||
})
|
|
||||||
.visibility(this.retryVisible)
|
|
||||||
.width(this.retryWidth)
|
|
||||||
.height(this.retryHeight)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Image(this.normalPixelMap ? this.glidePixelMapPack.pixelMap : (this.normalResource ? this.glideResource : this.glideString))
|
|
||||||
.objectFit(this.glideOption.imageFit ? this.glideOption.imageFit : ImageFit.Fill)
|
|
||||||
.visibility(this.imageVisible)
|
|
||||||
.width(this.imageWidth)
|
|
||||||
.height(this.imageHeight)
|
|
||||||
}
|
|
||||||
.width(this.glideOption.size ? this.glideOption.size.width : '100%')
|
|
||||||
.height(this.glideOption.size ? this.glideOption.size.height : '100%')
|
|
||||||
.backgroundColor(this.glideOption.backgroundColor ? this.glideOption.backgroundColor : Color.White)
|
|
||||||
.margin(this.glideOption.margin ? this.glideOption.margin : { left: 0, top: 0, right: 0, bottom: 0 })
|
|
||||||
}
|
|
||||||
|
|
||||||
watchGlideOption() {
|
|
||||||
this.glideExecute();
|
|
||||||
}
|
|
||||||
|
|
||||||
retryClick(){
|
|
||||||
this.hasRetry = true;
|
|
||||||
this.glideExecute();
|
|
||||||
}
|
|
||||||
|
|
||||||
aboutToAppear() {
|
|
||||||
console.log('glideImage aboutToAppear happened!')
|
|
||||||
this.glideExecute();
|
|
||||||
}
|
|
||||||
|
|
||||||
configNecessary(request: RequestOption){
|
|
||||||
// 为了测试重试加载 串讲完成后删除
|
|
||||||
if(this.glideOption.loadSrc == 'https://hbimg.huabanimg.com/testRetryxxxx' && this.hasRetry){
|
|
||||||
request.load('https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp')
|
|
||||||
.addListener((err, data) => {
|
|
||||||
this.glideChangeSource(data)
|
|
||||||
this.animateTo('image');
|
|
||||||
return false;
|
|
||||||
})
|
|
||||||
}else {
|
|
||||||
|
|
||||||
request.load(this.glideOption.loadSrc)
|
|
||||||
.addListener((err, data) => {
|
|
||||||
this.glideChangeSource(data)
|
|
||||||
this.animateTo('image');
|
|
||||||
return false;
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.glideOption.size) {
|
|
||||||
request.setImageViewSize(this.glideOption.size)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
configCacheStrategy(request: RequestOption){
|
|
||||||
if (this.glideOption.onlyRetrieveFromCache) {
|
|
||||||
request.retrieveDataFromCache(this.glideOption.onlyRetrieveFromCache)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.glideOption.isCacheable) {
|
|
||||||
request.skipMemoryCache(!this.glideOption.isCacheable)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.glideOption.strategy) {
|
|
||||||
request.diskCacheStrategy(this.glideOption.strategy)
|
|
||||||
}
|
|
||||||
if (this.glideOption.allCacheInfoCallback) {
|
|
||||||
request.addAllCacheInfoCallback(this.glideOption.allCacheInfoCallback)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
configDisplay(request: RequestOption){
|
|
||||||
if(this.glideOption.animateDuration >= 0){
|
|
||||||
request.animateDuraction = this.glideOption.animateDuration;
|
|
||||||
}
|
|
||||||
if (this.glideOption.placeholderSrc) {
|
|
||||||
request.placeholder(this.glideOption.placeholderSrc, (data) => {
|
|
||||||
this.glideChangeSource(data)
|
|
||||||
this.animateTo('image');
|
|
||||||
})
|
|
||||||
}
|
|
||||||
if (this.glideOption.thumbSizeMultiplier) {
|
|
||||||
request.thumbnail(this.glideOption.thumbSizeMultiplier, (data) => {
|
|
||||||
this.glideChangeSource(data)
|
|
||||||
this.animateTo('image');
|
|
||||||
})
|
|
||||||
}
|
|
||||||
if (this.glideOption.errorholderSrc) {
|
|
||||||
request.errorholder(this.glideOption.errorholderSrc, (data) => {
|
|
||||||
this.glideChangeSource(data)
|
|
||||||
this.animateTo('image');
|
|
||||||
})
|
|
||||||
}
|
|
||||||
if (this.glideOption.transformtions) {
|
|
||||||
request.transforms(this.glideOption.transformtions)
|
|
||||||
}
|
|
||||||
if (this.glideOption.dontAnimateFlag) {
|
|
||||||
request.dontAnimate()
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (this.glideOption.displayProgress) {
|
|
||||||
request.addProgressListener((percentValue: string) => {
|
|
||||||
// 如果进度条百分比 未展示大小,展示其动画
|
|
||||||
this.percent = percentValue;
|
|
||||||
if(this.glideOption.displayProgressListener){
|
|
||||||
this.glideOption.displayProgressListener(percentValue);
|
|
||||||
}
|
|
||||||
this.animateTo('progress');
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
if(this.glideOption.retryLoad){
|
|
||||||
request.addRetryListener((error: any) => {
|
|
||||||
console.log("RetryListener callback!")
|
|
||||||
this.animateTo('retry');
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// glide 第一次启动和数据刷新后重新发送请求
|
|
||||||
glideExecute() {
|
|
||||||
let request = new RequestOption();
|
|
||||||
this.configNecessary(request);
|
|
||||||
this.configCacheStrategy(request);
|
|
||||||
this.configDisplay(request);
|
|
||||||
let svgGif = Glide.getSvgAndGifFolder();
|
|
||||||
console.log("输出SVG和gif的缓存地址="+svgGif)
|
|
||||||
console.log("GlideImage Ready to 'call' method! Glide is null="+(Glide == null || Glide == undefined))
|
|
||||||
Glide.call(request);
|
|
||||||
}
|
|
||||||
|
|
||||||
glideChangeSource(data:GlideData) {
|
|
||||||
this.glideSpecialFixed(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
displayPixelMap(data:GlideData){
|
|
||||||
|
|
||||||
this.normalPixelMap = true;
|
|
||||||
this.normalResource = true;
|
|
||||||
|
|
||||||
let pixelMapPack2 = new PixelMapPack();
|
|
||||||
pixelMapPack2.pixelMap = data.glideValue as PixelMap;
|
|
||||||
this.glidePixelMapPack = pixelMapPack2;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
displayResource(data:GlideData){
|
|
||||||
this.normalPixelMap = false;
|
|
||||||
this.normalResource = true;
|
|
||||||
this.glideResource = data.glideValue as Resource;
|
|
||||||
}
|
|
||||||
|
|
||||||
displayString(data:GlideData){
|
|
||||||
|
|
||||||
this.normalPixelMap = false;
|
|
||||||
this.normalResource = false;
|
|
||||||
let firstIndex = (data.glideValue as string).indexOf(Glide.getSvgAndGifFolder());
|
|
||||||
let suffix = (data.glideValue as string).substring(firstIndex, (data.glideValue as string).length)
|
|
||||||
// let glideNeedStr = 'internal://app/' + suffix;
|
|
||||||
let glideNeedStr = 'file://' + data.glideValue;
|
|
||||||
this.glideString = glideNeedStr;
|
|
||||||
|
|
||||||
}
|
|
||||||
glideSpecialFixed(data:GlideData) {
|
|
||||||
if (data.isPixelMap()) {
|
|
||||||
this.displayPixelMap(data);
|
|
||||||
}
|
|
||||||
else if (data.isString()) {
|
|
||||||
this.displayString(data);
|
|
||||||
} else if (data.isResource()) {
|
|
||||||
this.displayResource(data);
|
|
||||||
} else {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
animateTo(name: string) {
|
|
||||||
if (name == 'progress') {
|
|
||||||
this.percentVisible = Visibility.Visible;
|
|
||||||
this.imageVisible = Visibility.Hidden;
|
|
||||||
this.retryVisible = Visibility.Hidden;
|
|
||||||
if (this.percentWidth == '0%' || this.percentHeight == '0%') {
|
|
||||||
animateTo({ duration: this.glideOption.animateDuration , curve: Curve.Linear }, () => {
|
|
||||||
this.percentWidth = '100%';
|
|
||||||
this.percentHeight = '100%';
|
|
||||||
this.imageWidth = '0%';
|
|
||||||
this.imageHeight = '0%';
|
|
||||||
this.retryWidth = '0%';
|
|
||||||
this.retryHeight = '0%';
|
|
||||||
})
|
|
||||||
}
|
|
||||||
} else if (name == 'image') {
|
|
||||||
this.imageVisible = Visibility.Visible;
|
|
||||||
this.percentVisible = Visibility.Hidden;
|
|
||||||
this.retryVisible = Visibility.Hidden;
|
|
||||||
if (this.imageWidth == '0%' || this.imageHeight == '0%') {
|
|
||||||
animateTo({ duration: this.glideOption.animateDuration, curve: Curve.Linear }, () => {
|
|
||||||
this.imageWidth = '100%';
|
|
||||||
this.imageHeight = '100%';
|
|
||||||
this.percentWidth = '0%';
|
|
||||||
this.percentHeight = '0%';
|
|
||||||
this.retryWidth = '0%';
|
|
||||||
this.retryHeight = '0%';
|
|
||||||
})
|
|
||||||
}
|
|
||||||
} else if (name == 'retry') {
|
|
||||||
this.retryVisible = Visibility.Visible;
|
|
||||||
this.imageVisible = Visibility.Hidden;
|
|
||||||
this.percentVisible = Visibility.Hidden;
|
|
||||||
if (this.retryWidth == '0%' || this.retryHeight == '0%') {
|
|
||||||
animateTo({ duration: this.glideOption.animateDuration, curve: Curve.Linear }, () => {
|
|
||||||
this.imageWidth = '0%';
|
|
||||||
this.imageHeight = '0%';
|
|
||||||
this.percentWidth = '0%';
|
|
||||||
this.percentHeight = '0%';
|
|
||||||
this.retryWidth = '100%';
|
|
||||||
this.retryHeight = '100%';
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
aboutToDisappear() {
|
|
||||||
}
|
|
||||||
|
|
||||||
onPageShow() {
|
|
||||||
}
|
|
||||||
|
|
||||||
onPageHide() {
|
|
||||||
}
|
|
||||||
|
|
||||||
onBackPress() {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var Glide;
|
|
||||||
var defaultTemp = globalThis.exports.default
|
|
||||||
if (defaultTemp != undefined) {
|
|
||||||
Glide = defaultTemp.data.glide;
|
|
||||||
}
|
|
|
@ -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 {AUTOMATIC} from "../cache/diskstrategy/enum/AUTOMATIC"
|
|
||||||
import {DiskStrategy} from "../cache/diskstrategy/DiskStrategy"
|
|
||||||
import {BaseTransform} from "../glide/transform/BaseTransform"
|
|
||||||
import {AllCacheInfo, IAllCacheInfoCallback} from "../glide/interface/iallcacheinfocallback"
|
|
||||||
|
|
||||||
export class GlideOption {
|
|
||||||
|
|
||||||
// 主图资源
|
|
||||||
loadSrc: string | PixelMap | Resource;
|
|
||||||
|
|
||||||
// 磁盘缓存策略
|
|
||||||
strategy?: DiskStrategy = new AUTOMATIC();
|
|
||||||
|
|
||||||
// gif加载展示一帧
|
|
||||||
dontAnimateFlag? = false;
|
|
||||||
|
|
||||||
// 占位图
|
|
||||||
placeholderSrc?: PixelMap | Resource;
|
|
||||||
|
|
||||||
// 失败占位图
|
|
||||||
errorholderSrc?: PixelMap | Resource;
|
|
||||||
|
|
||||||
// 缩略图,范围(0,1)
|
|
||||||
thumbSizeMultiplier?: number;
|
|
||||||
|
|
||||||
// 进度条
|
|
||||||
displayProgress?: boolean;
|
|
||||||
|
|
||||||
// 进度条回调
|
|
||||||
displayProgressListener?;
|
|
||||||
|
|
||||||
// 重试图层
|
|
||||||
retryLoad?: boolean;
|
|
||||||
|
|
||||||
// 动画时长
|
|
||||||
animateDuration?: number = 500;
|
|
||||||
|
|
||||||
// 仅使用缓存加载数据
|
|
||||||
onlyRetrieveFromCache?: boolean = false;
|
|
||||||
|
|
||||||
// 是否开启第一级内存缓存
|
|
||||||
isCacheable?: boolean = true;
|
|
||||||
|
|
||||||
// 变换相关
|
|
||||||
transformtions?: Array<BaseTransform<PixelMap>> = new Array();
|
|
||||||
|
|
||||||
// 输出缓存相关内容和信息
|
|
||||||
allCacheInfoCallback?: IAllCacheInfoCallback;
|
|
||||||
size: {
|
|
||||||
width: number,
|
|
||||||
height: number
|
|
||||||
};
|
|
||||||
imageFit?: ImageFit;
|
|
||||||
backgroundColor?: Color | number | string | Resource;
|
|
||||||
margin?: {
|
|
||||||
top?: number | string | Resource,
|
|
||||||
right?: number | string | Resource,
|
|
||||||
bottom?: number | string | Resource,
|
|
||||||
left?: number | string | Resource
|
|
||||||
} | number | string | Resource
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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 class PixelMapPack {
|
|
||||||
pixelMap:PixelMap
|
|
||||||
}
|
|
|
@ -1,294 +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 "../cache/diskstrategy/DiskStrategy"
|
|
||||||
import {AsyncCallback} from "../glide/interface/asynccallback"
|
|
||||||
import {AsyncSuccess} from "../glide/interface/AsyncSuccess"
|
|
||||||
import {AllCacheInfo, IAllCacheInfoCallback} from "../glide/interface/iallcacheinfocallback"
|
|
||||||
import {AUTOMATIC} from "../cache/diskstrategy/enum/AUTOMATIC"
|
|
||||||
import {BaseTransform} from "../glide/transform/BaseTransform"
|
|
||||||
import {RotateImageTransformation} from "../glide/transform/RotateImageTransformation"
|
|
||||||
import {GlideData} from "../glide/GlideData"
|
|
||||||
import fileio from '@ohos.fileio';
|
|
||||||
import image from '@ohos.multimedia.image';
|
|
||||||
import {CenterCrop} from '../glide/transform/pixelmap/CenterCrop'
|
|
||||||
import {CenterInside} from '../glide/transform/pixelmap/CenterInside'
|
|
||||||
import {FitCenter} from '../glide/transform/pixelmap/FitCenter'
|
|
||||||
|
|
||||||
export class RequestOption {
|
|
||||||
loadSrc: string | PixelMap | Resource;
|
|
||||||
strategy: DiskStrategy = new AUTOMATIC();
|
|
||||||
dontAnimateFlag = false;
|
|
||||||
placeholderSrc: PixelMap | Resource;
|
|
||||||
placeholderFunc: AsyncSuccess<GlideData>;
|
|
||||||
errorholderSrc: PixelMap | Resource;
|
|
||||||
errorholderFunc: AsyncSuccess<GlideData>;
|
|
||||||
errorholderData: GlideData;
|
|
||||||
thumbSizeMultiplier: number;
|
|
||||||
|
|
||||||
// 如果存在缩略图,则主图延时3000ms加载
|
|
||||||
thumbDelayTime: number = 3000
|
|
||||||
thumbholderFunc: AsyncSuccess<GlideData>;
|
|
||||||
requestListeners: Array<AsyncCallback<GlideData>>;
|
|
||||||
|
|
||||||
// 进度条
|
|
||||||
progressFunc: AsyncSuccess<string>;
|
|
||||||
|
|
||||||
// 重试图层
|
|
||||||
retryFunc: AsyncSuccess<GlideData>
|
|
||||||
|
|
||||||
// 图层切换时长
|
|
||||||
animateDuraction: number = 500;
|
|
||||||
size: {
|
|
||||||
width: number,
|
|
||||||
height: number
|
|
||||||
} = { width: -1, height: -1 };
|
|
||||||
|
|
||||||
// 网络下载数据回调
|
|
||||||
allCacheInfoCallback: IAllCacheInfoCallback;
|
|
||||||
onlyRetrieveFromCache: boolean = false;
|
|
||||||
isCacheable: boolean = true;
|
|
||||||
|
|
||||||
// 变换相关
|
|
||||||
transformtions: Array<BaseTransform<PixelMap>> = new Array();
|
|
||||||
generateCacheKey: string = "";
|
|
||||||
generateResourceKey: string = "";
|
|
||||||
generateDataKey: string = "";
|
|
||||||
private filesPath: string = ""; // data/data/包名/files目录
|
|
||||||
private cachesPath: string = ""; // 网络下载默认存储在data/data/包名/cache/GlideNetworkFolder/目标md5.img下面
|
|
||||||
|
|
||||||
// 下载原始文件地址
|
|
||||||
downloadFilePath: string = "";
|
|
||||||
|
|
||||||
// 网络文件下载统一存放
|
|
||||||
networkCacheFolder: string = "GlideNetworkFolder"
|
|
||||||
|
|
||||||
|
|
||||||
// 主线图片 状态变化 是否加载完成
|
|
||||||
// 主图未加载成功 显示占位图 主图加载成功不展示占位图
|
|
||||||
loadMainReady = false;
|
|
||||||
|
|
||||||
// 失败占位图展示状态 当true 表示主图加载失败需要展示失败占位图
|
|
||||||
loadErrorReady = false
|
|
||||||
|
|
||||||
// 缩略图展示
|
|
||||||
loadThumbnailReady = false;
|
|
||||||
_svgAndGifFolder: string = "svgAndGifFolder"; // svg和gif的文件路径地址
|
|
||||||
_svgAndGifCommitFile: string = "svgAndGifCommitFile"; // svg和gif提交记录
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
// 初始化全局监听
|
|
||||||
this.requestListeners = new Array();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* set image Component size
|
|
||||||
*/
|
|
||||||
setImageViewSize(imageSize: {
|
|
||||||
width: number,
|
|
||||||
height: number
|
|
||||||
}) {
|
|
||||||
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<GlideData>) {
|
|
||||||
this.placeholderSrc = src;
|
|
||||||
this.placeholderFunc = func;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
errorholder(src: PixelMap | Resource, func?: AsyncSuccess<GlideData>) {
|
|
||||||
this.errorholderSrc = src;
|
|
||||||
this.errorholderFunc = func;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
thumbnail(sizeMultiplier: number, func?: AsyncSuccess<GlideData>) {
|
|
||||||
this.thumbSizeMultiplier = sizeMultiplier;
|
|
||||||
this.thumbholderFunc = func;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
addProgressListener(func?: AsyncSuccess<string>) {
|
|
||||||
this.progressFunc = func;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
addRetryListener(func?: AsyncSuccess<any>) {
|
|
||||||
this.retryFunc = func;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
addListener(func: AsyncCallback<GlideData>) {
|
|
||||||
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) {
|
|
||||||
let rotateImage = new RotateImageTransformation(degreesToRotate);
|
|
||||||
this.transformtions.push(rotateImage);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
centerCrop() {
|
|
||||||
this.transformtions.push(new CenterCrop());
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
centerInside() {
|
|
||||||
this.transformtions.push(new CenterInside());
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
fitCenter() {
|
|
||||||
this.transformtions.push(new FitCenter());
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
transform(transform: BaseTransform<PixelMap>) {
|
|
||||||
this.transformtions.push(transform);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
transforms(transforms: BaseTransform<PixelMap>[]) {
|
|
||||||
this.transformtions = transforms;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 占位图解析成功
|
|
||||||
placeholderOnComplete(glidedata: GlideData) {
|
|
||||||
console.log("placeholderOnComplete has called!");
|
|
||||||
console.log("Main Image is Ready:" + this.loadMainReady);
|
|
||||||
if (!this.loadMainReady && !this.loadErrorReady && !this.loadThumbnailReady) {
|
|
||||||
// 主图未加载成功,并且未加载失败 显示占位图 主图加载成功或者加载失败后=>不展示占位图
|
|
||||||
this.placeholderFunc(glidedata)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 占位图解析失败
|
|
||||||
placeholderOnError(error) {
|
|
||||||
console.log("占位图解析失败 error =" + error)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 缩略图解析成功
|
|
||||||
thumbholderOnComplete(glidedata: GlideData) {
|
|
||||||
if (!this.loadMainReady && !this.loadErrorReady) {
|
|
||||||
//主图未加载成功,并且未加载失败 显示占位图 主图加载成功或者加载失败后=>不展示占位图
|
|
||||||
this.thumbholderFunc(glidedata)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 缩略图解析失败
|
|
||||||
thumbholderOnError(error) {
|
|
||||||
console.log("缩略图解析失败 error =" + error)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 加载失败 占位图解析成功
|
|
||||||
errorholderOnComplete(glidedata: GlideData) {
|
|
||||||
// 如果有错误占位图 先解析并保存在RequestOption中 等到加载失败时候进行调用
|
|
||||||
this.errorholderData = glidedata;
|
|
||||||
if (this.loadErrorReady) {
|
|
||||||
this.errorholderFunc(glidedata)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//加载失败 占位图解析失败
|
|
||||||
errorholderOnError(error) {
|
|
||||||
console.log("失败占位图解析失败 error =" + error)
|
|
||||||
}
|
|
||||||
|
|
||||||
loadComplete(glidedata: GlideData) {
|
|
||||||
this.loadMainReady = true;
|
|
||||||
// 三级缓存数据加载成功
|
|
||||||
for (let requestListener of this.requestListeners) {
|
|
||||||
var ret = requestListener("", glidedata);
|
|
||||||
if (ret) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 加载成功之后
|
|
||||||
Glide.removeRunning(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
loadError(err) {
|
|
||||||
console.log("loadError:"+err);
|
|
||||||
//失败占位图展示规则
|
|
||||||
this.loadErrorReady = true;
|
|
||||||
if (this.retryFunc) {
|
|
||||||
// 重试图层优先于加载失败展示
|
|
||||||
this.retryFunc(err)
|
|
||||||
} else {
|
|
||||||
if (this.errorholderData != null) {
|
|
||||||
this.errorholderFunc(this.errorholderData)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 加载失败之后
|
|
||||||
Glide.removeRunning(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
var Glide;
|
|
||||||
var defaultTemp = globalThis.exports.default
|
|
||||||
if (defaultTemp != undefined) {
|
|
||||||
Glide = defaultTemp.data.glide;
|
|
||||||
}
|
|
|
@ -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 {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 featureability from '@ohos.ability.featureAbility'
|
|
||||||
import {Engine} from '../compress/Engine'
|
|
||||||
|
|
||||||
export class CompressBuilder {
|
|
||||||
private _mTargetDir: string;
|
|
||||||
private _mLeastCompressSize: number= 100; //KB
|
|
||||||
private _mRenameListener: OnRenameListener;
|
|
||||||
private _mCompressListener: OnCompressListener;
|
|
||||||
private _mCompressionPredicate: CompressionPredicate
|
|
||||||
private _mStreamProviders: Array<CompressAdapter>;
|
|
||||||
private _mFocusAlpha: boolean;
|
|
||||||
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) {
|
|
||||||
var timestamp = (new Date()).valueOf();
|
|
||||||
this._outFilePath = this._mTargetDir + "/" + timestamp + (Math.random() * 100).toFixed(0) + ".jpg";
|
|
||||||
}
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public load(list: Array<string | Resource>): CompressBuilder {
|
|
||||||
for (var 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<string> {
|
|
||||||
if (!this._mTargetDir) {
|
|
||||||
let path = await featureability.getContext().getFilesDir();
|
|
||||||
var 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<string> {
|
|
||||||
let compressPromise = new Promise((resolve, reject) => {
|
|
||||||
|
|
||||||
let compressListener: OnCompressListener = {
|
|
||||||
start() {
|
|
||||||
},
|
|
||||||
onScuccess(p: PixelMap, 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 (var 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) {
|
|
||||||
var name = this._mRenameListener.reName();
|
|
||||||
if (this._outFilePath && name) {
|
|
||||||
var start = this._outFilePath.lastIndexOf("/") + 1
|
|
||||||
var end = this._outFilePath.length;
|
|
||||||
var replaceStr = this._outFilePath.substring(start, end);
|
|
||||||
this._outFilePath = this._outFilePath.replace(replaceStr, name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (this._mCompressListener) {
|
|
||||||
this._mCompressListener.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
for (var 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.onScuccess(null, element.getRecoursePath());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private getImageCacheFile() {
|
|
||||||
featureability.getContext()
|
|
||||||
.getFilesDir()
|
|
||||||
.then(path => {
|
|
||||||
var timestamp = (new Date()).valueOf();
|
|
||||||
this._outFilePath = path + "/compress/" + timestamp + (Math.random() * 100).toFixed(0) + ".jpg";
|
|
||||||
this.startCompress();
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
throw new Error("getImageCacheFile happened error:" + JSON.stringify(error));
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,208 +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 fileio from '@ohos.fileio';
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
var longSide = Math.max(srcWidth, srcHeight);
|
|
||||||
var shortSide = Math.min(srcWidth, srcHeight);
|
|
||||||
|
|
||||||
var 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() {
|
|
||||||
console.info("asasd compress()")
|
|
||||||
if (this.mCompressAdapter instanceof DataStringPathProvider) {
|
|
||||||
// file
|
|
||||||
this.mCompressAdapter.openInternal((buffer) => {
|
|
||||||
if (!buffer) {
|
|
||||||
if (this.mCompressListener) {
|
|
||||||
this.mCompressListener.onError("file read fail,and date is empty")
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!this.checkNeedCompress(buffer)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var imageResource = image.createImageSource(buffer as any);
|
|
||||||
imageResource.getImageInfo()
|
|
||||||
.then(info => {
|
|
||||||
var height = info.size.height;
|
|
||||||
var width = info.size.width;
|
|
||||||
var computeSize = this.computeSize(width, height);
|
|
||||||
console.info("asasd compress computeSize:" + computeSize);
|
|
||||||
let options = {
|
|
||||||
editable: true,
|
|
||||||
sampleSize: computeSize,
|
|
||||||
desiredPixelFormat: image.PixelMapFormat.RGB_565,
|
|
||||||
}
|
|
||||||
imageResource.createPixelMap(options)
|
|
||||||
.then(bitmap => {
|
|
||||||
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
this.mCompressListener.onError("ptah createPixelMap fail,because error:" + JSON.stringify(error))
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
this.mCompressListener.onError("ptah getImageInfo fail,because error:" + JSON.stringify(error))
|
|
||||||
})
|
|
||||||
|
|
||||||
})
|
|
||||||
} else if (this.mCompressAdapter instanceof RecourseProvider) {
|
|
||||||
// resource
|
|
||||||
this.mCompressAdapter.openInternal((buffer) => {
|
|
||||||
if (!buffer) {
|
|
||||||
if (this.mCompressListener) {
|
|
||||||
this.mCompressListener.onError("resource read fail,and date is empty")
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!this.checkNeedCompress(buffer)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var imageResource = image.createImageSource(buffer as any);
|
|
||||||
imageResource.getImageInfo()
|
|
||||||
.then(info => {
|
|
||||||
var height = info.size.height;
|
|
||||||
var width = info.size.width;
|
|
||||||
var computeSize = this.computeSize(width, height);
|
|
||||||
let packer = {
|
|
||||||
format: ["image/jpeg"],
|
|
||||||
quality: computeSize,
|
|
||||||
}
|
|
||||||
var imagePacker = image.createImagePacker();
|
|
||||||
imagePacker.packing(imageResource, packer as any, (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);
|
|
||||||
var isDirectory = this.checkDirExist(dirPath);
|
|
||||||
if (isDirectory) {
|
|
||||||
this.saveFile(this.mPath, compressBuffer);
|
|
||||||
this.handResult(compressBuffer, this.mPath);
|
|
||||||
} else {
|
|
||||||
fileio.mkdir(dirPath)
|
|
||||||
.then(() => {
|
|
||||||
this.saveFile(this.mPath, compressBuffer);
|
|
||||||
this.handResult(compressBuffer, this.mPath);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private handResult(buffer: ArrayBuffer, path: string) {
|
|
||||||
var imageRes = image.createImageSource(buffer as any);
|
|
||||||
let a={
|
|
||||||
editable: true,
|
|
||||||
}
|
|
||||||
imageRes.createPixelMap(a)
|
|
||||||
.then(bitmap => {
|
|
||||||
if (this.mCompressListener) {
|
|
||||||
this.mCompressListener.onScuccess(bitmap, path);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
if (this.mCompressListener) {
|
|
||||||
this.mCompressListener.onError("buffer generated pixelMap fail,because error:" + JSON.stringify(error))
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
private checkNeedCompress(buf: ArrayBuffer): boolean{
|
|
||||||
if (!buf) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
var length = buf.byteLength / 1024;
|
|
||||||
return length > this._mLeastCompressSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
private saveFile(path: string, content: ArrayBuffer) {
|
|
||||||
FileUtils.getInstance().writeFile(path,content);
|
|
||||||
}
|
|
||||||
|
|
||||||
private checkDirExist(dirPath: string): boolean{
|
|
||||||
var isExist;
|
|
||||||
try {
|
|
||||||
fileio.accessSync(dirPath, 0)
|
|
||||||
isExist = true;
|
|
||||||
} catch (e) {
|
|
||||||
//不符合条件则进入
|
|
||||||
isExist = false;
|
|
||||||
}
|
|
||||||
return isExist;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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<T> {
|
|
||||||
(t: T);
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -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();
|
|
||||||
/**
|
|
||||||
* compress success
|
|
||||||
*/
|
|
||||||
onScuccess(p: PixelMap, path: string);
|
|
||||||
/**
|
|
||||||
* compress fail
|
|
||||||
*/
|
|
||||||
onError(s: string);
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
mPath: string;
|
|
||||||
|
|
||||||
close() {
|
|
||||||
}
|
|
||||||
|
|
||||||
openData(): ArrayBuffer{
|
|
||||||
return this.mData;
|
|
||||||
}
|
|
||||||
|
|
||||||
getPath(): string{
|
|
||||||
return this.mPath;
|
|
||||||
};
|
|
||||||
|
|
||||||
abstract openInternal(callback: CompressDataListener<ArrayBuffer>);
|
|
||||||
|
|
||||||
abstract getRecoursePath(): string;
|
|
||||||
|
|
||||||
abstract getPixelMapFormat(): PixelMapFormat;
|
|
||||||
|
|
||||||
getFormat(s: string): PixelMapFormat{
|
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
|
@ -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();
|
|
||||||
|
|
||||||
openData():ArrayBuffer;
|
|
||||||
|
|
||||||
getPath(): string;
|
|
||||||
|
|
||||||
}
|
|
|
@ -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<ArrayBuffer>) {
|
|
||||||
if (!this.mPath) {
|
|
||||||
throw new Error('DataStringPathProvider error path is empty');
|
|
||||||
}
|
|
||||||
var buffer = FileUtils.getInstance().readFilePic(this.mPath);
|
|
||||||
this.mData = buffer;
|
|
||||||
if (callback) {
|
|
||||||
callback(buffer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
getPixelMapFormat(): PixelMapFormat{
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,111 +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 resmgr from '@ohos.resourceManager'
|
|
||||||
import {CompressDataListener} from "../listener/CompressDataListener"
|
|
||||||
import {FileTypeUtil} from '../../../glide/utils/FileTypeUtil'
|
|
||||||
|
|
||||||
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;
|
|
||||||
private _mPixelMapHeader: string;
|
|
||||||
|
|
||||||
constructor(s: Resource) {
|
|
||||||
super()
|
|
||||||
this._mResourceData = s;
|
|
||||||
this.mPath = RecourseProvider.DEFAULT_RESOURCE_PATH;
|
|
||||||
for (var index = 0; index < RecourseProvider.CHARS.length; index++) {
|
|
||||||
this._mLookup[RecourseProvider.CHARS.charCodeAt(index)] = index;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
getRecoursePath(): string{
|
|
||||||
return this.mPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
openInternal(callback: CompressDataListener<ArrayBuffer>) {
|
|
||||||
console.info("asasd compress openInternal _mData");
|
|
||||||
if (!this._mResourceData) {
|
|
||||||
throw Error("compress resource is empty");
|
|
||||||
}
|
|
||||||
resmgr.getResourceManager()
|
|
||||||
.then(result => {
|
|
||||||
result.getMedia(this._mResourceData
|
|
||||||
.id)
|
|
||||||
.then(data => {
|
|
||||||
let buffer = this.uint8ArrayToBuffer(data);
|
|
||||||
let fileTypeUtil = new FileTypeUtil()
|
|
||||||
this._mPixelMapHeader = fileTypeUtil.getFileType(buffer);
|
|
||||||
callback(buffer);
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
console.log("RecourseProvider openInternal err" + JSON.stringify(err));
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
getPixelMapFormat(): PixelMapFormat{
|
|
||||||
if (!this._mPixelMapHeader) {
|
|
||||||
return PixelMapFormat.NONE;
|
|
||||||
}
|
|
||||||
return this.getFormat(this._mPixelMapHeader);
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* data decode
|
|
||||||
*/
|
|
||||||
decode(base64: string, callback: CompressDataListener<ArrayBuffer>) {
|
|
||||||
let bufferLength = base64.length,
|
|
||||||
len = base64.length,
|
|
||||||
i,
|
|
||||||
p = 0,
|
|
||||||
encoded1,
|
|
||||||
encoded2,
|
|
||||||
encoded3,
|
|
||||||
encoded4;
|
|
||||||
|
|
||||||
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(arraybuffer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8ArrayToBuffer(array: Uint8Array): ArrayBuffer {
|
|
||||||
return array.buffer.slice(array.byteOffset, array.byteLength + array.byteOffset)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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 class Constants {
|
|
||||||
public static PROJECT_TAG: string= "Glide_js"
|
|
||||||
}
|
|
|
@ -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
|
|
||||||
}
|
|
|
@ -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 {AsyncTransform} from "../transform/AsyncTransform"
|
|
||||||
import image from "@ohos.multimedia.image"
|
|
||||||
import {TransformUtils} from "../transform/TransformUtils"
|
|
||||||
|
|
||||||
export namespace Crop {
|
|
||||||
|
|
||||||
export function crop(buf: ArrayBuffer, x: number, y: number, cropWidth: number, cropHeight: number, func?: AsyncTransform<PixelMap>, colorRatio?: number) {
|
|
||||||
if (!buf || buf.byteLength <= 0) {
|
|
||||||
console.log("Crop buf is empty");
|
|
||||||
if (func) {
|
|
||||||
func("Crop buf is empty", null);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var imageSource = image.createImageSource(buf as any);
|
|
||||||
TransformUtils.getPixelMapSize(imageSource, (error, size: {
|
|
||||||
width: number,
|
|
||||||
height: number
|
|
||||||
}) => {
|
|
||||||
if (!size) {
|
|
||||||
func(error, null)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var pixelMapWidth = size.width;
|
|
||||||
var pixelMapHeight = size.height;
|
|
||||||
if (x < 0 || x > pixelMapWidth) {
|
|
||||||
func("Crop error x must be less than pixelMapWidth ", null)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (y < 0 || y > pixelMapHeight) {
|
|
||||||
func("Crop error x must be less than pixelMapHeight ", null)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var options = {
|
|
||||||
editable: true,
|
|
||||||
rotate: 0,
|
|
||||||
desiredSize: {
|
|
||||||
width: pixelMapWidth,
|
|
||||||
height: pixelMapHeight
|
|
||||||
},
|
|
||||||
desiredRegion: { size: { width: cropWidth, height: cropHeight },
|
|
||||||
x: x,
|
|
||||||
y: y,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
imageSource.createPixelMap(options)
|
|
||||||
.then((data) => {
|
|
||||||
if (colorRatio && colorRatio <= 1) {
|
|
||||||
colorRatioPixelMap(data, pixelMapWidth, pixelMapHeight, colorRatio, func);
|
|
||||||
} else {
|
|
||||||
func("", data);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch((e) => {
|
|
||||||
func(e, null);
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
async function colorRatioPixelMap(data: any, width: number, height: number, colorRatio: number, func?: AsyncTransform<PixelMap>) {
|
|
||||||
if (!data) {
|
|
||||||
func("colorRatio pixelMap is null", null);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (colorRatio > 1) {
|
|
||||||
throw new Error("the colorRatio must be <= 1");
|
|
||||||
}
|
|
||||||
var buffer = new ArrayBuffer(width * height * 5);
|
|
||||||
var bytes = new Uint8Array(buffer);
|
|
||||||
var buffer1B = new ArrayBuffer(width * height * 5);
|
|
||||||
var bytes1B = new Uint8Array(buffer1B);
|
|
||||||
|
|
||||||
let readPromise = data.readPixelsToBuffer(buffer)
|
|
||||||
await readPromise;
|
|
||||||
for (let i = 0;i < bytes.length; i++) {
|
|
||||||
bytes1B[i] = bytes[i] * colorRatio;
|
|
||||||
}
|
|
||||||
let writePromise = data.writeBufferToPixels(buffer1B)
|
|
||||||
await writePromise;
|
|
||||||
func("", data);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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 {CropOptions} 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 => {
|
|
||||||
this._rotate = event.angle;
|
|
||||||
}), PinchGesture({ fingers: 2 }).onActionUpdate(event => {
|
|
||||||
this._scale = event.scale;
|
|
||||||
})
|
|
||||||
).onCancel(() => {
|
|
||||||
console.log("CropImage gesture cancel");
|
|
||||||
})
|
|
||||||
)
|
|
||||||
}.width(this._mOptions.size.width).height(this._mOptions.size.height);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,22 +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 CropOptions {
|
|
||||||
src: string | PixelMap | Resource;
|
|
||||||
size: {
|
|
||||||
width: number,
|
|
||||||
height: number;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
private y: number;
|
|
||||||
|
|
||||||
constructor(x: number, y: number) {
|
|
||||||
this.y = y;
|
|
||||||
this.x = x;
|
|
||||||
}
|
|
||||||
|
|
||||||
getX(): number{
|
|
||||||
return this.x;
|
|
||||||
}
|
|
||||||
|
|
||||||
getY(): number{
|
|
||||||
return this.y
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
export class PixelEntry {
|
|
||||||
a: number;
|
|
||||||
b: number;
|
|
||||||
r: number;
|
|
||||||
g: number;
|
|
||||||
f: number;
|
|
||||||
pixel: number;
|
|
||||||
|
|
||||||
public toString(): string {
|
|
||||||
return "PixelEntry a:" + this.a + ";b:" + this.b + ";r:" + this.r + ";g:" + this.g + ";f:" + this.f;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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 {RequestOption} from "../../glide/RequestOption"
|
|
||||||
import {FileTypeUtil} from "../../glide/utils/FileTypeUtil"
|
|
||||||
import {GlideData} from "../GlideData"
|
|
||||||
import {ParseImageUtil} from '../utils/ParseImageUtil'
|
|
||||||
import {ParseResClient} from '../resourcemanage/ParseResClient'
|
|
||||||
import image from "@ohos.multimedia.image"
|
|
||||||
|
|
||||||
export class ErrorHolderManager {
|
|
||||||
private options: RequestOption;
|
|
||||||
|
|
||||||
constructor(option: RequestOption) {
|
|
||||||
this.options = option;
|
|
||||||
}
|
|
||||||
|
|
||||||
static execute(option: RequestOption) {
|
|
||||||
let manager = new ErrorHolderManager(option);
|
|
||||||
return new Promise(manager.process.bind(manager))
|
|
||||||
.then(option.errorholderOnComplete.bind(option)).catch(option.errorholderOnError.bind(option));
|
|
||||||
}
|
|
||||||
|
|
||||||
process(onComplete, onError) {
|
|
||||||
this.displayErrorholder(onComplete, onError);
|
|
||||||
}
|
|
||||||
|
|
||||||
private displayErrorholder(onComplete, onError) {
|
|
||||||
console.log("displayErrorholder")
|
|
||||||
if (this.options.errorholderSrc instanceof image.PixelMap) {
|
|
||||||
let glidedata = new GlideData();
|
|
||||||
glidedata.glideType = GlideData.PIXELMAP
|
|
||||||
glidedata.glideValue = this.options.placeholderSrc as PixelMap
|
|
||||||
onComplete(glidedata);
|
|
||||||
} 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) => {
|
|
||||||
let fileTypeUtil = new FileTypeUtil();
|
|
||||||
let typeValue = fileTypeUtil.getFileType(arraybuffer);
|
|
||||||
if ("gif" == typeValue || "svg" == typeValue) {
|
|
||||||
let glidedata = new GlideData();
|
|
||||||
glidedata.glideType = "Resource"
|
|
||||||
glidedata.glideValue = this.options.errorholderSrc as Resource
|
|
||||||
glidedata.glideSourceType = typeValue;
|
|
||||||
onComplete(glidedata);
|
|
||||||
} else {
|
|
||||||
let parseImageUtils = new ParseImageUtil();
|
|
||||||
let success = (value: PixelMap) => {
|
|
||||||
let glidedata = new GlideData();
|
|
||||||
glidedata.glideType = "PixelMap"
|
|
||||||
glidedata.glideValue = value
|
|
||||||
glidedata.glideSourceType = typeValue;
|
|
||||||
onComplete(glidedata);
|
|
||||||
}
|
|
||||||
parseImageUtils.parseImage(arraybuffer, success, onError)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
resourceFetch.loadResource(res, suc, onError)
|
|
||||||
} else {
|
|
||||||
onError("ErrorHolderManager 输入参数有问题!")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,83 +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 "../../glide/RequestOption"
|
|
||||||
import {ResourceTypeEts} from "../../glide/constants/ResourceTypeEts"
|
|
||||||
import {Base64} from "../../cache/Base64"
|
|
||||||
import {FileTypeUtil} from "../../glide/utils/FileTypeUtil"
|
|
||||||
import {GlideData} from "../GlideData"
|
|
||||||
import {ParseImageUtil} from '../utils/ParseImageUtil'
|
|
||||||
import {ParseResClient} from '../resourcemanage/ParseResClient'
|
|
||||||
import resourceManager from '@ohos.resourceManager';
|
|
||||||
import image from "@ohos.multimedia.image"
|
|
||||||
|
|
||||||
export class PlaceHolderManager {
|
|
||||||
private options: RequestOption;
|
|
||||||
|
|
||||||
constructor(option: RequestOption) {
|
|
||||||
this.options = option;
|
|
||||||
}
|
|
||||||
|
|
||||||
static execute(option: RequestOption) {
|
|
||||||
let manager = new PlaceHolderManager(option);
|
|
||||||
return new Promise(manager.process.bind(manager))
|
|
||||||
.then(option.placeholderOnComplete.bind(option)).catch(option.placeholderOnError.bind(option));
|
|
||||||
}
|
|
||||||
|
|
||||||
process(onComplete, onError) {
|
|
||||||
this.displayPlaceholder(onComplete, onError);
|
|
||||||
}
|
|
||||||
|
|
||||||
private displayPlaceholder(onComplete, onError) {
|
|
||||||
console.log("displayPlaceholder")
|
|
||||||
if (this.options.placeholderSrc instanceof image.PixelMap) {
|
|
||||||
let glidedata = new GlideData();
|
|
||||||
glidedata.glideType = GlideData.PIXELMAP
|
|
||||||
glidedata.glideValue = this.options.placeholderSrc as PixelMap
|
|
||||||
onComplete(glidedata);
|
|
||||||
} 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) => {
|
|
||||||
let fileTypeUtil = new FileTypeUtil();
|
|
||||||
let typeValue = fileTypeUtil.getFileType(arraybuffer);
|
|
||||||
if ("gif" == typeValue || "svg" == typeValue) {
|
|
||||||
let glidedata = this.createGlideData("Resource", this.options.placeholderSrc as Resource, typeValue);
|
|
||||||
onComplete(glidedata);
|
|
||||||
} else {
|
|
||||||
let parseImageUtils = new ParseImageUtil();
|
|
||||||
let success = (value: PixelMap) => {
|
|
||||||
let glidedata = this.createGlideData('PixelMap', value, typeValue);
|
|
||||||
onComplete(glidedata);
|
|
||||||
}
|
|
||||||
parseImageUtils.parseImage(arraybuffer, success, onError)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
resourceFetch.loadResource(res, suc, onError)
|
|
||||||
} else {
|
|
||||||
onError("PlaceHolderManager 输入参数有问题!")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
private createGlideData(glideType:string, glideValue:PixelMap|string|Resource, glideSourceType:string):GlideData{
|
|
||||||
let glidedata = new GlideData();
|
|
||||||
glidedata.glideType = glideType;
|
|
||||||
glidedata.glideValue = glideValue;
|
|
||||||
glidedata.glideSourceType = glideSourceType;
|
|
||||||
return glidedata;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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 AsyncCallback<T> {
|
|
||||||
(err: string, data: T): boolean;
|
|
||||||
}
|
|
|
@ -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<T> {
|
|
||||||
(data: T);
|
|
||||||
}
|
|
|
@ -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 DataCallBack<T> {
|
|
||||||
callback(data: T);
|
|
||||||
}
|
|
|
@ -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 {GlideData} from "../../glide/glidedata"
|
|
||||||
|
|
||||||
export class AllCacheInfo {
|
|
||||||
memoryCacheInfo: {
|
|
||||||
key: string,
|
|
||||||
data: GlideData
|
|
||||||
}
|
|
||||||
|
|
||||||
resourceCacheInfo: {
|
|
||||||
path: string,
|
|
||||||
key: string
|
|
||||||
}
|
|
||||||
|
|
||||||
dataCacheInfo: {
|
|
||||||
path: string,
|
|
||||||
key: string
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IAllCacheInfoCallback {
|
|
||||||
(cacheInfo: AllCacheInfo);
|
|
||||||
}
|
|
|
@ -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 IParseImage {
|
|
||||||
parseImage(imageinfo:ArrayBuffer, onCompleteFunction, onErrorFunction);
|
|
||||||
parseImageThumbnail(scale:number, imageinfo:ArrayBuffer, onCompleteFunction, onErrorFunction);
|
|
||||||
}
|
|
|
@ -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 {IDataFetch} from "../networkmanage/IDataFetch"
|
|
||||||
import {RequestOption} from "../RequestOption"
|
|
||||||
import {Md5} from "../../cache/Md5"
|
|
||||||
import{FileUtils} from "../../cache/FileUtils"
|
|
||||||
|
|
||||||
import loadRequest from '@ohos.request';
|
|
||||||
|
|
||||||
export class DownloadClient implements IDataFetch {
|
|
||||||
loadData(request: RequestOption, onCompleteFunction, onErrorFunction) {
|
|
||||||
|
|
||||||
let requestUrl = request.loadSrc as string;
|
|
||||||
if (requestUrl.startsWith("http") || requestUrl.startsWith("https")) {
|
|
||||||
let filename = Md5.hashStr(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 desc = filename + ".img";
|
|
||||||
|
|
||||||
var downloadConfig = {
|
|
||||||
url: (request.loadSrc as string),
|
|
||||||
filePath: allpath,
|
|
||||||
header: {},
|
|
||||||
enableMetered: true,
|
|
||||||
enableRoaming: true,
|
|
||||||
description: desc,
|
|
||||||
networkType: 1,
|
|
||||||
title: filename,
|
|
||||||
};
|
|
||||||
|
|
||||||
let loadTask = null;
|
|
||||||
loadRequest.download(downloadConfig)
|
|
||||||
.then((downloadTask) => {
|
|
||||||
|
|
||||||
if(downloadTask){
|
|
||||||
loadTask = downloadTask;
|
|
||||||
|
|
||||||
loadTask.on('progress', (err, receivedSize, totalSize)=>{
|
|
||||||
let percent = Math.round(((receivedSize*1.0)/(totalSize*1.0))*100)+"%"
|
|
||||||
if(request.progressFunc) {
|
|
||||||
request.progressFunc(percent);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
loadTask.on('complete', () => {
|
|
||||||
let downloadPath = allpath;
|
|
||||||
request.downloadFilePath = downloadPath;
|
|
||||||
let arraybuffer = FileUtils.getInstance().readFilePic(downloadPath)
|
|
||||||
onCompleteFunction(arraybuffer);
|
|
||||||
FileUtils.getInstance().deleteFile(downloadPath);
|
|
||||||
|
|
||||||
loadTask.off('complete',()=>{
|
|
||||||
loadTask = null;
|
|
||||||
})
|
|
||||||
|
|
||||||
loadTask.off('pause',()=>{
|
|
||||||
})
|
|
||||||
|
|
||||||
loadTask.off('remove',()=>{
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
loadTask.off('progress',()=>{
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
loadTask.off('fail',()=>{
|
|
||||||
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
loadTask.on('pause',()=>{
|
|
||||||
})
|
|
||||||
|
|
||||||
loadTask.on('remove',()=>{
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
loadTask.on('fail',(err)=>{
|
|
||||||
onErrorFunction('DownloadClient Download task fail err ='+err)
|
|
||||||
if(loadTask) {
|
|
||||||
loadTask.remove().then(result => {
|
|
||||||
loadTask.off('complete', () => {
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
loadTask.off('pause', () => {
|
|
||||||
})
|
|
||||||
|
|
||||||
loadTask.off('remove', () => {
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
loadTask.off('progress', () => {
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
loadTask.off('fail', () => {
|
|
||||||
|
|
||||||
})
|
|
||||||
loadTask = null
|
|
||||||
}).catch(err => {
|
|
||||||
loadTask = null;
|
|
||||||
console.log('DownloadClient Download task fail err =' + err);
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
}else{
|
|
||||||
onErrorFunction('DownloadClient downloadTask dismiss!')
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
onErrorFunction(err)
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
onErrorFunction("DownloadClient 暂不支持除http之外的uri加载")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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, onCompleteFunction, onErrorFunction);
|
|
||||||
}
|
|
|
@ -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 {IDataFetch} from "../networkmanage/IDataFetch"
|
|
||||||
import {RequestOption} from "../RequestOption"
|
|
||||||
import {Md5} from "../../cache/Md5"
|
|
||||||
import {FileUtils} from "../../cache/FileUtils"
|
|
||||||
import {ParseResClient} from "../../glide/resourcemanage/ParseResClient"
|
|
||||||
import resourceManager from '@ohos.resourceManager';
|
|
||||||
|
|
||||||
export class SimulatedDownloadClient implements IDataFetch {
|
|
||||||
loadData(request: RequestOption, onCompleteFunction, onErrorFunction) {
|
|
||||||
console.log("SimulatedDownloadClient loadData");
|
|
||||||
let requestUrl = request.loadSrc as string;
|
|
||||||
let resource;
|
|
||||||
//jpg
|
|
||||||
if('https://hbimg.huabanimg.com/cc6af25f8d782d3cf3122bef4e61571378271145735e9-vEVggB' == requestUrl){
|
|
||||||
console.log("SimulatedDownloadClient jpg");
|
|
||||||
resource = $r('app.media.jpgNet')
|
|
||||||
}
|
|
||||||
//png
|
|
||||||
else if('https://img-blog.csdnimg.cn/20191215043500229.png' == requestUrl){
|
|
||||||
console.log("SimulatedDownloadClient png");
|
|
||||||
resource = $r('app.media.pngNet')
|
|
||||||
}
|
|
||||||
//bmp
|
|
||||||
else if('https://img-blog.csdn.net/20140514114029140' == requestUrl){
|
|
||||||
console.log("SimulatedDownloadClient bmp");
|
|
||||||
resource = $r('app.media.bmpNet')
|
|
||||||
}
|
|
||||||
//webp
|
|
||||||
else if('https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp' == requestUrl){
|
|
||||||
console.log("SimulatedDownloadClient webp");
|
|
||||||
resource = $r('app.media.webpNet')
|
|
||||||
}
|
|
||||||
//svg
|
|
||||||
else if('http://design-svc.fat.lunz.cn/StaticFiles/BP9999999772/BV9999999422/SA9999998420/30df266a-485e-411e-b178-b9fb1d8e0748.svg' == requestUrl){
|
|
||||||
console.log("SimulatedDownloadClient svg");
|
|
||||||
resource = $r('app.media.svgNet')
|
|
||||||
}
|
|
||||||
//gif
|
|
||||||
else if('https://pic.ibaotu.com/gif/18/17/16/51u888piCtqj.gif!fwpaa70/fw/700'== requestUrl){
|
|
||||||
console.log("SimulatedDownloadClient gif");
|
|
||||||
resource = $r('app.media.gifNet')
|
|
||||||
}else{
|
|
||||||
new Error("SimulatedDownloadClient not support otherUrl")
|
|
||||||
}
|
|
||||||
|
|
||||||
let resClient = new ParseResClient();
|
|
||||||
resClient.loadResource(resource,(arraybuffer)=>{
|
|
||||||
console.log("SimulatedDownloadClient loadResource callback! ok")
|
|
||||||
if(request.progressFunc) {
|
|
||||||
request.progressFunc("100%")
|
|
||||||
}
|
|
||||||
onCompleteFunction(arraybuffer)
|
|
||||||
},onErrorFunction)
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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 PngCallback<R,T>{
|
|
||||||
(sender:R, receover:T)
|
|
||||||
}
|
|
|
@ -1,18 +0,0 @@
|
||||||
import {Closeable} from "/glide/pngj/io/Closeable"
|
|
||||||
import {ImageInfo} from "/glide/pngj/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;
|
|
||||||
public interlaced: boolean;
|
|
||||||
|
|
||||||
constructor(shouldCloseStream: boolean) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
close(): void {
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,59 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2021 Huawei Device Co., Ltd.
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
import arkWorker from '@ohos.worker';
|
|
||||||
import {UPNG} from '../../glide/pngj/UPNG'
|
|
||||||
|
|
||||||
export function handler (e) {
|
|
||||||
var data = e.data;
|
|
||||||
switch (data.type) {
|
|
||||||
case 'readPngImageAsync':
|
|
||||||
var png = UPNG.decode(data.data);
|
|
||||||
let array = png.data;
|
|
||||||
let arrayData = array.buffer.slice(array.byteOffset, array.byteLength + array.byteOffset)
|
|
||||||
png.data = arrayData;
|
|
||||||
let dataObj = { type: 'readPngImageAsync', data: png, receiver: data.data}
|
|
||||||
arkWorker.parentPort.postMessage(dataObj, [png.data, data.data]);
|
|
||||||
break;
|
|
||||||
case 'writePngWithStringAsync':
|
|
||||||
let addInfo = data.info;
|
|
||||||
let pngDecode = UPNG.decode(data.data);
|
|
||||||
let newPng = UPNG.encodeWithString(addInfo, UPNG.toRGBA8(pngDecode), pngDecode.width, pngDecode.height, 0)
|
|
||||||
let dataObj2 = { type: 'writePngWithStringAsync', data: newPng, receiver: data.data}
|
|
||||||
arkWorker.parentPort.postMessage(dataObj2, [newPng, data.data]);
|
|
||||||
break;
|
|
||||||
case 'writePngAsync':
|
|
||||||
let pngDecode3 = UPNG.decode(data.data);
|
|
||||||
let newPng3 = UPNG.encode(UPNG.toRGBA8(pngDecode3), pngDecode3.width, pngDecode3.height, 0)
|
|
||||||
let dataObj3 = { type: 'writePngAsync', data: newPng3, receiver: data.data}
|
|
||||||
arkWorker.parentPort.postMessage(dataObj3, [newPng3, data.data]);
|
|
||||||
break;
|
|
||||||
case 'normal':
|
|
||||||
arkWorker.parentPort.postMessage(data);
|
|
||||||
break;
|
|
||||||
case 'error':
|
|
||||||
throw new Error('123');
|
|
||||||
break;
|
|
||||||
case 'buffer':
|
|
||||||
let uint8Array = new Uint8Array(data.data);
|
|
||||||
arkWorker.parentPort.postMessage(data, [data.data]);
|
|
||||||
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -1,144 +0,0 @@
|
||||||
import {UPNG} from '../pngj/UPNG';
|
|
||||||
import {PngCallback} from '../pngj/PngCallback';
|
|
||||||
import image from '@ohos.multimedia.image';
|
|
||||||
import resourceManager from '@ohos.resourceManager';
|
|
||||||
import featureability from '@ohos.ability.featureAbility'
|
|
||||||
import ArkWorker from '@ohos.worker'
|
|
||||||
|
|
||||||
export class Pngj {
|
|
||||||
readPngImageInfo(arraybuffer: ArrayBuffer, callback:PngCallback<ArrayBuffer, any>) {
|
|
||||||
let imageSource = image.createImageSource(arraybuffer as any);
|
|
||||||
imageSource.getImageInfo((err, value) => {
|
|
||||||
if (err) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
callback(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<ArrayBuffer, any>) {
|
|
||||||
var png = UPNG.decode(pngBuffer);
|
|
||||||
callback(pngBuffer, png)
|
|
||||||
}
|
|
||||||
|
|
||||||
writePngWithString(addInfo:string, pngBuffer: ArrayBuffer,callback:PngCallback<ArrayBuffer, any>) {
|
|
||||||
var pngDecode = UPNG.decode(pngBuffer);
|
|
||||||
var newPng = UPNG.encodeWithString(addInfo, UPNG.toRGBA8(pngDecode), pngDecode.width, pngDecode.height, 0)
|
|
||||||
callback(pngBuffer, newPng);
|
|
||||||
}
|
|
||||||
|
|
||||||
writePng(pngBuffer: ArrayBuffer,callback:PngCallback<ArrayBuffer, any>) {
|
|
||||||
var pngDecode = UPNG.decode(pngBuffer);
|
|
||||||
var newPng = UPNG.encode(UPNG.toRGBA8(pngDecode), pngDecode.width, pngDecode.height, 0)
|
|
||||||
callback(pngBuffer, newPng);
|
|
||||||
}
|
|
||||||
|
|
||||||
readPngImageAsync(pngBuffer: ArrayBuffer, callback:PngCallback<ArrayBuffer, any>){
|
|
||||||
let worker = new ArkWorker.Worker('workers/worker1.js', { type: 'classic', name: 'readPngImageAsync'})
|
|
||||||
worker.onerror = function(data){
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
worker.onmessageerror = function(e){
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
worker.onexit = function(){
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
worker.onmessage = function(e) {
|
|
||||||
var data = e.data;
|
|
||||||
switch (data.type) {
|
|
||||||
case 'readPngImageAsync':
|
|
||||||
callback(data.receiver, data.data)
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break
|
|
||||||
}
|
|
||||||
worker.terminate();
|
|
||||||
}
|
|
||||||
|
|
||||||
var obj = { type: 'readPngImageAsync', data:pngBuffer}
|
|
||||||
worker.postMessage(obj, [pngBuffer])
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
writePngWithStringAsync(addInfo:string, pngBuffer:ArrayBuffer, callback:PngCallback<ArrayBuffer,any>) {
|
|
||||||
let worker = new ArkWorker.Worker('workers/worker1.js', { type: 'classic', name: 'writePngWithStringAsync'})
|
|
||||||
worker.onerror = function(data){
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
worker.onmessageerror = function(e){
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
worker.onexit = function(){
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
worker.onmessage = function(e) {
|
|
||||||
var data = e.data;
|
|
||||||
switch (data.type) {
|
|
||||||
case 'writePngWithStringAsync':
|
|
||||||
callback(data.receiver, data.data)
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break
|
|
||||||
}
|
|
||||||
worker.terminate();
|
|
||||||
}
|
|
||||||
|
|
||||||
var obj = { type: 'writePngWithStringAsync', data:pngBuffer, info: addInfo}
|
|
||||||
worker.postMessage(obj, [pngBuffer])
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
writePngAsync(pngBuffer:ArrayBuffer, callback:PngCallback<ArrayBuffer,any>) {
|
|
||||||
let worker = new ArkWorker.Worker('workers/worker1.js', { type: 'classic', name: 'writePngAsync'})
|
|
||||||
worker.onerror = function(data){
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
worker.onmessageerror = function(e){
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
worker.onexit = function(){
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
worker.onmessage = function(e) {
|
|
||||||
var data = e.data;
|
|
||||||
switch (data.type) {
|
|
||||||
case 'writePngAsync':
|
|
||||||
callback(data.receiver, data.data)
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break
|
|
||||||
}
|
|
||||||
worker.terminate();
|
|
||||||
}
|
|
||||||
|
|
||||||
var obj = { type: 'writePngAsync', data:pngBuffer}
|
|
||||||
worker.postMessage(obj, [pngBuffer])
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,5 +0,0 @@
|
||||||
export class PngjException extends Error {
|
|
||||||
constructor(s: string) {
|
|
||||||
super(s)
|
|
||||||
}
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,166 +0,0 @@
|
||||||
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;
|
|
||||||
var 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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,5 +0,0 @@
|
||||||
export interface IBytesConsumer {
|
|
||||||
isDone(): boolean;
|
|
||||||
|
|
||||||
consume(buf: ArrayBuffer, offset: number, len: number): number;
|
|
||||||
}
|
|
|
@ -1,3 +0,0 @@
|
||||||
export interface Closeable {
|
|
||||||
close(): void;
|
|
||||||
}
|
|
|
@ -1,7 +0,0 @@
|
||||||
export class Sandbox {
|
|
||||||
|
|
||||||
|
|
||||||
public static convert(origFileName: string, destFileName: string) {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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<string, ArrayBuffer> {
|
|
||||||
private mDiskLruCache: DiskLruCache;
|
|
||||||
|
|
||||||
constructor(diskLruCache: DiskLruCache) {
|
|
||||||
this.mDiskLruCache = diskLruCache;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 缓存类型
|
|
||||||
getName(): string{
|
|
||||||
return "Level2DiskCache";
|
|
||||||
}
|
|
||||||
|
|
||||||
getCachePath():string{
|
|
||||||
let folderPath = this.mDiskLruCache.dirPath
|
|
||||||
if (folderPath.endsWith('/')) {
|
|
||||||
return folderPath;
|
|
||||||
} else {
|
|
||||||
return folderPath + '/'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
getValue(key: string): ArrayBuffer{
|
|
||||||
return this.mDiskLruCache.getCacheDataByKey(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
putValue(key: string, value: ArrayBuffer) {
|
|
||||||
this.mDiskLruCache.putCacheData(key, value, null)
|
|
||||||
}
|
|
||||||
|
|
||||||
removeValue(key: string): ArrayBuffer{
|
|
||||||
// Disk暂无实现
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
clear() {
|
|
||||||
this.mDiskLruCache.cleanCacheData();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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<K, V> {
|
|
||||||
|
|
||||||
// 缓存类型
|
|
||||||
getName(): string
|
|
||||||
|
|
||||||
getValue(key: K): V;
|
|
||||||
|
|
||||||
putValue(key: K, value: V);
|
|
||||||
|
|
||||||
removeValue(key: K): V;
|
|
||||||
|
|
||||||
clear();
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
|
@ -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 {ICache} from "../requestmanage/ICache"
|
|
||||||
import {LruCache} from "../../cache/LruCache"
|
|
||||||
|
|
||||||
export class MemoryCacheProxy <K, V> implements ICache<K, V> {
|
|
||||||
private mLruCache: LruCache<K, V>;
|
|
||||||
|
|
||||||
constructor(lruCache: LruCache<K, V>) {
|
|
||||||
this.mLruCache = lruCache;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 缓存类型
|
|
||||||
getName() {
|
|
||||||
return "Level1MemoryCache"
|
|
||||||
}
|
|
||||||
|
|
||||||
getValue(key: K): V{
|
|
||||||
console.log("Level1MemoryCache getValue come in!");
|
|
||||||
return this.mLruCache.get(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
putValue(key: K, value: V) {
|
|
||||||
this.mLruCache.put(key, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
removeValue(key: K): V{
|
|
||||||
return this.mLruCache.remove(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
clear() {
|
|
||||||
this.mLruCache.evicAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// 外界调用
|
|
||||||
loadMemoryCache(key: K, isMemoryCacheable: boolean): V{
|
|
||||||
// 是否开启内存缓存
|
|
||||||
if (!isMemoryCacheable) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
let cached = this.getValue(key)
|
|
||||||
if (cached != null) {
|
|
||||||
return cached;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,582 +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 "../../glide/RequestOption"
|
|
||||||
import {DiskLruCache} from "../../cache/DiskLruCache"
|
|
||||||
import {LruCache} from "../../cache/LruCache"
|
|
||||||
import {FileUtils} from "../../cache/FileUtils"
|
|
||||||
import {Md5} from "../../cache/Md5"
|
|
||||||
import{MemoryCacheProxy} from "../requestmanage/MemoryCacheProxy"
|
|
||||||
import{DiskCacheProxy} from "../requestmanage/DiskCacheProxy"
|
|
||||||
import{FileTypeUtil} from "../utils/FileTypeUtil"
|
|
||||||
import{IDataFetch} from "../../glide/networkmanage/IDataFetch"
|
|
||||||
import{IResourceFetch} from "../../glide/resourcemanage/IResourceFetch"
|
|
||||||
import{GlideData} from "../GlideData"
|
|
||||||
import {AllCacheInfo, IAllCacheInfoCallback} from "../../glide/interface/iallcacheinfocallback"
|
|
||||||
import{ParseImageUtil} from '../utils/ParseImageUtil'
|
|
||||||
import{IParseImage} from '../interface/IParseImage'
|
|
||||||
import image from "@ohos.multimedia.image"
|
|
||||||
|
|
||||||
export interface AsyncString {
|
|
||||||
(data: string): void;
|
|
||||||
}
|
|
||||||
|
|
||||||
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 mMemoryCacheProxy: MemoryCacheProxy<string, any>;
|
|
||||||
private mDiskCacheProxy: DiskCacheProxy;
|
|
||||||
private mIDataFetch: IDataFetch;
|
|
||||||
private mIResourceFetch: IResourceFetch;
|
|
||||||
private mParseImageUtil: IParseImage;
|
|
||||||
|
|
||||||
constructor(option: RequestOption, memoryCache1: LruCache<string, any>, diskMemoryCache1: DiskLruCache, dataFetch: IDataFetch, resourceFetch: IResourceFetch) {
|
|
||||||
this.options = option;
|
|
||||||
|
|
||||||
// 缓存部分
|
|
||||||
this.mMemoryCacheProxy = new MemoryCacheProxy(memoryCache1);
|
|
||||||
this.mDiskCacheProxy = new DiskCacheProxy(diskMemoryCache1);
|
|
||||||
|
|
||||||
// 网络下载能力
|
|
||||||
this.mIDataFetch = dataFetch;
|
|
||||||
|
|
||||||
// 本地数据解析能力
|
|
||||||
this.mIResourceFetch = resourceFetch;
|
|
||||||
|
|
||||||
// 解析image能力
|
|
||||||
this.mParseImageUtil = new ParseImageUtil();
|
|
||||||
}
|
|
||||||
|
|
||||||
static execute(option: RequestOption, memoryCache1: LruCache<string, any>, diskMemoryCache1: DiskLruCache, dataFetch: IDataFetch, resourceFetch: IResourceFetch) {
|
|
||||||
console.log("RequestManager execute")
|
|
||||||
let manager = new RequestManager(option, memoryCache1, diskMemoryCache1, dataFetch, resourceFetch);
|
|
||||||
return new Promise<PixelMap>(manager.process.bind(manager))
|
|
||||||
.then(option.loadComplete.bind(option))
|
|
||||||
.then(manager.loadCompleteAfter.bind(manager))
|
|
||||||
.catch(option.loadError.bind(option));
|
|
||||||
}
|
|
||||||
|
|
||||||
loadCompleteAfter() {
|
|
||||||
try { // 内部消化问题
|
|
||||||
console.log("loadCompleteAfter!")
|
|
||||||
if (this.options.allCacheInfoCallback) {
|
|
||||||
console.log("RequestOption =" + JSON.stringify(this.options));
|
|
||||||
|
|
||||||
// 内存缓存
|
|
||||||
let allCacheInfo = new AllCacheInfo();
|
|
||||||
let memoryCache = this.mMemoryCacheProxy.getValue(this.options.generateCacheKey);
|
|
||||||
allCacheInfo.memoryCacheInfo = {
|
|
||||||
key: this.options.generateCacheKey,
|
|
||||||
data: memoryCache
|
|
||||||
}
|
|
||||||
|
|
||||||
// 变换后缓存
|
|
||||||
allCacheInfo.resourceCacheInfo = {
|
|
||||||
key: Md5.hashStr(this.options.generateResourceKey),
|
|
||||||
path: (this.mDiskCacheProxy.getCachePath() + Md5.hashStr(this.options.generateResourceKey))
|
|
||||||
};
|
|
||||||
|
|
||||||
// 原图缓存
|
|
||||||
allCacheInfo.dataCacheInfo = {
|
|
||||||
key: Md5.hashStr(this.options.generateDataKey),
|
|
||||||
path: this.mDiskCacheProxy.getCachePath() + Md5.hashStr(this.options.generateDataKey)
|
|
||||||
}
|
|
||||||
this.options.allCacheInfoCallback(allCacheInfo)
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
console.log("after err =" + err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// DecodeJob work
|
|
||||||
private mStage: Stage = Stage.INITIALIZE;
|
|
||||||
private mRunReason: RunReason = RunReason.INITIALIZE;
|
|
||||||
|
|
||||||
process(onComplete, onError) {
|
|
||||||
console.log("RequestManager process !");
|
|
||||||
this.loadLeve1MemoryCache(onComplete, onError)
|
|
||||||
}
|
|
||||||
|
|
||||||
private runWrapped(request: RequestOption, runReason: RunReason, onComplete, onError) {
|
|
||||||
console.log("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("Unrecognized stage: " + current);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//究竟从哪里加载数据
|
|
||||||
private searchLoadFrom(request: RequestOption, current: Stage, onComplete, onError) {
|
|
||||||
console.log("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, onError) {
|
|
||||||
let success = (arraybuffer) => {
|
|
||||||
this.downloadSuccess(arraybuffer, onComplete, onError)
|
|
||||||
}
|
|
||||||
this.mIDataFetch.loadData(request, success, onError);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 加载本地资源
|
|
||||||
private loadSourceFormNative(request: RequestOption, onComplete, onError) {
|
|
||||||
console.log("RequestManager loadSourceFormNative")
|
|
||||||
// 本地解析后进行一级缓存
|
|
||||||
let success = (arrayBuffer) => {
|
|
||||||
// 使用媒体子系统 ImageSource解析文件 获取PixelMap
|
|
||||||
let fileTypeUtil = new FileTypeUtil();
|
|
||||||
let typeValue = fileTypeUtil.getFileType(arrayBuffer)
|
|
||||||
console.log("RequstManager - 文件类型为= " + typeValue)
|
|
||||||
if ((GlideData.GIF == typeValue && !request.dontAnimateFlag) || GlideData.SVG == typeValue) {
|
|
||||||
// 将图片资源 转换为文件地址
|
|
||||||
let folderPath = this.options.getFilesPath() + "/" + this.options._svgAndGifFolder;
|
|
||||||
let filePath = this.options.getFilesPath() + "/" + this.options._svgAndGifFolder + "/"
|
|
||||||
+ Md5.hashStr(this.options.generateDataKey) + "." + typeValue;
|
|
||||||
let filename = Md5.hashStr(this.options.generateDataKey) + "." + typeValue;
|
|
||||||
new Promise((resolve, reject) => {
|
|
||||||
// 存文件至svg目录,并且记录文件名
|
|
||||||
resolve("svg gif 文件开始本地保存!");
|
|
||||||
})
|
|
||||||
.then((res) => {
|
|
||||||
// 创建文件
|
|
||||||
FileUtils.getInstance()
|
|
||||||
.createFileProcess(folderPath, filePath, arrayBuffer);
|
|
||||||
// 写入记录
|
|
||||||
FileUtils.getInstance()
|
|
||||||
.writeData(this.options.getFilesPath() +
|
|
||||||
"/" + this.options._svgAndGifFolder + "/" + this.options._svgAndGifCommitFile, filename + "\n");
|
|
||||||
console.log("svg gif 本地保存成功 输出!");
|
|
||||||
let glidedata = this.createGlideData(GlideData.STRING, filePath, typeValue);
|
|
||||||
this.mMemoryCacheProxy.putValue(this.options.generateCacheKey, glidedata);
|
|
||||||
onComplete(glidedata);
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
onError(err)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (request.transformtions[0]) {
|
|
||||||
request.transformtions[0].transform(arrayBuffer, request, (error, pixelMap: PixelMap) => {
|
|
||||||
// 输出给Image
|
|
||||||
if (pixelMap) {
|
|
||||||
let glidedata = this.createGlideData(GlideData.PIXELMAP, pixelMap, typeValue);
|
|
||||||
this.mMemoryCacheProxy.putValue(request.generateCacheKey, glidedata);
|
|
||||||
onComplete(glidedata);
|
|
||||||
} else {
|
|
||||||
onError(error);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
let success = (value: PixelMap) => {
|
|
||||||
let glidedata = this.createGlideData(GlideData.PIXELMAP, value, typeValue);
|
|
||||||
this.mMemoryCacheProxy.putValue(request.generateCacheKey, glidedata);
|
|
||||||
onComplete(glidedata);
|
|
||||||
}
|
|
||||||
this.mParseImageUtil.parseImage(arrayBuffer, success, onError)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.mIResourceFetch.loadResource(request.loadSrc as Resource, success, onError);
|
|
||||||
}
|
|
||||||
// 加载磁盘缓存 原图
|
|
||||||
private loadDiskFromSource(request: RequestOption, onComplete, onError) {
|
|
||||||
console.log("RequestManager loadDiskFromSource")
|
|
||||||
let cached = this.mDiskCacheProxy.getValue(request.generateDataKey)
|
|
||||||
if (cached != null) {
|
|
||||||
this.parseDiskFile2PixelMap(request, cached, onComplete, onError)
|
|
||||||
} else {
|
|
||||||
this.mStage = Stage.SOURCE;
|
|
||||||
this.searchLoadFrom(this.options, this.mStage, onComplete, onError);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 加载磁盘缓存 变换后图片
|
|
||||||
private loadDiskFromTransform(request: RequestOption, onComplete, onError) {
|
|
||||||
console.log("RequestManager loadDiskFromTransform")
|
|
||||||
let cached = this.mDiskCacheProxy.getValue(request.generateResourceKey)
|
|
||||||
if (cached != null) {
|
|
||||||
this.parseDiskTransformFile2PixelMap(request, cached, onComplete, onError)
|
|
||||||
} else {
|
|
||||||
this.mStage = Stage.DATA_CACHE;
|
|
||||||
this.searchLoadFrom(this.options, this.mStage, onComplete, onError);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
parseSource(request: RequestOption, onComplete, onError) {
|
|
||||||
console.log("RequestManager parseSource")
|
|
||||||
if (request.loadSrc instanceof image.PixelMap) {
|
|
||||||
// PixelMap 外层捕获效率更高,不会进入这里
|
|
||||||
} else if (typeof request.loadSrc == 'string') {
|
|
||||||
this.loadSourceFromNetwork(request, onComplete, onError);
|
|
||||||
} else {
|
|
||||||
let res = request.loadSrc as Resource;
|
|
||||||
if (typeof res.id != 'undefined' && typeof res.id != 'undefined') {
|
|
||||||
this.loadSourceFormNative(request, onComplete, onError)
|
|
||||||
} else {
|
|
||||||
console.log("输入参数有问题!")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private loadLeve1MemoryCache(onComplete, onError) {
|
|
||||||
console.log("RequestManager loadLeve1MemoryCache")
|
|
||||||
// 一级缓存 内存获取
|
|
||||||
let cache = this.mMemoryCacheProxy.loadMemoryCache(this.options.generateCacheKey, this.options.isCacheable);
|
|
||||||
if (cache == null || typeof cache == 'undefined') {
|
|
||||||
// 处理磁盘加载 网络加载
|
|
||||||
this.runWrapped(this.options, this.mRunReason, onComplete, onError)
|
|
||||||
} else {
|
|
||||||
onComplete(cache);
|
|
||||||
return
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 解析磁盘文件变成PixeMap
|
|
||||||
private parseDiskFile2PixelMap(request: RequestOption, source: ArrayBuffer, onComplete, onError) {
|
|
||||||
// 步骤一:文件转为pixelMap 然后变换 给Image组件
|
|
||||||
let fileTypeUtil = new FileTypeUtil();
|
|
||||||
let typeValue = fileTypeUtil.getFileType(source);
|
|
||||||
if (((GlideData.GIF == typeValue && !request.dontAnimateFlag) || GlideData.SVG == typeValue)) {
|
|
||||||
// 将图片资源 转换为文件地址
|
|
||||||
let folderPath = this.options.getFilesPath() + "/" + this.options._svgAndGifFolder;
|
|
||||||
let filePath = this.options.getFilesPath() + "/" + this.options._svgAndGifFolder + "/"
|
|
||||||
+ Md5.hashStr(this.options.generateDataKey) + "." + typeValue;
|
|
||||||
let filename = Md5.hashStr(this.options.generateDataKey) + "." + typeValue;
|
|
||||||
new Promise((resolve, reject) => {
|
|
||||||
// 存文件至svg目录,并且记录文件名
|
|
||||||
resolve("svg gif 文件开始本地保存!");
|
|
||||||
}).then((res) => {
|
|
||||||
FileUtils.getInstance()
|
|
||||||
.createFileProcess(folderPath, filePath, source);
|
|
||||||
FileUtils.getInstance()
|
|
||||||
.writeData(this.options.getFilesPath() +
|
|
||||||
"/" + this.options._svgAndGifFolder + "/" + this.options._svgAndGifCommitFile, filename + "\n");
|
|
||||||
let glidedata = this.createGlideData(GlideData.STRING, filePath, typeValue)
|
|
||||||
this.mMemoryCacheProxy.putValue(this.options.generateCacheKey, glidedata);
|
|
||||||
onComplete(glidedata);
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
onError(err)
|
|
||||||
})
|
|
||||||
|
|
||||||
} else {
|
|
||||||
if (this.options.transformtions[0]) {
|
|
||||||
if (this.options.thumbSizeMultiplier) {
|
|
||||||
let thumbOption = 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 thumbCallback = this.options.thumbholderOnComplete.bind(this.options);
|
|
||||||
let thumbError = this.options.thumbholderOnError.bind(this.options);
|
|
||||||
this.options.transformtions[0].transform(source, thumbOption, (error, pixelMap: PixelMap) => {
|
|
||||||
if (pixelMap) {
|
|
||||||
let glidedata = this.createGlideData(GlideData.PIXELMAP, pixelMap, typeValue);
|
|
||||||
thumbCallback(glidedata);
|
|
||||||
} else {
|
|
||||||
thumbError(error);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
setTimeout(()=>{
|
|
||||||
this.options.transformtions[0].transform(source, request, (error, pixelMap: PixelMap) => {
|
|
||||||
if (pixelMap) {
|
|
||||||
// 保存一份变换后的图片PixelMap到MemoryCache
|
|
||||||
let glidedata = this.createGlideData(GlideData.PIXELMAP, pixelMap, typeValue);
|
|
||||||
this.mMemoryCacheProxy.putValue(this.options.generateCacheKey, glidedata);
|
|
||||||
onComplete(glidedata);
|
|
||||||
} else {
|
|
||||||
onError(error);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},this.options.thumbDelayTime);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.options.transformtions[0].transform(source, request, (error, pixelMap: PixelMap) => {
|
|
||||||
if (pixelMap) {
|
|
||||||
// 保存一份变换后的图片PixelMap到MemoryCache
|
|
||||||
let glidedata = this.createGlideData(GlideData.PIXELMAP, pixelMap, typeValue);
|
|
||||||
this.mMemoryCacheProxy.putValue(this.options.generateCacheKey, glidedata);
|
|
||||||
onComplete(glidedata);
|
|
||||||
} else {
|
|
||||||
onError(error);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// thumbnail 缩略图部分
|
|
||||||
if (request.thumbSizeMultiplier) {
|
|
||||||
let thumbCallback = this.options.thumbholderOnComplete.bind(this.options);
|
|
||||||
let thumbError = this.options.thumbholderOnError.bind(this.options);
|
|
||||||
let thumbSuccess = (value: PixelMap) => {
|
|
||||||
let glidedata = this.createGlideData(GlideData.PIXELMAP, value, typeValue);
|
|
||||||
thumbCallback(glidedata);
|
|
||||||
}
|
|
||||||
this.mParseImageUtil.parseImageThumbnail(request.thumbSizeMultiplier, source, thumbSuccess, thumbError);
|
|
||||||
setTimeout(()=>{
|
|
||||||
let success = (value: PixelMap) => {
|
|
||||||
let glidedata = this.createGlideData(GlideData.PIXELMAP, value, typeValue);
|
|
||||||
this.mMemoryCacheProxy.putValue(this.options.generateCacheKey, glidedata);
|
|
||||||
onComplete(glidedata);
|
|
||||||
}
|
|
||||||
this.mParseImageUtil.parseImage(source, success, onError)
|
|
||||||
},this.options.thumbDelayTime)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
let success = (value: PixelMap) => {
|
|
||||||
let glidedata = this.createGlideData(GlideData.PIXELMAP, value, typeValue);
|
|
||||||
this.mMemoryCacheProxy.putValue(this.options.generateCacheKey, glidedata);
|
|
||||||
onComplete(glidedata);
|
|
||||||
}
|
|
||||||
this.mParseImageUtil.parseImage(source, success, onError)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 解析磁盘变换后文件变成PixeMap
|
|
||||||
private parseDiskTransformFile2PixelMap(request: RequestOption, source: ArrayBuffer, onComplete, onError) {
|
|
||||||
let fileTypeUtil = new FileTypeUtil();
|
|
||||||
let typeValue = fileTypeUtil.getFileType(source);
|
|
||||||
// thumbnail 缩略图部分
|
|
||||||
if (request.thumbSizeMultiplier) {
|
|
||||||
let thumbCallback = this.options.thumbholderOnComplete.bind(this.options);
|
|
||||||
let thumbError = this.options.thumbholderOnError.bind(this.options);
|
|
||||||
let thumbSuccess = (value: PixelMap) => {
|
|
||||||
let glidedata = this.createGlideData(GlideData.PIXELMAP, value, typeValue);
|
|
||||||
thumbCallback(glidedata);
|
|
||||||
}
|
|
||||||
this.mParseImageUtil.parseImageThumbnail(request.thumbSizeMultiplier, source, thumbSuccess, thumbError);
|
|
||||||
setTimeout(()=>{
|
|
||||||
let success = (value: PixelMap) => {
|
|
||||||
let glidedata = this.createGlideData(GlideData.PIXELMAP, value, typeValue);
|
|
||||||
this.mMemoryCacheProxy.putValue(this.options.generateCacheKey, glidedata);
|
|
||||||
onComplete(glidedata);
|
|
||||||
}
|
|
||||||
this.mParseImageUtil.parseImage(source, success, onError)
|
|
||||||
},this.options.thumbDelayTime)
|
|
||||||
}else{
|
|
||||||
let success = (value: PixelMap) => {
|
|
||||||
let glidedata = this.createGlideData(GlideData.PIXELMAP, value, typeValue)
|
|
||||||
this.mMemoryCacheProxy.putValue(this.options.generateCacheKey, glidedata);
|
|
||||||
onComplete(glidedata);
|
|
||||||
}
|
|
||||||
this.mParseImageUtil.parseImage(source, success, onError)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private downloadSuccess(source: ArrayBuffer, onComplete, onError) {
|
|
||||||
console.info('Download task completed.');
|
|
||||||
|
|
||||||
// 下载成功之后 去data/data/包名/唯一路径/文件名 读取数据
|
|
||||||
// 步骤一:文件转为pixelMap 然后变换 给Image组件
|
|
||||||
// 步骤二: 文件名保存一份全局
|
|
||||||
// 步骤三:查看文件是否支持 非支持类型直接返回
|
|
||||||
let fileTypeUtil = new FileTypeUtil();
|
|
||||||
let filetype = fileTypeUtil.getFileType(source);
|
|
||||||
if (!fileTypeUtil.isImage(source)) {
|
|
||||||
onError("暂不支持 下载文件类型!类型=" + filetype);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if ((GlideData.GIF == filetype && !this.options.dontAnimateFlag) || GlideData.SVG == filetype) {
|
|
||||||
// 将图片资源 转换为文件地址
|
|
||||||
let folderPath = this.options.getFilesPath() + "/" + this.options._svgAndGifFolder;
|
|
||||||
let filePath = this.options.getFilesPath() + "/" + this.options._svgAndGifFolder + "/"
|
|
||||||
+ Md5.hashStr(this.options.generateDataKey) + "." + filetype;
|
|
||||||
let filename = Md5.hashStr(this.options.generateDataKey) + "." + filetype;
|
|
||||||
// 1.文件保存 2.内存缓存 3.输出结果
|
|
||||||
new Promise((resolve, reject) => {
|
|
||||||
// 存文件至svg目录,并且记录文件名
|
|
||||||
resolve("svg gif 文件开始本地保存!");
|
|
||||||
})
|
|
||||||
.then((res) => {
|
|
||||||
FileUtils.getInstance()
|
|
||||||
.createFileProcess(folderPath, filePath, source);
|
|
||||||
FileUtils.getInstance()
|
|
||||||
.writeData(this.options.getFilesPath() +
|
|
||||||
"/" + this.options._svgAndGifFolder + "/" + this.options._svgAndGifCommitFile, filename + "\n");
|
|
||||||
let glidedata = this.createGlideData(GlideData.STRING, filePath, filetype);
|
|
||||||
this.mMemoryCacheProxy.putValue(this.options.generateCacheKey, glidedata);
|
|
||||||
onComplete(glidedata);
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
onError(err)
|
|
||||||
})
|
|
||||||
|
|
||||||
// 保存二级磁盘缓存
|
|
||||||
new Promise((resolve, reject) => {
|
|
||||||
resolve(source)
|
|
||||||
})
|
|
||||||
.then((arraybuffer: ArrayBuffer) => {
|
|
||||||
this.mDiskCacheProxy.putValue(this.options.generateDataKey, arraybuffer)
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
console.log("err=" + err);
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
// 进行变换
|
|
||||||
if (this.options.transformtions[0]) {
|
|
||||||
// thumbnail 缩略图部分
|
|
||||||
if (this.options.thumbSizeMultiplier) {
|
|
||||||
this.thumbnailProcess(source, filetype, onComplete, onError);
|
|
||||||
} else {
|
|
||||||
this.options.transformtions[0].transform(source, this.options, (error, pixelMap: PixelMap) => {
|
|
||||||
if (pixelMap) {
|
|
||||||
this.saveCacheAndDisk(pixelMap, filetype, onComplete, source);
|
|
||||||
} else {
|
|
||||||
onError(error);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// thumbnail 缩略图部分
|
|
||||||
if (this.options.thumbSizeMultiplier) {
|
|
||||||
let thumbCallback = this.options.thumbholderOnComplete.bind(this.options);
|
|
||||||
let thumbError = this.options.thumbholderOnError.bind(this.options);
|
|
||||||
let thumbSuccess = (value: PixelMap) => {
|
|
||||||
let glidedata = this.createGlideData(GlideData.PIXELMAP, value, filetype);
|
|
||||||
thumbCallback(glidedata);
|
|
||||||
}
|
|
||||||
this.mParseImageUtil.parseImageThumbnail(this.options.thumbSizeMultiplier, source, thumbSuccess, thumbError);
|
|
||||||
setTimeout(() => {
|
|
||||||
let success = (value: PixelMap) => {
|
|
||||||
this.saveCacheAndDisk(value, filetype, onComplete, source);
|
|
||||||
}
|
|
||||||
this.mParseImageUtil.parseImage(source, success, onError)
|
|
||||||
}, this.options.thumbDelayTime)
|
|
||||||
} else {
|
|
||||||
let success = (value: PixelMap) => {
|
|
||||||
this.saveCacheAndDisk(value, filetype, onComplete, source);
|
|
||||||
}
|
|
||||||
this.mParseImageUtil.parseImage(source, success, onError)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
createGlideData(glideType:string, glideValue:PixelMap|string|Resource, glideSourceType:string):GlideData{
|
|
||||||
let glidedata = new GlideData();
|
|
||||||
glidedata.glideType = glideType;
|
|
||||||
glidedata.glideValue = glideValue;
|
|
||||||
glidedata.glideSourceType = glideSourceType;
|
|
||||||
return glidedata;
|
|
||||||
}
|
|
||||||
|
|
||||||
private saveCacheAndDisk(value: PixelMap, filetype:string, onComplete, source:ArrayBuffer){
|
|
||||||
let glidedata = this.createGlideData(GlideData.PIXELMAP, value, filetype);
|
|
||||||
this.mMemoryCacheProxy.putValue(this.options.generateCacheKey, glidedata);
|
|
||||||
let save2DiskCache = (arraybuffer) => {
|
|
||||||
this.mDiskCacheProxy.putValue(this.options.generateDataKey, arraybuffer)
|
|
||||||
}
|
|
||||||
let runSave2Disk = (resolve, reject) => {
|
|
||||||
resolve(source);
|
|
||||||
}
|
|
||||||
let promise = new Promise(runSave2Disk);
|
|
||||||
promise.then(save2DiskCache);
|
|
||||||
onComplete(glidedata);
|
|
||||||
}
|
|
||||||
|
|
||||||
thumbnailProcess(source:ArrayBuffer, filetype:string, onComplete, onError){
|
|
||||||
let thumbOption = 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 thumbCallback = this.options.thumbholderOnComplete.bind(this.options);
|
|
||||||
let thumbError = this.options.thumbholderOnError.bind(this.options);
|
|
||||||
this.options.transformtions[0].transform(source, thumbOption, (error, pixelMap: PixelMap) => {
|
|
||||||
if (pixelMap) {
|
|
||||||
let glidedata = this.createGlideData(GlideData.PIXELMAP, pixelMap, filetype);
|
|
||||||
thumbCallback(glidedata);
|
|
||||||
} else {
|
|
||||||
thumbError(error);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
setTimeout(() => {
|
|
||||||
this.options.transformtions[0].transform(source, this.options, (error, pixelMap: PixelMap) => {
|
|
||||||
if (pixelMap) {
|
|
||||||
this.saveCacheAndDisk(pixelMap, filetype, onComplete, source);
|
|
||||||
} else {
|
|
||||||
onError(error);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}, this.options.thumbDelayTime)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -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 IResourceFetch {
|
|
||||||
loadResource(res: Resource, onCompleteFunction, onErrorFunction);
|
|
||||||
}
|
|
|
@ -1,48 +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 '../../glide/constants/ResourceTypeEts'
|
|
||||||
|
|
||||||
import resourceManager from '@ohos.resourceManager';
|
|
||||||
|
|
||||||
export class ParseResClient implements IResourceFetch {
|
|
||||||
loadResource(res: Resource, onCompleteFunction, onErrorFunction) {
|
|
||||||
let resId = res.id;
|
|
||||||
let resType = res.type;
|
|
||||||
if (resType == ResourceTypeEts.MEDIA) {
|
|
||||||
resourceManager.getResourceManager()
|
|
||||||
.then(result => {
|
|
||||||
result.getMedia(resId)
|
|
||||||
.then(data => {
|
|
||||||
let arrayBuffer = this.typedArrayToBuffer(data);
|
|
||||||
onCompleteFunction(arrayBuffer)
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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 {IResourceFetch} from '../resourcemanage/IResourceFetch'
|
|
||||||
import {ResourceTypeEts} from '../../glide/constants/ResourceTypeEts'
|
|
||||||
import {Base64} from '../../cache/Base64'
|
|
||||||
|
|
||||||
import resourceManager from '@ohos.resourceManager';
|
|
||||||
|
|
||||||
export class ParseResClientBase64 implements IResourceFetch {
|
|
||||||
loadResource(res: Resource, onCompleteFunction, onErrorFunction) {
|
|
||||||
let resId = res.id;
|
|
||||||
let resType = res.type;
|
|
||||||
if (resType == ResourceTypeEts.MEDIA) {
|
|
||||||
resourceManager.getResourceManager()
|
|
||||||
.then(result => {
|
|
||||||
result.getMediaBase64(resId)
|
|
||||||
.then(data => {
|
|
||||||
let matchReg = ';base64,';
|
|
||||||
var firstIndex = data.indexOf(matchReg)
|
|
||||||
data = data.substring(firstIndex + matchReg.length, data.length)
|
|
||||||
let arrayBuffer = Base64.getInstance()
|
|
||||||
.decode(data);
|
|
||||||
onCompleteFunction(arrayBuffer)
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
onErrorFunction(err)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
else if (resType == ResourceTypeEts.RAWFILE) {
|
|
||||||
onErrorFunction('ParseResClientBase64 本地资源是rawfile暂时无法解析出错')
|
|
||||||
} else {
|
|
||||||
onErrorFunction('ParseResClientBase64 本地资源不是media也不是rawfile无法解析出错')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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 AsyncTransform<T> {
|
|
||||||
(err, data: T)
|
|
||||||
}
|
|
|
@ -1,24 +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 "../../glide/RequestOption"
|
|
||||||
|
|
||||||
export interface BaseTransform<T> {
|
|
||||||
//实现类 返回作为key生成的一部分
|
|
||||||
getName(): string;
|
|
||||||
|
|
||||||
transform(value: ArrayBuffer, request: RequestOption, func: AsyncTransform<T>);
|
|
||||||
}
|
|
|
@ -1,81 +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.ets"
|
|
||||||
import {AsyncTransform} from "../transform/AsyncTransform.ets"
|
|
||||||
import {Constants} from "../constants/Constants.ets"
|
|
||||||
import {RequestOption} from "../../glide/RequestOption.ets"
|
|
||||||
import {TransformUtils} from "../transform/TransformUtils.ets"
|
|
||||||
import image from "@ohos.multimedia.image"
|
|
||||||
import {fastBlur} from "../utils/FastBlur"
|
|
||||||
|
|
||||||
|
|
||||||
export class BlurTransformation implements BaseTransform<PixelMap> {
|
|
||||||
private _mRadius: number;
|
|
||||||
|
|
||||||
constructor(radius: number) {
|
|
||||||
this._mRadius = radius;
|
|
||||||
}
|
|
||||||
|
|
||||||
getName() {
|
|
||||||
return "BlurTransformation _mRadius:" + this._mRadius;
|
|
||||||
}
|
|
||||||
|
|
||||||
transform(buf: ArrayBuffer, request: RequestOption, func?: AsyncTransform<PixelMap>) {
|
|
||||||
if (!buf || buf.byteLength <= 0) {
|
|
||||||
console.log(Constants.PROJECT_TAG + ";BlurTransformation buf is empty");
|
|
||||||
if (func) {
|
|
||||||
func(Constants.PROJECT_TAG + ";BlurTransformation buf is empty", null);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var imageSource = image.createImageSource(buf as any);
|
|
||||||
TransformUtils.getPixelMapSize(imageSource, (error, size: {
|
|
||||||
width: number,
|
|
||||||
height: number
|
|
||||||
}) => {
|
|
||||||
if (!size) {
|
|
||||||
func(error, null)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var pixelMapWidth = size.width;
|
|
||||||
var pixelMapHeight = size.height;
|
|
||||||
var targetWidth = request.size.width;
|
|
||||||
var targetHeight = request.size.height;
|
|
||||||
if (pixelMapWidth < targetWidth) {
|
|
||||||
targetWidth = pixelMapWidth;
|
|
||||||
}
|
|
||||||
if (pixelMapHeight < targetHeight) {
|
|
||||||
targetHeight = pixelMapHeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
var options = {
|
|
||||||
editable: true,
|
|
||||||
desiredSize: {
|
|
||||||
width: targetWidth,
|
|
||||||
height: targetHeight
|
|
||||||
}
|
|
||||||
}
|
|
||||||
imageSource.createPixelMap(options)
|
|
||||||
.then((data) => {
|
|
||||||
fastBlur.blur(data, this._mRadius, true, func);
|
|
||||||
})
|
|
||||||
.catch((e) => {
|
|
||||||
console.log(Constants.PROJECT_TAG + ";error:" + e);
|
|
||||||
func(e, null);
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,105 +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.ets"
|
|
||||||
import {AsyncTransform} from "../transform/AsyncTransform.ets"
|
|
||||||
import {Constants} from "../constants/Constants.ets"
|
|
||||||
import {RequestOption} from "../../glide/RequestOption.ets"
|
|
||||||
import image from "@ohos.multimedia.image"
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* brightness value ranges from -1.0 to 1.0, with 0.0 as the normal level
|
|
||||||
*/
|
|
||||||
export class BrightnessFilterTransformation implements BaseTransform<PixelMap> {
|
|
||||||
private _mBrightness: number= 0.0;
|
|
||||||
|
|
||||||
constructor(brightness: number) {
|
|
||||||
this._mBrightness = brightness;
|
|
||||||
}
|
|
||||||
|
|
||||||
getName() {
|
|
||||||
return "BrightnessFilterTransformation:" + this._mBrightness;
|
|
||||||
}
|
|
||||||
|
|
||||||
async transform(buf: ArrayBuffer, request: RequestOption, func?: AsyncTransform<PixelMap>) {
|
|
||||||
if (!buf || buf.byteLength <= 0) {
|
|
||||||
console.log(Constants.PROJECT_TAG + ";GrayscaleTransformation buf is empty");
|
|
||||||
if (func) {
|
|
||||||
func(Constants.PROJECT_TAG + ";GrayscaleTransformation buf is empty", null);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var imageSource = image.createImageSource(buf as any);
|
|
||||||
|
|
||||||
let imageInfo = await imageSource.getImageInfo();
|
|
||||||
let size = {
|
|
||||||
width: imageInfo.size.width,
|
|
||||||
height: imageInfo.size.height
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!size) {
|
|
||||||
func(new Error("GrayscaleTransformation The image size does not exist."), null)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var pixelMapWidth = size.width;
|
|
||||||
var pixelMapHeight = size.height;
|
|
||||||
var targetWidth = request.size.width;
|
|
||||||
var targetHeight = request.size.height;
|
|
||||||
if (pixelMapWidth < targetWidth) {
|
|
||||||
targetWidth = pixelMapWidth;
|
|
||||||
}
|
|
||||||
if (pixelMapHeight < targetHeight) {
|
|
||||||
targetHeight = pixelMapHeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
var options = {
|
|
||||||
editable: true,
|
|
||||||
desiredSize: {
|
|
||||||
width: targetWidth,
|
|
||||||
height: targetHeight
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let data = await imageSource.createPixelMap(options);
|
|
||||||
|
|
||||||
let bufferData = new ArrayBuffer(data.getPixelBytesNumber());
|
|
||||||
await data.readPixelsToBuffer(bufferData);
|
|
||||||
|
|
||||||
var 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("", data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private checkVisAble(input: number) {
|
|
||||||
if (input > 255) {
|
|
||||||
input = 255;
|
|
||||||
}
|
|
||||||
if (input <= 0) {
|
|
||||||
input = 0;
|
|
||||||
}
|
|
||||||
return input;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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.ets"
|
|
||||||
import {AsyncTransform} from "../transform/AsyncTransform.ets"
|
|
||||||
import {Constants} from "../constants/Constants.ets"
|
|
||||||
import {RequestOption} from "../../glide/RequestOption.ets"
|
|
||||||
import image from "@ohos.multimedia.image"
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 以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<PixelMap> {
|
|
||||||
private _mContrast: number;
|
|
||||||
|
|
||||||
constructor(contrast: number) {
|
|
||||||
this._mContrast = contrast;
|
|
||||||
}
|
|
||||||
|
|
||||||
getName() {
|
|
||||||
return "ContrastFilterTransformation:" + this._mContrast;
|
|
||||||
}
|
|
||||||
|
|
||||||
async transform(buf: ArrayBuffer, request: RequestOption, func?: AsyncTransform<PixelMap>) {
|
|
||||||
if (!buf || buf.byteLength <= 0) {
|
|
||||||
console.log(Constants.PROJECT_TAG + ";ContrastFilterTransformation buf is empty");
|
|
||||||
if (func) {
|
|
||||||
func(Constants.PROJECT_TAG + ";ContrastFilterTransformation buf is empty", null);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var imageSource = image.createImageSource(buf as any);
|
|
||||||
|
|
||||||
let imageInfo = await imageSource.getImageInfo();
|
|
||||||
let size = {
|
|
||||||
width: imageInfo.size.width,
|
|
||||||
height: imageInfo.size.height
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!size) {
|
|
||||||
func(new Error("ContrastFilterTransformation The image size does not exist."), null)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var pixelMapWidth = size.width;
|
|
||||||
var pixelMapHeight = size.height;
|
|
||||||
var targetWidth = request.size.width;
|
|
||||||
var targetHeight = request.size.height;
|
|
||||||
if (pixelMapWidth < targetWidth) {
|
|
||||||
targetWidth = pixelMapWidth;
|
|
||||||
}
|
|
||||||
if (pixelMapHeight < targetHeight) {
|
|
||||||
targetHeight = pixelMapHeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
var options = {
|
|
||||||
editable: true,
|
|
||||||
desiredSize: {
|
|
||||||
width: targetWidth,
|
|
||||||
height: targetHeight
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let data = await imageSource.createPixelMap(options);
|
|
||||||
|
|
||||||
let bufferData = new ArrayBuffer(data.getPixelBytesNumber());
|
|
||||||
await data.readPixelsToBuffer(bufferData);
|
|
||||||
|
|
||||||
var 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) {
|
|
||||||
func("", data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private checkVisAble(input: number) {
|
|
||||||
if (input > 255) {
|
|
||||||
input = 255;
|
|
||||||
}
|
|
||||||
if (input <= 0) {
|
|
||||||
input = 0;
|
|
||||||
}
|
|
||||||
return input;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,139 +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.ets"
|
|
||||||
import {AsyncTransform} from "../transform/AsyncTransform.ets"
|
|
||||||
import {Constants} from "../constants/Constants.ets"
|
|
||||||
import {RequestOption} from "../../glide/RequestOption.ets"
|
|
||||||
import {TransformUtils} from "../transform/TransformUtils.ets"
|
|
||||||
import image from "@ohos.multimedia.image"
|
|
||||||
|
|
||||||
export class CropCircleTransformation implements BaseTransform<PixelMap> {
|
|
||||||
private static TAG: string= "CropCircleTransformation";
|
|
||||||
private mCenterX: number= 0;
|
|
||||||
private mCenterY: number= 0;
|
|
||||||
private mRadius: number= 0;
|
|
||||||
|
|
||||||
getName() {
|
|
||||||
return CropCircleTransformation.TAG + ";mCenterX:" + this.mCenterX
|
|
||||||
+ ";mCenterY:" + this.mCenterY
|
|
||||||
+ ";mRadius:" + this.mRadius;
|
|
||||||
}
|
|
||||||
|
|
||||||
transform(buf: ArrayBuffer, request: RequestOption, func?: AsyncTransform<PixelMap>) {
|
|
||||||
if (!buf || buf.byteLength <= 0) {
|
|
||||||
console.error(Constants.PROJECT_TAG + CropCircleTransformation.TAG + " buf is empty");
|
|
||||||
if (func) {
|
|
||||||
func(Constants.PROJECT_TAG + CropCircleTransformation.TAG + " buf is empty", null);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var imageSource = image.createImageSource(buf as any);
|
|
||||||
var that = this;
|
|
||||||
TransformUtils.getPixelMapSize(imageSource, (error, size: {
|
|
||||||
width: number,
|
|
||||||
height: number
|
|
||||||
}) => {
|
|
||||||
if (!size) {
|
|
||||||
func(error, null)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var pixelMapWidth = size.width;
|
|
||||||
var pixelMapHeight = size.height;
|
|
||||||
var targetWidth = request.size.width;
|
|
||||||
var targetHeight = request.size.height;
|
|
||||||
if (pixelMapWidth < targetWidth) {
|
|
||||||
targetWidth = pixelMapWidth;
|
|
||||||
}
|
|
||||||
if (pixelMapHeight < targetHeight) {
|
|
||||||
targetHeight = pixelMapHeight;
|
|
||||||
}
|
|
||||||
that.updatePixelMapSize(imageSource, targetWidth, targetHeight, func);
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
private updatePixelMapSize(imageSource: any, outWith: number, outHeight: number, func?: AsyncTransform<PixelMap>) {
|
|
||||||
var options = {
|
|
||||||
editable: true,
|
|
||||||
desiredSize: {
|
|
||||||
width: outWith,
|
|
||||||
height: outHeight
|
|
||||||
}
|
|
||||||
}
|
|
||||||
imageSource.createPixelMap(options)
|
|
||||||
.then(p => {
|
|
||||||
this.transformCircle(p, func);
|
|
||||||
})
|
|
||||||
.catch(e => {
|
|
||||||
console.error(Constants.PROJECT_TAG + CropCircleTransformation.TAG + " transform e:" + e);
|
|
||||||
if (func) {
|
|
||||||
func(Constants.PROJECT_TAG + CropCircleTransformation.TAG + "e" + e, null);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
private async transformCircle(data: any, func?: AsyncTransform<PixelMap>) {
|
|
||||||
let imageInfo = await data.getImageInfo();
|
|
||||||
let size = {
|
|
||||||
width: imageInfo.size.width,
|
|
||||||
height: imageInfo.size.height
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!size) {
|
|
||||||
func(new Error("CropCircleTransformation The image size does not exist."), null)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var height = size.height;
|
|
||||||
var width = 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 = new ArrayBuffer(data.getPixelBytesNumber());
|
|
||||||
await data.readPixelsToBuffer(bufferData);
|
|
||||||
|
|
||||||
var dataArray = new Uint8Array(bufferData);
|
|
||||||
|
|
||||||
for (var h = 0;h <= height; h++) {
|
|
||||||
for (var 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) {
|
|
||||||
func("", data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
isContainsCircle(x: number, y: number): boolean {
|
|
||||||
var a = Math.pow((this.mCenterX - x), 2);
|
|
||||||
var b = Math.pow((this.mCenterY - y), 2);
|
|
||||||
var c = Math.sqrt((a + b));
|
|
||||||
return c <= this.mRadius;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,168 +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.ets"
|
|
||||||
import {AsyncTransform} from "../transform/AsyncTransform.ets"
|
|
||||||
import {Constants} from "../constants/Constants.ets"
|
|
||||||
import {RequestOption} from "../../glide/RequestOption.ets"
|
|
||||||
import {TransformUtils} from "../transform/TransformUtils.ets"
|
|
||||||
import image from "@ohos.multimedia.image"
|
|
||||||
|
|
||||||
export class CropCircleWithBorderTransformation implements BaseTransform<PixelMap> {
|
|
||||||
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: {
|
|
||||||
r_color?: number,
|
|
||||||
g_color?: number,
|
|
||||||
b_color?: number,
|
|
||||||
}) {
|
|
||||||
this.mRColor = value.g_color;
|
|
||||||
this.mGColor = value.g_color;
|
|
||||||
this.mBColor = value.b_color;
|
|
||||||
this.mBorderSize = border_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
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<PixelMap>) {
|
|
||||||
if (!buf || buf.byteLength <= 0) {
|
|
||||||
console.log(Constants.PROJECT_TAG + ";CropCircleWithBorderTransformation buf is empty");
|
|
||||||
if (func) {
|
|
||||||
func(Constants.PROJECT_TAG + ";CropCircleWithBorderTransformation buf is empty", null);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var imageSource = image.createImageSource(buf as any);
|
|
||||||
var that = this;
|
|
||||||
TransformUtils.getPixelMapSize(imageSource, (error, size: {
|
|
||||||
width: number,
|
|
||||||
height: number
|
|
||||||
}) => {
|
|
||||||
if (!size) {
|
|
||||||
func(error, null)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var pixelMapWidth = size.width;
|
|
||||||
var pixelMapHeight = size.height;
|
|
||||||
var targetWidth = request.size.width;
|
|
||||||
var targetHeight = request.size.height;
|
|
||||||
if (pixelMapWidth < targetWidth) {
|
|
||||||
targetWidth = pixelMapWidth;
|
|
||||||
}
|
|
||||||
if (pixelMapHeight < targetHeight) {
|
|
||||||
targetHeight = pixelMapHeight;
|
|
||||||
}
|
|
||||||
that.updatePixelMapSize(imageSource, targetWidth, targetHeight, func);
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
private updatePixelMapSize(imageSource: any, outWith: number, outHeight: number, func?: AsyncTransform<PixelMap>) {
|
|
||||||
var options = {
|
|
||||||
editable: true,
|
|
||||||
desiredSize: {
|
|
||||||
width: outWith,
|
|
||||||
height: outHeight
|
|
||||||
}
|
|
||||||
}
|
|
||||||
imageSource.createPixelMap(options)
|
|
||||||
.then((pixelMap) => {
|
|
||||||
this.transformPixelMap(pixelMap, outWith, outHeight, func);
|
|
||||||
})
|
|
||||||
.catch(e => {
|
|
||||||
console.log(Constants.PROJECT_TAG + ";CropCircleWithBorderTransformation e:" + e);
|
|
||||||
if (func) {
|
|
||||||
func(Constants.PROJECT_TAG + ";CropCircleWithBorderTransformation e:" + e, null);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
private async transformPixelMap(pixelMap: any, width: number, height: number, func?: AsyncTransform<PixelMap>) {
|
|
||||||
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);
|
|
||||||
|
|
||||||
var 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) {
|
|
||||||
func("", pixelMap);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
isContainsCircle(x: number, y: number): boolean {
|
|
||||||
var a = Math.pow((this.mCenterX - x), 2);
|
|
||||||
var b = Math.pow((this.mCenterY - y), 2);
|
|
||||||
var c = Math.sqrt((a + b));
|
|
||||||
return c <= this.mRadius;
|
|
||||||
}
|
|
||||||
|
|
||||||
isContainsSmallCircle(x: number, y: number): boolean {
|
|
||||||
var a = Math.pow((this.mCenterX - x), 2);
|
|
||||||
var b = Math.pow((this.mCenterY - y), 2);
|
|
||||||
var c = Math.sqrt((a + b));
|
|
||||||
return c <= (this.mRadius - this.mBorderSize);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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.ets"
|
|
||||||
import {AsyncTransform} from "../transform/AsyncTransform.ets"
|
|
||||||
import {Constants} from "../constants/Constants.ets"
|
|
||||||
import {RequestOption} from "../../glide/RequestOption.ets"
|
|
||||||
|
|
||||||
import image from "@ohos.multimedia.image"
|
|
||||||
|
|
||||||
export class CropSquareTransformation implements BaseTransform<PixelMap> {
|
|
||||||
private static TAG: string= "CropSquareTransformation";
|
|
||||||
|
|
||||||
getName() {
|
|
||||||
return CropSquareTransformation.TAG + ";CropSquareTransformation:" + this;
|
|
||||||
}
|
|
||||||
|
|
||||||
transform(buf: ArrayBuffer, request: RequestOption, func?: AsyncTransform<PixelMap>) {
|
|
||||||
if (!buf || buf.byteLength <= 0) {
|
|
||||||
console.log(Constants.PROJECT_TAG + ";CropSquareTransformation buf is empty");
|
|
||||||
if (func) {
|
|
||||||
func(Constants.PROJECT_TAG + ";CropSquareTransformation buf is empty", null);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.squareCrop(buf, request, func);
|
|
||||||
}
|
|
||||||
|
|
||||||
squareCrop(buf: ArrayBuffer, request: RequestOption, func?: AsyncTransform<PixelMap>) {
|
|
||||||
var imageSource = image.createImageSource(buf as any);
|
|
||||||
imageSource.getImageInfo()
|
|
||||||
.then((p) => {
|
|
||||||
var pw = p.size.width;
|
|
||||||
var ph = p.size.height;
|
|
||||||
var outWidth = request.size.width;
|
|
||||||
var outHeight = request.size.height;
|
|
||||||
if (pw < outWidth) {
|
|
||||||
outWidth = pw;
|
|
||||||
}
|
|
||||||
if (ph < outHeight) {
|
|
||||||
outHeight = ph;
|
|
||||||
}
|
|
||||||
var targetSize = outWidth > outHeight ? outHeight : outWidth;
|
|
||||||
var options = {
|
|
||||||
editable: true,
|
|
||||||
rotate: 0,
|
|
||||||
desiredSize: {
|
|
||||||
width: outWidth,
|
|
||||||
height: outHeight
|
|
||||||
},
|
|
||||||
desiredRegion: { size: { width: targetSize, height: targetSize },
|
|
||||||
x: pw / 2 - targetSize / 2,
|
|
||||||
y: ph / 2 - targetSize / 2,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
imageSource.createPixelMap(options)
|
|
||||||
.then(data => {
|
|
||||||
if (func) {
|
|
||||||
func("", data);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(e => {
|
|
||||||
if (func) {
|
|
||||||
func(Constants.PROJECT_TAG + ";CropSquareTransformation e:" + e, null);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
.catch((error) => {
|
|
||||||
if (func) {
|
|
||||||
func(Constants.PROJECT_TAG + ";CropSquareTransformation error:" + error, 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.ets"
|
|
||||||
import {AsyncTransform} from "../transform/AsyncTransform.ets"
|
|
||||||
import {Constants} from "../constants/Constants.ets"
|
|
||||||
import {RequestOption} from "../../glide/RequestOption.ets"
|
|
||||||
import {TransformUtils} from "../transform/TransformUtils.ets"
|
|
||||||
import image from "@ohos.multimedia.image"
|
|
||||||
|
|
||||||
export class CropTransformation implements BaseTransform<PixelMap> {
|
|
||||||
private static TAG: string= "CropCircleTransformation";
|
|
||||||
private mWidth: number;
|
|
||||||
private mHeight: number;
|
|
||||||
private mCropType: CropType= CropType.CENTER;
|
|
||||||
|
|
||||||
constructor(width: number, height: number, cropType?: CropType) {
|
|
||||||
this.mWidth = width;
|
|
||||||
this.mHeight = height;
|
|
||||||
this.mCropType = cropType;
|
|
||||||
}
|
|
||||||
|
|
||||||
getName() {
|
|
||||||
return CropTransformation.TAG + ";mWidth:" + this.mWidth
|
|
||||||
+ ";mHeight:" + this.mHeight
|
|
||||||
+ ";mCropType:" + this.mCropType;
|
|
||||||
}
|
|
||||||
|
|
||||||
transform(buf: ArrayBuffer, request: RequestOption, func?: AsyncTransform<PixelMap>) {
|
|
||||||
if (!buf || buf.byteLength <= 0) {
|
|
||||||
console.log(Constants.PROJECT_TAG + ";CropTransformation buf is empty");
|
|
||||||
if (func) {
|
|
||||||
func(Constants.PROJECT_TAG + ";CropTransformation buf is empty", null);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var imageSource = image.createImageSource(buf as any);
|
|
||||||
TransformUtils.getPixelMapSize(imageSource, (error, size: {
|
|
||||||
width: number,
|
|
||||||
height: number
|
|
||||||
}) => {
|
|
||||||
if (!size) {
|
|
||||||
func(error, null)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var pixelMapWidth = size.width;
|
|
||||||
var pixelMapHeight = size.height;
|
|
||||||
|
|
||||||
this.mWidth = this.mWidth == 0 ? pixelMapWidth : this.mWidth;
|
|
||||||
this.mHeight = this.mHeight == 0 ? pixelMapHeight : this.mHeight;
|
|
||||||
|
|
||||||
var scaleX = this.mWidth / pixelMapWidth;
|
|
||||||
var scaleY = this.mHeight / pixelMapHeight;
|
|
||||||
var scale = Math.max(scaleX, scaleY);
|
|
||||||
|
|
||||||
var scaledWidth = scale * pixelMapWidth;
|
|
||||||
var scaledHeight = scale * pixelMapHeight;
|
|
||||||
var left = (this.mWidth - scaledWidth) / 2;
|
|
||||||
var top = Math.abs(this.getTop(pixelMapHeight));
|
|
||||||
var options = {
|
|
||||||
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) => {
|
|
||||||
func("", data);
|
|
||||||
})
|
|
||||||
.catch((e) => {
|
|
||||||
console.log(Constants.PROJECT_TAG + ";error:" + e);
|
|
||||||
func(e, null);
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
private getTop(scaledHeight: number): number{
|
|
||||||
switch (this.mCropType.valueOf()) {
|
|
||||||
case CropType.TOP.valueOf():
|
|
||||||
return 0;
|
|
||||||
case CropType.CENTER.valueOf():
|
|
||||||
return (this.mHeight - scaledHeight) / 2;
|
|
||||||
case CropType.BOTTOM.valueOf():
|
|
||||||
return this.mHeight - scaledHeight;
|
|
||||||
default:
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum CropType {
|
|
||||||
TOP,
|
|
||||||
CENTER,
|
|
||||||
BOTTOM
|
|
||||||
}
|
|
|
@ -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.ets"
|
|
||||||
import {AsyncTransform} from "../transform/AsyncTransform.ets"
|
|
||||||
import {Constants} from "../constants/Constants.ets"
|
|
||||||
import {RequestOption} from "../../glide/RequestOption.ets"
|
|
||||||
import {TransformUtils} from "../transform/TransformUtils.ets"
|
|
||||||
import image from "@ohos.multimedia.image"
|
|
||||||
|
|
||||||
export class GrayscaleTransformation implements BaseTransform<PixelMap> {
|
|
||||||
getName() {
|
|
||||||
return "GrayscaleTransformation:" + this;
|
|
||||||
}
|
|
||||||
|
|
||||||
async transform(buf: ArrayBuffer, request: RequestOption, func?: AsyncTransform<PixelMap>) {
|
|
||||||
if (!buf || buf.byteLength <= 0) {
|
|
||||||
console.log(Constants.PROJECT_TAG + ";GrayscaleTransformation buf is empty");
|
|
||||||
if (func) {
|
|
||||||
func(Constants.PROJECT_TAG + ";GrayscaleTransformation buf is empty", null);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var imageSource = image.createImageSource(buf as any);
|
|
||||||
|
|
||||||
let imageInfo = await imageSource.getImageInfo();
|
|
||||||
let size = {
|
|
||||||
width: imageInfo.size.width,
|
|
||||||
height: imageInfo.size.height
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!size) {
|
|
||||||
func(new Error("GrayscaleTransformation The image size does not exist."), null)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var pixelMapWidth = size.width;
|
|
||||||
var pixelMapHeight = size.height;
|
|
||||||
var targetWidth = request.size.width;
|
|
||||||
var targetHeight = request.size.height;
|
|
||||||
if (pixelMapWidth < targetWidth) {
|
|
||||||
targetWidth = pixelMapWidth;
|
|
||||||
}
|
|
||||||
if (pixelMapHeight < targetHeight) {
|
|
||||||
targetHeight = pixelMapHeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
var options = {
|
|
||||||
editable: true,
|
|
||||||
desiredSize: {
|
|
||||||
width: targetWidth,
|
|
||||||
height: targetHeight
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let data = await imageSource.createPixelMap(options);
|
|
||||||
|
|
||||||
let bufferData = new ArrayBuffer(data.getPixelBytesNumber());
|
|
||||||
let bufferNewData = new ArrayBuffer(data.getPixelBytesNumber());
|
|
||||||
await data.readPixelsToBuffer(bufferData);
|
|
||||||
|
|
||||||
var dataArray = new Uint8Array(bufferData);
|
|
||||||
var 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) {
|
|
||||||
func('', data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 将读取的像素点的rgb值,全部灰度化,得到灰度图片(黑白图片)加权平均法
|
|
||||||
*/
|
|
||||||
private grayscale(r: number, g: number, b: number): number{
|
|
||||||
return (r * 28 + g * 151 + b * 77) >> 8;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,102 +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.ets"
|
|
||||||
import {AsyncTransform} from "../transform/AsyncTransform.ets"
|
|
||||||
import {Constants} from "../constants/Constants.ets"
|
|
||||||
import {RequestOption} from "../../glide/RequestOption.ets"
|
|
||||||
import image from "@ohos.multimedia.image"
|
|
||||||
|
|
||||||
/**
|
|
||||||
** 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<PixelMap> {
|
|
||||||
getName() {
|
|
||||||
return "InvertFilterTransformation";
|
|
||||||
}
|
|
||||||
|
|
||||||
async transform(buf: ArrayBuffer, request: RequestOption, func?: AsyncTransform<PixelMap>) {
|
|
||||||
if (!buf || buf.byteLength <= 0) {
|
|
||||||
console.log(Constants.PROJECT_TAG + ";InvertFilterTransformation buf is empty");
|
|
||||||
if (func) {
|
|
||||||
func(Constants.PROJECT_TAG + ";InvertFilterTransformation buf is empty", null);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var imageSource = image.createImageSource(buf as any);
|
|
||||||
|
|
||||||
let imageInfo = await imageSource.getImageInfo();
|
|
||||||
let size = {
|
|
||||||
width: imageInfo.size.width,
|
|
||||||
height: imageInfo.size.height
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!size) {
|
|
||||||
func(new Error("InvertFilterTransformation The image size does not exist."), null)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var pixelMapWidth = size.width;
|
|
||||||
var pixelMapHeight = size.height;
|
|
||||||
var targetWidth = request.size.width;
|
|
||||||
var targetHeight = request.size.height;
|
|
||||||
if (pixelMapWidth < targetWidth) {
|
|
||||||
targetWidth = pixelMapWidth;
|
|
||||||
}
|
|
||||||
if (pixelMapHeight < targetHeight) {
|
|
||||||
targetHeight = pixelMapHeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
var options = {
|
|
||||||
editable: true,
|
|
||||||
desiredSize: {
|
|
||||||
width: targetWidth,
|
|
||||||
height: targetHeight
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let data = await imageSource.createPixelMap(options);
|
|
||||||
|
|
||||||
let bufferData = new ArrayBuffer(data.getPixelBytesNumber());
|
|
||||||
await data.readPixelsToBuffer(bufferData);
|
|
||||||
|
|
||||||
var 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) {
|
|
||||||
func('', data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private checkVisAble(input: number) {
|
|
||||||
if (input > 255) {
|
|
||||||
input = 255;
|
|
||||||
}
|
|
||||||
if (input <= 0) {
|
|
||||||
input = 0;
|
|
||||||
}
|
|
||||||
return input;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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 {BaseTransform} from "../transform/BaseTransform.ets"
|
|
||||||
import {AsyncTransform} from "../transform/AsyncTransform.ets"
|
|
||||||
import {Constants} from "../constants/Constants.ets"
|
|
||||||
import {RequestOption} from "../../glide/RequestOption.ets"
|
|
||||||
import {MaskUtils} from "../utils/MaskUtils.ets"
|
|
||||||
import image from "@ohos.multimedia.image"
|
|
||||||
import resmgr from "@ohos.resourceManager"
|
|
||||||
|
|
||||||
export class MaskTransformation implements BaseTransform<PixelMap> {
|
|
||||||
private _mResourceData: Resource;
|
|
||||||
|
|
||||||
constructor(maskBitmap: Resource) {
|
|
||||||
this._mResourceData = maskBitmap;
|
|
||||||
}
|
|
||||||
|
|
||||||
getName() {
|
|
||||||
return "MaskTransformation:" + this._mResourceData;
|
|
||||||
}
|
|
||||||
|
|
||||||
async transform(buf: ArrayBuffer, request: RequestOption, func?: AsyncTransform<PixelMap>) {
|
|
||||||
if (!buf || buf.byteLength <= 0) {
|
|
||||||
console.log(Constants.PROJECT_TAG + ";MaskTransformation buf is empty");
|
|
||||||
if (func) {
|
|
||||||
func(Constants.PROJECT_TAG + ";MaskTransformation buf is empty", null);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var imageSource = image.createImageSource(buf as any);
|
|
||||||
|
|
||||||
let imageInfo = await imageSource.getImageInfo();
|
|
||||||
let size = {
|
|
||||||
width: imageInfo.size.width,
|
|
||||||
height: imageInfo.size.height
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!size) {
|
|
||||||
func(new Error("MaskTransformation The image size does not exist."), null)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var pixelMapWidth = size.width;
|
|
||||||
var pixelMapHeight = size.height;
|
|
||||||
var targetWidth = request.size.width;
|
|
||||||
var targetHeight = request.size.height;
|
|
||||||
if (pixelMapWidth < targetWidth) {
|
|
||||||
targetWidth = pixelMapWidth;
|
|
||||||
}
|
|
||||||
if (pixelMapHeight < targetHeight) {
|
|
||||||
targetHeight = pixelMapHeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
var options = {
|
|
||||||
editable: true,
|
|
||||||
desiredSize: {
|
|
||||||
width: targetWidth,
|
|
||||||
height: targetHeight
|
|
||||||
}
|
|
||||||
}
|
|
||||||
imageSource.createPixelMap(options)
|
|
||||||
.then(data => {
|
|
||||||
this.openInternal(data, targetWidth, targetHeight, func)
|
|
||||||
})
|
|
||||||
.catch(e => {
|
|
||||||
func(e, null);
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
private openInternal(bitmap: any, width: number, height: number, func: AsyncTransform<PixelMap>) {
|
|
||||||
if (!this._mResourceData) {
|
|
||||||
throw new Error("MaskTransformation resource is empty");
|
|
||||||
}
|
|
||||||
resmgr.getResourceManager()
|
|
||||||
.then(result => {
|
|
||||||
result.getMedia(this._mResourceData
|
|
||||||
.id)
|
|
||||||
.then(array => {
|
|
||||||
let buffer = array.buffer.slice(array.byteOffset, array.byteLength + array.byteOffset);
|
|
||||||
var imageSource = image.createImageSource(buffer as any);
|
|
||||||
var options = {
|
|
||||||
editable: true,
|
|
||||||
desiredSize: {
|
|
||||||
width: width,
|
|
||||||
height: height
|
|
||||||
}
|
|
||||||
}
|
|
||||||
imageSource.createPixelMap(options)
|
|
||||||
.then(maskBitmap => {
|
|
||||||
MaskUtils.mask(bitmap, maskBitmap, func)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
func("MaskTransformation openInternal error" + err, 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.ets"
|
|
||||||
import {AsyncTransform} from "../transform/AsyncTransform.ets"
|
|
||||||
import {Constants} from "../constants/Constants.ets"
|
|
||||||
import {RequestOption} from "../../glide/RequestOption.ets"
|
|
||||||
import {TransformUtils} from "../transform/TransformUtils.ets"
|
|
||||||
import image from "@ohos.multimedia.image"
|
|
||||||
import {pixelUtils} from "../utils/PixelUtils"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Applies a Pixelation effect to the image.
|
|
||||||
* The pixel with a default of 10.0.
|
|
||||||
*/
|
|
||||||
export class PixelationFilterTransformation implements BaseTransform<PixelMap> {
|
|
||||||
private _mPixel: number= 10.0;
|
|
||||||
|
|
||||||
constructor(pixel?: number) {
|
|
||||||
if (pixel) {
|
|
||||||
this._mPixel = pixel;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
getName() {
|
|
||||||
return "PixelationFilterTransformation" + this._mPixel;
|
|
||||||
}
|
|
||||||
|
|
||||||
transform(buf: ArrayBuffer, request: RequestOption, func?: AsyncTransform<PixelMap>) {
|
|
||||||
if (!buf || buf.byteLength <= 0) {
|
|
||||||
console.log(Constants.PROJECT_TAG + ";PixelationFilterTransformation buf is empty");
|
|
||||||
if (func) {
|
|
||||||
func(Constants.PROJECT_TAG + ";PixelationFilterTransformation buf is empty", null);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var imageSource = image.createImageSource(buf as any);
|
|
||||||
TransformUtils.getPixelMapSize(imageSource, (error, size: {
|
|
||||||
width: number,
|
|
||||||
height: number
|
|
||||||
}) => {
|
|
||||||
if (!size) {
|
|
||||||
func(error, null)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var pixelMapWidth = size.width;
|
|
||||||
var pixelMapHeight = size.height;
|
|
||||||
var targetWidth = request.size.width;
|
|
||||||
var targetHeight = request.size.height;
|
|
||||||
if (pixelMapWidth < targetWidth) {
|
|
||||||
targetWidth = pixelMapWidth;
|
|
||||||
}
|
|
||||||
if (pixelMapHeight < targetHeight) {
|
|
||||||
targetHeight = pixelMapHeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
var options = {
|
|
||||||
editable: true,
|
|
||||||
desiredSize: {
|
|
||||||
width: targetWidth,
|
|
||||||
height: targetHeight
|
|
||||||
}
|
|
||||||
}
|
|
||||||
imageSource.createPixelMap(options)
|
|
||||||
.then((data) => {
|
|
||||||
pixelUtils.pixel(data, this._mPixel, func);
|
|
||||||
})
|
|
||||||
.catch((e) => {
|
|
||||||
console.log(Constants.PROJECT_TAG + ";error:" + e);
|
|
||||||
func(e, 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 {BaseTransform} from "../transform/BaseTransform.ets"
|
|
||||||
import {AsyncTransform} from "../transform/AsyncTransform.ets"
|
|
||||||
import {Constants} from "../constants/Constants.ets"
|
|
||||||
import {RequestOption} from "../../glide/RequestOption.ets"
|
|
||||||
import {TransformUtils} from "../transform/TransformUtils.ets"
|
|
||||||
|
|
||||||
import image from "@ohos.multimedia.image"
|
|
||||||
|
|
||||||
export class RotateImageTransformation implements BaseTransform<PixelMap> {
|
|
||||||
private mDegreesToRotate: number;
|
|
||||||
|
|
||||||
constructor(degreesToRotate: number) {
|
|
||||||
this.mDegreesToRotate = degreesToRotate;
|
|
||||||
}
|
|
||||||
|
|
||||||
getName() {
|
|
||||||
return "RotateImageTransformation" + ";degreesToRotate:" + this.mDegreesToRotate;
|
|
||||||
}
|
|
||||||
|
|
||||||
transform(buf: ArrayBuffer, request: RequestOption, func?: AsyncTransform<PixelMap>) {
|
|
||||||
if (!buf || buf.byteLength <= 0) {
|
|
||||||
console.log(Constants.PROJECT_TAG + ";RotateImageTransformation buf is empty");
|
|
||||||
if (func) {
|
|
||||||
func(Constants.PROJECT_TAG + ";RotateImageTransformation buf is empty", null);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var imageSource = image.createImageSource(buf as any);
|
|
||||||
TransformUtils.getPixelMapSize(imageSource, (error, size: {
|
|
||||||
width: number,
|
|
||||||
height: number
|
|
||||||
}) => {
|
|
||||||
if (!size) {
|
|
||||||
func(error, null)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var pixelMapWidth = size.width;
|
|
||||||
var pixelMapHeight = size.height;
|
|
||||||
var targetWidth = request.size.width;
|
|
||||||
var targetHeight = request.size.height;
|
|
||||||
if (pixelMapWidth < targetWidth) {
|
|
||||||
targetWidth = pixelMapWidth;
|
|
||||||
}
|
|
||||||
if (pixelMapHeight < targetHeight) {
|
|
||||||
targetHeight = pixelMapHeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
var options = {
|
|
||||||
editable: true,
|
|
||||||
rotate: this.mDegreesToRotate%360,
|
|
||||||
desiredSize: {
|
|
||||||
width: targetWidth,
|
|
||||||
height: targetHeight
|
|
||||||
}
|
|
||||||
}
|
|
||||||
imageSource.createPixelMap(options)
|
|
||||||
.then((data) => {
|
|
||||||
func("", data);
|
|
||||||
})
|
|
||||||
.catch((e) => {
|
|
||||||
console.log(Constants.PROJECT_TAG + ";error:" + e);
|
|
||||||
func(e, null);
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,223 +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.ets"
|
|
||||||
import {AsyncTransform} from "../transform/AsyncTransform.ets"
|
|
||||||
import {ArcPoint} from "../entry/ArcPoint.ets"
|
|
||||||
import {Constants} from "../constants/Constants.ets"
|
|
||||||
import {RequestOption} from "../../glide/RequestOption.ets"
|
|
||||||
import {TransformUtils} from "../transform/TransformUtils.ets"
|
|
||||||
|
|
||||||
import image from "@ohos.multimedia.image"
|
|
||||||
|
|
||||||
export class RoundedCornersTransformation implements BaseTransform<PixelMap> {
|
|
||||||
private mTop_left: number= 0;
|
|
||||||
private mTop_right: number= 0;
|
|
||||||
private mBottom_left: number= 0;
|
|
||||||
private mBottom_right: number= 0;
|
|
||||||
private mTransform_pixelMap: any;
|
|
||||||
private mPoint: ArcPoint[];
|
|
||||||
|
|
||||||
constructor(value: {
|
|
||||||
top_left?: number,
|
|
||||||
top_right?: number,
|
|
||||||
bottom_left?: number,
|
|
||||||
bottom_right?: number
|
|
||||||
}) {
|
|
||||||
this.mTop_left = value.top_left;
|
|
||||||
this.mTop_right = value.top_right;
|
|
||||||
this.mBottom_left = value.bottom_left;
|
|
||||||
this.mBottom_right = value.bottom_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<PixelMap>) {
|
|
||||||
if (!buf || buf.byteLength <= 0) {
|
|
||||||
console.log(Constants.PROJECT_TAG + ";RoundedCornersTransformation buf is empty");
|
|
||||||
if (func) {
|
|
||||||
func(Constants.PROJECT_TAG + ";RoundedCornersTransformation buf is empty", null);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var imageSource = image.createImageSource(buf as any);
|
|
||||||
var that = this;
|
|
||||||
TransformUtils.getPixelMapSize(imageSource, (error, size: {
|
|
||||||
width: number,
|
|
||||||
height: number
|
|
||||||
}) => {
|
|
||||||
if (!size) {
|
|
||||||
func(error, null)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var pixelMapWidth = size.width;
|
|
||||||
var pixelMapHeight = size.height;
|
|
||||||
var targetWidth = request.size.width;
|
|
||||||
var targetHeight = request.size.height;
|
|
||||||
if (pixelMapWidth < targetWidth) {
|
|
||||||
targetWidth = pixelMapWidth;
|
|
||||||
}
|
|
||||||
if (pixelMapHeight < targetHeight) {
|
|
||||||
targetHeight = pixelMapHeight;
|
|
||||||
}
|
|
||||||
that.transformPixelMap(imageSource, targetWidth, targetHeight, func);
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
private transformPixelMap(imageSource: any, outWith: number, outHeight: number, func?: AsyncTransform<PixelMap>) {
|
|
||||||
var options = {
|
|
||||||
editable: true,
|
|
||||||
desiredSize: {
|
|
||||||
width: outWith,
|
|
||||||
height: outHeight
|
|
||||||
}
|
|
||||||
}
|
|
||||||
imageSource.createPixelMap(options)
|
|
||||||
.then((pixelMap) => {
|
|
||||||
this.mTransform_pixelMap = pixelMap;
|
|
||||||
this.mTransform_pixelMap.getImageInfo()
|
|
||||||
.then((data) => {
|
|
||||||
let width = data.size.width;
|
|
||||||
let height = 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) {
|
|
||||||
func("", this.mTransform_pixelMap);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch((error) => {
|
|
||||||
console.log(Constants.PROJECT_TAG + "RoundedCornersTransformation error:" + error);
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.catch((e) => {
|
|
||||||
console.log(Constants.PROJECT_TAG + ";error:" + e);
|
|
||||||
if (func) {
|
|
||||||
func(e, null);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private top_left_corners() {
|
|
||||||
this.mPoint = new Array<ArcPoint>();
|
|
||||||
for (var time = 180; time < 270; time++) {
|
|
||||||
var hudu = (2 * Math.PI / 360) * time;
|
|
||||||
var x = this.mTop_left + Math.sin(hudu) * this.mTop_left;
|
|
||||||
var y = 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<ArcPoint>();
|
|
||||||
for (var time = 0; time < 90; time++) {
|
|
||||||
var hudu = (2 * Math.PI / 360) * time;
|
|
||||||
var x = (width - this.mTop_right) + Math.cos(hudu) * this.mTop_right;
|
|
||||||
var y = 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<ArcPoint>();
|
|
||||||
for (var time = 90; time < 180; time++) {
|
|
||||||
var hudu = (2 * Math.PI / 360) * time;
|
|
||||||
var x = this.mBottom_left + Math.cos(hudu) * this.mBottom_left;
|
|
||||||
var 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<ArcPoint>();
|
|
||||||
for (var time = 0; time < 90; time++) {
|
|
||||||
var hudu = (2 * Math.PI / 360) * time;
|
|
||||||
var x = width - this.mBottom_right + Math.cos(hudu) * this.mBottom_right;
|
|
||||||
var 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 (var index = 0; index < points.length; index++) {
|
|
||||||
const element = points[index];
|
|
||||||
let x = element.getX();
|
|
||||||
let y = element.getY();
|
|
||||||
|
|
||||||
for (var i = 0; i <= x; i++) {
|
|
||||||
var buffer1 = new ArrayBuffer(5);
|
|
||||||
var bytes1 = new Uint8Array(buffer1);
|
|
||||||
var writePositionRen = {
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
this.mTransform_pixelMap.writePixels(writePositionRen);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private hand_right_pixel_point(points: ArcPoint[], width: number) {
|
|
||||||
for (var index = 0; index < points.length; index++) {
|
|
||||||
const element = points[index];
|
|
||||||
let x = element.getX();
|
|
||||||
let y = element.getY();
|
|
||||||
|
|
||||||
for (var i = x; i <= width; i++) {
|
|
||||||
var buffer1 = new ArrayBuffer(5);
|
|
||||||
var bytes1 = new Uint8Array(buffer1);
|
|
||||||
var writePositionRen = {
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
this.mTransform_pixelMap.writePixels(writePositionRen);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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 {BaseTransform} from "../transform/BaseTransform.ets"
|
|
||||||
import {AsyncTransform} from "../transform/AsyncTransform.ets"
|
|
||||||
import {Constants} from "../constants/Constants.ets"
|
|
||||||
import {RequestOption} from "../../glide/RequestOption.ets"
|
|
||||||
import image from "@ohos.multimedia.image"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Applies a simple sepia effect.
|
|
||||||
* <p>
|
|
||||||
* The intensity with a default of 1.0.
|
|
||||||
*/
|
|
||||||
export class SepiaFilterTransformation implements BaseTransform<PixelMap> {
|
|
||||||
getName() {
|
|
||||||
return "SepiaFilterTransformation";
|
|
||||||
}
|
|
||||||
|
|
||||||
async transform(buf: ArrayBuffer, request: RequestOption, func?: AsyncTransform<PixelMap>) {
|
|
||||||
if (!buf || buf.byteLength <= 0) {
|
|
||||||
console.log(Constants.PROJECT_TAG + ";SepiaFilterTransformation buf is empty");
|
|
||||||
if (func) {
|
|
||||||
func(Constants.PROJECT_TAG + ";SepiaFilterTransformation buf is empty", null);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var imageSource = image.createImageSource(buf as any);
|
|
||||||
|
|
||||||
let imageInfo = await imageSource.getImageInfo();
|
|
||||||
let size = {
|
|
||||||
width: imageInfo.size.width,
|
|
||||||
height: imageInfo.size.height
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!size) {
|
|
||||||
func(new Error("SepiaFilterTransformation The image size does not exist."), null)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var pixelMapWidth = size.width;
|
|
||||||
var pixelMapHeight = size.height;
|
|
||||||
var targetWidth = request.size.width;
|
|
||||||
var targetHeight = request.size.height;
|
|
||||||
if (pixelMapWidth < targetWidth) {
|
|
||||||
targetWidth = pixelMapWidth;
|
|
||||||
}
|
|
||||||
if (pixelMapHeight < targetHeight) {
|
|
||||||
targetHeight = pixelMapHeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
var options = {
|
|
||||||
editable: true,
|
|
||||||
desiredSize: {
|
|
||||||
width: targetWidth,
|
|
||||||
height: targetHeight
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let data = await imageSource.createPixelMap(options);
|
|
||||||
|
|
||||||
let bufferData = new ArrayBuffer(data.getPixelBytesNumber());
|
|
||||||
let bufferNewData = new ArrayBuffer(data.getPixelBytesNumber());
|
|
||||||
await data.readPixelsToBuffer(bufferData);
|
|
||||||
|
|
||||||
var dataArray = new Uint8Array(bufferData);
|
|
||||||
var 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];
|
|
||||||
|
|
||||||
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) {
|
|
||||||
func("", 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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,73 +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.ets'
|
|
||||||
import {AsyncTransform} from '../transform/AsyncTransform.ets'
|
|
||||||
import {Constants} from '../constants/Constants.ets'
|
|
||||||
import {RequestOption} from '../../glide/RequestOption.ets'
|
|
||||||
import {TransformUtils} from '../transform/TransformUtils.ets'
|
|
||||||
import image from '@ohos.multimedia.image'
|
|
||||||
import {CalculatePixelUtils} from '../utils/CalculatePixelUtils'
|
|
||||||
|
|
||||||
export class SketchFilterTransformation implements BaseTransform<PixelMap> {
|
|
||||||
getName() {
|
|
||||||
return 'SketchFilterTransformation';
|
|
||||||
}
|
|
||||||
|
|
||||||
transform(buf: ArrayBuffer, request: RequestOption, func?: AsyncTransform<PixelMap>) {
|
|
||||||
if (!buf || buf.byteLength <= 0) {
|
|
||||||
throw new Error(Constants.PROJECT_TAG + ';SketchFilterTransformation buf is empty');
|
|
||||||
if (func) {
|
|
||||||
func(Constants.PROJECT_TAG + ';SketchFilterTransformation buf is empty', null);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var imageSource = image.createImageSource(buf as any);
|
|
||||||
TransformUtils.getPixelMapSize(imageSource, (error, size: {
|
|
||||||
width: number,
|
|
||||||
height: number
|
|
||||||
}) => {
|
|
||||||
if (!size) {
|
|
||||||
func(error, null)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var pixelMapWidth = size.width;
|
|
||||||
var pixelMapHeight = size.height;
|
|
||||||
var targetWidth = request.size.width;
|
|
||||||
var targetHeight = request.size.height;
|
|
||||||
if (pixelMapWidth < targetWidth) {
|
|
||||||
targetWidth = pixelMapWidth;
|
|
||||||
}
|
|
||||||
if (pixelMapHeight < targetHeight) {
|
|
||||||
targetHeight = pixelMapHeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
var options = {
|
|
||||||
editable: true,
|
|
||||||
desiredSize: {
|
|
||||||
width: targetWidth,
|
|
||||||
height: targetHeight
|
|
||||||
}
|
|
||||||
}
|
|
||||||
imageSource.createPixelMap(options)
|
|
||||||
.then((data) => {
|
|
||||||
CalculatePixelUtils.sketch(data, func);
|
|
||||||
})
|
|
||||||
.catch((e) => {
|
|
||||||
func(e, null);
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,182 +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.ets'
|
|
||||||
import {AsyncTransform} from '../transform/AsyncTransform.ets'
|
|
||||||
import {Constants} from '../constants/Constants.ets'
|
|
||||||
import {RequestOption} from '../../glide/RequestOption.ets'
|
|
||||||
import {TransformUtils} from '../transform/TransformUtils.ets'
|
|
||||||
import image from '@ohos.multimedia.image'
|
|
||||||
import {PixelEntry} from '../entry/PixelEntry'
|
|
||||||
import {ColorUtils} from '../utils/ColorUtils'
|
|
||||||
import {CalculatePixelUtils} from '../utils/CalculatePixelUtils'
|
|
||||||
|
|
||||||
export class SwirlFilterTransformation implements BaseTransform<PixelMap> {
|
|
||||||
private _degree: number;
|
|
||||||
|
|
||||||
constructor(degree: number) {
|
|
||||||
this._degree = degree;
|
|
||||||
}
|
|
||||||
|
|
||||||
getName() {
|
|
||||||
return 'SwirlFilterTransformation' + this._degree;
|
|
||||||
}
|
|
||||||
|
|
||||||
transform(buf: ArrayBuffer, request: RequestOption, func?: AsyncTransform<PixelMap>) {
|
|
||||||
if (!buf || buf.byteLength <= 0) {
|
|
||||||
throw new Error(Constants.PROJECT_TAG + ';SwirlFilterTransformation buf is empty');
|
|
||||||
if (func) {
|
|
||||||
func(Constants.PROJECT_TAG + ';SwirlFilterTransformation buf is empty', null);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var imageSource = image.createImageSource(buf as any);
|
|
||||||
TransformUtils.getPixelMapSize(imageSource, (error, size: {
|
|
||||||
width: number,
|
|
||||||
height: number
|
|
||||||
}) => {
|
|
||||||
if (!size) {
|
|
||||||
func(error, null)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var pixelMapWidth = size.width;
|
|
||||||
var pixelMapHeight = size.height;
|
|
||||||
var targetWidth = request.size.width;
|
|
||||||
var targetHeight = request.size.height;
|
|
||||||
if (pixelMapWidth < targetWidth) {
|
|
||||||
targetWidth = pixelMapWidth;
|
|
||||||
}
|
|
||||||
if (pixelMapHeight < targetHeight) {
|
|
||||||
targetHeight = pixelMapHeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
var options = {
|
|
||||||
editable: true,
|
|
||||||
desiredSize: {
|
|
||||||
width: targetWidth,
|
|
||||||
height: targetHeight
|
|
||||||
}
|
|
||||||
}
|
|
||||||
imageSource.createPixelMap(options)
|
|
||||||
.then((data) => {
|
|
||||||
this.swirl(data, this._degree, func);
|
|
||||||
})
|
|
||||||
.catch((e) => {
|
|
||||||
func(e, null);
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
private async swirl(bitmap: any, degree: number, func?: AsyncTransform<PixelMap>) {
|
|
||||||
let imageInfo = await bitmap.getImageInfo();
|
|
||||||
let size = {
|
|
||||||
width: imageInfo.size.width,
|
|
||||||
height: imageInfo.size.height
|
|
||||||
}
|
|
||||||
if (!size) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let width = size.width;
|
|
||||||
let height = size.height;
|
|
||||||
let pixEntry: Array<PixelEntry> = new Array();
|
|
||||||
|
|
||||||
|
|
||||||
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);
|
|
||||||
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) {
|
|
||||||
func("", bitmap);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,141 +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'
|
|
||||||
|
|
||||||
export class TransformUtils {
|
|
||||||
static centerCrop(buf: ArrayBuffer, outWidth: number, outHeihgt: number,
|
|
||||||
callback?: AsyncTransform<Promise<PixelMap>>) {
|
|
||||||
var imageSource = image.createImageSource(buf as any);
|
|
||||||
imageSource.getImageInfo()
|
|
||||||
.then((p) => {
|
|
||||||
var sw;
|
|
||||||
var sh;
|
|
||||||
var scale;
|
|
||||||
var pw = p.size.width;
|
|
||||||
var ph = 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;
|
|
||||||
}
|
|
||||||
var options = {
|
|
||||||
editable: true,
|
|
||||||
rotate: 0,
|
|
||||||
desiredRegion: { size: { width: sw, height: sh },
|
|
||||||
x: pw / 2 - sw / 2,
|
|
||||||
y: ph / 2 - sh / 2,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
if (callback) {
|
|
||||||
callback('', imageSource.createPixelMap(options));
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch((error) => {
|
|
||||||
callback(error, null);
|
|
||||||
})
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
static rotateImage(buf: ArrayBuffer, degreesToRotate: number): Promise<PixelMap>{
|
|
||||||
var imageSource = image.createImageSource(buf as any);
|
|
||||||
var options = {
|
|
||||||
editable: true,
|
|
||||||
rotate: degreesToRotate
|
|
||||||
}
|
|
||||||
return imageSource.createPixelMap(options);
|
|
||||||
}
|
|
||||||
|
|
||||||
static centerInside(buf: ArrayBuffer, outWidth: number, outHeihgt: number,
|
|
||||||
callback?: AsyncTransform<Promise<PixelMap>>) {
|
|
||||||
var imageSource = image.createImageSource(buf as any);
|
|
||||||
imageSource.getImageInfo()
|
|
||||||
.then((p) => {
|
|
||||||
var pw = p.size.width;
|
|
||||||
var ph = p.size.height;
|
|
||||||
if (pw <= outWidth && ph <= outHeihgt) {
|
|
||||||
callback('', imageSource.createPixelMap());
|
|
||||||
} else {
|
|
||||||
this.fitCenter(buf, outWidth, outHeihgt, callback);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch((error) => {
|
|
||||||
callback(error, null);
|
|
||||||
})
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
static fitCenter(buf: ArrayBuffer, outWidth: number, outHeihgt: number
|
|
||||||
, callback?: AsyncTransform<Promise<PixelMap>>) {
|
|
||||||
var imageSource = image.createImageSource(buf as any);
|
|
||||||
imageSource.getImageInfo()
|
|
||||||
.then((p) => {
|
|
||||||
var pw = p.size.width;
|
|
||||||
var ph = p.size.height;
|
|
||||||
var widthPercentage = outWidth / pw;
|
|
||||||
var heightPercentage = outHeihgt / ph;
|
|
||||||
var minPercentage = Math.min(widthPercentage, heightPercentage);
|
|
||||||
|
|
||||||
var targetWidth = Math.round(minPercentage * pw);
|
|
||||||
var targetHeight = Math.round(minPercentage * ph);
|
|
||||||
|
|
||||||
if (pw == targetWidth && ph == targetHeight) {
|
|
||||||
targetWidth = pw;
|
|
||||||
targetHeight = ph;
|
|
||||||
} else {
|
|
||||||
targetWidth = minPercentage * pw;
|
|
||||||
targetHeight = minPercentage * ph;
|
|
||||||
}
|
|
||||||
var options = {
|
|
||||||
editable: true,
|
|
||||||
rotate: 0,
|
|
||||||
desiredSize: { width: targetWidth, height: targetHeight }
|
|
||||||
}
|
|
||||||
if (callback) {
|
|
||||||
callback('', imageSource.createPixelMap(options));
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(e => {
|
|
||||||
if (callback) {
|
|
||||||
callback(e, null);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
static getPixelMapSize(imageSource: any, func: AsyncTransform<{
|
|
||||||
width: number,
|
|
||||||
height: number
|
|
||||||
}>) {
|
|
||||||
if (!imageSource) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
imageSource.getImageInfo((err, value) => {
|
|
||||||
if (err) {
|
|
||||||
func(err, null)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var pWidth = value.size.width;
|
|
||||||
var pHeight = value.size.height;
|
|
||||||
func('', { width: pWidth, height: pHeight });
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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 '../../../glide/RequestOption'
|
|
||||||
|
|
||||||
export class CenterCrop implements BaseTransform<PixelMap> {
|
|
||||||
getName() {
|
|
||||||
return 'CenterCrop:' + this;
|
|
||||||
}
|
|
||||||
|
|
||||||
transform(buf: ArrayBuffer, request: RequestOption, func?: AsyncTransform<PixelMap>) {
|
|
||||||
if (!buf || buf.byteLength <= 0) {
|
|
||||||
throw new Error(Constants.PROJECT_TAG + ';CenterCrop buf is empty');
|
|
||||||
if (func) {
|
|
||||||
func(Constants.PROJECT_TAG + ';CenterCrop buf is empty', null);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
TransformUtils.centerCrop(buf, request.size.width, request.size.height, (error, data) => {
|
|
||||||
data.then(p => {
|
|
||||||
func('', p);
|
|
||||||
}).catch(e => {
|
|
||||||
func(Constants.PROJECT_TAG + ';CenterCrop error:' + e, 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 '../../../glide/RequestOption'
|
|
||||||
|
|
||||||
export class CenterInside implements BaseTransform<PixelMap> {
|
|
||||||
getName() {
|
|
||||||
return 'CenterInside:' + this;
|
|
||||||
}
|
|
||||||
|
|
||||||
transform(buf: ArrayBuffer, request: RequestOption, func?: AsyncTransform<PixelMap>) {
|
|
||||||
if (!buf || buf.byteLength <= 0) {
|
|
||||||
throw new Error(Constants.PROJECT_TAG + ';CenterInside buf is empty');
|
|
||||||
if (func) {
|
|
||||||
func(Constants.PROJECT_TAG + ';CenterInside buf is empty', null);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
TransformUtils.centerInside(buf, request.size.width, request.size.height, (error, data) => {
|
|
||||||
data.then(p => {
|
|
||||||
func('', p);
|
|
||||||
}).catch(e => {
|
|
||||||
func(Constants.PROJECT_TAG + ';CenterInside error:' + e, null);
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue