1.【环境】

reactnative 0.62.0

react-native-opencv3 基础上做了修改,使用了4.3.0-contrib

com.quickbirdstudios:opencv:4.3.0-contrib

不要直接安装react-native-opencv3,因为只是在其基础上进行修改。从git上下载下代码

git clone GitHub - adamgf/react-native-opencv3: react-native-opencv3 wraps functionality from OpenCV Java SDK 3.4.4 + contrib modules and iOS OpenCV 3.4.1 + contrib modules for use in React-Native apps. Please enjoy!

2.【遇到的相关问题】

        1) 修改react-native-opencv3中的build.gradle,引用opencv4.3.0修改如下:

dependencies {
    implementation 'com.quickbirdstudios:opencv:4.3.0-contrib'
    implementation 'com.facebook.react:react-native:+'
}

        2)针对react-native-opencv3中的各种bug的修复

                a). react-native-opencv3中保存图像的错误修复

                     新增如下方法:

@ReactMethod
    public void imwrite(String outPath, ReadableMap srcMat, final Promise promise) {
        int matIndex = srcMat.getInt("matIndex");
        Mat mat = (Mat) MatManager.getInstance().matAtIndex(matIndex);
        FileUtils.getInstance().imwrite(outPath, mat, promise);
    }
 public static void imwrite(final String outpath, final Mat dst, final Promise promise) {
        try {
            if (outpath == null || outpath.length() == 0) {
                // TODO: if no path sent in then auto-generate??!!!?
                rejectInvalidParam(promise, outpath);
                return;
            }

            Imgcodecs.imwrite(outpath, dst);

            WritableNativeMap result = new WritableNativeMap();
            result.putInt("width", new Double(dst.size().width).intValue());
            result.putInt("height", new Double(dst.size().height).intValue());
            result.putString("uri", outpath);

            promise.resolve(result);
        } catch (Exception ex) {
            ex.printStackTrace();
            reject(promise, "EGENERIC", ex);
        }
    }

                b). 原来的RNOpencv4Module.matToImage方法读取图片是24位4通道,在opencv中使用时多数情况都用不了,因此新增方法:

 @ReactMethod
    public void imageToMatWith16Bit3Channels(String inPath, final Promise promise) {
        FileUtils.getInstance().imageToMatWith16Bit3Channels(inPath, promise);
    }
public static void imageToMatWith16Bit3Channels(final String inPath,  final Promise promise) {
        try {
            if (inPath == null || inPath.length() == 0) {
                rejectInvalidParam(promise, inPath);
                return;
            }

            File inFileTest = new File(inPath);
            if (!inFileTest.exists()) {
                rejectFileNotFound(promise, inPath);
                return;
            }
            if (inFileTest.isDirectory()) {
                rejectFileIsDirectory(promise, inPath);
                return;
            }

            java.io.FileInputStream inx = null;
            ByteArrayOutputStream out = null;
            Mat p2 = null;
            try {
                inx = new java.io.FileInputStream(new java.io.File(inPath));
                out = new ByteArrayOutputStream();
                byte[] data = new byte[1024];
                int count = -1;
                while ((count = inx.read(data)) != -1) {
                    out.write(data, 0, count);
                }
                p2 = Imgcodecs.imdecode(new MatOfByte(out.toByteArray()), Imgcodecs.IMREAD_UNCHANGED);
            } catch(Exception e2){
                e2.printStackTrace();
            } finally {
                if (inx != null) {
                    try {
                        inx.close();
                    } catch (Exception ezz) {

                    }
                }
                if (out != null) {
                    try {
                        out.close();
                    } catch (Exception ezz) {
                    }
                }
            }

            int matIndex = MatManager.getInstance().addMat(p2);
            WritableNativeMap result = new WritableNativeMap();
            result.putInt("cols", p2.cols());
            result.putInt("rows", p2.rows());
            result.putInt("matIndex", matIndex);
            promise.resolve(result);
        } catch (Exception ex) {
            reject(promise, "EGENERIC", ex);
        }
    }

                c). 对inpain函数的支持,新增类:CvPhotoModule.java,代码如下:


public class CvPhotoModule extends ReactContextBaseJavaModule {

    private static final String TAG = CvPhotoModule.class.getSimpleName();

    public CvPhotoModule(ReactApplicationContext reactContext) {
        super(reactContext);
    }

    @Override
    public String getName() {
        return "CvPhoto";
    }

