Android将自定义的SurfaceView保存为bitmap
2023-12-21 12:57:03
正常将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
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!