顾海波

【需求】适配鸿蒙

@@ -23,7 +23,7 @@ class IProcessingCameraImage implements ProcessingCameraImage { @@ -23,7 +23,7 @@ class IProcessingCameraImage implements ProcessingCameraImage {
23 } 23 }
24 24
25 IProcessingCameraImage._() { 25 IProcessingCameraImage._() {
26 - final DynamicLibrary convertImageLib = Platform.isAndroid 26 + final DynamicLibrary convertImageLib = Platform.isAndroid || Platform.operatingSystem == "ohos"
27 ? DynamicLibrary.open("libconvertImage.so") 27 ? DynamicLibrary.open("libconvertImage.so")
28 : DynamicLibrary.process(); 28 : DynamicLibrary.process();
29 _convertImageYuv420pToRGB = convertImageLib 29 _convertImageYuv420pToRGB = convertImageLib
  1 +/node_modules
  2 +/oh_modules
  3 +/.preview
  4 +/build
  5 +/.cxx
  6 +/.test
  1 +/**
  2 + * Use these variables when you tailor your ArkTS code. They must be of the const type.
  3 + */
  4 +export const HAR_VERSION = '1.0.0';
  5 +export const BUILD_MODE_NAME = 'debug';
  6 +export const DEBUG = true;
  7 +export const TARGET_NAME = 'default';
  8 +
  9 +/**
  10 + * BuildProfile Class is used only for compatibility purposes.
  11 + */
  12 +export default class BuildProfile {
  13 + static readonly HAR_VERSION = HAR_VERSION;
  14 + static readonly BUILD_MODE_NAME = BUILD_MODE_NAME;
  15 + static readonly DEBUG = DEBUG;
  16 + static readonly TARGET_NAME = TARGET_NAME;
  17 +}
  1 +{
  2 + "apiType": "stageMode",
  3 + "buildOption": {
  4 + "externalNativeOptions": {
  5 + "path": "./src/main/cpp/CMakeLists.txt",
  6 + "arguments": "",
  7 + "cppFlags": "",
  8 + }
  9 + },
  10 + "buildOptionSet": [
  11 + {
  12 + "name": "release",
  13 + "arkOptions": {
  14 + "obfuscation": {
  15 + "ruleOptions": {
  16 + "enable": false,
  17 + "files": [
  18 + "./obfuscation-rules.txt"
  19 + ]
  20 + },
  21 + "consumerFiles": [
  22 + "./consumer-rules.txt"
  23 + ]
  24 + }
  25 + },
  26 + "nativeLib": {
  27 + "debugSymbol": {
  28 + "strip": true,
  29 + "exclude": []
  30 + }
  31 + }
  32 + },
  33 + ],
  34 + "targets": [
  35 + {
  36 + "name": "default"
  37 + },
  38 + {
  39 + "name": "processing_camera_image"
  40 + }
  41 + ]
  42 +}
  1 +import { harTasks } from '@ohos/hvigor-ohos-plugin';
  2 +
  3 +export default {
  4 + system: harTasks, /* Built-in plugin of Hvigor. It cannot be modified. */
  5 + plugins:[] /* Custom plugin to extend the functionality of Hvigor. */
  6 +}
  1 +import ProcessingCameraImagePlugin from './src/main/ets/plugin/ProcessingCameraImagePlugin.ets';
  2 +export default ProcessingCameraImagePlugin;
  1 +# Define project specific obfuscation rules here.
  2 +# You can include the obfuscation configuration files in the current module's build-profile.json5.
  3 +#
  4 +# For more details, see
  5 +# https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/source-obfuscation-V5
  6 +
  7 +# Obfuscation options:
  8 +# -disable-obfuscation: disable all obfuscations
  9 +# -enable-property-obfuscation: obfuscate the property names
  10 +# -enable-toplevel-obfuscation: obfuscate the names in the global scope
  11 +# -compact: remove unnecessary blank spaces and all line feeds
  12 +# -remove-log: remove all console.* statements
  13 +# -print-namecache: print the name cache that contains the mapping from the old names to new names
  14 +# -apply-namecache: reuse the given cache file
  15 +
  16 +# Keep options:
  17 +# -keep-property-name: specifies property names that you want to keep
  18 +# -keep-global-name: specifies names that you want to keep in the global scope
  19 +
  20 +-enable-property-obfuscation
  21 +-enable-toplevel-obfuscation
  22 +-enable-filename-obfuscation
  23 +-enable-export-obfuscation
  1 +{
  2 + "name": "processing_camera_image",
  3 + "version": "1.0.0",
  4 + "description": "Please describe the basic information.",
  5 + "main": "Index.ets",
  6 + "author": "",
  7 + "license": "",
  8 + "dependencies": {
  9 + "@ohos/flutter_ohos": "file:./libs/flutter_embedding.har",
  10 + "libconvertImage.so": "file:./src/main/cpp/types/libconvertImage"
  11 + },
  12 + "modelVersion": "5.0.1",
  13 + "compatibleSdkVersion": "13",
  14 + "compatibleSdkType": "HarmonyOS"
  15 +}
  1 +# the minimum version of CMake.
  2 +cmake_minimum_required(VERSION 3.5.0)
  3 +project(MyApplication2)
  4 +
  5 +set(NATIVERENDER_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR})
  6 +
  7 +if(DEFINED PACKAGE_FIND_FILE)
  8 + include(${PACKAGE_FIND_FILE})
  9 +endif()
  10 +
  11 +include_directories(${NATIVERENDER_ROOT_PATH}
  12 + ${NATIVERENDER_ROOT_PATH}/include)
  13 +
  14 +add_library(convertImage SHARED napi_init.cpp converter.c)
  15 +target_link_libraries(convertImage PUBLIC libace_napi.z.so)
  1 +//
  2 +// Created by thuanpm on 4/22/22.
  3 +//
  4 +
  5 +#include <stdio.h>
  6 +#include "converter.h"
  7 +#include <math.h>
  8 +#include <stdlib.h>
  9 +
  10 +#define HEXFF 255
  11 +
  12 +int _clamp(int lower, int higher, int val)
  13 +{
  14 + if (val < lower)
  15 + return 0;
  16 + else if (val > higher)
  17 + return 255;
  18 + else
  19 + return val;
  20 +}
  21 +
  22 +uint32_t *_rotaion_image_32bit(uint32_t *src, double angle, int width, int height, uint32_t background_color)
  23 +{
  24 + double rad = (angle * M_PI / 180.0);
  25 + double sinVal = sin(rad);
  26 + double cosVal = cos(rad);
  27 + int new_width = (int)(fabs(sinVal * height) + fabs(cosVal * width));
  28 + int new_height = (int)(fabs(sinVal * width) + fabs(cosVal * height));
  29 + double w2 = 0.5 * width;
  30 + double h2 = 0.5 * height;
  31 + double dw2 = 0.5 * new_width;
  32 + double dh2 = 0.5 * new_height;
  33 +
  34 + uint32_t *dest = malloc(sizeof(uint32_t) * (new_width * new_height));
  35 +
  36 + for (int i = 0; i < new_height; ++i)
  37 + {
  38 + for (int j = 0; j < new_width; ++j)
  39 + {
  40 + int oriX = (int)(w2 + (j - dw2) * cosVal + (i - dh2) * sinVal);
  41 + int oriY = (int)(h2 - (j - dw2) * sinVal + (i - dh2) * cosVal);
  42 + if (oriX >= 0 && oriX < width && oriY >= 0 && oriY < height)
  43 + {
  44 + dest[i * new_width + j] = src[oriX + oriY * width];
  45 + }
  46 + else
  47 + {
  48 + dest[i * new_width + j] = background_color;
  49 + }
  50 + }
  51 + }
  52 + free(src);
  53 + return dest;
  54 +}
  55 +
  56 +uint8_t *_rotaion_image_8bit(uint8_t *src, double angle, int width, int height, uint8_t background_color)
  57 +{
  58 + double rad = (angle * M_PI / 180.0);
  59 + double sinVal = sin(rad);
  60 + double cosVal = cos(rad);
  61 + int new_width = (int)(fabs(sinVal * height) + fabs(cosVal * width));
  62 + int new_height = (int)(fabs(sinVal * width) + fabs(cosVal * height));
  63 + double w2 = 0.5 * width;
  64 + double h2 = 0.5 * height;
  65 + double dw2 = 0.5 * new_width;
  66 + double dh2 = 0.5 * new_height;
  67 +
  68 + uint8_t *dest = malloc(sizeof(uint8_t) * (new_width * new_height));
  69 +
  70 + for (int i = 0; i < new_height; ++i)
  71 + {
  72 + for (int j = 0; j < new_width; ++j)
  73 + {
  74 + int oriX = (int)(w2 + (j - dw2) * cosVal + (i - dh2) * sinVal);
  75 + int oriY = (int)(h2 - (j - dw2) * sinVal + (i - dh2) * cosVal);
  76 + if (oriX >= 0 && oriX < width && oriY >= 0 && oriY < height)
  77 + {
  78 + dest[i * new_width + j] = src[oriX + oriY * width];
  79 + }
  80 + else
  81 + {
  82 + dest[i * new_width + j] = background_color;
  83 + }
  84 + }
  85 + }
  86 + free(src);
  87 + return dest;
  88 +}
  89 +
  90 +void _flip_horizontal_32bit(int width, int height, uint32_t *src)
  91 +{
  92 + int dw2 = (int)(width / 2);
  93 + for (int y = 0; y < height; ++y)
  94 + {
  95 + int y1 = (y * width);
  96 + for (int x = 0; x < dw2; ++x)
  97 + {
  98 + int x2 = (width - 1 - x);
  99 + uint32_t t = src[y1 + x2];
  100 + src[y1 + x2] = src[y1 + x];
  101 + src[y1 + x] = t;
  102 + }
  103 + }
  104 +}
  105 +
  106 +void _flip_horizontal_8bit(int width, int height, uint8_t *src)
  107 +{
  108 + int dw2 = (int)(width / 2);
  109 + for (int y = 0; y < height; ++y)
  110 + {
  111 + int y1 = (y * width);
  112 + for (int x = 0; x < dw2; ++x)
  113 + {
  114 + int x2 = (width - 1 - x);
  115 + uint8_t t = src[y1 + x2];
  116 + src[y1 + x2] = src[y1 + x];
  117 + src[y1 + x] = t;
  118 + }
  119 + }
  120 +}
  121 +
  122 +void _flip_vertical_32bit(int width, int height, uint32_t *src)
  123 +{
  124 + int h2 = (int)(height / 2);
  125 + for (int y = 0; y < h2; ++y)
  126 + {
  127 + int y1 = (y * width);
  128 + int y2 = (height - 1 - y) * width;
  129 + for (int x = 0; x < width; ++x)
  130 + {
  131 + uint32_t t = src[y2 + x];
  132 + src[y2 + x] = src[y1 + x];
  133 + src[y1 + x] = t;
  134 + }
  135 + }
  136 +}
  137 +
  138 +void _flip_vertical_8bit(int width, int height, uint8_t *src)
  139 +{
  140 + int h2 = (int)(height / 2);
  141 + for (int y = 0; y < h2; ++y)
  142 + {
  143 + int y1 = (y * width);
  144 + int y2 = (height - 1 - y) * width;
  145 + for (int x = 0; x < width; ++x)
  146 + {
  147 + uint8_t t = src[y2 + x];
  148 + src[y2 + x] = src[y1 + x];
  149 + src[y1 + x] = t;
  150 + }
  151 + }
  152 +}
  153 +
  154 +uint32_t *convert_image_yuv420p_to_gray(uint8_t *plane0, int width, int height, double angleRotation, uint32_t background_color, bool flip_vertical, bool flip_horizontal)
  155 +{
  156 + int x, y;
  157 + int yp, index;
  158 +
  159 + uint32_t *src = malloc(sizeof(uint32_t) * (width * height));
  160 +
  161 + for (x = 0; x < width; x++)
  162 + {
  163 + for (y = 0; y < height; y++)
  164 + {
  165 + index = y * width + x;
  166 + yp = plane0[index];
  167 + src[x + y * width] = (HEXFF << 24) | (yp << 16) | (yp << 8) | yp;
  168 + }
  169 + }
  170 + if (flip_horizontal)
  171 + {
  172 + _flip_horizontal_32bit(width, height, src);
  173 + }
  174 + if (flip_vertical)
  175 + {
  176 + _flip_vertical_32bit(width, height, src);
  177 + }
  178 +
  179 + if (angleRotation == 0)
  180 + {
  181 + return src;
  182 + }
  183 +
  184 + else
  185 + {
  186 + return _rotaion_image_32bit(src, angleRotation, width, height, background_color);
  187 + }
  188 +}
  189 +
  190 +uint8_t *convert_image_yuv420p_to_gray_8bit(uint8_t *plane0, int width, int height, double angleRotation, uint8_t background_color, bool flip_vertical, bool flip_horizontal)
  191 +{
  192 + int x, y;
  193 + int index;
  194 + uint8_t yp;
  195 +
  196 + uint8_t *src = malloc(sizeof(uint8_t) * (width * height));
  197 +
  198 + for (x = 0; x < width; x++)
  199 + {
  200 + for (y = 0; y < height; y++)
  201 + {
  202 + index = y * width + x;
  203 + yp = plane0[index];
  204 + src[x + y * width] = yp;
  205 + }
  206 + }
  207 +
  208 + if (flip_horizontal)
  209 + {
  210 + _flip_horizontal_8bit(width, height, src);
  211 + }
  212 + if (flip_vertical)
  213 + {
  214 + _flip_vertical_8bit(width, height, src);
  215 + }
  216 +
  217 + if (angleRotation == 0)
  218 + {
  219 + return src;
  220 + }
  221 + else
  222 + {
  223 + return _rotaion_image_8bit(src, angleRotation, width, height, background_color);
  224 + }
  225 +}
  226 +
  227 +uint32_t *convert_image_yuv420p_to_rgb(uint8_t *plane0, uint8_t *plane1, uint8_t *plane2, int bytesPerRow, int bytesPerPixel, int width, int height, double angleRotation, uint32_t background_color, bool flip_vertical, bool flip_horizontal)
  228 +{
  229 + int x, y, uvIndex, index;
  230 + int yp, up, vp;
  231 + int r, g, b;
  232 + int rt, gt, bt;
  233 +
  234 + uint32_t *src = malloc(sizeof(uint32_t) * (width * height));
  235 +
  236 + for (x = 0; x < width; ++x)
  237 + {
  238 + for (y = 0; y < height; ++y)
  239 + {
  240 + uvIndex = bytesPerPixel * ((int)floor(x / 2)) + bytesPerRow * ((int)floor(y / 2));
  241 + index = y * width + x;
  242 +
  243 + yp = plane0[index];
  244 + up = plane1[uvIndex];
  245 + vp = plane2[uvIndex];
  246 + rt = round(yp + vp * 1436 / 1024 - 179);
  247 + gt = round(yp - up * 46549 / 131072 + 44 - vp * 93604 / 131072 + 91);
  248 + bt = round(yp + up * 1814 / 1024 - 227);
  249 + r = _clamp(0, 255, rt);
  250 + g = _clamp(0, 255, gt);
  251 + b = _clamp(0, 255, bt);
  252 + src[x + y * width] = (HEXFF << 24) | (b << 16) | (g << 8) | r;
  253 + }
  254 + }
  255 + if (flip_horizontal)
  256 + {
  257 + _flip_horizontal_32bit(width, height, src);
  258 + }
  259 + if (flip_vertical)
  260 + {
  261 + _flip_vertical_32bit(width, height, src);
  262 + }
  263 +
  264 + if (angleRotation == 0)
  265 + {
  266 + return src;
  267 + }
  268 + else
  269 + {
  270 + return _rotaion_image_32bit(src, angleRotation, width, height, background_color);
  271 + }
  272 +}
  273 +
  274 +uint32_t *convert_image_nv12_to_rgb(uint8_t *plane0, uint8_t *plane1, int bytesPerRow, int bytesPerPixel, int width, int height, double angleRotation, uint32_t background_color, bool flip_vertical, bool flip_horizontal)
  275 +{
  276 + int x, y, uvIndex, index;
  277 + int yp, up, vp;
  278 + int r, g, b;
  279 + int rt, gt, bt;
  280 +
  281 + uint32_t *src = malloc(sizeof(uint32_t) * (width * height));
  282 +
  283 + for (x = 0; x < width; ++x)
  284 + {
  285 + for (y = 0; y < height; ++y)
  286 + {
  287 + uvIndex = bytesPerPixel * ((int)floor(x / 2)) + bytesPerRow * ((int)floor(y / 2));
  288 + index = y * width + x;
  289 +
  290 + yp = plane0[index];
  291 + up = plane1[uvIndex];
  292 + vp = plane1[uvIndex + 1];
  293 + rt = round(yp + vp * 1436 / 1024 - 179);
  294 + gt = round(yp - up * 46549 / 131072 + 44 - vp * 93604 / 131072 + 91);
  295 + bt = round(yp + up * 1814 / 1024 - 227);
  296 + r = _clamp(0, 255, rt);
  297 + g = _clamp(0, 255, gt);
  298 + b = _clamp(0, 255, bt);
  299 + src[x + y * width] = (HEXFF << 24) | (b << 16) | (g << 8) | r;
  300 + }
  301 + }
  302 + if (flip_horizontal)
  303 + {
  304 + _flip_horizontal_32bit(width, height, src);
  305 + }
  306 + if (flip_vertical)
  307 + {
  308 + _flip_vertical_32bit(width, height, src);
  309 + }
  310 + if (angleRotation == 0)
  311 + {
  312 + return src;
  313 + }
  314 + else
  315 + {
  316 + return _rotaion_image_32bit(src, angleRotation, width, height, background_color);
  317 + }
  318 +}
  1 +//
  2 +// Created by thuanpm on 4/22/22.
  3 +//
  4 +
  5 +#ifndef PROCESSING_CAMERA_IMAGE_CONVERTER_H
  6 +#define PROCESSING_CAMERA_IMAGE_CONVERTER_H
  7 +
  8 +#ifdef __cplusplus
  9 +extern "C"
  10 +{
  11 +#endif
  12 +
  13 +#include <stdbool.h>
  14 +
  15 + uint8_t *convert_image_yuv420p_to_gray_8bit(uint8_t *plane0, int width, int height, double angleRotation, uint8_t background_color, bool flip_vertical, bool flip_horizontal);
  16 + uint32_t *convert_image_nv12_to_rgb(uint8_t *plane0, uint8_t *plane1, int bytesPerRow, int bytesPerPixel, int width, int height, double angleRotation, uint32_t background_color, bool flip_vertical, bool flip_horizontal);
  17 + uint32_t *convert_image_yuv420p_to_gray(uint8_t *plane0, int width, int height, double angleRotation, uint32_t background_color, bool flip_vertical, bool flip_horizontal);
  18 + uint32_t *convert_image_yuv420p_to_rgb(uint8_t *plane0, uint8_t *plane1, uint8_t *plane2, int bytesPerRow, int bytesPerPixel, int width, int height, double angleRotation, uint32_t background_color, bool flip_vertical, bool flip_horizontal);
  19 +
  20 +#ifdef __cplusplus
  21 +}
  22 +#endif
  23 +
  24 +#endif // PROCESSING_CAMERA_IMAGE_CONVERTER_H
  1 +#include "napi/native_api.h"
  2 +
  3 +static napi_value Add(napi_env env, napi_callback_info info)
  4 +{
  5 + size_t argc = 2;
  6 + napi_value args[2] = {nullptr};
  7 +
  8 + napi_get_cb_info(env, info, &argc, args , nullptr, nullptr);
  9 +
  10 + napi_valuetype valuetype0;
  11 + napi_typeof(env, args[0], &valuetype0);
  12 +
  13 + napi_valuetype valuetype1;
  14 + napi_typeof(env, args[1], &valuetype1);
  15 +
  16 + double value0;
  17 + napi_get_value_double(env, args[0], &value0);
  18 +
  19 + double value1;
  20 + napi_get_value_double(env, args[1], &value1);
  21 +
  22 + napi_value sum;
  23 + napi_create_double(env, value0 + value1, &sum);
  24 +
  25 + return sum;
  26 +
  27 +}
  28 +
  29 +EXTERN_C_START
  30 +static napi_value Init(napi_env env, napi_value exports)
  31 +{
  32 + napi_property_descriptor desc[] = {
  33 + { "add", nullptr, Add, nullptr, nullptr, nullptr, napi_default, nullptr }
  34 + };
  35 + napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
  36 + return exports;
  37 +}
  38 +EXTERN_C_END
  39 +
  40 +static napi_module demoModule = {
  41 + .nm_version = 1,
  42 + .nm_flags = 0,
  43 + .nm_filename = nullptr,
  44 + .nm_register_func = Init,
  45 + .nm_modname = "entry",
  46 + .nm_priv = ((void*)0),
  47 + .reserved = { 0 },
  48 +};
  49 +
  50 +extern "C" __attribute__((constructor)) void RegisterEntryModule(void)
  51 +{
  52 + napi_module_register(&demoModule);
  53 +}
  1 +export const add: (a: number, b: number) => number;
  1 +{
  2 + "name": "libconvertImage.so",
  3 + "types": "./Index.d.ts",
  4 + "version": "1.0.0",
  5 + "description": "Please describe the basic information."
  6 +}
  1 +import {
  2 + FlutterPlugin,
  3 + FlutterPluginBinding,
  4 + MethodCall,
  5 + MethodCallHandler,
  6 + MethodChannel,
  7 + MethodResult,
  8 +} from '@ohos/flutter_ohos';
  9 +
  10 +import common from '@ohos.app.ability.common';
  11 +
  12 +/** ProcessingCameraImagePlugin **/
  13 +export default class ProcessingCameraImagePlugin implements FlutterPlugin, MethodCallHandler {
  14 + private channel: MethodChannel | null = null;
  15 + private context: common.Context | null = null;
  16 +
  17 + constructor(context?: common.Context) {
  18 + if (context) {
  19 + this.context = context;
  20 + }
  21 + }
  22 +
  23 + getUniqueClassName(): string {
  24 + return "ProcessingCameraImagePlugin"
  25 + }
  26 +
  27 + onAttachedToEngine(binding: FlutterPluginBinding): void {
  28 + this.channel = new MethodChannel(binding.getBinaryMessenger(), "processing_camera_image");
  29 + this.channel.setMethodCallHandler(this)
  30 +
  31 + this.context = binding.getApplicationContext();
  32 + // hilog.info(0x0000, 'start', 'MMKVPlugin onAttachedToEngine: %{public}s', this.context);
  33 + }
  34 +
  35 + onDetachedFromEngine(binding: FlutterPluginBinding): void {
  36 + if (this.channel != null) {
  37 + this.channel.setMethodCallHandler(null)
  38 + }
  39 + }
  40 +
  41 + onMethodCall(call: MethodCall, result: MethodResult): void {
  42 + result.notImplemented()
  43 + }
  44 +}
  1 +{
  2 + "module": {
  3 + "name": "processing_camera_image",
  4 + "type": "har",
  5 + "deviceTypes": [
  6 + "phone",
  7 + "tablet",
  8 + "2in1"
  9 + ]
  10 + }
  11 +}
@@ -35,6 +35,8 @@ flutter: @@ -35,6 +35,8 @@ flutter:
35 pluginClass: ProcessingCameraImagePlugin 35 pluginClass: ProcessingCameraImagePlugin
36 ios: 36 ios:
37 pluginClass: ProcessingCameraImagePlugin 37 pluginClass: ProcessingCameraImagePlugin
  38 + ohos:
  39 + pluginClass: ProcessingCameraImagePlugin
38 40
39 # To add assets to your plugin package, add an assets section, like this: 41 # To add assets to your plugin package, add an assets section, like this:
40 # assets: 42 # assets: