android 画 波形

本文介绍如何在Android应用中实现绘制WAV音频文件的波形图,通过自定义View展示波形效果。详细讲解了关键步骤和代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近做了一个小的项目,涉及的android 画wav文件的波形图。下面给出自定义view的示例:

package com.example.showwave.view;

import android.R.integer;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.util.AttributeSet;
import android.view.View;

public class WaveView extends View {
    private float[] audioData = null;
    private int width = 0;
    private int height = 400;
    public void setWidth(int width){
        this.width = width;
    }
    public void setHeight(int height){
        this.height = height;
    }

    private Paint paint;
    private Paint paint1;
    public WaveView(Context context) {
        super(context);
        this.paint = new Paint();
        this.paint1 = new Paint();

    }

    public WaveView(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.paint = new Paint();
        this.paint1 = new Paint();
    }

    public WaveView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        this.paint = new Paint();
        this.paint1 = new Paint();
    }
    @Override
    public void onDraw(Canvas canvas) {
        paint.setColor(Color.BLACK);
        // 设置字体大小
        paint.setTextSize(25);
        // 让画出的图形是空心的
        paint.setStyle(Paint.Style.FILL);
        // 设置画出的线的 粗细程度
        paint.setStrokeWidth(1);
        paint1.setColor(Color.BLUE);
        paint1.setTextSize(25);
        paint1.setStyle(Paint.Style.FILL);
        canvas.drawText("y", 10, 30, paint);
        canvas.drawText("x", width-140, 40+height/2, paint);
        drawAL(10, 40+height/2, width-150, 40+height/2, canvas);
        drawAL(10, 40+height, 10, 30, canvas);
        canvas.drawText("左声道", width-180, 75, paint);
        canvas.drawText("右声道", width-180, 115, paint);
        paint.setColor(Color.RED);
        canvas.drawLine(width-300, 70, width-200, 70, paint);
        canvas.drawLine(width-300, 110, width-200, 110, paint1);
        double ratio = (double)(width-200)/512;
        if (audioData != null) {
            for (int i = 0; i < audioData.length - 1; i++) {
                canvas.drawLine((float) (i*ratio+10), audioData[i] + 40+height/2, (float) ((i+1)*ratio+10), audioData[i + 1] + 40+height/2, paint);
            }
        }



        super.onDraw(canvas);
    }

     public void setAudioData(float[] aduioData) {
            this.audioData = aduioData;
            invalidate();
     }



    /**
     * 
     * @param canvas
     * @param p1
     *            周期大小
     * @param p2
     *            采样点数
     */
    public void drawSin(Canvas canvas, int p1, int p2) {
        float[] x = new float[p2];
        float[] y = new float[p2];
        double Pi = 2 * Math.PI;
        float t1 = (float) 390 / p2;
        x[0] = 10;
        y[0] = 280;
        for (int i = 1; i < p2; i++) {
            x[i] = (i * t1) + 10;
            y[i] = -(float) Math.sin(i * t1 * Pi / p1) * 70 + 280;
            canvas.drawLine(x[i - 1], y[i - 1], x[i], y[i], paint);
        }

    }

    /**
     * 画箭头
     * 
     * @param sx
     * @param sy
     * @param ex
     * @param ey
     */
    public void drawAL(int sx, int sy, int ex, int ey, Canvas canvas) {
        double H = 8; // 箭头高度
        double L = 3.5; // 底边的一半
        int x3 = 0;
        int y3 = 0;
        int x4 = 0;
        int y4 = 0;
        double awrad = Math.atan(L / H); // 箭头角度
        double arraow_len = Math.sqrt(L * L + H * H); // 箭头的长度
        double[] arrXY_1 = rotateVec(ex - sx, ey - sy, awrad, true, arraow_len);
        double[] arrXY_2 = rotateVec(ex - sx, ey - sy, -awrad, true, arraow_len);
        double x_3 = ex - arrXY_1[0]; // (x3,y3)是第一端点
        double y_3 = ey - arrXY_1[1];
        double x_4 = ex - arrXY_2[0]; // (x4,y4)是第二端点
        double y_4 = ey - arrXY_2[1];
        Double X3 = new Double(x_3);
        x3 = X3.intValue();
        Double Y3 = new Double(y_3);
        y3 = Y3.intValue();
        Double X4 = new Double(x_4);
        x4 = X4.intValue();
        Double Y4 = new Double(y_4);
        y4 = Y4.intValue();
        // 画线
        canvas.drawLine(sx, sy, ex, ey, paint);
        Path triangle = new Path();
        triangle.moveTo(ex, ey);
        triangle.lineTo(x3, y3);
        triangle.lineTo(x4, y4);
        triangle.close();
        canvas.drawPath(triangle, paint);

    }

    // 计算
    public double[] rotateVec(int px, int py, double ang, boolean isChLen,
            double newLen) {
        double mathstr[] = new double[2];
        // 矢量旋转函数,参数含义分别是x分量、y分量、旋转角、是否改变长度、新长度
        double vx = px * Math.cos(ang) - py * Math.sin(ang);
        double vy = px * Math.sin(ang) + py * Math.cos(ang);
        if (isChLen) {
            double d = Math.sqrt(vx * vx + vy * vy);
            vx = vx / d * newLen;
            vy = vy / d * newLen;
            mathstr[0] = vx;
            mathstr[1] = vy;
        }
        return mathstr;
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值