Android将自定义的SurfaceView保存为bitmap

发布时间:2023年12月21日

正常将View保存为Bitmap的方法:

    private Bitmap getViewToBitmap(View view) {
//        layoutView(view);
        //创建Bitmap,最后一个参数代表图片的质量.
        Bitmap bitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Bitmap.Config.ARGB_8888);
        if (bitmap != null) {
            //View把内容绘制到canvas上,同时保存在bitmap.
            Canvas c = new Canvas(bitmap);
//            c.drawColor(Color.WHITE);
            view.draw(c);
            c.setBitmap(null);
        }

        return bitmap;
    }

SurfaceView保存为bitmap比较特殊:

1.通过SurfaceView绘制图形,我们可以得到绘制图形后的path

2.启用新的canvas,将path绘制到canvas

public class AudioWaveView extends SurfaceView implements Callback, Runnable, Serializable {
    private short[] mWaveData;
    private List<Short> pointList = Collections.synchronizedList(new LinkedList<>());
    private Paint mPaint;
    private Paint mPaintIssue;
    private SurfaceHolder mHolder;
    private int mWidth = 0;
    private int mHeight = 0;
    private int mCenterY = 0;
    //网格颜色
    protected int mGridColor = Color.parseColor("#D7D7D7");
    protected Paint paint;
    public float points[];
    private boolean isRunning = false;
    private boolean isDraw = false;
    List<Short> nativeDatas = null;
    volatile ThreadPoolExecutor singleThreadExecutor;//单线程池
    private Canvas canvas = null;
    private int len = 0;
    private int index = 0;
    private volatile boolean isRedPaint;

    private boolean isDrawArea;//是否绘制背景区域


    //    private Runnable drawRunAble = new Runnable() {
//        @Override
//        public void run() {
//                drawFrame();
//        }
//    };
    @Override
    public void run() {
        while (isRunning) {
            if (isDrawArea) {
                drawArea();
            }
            if (isDraw) {
                drawFrame();
            } else {
                Thread.yield();
            }
        }
    }

    synchronized void drawArea() {
        canvas = null;
        try {

            if (!isRunning) {
                return;
            }
            canvas = mHolder.lockCanvas();

            if (canvas != null) {
                // draw something
                canvas.drawRect(mWidth / 4, 0, mWidth / 4 * 3, mHeight, mPaintIssue);
                isDrawArea = false;
            }
        } catch (Exception e) {
            e.printStackTrace();
            isDrawArea = false;
        } finally {
            isDrawArea = false;
            if (canvas != null)

                try {
                    mHolder.unlockCanvasAndPost(canvas);
                } catch (Exception e) {
                    e.printStackTrace();
                }
        }


    }

    public void addWaveDataAndPaint(short[] waveData, boolean isRedPaint) {
        this.isRedPaint = isRedPaint;
        addWaveData(waveData);
    }


    public void addWaveData(short[] waveData) {
//        if (BaseApplication.isMeasure && isRunning){
//            synchronized(mWaveDataList){
//                mWaveDataList.add(waveData);
//                //drawFrame();
//            }
//        }
        if (!isRunning || waveData == null) {
            return;
        }

        if (nativeDatas == null) {
            nativeDatas = new ArrayList<>();
        }
        for (int i = 0; i < waveData.length; i++) {
            nativeDatas.add((short) (mCenterY - waveData[i] / (32768 / mCenterY)));
        }
        if (nativeDatas.size() >= 800) {
            addPointThreadExecutor(nativeDatas);
            nativeDatas = new ArrayList<>();
        }


    }

    private void addPointThreadExecutor(List<Short> nativeDatas) {

        if (!isRunning || nativeDatas == null) {
            return;
        }
        if (singleThreadExecutor == null || singleThreadExecutor.isShutdown()) {
            startSingleThreadExecutor();
            return;
        }
        //Log.e("====>", "singleThreadExecutor.getQueue().size() = " + singleThreadExecutor.getQueue().size());
        if (singleThreadExecutor.getQueue().size() >= 5) {
            Log.e("====>", "singleThreadExecutor.getQueue().size() = " + singleThreadExecutor.getQueue().size());
            return;
        }

        singleThreadExecutor.execute(new Runnable() {
            @Override
            public void run() {
                List<Short> dataList = nativeDatas;
                synchronized (pointList) {
                    for (int i = 0; i < dataList.size(); i += 10) {
                        if (pointList.size() >= mWidth) {
                            pointList.remove(0);
                        }
                        pointList.add(dataList.get(i));
//                    if (i%4 == 0){
//                        SystemClock.sleep(1);
//                    }

                    }
                    isDraw = true;
                }

            }
        });

    }


