2010-06-08 12 views
8

Ho bisogno di ruotare un ImageView di alcuni gradi. Sto facendo questo da sottoclassi ImageView e sovraccarico onDraw()Come ruotare un drawable con anti-aliasing abilitato

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

Il problema è che l'immagine che ne risulta mostra un mazzo di scalettature.

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

Come posso antialias un ImageView che ho bisogno di ruotare al fine di eliminare scalettature? C'è un modo migliore per farlo?

risposta

4

Se sapete che il vostro Drawable è un BitmapDrawable, è possibile utilizzare l'anti-aliasing in Paint della bitmap di fare qualcosa di simile al seguente:

/** 
* 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

Questa rotazione risolve solo una parte del problema - bordi frastagliati, ma l'immagine invece è diventata strana.

ifound solo una soluzione ancora: in OnDraw o la spedizione metodo 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();  
3

Set antialias e filterBitmap alla vernice che disegnare è la bitmap. Ho avuto un problema simile e questo ha funzionato per me:

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

@ soluzione Primoz990 ha funzionato per me :) Ho anche abilitato dithering, quindi il mio codice finale che rimuove i bordi frastagliati di rotazione è questo:

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

ho fatto quanto segue per farlo funzionare:

In AndroidManifest.xml ho abilitato l'accelerazione hardware <application android:hardwareAccelerated="true">.

Invece di utilizzare disegnare metodo una consuetudine, ho cambiato lo strato-tipo del genitore-vista con accelerazione hardware con anti-aliasing abilitato e ha aggiunto le mie subviews come segue:

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

devo aggiungi che il ritaglio non può essere disattivato quando si utilizza questo approccio.