Как повернуть нанесение с включенным сглаживанием с псевдонимом

StackOverflow https://stackoverflow.com/questions/3002094

Вопрос

Мне нужно повернуть изображение на несколько градусов. Я делаю это с помощью подклассов 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();
}

Проблема в том, что изображение, которое приводит к тому, что показывает кучу jaggies.

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

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

Это было полезно?

Решение

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

/**
 * 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();
    }
}

Другие советы

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

Paint bitmapPaint = new Paint();
bitmapPaint.setAntiAlias(true);
bitmapPaint.setFilterBitmap(true);

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

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

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

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);

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

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

IFOUNT только одно решение: в OnDaw или Dispatch Draw Method

        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();       

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

Paint bitmapPaint =  new Paint();
bitmapPaint.setAntiAlias(true);
bitmapPaint.setFilterBitmap(true);
bitmapPaint.setDither(true);
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top