2013-04-01 6 views
16

私は過去1日を探していましたが、私は成功しませんでした。サークルを四角形に切り抜く - プログラム的に

私はAPIからイメージを取得し、次のコードを使用してビットマップファイルにダウンロードします。

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

私は四角形の画像を得て、四隅を切り抜いて円形の画像にしたいと思います。実現可能な方法はありますか?

関連するすべての回答が歓迎されます。前もって感謝します 。

+0

私の頭の上からはわかりませんが、代わりのアプローチとして、元の画像の上にサイズを切り取った穴があるアルファサークル画像を作成することができます。これは、サークルクラスを使用して適切な編集を行うのに比べて理想的ではありませんが、あなたが探しているものが見つからず、すばやい解決が必要な場合は別の方法です。 –

答えて

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

このコードは、onDraw()が呼び出されるたびにクリップされたビットマップを再作成します。ソースビットマップが変更されてから描画されるときにのみ、切り抜かれたドロウアブルへの参照を作成する方がよいでしょう。実際、ソースビットマップへの参照も失われる可能性があります。また、描画ループの外でペイントを割り当てる方が良い。 – greg7gkb

+0

@ greg7gkbの提案は、時間があるとき投稿を改善します – Raghunandan

0

これは単純に、XMLで行うことができ、ここに私の答えをご覧ください。 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

は、ビットマップ上に円を描くように機能ブローを使用して、

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

偉大な機能が、この行は何を行う: paint.setXfermode(新しいPorterDuffXfermode(Mode.SRC_IN)); – bebosh

+0

@beboshこれは、ビットマップの描画モードを設定します(http://ssp.impulsetrain.com/porterduff.html参照)...またはこのメソッドへの呼び出しが必要な理由を尋ねていますか? – greg7gkb

+0

このカスタムメソッドはエラーなしで正常に動作しますが、水平楕円形のイメージを生成します。 RoundedBitmapDrawableFactoryを使用すると、完璧な円が生成されます(ちょうどFYI)。 – JamisonMan111

2

ローマン・ヌリックは、カスタムドロアブルを使用して、そうしたことを行うシェーダを非常に直接的に使用することを提案しています。

コードを少し変更して楕円形の画像を作り、自分でテストしました。効果とパフォーマンスは本当に良いです:

ビットマップが取得され
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

たらRoundedBitmapDrawableFactoryv4 Support LibraryからRoundedBitmapDrawableを生成するために使用することができます。その場合、Drawableは、ImageViewに、または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

Godfreyさんありがとうございました。この答えは最も簡単で最善の答えです。これは受け入れられた答えでなければなりません! – JamisonMan111

+0

ありがとう、それは非常に役に立つです@ゴッドフレー公爵 – Shruti

関連する問題