手机自动画图

手机自动画图,第1张

之前写了一篇博客,是关于用python的turtle库实现自动画图的程序。有兴趣的可以去看一下,博客链接:python使用turtle实现自动绘图

演示视频:

海龟画图python

20211222

最近我将这个画图的程序部署到移动端上,从相册中选择图像,然后实现自动绘制。
app下载。

移动端上的演示视频:

自动绘图

下面分析一下绘图的主要代码:
mainactivity.java

package com.myapp.drawpic2;

import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.NotificationManagerCompat;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Bitmap;
//import android.graphics.BitmapFactory;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.provider.MediaStore;
//import android.util.Log;
import android.util.Log;
import android.view.View;
import android.widget.Button;
//import android.widget.FrameLayout;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.RelativeLayout;
//import android.widget.TextView;
import android.widget.Toast;

import org.json.JSONObject;
import org.opencv.android.OpenCVLoader;
//import org.opencv.android.Utils;
//import org.opencv.core.CvType;
import org.opencv.core.Mat;

import cn.jpush.android.api.JPushInterface;
//import org.opencv.core.MatOfPoint;
//import org.opencv.core.Point;
//import org.opencv.dnn.Net;
//import org.opencv.imgproc.Imgproc;
//
//import java.util.ArrayList;
//import java.util.List;
//import java.util.Timer;
//import java.util.TimerTask;
//import java.util.logging.Handler;

public class MainActivity extends AppCompatActivity {

    // Used to load the 'native-lib' library on application startup.
    static {
        System.loadLibrary("native-lib");
    }

    //极光推送
    //for receive customer msg from jpush server
    private MessageReceiver mMessageReceiver;
    public static final String MESSAGE_RECEIVED_ACTION = "com.myapp.drawpic2.MESSAGE_RECEIVED_ACTION";
    public static final String KEY_TITLE = "title";
    public static final String KEY_MESSAGE = "message";
    public static final String KEY_EXTRAS = "extras";
    private EditText msgText;




    private Bitmap bmp;

    private Mat src;
    private Mat dst;
    private Canvas mcanvas;
    private Paint paint;
    private Path path;

    private Button btn;
    private Button camera;
    private Button draw;
    private ImageView imageView;
    private Bitmap bitmap;

    private Bitmap mybmp;

    private MyView vie;

    private ImageView waring;



    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        JPushInterface.init(getApplicationContext());//极光接口初始化,否则用不了
        registerMessageReceiver();//注册消息接收器

        iniLoadOpenCV();

        if (!isNotificationEnabled(this)){
            gotoSet();
        }else {
            //允许通知
        }


        waring=findViewById(R.id.waring);

        RelativeLayout relativeLayout=findViewById(R.id.relate);
        btn=findViewById(R.id.btn);
        draw=findViewById(R.id.btn2);

        btn.setVisibility(View.VISIBLE);
        draw.setVisibility(View.VISIBLE);

        imageView=findViewById(R.id.image);


//        HandPic handPic=new HandPic(this);
//        relativeLayout.addView(handPic);
        waring.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent=new Intent(MainActivity.this,Waring.class);
                startActivity(intent);
            }
        });

        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                try {
                    relativeLayout.addView(waring);
                } catch (Exception e) {
                    e.printStackTrace();
                }


                Intent intent = new Intent(Intent.ACTION_PICK, null);
                intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");
                startActivityForResult(intent, 2);


                //移除组件
                if(vie!=null){
                    relativeLayout.removeView(vie);
                }

            }
        });

        draw.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                try {
                    relativeLayout.removeView(vie);
                } catch (Exception e) {
                    e.printStackTrace();
                }

                relativeLayout.removeView(waring);

                //获取bitmap
                imageView.setDrawingCacheEnabled(true);
                bitmap = Bitmap.createBitmap(imageView.getDrawingCache());
                imageView.setDrawingCacheEnabled(false);

                vie=new MyView(MainActivity.this,bitmap);


                relativeLayout.addView(vie);
