2013-04-01 13 views
16

stavo cercando un giorno passato e non ho avuto successo.Ritaglia l'immagine quadrata al cerchio - Programmabile

ottengo l'immagine dall'API e la scarico in un file bitmap utilizzando il seguente codice.

private Bitmap DownloadImage(String URL) 
    { 
     Bitmap bitmap = null; 
     InputStream in = null; 
     try 
     { 
      in = OpenHttpConnection(URL); 
      bitmap = BitmapFactory.decodeStream(in); 
      in.close(); 
     } 
     catch (IOException e1) 
     { 
      e1.printStackTrace(); 
     } 
     return bitmap; 
    } 

    private InputStream OpenHttpConnection(String urlString) throws IOException 
    { 
     InputStream in = null; 
     int response = -1; 

     URL url = new URL(urlString); 
     URLConnection conn = url.openConnection(); 

     if (!(conn instanceof HttpURLConnection)) 
      throw new IOException("Not an HTTP connection"); 

     try 
     { 
      HttpURLConnection httpConn = (HttpURLConnection) conn; 
      httpConn.setAllowUserInteraction(false); 
      httpConn.setInstanceFollowRedirects(true); 
      httpConn.setRequestMethod("GET"); 
      httpConn.connect(); 

      response = httpConn.getResponseCode(); 
      if (response == HttpURLConnection.HTTP_OK) 
      { 
       in = httpConn.getInputStream(); 
      } 
     } 
     catch (Exception ex) 
     { 
      throw new IOException("Error connecting"); 
     } 
     return in; 
    } 

E ottengo l'immagine come un quadrato e voglio ritagliare i quattro angoli e renderlo all'immagine circolare. C'è un modo possibile per raggiungere?

Qualsiasi risposta correlata è accolta favorevolmente. Grazie in anticipo .

+0

Non sono sicuro fuori dalla parte superiore della mia testa, ma suppongo che come approccio alternativo potrebbe essere quello di creare un'immagine cerchio alpha con il foro tagliato dimensioni sopra l'immagine originale. Questo non è l'ideale se paragonato a lavorare con una classe circle e fare le modifiche appropriate, ma un'alternativa se non trovi quello che stai cercando e hai bisogno di una risoluzione veloce. –

risposta

19
public class MainActivity extends Activity { 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     // TODO Auto-generated method stub 
     super.onCreate(savedInstanceState); 
     DrawingView dv = new DrawingView(this); 
     setContentView(dv); 
    } 

    class DrawingView extends View { 
     Bitmap bitmap; 

     public DrawingView(Context context) { 
      super(context); 
      bitmap = BitmapFactory.decodeResource(context.getResources(), 
        R.drawable.glossy_overlay); 

     } 

     @Override 
     public void onDraw(Canvas canvas) { 
      Paint paint = new Paint(); 
      // paint.setColor(Color.CYAN); 
      canvas.drawBitmap(getclip(), 30, 20, paint); 
     } 

     public Bitmap getclip() { 
      Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), 
        bitmap.getHeight(), Config.ARGB_8888); 
      Canvas canvas = new Canvas(output); 
      final int color = 0xff424242; 
      final Paint paint = new Paint(); 
      final Rect rect = new Rect(0, 0, bitmap.getWidth(), 
        bitmap.getHeight()); 

      paint.setAntiAlias(true); 
      canvas.drawARGB(0, 0, 0, 0); 
      // paint.setColor(color); 
      canvas.drawCircle(bitmap.getWidth()/2, 
        bitmap.getHeight()/2, bitmap.getWidth()/2, paint); 
      paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN)); 
      canvas.drawBitmap(bitmap, rect, rect, paint); 
      return output; 
     } 
    } 
} 
+2

Questo codice ricrea la bitmap tagliata ogni volta che viene chiamato onDraw(). È meglio creare un riferimento al disegnabile ritagliato solo quando la bitmap di origine cambia e quindi la disegna. In effetti, puoi anche perdere il riferimento alla bitmap di origine. È anche meglio allocare Paint all'esterno del ciclo di disegno. – greg7gkb

+0

@ greg7gkb suggerito per migliorare il post quando ho tempo – Raghunandan

0

Questo può essere fatto semplicemente in xml, Si prega di vedere la mia risposta qui: https://stackoverflow.com/a/18287979/665930

<RelativeLayout 
      android:id="@+id/icon_layout" 
      android:layout_width="@dimen/icon_mask" 
      android:layout_height="@dimen/icon_mask" 
      android:layout_alignParentLeft="true" 
      android:layout_alignParentTop="true" > 

      <ImageView 
       android:id="@+id/icon" 
       android:layout_width="@dimen/icon" 
       android:layout_height="@dimen/icon" 
       android:layout_centerInParent="true" 
       android:scaleType="fitXY" > 
      </ImageView> 

      <ImageView 
       android:id="@+id/icon_mask" 
       android:layout_width="@dimen/icon_mask" 
       android:layout_height="@dimen/icon_mask" 
       android:layout_centerInParent="true" 
       android:background="@drawable/circle" 
       android:scaleType="fitXY" > 
      </ImageView> 


