Android: onDraw方法使用DrawPoint()在画布上引起抖动和失真



我正在开发一个应用程序,它或多或少地在画布上绘制一个二维矩阵的值。这个矩阵的值被缩放到Alpha级别以说明强度,矩阵的坐标只是从行和列索引中推断出来的。下面是我的onDraw例程。

public void onDraw(Canvas canvas, float [][] spectrum, float nsegs,int seglen) {
    //canvas.translate(0,0);
    //alpha = 0;

    int canHeight = canvas.getHeight();
    int canWidth = canvas.getWidth();

    //float[] array = generateData(512);
    float [] spec = new float[seglen];
    final float bw = (float)(canWidth-2)/nsegs;
    final float bh = (float)(canHeight-2)/(float) seglen;
    for (int i = 0;i<seglen;i++){
        spec[i] = spectrum[i][index];   // One column at a time
    }
    float max = maxVal(spec);
    float min = minVal(spec);
    xcoor = index;
        for (int n = 0; n < seglen; n++){ 

            //Scale value to alpha (0-255)
            alpha =(int)Math.round((((spec[n] - min)/max)*255.0));
            ycoor = n;
            paint.setAlpha(alpha);
            canvas.drawPoint(xcoor,ycoor, paint);

        }
        index = (int) (index +1);
    if (index == nsegs-1){
        index = 0;
    }
}

这里油漆配置被预先定义为:

            Paint   paint = new Paint();
            paint.setStyle(Paint.Style.FILL);
    paint.setColor(Color.WHITE);
    paint.setStrokeWidth(2);

这个程序每次绘制一个像素,填充一列像素,等于矩阵中一列的元素数量。然后从下一列开始,其中仍然显示前一列,依此类推。在这个阶段,当所有列都已填满时,它再次从第一列开始,在前面的元素上绘制。

问题:尾列虽然已经绘制,但似乎闪烁和跳跃,阿尔法也是如此。我曾尝试canvas.save()和canvas.restore()来捕获整个画布并在列印列后恢复它。我已经仔细检查了所有的行和列索引和alpha值,以确保坐标按所需的方式增加(它们确实如此)。这与示例APIdemo DrawPoints.java非常相似,但是有三个主要区别。

  1. 我正在使用DrawPoint而不是DrawPoints,和
  2. 我不使用"canvas"。setcolor",因为它从画布上移除尾栏。
  3. 这个onDraw函数在一个扩展了SurfaceView的线程中运行

在上面的例子中,我使用的是SurfaceView而不是View。Out of Android dev docs

注意:每次从SurfaceHolder中检索画布时,画布的先前状态将被保留。为了正确地动画你的图形,你必须重新绘制整个表面。例如,您可以通过使用drawColor()填充颜色或使用drawBitmap()设置背景图像来清除画布的先前状态。否则,您将看到您之前执行的绘图的痕迹。

解决方案,每次重新绘制整个画布以防止抖动

最新更新