Android将自定义的SurfaceView保存为bitmap

正常将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);}}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/240956.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【CentOS 7.9 分区】挂载硬盘为LVM操作实例

LVM与标准分区有何区别&#xff0c;如何选择 目录 1 小系统使用LVM的益处&#xff1a;2 大系统使用LVM的益处&#xff1a;3 优点&#xff1a;CentOS 7.9 挂载硬盘为LVM操作实例查看硬盘情况格式化硬盘创建PV创建VG创建LV创建文件系统并挂载自动挂载添加&#xff1a;注意用空格间…

pip 常用指令 pip list 命令用法介绍

&#x1f4d1;pip 常用命令归类整理 pip list 是一个用于列出已安装的 Python 包的命令。这个命令会显示出所有已安装的包&#xff0c;以及它们的版本号。 pip list 命令有以下参数 -o, --outdated&#xff1a;列出所有过时的包&#xff0c;即有新版本可用的包。-u, --uptod…

3D 纹理贴图基础知识

在线工具推荐&#xff1a; 3D数字孪生场景编辑器 - GLTF/GLB材质纹理编辑器 - 3D模型在线转换 - Three.js AI自动纹理开发包 - YOLO 虚幻合成数据生成器 - 三维模型预览图生成器 - 3D模型语义搜索引擎 介绍 纹理贴图是创建模型时离不开的最后一块拼图。同样&#xff0c;…

综合评价---DEA数据包络分析

数据包络分析(Data Envelopment Analysis&#xff0c;DEA)&#xff0c;1978年由 Charnes、Cooper和Rhodes创建的一种绩效评价技术(performance technique) 。采用多投入、多产出数据对多个决策单元(Decision Making Unit) 的相对效率进行评价因DEA的诸多优势&#xff0c;被广泛…

JavaScript——数据类型判断方法汇总

1. typeof // 1.typeof 数组、对象和null都会被视为object 其他类型都判定正确 console.log(typeof {}); // object console.log(typeof []); // object console.log(typeof null); // object console.log(typeof function () {}); // function console.log(typeof 1); // num…

【.Net8教程】(一)读取配置文件全面总结

环境&#xff1a;.net8.0 1. 准备条件 先在appsettings.Development.json或appsettings.json添加配置 添加一个DbOption {"DbOption": {"Conn": "foolishsundaycsdn"} }2.直接读取json配置节点的几种写法 在Main函数中读取json配置 方式一 …

Linux环境下通过journal命令查看和管理日志

文章目录 前言问题分析journal 和 syslog 对比journal 和 syslog 配置使用journalctl查看和管理日志查看日志查看指定服务日志查看调整存储 回到文章开头的问题总结 前言 就在半月之前&#xff0c;负责打包更新的服务器突然登录不上去了&#xff0c;赶紧找来运维的同事帮忙解决…

【数据结构之顺序表】

数据结构学习笔记---002 数据结构之顺序表1、介绍线性表1.1、什么是线性表? 2、什么是顺序表?2.1、概念及结构2.2、顺序表的分类 3、顺序表接口的实现3.1、顺序表动态存储结构的Seqlist.h3.1.1、定义顺序表的动态存储结构3.1.2、声明顺序表各个接口的函数 3.2、顺序表动态存储…

b2b订货系统成本是多少

批发贸易企业都上b2b订货系统&#xff0c;b2b订货系统成本究竟是多少&#xff0c;今天我们来算一算&#xff0c;尤其是最后一个大家可能会忽略。 一是b2b订货系统模板的功能费用&#xff0c;这部分一般各大厂家是明码标价&#xff0c;比如易订货12800元/年&#xff0c;核货宝首…

深入理解 Rust 中的容器类型及其应用

Rust 作为一种系统编程语言&#xff0c;提供了丰富的容器类型来处理各种数据结构和算法。这些容器类型不仅支持基本的数据存储和访问&#xff0c;还提供了高效的内存管理和安全性保障。本文将详细介绍 Rust 中的几种主要容器类型&#xff0c;包括它们的用法、特点和适用场景&am…

【IDEA】try-catch自动生成中修改catch的内容

编辑器 --> 文件和代码模板 --> 代码 --> Catch Statement Body

【雷达原理】雷达测速原理及实现方法

一、雷达测速原理 1.1 多普勒频率 当目标和雷达之间存在相对运动时&#xff0c;若雷达发射信号的工作频率为&#xff0c;则接收信号的频率为&#xff0c;其中为多普勒频率。将这种由于目标相对于辐射源运动而导致回波信号的频率发生变化的现象称为多普勒效应。 如图1-1所示&a…

优先级队列与仿函数

优先级队列 优先级队列 priority_queue 是一种容器适配器&#xff0c;听起来是队列&#xff0c;其实它的底层数据结构是堆&#xff0c;所谓的优先级为默认越大的数优先级越高&#xff0c;即默认为大堆。 使用方式如下面的代码&#xff1a; #include<iostream> #includ…

攻防世界——game 游戏

下载下来是一个exe文件&#xff0c;可以用IDA打开 我们先运行一下 这是属于第二种类型&#xff0c;完成一个操作后给你flag 这种题我更倾向于动调直接得到flag 我们查壳 没有保护壳&#xff0c;直接32打开 进入字符串界面&#xff0c;找到显示的那部分 int __cdecl main_0(…

Java经典面试题——手写快速排序和归并排序

题目链接&#xff1a;https://www.luogu.com.cn/problem/P1177 输入模板&#xff1a; 5 4 2 4 5 1快速排序 技巧&#xff1a;交换数组中的两个位置 a[l] a[l] a[r] - (a[r] a[l]); 稳定不稳定&#xff1f;:不稳定 注意找哨兵那里内循环的等于号不能漏&#xff0c;不然…

MyBatis的ORM映射

目录 什么是ORM 一&#xff0c;列的别名 二&#xff0c;结果映射 三&#xff0c;总结 什么是ORM ORM&#xff1a;对象关系映射&#xff08;Object Relational Mapping&#xff0c;简称ORM&#xff09;模式是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术。简…

时间与时间戳转换及android和ios对时间识别的区别

注意&#xff1a; "2021-05-01 12:53:59.55" 时间对象在 ios 中会出现 NaN-NaN1-NaN 需要将对象格式化为&#xff1a;"2021/05/01 12:53:59.55" 可同时兼容 android 和 ios。 //将某时间转时间戳 /* var time new Date("2021-05-01 12:53:59.55&qu…

力扣思维题——寻找重复数

题目链接&#xff1a;https://leetcode.cn/problems/find-the-duplicate-number/description/?envTypestudy-plan-v2&envIdtop-100-liked 这题的思维难度较大。一种是利用双指针法进行计算环的起点&#xff0c;这种方法在面试里很难说清楚&#xff0c;也很难想到。大致做…

idea structure视图介绍

作用 idea的Structure视图可以辅助查看代码结构 如何呼出Structure视图&#xff1f; Alt 7 Ctrl F12 侧边栏点Structure 我的常用配置 1、选Show Toolbar&#xff0c;便于使用功能按钮 2、使用Float视图&#xff0c;悬浮于窗口表面&#xff0c;可以使用 ShiftEsc来退出…

C语言初学6:循环

while 循环 一、while 循环的语法&#xff1a; while(condition) {statement(s); } condition 为任意非零值时都为 true。当条件为 true 时执行循环。 当条件为 false 时&#xff0c;退出循环&#xff0c;程序流将继续执行紧接着循环的下一条语句。 二、while 循环举例 #i…