正常将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();
// }
// };@Overridepublic 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 somethingcanvas.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() {@Overridepublic 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 somethingdrawCube(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;}@Overrideprotected 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();}}@Overrideprotected 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) {//新建bitmapBitmap 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);}}
}