《Android开发卷——设置圆形头像,Android截取圆形图片》
在有一些程序开发中,有时候会用到圆形,截取一张图片的一部分圆形,作为头像或者其他.
本实例就是截图圆形,设置头像的.
首先讲解一些代码
<ImageView android:id="@+id/screenshot_img"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="matrix"/>
图片属性要设置成android:scaleType="matrix",这样图片才可以通过触摸,放大缩小.
主类功能:点击按钮选择图片或者拍照
public class MainActivity extends Activity { private Button btnImg; /**
* 表示选择的是相机--0
*/
private final int IMAGE_CAPTURE = 0;
/**
* 表示选择的是相册--1
*/
private final int IMAGE_MEDIA = 1; /**
* 图片保存SD卡位置
*/
private final static String IMG_PATH = Environment
.getExternalStorageDirectory() + "/chillax/imgs/"; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); btnImg = (Button)findViewById(R.id.btn_find_img);
btnImg.setOnClickListener(BtnClick);
} OnClickListener BtnClick = new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
setImage();
}
}; /**
* 选择图片
*/
public void setImage() {
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("选择图片");
builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {}
});
builder.setPositiveButton("相机", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
startActivityForResult(intent, IMAGE_CAPTURE);
}
});
builder.setNeutralButton("相册", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("image/*");
startActivityForResult(intent, IMAGE_MEDIA);
}
});
AlertDialog alert = builder.create();
alert.show();
} /**
* 根据用户选择,返回图片资源
*/
public void onActivityResult(int requestCode, int resultCode, Intent data) { ContentResolver resolver = this.getContentResolver(); BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 2;// 图片高宽度都为本来的二分之一,即图片大小为本来的大小的四分之一
options.inTempStorage = new byte[5 * 1024]; if (data != null){
if (requestCode == IMAGE_MEDIA){
try {
if(data.getData() == null){
}else{ // 获得图片的uri
Uri uri = data.getData(); // 将字节数组转换为ImageView可调用的Bitmap对象
Bitmap bitmap = BitmapFactory.decodeStream(
resolver.openInputStream(uri), null,options); //图片路径
String imgPath = IMG_PATH+"Test.png"; //保存图片
saveFile(bitmap, imgPath); Intent i = new Intent(MainActivity.this,ScreenshotImg.class);
i.putExtra("ImgPath", imgPath);
this.startActivity(i); }
} catch (Exception e) {
System.out.println(e.getMessage());
} }else if(requestCode == IMAGE_CAPTURE) {// 相机
if (data != null) {
if(data.getExtras() == null){
}else{ // 相机返回的图片数据
Bitmap bitmap = (Bitmap) data.getExtras().get("data"); //图片路径
String imgPath = IMG_PATH+"Test.png"; //保存图片
saveFile(bitmap, imgPath); Intent i = new Intent(MainActivity.this,ScreenshotImg.class);
i.putExtra("ImgPath", imgPath);
this.startActivity(i);
}
}
}
}
} /**
* 保存图片到app指定路径
* @param bm头像图片资源
* @param fileName保存名称
*/
public static void saveFile(Bitmap bm, String filePath) {
try {
String Path = filePath.substring(0, filePath.lastIndexOf("/"));
File dirFile = new File(Path);
if (!dirFile.exists()) {
dirFile.mkdirs();
}
File myCaptureFile = new File(filePath);
BufferedOutputStream bo = null;
bo = new BufferedOutputStream(new FileOutputStream(myCaptureFile));
bm.compress(Bitmap.CompressFormat.PNG, 100, bo); bo.flush();
bo.close(); } catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
} @Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
} }
注意:有时候要对图片进行压缩,不然在程序中很容易就造成内存溢出.
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 2;// 图片高宽度都为本来的二分之一
options.inTempStorage = new byte[5 * 1024];
// 获得图片的uri
Uri uri = data.getData();
// 将字节数组转换为ImageView可调用的Bitmap对象
Bitmap bitmap = BitmapFactory.decodeStream(resolver.openInputStream(uri), null,options);
图片缩放,截图类:
public class ScreenshotImg extends Activity { private LinearLayout imgSave;
private ImageView imgView,imgScreenshot;
private String imgPath; private static final int NONE = 0;
private static final int DRAG = 1;
private static final int ZOOM = 2; private int mode = NONE;
private float oldDist;
private Matrix matrix = new Matrix();
private Matrix savedMatrix = new Matrix();
private PointF start = new PointF();
private PointF mid = new PointF(); @Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
this.setContentView(R.layout.img_screenshot); imgView = (ImageView)findViewById(R.id.screenshot_img);
imgScreenshot = (ImageView)findViewById(R.id.screenshot);
imgSave = (LinearLayout)findViewById(R.id.img_save); Intent i = getIntent();
imgPath = i.getStringExtra("ImgPath"); Bitmap bitmap = getImgSource(imgPath); if(bitmap!=null){
imgView.setImageBitmap(bitmap);
imgView.setOnTouchListener(touch);
imgSave.setOnClickListener(imgClick);
} } OnClickListener imgClick = new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
imgView.setDrawingCacheEnabled(true);
Bitmap bitmap = Bitmap.createBitmap(imgView.getDrawingCache()); int w = imgScreenshot.getWidth();
int h = imgScreenshot.getHeight(); int left = imgScreenshot.getLeft();
int right = imgScreenshot.getRight();
int top = imgScreenshot.getTop();
int bottom = imgScreenshot.getBottom(); Bitmap targetBitmap = Bitmap.createBitmap(w,h,Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(targetBitmap);
Path path = new Path(); path.addCircle((float)((right-left) / 2),((float)((bottom-top)) / 2), (float)(w / 2),
Path.Direction.CCW); canvas.clipPath(path); canvas.drawBitmap(bitmap,new Rect(left,top,right,bottom),new Rect(left,top,right,bottom),null); MainActivity.saveFile(targetBitmap, imgPath); Toast.makeText(getBaseContext(), "保存成功", Toast.LENGTH_LONG).show(); finish();
}
}; /**
* 触摸事件
*/
OnTouchListener touch = new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
ImageView view = (ImageView) v;
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
savedMatrix.set(matrix); // 把原始 Matrix对象保存起来
start.set(event.getX(), event.getY()); // 设置x,y坐标
mode = DRAG;
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_POINTER_UP:
mode = NONE;
break;
case MotionEvent.ACTION_POINTER_DOWN:
oldDist = spacing(event);
if (oldDist > 10f) {
savedMatrix.set(matrix);
midPoint(mid, event); // 求出手指两点的中点
mode = ZOOM;
}
break;
case MotionEvent.ACTION_MOVE:
if (mode == DRAG) {
matrix.set(savedMatrix); matrix.postTranslate(event.getX() - start.x, event.getY()
- start.y);
} else if (mode == ZOOM) {
float newDist = spacing(event);
if (newDist > 10f) {
matrix.set(savedMatrix);
float scale = newDist / oldDist;
matrix.postScale(scale, scale, mid.x, mid.y);
}
}
break;
}
System.out.println(event.getAction());
view.setImageMatrix(matrix);
return true;
}
}; //求两点距离
private float spacing(MotionEvent event) {
float x = event.getX(0) - event.getX(1);
float y = event.getY(0) - event.getY(1);
return FloatMath.sqrt(x * x + y * y);
} //求两点间中点
private void midPoint(PointF point, MotionEvent event) {
float x = event.getX(0) + event.getX(1);
float y = event.getY(0) + event.getY(1);
point.set(x / 2, y / 2);
} /**
* 從指定路徑讀取圖片資源
*/
public Bitmap getImgSource(String pathString) { Bitmap bitmap = null;
BitmapFactory.Options opts = new BitmapFactory.Options();
// opts.inSampleSize = 2; try {
File file = new File(pathString);
if (file.exists()) {
bitmap = BitmapFactory.decodeFile(pathString, opts);
}
if (bitmap == null) {
return null;
} else {
return bitmap;
}
} catch (Exception e) {
e.printStackTrace();
return null;
}
} }
截图关键语句:
Bitmap targetBitmap = Bitmap.createBitmap(w,h,Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(targetBitmap);
Path path = new Path();
path.addCircle((float)((right-left) / 2),((float)((bottom-top)) / 2), (float)(w / 2),
Path.Direction.CCW); //绘制圆形
canvas.clipPath(path);
canvas.drawBitmap(bitmap,new Rect(left,top,right,bottom),new Rect(left,top,right,bottom),null); //截图
项目源码:http://download.csdn.net/detail/chillax_li/7120673
(有人说保存图片之后,没打开图片.这是因为我没打开它,要看效果的话,要自己用图库打开,就能看到效果了.这里说明一下)
尊重原创,转载请注明出处:http://blog.csdn.net/chillax_li/article/details/22591681
《Android开发卷——设置圆形头像,Android截取圆形图片》的更多相关文章
- 简单物联网:外网访问内网路由器下树莓派Flask服务器
最近做一个小东西,大概过程就是想在教室,宿舍控制实验室的一些设备. 已经在树莓上搭了一个轻量的flask服务器,在实验室的路由器下,任何设备都是可以访问的:但是有一些限制条件,比如我想在宿舍控制我种花 ...
- 利用ssh反向代理以及autossh实现从外网连接内网服务器
前言 最近遇到这样一个问题,我在实验室架设了一台服务器,给师弟或者小伙伴练习Linux用,然后平时在实验室这边直接连接是没有问题的,都是内网嘛.但是回到宿舍问题出来了,使用校园网的童鞋还是能连接上,使 ...
- 外网访问内网Docker容器
外网访问内网Docker容器 本地安装了Docker容器,只能在局域网内访问,怎样从外网也能访问本地Docker容器? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Docker容器 ...
- 外网访问内网SpringBoot
外网访问内网SpringBoot 本地安装了SpringBoot,只能在局域网内访问,怎样从外网也能访问本地SpringBoot? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装Java 1 ...
- 外网访问内网Elasticsearch WEB
外网访问内网Elasticsearch WEB 本地安装了Elasticsearch,只能在局域网内访问其WEB,怎样从外网也能访问本地Elasticsearch? 本文将介绍具体的实现步骤. 1. ...
- 怎样从外网访问内网Rails
外网访问内网Rails 本地安装了Rails,只能在局域网内访问,怎样从外网也能访问本地Rails? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Rails 默认安装的Rails端口 ...
- 怎样从外网访问内网Memcached数据库
外网访问内网Memcached数据库 本地安装了Memcached数据库,只能在局域网内访问,怎样从外网也能访问本地Memcached数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装 ...
- 怎样从外网访问内网CouchDB数据库
外网访问内网CouchDB数据库 本地安装了CouchDB数据库,只能在局域网内访问,怎样从外网也能访问本地CouchDB数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Cou ...
- 怎样从外网访问内网DB2数据库
外网访问内网DB2数据库 本地安装了DB2数据库,只能在局域网内访问,怎样从外网也能访问本地DB2数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动DB2数据库 默认安装的DB2 ...
- 怎样从外网访问内网OpenLDAP数据库
外网访问内网OpenLDAP数据库 本地安装了OpenLDAP数据库,只能在局域网内访问,怎样从外网也能访问本地OpenLDAP数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动 ...
随机推荐
- PolarDB-X 全局Binlog解读之性能篇(上)
简介: 本篇来介绍一下PolarDB-X全局binlog在性能方面的一些设计和思考,先通过几个实际的测试案例来展示全局binlog的性能情况,然后结合这些案例来深入讲解全局binlog关于优化的故事. ...
- 阿里巴巴云原生 etcd 服务集群管控优化实践
简介: 这些年,阿里云原生 etcd 服务发生了翻天覆地的变化,这篇文章主要分享一下 etcd 服务在面对业务量大规模增长下遇到的问题以及我们是如何解决的,希望对读者了解 etcd 的使用和管控运维提 ...
- Apsara Stack 技术百科 | 标准化的云时代:一云多芯
简介:随着今年云栖大会现场平头哥的自研云芯片倚天710发布,以及众多新兴厂商的芯片发布,将有越来越多的类型芯片进入到主流市场,"多芯"的架构将在数据中心中越来越常见,阿里云混合云 ...
- 带你体验云原生场景下 Serverless 应用编程模型
简介: 阿里云 Knative 基于 ASK 之上,在完全兼容社区 Knaitve 的同时对 FC.ECI 工作负载进行统一应用编排,支持事件驱动.自动弹性,为您提供统一的 Serverless 应 ...
- vue中使用vue-b2wordcloud创建词云
安装使用 安装:使用npm install vue-b2wordcloud --save或者直接在vue ui中添加vue-b2wordcloud运行依赖 使用:在main.js中导入使用 impor ...
- 05.Java 方法详解
1.方法的定义及调用 设计方法的原则:一个方法只完成一个功能,有利于后期的扩展 方法的定义: 修饰符(可选) 返回值类型 方法名(参数类型 参数名(可选)){ 方法体 return 返回值; } 2. ...
- ETSI GS MEC 012,无线网络信息服务 API
目录 文章目录 目录 版本 功能理解 版本 ETSI GS MEC 012 V2.1.1 (2019-12) 功能理解 RNIS(Radio Network Information Service,无 ...
- EDP .Net开发框架--业务模型
平台下载地址:https://gitee.com/alwaysinsist/edp 业务模型概述 业务模型管理中所涉及的业务模型,业务模型的属性,业务模型的视图都是可以通过权限设置来实现数据的行(视图 ...
- 保姆教程系列:Git 实用命令详解
!!!是的没错,胖友们,保姆教程系列又更新了!!! @ 目录 前言 1.将本地项目推送到远程仓库 2. Idea Git回退到某个历史版本 3. 修改项目关联远程地址方法 4. Git 修改分支的名称 ...
- ShardingJDBC使用不当引发的线上事故
本文讲述一个由 ShardingJDBC 使用不当引起的悲惨故事. 一. 问题重现 有一天运营反馈我们部分订单状态和第三方订单状态无法同步. 根据现象找到了不能同步订单状态是因为 order 表的 t ...