//                btn.setVisibility(View.INVISIBLE);
//                draw.setVisibility(View.INVISIBLE);


            }
        });




//        bmp= BitmapFactory.decodeResource(getResources(),R.drawable.b2);
//        imageView=findViewById(R.id.image1);
//        imageView.setImageBitmap(bmp);
//
//        //bitmap转mat
//        src=new Mat();
//        dst=new Mat();
//        Utils.bitmapToMat(bmp,src);
//        //灰度化
//        Imgproc.cvtColor(src,src,Imgproc.COLOR_RGBA2GRAY);
//        //二值化
//        Imgproc.threshold(src,src,0,255,8);
//        //开运算
//        Mat keral=Mat.ones(7,7, CvType.CV_8UC1);
//        Imgproc.morphologyEx(src,src,Imgproc.MORPH_OPEN,keral);
//        Utils.matToBitmap(src,bmp);
//        List contours=new ArrayList<>();
//        Mat mm=new Mat();
//        Imgproc.findContours(src,contours,mm,Imgproc.RETR_TREE,Imgproc.CHAIN_APPROX_SIMPLE);
//        Log.i("aa",String.valueOf(contours.get(0).toList()));
//
//        paint=new Paint();
//        paint.setStrokeWidth(3);
//        //设置不填充
        paint.setStyle(Paint.Style.STROKE);
        android.graphics.Bitmap.Config bitmapConfig = bmp.getConfig();
        Bitmap bp = bmp.copy(bitmapConfig, true);
        mcanvas=new Canvas(bp);
//
//        Bitmap bp=Bitmap.createBitmap(bmp.getWidth(),bmp.getHeight(),Bitmap.Config.ARGB_8888);
//        //将白板图像显示到界面上
//        imageView.setImageBitmap(bp);
//        //画图
//        mcanvas=new Canvas(bp);
//        for (MatOfPoint points:contours){
//            List lieb=points.toList();
//
//            path=new Path();
//            for (int i=0; i
//                if (i==0){
//                    path.moveTo((float)lieb.get(i).x,(float)lieb.get(i).y);
                    Log.i("aa",""+lieb.get(i).x+" "+lieb.get(i).y);
//                }else {
//                    path.lineTo((float)lieb.get(i).x,(float)lieb.get(i).y);
//
//                    Log.i("aa",""+lieb.get(i).x+" "+lieb.get(i).y);
//                };
//                mcanvas.drawCircle(500,500,i+1,paint);
//
//            };

//            mcanvas.drawCircle(500,500,1000,paint);
//            mcanvas.drawPath(path, paint);




//        }

//        mcanvas.drawCircle(500,500,500,paint);





