update code because of some idea

Signed-off-by: tyBrave <tianyong13@huawei.com>
This commit is contained in:
tyBrave 2023-02-22 10:55:02 +08:00
parent 3762e6ecbf
commit 0799ed85e2
54 changed files with 1032 additions and 775 deletions

View File

@ -433,6 +433,9 @@ request.skipMemoryCache(true)
| request.sketchFilter() | SketchFilterTransformation | 素描滤波器 |
| request.mask() | MaskTransformation | 遮罩 |
| request.swirlFilter() | SwirlFilterTransformation | 扭曲滤波器 |
| request.kuwaharaFilter() | KuwaharaFilterTransform | 桑原滤波器 |
| request.toonFilter() | ToonFilterTransform | 动画滤波器 |
| request.vignetteFilter() | VignetteFilterTransform | 装饰滤波器 |
<img src="screenshot/gif4.gif" width="50%"/>

View File

@ -756,7 +756,7 @@ struct TransformPixelMapPage {
})
.setImageViewSize({ width: vp2px(200), height: vp2px(200) })
.skipMemoryCache(true)
.openEfficient()
.enableGPU()
.grayscale()
ImageKnife.call(imageKnifeOption);
@ -777,7 +777,7 @@ struct TransformPixelMapPage {
})
.setImageViewSize({ width: vp2px(200), height: vp2px(200) })
.skipMemoryCache(true)
.openEfficient()
.enableGPU()
.brightnessFilter(brightness)
ImageKnife.call(imageKnifeOption);
@ -798,7 +798,7 @@ struct TransformPixelMapPage {
})
.setImageViewSize({ width: vp2px(200), height: vp2px(200) })
.skipMemoryCache(true)
.openEfficient()
.enableGPU()
.contrastFilter(contrast)
ImageKnife.call(imageKnifeOption);
@ -819,7 +819,7 @@ struct TransformPixelMapPage {
})
.setImageViewSize({ width: vp2px(200), height: vp2px(200) })
.skipMemoryCache(true)
.openEfficient()
.enableGPU()
.invertFilter()
ImageKnife.call(imageKnifeOption);
@ -840,7 +840,7 @@ struct TransformPixelMapPage {
})
.setImageViewSize({ width: vp2px(200), height: vp2px(200) })
.skipMemoryCache(true)
.openEfficient()
.enableGPU()
.sepiaFilter()
ImageKnife.call(imageKnifeOption);
@ -861,7 +861,7 @@ struct TransformPixelMapPage {
})
.setImageViewSize({ width: vp2px(200), height: vp2px(200) })
.skipMemoryCache(true)
.openEfficient()
.enableGPU()
.sketchFilter()
ImageKnife.call(imageKnifeOption);
@ -882,7 +882,7 @@ struct TransformPixelMapPage {
})
.setImageViewSize({ width: vp2px(200), height: vp2px(200) })
.skipMemoryCache(true)
.openEfficient()
.enableGPU()
.blur(radius)
ImageKnife.call(imageKnifeOption);
@ -902,7 +902,7 @@ struct TransformPixelMapPage {
})
.setImageViewSize({ width: vp2px(200), height: vp2px(200) })
.skipMemoryCache(true)
.openEfficient()
.enableGPU()
.pixelationFilter(pixel)
ImageKnife.call(imageKnifeOption);
@ -923,7 +923,7 @@ struct TransformPixelMapPage {
})
.setImageViewSize({ width: vp2px(200), height: vp2px(200) })
.skipMemoryCache(true)
.openEfficient()
.enableGPU()
.swirlFilter(80)
// .diskCacheStrategy(new NONE())
ImageKnife.call(imageKnifeOption);
@ -952,7 +952,7 @@ struct TransformPixelMapPage {
}
/**
*kuwahar
*kuwahara
*/
kuwaharaHandlePixelMap() {
let imageKnifeOption = new RequestOption();
@ -965,7 +965,7 @@ struct TransformPixelMapPage {
})
.setImageViewSize({ width: vp2px(200), height: vp2px(200) })
.skipMemoryCache(true)
.openEfficient()
.enableGPU()
.kuwaharaFilter(20.0)
// .diskCacheStrategy(new NONE())
ImageKnife.call(imageKnifeOption);
@ -986,7 +986,7 @@ struct TransformPixelMapPage {
})
.setImageViewSize({ width: vp2px(200), height: vp2px(200) })
.skipMemoryCache(true)
.openEfficient()
.enableGPU()
.toonFilter(0.2, 50.0);
// .diskCacheStrategy(new NONE())
ImageKnife.call(imageKnifeOption);
@ -1007,7 +1007,7 @@ struct TransformPixelMapPage {
})
.setImageViewSize({ width: vp2px(200), height: vp2px(200) })
.skipMemoryCache(true)
.openEfficient()
.enableGPU()
.vignetteFilter([0.5, 0.5], [0.0, 0.0, 0.0], [0.3, 0.5])
// .diskCacheStrategy(new NONE())
ImageKnife.call(imageKnifeOption);

View File

@ -0,0 +1,16 @@
## 1.0.0
获取图片的buffer数据使用openGL、着色器Shader操作GPU达到图片滤波器的效
- 支持模糊滤波器
- 支持亮度滤波器
- 支持颜色反转滤波器
- 支持对比度滤波器
- 支持灰色滤波器
- 支持桑原滤波器
- 支持马赛克滤波器
- 支持乌墨色滤波器
- 支持素描滤波器
- 支持扭曲滤波器
- 支持动画滤波器
- 支持装饰滤波器

201
gpu_transform/LICENSE Normal file
View File

@ -0,0 +1,201 @@
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.

View File

@ -0,0 +1,11 @@
[
{
"Name": "android-gpuimage",
"License": " Apache License, Version 2.0",
"License File": "https://github.com/cats-oss/android-gpuimage",
"Version Number": "4.13.1",
"Owner" : "cats-oss",
"Upstream URL": "https://github.com/cats-oss/android-gpuimage",
"Description": "Android filters based on OpenGL (idea from GPUImage for iOS)"
}
]

79
gpu_transform/README.md Normal file
View File

