本文介绍了SurfaceView.lockCanvas()不正确清除缓冲位图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经创建,为了延伸SurfaceView循环一系列ARGB位图的一类。
这主要是工作的,所不同的是底层位图的状态(通常,但不总是)对每个新的帧

preserved

在换句话说,如果我显示第一帧是不透明的,和随后的帧是透明的,然后从原始帧中的不透明像素被不当新帧被绘制清除出去。

此行​​为混淆了我,因为SurfaceHolder.lockCanvas()的文​​件明确规定:

表面的内容从未$ unlockCanvas之间和lockCanvas(),因为这个原因,在表面区域内的每个像素必须写入p $ pserved()。

如果我只是有一个坚实的背景,然后调用canvas.drawARGB(255,0,0,0)成功以清零黑色...但我希望有一个透明的背景,而我不能清除它为透明的颜色,因为canvas.drawARGB(0,0,0,0)没有效果。

 进口的java.util.ArrayList;
进口了java.util.Random;进口android.content.Context;
进口android.graphics.Canvas;
进口android.graphics.Color;
进口android.graphics.Matrix;
进口android.graphics.Paint;
进口android.view.SurfaceHolder;
进口android.view.SurfaceView;/ *
 *接受通过它们位图缓冲液和循环的序列。
 * /类AnimatedBufferView扩展了SurfaceView实现Runnable
{
    线程线程= NULL;
    SurfaceHolder surfaceHolder;
    挥发性布尔运行= FALSE;    ArrayList的<&位图GT;帧;
    INT curIndex = 0;    公共AnimatedBufferView(ArrayList的<&位图GT; _frames,上下文的背景下)
    {
        超级(上下文);
        surfaceHolder = getHolder();
        帧= _frames;
    }    公共无效onResume(){
        运行= TRUE;
        线程=新主题(本);
        thread.start();
    }    公共无效的onPause(){
        布尔重试= TRUE;
        运行= FALSE;
        而(重试){
            尝试{
                的Thread.join();
                重试= FALSE;
            }赶上(InterruptedException的E){
                // TODO自动生成catch块
                e.printStackTrace();
            }
        }
    }    @覆盖
    公共无效的run()
    {
        // TODO自动生成方法存根
        而(运行)
        {
            如果(surfaceHolder.getSurface()。isValid()的)
            {
                帆布帆布= surfaceHolder.lockCanvas();                //清除缓冲区?
                //canvas.drawARGB(255,0,0,0);                //显示保存的帧缓冲..
                矩阵同一性=新的Matrix();
                位图帧= frames.get(curIndex);
                canvas.drawBitmap(帧,身份,NULL);
                surfaceHolder.unlockCanvasAndPost(画布);                curIndex =(curIndex + 1)%frames.size();                尝试{
                    Thread.sleep代码(100);
                }赶上(InterruptedException的E){
                    // TODO自动生成catch块
                    e.printStackTrace();
                }
            }
        }
    }
}


解决方案

好吧,发现问题的默认波特 - 达夫绘图,使得绘制一个透明的颜色是不可能的模式。只需要改变模式。即

 画布油画surfaceView.lockCanvas();
canvas.drawColor(0,Mode.CLEAR);

I have created a class that extends SurfaceView in order to cycle a series of ARGB bitmaps.This mostly works, except that the state of the underlying bitmap is (usually, but not always) preserved for each new frame.

In other words, if the first frame I display is opaque, and subsequent frames are transparent, then the opaque pixels from the original frame are not cleared out when the new frames are drawn.

This behavior confuses me, because the documentation for SurfaceHolder.lockCanvas() specifically states:

"The content of the Surface is never preserved between unlockCanvas() and lockCanvas(), for this reason, every pixel within the Surface area must be written."

If I just had a solid background, then calling canvas.drawARGB(255,0,0,0) succeeds to clear it to black...but I want to have a transparent background, and I can't clear it to a transparent color, because canvas.drawARGB(0,0,0,0) has no effect.

import java.util.ArrayList;
import java.util.Random;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

/*
 * Accepts a sequence of Bitmap buffers and cycles through them.
 */

class AnimatedBufferView extends SurfaceView implements Runnable
{
    Thread thread = null;
    SurfaceHolder surfaceHolder;
    volatile boolean running = false;

    ArrayList<Bitmap> frames;
    int curIndex = 0;

    public AnimatedBufferView(ArrayList<Bitmap> _frames, Context context) 
    {
        super(context);
        surfaceHolder = getHolder();
        frames = _frames;
    }

    public void onResume(){
        running = true;
        thread = new Thread(this);
        thread.start();
    }

    public void onPause(){
        boolean retry = true;
        running = false;
        while(retry){
            try {
                thread.join();
                retry = false;
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

    @Override
    public void run() 
    {
        // TODO Auto-generated method stub
        while(running)
        {
            if(surfaceHolder.getSurface().isValid())
            {               
                Canvas canvas = surfaceHolder.lockCanvas();

                //clear the buffer?
                //canvas.drawARGB(255, 0, 0, 0);

                //display the saved frame-buffer..
                Matrix identity = new Matrix();
                Bitmap frame = frames.get(curIndex);
                canvas.drawBitmap(frame, identity, null);


                surfaceHolder.unlockCanvasAndPost(canvas);

                curIndex = (curIndex + 1) % frames.size();

                try {
                    thread.sleep( 100 );
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    }
}
解决方案

Ok, discovered the problem was the default Porter-Duff drawing mode that made drawing a transparent color impossible. Just have to change mode. ie,

Canvas canvas surfaceView.lockCanvas();
canvas.drawColor(0, Mode.CLEAR);

这篇关于SurfaceView.lockCanvas()不正确清除缓冲位图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-16 21:15