//        Log.i("aa",String.valueOf(contours.get(0).toList().get(0).x));
    }




    /**
     * A native method that is implemented by the 'native-lib' native library,
     * which is packaged with this application.
     */


    public native String stringFromJNI();

    //opencv初始化
    private void iniLoadOpenCV(){
        boolean success= OpenCVLoader.initDebug();
        if (success){
//            Toast.makeText(this.getApplicationContext(),"Load OpenCV Succesful",Toast.LENGTH_LONG).show();
        }else {
            Toast.makeText(this.getApplicationContext(),"Load OpenCV Failed",Toast.LENGTH_LONG).show();
        }
    }

    private Uri uri;
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == 2) {
            // 从相册返回的数据
//            Log.e(this.getClass().getName(), "Result:" + data.toString());
            if (data != null) {
                // 得到图片的全路径

                try{
                    uri = data.getData();
                    imageView.setImageURI(uri);
                } catch (Exception e) {
                    e.printStackTrace();
                }
//                imageView.setImageURI(uri);
//                Log.e(this.getClass().getName(), "Uri:" + String.valueOf(uri));
//                Log.i("aa",""+uri);
            }
        }
    }

    public void registerMessageReceiver() {
        mMessageReceiver = new MessageReceiver();
        IntentFilter filter = new IntentFilter();
        filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
        filter.addAction(MESSAGE_RECEIVED_ACTION);
        LocalBroadcastManager.getInstance(this).registerReceiver(mMessageReceiver, filter);
    }

    public class MessageReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            try {
                if (MESSAGE_RECEIVED_ACTION.equals(intent.getAction())) {
                    String messge = intent.getStringExtra(KEY_MESSAGE);
                    String extras = intent.getStringExtra(KEY_EXTRAS);
                    StringBuilder showMsg = new StringBuilder();
                    showMsg.append(KEY_MESSAGE + " : " + messge + "\n");
                    if (!ExampleUtil.isEmpty(extras)) {
                        showMsg.append(KEY_EXTRAS + " : " + extras + "\n");
                    }
                    setCostomMsg(showMsg.toString());
                }
            } catch (Exception e){
            }
        }
    }

    //设置自定义消息
    private void setCostomMsg(String msg){
        if (null != msgText) {
            msgText.setText(msg);
            msgText.setVisibility(View.VISIBLE);
        }
    }



    //是否开启通知接收
    private boolean isNotificationEnabled(Context context) {
        boolean isOpened = false;
        try {
            isOpened = NotificationManagerCompat.from(context).areNotificationsEnabled();
        } catch (Exception e) {
            e.printStackTrace();
            isOpened = false;
        }
        return isOpened;

    }
    //去设置
    private void gotoSet() {
        Intent intent = new Intent();
        if (Build.VERSION.SDK_INT >= 26) {
            // android 8.0引导
            intent.setAction("android.settings.APP_NOTIFICATION_SETTINGS");
            intent.putExtra("android.provider.extra.APP_PACKAGE", getPackageName());
        } else if (Build.VERSION.SDK_INT >= 21) {
            // android 5.0-7.0
            intent.setAction("android.settings.APP_NOTIFICATION_SETTINGS");
            intent.putExtra("app_package", getPackageName());
            intent.putExtra("app_uid", getApplicationInfo().uid);
        } else {
            // 其他
            intent.setAction("android.settings.APPLICATION_DETAILS_SETTINGS");
            intent.setData(Uri.fromParts("package", getPackageName(), null));
        }
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        startActivity(intent);

    }

}

绘制图像的代码都在myview.java中。
myview.java

package com.myapp.drawpic2;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ComposePathEffect;
import android.graphics.CornerPathEffect;
import android.graphics.DashPathEffect;
import android.graphics.DiscretePathEffect;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PathDashPathEffect;
import android.graphics.PathEffect;
import android.graphics.SumPathEffect;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;

import org.opencv.android.Utils;
import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.MatOfPoint;
import org.opencv.core.Point;
import org.opencv.imgproc.Imgproc;

import java.util.ArrayList;
import java.util.List;


class MyView extends View {
    float phase;
    private Paint paint;
    Path path;
    Path path2;
    private Bitmap bmp;
//    private Bitmap mybmp;
    private Canvas mCanvas;

    private int pic_width;
    private int pic_height;
    private int view_width;
    private int view_height;
    private Bitmap hand_bmp;

