2013-04-01 20 views
16

Ich war auf der Suche nach vergangenen Tag und ich war nicht erfolgreich.Crop Quadrat Bild zu kreisen - programmatisch

Ich bekomme das Bild von API, und ich lade es in eine Bitmap-Datei mit dem folgenden Code.

Und ich bekomme das Bild als ein Quadrat und ich möchte die vier Ecken zuschneiden und es zu einem kreisförmigen Bild machen. Gibt es einen möglichen Weg?

Alle damit verbundenen Antworten sind willkommen. Danke im Voraus .

+0

Nicht sicher von der Spitze meines Kopfes, aber ich nehme an, als alternative Vorgehensweise könnte ein Alpha-Kreis Bild mit dem Loch oben auf dem Originalbild ausgeschnitten erstellen. Dies ist nicht ideal im Vergleich zum Arbeiten mit einer Zirkelklasse und den entsprechenden Bearbeitungen, aber eine Alternative, wenn Sie nicht finden, was Sie suchen und eine schnelle Lösung benötigen. –

Antwort

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

Dieser Code erstellt die abgeschnittene Bitmap bei jedem Aufruf von onDraw() neu. Es empfiehlt sich, einen Verweis auf das ausgeschnittene Zeichen nur dann zu erstellen, wenn sich das Quell-Bitmap ändert, und es dann zu zeichnen. In der Tat können Sie den Verweis auf die Quellbitmap ebenfalls verlieren. Außerdem sollten Sie Paint außerhalb der Zeichnungsschleife zuweisen. – greg7gkb

+0

@ greg7gkb Vorschlag genommen wird die Post verbessern, wenn ich Zeit habe – Raghunandan

0

Dies kann einfach in xml getan werden, finden Sie in meiner Antwort hier: 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

die Funktion Schlag verwenden Kreis auf Bitmap zu zeichnen und dann die eingekreisten Bitmap 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

Große Funktion, aber was diese Linie tun: paint.setXfermode (neue PorterDuffXfermode (Mode.SRC_IN)); – bebosh

+0

@bebosh setzt den Zeichnungsmodus für die Bitmap (siehe http://ssp.impulsetrain.com/porterduff.html) ... oder fragen Sie, warum der Aufruf dieser Methode erforderlich ist? – greg7gkb

+0

Diese benutzerdefinierte Methode funktioniert problemlos, erzeugt aber ein horizontales Oval. Die Verwendung von RoundedBitmapDrawableFactory erzeugt einen perfekten Kreis, nur FYI. – JamisonMan111

2

Roman Nurik schlagen eine sehr direkte Verwendung von Shadern vor, um solche Dinge zu tun, mit einem benutzerdefinierten Zeichensatz.

Ich ändere den Code ein bisschen, um ein ovales Bild zu machen und testete mich. Die Wirkung und Leistung ist wirklich gut:

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

Sobald die Bitmap abgerufen RoundedBitmapDrawableFactory verwendet werden kann, ein RoundedBitmapDrawable vom v4 Support Library zu erzeugen. Diese Drawable kann dann auf eine ImageView oder direkt auf eine Canvas gezogen werden.

+2

Vielen Dank Godfrey, diese Antwort ist die einfachste und beste Antwort. Dies sollte die akzeptierte Antwort sein! – JamisonMan111

+0

Vielen Dank, es ist sehr hilfreich @Godfrey Duke – Shruti