</RelativeLayout> 


<?xml version="1.0" encoding="utf-8"?> 
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval" > 
    <gradient android:startColor="#00FFFFFF" android:endColor="#00FFFFFF" 
     android:angle="270"/> 
    <stroke android:width="10dp" android:color="#FFAAAAAA"/> 
13

usare il colpo la funzione per disegnare cerchio sul bitmap e quindi impostare la bitmap cerchiata a imageview

public static Bitmap getclip(Bitmap bitmap) { 
    Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), 
      bitmap.getHeight(), Config.ARGB_8888); 
    Canvas canvas = new Canvas(output); 

    final Paint paint = new Paint(); 
    final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight()); 

    paint.setAntiAlias(true); 
    canvas.drawARGB(0, 0, 0, 0); 
    canvas.drawCircle(bitmap.getWidth()/2, bitmap.getHeight()/2, 
      bitmap.getWidth()/2, paint); 
    paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN)); 
    canvas.drawBitmap(bitmap, rect, rect, paint); 
    return output; 
} 
+0

Grande funzione, ma cosa fa questa riga: paint.setXfermode (nuovo PorterDuffXfermode (Mode.SRC_IN)); – bebosh

+0

@bebosh imposta la modalità di disegno per la bitmap (vedi http://ssp.impulsetrain.com/porterduff.html) ... o stai chiedendo perché è necessaria la chiamata a questo metodo? – greg7gkb

+0

Questo metodo personalizzato funziona perfettamente senza errori ma produce un'immagine ovale orizzontale. L'utilizzo di RoundedBitmapDrawableFactory produce un cerchio perfetto, solo FYI. – JamisonMan111

2

Roman Nurik propone un uso molto diretto di shader per fare cose del genere, con un drawable personalizzato.

Cambiare leggermente il codice per creare un'immagine ovale e verificare me stesso. L'effetto e le prestazioni sono davvero buono:

public class StreamDrawable extends Drawable { 
private static final boolean USE_VIGNETTE = true; 

private final RectF mRect = new RectF(); 
private final BitmapShader mBitmapShader; 
private final Paint mPaint; 
private final int mMargin; 

public StreamDrawable(Bitmap bitmap, int margin) { 

    mBitmapShader = new BitmapShader(bitmap, 
      Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); 

    mPaint = new Paint(); 
    mPaint.setAntiAlias(true); 
    mPaint.setShader(mBitmapShader); 

    mMargin = margin; 
} 

@Override 
protected void onBoundsChange(Rect bounds) { 
    super.onBoundsChange(bounds); 
    mRect.set(mMargin, mMargin, bounds.width() - mMargin, bounds.height() - mMargin); 

    if (USE_VIGNETTE) { 
     RadialGradient vignette = new RadialGradient(
       mRect.centerX(), mRect.centerY() * 1.0f/0.7f, mRect.centerX() * 1.3f, 
       new int[] { 0, 0, 0x7f000000 }, new float[] { 0.0f, 0.7f, 1.0f }, 
       Shader.TileMode.CLAMP); 

     Matrix oval = new Matrix(); 
     oval.setScale(1.0f, 0.7f); 
     vignette.setLocalMatrix(oval); 

     mPaint.setShader(
       new ComposeShader(mBitmapShader, vignette, PorterDuff.Mode.SRC_OVER)); 
    } 
} 

@Override 
public void draw(Canvas canvas) { 
    canvas.drawOval(mRect, mPaint); 
} 

@Override 
public int getOpacity() { 
    return PixelFormat.TRANSLUCENT; 
} 

@Override 
public void setAlpha(int alpha) { 
    mPaint.setAlpha(alpha); 
} 

@Override 
public void setColorFilter(ColorFilter cf) { 
    mPaint.setColorFilter(cf); 
} 
} 
14

Una volta che l'immagine bitmap viene recuperato RoundedBitmapDrawableFactory può essere utilizzato per generare un RoundedBitmapDrawable dal v4 Support Library. È possibile quindi applicare Drawable a ImageView o direttamente a Canvas.

// Create the RoundedBitmapDrawable. 
RoundedBitmapDrawable roundDrawable = RoundedBitmapDrawableFactory.create(getResources(), bitmap); 
roundDrawable.setCircular(true); 

// Apply it to an ImageView. 
ImageView imageView = (ImageView)findViewById(R.id.imageView); 
imageView.setImageDrawable(roundDrawable); 

// Alternatively, draw it to an canvas (e.g. in onDraw where a Canvas is available). 
// setBounds since there's no View handling size and positioning. 
roundDrawable.setBounds(left, top, right, bottom); 
roundDrawable.draw(canvas); 
+2

Grazie mille Godfrey, questa risposta è la risposta più semplice e migliore. Questa dovrebbe essere la risposta accettata! – JamisonMan111

+0

grazie mille, è molto utile @Godfrey Duke – Shruti

Problemi correlati