    public MyView(Context context,Bitmap mybmp) {
        super(context);
        handx=500;
        handy=500;
        paint = new Paint();
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeWidth(3);
        paint.setColor(0xFFFFFFFF);

        path = new Path();
        path2 = new Path();

        pic_width=mybmp.getWidth();
        pic_height=mybmp.getHeight();
//        path.moveTo(0, 0);

//        mybmp= BitmapFactory.decodeResource(getResources(),R.drawable.b2);
        counter=findcounters(mybmp);
    }



    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        view_width= getMeasuredWidth();
        view_height= getMeasuredHeight();
//        Log.i("aa","窗口宽高"+width1+" "+height1);

//        Log.i("aa","图片宽高"+width+" "+height);
        bmp=Bitmap.createBitmap(view_width,view_height,Bitmap.Config.ARGB_8888);
        mCanvas=new Canvas(bmp);
        mCanvas.drawColor(Color.BLACK);
    }


    float x;
    float y;

    float u=0;
    float v;

    private List<MatOfPoint> counter;
    int con=0;
    int zbiao=0;

    private boolean first_count;
    private boolean first_point;

    private Mat mat=new Mat();

    float handx;
    float handy;

    @Override
    protected void onDraw(Canvas canvas) {
        //创建并初始化Path

        //将背景色填充成白色
//        canvas.drawColor(Color.WHITE);
        if (con<counter.size()){


            List<Point> points=counter.get(con).toList();
            //寻找填充值
            MatOfPoint matOfPoint=counter.get(con);

            //寻找最左边的x坐标
            mat=matOfPoint.reshape(1,matOfPoint.rows());
            Mat mat_x=mat.colRange(0,1);
            Core.MinMaxLocResult out=Core.minMaxLoc(mat_x);

            double minx_value=out.minVal;
            Point index_min=out.minLoc;
            double maxx_value=out.maxVal;
            Point index_max=out.maxLoc;

            int[] xy=new int[2];
            mat.get((int)index_min.y,0,xy);
            byte[] data=new byte[src.cols()];
            src.get(xy[1],0,data);



            if(xy[0]+1<data.length){
                int yy=data[xy[0]+1];
                if(yy!=0){
                    //填充白色
                    paint.setColor(0xFFFFFFFF);

                }else {
                    paint.setColor(0xFF000000);

                }

//                paint.setStyle(Paint.Style.FILL);
//                mCanvas.drawPath(path2,paint);
                Log.i("aa",yy+"");
            }
//            Mat mat2=mat.rowRange((int)index_min.y,(int)index_min.y+1);


            if (zbiao<points.size()){

                x=(float)points.get(zbiao).x;
                y=(float)points.get(zbiao).y;
//                Log.i("aa",x+" "+y);
                x=x*((float) view_width/(float) pic_width);
                y=y*((float) view_height/(float) pic_height);
                //确定轮廓的第一个坐标

                if (zbiao==0){
                    path.moveTo((int)x,(int)y);

                    path2.moveTo((int)x,(int)y);
                }else {
                    path.lineTo((int)x,(int)y);
                    path2.lineTo((int)x,(int)y);

                }

//                Log.i("aa",x+" "+y);


                zbiao++;
            }else {
                paint.setStyle(Paint.Style.FILL);
                mCanvas.drawPath(path2,paint);

                path = new Path();
                path2 = new Path();

                zbiao=0;
                con++;
            }




        }else {

            con=counter.size();
        }





        paint.setStyle(Paint.Style.STROKE);
        mCanvas.drawPath(path,paint);

//        Log.i("aa",""+counter.size()+" "+con);
        canvas.drawBitmap(bmp,0,0,null);

        hand_bmp= BitmapFactory.decodeResource(this.getResources(),R.mipmap.hand);
        handx=x-30;
        handy=y-30;
        if (con<counter.size()){
            canvas.drawBitmap(hand_bmp,handx,handy,paint);
        }

        invalidate();
    }

    private Mat src;

    private List<MatOfPoint> findcounters(Bitmap bmp){
//        bmp= BitmapFactory.decodeResource(getResources(),R.drawable.b2);
        //bitmap转mat
        src=new Mat();
        Utils.bitmapToMat(bmp,src);
        //灰度化
        Imgproc.cvtColor(src,src,Imgproc.COLOR_RGBA2GRAY);
        //二值化
        Imgproc.threshold(src,src,0,255,8);
        //开运算
//        Mat keral=Mat.ones(7,7, CvType.CV_8UC1);
//        Imgproc.morphologyEx(src,src,Imgproc.MORPH_OPEN,keral);

        Utils.matToBitmap(src,bmp);
        List<MatOfPoint> contours=new ArrayList<>();
        Mat mm=new Mat();
        Imgproc.findContours(src,contours,mm,Imgproc.RETR_TREE,Imgproc.CHAIN_APPROX_SIMPLE);
        return contours;
    }



}

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/langs/714430.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-04-24
下一篇2022-04-24

发表评论

登录后才能评论

评论列表(0条)

    保存