Быстрое рисование на холсте Bitmap android ics

Я разрабатывал приложение для рисования на планшетах ics android и столкнулся с проблемой, которую не могу понять, как исправить.

Проблема в том, что я рисую правильно и рисую в режиме реального времени, НО когда я двигаюсь очень-очень быстро (проверено на реальных планшетах), круги на самом деле не круги, они выглядят как пилигоны с 5 или 6 сторонами...

Здесь я объявляю растровое изображение и назначаю его холсту:

    Display display = getWindowManager().getDefaultDisplay();
    Point size = new Point();
    display.getSize(size);
    width = size.x;
    height = size.y;
    bm = Bitmap.createBitmap(width, height-50,Bitmap.Config.ARGB_8888); 
    c = new Canvas(bm);

Вот код, который я использую для получения x, y: (layP — это «Painter», который вы увидите здесь.

class SaveOnTouchListener implements OnTouchListener{

    public boolean onTouch(View v, MotionEvent e) {
        final float x = e.getX();
        final float y = e.getY();
        if(e.getAction() == MotionEvent.ACTION_DOWN){  
            startx.add(x);
            starty.add(y);
            x1 = x;
            y1 = y;
        } else if(e.getAction() == MotionEvent.ACTION_MOVE){  
            endx.add(x);
            endy.add(y);
            x2 = x;
            y2 = y;
            if (id == 1) strokes.add(sb.getProgress()+1);
            else strokes.add(4*(sb.getProgress()+1));
            layP.draw();
            startx.add(x);
            starty.add(y);
            x1 = x;
            y1 = y;
        } else if(e.getAction() == MotionEvent.ACTION_UP){  
            x2 = x;
            y2 = y;
            endx.add(x);
            endy.add(y);
            strokes.add(stroke);
            layP.draw();
            return false;
        }
        return true;
    }

}

И, наконец, вот код для «художника», который представляет собой холст, и метод onDraw() (я использую невалидацию (t, l, r, b), чтобы сделать его оптимизированным....)

private class Painter extends View{
    public Painter(Context context){
        super(context);
    }

    public void draw() {
        if (firstPainting) {
                            //paint the canvas white just once
            Paint paint = new Paint();
            paint.setStyle(Paint.Style.FILL);
            paint.setColor(Color.WHITE);
            c.drawPaint(paint);
            firstPainting = false;
            layP.invalidate();
        }
        else {
                Paint paint = new Paint();
                paint.setStyle(Paint.Style.FILL);
                paint.setAntiAlias(true);
                int r = startx.get(startx.size()-1).intValue();
                int t = starty.get(starty.size()-1).intValue();
                int l = endx.get(endx.size()-1).intValue();
                int b = endy.get(endy.size()-1).intValue();
                int n = strokes.get(strokes.size()-1);
                paint.setStrokeWidth(n);
                paint.setColor(COLOR.BLACK);
                c.drawLine(r, t, l, b, paint);
                c.drawCircle(r, t, n/2, paint);

                if (l > r) {
                    int aux = l;
                    l = r;
                    r = aux;
                }
                if (t > b) {
                    int aux = t;
                    t = b;
                    b = aux;
                }
                r += n;
                l -= n;
                t -= n;
                b += n;
                if (t < 0) t = 0;
                if (l < 0) l = 0;
                layP.invalidate(l,t,r,b);
        }
    }


    @Override 
    protected void onDraw(Canvas c) {
            c.drawBitmap(bm, 0, 0, null);
    }
}
}

Как видите, я использую BitMap и просто аннулирую зону, которую нужно аннулировать, я не знаю, что еще делать.

Есть ли способ правильно рисовать? Даже если мне придется изменить все растровые изображения и холст.

Я пытался реализовать Безье, но не знаю, как это сделать, так как мне нужны следующие точки перед рисованием линий.

Я нашел метод Безье, думаю, попробую.


person Miquel Coll    schedule 27.06.2012    source источник


Ответы (1)


Мне вообще непонятно, что вы пытаетесь сделать. Судя по вашему тексту, вы пытаетесь сделать базовое «рисование пальцем», где вы просто рисуете кривые, соответствующие входным данным. Ваш код не очень похож на меня, но между переменными, которые вы используете, объявления для которых мы не видели (stroke и strokes), и однобуквенными именами переменных, я немного потерялся. Конечно, эти две строки:

c.drawLine(r, t, l, b, paint);
c.drawCircle(r, t, n/2, paint);

сделайте вид, что вы хотите большего, чем просто рисовать то, что пользователь рисует пальцем.

Тем не менее, я хотел бы попытаться помочь. drawCircle() действительно всегда нужно рисовать круги. Рисование линий между точками даст вам острые углы (многоугольники, если вы замкнете фигуру). Если вы хотите плавно рисовать такие пути, то кривые Безье — это то, что вам нужно.

Если вы загрузите пример кода из SDK, вы найдете пример под названием "FingerPaint". это очень хорошо демонстрирует, как плавно рисовать произвольные кривые.

person Darshan Rivka Whittle    schedule 06.07.2012
comment
Извините за задержку, это было давно, но я наконец-то использовал Безье, как вы сказали, и теперь я это увидел. Спасибо! - person Miquel Coll; 11.12.2013