前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Android SurfaceView onTouchEvent配合OpenCV显示

Android SurfaceView onTouchEvent配合OpenCV显示

作者头像
Vaccae
发布2019-09-24 17:45:23
1K0
发布2019-09-24 17:45:23
举报
文章被收录于专栏:微卡智享微卡智享微卡智享

以前我们整体的介绍了利用SurfaceView调用系统的Camera显示图像,并且通过NDK OpenCV的方式进行图像处理,今天这篇我们就是来介绍一下,在SurfaceView中点击显示图像中的区域进行定位,方便我们手动调整图像的。最后完整的代码会在整个系列都做完后上传到GItHub中。

视频演示

视频说明

通过SurfaceView中点击事件其实相对来说很简单,只要重写onTouchEvent事件就可以。

在参数event里面的getRawX和getRawY就可以获取到点击的坐标点。但是看过以前SurfaceView调用camera的朋友应该记得,我们还除了要旋转相机角度,还要对画布的大小对显示的图像进行缩放,所以本章的重点是解决我们点击的图像怎么对应到上面视频中显示出来的红点位置。

实现思路

点击时进行计算处理

  1. 在onTouchevent事件中获取到屏幕的宽和高。
  2. 通到getRawx和getRawY的坐标计算出在总屏幕中位置比例。
  3. 在调用NDK时通过用生成的图片的宽高乘比例计算出点击的位置坐标(会有一点小的误差,但不影响)。
  4. NDK实现中对坐标进行画圈显示出来。

代码实现

程序框架我们就不在重新搭建了,用的还是《Android利用SurfaceView显示Camera图像爬坑记(六) -- 用OpenCV进行Canny边缘检测》那个Demo。

接下来直接开始

01

VaccaeSurfaceView修改

首先我们先定义几个变量,用于计算我们的坐标点,如图:

然后在VaccaeSurfaceView中直接重写onTouchEvent事件,如下:

我们先通过定义DisplayMetrics来获取到屏幕的分辨率,然后要根据点击的位置横坐标除屏幕长度,纵坐标除屏幕高度计算出对应的比例。

然后在原来的图片处理方法nv21ToBitmap 中,根据图像大小重新计算图片中的坐标x,y的点

nv21ToBitmap方法:

private Bitmap nv21ToBitmap(byte[] nv21, int width, int height) {
    Bitmap bitmap=null;
    try {
        YuvImage image=new YuvImage(nv21, ImageFormat.NV21, width, height, null);
        ByteArrayOutputStream stream=new ByteArrayOutputStream();
        image.compressToJpeg(new Rect(0, 0, width, height), 80, stream);
        //将rawImage转换成bitmap
        BitmapFactory.Options options=new BitmapFactory.Options();
        options.inPreferredConfig=Bitmap.Config.ARGB_8888;
        bitmap=BitmapFactory.decodeByteArray(stream.toByteArray(), 0, stream.size(), options);

        //加入图像旋转
        Matrix m=new Matrix();
        m.postRotate(rotatedegree);
        bitmap=Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(),
                m, true);

        //调用JNI方法处理图像
        if (istouch) {
            touchx=(int) (bitmap.getWidth() * touchxscale);
            touchy=(int) (bitmap.getHeight() * touchyscale);

            bitmap=VaccaeOpenCVJNI.getCameraframetouchbitbmp(bitmap, touchx, touchy);
        }
        stream.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
    return bitmap;
}

02

JNI方法实现

我们在VaccaeOpenCVJNI中加入一个新的native方法

然后通过ALT+Enter直接在我们的native-lib.cpp里面自动生成对应的方法,主要就是生成了Mat图像后加入刚才的点坐标进行画半径50的圆并填充。

完整的实现代码

extern "C"
JNIEXPORT jobject JNICALL
Java_dem_vac_surfaceviewdemo_VaccaeOpenCVJNI_getCameraframetouchbitbmp(JNIEnv *env, jclass clazz,
                                                                       jobject bmp, jint touchx,
                                                                       jint touchy) {
    AndroidBitmapInfo bitmapInfo;
    void *pixelscolor;
    int ret;

    //获取图像信息,如果返回值小于0就是执行失败
    if ((ret = AndroidBitmap_getInfo(env, bmp, &bitmapInfo)) < 0) {
        LOGI("AndroidBitmap_getInfo failed! error-%d", ret);
        return NULL;
    }

    //判断图像类型是不是RGBA_8888类型
    if (bitmapInfo.format != ANDROID_BITMAP_FORMAT_RGBA_8888) {
        LOGI("BitmapInfoFormat error");
        return NULL;
    }

    //获取图像像素值
    if ((ret = AndroidBitmap_lockPixels(env, bmp, &pixelscolor)) < 0) {
        LOGI("AndroidBitmap_lockPixels() failed ! error=%d", ret);
        return NULL;
    }

    //生成源图像
    cv::Mat src(bitmapInfo.height, bitmapInfo.width, CV_8UC4, pixelscolor);

    //点击的点
    cv::Point point(touchx, touchy);
    cv::circle(src, point, 50, cv::Scalar(255, 0, 0), -1);

    //获取原图片的参数
    jclass java_bitmap_class = (jclass) env->FindClass("android/graphics/Bitmap");
    jmethodID mid = env->GetMethodID(java_bitmap_class, "getConfig",
                                     "()Landroid/graphics/Bitmap$Config;");
    jobject bitmap_config = env->CallObjectMethod(bmp, mid);
    //将SRC转换为图片
    jobject _bitmap = mat2bitmap(env, src, false, bitmap_config);

    AndroidBitmap_unlockPixels(env, bmp);


    return _bitmap;
}

这样我们的SurfaceView中点击效果在OpenCV中就实现了,下图就是视频中的点击效果显示。

-END-

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-09-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 微卡智享 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
图片处理
图片处理(Image Processing,IP)是由腾讯云数据万象提供的丰富的图片处理服务,广泛应用于腾讯内部各产品。支持对腾讯云对象存储 COS 或第三方源的图片进行处理,提供基础处理能力(图片裁剪、转格式、缩放、打水印等)、图片瘦身能力(Guetzli 压缩、AVIF 转码压缩)、盲水印版权保护能力,同时支持先进的图像 AI 功能(图像增强、图像标签、图像评分、图像修复、商品抠图等),满足多种业务场景下的图片处理需求。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档