From 75f08250a285f17896ebe87c58819af617dd1c31 Mon Sep 17 00:00:00 2001 From: tyBrave Date: Thu, 2 Feb 2023 16:59:13 +0800 Subject: [PATCH 01/10] add gpu transform module Signed-off-by: tyBrave --- build-profile.json5 | 6 +- entry/src/main/ets/pages/cropImagePage2.ets | 3 +- .../main/ets/pages/transformPixelMapPage.ets | 311 +++++-- gpu_transform/.gitignore | 4 + gpu_transform/build-profile.json5 | 19 + gpu_transform/hvigorfile.ts | 2 + gpu_transform/index.ets | 33 + gpu_transform/package.json | 14 + gpu_transform/src/main/cpp/CMakeLists.txt | 33 + .../src/main/cpp/common/native_common.h | 57 ++ .../src/main/cpp/constant/constant_shape.h | 448 ++++++++++ gpu_transform/src/main/cpp/napi/napi_init.cpp | 99 +++ .../src/main/cpp/render/EGLRender.cpp | 822 ++++++++++++++++++ gpu_transform/src/main/cpp/render/EGLRender.h | 120 +++ .../src/main/cpp/types/libentry/index.d.ts | 16 + .../src/main/cpp/types/libentry/package.json | 4 + gpu_transform/src/main/cpp/util/DebugLog.h | 32 + gpu_transform/src/main/cpp/util/GLUtils.cpp | 109 +++ gpu_transform/src/main/cpp/util/GLUtils.h | 37 + gpu_transform/src/main/cpp/util/NapiUtil.cpp | 49 ++ gpu_transform/src/main/cpp/util/NapiUtil.h | 35 + gpu_transform/src/main/cpp/util/NativeImage.h | 162 ++++ .../GPUImage3x3TextureSamplingFilter.ts | 51 ++ .../main/ets/gpu/filter/GPUImageBlurFilter.ts | 81 ++ .../gpu/filter/GPUImageBrightnessFilter.ts | 44 + .../gpu/filter/GPUImageColorInvertFilter.ts | 37 + .../gpu/filter/GPUImageColorMatrixFilter.ts | 57 ++ .../ets/gpu/filter/GPUImageContrastFilter.ts | 46 + .../src/main/ets/gpu/filter/GPUImageFilter.ts | 331 +++++++ .../ets/gpu/filter/GPUImageFilterGroup.ts | 38 + .../ets/gpu/filter/GPUImageGrayscaleFilter.ts | 36 + .../ets/gpu/filter/GPUImageKuwaharaFilter.ts | 45 + .../gpu/filter/GPUImagePixelationFilter.ts | 43 + .../ets/gpu/filter/GPUImageSepiaToneFilter.ts | 40 + .../ets/gpu/filter/GPUImageSketchFilter.ts | 37 + .../ets/gpu/filter/GPUImageSwirlFilter.ts | 55 ++ .../main/ets/gpu/filter/GPUImageToonFilter.ts | 49 ++ .../ets/gpu/filter/GPUImageVignetterFilter.ts | 58 ++ .../src/main/ets/gpu/gl/GPUFilterType.ts | 31 + .../src/main/ets/gpu/gl/NativeEglRender.ts | 101 +++ .../src/main/ets/gpu/interface/Runnable.ts | 18 + gpu_transform/src/main/module.json5 | 10 + .../main/resources/base/element/string.json | 8 + .../main/resources/en_US/element/string.json | 8 + .../main/resources/zh_CN/element/string.json | 8 + imageknife/index.ets | 3 + imageknife/package.json | 7 +- .../components/imageknife/RequestOption.ets | 164 ++-- .../transform/BlurTransformation.ets | 6 +- .../BrightnessFilterTransformation.ets | 16 +- .../ContrastFilterTransformation.ets | 16 +- .../transform/GrayscaleTransformation.ets | 13 + .../transform/InvertFilterTransformation.ets | 13 + .../transform/KuwaharaFilterTransform.ts | 101 +++ .../PixelationFilterTransformation.ets | 8 +- .../transform/SepiaFilterTransformation.ets | 16 +- .../transform/SketchFilterTransformation.ets | 6 +- .../transform/SwirlFilterTransformation.ets | 44 +- .../transform/ToonFilterTransform.ts | 108 +++ .../transform/VignetteFilterTransform.ts | 114 +++ .../imageknife/utils/CalculatePixelUtils.ets | 45 +- .../components/imageknife/utils/FastBlur.ets | 35 +- .../imageknife/utils/PixelUtils.ets | 27 + 63 files changed, 4207 insertions(+), 182 deletions(-) create mode 100644 gpu_transform/.gitignore create mode 100644 gpu_transform/build-profile.json5 create mode 100644 gpu_transform/hvigorfile.ts create mode 100644 gpu_transform/index.ets create mode 100644 gpu_transform/package.json create mode 100644 gpu_transform/src/main/cpp/CMakeLists.txt create mode 100644 gpu_transform/src/main/cpp/common/native_common.h create mode 100644 gpu_transform/src/main/cpp/constant/constant_shape.h create mode 100644 gpu_transform/src/main/cpp/napi/napi_init.cpp create mode 100644 gpu_transform/src/main/cpp/render/EGLRender.cpp create mode 100644 gpu_transform/src/main/cpp/render/EGLRender.h create mode 100644 gpu_transform/src/main/cpp/types/libentry/index.d.ts create mode 100644 gpu_transform/src/main/cpp/types/libentry/package.json create mode 100644 gpu_transform/src/main/cpp/util/DebugLog.h create mode 100644 gpu_transform/src/main/cpp/util/GLUtils.cpp create mode 100644 gpu_transform/src/main/cpp/util/GLUtils.h create mode 100644 gpu_transform/src/main/cpp/util/NapiUtil.cpp create mode 100644 gpu_transform/src/main/cpp/util/NapiUtil.h create mode 100644 gpu_transform/src/main/cpp/util/NativeImage.h create mode 100644 gpu_transform/src/main/ets/gpu/filter/GPUImage3x3TextureSamplingFilter.ts create mode 100644 gpu_transform/src/main/ets/gpu/filter/GPUImageBlurFilter.ts create mode 100644 gpu_transform/src/main/ets/gpu/filter/GPUImageBrightnessFilter.ts create mode 100644 gpu_transform/src/main/ets/gpu/filter/GPUImageColorInvertFilter.ts create mode 100644 gpu_transform/src/main/ets/gpu/filter/GPUImageColorMatrixFilter.ts create mode 100644 gpu_transform/src/main/ets/gpu/filter/GPUImageContrastFilter.ts create mode 100644 gpu_transform/src/main/ets/gpu/filter/GPUImageFilter.ts create mode 100644 gpu_transform/src/main/ets/gpu/filter/GPUImageFilterGroup.ts create mode 100644 gpu_transform/src/main/ets/gpu/filter/GPUImageGrayscaleFilter.ts create mode 100644 gpu_transform/src/main/ets/gpu/filter/GPUImageKuwaharaFilter.ts create mode 100644 gpu_transform/src/main/ets/gpu/filter/GPUImagePixelationFilter.ts create mode 100644 gpu_transform/src/main/ets/gpu/filter/GPUImageSepiaToneFilter.ts create mode 100644 gpu_transform/src/main/ets/gpu/filter/GPUImageSketchFilter.ts create mode 100644 gpu_transform/src/main/ets/gpu/filter/GPUImageSwirlFilter.ts create mode 100644 gpu_transform/src/main/ets/gpu/filter/GPUImageToonFilter.ts create mode 100644 gpu_transform/src/main/ets/gpu/filter/GPUImageVignetterFilter.ts create mode 100644 gpu_transform/src/main/ets/gpu/gl/GPUFilterType.ts create mode 100644 gpu_transform/src/main/ets/gpu/gl/NativeEglRender.ts create mode 100644 gpu_transform/src/main/ets/gpu/interface/Runnable.ts create mode 100644 gpu_transform/src/main/module.json5 create mode 100644 gpu_transform/src/main/resources/base/element/string.json create mode 100644 gpu_transform/src/main/resources/en_US/element/string.json create mode 100644 gpu_transform/src/main/resources/zh_CN/element/string.json create mode 100644 imageknife/src/main/ets/components/imageknife/transform/KuwaharaFilterTransform.ts create mode 100644 imageknife/src/main/ets/components/imageknife/transform/ToonFilterTransform.ts create mode 100644 imageknife/src/main/ets/components/imageknife/transform/VignetteFilterTransform.ts diff --git a/build-profile.json5 b/build-profile.json5 index daded0e..46629bc 100644 --- a/build-profile.json5 +++ b/build-profile.json5 @@ -7,7 +7,7 @@ "name": "default", "signingConfig": "default" } - ], + ] }, "modules": [ { @@ -25,6 +25,10 @@ { "name": "imageknife", "srcPath": "./imageknife" + }, + { + "name": "gpu_transform", + "srcPath": "./gpu_transform" } ] } \ No newline at end of file diff --git a/entry/src/main/ets/pages/cropImagePage2.ets b/entry/src/main/ets/pages/cropImagePage2.ets index 2643e39..a273999 100644 --- a/entry/src/main/ets/pages/cropImagePage2.ets +++ b/entry/src/main/ets/pages/cropImagePage2.ets @@ -22,8 +22,9 @@ import { CropCallback } from '@ohos/imageknife' import { FileUtils } from '@ohos/imageknife' -@Component + @Entry +@Component export struct CropImagePage2 { @State options1: PixelMapCrop.Options = new PixelMapCrop.Options(); @State cropTap: boolean = false; diff --git a/entry/src/main/ets/pages/transformPixelMapPage.ets b/entry/src/main/ets/pages/transformPixelMapPage.ets index bcffc37..c31527e 100644 --- a/entry/src/main/ets/pages/transformPixelMapPage.ets +++ b/entry/src/main/ets/pages/transformPixelMapPage.ets @@ -27,11 +27,11 @@ import { BrightnessFilterTransformation } from '@ohos/imageknife' import { ContrastFilterTransformation } from '@ohos/imageknife' import { InvertFilterTransformation } from '@ohos/imageknife' import { SepiaFilterTransformation } from '@ohos/imageknife' -import {SketchFilterTransformation} from '@ohos/imageknife' -import {BlurTransformation} from '@ohos/imageknife' -import {PixelationFilterTransformation} from '@ohos/imageknife' -import {MaskTransformation} from '@ohos/imageknife' -import {SwirlFilterTransformation} from '@ohos/imageknife' +import { SketchFilterTransformation } from '@ohos/imageknife' +import { BlurTransformation } from '@ohos/imageknife' +import { PixelationFilterTransformation } from '@ohos/imageknife' +import { MaskTransformation } from '@ohos/imageknife' +import { SwirlFilterTransformation } from '@ohos/imageknife' /** @@ -44,26 +44,29 @@ let mUrl = $r('app.media.pngSample'); @Entry @Component struct TransformPixelMapPage { - @State url: string= ""; - @State mCropPixelMap: PixelMap= undefined; - @State mRoundPixelMap: PixelMap= undefined; - @State mCirclePixelMap: PixelMap= undefined; - @State mCircleBorderPixelMap: PixelMap= undefined; - @State mRotatePixelMap: PixelMap= undefined; - @State mSquarePixelMap: PixelMap= undefined; - @State mClipTopPixelMap: PixelMap= undefined; - @State mClipCenterPixelMap: PixelMap= undefined; - @State mClipBottomPixelMap: PixelMap= undefined; - @State mGrayscalePixelMap: PixelMap= undefined; - @State mBrightnessPixelMap: PixelMap= undefined; - @State mContrastPixelMap: PixelMap= undefined; - @State mInvertPixelMap: PixelMap= undefined; - @State mSepiaPixelMap: PixelMap= undefined; - @State mSketchPixelMap: PixelMap= undefined; - @State mBlurPixelMap: PixelMap= undefined; - @State mPixelPixelMap: PixelMap= undefined; - @State mSwirlPixelMap: PixelMap= undefined; - @State mMaskPixelMap: PixelMap= undefined; + @State url: string = ""; + @State mCropPixelMap: PixelMap = undefined; + @State mRoundPixelMap: PixelMap = undefined; + @State mCirclePixelMap: PixelMap = undefined; + @State mCircleBorderPixelMap: PixelMap = undefined; + @State mRotatePixelMap: PixelMap = undefined; + @State mSquarePixelMap: PixelMap = undefined; + @State mClipTopPixelMap: PixelMap = undefined; + @State mClipCenterPixelMap: PixelMap = undefined; + @State mClipBottomPixelMap: PixelMap = undefined; + @State mGrayscalePixelMap: PixelMap = undefined; + @State mBrightnessPixelMap: PixelMap = undefined; + @State mContrastPixelMap: PixelMap = undefined; + @State mInvertPixelMap: PixelMap = undefined; + @State mSepiaPixelMap: PixelMap = undefined; + @State mSketchPixelMap: PixelMap = undefined; + @State mBlurPixelMap: PixelMap = undefined; + @State mPixelPixelMap: PixelMap = undefined; + @State mSwirlPixelMap: PixelMap = undefined; + @State mMaskPixelMap: PixelMap = undefined; + @State mKuwaharaPixelMap: PixelMap = undefined; + @State mToonPixelMap: PixelMap = undefined; + @State mVignettePixelMap: PixelMap = undefined; build() { Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center }) { @@ -98,7 +101,7 @@ struct TransformPixelMapPage { }); }.margin({ top: 10 }) - Image(this.mCropPixelMap ) + Image(this.mCropPixelMap) .objectFit(ImageFit.None) .width(100) .height(100) @@ -151,7 +154,7 @@ struct TransformPixelMapPage { }); }.margin({ top: 10 }) - Image(this.mRoundPixelMap ) + Image(this.mRoundPixelMap) .objectFit(ImageFit.Fill) .width(100) .height(100) @@ -170,7 +173,7 @@ struct TransformPixelMapPage { .onClick(() => { this.circleTransformation(); }); - Image(this.mCirclePixelMap ) + Image(this.mCirclePixelMap) .width(200) .height(200) .margin({ top: 10 }) @@ -188,7 +191,7 @@ struct TransformPixelMapPage { .onClick(() => { this.circleBorderTransformation(5); }); - Image(this.mCircleBorderPixelMap ) + Image(this.mCircleBorderPixelMap) .width(200) .height(200) .margin({ top: 10 }) @@ -210,7 +213,7 @@ struct TransformPixelMapPage { } this.transformRotate(mRotate); }); - Image(this.mRotatePixelMap ) + Image(this.mRotatePixelMap) .width(200) .height(200) .margin({ top: 10 }) @@ -228,7 +231,7 @@ struct TransformPixelMapPage { .onClick(() => { this.transformSquare(); }); - Image(this.mSquarePixelMap ) + Image(this.mSquarePixelMap) .objectFit(ImageFit.Fill) .width(200) .height(200) @@ -266,17 +269,17 @@ struct TransformPixelMapPage { }.margin({ top: 10 }) Row({ space: 1 }) { - Image(this.mClipTopPixelMap ) + Image(this.mClipTopPixelMap) .objectFit(ImageFit.Fill) .width(100) .height(100) .margin({ top: 10 }) - Image(this.mClipCenterPixelMap ) + Image(this.mClipCenterPixelMap) .objectFit(ImageFit.Fill) .width(100) .height(100) .margin({ top: 10 }) - Image(this.mClipBottomPixelMap ) + Image(this.mClipBottomPixelMap) .objectFit(ImageFit.Fill) .width(100) .height(100) @@ -295,7 +298,7 @@ struct TransformPixelMapPage { .onClick(() => { this.grayscalePixelMap(); }); - Image(this.mGrayscalePixelMap ) + Image(this.mGrayscalePixelMap) .objectFit(ImageFit.Fill) .width(200) .height(200) @@ -313,7 +316,7 @@ struct TransformPixelMapPage { .onClick(() => { this.brightnessPixelMap(0.8); }); - Image(this.mBrightnessPixelMap ) + Image(this.mBrightnessPixelMap) .objectFit(ImageFit.Fill) .width(200) .height(200) @@ -331,7 +334,7 @@ struct TransformPixelMapPage { .onClick(() => { this.contrastPixelMap(4); }); - Image(this.mContrastPixelMap ) + Image(this.mContrastPixelMap) .objectFit(ImageFit.Fill) .width(200) .height(200) @@ -349,7 +352,7 @@ struct TransformPixelMapPage { .onClick(() => { this.invertPixelMap(); }); - Image(this.mInvertPixelMap ) + Image(this.mInvertPixelMap) .objectFit(ImageFit.Fill) .width(200) .height(200) @@ -368,7 +371,7 @@ struct TransformPixelMapPage { .onClick(() => { this.sepiaPixelMap(); }); - Image(this.mSepiaPixelMap ) + Image(this.mSepiaPixelMap) .objectFit(ImageFit.Fill) .width(200) .height(200) @@ -386,7 +389,7 @@ struct TransformPixelMapPage { .onClick(() => { this.sketchPixelMap(); }); - Image(this.mSketchPixelMap ) + Image(this.mSketchPixelMap) .objectFit(ImageFit.Fill) .width(200) .height(200) @@ -405,7 +408,7 @@ struct TransformPixelMapPage { .onClick(() => { this.blurHandlePixelMap(20); }); - Image(this.mBlurPixelMap ) + Image(this.mBlurPixelMap) .objectFit(ImageFit.Fill) .width(200) .height(200) @@ -425,7 +428,7 @@ struct TransformPixelMapPage { .onClick(() => { this.pixelHandlePixelMap(20); }); - Image(this.mPixelPixelMap ) + Image(this.mPixelPixelMap) .objectFit(ImageFit.Fill) .width(200) .height(200) @@ -444,7 +447,7 @@ struct TransformPixelMapPage { .onClick(() => { this.swirlHandlePixelMap(); }); - Image(this.mSwirlPixelMap ) + Image(this.mSwirlPixelMap) .objectFit(ImageFit.Fill) .width(200) .height(200) @@ -463,7 +466,64 @@ struct TransformPixelMapPage { .onClick(() => { this.maskHandlePixelMap($r('app.media.mask_starfish')); }); - Image(this.mMaskPixelMap ) + Image(this.mMaskPixelMap) + .objectFit(ImageFit.Fill) + .width(200) + .height(200) + .margin({ top: 10 }) + + }.margin({ top: 10 }); + + Column() { + Text("KuwaharaFilterTransform").fontColor(Color.Gray).fontSize(16); + Button() { + Text("图片kuwahara").fontSize(13).fontColor(Color.White) + } + .height(35) + .width(120) + .margin({ top: 10 }) + .onClick(() => { + this.kuwaharaHandlePixelMap(); + }); + Image(this.mKuwaharaPixelMap) + .objectFit(ImageFit.Fill) + .width(200) + .height(200) + .margin({ top: 10 }) + + }.margin({ top: 10 }); + + Column() { + Text("ToonFilterTransform").fontColor(Color.Gray).fontSize(16); + Button() { + Text("图片toon").fontSize(13).fontColor(Color.White) + } + .height(35) + .width(120) + .margin({ top: 10 }) + .onClick(() => { + this.toonHandlePixelMap(); + }); + Image(this.mToonPixelMap) + .objectFit(ImageFit.Fill) + .width(200) + .height(200) + .margin({ top: 10 }) + + }.margin({ top: 10 }); + + Column() { + Text("VignetteFilterTransform").fontColor(Color.Gray).fontSize(16); + Button() { + Text("图片vignette").fontSize(13).fontColor(Color.White) + } + .height(35) + .width(120) + .margin({ top: 10 }) + .onClick(() => { + this.vignetteHandlePixelMap(); + }); + Image(this.mVignettePixelMap) .objectFit(ImageFit.Fill) .width(200) .height(200) @@ -481,19 +541,19 @@ struct TransformPixelMapPage { } -/** + /** * centerCrop */ centerCrop() { var imageKnifeOption = new RequestOption(); imageKnifeOption.load($r('app.media.jpgSample')) - // imageKnifeOption.load(mUrl) + // imageKnifeOption.load(mUrl) .addListener((err, data) => { let result = undefined; this.mCropPixelMap = result; setTimeout(() => { let result2 = undefined; - result2 = data.drawPixelMap.imagePixelMap as PixelMap; + result2 = data.drawPixelMap.imagePixelMap as PixelMap; this.mCropPixelMap = result2; }, 100) return false; @@ -504,7 +564,7 @@ struct TransformPixelMapPage { ImageKnife.call(imageKnifeOption); } -/** + /** * centerInside */ centerInside() { @@ -515,7 +575,7 @@ struct TransformPixelMapPage { this.mCropPixelMap = result; setTimeout(() => { let result2 = undefined; - result2 = data.drawPixelMap.imagePixelMap as PixelMap; + result2 = data.drawPixelMap.imagePixelMap as PixelMap; this.mCropPixelMap = result2; }, 100) return false; @@ -526,7 +586,7 @@ struct TransformPixelMapPage { ImageKnife.call(imageKnifeOption); } -/** + /** * centerInside */ fitCenter() { @@ -537,7 +597,7 @@ struct TransformPixelMapPage { this.mCropPixelMap = result; setTimeout(() => { let result2 = undefined; - result2 = data.drawPixelMap.imagePixelMap as PixelMap; + result2 = data.drawPixelMap.imagePixelMap as PixelMap; this.mCropPixelMap = result2; }, 100) return false; @@ -547,11 +607,11 @@ struct TransformPixelMapPage { .fitCenter(); ImageKnife.call(imageKnifeOption); } -/** + /** * 圆角设置 */ roundedCornersTransformation(top_left: number, - bottom_left: number, top_right: number, bottom_right: number) { + bottom_left: number, top_right: number, bottom_right: number) { var imageKnifeOption = new RequestOption(); imageKnifeOption.load(mUrl) @@ -560,18 +620,23 @@ struct TransformPixelMapPage { this.mRoundPixelMap = result; setTimeout(() => { let result2 = undefined; - result2 = data.drawPixelMap.imagePixelMap as PixelMap; + result2 = data.drawPixelMap.imagePixelMap as PixelMap; this.mRoundPixelMap = result2; }, 100) return false; }) .setImageViewSize({ width: vp2px(100), height: vp2px(100) }) .skipMemoryCache(true) - .roundedCorners({ top_left: top_left, top_right: top_right, bottom_left: bottom_left, bottom_right: bottom_right }) + .roundedCorners({ + top_left: top_left, + top_right: top_right, + bottom_left: bottom_left, + bottom_right: bottom_right + }) ImageKnife.call(imageKnifeOption); } -/** + /** * 裁剪圆 */ circleTransformation() { @@ -579,7 +644,7 @@ struct TransformPixelMapPage { imageKnifeOption.load(mUrl) .addListener((err, data) => { let result = undefined; - result = data.drawPixelMap.imagePixelMap as PixelMap; + result = data.drawPixelMap.imagePixelMap as PixelMap; this.mCirclePixelMap = result; return false; }) @@ -589,7 +654,7 @@ struct TransformPixelMapPage { ImageKnife.call(imageKnifeOption); } -/** + /** * 圆环裁剪 */ circleBorderTransformation(border: number) { @@ -599,7 +664,7 @@ struct TransformPixelMapPage { imageKnifeOption.load(mUrl) .addListener((err, data) => { let result = undefined; - result = data.drawPixelMap.imagePixelMap as PixelMap; + result = data.drawPixelMap.imagePixelMap as PixelMap; this.mCircleBorderPixelMap = result; return false; }) @@ -610,7 +675,7 @@ struct TransformPixelMapPage { ImageKnife.call(imageKnifeOption); } -/** + /** * 旋转 */ transformRotate(angled: number) { @@ -619,7 +684,7 @@ struct TransformPixelMapPage { imageKnifeOption.load(mUrl) .addListener((err, data) => { let result = undefined; - result = data.drawPixelMap.imagePixelMap as PixelMap; + result = data.drawPixelMap.imagePixelMap as PixelMap; this.mRotatePixelMap = result; return false; }) @@ -629,7 +694,7 @@ struct TransformPixelMapPage { ImageKnife.call(imageKnifeOption); } -/** + /** * 正方形裁剪 */ transformSquare() { @@ -638,7 +703,7 @@ struct TransformPixelMapPage { imageKnifeOption.load(mUrl) .addListener((err, data) => { let result = undefined; - result = data.drawPixelMap.imagePixelMap as PixelMap; + result = data.drawPixelMap.imagePixelMap as PixelMap; this.mSquarePixelMap = result; return false; }) @@ -648,7 +713,7 @@ struct TransformPixelMapPage { ImageKnife.call(imageKnifeOption); } -/** + /** * 区域裁剪 */ clipPixelMap(width: number, height: number, cropType: CropType) { @@ -658,13 +723,13 @@ struct TransformPixelMapPage { .addListener((err, data) => { let result = undefined; if (cropType == CropType.TOP) { - result = data.drawPixelMap.imagePixelMap as PixelMap; + result = data.drawPixelMap.imagePixelMap as PixelMap; this.mClipTopPixelMap = result; } else if (cropType == CropType.CENTER) { - result = data.drawPixelMap.imagePixelMap as PixelMap; + result = data.drawPixelMap.imagePixelMap as PixelMap; this.mClipCenterPixelMap = result; } else if (cropType == CropType.BOTTOM) { - result = data.drawPixelMap.imagePixelMap as PixelMap; + result = data.drawPixelMap.imagePixelMap as PixelMap; this.mClipBottomPixelMap = result; } return false; @@ -676,7 +741,7 @@ struct TransformPixelMapPage { } -/** + /** * 灰度 */ grayscalePixelMap() { @@ -685,18 +750,19 @@ struct TransformPixelMapPage { imageKnifeOption.load(mUrl) .addListener((err, data) => { let result = undefined; - result = data.drawPixelMap.imagePixelMap as PixelMap; + result = data.drawPixelMap.imagePixelMap as PixelMap; this.mGrayscalePixelMap = result; return false; }) .setImageViewSize({ width: vp2px(200), height: vp2px(200) }) .skipMemoryCache(true) + .openEfficient() .grayscale() ImageKnife.call(imageKnifeOption); } -/** + /** *亮度b */ brightnessPixelMap(brightness: number) { @@ -705,18 +771,19 @@ struct TransformPixelMapPage { imageKnifeOption.load(mUrl) .addListener((err, data) => { let result = undefined; - result = data.drawPixelMap.imagePixelMap as PixelMap; + result = data.drawPixelMap.imagePixelMap as PixelMap; this.mBrightnessPixelMap = result; return false; }) .setImageViewSize({ width: vp2px(200), height: vp2px(200) }) .skipMemoryCache(true) + .openEfficient() .brightnessFilter(brightness) ImageKnife.call(imageKnifeOption); } -/** + /** *对比度 */ contrastPixelMap(contrast: number) { @@ -725,18 +792,19 @@ struct TransformPixelMapPage { imageKnifeOption.load(mUrl) .addListener((err, data) => { let result = undefined; - result = data.drawPixelMap.imagePixelMap as PixelMap; + result = data.drawPixelMap.imagePixelMap as PixelMap; this.mContrastPixelMap = result; return false; }) .setImageViewSize({ width: vp2px(200), height: vp2px(200) }) .skipMemoryCache(true) + .openEfficient() .contrastFilter(contrast) ImageKnife.call(imageKnifeOption); } -/** + /** *反转处理 */ invertPixelMap() { @@ -745,18 +813,19 @@ struct TransformPixelMapPage { imageKnifeOption.load(mUrl) .addListener((err, data) => { let result = undefined; - result = data.drawPixelMap.imagePixelMap as PixelMap; + result = data.drawPixelMap.imagePixelMap as PixelMap; this.mInvertPixelMap = result; return false; }) .setImageViewSize({ width: vp2px(200), height: vp2px(200) }) .skipMemoryCache(true) + .openEfficient() .invertFilter() ImageKnife.call(imageKnifeOption); } -/** + /** *照片老旧出来(黑褐色) */ sepiaPixelMap() { @@ -765,18 +834,19 @@ struct TransformPixelMapPage { imageKnifeOption.load(mUrl) .addListener((err, data) => { let result = undefined; - result = data.drawPixelMap.imagePixelMap as PixelMap; + result = data.drawPixelMap.imagePixelMap as PixelMap; this.mSepiaPixelMap = result; return false; }) .setImageViewSize({ width: vp2px(200), height: vp2px(200) }) .skipMemoryCache(true) + .openEfficient() .sepiaFilter() ImageKnife.call(imageKnifeOption); } -/** + /** *素描 */ sketchPixelMap() { @@ -785,18 +855,19 @@ struct TransformPixelMapPage { imageKnifeOption.load(mUrl) .addListener((err, data) => { let result = undefined; - result = data.drawPixelMap.imagePixelMap as PixelMap; + result = data.drawPixelMap.imagePixelMap as PixelMap; this.mSketchPixelMap = result; return false; }) .setImageViewSize({ width: vp2px(200), height: vp2px(200) }) .skipMemoryCache(true) + .openEfficient() .sketchFilter() ImageKnife.call(imageKnifeOption); } -/** + /** *模糊 */ blurHandlePixelMap(radius: number) { @@ -805,17 +876,18 @@ struct TransformPixelMapPage { imageKnifeOption.load(mUrl) .addListener((err, data) => { let result = undefined; - result = data.drawPixelMap.imagePixelMap as PixelMap; + result = data.drawPixelMap.imagePixelMap as PixelMap; this.mBlurPixelMap = result; return false; }) .setImageViewSize({ width: vp2px(200), height: vp2px(200) }) .skipMemoryCache(true) + .openEfficient() .blur(radius) ImageKnife.call(imageKnifeOption); } -/** + /** *马赛克 */ pixelHandlePixelMap(pixel: number) { @@ -824,18 +896,19 @@ struct TransformPixelMapPage { imageKnifeOption.load(mUrl) .addListener((err, data) => { let result = undefined; - result = data.drawPixelMap.imagePixelMap as PixelMap; + result = data.drawPixelMap.imagePixelMap as PixelMap; this.mPixelPixelMap = result; return false; }) .setImageViewSize({ width: vp2px(200), height: vp2px(200) }) .skipMemoryCache(true) + .openEfficient() .pixelationFilter(pixel) ImageKnife.call(imageKnifeOption); } -/** + /** *扭曲 */ swirlHandlePixelMap() { @@ -844,18 +917,19 @@ struct TransformPixelMapPage { imageKnifeOption.load(mUrl) .addListener((err, data) => { let result = undefined; - result = data.drawPixelMap.imagePixelMap as PixelMap; + result = data.drawPixelMap.imagePixelMap as PixelMap; this.mSwirlPixelMap = result; return false; }) .setImageViewSize({ width: vp2px(200), height: vp2px(200) }) .skipMemoryCache(true) + .openEfficient() .swirlFilter(80) // .diskCacheStrategy(new NONE()) ImageKnife.call(imageKnifeOption); } -/** + /** *遮罩 */ maskHandlePixelMap(maskResource: Resource) { @@ -865,7 +939,7 @@ struct TransformPixelMapPage { imageKnifeOption.load(mUrl) .addListener((err, data) => { let result = undefined; - result = data.drawPixelMap.imagePixelMap as PixelMap; + result = data.drawPixelMap.imagePixelMap as PixelMap; this.mMaskPixelMap = result; return false; }) @@ -876,6 +950,69 @@ struct TransformPixelMapPage { ImageKnife.call(imageKnifeOption); } + + /** + *kuwahar + */ + kuwaharaHandlePixelMap() { + let imageKnifeOption = new RequestOption(); + imageKnifeOption.load(mUrl) + .addListener((err, data) => { + let result = undefined; + result = data.drawPixelMap.imagePixelMap as PixelMap; + this.mKuwaharaPixelMap = result; + return false; + }) + .setImageViewSize({ width: vp2px(200), height: vp2px(200) }) + .skipMemoryCache(true) + .openEfficient() + .kuwaharaFilter(20.0) + // .diskCacheStrategy(new NONE()) + ImageKnife.call(imageKnifeOption); + + } + + /** + *toon + */ + toonHandlePixelMap() { + let imageKnifeOption = new RequestOption(); + imageKnifeOption.load(mUrl) + .addListener((err, data) => { + let result = undefined; + result = data.drawPixelMap.imagePixelMap as PixelMap; + this.mToonPixelMap = result; + return false; + }) + .setImageViewSize({ width: vp2px(200), height: vp2px(200) }) + .skipMemoryCache(true) + .openEfficient() + .toonFilter(0.2, 50.0); + // .diskCacheStrategy(new NONE()) + ImageKnife.call(imageKnifeOption); + + } + + /** + *vignette + */ + vignetteHandlePixelMap() { + let imageKnifeOption = new RequestOption(); + imageKnifeOption.load(mUrl) + .addListener((err, data) => { + let result = undefined; + result = data.drawPixelMap.imagePixelMap as PixelMap; + this.mVignettePixelMap = result; + return false; + }) + .setImageViewSize({ width: vp2px(200), height: vp2px(200) }) + .skipMemoryCache(true) + .openEfficient() + .vignetteFilter([0.5, 0.5], [0.0, 0.0, 0.0], [0.3, 0.5]) + // .diskCacheStrategy(new NONE()) + ImageKnife.call(imageKnifeOption); + + } } var ImageKnife = globalThis.ImageKnife \ No newline at end of file diff --git a/gpu_transform/.gitignore b/gpu_transform/.gitignore new file mode 100644 index 0000000..5a6ba80 --- /dev/null +++ b/gpu_transform/.gitignore @@ -0,0 +1,4 @@ +/node_modules +/.preview +/build +/.cxx \ No newline at end of file diff --git a/gpu_transform/build-profile.json5 b/gpu_transform/build-profile.json5 new file mode 100644 index 0000000..85011b1 --- /dev/null +++ b/gpu_transform/build-profile.json5 @@ -0,0 +1,19 @@ +{ + "apiType": "stageMode", + "buildOption": { + "externalNativeOptions": { + "path": "./src/main/cpp/CMakeLists.txt", + "arguments": "", + "abiFilters": [ + "armeabi-v7a", + "arm64-v8a" + ], + "cppFlags": "" + }, + }, + "targets": [ + { + "name": "default" + } + ] +} diff --git a/gpu_transform/hvigorfile.ts b/gpu_transform/hvigorfile.ts new file mode 100644 index 0000000..47e6e1f --- /dev/null +++ b/gpu_transform/hvigorfile.ts @@ -0,0 +1,2 @@ +// Script for compiling build behavior. It is built in the build plug-in and cannot be modified currently. +export { harTasks } from '@ohos/hvigor-ohos-plugin'; \ No newline at end of file diff --git a/gpu_transform/index.ets b/gpu_transform/index.ets new file mode 100644 index 0000000..ddc8ea4 --- /dev/null +++ b/gpu_transform/index.ets @@ -0,0 +1,33 @@ +/* + * 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 { GPUImage3x3TextureSamplingFilter } from './src/main/ets/gpu/filter/GPUImage3x3TextureSamplingFilter' +export { GPUImageBlurFilter } from './src/main/ets/gpu/filter/GPUImageBlurFilter' +export { GPUImageBrightnessFilter } from './src/main/ets/gpu/filter/GPUImageBrightnessFilter' +export { GPUImageColorInvertFilter } from './src/main/ets/gpu/filter/GPUImageColorInvertFilter' +export { GPUImageColorMatrixFilter } from './src/main/ets/gpu/filter/GPUImageColorMatrixFilter' +export { GPUImageContrastFilter } from './src/main/ets/gpu/filter/GPUImageContrastFilter' +export { GPUImageFilter } from './src/main/ets/gpu/filter/GPUImageFilter' +export { GPUImageFilterGroup } from './src/main/ets/gpu/filter/GPUImageFilterGroup' +export { GPUImageGrayscaleFilter } from './src/main/ets/gpu/filter/GPUImageGrayscaleFilter' +export { GPUImageKuwaharaFilter } from './src/main/ets/gpu/filter/GPUImageKuwaharaFilter' +export { GPUImagePixelationFilter } from './src/main/ets/gpu/filter/GPUImagePixelationFilter' +export { GPUImageSepiaToneFilter } from './src/main/ets/gpu/filter/GPUImageSepiaToneFilter' +export { GPUImageSketchFilter } from './src/main/ets/gpu/filter/GPUImageSketchFilter' +export { GPUImageSwirlFilter } from './src/main/ets/gpu/filter/GPUImageSwirlFilter' +export { GPUImageToonFilter } from './src/main/ets/gpu/filter/GPUImageToonFilter' +export { GPUImageVignetterFilter } from './src/main/ets/gpu/filter/GPUImageVignetterFilter' + + diff --git a/gpu_transform/package.json b/gpu_transform/package.json new file mode 100644 index 0000000..9590234 --- /dev/null +++ b/gpu_transform/package.json @@ -0,0 +1,14 @@ +{ + "license": "ISC", + "types": "", + "devDependencies": {}, + "name": "@ohos/gpu_transform", + "description": "a npm package which contains arkUI2.0 page", + "ohos": { + "org": "" + }, + "main": "index.ets", + "type": "module", + "version": "1.0.0", + "dependencies": {} +} diff --git a/gpu_transform/src/main/cpp/CMakeLists.txt b/gpu_transform/src/main/cpp/CMakeLists.txt new file mode 100644 index 0000000..fcd5572 --- /dev/null +++ b/gpu_transform/src/main/cpp/CMakeLists.txt @@ -0,0 +1,33 @@ +# the minimum version of CMake. +cmake_minimum_required(VERSION 3.4.1) +project(gpu_transform) + +set(NATIVERENDER_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR}) + +include_directories(${NATIVERENDER_ROOT_PATH} + ${NATIVERENDER_ROOT_PATH}/include + ${NATIVERENDER_ROOT_PATH}/util + ${NATIVERENDER_ROOT_PATH}/napi + ${NATIVERENDER_ROOT_PATH}/common + ${NATIVERENDER_ROOT_PATH}/render + ${NATIVERENDER_ROOT_PATH}/constant + ) + +add_library(nativeGpu SHARED + napi/napi_init.cpp + render/EGLRender.cpp + util/GLUtils.cpp + util/NapiUtil.cpp + ) + +find_library ( + hilog-lib + hilog_ndk.z ) +find_library ( + EGL-lib + EGL ) +find_library ( + GLES-lib + GLESv3 ) + +target_link_libraries(nativeGpu PUBLIC ${hilog-lib} ${EGL-lib} ${GLES-lib} libace_napi.z.so libc++.a) \ No newline at end of file diff --git a/gpu_transform/src/main/cpp/common/native_common.h b/gpu_transform/src/main/cpp/common/native_common.h new file mode 100644 index 0000000..4d21ea1 --- /dev/null +++ b/gpu_transform/src/main/cpp/common/native_common.h @@ -0,0 +1,57 @@ +/* + * 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. + */ + +// +// 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 + +#define NAPI_RETVAL_NOTHING + +#define GET_AND_THROW_LAST_ERROR(env) \ + do { \ + const napi_extended_error_info* errorInfo = nullptr; \ + napi_get_last_error_info((env),&errorInfo); \ + bool isPending = false; \ + napi_is_exception_pending((env),&isPending); \ + if(!isPending && errorInfo != nullptr) { \ + const char* errorMessage = \ + errorInfo->error_message != nullptr ? errorInfo->error_message : "empty error message"; \ + napi_throw_error((env),nullptr,errorMessage); \ + } \ + } while (0) + +#define DECLARE_NAPI_FUNCTION(name, func) \ + { \ + (name),nullptr,(func),nullptr,nullptr,nullptr,napi_default,nullptr \ + } + + +#define NAPI_CALL_BASE(env, theCall, retVal) \ + do { \ + if((theCall) != napi_ok) { \ + GET_AND_THROW_LAST_ERROR((env)); \ + return retVal; \ + } \ + } while (0) + + +#define NAPI_CALL(env, theCall) NAPI_CALL_BASE(env, theCall, nullptr) + +#endif //GPU_ImageETS_native_common_H diff --git a/gpu_transform/src/main/cpp/constant/constant_shape.h b/gpu_transform/src/main/cpp/constant/constant_shape.h new file mode 100644 index 0000000..a7dcc1e --- /dev/null +++ b/gpu_transform/src/main/cpp/constant/constant_shape.h @@ -0,0 +1,448 @@ +/* + * 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. + */ + +// +// 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 + +const char vShaderStr[] = + "#version 300 es \n" + "layout(location = 0) in vec4 a_position; \n" + "layout(location = 1) in vec2 a_texCoord; \n" + "out vec2 v_texCoord; \n" + "void main() \n" + "{ \n" + " gl_Position = a_position; \n" + " v_texCoord = a_texCoord; \n" + "} \n"; + +const char fShaderStr0[] = + "#version 300 es \n" + "precision mediump float; \n" + "in vec2 v_texCoord; \n" + "layout(location = 0) out vec4 outColor; \n" + "uniform sampler2D s_TextureMap; \n" + "void main() \n" + "{ \n" + "outColor = texture(s_TextureMap,v_texCoord); \n" + "} \n"; + +const char v3x3ShaderStr[] = + "#version 300 es\n" + "precision highp float;\n" + "layout(location = 0) in vec4 a_position;\n" + "layout(location = 1) in vec2 a_texCoord;\n" + "uniform highp float texelWidth;\n" + "uniform highp float texelHeight;\n" + "out vec2 v_texCoord;\n" + "out vec2 leftTextureCoordinate;\n" + "out vec2 rightTextureCoordinate;\n" + "out vec2 topTextureCoordinate;\n" + "out vec2 topLeftTextureCoordinate;\n" + "out vec2 topRightTextureCoordinate;\n" + "out vec2 bottomTextureCoordinate;\n" + "out vec2 bottomLeftTextureCoordinate;\n" + "out vec2 bottomRightTextureCoordinate;\n" + "void main()\n" + "{\n" + "gl_Position = a_position;\n" + "vec2 widthStep = vec2(texelWidth, 0.0);\n" + "vec2 heightStep = vec2(0.0, texelHeight);\n" + "vec2 widthHeightStep = vec2(texelWidth, texelHeight);\n" + "vec2 widthNegativeHeightStep = vec2(texelWidth, -texelHeight);\n" + "v_texCoord = a_texCoord;\n" + "leftTextureCoordinate = a_texCoord - widthStep;\n" + "rightTextureCoordinate = a_texCoord + widthStep;\n" + "\n" + "topTextureCoordinate = a_texCoord - heightStep;\n" + "topLeftTextureCoordinate = a_texCoord - widthHeightStep;\n" + "topRightTextureCoordinate = a_texCoord + widthNegativeHeightStep;\n" + "\n" + "bottomTextureCoordinate = a_texCoord +heightStep;\n" + "bottomLeftTextureCoordinate = a_texCoord - widthNegativeHeightStep;\n" + "bottomRightTextureCoordinate = a_texCoord + widthHeightStep;\n" + "}"; + + +//kuwahara +const char fShaderStr3[] = + "#version 300 es\n" + "precision highp float;\n" + "layout(location = 0) out vec4 outColor;\n" + "in vec2 v_texCoord;\n" + "uniform lowp sampler2D s_TextureMap;\n" + "uniform vec2 u_texSize;\n" + "uniform highp float radius;\n" + "const vec2 src_size = vec2(1.0 / 768.0, 1.0 / 1024.0);\n" + "void main() {\n" + "vec2 uv = v_texCoord;\n" + "float n = float((radius + 1.0) * (radius + 1.0));\n" + "int i ; int j ;\n" + "vec3 m0 = vec3(0.0); vec3 m1 = vec3(0.0); vec3 m2 = vec3(0.0); vec3 m3 = vec3(0.0);\n" + "vec3 s0 = vec3(0.0); vec3 s1 = vec3(0.0); vec3 s2 = vec3(0.0); vec3 s3 = vec3(0.0);\n" + "vec3 c;\n" + "for (j = -int(radius); j <=0; ++j) {\n" + "for (i = -int(radius); i <=0; ++i) {\n" + "c = texture(s_TextureMap,uv + vec2(i,j) * src_size).rgb;\n" + "m0 += c;\n" + "s0 += c * c;\n" + "}\n" + "}\n" + "for (j = -int(radius); j <=0; ++j) {\n" + "for (i =0; i <=int(radius); ++i) {\n" + "c = texture(s_TextureMap,uv + vec2(i,j) * src_size).rgb;\n" + "m1 += c;\n" + "s1 += c * c;\n" + "}\n" + "}\n" + "for (j = 0; j <=int(radius); ++j) {\n" + "for (i = 0; i <= int(radius); ++i) {\n" + "c = texture(s_TextureMap,uv + vec2(i,j) * src_size).rgb;\n" + "m2 += c;\n" + "s2 += c * c;\n" + "}\n" + "}\n" + "for (j = 0; j <=int(radius); ++j) {\n" + "for (i = -int(radius); i <= 0; ++i) {\n" + "c = texture(s_TextureMap,uv + vec2(i,j) * src_size).rgb;\n" + "m3 += c;\n" + "s3 += c * c;\n" + "}\n" + "}\n" + "\n" + "\n" + "float min_sigma2 = 1e+2;\n" + "m0 /= n;\n" + "s0 = abs(s0 /n - m0 * m0);\n" + "\n" + "float sigma2 = s0.r + s0.g + s0.b;\n" + "if (sigma2 < min_sigma2) {\n" + "min_sigma2 = sigma2;\n" + "outColor = vec4(m0,1.0);\n" + "}\n" + "\n" + "m1 /= n;\n" + "s1 = abs(s1 / n -m1 * m1);\n" + "\n" + "sigma2 = s1.r + s1.g + s1.b;\n" + "if (sigma2 < min_sigma2) {\n" + "min_sigma2 = sigma2;\n" + "outColor = vec4(m1,1.0);\n" + "}\n" + "\n" + "m2 /= n;\n" + "s2 = abs(s2 / n -m2 * m2);\n" + "\n" + "sigma2 = s2.r + s2.g + s2.b;\n" + "if (sigma2 < min_sigma2) {\n" + "min_sigma2 = sigma2;\n" + "outColor = vec4(m2,1.0);\n" + "}\n" + "\n" + "m3 /= n;\n" + "s3 = abs(s3 / n -m3 * m3);\n" + "\n" + "sigma2 = s3.r + s3.g + s3.b;\n" + "if (sigma2 < min_sigma2) {\n" + "min_sigma2 = sigma2;\n" + "outColor = vec4(m3,1.0);\n" + "}\n" + "}\n"; + + +//旋转 +const char swirlFShaderStr[] = + "#version 300 es\n" + "precision highp float;\n" + "layout(location = 0) out vec4 outColor;\n" + "in vec2 v_texCoord;\n" + "uniform lowp sampler2D s_TextureMap;\n" + "uniform vec2 u_texSize;\n" + "uniform highp float radius;\n" + "uniform highp float angle;\n" + "uniform vec2 center;\n" + "void main() {\n" + "vec2 tc = v_texCoord * u_texSize;\n" + "tc -= center;\n" + "float dist = length(tc);\n" + "if (dist < radius) {\n" + "float percent = (radius - dist) / radius;\n" + "float theta = percent * percent * angle * 8.0;\n" + "float s = sin(theta);\n" + "float c = cos(theta);\n" + "tc = vec2(dot(tc, vec2(c, -s)), dot(tc, vec2(s, c)));\n" + "}\n" + "tc += center;\n" + "outColor = texture(s_TextureMap, tc / u_texSize);\n" + "}"; + + +//亮度 +const char brightFShaderStr[] = + "#version 300 es\n" + "precision highp float;\n" + "in vec2 v_texCoord;\n" + "\n" + "uniform lowp sampler2D s_TextureMap;\n" + "uniform lowp float brightness;\n" + "layout(location = 0) out vec4 outColor;\n" + "\n" + "void main()\n" + "{\n" + "lowp vec4 textureColor = texture(s_TextureMap, v_texCoord);\n" + "\n" + "outColor = vec4((textureColor.rgb + vec3(brightness)), textureColor.w);\n" + "}"; + +//反转 +const char contrastFShaderStr[] = + "#version 300 es\n" + "precision highp float;\n" + "in vec2 v_texCoord;\n" + "\n" + "uniform lowp sampler2D s_TextureMap;\n" + "uniform lowp float contrast;\n" + "layout(location = 0) out vec4 outColor;\n" + "\n" + "void main()\n" + "{\n" + "lowp vec4 textureColor = texture(s_TextureMap, v_texCoord);\n" + "\n" + "outColor = vec4(((textureColor.rgb - vec3(0.5)) * contrast + vec3(0.5)), textureColor.w);\n" + "}"; + +//invert +const char invertFShaderStr[] = + "#version 300 es\n" + "precision highp float;\n" + "int vec2 v_texCoord;\n" + "\n" + "uniform lowp sampler2D s_TextureMap;\n" + "layout(location = 0) out vec4 outColor;\n" + "\n" + "void main()\n" + "{\n" + "lowp vec4 textureColor = texture(s_TextureMap, v_texCoord);\n" + "\n" + "outColor = vec4((1.0 - textureColor.rgb), textureColor.w);\n" + "}"; + +//pixel +const char pixelFShaderStr[] = + "#version 300 es\n" + "precision highp float;\n" + "in vec2 v_texCoord;\n" + "uniform float imageWidthFactor;\n" + "uniform float imageHeightFactor;\n" + "uniform lowp sampler2D s_TextureMap;\n" + "uniform float pixel;\n" + "layout(location = 0) out vec4 outColor;\n" + + "void main()\n" + "{\n" + "vec2 uv = v_texCoord.xy;\n" + "float dx = pixel * imageWidthFactor;\n" + "float dy = pixel * imageHeightFactor;\n" + "vec2 coord = vec2(dx * floor(uv.x / dx), dy * floor(uv.y / dy));\n" + "vec3 tc = texture(s_TextureMap, coord).xyz;\n" + "outColor = vec4(tc, 1.0);\n" + "}"; + +//vignette +const char vignetteFShaderStr[] = + "#version 300 es\n" + "precision highp float;\n" + "uniform lowp sampler2D s_TextureMap;\n" + "in vec2 v_texCoord;\n" + "layout(location = 0) out vec4 outColor;\n" + "\n" + "uniform lowp vec2 vignetteCenter;\n" + "uniform lowp vec3 vignetteColor;\n" + "uniform highp float vignetteStart;\n" + "uniform highp float vignetteEnd;\n" + "\n" + "void main()\n" + "{\n" + "lowp vec3 rgb = texture(s_TextureMap, v_texCoord).rgb;\n" + "lowp float d = distance(v_texCoord, vec2(0.5,0.5));\n" + "rgb *= (1.0 - smoothstep(vignetteStart , vignetteEnd, d));\n" + "outColor = vec4(vec3(rgb), 1.0);\n" + "\n" + "lowp vec3 rgb2 = texture(s_TextureMap, v_texCoord).rgb;\n" + "lowp float d2 = distance(v_texCoord, vec2(vignetteCenter.x, vignetteCenter.y));\n" + "lowp float percent = smoothstep(vignetteStart, vignetteEnd, d2);\n" + "outColor = vec4(mix(rgb2.x,vignetteColor.x,percent), mix(rgb2.y, vignetteColor.y, percent), mix(rgb2.z, vignetteColor.z, percent), 1.0);\n" + "}"; + + +//ColorMatrix +const char colorMatrixFShaderStr[] = + "#version 300 es\n" + "precision highp float;\n" + "in vec2 v_texCoord;\n" + "uniform lowp sampler2D s_TextureMap;\n" + "layout(location = 0) out vec4 outColor;\n" + "\n" + "uniform lowp mat4 colorMatrix;\n" + "uniform lowp float intensity;\n" + "void main()\n" + "{\n" + "lowp vec4 textureColor = texture(s_TextureMap, v_texCoord);\n" + "lowp vec4 outputColor = textureColor * colorMatrix;\n" + "outColor = (intensity * outputColor) + ((1.0 - intensity) * textureColor);\n" + "}"; + + +//toon +const char toonFShaderStr[] = + "#version 300 es\n" + "precision highp float;\n" + "in vec2 v_texCoord;\n" + "layout(location = 0) out vec4 outColor;\n" + "in vec2 leftTextureCoordinate;\n" + "in vec2 rightTextureCoordinate;\n" + "in vec2 topTextureCoordinate;\n" + "in vec2 topLeftTextureCoordinate;\n" + "in vec2 topRightTextureCoordinate;\n" + "in vec2 bottomTextureCoordinate;\n" + "in vec2 bottomLeftTextureCoordinate;\n" + "in vec2 bottomRightTextureCoordinate;\n" + "uniform lowp sampler2D s_TextureMap;\n" + "uniform highp float intensity;\n" + "uniform highp float threshold;\n" + "uniform highp float quantizationLevels;\n" + "const highp vec3 W = vec3(0.2125, 0.7154, 0.0721);\n" + "void main()\n" + "{\n" + "vec4 textureColor = texture(s_TextureMap, v_texCoord);\n" + "float bottomLeftIntensity = texture(s_TextureMap, bottomLeftTextureCoordinate).r;\n" + "float topRightIntensity = texture(s_TextureMap, topRightTextureCoordinate).r;\n" + "float topLeftIntensity = texture(s_TextureMap, topLeftTextureCoordinate).r;\n" + "float bottomRightIntensity = texture(s_TextureMap, bottomRightTextureCoordinate).r;\n" + "float leftIntensity = texture(s_TextureMap, leftTextureCoordinate).r;\n" + "float rightIntensity = texture(s_TextureMap, rightTextureCoordinate).r;\n" + "float bottomIntensity = texture(s_TextureMap, bottomTextureCoordinate).r;\n" + "float topIntensity = texture(s_TextureMap, topTextureCoordinate).r;\n" + "float h = -topLeftIntensity - 2.0 * topIntensity - topRightIntensity + bottomLeftIntensity +2.0 * bottomIntensity + bottomRightIntensity;\n" + "float v = -bottomLeftIntensity - 2.0 * leftIntensity - topLeftIntensity + bottomRightIntensity +2.0 * rightIntensity + topRightIntensity;\n" + "float mag = length(vec2(h, v));\n" + "\n" + "vec3 posterizedImageColor = floor((textureColor.rgb * quantizationLevels) + 0.5) / quantizationLevels;\n" + "\n" + "float thresholdTest = 1.0 - step(threshold, mag);\n" + "\n" + "outColor = vec4(posterizedImageColor * thresholdTest, textureColor.a);\n" + "}"; + + + +//grayScale +const char grayScaleShaderStr[] = + "#version 300 es\n" + "precision highp float;\n" + "in vec2 v_texCoord;\n" + "uniform lowp sampler2D s_TextureMap;\n" + "layout(location = 0) out vec4 outColor;\n" + "const highp vec3 W = vec3(0.2125, 0.7154, 0.0721);\n" + "void main()\n" + "{\n" + "lowp vec4 textureColor = texture(s_TextureMap, v_texCoord);\n" + "float luminance = dot(textureColor.rgb, W);\n" + "outColor = vec4(vec3(luminance), textureColor.a);\n" + "}"; + +//sketch +const char sketchShaderStr[] = + "#version 300 es\n" + "precision highp float;\n" + "layout(location = 0) out vec4 outColor;\n" + "uniform lowp sampler2D s_TextureMap;\n" + + "in vec2 textureCoordinate;\n" + "in vec2 leftTextureCoordinate;\n" + "in vec2 rightTextureCoordinate;\n" + "\n" + "in vec2 topTextureCoordinate;\n" + "in vec2 topLeftTextureCoordinate;\n" + "in vec2 topRightTextureCoordinate;\n" + "\n" + "in vec2 bottomTextureCoordinate;\n" + "in vec2 bottomLeftTextureCoordinate;\n" + "in vec2 bottomRightTextureCoordinate;\n" + "\n" + "void main()\n" + "{\n" + "float bottomLeftIntensity = texture(s_TextureMap, bottomLeftTextureCoordinate).r;\n" + "float topRightIntensity = texture(s_TextureMap, topRightTextureCoordinate).r;\n" + "float topLeftIntensity = texture(s_TextureMap, topLeftTextureCoordinate).r;\n" + "float bottomRightIntensity = texture(s_TextureMap, bottomRightTextureCoordinate).r;\n" + "float leftIntensity = texture(s_TextureMap, leftTextureCoordinate).r;\n" + "float rightIntensity = texture(s_TextureMap, rightTextureCoordinate).r;\n" + "float bottomIntensity = texture(s_TextureMap, bottomTextureCoordinate).r;\n" + "float topIntensity = texture(s_TextureMap, topTextureCoordinate).r;\n" + "float h = -topLeftIntensity - 2.0 * topIntensity - topRightIntensity + bottomLeftIntensity +2.0 * bottomIntensity + bottomRightIntensity;\n" + "float v = -bottomLeftIntensity - 2.0 * leftIntensity - topLeftIntensity + bottomRightIntensity +2.0 * rightIntensity + topRightIntensity;\n" + "float mag = 1.0-length(vec2(h, v));\n" + "outColor = vec4(vec3(mag), 1.0);\n" + "}"; + +//blur +const char blurShaderStr[] = + "#version 300 es\n" + "precision highp float;\n" + "uniform lowp sampler2D s_TextureMap;\n" + "in vec2 v_texCoord;\n" + "layout(location = 0) out vec4 outColor;\n" + + "uniform highp int blurRadius;\n" + "uniform highp vec2 blurOffset;\n" + "\n" + "uniform highp float sumWeight;\n" + "float PI = 3.1415926;\n" + "float getWeight(int i)\n" + "{\n" + "float sigma = float(blurRadius) / 3.0 ;\n" + "return (1.0 / sqrt(2.0 * PI * sigma * sigma)) * exp(-float(i * i) / (2.0 * sigma * sigma)) / sumWeight;\n" + "}\n" + + "vec2 clampCoordinate (vec2 coordinate)\n" + "{\n" + "return vec2(clamp(coordinate.x, 0.0, 1.0), clamp(coordinate.y, 0.0, 1.0));\n" + "}\n" + "\n" + "void main()\n" + "{\n" + "vec4 sourceColor = texture(s_TextureMap, v_texCoord);\n" + "if (blurRadius <= 1)\n" + "{\n" + "outColor = sourceColor;\n" + "return;\n" + "}\n" + "float weight = getWeight(0);\n" + "vec3 finalColor = sourceColor.rgb * weight;\n" + "for(int i = 1; i < blurRadius; i++) {\n" + "weight = getWeight(i);\n" + "finalColor += texture(s_TextureMap, clampCoordinate(v_texCoord - blurOffset * float(i))).rgb * weight;\n" + "finalColor += texture(s_TextureMap, clampCoordinate(v_texCoord + blurOffset * float(i))).rgb * weight;\n" + "}\n" + "outColor = vec4(finalColor, sourceColor.a);\n" + "}\n"; + +#endif //GPU_ImageETS_constant_shape_H diff --git a/gpu_transform/src/main/cpp/napi/napi_init.cpp b/gpu_transform/src/main/cpp/napi/napi_init.cpp new file mode 100644 index 0000000..da6b550 --- /dev/null +++ b/gpu_transform/src/main/cpp/napi/napi_init.cpp @@ -0,0 +1,99 @@ +/* + * 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. + */ + +// +// 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 +#include +#include +#include "DebugLog.h" +#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[] = { + DECLARE_NAPI_FUNCTION("EglRenderInit",EGLRender:: RenderInit), + DECLARE_NAPI_FUNCTION("EglRenderSetImageData",EGLRender:: RenderSetData), + DECLARE_NAPI_FUNCTION("EglPixelMapSurface",EGLRender:: GetPixelMapOfSurface), + DECLARE_NAPI_FUNCTION("EglRenderSetIntParams",EGLRender:: RenderSetIntParams), + DECLARE_NAPI_FUNCTION("EglIsInit",EGLRender:: EGLIsInit), + DECLARE_NAPI_FUNCTION("EglDestroy",EGLRender:: DestroyGlesEnv), + + + DECLARE_NAPI_FUNCTION("EglUseProgram",EGLRender:: StartUseProgram), + DECLARE_NAPI_FUNCTION("EglRendering",EGLRender:: Rendering), + + DECLARE_NAPI_FUNCTION("EglUniform1i",EGLRender:: RenderGlUniform1i), + DECLARE_NAPI_FUNCTION("EglUniform1f",EGLRender:: RenderGlUniform1f), + DECLARE_NAPI_FUNCTION("EglUniform2fv",EGLRender:: RenderGlUniform2fv), + + DECLARE_NAPI_FUNCTION("EglSetTypeArrayOfFloat",EGLRender:: setTypeArrayOfFloat), + + DECLARE_NAPI_FUNCTION("EglSetTypeArrayOfMatrix3f",EGLRender:: setTypeArrayOfMatrix3f), + DECLARE_NAPI_FUNCTION("EglSetTypeArrayOfMatrix4f",EGLRender:: setTypeArrayOfMatrix4f), + }; + NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]),desc)); + return exports; +} + +/** + * Napi Module define + */ +static napi_module nativeGpuModule = { + .nm_version =1, + .nm_flags = 0, + .nm_filename = nullptr, + .nm_register_func = Init, + .nm_modname = "nativeGpu", + .nm_priv = ((void*)0), + .reserved = { 0 }, +}; + +extern "C" __attribute__((constructor)) void RegisterModule(void) +{ + napi_module_register(&nativeGpuModule); +} \ No newline at end of file diff --git a/gpu_transform/src/main/cpp/render/EGLRender.cpp b/gpu_transform/src/main/cpp/render/EGLRender.cpp new file mode 100644 index 0000000..95e2570 --- /dev/null +++ b/gpu_transform/src/main/cpp/render/EGLRender.cpp @@ -0,0 +1,822 @@ +/* + * 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. + */ + +// +// 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 "native_common.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include "DebugLog.h" +#include "constant/constant_shape.h" +#include "GLUtils.h" +#include "../util/NapiUtil.h" + + +#define PARAM_TYPE_SHADER_INDEX 300 + +#define VERTEX_POS_LOC 0 +#define TEXTURE_POS_LOC 1 + +const int32_t STR_DEFAULT_SIZE = 1024; +EGLRender *EGLRender::sInstance = nullptr; + +//顶点坐标 +const GLfloat vVertices[] = { + -1.0f, -1.0f, 0.0f, //bottom left + 1.0f, -1.0f, 0.0f, //bottom right + -1.0f, 1.0f, 0.0f, //top left + 1.0f, 1.0f, 0.0f, //top right +}; + +//正常纹理坐标 +const GLfloat vTexCoors[] = { + 0.0f, 1.0f, //bottom left + 1.0f, 1.0f, //bottom right + 0.0f, 0.0f, //top left + 1.0f, 0.0f, //top right +}; + +//fbo 纹理坐标与正常纹理方向不同(上下镜像) +const GLfloat vFboTexCoors[] = { + 0.0f, 0.0f, //bottom left + 1.0f, 0.0f, //bottom right + 0.0f, 1.0f, //top left + 1.0f, 1.0f, //top right +}; + +const GLushort indices[] = { 0, 1, 2, 1, 3, 2 }; + + +napi_value EGLRender::RenderInit(napi_env env, napi_callback_info info) { + napi_value exports; + + NAPI_CALL(env, napi_create_object(env, &exports)); + napi_property_descriptor desc[] = { + + }; + NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]),desc)); + + EGLRender::GetInstance() ->Init(); + return exports; +} + + +napi_value EGLRender::RenderSetData(napi_env env, napi_callback_info info) { + size_t argc = 3; + napi_value args[3] = { nullptr }; + napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); + + void* buffer; + size_t bufferLength; + napi_status buffStatus = napi_get_arraybuffer_info(env, args[0], &buffer, &bufferLength); + if (buffStatus != napi_ok) { + return nullptr; + } + + uint8_t* uint8_buf = reinterpret_cast(buffer); + uint32_t width; + napi_status wStatus = napi_get_value_uint32(env, args[1], &width); + if (wStatus != napi_ok) { + return nullptr; + } + uint32_t height; + napi_status hStatus = napi_get_value_uint32(env, args[2], &height); + if (hStatus != napi_ok) { + return nullptr; + } + + EGLRender::GetInstance() -> SetImageData(uint8_buf, width, height); + return nullptr; +} + +napi_value EGLRender::RenderSetIntParams(napi_env env, napi_callback_info info) { + LOGI("gl--> RenderSetIntParams start"); + size_t argc = 2; + napi_value args[2] = { nullptr }; + napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); + + uint32_t type; + napi_status tStatus = napi_get_value_uint32(env, args[0], &type); + if (tStatus != napi_ok) { + return nullptr; + } + uint32_t param; + napi_status pStatus = napi_get_value_uint32(env, args[1], ¶m); + if (pStatus != napi_ok) { + return nullptr; + } + EGLRender::GetInstance() -> SetIntParams(type, param); + return nullptr; +} + +napi_value EGLRender::GetPixelMapOfSurface(napi_env env, napi_callback_info info) { + size_t argc = 4; + napi_value args[4] = { nullptr }; + napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); + + uint32_t x; + napi_status xStatus = napi_get_value_uint32(env, args[0], &x); + if (xStatus != napi_ok) { + return nullptr; + } + + uint32_t y; + napi_status yStatus = napi_get_value_uint32(env, args[1], &y); + if (yStatus != napi_ok) { + return nullptr; + } + + uint32_t surfaceWidth; + napi_status swStatus = napi_get_value_uint32(env, args[2], &surfaceWidth); + if (swStatus != napi_ok) { + return nullptr; + } + + uint32_t surfaceHeight; + napi_status shStatus = napi_get_value_uint32(env, args[3], &surfaceHeight); + if (shStatus != napi_ok) { + return nullptr; + } + + uint8_t* pixels = (uint8_t*) malloc(surfaceWidth * surfaceHeight * 4); + + glPixelStorei(GL_PACK_ALIGNMENT, 1); + glReadPixels(x, y, surfaceWidth, surfaceHeight, GL_RGBA, GL_UNSIGNED_BYTE, pixels); + + NativeImageUtil::flip(&pixels, surfaceWidth, surfaceHeight); + napi_value array; + int byte_length = surfaceWidth * surfaceHeight * 4; + if (!NativeImageUtil::CreateArrayBuffer(env, pixels, byte_length, &array)) { + LOGI("gl--> GetPixelMapOfSurface error"); + } + free(pixels); + return array; +} + +napi_value EGLRender::EGLIsInit(napi_env env, napi_callback_info info) { + napi_value isInit; + int32_t value; + if (EGLRender::GetInstance() -> m_IsGLContextReady) { + value = 1; + }else { + value = 0; + } + napi_status status = napi_create_int32(env, value, &isInit); + if (status != napi_ok) { + return nullptr; + } + return isInit; +} + +napi_value EGLRender::DestroyGlesEnv(napi_env env, napi_callback_info info) { + EGLRender::GetInstance() -> UnInit(); + return nullptr; +} + +napi_value EGLRender::StartUseProgram(napi_env env, napi_callback_info info) { + EGLRender::GetInstance() -> UseProgram(); + return nullptr; +} + +napi_value EGLRender::Rendering(napi_env env, napi_callback_info info) { + //7 . 渲染 + glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, (const void *)0); + glBindVertexArray(GL_NONE); + glBindTexture(GL_TEXTURE_2D, GL_NONE); + return nullptr; +} + +napi_value EGLRender::setTypeArrayOfFloat(napi_env env, napi_callback_info info) { + + size_t argc = 3; + napi_value args[3] = { nullptr }; + napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); + + std::string locationContent; + NapiUtil::JsValueToString(env, args[0], 1024, locationContent); + + char* location = (char*)locationContent.c_str(); + + std::string content; + NapiUtil::JsValueToString(env, args[1], 1024, content); + + char* key = (char*)content.c_str(); + + napi_typedarray_type dataType = napi_float32_array; + void* buffer; + size_t bufferLength; + size_t byte_offset; + napi_status buffStatus = napi_get_typedarray_info(env, args[2], &dataType, &bufferLength, &buffer, &args[2], &byte_offset); + if (buffStatus != napi_ok){ + return nullptr; + } + + float* value = reinterpret_cast(buffer); + + int uniformType; + + if (strcmp(key, "glUniform2fv") == 0) { + uniformType = 2; + }else if (strcmp(key, "glUniform3fv") == 0) { + uniformType = 3; + }else if (strcmp(key, "glUniform4fv") == 0) { + uniformType = 4; + }else if (strcmp(key, "glUniform1fv") == 0) { + uniformType = 1; + }else if (strcmp(key, "glUniform2f") == 0) { + uniformType = 21; + } + + EGLRender::GetInstance() -> GlUniformArray(location, value, uniformType); + return nullptr; +} + +napi_value EGLRender::setTypeArrayOfMatrix3f(napi_env env, napi_callback_info info) { + size_t argc = 2; + napi_value args[2] = { nullptr }; + napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); + + std::string locationContent; + NapiUtil::JsValueToString(env, args[0], 1024, locationContent); + + char* location = (char*)locationContent.c_str(); + + napi_typedarray_type dataType = napi_float32_array; + void* buffer; + size_t bufferLength; + size_t byte_offset; + napi_status buffStatus = napi_get_typedarray_info(env, args[1], &dataType, &bufferLength, &buffer, &args[1], &byte_offset); + if (buffStatus != napi_ok){ + return nullptr; + } + + float* value = reinterpret_cast(buffer); + + EGLRender::GetInstance() -> GlUniformMatrix(location, value, 3); + + return nullptr; +} + +napi_value EGLRender::setTypeArrayOfMatrix4f(napi_env env, napi_callback_info info) { + size_t argc = 2; + napi_value args[2] = { nullptr }; + napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); + + std::string locationContent; + NapiUtil::JsValueToString(env, args[0], 1024, locationContent); + + char* location = (char*)locationContent.c_str(); + + napi_typedarray_type dataType = napi_float32_array; + void* buffer; + size_t bufferLength; + size_t byte_offset; + napi_status buffStatus = napi_get_typedarray_info(env, args[1], &dataType, &bufferLength, &buffer, &args[1], &byte_offset); + if (buffStatus != napi_ok){ + return nullptr; + } + + float* value = reinterpret_cast(buffer); + + EGLRender::GetInstance() -> GlUniformMatrix(location, value, 4); + return nullptr; +} + +napi_value EGLRender::RenderGlUniform1i(napi_env env, napi_callback_info info) { + //int + size_t argc = 2; + napi_value args[2] = { nullptr }; + napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); + + std::string content; + NapiUtil::JsValueToString(env, args[0], 1024, content); + uint32_t value; + napi_status status = napi_get_value_uint32(env, args[1], &value); + if (status != napi_ok) { + return nullptr; + } + EGLRender::GetInstance() -> GlUniform((char*)content.c_str(), value, 0); + return nullptr; +} + +napi_value EGLRender::RenderGlUniform1f(napi_env env, napi_callback_info info) { + //float + size_t argc = 2; + napi_value args[2] = { nullptr }; + napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); + + std::string content; + NapiUtil::JsValueToString(env, args[0], 1024, content); + double value; + napi_status status = napi_get_value_double(env, args[1], &value); + if (status != napi_ok) { + return nullptr; + } + EGLRender::GetInstance() -> GlUniform((char*)content.c_str(), value, 1); + return nullptr; +} + +napi_value EGLRender::RenderGlUniform2fv(napi_env env, napi_callback_info info) { + //float 数组 + size_t argc = 3; + napi_value args[3] = { nullptr }; + napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); + + std::string content; + NapiUtil::JsValueToString(env, args[0], 1024, content); + + double value; + napi_status status = napi_get_value_double(env, args[1], &value); + if (status != napi_ok) { + return nullptr; + } + double value2; + napi_status status2 = napi_get_value_double(env, args[2], &value2); + if (status2 != napi_ok) { + return nullptr; + } + + float vce2[2]; + vce2[0] = value; + vce2[1] = value2; + EGLRender::GetInstance() -> GlUniformArray((char*)content.c_str(), vce2, 10); + return nullptr; +} + +EGLRender::EGLRender() { + m_ImageTextureId = GL_NONE; + m_FboTextureId = GL_NONE; + m_SamplerLoc = GL_NONE; + m_TexSizeLoc = GL_NONE; + + m_FboId = GL_NONE; + m_ProgramObj = GL_NONE; + m_VertexShader = GL_NONE; + m_FragmentShader = GL_NONE; + m_eglDisplay = nullptr; + m_IsGLContextReady = false; + m_ShaderIndex = 0; + +} +EGLRender::~EGLRender() { +} +void EGLRender::Init() { + if (CreateGlEnv() == 0) + { + m_IsGLContextReady = true; + } + if (!m_IsGLContextReady) { + return; + } + + glGenTextures(1, &m_ImageTextureId); //生成纹理名称 + glBindTexture(GL_TEXTURE_2D, m_ImageTextureId); //允许建立一个绑定到目标纹理的有名称的纹理 + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glBindTexture(GL_TEXTURE_2D, GL_NONE); + + glGenTextures(1, &m_FboTextureId); + glBindTexture(GL_TEXTURE_2D, m_FboTextureId); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glBindTexture(GL_TEXTURE_2D, GL_NONE); + + + m_ProgramObj = GLUtils::CreateProgram(vShaderStr, fShaderStr0, m_VertexShader, + m_FragmentShader); + if (!m_ProgramObj) { + GLUtils::CheckGLError("Create Program"); + return; + } + + // Generate VBO Ids and load the VBOs width data + glGenBuffers(3, m_VboIds); + glBindBuffer(GL_ARRAY_BUFFER, m_VboIds[0]); + glBufferData(GL_ARRAY_BUFFER, sizeof(vVertices), vVertices, GL_STATIC_DRAW); + + glBindBuffer(GL_ARRAY_BUFFER, m_VboIds[1]); + glBufferData(GL_ARRAY_BUFFER, sizeof(vFboTexCoors), vTexCoors, GL_STATIC_DRAW); + + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_VboIds[2]); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); + + // Generate VAO Ids + glGenVertexArrays(1, m_VaoIds); + + // FBO off screen rendering VAO + glBindVertexArray(m_VaoIds[0]); + + glBindBuffer(GL_ARRAY_BUFFER, m_VboIds[0]); + glEnableVertexAttribArray(VERTEX_POS_LOC); + glVertexAttribPointer(VERTEX_POS_LOC, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (const void *)0); + glBindBuffer(GL_ARRAY_BUFFER,GL_NONE); + + glBindBuffer(GL_ARRAY_BUFFER, m_VboIds[1]); + glEnableVertexAttribArray(TEXTURE_POS_LOC); + glVertexAttribPointer(TEXTURE_POS_LOC, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), (const void *)0); + glBindBuffer(GL_ARRAY_BUFFER,GL_NONE); + + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_VboIds[2]); + glBindVertexArray(GL_NONE); +} + +int EGLRender::CreateGlEnv() { + const EGLint confAttr[] = + { + EGL_RENDERABLE_TYPE, EGL_OPENGL_ES3_BIT_KHR, + EGL_SURFACE_TYPE, EGL_PBUFFER_BIT, + EGL_RED_SIZE, 8, + EGL_GREEN_SIZE, 8, + EGL_BLUE_SIZE, 8, + EGL_ALPHA_SIZE, 8, + EGL_DEPTH_SIZE, 16, + EGL_STENCIL_SIZE, 8, + EGL_NONE + }; + // EGL context attributes + const EGLint ctxAttr[] = { + EGL_CONTEXT_CLIENT_VERSION, 2, + EGL_NONE + }; + + // surface attributes + // the surface size is set to the input frame size + const EGLint surfaceAttr[] = { + EGL_WIDTH, 1, + EGL_HEIGHT, 1, + EGL_NONE + }; + EGLint eglMajVers, eglMinVers; + EGLint numConfigs; + int resultCode = 0; + do + { + m_eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); + if (m_eglDisplay == EGL_NO_DISPLAY) { + resultCode = -1; + break; + } + + // 初始化 egl 方法 + if (!eglInitialize(m_eglDisplay, &eglMajVers, &eglMinVers)) { + resultCode = -1; + break; + } + + //获取 EGLConfig 对象,确定渲染表面的配置信息 + if (!eglChooseConfig(m_eglDisplay, confAttr, &m_eglConf, 1, &numConfigs)) { + resultCode = -1; + break; + } + + // 创建渲染表面 EGLSurface 使用 eglCreateBufferSurface 创建屏幕外渲染区域 + m_eglSurface = eglCreatePbufferSurface(m_eglDisplay, m_eglConf, surfaceAttr); + if (m_eglSurface == EGL_NO_SURFACE) { + switch(eglGetError()) + { + case EGL_BAD_ALLOC: + LOGI("gl-->::CreateGlesEnv Not enough resources available"); + break; + case EGL_BAD_CONFIG: + LOGI("gl-->::CreateGlesEnv provided EGLConfig is invalid"); + break; + case EGL_BAD_PARAMETER: + LOGI("gl-->::CreateGlesEnv provided EGL_WIDTH and EGL_HEIGHT is invalid"); + break; + case EGL_BAD_MATCH: + LOGI("gl-->::CreateGlesEnv Check window and EGLConfig attributes"); + break; + } + } + + // 创建渲染上下文 EGLContext + m_eglCtx = eglCreateContext(m_eglDisplay, m_eglConf, EGL_NO_CONTEXT, ctxAttr); + if (m_eglCtx == EGL_NO_CONTEXT) + { + EGLint error = eglGetError(); + if (error == EGL_BAD_CONFIG) + { + LOGI("gl-->::CreateGlesEnv EGL_BAD_CONFIG"); + resultCode = -1; + break; + } + } + + //绑定上下文 + if(!eglMakeCurrent(m_eglDisplay, m_eglSurface, m_eglSurface, m_eglCtx)) + { + resultCode = -1; + break; + } + LOGI("gl-->::CreateGlesEnv initialize success"); + } while (false); + + if(resultCode != 0) + { + LOGI("gl-->::CreateGlesEnv fail"); + } + + return resultCode; +} + +void EGLRender::SetImageData(uint8_t *pData, int width, int height) { + if (pData && m_IsGLContextReady) + { + if (m_RenderImage.ppPlane[0]) + { + NativeImageUtil::FreeNativeImage(&m_RenderImage); + m_RenderImage.ppPlane[0] = nullptr; + } + m_RenderImage.width = width; + m_RenderImage.height = height; + m_RenderImage.format = IMAGE_FORMAT_RGBA; + NativeImageUtil::AllocNativeImage(&m_RenderImage); + memcpy(m_RenderImage.ppPlane[0], pData, width * height *4); + + glBindTexture(GL_TEXTURE_2D, m_ImageTextureId); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_RenderImage.width, m_RenderImage.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, m_RenderImage.ppPlane[0]); + glBindTexture(GL_TEXTURE_2D, GL_NONE); + + if (m_FboId == GL_NONE) + { + // Create FBO + glGenFramebuffers(1, &m_FboId); + glBindFramebuffer(GL_FRAMEBUFFER, m_FboId); + glBindTexture(GL_TEXTURE_2D, m_FboTextureId); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_FboTextureId, 0); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_RenderImage.width, m_RenderImage.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); + if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { + LOGI("gl--> EGLRender ::SetImageData glCheckFramebufferStatus status != GL_FRAMEBUFFER_COMPLETE"); + } + glBindTexture(GL_TEXTURE_2D, GL_NONE); + glBindFramebuffer(GL_FRAMEBUFFER, GL_NONE); + } + LOGI("gl--> :: SetImageData end"); + } +} + +void EGLRender::SetIntParams(int paramType, int param) { + LOGI("gl--> EGLRender::SetIntParams paramType = %{public}d,param = %{public}d", paramType, param); + switch(paramType) + { + case PARAM_TYPE_SHADER_INDEX: + { + if (param >= 0) + { + if (m_ProgramObj) + { + glDeleteProgram(m_ProgramObj); + m_ProgramObj = GL_NONE; + } + const char* vShader[1]; + vShader[0] = vShaderStr; + const char* fShader[1]; + switch(param) + { + case 4: + { + fShader[0] = fShaderStr3; + break; + } + case 7: + { + fShader[0] = swirlFShaderStr; + break; + } + case 0: + { + fShader[0] = brightFShaderStr; + break; + } + case 1: + { + fShader[0] = contrastFShaderStr; + break; + } + case 2: + { + fShader[0] = invertFShaderStr; + break; + } + case 3: + { + fShader[0] = pixelFShaderStr; + break; + } + case 5: + { + fShader[0] = colorMatrixFShaderStr; + break; + } + case 6: + { + fShader[0] = sketchShaderStr; + vShader[0] = v3x3ShaderStr; + break; + } + case 8: + { + fShader[0] = toonFShaderStr; + vShader[0] = v3x3ShaderStr; + break; + } + case 9: + { + fShader[0] = vignetteFShaderStr; + break; + } + case 10: + { + fShader[0] = grayScaleShaderStr; + break; + } + case 12: + { + fShader[0] = blurShaderStr; + break; + } + } + + m_ProgramObj = GLUtils::CreateProgram(vShader[0], fShader[0], m_VertexShader, + m_FragmentShader); + if (!m_ProgramObj) + { + GLUtils::CheckGLError("Create Program"); + LOGI("gl--> EGLRender::SetIntParams Could not create program."); + return; + } + + m_SamplerLoc = glGetUniformLocation(m_ProgramObj, "s_TextureMap"); + m_TexSizeLoc = glGetUniformLocation(m_ProgramObj, "u_texSize"); + } + } + break; + default: + break; + } +} + +void EGLRender::UseProgram() { + if (m_ProgramObj == GL_NONE) return; + glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + glClear(GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glViewport(0, 0, m_RenderImage.width, m_RenderImage.height); + + //DO FBO off screen rendering + glUseProgram(m_ProgramObj); + glBindFramebuffer(GL_FRAMEBUFFER, m_FboId); + + glBindVertexArray(m_VaoIds[0]); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, m_ImageTextureId); + glUniform1i(m_SamplerLoc, 0); + + if (m_TexSizeLoc > -1) { + GLfloat size[2]; + size[0] = m_RenderImage.width; + size[1] = m_RenderImage.height; + glUniform2f(m_TexSizeLoc, size[0], size[1]); + } +} + +void EGLRender::GlUniform(char* strLocation, float value, int unType) { + GLint location = glGetUniformLocation(m_ProgramObj, strLocation); + switch(unType) + { + case 0: + glUniform1i(location, (int)value); + break; + case 1: + glUniform1f(location, value); + break; + } +} + +void EGLRender::GlUniformArray(char* strLocation, float* value, int unType) { + GLint location = glGetUniformLocation(m_ProgramObj, strLocation); + switch(unType) + { + case 10: + GLfloat vec2[2]; + vec2[0] = value[0] * m_RenderImage.width; + vec2[1] = value[1] * m_RenderImage.height; + glUniform2fv(location, 1, vec2); + break; + case 21: + glUniform2f(location, value[0], value[1]); + break; + case 1: + glUniform1fv(location, 1, value); + break; + case 2: + glUniform2fv(location, 1, value); + break; + case 3: + glUniform3fv(location, 1, value); + break; + case 4: + glUniform4fv(location, 1, value); + break; + } +} + +void EGLRender::GlUniformMatrix(char* strLocation, float* value, int unType) { + GLint location = glGetUniformLocation(m_ProgramObj, strLocation); + switch(unType) + { + case 3: + glUniformMatrix3fv(location, 1, false,value); + break; + case 4: + glUniformMatrix4fv(location, 1, false, value); + break; + } +} + +void EGLRender::UnInit() { + if (m_ProgramObj) + { + glDeleteProgram(m_ProgramObj); + m_ProgramObj = GL_NONE; + } + + if(m_ImageTextureId) + { + glDeleteTextures(1, &m_ImageTextureId); + m_ImageTextureId = GL_NONE; + } + + if (m_FboTextureId) + { + glDeleteTextures(1, &m_FboTextureId); + m_FboTextureId = GL_NONE; + } + + if (m_VboIds[0]) + { + glDeleteBuffers(3, m_VboIds); + m_VboIds[0] = GL_NONE; + m_VboIds[1] = GL_NONE; + m_VboIds[2] = GL_NONE; + } + + if (m_VaoIds[0]) + { + glDeleteVertexArrays(1, m_VaoIds); + m_VaoIds[0] = GL_NONE; + } + + if (m_FboId) + { + glDeleteFramebuffers(1, &m_FboId); + m_FboId = GL_NONE; + } + if (m_IsGLContextReady) + { + DestroyGl(); + m_IsGLContextReady = false; + } +} +void EGLRender::DestroyGl() { + //释放 EGL 环境 + if (m_eglDisplay != EGL_NO_DISPLAY) { + eglMakeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); + eglDestroyContext(m_eglDisplay, m_eglCtx); + eglDestroySurface(m_eglDisplay, m_eglSurface); + eglReleaseThread(); + eglTerminate(m_eglDisplay); + } + + m_eglDisplay = EGL_NO_DISPLAY; + m_eglSurface = EGL_NO_SURFACE; + m_eglCtx = EGL_NO_CONTEXT; +} diff --git a/gpu_transform/src/main/cpp/render/EGLRender.h b/gpu_transform/src/main/cpp/render/EGLRender.h new file mode 100644 index 0000000..07ae4d5 --- /dev/null +++ b/gpu_transform/src/main/cpp/render/EGLRender.h @@ -0,0 +1,120 @@ +/* + * 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. + */ + +// +// 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 +#include +#include +#include +#include +#include +#include "NativeImage.h" + +#define EGL_FEATURE_NUM 7 + +class EGLRender { + + public: + EGLRender(); + ~EGLRender(); + + static EGLRender* GetInstance() { + if(sInstance == nullptr) { + sInstance = new EGLRender(); + } + return sInstance; + } + + static void DestroyRender() { + if(sInstance) { + delete sInstance; + sInstance = nullptr; + } + } + 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); + static napi_value RenderSetIntParams(napi_env env, napi_callback_info info); + static napi_value EGLIsInit(napi_env env, napi_callback_info info); + + static napi_value DestroyGlesEnv(napi_env env, napi_callback_info info); + + static napi_value StartUseProgram(napi_env env, napi_callback_info info); + + static napi_value Rendering(napi_env env, napi_callback_info info); + + + static napi_value RenderGlUniform1i(napi_env env, napi_callback_info info); + static napi_value RenderGlUniform1f(napi_env env, napi_callback_info info); + static napi_value RenderGlUniform2fv(napi_env env, napi_callback_info info); + static napi_value setTypeArrayOfFloat(napi_env env, napi_callback_info info); + + static napi_value setTypeArrayOfMatrix3f(napi_env env, napi_callback_info info); + static napi_value setTypeArrayOfMatrix4f(napi_env env, napi_callback_info info); + + void Init(); + + int CreateGlEnv(); + + void SetImageData(uint8_t *pData, int width, int height); + + void SetIntParams(int paramType, int param); + + void UseProgram(); + + void Draw(); + + void GlUniform(char* location, float value, int unType); + void GlUniformArray(char* location, float* value, int unType); + + void GlUniformMatrix(char* location, float* value, int unType); + + void DestroyGl(); + + void UnInit(); + + private: + static EGLRender* sInstance; + GLuint m_ImageTextureId; + GLuint m_FboTextureId; + GLuint m_FboId; + GLuint m_VaoIds[1] = {GL_NONE}; + GLuint m_VboIds[3] = {GL_NONE}; + GLint m_SamplerLoc; + GLint m_TexSizeLoc; + + NativeImage m_RenderImage; + GLuint m_ProgramObj; + GLuint m_VertexShader; + GLuint m_FragmentShader; + + EGLConfig m_eglConf; + EGLSurface m_eglSurface; + EGLContext m_eglCtx; + EGLDisplay m_eglDisplay; + bool m_IsGLContextReady; + const char* m_fShaderStrs[EGL_FEATURE_NUM]; + int m_ShaderIndex; + + +}; + +#endif //GPU_ImageETS_EGLRender_H diff --git a/gpu_transform/src/main/cpp/types/libentry/index.d.ts b/gpu_transform/src/main/cpp/types/libentry/index.d.ts new file mode 100644 index 0000000..f7314d0 --- /dev/null +++ b/gpu_transform/src/main/cpp/types/libentry/index.d.ts @@ -0,0 +1,16 @@ +/* + * 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 const add: (a: number, b: number) => number; \ No newline at end of file diff --git a/gpu_transform/src/main/cpp/types/libentry/package.json b/gpu_transform/src/main/cpp/types/libentry/package.json new file mode 100644 index 0000000..cf40ccb --- /dev/null +++ b/gpu_transform/src/main/cpp/types/libentry/package.json @@ -0,0 +1,4 @@ +{ + "name": "libentry.so", + "types": "./index.d.ts" +} \ No newline at end of file diff --git a/gpu_transform/src/main/cpp/util/DebugLog.h b/gpu_transform/src/main/cpp/util/DebugLog.h new file mode 100644 index 0000000..5ab3f74 --- /dev/null +++ b/gpu_transform/src/main/cpp/util/DebugLog.h @@ -0,0 +1,32 @@ +/* + * 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. + */ + +// +// 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 + +#include + +#define LOGI(...)((void)OH_LOG_Print(LOG_APP, LOG_INFO, LOG_DOMAIN, "OH_GPU_LOG", __VA_ARGS__)) +#define LOGD(...)((void)OH_LOG_Print(LOG_APP, LOG_DEBUG, LOG_DOMAIN, "OH_GPU_LOG", __VA_ARGS__)) +#define LOGW(...)((void)OH_LOG_Print(LOG_APP, LOG_WARN, LOG_DOMAIN, "OH_GPU_LOG", __VA_ARGS__)) +#define LOGE(...)((void)OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_DOMAIN, "OH_GPU_LOG", __VA_ARGS__)) + +#endif //GPU_ImageETS_DebugLog_H diff --git a/gpu_transform/src/main/cpp/util/GLUtils.cpp b/gpu_transform/src/main/cpp/util/GLUtils.cpp new file mode 100644 index 0000000..8e0c2b3 --- /dev/null +++ b/gpu_transform/src/main/cpp/util/GLUtils.cpp @@ -0,0 +1,109 @@ +/* + * 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. + */ + +// +// 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 "GLUtils.h" +#include "DebugLog.h" +#include +#include + +GLuint GLUtils::LoadShader(GLenum shaderType, const char *pSource) +{ + GLuint shader = 0; + shader = glCreateShader(shaderType); + if (shader) + { + glShaderSource(shader, 1, &pSource, NULL); + glCompileShader(shader); + GLint compiled = 0; + glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled); + if (!compiled) { + GLint infoLen = 0; + glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen); + if (infoLen) + { + char* buf = (char*) malloc((size_t)infoLen); + if (buf) + { + glGetShaderInfoLog(shader, infoLen, NULL, buf); + free(buf); + } + glDeleteShader(shader); + shader = 0; + } + } + } + return shader; +} + +GLuint GLUtils::CreateProgram(const char *pVertexShaderSource, const char *pFragShaderSource, GLuint &vertexShaderHandle, GLuint &fragShaderHandle) +{ + GLuint program = 0; + vertexShaderHandle = LoadShader(GL_VERTEX_SHADER, pVertexShaderSource); + if (!vertexShaderHandle) return program; + fragShaderHandle = LoadShader(GL_FRAGMENT_SHADER, pFragShaderSource); + if (!fragShaderHandle) return program; + + program = glCreateProgram(); + if(program) + { + glAttachShader(program, vertexShaderHandle); + CheckGLError("glAttachShader"); + glAttachShader(program, fragShaderHandle); + CheckGLError("glAttachShader"); + glLinkProgram(program); + GLint linkStatus = GL_FALSE; + glGetProgramiv(program, GL_LINK_STATUS, &linkStatus); + + glDetachShader(program, vertexShaderHandle); + glDeleteShader(vertexShaderHandle); + vertexShaderHandle = 0; + glDetachShader(program, fragShaderHandle); + glDeleteShader(fragShaderHandle); + fragShaderHandle = 0; + + if(linkStatus != GL_TRUE) + { + GLint bufLength = 0; + glGetProgramiv(program,GL_INFO_LOG_LENGTH, &bufLength); + if (bufLength) + { + char* buf = (char*) malloc((size_t)bufLength); + if (buf) + { + glGetProgramInfoLog(program, bufLength, NULL, buf); + free(buf); + } + } + glDeleteProgram(program); + program = 0; + } + } + return program; +} + +void GLUtils::CheckGLError(const char *pGLOperation) +{ + for(GLint error = glGetError(); error; error = glGetError()) + { + LOGI("GLUtils::CheckGLError GL Operation %{public}s() glError (0x%x)\n", pGLOperation, error); + + } +} diff --git a/gpu_transform/src/main/cpp/util/GLUtils.h b/gpu_transform/src/main/cpp/util/GLUtils.h new file mode 100644 index 0000000..3dccdfa --- /dev/null +++ b/gpu_transform/src/main/cpp/util/GLUtils.h @@ -0,0 +1,37 @@ +/* + * 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. + */ + +// +// 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 + +#include + +class GLUtils { + public: + static GLuint LoadShader(GLenum shaderType, const char *pSource); + static GLuint CreateProgram(const char *pVertexShaderSource, const char *pFragShaderSource, + GLuint &vertexShaderHandle, + GLuint &fragShaderHandle); + static GLuint CreateProgram(const char *pVertexShaderSource, const char *pFragShaderSource); + static void CheckGLError(const char *pGLOperation); +}; + +#endif //GPU_ImageETS_GLUtils_H diff --git a/gpu_transform/src/main/cpp/util/NapiUtil.cpp b/gpu_transform/src/main/cpp/util/NapiUtil.cpp new file mode 100644 index 0000000..30df64b --- /dev/null +++ b/gpu_transform/src/main/cpp/util/NapiUtil.cpp @@ -0,0 +1,49 @@ +/* + * 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. + */ + +// +// 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" +#include "DebugLog.h" +#include +#include +#include +#include +#include + +const int32_t MAX_STR_LENGTH = 1024; + +void NapiUtil::JsValueToString(const napi_env &env, const napi_value &value, const int32_t bufLen, std::string &target) +{ + if (bufLen <= 0 || bufLen > MAX_STR_LENGTH) { + LOGI("%s string too long malloc failed",__func__); + return; + } + + std::unique_ptr buf = std::make_unique (bufLen); + if (buf.get() == nullptr) + { + LOGI("%s nullptr js object to string malloc failed",__func__); + return; + } + (void) memset(buf.get(), 0, bufLen); + size_t result = 0; + napi_get_value_string_utf8(env, value, buf.get(), bufLen, &result); + target = buf.get(); +} \ No newline at end of file diff --git a/gpu_transform/src/main/cpp/util/NapiUtil.h b/gpu_transform/src/main/cpp/util/NapiUtil.h new file mode 100644 index 0000000..34c02fd --- /dev/null +++ b/gpu_transform/src/main/cpp/util/NapiUtil.h @@ -0,0 +1,35 @@ +/* + * 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. + */ + +// +// 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 + +#include +#include +#include "native_common.h" + +class NapiUtil { + public: + static void JsValueToString(const napi_env &env, const napi_value &value, const int32_t bufLen, + std::string &target); +}; + +#endif //GPU_ImageETS_NapiUtil_H diff --git a/gpu_transform/src/main/cpp/util/NativeImage.h b/gpu_transform/src/main/cpp/util/NativeImage.h new file mode 100644 index 0000000..f15b367 --- /dev/null +++ b/gpu_transform/src/main/cpp/util/NativeImage.h @@ -0,0 +1,162 @@ +/* + * 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. + */ + +// +// 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 + +#include +#include +#include +#include +#include +#include +#include "DebugLog.h" +#include + +#define IMAGE_FORMAT_RGBA 0x01 +#define IMAGE_FORMAT_NV21 0x02 +#define IMAGE_FORMAT_NV12 0x03 +#define IMAGE_FORMAT_I420 0x04 +#define IMAGE_FORMAT_YUYV 0x05 +#define IMAGE_FORMAT_GRAY 0x06 +#define IMAGE_FORMAT_I444 0x07 +#define IMAGE_FORMAT_P010 0x08 + +#define IMAGE_FORMAT_RGBA_EXT "RGB32" +#define IMAGE_FORMAT_NV21_EXT "NV21" +#define IMAGE_FORMAT_NV12_EXT "NV12" +#define IMAGE_FORMAT_I420_EXT "I420" +#define IMAGE_FORMAT_YUYV_EXT "YUYV" +#define IMAGE_FORMAT_GRAY_EXT "GRAY" +#define IMAGE_FORMAT_I444_EXT "I444" +#define IMAGE_FORMAT_P010_EXT "P010" // 16bit NV21 + + +struct NativeImage +{ + int width; + int height; + int format; + uint8_t *ppPlane[3]; + + NativeImage() + { + width = 0; + height = 0; + format = 0; + ppPlane[0] = nullptr; + ppPlane[1] = nullptr; + ppPlane[2] = nullptr; + } +}; + +class NativeImageUtil +{ + public: + static void AllocNativeImage(NativeImage *pImage) + { + if (pImage ->height ==0 || pImage ->width == 0) return; + switch(pImage -> format) + { + case IMAGE_FORMAT_RGBA: + { + pImage->ppPlane[0] = static_cast(malloc(pImage->width * pImage ->height * 4)); + } + break; + case IMAGE_FORMAT_YUYV: + { + pImage->ppPlane[0] = static_cast(malloc(pImage->width * pImage ->height * 2)); + } + break; + case IMAGE_FORMAT_NV12: + case IMAGE_FORMAT_NV21: + { + pImage->ppPlane[0] = static_cast(malloc(pImage->width * pImage ->height * 1.5)); + pImage->ppPlane[1] = pImage->ppPlane[0] + pImage->width * pImage->height; + } + break; + case IMAGE_FORMAT_I420: + { + pImage->ppPlane[0] = static_cast(malloc(pImage->width * pImage ->height * 1.5)); + pImage->ppPlane[1] = pImage->ppPlane[0] + pImage->width * pImage->height; + pImage->ppPlane[2] = pImage->ppPlane[1] + pImage->width * (pImage->height >> 2); + } + break; + case IMAGE_FORMAT_GRAY: + { + pImage->ppPlane[0] = static_cast(malloc(pImage->width * pImage ->height)); + } + break; + case IMAGE_FORMAT_I444: + { + pImage->ppPlane[0] = static_cast(malloc(pImage->width * pImage ->height * 3)); + } + break; + case IMAGE_FORMAT_P010: + { + pImage->ppPlane[0] = static_cast(malloc(pImage->width * pImage ->height * 3)); + pImage->ppPlane[1] = pImage->ppPlane[0] + pImage->width * pImage->height * 2; + } + break; + default: + break; + } + } + + static void FreeNativeImage(NativeImage *pImage) + { + if (pImage == nullptr || pImage->ppPlane[0] == nullptr) return; + free(pImage->ppPlane[0]); + pImage->ppPlane[0] = nullptr; + pImage->ppPlane[1] = nullptr; + pImage->ppPlane[2] = nullptr; + } + + static bool CreateArrayBuffer(napi_env env, void* src, size_t srcLen, napi_value *res) + { + if (src == nullptr || srcLen == 0) + { + return false; + } + void *nativePtr = nullptr; + if (napi_create_arraybuffer(env, srcLen, &nativePtr, res) != napi_ok || nativePtr == nullptr) + { + return false; + } + memcpy(nativePtr, src, srcLen); + return true; + } + + static void flip(uint8_t** buf, int width, int height) + { + int totalLength = width * height * 4; + int oneLineLength = width * 4; + uint8_t* tmp = (uint8_t*)malloc(totalLength); + memcpy(tmp, *buf, totalLength); + memset(*buf, 0, sizeof(uint8_t)*totalLength); + for(int i = 0; i < height; i++) { + memcpy(*buf + oneLineLength * i, tmp + totalLength - oneLineLength * (i+1), oneLineLength); + } + free(tmp); + } +}; + +#endif //GPU_ImageETS_NativeImage_H diff --git a/gpu_transform/src/main/ets/gpu/filter/GPUImage3x3TextureSamplingFilter.ts b/gpu_transform/src/main/ets/gpu/filter/GPUImage3x3TextureSamplingFilter.ts new file mode 100644 index 0000000..8719877 --- /dev/null +++ b/gpu_transform/src/main/ets/gpu/filter/GPUImage3x3TextureSamplingFilter.ts @@ -0,0 +1,51 @@ +/* + * 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 {GPUImageFilter} from './GPUImageFilter' +import {GPUFilterType} from '../gl/GPUFilterType' + +export class GPUImage3x3TextureSamplingFilter extends GPUImageFilter{ + private texelWidth:number; + private texelHeight:number; + private lineSize:number = 1.0; + + constructor(){ + super(); + } + + getFilterType():GPUFilterType{ + return GPUFilterType.X3TEXTURE; + } + + onInitialized(){ + + } + onReadySize(){ + + } + setLineSize(lineSize:number){ + this.lineSize = lineSize; + } + + 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); + } +} \ No newline at end of file diff --git a/gpu_transform/src/main/ets/gpu/filter/GPUImageBlurFilter.ts b/gpu_transform/src/main/ets/gpu/filter/GPUImageBlurFilter.ts new file mode 100644 index 0000000..8ca86c1 --- /dev/null +++ b/gpu_transform/src/main/ets/gpu/filter/GPUImageBlurFilter.ts @@ -0,0 +1,81 @@ +/* + * 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 {GPUImageFilter} from './GPUImageFilter' +import {GPUFilterType} from '../gl/GPUFilterType' + +export class GPUImageBlurFilter extends GPUImageFilter{ + private blurRadius:number; + private blurOffset:Array; + private sumWeight:number; + + constructor(){ + super(); + } + + getFilterType():GPUFilterType{ + return GPUFilterType.BLUR; + } + + onInitialized(){ + + } + onReadySize(){ + + } + + setBlurRadius(blurRadius:number){ + this.blurRadius = blurRadius; + this.setInteger("blurRadius",this.blurRadius); + this.calculateSumWeight(); + } + + setBlurOffset(blurOffset:Array){ + let offset = new Array(2); + + if (this.width<=0||this.height<=0) { + throw new Error("the width or height must be greater than 0"); + } + if (!blurOffset || blurOffset.length!==2) { + throw new Error("you should a valid value needs to be set.") + } + offset[0] = blurOffset[0]/this.width; + offset[1] = blurOffset[1] / this.height; + this.blurOffset = offset; + this.setFloat2f("blurOffset",this.blurOffset); + } + + setSumWeight(sumWeight:number){ + this.sumWeight = sumWeight; + this .setFloat("sumWeight",this.sumWeight); + } + + private calculateSumWeight(){ + if (this.blurRadius < 1) { + this.setSumWeight(0); + return; + } + 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))); + sumWeight += weight; + if (i != 0) { + sumWeight +=weight; + } + } + this.setSumWeight(sumWeight); + } +} \ No newline at end of file diff --git a/gpu_transform/src/main/ets/gpu/filter/GPUImageBrightnessFilter.ts b/gpu_transform/src/main/ets/gpu/filter/GPUImageBrightnessFilter.ts new file mode 100644 index 0000000..0e41c2a --- /dev/null +++ b/gpu_transform/src/main/ets/gpu/filter/GPUImageBrightnessFilter.ts @@ -0,0 +1,44 @@ +/* + * 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 {GPUImageFilter} from './GPUImageFilter' +import {GPUFilterType} from '../gl/GPUFilterType' + +export class GPUImageBrightnessFilter extends GPUImageFilter{ + private brightness:number = 25 + + constructor(brightness?:number){ + super() + if (brightness) { + this.brightness =brightness; + } + } + + getFilterType():GPUFilterType{ + return GPUFilterType.BRIGHT; + } + + onInitialized(){ + + } + onReadySize(){ + + } + + setBrightness(brightness:number){ + this.brightness = brightness; + this.setFloat("brightness",this.brightness); + } +} \ No newline at end of file diff --git a/gpu_transform/src/main/ets/gpu/filter/GPUImageColorInvertFilter.ts b/gpu_transform/src/main/ets/gpu/filter/GPUImageColorInvertFilter.ts new file mode 100644 index 0000000..d7251e7 --- /dev/null +++ b/gpu_transform/src/main/ets/gpu/filter/GPUImageColorInvertFilter.ts @@ -0,0 +1,37 @@ +/* + * 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 {GPUImageFilter} from './GPUImageFilter' +import {GPUFilterType} from '../gl/GPUFilterType' + +export class GPUImageColorInvertFilter extends GPUImageFilter{ + + + constructor(){ + super() + + } + + getFilterType():GPUFilterType{ + return GPUFilterType.INVERT; + } + + onInitialized(){ + + } + onReadySize(){ + + } +} \ No newline at end of file diff --git a/gpu_transform/src/main/ets/gpu/filter/GPUImageColorMatrixFilter.ts b/gpu_transform/src/main/ets/gpu/filter/GPUImageColorMatrixFilter.ts new file mode 100644 index 0000000..fb520ce --- /dev/null +++ b/gpu_transform/src/main/ets/gpu/filter/GPUImageColorMatrixFilter.ts @@ -0,0 +1,57 @@ +/* + * 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 {GPUImageFilter} from './GPUImageFilter' +import {GPUFilterType} from '../gl/GPUFilterType' + +export class GPUImageColorMatrixFilter extends GPUImageFilter{ + + private intensity :number = 1.0; + private colorMatrix:Array = [ + 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){ + super() + if (intensity) { + this.intensity = intensity; + } + } + + getFilterType():GPUFilterType{ + return GPUFilterType.CONTRAST; + } + + onInitialized(){ + + } + onReadySize(){ + + } + + setIntensity(intensity:number){ + this.intensity = intensity; + this.setFloat("intensity",this.intensity); + } + + setColorMatrix(colorMatrix:Array){ + this.colorMatrix = colorMatrix; + this.setUniformMatrix4f("colorMatrix",this.colorMatrix); + } +} \ No newline at end of file diff --git a/gpu_transform/src/main/ets/gpu/filter/GPUImageContrastFilter.ts b/gpu_transform/src/main/ets/gpu/filter/GPUImageContrastFilter.ts new file mode 100644 index 0000000..a14fc3e --- /dev/null +++ b/gpu_transform/src/main/ets/gpu/filter/GPUImageContrastFilter.ts @@ -0,0 +1,46 @@ +/* + * 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 {GPUImageFilter} from './GPUImageFilter' +import {GPUFilterType} from '../gl/GPUFilterType' + +export class GPUImageContrastFilter extends GPUImageFilter{ + + private contrast :number = 1.0; + + + constructor(contrast?:number){ + super() + if (contrast) { + this.contrast = contrast; + } + } + + getFilterType():GPUFilterType{ + return GPUFilterType.CONTRAST; + } + + onInitialized(){ + + } + onReadySize(){ + + } + + setContrast(contrast:number){ + this.contrast = contrast; + this.setFloat("contrast",this.contrast); + } +} \ No newline at end of file diff --git a/gpu_transform/src/main/ets/gpu/filter/GPUImageFilter.ts b/gpu_transform/src/main/ets/gpu/filter/GPUImageFilter.ts new file mode 100644 index 0000000..23adf93 --- /dev/null +++ b/gpu_transform/src/main/ets/gpu/filter/GPUImageFilter.ts @@ -0,0 +1,331 @@ +/* + * 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 {NativeEglRender} from '../gl/NativeEglRender' +import {GPUFilterType} from '../gl/GPUFilterType' +import {Runnable} from '../interface/Runnable' + +import image from '@ohos.multimedia.image'; +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; + protected width:number; + protected height:number; + + constructor(){ + this.render = new NativeEglRender(); + this.runOnDraw = new LinkedList(); + } + + 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; + } + if (!this.render.native_glIsInit()) { + throw new Error("the egl surface not init"); + } + this.render.native_EglRenderSetIntParams(300,filterType); + } + + setImageData(buf:ArrayBuffer,width:number,height:number){ + if (!buf) { + throw new Error("this pixelMap data is empty"); + } + if (width <= 0 || height <= 0) { + throw new Error("this pixelMap width and height is invalidation") + } + this.width = width; + this.height = height; + this.ifNeedInit(); + this.onReadySize(); + this.setSurfaceFilterType(); + this.render.native_EglRenderSetImageData(buf,width,height); + + } + + + protected onDraw(){ + if (!this.render.native_glIsInit()) { + throw new Error("the egl surface not init") + } + this.render.native_EglUseProgram(); + this.runPendingOnDrawTasks(); + this.onRendering(); + } + + protected onRendering(){ + this.render.native_EglRendering(); + } + + getPixelMapBuf(x:number,y:number,width:number,height:number):Promise{ + if (x<0||y<0) { + throw new Error("the x or y should be greater than 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)=>{ + that.onDraw(); + let buf = this .render.native_EglBitmapFromGLSurface(x,y,width,height); + if (!buf) { + rejects(new Error("get pixelMap fail")) + }else{ + resolve(buf); + that.destroy(); + } + }) + } + + + ifNeedInit(){ + if (this.render) { + this.isInitialized = this.render.native_glIsInit(); + if (!this.isInitialized) { + this.init(); + } + } + } + + protected runPendingOnDrawTasks(){ + while(this.runOnDraw.length>0){ + this.runOnDraw.removeFirst().run(); + } + } + + protected addRunOnDraw(runAble:Runnable){ + if (!runAble) { + return; + } + this.runOnDraw.add(runAble); + } + + protected setInteger(location:string,value:number){ + let that = this; + let able:Runnable = { + run(){ + that.ifNeedInit(); + that.render.native_setInteger(location,value); + } + } + this.addRunOnDraw(able); + } + + protected setFloat(location:string,value:number){ + let that = this; + let able:Runnable = { + run(){ + that.ifNeedInit(); + that.render.native_setFloat(location,value); + } + } + this.addRunOnDraw(able); + } + + + protected setPoint(location:string,vf1:number,vf2:number){ + + let that = this; + let able:Runnable = { + run(){ + that.ifNeedInit(); + that.render.native_setPoint(location,vf1,vf2); + } + } + this.addRunOnDraw(able); + } + + + protected setFloat2f(location:string,value:Array){ + if (value.length !==2) { + return; + } + let that = this; + let able:Runnable = { + run(){ + that.ifNeedInit(); + let array = new Float32Array(2); + array[0] = value[0]; + array[1] = value[1]; + that.render.native_setFloat2f(location,array); + } + } + this.addRunOnDraw(able); + } + + protected setFloatVec2(location:string,value:Array){ + if (value.length !==2) { + return; + } + let that = this; + let able:Runnable = { + run(){ + that.ifNeedInit(); + let array = new Float32Array(2); + array[0] = value[0]; + array[1] = value[1]; + that.render.native_setFloatVec2(location,array); + } + } + this.addRunOnDraw(able); + } + + protected setFloatVec3(location:string,value:Array){ + if (value.length !==3) { + return; + } + let that = this; + let able:Runnable = { + run(){ + that.ifNeedInit(); + let array = new Float32Array(3); + array[0] = value[0]; + array[1] = value[1]; + array[2] = value[2]; + that.render.native_setFloatVec3(location,array); + } + } + this.addRunOnDraw(able); + } + + + protected setFloatVec4(location:string,value:Array){ + if (value.length !==4) { + return; + } + let that = this; + let able:Runnable = { + run(){ + that.ifNeedInit(); + 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); + } + } + this.addRunOnDraw(able); + } + + + protected setUniformMatrix3f(location:string,value:Array){ + if (!value) { + return; + } + let that = this; + let able:Runnable = { + run(){ + that.ifNeedInit(); + let array = new Float32Array(value.length); + for (let i = 0; i < value.length; i++) { + array[i] = value[i]; + + } + that.render.native_setUniformMatrix3f(location,array); + } + } + this.addRunOnDraw(able); + } + + protected setUniformMatrix4f(location:string,value:Array){ + if (!value) { + return; + } + let that = this; + let able:Runnable = { + run(){ + that.ifNeedInit(); + let array = new Float32Array(value.length); + for (let i = 0; i < value.length; i++) { + array[i] = value[i]; + + } + that.render.native_setUniformMatrix4f(location,array); + } + } + this.addRunOnDraw(able); + } + + getFilters():ArrayList{ + return null; + } + + destroy(){ + this.render.native_glIsDestroy(); + this.render = null; + this.isInitialized = false; + } + + + abstract getFilterType():GPUFilterType; + abstract onReadySize(); + abstract onInitialized(); +} \ No newline at end of file diff --git a/gpu_transform/src/main/ets/gpu/filter/GPUImageFilterGroup.ts b/gpu_transform/src/main/ets/gpu/filter/GPUImageFilterGroup.ts new file mode 100644 index 0000000..1c10cbe --- /dev/null +++ b/gpu_transform/src/main/ets/gpu/filter/GPUImageFilterGroup.ts @@ -0,0 +1,38 @@ +/* + * 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 {GPUImageFilter} from './GPUImageFilter' +import {GPUFilterType} from '../gl/GPUFilterType' +import ArrayList from '@ohos.util.ArrayList'; + +export abstract class GPUImageFilterGroup extends GPUImageFilter{ + + private filters :ArrayList; + + + constructor(){ + super() + this.filters = new ArrayList(); + } + + addFilter(aFilter:GPUImageFilter){ + this.filters.add(aFilter); + } + + getFilters():ArrayList{ + return this.filters; + } +} + diff --git a/gpu_transform/src/main/ets/gpu/filter/GPUImageGrayscaleFilter.ts b/gpu_transform/src/main/ets/gpu/filter/GPUImageGrayscaleFilter.ts new file mode 100644 index 0000000..6d87b4f --- /dev/null +++ b/gpu_transform/src/main/ets/gpu/filter/GPUImageGrayscaleFilter.ts @@ -0,0 +1,36 @@ +/* + * 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 {GPUImageFilter} from './GPUImageFilter' +import {GPUFilterType} from '../gl/GPUFilterType' + +export class GPUImageGrayscaleFilter extends GPUImageFilter{ + constructor(){ + super() + + } + + getFilterType():GPUFilterType{ + return GPUFilterType.GRAYSCALE; + } + + onInitialized(){ + + } + onReadySize(){ + + } +} + diff --git a/gpu_transform/src/main/ets/gpu/filter/GPUImageKuwaharaFilter.ts b/gpu_transform/src/main/ets/gpu/filter/GPUImageKuwaharaFilter.ts new file mode 100644 index 0000000..c25a181 --- /dev/null +++ b/gpu_transform/src/main/ets/gpu/filter/GPUImageKuwaharaFilter.ts @@ -0,0 +1,45 @@ +/* + * 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 {GPUImageFilter} from './GPUImageFilter' +import {GPUFilterType} from '../gl/GPUFilterType' + +export class GPUImageKuwaharaFilter extends GPUImageFilter{ + private _radius :number = 25; + constructor(radius?:number){ + super() + if (radius) { + this._radius= radius; + } + + } + + getFilterType():GPUFilterType{ + return GPUFilterType.KUWAHARA; + } + + onInitialized(){ + + } + onReadySize(){ + + } + + setRadius(radius:number){ + this._radius = radius; + this.setFloat("radius",this._radius); + } +} + diff --git a/gpu_transform/src/main/ets/gpu/filter/GPUImagePixelationFilter.ts b/gpu_transform/src/main/ets/gpu/filter/GPUImagePixelationFilter.ts new file mode 100644 index 0000000..36f4098 --- /dev/null +++ b/gpu_transform/src/main/ets/gpu/filter/GPUImagePixelationFilter.ts @@ -0,0 +1,43 @@ +/* + * 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 {GPUImageFilter} from './GPUImageFilter' +import {GPUFilterType} from '../gl/GPUFilterType' + +export class GPUImagePixelationFilter extends GPUImageFilter{ + private pixel :number = 1.0; + constructor(){ + super() + } + + getFilterType():GPUFilterType{ + return GPUFilterType.PIXELATION; + } + + onInitialized(){ + + } + 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); + } +} + diff --git a/gpu_transform/src/main/ets/gpu/filter/GPUImageSepiaToneFilter.ts b/gpu_transform/src/main/ets/gpu/filter/GPUImageSepiaToneFilter.ts new file mode 100644 index 0000000..9380270 --- /dev/null +++ b/gpu_transform/src/main/ets/gpu/filter/GPUImageSepiaToneFilter.ts @@ -0,0 +1,40 @@ +/* + * 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 { GPUImageColorMatrixFilter } from './GPUImageColorMatrixFilter' +import { GPUFilterType } from '../gl/GPUFilterType' + +export class GPUImageSepiaToneFilter extends GPUImageColorMatrixFilter { + constructor(intensity?: number) { + super() + this.setIntensity(intensity ? intensity : 1.0); + this.setColorMatrix([ + 0.3588, 0.7044, 0.1368, 0.0, + 0.2990, 0.5870, 0.1140, 0.0, + 0.2392, 0.4696, 0.0912, 0.0, + 0.0, 0.0, 0.0, 1.0 + ]) + } + + getFilterType(): GPUFilterType { + return GPUFilterType.SEPIA; + } + + + onReadySize() { + + } +} + diff --git a/gpu_transform/src/main/ets/gpu/filter/GPUImageSketchFilter.ts b/gpu_transform/src/main/ets/gpu/filter/GPUImageSketchFilter.ts new file mode 100644 index 0000000..d7c37fd --- /dev/null +++ b/gpu_transform/src/main/ets/gpu/filter/GPUImageSketchFilter.ts @@ -0,0 +1,37 @@ +/* + * 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 { GPUImage3x3TextureSamplingFilter } from './GPUImage3x3TextureSamplingFilter' +import { GPUFilterType } from '../gl/GPUFilterType' + +export class GPUImageSketchFilter extends GPUImage3x3TextureSamplingFilter { + constructor() { + super() + } + + getFilterType(): GPUFilterType { + return GPUFilterType.SKETCH; + } + + onInitialized() { + + } + + onReadySize() { + this.setTexelWidth(this.width); + this.setTexelHeight(this.height); + } +} + diff --git a/gpu_transform/src/main/ets/gpu/filter/GPUImageSwirlFilter.ts b/gpu_transform/src/main/ets/gpu/filter/GPUImageSwirlFilter.ts new file mode 100644 index 0000000..d83ddb5 --- /dev/null +++ b/gpu_transform/src/main/ets/gpu/filter/GPUImageSwirlFilter.ts @@ -0,0 +1,55 @@ +/* + * 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 { 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; + + constructor() { + super() + } + + getFilterType(): GPUFilterType { + return GPUFilterType.SWIRL; + } + + onInitialized() { + + } + + onReadySize() { + } + + setRadius(radius:number){ + this._radius =radius; + this.setFloat("radius",this._radius); + } + + setAngle(angle:number){ + this._angle = angle; + this.setFloat("angle",this._angle); + } + + setCenter(x_center:number,y_center:number){ + this._xCenter = x_center; + this._yCenter = y_center; + this.setPoint("center",x_center,y_center); + } +} \ No newline at end of file diff --git a/gpu_transform/src/main/ets/gpu/filter/GPUImageToonFilter.ts b/gpu_transform/src/main/ets/gpu/filter/GPUImageToonFilter.ts new file mode 100644 index 0000000..f05ac8f --- /dev/null +++ b/gpu_transform/src/main/ets/gpu/filter/GPUImageToonFilter.ts @@ -0,0 +1,49 @@ +/* + * 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 { GPUImage3x3TextureSamplingFilter } from './GPUImage3x3TextureSamplingFilter' +import { GPUFilterType } from '../gl/GPUFilterType' + +export class GPUImageToonFilter extends GPUImage3x3TextureSamplingFilter { + private threshold:number = 0.2; + private quantizationLevels:number = 10.0; + + constructor() { + super() + } + + getFilterType(): GPUFilterType { + return GPUFilterType.TOON; + } + + onInitialized() { + + } + + onReadySize() { + this.setTexelWidth(this.width); + this.setTexelHeight(this.height); + } + + setThreshold(threshold:number){ + this.threshold = threshold; + this.setFloat("threshold",threshold); + } + + setQuantizationLevels(quantizationLevels:number){ + this.quantizationLevels = quantizationLevels; + this.setFloat("quantizationLevels",quantizationLevels); + } +} \ No newline at end of file diff --git a/gpu_transform/src/main/ets/gpu/filter/GPUImageVignetterFilter.ts b/gpu_transform/src/main/ets/gpu/filter/GPUImageVignetterFilter.ts new file mode 100644 index 0000000..d0fd942 --- /dev/null +++ b/gpu_transform/src/main/ets/gpu/filter/GPUImageVignetterFilter.ts @@ -0,0 +1,58 @@ +/* + * 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 { GPUImageFilter } from './GPUImageFilter' +import { GPUFilterType } from '../gl/GPUFilterType' + +export class GPUImageVignetterFilter extends GPUImageFilter { + private vignetteCenter:Array = [0.0,0.0]; + private vignetteColor:Array =[0.0,0.0,0.0]; + private vignetteStart:number; + private vignetteEnd:number; + + constructor() { + super() + } + + getFilterType(): GPUFilterType { + return GPUFilterType.VIGNETTE; + } + + onInitialized() { + + } + + onReadySize() { + } + + setVignetteCenter(center:Array){ + this.vignetteCenter =center; + this.setFloatVec2("vignetteCenter",center); + } + + setVignetteColor(colors:Array){ + this.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); + } +} \ No newline at end of file diff --git a/gpu_transform/src/main/ets/gpu/gl/GPUFilterType.ts b/gpu_transform/src/main/ets/gpu/gl/GPUFilterType.ts new file mode 100644 index 0000000..fd6ee5b --- /dev/null +++ b/gpu_transform/src/main/ets/gpu/gl/GPUFilterType.ts @@ -0,0 +1,31 @@ +/* + * 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 GPUFilterType{ + BRIGHT, + CONTRAST, + INVERT, + KUWAHARA, + PIXELATION, + SEPIA, + SKETCH, + SWIRL, + TOON, + VIGNETTE, + COLOR_M, + GRAYSCALE, + X3TEXTURE, + BLUR +} \ No newline at end of file diff --git a/gpu_transform/src/main/ets/gpu/gl/NativeEglRender.ts b/gpu_transform/src/main/ets/gpu/gl/NativeEglRender.ts new file mode 100644 index 0000000..30afbcd --- /dev/null +++ b/gpu_transform/src/main/ets/gpu/gl/NativeEglRender.ts @@ -0,0 +1,101 @@ +/* + * 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 nativeGpu from "libnativeGpu.so" + +export class NativeEglRender{ + static EGLTrue : number =1; + + native_EglRenderInit():void{ + nativeGpu.EglRenderInit(); + } + + native_EglRenderSetImageData(bytes:ArrayBuffer,width:number,height:number){ + nativeGpu.EglRenderSetImageData(bytes,width,height); + } + + 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); + return num; + } + + native_glIsInit():boolean{ + let initStatus= nativeGpu.EglIsInit(); + if (initStatus === NativeEglRender.EGLTrue) { + return true; + } + return false; + } + + native_EglUseProgram(){ + nativeGpu.EglUseProgram(); + } + + native_EglRendering(){ + nativeGpu.EglRendering(); + } + + 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_setFloat2f(key:string,value:Float32Array){ + this.native_setTypeArray(key,"glUniform2f",value); + } + + native_setFloatVec2(key:string,value:Float32Array){ + this.native_setTypeArray(key,"glUniform2fv",value); + } + + native_setFloatVec3(key:string,value:Float32Array){ + this.native_setTypeArray(key,"glUniform3fv",value); + } + + native_setFloatVec4(key:string,value:Float32Array){ + this.native_setTypeArray(key,"glUniform4fv",value); + } + + native_setFloatArray(key:string,value:Float32Array){ + this.native_setTypeArray(key,"glUniform1fv",value); + } + + native_setUniformMatrix3f(key:string,value:Float32Array){ + nativeGpu.EglSetTypeArrayOfMatrix3f(key,value); + } + + + native_setUniformMatrix4f(key:string,value:Float32Array){ + nativeGpu.EglSetTypeArrayOfMatrix4f(key,value); + } + + native_setTypeArray(key:string,uniformType:string,data:Float32Array){ + nativeGpu.EglSetTypeArrayOfFloat(key,uniformType,data); + } + + native_glIsDestroy(){ + nativeGpu.EglDestroy(); + } +} \ No newline at end of file diff --git a/gpu_transform/src/main/ets/gpu/interface/Runnable.ts b/gpu_transform/src/main/ets/gpu/interface/Runnable.ts new file mode 100644 index 0000000..39f4bc1 --- /dev/null +++ b/gpu_transform/src/main/ets/gpu/interface/Runnable.ts @@ -0,0 +1,18 @@ +/* + * 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 Runnable{ + run(); +} \ No newline at end of file diff --git a/gpu_transform/src/main/module.json5 b/gpu_transform/src/main/module.json5 new file mode 100644 index 0000000..ad730e4 --- /dev/null +++ b/gpu_transform/src/main/module.json5 @@ -0,0 +1,10 @@ +{ + "module": { + "name": "gpu_transform", + "type": "har", + "deviceTypes": [ + "default", + "tablet" + ] + } +} diff --git a/gpu_transform/src/main/resources/base/element/string.json b/gpu_transform/src/main/resources/base/element/string.json new file mode 100644 index 0000000..1e76de0 --- /dev/null +++ b/gpu_transform/src/main/resources/base/element/string.json @@ -0,0 +1,8 @@ +{ + "string": [ + { + "name": "page_show", + "value": "page from npm package" + } + ] +} diff --git a/gpu_transform/src/main/resources/en_US/element/string.json b/gpu_transform/src/main/resources/en_US/element/string.json new file mode 100644 index 0000000..1e76de0 --- /dev/null +++ b/gpu_transform/src/main/resources/en_US/element/string.json @@ -0,0 +1,8 @@ +{ + "string": [ + { + "name": "page_show", + "value": "page from npm package" + } + ] +} diff --git a/gpu_transform/src/main/resources/zh_CN/element/string.json b/gpu_transform/src/main/resources/zh_CN/element/string.json new file mode 100644 index 0000000..1e76de0 --- /dev/null +++ b/gpu_transform/src/main/resources/zh_CN/element/string.json @@ -0,0 +1,8 @@ +{ + "string": [ + { + "name": "page_show", + "value": "page from npm package" + } + ] +} diff --git a/imageknife/index.ets b/imageknife/index.ets index d4ee93c..b37f483 100644 --- a/imageknife/index.ets +++ b/imageknife/index.ets @@ -70,6 +70,9 @@ export * from './src/main/ets/components/imageknife/transform/SepiaFilterTransfo export * from './src/main/ets/components/imageknife/transform/SketchFilterTransformation' export * from './src/main/ets/components/imageknife/transform/MaskTransformation' export * from './src/main/ets/components/imageknife/transform/SwirlFilterTransformation' +export * from './src/main/ets/components/imageknife/transform/KuwaharaFilterTransform' +export * from './src/main/ets/components/imageknife/transform/ToonFilterTransform' +export * from './src/main/ets/components/imageknife/transform/VignetteFilterTransform' export * from './src/main/ets/components/imageknife/transform/TransformUtils' export * from './src/main/ets/components/imageknife/transform/TransformType' export * from './src/main/ets/components/imageknife/transform/pixelmap/CenterCrop' diff --git a/imageknife/package.json b/imageknife/package.json index 40edd3c..7de7f53 100644 --- a/imageknife/package.json +++ b/imageknife/package.json @@ -12,6 +12,7 @@ }, "main": "index.ets", "repository": "https://gitee.com/openharmony-tpc/ImageKnife", + "type": "module", "version": "1.0.5", "dependencies": { "pako": "^1.0.5", @@ -19,7 +20,8 @@ "@ohos/disklrucache": "^1.0.0", "@ohos/svg": "1.1.0", "crc-32": "^1.2.0", - "spark-md5": "^3.0.2" + "spark-md5": "^3.0.2", + "@ohos/gpu_transform": "file:../gpu_transform" }, "tags": [ "ImageCache", @@ -27,6 +29,5 @@ ], "license": "Apache License 2.0", "devDependencies": {}, - "name": "@ohos/imageknife", - "type": "module" + "name": "@ohos/imageknife" } diff --git a/imageknife/src/main/ets/components/imageknife/RequestOption.ets b/imageknife/src/main/ets/components/imageknife/RequestOption.ets index 066dd27..ac6225a 100644 --- a/imageknife/src/main/ets/components/imageknife/RequestOption.ets +++ b/imageknife/src/main/ets/components/imageknife/RequestOption.ets @@ -13,36 +13,39 @@ * limitations under the License. */ -import {DiskStrategy} from "../cache/diskstrategy/DiskStrategy" -import {AsyncCallback} from "../imageknife/interface/asynccallback" -import {AsyncSuccess} from "../imageknife/interface/AsyncSuccess" -import {IAllCacheInfoCallback} from "../imageknife/interface/IAllCacheInfoCallback" -import {AUTOMATIC} from "../cache/diskstrategy/enum/AUTOMATIC" -import {BaseTransform} from "../imageknife/transform/BaseTransform" -import {RotateImageTransformation} from "../imageknife/transform/RotateImageTransformation" -import {ImageKnifeData} from "../imageknife/ImageKnifeData" -import {CenterCrop} from '../imageknife/transform/pixelmap/CenterCrop' -import {CenterInside} from '../imageknife/transform/pixelmap/CenterInside' -import {FitCenter} from '../imageknife/transform/pixelmap/FitCenter' -import {RoundedCornersTransformation} from '../imageknife/transform/RoundedCornersTransformation' +import { DiskStrategy } from "../cache/diskstrategy/DiskStrategy" +import { AsyncCallback } from "../imageknife/interface/asynccallback" +import { AsyncSuccess } from "../imageknife/interface/AsyncSuccess" +import { IAllCacheInfoCallback } from "../imageknife/interface/IAllCacheInfoCallback" +import { AUTOMATIC } from "../cache/diskstrategy/enum/AUTOMATIC" +import { BaseTransform } from "../imageknife/transform/BaseTransform" +import { RotateImageTransformation } from "../imageknife/transform/RotateImageTransformation" +import { ImageKnifeData } from "../imageknife/ImageKnifeData" +import { CenterCrop } from '../imageknife/transform/pixelmap/CenterCrop' +import { CenterInside } from '../imageknife/transform/pixelmap/CenterInside' +import { FitCenter } from '../imageknife/transform/pixelmap/FitCenter' +import { RoundedCornersTransformation } from '../imageknife/transform/RoundedCornersTransformation' -import {CropCircleTransformation} from '../imageknife/transform/CropCircleTransformation' +import { CropCircleTransformation } from '../imageknife/transform/CropCircleTransformation' -import {CropCircleWithBorderTransformation} from '../imageknife/transform/CropCircleWithBorderTransformation' -import {CropSquareTransformation} from '../imageknife/transform/CropSquareTransformation' -import {CropTransformation} from '../imageknife/transform/CropTransformation' -import {CropType} from '../imageknife/transform/CropTransformation' -import {GrayscaleTransformation} from '../imageknife/transform/GrayscaleTransformation' -import {BrightnessFilterTransformation} from '../imageknife/transform/BrightnessFilterTransformation' -import {ContrastFilterTransformation} from '../imageknife/transform/ContrastFilterTransformation' -import {InvertFilterTransformation} from '../imageknife/transform/InvertFilterTransformation' -import {SepiaFilterTransformation} from '../imageknife/transform/SepiaFilterTransformation' -import {SketchFilterTransformation} from '../imageknife/transform/SketchFilterTransformation' -import {BlurTransformation} from '../imageknife/transform/BlurTransformation' -import {PixelationFilterTransformation} from '../imageknife/transform/PixelationFilterTransformation' -import {MaskTransformation} from '../imageknife/transform/MaskTransformation' -import {SwirlFilterTransformation} from '../imageknife/transform/SwirlFilterTransformation' -import {LogUtil} from '../imageknife/utils/LogUtil' +import { CropCircleWithBorderTransformation } from '../imageknife/transform/CropCircleWithBorderTransformation' +import { CropSquareTransformation } from '../imageknife/transform/CropSquareTransformation' +import { CropTransformation } from '../imageknife/transform/CropTransformation' +import { CropType } from '../imageknife/transform/CropTransformation' +import { GrayscaleTransformation } from '../imageknife/transform/GrayscaleTransformation' +import { BrightnessFilterTransformation } from '../imageknife/transform/BrightnessFilterTransformation' +import { ContrastFilterTransformation } from '../imageknife/transform/ContrastFilterTransformation' +import { InvertFilterTransformation } from '../imageknife/transform/InvertFilterTransformation' +import { SepiaFilterTransformation } from '../imageknife/transform/SepiaFilterTransformation' +import { SketchFilterTransformation } from '../imageknife/transform/SketchFilterTransformation' +import { BlurTransformation } from '../imageknife/transform/BlurTransformation' +import { PixelationFilterTransformation } from '../imageknife/transform/PixelationFilterTransformation' +import { MaskTransformation } from '../imageknife/transform/MaskTransformation' +import { SwirlFilterTransformation } from '../imageknife/transform/SwirlFilterTransformation' +import { KuwaharaFilterTransform } from '../imageknife/transform/KuwaharaFilterTransform' +import { ToonFilterTransform } from '../imageknife/transform/ToonFilterTransform' +import { VignetteFilterTransform } from '../imageknife/transform/VignetteFilterTransform' +import { LogUtil } from '../imageknife/utils/LogUtil' export class RequestOption { loadSrc: string | PixelMap | Resource; @@ -67,7 +70,6 @@ export class RequestOption { retryholderSrc: PixelMap | Resource; retryholderFunc: AsyncSuccess retryholderData: ImageKnifeData - size: { width: number, height: number @@ -78,6 +80,8 @@ export class RequestOption { onlyRetrieveFromCache: boolean = false; isCacheable: boolean = true; + //开启GPU变换绘制 + isOpenGpuTransform: boolean = false; // 变换相关 transformations: Array> = new Array(); generateCacheKey: string = ""; @@ -173,10 +177,10 @@ export class RequestOption { return this; } - thumbnail(sizeMultiplier: number, func?: AsyncSuccess,displayTime?:number) { + thumbnail(sizeMultiplier: number, func?: AsyncSuccess, displayTime?: number) { this.thumbSizeMultiplier = sizeMultiplier; this.thumbHolderFunc = func; - if(displayTime){ + if (displayTime) { this.thumbDelayTime = displayTime; } return this; @@ -187,8 +191,6 @@ export class RequestOption { return this; } - - addListener(func: AsyncCallback) { this.requestListeners.push(func); return this; @@ -218,111 +220,153 @@ export class RequestOption { this.transformations.push(new CenterCrop()); return this; } + centerInside() { this.transformations.push(new CenterInside()); return this; } + fitCenter() { this.transformations.push(new FitCenter()); return this; } - roundedCorners(obj:{ top_left: number, top_right: number, bottom_left: number, bottom_right: number }){ - let transformation = new RoundedCornersTransformation({top_left: obj.top_left, top_right: obj.top_right, bottom_left: obj.bottom_left, bottom_right: obj.bottom_right}) + roundedCorners(obj: { + top_left: number, + top_right: number, + bottom_left: number, + bottom_right: number + }) { + let transformation = new RoundedCornersTransformation({ + top_left: obj.top_left, + top_right: obj.top_right, + bottom_left: obj.bottom_left, + bottom_right: obj.bottom_right + }) this.transformations.push(transformation); return this; } - cropCircle(){ + cropCircle() { let transformation = new CropCircleTransformation() this.transformations.push(transformation); return this; } - cropCircleWithBorder(border:number, obj:{ r_color: number, g_color: number, b_color: number }){ - let transformation = new CropCircleWithBorderTransformation(border,obj) + cropCircleWithBorder(border: number, obj: { + r_color: number, + g_color: number, + b_color: number + }) { + let transformation = new CropCircleWithBorderTransformation(border, obj) this.transformations.push(transformation); return this; } - cropSquare(){ + cropSquare() { let transformation = new CropSquareTransformation() this.transformations.push(transformation); return this; } - crop(width: number, height: number, cropType: CropType){ + crop(width: number, height: number, cropType: CropType) { let transformation = new CropTransformation(width, height, cropType) this.transformations.push(transformation); return this; } - grayscale(){ + grayscale() { let transformation = new GrayscaleTransformation() this.transformations.push(transformation); return this; } - brightnessFilter(brightness:number){ + brightnessFilter(brightness: number) { let transformation = new BrightnessFilterTransformation(brightness) this.transformations.push(transformation); return this; } - contrastFilter(contrast:number){ + contrastFilter(contrast: number) { let transformation = new ContrastFilterTransformation(contrast) this.transformations.push(transformation); return this; } - invertFilter(){ + invertFilter() { let transformation = new InvertFilterTransformation() this.transformations.push(transformation); return this; } - sepiaFilter(){ + sepiaFilter() { let transformation = new SepiaFilterTransformation() this.transformations.push(transformation); return this; } - sketchFilter(){ + sketchFilter() { let transformation = new SketchFilterTransformation() this.transformations.push(transformation); return this; } - blur(radius: number){ + blur(radius: number) { let transformation = new BlurTransformation(radius) this.transformations.push(transformation); return this; } - pixelationFilter(pixel: number){ + pixelationFilter(pixel: number) { let transformation = new PixelationFilterTransformation(pixel) this.transformations.push(transformation); return this; } - swirlFilter(degree: number){ + swirlFilter(degree: number) { let transformation = new SwirlFilterTransformation(degree) this.transformations.push(transformation); return this; } - mask(maskResource: Resource){ + + mask(maskResource: Resource) { let transformation = new MaskTransformation(maskResource) this.transformations.push(transformation); return this; } - transform(input:BaseTransform){ + + kuwaharaFilter(radius: number) { + let transformation = new KuwaharaFilterTransform(radius); + this.transformations.push(transformation); + return this; + } + + toonFilter(threshold: number, quantizationLevels: number) { + let transformation = new ToonFilterTransform(threshold, quantizationLevels); + this.transformations.push(transformation); + return this; + } + + vignetteFilter(centerPoint: Array, vignetteColor: Array, vignetteSpace: Array) { + let transformation = new VignetteFilterTransform(centerPoint, vignetteColor, vignetteSpace); + this.transformations.push(transformation); + return this; + } + + transform(input: BaseTransform) { this.transformations.push(input); return this; } - transforms(inputs:BaseTransform[]){ + + transforms(inputs: BaseTransform[]) { this.transformations = inputs; return this; } + //开启GPU变换绘制 + openEfficient() { + this.isOpenGpuTransform = true; + return this; + } // 占位图解析成功 placeholderOnComplete(imageKnifeData: ImageKnifeData) { @@ -340,8 +384,6 @@ export class RequestOption { } - - // 缩略图解析成功 thumbholderOnComplete(imageKnifeData: ImageKnifeData) { if (!this.loadMainReady && !(this.loadErrorReady || this.loadRetryReady)) { @@ -369,15 +411,15 @@ export class RequestOption { LogUtil.log("失败占位图解析失败 error =" + error) } - retryholderOnComplete(imageKnifeData: ImageKnifeData){ + retryholderOnComplete(imageKnifeData: ImageKnifeData) { this.retryholderData = imageKnifeData; - if(this.loadRetryReady){ + if (this.loadRetryReady) { this.retryholderFunc(imageKnifeData) } } - retryholderOnError(error){ - LogUtil.log("重试占位图解析失败 error ="+ error) + retryholderOnError(error) { + LogUtil.log("重试占位图解析失败 error =" + error) } loadComplete(imageKnifeData: ImageKnifeData) { @@ -394,13 +436,13 @@ export class RequestOption { } loadError(err) { - LogUtil.log("loadError:"+err); - LogUtil.log("loadError stack=:"+JSON.stringify(err.stack)); + LogUtil.log("loadError:" + err); + LogUtil.log("loadError stack=:" + JSON.stringify(err.stack)); //失败占位图展示规则 if (this.retryholderFunc) { // 重试图层优先于加载失败展示 this.loadRetryReady = true; - if(this.retryholderData != null){ + if (this.retryholderData != null) { this.retryholderFunc(this.retryholderData) } } else { diff --git a/imageknife/src/main/ets/components/imageknife/transform/BlurTransformation.ets b/imageknife/src/main/ets/components/imageknife/transform/BlurTransformation.ets index bd37413..4523ba6 100644 --- a/imageknife/src/main/ets/components/imageknife/transform/BlurTransformation.ets +++ b/imageknife/src/main/ets/components/imageknife/transform/BlurTransformation.ets @@ -71,7 +71,11 @@ export class BlurTransformation implements BaseTransform { } imageSource.createPixelMap(options) .then((data) => { - fastBlur.blur(data, this._mRadius, true, func); + if (request.isOpenGpuTransform) { + fastBlur.blurGPU(data, this._mRadius, true, func); + } else { + fastBlur.blur(data, this._mRadius, true, func); + } }) .catch((e) => { LogUtil.log(Constants.PROJECT_TAG + ";error:" + e); diff --git a/imageknife/src/main/ets/components/imageknife/transform/BrightnessFilterTransformation.ets b/imageknife/src/main/ets/components/imageknife/transform/BrightnessFilterTransformation.ets index aa05957..d3a72d4 100644 --- a/imageknife/src/main/ets/components/imageknife/transform/BrightnessFilterTransformation.ets +++ b/imageknife/src/main/ets/components/imageknife/transform/BrightnessFilterTransformation.ets @@ -17,9 +17,9 @@ import { BaseTransform } from "../transform/BaseTransform" import { AsyncTransform } from "../transform/AsyncTransform" import { Constants } from "../constants/Constants" import { RequestOption } from "../../imageknife/RequestOption" -import {LogUtil} from '../../imageknife/utils/LogUtil' +import { LogUtil } from '../../imageknife/utils/LogUtil' import image from "@ohos.multimedia.image" - +import { GPUImageBrightnessFilter } from '@ohos/gpu_transform' /** * brightness value ranges from -1.0 to 1.0, with 0.0 as the normal level @@ -78,6 +78,18 @@ export class BrightnessFilterTransformation implements BaseTransform { let bufferData = new ArrayBuffer(data.getPixelBytesNumber()); await data.readPixelsToBuffer(bufferData); + if (request.isOpenGpuTransform) { + let filter = new GPUImageBrightnessFilter(); + filter.setImageData(bufferData, targetWidth, targetHeight); + filter.setBrightness(this._mBrightness); + let buf = await filter.getPixelMapBuf(0, 0, targetWidth, targetHeight); + data.writeBufferToPixels(buf); + if (func) { + func("success", data); + } + return; + } + var dataArray = new Uint8Array(bufferData); for (let index = 0; index < dataArray.length; index += 4) { diff --git a/imageknife/src/main/ets/components/imageknife/transform/ContrastFilterTransformation.ets b/imageknife/src/main/ets/components/imageknife/transform/ContrastFilterTransformation.ets index b152aac..a7c2ddb 100644 --- a/imageknife/src/main/ets/components/imageknife/transform/ContrastFilterTransformation.ets +++ b/imageknife/src/main/ets/components/imageknife/transform/ContrastFilterTransformation.ets @@ -17,9 +17,9 @@ import { BaseTransform } from "../transform/BaseTransform" import { AsyncTransform } from "../transform/AsyncTransform" import { Constants } from "../constants/Constants" import { RequestOption } from "../../imageknife/RequestOption" -import {LogUtil} from '../../imageknife/utils/LogUtil' +import { LogUtil } from '../../imageknife/utils/LogUtil' import image from "@ohos.multimedia.image" - +import { GPUImageContrastFilter } from '@ohos/gpu_transform' /** * 以24位色图像为例子,每种色彩都可以用0-255, @@ -91,6 +91,18 @@ export class ContrastFilterTransformation implements BaseTransform { let bufferData = new ArrayBuffer(data.getPixelBytesNumber()); await data.readPixelsToBuffer(bufferData); + if (request.isOpenGpuTransform) { + let filter = new GPUImageContrastFilter(); + filter.setImageData(bufferData, targetWidth, targetHeight); + filter.setContrast(this._mContrast) + let buf = await filter.getPixelMapBuf(0, 0, targetWidth, targetHeight); + data.writeBufferToPixels(buf); + if (func) { + func("success", data); + } + return; + } + var dataArray = new Uint8Array(bufferData); let brightness = 0; //亮度的偏移量,可以默认0 diff --git a/imageknife/src/main/ets/components/imageknife/transform/GrayscaleTransformation.ets b/imageknife/src/main/ets/components/imageknife/transform/GrayscaleTransformation.ets index 2333d47..621feeb 100644 --- a/imageknife/src/main/ets/components/imageknife/transform/GrayscaleTransformation.ets +++ b/imageknife/src/main/ets/components/imageknife/transform/GrayscaleTransformation.ets @@ -20,6 +20,7 @@ import { RequestOption } from "../../imageknife/RequestOption" import { TransformUtils } from "../transform/TransformUtils" import {LogUtil} from '../../imageknife/utils/LogUtil' import image from "@ohos.multimedia.image" +import { GPUImageGrayscaleFilter } from '@ohos/gpu_transform' export class GrayscaleTransformation implements BaseTransform { getName() { @@ -70,6 +71,18 @@ export class GrayscaleTransformation implements BaseTransform { let bufferNewData = new ArrayBuffer(data.getPixelBytesNumber()); await data.readPixelsToBuffer(bufferData); + if (request.isOpenGpuTransform) { + let filter = new GPUImageGrayscaleFilter(); + filter.setImageData(bufferData, targetWidth, targetHeight); + let buf = await filter.getPixelMapBuf(0, 0, targetWidth, targetHeight); + data.writeBufferToPixels(buf); + if (func) { + func("success", data); + } + return; + } + + var dataArray = new Uint8Array(bufferData); var dataNewArray = new Uint8Array(bufferNewData); diff --git a/imageknife/src/main/ets/components/imageknife/transform/InvertFilterTransformation.ets b/imageknife/src/main/ets/components/imageknife/transform/InvertFilterTransformation.ets index 91b9431..40fe63c 100644 --- a/imageknife/src/main/ets/components/imageknife/transform/InvertFilterTransformation.ets +++ b/imageknife/src/main/ets/components/imageknife/transform/InvertFilterTransformation.ets @@ -19,6 +19,7 @@ import { Constants } from "../constants/Constants" import { RequestOption } from "../../imageknife/RequestOption" import {LogUtil} from '../../imageknife/utils/LogUtil' import image from "@ohos.multimedia.image" +import { GPUImageColorInvertFilter } from '@ohos/gpu_transform' /** ** Image inversion is particularly useful for enhancing white or gray detail in @@ -78,6 +79,18 @@ export class InvertFilterTransformation implements BaseTransform { let bufferData = new ArrayBuffer(data.getPixelBytesNumber()); await data.readPixelsToBuffer(bufferData); + if (request.isOpenGpuTransform) { + let filter = new GPUImageColorInvertFilter(); + filter.setImageData(bufferData, targetWidth, targetHeight); + let buf = await filter.getPixelMapBuf(0, 0, targetWidth, targetHeight); + data.writeBufferToPixels(buf); + if (func) { + func("success", data); + } + return; + } + + var dataArray = new Uint8Array(bufferData); for (let index = 0; index < dataArray.length; index += 4) { diff --git a/imageknife/src/main/ets/components/imageknife/transform/KuwaharaFilterTransform.ts b/imageknife/src/main/ets/components/imageknife/transform/KuwaharaFilterTransform.ts new file mode 100644 index 0000000..7e8fb80 --- /dev/null +++ b/imageknife/src/main/ets/components/imageknife/transform/KuwaharaFilterTransform.ts @@ -0,0 +1,101 @@ +/* + * 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 { + private _mRadius: number; + + constructor(radius: number) { + this._mRadius = radius; + } + + getName() { + return "KuwaharaFilterTransform _mRadius:" + this._mRadius; + } + + transform(buf: ArrayBuffer, request: RequestOption, func?: AsyncTransform) { + if (!buf || buf.byteLength <= 0) { + LogUtil.log(Constants.PROJECT_TAG + ";KuwaharaFilterTransform buf is empty"); + if (func) { + 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) { + 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); + } + } +} \ No newline at end of file diff --git a/imageknife/src/main/ets/components/imageknife/transform/PixelationFilterTransformation.ets b/imageknife/src/main/ets/components/imageknife/transform/PixelationFilterTransformation.ets index 6aece60..e8812fd 100644 --- a/imageknife/src/main/ets/components/imageknife/transform/PixelationFilterTransformation.ets +++ b/imageknife/src/main/ets/components/imageknife/transform/PixelationFilterTransformation.ets @@ -18,7 +18,7 @@ import { AsyncTransform } from "../transform/AsyncTransform" import { Constants } from "../constants/Constants" import { RequestOption } from "../../imageknife/RequestOption" import { TransformUtils } from "../transform/TransformUtils" -import {LogUtil} from '../../imageknife/utils/LogUtil' +import { LogUtil } from '../../imageknife/utils/LogUtil' import image from "@ohos.multimedia.image" import { pixelUtils } from "../utils/PixelUtils" @@ -76,7 +76,11 @@ export class PixelationFilterTransformation implements BaseTransform { } imageSource.createPixelMap(options) .then((data) => { - pixelUtils.pixel(data, this._mPixel, func); + if (request.isOpenGpuTransform) { + pixelUtils.pixelGPU(data, this._mPixel, func); + } else { + pixelUtils.pixel(data, this._mPixel, func); + } }) .catch((e) => { LogUtil.log(Constants.PROJECT_TAG + ";error:" + e); diff --git a/imageknife/src/main/ets/components/imageknife/transform/SepiaFilterTransformation.ets b/imageknife/src/main/ets/components/imageknife/transform/SepiaFilterTransformation.ets index 98f954e..56eee5b 100644 --- a/imageknife/src/main/ets/components/imageknife/transform/SepiaFilterTransformation.ets +++ b/imageknife/src/main/ets/components/imageknife/transform/SepiaFilterTransformation.ets @@ -17,8 +17,9 @@ import { BaseTransform } from "../transform/BaseTransform" import { AsyncTransform } from "../transform/AsyncTransform" import { Constants } from "../constants/Constants" import { RequestOption } from "../../imageknife/RequestOption" -import {LogUtil} from '../../imageknife/utils/LogUtil' +import { LogUtil } from '../../imageknife/utils/LogUtil' import image from "@ohos.multimedia.image" +import { GPUImageSepiaToneFilter } from '@ohos/gpu_transform' /** * Applies a simple sepia effect. @@ -72,9 +73,20 @@ export class SepiaFilterTransformation implements BaseTransform { let data = await imageSource.createPixelMap(options); let bufferData = new ArrayBuffer(data.getPixelBytesNumber()); - let bufferNewData = new ArrayBuffer(data.getPixelBytesNumber()); await data.readPixelsToBuffer(bufferData); + if (request.isOpenGpuTransform) { + let filter = new GPUImageSepiaToneFilter(); + filter.setImageData(bufferData, targetWidth, targetHeight); + let buf = await filter.getPixelMapBuf(0, 0, targetWidth, targetHeight); + data.writeBufferToPixels(buf); + if (func) { + func("success", data); + } + return; + } + + let bufferNewData = new ArrayBuffer(data.getPixelBytesNumber()); var dataArray = new Uint8Array(bufferData); var dataNewArray = new Uint8Array(bufferNewData); diff --git a/imageknife/src/main/ets/components/imageknife/transform/SketchFilterTransformation.ets b/imageknife/src/main/ets/components/imageknife/transform/SketchFilterTransformation.ets index e6c004d..af55d3f 100644 --- a/imageknife/src/main/ets/components/imageknife/transform/SketchFilterTransformation.ets +++ b/imageknife/src/main/ets/components/imageknife/transform/SketchFilterTransformation.ets @@ -63,7 +63,11 @@ export class SketchFilterTransformation implements BaseTransform { } imageSource.createPixelMap(options) .then((data) => { - CalculatePixelUtils.sketch(data, func); + if (request.isOpenGpuTransform) { + CalculatePixelUtils.sketchGpu(data, func); + } else { + CalculatePixelUtils.sketch(data, func); + } }) .catch((e) => { func(e, null); diff --git a/imageknife/src/main/ets/components/imageknife/transform/SwirlFilterTransformation.ets b/imageknife/src/main/ets/components/imageknife/transform/SwirlFilterTransformation.ets index fd6aeea..a01ac47 100644 --- a/imageknife/src/main/ets/components/imageknife/transform/SwirlFilterTransformation.ets +++ b/imageknife/src/main/ets/components/imageknife/transform/SwirlFilterTransformation.ets @@ -22,16 +22,27 @@ import image from '@ohos.multimedia.image' import { PixelEntry } from '../entry/PixelEntry' import { ColorUtils } from '../utils/ColorUtils' import { CalculatePixelUtils } from '../utils/CalculatePixelUtils' +import { GPUImageSwirlFilter } from '@ohos/gpu_transform' export class SwirlFilterTransformation implements BaseTransform { - private _degree: number; + private radius: number = 0; + private _angle: number = 0.9; + private _xCenter: number = 0.5; + private _yCenter: number = 0.5; - constructor(degree: number) { - this._degree = degree; + constructor(radius: number, angle?: number, centerPoint?: Array) { + this.radius = radius; + if (angle) { + this._angle = angle; + } + if (centerPoint && centerPoint.length === 2) { + this._xCenter = centerPoint[0]; + this._yCenter = centerPoint[1]; + } } getName() { - return 'SwirlFilterTransformation' + this._degree; + return 'SwirlFilterTransformation' + this.radius; } transform(buf: ArrayBuffer, request: RequestOption, func?: AsyncTransform) { @@ -71,7 +82,7 @@ export class SwirlFilterTransformation implements BaseTransform { } imageSource.createPixelMap(options) .then((data) => { - this.swirl(data, this._degree, func); + this.swirl(data, this.radius, request, func); }) .catch((e) => { func(e, null); @@ -79,7 +90,7 @@ export class SwirlFilterTransformation implements BaseTransform { }) } - private async swirl(bitmap: any, degree: number, func?: AsyncTransform) { + private async swirl(bitmap: any, degree: number, request: RequestOption, func?: AsyncTransform) { let imageInfo = await bitmap.getImageInfo(); let size = { width: imageInfo.size.width, @@ -90,13 +101,28 @@ export class SwirlFilterTransformation implements BaseTransform { } let width = size.width; let height = size.height; - let pixEntry: Array = new Array(); - let rgbData = CalculatePixelUtils.createInt2DArray(height, width); - let bufferData = new ArrayBuffer(bitmap.getPixelBytesNumber()); await bitmap.readPixelsToBuffer(bufferData); + if (request.isOpenGpuTransform) { + let filter = new GPUImageSwirlFilter(); + filter.setImageData(bufferData, width, height); + filter.setRadius(degree); + filter.setAngle(this._angle) + filter.setCenter(this._xCenter, this._yCenter) + let buf = await filter.getPixelMapBuf(0, 0, width, height); + bitmap.writeBufferToPixels(buf); + if (func) { + func("success", bitmap); + } + return; + } + + let pixEntry: Array = new Array(); + + let rgbData = CalculatePixelUtils.createInt2DArray(height, width); + let dataArray = new Uint8Array(bufferData); let ph = 0; diff --git a/imageknife/src/main/ets/components/imageknife/transform/ToonFilterTransform.ts b/imageknife/src/main/ets/components/imageknife/transform/ToonFilterTransform.ts new file mode 100644 index 0000000..eb83f50 --- /dev/null +++ b/imageknife/src/main/ets/components/imageknife/transform/ToonFilterTransform.ts @@ -0,0 +1,108 @@ +/* + * 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 { + 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) { + 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) { + 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); + } + } +} \ No newline at end of file diff --git a/imageknife/src/main/ets/components/imageknife/transform/VignetteFilterTransform.ts b/imageknife/src/main/ets/components/imageknife/transform/VignetteFilterTransform.ts new file mode 100644 index 0000000..176a7cd --- /dev/null +++ b/imageknife/src/main/ets/components/imageknife/transform/VignetteFilterTransform.ts @@ -0,0 +1,114 @@ +/* + * 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 { + private centerPoint: Array = [0.5, 0.5]; + private vignetteColor: Array = [0.0, 0.0, 0.0]; + private vignetteSpace: Array = [0.3, 0.75]; + + constructor(centerPoint: Array, vignetteColor: Array, vignetteSpace: Array) { + if (centerPoint.length === 2) { + this.centerPoint = centerPoint; + } + if (vignetteColor.length === 3) { + this.vignetteColor = vignetteColor; + } + if (vignetteSpace.length === 2) { + this.vignetteSpace = vignetteSpace; + } + } + + getName() { + return "VignetteFilterTransform centerPoint:" + this.centerPoint + ";vignetteColor:" + this.vignetteColor + ";vignetteSpace:" + this.vignetteSpace; + } + + transform(buf: ArrayBuffer, request: RequestOption, func?: AsyncTransform) { + if (!buf || buf.byteLength <= 0) { + LogUtil.log(Constants.PROJECT_TAG + ";VignetteFilterTransform buf is empty"); + if (func) { + 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) { + 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); + } + } +} \ No newline at end of file diff --git a/imageknife/src/main/ets/components/imageknife/utils/CalculatePixelUtils.ets b/imageknife/src/main/ets/components/imageknife/utils/CalculatePixelUtils.ets index c13e4f6..e9d5300 100644 --- a/imageknife/src/main/ets/components/imageknife/utils/CalculatePixelUtils.ets +++ b/imageknife/src/main/ets/components/imageknife/utils/CalculatePixelUtils.ets @@ -12,9 +12,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import {PixelEntry} from "../entry/PixelEntry" -import {AsyncTransform} from "../transform/AsyncTransform" -import {ColorUtils} from "./ColorUtils" +import { PixelEntry } from "../entry/PixelEntry" +import { AsyncTransform } from "../transform/AsyncTransform" +import { ColorUtils } from "./ColorUtils" +import { GPUImageSketchFilter } from '@ohos/gpu_transform' export namespace CalculatePixelUtils { export async function sketch(p: any, func: AsyncTransform) { @@ -96,7 +97,7 @@ export namespace CalculatePixelUtils { } var gaussGray = (psrc: Array, horz: number, vert: number, - width: number, height: number): number=> { + width: number, height: number): number => { let dst, src, n_p, n_m, d_p, d_m, bd_p, bd_m, val_p, val_m, initial_p, initial_m: Array; let i, j, t, k, row, col, terms, std_dev, sp_p_idx, sp_m_idx, vp_idx, vm_idx: number; let row_stride = width; @@ -204,8 +205,8 @@ export namespace CalculatePixelUtils { } var findConstants = (n_p: Array, n_m: Array, d_p: Array, - d_m: Array, bd_p: Array - , bd_m: Array, std_dev: number)=> { + d_m: Array, bd_p: Array + , bd_m: Array, std_dev: number) => { let div = Math.sqrt(2 * 3.141593) * std_dev; let x0 = -1.783 / std_dev; let x1 = -1.723 / std_dev; @@ -263,16 +264,16 @@ export namespace CalculatePixelUtils { } var transferGaussPixels = (src1: Array, src2: Array, - dest: Array, bytes: number, width: number)=> { + dest: Array, bytes: number, width: number) => { let i, j, k, b, sum: number; let bend = bytes * width; i = j = k = 0; for (b = 0; b < bend; b++) { sum = src1[i++] + src2[j++]; if (sum > 255) - sum = 255; + sum = 255; else if (sum < 0) - sum = 0; + sum = 0; dest[k++] = sum; } } @@ -296,4 +297,30 @@ export namespace CalculatePixelUtils { } return array; } + + export async function sketchGpu(p: any, func: AsyncTransform) { + let imageInfo = await p.getImageInfo(); + let size = { + width: imageInfo.size.width, + height: imageInfo.size.height + } + if (!size) { + func(new Error("sketch The image size does not exist."), null) + return; + } + + let w = size.width; + let h = size.height; + + let bufferData = new ArrayBuffer(p.getPixelBytesNumber()); + await p.readPixelsToBuffer(bufferData); + let filter = new GPUImageSketchFilter(); + filter.setImageData(bufferData, w, h); + filter.getPixelMapBuf(0, 0, w, h).then((buf) => { + p.writeBufferToPixels(buf); + if (func) { + func("success", p); + } + }) + } } \ No newline at end of file diff --git a/imageknife/src/main/ets/components/imageknife/utils/FastBlur.ets b/imageknife/src/main/ets/components/imageknife/utils/FastBlur.ets index 396a871..568b5cc 100644 --- a/imageknife/src/main/ets/components/imageknife/utils/FastBlur.ets +++ b/imageknife/src/main/ets/components/imageknife/utils/FastBlur.ets @@ -17,7 +17,7 @@ import {CalculatePixelUtils} from "./CalculatePixelUtils" import {PixelEntry} from "../entry/PixelEntry" import {AsyncTransform} from "../transform/AsyncTransform" import {ColorUtils} from "./ColorUtils" - +import { GPUImageBlurFilter } from '@ohos/gpu_transform' export namespace fastBlur { @@ -290,4 +290,37 @@ export namespace fastBlur { func("success", bitmap); } } + export async function blurGPU(bitmap: any, radius: number, canReuseInBitmap: boolean, func: AsyncTransform) { + if (radius < 1) { + func("error,radius must be greater than 1 ", null); + return; + } + + let imageInfo = await bitmap.getImageInfo(); + let size = { + width: imageInfo.size.width, + height: imageInfo.size.height + } + + if (!size) { + func(new Error("fastBlur The image size does not exist."), null) + return; + } + + let w = size.width; + let h = size.height; + + let bufferData = new ArrayBuffer(bitmap.getPixelBytesNumber()); + await bitmap.readPixelsToBuffer(bufferData); + let filter = new GPUImageBlurFilter(); + filter.setImageData(bufferData, w, h); + filter.setBlurRadius(radius); + filter.setBlurOffset([1.0, 1.0]) + filter.getPixelMapBuf(0, 0, w, h).then((buf) => { + bitmap.writeBufferToPixels(buf); + if (func) { + func("success", bitmap); + } + }) + } } diff --git a/imageknife/src/main/ets/components/imageknife/utils/PixelUtils.ets b/imageknife/src/main/ets/components/imageknife/utils/PixelUtils.ets index 03fd923..2895fc0 100644 --- a/imageknife/src/main/ets/components/imageknife/utils/PixelUtils.ets +++ b/imageknife/src/main/ets/components/imageknife/utils/PixelUtils.ets @@ -17,6 +17,7 @@ import {CalculatePixelUtils} from "./CalculatePixelUtils" import {PixelEntry} from "../entry/PixelEntry" import {AsyncTransform} from "../transform/AsyncTransform" import {ColorUtils} from "./ColorUtils" +import {GPUImagePixelationFilter} from '@ohos/gpu_transform' export namespace pixelUtils { @@ -129,4 +130,30 @@ export namespace pixelUtils { func("success", bitmap); } } + export async function pixelGPU(bitmap: any, pixel: number, func: AsyncTransform) { + + let imageInfo = await bitmap.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; + } + let w = size.width; + let h = size.height; + + let bufferData = new ArrayBuffer(bitmap.getPixelBytesNumber()); + await bitmap.readPixelsToBuffer(bufferData); + let filter = new GPUImagePixelationFilter(); + filter.setImageData(bufferData, w, h); + filter.setPixel(pixel) + filter.getPixelMapBuf(0, 0, w, h).then((buf) => { + bitmap.writeBufferToPixels(buf); + if (func) { + func("success", bitmap); + } + }) + } } \ No newline at end of file From 91f022516f064b632e8dc017b3351abf8d5dab23 Mon Sep 17 00:00:00 2001 From: tyBrave Date: Thu, 2 Feb 2023 17:36:22 +0800 Subject: [PATCH 02/10] update shape code of invert transform Signed-off-by: tyBrave --- gpu_transform/src/main/cpp/constant/constant_shape.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gpu_transform/src/main/cpp/constant/constant_shape.h b/gpu_transform/src/main/cpp/constant/constant_shape.h index a7dcc1e..8030763 100644 --- a/gpu_transform/src/main/cpp/constant/constant_shape.h +++ b/gpu_transform/src/main/cpp/constant/constant_shape.h @@ -232,7 +232,7 @@ const char contrastFShaderStr[] = const char invertFShaderStr[] = "#version 300 es\n" "precision highp float;\n" - "int vec2 v_texCoord;\n" + "in vec2 v_texCoord;\n" "\n" "uniform lowp sampler2D s_TextureMap;\n" "layout(location = 0) out vec4 outColor;\n" From 57d773e582a0bdad3b11b5fbadfdb14b977833a8 Mon Sep 17 00:00:00 2001 From: tyBrave Date: Fri, 3 Feb 2023 10:48:56 +0800 Subject: [PATCH 03/10] updae code of codecheck Signed-off-by: tyBrave --- .../src/main/cpp/constant/constant_shape.h | 35 ++++ .../src/main/cpp/render/EGLRender.cpp | 176 ++++++++++-------- gpu_transform/src/main/cpp/render/EGLRender.h | 2 +- gpu_transform/src/main/cpp/util/NativeImage.h | 79 ++++---- package.json | 32 ++-- 5 files changed, 185 insertions(+), 139 deletions(-) diff --git a/gpu_transform/src/main/cpp/constant/constant_shape.h b/gpu_transform/src/main/cpp/constant/constant_shape.h index 8030763..b3a5f23 100644 --- a/gpu_transform/src/main/cpp/constant/constant_shape.h +++ b/gpu_transform/src/main/cpp/constant/constant_shape.h @@ -22,6 +22,41 @@ #ifndef GPU_ImageETS_constant_shape_H #define GPU_ImageETS_constant_shape_H + +const int UNIFORM_TYPE_2FV_SIZE = 10; +const int UNIFORM_TYPE_FV = 1; +const int UNIFORM_TYPE_2FV = 2; +const int UNIFORM_TYPE_3FV = 3; +const int UNIFORM_TYPE_4FV = 4; +const int UNIFORM_TYPE_2F = 21; + +const int DEFAULT_ZERO = 0; +const int DEFAULT_ONE = 1; +const int DEFAULT_TWO = 2; +const int DEFAULT_THREE = 3; +const int DEFAULT_FOUR = 4; +const float DEFAULT_ONE_HALF = 1.5; + +const int UNIFORM_TYPE_ZERO = 0; +const int UNIFORM_TYPE_ONE = 1; +const int UNIFORM_TYPE_THREE = 3; +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_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; + + const char vShaderStr[] = "#version 300 es \n" "layout(location = 0) in vec4 a_position; \n" diff --git a/gpu_transform/src/main/cpp/render/EGLRender.cpp b/gpu_transform/src/main/cpp/render/EGLRender.cpp index 95e2570..d23a2a0 100644 --- a/gpu_transform/src/main/cpp/render/EGLRender.cpp +++ b/gpu_transform/src/main/cpp/render/EGLRender.cpp @@ -36,10 +36,10 @@ #include "../util/NapiUtil.h" -#define PARAM_TYPE_SHADER_INDEX 300 +const int PARAM_TYPE_SHADER_INDEX = 300; -#define VERTEX_POS_LOC 0 -#define TEXTURE_POS_LOC 1 +const int VERTEX_POS_LOC = 0; +const int TEXTURE_POS_LOC = 1; const int32_t STR_DEFAULT_SIZE = 1024; EGLRender *EGLRender::sInstance = nullptr; @@ -162,14 +162,14 @@ napi_value EGLRender::GetPixelMapOfSurface(napi_env env, napi_callback_info info return nullptr; } - uint8_t* pixels = (uint8_t*) malloc(surfaceWidth * surfaceHeight * 4); + uint8_t* pixels = (uint8_t*) malloc(surfaceWidth * surfaceHeight * DEFAULT_FOUR); glPixelStorei(GL_PACK_ALIGNMENT, 1); glReadPixels(x, y, surfaceWidth, surfaceHeight, GL_RGBA, GL_UNSIGNED_BYTE, pixels); NativeImageUtil::flip(&pixels, surfaceWidth, surfaceHeight); napi_value array; - int byte_length = surfaceWidth * surfaceHeight * 4; + int byte_length = surfaceWidth * surfaceHeight * DEFAULT_FOUR; if (!NativeImageUtil::CreateArrayBuffer(env, pixels, byte_length, &array)) { LOGI("gl--> GetPixelMapOfSurface error"); } @@ -217,12 +217,12 @@ napi_value EGLRender::setTypeArrayOfFloat(napi_env env, napi_callback_info info) napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); std::string locationContent; - NapiUtil::JsValueToString(env, args[0], 1024, locationContent); + NapiUtil::JsValueToString(env, args[0], STR_DEFAULT_SIZE, locationContent); char* location = (char*)locationContent.c_str(); std::string content; - NapiUtil::JsValueToString(env, args[1], 1024, content); + NapiUtil::JsValueToString(env, args[1], STR_DEFAULT_SIZE, content); char* key = (char*)content.c_str(); @@ -240,15 +240,15 @@ napi_value EGLRender::setTypeArrayOfFloat(napi_env env, napi_callback_info info) int uniformType; if (strcmp(key, "glUniform2fv") == 0) { - uniformType = 2; + uniformType = UNIFORM_TYPE_2FV; }else if (strcmp(key, "glUniform3fv") == 0) { - uniformType = 3; + uniformType = UNIFORM_TYPE_3FV; }else if (strcmp(key, "glUniform4fv") == 0) { - uniformType = 4; + uniformType = UNIFORM_TYPE_4FV; }else if (strcmp(key, "glUniform1fv") == 0) { - uniformType = 1; + uniformType = UNIFORM_TYPE_FV; }else if (strcmp(key, "glUniform2f") == 0) { - uniformType = 21; + uniformType = UNIFORM_TYPE_2F; } EGLRender::GetInstance() -> GlUniformArray(location, value, uniformType); @@ -261,7 +261,7 @@ napi_value EGLRender::setTypeArrayOfMatrix3f(napi_env env, napi_callback_info in napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); std::string locationContent; - NapiUtil::JsValueToString(env, args[0], 1024, locationContent); + NapiUtil::JsValueToString(env, args[0], STR_DEFAULT_SIZE, locationContent); char* location = (char*)locationContent.c_str(); @@ -276,7 +276,7 @@ napi_value EGLRender::setTypeArrayOfMatrix3f(napi_env env, napi_callback_info in float* value = reinterpret_cast(buffer); - EGLRender::GetInstance() -> GlUniformMatrix(location, value, 3); + EGLRender::GetInstance() -> GlUniformMatrix(location, value, UNIFORM_TYPE_THREE); return nullptr; } @@ -287,7 +287,7 @@ napi_value EGLRender::setTypeArrayOfMatrix4f(napi_env env, napi_callback_info in napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); std::string locationContent; - NapiUtil::JsValueToString(env, args[0], 1024, locationContent); + NapiUtil::JsValueToString(env, args[0], STR_DEFAULT_SIZE, locationContent); char* location = (char*)locationContent.c_str(); @@ -302,7 +302,7 @@ napi_value EGLRender::setTypeArrayOfMatrix4f(napi_env env, napi_callback_info in float* value = reinterpret_cast(buffer); - EGLRender::GetInstance() -> GlUniformMatrix(location, value, 4); + EGLRender::GetInstance() -> GlUniformMatrix(location, value, UNIFORM_TYPE_FOUR); return nullptr; } @@ -313,13 +313,13 @@ napi_value EGLRender::RenderGlUniform1i(napi_env env, napi_callback_info info) { napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); std::string content; - NapiUtil::JsValueToString(env, args[0], 1024, content); + NapiUtil::JsValueToString(env, args[0], STR_DEFAULT_SIZE, content); uint32_t value; napi_status status = napi_get_value_uint32(env, args[1], &value); if (status != napi_ok) { return nullptr; } - EGLRender::GetInstance() -> GlUniform((char*)content.c_str(), value, 0); + EGLRender::GetInstance() -> GlUniform((char*)content.c_str(), value, UNIFORM_TYPE_ZERO); return nullptr; } @@ -330,13 +330,13 @@ napi_value EGLRender::RenderGlUniform1f(napi_env env, napi_callback_info info) { napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); std::string content; - NapiUtil::JsValueToString(env, args[0], 1024, content); + NapiUtil::JsValueToString(env, args[0], STR_DEFAULT_SIZE, content); double value; napi_status status = napi_get_value_double(env, args[1], &value); if (status != napi_ok) { return nullptr; } - EGLRender::GetInstance() -> GlUniform((char*)content.c_str(), value, 1); + EGLRender::GetInstance() -> GlUniform((char*)content.c_str(), value, UNIFORM_TYPE_ONE); return nullptr; } @@ -347,7 +347,7 @@ napi_value EGLRender::RenderGlUniform2fv(napi_env env, napi_callback_info info) napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); std::string content; - NapiUtil::JsValueToString(env, args[0], 1024, content); + NapiUtil::JsValueToString(env, args[0], STR_DEFAULT_SIZE, content); double value; napi_status status = napi_get_value_double(env, args[1], &value); @@ -363,7 +363,7 @@ napi_value EGLRender::RenderGlUniform2fv(napi_env env, napi_callback_info info) float vce2[2]; vce2[0] = value; vce2[1] = value2; - EGLRender::GetInstance() -> GlUniformArray((char*)content.c_str(), vce2, 10); + EGLRender::GetInstance() -> GlUniformArray((char*)content.c_str(), vce2, UNIFORM_TYPE_2FV_SIZE); return nullptr; } @@ -418,33 +418,33 @@ void EGLRender::Init() { } // Generate VBO Ids and load the VBOs width data - glGenBuffers(3, m_VboIds); - glBindBuffer(GL_ARRAY_BUFFER, m_VboIds[0]); + glGenBuffers(DEFAULT_THREE, m_VboIds); + glBindBuffer(GL_ARRAY_BUFFER, m_VboIds[DEFAULT_ZERO]); glBufferData(GL_ARRAY_BUFFER, sizeof(vVertices), vVertices, GL_STATIC_DRAW); - glBindBuffer(GL_ARRAY_BUFFER, m_VboIds[1]); + glBindBuffer(GL_ARRAY_BUFFER, m_VboIds[DEFAULT_ONE]); glBufferData(GL_ARRAY_BUFFER, sizeof(vFboTexCoors), vTexCoors, GL_STATIC_DRAW); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_VboIds[2]); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_VboIds[DEFAULT_TWO]); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); // Generate VAO Ids - glGenVertexArrays(1, m_VaoIds); + glGenVertexArrays(DEFAULT_ONE, m_VaoIds); // FBO off screen rendering VAO - glBindVertexArray(m_VaoIds[0]); + glBindVertexArray(m_VaoIds[DEFAULT_ZERO]); - glBindBuffer(GL_ARRAY_BUFFER, m_VboIds[0]); + glBindBuffer(GL_ARRAY_BUFFER, m_VboIds[DEFAULT_ZERO]); glEnableVertexAttribArray(VERTEX_POS_LOC); - glVertexAttribPointer(VERTEX_POS_LOC, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (const void *)0); + glVertexAttribPointer(VERTEX_POS_LOC, DEFAULT_THREE, GL_FLOAT, GL_FALSE, DEFAULT_THREE * sizeof(GLfloat), (const void *)DEFAULT_ZERO); glBindBuffer(GL_ARRAY_BUFFER,GL_NONE); - glBindBuffer(GL_ARRAY_BUFFER, m_VboIds[1]); + glBindBuffer(GL_ARRAY_BUFFER, m_VboIds[DEFAULT_ONE]); glEnableVertexAttribArray(TEXTURE_POS_LOC); - glVertexAttribPointer(TEXTURE_POS_LOC, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), (const void *)0); + glVertexAttribPointer(TEXTURE_POS_LOC, DEFAULT_TWO, GL_FLOAT, GL_FALSE, DEFAULT_TWO * sizeof(GLfloat), (const void *)DEFAULT_ZERO); glBindBuffer(GL_ARRAY_BUFFER,GL_NONE); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_VboIds[2]); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_VboIds[DEFAULT_TWO]); glBindVertexArray(GL_NONE); } @@ -514,6 +514,9 @@ int EGLRender::CreateGlEnv() { case EGL_BAD_MATCH: LOGI("gl-->::CreateGlesEnv Check window and EGLConfig attributes"); break; + default: + LOGI("gl-->::CreateGlesEnv happen default error"); + break; } } @@ -559,7 +562,7 @@ void EGLRender::SetImageData(uint8_t *pData, int width, int height) { m_RenderImage.height = height; m_RenderImage.format = IMAGE_FORMAT_RGBA; NativeImageUtil::AllocNativeImage(&m_RenderImage); - memcpy(m_RenderImage.ppPlane[0], pData, width * height *4); + memcpy(m_RenderImage.ppPlane[0], pData, width * height * DEFAULT_FOUR); glBindTexture(GL_TEXTURE_2D, m_ImageTextureId); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_RenderImage.width, m_RenderImage.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, m_RenderImage.ppPlane[0]); @@ -601,68 +604,71 @@ void EGLRender::SetIntParams(int paramType, int param) { const char* fShader[1]; switch(param) { - case 4: + case SHADER_TYPE_KUWAHARA: { fShader[0] = fShaderStr3; break; } - case 7: + case SHADER_TYPE_SWIRL: { fShader[0] = swirlFShaderStr; break; } - case 0: + case SHADER_TYPE_BRIGHT: { fShader[0] = brightFShaderStr; break; } - case 1: + case SHADER_TYPE_CONTRAST: { fShader[0] = contrastFShaderStr; break; } - case 2: + case SHADER_TYPE_INVERT: { fShader[0] = invertFShaderStr; break; } - case 3: + case SHADER_TYPE_PIXELATION: { fShader[0] = pixelFShaderStr; break; } - case 5: + case SHADER_TYPE_SEPIA: { fShader[0] = colorMatrixFShaderStr; break; } - case 6: + case SHADER_TYPE_SKETCH: { fShader[0] = sketchShaderStr; vShader[0] = v3x3ShaderStr; break; } - case 8: + case SHADER_TYPE_TOON: { fShader[0] = toonFShaderStr; vShader[0] = v3x3ShaderStr; break; } - case 9: + case SHADER_TYPE_VIGNETTE: { fShader[0] = vignetteFShaderStr; break; } - case 10: + case SHADER_TYPE_GRAYSCALE: { fShader[0] = grayScaleShaderStr; break; } - case 12: + case SHADER_TYPE_BLUR: { fShader[0] = blurShaderStr; break; } + default: + vShader[0] = vShaderStr; + break; } m_ProgramObj = GLUtils::CreateProgram(vShader[0], fShader[0], m_VertexShader, @@ -708,56 +714,62 @@ void EGLRender::UseProgram() { } } -void EGLRender::GlUniform(char* strLocation, float value, int unType) { - GLint location = glGetUniformLocation(m_ProgramObj, strLocation); +void EGLRender::GlUniform(char* location, float value, int unType) { + GLint ll = glGetUniformLocation(m_ProgramObj, location); switch(unType) { - case 0: - glUniform1i(location, (int)value); + case UNIFORM_TYPE_ZERO: + glUniform1i(ll, (int)value); break; - case 1: - glUniform1f(location, value); + case UNIFORM_TYPE_ONE: + glUniform1f(ll, value); + break; + default: break; } } -void EGLRender::GlUniformArray(char* strLocation, float* value, int unType) { - GLint location = glGetUniformLocation(m_ProgramObj, strLocation); +void EGLRender::GlUniformArray(char* location, float* value, int unType) { + GLint ll = glGetUniformLocation(m_ProgramObj, location); switch(unType) { - case 10: + case UNIFORM_TYPE_2FV_SIZE: GLfloat vec2[2]; vec2[0] = value[0] * m_RenderImage.width; vec2[1] = value[1] * m_RenderImage.height; - glUniform2fv(location, 1, vec2); + glUniform2fv(ll, 1, vec2); break; - case 21: - glUniform2f(location, value[0], value[1]); + case UNIFORM_TYPE_2F: + glUniform2f(ll, value[0], value[1]); break; - case 1: - glUniform1fv(location, 1, value); + case UNIFORM_TYPE_FV: + glUniform1fv(ll, 1, value); break; - case 2: - glUniform2fv(location, 1, value); + case UNIFORM_TYPE_2FV: + glUniform2fv(ll, 1, value); break; - case 3: - glUniform3fv(location, 1, value); + case UNIFORM_TYPE_3FV: + glUniform3fv(ll, 1, value); break; - case 4: - glUniform4fv(location, 1, value); + case UNIFORM_TYPE_4FV: + glUniform4fv(ll, 1, value); + break; + default: break; } } -void EGLRender::GlUniformMatrix(char* strLocation, float* value, int unType) { - GLint location = glGetUniformLocation(m_ProgramObj, strLocation); +void EGLRender::GlUniformMatrix(char* location, float* value, int unType) { + GLint ll = glGetUniformLocation(m_ProgramObj, location); switch(unType) { - case 3: - glUniformMatrix3fv(location, 1, false,value); + case UNIFORM_TYPE_THREE: + glUniformMatrix3fv(ll, 1, false,value); break; - case 4: - glUniformMatrix4fv(location, 1, false, value); + case UNIFORM_TYPE_FOUR: + glUniformMatrix4fv(ll, 1, false, value); + break; + default: break; } } @@ -771,28 +783,28 @@ void EGLRender::UnInit() { if(m_ImageTextureId) { - glDeleteTextures(1, &m_ImageTextureId); + glDeleteTextures(DEFAULT_ONE, &m_ImageTextureId); m_ImageTextureId = GL_NONE; } if (m_FboTextureId) { - glDeleteTextures(1, &m_FboTextureId); + glDeleteTextures(DEFAULT_ONE, &m_FboTextureId); m_FboTextureId = GL_NONE; } - if (m_VboIds[0]) + if (m_VboIds[DEFAULT_ZERO]) { - glDeleteBuffers(3, m_VboIds); - m_VboIds[0] = GL_NONE; - m_VboIds[1] = GL_NONE; - m_VboIds[2] = GL_NONE; + glDeleteBuffers(DEFAULT_THREE, m_VboIds); + m_VboIds[DEFAULT_ZERO] = GL_NONE; + m_VboIds[DEFAULT_ONE] = GL_NONE; + m_VboIds[DEFAULT_TWO] = GL_NONE; } - if (m_VaoIds[0]) + if (m_VaoIds[DEFAULT_ZERO]) { - glDeleteVertexArrays(1, m_VaoIds); - m_VaoIds[0] = GL_NONE; + glDeleteVertexArrays(DEFAULT_ONE, m_VaoIds); + m_VaoIds[DEFAULT_ZERO] = GL_NONE; } if (m_FboId) diff --git a/gpu_transform/src/main/cpp/render/EGLRender.h b/gpu_transform/src/main/cpp/render/EGLRender.h index 07ae4d5..df3c02c 100644 --- a/gpu_transform/src/main/cpp/render/EGLRender.h +++ b/gpu_transform/src/main/cpp/render/EGLRender.h @@ -28,7 +28,7 @@ #include #include "NativeImage.h" -#define EGL_FEATURE_NUM 7 +const int EGL_FEATURE_NUM = 7; class EGLRender { diff --git a/gpu_transform/src/main/cpp/util/NativeImage.h b/gpu_transform/src/main/cpp/util/NativeImage.h index f15b367..b7c3d47 100644 --- a/gpu_transform/src/main/cpp/util/NativeImage.h +++ b/gpu_transform/src/main/cpp/util/NativeImage.h @@ -30,6 +30,7 @@ #include #include "DebugLog.h" #include +#include "constant/constant_shape.h" #define IMAGE_FORMAT_RGBA 0x01 #define IMAGE_FORMAT_NV21 0x02 @@ -55,16 +56,16 @@ struct NativeImage int width; int height; int format; - uint8_t *ppPlane[3]; + uint8_t *ppPlane[DEFAULT_THREE]; NativeImage() { - width = 0; - height = 0; - format = 0; - ppPlane[0] = nullptr; - ppPlane[1] = nullptr; - ppPlane[2] = nullptr; + width = DEFAULT_ZERO; + height = DEFAULT_ZERO; + format = DEFAULT_ZERO; + ppPlane[DEFAULT_ZERO] = nullptr; + ppPlane[DEFAULT_ONE] = nullptr; + ppPlane[DEFAULT_TWO] = nullptr; } }; @@ -73,49 +74,49 @@ class NativeImageUtil public: static void AllocNativeImage(NativeImage *pImage) { - if (pImage ->height ==0 || pImage ->width == 0) return; + if (pImage ->height == DEFAULT_ZERO || pImage ->width == DEFAULT_ZERO) return; switch(pImage -> format) { case IMAGE_FORMAT_RGBA: { - pImage->ppPlane[0] = static_cast(malloc(pImage->width * pImage ->height * 4)); + pImage->ppPlane[DEFAULT_ZERO] = static_cast(malloc(pImage->width * pImage ->height * DEFAULT_FOUR)); } - break; + break; case IMAGE_FORMAT_YUYV: { - pImage->ppPlane[0] = static_cast(malloc(pImage->width * pImage ->height * 2)); + pImage->ppPlane[DEFAULT_ZERO] = static_cast(malloc(pImage->width * pImage ->height * DEFAULT_TWO)); } - break; + break; case IMAGE_FORMAT_NV12: case IMAGE_FORMAT_NV21: { - pImage->ppPlane[0] = static_cast(malloc(pImage->width * pImage ->height * 1.5)); - pImage->ppPlane[1] = pImage->ppPlane[0] + pImage->width * pImage->height; + pImage->ppPlane[DEFAULT_ZERO] = static_cast(malloc(pImage->width * pImage ->height * DEFAULT_ONE_HALF)); + pImage->ppPlane[DEFAULT_ONE] = pImage->ppPlane[DEFAULT_ZERO] + pImage->width * pImage->height; } - break; + break; case IMAGE_FORMAT_I420: { - pImage->ppPlane[0] = static_cast(malloc(pImage->width * pImage ->height * 1.5)); - pImage->ppPlane[1] = pImage->ppPlane[0] + pImage->width * pImage->height; - pImage->ppPlane[2] = pImage->ppPlane[1] + pImage->width * (pImage->height >> 2); + pImage->ppPlane[DEFAULT_ZERO] = static_cast(malloc(pImage->width * pImage ->height * DEFAULT_ONE_HALF)); + pImage->ppPlane[DEFAULT_ONE] = pImage->ppPlane[DEFAULT_ZERO] + pImage->width * pImage->height; + pImage->ppPlane[DEFAULT_TWO] = pImage->ppPlane[DEFAULT_ONE] + pImage->width * (pImage->height >> DEFAULT_TWO); } - break; + break; case IMAGE_FORMAT_GRAY: { - pImage->ppPlane[0] = static_cast(malloc(pImage->width * pImage ->height)); + pImage->ppPlane[DEFAULT_ZERO] = static_cast(malloc(pImage->width * pImage ->height)); } - break; + break; case IMAGE_FORMAT_I444: { - pImage->ppPlane[0] = static_cast(malloc(pImage->width * pImage ->height * 3)); + pImage->ppPlane[DEFAULT_ZERO] = static_cast(malloc(pImage->width * pImage ->height * DEFAULT_THREE)); } - break; + break; case IMAGE_FORMAT_P010: { - pImage->ppPlane[0] = static_cast(malloc(pImage->width * pImage ->height * 3)); - pImage->ppPlane[1] = pImage->ppPlane[0] + pImage->width * pImage->height * 2; + pImage->ppPlane[DEFAULT_ZERO] = static_cast(malloc(pImage->width * pImage ->height * DEFAULT_THREE)); + pImage->ppPlane[DEFAULT_ONE] = pImage->ppPlane[DEFAULT_ZERO] + pImage->width * pImage->height * DEFAULT_TWO; } - break; + break; default: break; } @@ -123,22 +124,20 @@ class NativeImageUtil static void FreeNativeImage(NativeImage *pImage) { - if (pImage == nullptr || pImage->ppPlane[0] == nullptr) return; - free(pImage->ppPlane[0]); - pImage->ppPlane[0] = nullptr; - pImage->ppPlane[1] = nullptr; - pImage->ppPlane[2] = nullptr; + if (pImage == nullptr || pImage->ppPlane[DEFAULT_ZERO] == nullptr) return; + free(pImage->ppPlane[DEFAULT_ZERO]); + pImage->ppPlane[DEFAULT_ZERO] = nullptr; + pImage->ppPlane[DEFAULT_ONE] = nullptr; + pImage->ppPlane[DEFAULT_TWO] = nullptr; } static bool CreateArrayBuffer(napi_env env, void* src, size_t srcLen, napi_value *res) { - if (src == nullptr || srcLen == 0) - { + if (src == nullptr || srcLen == DEFAULT_ZERO) { return false; } void *nativePtr = nullptr; - if (napi_create_arraybuffer(env, srcLen, &nativePtr, res) != napi_ok || nativePtr == nullptr) - { + if (napi_create_arraybuffer(env, srcLen, &nativePtr, res) != napi_ok || nativePtr == nullptr) { return false; } memcpy(nativePtr, src, srcLen); @@ -147,16 +146,16 @@ class NativeImageUtil static void flip(uint8_t** buf, int width, int height) { - int totalLength = width * height * 4; - int oneLineLength = width * 4; + int totalLength = width * height * DEFAULT_FOUR; + int oneLineLength = width * DEFAULT_FOUR; uint8_t* tmp = (uint8_t*)malloc(totalLength); memcpy(tmp, *buf, totalLength); - memset(*buf, 0, sizeof(uint8_t)*totalLength); - for(int i = 0; i < height; i++) { + memset(*buf, DEFAULT_ZERO, sizeof(uint8_t)*totalLength); + for (int i = 0; i < height; i++) { memcpy(*buf + oneLineLength * i, tmp + totalLength - oneLineLength * (i+1), oneLineLength); } free(tmp); } }; -#endif //GPU_ImageETS_NativeImage_H +#endif // GPU_ImageETS_NativeImage_H diff --git a/package.json b/package.json index fbc532c..d7dc956 100644 --- a/package.json +++ b/package.json @@ -1,19 +1,19 @@ { - "license": "ISC", - "devDependencies": {}, - "name": "imageknife", - "ohos": { - "org": "huawei", - "directoryLevel": "project", - "buildTool": "hvigor" + "license":"ISC", + "devDependencies":{}, + "name":"imageknife", + "ohos":{ + "org":"huawei", + "directoryLevel":"project", + "buildTool":"hvigor" }, - "description": "example description", - "repository": {}, - "version": "1.0.0", - "dependencies": { - "@ohos/hypium": "1.0.3", - "@ohos/hvigor-ohos-plugin": "1.3.1", - "hypium": "^1.0.0", - "@ohos/hvigor": "1.3.1" + "description":"example description", + "repository":{}, + "version":"1.0.0", + "dependencies":{ + "@ohos/hypium":"1.0.3", + "@ohos/hvigor-ohos-plugin":"1.3.1", + "hypium":"^1.0.0", + "@ohos/hvigor":"1.3.1" } -} +} \ No newline at end of file From 83014e5457dc45a0e97079fda15133c6ec89dabb Mon Sep 17 00:00:00 2001 From: tyBrave Date: Mon, 6 Feb 2023 10:29:22 +0800 Subject: [PATCH 04/10] update code,because of code check Signed-off-by: tyBrave --- .../src/main/cpp/common/native_common.h | 2 +- .../src/main/cpp/constant/constant_shape.h | 33 +-- gpu_transform/src/main/cpp/napi/napi_init.cpp | 1 - .../src/main/cpp/render/EGLRender.cpp | 237 +++++++++++------- gpu_transform/src/main/cpp/render/EGLRender.h | 2 +- gpu_transform/src/main/cpp/util/DebugLog.h | 2 +- gpu_transform/src/main/cpp/util/GLUtils.cpp | 14 +- gpu_transform/src/main/cpp/util/GLUtils.h | 2 +- gpu_transform/src/main/cpp/util/NapiUtil.cpp | 6 +- gpu_transform/src/main/cpp/util/NapiUtil.h | 2 +- gpu_transform/src/main/cpp/util/NativeImage.h | 11 +- 11 files changed, 184 insertions(+), 128 deletions(-) diff --git a/gpu_transform/src/main/cpp/common/native_common.h b/gpu_transform/src/main/cpp/common/native_common.h index 4d21ea1..b4e4c78 100644 --- a/gpu_transform/src/main/cpp/common/native_common.h +++ b/gpu_transform/src/main/cpp/common/native_common.h @@ -30,7 +30,7 @@ napi_get_last_error_info((env),&errorInfo); \ bool isPending = false; \ napi_is_exception_pending((env),&isPending); \ - if(!isPending && errorInfo != nullptr) { \ + if (!isPending && errorInfo != nullptr) { \ const char* errorMessage = \ errorInfo->error_message != nullptr ? errorInfo->error_message : "empty error message"; \ napi_throw_error((env),nullptr,errorMessage); \ diff --git a/gpu_transform/src/main/cpp/constant/constant_shape.h b/gpu_transform/src/main/cpp/constant/constant_shape.h index b3a5f23..e846f36 100644 --- a/gpu_transform/src/main/cpp/constant/constant_shape.h +++ b/gpu_transform/src/main/cpp/constant/constant_shape.h @@ -115,8 +115,7 @@ const char v3x3ShaderStr[] = "bottomRightTextureCoordinate = a_texCoord + widthHeightStep;\n" "}"; - -//kuwahara +// kuwahara const char fShaderStr3[] = "#version 300 es\n" "precision highp float;\n" @@ -201,8 +200,7 @@ const char fShaderStr3[] = "}\n" "}\n"; - -//旋转 +// 旋转 const char swirlFShaderStr[] = "#version 300 es\n" "precision highp float;\n" @@ -228,8 +226,7 @@ const char swirlFShaderStr[] = "outColor = texture(s_TextureMap, tc / u_texSize);\n" "}"; - -//亮度 +// 亮度 const char brightFShaderStr[] = "#version 300 es\n" "precision highp float;\n" @@ -246,7 +243,7 @@ const char brightFShaderStr[] = "outColor = vec4((textureColor.rgb + vec3(brightness)), textureColor.w);\n" "}"; -//反转 +// 反转 const char contrastFShaderStr[] = "#version 300 es\n" "precision highp float;\n" @@ -263,7 +260,7 @@ const char contrastFShaderStr[] = "outColor = vec4(((textureColor.rgb - vec3(0.5)) * contrast + vec3(0.5)), textureColor.w);\n" "}"; -//invert +// invert const char invertFShaderStr[] = "#version 300 es\n" "precision highp float;\n" @@ -279,7 +276,7 @@ const char invertFShaderStr[] = "outColor = vec4((1.0 - textureColor.rgb), textureColor.w);\n" "}"; -//pixel +// pixel const char pixelFShaderStr[] = "#version 300 es\n" "precision highp float;\n" @@ -300,7 +297,7 @@ const char pixelFShaderStr[] = "outColor = vec4(tc, 1.0);\n" "}"; -//vignette +// vignette const char vignetteFShaderStr[] = "#version 300 es\n" "precision highp float;\n" @@ -326,8 +323,7 @@ const char vignetteFShaderStr[] = "outColor = vec4(mix(rgb2.x,vignetteColor.x,percent), mix(rgb2.y, vignetteColor.y, percent), mix(rgb2.z, vignetteColor.z, percent), 1.0);\n" "}"; - -//ColorMatrix +// ColorMatrix const char colorMatrixFShaderStr[] = "#version 300 es\n" "precision highp float;\n" @@ -344,8 +340,7 @@ const char colorMatrixFShaderStr[] = "outColor = (intensity * outputColor) + ((1.0 - intensity) * textureColor);\n" "}"; - -//toon +// toon const char toonFShaderStr[] = "#version 300 es\n" "precision highp float;\n" @@ -386,9 +381,7 @@ const char toonFShaderStr[] = "outColor = vec4(posterizedImageColor * thresholdTest, textureColor.a);\n" "}"; - - -//grayScale +// grayScale const char grayScaleShaderStr[] = "#version 300 es\n" "precision highp float;\n" @@ -403,7 +396,7 @@ const char grayScaleShaderStr[] = "outColor = vec4(vec3(luminance), textureColor.a);\n" "}"; -//sketch +// sketch const char sketchShaderStr[] = "#version 300 es\n" "precision highp float;\n" @@ -438,7 +431,7 @@ const char sketchShaderStr[] = "outColor = vec4(vec3(mag), 1.0);\n" "}"; -//blur +// blur const char blurShaderStr[] = "#version 300 es\n" "precision highp float;\n" @@ -480,4 +473,4 @@ const char blurShaderStr[] = "outColor = vec4(finalColor, sourceColor.a);\n" "}\n"; -#endif //GPU_ImageETS_constant_shape_H +#endif // GPU_ImageETS_constant_shape_H diff --git a/gpu_transform/src/main/cpp/napi/napi_init.cpp b/gpu_transform/src/main/cpp/napi/napi_init.cpp index da6b550..9f7a6a2 100644 --- a/gpu_transform/src/main/cpp/napi/napi_init.cpp +++ b/gpu_transform/src/main/cpp/napi/napi_init.cpp @@ -63,7 +63,6 @@ static napi_value Init(napi_env env, napi_value exports) { DECLARE_NAPI_FUNCTION("EglIsInit",EGLRender:: EGLIsInit), DECLARE_NAPI_FUNCTION("EglDestroy",EGLRender:: DestroyGlesEnv), - DECLARE_NAPI_FUNCTION("EglUseProgram",EGLRender:: StartUseProgram), DECLARE_NAPI_FUNCTION("EglRendering",EGLRender:: Rendering), diff --git a/gpu_transform/src/main/cpp/render/EGLRender.cpp b/gpu_transform/src/main/cpp/render/EGLRender.cpp index d23a2a0..54eba24 100644 --- a/gpu_transform/src/main/cpp/render/EGLRender.cpp +++ b/gpu_transform/src/main/cpp/render/EGLRender.cpp @@ -21,7 +21,6 @@ #include "EGLRender.h" -#include "native_common.h" #include #include #include @@ -30,6 +29,7 @@ #include #include #include +#include "native_common.h" #include "DebugLog.h" #include "constant/constant_shape.h" #include "GLUtils.h" @@ -44,34 +44,35 @@ const int TEXTURE_POS_LOC = 1; const int32_t STR_DEFAULT_SIZE = 1024; EGLRender *EGLRender::sInstance = nullptr; -//顶点坐标 +// 顶点坐标 const GLfloat vVertices[] = { - -1.0f, -1.0f, 0.0f, //bottom left - 1.0f, -1.0f, 0.0f, //bottom right - -1.0f, 1.0f, 0.0f, //top left - 1.0f, 1.0f, 0.0f, //top right + -1.0f, -1.0f, 0.0f, // bottom left + 1.0f, -1.0f, 0.0f, // bottom right + -1.0f, 1.0f, 0.0f, // top left + 1.0f, 1.0f, 0.0f, // top right }; -//正常纹理坐标 +// 正常纹理坐标 const GLfloat vTexCoors[] = { - 0.0f, 1.0f, //bottom left - 1.0f, 1.0f, //bottom right - 0.0f, 0.0f, //top left - 1.0f, 0.0f, //top right + 0.0f, 1.0f, // bottom left + 1.0f, 1.0f, // bottom right + 0.0f, 0.0f, // top left + 1.0f, 0.0f, // top right }; -//fbo 纹理坐标与正常纹理方向不同(上下镜像) +// fbo 纹理坐标与正常纹理方向不同(上下镜像) const GLfloat vFboTexCoors[] = { - 0.0f, 0.0f, //bottom left - 1.0f, 0.0f, //bottom right - 0.0f, 1.0f, //top left - 1.0f, 1.0f, //top right + 0.0f, 0.0f, // bottom left + 1.0f, 0.0f, // bottom right + 0.0f, 1.0f, // top left + 1.0f, 1.0f, // top right }; const GLushort indices[] = { 0, 1, 2, 1, 3, 2 }; -napi_value EGLRender::RenderInit(napi_env env, napi_callback_info info) { +napi_value EGLRender::RenderInit(napi_env env, napi_callback_info info) +{ napi_value exports; NAPI_CALL(env, napi_create_object(env, &exports)); @@ -85,7 +86,8 @@ napi_value EGLRender::RenderInit(napi_env env, napi_callback_info info) { } -napi_value EGLRender::RenderSetData(napi_env env, napi_callback_info info) { +napi_value EGLRender::RenderSetData(napi_env env, napi_callback_info info) +{ size_t argc = 3; napi_value args[3] = { nullptr }; napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); @@ -93,19 +95,22 @@ napi_value EGLRender::RenderSetData(napi_env env, napi_callback_info info) { void* buffer; size_t bufferLength; napi_status buffStatus = napi_get_arraybuffer_info(env, args[0], &buffer, &bufferLength); - if (buffStatus != napi_ok) { + if (buffStatus != napi_ok) + { return nullptr; } uint8_t* uint8_buf = reinterpret_cast(buffer); uint32_t width; napi_status wStatus = napi_get_value_uint32(env, args[1], &width); - if (wStatus != napi_ok) { + if (wStatus != napi_ok) + { return nullptr; } uint32_t height; napi_status hStatus = napi_get_value_uint32(env, args[2], &height); - if (hStatus != napi_ok) { + if (hStatus != napi_ok) + { return nullptr; } @@ -113,7 +118,8 @@ napi_value EGLRender::RenderSetData(napi_env env, napi_callback_info info) { return nullptr; } -napi_value EGLRender::RenderSetIntParams(napi_env env, napi_callback_info info) { +napi_value EGLRender::RenderSetIntParams(napi_env env, napi_callback_info info) +{ LOGI("gl--> RenderSetIntParams start"); size_t argc = 2; napi_value args[2] = { nullptr }; @@ -121,44 +127,51 @@ napi_value EGLRender::RenderSetIntParams(napi_env env, napi_callback_info info) uint32_t type; napi_status tStatus = napi_get_value_uint32(env, args[0], &type); - if (tStatus != napi_ok) { + if (tStatus != napi_ok) + { return nullptr; } uint32_t param; napi_status pStatus = napi_get_value_uint32(env, args[1], ¶m); - if (pStatus != napi_ok) { + if (pStatus != napi_ok) + { return nullptr; } EGLRender::GetInstance() -> SetIntParams(type, param); return nullptr; } -napi_value EGLRender::GetPixelMapOfSurface(napi_env env, napi_callback_info info) { +napi_value EGLRender::GetPixelMapOfSurface(napi_env env, napi_callback_info info) +{ size_t argc = 4; napi_value args[4] = { nullptr }; napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); uint32_t x; napi_status xStatus = napi_get_value_uint32(env, args[0], &x); - if (xStatus != napi_ok) { + if (xStatus != napi_ok) + { return nullptr; } uint32_t y; napi_status yStatus = napi_get_value_uint32(env, args[1], &y); - if (yStatus != napi_ok) { + if (yStatus != napi_ok) + { return nullptr; } uint32_t surfaceWidth; napi_status swStatus = napi_get_value_uint32(env, args[2], &surfaceWidth); - if (swStatus != napi_ok) { + if (swStatus != napi_ok) + { return nullptr; } uint32_t surfaceHeight; napi_status shStatus = napi_get_value_uint32(env, args[3], &surfaceHeight); - if (shStatus != napi_ok) { + if (shStatus != napi_ok) + { return nullptr; } @@ -170,47 +183,55 @@ napi_value EGLRender::GetPixelMapOfSurface(napi_env env, napi_callback_info info NativeImageUtil::flip(&pixels, surfaceWidth, surfaceHeight); napi_value array; int byte_length = surfaceWidth * surfaceHeight * DEFAULT_FOUR; - if (!NativeImageUtil::CreateArrayBuffer(env, pixels, byte_length, &array)) { + if (!NativeImageUtil::CreateArrayBuffer(env, pixels, byte_length, &array)) + { LOGI("gl--> GetPixelMapOfSurface error"); } free(pixels); return array; } -napi_value EGLRender::EGLIsInit(napi_env env, napi_callback_info info) { +napi_value EGLRender::EGLIsInit(napi_env env, napi_callback_info info) +{ napi_value isInit; int32_t value; - if (EGLRender::GetInstance() -> m_IsGLContextReady) { + if (EGLRender::GetInstance() -> m_IsGLContextReady) + { value = 1; }else { value = 0; } napi_status status = napi_create_int32(env, value, &isInit); - if (status != napi_ok) { + if (status != napi_ok) + { return nullptr; } return isInit; } -napi_value EGLRender::DestroyGlesEnv(napi_env env, napi_callback_info info) { +napi_value EGLRender::DestroyGlesEnv(napi_env env, napi_callback_info info) +{ EGLRender::GetInstance() -> UnInit(); return nullptr; } -napi_value EGLRender::StartUseProgram(napi_env env, napi_callback_info info) { +napi_value EGLRender::StartUseProgram(napi_env env, napi_callback_info info) +{ EGLRender::GetInstance() -> UseProgram(); return nullptr; } -napi_value EGLRender::Rendering(napi_env env, napi_callback_info info) { - //7 . 渲染 +napi_value EGLRender::Rendering(napi_env env, napi_callback_info info) +{ + // 渲染 glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, (const void *)0); glBindVertexArray(GL_NONE); glBindTexture(GL_TEXTURE_2D, GL_NONE); return nullptr; } -napi_value EGLRender::setTypeArrayOfFloat(napi_env env, napi_callback_info info) { +napi_value EGLRender::setTypeArrayOfFloat(napi_env env, napi_callback_info info) +{ size_t argc = 3; napi_value args[3] = { nullptr }; @@ -231,7 +252,8 @@ napi_value EGLRender::setTypeArrayOfFloat(napi_env env, napi_callback_info info) size_t bufferLength; size_t byte_offset; napi_status buffStatus = napi_get_typedarray_info(env, args[2], &dataType, &bufferLength, &buffer, &args[2], &byte_offset); - if (buffStatus != napi_ok){ + if (buffStatus != napi_ok) + { return nullptr; } @@ -239,15 +261,20 @@ napi_value EGLRender::setTypeArrayOfFloat(napi_env env, napi_callback_info info) int uniformType; - if (strcmp(key, "glUniform2fv") == 0) { + if (strcmp(key, "glUniform2fv") == 0) + { uniformType = UNIFORM_TYPE_2FV; - }else if (strcmp(key, "glUniform3fv") == 0) { + }else if (strcmp(key, "glUniform3fv") == 0) + { uniformType = UNIFORM_TYPE_3FV; - }else if (strcmp(key, "glUniform4fv") == 0) { + }else if (strcmp(key, "glUniform4fv") == 0) + { uniformType = UNIFORM_TYPE_4FV; - }else if (strcmp(key, "glUniform1fv") == 0) { + }else if (strcmp(key, "glUniform1fv") == 0) + { uniformType = UNIFORM_TYPE_FV; - }else if (strcmp(key, "glUniform2f") == 0) { + }else if (strcmp(key, "glUniform2f") == 0) + { uniformType = UNIFORM_TYPE_2F; } @@ -255,7 +282,8 @@ napi_value EGLRender::setTypeArrayOfFloat(napi_env env, napi_callback_info info) return nullptr; } -napi_value EGLRender::setTypeArrayOfMatrix3f(napi_env env, napi_callback_info info) { +napi_value EGLRender::setTypeArrayOfMatrix3f(napi_env env, napi_callback_info info) +{ size_t argc = 2; napi_value args[2] = { nullptr }; napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); @@ -270,7 +298,8 @@ napi_value EGLRender::setTypeArrayOfMatrix3f(napi_env env, napi_callback_info in size_t bufferLength; size_t byte_offset; napi_status buffStatus = napi_get_typedarray_info(env, args[1], &dataType, &bufferLength, &buffer, &args[1], &byte_offset); - if (buffStatus != napi_ok){ + if (buffStatus != napi_ok) + { return nullptr; } @@ -281,7 +310,8 @@ napi_value EGLRender::setTypeArrayOfMatrix3f(napi_env env, napi_callback_info in return nullptr; } -napi_value EGLRender::setTypeArrayOfMatrix4f(napi_env env, napi_callback_info info) { +napi_value EGLRender::setTypeArrayOfMatrix4f(napi_env env, napi_callback_info info) +{ size_t argc = 2; napi_value args[2] = { nullptr }; napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); @@ -296,7 +326,8 @@ napi_value EGLRender::setTypeArrayOfMatrix4f(napi_env env, napi_callback_info in size_t bufferLength; size_t byte_offset; napi_status buffStatus = napi_get_typedarray_info(env, args[1], &dataType, &bufferLength, &buffer, &args[1], &byte_offset); - if (buffStatus != napi_ok){ + if (buffStatus != napi_ok) + { return nullptr; } @@ -306,8 +337,9 @@ napi_value EGLRender::setTypeArrayOfMatrix4f(napi_env env, napi_callback_info in return nullptr; } -napi_value EGLRender::RenderGlUniform1i(napi_env env, napi_callback_info info) { - //int +napi_value EGLRender::RenderGlUniform1i(napi_env env, napi_callback_info info) +{ + // int size_t argc = 2; napi_value args[2] = { nullptr }; napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); @@ -316,15 +348,17 @@ napi_value EGLRender::RenderGlUniform1i(napi_env env, napi_callback_info info) { NapiUtil::JsValueToString(env, args[0], STR_DEFAULT_SIZE, content); uint32_t value; napi_status status = napi_get_value_uint32(env, args[1], &value); - if (status != napi_ok) { + if (status != napi_ok) + { return nullptr; } EGLRender::GetInstance() -> GlUniform((char*)content.c_str(), value, UNIFORM_TYPE_ZERO); return nullptr; } -napi_value EGLRender::RenderGlUniform1f(napi_env env, napi_callback_info info) { - //float +napi_value EGLRender::RenderGlUniform1f(napi_env env, napi_callback_info info) +{ + // float size_t argc = 2; napi_value args[2] = { nullptr }; napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); @@ -333,15 +367,17 @@ napi_value EGLRender::RenderGlUniform1f(napi_env env, napi_callback_info info) { NapiUtil::JsValueToString(env, args[0], STR_DEFAULT_SIZE, content); double value; napi_status status = napi_get_value_double(env, args[1], &value); - if (status != napi_ok) { + if (status != napi_ok) + { return nullptr; } EGLRender::GetInstance() -> GlUniform((char*)content.c_str(), value, UNIFORM_TYPE_ONE); return nullptr; } -napi_value EGLRender::RenderGlUniform2fv(napi_env env, napi_callback_info info) { - //float 数组 +napi_value EGLRender::RenderGlUniform2fv(napi_env env, napi_callback_info info) +{ + // float 数组 size_t argc = 3; napi_value args[3] = { nullptr }; napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); @@ -351,12 +387,14 @@ napi_value EGLRender::RenderGlUniform2fv(napi_env env, napi_callback_info info) double value; napi_status status = napi_get_value_double(env, args[1], &value); - if (status != napi_ok) { + if (status != napi_ok) + { return nullptr; } double value2; napi_status status2 = napi_get_value_double(env, args[2], &value2); - if (status2 != napi_ok) { + if (status2 != napi_ok) + { return nullptr; } @@ -367,7 +405,8 @@ napi_value EGLRender::RenderGlUniform2fv(napi_env env, napi_callback_info info) return nullptr; } -EGLRender::EGLRender() { +EGLRender::EGLRender() +{ m_ImageTextureId = GL_NONE; m_FboTextureId = GL_NONE; m_SamplerLoc = GL_NONE; @@ -382,19 +421,22 @@ EGLRender::EGLRender() { m_ShaderIndex = 0; } -EGLRender::~EGLRender() { +EGLRender::~EGLRender() +{ } -void EGLRender::Init() { +void EGLRender::Init() +{ if (CreateGlEnv() == 0) { m_IsGLContextReady = true; } - if (!m_IsGLContextReady) { + if (!m_IsGLContextReady) + { return; } - glGenTextures(1, &m_ImageTextureId); //生成纹理名称 - glBindTexture(GL_TEXTURE_2D, m_ImageTextureId); //允许建立一个绑定到目标纹理的有名称的纹理 + glGenTextures(1, &m_ImageTextureId); // 生成纹理名称 + glBindTexture(GL_TEXTURE_2D, m_ImageTextureId); // 允许建立一个绑定到目标纹理的有名称的纹理 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); @@ -412,7 +454,8 @@ void EGLRender::Init() { m_ProgramObj = GLUtils::CreateProgram(vShaderStr, fShaderStr0, m_VertexShader, m_FragmentShader); - if (!m_ProgramObj) { + if (!m_ProgramObj) + { GLUtils::CheckGLError("Create Program"); return; } @@ -448,7 +491,8 @@ void EGLRender::Init() { glBindVertexArray(GL_NONE); } -int EGLRender::CreateGlEnv() { +int EGLRender::CreateGlEnv() +{ const EGLint confAttr[] = { EGL_RENDERABLE_TYPE, EGL_OPENGL_ES3_BIT_KHR, @@ -480,26 +524,30 @@ int EGLRender::CreateGlEnv() { do { m_eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); - if (m_eglDisplay == EGL_NO_DISPLAY) { + if (m_eglDisplay == EGL_NO_DISPLAY) + { resultCode = -1; break; } // 初始化 egl 方法 - if (!eglInitialize(m_eglDisplay, &eglMajVers, &eglMinVers)) { + if (!eglInitialize(m_eglDisplay, &eglMajVers, &eglMinVers)) + { resultCode = -1; break; } - //获取 EGLConfig 对象,确定渲染表面的配置信息 - if (!eglChooseConfig(m_eglDisplay, confAttr, &m_eglConf, 1, &numConfigs)) { + // 获取 EGLConfig 对象,确定渲染表面的配置信息 + if (!eglChooseConfig(m_eglDisplay, confAttr, &m_eglConf, 1, &numConfigs)) + { resultCode = -1; break; } // 创建渲染表面 EGLSurface 使用 eglCreateBufferSurface 创建屏幕外渲染区域 m_eglSurface = eglCreatePbufferSurface(m_eglDisplay, m_eglConf, surfaceAttr); - if (m_eglSurface == EGL_NO_SURFACE) { + if (m_eglSurface == EGL_NO_SURFACE) + { switch(eglGetError()) { case EGL_BAD_ALLOC: @@ -525,7 +573,7 @@ int EGLRender::CreateGlEnv() { if (m_eglCtx == EGL_NO_CONTEXT) { EGLint error = eglGetError(); - if (error == EGL_BAD_CONFIG) + if (error == EGL_BAD_CONFIG) { LOGI("gl-->::CreateGlesEnv EGL_BAD_CONFIG"); resultCode = -1; @@ -533,8 +581,8 @@ int EGLRender::CreateGlEnv() { } } - //绑定上下文 - if(!eglMakeCurrent(m_eglDisplay, m_eglSurface, m_eglSurface, m_eglCtx)) + // 绑定上下文 + if (!eglMakeCurrent(m_eglDisplay, m_eglSurface, m_eglSurface, m_eglCtx)) { resultCode = -1; break; @@ -542,7 +590,7 @@ int EGLRender::CreateGlEnv() { LOGI("gl-->::CreateGlesEnv initialize success"); } while (false); - if(resultCode != 0) + if (resultCode != 0) { LOGI("gl-->::CreateGlesEnv fail"); } @@ -550,7 +598,8 @@ int EGLRender::CreateGlEnv() { return resultCode; } -void EGLRender::SetImageData(uint8_t *pData, int width, int height) { +void EGLRender::SetImageData(uint8_t *pData, int width, int height) +{ if (pData && m_IsGLContextReady) { if (m_RenderImage.ppPlane[0]) @@ -576,7 +625,8 @@ void EGLRender::SetImageData(uint8_t *pData, int width, int height) { glBindTexture(GL_TEXTURE_2D, m_FboTextureId); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_FboTextureId, 0); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_RenderImage.width, m_RenderImage.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); - if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { + if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) + { LOGI("gl--> EGLRender ::SetImageData glCheckFramebufferStatus status != GL_FRAMEBUFFER_COMPLETE"); } glBindTexture(GL_TEXTURE_2D, GL_NONE); @@ -586,7 +636,8 @@ void EGLRender::SetImageData(uint8_t *pData, int width, int height) { } } -void EGLRender::SetIntParams(int paramType, int param) { +void EGLRender::SetIntParams(int paramType, int param) +{ LOGI("gl--> EGLRender::SetIntParams paramType = %{public}d,param = %{public}d", paramType, param); switch(paramType) { @@ -690,14 +741,15 @@ void EGLRender::SetIntParams(int paramType, int param) { } } -void EGLRender::UseProgram() { +void EGLRender::UseProgram() +{ if (m_ProgramObj == GL_NONE) return; glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClear(GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glViewport(0, 0, m_RenderImage.width, m_RenderImage.height); - //DO FBO off screen rendering + // DO FBO off screen rendering glUseProgram(m_ProgramObj); glBindFramebuffer(GL_FRAMEBUFFER, m_FboId); @@ -706,7 +758,8 @@ void EGLRender::UseProgram() { glBindTexture(GL_TEXTURE_2D, m_ImageTextureId); glUniform1i(m_SamplerLoc, 0); - if (m_TexSizeLoc > -1) { + if (m_TexSizeLoc > -1) + { GLfloat size[2]; size[0] = m_RenderImage.width; size[1] = m_RenderImage.height; @@ -714,7 +767,8 @@ void EGLRender::UseProgram() { } } -void EGLRender::GlUniform(char* location, float value, int unType) { +void EGLRender::GlUniform(char* location, float value, int unType) +{ GLint ll = glGetUniformLocation(m_ProgramObj, location); switch(unType) { @@ -729,7 +783,8 @@ void EGLRender::GlUniform(char* location, float value, int unType) { } } -void EGLRender::GlUniformArray(char* location, float* value, int unType) { +void EGLRender::GlUniformArray(char* location, float* value, int unType) +{ GLint ll = glGetUniformLocation(m_ProgramObj, location); switch(unType) { @@ -759,7 +814,8 @@ void EGLRender::GlUniformArray(char* location, float* value, int unType) { } } -void EGLRender::GlUniformMatrix(char* location, float* value, int unType) { +void EGLRender::GlUniformMatrix(char* location, float* value, int unType) +{ GLint ll = glGetUniformLocation(m_ProgramObj, location); switch(unType) { @@ -774,14 +830,15 @@ void EGLRender::GlUniformMatrix(char* location, float* value, int unType) { } } -void EGLRender::UnInit() { +void EGLRender::UnInit() +{ if (m_ProgramObj) { glDeleteProgram(m_ProgramObj); m_ProgramObj = GL_NONE; } - if(m_ImageTextureId) + if (m_ImageTextureId) { glDeleteTextures(DEFAULT_ONE, &m_ImageTextureId); m_ImageTextureId = GL_NONE; @@ -818,9 +875,11 @@ void EGLRender::UnInit() { m_IsGLContextReady = false; } } -void EGLRender::DestroyGl() { - //释放 EGL 环境 - if (m_eglDisplay != EGL_NO_DISPLAY) { +void EGLRender::DestroyGl() +{ + // 释放 EGL 环境 + if (m_eglDisplay != EGL_NO_DISPLAY) + { eglMakeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); eglDestroyContext(m_eglDisplay, m_eglCtx); eglDestroySurface(m_eglDisplay, m_eglSurface); diff --git a/gpu_transform/src/main/cpp/render/EGLRender.h b/gpu_transform/src/main/cpp/render/EGLRender.h index df3c02c..7b889bc 100644 --- a/gpu_transform/src/main/cpp/render/EGLRender.h +++ b/gpu_transform/src/main/cpp/render/EGLRender.h @@ -117,4 +117,4 @@ class EGLRender { }; -#endif //GPU_ImageETS_EGLRender_H +#endif // GPU_ImageETS_EGLRender_H diff --git a/gpu_transform/src/main/cpp/util/DebugLog.h b/gpu_transform/src/main/cpp/util/DebugLog.h index 5ab3f74..bf5bee5 100644 --- a/gpu_transform/src/main/cpp/util/DebugLog.h +++ b/gpu_transform/src/main/cpp/util/DebugLog.h @@ -29,4 +29,4 @@ #define LOGW(...)((void)OH_LOG_Print(LOG_APP, LOG_WARN, LOG_DOMAIN, "OH_GPU_LOG", __VA_ARGS__)) #define LOGE(...)((void)OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_DOMAIN, "OH_GPU_LOG", __VA_ARGS__)) -#endif //GPU_ImageETS_DebugLog_H +#endif // GPU_ImageETS_DebugLog_H diff --git a/gpu_transform/src/main/cpp/util/GLUtils.cpp b/gpu_transform/src/main/cpp/util/GLUtils.cpp index 8e0c2b3..e3adbfa 100644 --- a/gpu_transform/src/main/cpp/util/GLUtils.cpp +++ b/gpu_transform/src/main/cpp/util/GLUtils.cpp @@ -19,10 +19,10 @@ // Node APIs are not fully supported. To solve the compilation error of the interface cannot be found, // please include "napi/native_api.h". -#include "GLUtils.h" -#include "DebugLog.h" #include #include +#include "GLUtils.h" +#include "DebugLog.h" GLuint GLUtils::LoadShader(GLenum shaderType, const char *pSource) { @@ -34,7 +34,8 @@ GLuint GLUtils::LoadShader(GLenum shaderType, const char *pSource) glCompileShader(shader); GLint compiled = 0; glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled); - if (!compiled) { + if (!compiled) + { GLint infoLen = 0; glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen); if (infoLen) @@ -62,7 +63,7 @@ GLuint GLUtils::CreateProgram(const char *pVertexShaderSource, const char *pFrag if (!fragShaderHandle) return program; program = glCreateProgram(); - if(program) + if (program) { glAttachShader(program, vertexShaderHandle); CheckGLError("glAttachShader"); @@ -79,7 +80,7 @@ GLuint GLUtils::CreateProgram(const char *pVertexShaderSource, const char *pFrag glDeleteShader(fragShaderHandle); fragShaderHandle = 0; - if(linkStatus != GL_TRUE) + if (linkStatus != GL_TRUE) { GLint bufLength = 0; glGetProgramiv(program,GL_INFO_LOG_LENGTH, &bufLength); @@ -101,9 +102,8 @@ GLuint GLUtils::CreateProgram(const char *pVertexShaderSource, const char *pFrag void GLUtils::CheckGLError(const char *pGLOperation) { - for(GLint error = glGetError(); error; error = glGetError()) + for (GLint error = glGetError(); error; error = glGetError()) { LOGI("GLUtils::CheckGLError GL Operation %{public}s() glError (0x%x)\n", pGLOperation, error); - } } diff --git a/gpu_transform/src/main/cpp/util/GLUtils.h b/gpu_transform/src/main/cpp/util/GLUtils.h index 3dccdfa..ff126da 100644 --- a/gpu_transform/src/main/cpp/util/GLUtils.h +++ b/gpu_transform/src/main/cpp/util/GLUtils.h @@ -34,4 +34,4 @@ class GLUtils { static void CheckGLError(const char *pGLOperation); }; -#endif //GPU_ImageETS_GLUtils_H +#endif // GPU_ImageETS_GLUtils_H diff --git a/gpu_transform/src/main/cpp/util/NapiUtil.cpp b/gpu_transform/src/main/cpp/util/NapiUtil.cpp index 30df64b..bdb8889 100644 --- a/gpu_transform/src/main/cpp/util/NapiUtil.cpp +++ b/gpu_transform/src/main/cpp/util/NapiUtil.cpp @@ -20,18 +20,20 @@ // please include "napi/native_api.h". #include "NapiUtil.h" -#include "DebugLog.h" + #include #include #include #include #include +#include "DebugLog.h" const int32_t MAX_STR_LENGTH = 1024; void NapiUtil::JsValueToString(const napi_env &env, const napi_value &value, const int32_t bufLen, std::string &target) { - if (bufLen <= 0 || bufLen > MAX_STR_LENGTH) { + if (bufLen <= 0 || bufLen > MAX_STR_LENGTH) + { LOGI("%s string too long malloc failed",__func__); return; } diff --git a/gpu_transform/src/main/cpp/util/NapiUtil.h b/gpu_transform/src/main/cpp/util/NapiUtil.h index 34c02fd..bab7edd 100644 --- a/gpu_transform/src/main/cpp/util/NapiUtil.h +++ b/gpu_transform/src/main/cpp/util/NapiUtil.h @@ -32,4 +32,4 @@ class NapiUtil { std::string &target); }; -#endif //GPU_ImageETS_NapiUtil_H +#endif // GPU_ImageETS_NapiUtil_H diff --git a/gpu_transform/src/main/cpp/util/NativeImage.h b/gpu_transform/src/main/cpp/util/NativeImage.h index b7c3d47..dafb083 100644 --- a/gpu_transform/src/main/cpp/util/NativeImage.h +++ b/gpu_transform/src/main/cpp/util/NativeImage.h @@ -28,8 +28,8 @@ #include #include #include -#include "DebugLog.h" #include +#include "DebugLog.h" #include "constant/constant_shape.h" #define IMAGE_FORMAT_RGBA 0x01 @@ -133,11 +133,13 @@ class NativeImageUtil static bool CreateArrayBuffer(napi_env env, void* src, size_t srcLen, napi_value *res) { - if (src == nullptr || srcLen == DEFAULT_ZERO) { + if (src == nullptr || srcLen == DEFAULT_ZERO) + { return false; } void *nativePtr = nullptr; - if (napi_create_arraybuffer(env, srcLen, &nativePtr, res) != napi_ok || nativePtr == nullptr) { + if (napi_create_arraybuffer(env, srcLen, &nativePtr, res) != napi_ok || nativePtr == nullptr) + { return false; } memcpy(nativePtr, src, srcLen); @@ -151,7 +153,8 @@ class NativeImageUtil uint8_t* tmp = (uint8_t*)malloc(totalLength); memcpy(tmp, *buf, totalLength); memset(*buf, DEFAULT_ZERO, sizeof(uint8_t)*totalLength); - for (int i = 0; i < height; i++) { + for (int i = 0; i < height; i++) + { memcpy(*buf + oneLineLength * i, tmp + totalLength - oneLineLength * (i+1), oneLineLength); } free(tmp); From d18694a96e804113a4ca08928a7f974394717cf5 Mon Sep 17 00:00:00 2001 From: tyBrave Date: Mon, 6 Feb 2023 17:21:37 +0800 Subject: [PATCH 05/10] update code,because of code check Signed-off-by: tyBrave --- .../src/main/cpp/common/native_common.h | 48 +-- .../src/main/cpp/constant/constant_shape.h | 28 +- gpu_transform/src/main/cpp/napi/napi_init.cpp | 33 +- .../src/main/cpp/render/EGLRender.cpp | 349 ++++++++---------- gpu_transform/src/main/cpp/render/EGLRender.h | 20 +- gpu_transform/src/main/cpp/util/GLUtils.cpp | 48 ++- gpu_transform/src/main/cpp/util/GLUtils.h | 2 +- gpu_transform/src/main/cpp/util/NapiUtil.cpp | 12 +- gpu_transform/src/main/cpp/util/NapiUtil.h | 4 +- gpu_transform/src/main/cpp/util/NativeImage.h | 80 ++-- 10 files changed, 282 insertions(+), 342 deletions(-) diff --git a/gpu_transform/src/main/cpp/common/native_common.h b/gpu_transform/src/main/cpp/common/native_common.h index b4e4c78..3a8442b 100644 --- a/gpu_transform/src/main/cpp/common/native_common.h +++ b/gpu_transform/src/main/cpp/common/native_common.h @@ -24,34 +24,34 @@ #define NAPI_RETVAL_NOTHING -#define GET_AND_THROW_LAST_ERROR(env) \ - do { \ - const napi_extended_error_info* errorInfo = nullptr; \ - napi_get_last_error_info((env),&errorInfo); \ - bool isPending = false; \ - napi_is_exception_pending((env),&isPending); \ - if (!isPending && errorInfo != nullptr) { \ - const char* errorMessage = \ - errorInfo->error_message != nullptr ? errorInfo->error_message : "empty error message"; \ - napi_throw_error((env),nullptr,errorMessage); \ - } \ - } while (0) +#define GET_AND_THROW_LAST_ERROR(env) \ + do { \ + const napi_extended_error_info* errorInfo = nullptr; \ + napi_get_last_error_info((env), &errorInfo); \ + bool isPending = false; \ + napi_is_exception_pending((env), &isPending); \ + if (!isPending && errorInfo != nullptr) { \ + const char* errorMessage = \ + errorInfo->error_message != nullptr ? errorInfo->error_message : "empty error message"; \ + napi_throw_error((env), nullptr, errorMessage); \ + } \ + } while (0) -#define DECLARE_NAPI_FUNCTION(name, func) \ - { \ - (name),nullptr,(func),nullptr,nullptr,nullptr,napi_default,nullptr \ - } +#define DECLARE_NAPI_FUNCTION(name, func) \ + { \ + (name), nullptr, (func), nullptr, nullptr, nullptr, napi_default, nullptr \ + } -#define NAPI_CALL_BASE(env, theCall, retVal) \ - do { \ - if((theCall) != napi_ok) { \ - GET_AND_THROW_LAST_ERROR((env)); \ - return retVal; \ - } \ - } while (0) +#define NAPI_CALL_BASE(env, theCall, retVal) \ + do { \ + if ((theCall) != napi_ok) { \ + GET_AND_THROW_LAST_ERROR((env)); \ + return retVal; \ + } \ + } while (0) #define NAPI_CALL(env, theCall) NAPI_CALL_BASE(env, theCall, nullptr) -#endif //GPU_ImageETS_native_common_H +#endif // GPU_ImageETS_native_common_H diff --git a/gpu_transform/src/main/cpp/constant/constant_shape.h b/gpu_transform/src/main/cpp/constant/constant_shape.h index e846f36..78de807 100644 --- a/gpu_transform/src/main/cpp/constant/constant_shape.h +++ b/gpu_transform/src/main/cpp/constant/constant_shape.h @@ -57,7 +57,7 @@ const int SHADER_TYPE_GRAYSCALE = 10; const int SHADER_TYPE_BLUR = 12; -const char vShaderStr[] = +const char vShaderStr[] = "#version 300 es \n" "layout(location = 0) in vec4 a_position; \n" "layout(location = 1) in vec2 a_texCoord; \n" @@ -79,7 +79,7 @@ const char fShaderStr0[] = "outColor = texture(s_TextureMap,v_texCoord); \n" "} \n"; -const char v3x3ShaderStr[] = +const char v3x3ShaderStr[] = "#version 300 es\n" "precision highp float;\n" "layout(location = 0) in vec4 a_position;\n" @@ -116,7 +116,7 @@ const char v3x3ShaderStr[] = "}"; // kuwahara -const char fShaderStr3[] = +const char fShaderStr3[] = "#version 300 es\n" "precision highp float;\n" "layout(location = 0) out vec4 outColor;\n" @@ -201,7 +201,7 @@ const char fShaderStr3[] = "}\n"; // 旋转 -const char swirlFShaderStr[] = +const char swirlFShaderStr[] = "#version 300 es\n" "precision highp float;\n" "layout(location = 0) out vec4 outColor;\n" @@ -227,7 +227,7 @@ const char swirlFShaderStr[] = "}"; // 亮度 -const char brightFShaderStr[] = +const char brightFShaderStr[] = "#version 300 es\n" "precision highp float;\n" "in vec2 v_texCoord;\n" @@ -244,7 +244,7 @@ const char brightFShaderStr[] = "}"; // 反转 -const char contrastFShaderStr[] = +const char contrastFShaderStr[] = "#version 300 es\n" "precision highp float;\n" "in vec2 v_texCoord;\n" @@ -261,7 +261,7 @@ const char contrastFShaderStr[] = "}"; // invert -const char invertFShaderStr[] = +const char invertFShaderStr[] = "#version 300 es\n" "precision highp float;\n" "in vec2 v_texCoord;\n" @@ -277,7 +277,7 @@ const char invertFShaderStr[] = "}"; // pixel -const char pixelFShaderStr[] = +const char pixelFShaderStr[] = "#version 300 es\n" "precision highp float;\n" "in vec2 v_texCoord;\n" @@ -298,7 +298,7 @@ const char pixelFShaderStr[] = "}"; // vignette -const char vignetteFShaderStr[] = +const char vignetteFShaderStr[] = "#version 300 es\n" "precision highp float;\n" "uniform lowp sampler2D s_TextureMap;\n" @@ -324,7 +324,7 @@ const char vignetteFShaderStr[] = "}"; // ColorMatrix -const char colorMatrixFShaderStr[] = +const char colorMatrixFShaderStr[] = "#version 300 es\n" "precision highp float;\n" "in vec2 v_texCoord;\n" @@ -341,7 +341,7 @@ const char colorMatrixFShaderStr[] = "}"; // toon -const char toonFShaderStr[] = +const char toonFShaderStr[] = "#version 300 es\n" "precision highp float;\n" "in vec2 v_texCoord;\n" @@ -382,7 +382,7 @@ const char toonFShaderStr[] = "}"; // grayScale -const char grayScaleShaderStr[] = +const char grayScaleShaderStr[] = "#version 300 es\n" "precision highp float;\n" "in vec2 v_texCoord;\n" @@ -397,7 +397,7 @@ const char grayScaleShaderStr[] = "}"; // sketch -const char sketchShaderStr[] = +const char sketchShaderStr[] = "#version 300 es\n" "precision highp float;\n" "layout(location = 0) out vec4 outColor;\n" @@ -432,7 +432,7 @@ const char sketchShaderStr[] = "}"; // blur -const char blurShaderStr[] = +const char blurShaderStr[] = "#version 300 es\n" "precision highp float;\n" "uniform lowp sampler2D s_TextureMap;\n" diff --git a/gpu_transform/src/main/cpp/napi/napi_init.cpp b/gpu_transform/src/main/cpp/napi/napi_init.cpp index 9f7a6a2..667d663 100644 --- a/gpu_transform/src/main/cpp/napi/napi_init.cpp +++ b/gpu_transform/src/main/cpp/napi/napi_init.cpp @@ -54,28 +54,29 @@ static napi_value Add(napi_env env, napi_callback_info info) } -static napi_value Init(napi_env env, napi_value exports) { +static napi_value Init(napi_env env, napi_value exports) +{ napi_property_descriptor desc[] = { - DECLARE_NAPI_FUNCTION("EglRenderInit",EGLRender:: RenderInit), - DECLARE_NAPI_FUNCTION("EglRenderSetImageData",EGLRender:: RenderSetData), - DECLARE_NAPI_FUNCTION("EglPixelMapSurface",EGLRender:: GetPixelMapOfSurface), - DECLARE_NAPI_FUNCTION("EglRenderSetIntParams",EGLRender:: RenderSetIntParams), - DECLARE_NAPI_FUNCTION("EglIsInit",EGLRender:: EGLIsInit), - DECLARE_NAPI_FUNCTION("EglDestroy",EGLRender:: DestroyGlesEnv), + DECLARE_NAPI_FUNCTION("EglRenderInit", EGLRender:: RenderInit), + DECLARE_NAPI_FUNCTION("EglRenderSetImageData", EGLRender:: RenderSetData), + DECLARE_NAPI_FUNCTION("EglPixelMapSurface", EGLRender:: GetPixelMapOfSurface), + DECLARE_NAPI_FUNCTION("EglRenderSetIntParams", EGLRender:: RenderSetIntParams), + DECLARE_NAPI_FUNCTION("EglIsInit", EGLRender:: EGLIsInit), + DECLARE_NAPI_FUNCTION("EglDestroy", EGLRender:: DestroyGlesEnv), - DECLARE_NAPI_FUNCTION("EglUseProgram",EGLRender:: StartUseProgram), - DECLARE_NAPI_FUNCTION("EglRendering",EGLRender:: Rendering), + DECLARE_NAPI_FUNCTION("EglUseProgram", EGLRender:: StartUseProgram), + DECLARE_NAPI_FUNCTION("EglRendering", EGLRender:: Rendering), - DECLARE_NAPI_FUNCTION("EglUniform1i",EGLRender:: RenderGlUniform1i), - DECLARE_NAPI_FUNCTION("EglUniform1f",EGLRender:: RenderGlUniform1f), - DECLARE_NAPI_FUNCTION("EglUniform2fv",EGLRender:: RenderGlUniform2fv), + DECLARE_NAPI_FUNCTION("EglUniform1i", EGLRender:: RenderGlUniform1i), + DECLARE_NAPI_FUNCTION("EglUniform1f", EGLRender:: RenderGlUniform1f), + DECLARE_NAPI_FUNCTION("EglUniform2fv", EGLRender:: RenderGlUniform2fv), - DECLARE_NAPI_FUNCTION("EglSetTypeArrayOfFloat",EGLRender:: setTypeArrayOfFloat), + DECLARE_NAPI_FUNCTION("EglSetTypeArrayOfFloat", EGLRender:: setTypeArrayOfFloat), - DECLARE_NAPI_FUNCTION("EglSetTypeArrayOfMatrix3f",EGLRender:: setTypeArrayOfMatrix3f), - DECLARE_NAPI_FUNCTION("EglSetTypeArrayOfMatrix4f",EGLRender:: setTypeArrayOfMatrix4f), + DECLARE_NAPI_FUNCTION("EglSetTypeArrayOfMatrix3f", EGLRender:: setTypeArrayOfMatrix3f), + DECLARE_NAPI_FUNCTION("EglSetTypeArrayOfMatrix4f", EGLRender:: setTypeArrayOfMatrix4f), }; - NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]),desc)); + NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc)); return exports; } diff --git a/gpu_transform/src/main/cpp/render/EGLRender.cpp b/gpu_transform/src/main/cpp/render/EGLRender.cpp index 54eba24..bce24f5 100644 --- a/gpu_transform/src/main/cpp/render/EGLRender.cpp +++ b/gpu_transform/src/main/cpp/render/EGLRender.cpp @@ -45,7 +45,7 @@ const int32_t STR_DEFAULT_SIZE = 1024; EGLRender *EGLRender::sInstance = nullptr; // 顶点坐标 -const GLfloat vVertices[] = { +const static GLfloat vVertices[] = { -1.0f, -1.0f, 0.0f, // bottom left 1.0f, -1.0f, 0.0f, // bottom right -1.0f, 1.0f, 0.0f, // top left @@ -53,7 +53,7 @@ const GLfloat vVertices[] = { }; // 正常纹理坐标 -const GLfloat vTexCoors[] = { +const static GLfloat vTexCoors[] = { 0.0f, 1.0f, // bottom left 1.0f, 1.0f, // bottom right 0.0f, 0.0f, // top left @@ -61,28 +61,24 @@ const GLfloat vTexCoors[] = { }; // fbo 纹理坐标与正常纹理方向不同(上下镜像) -const GLfloat vFboTexCoors[] = { +const static GLfloat vFboTexCoors[] = { 0.0f, 0.0f, // bottom left 1.0f, 0.0f, // bottom right 0.0f, 1.0f, // top left 1.0f, 1.0f, // top right }; -const GLushort indices[] = { 0, 1, 2, 1, 3, 2 }; +const static GLushort indices[] = { 0, 1, 2, 1, 3, 2 }; napi_value EGLRender::RenderInit(napi_env env, napi_callback_info info) { napi_value exports; - NAPI_CALL(env, napi_create_object(env, &exports)); - napi_property_descriptor desc[] = { - - }; - NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]),desc)); - + napi_property_descriptor desc[] = {}; + NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc)); EGLRender::GetInstance() ->Init(); - return exports; + return exports; } @@ -91,26 +87,22 @@ napi_value EGLRender::RenderSetData(napi_env env, napi_callback_info info) size_t argc = 3; napi_value args[3] = { nullptr }; napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); - void* buffer; size_t bufferLength; napi_status buffStatus = napi_get_arraybuffer_info(env, args[0], &buffer, &bufferLength); - if (buffStatus != napi_ok) - { + if (buffStatus != napi_ok) { return nullptr; } uint8_t* uint8_buf = reinterpret_cast(buffer); uint32_t width; napi_status wStatus = napi_get_value_uint32(env, args[1], &width); - if (wStatus != napi_ok) - { + if (wStatus != napi_ok) { return nullptr; } uint32_t height; napi_status hStatus = napi_get_value_uint32(env, args[2], &height); - if (hStatus != napi_ok) - { + if (hStatus != napi_ok) { return nullptr; } @@ -123,20 +115,18 @@ napi_value EGLRender::RenderSetIntParams(napi_env env, napi_callback_info info) LOGI("gl--> RenderSetIntParams start"); size_t argc = 2; napi_value args[2] = { nullptr }; - napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); + napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); uint32_t type; napi_status tStatus = napi_get_value_uint32(env, args[0], &type); - if (tStatus != napi_ok) - { + if (tStatus != napi_ok) { return nullptr; } uint32_t param; napi_status pStatus = napi_get_value_uint32(env, args[1], ¶m); - if (pStatus != napi_ok) - { + if (pStatus != napi_ok) { return nullptr; - } + } EGLRender::GetInstance() -> SetIntParams(type, param); return nullptr; } @@ -145,35 +135,31 @@ napi_value EGLRender::GetPixelMapOfSurface(napi_env env, napi_callback_info info { size_t argc = 4; napi_value args[4] = { nullptr }; - napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); + napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); uint32_t x; napi_status xStatus = napi_get_value_uint32(env, args[0], &x); - if (xStatus != napi_ok) - { + if (xStatus != napi_ok) { return nullptr; } uint32_t y; napi_status yStatus = napi_get_value_uint32(env, args[1], &y); - if (yStatus != napi_ok) - { + if (yStatus != napi_ok) { return nullptr; - } + } uint32_t surfaceWidth; napi_status swStatus = napi_get_value_uint32(env, args[2], &surfaceWidth); - if (swStatus != napi_ok) - { + if (swStatus != napi_ok) { return nullptr; - } + } uint32_t surfaceHeight; napi_status shStatus = napi_get_value_uint32(env, args[3], &surfaceHeight); - if (shStatus != napi_ok) - { + if (shStatus != napi_ok) { return nullptr; - } + } uint8_t* pixels = (uint8_t*) malloc(surfaceWidth * surfaceHeight * DEFAULT_FOUR); @@ -183,8 +169,7 @@ napi_value EGLRender::GetPixelMapOfSurface(napi_env env, napi_callback_info info NativeImageUtil::flip(&pixels, surfaceWidth, surfaceHeight); napi_value array; int byte_length = surfaceWidth * surfaceHeight * DEFAULT_FOUR; - if (!NativeImageUtil::CreateArrayBuffer(env, pixels, byte_length, &array)) - { + if (!NativeImageUtil::CreateArrayBuffer(env, pixels, byte_length, &array)) { LOGI("gl--> GetPixelMapOfSurface error"); } free(pixels); @@ -195,15 +180,13 @@ napi_value EGLRender::EGLIsInit(napi_env env, napi_callback_info info) { napi_value isInit; int32_t value; - if (EGLRender::GetInstance() -> m_IsGLContextReady) - { + if (EGLRender::GetInstance() -> m_IsGLContextReady) { value = 1; }else { value = 0; } napi_status status = napi_create_int32(env, value, &isInit); - if (status != napi_ok) - { + if (status != napi_ok) { return nullptr; } return isInit; @@ -232,10 +215,9 @@ napi_value EGLRender::Rendering(napi_env env, napi_callback_info info) napi_value EGLRender::setTypeArrayOfFloat(napi_env env, napi_callback_info info) { - size_t argc = 3; napi_value args[3] = { nullptr }; - napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); + napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); std::string locationContent; NapiUtil::JsValueToString(env, args[0], STR_DEFAULT_SIZE, locationContent); @@ -251,9 +233,9 @@ napi_value EGLRender::setTypeArrayOfFloat(napi_env env, napi_callback_info info) void* buffer; size_t bufferLength; size_t byte_offset; - napi_status buffStatus = napi_get_typedarray_info(env, args[2], &dataType, &bufferLength, &buffer, &args[2], &byte_offset); - if (buffStatus != napi_ok) - { + napi_status buffStatus = napi_get_typedarray_info(env, + args[2], &dataType, &bufferLength, &buffer, &args[2], &byte_offset); + if (buffStatus != napi_ok) { return nullptr; } @@ -261,20 +243,15 @@ napi_value EGLRender::setTypeArrayOfFloat(napi_env env, napi_callback_info info) int uniformType; - if (strcmp(key, "glUniform2fv") == 0) - { + if (strcmp(key, "glUniform2fv") == 0) { uniformType = UNIFORM_TYPE_2FV; - }else if (strcmp(key, "glUniform3fv") == 0) - { + }else if (strcmp(key, "glUniform3fv") == 0) { uniformType = UNIFORM_TYPE_3FV; - }else if (strcmp(key, "glUniform4fv") == 0) - { + }else if (strcmp(key, "glUniform4fv") == 0) { uniformType = UNIFORM_TYPE_4FV; - }else if (strcmp(key, "glUniform1fv") == 0) - { + }else if (strcmp(key, "glUniform1fv") == 0) { uniformType = UNIFORM_TYPE_FV; - }else if (strcmp(key, "glUniform2f") == 0) - { + }else if (strcmp(key, "glUniform2f") == 0) { uniformType = UNIFORM_TYPE_2F; } @@ -286,7 +263,7 @@ napi_value EGLRender::setTypeArrayOfMatrix3f(napi_env env, napi_callback_info in { size_t argc = 2; napi_value args[2] = { nullptr }; - napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); + napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); std::string locationContent; NapiUtil::JsValueToString(env, args[0], STR_DEFAULT_SIZE, locationContent); @@ -297,9 +274,9 @@ napi_value EGLRender::setTypeArrayOfMatrix3f(napi_env env, napi_callback_info in void* buffer; size_t bufferLength; size_t byte_offset; - napi_status buffStatus = napi_get_typedarray_info(env, args[1], &dataType, &bufferLength, &buffer, &args[1], &byte_offset); - if (buffStatus != napi_ok) - { + napi_status buffStatus = napi_get_typedarray_info(env, + args[1], &dataType, &bufferLength, &buffer, &args[1], &byte_offset); + if (buffStatus != napi_ok) { return nullptr; } @@ -314,7 +291,7 @@ napi_value EGLRender::setTypeArrayOfMatrix4f(napi_env env, napi_callback_info in { size_t argc = 2; napi_value args[2] = { nullptr }; - napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); + napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); std::string locationContent; NapiUtil::JsValueToString(env, args[0], STR_DEFAULT_SIZE, locationContent); @@ -325,9 +302,9 @@ napi_value EGLRender::setTypeArrayOfMatrix4f(napi_env env, napi_callback_info in void* buffer; size_t bufferLength; size_t byte_offset; - napi_status buffStatus = napi_get_typedarray_info(env, args[1], &dataType, &bufferLength, &buffer, &args[1], &byte_offset); - if (buffStatus != napi_ok) - { + napi_status buffStatus = napi_get_typedarray_info(env, + args[1], &dataType, &bufferLength, &buffer, &args[1], &byte_offset); + if (buffStatus != napi_ok) { return nullptr; } @@ -342,14 +319,13 @@ napi_value EGLRender::RenderGlUniform1i(napi_env env, napi_callback_info info) // int size_t argc = 2; napi_value args[2] = { nullptr }; - napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); + napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); std::string content; NapiUtil::JsValueToString(env, args[0], STR_DEFAULT_SIZE, content); uint32_t value; napi_status status = napi_get_value_uint32(env, args[1], &value); - if (status != napi_ok) - { + if (status != napi_ok) { return nullptr; } EGLRender::GetInstance() -> GlUniform((char*)content.c_str(), value, UNIFORM_TYPE_ZERO); @@ -361,14 +337,13 @@ napi_value EGLRender::RenderGlUniform1f(napi_env env, napi_callback_info info) // float size_t argc = 2; napi_value args[2] = { nullptr }; - napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); + napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); std::string content; NapiUtil::JsValueToString(env, args[0], STR_DEFAULT_SIZE, content); double value; napi_status status = napi_get_value_double(env, args[1], &value); - if (status != napi_ok) - { + if (status != napi_ok) { return nullptr; } EGLRender::GetInstance() -> GlUniform((char*)content.c_str(), value, UNIFORM_TYPE_ONE); @@ -380,21 +355,19 @@ napi_value EGLRender::RenderGlUniform2fv(napi_env env, napi_callback_info info) // float 数组 size_t argc = 3; napi_value args[3] = { nullptr }; - napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); + napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); std::string content; NapiUtil::JsValueToString(env, args[0], STR_DEFAULT_SIZE, content); double value; napi_status status = napi_get_value_double(env, args[1], &value); - if (status != napi_ok) - { + if (status != napi_ok) { return nullptr; } double value2; napi_status status2 = napi_get_value_double(env, args[2], &value2); - if (status2 != napi_ok) - { + if (status2 != napi_ok) { return nullptr; } @@ -419,19 +392,16 @@ EGLRender::EGLRender() m_eglDisplay = nullptr; m_IsGLContextReady = false; m_ShaderIndex = 0; - } EGLRender::~EGLRender() { } void EGLRender::Init() { - if (CreateGlEnv() == 0) - { + if (CreateGlEnv() == 0) { m_IsGLContextReady = true; } - if (!m_IsGLContextReady) - { + if (!m_IsGLContextReady) { return; } @@ -448,14 +418,12 @@ void EGLRender::Init() glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glBindTexture(GL_TEXTURE_2D, GL_NONE); - m_ProgramObj = GLUtils::CreateProgram(vShaderStr, fShaderStr0, m_VertexShader, - m_FragmentShader); - if (!m_ProgramObj) - { + m_FragmentShader); + if (!m_ProgramObj) { GLUtils::CheckGLError("Create Program"); return; } @@ -469,7 +437,7 @@ void EGLRender::Init() glBufferData(GL_ARRAY_BUFFER, sizeof(vFboTexCoors), vTexCoors, GL_STATIC_DRAW); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_VboIds[DEFAULT_TWO]); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); // Generate VAO Ids glGenVertexArrays(DEFAULT_ONE, m_VaoIds); @@ -479,13 +447,22 @@ void EGLRender::Init() glBindBuffer(GL_ARRAY_BUFFER, m_VboIds[DEFAULT_ZERO]); glEnableVertexAttribArray(VERTEX_POS_LOC); - glVertexAttribPointer(VERTEX_POS_LOC, DEFAULT_THREE, GL_FLOAT, GL_FALSE, DEFAULT_THREE * sizeof(GLfloat), (const void *)DEFAULT_ZERO); - glBindBuffer(GL_ARRAY_BUFFER,GL_NONE); + glVertexAttribPointer(VERTEX_POS_LOC, + DEFAULT_THREE, + GL_FLOAT, GL_FALSE, + DEFAULT_THREE * sizeof(GLfloat), + (const void *)DEFAULT_ZERO); + glBindBuffer(GL_ARRAY_BUFFER, GL_NONE); glBindBuffer(GL_ARRAY_BUFFER, m_VboIds[DEFAULT_ONE]); glEnableVertexAttribArray(TEXTURE_POS_LOC); - glVertexAttribPointer(TEXTURE_POS_LOC, DEFAULT_TWO, GL_FLOAT, GL_FALSE, DEFAULT_TWO * sizeof(GLfloat), (const void *)DEFAULT_ZERO); - glBindBuffer(GL_ARRAY_BUFFER,GL_NONE); + glVertexAttribPointer(TEXTURE_POS_LOC, + DEFAULT_TWO, + GL_FLOAT, + GL_FALSE, + DEFAULT_TWO * sizeof(GLfloat), + (const void *)DEFAULT_ZERO); + glBindBuffer(GL_ARRAY_BUFFER, GL_NONE); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_VboIds[DEFAULT_TWO]); glBindVertexArray(GL_NONE); @@ -493,7 +470,7 @@ void EGLRender::Init() int EGLRender::CreateGlEnv() { - const EGLint confAttr[] = + const EGLint confAttr[] = { EGL_RENDERABLE_TYPE, EGL_OPENGL_ES3_BIT_KHR, EGL_SURFACE_TYPE, EGL_PBUFFER_BIT, @@ -506,14 +483,14 @@ int EGLRender::CreateGlEnv() EGL_NONE }; // EGL context attributes - const EGLint ctxAttr[] = { + const EGLint ctxAttr[] = + { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; - // surface attributes - // the surface size is set to the input frame size - const EGLint surfaceAttr[] = { + const EGLint surfaceAttr[] = + { EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE @@ -521,35 +498,29 @@ int EGLRender::CreateGlEnv() EGLint eglMajVers, eglMinVers; EGLint numConfigs; int resultCode = 0; - do - { + do { m_eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); - if (m_eglDisplay == EGL_NO_DISPLAY) - { + if (m_eglDisplay == EGL_NO_DISPLAY) { resultCode = -1; break; } // 初始化 egl 方法 - if (!eglInitialize(m_eglDisplay, &eglMajVers, &eglMinVers)) - { + if (!eglInitialize(m_eglDisplay, &eglMajVers, &eglMinVers)) { resultCode = -1; break; } // 获取 EGLConfig 对象,确定渲染表面的配置信息 - if (!eglChooseConfig(m_eglDisplay, confAttr, &m_eglConf, 1, &numConfigs)) - { + if (!eglChooseConfig(m_eglDisplay, confAttr, &m_eglConf, 1, &numConfigs)) { resultCode = -1; break; } // 创建渲染表面 EGLSurface 使用 eglCreateBufferSurface 创建屏幕外渲染区域 m_eglSurface = eglCreatePbufferSurface(m_eglDisplay, m_eglConf, surfaceAttr); - if (m_eglSurface == EGL_NO_SURFACE) - { - switch(eglGetError()) - { + if (m_eglSurface == EGL_NO_SURFACE) { + switch(eglGetError()) { case EGL_BAD_ALLOC: LOGI("gl-->::CreateGlesEnv Not enough resources available"); break; @@ -570,28 +541,24 @@ int EGLRender::CreateGlEnv() // 创建渲染上下文 EGLContext m_eglCtx = eglCreateContext(m_eglDisplay, m_eglConf, EGL_NO_CONTEXT, ctxAttr); - if (m_eglCtx == EGL_NO_CONTEXT) - { + if (m_eglCtx == EGL_NO_CONTEXT) { EGLint error = eglGetError(); - if (error == EGL_BAD_CONFIG) - { + if (error == EGL_BAD_CONFIG) { LOGI("gl-->::CreateGlesEnv EGL_BAD_CONFIG"); resultCode = -1; break; - } + } } // 绑定上下文 - if (!eglMakeCurrent(m_eglDisplay, m_eglSurface, m_eglSurface, m_eglCtx)) - { + if (!eglMakeCurrent(m_eglDisplay, m_eglSurface, m_eglSurface, m_eglCtx)) { resultCode = -1; break; - } + } LOGI("gl-->::CreateGlesEnv initialize success"); } while (false); - if (resultCode != 0) - { + if (resultCode != 0) { LOGI("gl-->::CreateGlesEnv fail"); } @@ -600,10 +567,8 @@ int EGLRender::CreateGlEnv() void EGLRender::SetImageData(uint8_t *pData, int width, int height) { - if (pData && m_IsGLContextReady) - { - if (m_RenderImage.ppPlane[0]) - { + if (pData && m_IsGLContextReady) { + if (m_RenderImage.ppPlane[0]) { NativeImageUtil::FreeNativeImage(&m_RenderImage); m_RenderImage.ppPlane[0] = nullptr; } @@ -614,106 +579,103 @@ void EGLRender::SetImageData(uint8_t *pData, int width, int height) memcpy(m_RenderImage.ppPlane[0], pData, width * height * DEFAULT_FOUR); glBindTexture(GL_TEXTURE_2D, m_ImageTextureId); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_RenderImage.width, m_RenderImage.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, m_RenderImage.ppPlane[0]); + glTexImage2D(GL_TEXTURE_2D, + 0, + GL_RGBA, + m_RenderImage.width, + m_RenderImage.height, + 0, + GL_RGBA, + GL_UNSIGNED_BYTE, + m_RenderImage.ppPlane[0]); glBindTexture(GL_TEXTURE_2D, GL_NONE); - if (m_FboId == GL_NONE) - { + if (m_FboId == GL_NONE) { // Create FBO glGenFramebuffers(1, &m_FboId); glBindFramebuffer(GL_FRAMEBUFFER, m_FboId); glBindTexture(GL_TEXTURE_2D, m_FboTextureId); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_FboTextureId, 0); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_RenderImage.width, m_RenderImage.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); - if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) - { + glTexImage2D(GL_TEXTURE_2D, + 0, + GL_RGBA, + m_RenderImage.width, + m_RenderImage.height, + 0, + GL_RGBA, + GL_UNSIGNED_BYTE, + nullptr); + if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { LOGI("gl--> EGLRender ::SetImageData glCheckFramebufferStatus status != GL_FRAMEBUFFER_COMPLETE"); } glBindTexture(GL_TEXTURE_2D, GL_NONE); glBindFramebuffer(GL_FRAMEBUFFER, GL_NONE); - } + } LOGI("gl--> :: SetImageData end"); - } + } } void EGLRender::SetIntParams(int paramType, int param) { LOGI("gl--> EGLRender::SetIntParams paramType = %{public}d,param = %{public}d", paramType, param); - switch(paramType) - { - case PARAM_TYPE_SHADER_INDEX: - { - if (param >= 0) - { - if (m_ProgramObj) - { + switch (paramType) { + case PARAM_TYPE_SHADER_INDEX: { + if (param >= 0) { + if (m_ProgramObj) { glDeleteProgram(m_ProgramObj); m_ProgramObj = GL_NONE; - } + } const char* vShader[1]; vShader[0] = vShaderStr; const char* fShader[1]; - switch(param) - { - case SHADER_TYPE_KUWAHARA: - { + switch (param) { + case SHADER_TYPE_KUWAHARA: { fShader[0] = fShaderStr3; break; } - case SHADER_TYPE_SWIRL: - { + case SHADER_TYPE_SWIRL: { fShader[0] = swirlFShaderStr; break; } - case SHADER_TYPE_BRIGHT: - { + case SHADER_TYPE_BRIGHT: { fShader[0] = brightFShaderStr; break; } - case SHADER_TYPE_CONTRAST: - { + case SHADER_TYPE_CONTRAST: { fShader[0] = contrastFShaderStr; break; } - case SHADER_TYPE_INVERT: - { + case SHADER_TYPE_INVERT: { fShader[0] = invertFShaderStr; break; } - case SHADER_TYPE_PIXELATION: - { + case SHADER_TYPE_PIXELATION: { fShader[0] = pixelFShaderStr; break; } - case SHADER_TYPE_SEPIA: - { + case SHADER_TYPE_SEPIA: { fShader[0] = colorMatrixFShaderStr; break; } - case SHADER_TYPE_SKETCH: - { + case SHADER_TYPE_SKETCH: { fShader[0] = sketchShaderStr; vShader[0] = v3x3ShaderStr; break; } - case SHADER_TYPE_TOON: - { + case SHADER_TYPE_TOON: { fShader[0] = toonFShaderStr; vShader[0] = v3x3ShaderStr; break; } - case SHADER_TYPE_VIGNETTE: - { + case SHADER_TYPE_VIGNETTE: { fShader[0] = vignetteFShaderStr; break; } - case SHADER_TYPE_GRAYSCALE: - { + case SHADER_TYPE_GRAYSCALE: { fShader[0] = grayScaleShaderStr; break; } - case SHADER_TYPE_BLUR: - { + case SHADER_TYPE_BLUR: { fShader[0] = blurShaderStr; break; } @@ -723,13 +685,12 @@ void EGLRender::SetIntParams(int paramType, int param) } m_ProgramObj = GLUtils::CreateProgram(vShader[0], fShader[0], m_VertexShader, - m_FragmentShader); - if (!m_ProgramObj) - { + m_FragmentShader); + if (!m_ProgramObj) { GLUtils::CheckGLError("Create Program"); LOGI("gl--> EGLRender::SetIntParams Could not create program."); return; - } + } m_SamplerLoc = glGetUniformLocation(m_ProgramObj, "s_TextureMap"); m_TexSizeLoc = glGetUniformLocation(m_ProgramObj, "u_texSize"); @@ -758,8 +719,7 @@ void EGLRender::UseProgram() glBindTexture(GL_TEXTURE_2D, m_ImageTextureId); glUniform1i(m_SamplerLoc, 0); - if (m_TexSizeLoc > -1) - { + if (m_TexSizeLoc > -1) { GLfloat size[2]; size[0] = m_RenderImage.width; size[1] = m_RenderImage.height; @@ -770,8 +730,7 @@ void EGLRender::UseProgram() void EGLRender::GlUniform(char* location, float value, int unType) { GLint ll = glGetUniformLocation(m_ProgramObj, location); - switch(unType) - { + switch (unType) { case UNIFORM_TYPE_ZERO: glUniform1i(ll, (int)value); break; @@ -786,8 +745,7 @@ void EGLRender::GlUniform(char* location, float value, int unType) void EGLRender::GlUniformArray(char* location, float* value, int unType) { GLint ll = glGetUniformLocation(m_ProgramObj, location); - switch(unType) - { + switch (unType) { case UNIFORM_TYPE_2FV_SIZE: GLfloat vec2[2]; vec2[0] = value[0] * m_RenderImage.width; @@ -817,10 +775,9 @@ void EGLRender::GlUniformArray(char* location, float* value, int unType) void EGLRender::GlUniformMatrix(char* location, float* value, int unType) { GLint ll = glGetUniformLocation(m_ProgramObj, location); - switch(unType) - { + switch (unType) { case UNIFORM_TYPE_THREE: - glUniformMatrix3fv(ll, 1, false,value); + glUniformMatrix3fv(ll, 1, false, value); break; case UNIFORM_TYPE_FOUR: glUniformMatrix4fv(ll, 1, false, value); @@ -832,54 +789,46 @@ void EGLRender::GlUniformMatrix(char* location, float* value, int unType) void EGLRender::UnInit() { - if (m_ProgramObj) - { + if (m_ProgramObj) { glDeleteProgram(m_ProgramObj); m_ProgramObj = GL_NONE; - } + } - if (m_ImageTextureId) - { + if (m_ImageTextureId) { glDeleteTextures(DEFAULT_ONE, &m_ImageTextureId); m_ImageTextureId = GL_NONE; - } + } - if (m_FboTextureId) - { + if (m_FboTextureId) { glDeleteTextures(DEFAULT_ONE, &m_FboTextureId); m_FboTextureId = GL_NONE; - } + } - if (m_VboIds[DEFAULT_ZERO]) - { + if (m_VboIds[DEFAULT_ZERO]) { glDeleteBuffers(DEFAULT_THREE, m_VboIds); m_VboIds[DEFAULT_ZERO] = GL_NONE; m_VboIds[DEFAULT_ONE] = GL_NONE; m_VboIds[DEFAULT_TWO] = GL_NONE; } - if (m_VaoIds[DEFAULT_ZERO]) - { + if (m_VaoIds[DEFAULT_ZERO]) { glDeleteVertexArrays(DEFAULT_ONE, m_VaoIds); m_VaoIds[DEFAULT_ZERO] = GL_NONE; - } + } - if (m_FboId) - { + if (m_FboId) { glDeleteFramebuffers(1, &m_FboId); m_FboId = GL_NONE; - } - if (m_IsGLContextReady) - { + } + if (m_IsGLContextReady) { DestroyGl(); m_IsGLContextReady = false; - } + } } void EGLRender::DestroyGl() { // 释放 EGL 环境 - if (m_eglDisplay != EGL_NO_DISPLAY) - { + if (m_eglDisplay != EGL_NO_DISPLAY) { eglMakeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); eglDestroyContext(m_eglDisplay, m_eglCtx); eglDestroySurface(m_eglDisplay, m_eglSurface); diff --git a/gpu_transform/src/main/cpp/render/EGLRender.h b/gpu_transform/src/main/cpp/render/EGLRender.h index 7b889bc..db4911b 100644 --- a/gpu_transform/src/main/cpp/render/EGLRender.h +++ b/gpu_transform/src/main/cpp/render/EGLRender.h @@ -31,20 +31,23 @@ const int EGL_FEATURE_NUM = 7; class EGLRender { - - public: +public: EGLRender(); ~EGLRender(); - static EGLRender* GetInstance() { - if(sInstance == nullptr) { + static EGLRender* GetInstance() + { + if(sInstance == nullptr) + { sInstance = new EGLRender(); } return sInstance; } - static void DestroyRender() { - if(sInstance) { + static void DestroyRender() + { + if (sInstance) + { delete sInstance; sInstance = nullptr; } @@ -61,7 +64,6 @@ class EGLRender { static napi_value Rendering(napi_env env, napi_callback_info info); - static napi_value RenderGlUniform1i(napi_env env, napi_callback_info info); static napi_value RenderGlUniform1f(napi_env env, napi_callback_info info); static napi_value RenderGlUniform2fv(napi_env env, napi_callback_info info); @@ -91,7 +93,7 @@ class EGLRender { void UnInit(); - private: +private: static EGLRender* sInstance; GLuint m_ImageTextureId; GLuint m_FboTextureId; @@ -113,8 +115,6 @@ class EGLRender { bool m_IsGLContextReady; const char* m_fShaderStrs[EGL_FEATURE_NUM]; int m_ShaderIndex; - - }; #endif // GPU_ImageETS_EGLRender_H diff --git a/gpu_transform/src/main/cpp/util/GLUtils.cpp b/gpu_transform/src/main/cpp/util/GLUtils.cpp index e3adbfa..fdeb4a5 100644 --- a/gpu_transform/src/main/cpp/util/GLUtils.cpp +++ b/gpu_transform/src/main/cpp/util/GLUtils.cpp @@ -28,24 +28,20 @@ GLuint GLUtils::LoadShader(GLenum shaderType, const char *pSource) { GLuint shader = 0; shader = glCreateShader(shaderType); - if (shader) - { + if (shader) { glShaderSource(shader, 1, &pSource, NULL); glCompileShader(shader); GLint compiled = 0; glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled); - if (!compiled) - { + if (!compiled) { GLint infoLen = 0; glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen); - if (infoLen) - { + if (infoLen) { char* buf = (char*) malloc((size_t)infoLen); - if (buf) - { + if (buf) { glGetShaderInfoLog(shader, infoLen, NULL, buf); free(buf); - } + } glDeleteShader(shader); shader = 0; } @@ -54,17 +50,19 @@ GLuint GLUtils::LoadShader(GLenum shaderType, const char *pSource) return shader; } -GLuint GLUtils::CreateProgram(const char *pVertexShaderSource, const char *pFragShaderSource, GLuint &vertexShaderHandle, GLuint &fragShaderHandle) +GLuint GLUtils::CreateProgram(const char *pVertexShaderSource, + const char *pFragShaderSource, + GLuint &vertexShaderHandle, + GLuint &fragShaderHandle) { GLuint program = 0; vertexShaderHandle = LoadShader(GL_VERTEX_SHADER, pVertexShaderSource); if (!vertexShaderHandle) return program; fragShaderHandle = LoadShader(GL_FRAGMENT_SHADER, pFragShaderSource); - if (!fragShaderHandle) return program; + if (!fragShaderHandle) return program; program = glCreateProgram(); - if (program) - { + if (program) { glAttachShader(program, vertexShaderHandle); CheckGLError("glAttachShader"); glAttachShader(program, fragShaderHandle); @@ -78,32 +76,28 @@ GLuint GLUtils::CreateProgram(const char *pVertexShaderSource, const char *pFrag vertexShaderHandle = 0; glDetachShader(program, fragShaderHandle); glDeleteShader(fragShaderHandle); - fragShaderHandle = 0; + fragShaderHandle = 0; - if (linkStatus != GL_TRUE) - { + if (linkStatus != GL_TRUE) { GLint bufLength = 0; - glGetProgramiv(program,GL_INFO_LOG_LENGTH, &bufLength); - if (bufLength) - { + glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength); + if (bufLength) { char* buf = (char*) malloc((size_t)bufLength); - if (buf) - { + if (buf) { glGetProgramInfoLog(program, bufLength, NULL, buf); free(buf); - } - } + } + } glDeleteProgram(program); program = 0; - } - } + } + } return program; } void GLUtils::CheckGLError(const char *pGLOperation) { - for (GLint error = glGetError(); error; error = glGetError()) - { + for (GLint error = glGetError(); error; error = glGetError()) { LOGI("GLUtils::CheckGLError GL Operation %{public}s() glError (0x%x)\n", pGLOperation, error); } } diff --git a/gpu_transform/src/main/cpp/util/GLUtils.h b/gpu_transform/src/main/cpp/util/GLUtils.h index ff126da..7dd057d 100644 --- a/gpu_transform/src/main/cpp/util/GLUtils.h +++ b/gpu_transform/src/main/cpp/util/GLUtils.h @@ -25,7 +25,7 @@ #include class GLUtils { - public: +public: static GLuint LoadShader(GLenum shaderType, const char *pSource); static GLuint CreateProgram(const char *pVertexShaderSource, const char *pFragShaderSource, GLuint &vertexShaderHandle, diff --git a/gpu_transform/src/main/cpp/util/NapiUtil.cpp b/gpu_transform/src/main/cpp/util/NapiUtil.cpp index bdb8889..8422637 100644 --- a/gpu_transform/src/main/cpp/util/NapiUtil.cpp +++ b/gpu_transform/src/main/cpp/util/NapiUtil.cpp @@ -32,18 +32,16 @@ const int32_t MAX_STR_LENGTH = 1024; void NapiUtil::JsValueToString(const napi_env &env, const napi_value &value, const int32_t bufLen, std::string &target) { - if (bufLen <= 0 || bufLen > MAX_STR_LENGTH) - { - LOGI("%s string too long malloc failed",__func__); + if (bufLen <= 0 || bufLen > MAX_STR_LENGTH) { + LOGI("%s string too long malloc failed", __func__); return; } std::unique_ptr buf = std::make_unique (bufLen); - if (buf.get() == nullptr) - { - LOGI("%s nullptr js object to string malloc failed",__func__); + if (buf.get() == nullptr) { + LOGI("%s nullptr js object to string malloc failed", __func__); return; - } + } (void) memset(buf.get(), 0, bufLen); size_t result = 0; napi_get_value_string_utf8(env, value, buf.get(), bufLen, &result); diff --git a/gpu_transform/src/main/cpp/util/NapiUtil.h b/gpu_transform/src/main/cpp/util/NapiUtil.h index bab7edd..a5331b3 100644 --- a/gpu_transform/src/main/cpp/util/NapiUtil.h +++ b/gpu_transform/src/main/cpp/util/NapiUtil.h @@ -27,9 +27,9 @@ #include "native_common.h" class NapiUtil { - public: +public: static void JsValueToString(const napi_env &env, const napi_value &value, const int32_t bufLen, - std::string &target); + std::string &target); }; #endif // GPU_ImageETS_NapiUtil_H diff --git a/gpu_transform/src/main/cpp/util/NativeImage.h b/gpu_transform/src/main/cpp/util/NativeImage.h index dafb083..100a959 100644 --- a/gpu_transform/src/main/cpp/util/NativeImage.h +++ b/gpu_transform/src/main/cpp/util/NativeImage.h @@ -51,8 +51,7 @@ #define IMAGE_FORMAT_P010_EXT "P010" // 16bit NV21 -struct NativeImage -{ +struct NativeImage { int width; int height; int format; @@ -69,54 +68,56 @@ struct NativeImage } }; -class NativeImageUtil -{ - public: +class NativeImageUtil { +public: static void AllocNativeImage(NativeImage *pImage) { if (pImage ->height == DEFAULT_ZERO || pImage ->width == DEFAULT_ZERO) return; - switch(pImage -> format) - { - case IMAGE_FORMAT_RGBA: - { - pImage->ppPlane[DEFAULT_ZERO] = static_cast(malloc(pImage->width * pImage ->height * DEFAULT_FOUR)); + switch (pImage -> format) { + case IMAGE_FORMAT_RGBA: { + pImage->ppPlane[DEFAULT_ZERO] = + static_cast(malloc(pImage->width * pImage ->height * DEFAULT_FOUR)); } break; - case IMAGE_FORMAT_YUYV: - { - pImage->ppPlane[DEFAULT_ZERO] = static_cast(malloc(pImage->width * pImage ->height * DEFAULT_TWO)); + case IMAGE_FORMAT_YUYV: { + pImage->ppPlane[DEFAULT_ZERO] = + static_cast(malloc(pImage->width * pImage ->height * DEFAULT_TWO)); } break; case IMAGE_FORMAT_NV12: - case IMAGE_FORMAT_NV21: - { - pImage->ppPlane[DEFAULT_ZERO] = static_cast(malloc(pImage->width * pImage ->height * DEFAULT_ONE_HALF)); - pImage->ppPlane[DEFAULT_ONE] = pImage->ppPlane[DEFAULT_ZERO] + pImage->width * pImage->height; + case IMAGE_FORMAT_NV21: { + pImage->ppPlane[DEFAULT_ZERO] = + static_cast(malloc(pImage->width * pImage ->height * DEFAULT_ONE_HALF)); + pImage->ppPlane[DEFAULT_ONE] = + pImage->ppPlane[DEFAULT_ZERO] + pImage->width * pImage->height; } break; - case IMAGE_FORMAT_I420: - { - pImage->ppPlane[DEFAULT_ZERO] = static_cast(malloc(pImage->width * pImage ->height * DEFAULT_ONE_HALF)); - pImage->ppPlane[DEFAULT_ONE] = pImage->ppPlane[DEFAULT_ZERO] + pImage->width * pImage->height; - pImage->ppPlane[DEFAULT_TWO] = pImage->ppPlane[DEFAULT_ONE] + pImage->width * (pImage->height >> DEFAULT_TWO); + case IMAGE_FORMAT_I420: { + pImage->ppPlane[DEFAULT_ZERO] = + static_cast(malloc(pImage->width * pImage ->height * DEFAULT_ONE_HALF)); + pImage->ppPlane[DEFAULT_ONE] = + pImage->ppPlane[DEFAULT_ZERO] + pImage->width * pImage->height; + pImage->ppPlane[DEFAULT_TWO] = + pImage->ppPlane[DEFAULT_ONE] + pImage->width * (pImage->height >> DEFAULT_TWO); } break; - case IMAGE_FORMAT_GRAY: - { - pImage->ppPlane[DEFAULT_ZERO] = static_cast(malloc(pImage->width * pImage ->height)); + case IMAGE_FORMAT_GRAY: { + pImage->ppPlane[DEFAULT_ZERO] = + static_cast(malloc(pImage->width * pImage ->height)); } break; - case IMAGE_FORMAT_I444: - { - pImage->ppPlane[DEFAULT_ZERO] = static_cast(malloc(pImage->width * pImage ->height * DEFAULT_THREE)); + case IMAGE_FORMAT_I444: { + pImage->ppPlane[DEFAULT_ZERO] = + static_cast(malloc(pImage->width * pImage ->height * DEFAULT_THREE)); } - break; - case IMAGE_FORMAT_P010: - { - pImage->ppPlane[DEFAULT_ZERO] = static_cast(malloc(pImage->width * pImage ->height * DEFAULT_THREE)); - pImage->ppPlane[DEFAULT_ONE] = pImage->ppPlane[DEFAULT_ZERO] + pImage->width * pImage->height * DEFAULT_TWO; + break; + case IMAGE_FORMAT_P010: { + pImage->ppPlane[DEFAULT_ZERO] = + static_cast(malloc(pImage->width * pImage ->height * DEFAULT_THREE)); + pImage->ppPlane[DEFAULT_ONE] = + pImage->ppPlane[DEFAULT_ZERO] + pImage->width * pImage->height * DEFAULT_TWO; } - break; + break; default: break; } @@ -133,13 +134,11 @@ class NativeImageUtil static bool CreateArrayBuffer(napi_env env, void* src, size_t srcLen, napi_value *res) { - if (src == nullptr || srcLen == DEFAULT_ZERO) - { + if (src == nullptr || srcLen == DEFAULT_ZERO) { return false; - } + } void *nativePtr = nullptr; - if (napi_create_arraybuffer(env, srcLen, &nativePtr, res) != napi_ok || nativePtr == nullptr) - { + if (napi_create_arraybuffer(env, srcLen, &nativePtr, res) != napi_ok || nativePtr == nullptr) { return false; } memcpy(nativePtr, src, srcLen); @@ -153,8 +152,7 @@ class NativeImageUtil uint8_t* tmp = (uint8_t*)malloc(totalLength); memcpy(tmp, *buf, totalLength); memset(*buf, DEFAULT_ZERO, sizeof(uint8_t)*totalLength); - for (int i = 0; i < height; i++) - { + for (int i = 0; i < height; i++) { memcpy(*buf + oneLineLength * i, tmp + totalLength - oneLineLength * (i+1), oneLineLength); } free(tmp); From a241953878042c63ebb2cb87bdc174d1ffdc1367 Mon Sep 17 00:00:00 2001 From: tyBrave Date: Tue, 7 Feb 2023 11:06:00 +0800 Subject: [PATCH 06/10] update code,because of line space Signed-off-by: tyBrave --- .../src/main/cpp/common/native_common.h | 2 +- gpu_transform/src/main/cpp/napi/napi_init.cpp | 32 +++-- .../src/main/cpp/render/EGLRender.cpp | 124 ++++++------------ gpu_transform/src/main/cpp/render/EGLRender.h | 6 +- gpu_transform/src/main/cpp/util/NativeImage.h | 2 +- 5 files changed, 61 insertions(+), 105 deletions(-) diff --git a/gpu_transform/src/main/cpp/common/native_common.h b/gpu_transform/src/main/cpp/common/native_common.h index 3a8442b..f2db746 100644 --- a/gpu_transform/src/main/cpp/common/native_common.h +++ b/gpu_transform/src/main/cpp/common/native_common.h @@ -49,7 +49,7 @@ GET_AND_THROW_LAST_ERROR((env)); \ return retVal; \ } \ - } while (0) + } while (0) #define NAPI_CALL(env, theCall) NAPI_CALL_BASE(env, theCall, nullptr) diff --git a/gpu_transform/src/main/cpp/napi/napi_init.cpp b/gpu_transform/src/main/cpp/napi/napi_init.cpp index 667d663..cee7544 100644 --- a/gpu_transform/src/main/cpp/napi/napi_init.cpp +++ b/gpu_transform/src/main/cpp/napi/napi_init.cpp @@ -33,7 +33,7 @@ static napi_value Add(napi_env env, napi_callback_info info) size_t argc = 2; napi_value args[2] = {nullptr}; - napi_get_cb_info(env, info, &argc, args , nullptr, nullptr); + napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); napi_valuetype valuetype0; napi_typeof(env, args[0], &valuetype0); @@ -49,32 +49,30 @@ static napi_value Add(napi_env env, napi_callback_info info) 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[] = { - DECLARE_NAPI_FUNCTION("EglRenderInit", EGLRender:: RenderInit), - DECLARE_NAPI_FUNCTION("EglRenderSetImageData", EGLRender:: RenderSetData), - DECLARE_NAPI_FUNCTION("EglPixelMapSurface", EGLRender:: GetPixelMapOfSurface), - DECLARE_NAPI_FUNCTION("EglRenderSetIntParams", EGLRender:: RenderSetIntParams), - DECLARE_NAPI_FUNCTION("EglIsInit", EGLRender:: EGLIsInit), - DECLARE_NAPI_FUNCTION("EglDestroy", EGLRender:: DestroyGlesEnv), + DECLARE_NAPI_FUNCTION("EglRenderInit", EGLRender::RenderInit), + DECLARE_NAPI_FUNCTION("EglRenderSetImageData", EGLRender::RenderSetData), + DECLARE_NAPI_FUNCTION("EglPixelMapSurface", EGLRender::GetPixelMapOfSurface), + DECLARE_NAPI_FUNCTION("EglRenderSetIntParams", EGLRender::RenderSetIntParams), + DECLARE_NAPI_FUNCTION("EglIsInit", EGLRender::EGLIsInit), + DECLARE_NAPI_FUNCTION("EglDestroy", EGLRender::DestroyGlesEnv), - DECLARE_NAPI_FUNCTION("EglUseProgram", EGLRender:: StartUseProgram), - DECLARE_NAPI_FUNCTION("EglRendering", EGLRender:: Rendering), + DECLARE_NAPI_FUNCTION("EglUseProgram", EGLRender::StartUseProgram), + DECLARE_NAPI_FUNCTION("EglRendering", EGLRender::Rendering), - DECLARE_NAPI_FUNCTION("EglUniform1i", EGLRender:: RenderGlUniform1i), - DECLARE_NAPI_FUNCTION("EglUniform1f", EGLRender:: RenderGlUniform1f), - DECLARE_NAPI_FUNCTION("EglUniform2fv", EGLRender:: RenderGlUniform2fv), + DECLARE_NAPI_FUNCTION("EglUniform1i", EGLRender::RenderGlUniform1i), + DECLARE_NAPI_FUNCTION("EglUniform1f", EGLRender::RenderGlUniform1f), + DECLARE_NAPI_FUNCTION("EglUniform2fv", EGLRender::RenderGlUniform2fv), - DECLARE_NAPI_FUNCTION("EglSetTypeArrayOfFloat", EGLRender:: setTypeArrayOfFloat), + DECLARE_NAPI_FUNCTION("EglSetTypeArrayOfFloat", EGLRender::setTypeArrayOfFloat), - DECLARE_NAPI_FUNCTION("EglSetTypeArrayOfMatrix3f", EGLRender:: setTypeArrayOfMatrix3f), - DECLARE_NAPI_FUNCTION("EglSetTypeArrayOfMatrix4f", EGLRender:: setTypeArrayOfMatrix4f), + DECLARE_NAPI_FUNCTION("EglSetTypeArrayOfMatrix3f", EGLRender::setTypeArrayOfMatrix3f), + DECLARE_NAPI_FUNCTION("EglSetTypeArrayOfMatrix4f", EGLRender::setTypeArrayOfMatrix4f), }; NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc)); return exports; diff --git a/gpu_transform/src/main/cpp/render/EGLRender.cpp b/gpu_transform/src/main/cpp/render/EGLRender.cpp index bce24f5..fc9ee69 100644 --- a/gpu_transform/src/main/cpp/render/EGLRender.cpp +++ b/gpu_transform/src/main/cpp/render/EGLRender.cpp @@ -182,7 +182,7 @@ napi_value EGLRender::EGLIsInit(napi_env env, napi_callback_info info) int32_t value; if (EGLRender::GetInstance() -> m_IsGLContextReady) { value = 1; - }else { + } else { value = 0; } napi_status status = napi_create_int32(env, value, &isInit); @@ -234,7 +234,7 @@ napi_value EGLRender::setTypeArrayOfFloat(napi_env env, napi_callback_info info) size_t bufferLength; size_t byte_offset; napi_status buffStatus = napi_get_typedarray_info(env, - args[2], &dataType, &bufferLength, &buffer, &args[2], &byte_offset); + args[2], &dataType, &bufferLength, &buffer, &args[2], &byte_offset); if (buffStatus != napi_ok) { return nullptr; } @@ -245,13 +245,13 @@ napi_value EGLRender::setTypeArrayOfFloat(napi_env env, napi_callback_info info) if (strcmp(key, "glUniform2fv") == 0) { uniformType = UNIFORM_TYPE_2FV; - }else if (strcmp(key, "glUniform3fv") == 0) { + } else if (strcmp(key, "glUniform3fv") == 0) { uniformType = UNIFORM_TYPE_3FV; - }else if (strcmp(key, "glUniform4fv") == 0) { + } else if (strcmp(key, "glUniform4fv") == 0) { uniformType = UNIFORM_TYPE_4FV; - }else if (strcmp(key, "glUniform1fv") == 0) { + } else if (strcmp(key, "glUniform1fv") == 0) { uniformType = UNIFORM_TYPE_FV; - }else if (strcmp(key, "glUniform2f") == 0) { + } else if (strcmp(key, "glUniform2f") == 0) { uniformType = UNIFORM_TYPE_2F; } @@ -275,7 +275,7 @@ napi_value EGLRender::setTypeArrayOfMatrix3f(napi_env env, napi_callback_info in size_t bufferLength; size_t byte_offset; napi_status buffStatus = napi_get_typedarray_info(env, - args[1], &dataType, &bufferLength, &buffer, &args[1], &byte_offset); + args[1], &dataType, &bufferLength, &buffer, &args[1], &byte_offset); if (buffStatus != napi_ok) { return nullptr; } @@ -303,7 +303,7 @@ napi_value EGLRender::setTypeArrayOfMatrix4f(napi_env env, napi_callback_info in size_t bufferLength; size_t byte_offset; napi_status buffStatus = napi_get_typedarray_info(env, - args[1], &dataType, &bufferLength, &buffer, &args[1], &byte_offset); + args[1], &dataType, &bufferLength, &buffer, &args[1], &byte_offset); if (buffStatus != napi_ok) { return nullptr; } @@ -404,7 +404,6 @@ void EGLRender::Init() if (!m_IsGLContextReady) { return; } - glGenTextures(1, &m_ImageTextureId); // 生成纹理名称 glBindTexture(GL_TEXTURE_2D, m_ImageTextureId); // 允许建立一个绑定到目标纹理的有名称的纹理 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); @@ -420,15 +419,12 @@ void EGLRender::Init() glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glBindTexture(GL_TEXTURE_2D, GL_NONE); - m_ProgramObj = GLUtils::CreateProgram(vShaderStr, fShaderStr0, m_VertexShader, m_FragmentShader); if (!m_ProgramObj) { GLUtils::CheckGLError("Create Program"); return; } - - // Generate VBO Ids and load the VBOs width data glGenBuffers(DEFAULT_THREE, m_VboIds); glBindBuffer(GL_ARRAY_BUFFER, m_VboIds[DEFAULT_ZERO]); glBufferData(GL_ARRAY_BUFFER, sizeof(vVertices), vVertices, GL_STATIC_DRAW); @@ -438,30 +434,26 @@ void EGLRender::Init() glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_VboIds[DEFAULT_TWO]); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); - - // Generate VAO Ids glGenVertexArrays(DEFAULT_ONE, m_VaoIds); - - // FBO off screen rendering VAO glBindVertexArray(m_VaoIds[DEFAULT_ZERO]); glBindBuffer(GL_ARRAY_BUFFER, m_VboIds[DEFAULT_ZERO]); glEnableVertexAttribArray(VERTEX_POS_LOC); glVertexAttribPointer(VERTEX_POS_LOC, - DEFAULT_THREE, - GL_FLOAT, GL_FALSE, - DEFAULT_THREE * sizeof(GLfloat), - (const void *)DEFAULT_ZERO); + DEFAULT_THREE, + GL_FLOAT, GL_FALSE, + DEFAULT_THREE * sizeof(GLfloat), + (const void *)DEFAULT_ZERO); glBindBuffer(GL_ARRAY_BUFFER, GL_NONE); glBindBuffer(GL_ARRAY_BUFFER, m_VboIds[DEFAULT_ONE]); glEnableVertexAttribArray(TEXTURE_POS_LOC); glVertexAttribPointer(TEXTURE_POS_LOC, - DEFAULT_TWO, - GL_FLOAT, - GL_FALSE, - DEFAULT_TWO * sizeof(GLfloat), - (const void *)DEFAULT_ZERO); + DEFAULT_TWO, + GL_FLOAT, + GL_FALSE, + DEFAULT_TWO * sizeof(GLfloat), + (const void *)DEFAULT_ZERO); glBindBuffer(GL_ARRAY_BUFFER, GL_NONE); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_VboIds[DEFAULT_TWO]); @@ -470,8 +462,7 @@ void EGLRender::Init() int EGLRender::CreateGlEnv() { - const EGLint confAttr[] = - { + const EGLint confAttr[] = { EGL_RENDERABLE_TYPE, EGL_OPENGL_ES3_BIT_KHR, EGL_SURFACE_TYPE, EGL_PBUFFER_BIT, EGL_RED_SIZE, 8, @@ -482,15 +473,11 @@ int EGLRender::CreateGlEnv() EGL_STENCIL_SIZE, 8, EGL_NONE }; - // EGL context attributes - const EGLint ctxAttr[] = - { + const EGLint ctxAttr[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; - - const EGLint surfaceAttr[] = - { + const EGLint surfaceAttr[] = { EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE @@ -504,64 +491,37 @@ int EGLRender::CreateGlEnv() resultCode = -1; break; } - // 初始化 egl 方法 if (!eglInitialize(m_eglDisplay, &eglMajVers, &eglMinVers)) { resultCode = -1; break; } - // 获取 EGLConfig 对象,确定渲染表面的配置信息 if (!eglChooseConfig(m_eglDisplay, confAttr, &m_eglConf, 1, &numConfigs)) { resultCode = -1; break; } - // 创建渲染表面 EGLSurface 使用 eglCreateBufferSurface 创建屏幕外渲染区域 m_eglSurface = eglCreatePbufferSurface(m_eglDisplay, m_eglConf, surfaceAttr); if (m_eglSurface == EGL_NO_SURFACE) { - switch(eglGetError()) { - case EGL_BAD_ALLOC: - LOGI("gl-->::CreateGlesEnv Not enough resources available"); - break; - case EGL_BAD_CONFIG: - LOGI("gl-->::CreateGlesEnv provided EGLConfig is invalid"); - break; - case EGL_BAD_PARAMETER: - LOGI("gl-->::CreateGlesEnv provided EGL_WIDTH and EGL_HEIGHT is invalid"); - break; - case EGL_BAD_MATCH: - LOGI("gl-->::CreateGlesEnv Check window and EGLConfig attributes"); - break; - default: - LOGI("gl-->::CreateGlesEnv happen default error"); - break; - } + LOGI("gl-->::CreateGlesEnv happen default error"); + break; } - // 创建渲染上下文 EGLContext m_eglCtx = eglCreateContext(m_eglDisplay, m_eglConf, EGL_NO_CONTEXT, ctxAttr); if (m_eglCtx == EGL_NO_CONTEXT) { EGLint error = eglGetError(); if (error == EGL_BAD_CONFIG) { - LOGI("gl-->::CreateGlesEnv EGL_BAD_CONFIG"); resultCode = -1; break; } - } - + } // 绑定上下文 if (!eglMakeCurrent(m_eglDisplay, m_eglSurface, m_eglSurface, m_eglCtx)) { resultCode = -1; break; } - LOGI("gl-->::CreateGlesEnv initialize success"); } while (false); - - if (resultCode != 0) { - LOGI("gl-->::CreateGlesEnv fail"); - } - return resultCode; } @@ -580,14 +540,14 @@ void EGLRender::SetImageData(uint8_t *pData, int width, int height) glBindTexture(GL_TEXTURE_2D, m_ImageTextureId); glTexImage2D(GL_TEXTURE_2D, - 0, - GL_RGBA, - m_RenderImage.width, - m_RenderImage.height, - 0, - GL_RGBA, - GL_UNSIGNED_BYTE, - m_RenderImage.ppPlane[0]); + 0, + GL_RGBA, + m_RenderImage.width, + m_RenderImage.height, + 0, + GL_RGBA, + GL_UNSIGNED_BYTE, + m_RenderImage.ppPlane[0]); glBindTexture(GL_TEXTURE_2D, GL_NONE); if (m_FboId == GL_NONE) { @@ -597,14 +557,14 @@ void EGLRender::SetImageData(uint8_t *pData, int width, int height) glBindTexture(GL_TEXTURE_2D, m_FboTextureId); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_FboTextureId, 0); glTexImage2D(GL_TEXTURE_2D, - 0, - GL_RGBA, - m_RenderImage.width, - m_RenderImage.height, - 0, - GL_RGBA, - GL_UNSIGNED_BYTE, - nullptr); + 0, + GL_RGBA, + m_RenderImage.width, + m_RenderImage.height, + 0, + GL_RGBA, + GL_UNSIGNED_BYTE, + nullptr); if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { LOGI("gl--> EGLRender ::SetImageData glCheckFramebufferStatus status != GL_FRAMEBUFFER_COMPLETE"); } @@ -683,7 +643,6 @@ void EGLRender::SetIntParams(int paramType, int param) vShader[0] = vShaderStr; break; } - m_ProgramObj = GLUtils::CreateProgram(vShader[0], fShader[0], m_VertexShader, m_FragmentShader); if (!m_ProgramObj) { @@ -691,7 +650,6 @@ void EGLRender::SetIntParams(int paramType, int param) LOGI("gl--> EGLRender::SetIntParams Could not create program."); return; } - m_SamplerLoc = glGetUniformLocation(m_ProgramObj, "s_TextureMap"); m_TexSizeLoc = glGetUniformLocation(m_ProgramObj, "u_texSize"); } @@ -704,7 +662,9 @@ void EGLRender::SetIntParams(int paramType, int param) void EGLRender::UseProgram() { - if (m_ProgramObj == GL_NONE) return; + if (m_ProgramObj == GL_NONE) { + return; + } glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClear(GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); diff --git a/gpu_transform/src/main/cpp/render/EGLRender.h b/gpu_transform/src/main/cpp/render/EGLRender.h index db4911b..4947f9b 100644 --- a/gpu_transform/src/main/cpp/render/EGLRender.h +++ b/gpu_transform/src/main/cpp/render/EGLRender.h @@ -37,8 +37,7 @@ public: static EGLRender* GetInstance() { - if(sInstance == nullptr) - { + if (sInstance == nullptr) { sInstance = new EGLRender(); } return sInstance; @@ -46,8 +45,7 @@ public: static void DestroyRender() { - if (sInstance) - { + if (sInstance) { delete sInstance; sInstance = nullptr; } diff --git a/gpu_transform/src/main/cpp/util/NativeImage.h b/gpu_transform/src/main/cpp/util/NativeImage.h index 100a959..d4db217 100644 --- a/gpu_transform/src/main/cpp/util/NativeImage.h +++ b/gpu_transform/src/main/cpp/util/NativeImage.h @@ -75,7 +75,7 @@ public: if (pImage ->height == DEFAULT_ZERO || pImage ->width == DEFAULT_ZERO) return; switch (pImage -> format) { case IMAGE_FORMAT_RGBA: { - pImage->ppPlane[DEFAULT_ZERO] = + pImage->ppPlane[DEFAULT_ZERO] = static_cast(malloc(pImage->width * pImage ->height * DEFAULT_FOUR)); } break; From 9aac9ccc1e29c92307066e65f24a07e0686eeae0 Mon Sep 17 00:00:00 2001 From: tyBrave Date: Tue, 7 Feb 2023 17:40:35 +0800 Subject: [PATCH 07/10] update code because of function than 50 lines Signed-off-by: tyBrave --- .../src/main/cpp/render/EGLRender.cpp | 57 ++++++++----------- gpu_transform/src/main/cpp/render/EGLRender.h | 2 +- gpu_transform/src/main/cpp/util/GLUtils.cpp | 2 +- 3 files changed, 25 insertions(+), 36 deletions(-) diff --git a/gpu_transform/src/main/cpp/render/EGLRender.cpp b/gpu_transform/src/main/cpp/render/EGLRender.cpp index fc9ee69..72a4eb4 100644 --- a/gpu_transform/src/main/cpp/render/EGLRender.cpp +++ b/gpu_transform/src/main/cpp/render/EGLRender.cpp @@ -396,6 +396,23 @@ EGLRender::EGLRender() EGLRender::~EGLRender() { } +void EGLRender::TexturesInit() +{ + glGenTextures(1, &m_ImageTextureId); // 生成纹理名称 + glBindTexture(GL_TEXTURE_2D, m_ImageTextureId); // 允许建立一个绑定到目标纹理的有名称的纹理 + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glBindTexture(GL_TEXTURE_2D, GL_NONE); + glGenTextures(1, &m_FboTextureId); + glBindTexture(GL_TEXTURE_2D, m_FboTextureId); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glBindTexture(GL_TEXTURE_2D, GL_NONE); +} void EGLRender::Init() { if (CreateGlEnv() == 0) { @@ -404,21 +421,7 @@ void EGLRender::Init() if (!m_IsGLContextReady) { return; } - glGenTextures(1, &m_ImageTextureId); // 生成纹理名称 - glBindTexture(GL_TEXTURE_2D, m_ImageTextureId); // 允许建立一个绑定到目标纹理的有名称的纹理 - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glBindTexture(GL_TEXTURE_2D, GL_NONE); - - glGenTextures(1, &m_FboTextureId); - glBindTexture(GL_TEXTURE_2D, m_FboTextureId); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glBindTexture(GL_TEXTURE_2D, GL_NONE); + EGLRender::GetInstance() -> TexturesInit(); m_ProgramObj = GLUtils::CreateProgram(vShaderStr, fShaderStr0, m_VertexShader, m_FragmentShader); if (!m_ProgramObj) { @@ -428,15 +431,12 @@ void EGLRender::Init() glGenBuffers(DEFAULT_THREE, m_VboIds); glBindBuffer(GL_ARRAY_BUFFER, m_VboIds[DEFAULT_ZERO]); glBufferData(GL_ARRAY_BUFFER, sizeof(vVertices), vVertices, GL_STATIC_DRAW); - glBindBuffer(GL_ARRAY_BUFFER, m_VboIds[DEFAULT_ONE]); glBufferData(GL_ARRAY_BUFFER, sizeof(vFboTexCoors), vTexCoors, GL_STATIC_DRAW); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_VboIds[DEFAULT_TWO]); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); glGenVertexArrays(DEFAULT_ONE, m_VaoIds); glBindVertexArray(m_VaoIds[DEFAULT_ZERO]); - glBindBuffer(GL_ARRAY_BUFFER, m_VboIds[DEFAULT_ZERO]); glEnableVertexAttribArray(VERTEX_POS_LOC); glVertexAttribPointer(VERTEX_POS_LOC, @@ -445,7 +445,6 @@ void EGLRender::Init() DEFAULT_THREE * sizeof(GLfloat), (const void *)DEFAULT_ZERO); glBindBuffer(GL_ARRAY_BUFFER, GL_NONE); - glBindBuffer(GL_ARRAY_BUFFER, m_VboIds[DEFAULT_ONE]); glEnableVertexAttribArray(TEXTURE_POS_LOC); glVertexAttribPointer(TEXTURE_POS_LOC, @@ -455,7 +454,6 @@ void EGLRender::Init() DEFAULT_TWO * sizeof(GLfloat), (const void *)DEFAULT_ZERO); glBindBuffer(GL_ARRAY_BUFFER, GL_NONE); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_VboIds[DEFAULT_TWO]); glBindVertexArray(GL_NONE); } @@ -463,24 +461,15 @@ void EGLRender::Init() int EGLRender::CreateGlEnv() { const EGLint confAttr[] = { - EGL_RENDERABLE_TYPE, EGL_OPENGL_ES3_BIT_KHR, - EGL_SURFACE_TYPE, EGL_PBUFFER_BIT, - EGL_RED_SIZE, 8, - EGL_GREEN_SIZE, 8, - EGL_BLUE_SIZE, 8, - EGL_ALPHA_SIZE, 8, - EGL_DEPTH_SIZE, 16, - EGL_STENCIL_SIZE, 8, - EGL_NONE + EGL_RENDERABLE_TYPE, EGL_OPENGL_ES3_BIT_KHR, EGL_SURFACE_TYPE, EGL_PBUFFER_BIT, + EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8, EGL_ALPHA_SIZE, 8, + EGL_DEPTH_SIZE, 16, EGL_STENCIL_SIZE, 8, EGL_NONE }; const EGLint ctxAttr[] = { - EGL_CONTEXT_CLIENT_VERSION, 2, - EGL_NONE + EGL_CONTEXT_CLIENT_VERSION, 2,EGL_NONE }; const EGLint surfaceAttr[] = { - EGL_WIDTH, 1, - EGL_HEIGHT, 1, - EGL_NONE + EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE }; EGLint eglMajVers, eglMinVers; EGLint numConfigs; diff --git a/gpu_transform/src/main/cpp/render/EGLRender.h b/gpu_transform/src/main/cpp/render/EGLRender.h index 4947f9b..411c397 100644 --- a/gpu_transform/src/main/cpp/render/EGLRender.h +++ b/gpu_transform/src/main/cpp/render/EGLRender.h @@ -71,7 +71,7 @@ public: static napi_value setTypeArrayOfMatrix4f(napi_env env, napi_callback_info info); void Init(); - + void TexturesInit(); int CreateGlEnv(); void SetImageData(uint8_t *pData, int width, int height); diff --git a/gpu_transform/src/main/cpp/util/GLUtils.cpp b/gpu_transform/src/main/cpp/util/GLUtils.cpp index fdeb4a5..9850f73 100644 --- a/gpu_transform/src/main/cpp/util/GLUtils.cpp +++ b/gpu_transform/src/main/cpp/util/GLUtils.cpp @@ -21,8 +21,8 @@ #include #include -#include "GLUtils.h" #include "DebugLog.h" +#include "GLUtils.h" GLuint GLUtils::LoadShader(GLenum shaderType, const char *pSource) { From 3762e6ecbf058772ce9ba62d69d22a73aa405f46 Mon Sep 17 00:00:00 2001 From: tyBrave Date: Tue, 7 Feb 2023 17:52:42 +0800 Subject: [PATCH 08/10] remove space of code Signed-off-by: tyBrave --- gpu_transform/src/main/cpp/render/EGLRender.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gpu_transform/src/main/cpp/render/EGLRender.cpp b/gpu_transform/src/main/cpp/render/EGLRender.cpp index 72a4eb4..19e3df6 100644 --- a/gpu_transform/src/main/cpp/render/EGLRender.cpp +++ b/gpu_transform/src/main/cpp/render/EGLRender.cpp @@ -466,7 +466,7 @@ int EGLRender::CreateGlEnv() EGL_DEPTH_SIZE, 16, EGL_STENCIL_SIZE, 8, EGL_NONE }; const EGLint ctxAttr[] = { - EGL_CONTEXT_CLIENT_VERSION, 2,EGL_NONE + EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; const EGLint surfaceAttr[] = { EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE From 0799ed85e27d161594b41a854b76fbf148ab0dcf Mon Sep 17 00:00:00 2001 From: tyBrave Date: Wed, 22 Feb 2023 10:55:02 +0800 Subject: [PATCH 09/10] update code because of some idea Signed-off-by: tyBrave --- README.md | 3 + .../main/ets/pages/transformPixelMapPage.ets | 26 +-- gpu_transform/CHANGELOG.md | 16 ++ gpu_transform/LICENSE | 201 ++++++++++++++++ gpu_transform/README.OpenSource | 11 + gpu_transform/README.md | 79 +++++++ gpu_transform/package.json | 34 ++- gpu_transform/src/main/cpp/CMakeLists.txt | 8 +- .../src/main/cpp/common/native_common.h | 1 - .../src/main/cpp/constant/constant_shape.h | 5 +- gpu_transform/src/main/cpp/napi/napi_init.cpp | 26 --- .../src/main/cpp/render/EGLRender.cpp | 14 +- gpu_transform/src/main/cpp/render/EGLRender.h | 15 +- .../src/main/cpp/types/libentry/index.d.ts | 15 +- gpu_transform/src/main/cpp/util/DebugLog.h | 1 - gpu_transform/src/main/cpp/util/GLUtils.cpp | 1 - gpu_transform/src/main/cpp/util/GLUtils.h | 1 - gpu_transform/src/main/cpp/util/NapiUtil.cpp | 1 - gpu_transform/src/main/cpp/util/NapiUtil.h | 1 - gpu_transform/src/main/cpp/util/NativeImage.h | 3 +- .../GPUImage3x3TextureSamplingFilter.ts | 36 +-- .../main/ets/gpu/filter/GPUImageBlurFilter.ts | 49 ++-- .../gpu/filter/GPUImageBrightnessFilter.ts | 27 +-- .../gpu/filter/GPUImageColorInvertFilter.ts | 17 +- .../gpu/filter/GPUImageColorMatrixFilter.ts | 41 ++-- .../ets/gpu/filter/GPUImageContrastFilter.ts | 31 ++- .../src/main/ets/gpu/filter/GPUImageFilter.ts | 217 +++++++----------- .../ets/gpu/filter/GPUImageFilterGroup.ts | 16 +- .../ets/gpu/filter/GPUImageGrayscaleFilter.ts | 15 +- .../ets/gpu/filter/GPUImageKuwaharaFilter.ts | 28 +-- .../gpu/filter/GPUImagePixelationFilter.ts | 32 +-- .../ets/gpu/filter/GPUImageSepiaToneFilter.ts | 1 - .../ets/gpu/filter/GPUImageSwirlFilter.ts | 22 +- .../main/ets/gpu/filter/GPUImageToonFilter.ts | 16 +- .../ets/gpu/filter/GPUImageVignetterFilter.ts | 33 +-- .../src/main/ets/gpu/gl/GPUFilterType.ts | 8 +- .../src/main/ets/gpu/gl/NativeEglRender.ts | 76 +++--- .../src/main/ets/gpu/interface/Runnable.ts | 2 +- .../components/imageknife/RequestOption.ets | 6 +- .../transform/BlurTransformation.ets | 2 +- .../BrightnessFilterTransformation.ets | 2 +- .../ContrastFilterTransformation.ets | 2 +- .../transform/GrayscaleTransformation.ets | 2 +- .../transform/InvertFilterTransformation.ets | 2 +- .../transform/KuwaharaFilterTransform.ets | 103 +++++++++ .../transform/KuwaharaFilterTransform.ts | 101 -------- .../PixelationFilterTransformation.ets | 2 +- .../transform/SepiaFilterTransformation.ets | 2 +- .../transform/SketchFilterTransformation.ets | 2 +- .../transform/SwirlFilterTransformation.ets | 4 +- .../transform/ToonFilterTransform.ets | 110 +++++++++ .../transform/ToonFilterTransform.ts | 108 --------- .../transform/VignetteFilterTransform.ets | 116 ++++++++++ .../transform/VignetteFilterTransform.ts | 114 --------- 54 files changed, 1032 insertions(+), 775 deletions(-) create mode 100644 gpu_transform/CHANGELOG.md create mode 100644 gpu_transform/LICENSE create mode 100644 gpu_transform/README.OpenSource create mode 100644 gpu_transform/README.md create mode 100644 imageknife/src/main/ets/components/imageknife/transform/KuwaharaFilterTransform.ets delete mode 100644 imageknife/src/main/ets/components/imageknife/transform/KuwaharaFilterTransform.ts create mode 100644 imageknife/src/main/ets/components/imageknife/transform/ToonFilterTransform.ets delete mode 100644 imageknife/src/main/ets/components/imageknife/transform/ToonFilterTransform.ts create mode 100644 imageknife/src/main/ets/components/imageknife/transform/VignetteFilterTransform.ets delete mode 100644 imageknife/src/main/ets/components/imageknife/transform/VignetteFilterTransform.ts diff --git a/README.md b/README.md index 15d70fb..f20fcbd 100644 --- a/README.md +++ b/README.md @@ -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 | 装饰滤波器 | diff --git a/entry/src/main/ets/pages/transformPixelMapPage.ets b/entry/src/main/ets/pages/transformPixelMapPage.ets index c31527e..c12da4a 100644 --- a/entry/src/main/ets/pages/transformPixelMapPage.ets +++ b/entry/src/main/ets/pages/transformPixelMapPage.ets @@ -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); diff --git a/gpu_transform/CHANGELOG.md b/gpu_transform/CHANGELOG.md new file mode 100644 index 0000000..80d9941 --- /dev/null +++ b/gpu_transform/CHANGELOG.md @@ -0,0 +1,16 @@ +## 1.0.0 +获取图片的buffer数据,使用openGL、着色器(Shader),操作GPU,达到图片滤波器的效 +- 支持模糊滤波器 +- 支持亮度滤波器 +- 支持颜色反转滤波器 +- 支持对比度滤波器 +- 支持灰色滤波器 +- 支持桑原滤波器 +- 支持马赛克滤波器 +- 支持乌墨色滤波器 +- 支持素描滤波器 +- 支持扭曲滤波器 +- 支持动画滤波器 +- 支持装饰滤波器 + + diff --git a/gpu_transform/LICENSE b/gpu_transform/LICENSE new file mode 100644 index 0000000..8dada3e --- /dev/null +++ b/gpu_transform/LICENSE @@ -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. diff --git a/gpu_transform/README.OpenSource b/gpu_transform/README.OpenSource new file mode 100644 index 0000000..f7d9005 --- /dev/null +++ b/gpu_transform/README.OpenSource @@ -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)" + } +] \ No newline at end of file diff --git a/gpu_transform/README.md b/gpu_transform/README.md new file mode 100644 index 0000000..08e3ad5 --- /dev/null +++ b/gpu_transform/README.md @@ -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) ,请自由的享受和参与开源。 + + diff --git a/gpu_transform/package.json b/gpu_transform/package.json index 9590234..e2644e5 100644 --- a/gpu_transform/package.json +++ b/gpu_transform/package.json @@ -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":{} +} \ No newline at end of file diff --git a/gpu_transform/src/main/cpp/CMakeLists.txt b/gpu_transform/src/main/cpp/CMakeLists.txt index fcd5572..6407f87 100644 --- a/gpu_transform/src/main/cpp/CMakeLists.txt +++ b/gpu_transform/src/main/cpp/CMakeLists.txt @@ -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 ( diff --git a/gpu_transform/src/main/cpp/common/native_common.h b/gpu_transform/src/main/cpp/common/native_common.h index f2db746..1c178b8 100644 --- a/gpu_transform/src/main/cpp/common/native_common.h +++ b/gpu_transform/src/main/cpp/common/native_common.h @@ -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 diff --git a/gpu_transform/src/main/cpp/constant/constant_shape.h b/gpu_transform/src/main/cpp/constant/constant_shape.h index 78de807..1cac03d 100644 --- a/gpu_transform/src/main/cpp/constant/constant_shape.h +++ b/gpu_transform/src/main/cpp/constant/constant_shape.h @@ -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; diff --git a/gpu_transform/src/main/cpp/napi/napi_init.cpp b/gpu_transform/src/main/cpp/napi/napi_init.cpp index cee7544..da55125 100644 --- a/gpu_transform/src/main/cpp/napi/napi_init.cpp +++ b/gpu_transform/src/main/cpp/napi/napi_init.cpp @@ -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 @@ -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[] = { diff --git a/gpu_transform/src/main/cpp/render/EGLRender.cpp b/gpu_transform/src/main/cpp/render/EGLRender.cpp index 19e3df6..0a051de 100644 --- a/gpu_transform/src/main/cpp/render/EGLRender.cpp +++ b/gpu_transform/src/main/cpp/render/EGLRender.cpp @@ -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 +#include #include #include #include @@ -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)) { diff --git a/gpu_transform/src/main/cpp/render/EGLRender.h b/gpu_transform/src/main/cpp/render/EGLRender.h index 411c397..7456ba5 100644 --- a/gpu_transform/src/main/cpp/render/EGLRender.h +++ b/gpu_transform/src/main/cpp/render/EGLRender.h @@ -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); diff --git a/gpu_transform/src/main/cpp/types/libentry/index.d.ts b/gpu_transform/src/main/cpp/types/libentry/index.d.ts index f7314d0..dc8e76e 100644 --- a/gpu_transform/src/main/cpp/types/libentry/index.d.ts +++ b/gpu_transform/src/main/cpp/types/libentry/index.d.ts @@ -13,4 +13,17 @@ * limitations under the License. */ -export const add: (a: number, b: number) => number; \ No newline at end of file +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; \ No newline at end of file diff --git a/gpu_transform/src/main/cpp/util/DebugLog.h b/gpu_transform/src/main/cpp/util/DebugLog.h index bf5bee5..d3fea9c 100644 --- a/gpu_transform/src/main/cpp/util/DebugLog.h +++ b/gpu_transform/src/main/cpp/util/DebugLog.h @@ -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 diff --git a/gpu_transform/src/main/cpp/util/GLUtils.cpp b/gpu_transform/src/main/cpp/util/GLUtils.cpp index 9850f73..cbced39 100644 --- a/gpu_transform/src/main/cpp/util/GLUtils.cpp +++ b/gpu_transform/src/main/cpp/util/GLUtils.cpp @@ -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 #include diff --git a/gpu_transform/src/main/cpp/util/GLUtils.h b/gpu_transform/src/main/cpp/util/GLUtils.h index 7dd057d..df80ce9 100644 --- a/gpu_transform/src/main/cpp/util/GLUtils.h +++ b/gpu_transform/src/main/cpp/util/GLUtils.h @@ -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 diff --git a/gpu_transform/src/main/cpp/util/NapiUtil.cpp b/gpu_transform/src/main/cpp/util/NapiUtil.cpp index 8422637..eba879f 100644 --- a/gpu_transform/src/main/cpp/util/NapiUtil.cpp +++ b/gpu_transform/src/main/cpp/util/NapiUtil.cpp @@ -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" diff --git a/gpu_transform/src/main/cpp/util/NapiUtil.h b/gpu_transform/src/main/cpp/util/NapiUtil.h index a5331b3..3d2b375 100644 --- a/gpu_transform/src/main/cpp/util/NapiUtil.h +++ b/gpu_transform/src/main/cpp/util/NapiUtil.h @@ -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 diff --git a/gpu_transform/src/main/cpp/util/NativeImage.h b/gpu_transform/src/main/cpp/util/NativeImage.h index d4db217..d79018d 100644 --- a/gpu_transform/src/main/cpp/util/NativeImage.h +++ b/gpu_transform/src/main/cpp/util/NativeImage.h @@ -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; diff --git a/gpu_transform/src/main/ets/gpu/filter/GPUImage3x3TextureSamplingFilter.ts b/gpu_transform/src/main/ets/gpu/filter/GPUImage3x3TextureSamplingFilter.ts index 8719877..14d74c4 100644 --- a/gpu_transform/src/main/ets/gpu/filter/GPUImage3x3TextureSamplingFilter.ts +++ b/gpu_transform/src/main/ets/gpu/filter/GPUImage3x3TextureSamplingFilter.ts @@ -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); } } \ No newline at end of file diff --git a/gpu_transform/src/main/ets/gpu/filter/GPUImageBlurFilter.ts b/gpu_transform/src/main/ets/gpu/filter/GPUImageBlurFilter.ts index 8ca86c1..08930fa 100644 --- a/gpu_transform/src/main/ets/gpu/filter/GPUImageBlurFilter.ts +++ b/gpu_transform/src/main/ets/gpu/filter/GPUImageBlurFilter.ts @@ -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; - private sumWeight:number; +export class GPUImageBlurFilter extends GPUImageFilter { + private blurRadius: number; + private blurOffset: Array; + 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){ + setBlurOffset(blurOffset: Array) { let offset = new Array(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); diff --git a/gpu_transform/src/main/ets/gpu/filter/GPUImageBrightnessFilter.ts b/gpu_transform/src/main/ets/gpu/filter/GPUImageBrightnessFilter.ts index 0e41c2a..bc60f9e 100644 --- a/gpu_transform/src/main/ets/gpu/filter/GPUImageBrightnessFilter.ts +++ b/gpu_transform/src/main/ets/gpu/filter/GPUImageBrightnessFilter.ts @@ -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); } } \ No newline at end of file diff --git a/gpu_transform/src/main/ets/gpu/filter/GPUImageColorInvertFilter.ts b/gpu_transform/src/main/ets/gpu/filter/GPUImageColorInvertFilter.ts index d7251e7..c7699ca 100644 --- a/gpu_transform/src/main/ets/gpu/filter/GPUImageColorInvertFilter.ts +++ b/gpu_transform/src/main/ets/gpu/filter/GPUImageColorInvertFilter.ts @@ -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() { } } \ No newline at end of file diff --git a/gpu_transform/src/main/ets/gpu/filter/GPUImageColorMatrixFilter.ts b/gpu_transform/src/main/ets/gpu/filter/GPUImageColorMatrixFilter.ts index fb520ce..606588a 100644 --- a/gpu_transform/src/main/ets/gpu/filter/GPUImageColorMatrixFilter.ts +++ b/gpu_transform/src/main/ets/gpu/filter/GPUImageColorMatrixFilter.ts @@ -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 = [ - 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 = [ + 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){ + setColorMatrix(colorMatrix: Array) { this.colorMatrix = colorMatrix; - this.setUniformMatrix4f("colorMatrix",this.colorMatrix); + this.setUniformMatrix4f("colorMatrix", this.colorMatrix); } } \ No newline at end of file diff --git a/gpu_transform/src/main/ets/gpu/filter/GPUImageContrastFilter.ts b/gpu_transform/src/main/ets/gpu/filter/GPUImageContrastFilter.ts index a14fc3e..9d35176 100644 --- a/gpu_transform/src/main/ets/gpu/filter/GPUImageContrastFilter.ts +++ b/gpu_transform/src/main/ets/gpu/filter/GPUImageContrastFilter.ts @@ -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); + } } \ No newline at end of file diff --git a/gpu_transform/src/main/ets/gpu/filter/GPUImageFilter.ts b/gpu_transform/src/main/ets/gpu/filter/GPUImageFilter.ts index 23adf93..3dbccff 100644 --- a/gpu_transform/src/main/ets/gpu/filter/GPUImageFilter.ts +++ b/gpu_transform/src/main/ets/gpu/filter/GPUImageFilter.ts @@ -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; - protected width:number; - protected height:number; +export abstract class GPUImageFilter { + private render: NativeEglRender; + private isInitialized: boolean; + private runOnDraw: LinkedList; + 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{ - if (x<0||y<0) { + getPixelMapBuf(x: number, y: number, width: number, height: number): Promise { + 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){ - if (value.length !==2) { + protected setFloat2f(location: string, value: Array) { + 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){ - if (value.length !==2) { + protected setFloatVec2(location: string, value: Array) { + 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){ - if (value.length !==3) { + protected setFloatVec3(location: string, value: Array) { + 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){ - if (value.length !==4) { + protected setFloatVec4(location: string, value: Array) { + 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){ + protected setUniformMatrix3f(location: string, value: Array) { 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){ + protected setUniformMatrix4f(location: string, value: Array) { 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{ + getFilters(): ArrayList { return null; } - destroy(){ + destroy() { this.render.native_glIsDestroy(); this.render = null; this.isInitialized = false; } + abstract getFilterType(): GPUFilterType; - abstract getFilterType():GPUFilterType; abstract onReadySize(); + abstract onInitialized(); } \ No newline at end of file diff --git a/gpu_transform/src/main/ets/gpu/filter/GPUImageFilterGroup.ts b/gpu_transform/src/main/ets/gpu/filter/GPUImageFilterGroup.ts index 1c10cbe..7cef433 100644 --- a/gpu_transform/src/main/ets/gpu/filter/GPUImageFilterGroup.ts +++ b/gpu_transform/src/main/ets/gpu/filter/GPUImageFilterGroup.ts @@ -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; - private filters :ArrayList; - - - constructor(){ + constructor() { super() this.filters = new ArrayList(); } - addFilter(aFilter:GPUImageFilter){ + addFilter(aFilter: GPUImageFilter) { this.filters.add(aFilter); } - getFilters():ArrayList{ + getFilters(): ArrayList { return this.filters; } } diff --git a/gpu_transform/src/main/ets/gpu/filter/GPUImageGrayscaleFilter.ts b/gpu_transform/src/main/ets/gpu/filter/GPUImageGrayscaleFilter.ts index 6d87b4f..9ae8521 100644 --- a/gpu_transform/src/main/ets/gpu/filter/GPUImageGrayscaleFilter.ts +++ b/gpu_transform/src/main/ets/gpu/filter/GPUImageGrayscaleFilter.ts @@ -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() { } } diff --git a/gpu_transform/src/main/ets/gpu/filter/GPUImageKuwaharaFilter.ts b/gpu_transform/src/main/ets/gpu/filter/GPUImageKuwaharaFilter.ts index c25a181..6aff40f 100644 --- a/gpu_transform/src/main/ets/gpu/filter/GPUImageKuwaharaFilter.ts +++ b/gpu_transform/src/main/ets/gpu/filter/GPUImageKuwaharaFilter.ts @@ -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); } } diff --git a/gpu_transform/src/main/ets/gpu/filter/GPUImagePixelationFilter.ts b/gpu_transform/src/main/ets/gpu/filter/GPUImagePixelationFilter.ts index 36f4098..1959db8 100644 --- a/gpu_transform/src/main/ets/gpu/filter/GPUImagePixelationFilter.ts +++ b/gpu_transform/src/main/ets/gpu/filter/GPUImagePixelationFilter.ts @@ -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); } } diff --git a/gpu_transform/src/main/ets/gpu/filter/GPUImageSepiaToneFilter.ts b/gpu_transform/src/main/ets/gpu/filter/GPUImageSepiaToneFilter.ts index 9380270..f28c1c0 100644 --- a/gpu_transform/src/main/ets/gpu/filter/GPUImageSepiaToneFilter.ts +++ b/gpu_transform/src/main/ets/gpu/filter/GPUImageSepiaToneFilter.ts @@ -32,7 +32,6 @@ export class GPUImageSepiaToneFilter extends GPUImageColorMatrixFilter { return GPUFilterType.SEPIA; } - onReadySize() { } diff --git a/gpu_transform/src/main/ets/gpu/filter/GPUImageSwirlFilter.ts b/gpu_transform/src/main/ets/gpu/filter/GPUImageSwirlFilter.ts index d83ddb5..2209327 100644 --- a/gpu_transform/src/main/ets/gpu/filter/GPUImageSwirlFilter.ts +++ b/gpu_transform/src/main/ets/gpu/filter/GPUImageSwirlFilter.ts @@ -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); } } \ No newline at end of file diff --git a/gpu_transform/src/main/ets/gpu/filter/GPUImageToonFilter.ts b/gpu_transform/src/main/ets/gpu/filter/GPUImageToonFilter.ts index f05ac8f..595f97c 100644 --- a/gpu_transform/src/main/ets/gpu/filter/GPUImageToonFilter.ts +++ b/gpu_transform/src/main/ets/gpu/filter/GPUImageToonFilter.ts @@ -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); } } \ No newline at end of file diff --git a/gpu_transform/src/main/ets/gpu/filter/GPUImageVignetterFilter.ts b/gpu_transform/src/main/ets/gpu/filter/GPUImageVignetterFilter.ts index d0fd942..00ebeed 100644 --- a/gpu_transform/src/main/ets/gpu/filter/GPUImageVignetterFilter.ts +++ b/gpu_transform/src/main/ets/gpu/filter/GPUImageVignetterFilter.ts @@ -17,10 +17,10 @@ import { GPUImageFilter } from './GPUImageFilter' import { GPUFilterType } from '../gl/GPUFilterType' export class GPUImageVignetterFilter extends GPUImageFilter { - private vignetteCenter:Array = [0.0,0.0]; - private vignetteColor:Array =[0.0,0.0,0.0]; - private vignetteStart:number; - private vignetteEnd:number; + private vignetteCenter: Array = [0.0, 0.0]; + private vignetteColor: Array = [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){ - this.vignetteCenter =center; - this.setFloatVec2("vignetteCenter",center); + setVignetteCenter(center: Array) { + this.vignetteCenter = center; + this.setFloatVec2("vignetteCenter", center); } - setVignetteColor(colors:Array){ + setVignetteColor(colors: Array) { 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); } } \ No newline at end of file diff --git a/gpu_transform/src/main/ets/gpu/gl/GPUFilterType.ts b/gpu_transform/src/main/ets/gpu/gl/GPUFilterType.ts index fd6ee5b..df20c38 100644 --- a/gpu_transform/src/main/ets/gpu/gl/GPUFilterType.ts +++ b/gpu_transform/src/main/ets/gpu/gl/GPUFilterType.ts @@ -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 } \ No newline at end of file diff --git a/gpu_transform/src/main/ets/gpu/gl/NativeEglRender.ts b/gpu_transform/src/main/ets/gpu/gl/NativeEglRender.ts index 30afbcd..5b1da6b 100644 --- a/gpu_transform/src/main/ets/gpu/gl/NativeEglRender.ts +++ b/gpu_transform/src/main/ets/gpu/gl/NativeEglRender.ts @@ -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(); } } \ No newline at end of file diff --git a/gpu_transform/src/main/ets/gpu/interface/Runnable.ts b/gpu_transform/src/main/ets/gpu/interface/Runnable.ts index 39f4bc1..39597d4 100644 --- a/gpu_transform/src/main/ets/gpu/interface/Runnable.ts +++ b/gpu_transform/src/main/ets/gpu/interface/Runnable.ts @@ -13,6 +13,6 @@ * limitations under the License. */ -export interface Runnable{ +export interface Runnable { run(); } \ No newline at end of file diff --git a/imageknife/src/main/ets/components/imageknife/RequestOption.ets b/imageknife/src/main/ets/components/imageknife/RequestOption.ets index ac6225a..14c27f1 100644 --- a/imageknife/src/main/ets/components/imageknife/RequestOption.ets +++ b/imageknife/src/main/ets/components/imageknife/RequestOption.ets @@ -81,7 +81,7 @@ export class RequestOption { isCacheable: boolean = true; //开启GPU变换绘制 - isOpenGpuTransform: boolean = false; + gpuEnabled: boolean = false; // 变换相关 transformations: Array> = new Array(); generateCacheKey: string = ""; @@ -363,8 +363,8 @@ export class RequestOption { return this; } //开启GPU变换绘制 - openEfficient() { - this.isOpenGpuTransform = true; + enableGPU() { + this.gpuEnabled = true; return this; } diff --git a/imageknife/src/main/ets/components/imageknife/transform/BlurTransformation.ets b/imageknife/src/main/ets/components/imageknife/transform/BlurTransformation.ets index 4523ba6..70a479c 100644 --- a/imageknife/src/main/ets/components/imageknife/transform/BlurTransformation.ets +++ b/imageknife/src/main/ets/components/imageknife/transform/BlurTransformation.ets @@ -71,7 +71,7 @@ export class BlurTransformation implements BaseTransform { } 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); diff --git a/imageknife/src/main/ets/components/imageknife/transform/BrightnessFilterTransformation.ets b/imageknife/src/main/ets/components/imageknife/transform/BrightnessFilterTransformation.ets index d3a72d4..d099976 100644 --- a/imageknife/src/main/ets/components/imageknife/transform/BrightnessFilterTransformation.ets +++ b/imageknife/src/main/ets/components/imageknife/transform/BrightnessFilterTransformation.ets @@ -78,7 +78,7 @@ export class BrightnessFilterTransformation implements BaseTransform { 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); diff --git a/imageknife/src/main/ets/components/imageknife/transform/ContrastFilterTransformation.ets b/imageknife/src/main/ets/components/imageknife/transform/ContrastFilterTransformation.ets index a7c2ddb..57d46c4 100644 --- a/imageknife/src/main/ets/components/imageknife/transform/ContrastFilterTransformation.ets +++ b/imageknife/src/main/ets/components/imageknife/transform/ContrastFilterTransformation.ets @@ -91,7 +91,7 @@ export class ContrastFilterTransformation implements BaseTransform { 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) diff --git a/imageknife/src/main/ets/components/imageknife/transform/GrayscaleTransformation.ets b/imageknife/src/main/ets/components/imageknife/transform/GrayscaleTransformation.ets index 621feeb..1c0fd77 100644 --- a/imageknife/src/main/ets/components/imageknife/transform/GrayscaleTransformation.ets +++ b/imageknife/src/main/ets/components/imageknife/transform/GrayscaleTransformation.ets @@ -71,7 +71,7 @@ export class GrayscaleTransformation implements BaseTransform { 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); diff --git a/imageknife/src/main/ets/components/imageknife/transform/InvertFilterTransformation.ets b/imageknife/src/main/ets/components/imageknife/transform/InvertFilterTransformation.ets index 40fe63c..ffd131c 100644 --- a/imageknife/src/main/ets/components/imageknife/transform/InvertFilterTransformation.ets +++ b/imageknife/src/main/ets/components/imageknife/transform/InvertFilterTransformation.ets @@ -79,7 +79,7 @@ export class InvertFilterTransformation implements BaseTransform { 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); diff --git a/imageknife/src/main/ets/components/imageknife/transform/KuwaharaFilterTransform.ets b/imageknife/src/main/ets/components/imageknife/transform/KuwaharaFilterTransform.ets new file mode 100644 index 0000000..5ce2725 --- /dev/null +++ b/imageknife/src/main/ets/components/imageknife/transform/KuwaharaFilterTransform.ets @@ -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 { + private _mRadius: number; + + constructor(radius: number) { + this._mRadius = radius; + } + + getName() { + return "KuwaharaFilterTransform _mRadius:" + this._mRadius; + } + + transform(buf: ArrayBuffer, request: RequestOption, func?: AsyncTransform) { + if (!buf || buf.byteLength <= 0) { + LogUtil.log(Constants.PROJECT_TAG + ";KuwaharaFilterTransform buf is empty"); + if (func) { + 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) { + 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); + } + } +} \ No newline at end of file diff --git a/imageknife/src/main/ets/components/imageknife/transform/KuwaharaFilterTransform.ts b/imageknife/src/main/ets/components/imageknife/transform/KuwaharaFilterTransform.ts deleted file mode 100644 index 7e8fb80..0000000 --- a/imageknife/src/main/ets/components/imageknife/transform/KuwaharaFilterTransform.ts +++ /dev/null @@ -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 { - private _mRadius: number; - - constructor(radius: number) { - this._mRadius = radius; - } - - getName() { - return "KuwaharaFilterTransform _mRadius:" + this._mRadius; - } - - transform(buf: ArrayBuffer, request: RequestOption, func?: AsyncTransform) { - if (!buf || buf.byteLength <= 0) { - LogUtil.log(Constants.PROJECT_TAG + ";KuwaharaFilterTransform buf is empty"); - if (func) { - 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) { - 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); - } - } -} \ No newline at end of file diff --git a/imageknife/src/main/ets/components/imageknife/transform/PixelationFilterTransformation.ets b/imageknife/src/main/ets/components/imageknife/transform/PixelationFilterTransformation.ets index e8812fd..32705e5 100644 --- a/imageknife/src/main/ets/components/imageknife/transform/PixelationFilterTransformation.ets +++ b/imageknife/src/main/ets/components/imageknife/transform/PixelationFilterTransformation.ets @@ -76,7 +76,7 @@ export class PixelationFilterTransformation implements BaseTransform { } imageSource.createPixelMap(options) .then((data) => { - if (request.isOpenGpuTransform) { + if (request.gpuEnabled) { pixelUtils.pixelGPU(data, this._mPixel, func); } else { pixelUtils.pixel(data, this._mPixel, func); diff --git a/imageknife/src/main/ets/components/imageknife/transform/SepiaFilterTransformation.ets b/imageknife/src/main/ets/components/imageknife/transform/SepiaFilterTransformation.ets index 56eee5b..eee5d66 100644 --- a/imageknife/src/main/ets/components/imageknife/transform/SepiaFilterTransformation.ets +++ b/imageknife/src/main/ets/components/imageknife/transform/SepiaFilterTransformation.ets @@ -75,7 +75,7 @@ export class SepiaFilterTransformation implements BaseTransform { 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); diff --git a/imageknife/src/main/ets/components/imageknife/transform/SketchFilterTransformation.ets b/imageknife/src/main/ets/components/imageknife/transform/SketchFilterTransformation.ets index af55d3f..aa3dbf7 100644 --- a/imageknife/src/main/ets/components/imageknife/transform/SketchFilterTransformation.ets +++ b/imageknife/src/main/ets/components/imageknife/transform/SketchFilterTransformation.ets @@ -63,7 +63,7 @@ export class SketchFilterTransformation implements BaseTransform { } imageSource.createPixelMap(options) .then((data) => { - if (request.isOpenGpuTransform) { + if (request.gpuEnabled) { CalculatePixelUtils.sketchGpu(data, func); } else { CalculatePixelUtils.sketch(data, func); diff --git a/imageknife/src/main/ets/components/imageknife/transform/SwirlFilterTransformation.ets b/imageknife/src/main/ets/components/imageknife/transform/SwirlFilterTransformation.ets index a01ac47..891f315 100644 --- a/imageknife/src/main/ets/components/imageknife/transform/SwirlFilterTransformation.ets +++ b/imageknife/src/main/ets/components/imageknife/transform/SwirlFilterTransformation.ets @@ -90,7 +90,7 @@ export class SwirlFilterTransformation implements BaseTransform { }) } - private async swirl(bitmap: any, degree: number, request: RequestOption, func?: AsyncTransform) { + private async swirl(bitmap: image.PixelMap, degree: number, request: RequestOption, func?: AsyncTransform) { let imageInfo = await bitmap.getImageInfo(); let size = { width: imageInfo.size.width, @@ -105,7 +105,7 @@ export class SwirlFilterTransformation implements BaseTransform { 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); diff --git a/imageknife/src/main/ets/components/imageknife/transform/ToonFilterTransform.ets b/imageknife/src/main/ets/components/imageknife/transform/ToonFilterTransform.ets new file mode 100644 index 0000000..90e1647 --- /dev/null +++ b/imageknife/src/main/ets/components/imageknife/transform/ToonFilterTransform.ets @@ -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 { + 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) { + 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) { + 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); + } + } +} \ No newline at end of file diff --git a/imageknife/src/main/ets/components/imageknife/transform/ToonFilterTransform.ts b/imageknife/src/main/ets/components/imageknife/transform/ToonFilterTransform.ts deleted file mode 100644 index eb83f50..0000000 --- a/imageknife/src/main/ets/components/imageknife/transform/ToonFilterTransform.ts +++ /dev/null @@ -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 { - 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) { - 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) { - 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); - } - } -} \ No newline at end of file diff --git a/imageknife/src/main/ets/components/imageknife/transform/VignetteFilterTransform.ets b/imageknife/src/main/ets/components/imageknife/transform/VignetteFilterTransform.ets new file mode 100644 index 0000000..4f34dbc --- /dev/null +++ b/imageknife/src/main/ets/components/imageknife/transform/VignetteFilterTransform.ets @@ -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 { + private centerPoint: Array = [0.5, 0.5]; + private vignetteColor: Array = [0.0, 0.0, 0.0]; + private vignetteSpace: Array = [0.3, 0.75]; + + constructor(centerPoint: Array, vignetteColor: Array, vignetteSpace: Array) { + if (centerPoint.length === 2) { + this.centerPoint = centerPoint; + } + if (vignetteColor.length === 3) { + this.vignetteColor = vignetteColor; + } + if (vignetteSpace.length === 2) { + this.vignetteSpace = vignetteSpace; + } + } + + getName() { + return "VignetteFilterTransform centerPoint:" + this.centerPoint + ";vignetteColor:" + this.vignetteColor + ";vignetteSpace:" + this.vignetteSpace; + } + + transform(buf: ArrayBuffer, request: RequestOption, func?: AsyncTransform) { + if (!buf || buf.byteLength <= 0) { + LogUtil.log(Constants.PROJECT_TAG + ";VignetteFilterTransform buf is empty"); + if (func) { + 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) { + 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); + } + } +} \ No newline at end of file diff --git a/imageknife/src/main/ets/components/imageknife/transform/VignetteFilterTransform.ts b/imageknife/src/main/ets/components/imageknife/transform/VignetteFilterTransform.ts deleted file mode 100644 index 176a7cd..0000000 --- a/imageknife/src/main/ets/components/imageknife/transform/VignetteFilterTransform.ts +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright (C) 2021 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { 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 { - private centerPoint: Array = [0.5, 0.5]; - private vignetteColor: Array = [0.0, 0.0, 0.0]; - private vignetteSpace: Array = [0.3, 0.75]; - - constructor(centerPoint: Array, vignetteColor: Array, vignetteSpace: Array) { - if (centerPoint.length === 2) { - this.centerPoint = centerPoint; - } - if (vignetteColor.length === 3) { - this.vignetteColor = vignetteColor; - } - if (vignetteSpace.length === 2) { - this.vignetteSpace = vignetteSpace; - } - } - - getName() { - return "VignetteFilterTransform centerPoint:" + this.centerPoint + ";vignetteColor:" + this.vignetteColor + ";vignetteSpace:" + this.vignetteSpace; - } - - transform(buf: ArrayBuffer, request: RequestOption, func?: AsyncTransform) { - if (!buf || buf.byteLength <= 0) { - LogUtil.log(Constants.PROJECT_TAG + ";VignetteFilterTransform buf is empty"); - if (func) { - 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) { - 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); - } - } -} \ No newline at end of file From 779d4dd02d8b039ea07a8fca6886e7e6754ade15 Mon Sep 17 00:00:00 2001 From: tyBrave Date: Wed, 22 Feb 2023 11:14:25 +0800 Subject: [PATCH 10/10] update CHANGELOG,md file Signed-off-by: tyBrave --- gpu_transform/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gpu_transform/CHANGELOG.md b/gpu_transform/CHANGELOG.md index 80d9941..b6f5f7b 100644 --- a/gpu_transform/CHANGELOG.md +++ b/gpu_transform/CHANGELOG.md @@ -1,5 +1,5 @@ ## 1.0.0 -获取图片的buffer数据,使用openGL、着色器(Shader),操作GPU,达到图片滤波器的效 +获取图片的buffer数据,使用openGL、着色器(Shader),操作GPU,达到图片滤波器的效果 - 支持模糊滤波器 - 支持亮度滤波器 - 支持颜色反转滤波器