个人资料上传头像模块,拍照+图库+图片剪裁+圆形头像

先看效果图:

注意: 因为模拟器的原因裁剪图片的页面只能拖拽,实际在手机上是可以放大旋转等操作的

实现思路:

1.三个自定义的view,分别是圆形的Imageview,可拖拽放大旋转的Imageview,裁剪图片的view(裁剪页面的矩形)

2.点击主界面的上传头像,开启一个透明的透明的Activity,在这个Activity中可以选择拍照或者是图库,不管选择哪种,将返回结果的图片路径传递到裁剪页面

3.裁剪页面:先将图片根据屏幕的比例等比例缩小加载成bitmap对象,设置给可拖拽放大旋转的Imageview,这个时候我们就可以对图片进行拖动放大等,最后我们将图片传递到MainActivity设置为头像,并上传至服务器

具体步骤:

1.先在MainActivity中,我们需要做三件事:点击后开启透明的选择获取图片方式的页面,注册广播接受者来接受最终处理好的图片,上传图片

                @Overridepublic void onReceive(Context context, Intent intent) {if ("account_active".equals(intent.getAction())) {byte[] bis = intent.getByteArrayExtra("bitmap");Bitmap bitmap = BitmapFactory.decodeByteArray(bis, 0,bis.length);// 将图片数组转换成图片iv_head_img.setImageBitmap(bitmap);//这个Imageview是圆形的Imageview// 在这里上传图片 上传的格式看你们公司的要求了// 如果要转换成数组上传就使用BitmapFactory将bitmap对象转换成数组再传// if(bitmap != null){// uploadImage(bitmap, BaseApplication.userBean.getUsername());// }else{// CustomToast.createToast().showFaild(AccountUpdateActivity.this,// "图片文件错误");// }}} 
注意:上传图片我们这边是将图片转换成base64位,进行上传的,注意用post请求

2.选择图片页面,我们需要做的是:选择图片的方式拍照或者是图库,获取到的图片进行判断,将图片的位置传递给裁剪页面

       第1种    选择拍照:

               // 执行拍照前,应该先判断SD卡是否存在String SDState = Environment.getExternalStorageState();if (SDState.equals(Environment.MEDIA_MOUNTED)) {// 如果内存卡已经挂载Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File(Environment.getExternalStorageDirectory(), "camera.jpg")));intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 0);startActivityForResult(intent, SELECT_PIC_BY_TAKE_PHOTO);} else {Toast.makeText(this, "内存卡不存在", Toast.LENGTH_SHORT).show();} 
             返回结果后将图片路径传递给剪裁界面:

                                try {Intent intent = new Intent(this, ClipPictureActivity.class);// 开启裁剪的界面intent.putExtra("picPath", "/sdcard/camera.jpg");intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK| Intent.FLAG_ACTIVITY_CLEAR_TOP);startActivity(intent);finish();} catch (Exception e) {e.printStackTrace();} 
        第2种     从图库获取图片路径

               // 选择照片的时候也一样,我们用Action为Intent.ACTION_GET_CONTENT,// 有些人使用其他的Action但我发现在有些机子中会出问题,所以优先选择这个Intent intent = new Intent();intent.setType("image/*");intent.setAction(Intent.ACTION_GET_CONTENT);startActivityForResult(intent, SELECT_PIC_BY_PICK_PHOTO);

           返回结果时,进行非空格式的判断等,并将图片路径传递给剪裁界面:
               	if (requestCode == SELECT_PIC_BY_PICK_PHOTO) {// 从相册取图片,有些手机有异常情况,请注意if (data == null) {Toast.makeText(this, "选择图片文件出错", Toast.LENGTH_LONG).show();return;}photoUri = data.getData();if (photoUri == null) {Toast.makeText(this, "选择图片文件出错", Toast.LENGTH_LONG).show();return;}}String[] pojo = { MediaStore.Images.Media.DATA };@SuppressWarnings("deprecation")Cursor cursor = managedQuery(photoUri, pojo, null, null, null);if (cursor != null) {int columnIndex = cursor.getColumnIndexOrThrow(pojo[0]);cursor.moveToFirst();picPath = cursor.getString(columnIndex);cursor.close();}if (picPath != null&& (picPath.endsWith(".png") || picPath.endsWith(".PNG")|| picPath.endsWith(".jpg") || picPath.endsWith(".JPG"))) {Intent intent = new Intent(this, ClipPictureActivity.class);intent.putExtra("picPath", picPath);intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK| Intent.FLAG_ACTIVITY_CLEAR_TOP);startActivity(intent);finish();} else {Toast.makeText(this, "选择图片文件不正确", Toast.LENGTH_SHORT).show();}
3.裁剪界面:为TouchImageview添加触摸事件的监听和添加全局view树的观察者,将裁剪的view添加进去,在触摸事件中对图片操作,保存图片并发广播通知MainActivity

   第一步     添加全局view树的观察者,将裁剪的view添加进去.可是为什么不直接将裁剪的view放在布局文件中?因为这个裁剪的view的大小是不确定的,我们需要根据图片的大小来设置剪裁view的大小!

    那为什么不在直接在onCreate中添加,而要在TouchImageview的全局view树的观察者中添加呢?因为在系统再调用onCreate方法时,并没有把布局文件中的每个view画出来,

                只是知道布局中有这么个东西,不信你可以试试,在onCreate方法中获取任何一个空间的宽和高试试,会是0.而我们在viewTree的观察者中的onGlobalLayout是在控件已经

                 全部画上去之后才调用,这个时候我们自然也会能获得每个空间的真实大小,而不是0

     

             ViewTreeObserver observer = srcPic.getViewTreeObserver();observer.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {@SuppressWarnings("deprecation")public void onGlobalLayout() {srcPic.getViewTreeObserver().removeGlobalOnLayoutListener(this);initClipView(srcPic.getTop());//添加裁剪的view}});

第二步  添加裁剪的view,并将图片按屏幕的比例显示出来           
        /*** 初始化截图区域,并将源图按裁剪框比例缩放* * @param top*/private void initClipView(int top) {bitmap = getBitmapByPath(url);//将原图压缩到原来的1/2clipview = new ClipView(ClipPictureActivity.this);clipview.setCustomTopBarHeight(top);clipview.addOnDrawCompleteListener(new OnDrawListenerComplete() {public void onDrawCompelete() {clipview.removeOnDrawCompleteListener();int clipHeight = clipview.getClipHeight();int clipWidth = clipview.getClipWidth();int midX = clipview.getClipLeftMargin() + (clipWidth / 2);int midY = clipview.getClipTopMargin() + (clipHeight / 2);int imageWidth = bitmap.getWidth();int imageHeight = bitmap.getHeight();// 按裁剪框求缩放比例float scale = (clipWidth * 1.0f) / imageWidth;if (imageWidth > imageHeight) {scale = (clipHeight * 1.0f) / imageHeight;}// 起始中心点float imageMidX = imageWidth * scale / 2;float imageMidY = clipview.getCustomTopBarHeight()+ imageHeight * scale / 2;srcPic.setScaleType(ScaleType.MATRIX);// 缩放matrix.postScale(scale, scale);// 平移matrix.postTranslate(midX - imageMidX, midY - imageMidY);srcPic.setImageMatrix(matrix);srcPic.setImageBitmap(bitmap);}});this.addContentView(clipview, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));} 
第三步  触摸事件 

     第一个手指按下默认是拖拽   第二个手机按下根据两个手指间的距离  如果大于10个像素  就认为是缩放  根据手机移动的距离将图片移动和缩放

    手指离开屏幕清除模式

  

        public boolean onTouch(View v, MotionEvent event) {ImageView view = (ImageView) v;switch (event.getAction() & MotionEvent.ACTION_MASK) {case MotionEvent.ACTION_DOWN:savedMatrix.set(matrix);// 设置开始点位置start.set(event.getX(), event.getY());mode = DRAG;break;case MotionEvent.ACTION_POINTER_DOWN://第二个手指按下oldDist = spacing(event);if (oldDist > 10f) {//缩放savedMatrix.set(matrix);midPoint(mid, event);mode = ZOOM;}break;case MotionEvent.ACTION_UP:case MotionEvent.ACTION_POINTER_UP:mode = NONE;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);//根据mid进行缩放}}break;}view.setImageMatrix(matrix);return true;}/*** 多点触控时,计算最先放下的两指距离* * @param event* @return*/private float spacing(MotionEvent event) {float x = event.getX(0) - event.getX(1);float y = event.getY(0) - event.getY(1);return (float) Math.sqrt(x * x + y * y);}/*** 多点触控时,计算最先放下的两指中心坐标* * @param point* @param event*/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);}
第四步  保存图片并将图片传递到MainActivity中
     
 	private void save() {Bitmap clipBitmap = getBitmap();ByteArrayOutputStream baos = new ByteArrayOutputStream();clipBitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);//将图片转换成数组byte[] bitmapByte = baos.toByteArray();Intent intent = new Intent("account_active");//发广播   将图片的数组传过去intent.putExtra("bitmap", bitmapByte);sendBroadcast(intent);finish();}/*** 获取裁剪框内截图* * @return*/private Bitmap getBitmap() {// 获取截屏View view = this.getWindow().getDecorView();view.setDrawingCacheEnabled(true);view.buildDrawingCache();// 获取状态栏高度Rect frame = new Rect();this.getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);int statusBarHeight = frame.top;Bitmap finalBitmap = Bitmap.createBitmap(view.getDrawingCache(),clipview.getClipLeftMargin(), clipview.getClipTopMargin()+ statusBarHeight, clipview.getClipWidth(),clipview.getClipHeight());// 释放资源view.destroyDrawingCache();return finalBitmap;} 

最后,点击这里获取源码









本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/49553.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vant 列表组件:App我的、个人中心(含头像、手机号、用户名、点击交互)

案例截图&#xff1a; <template> <div class"app-container"><!-- 导类栏 --><van-nav-bartitle"我的"left-arrowclick-left"$router.back()"/><!-- 我的 --><div class"wii-user-head"><!--…

Android开发之用户头像上传

一&#xff0c;概述 本篇博客总结一下自己在开发过程中应用到的一些知识&#xff0c;在本篇博客中带领大家完成用户头像选择或者拍照上传&#xff0c;并对图片进行大小的压缩&#xff0c;和形状的控制&#xff0c;可以将用户选择到的图片裁剪成圆形上传。 ok&#xff0c;我们开…

X站全称是什么_考不上高中上什么专业

商洛考不上高中上什么好处 高职和大专区别是什么&#xff1f;高职不如大专吗&#xff1f;高职毕业是否可以续读本科&#xff1f;高职毕业只能做工人吗&#xff1f;高职和大专的主要区别在分为学习内容上的不同以及表达内容等方面的不同&#xff0c;但是本质上并没有区别&#x…

一文搞清到底什么是 .NET?

现在各种 .NET 满天飞&#xff0c;别说新手了&#xff0c;连我这样的老手都差点被绕进去。到底什么是 .NET 呢&#xff1f;《通俗易懂&#xff0c;什么是.NET?什么是.NET Framework&#xff1f;什么是.NET Core? 》这篇文章好长呀&#xff0c;不知道你看完了没有&#xff0c;…

中台,都他妈被你们说糊涂了,文内才是正宗解释,别摸石头过河了,石头早就有了...

&#xff08;1&#xff09;我们先说说技术架构分层 我们按技术架构通常是这样的&#xff1a; 1、UI交互层&#xff1a;Windows UI、PC Web UI、移动App UI、微信小程序UI、摄像头视觉识别人机界面、语音交互人机界面 2、逻辑层&#xff1a;面向对象技术/组件技术/SOA服务中间件…

Vue与React不是真正的响应式编程,Svelte才是正宗

这个题目可能有点夸张&#xff0c;但不管怎样 Svelte 和它的理念就是这样的。如果你还没听说过 Svelte 的话就去了解一下吧——你会见证一场革命的&#xff0c;它将取得空前的成就&#xff08;没有给 Svelte 团队增加压力的意思&#xff09;。 本文不是 Svelte 的入门教程。Sv…

mysql是怎样运行的 从根儿 百度云_读书笔记-MySQL 是怎样运行的:从根儿上理解 MySQL...

mysqld_safe mysqld_safe是一个启动脚本&#xff0c;它会间接的调用mysqld&#xff0c;而且还顺便启动了另外一个监控进程&#xff0c;这个监控进程在服务器进程挂了的时候&#xff0c;可以帮助重启 它。另外&#xff0c;使用mysqld_safe启动服务器程序时&#xff0c;它会将服务…

MariaDB: 谁是更为正宗的MYSQL

随着Oracle买下Sun&#xff0c;MySQL也落入了关系型数据库王者之手。而早在2009年&#xff0c;考虑到Oracle的名声以及其入手之后闭源的可能性&#xff0c;MySQL之父的Michael便先行一步&#xff0c;以他女儿Maria的名字开始了MySQL的另外一个衍生版本&#xff1a;MariaDB。 Mi…

区块链入门教程

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 区块链&#xff08;blockchain&#xff09;是眼下的大热门&#xff0c;新闻媒体大量报道&#xff0c;宣称它将创造未来。 可是&#xf…

真的会谢,ChatGpt能不能靠谱点

我想让GPT帮我生成一个可以实现一根绳子抖动的效果。 一直沟通&#xff1a; 然后它给我生成了一段还是达不到效果的代码&#xff0c;并且代码还不全&#xff01; 本来我想要这种&#xff1a;TweenMax结合elastic-progress的弹性进度条动画 但是ChatGPT给我的代码最后效果是&a…

本科计算机论文致谢词,有关本科毕业的论文致谢词范文

有关本科毕业的论文致谢词范文 本科毕业论文致谢范例一 时间如梭,转眼毕业在即。回想在大学求学的四年,心中充满无限感激和留恋之情。感谢母校为我们提供的良好学习环境,使我们能够在此专心学习,陶冶情操。谨向我的论文指导老师王副教授致以最诚挚的谢意!王老师不仅在学业上…

计算机专业毕业设计致谢,那些笑哭的毕业论文致谢

原标题&#xff1a;那些笑哭的毕业论文致谢 相比正文的废话连篇&#xff0c;冗长乏味&#xff0c;致谢完全可以成为论文的弹幕&#xff0c;专供吐槽。咱们的致谢不用非得把七大姑、八大姨都拉出来感谢一番&#xff0c;像下面这些言语上既诙谐又大胆的致谢言辞&#xff0c;小编就…

html实训报告致谢,毕业论文致谢信(精选10篇)

毕业论文致谢信(精选10篇) 大学生活将要谢下帷幕,我们都知道毕业前要通过毕业论文,毕业论文是一种有准备、有计划的检验大学学习成果的形式,那么优秀的毕业论文是什么样的呢?下面是小编为大家收集的毕业论文致谢信(精选10篇),供大家参考借鉴,希望可以帮助到有需要的朋友。…

html项目的致谢词,毕业论文致谢词范文200字(精选10篇)

毕业论文致谢词范文200字(精选10篇) 导语:大学三年学习时光已经接近尾声,在此我想对我的母校,我的父母、亲人们,我的老师和同学们表达我由衷的谢意。下面是小编整理的毕业论文致谢词范文200字,欢迎参考借鉴! 毕业论文致谢词1 首先感谢学校为作者提供了深造的机会,在四年…

中科院博士论文致谢感人,如果让AI来写又会是怎样

今天&#xff0c;达摩院发布全球最大规模的 中文文本预训练语言模型——PLUG PLUG的参数规模达270亿 它集语言理解与生成能力于一身 在小说创作、诗歌生成、 智能问答等领域表现突出 还以80.614分刷新了CLUE分类榜单纪录 排名仅次于“人类”组 今天阿云也挑了几部经典作品…

matlab论文致谢,2020大学毕业论文致谢信

2020大学毕业论文致谢信 论文致谢词的作用主要是为了表示尊重所有合作者的劳动&#xff0c;它有利于促进形成相互帮助的社会风气。下面是小编为大家精心准备的2020大学毕业论文致谢信&#xff0c;仅供大家参考阅读&#xff01; 2020大学毕业论文致谢信1 我选择了周老师的课题&a…

计算机专业毕业设计致谢,计算机毕业论文致谢范文3篇

计算机毕业论文致谢范文3篇 计算机是20世纪最先进的科学技术发明之一&#xff0c;对人类的生产活动和社会活动产生了极其重要的影响并以强大的生命力飞速发展它的应用领域从最初的军事科研应用扩展到社会的各个领域&#xff0c;已形成了规模巨大的计算机产业带动了全球范围的技…

毕业论文致谢到底要怎么写?

毕业论文论文的致谢怎么写&#xff1f; 这里的标题只是个问句&#xff0c;以下的文字并不会给出答案&#xff0c;毕竟&#xff0c;毕业论文的致谢是最难写的一部分。依我看来&#xff0c;毕业论文致谢&#xff0c;大抵分为两种&#xff0c;一种是中规中矩型&#xff0c;列一堆人…

计算机毕业论文致谢,计算机软件毕业论文致谢词

计算机软件毕业论文致谢词 致谢应以简短的文字对课题研究与论文撰写过程中间直接给予帮助的人员表示自己的谢意,这不仅是一种礼貌,也是对他人劳动的尊重,下面是小编搜集整理的计算机软件毕业论文致谢词,供大家阅读查看。 致谢一: 时间飞逝,大学的学习生活很快就要过去,在…

计算机科学与技术的论文致谢,毕业论文致谢200字(精选7篇)

毕业论文致谢200字(精选7篇) 充实的大学生活即将结束,同学们毕业前都要通过最后的毕业论文,毕业论文是一种比较重要的检验大学学习成果的形式,如何把毕业论文做到重点突出呢?以下是小编整理的毕业论文致谢200字(精选7篇),欢迎大家借鉴与参考,希望对大家有所帮助。 毕业论…