@ -0,0 +1,79 @@
## gpu_transform
该module通过获取图片的buffer数据使用openGL、着色器Shader操作GPU达到图片滤波器的效果。
本项目基于开源库 [android-gpuimage](https://github.com/cats-oss/android-gpuimage) 进行OpenHarmony的自研版本
## 下载安装
```
npm install @ohos/gpu_transform --save
```
## 例子说明
```
//获取像素点数据
let bufferData = new ArrayBuffer(bitmap.getPixelBytesNumber());
await bitmap.readPixelsToBuffer(bufferData);
// 使用GPUImageVignetterFilter过滤器
let filter = new GPUImageVignetterFilter();
filter.setImageData(bufferData, targetWidth, targetHeight);
filter.setVignetteCenter(this.centerPoint);
filter.setVignetteColor(this.vignetteColor);
filter.setVignetteStart(this.vignetteSpace[0]);
filter.setVignetteEnd(this.vignetteSpace[1]);
//获取经过gpu处理的像素点数据
let buf = await filter.getPixelMapBuf(0, 0, targetWidth, targetHeight)
//像素点数据写入
bitmap.writeBufferToPixels(buf);
```
## 滤波器类型说明
| 滤波器类型 | 描述 |
| ---------------------------- | ---------------------------|
| GPUImageBlurFilter | 模糊滤波器 |
| GPUImageBrightnessFilter | 亮度滤波器 |
| GPUImageColorInvertFilter | 颜色反转滤波器 |
| GPUImageContrastFilter | 对比度滤波器 |
| GPUImageGrayscaleFilter | 灰色滤波器 |
| GPUImageKuwaharaFilter | 桑原滤波器 |
| GPUImagePixelationFilter | 马赛克滤波器 |
| GPUImageSepiaToneFilter | 乌墨色滤波器 |
| GPUImageSketchFilter | 素描滤波器 |
| GPUImageSwirlFilter | 扭曲滤波器 |
| GPUImageToonFilter | 动画滤波器 |
| GPUImageVignetterFilter | 装饰滤波器 |
## 目录结构
```
/gpu_transform/src/main
--cpp
--common # napi公共方法封装
--constant # 顶点、片元着色器
--napi # native入口
--render # 绘制
--util # 工具层
--ets
--filter # 各种滤波器
--gl # native的js层
--interface # 接口
```
## 兼容性
支持 OpenHarmony API version 9 及以上版本。
## 贡献代码
使用过程中发现任何问题都可以提 [issue](https://gitee.com/openharmony-tpc/ImageKnife/issues) 给我们,当然,我们也非常欢迎你给我们发 [PR](https://gitee.com/openharmony-tpc/ImageKnife/issues) 。
## 开源协议
本项目基于 [Apache License 2.0](https://gitee.com/openharmony-tpc/ImageKnife/blob/master/LICENSE) ,请自由的享受和参与开源。

View File

@ -1,14 +1,24 @@
{
"license": "ISC",
"types": "",
"devDependencies": {},
"name": "@ohos/gpu_transform",
"description": "a npm package which contains arkUI2.0 page",
"ohos": {
"org": ""
"license":"Apache License 2.0",
"types":"",
"devDependencies":{},
"keywords":[
"OpenHarmony",
"transformation",
"gpu_transform"
],
"name":"@ohos/gpu_transform",
"description":"based on OpenHarmony system, it can quickly realize image blur, Mosaic, sketch and other transformation effects through GPU",
"author":"ohos_tpc",
"ohos":{
"org":"opensource"
},
"main": "index.ets",
"type": "module",
"version": "1.0.0",
"dependencies": {}
}
"tags":[
"Tool"
],
"main":"index.ets",
"repository":"https://gitee.com/openharmony-tpc/ImageKnife",
"type":"module",
"version":"1.0.0",
"dependencies":{}
}

View File

@ -14,10 +14,10 @@ include_directories(${NATIVERENDER_ROOT_PATH}
)
add_library(nativeGpu SHARED
napi/napi_init.cpp
render/EGLRender.cpp
util/GLUtils.cpp
util/NapiUtil.cpp
${NATIVERENDER_ROOT_PATH}/napi/napi_init.cpp
${NATIVERENDER_ROOT_PATH}/render/EGLRender.cpp
${NATIVERENDER_ROOT_PATH}/util/GLUtils.cpp
${NATIVERENDER_ROOT_PATH}/util/NapiUtil.cpp
)
find_library (

View File

@ -17,7 +17,6 @@
// Created on 2022/12/15.
//
// Node APIs are not fully supported. To solve the compilation error of the interface cannot be found,
// please include "napi/native_api.h".
#ifndef GPU_ImageETS_native_common_H
#define GPU_ImageETS_native_common_H

View File

@ -17,7 +17,6 @@
// Created on 2022/12/16.
//
// Node APIs are not fully supported. To solve the compilation error of the interface cannot be found,
// please include "napi/native_api.h".
#ifndef GPU_ImageETS_constant_shape_H
#define GPU_ImageETS_constant_shape_H
@ -46,13 +45,13 @@ const int UNIFORM_TYPE_FOUR = 4;
const int SHADER_TYPE_BRIGHT = 0;
const int SHADER_TYPE_CONTRAST = 1;
const int SHADER_TYPE_INVERT = 2;
const int SHADER_TYPE_KUWAHARA = 4;
const int SHADER_TYPE_PIXELATION = 3;
const int SHADER_TYPE_KUWAHARA = 4;
const int SHADER_TYPE_SEPIA = 5;
const int SHADER_TYPE_SKETCH = 6;
const int SHADER_TYPE_SWIRL = 7;
const int SHADER_TYPE_TOON = 8;
const int SHADER_TYPE_VIGNETTE = 9;
const int SHADER_TYPE_SEPIA = 5;
const int SHADER_TYPE_GRAYSCALE = 10;
const int SHADER_TYPE_BLUR = 12;

View File

@ -17,7 +17,6 @@
// Created on 2022/12/20.
//
// Node APIs are not fully supported. To solve the compilation error of the interface cannot be found,
// please include "napi/native_api.h".
#include <js_native_api.h>
@ -27,31 +26,6 @@
#include "native_common.h"
#include "EGLRender.h"
static napi_value Add(napi_env env, napi_callback_info info)
{
size_t requireArgc = 2;
size_t argc = 2;
napi_value args[2] = {nullptr};
napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
napi_valuetype valuetype0;
napi_typeof(env, args[0], &valuetype0);
napi_valuetype valuetype1;
napi_typeof(env, args[1], &valuetype1);
double value0;
napi_get_value_double(env, args[0], &value0);
double value1;
napi_get_value_double(env, args[1], &value1);
napi_value sum;
napi_create_double(env, value0 + value1, &sum);
return sum;
}
static napi_value Init(napi_env env, napi_value exports)
{
napi_property_descriptor desc[] = {

View File

@ -17,11 +17,11 @@
// Created on 2022/12/20.
//
// Node APIs are not fully supported. To solve the compilation error of the interface cannot be found,
// please include "napi/native_api.h".
#include "EGLRender.h"
#include <js_native_api.h>
#include <mutex>
#include <napi/native_api.h>
#include <stdlib.h>
#include <EGL/egl.h>
@ -69,7 +69,17 @@ const static GLfloat vFboTexCoors[] = {
};
const static GLushort indices[] = { 0, 1, 2, 1, 3, 2 };
std::mutex mtx;
EGLRender* EGLRender::GetInstance()
{
mtx.lock();
if (sInstance == nullptr) {
sInstance = new EGLRender();
}
mtx.unlock();
return sInstance;
}
napi_value EGLRender::RenderInit(napi_env env, napi_callback_info info)
{
@ -166,7 +176,7 @@ napi_value EGLRender::GetPixelMapOfSurface(napi_env env, napi_callback_info info
glPixelStorei(GL_PACK_ALIGNMENT, 1);
glReadPixels(x, y, surfaceWidth, surfaceHeight, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
NativeImageUtil::flip(&pixels, surfaceWidth, surfaceHeight);
NativeImageUtil::Flip(&pixels, surfaceWidth, surfaceHeight);
napi_value array;
int byte_length = surfaceWidth * surfaceHeight * DEFAULT_FOUR;
if (!NativeImageUtil::CreateArrayBuffer(env, pixels, byte_length, &array)) {

View File

@ -17,7 +17,6 @@
// Created on 2022/12/20.
//
// Node APIs are not fully supported. To solve the compilation error of the interface cannot be found,
// please include "napi/native_api.h".
#ifndef GPU_ImageETS_EGLRender_H
#define GPU_ImageETS_EGLRender_H
@ -29,20 +28,11 @@
#include "NativeImage.h"
const int EGL_FEATURE_NUM = 7;
class EGLRender {
public:
private:
EGLRender();
~EGLRender();
static EGLRender* GetInstance()
{
if (sInstance == nullptr) {
sInstance = new EGLRender();
}
return sInstance;
}
public:
static void DestroyRender()
{
if (sInstance) {
@ -50,6 +40,7 @@ public:
sInstance = nullptr;
}
}
static EGLRender* GetInstance();
static napi_value RenderInit(napi_env env, napi_callback_info info);
static napi_value RenderSetData(napi_env env, napi_callback_info info);
static napi_value GetPixelMapOfSurface(napi_env env, napi_callback_info info);

View File

@ -13,4 +13,17 @@
* limitations under the License.
*/
export const add: (a: number, b: number) => number;
export const EglRenderInit: () => void;
export const EglRenderSetImageData: (bytes:ArrayBuffer,width:number,height:number) => void;
export const EglRenderSetIntParams: (paramType:number,param:number) => void;
export const EglPixelMapSurface: (x:number,y:number,w:number,h:number) => ArrayBuffer;
export const EglIsInit: () => number;
export const EglUseProgram: () => void;
export const EglRendering: () => void;
export const EglUniform1i: (key:string,value:number) => void;
export const EglUniform1f: (key:string,value:number) => void;
export const EglUniform2fv: (key:string,vf1:number,vf2:number) => void;
export const EglSetTypeArrayOfFloat: (key:string,uniformType:string,data:Float32Array) => void;
export const EglSetTypeArrayOfMatrix3f: (key:string,value:Float32Array) => void;
export const EglSetTypeArrayOfMatrix4f: (key:string,value:Float32Array) => void;
export const EglDestroy: () => void;

View File

@ -17,7 +17,6 @@
// Created on 2022/12/21.
//
// Node APIs are not fully supported. To solve the compilation error of the interface cannot be found,
// please include "napi/native_api.h".
#ifndef GPU_ImageETS_DebugLog_H
#define GPU_ImageETS_DebugLog_H

View File

@ -17,7 +17,6 @@
// Created on 2022/12/21.
//
// Node APIs are not fully supported. To solve the compilation error of the interface cannot be found,
// please include "napi/native_api.h".
#include <malloc.h>
#include <stddef.h>

View File

@ -17,7 +17,6 @@
// Created on 2022/12/21.
//
// Node APIs are not fully supported. To solve the compilation error of the interface cannot be found,
// please include "napi/native_api.h".
#ifndef GPU_ImageETS_GLUtils_H
#define GPU_ImageETS_GLUtils_H

View File

@ -17,7 +17,6 @@
// Created on 2022/12/21.
//
// Node APIs are not fully supported. To solve the compilation error of the interface cannot be found,
// please include "napi/native_api.h".
#include "NapiUtil.h"

View File

@ -17,7 +17,6 @@
// Created on 2022/12/21.
//
// Node APIs are not fully supported. To solve the compilation error of the interface cannot be found,
// please include "napi/native_api.h".
#ifndef GPU_ImageETS_NapiUtil_H
#define GPU_ImageETS_NapiUtil_H

View File

@ -17,7 +17,6 @@
// Created on 2022/12/21.
//
// Node APIs are not fully supported. To solve the compilation error of the interface cannot be found,
// please include "napi/native_api.h".
#ifndef GPU_ImageETS_NativeImage_H
#define GPU_ImageETS_NativeImage_H
@ -145,7 +144,7 @@ public:
return true;
}
static void flip(uint8_t** buf, int width, int height)
static void Flip(uint8_t** buf, int width, int height)
{
int totalLength = width * height * DEFAULT_FOUR;
int oneLineLength = width * DEFAULT_FOUR;

View File

@ -13,39 +13,41 @@
* limitations under the License.
*/
import {GPUImageFilter} from './GPUImageFilter'
import {GPUFilterType} from '../gl/GPUFilterType'
import { GPUImageFilter } from './GPUImageFilter'
import { GPUFilterType } from '../gl/GPUFilterType'
export class GPUImage3x3TextureSamplingFilter extends GPUImageFilter{
private texelWidth:number;
private texelHeight:number;
private lineSize:number = 1.0;
export class GPUImage3x3TextureSamplingFilter extends GPUImageFilter {
private texelWidth: number;
private texelHeight: number;
private lineSize: number = 1.0;
constructor(){
constructor() {
super();
}
getFilterType():GPUFilterType{
getFilterType(): GPUFilterType {
return GPUFilterType.X3TEXTURE;
}
onInitialized(){
onInitialized() {
}
onReadySize(){
onReadySize() {
}
setLineSize(lineSize:number){
setLineSize(lineSize: number) {
this.lineSize = lineSize;
}
setTexelWidth(texelWidth:number){
this.texelWidth = this.lineSize/texelWidth;
this.setFloat("texelWidth",this.texelWidth);
setTexelWidth(texelWidth: number) {
this.texelWidth = this.lineSize / texelWidth;
this.setFloat("texelWidth", this.texelWidth);
}
setTexelHeight(texelHeight:number){
this.texelHeight = this.lineSize/texelHeight;
this.setFloat("texelHeight",this.texelHeight);
setTexelHeight(texelHeight: number) {
this.texelHeight = this.lineSize / texelHeight;
this.setFloat("texelHeight", this.texelHeight);
}
}

View File

@ -13,56 +13,57 @@
* limitations under the License.
*/
import {GPUImageFilter} from './GPUImageFilter'
import {GPUFilterType} from '../gl/GPUFilterType'
import { GPUImageFilter } from './GPUImageFilter'
import { GPUFilterType } from '../gl/GPUFilterType'
export class GPUImageBlurFilter extends GPUImageFilter{
private blurRadius:number;
private blurOffset:Array<number>;
private sumWeight:number;
export class GPUImageBlurFilter extends GPUImageFilter {
private blurRadius: number;
private blurOffset: Array<number>;
private sumWeight: number;
constructor(){
constructor() {
super();
}
getFilterType():GPUFilterType{
getFilterType(): GPUFilterType {
return GPUFilterType.BLUR;
}
onInitialized(){
}
onReadySize(){
onInitialized() {
}
setBlurRadius(blurRadius:number){
onReadySize() {
}
setBlurRadius(blurRadius: number) {
this.blurRadius = blurRadius;
this.setInteger("blurRadius",this.blurRadius);
this.setInteger("blurRadius", this.blurRadius);
this.calculateSumWeight();
}
setBlurOffset(blurOffset:Array<number>){
setBlurOffset(blurOffset: Array<number>) {
let offset = new Array<number>(2);
if (this.width<=0||this.height<=0) {
if (this.width <= 0 || this.height <= 0) {
throw new Error("the width or height must be greater than 0");
}
if (!blurOffset || blurOffset.length!==2) {
if (!blurOffset || blurOffset.length !== 2) {
throw new Error("you should a valid value needs to be set.")
}
offset[0] = blurOffset[0]/this.width;
offset[0] = blurOffset[0] / this.width;
offset[1] = blurOffset[1] / this.height;
this.blurOffset = offset;
this.setFloat2f("blurOffset",this.blurOffset);
this.setFloat2f("blurOffset", this.blurOffset);
}
setSumWeight(sumWeight:number){
setSumWeight(sumWeight: number) {
this.sumWeight = sumWeight;
this .setFloat("sumWeight",this.sumWeight);
this.setFloat("sumWeight", this.sumWeight);
}
private calculateSumWeight(){
private calculateSumWeight() {
if (this.blurRadius < 1) {
this.setSumWeight(0);
return;
@ -70,10 +71,10 @@ export class GPUImageBlurFilter extends GPUImageFilter{
let sumWeight = 0;
let sigma = this.blurRadius / 3.0;
for (let i = 0; i < this.blurRadius; i++) {
let weight = ((1.0/Math.sqrt(2.0*Math.PI*sigma*sigma))*Math.exp(-(i*i)/(2.0*sigma*sigma)));
let weight = ((1.0 / Math.sqrt(2.0 * Math.PI * sigma * sigma)) * Math.exp(-(i * i) / (2.0 * sigma * sigma)));
sumWeight += weight;
if (i != 0) {
sumWeight +=weight;
sumWeight += weight;
}
}
this.setSumWeight(sumWeight);

View File

@ -13,32 +13,33 @@
* limitations under the License.
*/
import {GPUImageFilter} from './GPUImageFilter'
import {GPUFilterType} from '../gl/GPUFilterType'
import { GPUImageFilter } from './GPUImageFilter'
import { GPUFilterType } from '../gl/GPUFilterType'
export class GPUImageBrightnessFilter extends GPUImageFilter{
private brightness:number = 25
export class GPUImageBrightnessFilter extends GPUImageFilter {
private brightness: number = 25
constructor(brightness?:number){
constructor(brightness?: number) {
super()
if (brightness) {
this.brightness =brightness;
this.brightness = brightness;
}
}
getFilterType():GPUFilterType{
getFilterType(): GPUFilterType {
return GPUFilterType.BRIGHT;
}
onInitialized(){
}
onReadySize(){
onInitialized() {
}
setBrightness(brightness:number){
onReadySize() {
}
setBrightness(brightness: number) {
this.brightness = brightness;
this.setFloat("brightness",this.brightness);
this.setFloat("brightness", this.brightness);
}
}

View File

@ -13,25 +13,24 @@
* limitations under the License.
*/
import {GPUImageFilter} from './GPUImageFilter'
import {GPUFilterType} from '../gl/GPUFilterType'
import { GPUImageFilter } from './GPUImageFilter'
import { GPUFilterType } from '../gl/GPUFilterType'
export class GPUImageColorInvertFilter extends GPUImageFilter{
constructor(){
export class GPUImageColorInvertFilter extends GPUImageFilter {
constructor() {
super()
}
getFilterType():GPUFilterType{
getFilterType(): GPUFilterType {
return GPUFilterType.INVERT;
}
onInitialized(){
onInitialized() {
}
onReadySize(){
onReadySize() {
}
}

View File

@ -13,45 +13,44 @@
* limitations under the License.
*/
import {GPUImageFilter} from './GPUImageFilter'
import {GPUFilterType} from '../gl/GPUFilterType'
import { GPUImageFilter } from './GPUImageFilter'
import { GPUFilterType } from '../gl/GPUFilterType'
export class GPUImageColorMatrixFilter extends GPUImageFilter{
private intensity :number = 1.0;
private colorMatrix:Array<number> = [
1.0,0.0,0.0,0.0,
0.0,1.0,0.0,0.0,
0.0,0.0,1.0,0.0,
0.0,0.0,0.0,1.0
export class GPUImageColorMatrixFilter extends GPUImageFilter {
private intensity: number = 1.0;
private colorMatrix: Array<number> = [
1.0, 0.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 1.0
]
constructor(intensity?:number){
constructor(intensity?: number) {
super()
if (intensity) {
this.intensity = intensity;
}
}
getFilterType():GPUFilterType{
getFilterType(): GPUFilterType {
return GPUFilterType.CONTRAST;
}
onInitialized(){
}
onReadySize(){
onInitialized() {
}
setIntensity(intensity:number){
onReadySize() {
}
setIntensity(intensity: number) {
this.intensity = intensity;
this.setFloat("intensity",this.intensity);
this.setFloat("intensity", this.intensity);
}
setColorMatrix(colorMatrix:Array<number>){
setColorMatrix(colorMatrix: Array<number>) {
this.colorMatrix = colorMatrix;
this.setUniformMatrix4f("colorMatrix",this.colorMatrix);
this.setUniformMatrix4f("colorMatrix", this.colorMatrix);
}
}

View File

@ -13,34 +13,33 @@
* limitations under the License.
*/
import {GPUImageFilter} from './GPUImageFilter'
import {GPUFilterType} from '../gl/GPUFilterType'
import { GPUImageFilter } from './GPUImageFilter'
import { GPUFilterType } from '../gl/GPUFilterType'
export class GPUImageContrastFilter extends GPUImageFilter{
export class GPUImageContrastFilter extends GPUImageFilter {
private contrast: number = 1.0;
private contrast :number = 1.0;
constructor(contrast?:number){
constructor(contrast?: number) {
super()
if (contrast) {
this.contrast = contrast;
}
}
getFilterType():GPUFilterType{
getFilterType(): GPUFilterType {
return GPUFilterType.CONTRAST;
}
onInitialized(){
}
onReadySize(){
onInitialized() {
}
setContrast(contrast:number){
this.contrast = contrast;
this.setFloat("contrast",this.contrast);
}
onReadySize() {
}
setContrast(contrast: number) {
this.contrast = contrast;
this.setFloat("contrast", this.contrast);
}
}

View File

@ -13,87 +13,40 @@
* limitations under the License.
*/
import {NativeEglRender} from '../gl/NativeEglRender'
import {GPUFilterType} from '../gl/GPUFilterType'
import {Runnable} from '../interface/Runnable'
import image from '@ohos.multimedia.image';
import { NativeEglRender } from '../gl/NativeEglRender'
import { GPUFilterType } from '../gl/GPUFilterType'
import { Runnable } from '../interface/Runnable'
import LinkedList from '@ohos.util.LinkedList';
import ArrayList from '@ohos.util.ArrayList';
export abstract class GPUImageFilter{
private render:NativeEglRender;
private isInitialized:boolean;
private runOnDraw:LinkedList<Runnable>;
protected width:number;
protected height:number;
export abstract class GPUImageFilter {
private render: NativeEglRender;
private isInitialized: boolean;
private runOnDraw: LinkedList<Runnable>;
protected width: number;
protected height: number;
constructor(){
constructor() {
this.render = new NativeEglRender();
this.runOnDraw = new LinkedList();
}
private init(){
private init() {
if (this.render) {
this.render.native_EglRenderInit();
}
this.onInitialized();
}
protected setSurfaceFilterType(){
let filter = this .getFilterType();
let filterType :number;
switch(filter){
case GPUFilterType.BRIGHT:
filterType = 0;
break;
case GPUFilterType.CONTRAST:
filterType = 1;
break;
case GPUFilterType.INVERT:
filterType = 2;
break;
case GPUFilterType.PIXELATION:
filterType = 3;
break;
case GPUFilterType.KUWAHARA:
filterType = 4;
break;
case GPUFilterType.SEPIA:
filterType = 5;
break;
case GPUFilterType.SKETCH:
filterType = 6;
break;
case GPUFilterType.SWIRL:
filterType = 7;
break;
case GPUFilterType.TOON:
filterType = 8;
break;
case GPUFilterType.VIGNETTE:
filterType = 9;
break;
case GPUFilterType.GRAYSCALE:
filterType = 10;
break;
case GPUFilterType.X3TEXTURE:
filterType = 11;
break;
case GPUFilterType.BLUR:
filterType = 12;
break;
case GPUFilterType.COLOR_M:
filterType = 100;
break;
}
protected setSurfaceFilterType() {
let filter = this.getFilterType();
if (!this.render.native_glIsInit()) {
throw new Error("the egl surface not init");
}
this.render.native_EglRenderSetIntParams(300,filterType);
this.render.native_EglRenderSetIntParams(300, filter.valueOf());
}
setImageData(buf:ArrayBuffer,width:number,height:number){
setImageData(buf: ArrayBuffer, width: number, height: number) {
if (!buf) {
throw new Error("this pixelMap data is empty");
}
@ -102,15 +55,13 @@ export abstract class GPUImageFilter{
}
this.width = width;
this.height = height;
this.ifNeedInit();
this.ensureInit();
this.onReadySize();
this.setSurfaceFilterType();
this.render.native_EglRenderSetImageData(buf,width,height);
this.render.native_EglRenderSetImageData(buf, width, height);
}
protected onDraw(){
protected onDraw() {
if (!this.render.native_glIsInit()) {
throw new Error("the egl surface not init")
}
@ -119,32 +70,31 @@ export abstract class GPUImageFilter{
this.onRendering();
}
protected onRendering(){
protected onRendering() {
this.render.native_EglRendering();
}
getPixelMapBuf(x:number,y:number,width:number,height:number):Promise<ArrayBuffer>{
if (x<0||y<0) {
getPixelMapBuf(x: number, y: number, width: number, height: number): Promise<ArrayBuffer> {
if (x < 0 || y < 0) {
throw new Error("the x or y should be greater than 0")
}
if (width<=0||height<=0) {
if (width <= 0 || height <= 0) {
throw new Error("the width or height should be greater than 0")
}
let that = this;
return new Promise((resolve,rejects)=>{
return new Promise((resolve, rejects) => {
that.onDraw();
let buf = this .render.native_EglBitmapFromGLSurface(x,y,width,height);
let buf = this.render.native_EglBitmapFromGLSurface(x, y, width, height);
if (!buf) {
rejects(new Error("get pixelMap fail"))
}else{
} else {
resolve(buf);
that.destroy();
}
})
}
ifNeedInit(){
ensureInit() {
if (this.render) {
this.isInitialized = this.render.native_glIsInit();
if (!this.isInitialized) {
@ -153,179 +103,176 @@ export abstract class GPUImageFilter{
}
}
protected runPendingOnDrawTasks(){
while(this.runOnDraw.length>0){
protected runPendingOnDrawTasks() {
while (this.runOnDraw.length > 0) {
this.runOnDraw.removeFirst().run();
}
}
protected addRunOnDraw(runAble:Runnable){
protected addRunOnDraw(runAble: Runnable) {
if (!runAble) {
return;
}
this.runOnDraw.add(runAble);
}
protected setInteger(location:string,value:number){
protected setInteger(location: string, value: number) {
let that = this;
let able:Runnable = {
run(){
that.ifNeedInit();
that.render.native_setInteger(location,value);
let able: Runnable = {
run() {
that.ensureInit();
that.render.native_setInteger(location, value);
}
}
this.addRunOnDraw(able);
}
protected setFloat(location:string,value:number){
protected setFloat(location: string, value: number) {
let that = this;
let able:Runnable = {
run(){
that.ifNeedInit();
that.render.native_setFloat(location,value);
let able: Runnable = {
run() {
that.ensureInit();
that.render.native_setFloat(location, value);
}
}
this.addRunOnDraw(able);
}
protected setPoint(location:string,vf1:number,vf2:number){
protected setPoint(location: string, vf1: number, vf2: number) {
let that = this;
let able:Runnable = {
run(){
that.ifNeedInit();
that.render.native_setPoint(location,vf1,vf2);
let able: Runnable = {
run() {
that.ensureInit();
that.render.native_setPoint(location, vf1, vf2);
}
}
this.addRunOnDraw(able);
}
protected setFloat2f(location:string,value:Array<number>){
if (value.length !==2) {
protected setFloat2f(location: string, value: Array<number>) {
if (value.length !== 2) {
return;
}
let that = this;
let able:Runnable = {
run(){
that.ifNeedInit();
let able: Runnable = {
run() {
that.ensureInit();
let array = new Float32Array(2);
array[0] = value[0];
array[1] = value[1];
that.render.native_setFloat2f(location,array);
that.render.native_setFloat2f(location, array);
}
}
this.addRunOnDraw(able);
}
protected setFloatVec2(location:string,value:Array<number>){
if (value.length !==2) {
protected setFloatVec2(location: string, value: Array<number>) {
if (value.length !== 2) {
return;
}
let that = this;
let able:Runnable = {
run(){
that.ifNeedInit();
let able: Runnable = {
run() {
that.ensureInit();
let array = new Float32Array(2);
array[0] = value[0];
array[1] = value[1];
that.render.native_setFloatVec2(location,array);
that.render.native_setFloatVec2(location, array);
}
}
this.addRunOnDraw(able);
}
protected setFloatVec3(location:string,value:Array<number>){
if (value.length !==3) {
protected setFloatVec3(location: string, value: Array<number>) {
if (value.length !== 3) {
return;
}
let that = this;
let able:Runnable = {
run(){
that.ifNeedInit();
let able: Runnable = {
run() {
that.ensureInit();
let array = new Float32Array(3);
array[0] = value[0];
array[1] = value[1];
array[2] = value[2];
that.render.native_setFloatVec3(location,array);
that.render.native_setFloatVec3(location, array);
}
}
this.addRunOnDraw(able);
}
protected setFloatVec4(location:string,value:Array<number>){
if (value.length !==4) {
protected setFloatVec4(location: string, value: Array<number>) {
if (value.length !== 4) {
return;
}
let that = this;
let able:Runnable = {
run(){
that.ifNeedInit();
let able: Runnable = {
run() {
that.ensureInit();
let array = new Float32Array(4);
array[0] = value[0];
array[1] = value[1];
array[2] = value[2];
array[3] = value[3];
that.render.native_setFloatVec4(location,array);
that.render.native_setFloatVec4(location, array);
}
}
this.addRunOnDraw(able);
}
protected setUniformMatrix3f(location:string,value:Array<number>){
protected setUniformMatrix3f(location: string, value: Array<number>) {
if (!value) {
return;
}
let that = this;
let able:Runnable = {
run(){
that.ifNeedInit();
let able: Runnable = {
run() {
that.ensureInit();
let array = new Float32Array(value.length);
for (let i = 0; i < value.length; i++) {
array[i] = value[i];
}
that.render.native_setUniformMatrix3f(location,array);
that.render.native_setUniformMatrix3f(location, array);
}
}
this.addRunOnDraw(able);
}
protected setUniformMatrix4f(location:string,value:Array<number>){
protected setUniformMatrix4f(location: string, value: Array<number>) {
if (!value) {
return;
}
let that = this;
let able:Runnable = {
run(){
that.ifNeedInit();
let able: Runnable = {
run() {
that.ensureInit();
let array = new Float32Array(value.length);
for (let i = 0; i < value.length; i++) {
array[i] = value[i];
}
that.render.native_setUniformMatrix4f(location,array);
that.render.native_setUniformMatrix4f(location, array);
}
}
this.addRunOnDraw(able);
}
getFilters():ArrayList<GPUImageFilter>{
getFilters(): ArrayList<GPUImageFilter> {
return null;
}
destroy(){
destroy() {
this.render.native_glIsDestroy();
this.render = null;
this.isInitialized = false;
}
abstract getFilterType(): GPUFilterType;
abstract getFilterType():GPUFilterType;
abstract onReadySize();
abstract onInitialized();
}

View File

@ -13,25 +13,23 @@
* limitations under the License.
*/
import {GPUImageFilter} from './GPUImageFilter'
import {GPUFilterType} from '../gl/GPUFilterType'
import { GPUImageFilter } from './GPUImageFilter'
import { GPUFilterType } from '../gl/GPUFilterType'
import ArrayList from '@ohos.util.ArrayList';
export abstract class GPUImageFilterGroup extends GPUImageFilter{
export abstract class GPUImageFilterGroup extends GPUImageFilter {
private filters: ArrayList<GPUImageFilter>;
private filters :ArrayList<GPUImageFilter>;
constructor(){
constructor() {
super()
this.filters = new ArrayList();
}
addFilter(aFilter:GPUImageFilter){
addFilter(aFilter: GPUImageFilter) {
this.filters.add(aFilter);
}
getFilters():ArrayList<GPUImageFilter>{
getFilters(): ArrayList<GPUImageFilter> {
return this.filters;
}
}

View File

@ -13,23 +13,24 @@
* limitations under the License.
*/
import {GPUImageFilter} from './GPUImageFilter'
import {GPUFilterType} from '../gl/GPUFilterType'
import { GPUImageFilter } from './GPUImageFilter'
import { GPUFilterType } from '../gl/GPUFilterType'
export class GPUImageGrayscaleFilter extends GPUImageFilter{
constructor(){
export class GPUImageGrayscaleFilter extends GPUImageFilter {
constructor() {
super()
}
getFilterType():GPUFilterType{
getFilterType(): GPUFilterType {
return GPUFilterType.GRAYSCALE;
}
onInitialized(){
onInitialized() {
}
onReadySize(){
onReadySize() {
}
}

View File

@ -13,33 +13,35 @@
* limitations under the License.
*/
import {GPUImageFilter} from './GPUImageFilter'
import {GPUFilterType} from '../gl/GPUFilterType'
import { GPUImageFilter } from './GPUImageFilter'
import { GPUFilterType } from '../gl/GPUFilterType'
export class GPUImageKuwaharaFilter extends GPUImageFilter{
private _radius :number = 25;
constructor(radius?:number){
export class GPUImageKuwaharaFilter extends GPUImageFilter {
private _radius: number = 25;
constructor(radius?: number) {
super()
if (radius) {
this._radius= radius;
this._radius = radius;
}
}
getFilterType():GPUFilterType{
getFilterType(): GPUFilterType {
return GPUFilterType.KUWAHARA;
}
onInitialized(){
}
onReadySize(){
onInitialized() {
}
setRadius(radius:number){
onReadySize() {
}
setRadius(radius: number) {
this._radius = radius;
this.setFloat("radius",this._radius);
this.setFloat("radius", this._radius);
}
}

View File

@ -13,31 +13,33 @@
* limitations under the License.
*/
import {GPUImageFilter} from './GPUImageFilter'
import {GPUFilterType} from '../gl/GPUFilterType'
import { GPUImageFilter } from './GPUImageFilter'
import { GPUFilterType } from '../gl/GPUFilterType'
export class GPUImagePixelationFilter extends GPUImageFilter{
private pixel :number = 1.0;
constructor(){
export class GPUImagePixelationFilter extends GPUImageFilter {
private pixel: number = 1.0;
constructor() {
super()
}
getFilterType():GPUFilterType{
getFilterType(): GPUFilterType {
return GPUFilterType.PIXELATION;
}
onInitialized(){
}
onReadySize(){
onInitialized() {
}
setPixel(pixel:number){
this.pixel =pixel;
this.setFloat("imageWidthFactor",1.0/this.width);
this.setFloat("imageHeightFactor",1.0/this.height);
this.setFloat("pixel",this.pixel);
onReadySize() {
}
setPixel(pixel: number) {
this.pixel = pixel;
this.setFloat("imageWidthFactor", 1.0 / this.width);
this.setFloat("imageHeightFactor", 1.0 / this.height);
this.setFloat("pixel", this.pixel);
}
}

View File

@ -32,7 +32,6 @@ export class GPUImageSepiaToneFilter extends GPUImageColorMatrixFilter {
return GPUFilterType.SEPIA;
}
onReadySize() {
}

View File

@ -17,10 +17,10 @@ import { GPUImageFilter } from './GPUImageFilter'
import { GPUFilterType } from '../gl/GPUFilterType'
export class GPUImageSwirlFilter extends GPUImageFilter {
private _radius:number = 25;
private _angle:number = 0.9;
private _xCenter:number = 0.5;
private _yCenter:number = 0.5;
private _radius: number = 25;
private _angle: number = 0.9;
private _xCenter: number = 0.5;
private _yCenter: number = 0.5;
constructor() {
super()
@ -37,19 +37,19 @@ export class GPUImageSwirlFilter extends GPUImageFilter {
onReadySize() {
}
setRadius(radius:number){
this._radius =radius;
this.setFloat("radius",this._radius);
setRadius(radius: number) {
this._radius = radius;
this.setFloat("radius", this._radius);
}
setAngle(angle:number){
setAngle(angle: number) {
this._angle = angle;
this.setFloat("angle",this._angle);
this.setFloat("angle", this._angle);
}
setCenter(x_center:number,y_center:number){
setCenter(x_center: number, y_center: number) {
this._xCenter = x_center;
this._yCenter = y_center;
this.setPoint("center",x_center,y_center);
this.setPoint("center", x_center, y_center);
}
}

View File

@ -17,8 +17,8 @@ import { GPUImage3x3TextureSamplingFilter } from './GPUImage3x3TextureSamplingFi
import { GPUFilterType } from '../gl/GPUFilterType'
export class GPUImageToonFilter extends GPUImage3x3TextureSamplingFilter {
private threshold:number = 0.2;
private quantizationLevels:number = 10.0;
private threshold: number = 0.2;
private quantizationLevels: number = 10.0;
constructor() {
super()
@ -37,13 +37,13 @@ export class GPUImageToonFilter extends GPUImage3x3TextureSamplingFilter {
this.setTexelHeight(this.height);
}
setThreshold(threshold:number){
this.threshold = threshold;
this.setFloat("threshold",threshold);
}
setThreshold(threshold: number) {
this.threshold = threshold;
this.setFloat("threshold", threshold);
}
setQuantizationLevels(quantizationLevels:number){
setQuantizationLevels(quantizationLevels: number) {
this.quantizationLevels = quantizationLevels;
this.setFloat("quantizationLevels",quantizationLevels);
this.setFloat("quantizationLevels", quantizationLevels);
}
}

View File

@ -17,10 +17,10 @@ import { GPUImageFilter } from './GPUImageFilter'
import { GPUFilterType } from '../gl/GPUFilterType'
export class GPUImageVignetterFilter extends GPUImageFilter {
private vignetteCenter:Array<number> = [0.0,0.0];
private vignetteColor:Array<number> =[0.0,0.0,0.0];
private vignetteStart:number;
private vignetteEnd:number;
private vignetteCenter: Array<number> = [0.0, 0.0];
private vignetteColor: Array<number> = [0.0, 0.0, 0.0];
private vignetteStart: number;
private vignetteEnd: number;
constructor() {
super()
@ -37,22 +37,23 @@ export class GPUImageVignetterFilter extends GPUImageFilter {
onReadySize() {
}
setVignetteCenter(center:Array<number>){
this.vignetteCenter =center;
this.setFloatVec2("vignetteCenter",center);
setVignetteCenter(center: Array<number>) {
this.vignetteCenter = center;
this.setFloatVec2("vignetteCenter", center);
}
setVignetteColor(colors:Array<number>){
setVignetteColor(colors: Array<number>) {
this.vignetteColor = colors;
this.setFloatVec3("vignetteColor",colors);
this.setFloatVec3("vignetteColor", colors);
}
setVignetteStart(start:number){
this.vignetteStart =start;
this.setFloat("vignetteStart",this.vignetteStart);
}
setVignetteEnd(end:number){
this.vignetteEnd =end;
this.setFloat("vignetteEnd",this.vignetteEnd);
setVignetteStart(start: number) {
this.vignetteStart = start;
this.setFloat("vignetteStart", this.vignetteStart);
}
setVignetteEnd(end: number) {
this.vignetteEnd = end;
this.setFloat("vignetteEnd", this.vignetteEnd);
}
}

View File

@ -13,19 +13,19 @@
* limitations under the License.
*/
export enum GPUFilterType{
export enum GPUFilterType {
BRIGHT,
CONTRAST,
INVERT,
KUWAHARA,
PIXELATION,
KUWAHARA,
SEPIA,
SKETCH,
SWIRL,
TOON,
VIGNETTE,
COLOR_M,
GRAYSCALE,
X3TEXTURE,
BLUR
BLUR,
COLOR_M
}

View File

@ -15,87 +15,87 @@
import nativeGpu from "libnativeGpu.so"
export class NativeEglRender{
static EGLTrue : number =1;
export class NativeEglRender {
static EGLTrue: number = 1;
native_EglRenderInit():void{
native_EglRenderInit(): void {
nativeGpu.EglRenderInit();
}
native_EglRenderSetImageData(bytes:ArrayBuffer,width:number,height:number){
nativeGpu.EglRenderSetImageData(bytes,width,height);
native_EglRenderSetImageData(bytes: ArrayBuffer, width: number, height: number) {
nativeGpu.EglRenderSetImageData(bytes, width, height);
}
native_EglRenderSetIntParams(paramType:number,param:number){
nativeGpu.EglRenderSetIntParams(paramType,param);
native_EglRenderSetIntParams(paramType: number, param: number) {
nativeGpu.EglRenderSetIntParams(paramType, param);
}
native_EglBitmapFromGLSurface(x:number,y:number,w:number,h:number):ArrayBuffer{
let num = nativeGpu.EglPixelMapSurface(x,y,w,h);
native_EglBitmapFromGLSurface(x: number, y: number, w: number, h: number): ArrayBuffer {
let num = nativeGpu.EglPixelMapSurface(x, y, w, h);
return num;
}
native_glIsInit():boolean{
let initStatus= nativeGpu.EglIsInit();
native_glIsInit(): boolean {
let initStatus = nativeGpu.EglIsInit();
if (initStatus === NativeEglRender.EGLTrue) {
return true;
}
return false;
}
native_EglUseProgram(){
native_EglUseProgram() {
nativeGpu.EglUseProgram();
}
native_EglRendering(){
native_EglRendering() {
nativeGpu.EglRendering();
}
native_setInteger(key:string,value:number){
nativeGpu.EglUniform1i(key,value)
native_setInteger(key: string, value: number) {
nativeGpu.EglUniform1i(key, value)
}
native_setFloat(key:string,value:number){
nativeGpu.EglUniform1f(key,value)
}
native_setPoint(key:string,vf1:number,vf2:number){
nativeGpu.EglUniform2fv(key,vf1,vf2);
native_setFloat(key: string, value: number) {
nativeGpu.EglUniform1f(key, value)
}
native_setFloat2f(key:string,value:Float32Array){
this.native_setTypeArray(key,"glUniform2f",value);
native_setPoint(key: string, vf1: number, vf2: number) {
nativeGpu.EglUniform2fv(key, vf1, vf2);
}
native_setFloatVec2(key:string,value:Float32Array){
this.native_setTypeArray(key,"glUniform2fv",value);
native_setFloat2f(key: string, value: Float32Array) {
this.native_setTypeArray(key, "glUniform2f", value);
}
native_setFloatVec3(key:string,value:Float32Array){
this.native_setTypeArray(key,"glUniform3fv",value);
native_setFloatVec2(key: string, value: Float32Array) {
this.native_setTypeArray(key, "glUniform2fv", value);
}
native_setFloatVec4(key:string,value:Float32Array){
this.native_setTypeArray(key,"glUniform4fv",value);
native_setFloatVec3(key: string, value: Float32Array) {
this.native_setTypeArray(key, "glUniform3fv", value);
}
native_setFloatArray(key:string,value:Float32Array){
this.native_setTypeArray(key,"glUniform1fv",value);
native_setFloatVec4(key: string, value: Float32Array) {
this.native_setTypeArray(key, "glUniform4fv", value);
}
native_setUniformMatrix3f(key:string,value:Float32Array){
nativeGpu.EglSetTypeArrayOfMatrix3f(key,value);
native_setFloatArray(key: string, value: Float32Array) {
this.native_setTypeArray(key, "glUniform1fv", value);
}
native_setUniformMatrix4f(key:string,value:Float32Array){
nativeGpu.EglSetTypeArrayOfMatrix4f(key,value);
native_setUniformMatrix3f(key: string, value: Float32Array) {
nativeGpu.EglSetTypeArrayOfMatrix3f(key, value);
}
native_setTypeArray(key:string,uniformType:string,data:Float32Array){
nativeGpu.EglSetTypeArrayOfFloat(key,uniformType,data);
native_setUniformMatrix4f(key: string, value: Float32Array) {
nativeGpu.EglSetTypeArrayOfMatrix4f(key, value);
}
native_glIsDestroy(){
native_setTypeArray(key: string, uniformType: string, data: Float32Array) {
nativeGpu.EglSetTypeArrayOfFloat(key, uniformType, data);
}
native_glIsDestroy() {
nativeGpu.EglDestroy();
}
}

View File

@ -13,6 +13,6 @@
* limitations under the License.
*/
export interface Runnable{
export interface Runnable {
run();
}

View File

@ -81,7 +81,7 @@ export class RequestOption {
isCacheable: boolean = true;
//开启GPU变换绘制
isOpenGpuTransform: boolean = false;
gpuEnabled: boolean = false;
// 变换相关
transformations: Array<BaseTransform<PixelMap>> = new Array();
generateCacheKey: string = "";
@ -363,8 +363,8 @@ export class RequestOption {
return this;
}
//开启GPU变换绘制
openEfficient() {
this.isOpenGpuTransform = true;
enableGPU() {
this.gpuEnabled = true;
return this;
}

View File

@ -71,7 +71,7 @@ export class BlurTransformation implements BaseTransform<PixelMap> {
}
imageSource.createPixelMap(options)
.then((data) => {
if (request.isOpenGpuTransform) {
if (request.gpuEnabled) {
fastBlur.blurGPU(data, this._mRadius, true, func);
} else {
fastBlur.blur(data, this._mRadius, true, func);

View File

@ -78,7 +78,7 @@ export class BrightnessFilterTransformation implements BaseTransform<PixelMap> {
let bufferData = new ArrayBuffer(data.getPixelBytesNumber());
await data.readPixelsToBuffer(bufferData);
if (request.isOpenGpuTransform) {
if (request.gpuEnabled) {
let filter = new GPUImageBrightnessFilter();
filter.setImageData(bufferData, targetWidth, targetHeight);
filter.setBrightness(this._mBrightness);

View File

@ -91,7 +91,7 @@ export class ContrastFilterTransformation implements BaseTransform<PixelMap> {
let bufferData = new ArrayBuffer(data.getPixelBytesNumber());
await data.readPixelsToBuffer(bufferData);
if (request.isOpenGpuTransform) {
if (request.gpuEnabled) {
let filter = new GPUImageContrastFilter();
filter.setImageData(bufferData, targetWidth, targetHeight);
filter.setContrast(this._mContrast)

View File

@ -71,7 +71,7 @@ export class GrayscaleTransformation implements BaseTransform<PixelMap> {
let bufferNewData = new ArrayBuffer(data.getPixelBytesNumber());
await data.readPixelsToBuffer(bufferData);
if (request.isOpenGpuTransform) {
if (request.gpuEnabled) {
let filter = new GPUImageGrayscaleFilter();
filter.setImageData(bufferData, targetWidth, targetHeight);
let buf = await filter.getPixelMapBuf(0, 0, targetWidth, targetHeight);

View File

@ -79,7 +79,7 @@ export class InvertFilterTransformation implements BaseTransform<PixelMap> {
let bufferData = new ArrayBuffer(data.getPixelBytesNumber());
await data.readPixelsToBuffer(bufferData);
if (request.isOpenGpuTransform) {
if (request.gpuEnabled) {
let filter = new GPUImageColorInvertFilter();
filter.setImageData(bufferData, targetWidth, targetHeight);
let buf = await filter.getPixelMapBuf(0, 0, targetWidth, targetHeight);

View File

@ -0,0 +1,103 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { BaseTransform } from "../transform/BaseTransform"
import { AsyncTransform } from "../transform/AsyncTransform"
import { Constants } from "../constants/Constants"
import { RequestOption } from "../../imageknife/RequestOption"
import { TransformUtils } from "../transform/TransformUtils"
import image from "@ohos.multimedia.image"
import { LogUtil } from '../../imageknife/utils/LogUtil'
import { GPUImageKuwaharaFilter } from '@ohos/gpu_transform'
export class KuwaharaFilterTransform implements BaseTransform<PixelMap> {
private _mRadius: number;
constructor(radius: number) {
this._mRadius = radius;
}
getName() {
return "KuwaharaFilterTransform _mRadius:" + this._mRadius;
}
transform(buf: ArrayBuffer, request: RequestOption, func?: AsyncTransform<PixelMap>) {
if (!buf || buf.byteLength <= 0) {
LogUtil.log(Constants.PROJECT_TAG + ";KuwaharaFilterTransform buf is empty");
if (func) {
func(Constants.PROJECT_TAG + ";KuwaharaFilterTransform buf is empty", null);
}
return;
}
if (!request.gpuEnabled) {
LogUtil.error(Constants.PROJECT_TAG + ";the KuwaharaFilterTransform supported only in GPU mode");
if (func) {
func(Constants.PROJECT_TAG + ";;the KuwaharaFilterTransform supported only in GPU mode", null);
}
return;
}
var that = this;
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) => {
that.kuwahara(data, targetWidth, targetHeight, func);
})
.catch((e) => {
LogUtil.log(Constants.PROJECT_TAG + ";error:" + e);
func(e, null);
})
})
}
private async kuwahara(bitmap: image.PixelMap, targetWidth: number, targetHeight: number, func: AsyncTransform<PixelMap>) {
let bufferData = new ArrayBuffer(bitmap.getPixelBytesNumber());
await bitmap.readPixelsToBuffer(bufferData);
let filter = new GPUImageKuwaharaFilter();
filter.setImageData(bufferData, targetWidth, targetHeight);
filter.setRadius(this._mRadius);
let buf = await filter.getPixelMapBuf(0, 0, targetWidth, targetHeight)
bitmap.writeBufferToPixels(buf);
if (func) {
func("success", bitmap);
}
}
}

View File

@ -1,101 +0,0 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { BaseTransform } from "../transform/BaseTransform"
import { AsyncTransform } from "../transform/AsyncTransform"
import { Constants } from "../constants/Constants"
import { RequestOption } from "../../imageknife/RequestOption"
import { TransformUtils } from "../transform/TransformUtils"
import image from "@ohos.multimedia.image"
import { fastBlur } from "../utils/FastBlur"
import { LogUtil } from '../../imageknife/utils/LogUtil'
import { GPUImageKuwaharaFilter } from '@ohos/gpu_transform'
export class KuwaharaFilterTransform implements BaseTransform<PixelMap> {
private _mRadius: number;
constructor(radius: number) {
this._mRadius = radius;
}
getName() {
return "KuwaharaFilterTransform _mRadius:" + this._mRadius;
}
transform(buf: ArrayBuffer, request: RequestOption, func?: AsyncTransform<PixelMap>) {
if (!buf || buf.byteLength <= 0) {
LogUtil.log(Constants.PROJECT_TAG + ";KuwaharaFilterTransform buf is empty");
if (func) {
func(Constants.PROJECT_TAG + ";KuwaharaFilterTransform buf is empty", null);
}
return;
}
if (!request.isOpenGpuTransform) {
LogUtil.error(Constants.PROJECT_TAG + ";the KuwaharaFilterTransform supported only in GPU mode");
return;
}
var that = this;
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) => {
that.kuwahara(data, targetWidth, targetHeight, func);
})
.catch((e) => {
LogUtil.log(Constants.PROJECT_TAG + ";error:" + e);
func(e, null);
})
})
}
async kuwahara(bitmap: any, targetWidth: number, targetHeight: number, func: AsyncTransform<PixelMap>) {
let bufferData = new ArrayBuffer(bitmap.getPixelBytesNumber());
await bitmap.readPixelsToBuffer(bufferData);
let filter = new GPUImageKuwaharaFilter();
filter.setImageData(bufferData, targetWidth, targetHeight);
filter.setRadius(this._mRadius);
let buf = await filter.getPixelMapBuf(0, 0, targetWidth, targetHeight)
bitmap.writeBufferToPixels(buf);
if (func) {
func("success", bitmap);
}
}
}

View File

@ -76,7 +76,7 @@ export class PixelationFilterTransformation implements BaseTransform<PixelMap> {
}
imageSource.createPixelMap(options)
.then((data) => {
if (request.isOpenGpuTransform) {
if (request.gpuEnabled) {
pixelUtils.pixelGPU(data, this._mPixel, func);
} else {
pixelUtils.pixel(data, this._mPixel, func);

View File

@ -75,7 +75,7 @@ export class SepiaFilterTransformation implements BaseTransform<PixelMap> {
let bufferData = new ArrayBuffer(data.getPixelBytesNumber());
await data.readPixelsToBuffer(bufferData);
if (request.isOpenGpuTransform) {
if (request.gpuEnabled) {
let filter = new GPUImageSepiaToneFilter();
filter.setImageData(bufferData, targetWidth, targetHeight);
let buf = await filter.getPixelMapBuf(0, 0, targetWidth, targetHeight);

View File

@ -63,7 +63,7 @@ export class SketchFilterTransformation implements BaseTransform<PixelMap> {
}
imageSource.createPixelMap(options)
.then((data) => {
if (request.isOpenGpuTransform) {
if (request.gpuEnabled) {
CalculatePixelUtils.sketchGpu(data, func);
} else {
CalculatePixelUtils.sketch(data, func);

View File

@ -90,7 +90,7 @@ export class SwirlFilterTransformation implements BaseTransform<PixelMap> {
})
}
private async swirl(bitmap: any, degree: number, request: RequestOption, func?: AsyncTransform<PixelMap>) {
private async swirl(bitmap: image.PixelMap, degree: number, request: RequestOption, func?: AsyncTransform<PixelMap>) {
let imageInfo = await bitmap.getImageInfo();
let size = {
width: imageInfo.size.width,
@ -105,7 +105,7 @@ export class SwirlFilterTransformation implements BaseTransform<PixelMap> {
let bufferData = new ArrayBuffer(bitmap.getPixelBytesNumber());
await bitmap.readPixelsToBuffer(bufferData);
if (request.isOpenGpuTransform) {
if (request.gpuEnabled) {
let filter = new GPUImageSwirlFilter();
filter.setImageData(bufferData, width, height);
filter.setRadius(degree);

View File

@ -0,0 +1,110 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { BaseTransform } from "../transform/BaseTransform"
import { AsyncTransform } from "../transform/AsyncTransform"
import { Constants } from "../constants/Constants"
import { RequestOption } from "../../imageknife/RequestOption"
import { TransformUtils } from "../transform/TransformUtils"
import image from "@ohos.multimedia.image"
import { LogUtil } from '../../imageknife/utils/LogUtil'
import { GPUImageToonFilter } from '@ohos/gpu_transform'
export class ToonFilterTransform implements BaseTransform<PixelMap> {
private threshold: number = 0.2;
private quantizationLevels: number = 10.0;
constructor(threshold?: number, quantizationLevels?: number) {
if (threshold) {
this.threshold = threshold;
}
if (quantizationLevels) {
this.quantizationLevels = quantizationLevels;
}
}
getName() {
return "ToonFilterTransform threshold:" + this.threshold + ";quantizationLevels:" + this.quantizationLevels;
}
transform(buf: ArrayBuffer, request: RequestOption, func?: AsyncTransform<PixelMap>) {
if (!buf || buf.byteLength <= 0) {
LogUtil.log(Constants.PROJECT_TAG + ";ToonFilterTransform buf is empty");
if (func) {
func(Constants.PROJECT_TAG + ";ToonFilterTransform buf is empty", null);
}
return;
}
if (!request.gpuEnabled) {
LogUtil.error(Constants.PROJECT_TAG + ";the ToonFilterTransform supported only in GPU mode");
if (func) {
func(Constants.PROJECT_TAG + ";the ToonFilterTransform supported only in GPU mode", null);
}
return;
}
var that = this;
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) => {
that.toon(data, targetWidth, targetHeight, func);
})
.catch((e) => {
LogUtil.log(Constants.PROJECT_TAG + ";error:" + e);
func(e, null);
})
})
}
private async toon(bitmap: image.PixelMap, targetWidth: number, targetHeight: number, func: AsyncTransform<PixelMap>) {
let bufferData = new ArrayBuffer(bitmap.getPixelBytesNumber());
await bitmap.readPixelsToBuffer(bufferData);
let filter = new GPUImageToonFilter();
filter.setImageData(bufferData, targetWidth, targetHeight);
filter.setThreshold(this.threshold);
filter.setQuantizationLevels(this.quantizationLevels);
let buf = await filter.getPixelMapBuf(0, 0, targetWidth, targetHeight)
bitmap.writeBufferToPixels(buf);
if (func) {
func("success", bitmap);
}
}
}

View File

@ -1,108 +0,0 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { BaseTransform } from "../transform/BaseTransform"
import { AsyncTransform } from "../transform/AsyncTransform"
import { Constants } from "../constants/Constants"
import { RequestOption } from "../../imageknife/RequestOption"
import { TransformUtils } from "../transform/TransformUtils"
import image from "@ohos.multimedia.image"
import { fastBlur } from "../utils/FastBlur"
import { LogUtil } from '../../imageknife/utils/LogUtil'
import { GPUImageToonFilter } from '@ohos/gpu_transform'
export class ToonFilterTransform implements BaseTransform<PixelMap> {
private threshold: number = 0.2;
private quantizationLevels: number = 10.0;
constructor(threshold?: number, quantizationLevels?: number) {
if (threshold) {
this.threshold = threshold;
}
if (quantizationLevels) {
this.quantizationLevels = quantizationLevels;
}
}
getName() {
return "ToonFilterTransform threshold:" + this.threshold + ";quantizationLevels:" + this.quantizationLevels;
}
transform(buf: ArrayBuffer, request: RequestOption, func?: AsyncTransform<PixelMap>) {
if (!buf || buf.byteLength <= 0) {
LogUtil.log(Constants.PROJECT_TAG + ";ToonFilterTransform buf is empty");
if (func) {
func(Constants.PROJECT_TAG + ";ToonFilterTransform buf is empty", null);
}
return;
}
if (!request.isOpenGpuTransform) {
LogUtil.error(Constants.PROJECT_TAG + ";the ToonFilterTransform supported only in GPU mode");
return;
}
var that = this;
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) => {
that.toon(data, targetWidth, targetHeight, func);
})
.catch((e) => {
LogUtil.log(Constants.PROJECT_TAG + ";error:" + e);
func(e, null);
})
})
}
async toon(bitmap: any, targetWidth: number, targetHeight: number, func: AsyncTransform<PixelMap>) {
let bufferData = new ArrayBuffer(bitmap.getPixelBytesNumber());
await bitmap.readPixelsToBuffer(bufferData);
let filter = new GPUImageToonFilter();
filter.setImageData(bufferData, targetWidth, targetHeight);
filter.setThreshold(this.threshold);
filter.setQuantizationLevels(this.quantizationLevels);
let buf = await filter.getPixelMapBuf(0, 0, targetWidth, targetHeight)
bitmap.writeBufferToPixels(buf);
if (func) {
func("success", bitmap);
}
}
}

View File

@ -0,0 +1,116 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { BaseTransform } from "../transform/BaseTransform"
import { AsyncTransform } from "../transform/AsyncTransform"
import { Constants } from "../constants/Constants"
import { RequestOption } from "../../imageknife/RequestOption"
import { TransformUtils } from "../transform/TransformUtils"
import image from "@ohos.multimedia.image"
import { LogUtil } from '../../imageknife/utils/LogUtil'
import { GPUImageVignetterFilter } from '@ohos/gpu_transform'
export class VignetteFilterTransform implements BaseTransform<PixelMap> {
private centerPoint: Array<number> = [0.5, 0.5];
private vignetteColor: Array<number> = [0.0, 0.0, 0.0];
private vignetteSpace: Array<number> = [0.3, 0.75];
constructor(centerPoint: Array<number>, vignetteColor: Array<number>, vignetteSpace: Array<number>) {
if (centerPoint.length === 2) {
this.centerPoint = centerPoint;
}
if (vignetteColor.length === 3) {
this.vignetteColor = vignetteColor;
}
if (vignetteSpace.length === 2) {
this.vignetteSpace = vignetteSpace;
}
}
getName() {
return "VignetteFilterTransform centerPoint:" + this.centerPoint + ";vignetteColor:" + this.vignetteColor + ";vignetteSpace:" + this.vignetteSpace;
}
transform(buf: ArrayBuffer, request: RequestOption, func?: AsyncTransform<PixelMap>) {
if (!buf || buf.byteLength <= 0) {
LogUtil.log(Constants.PROJECT_TAG + ";VignetteFilterTransform buf is empty");
if (func) {
func(Constants.PROJECT_TAG + ";VignetteFilterTransform buf is empty", null);
}
return;
}
if (!request.gpuEnabled) {
LogUtil.error(Constants.PROJECT_TAG + ";the VignetteFilterTransform supported only in GPU mode");
if (func) {
func(Constants.PROJECT_TAG + ";the VignetteFilterTransform supported only in GPU mode", null);
}
return;
}
var that = this;
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) => {
that.vignette(data, targetWidth, targetHeight, func);
})
.catch((e) => {
LogUtil.log(Constants.PROJECT_TAG + ";error:" + e);
func(e, null);
})
})
}
private async vignette(bitmap: image.PixelMap, targetWidth: number, targetHeight: number, func: AsyncTransform<PixelMap>) {
let bufferData = new ArrayBuffer(bitmap.getPixelBytesNumber());
await bitmap.readPixelsToBuffer(bufferData);
let filter = new GPUImageVignetterFilter();
filter.setImageData(bufferData, targetWidth, targetHeight);
filter.setVignetteCenter(this.centerPoint);
filter.setVignetteColor(this.vignetteColor);
filter.setVignetteStart(this.vignetteSpace[0]);
filter.setVignetteEnd(this.vignetteSpace[1]);
let buf = await filter.getPixelMapBuf(0, 0, targetWidth, targetHeight)
bitmap.writeBufferToPixels(buf);
if (func) {
func("success", bitmap);
}
}
}

View File

@ -1,114 +0,0 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { BaseTransform } from "../transform/BaseTransform"
import { AsyncTransform } from "../transform/AsyncTransform"
import { Constants } from "../constants/Constants"
import { RequestOption } from "../../imageknife/RequestOption"
import { TransformUtils } from "../transform/TransformUtils"
import image from "@ohos.multimedia.image"
import { fastBlur } from "../utils/FastBlur"
import { LogUtil } from '../../imageknife/utils/LogUtil'
import { GPUImageVignetterFilter } from '@ohos/gpu_transform'
export class VignetteFilterTransform implements BaseTransform<PixelMap> {
private centerPoint: Array<number> = [0.5, 0.5];
private vignetteColor: Array<number> = [0.0, 0.0, 0.0];
private vignetteSpace: Array<number> = [0.3, 0.75];
constructor(centerPoint: Array<number>, vignetteColor: Array<number>, vignetteSpace: Array<number>) {
if (centerPoint.length === 2) {
this.centerPoint = centerPoint;
}
if (vignetteColor.length === 3) {
this.vignetteColor = vignetteColor;
}
if (vignetteSpace.length === 2) {
this.vignetteSpace = vignetteSpace;
}
}
getName() {
return "VignetteFilterTransform centerPoint:" + this.centerPoint + ";vignetteColor:" + this.vignetteColor + ";vignetteSpace:" + this.vignetteSpace;
}
transform(buf: ArrayBuffer, request: RequestOption, func?: AsyncTransform<PixelMap>) {
if (!buf || buf.byteLength <= 0) {
LogUtil.log(Constants.PROJECT_TAG + ";VignetteFilterTransform buf is empty");
if (func) {
func(Constants.PROJECT_TAG + ";VignetteFilterTransform buf is empty", null);
}
return;
}
if (!request.isOpenGpuTransform) {
LogUtil.error(Constants.PROJECT_TAG + ";the VignetteFilterTransform supported only in GPU mode");
return;
}
var that = this;
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) => {
that.vignette(data, targetWidth, targetHeight, func);
})
.catch((e) => {
LogUtil.log(Constants.PROJECT_TAG + ";error:" + e);
func(e, null);
})
})
}
async vignette(bitmap: any, targetWidth: number, targetHeight: number, func: AsyncTransform<PixelMap>) {
let bufferData = new ArrayBuffer(bitmap.getPixelBytesNumber());
await bitmap.readPixelsToBuffer(bufferData);
let filter = new GPUImageVignetterFilter();
filter.setImageData(bufferData, targetWidth, targetHeight);
filter.setVignetteCenter(this.centerPoint);
filter.setVignetteColor(this.vignetteColor);
filter.setVignetteStart(this.vignetteSpace[0]);
filter.setVignetteEnd(this.vignetteSpace[1]);
let buf = await filter.getPixelMapBuf(0, 0, targetWidth, targetHeight)
bitmap.writeBufferToPixels(buf);
if (func) {
func("success", bitmap);
}
}
}