    synchronized void drawFrame() {
        canvas = null;
        try {

            if (!isRunning) {
                return;
            }
            canvas = mHolder.lockCanvas();

            if (canvas != null) {
                // draw something
                drawCube(canvas);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (canvas != null)

                try {
                    mHolder.unlockCanvasAndPost(canvas);
                } catch (Exception e) {
                    e.printStackTrace();
                }
        }


    }

    public AudioWaveView(Context context) {
        this(context, null);
    }

    public AudioWaveView(Context context, AttributeSet attributeSet) {
        super(context, attributeSet);
        initView();
    }

    private void initView() {
        if (mHolder == null) {
            mHolder = getHolder();
            mHolder.addCallback(this);
            setZOrderOnTop(true);// 设置画布 背景透明
            mHolder.setFormat(PixelFormat.TRANSLUCENT);
        }
        Rect frame = mHolder.getSurfaceFrame();
        mHeight = frame.height();
        mCenterY = frame.centerY();
        mWidth = frame.width();

        points = new float[mWidth * 4];
        if (mPaint == null) {
            mPaint = new Paint();
            mPaint.setColor(Color.parseColor("#0077D4"));
            mPaint.setAntiAlias(true);
            mPaint.setStrokeWidth(2);
            mPaint.setStrokeCap(Paint.Cap.ROUND);
            mPaint.setStyle(Paint.Style.STROKE);
        }
        if (paint == null) {
            paint = new Paint();
            paint.setColor(mGridColor);
            paint.setStrokeWidth(1);
        }
        mPaintIssue = new Paint();
        mPaintIssue.setColor(Color.parseColor("#7F0077D4"));
        mPaintIssue.setAntiAlias(true);
        mPaintIssue.setStrokeWidth(1);
        mPaintIssue.setStrokeCap(Paint.Cap.ROUND);
        mPaintIssue.setStyle(Paint.Style.FILL_AND_STROKE);
    }

    public void drawIssueArea() {
        this.isDrawArea = true;
        new Thread(this).start();

    }


    public void drawCube(Canvas canvas) {
        canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
        /*画波形,数据在之前已经填充好了*/
        len = pointList.size();
        if (len >= 2) {
            index = mWidth - len;
            for (int i = index + 1; i < mWidth; i++) {
                points[i * 4] = i - 1;
                points[i * 4 + 1] = pointList.get(i - index - 1);
                points[i * 4 + 2] = i;
                points[i * 4 + 3] = pointList.get(i - index);
            }
        }
        if (isRedPaint) {
            mPaint.setColor(Color.RED);
        } else {
            mPaint.setColor(Color.parseColor("#0077D4"));
        }
        canvas.drawLines(points, mPaint);
        isDraw = false;
    }


    @Override
    protected void onVisibilityChanged(@NonNull View changedView, int visibility) {
        super.onVisibilityChanged(changedView, visibility);
        if (visibility == VISIBLE) {
            //LoggerUtil.d("onVisibilityChanged : VISIBLE");
            isRunning = true;
            //mDrawWaveThread.execute(drawRunAble);
        } else if (visibility == INVISIBLE) {
//            LoggerUtil.d("onVisibilityChanged : INVISIBLE");
            isRunning = false;
            //pointList.clear();
        }
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        mHeight = h;
        mWidth = w;
        mCenterY = h / 2;
    }

    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
//        LoggerUtil.d("surfaceChanged");

    }

    public void surfaceCreated(SurfaceHolder holder) {
//        LoggerUtil.d("surfaceCreated");
        initView();
        isRunning = true;
        Thread thread = new Thread(this);
        thread.start();
        startSingleThreadExecutor();
    }


    public void surfaceDestroyed(SurfaceHolder holder) {

        isRunning = false;

    }

    private void startSingleThreadExecutor() {
        if (singleThreadExecutor != null && !singleThreadExecutor.isShutdown()) {
            singleThreadExecutor.shutdownNow();
        }

        singleThreadExecutor = new ThreadPoolExecutor(1, 1,
                0L, TimeUnit.MILLISECONDS,
                new ArrayBlockingQueue<>(10));
    }

    public void clearDatas() {
        if (pointList != null) {
            pointList.clear();
        }
        if (nativeDatas != null) {
            nativeDatas.clear();
        }

        startSingleThreadExecutor();
        isDraw = true;
        points = new float[mWidth * 4];
        drawFrame();

    }

    public Bitmap getBitmap(String title) {
        //新建bitmap
        Bitmap bitmap = Bitmap.createBitmap(mWidth, mHeight, Bitmap.Config.ARGB_8888);
        //创建新的画布
        Canvas canvas = new Canvas(bitmap);
        //设置画布背景色
//        canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
        canvas.drawColor(Color.WHITE);
        //设置绘制路径、画笔
        drawGird(canvas, Color.parseColor("#D7D7D7"));
        canvas.drawLines(points, mPaint);
        if (!TextUtils.isEmpty(title)) {
            Paint textPaint = new Paint();
            textPaint.setColor(Color.parseColor("#0077D4"));
            textPaint.setAntiAlias(true);
            textPaint.setStrokeWidth(2);
            textPaint.setStrokeCap(Paint.Cap.ROUND);
            textPaint.setStyle(Paint.Style.STROKE);
            textPaint.setTextSize(16f);

            canvas.drawText(title, 20, 30, textPaint);
        }
        return bitmap;
    }

    /**
     * 画网格
     *
     * @param canvas
     * @param color
     */
    private void drawGird(Canvas canvas, int color) {
        Paint paint = new Paint();
        paint.setAntiAlias(true);
        paint.setStyle(Paint.Style.FILL);
        paint.setColor(color);
        paint.setStrokeWidth(2);
        //float colSpace = width * 1f / cols;
        int colSpace = 20;
        int cols = this.mWidth / colSpace;
        int heightCount = (int) Math.floor((double) mHeight / 20);//向下取整
        float space = (this.mHeight - heightCount * 20) / 2;
        //画竖线
        for (int i = 0; i <= this.mWidth / 20; i++) {
            canvas.drawLine(i * colSpace, space, i * colSpace, heightCount * colSpace + space, paint);
        }

        //画横线
        for (int i = 0; i <= heightCount; i++) {
            canvas.drawLine(0, i * colSpace + space, mWidth, i * colSpace + space, paint);
        }
    }
}
文章来源:https://blog.csdn.net/zhijiandedaima/article/details/135126307
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。