效果图
程序的逻辑就是我们点击按钮就调用系统相册,然后再我们选择了相应的图片后,我们调用系统的裁剪图片的功能来进行图片的裁剪,再然后我们将裁剪后的图片获得,然后对其进行设置显示的样式,最后以圆形显示出来就好了。
这种功能在我们很多程序中都有见到,最多的就是让我们设置用户的头像的时候,选择本地图片来设置。那我们来看看程序的代码实现吧。
布局就简单的一个按钮和一个ImageView,这里就不再贴出来了。
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
private Button button;
private ImageView imageView;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
}
private void init() {
button= (Button) findViewById(R.id.button);
imageView= (ImageView) findViewById(R.id.imageView);
button.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.button:
Intent intent=new Intent();
//获取文件的类型,image/*表示就是图片
intent.setType("image/*");
//下面是打开系统相册的Action
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(intent,1);
break;
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode!=RESULT_CANCELED){
switch (requestCode){
case 1:
//从相册中选取的图片的uri保存在data中
startPhotoZoom(data.getData());
break;
case 2:
//截取完的图片数据存放在类型为intent的data中
viewToImage(data);
}
}
}
private void viewToImage(Intent data) {
//姐去玩的图片数据存放在类型为intent的data中
Bundle bundle=data.getExtras();
if (bundle!=null){
Bitmap bitmap=bundle.getParcelable("data");
Bitmap bitmap_bg=Bitmap.createBitmap(bitmap.getWidth(),bitmap.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas=new Canvas(bitmap_bg);
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setColor(Color.GREEN);
//这里使用了绘图的模式的功能,在上一篇博客有讲,PorterDuff.Mode.SRC_IN表示两个图层显示重合部分上面图层的内容
canvas.drawOval(new RectF(0,0,bitmap.getWidth(),bitmap.getHeight()),paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
canvas.drawBitmap(bitmap,0,0,paint);
imageView.setImageBitmap(bitmap_bg);
}else {
Toast.makeText(MainActivity.this, "数据为空", Toast.LENGTH_SHORT).show();
}
}
private void startPhotoZoom(Uri uri) {
//这是进行系统裁剪功能的Action
Intent intent=new Intent("com.android.camera.action.CROP");
intent.setDataAndType(uri,"image/*");
//设置裁剪
intent.putExtra("crop","true");
//设置裁剪宽高的比例
intent.putExtra("aspectX",1);
intent.putExtra("aspectY",1);
//自由截取的方法,默认就是自由截图
// intent.putExtra("scale",true);
//设置图片的输出尺寸
intent.putExtra("outputX", 320);
intent.putExtra("outputY", 320);
//将截取的图片返回回来,如果不屑、写这句话,默认将截取的图片保存到源目录
intent.putExtra("return-data", true);
startActivityForResult(intent,2);
}
}
请注意这里的代码
canvas.drawOval(new RectF(0,0,bitmap.getWidth(),bitmap.getHeight()),paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
canvas.drawBitmap(bitmap,0,0,paint);
- 可以看到这里我是先绘制的一个圆形,在绘制的图片的bitmap,这里的顺序只能这样绘制,具体原因我也没搞清,如果先画bitmap在画原型,那么PorterDuff.Mode.SRC_IN的设置就不会有效果,不知道为什么。
- 还有一种方式就是我不绘制图形,我再创建一个bitmap和图像bitmap绘制在一起,这样就不需要分顺序了,怎么绘制都可以得到圆形的图片内容。
- 研究好久也没搞懂,不知道是我代码的问题还是其他,如果哪位博友知道的话,还请指正,十分感谢。