保存涂抹区域的图片_升级版

来源:互联网 发布:mac ps安装失败 编辑:程序博客网 时间:2024/04/29 09:11

还是有空截张图,给大家看看效果,效果展示的是涂抹区域进行文字识别,然后进行百度翻译的一种演示



上次写了一篇关于涂抹图片保存本地的view,后来实际测试中发现一个问题,就是不同的手机拍照显示不同的大小,这就尴尬了 ,高像素的手机显示图片太大,界面显示不齐全,低像素的手机图片也不能铺满屏幕 ,这个问题就涉及到图片的压缩与拉伸,这里优化一下以前的代码

原文地址 :http://blog.csdn.net/fkgjdkblxckvbxbgb/article/details/76649928

有希望了解原理的卓友可以去看上次写的那一篇博文 ,这里贴源码,主要是屏幕适配以及图片的压缩

图片压缩的类,因为照相机拍照的比例是4:3,我这里就直接按照4:3的比例进行压缩

package com.reeman.ringtranslate.util.image;import android.graphics.Bitmap;import android.graphics.BitmapFactory;public class ImageSizeUtil {    /***     * 读取图片资源     * @param reqWidth     * @return     */    public static Bitmap decodeSampleBitmap(String picPath, int reqWidth) {        BitmapFactory.Options options = new BitmapFactory.Options();        options.inJustDecodeBounds = true;   //去加载图片        BitmapFactory.decodeFile(picPath, options);        options.inSampleSize = calculateImSampleSize(options, reqWidth);        options.inJustDecodeBounds = false;        return BitmapFactory.decodeFile(picPath, options);    }    /***     * 计算图片的压缩比例     * @param options     * @param reqWidth     * @return     */    private static int calculateImSampleSize(BitmapFactory.Options options, int reqWidth) {        int reqHeight = reqWidth * 4 / 3;        if (reqWidth == 0) {            return 1;        }        int height = options.outHeight;        int width = options.outWidth;        int inSampleSize = 1;        if (height > reqHeight || reqWidth > reqWidth) {            int halfWidth = width / 2;            int halfHeight = height / 2;            while ((halfHeight / inSampleSize) >= reqHeight || (halfWidth / inSampleSize) >= reqWidth) {                inSampleSize *= 2;  //压缩过的图片比例比控件大,再次缩减压缩比例            }        }        return inSampleSize;    }}

涂抹区域的代码我






修正了一些部分,在每次重绘之前,都清掉以前的轨迹,就在OnTouch-MothionEventDown里面。见代码

package com.reeman.ringtranslate.view;import android.content.Context;import android.graphics.Bitmap;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.Path;import android.graphics.PorterDuff;import android.graphics.PorterDuffXfermode;import android.graphics.RectF;import android.os.Environment;import android.util.AttributeSet;import android.util.Log;import android.view.MotionEvent;import android.view.View;import com.reeman.ringtranslate.domain.TouchPoint;import com.reeman.ringtranslate.util.image.ImageSizeUtil;import com.reeman.ringtranslate.util.SharedPerManager;import java.io.File;import java.io.FileOutputStream;import java.util.ArrayList;import java.util.Collections;import java.util.List;public class XfermodeView extends View {    public static final String TEMP_PATH = Environment.getExternalStorageDirectory().getAbsolutePath() +            "/reeman/ringTranslate/picture/temp.jpg";    private Bitmap mBgBitmap;    Bitmap mFgBitmap;    private Paint mPaint;    private Canvas mCanvas;    private Path mPath;    int FINGER_WIDTH = 40;    int BLACK_HALF_COLOR = 0x89000000;    public XfermodeView(Context context) {        this(context, null);    }    public XfermodeView(Context context, AttributeSet attrs) {        this(context, attrs, 0);    }    public XfermodeView(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        init();    }    @Override    protected void onDraw(Canvas canvas) {        canvas.drawBitmap(mBgBitmap, 0, 0, null);        canvas.drawBitmap(mFgBitmap, 0, 0, null);    }    private void init() {        mPaint = new Paint();        mPaint.setAlpha(0);        mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));        mPaint.setStyle(Paint.Style.STROKE);        mPaint.setStrokeJoin(Paint.Join.ROUND);        mPaint.setStrokeWidth(100);        mPaint.setStrokeCap(Paint.Cap.ROUND);        mPath = new Path();    }    @Override    public boolean onTouchEvent(MotionEvent event) {        switch (event.getAction()) {            case MotionEvent.ACTION_DOWN:                listener.onEvent(MotionEvent.ACTION_DOWN);                listPoint.clear();                listPoint.add(new TouchPoint(event.getX(), event.getY()));                clearCanvas();                mPath.reset();                invalidate();                mPath.moveTo(event.getX(), event.getY());                break;            case MotionEvent.ACTION_MOVE:                listener.onEvent(MotionEvent.ACTION_MOVE);                listPoint.add(new TouchPoint(event.getX(), event.getY()));                mPath.lineTo(event.getX(), event.getY());                break;            case MotionEvent.ACTION_UP:                listener.onEvent(MotionEvent.ACTION_UP);                listPoint.add(new TouchPoint(event.getX(), event.getY()));                changePoints();                break;        }        mCanvas.drawPath(mPath, mPaint);        invalidate();        return true;    }    public void clearCanvas() {        if (mPaint == null || mCanvas == null) {            return;        }        mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));        mCanvas.drawPaint(mPaint);        mCanvas = new Canvas(mFgBitmap);        mCanvas.drawColor(BLACK_HALF_COLOR);        invalidate();    }    List<TouchPoint> listPoint = new ArrayList<>();    List<Float> pointX = new ArrayList<>();    List<Float> pointY = new ArrayList<>();    /***     * 计算手指滑动的区域     */    private void changePoints() {        pointX.clear();        pointY.clear();        for (int i = 0; i < listPoint.size(); i++) {            pointX.add(listPoint.get(i).getPointX());            pointY.add(listPoint.get(i).getPointY());        }        /***         * 这里因为用户会反复的涂抹,所以吧所有的移动点添加到集合中,然后对所有的点取值         * 取出手指的最大范围和最小范围,         */        float minX = Collections.min(pointX);        float minY = Collections.min(pointY);        float maxX = Collections.max(pointX);        float maxY = Collections.max(pointY);        /***         * 这里加上笔触的宽度         */        minX = minX - FINGER_WIDTH;        minY = minY - FINGER_WIDTH;        maxX = maxX + FINGER_WIDTH;        maxY = maxY + FINGER_WIDTH;        if (minX < 0) {            minX = 0;        }        if (minY < 0) {            minY = 0;        }        if (maxX > SharedPerManager.getWidth()) {            maxX = SharedPerManager.getWidth();        }        if (maxY > SharedPerManager.getHeight()) {            maxY = SharedPerManager.getHeight();        }        //这是手指绘制的区域        RectF rect = new RectF(minX, minY, maxX, maxY);        saveBitmap(rect);    }    /***     * 保存图片到本地     * @param rect     */    private void saveBitmap(RectF rect) {        try {            Log.i("point", "====保存的尺寸==" + rect.left + "/" + rect.top + "  ///" + rect.right + "/" + rect.bottom);            float rectWidth = Math.abs(rect.left - rect.right);            float rectHeight = Math.abs(rect.top - rect.bottom);            Log.i("point", "====保存的面积==" + rectWidth * rectHeight);            if (rectWidth * rectHeight < 6500) {                listener.touchCutError("涂抹区域太小");                return;            }            Bitmap bmp = Bitmap.createBitmap((int) rect.width(), (int) rect.height(), Bitmap.Config.ARGB_8888);            Canvas canvas = new Canvas(bmp);            canvas.translate(-(rect.left), -(rect.top));            canvas.drawColor(Color.WHITE);            canvas.drawBitmap(mBgBitmap, 0, 0, null);            canvas.save(Canvas.ALL_SAVE_FLAG);            canvas.restore();            File file = new File(TEMP_PATH);            if (!file.getParentFile().exists()) {                file.getParentFile().mkdirs();            }            if (!file.exists()) {                file.createNewFile();            }            FileOutputStream fos = new FileOutputStream(file.getPath());            bmp.compress(Bitmap.CompressFormat.PNG, 100, fos);            fos.close();            listener.touchBackUrl(file.getPath());        } catch (Exception e) {            listener.touchCutError(e.toString());            e.printStackTrace();        }    }    public void setBitmap(String path) {        mBgBitmap = ImageSizeUtil.decodeSampleBitmap(path, SharedPerManager.getWidth());        mFgBitmap = Bitmap.createBitmap(mBgBitmap.getWidth(), mBgBitmap.getHeight(), Bitmap.Config.ARGB_8888);        mCanvas = new Canvas(mFgBitmap);        mCanvas.drawColor(BLACK_HALF_COLOR);        invalidate();    }    TouchCutListener listener;    public void setOnTouchCutListener(TouchCutListener listener) {        this.listener = listener;    }    public interface TouchCutListener {        void onEvent(int event);        void touchBackUrl(String filePath);        void touchCutError(String error);    }}

主界面的代码

1:初始化代码

@BindView(R.id.as_modeview)XfermodeView mModeview;

2:设置图片地址

Modeview.setBitmap(mPath);











原创粉丝点击