2010-06-08 4 views
8

Necesito rotar un ImageView por unos pocos grados. Estoy haciendo esto subclasificando ImageView y la sobrecarga onDraw()Cómo rotar un dibujable con anti-aliasing habilitado

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

El problema es que la imagen resultante muestra un manojo de dientes de sierra.

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

Como puedo AntiAlias ​​un ImageView que necesito para girar con el fin de eliminar el efecto de escalón? ¿Hay una mejor manera de hacer esto?

Respuesta

4

Si usted sabe que su Disponibles es un BitmapDrawable, puede utilizar el suavizado en la pintura del mapa de bits para hacer algo como lo siguiente:

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

Esta rotación resuelve sólo una parte del problema - los bordes dentados, pero la imagen en cambio se volvió extraña.

Ifound sólo una solución aún: en OnDraw o empate despacho método

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

Set antialias y filterBitmap a la pintura que es dibujar el mapa de bits. que tenía un problema similar y esto funcionó para mí:

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

@ solución de Primoz990 trabajó para mí :) Me han podido, además interpolación de colores, por lo que mi código final que elimina los bordes dentados en la rotación es la siguiente:

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

hice lo siguiente para conseguir que funcione:

En AndroidManifest.xml he activado la aceleración por hardware <application android:hardwareAccelerated="true">.

En lugar de utilizar una costumbre dibujar-método, he cambiado el tipo de capa de la matriz con vistas al acelerado por hardware con anti-aliasing activado y ha añadido mis subvistas de la siguiente manera:

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

tengo que agregue que el recorte no se puede desactivar cuando se usa este enfoque.