Как вращать рисованный объект с включенным сглаживанием - PullRequest
8 голосов
/ 09 июня 2010

Мне нужно повернуть ImageView на несколько градусов. Я делаю это путем создания подклассов ImageView и перегрузки onDraw()

@Override
protected void onDraw(Canvas canvas) {
    canvas.save();
    canvas.scale(0.92f,0.92f);
    canvas.translate(14, 0);
    canvas.rotate(1,0,0);
    super.onDraw(canvas);
    canvas.restore();
}

Проблема в том, что на изображении, которое появляется, показано несколько неровностей.

http://img.skitch.com/20100608-gmdy4sexsm1c71di9rgiktdjhu.png

Как я могу сгладить ImageView, который мне нужно повернуть, чтобы устранить неровности? Есть ли лучший способ сделать это?

Ответы [ 5 ]

5 голосов
/ 09 июня 2010

Если вы знаете, что ваш Drawable является BitmapDrawable, вы можете использовать сглаживание в растровом изображении, чтобы сделать что-то вроде следующего:

/**
 * Not as full featured as ImageView.onDraw().  Does not handle 
 * drawables other than BitmapDrawable, crop to padding, or other adjustments.
 */
@Override
protected void onDraw(Canvas canvas) {
    final Drawable d = getDrawable();

    if( d!=null && d instanceof BitmapDrawable && ((BitmapDrawable)d).getBitmap()!=null ) {
        final Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);
        final int paddingLeft = getPaddingLeft();
        final int paddingTop = getPaddingTop();

        canvas.save();

        // do my rotation and other adjustments
        canvas.scale(0.92f,0.92f);
        canvas.rotate(1,0,0);

        if( paddingLeft!=0 )
            canvas.translate(paddingLeft,0);

        if( paddingTop!=0 )
            canvas.translate(0,paddingTop);

        canvas.drawBitmap( ((BitmapDrawable)d).getBitmap(),0,0,p );
        canvas.restore();
    }
}
4 голосов
/ 08 мая 2012

Установите сглаживание и filterBitmap для краски, которая рисует растровое изображение.У меня была похожая проблема, и это сработало для меня:

Paint bitmapPaint = new Paint();
bitmapPaint.setAntiAlias(true);
bitmapPaint.setFilterBitmap(true);
1 голос
/ 30 сентября 2014

Я сделал следующее, чтобы заставить его работать:

В AndroidManifest.xml Я включил аппаратное ускорение <application android:hardwareAccelerated="true">.

Вместо использования пользовательского метода рисования я изменил тип слоя родительского представления на аппаратно-ускоренный с включенным сглаживанием и добавил свои подпредставления следующим образом:

Paint layerPaint =  new Paint();
layerPaint.setAntiAlias(true);
layerPaint.setFilterBitmap(true);
layerPaint.setDither(true);

RelativeLayout parentLayout = (RelativeLayout) LayoutInflater.from(context).inflate(R.layout.myLayout, null);
parentLayout.setLayerType(View.LAYER_TYPE_HARDWARE, layerPaint);

parentLayout.addView(myChildView);

Я должен добавить, что отсечение не может быть отключено при использовании этого подхода.

0 голосов
/ 15 августа 2012

@ Решение Primoz990 для меня сработало :) Я также включил дизеринг, поэтому мой последний код, который удаляет зубчатые края при вращении, таков:

0 голосов
/ 18 августа 2011

Это вращение решает только одну часть проблемы - неровные края, но вместо этого изображение стало более странным.

если найдено только одно решение: в методе ondraw или dispatch draw

        Bitmap bmp = ((BitmapDrawable)image.getDrawable()).getBitmap();
    double scale = (0.0+bmp.getWidth()+40.0)/getWidth();
    if (scale > 1){
        bmp = Bitmap.createScaledBitmap(bmp, getWidth()-40, (int) (bmp.getHeight()/scale), true);
    }

    canvas.drawColor(Color.TRANSPARENT); 
    canvas.save();

    canvas.translate(20, yShift);

    int left = borderSize;
    int top = borderSize;
    int right = bmp.getWidth() - borderSize;
    int bottom = bmp.getHeight() - borderSize;

    if(showText){
        mPaint.setColor(Color.WHITE);
        canvas.rotate(getAngel());
        canvas.drawRect(left, top, right, bottom, mPaint);

        canvas.translate(0,0);
        textFrame.draw(canvas);
    }else{
        // rotaed bitmap 
        mMatrix.setRotate(getAngel());

        // draw bitmap after creation of new rotated bitmap from rotated matrix
        canvas.drawBitmap(Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(), bmp.getHeight(), mMatrix, true)
                   , 0, 0, mPaint);
    }
    canvas.restore();       
...