    @ReactMethod
    public void inpaint(final ReadableMap sourceMat, final ReadableMap maskMat, final ReadableMap destMat,final double inpaintRadius,final int flags, final Promise promise) {
        try {
            int matIndex = sourceMat.getInt("matIndex");
            Mat srMat = (Mat) MatManager.getInstance().matAtIndex(matIndex);
            matIndex = maskMat.getInt("matIndex");
            Mat maskBGR = (Mat) MatManager.getInstance().matAtIndex(matIndex);
            matIndex = destMat.getInt("matIndex");
            Mat dtMat = (Mat) MatManager.getInstance().matAtIndex(matIndex);
            Photo.inpaint(srMat, maskBGR, dtMat, inpaintRadius, flags);
            promise.resolve("ok");
        }catch(Exception e) {
            e.printStackTrace();
            promise.reject(null, e.getMessage());
        }
    }
}

                d). 新增绘制矩形方法,代码如下:

package com.huxg.opencv4bridge;

import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.uimanager.UIBlock;

import org.opencv.core.Mat;
import org.opencv.core.Rect;
import org.opencv.core.Scalar;
import org.opencv.imgproc.Imgproc;

public class CvImgprocModule extends ReactContextBaseJavaModule {

    private static final String TAG = CvImgprocModule.class.getSimpleName();

    public CvImgprocModule(ReactApplicationContext reactContext) {
        super(reactContext);
    }

    @Override
    public String getName() {
        return "CvImgproc";
    }

    @ReactMethod
    public void drawRectangle(final ReadableMap matMap, final ReadableMap rectMap, final ReadableMap colorMap,  final Promise promise) {
        try {
            int matIndex = matMap.getInt("matIndex");
            Mat mat = (Mat) MatManager.getInstance().matAtIndex(matIndex);

            int x = rectMap.getInt("left");
            int y = rectMap.getInt("top");
            int width = rectMap.getInt("width");
            int height = rectMap.getInt("height");
            Rect rect = new Rect(x, y, width, height);

            ReadableArray scalarVal = colorMap.getArray("vals");
            Scalar scalar = new Scalar(scalarVal.getDouble(0), scalarVal.getDouble(1), scalarVal.getDouble(2), scalarVal.getDouble(3));

            Imgproc.rectangle(mat, rect, scalar);

            MatManager.getInstance().setMat(matIndex, mat);
            promise.resolve("ok");
        }catch(Exception e) {
            promise.reject(null, e.getMessage());
        }
    }

    @ReactMethod
    public void drawBorderedRectangle(final ReadableMap matMap, final ReadableMap rectMap, final ReadableMap colorMap,  int thickness, final Promise promise) {
        try {
            int matIndex = matMap.getInt("matIndex");
            Mat mat = (Mat) MatManager.getInstance().matAtIndex(matIndex);

            int x = rectMap.getInt("left");
            int y = rectMap.getInt("top");
            int width = rectMap.getInt("width");
            int height = rectMap.getInt("height");
            Rect rect = new Rect(x, y, width, height);

            ReadableArray scalarVal = colorMap.getArray("vals");
            Scalar scalar = new Scalar(scalarVal.getDouble(0), scalarVal.getDouble(1), scalarVal.getDouble(2), scalarVal.getDouble(3));

            Imgproc.rectangle(mat, rect, scalar, thickness);

            MatManager.getInstance().setMat(matIndex, mat);
            promise.resolve("ok");
        }catch(Exception e) {
            promise.reject(null, e.getMessage());
        }
    }

    @ReactMethod
    public void drawSolidRectangle(final ReadableMap matMap, final ReadableMap rectMap, final ReadableMap colorMap, final Promise promise) {
        try {
            int matIndex = matMap.getInt("matIndex");
            Mat mat = (Mat) MatManager.getInstance().matAtIndex(matIndex);

            int x = rectMap.getInt("left");
            int y = rectMap.getInt("top");
            int width = rectMap.getInt("width");
            int height = rectMap.getInt("height");
            Rect rect = new Rect(x, y, width, height);

            ReadableArray scalarVal = colorMap.getArray("vals");
            Scalar scalar = new Scalar(scalarVal.getDouble(0), scalarVal.getDouble(1), scalarVal.getDouble(2), scalarVal.getDouble(3));

            Imgproc.rectangle(mat, rect, scalar, -1);

            MatManager.getInstance().setMat(matIndex, mat);
            promise.resolve("ok");
        }catch(Exception e) {
            promise.reject(null, e.getMessage());
        }
    }
}

如果希望要全部的react-native-opencv4的代码可以给我发邮件。

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