Android,如何从位图中裁剪圆形区域

androidapps/applicationsmobile development更新于 2026/1/15 7:22:17

本示例演示了如何在 Android 中从位图中裁剪圆形区域。

步骤 1  − 在 Android Studio 中创建一个新项目,前往"文件"->"新建项目",并填写所有必需信息以创建新项目。

步骤 2  − 将以下代码添加到 res/layout/activity_main.xml。

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:app="http://schemas.android.com/apk/res-auto"
   xmlns:tools="http://schemas.android.com/tools"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   tools:context=".MainActivity"
   android:id="@+id/rl"
   android:padding="16dp"
   android:background="#edf2ea">
   <ImageView
      android:id="@+id/iv"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_centerInParent="true"/>
   <Button
      android:id="@+id/btn"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="Circular It"
      android:layout_alignParentBottom="true"
      android:layout_alignParentRight="true"/>
</RelativeLayout>

步骤 3  − 将以下代码添加到 src/MainActivity.java

package com.medkart.sample;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.RelativeLayout;
public class MainActivity extends AppCompatActivity {
   private Context mContext;
   private Resources mResources;
   private RelativeLayout mRelativeLayout;
   private Button mBTN;
   private ImageView mImageView;
   private Bitmap mBitmap;
   @Override
   protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);
      // 获取应用上下文
      mContext = getApplicationContext();
      // 获取资源
      mResources = getResources();
      // 从 XML 布局中获取小部件引用
      mRelativeLayout = (RelativeLayout) findViewById(R.id.rl);
      mImageView = (ImageView) findViewById(R.id.iv);
      mBTN = (Button) findViewById(R.id.btn);
      // 获取位图资源 ID
      final int bitmapResourceID =R.drawable.flower;
      // 将图片设置为 ImageView
      mImageView.setImageBitmap(BitmapFactory.decodeResource(mResources, bitmapResourceID));
      // 为 Button 小部件设置点击监听器
      mBTN.setOnClickListener(new View.OnClickListener() {
         @Override
         public void onClick(View view) {
            // 从 drawable 资源中获取位图
            mBitmap = BitmapFactory.decodeResource(mResources, bitmapResourceID);
            // 创建圆形位图
            mBitmap = getCircularBitmap(mBitmap);
            // 在圆形位图周围添加边框
            mBitmap = addBorderToCircularBitmap(mBitmap, 15, Color.WHITE);
            // 在圆形位图周围添加阴影
            mBitmap = addShadowToCircularBitmap(mBitmap, 4, Color.LTGRAY);
            // 将 ImageView 图像设置为可绘制对象
            mImageView.setImageBitmap(mBitmap);
         }
      });
   }
   protected Bitmap getCircularBitmap(Bitmap srcBitmap) {
      // 计算带边框的圆形位图宽度
      int squareBitmapWidth = Math.min(srcBitmap.getWidth(), srcBitmap.getHeight());
      // 初始化一个新的 Bitmap 实例
      Bitmap dstBitmap = Bitmap.createBitmap (
         squareBitmapWidth, // 宽度
         squareBitmapWidth, // 高度
         Bitmap.Config.ARGB_8888 // 配置
      );
      Canvas canvas = new Canvas(dstBitmap);
      // 初始化一个新的 Paint 实例
      Paint paint = new Paint();
      paint.setAntiAlias(true);
      Rect rect = new Rect(0, 0, squareBitmapWidth, squareBitmapWidth);
      RectF rectF = new RectF(rect);
      canvas.drawOval(rectF, paint);
      paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
      // 计算复制位图的左侧和顶部
      float left = (squareBitmapWidth-srcBitmap.getWidth())/2;
      float top = (squareBitmapWidth-srcBitmap.getHeight())/2;
      canvas.drawBitmap(srcBitmap, left, top, paint);
      // 释放与此位图关联的原生对象。
      srcBitmap.recycle();
      // 返回圆形位图
      return dstBitmap;
   }
   // 自定义方法,为圆形位图添加边框
   protected Bitmap addBorderToCircularBitmap(Bitmap srcBitmap, int borderWidth, int borderColor) {
      // 计算带边框的圆形位图宽度
      int dstBitmapWidth = srcBitmap.getWidth()+borderWidth*2;
      // 初始化一个新的 Bitmap,使其成为带边框的圆形位图
      Bitmap dstBitmap = Bitmap.createBitmap(dstBitmapWidth,dstBitmapWidth, Bitmap.Config.ARGB_8888);
      // 初始化一个新的 Canvas 实例
      Canvas canvas = new Canvas(dstBitmap);
      // 将源位图绘制到画布上
      canvas.drawBitmap(srcBitmap, borderWidth, borderWidth, null);
      // 初始化一个新的 Paint 实例来绘制边框
      Paint paint = new Paint();
      paint.setColor(borderColor);
      paint.setStyle(Paint.Style.STROKE);
      paint.setStrokeWidth(borderWidth);
      paint.setAntiAlias(true);
      canvas.drawCircle(
         canvas.getWidth() / 2, // cx
         canvas.getWidth() / 2, // cy
         canvas.getWidth()/2 - borderWidth / 2, // 半径
         paint // 绘制
      );
      // 释放与此位图关联的原生对象。
      srcBitmap.recycle();
      // 返回带边框的圆形位图
      return dstBitmap;
   }
   // 自定义方法,在圆形位图周围添加阴影
   protected Bitmap addShadowToCircularBitmap(Bitmap srcBitmap, int shadowWidth, int shadowColor){
      // 计算带阴影的圆形位图宽度
      int dstBitmapWidth = srcBitmap.getWidth()+shadowWidth*2;
      Bitmap dstBitmap = Bitmap.createBitmap(dstBitmapWidth,dstBitmapWidth, Bitmap.Config.ARGB_8888);
      // 初始化一个新的 Canvas 实例
      Canvas canvas = new Canvas(dstBitmap);
      canvas.drawBitmap(srcBitmap, shadowWidth, shadowWidth, null);
      // 绘制圆形位图阴影
      Paint paint = new Paint();
      paint.setColor(shadowColor);
      paint.setStyle(Paint.Style.STROKE);
      paint.setStrokeWidth(shadowWidth);
      paint.setAntiAlias(true);
      // 在圆形位图周围绘制阴影
      canvas.drawCircle (
         dstBitmapWidth / 2, // cx
         dstBitmapWidth / 2, // cy
         dstBitmapWidth / 2 - shadowWidth / 2, // Radius
         paint // Paint
      );
      srcBitmap.recycle();
      return dstBitmap;
   }
}

步骤 4  − 将以下代码添加到 Manifests/AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
   package="com.medkart.sample">
   <application
      android:allowBackup="true"
      android:icon="@mipmap/ic_launcher"
      android:label="@string/app_name"
      android:roundIcon="@mipmap/ic_launcher_round"
      android:supportsRtl="true"
      android:theme="@style/AppTheme">
      <activity android:name=".MainActivity">
         <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
         </intent-filter>
      </activity>
   </application>
</manifest>

让我们尝试运行您的应用程序。假设您已将实际的 Android 移动设备连接到电脑。要从 Android Studio 运行该应用程序,请打开项目的某个活动文件,然后点击工具栏上的"运行"播放图标图标。选择您的移动设备作为选项,然后检查将显示默认屏幕的移动设备 –

点击此处下载项目代码。


相关文章