在SurfaceView上绘图时出现问题

发布于 2024-10-08 11:09:36 字数 1128 浏览 3 评论 0原文

我正在 Android 中尝试使用 SurfaceView,并尝试创建一个简单的绘图类型应用程序,您可以通过触摸来“绘图”。我有一个线程正在运行来处理画布上的绘图,但遇到了一些性能问题。我读过 http://developer.android.com/guide/topics/graphics/ index.html 表明您需要重新绘制整个表面,因此我尝试将所有触摸点存储在浮点数组 mPoints 中,然后每次都重新绘制它们。问题是,当积累了很多点时,它会变得非常慢。这是代码:

    @Override
    public void run() { 

        while(mIsRunning) {
            Canvas c = null;
            try {                   
                c = mSurface.lockCanvas(null);
                synchronized(mSurface) {
                    int size = mPoints.getSize();
                    for(int i = 0; i < size; i += 2) {
                        c.drawCircle(mPoints.get(i), mPoints.get(i + 1), 3, mPaint);                            
                    }   
                }                                   
            }
            finally {
                if (c != null)
                    mSurface.unlockCanvasAndPost(c);
            }       

        }   
    }

但是,当我更新它以清除浮点数组并只绘制新的触摸点时,它会导致大量闪烁。据我所知,这是因为 Android 使用双缓冲。我不知道如何解决这些问题。

I'm experimenting with the SurfaceView in Android and I'm trying to create a simple drawing type application, where you "draw" by touch on it. I have a thread running to handle the drawing onto the canvas but I'm hitting some performance issues. I read on http://developer.android.com/guide/topics/graphics/index.html that you need to repaint the entire surface so I tried storing all the touched points in a float array mPoints and than redraw them every time. Problem is when a lot of points build up it gets really slow. Here is the code for that:

    @Override
    public void run() { 

        while(mIsRunning) {
            Canvas c = null;
            try {                   
                c = mSurface.lockCanvas(null);
                synchronized(mSurface) {
                    int size = mPoints.getSize();
                    for(int i = 0; i < size; i += 2) {
                        c.drawCircle(mPoints.get(i), mPoints.get(i + 1), 3, mPaint);                            
                    }   
                }                                   
            }
            finally {
                if (c != null)
                    mSurface.unlockCanvasAndPost(c);
            }       

        }   
    }

However when I updated it so that it cleared the float array and only drew new touched points it causes a lot of flickering. From what I can tell this is because Android uses double buffering. I'm not sure how to get around these problems.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

寒冷纷飞旳雪 2024-10-15 11:09:36

尝试写入位图,然后每次都重新绘制位图。您也许可以保留最后 10 点的记录或允许撤消等的记录。

try writing to a bitmap and then redrawing the bitmap every time. You can maybe keep a record of last 10 points or something to allow undo etc.

琴流音 2024-10-15 11:09:36

基于阿迪尔的答案,这是我想出的并且似乎有效。如果您尝试绘制一条连续的点线,它似乎并不能完全拾取每个点,因此它需要一些进一步的优化,但它确实完成了工作:

    @Override
    public void run() {
        mDrawing = Bitmap.createBitmap(mWidth, mHeight, Bitmap.Config.ARGB_8888);       
        Canvas tempCanvas = new Canvas();
        tempCanvas.setBitmap(mDrawing);

        Canvas c = null;
        while(mIsRunning) {
            int size = mPoints.getSize();
            for(int i = 0; i < size; i += 2) {
                tempCanvas.drawCircle(mPoints.get(i), mPoints.get(i + 1), 3, mPaint);                           
            }    

            mPoints.empty();

            try {                   
                c = mSurface.lockCanvas(null);
                synchronized(mSurface) {
                    c.drawBitmap(mDrawing, 0, 0, mPaint);
                }                                   
            }
            finally {
                if (c != null)
                    mSurface.unlockCanvasAndPost(c);
            }       

        }   
    }

Building on Adil's answer, this is what I came up with and seems to work. It doesn't seem to quite pick up every single point if you try and draw a continuous line of points so it needs some further optimization but it does get the job done:

    @Override
    public void run() {
        mDrawing = Bitmap.createBitmap(mWidth, mHeight, Bitmap.Config.ARGB_8888);       
        Canvas tempCanvas = new Canvas();
        tempCanvas.setBitmap(mDrawing);

        Canvas c = null;
        while(mIsRunning) {
            int size = mPoints.getSize();
            for(int i = 0; i < size; i += 2) {
                tempCanvas.drawCircle(mPoints.get(i), mPoints.get(i + 1), 3, mPaint);                           
            }    

            mPoints.empty();

            try {                   
                c = mSurface.lockCanvas(null);
                synchronized(mSurface) {
                    c.drawBitmap(mDrawing, 0, 0, mPaint);
                }                                   
            }
            finally {
                if (c != null)
                    mSurface.unlockCanvasAndPost(c);
            }       

        }   
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文