仿百度汉语拍照涂抹识别(一)

之前做过一个项目是关于手写识别的,本篇文章主要分三步介绍:
1.自定义相机拍照显示要识别的图片
2.在图片上面进行手指的触摸操作,模拟选中要操作的区域,选择要选中的文字
3.用ocr技术识别出来选中的文字,后续还有中英文释义派生,这里先忽略了

上图
这里写图片描述 这里写图片描述

自定义相机,自动对焦,支持触摸涂抹:
具体步骤:
自动对焦功能,这里是自定义一个focusview,调用camera.autoFocus(this)方法。

/**
     * 设置焦点和测光区域
     *
     * @param event
     */
    public void focusOnTouch(MotionEvent event) {

        int[] location = new int[2];
        RelativeLayout relativeLayout = (RelativeLayout) getParent();
        relativeLayout.getLocationOnScreen(location);

        Rect focusRect = Utils.calculateTapArea(mFocusView.getWidth(),
                mFocusView.getHeight(), 1f, event.getRawX(), event.getRawY(),
                location[0], location[0] + relativeLayout.getWidth(), location[1],
                location[1] + relativeLayout.getHeight());
        Rect meteringRect = Utils.calculateTapArea(mFocusView.getWidth(),
                mFocusView.getHeight(), 1.5f, event.getRawX(), event.getRawY(),
                location[0], location[0] + relativeLayout.getWidth(), location[1],
                location[1] + relativeLayout.getHeight());

        Camera.Parameters parameters = camera.getParameters();
        parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);

        if (parameters.getMaxNumFocusAreas() > 0) {
            List<Camera.Area> focusAreas = new ArrayList<Camera.Area>();
            focusAreas.add(new Camera.Area(focusRect, 1000));

            parameters.setFocusAreas(focusAreas);
        }

        if (parameters.getMaxNumMeteringAreas() > 0) {
            List<Camera.Area> meteringAreas = new ArrayList<Camera.Area>();
            meteringAreas.add(new Camera.Area(meteringRect, 1000));

            parameters.setMeteringAreas(meteringAreas);
        }

        try {
            camera.setParameters(parameters);
        } catch (Exception e) {
        }
        camera.autoFocus(this);
    }

    /**
     * 设置聚焦的图片
     *
     * @param focusView
     */
    public void setFocusView(FocusView focusView) {
        this.mFocusView = focusView;
    }

    /**
     * 设置自动聚焦,并且聚焦的圈圈显示在屏幕中间位置
     */
    public void setFocus() {
        if (!mFocusView.isFocusing()) {
            try {
                camera.autoFocus(this);
                mFocusView.setX((Utils.getWidthInPx(getContext()) - mFocusView.getWidth()) / 2);
                mFocusView.setY((Utils.getHeightInPx(getContext()) - mFocusView.getHeight()) / 2);
                mFocusView.beginFocus();

            } catch (Exception e) {
            }
        }
    }

这里手指的滑动涂抹效果,定义一个rubberview,创建一个trackBitmap,一会儿要在此图片上画滑动轨迹,然后通过Xfermode技术同遮罩层图片融合就能实现涂抹的效果:

@Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);

        int width = right - left;
        int height = bottom - top;

        // 初始化轨迹图片,稍后将在此图上绘制触摸轨迹
        if (trackBitmap == null) {
            trackBitmap = Bitmap.createBitmap(width - getPaddingRight() - getPaddingLeft(), height - getPaddingBottom() - getPaddingTop(), Bitmap.Config.ARGB_8888);
            trackBitmapCanvas = new Canvas(trackBitmap);
            // 如果已经创建了但是宽高有变化就重新创建
        } else if (trackBitmap.getWidth() != width - getPaddingRight() - getPaddingLeft() || trackBitmap.getHeight() != height - getPaddingBottom() - getPaddingTop()) {
            trackBitmap.recycle();
            trackBitmap = Bitmap.createBitmap(width - getPaddingRight() - getPaddingLeft(), height - getPaddingBottom() - getPaddingTop(), Bitmap.Config.ARGB_8888);
            trackBitmapCanvas.setBitmap(trackBitmap);
        }

        // 初始化遮罩图片
        if (maskBitmap == null) {
            maskBitmap = Bitmap.createBitmap(width - getPaddingRight() - getPaddingLeft(), height - getPaddingBottom() - getPaddingTop(), Bitmap.Config.ARGB_8888);
//            new Canvas(maskBitmap).drawColor(defaultMaskColor);
            new Canvas(maskBitmap).drawColor(Color.argb(100, 0, 0, 0));
//            new Canvas(maskBitmap).drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);//绘制透明色
        }

        // 初始化dst位置
        if (dstRect == null) {
            dstRect = new Rect(getPaddingLeft(), getPaddingTop(), width - getPaddingRight(), height - getPaddingBottom());
        } else {
            dstRect.set(getPaddingLeft(), getPaddingTop(), width - getPaddingRight(), height - getPaddingBottom());
        }
        srcRect = computeSrcRect(new Point(maskBitmap.getWidth(), maskBitmap.getHeight()), new Point(dstRect.width(), dstRect.height()), ImageView.ScaleType.CENTER_CROP);
    }

主要看看重写onlayout中的方法,初始化遮罩图片,在灰色阴影图上画滑动轨迹,纪录轨迹的多点坐标,算出画出的图片,生成轨迹图片,到这里前面两部分就都完成了,后续会讲述图片的具体生成方法以及ocr的识别。

这里计算图形滑动的区域:

public static Rect computeSrcRect(Point sourceSize, Point targetSize, ImageView.ScaleType scaleType) {
        if (scaleType == ImageView.ScaleType.CENTER_INSIDE || scaleType == ImageView.ScaleType.MATRIX || scaleType == ImageView.ScaleType.FIT_XY) {
            return new Rect(0, 0, sourceSize.x, sourceSize.y);
        } else {
            float scale;
            if (Math.abs(sourceSize.x - targetSize.x) < Math.abs(sourceSize.y - targetSize.y)) {
                scale = (float) sourceSize.x / targetSize.x;
                if ((int) (targetSize.y * scale) > sourceSize.y) {
                    scale = (float) sourceSize.y / targetSize.y;
                }
            } else {
                scale = (float) sourceSize.y / targetSize.y;
                if ((int) (targetSize.x * scale) > sourceSize.x) {
                    scale = (float) sourceSize.x / targetSize.x;
                }
            }
            int srcLeft;
            int srcTop;
            int srcWidth = (int) (targetSize.x * scale);
            int srcHeight = (int) (targetSize.y * scale);
            if (scaleType == ImageView.ScaleType.FIT_START) {
                srcLeft = 0;
                srcTop = 0;
            } else if (scaleType == ImageView.ScaleType.FIT_END) {
                if (sourceSize.x > sourceSize.y) {
                    srcLeft = sourceSize.x - srcWidth;
                    srcTop = 0;
                } else {
                    srcLeft = 0;
                    srcTop = sourceSize.y - srcHeight;
                }
            } else {
                if (sourceSize.x > sourceSize.y) {
                    srcLeft = (sourceSize.x - srcWidth) / 2;
                    srcTop = 0;
                } else {
                    srcLeft = 0;
                    srcTop = (sourceSize.y - srcHeight) / 2;
                }
            }
            return new Rect(srcLeft, srcTop, srcLeft + srcWidth, srcTop + srcHeight);
        }
    }

demo正在整理之中。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值