2013-04-01 69 views
16

tôi đã tìm kiếm một ngày qua và tôi đã không thành công.Cắt hình vuông thành hình tròn - Lập trình

tôi lấy hình ảnh từ API và tôi tải xuống tệp bitmap bằng cách sử dụng mã sau.

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

Và tôi lấy hình ảnh làm hình vuông và tôi muốn cắt bốn góc và làm thành hình tròn. Có cách nào có thể đạt được không?

Mọi câu trả lời có liên quan đều được hoan nghênh. Cảm ơn trước .

+0

Không chắc chắn trên đầu của tôi, nhưng tôi cho rằng cách tiếp cận thay thế có thể là tạo hình ảnh vòng tròn alpha với lỗ cắt có kích thước trên đầu hình ảnh gốc. Đây không phải là lý tưởng so với làm việc với một lớp vòng tròn và thực hiện các chỉnh sửa thích hợp, nhưng thay thế nếu bạn không tìm thấy những gì bạn đang tìm kiếm và cần một giải pháp nhanh chóng. –

Trả lời

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

Mã này sẽ tạo lại bitmap đã cắt bớt mỗi khi onDraw() được gọi. Tốt hơn để tạo tham chiếu đến bản vẽ được cắt bớt chỉ khi bitmap nguồn thay đổi và sau đó vẽ nó. Thực tế, bạn cũng có thể mất tham chiếu tới bitmap nguồn. Cũng tốt hơn để phân bổ Sơn bên ngoài vòng lặp vẽ. – greg7gkb

+0

@ greg7gkb đề xuất được thực hiện sẽ cải thiện bài đăng khi tôi có thời gian – Raghunandan

0

này có thể chỉ cần thực hiện trong xml, hãy xem câu trả lời của tôi ở đây: 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

sử dụng chức năng đòn để vẽ vòng tròn trên bitmap và sau đó thiết lập các bitmap được khoanh tròn để 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

Chức năng tuyệt vời, nhưng dòng này làm gì: paint.setXfermode (new PorterDuffXfermode (Mode.SRC_IN)); – bebosh

+0

@bebosh này đặt chế độ vẽ cho bitmap (xem http://ssp.impulsetrain.com/porterduff.html) ... hoặc bạn có hỏi tại sao cuộc gọi đến phương thức này là bắt buộc không? – greg7gkb

+0

Phương thức tùy chỉnh này hoạt động tốt mà không có lỗi nhưng tạo ra hình ảnh là hình bầu dục nằm ngang. Sử dụng RoundedBitmapDrawableFactory tạo ra một vòng tròn hoàn hảo, chỉ là FYI. – JamisonMan111

2

Roman Nurik đề xuất sử dụng trực tiếp các trình đổ bóng để thực hiện những việc như vậy, với tùy chỉnh có thể vẽ được.

Tôi thay đổi mã một chút để tạo hình bầu dục và tự kiểm tra. Hiệu quả và hiệu suất là thực sự tốt:

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

Khi bitmap được lấy RoundedBitmapDrawableFactory thể được sử dụng để tạo ra một RoundedBitmapDrawable từ v4 Support Library. Sau đó, Drawable có thể được áp dụng cho một số ImageView hoặc được vẽ trực tiếp đến 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

Cảm ơn bạn rất nhiều Godfrey, câu trả lời này là câu trả lời đơn giản và tốt nhất. Đây sẽ là câu trả lời được chấp nhận! – JamisonMan111

+0

cảm ơn bạn rất nhiều, nó rất hữu ích @Godfrey Duke – Shruti

Các vấn đề liên quan