需要图片集和源码请点赞关注收藏后评论区留言~~~
所谓抠图神器,就是从一副图片中扣出用户想要的某块区域
一、需求描述
美图的修图功能如此强大,离不开专业的图片加工技术,抠图便是其中重要的一项功能。在App界面底部点击抠图按钮,再选择下方的形状按钮就会出现等待抠图的目标区域,然后通过手指触摸挪动方框,也可两指并用缩放或者旋转方框,调整方框大小以及角度后,再点击右下角的三点按钮,选择弹出菜单中的存为贴纸,就可以在贴纸功能中查看已经扣好的图片。
示意图如下
二、功能分析
抠图工具通过对图像进行平移,缩放,旋转等操作把图像的某个区域扣下来,抠图工具要提供打工图片和保存图片两种操作,其中打开图片支持从手机相册选取待加工的原始图片,保存图片支持把抠出来的图像保存到存储卡
打开原始图片后 工具界面进入抠图模式 主界面上没有任何控制按钮,抠哪个区域完全靠手势操作 需要实现的手势处理有以下五种
1:挪动高亮区域的手势
2:调整高亮区域边界的手势
3:挪动图片的手势
4:缩放图片的手势
5:旋转图片的手势
三、效果展示
演示视频如下
美图秀秀
点击右上角的三角按钮 可以打开和保存图片
下面用我们熟知的足坛巨星C罗举例
可以对图像进行放缩 旋转等操作
四、代码
java类
package com.example.event; import com.example.event.util.BitmapUtil; import com.example.event.util.DateUtil; import com.example.event.widget.BitmapView; import com.example.event.widget.MeituView; import com.example.event.widget.MeituView.ImageChangetListener; import android.app.Activity; import android.content.Intent; import android.graphics.Bitmap; import android.graphics.Rect; import android.net.Uri; import android.os.Bundle; import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.widget.Toolbar; import android.os.Environment; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.WindowManager; import android.widget.TextView; import android.widget.Toast; public class MeituActivity extends Activity implements ImageChangetListener { private final static String TAG = "MeituActivity"; private int CHOOSE_CODE = 3; // 只在相册挑选图片的请求码 private MeituView mv_content; // 声明一个美图视图对象 private BitmapView bv_content; // 声明一个位图视图对象 private TextView tv_hint; // 声明一个文本视图对象 @Override protected void onCreate(Bundle savedInstanceState) { private void initView() { Toolbar tl_head = findViewById(R.id.tl_head); tl_head.setTitle("抠图工具"); setSupportActionBar(tl_head); // 替换系统自带的ActionBar // 设置工具栏左侧导航图标的点击监听器 tl_head.setNavigationOnClickListener(view -> finish()); mv_content = findViewById(R.id.mv_content); mv_content.setImageChangetListener(this); // 设置美图视图的图像变更监听器 bv_content = findViewById(R.id.bv_content); bv_content.setDrawingCacheEnabled(true); // 开启位图视图的绘图缓存 tv_hint = findViewById(R.id.tv_hint); } private void setSupportActionBar(Toolbar tl_head) { } // 刷新图像展示 private void refreshImage(boolean is_first) { Bitmap bitmap = bv_content.getDrawingCache(); // 从绘图缓存获取位图对象 mv_content.setOrigBitmap(bitmap); // 设置美图视图的原始位图 if (is_first) { // 首次打开 int left = bitmap.getWidth() / 4; int top = bitmap.getHeight() / 4; // 设置美图视图的位图边界 mv_content.setBitmapRect(new Rect(left, top, left * 2, top * 2)); } else { // 非首次打开 // 设置美图视图的位图边界 mv_content.setBitmapRect(mv_content.getBitmapRect()); } } // 在图片平移时触发 @Override public void onImageTraslate(int offsetX, int offsetY, boolean bReset) { bv_content.setOffset(offsetX, offsetY, bReset); // 设置位图视图的偏移距离 refreshImage(false); // 刷新图像展示 } // 在图片缩放时触发 @Override public void onImageScale(float ratio) { bv_content.setScaleRatio(ratio, false); // 设置位图视图的缩放比率 refreshImage(false); // 刷新图像展示 } // 在图片旋转时触发 @Override public void onImageRotate(int degree) { bv_content.setRotateDegree(degree, false); // 设置位图视图的旋转角度 refreshImage(false); // 刷新图像展示 } // 在图片点击时触发 @Override public void onImageClick() {} // 在图片长按时触发 @Override public void onImageLongClick() {} // 在创建选项菜单时调用 @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.menu_meitu, menu); return true; } // 在选中菜单项时调用 @Override public boolean onOptionsItemSelected(MenuItem item) { if (item.getItemId() == R.id.menu_file_open) { // 点击了“打开文件” // 创建一个内容获取动作的意图(准备跳到系统相册) Intent albumIntent = new Intent(Intent.ACTION_GET_CONTENT); albumIntent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, false); // 是否允许多选 albumIntent.setType("image/*"); // 类型为图像 startActivityForResult(albumIntent, CHOOSE_CODE); // 打开系统相册 } else if (item.getItemId() == R.id.menu_file_save) { // 点击了“保存文件” Bitmap bitmap = mv_content.getCropBitmap(); // 获取美图视图处理后的位图 // 生成图片文件的保存路径 String path = String.format("%s/%s.jpg", getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS).toString(), DateUtil.getNowDateTime()); BitmapUtil.saveImage(path, bitmap); // 把位图保存为图片文件 BitmapUtil.notifyPhotoAlbum(this, path); // 通知相册来了张新图片 Toast.makeText(this, "已保存抠好的图片 "+path, Toast.LENGTH_SHORT).show(); } return super.onOptionsItemSelected(item); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent intent) { super.onActivityResult(requestCode, resultCode, intent); if (resultCode == RESULT_OK && requestCode == CHOOSE_CODE) { // 从相册返回 if (intent.getData() != null) { // 从相册选择一张照片 Uri uri = intent.getData(); // 获得已选择照片的路径对象 // 根据指定图片的uri,获得自动缩小后的位图对象 Bitmap bitmap = BitmapUtil.getAutoZoomImage(this, uri); bv_content.setImageBitmap(bitmap); // 设置位图视图的位图对象 refreshImage(true); // 刷新图像展示 tv_hint.setVisibility(View.GONE); } } } }
XML文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <androidx.appcompat.widget.Toolbar android:id="@+id/tl_head" android:layout_width="match_parent" android:layout_height="50dp" android:background="@color/blue_light" app:navigationIcon="@drawable/icon_back" /> <RelativeLayout android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1"> <com.example.event.widget.BitmapView android:id="@+id/bv_content" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/white" android:scaleType="centerCrop" /> <com.example.event.widget.MeituView android:id="@+id/mv_content" android:layout_width="match_parent" android:layout_height="match_parent" /> <TextView android:id="@+id/tv_hint" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="请点击右上角的三点图标,先打开图片文件,再开始抠图操作" android:textColor="@color/black" android:textSize="17sp" /> </RelativeLayout> </LinearLayout>
创作不易 觉得有帮助请点赞关注收藏~~~