转载请注明出处http://blog.csdn.net/u014163726/article/details/44994197


       这么长时间没写博客感觉手都要生了啊,最近因为工作的关系来到了上海,目前还算稳定,所以抓紧时间写篇博客压压惊。

     标题早已经看穿一切,这次我们来模仿一下qq上传头像的功能,先上一个未完成版的效果图,银魂第四季重开放上一张萌萌哒的图片。


         这还是要用到我们自定义View的知识,首先从相册中获取图片的部分我就不详细介绍了。

/*** 获得图片*/protected void onActivityResult(int requestCode, int resultCode, Intent data) {if (requestCode == CHOOSE_BIG_PICTURE) {photoBitmap = null;photoViewBitmap = null;try {Uri originalUri = data.getData();int angle = getExifOrientation(getRealPathFromURI(originalUri));if (angle != 0) { // 如果照片出现了 旋转 那么 就更改旋转度数Matrix matrix = new Matrix();matrix.postRotate(angle);photoBitmap = getBitmapFromUri(photoBitmap, originalUri);photoViewBitmap = Bitmap.createBitmap(photoBitmap, 0, 0,photoBitmap.getWidth(), photoBitmap.getHeight(),matrix, true);clipView.setBitmap(photoViewBitmap);} else {clipView.setBitmap(getBitmapFromUri(photoBitmap,originalUri));}photoBitmap.recycle();photoViewBitmap.recycle();} catch (Exception e) {System.out.println(e.getMessage());}}}
我当时用的是三星的Note3测试发现获取的图片会发生旋转十分的坑爹。。所以我们还需要根据uri拿到路径然后再判断图片是否旋转。
   /*** 根据Uri获得bitmap* * @param bitmap* @param uri* @return*/private Bitmap getBitmapFromUri(Bitmap bitmap, Uri uri) {try {bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), uri);return bitmap;} catch (Exception e) {Log.d("TAG", e.getLocalizedMessage());return null;}}/*** 获得系统相册图片*/private void getAlbum() {Intent intent = new Intent(Intent.ACTION_PICK);intent.setType("image/*");// 相片类型startActivityForResult(intent, CHOOSE_BIG_PICTURE);}/*** 旋转图片* * @param filepath* @return*/private int getExifOrientation(String filepath) {int degree = 0;ExifInterface exif = null;try {exif = new ExifInterface(filepath);} catch (IOException ex) {}if (exif != null) {int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, -1);if (orientation != -1) {switch (orientation) {case ExifInterface.ORIENTATION_ROTATE_90:degree = 90;break;case ExifInterface.ORIENTATION_ROTATE_180:degree = 180;break;case ExifInterface.ORIENTATION_ROTATE_270:degree = 270;break;}}}return degree;}/*** 根据Uri拿到路径* * @param contentUri* @return*/public String getRealPathFromURI(Uri contentUri) {String res = null;String[] proj = { MediaStore.Images.Media.DATA };Cursor cursor = getContentResolver().query(contentUri, proj, null,null, null);if (cursor.moveToFirst()) {int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);res = cursor.getString(column_index);}cursor.close();return res;}

拿到图片之后就进入我们的自定义view环节啦。

public class ClipView extends View {/*** 画笔*/private Paint paint;/*** 图片*/private Bitmap mBitmap;/*** 画布*/private Canvas mCanvas;/*** 蒙版*/private Bitmap bitmap;/*** 起点坐标*/private int startX, startY;/*** 移动距离*/private int distanceX, distanceY;/*** 图片坐标*/private int widthX, heightY;int x = 0, y = 0;public ClipView(Context context) {super(context);init();// TODO Auto-generated constructor stub}public ClipView(Context context, AttributeSet attrs) {super(context, attrs);init();}public ClipView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);init();}

我们默认把传进来的图片缩放至600,800这样不会让图片过大也不会过小。

/*** 缩放图片* * @param bgimage* @param newWidth* @param newHeight* @return*/private Bitmap zoomImage(Bitmap bgimage, double newWidth, double newHeight) {// 获取这个图片的宽和高float width = bgimage.getWidth();float height = bgimage.getHeight();// 创建操作图片用的matrix对象Matrix matrix = new Matrix();// 计算宽高缩放率float scaleWidth = ((float) newWidth) / width;float scaleHeight = ((float) newHeight) / height;// 缩放图片动作matrix.postScale(scaleWidth, scaleHeight);Bitmap bitmap = Bitmap.createBitmap(bgimage, 0, 0, (int) width,(int) height, matrix, true);return bitmap;}/*** 拿到图片首先进行缩放* * @param bitmap*/public void setBitmap(Bitmap bitmap) {this.mBitmap = zoomImage(bitmap, 600, 800);startX = -(600 / 2);startY = -(800 / 2);widthX = startX;heightY = startY;postInvalidate();}

做到这一步的时候我们再来看看效果

可以看到我们光有了图片还是远远不够滴,我们还需要一个圆以及一个蒙版效果,那么问题就来了,这个蒙版效果是怎么做的呢,再上一张图,图片来自网络
看到这张图我们要知道先绘制的是黄色的后绘制的是蓝色的,那么我们蒙版的效果要用哪种来实现呢。
我选择用DstOut,这种模式取得是非交集下层部分。理清了思路,接下来我们就继续写代码吧。
private void init() {// 创建空白画布bitmap = Bitmap.createBitmap(600, 800, Config.ARGB_8888);mCanvas = new Canvas(bitmap);paint = new Paint();paint.setStyle(Style.FILL);paint.setStrokeWidth(2);paint.setAntiAlias(true);}@Overrideprotected void onDraw(Canvas canvas) {canvas.translate(getWidth() / 2, getHeight() / 2);if (mBitmap != null) {restartCanvas();canvas.drawBitmap(mBitmap, widthX, heightY, null);mCanvas.drawCircle(-widthX, -heightY, 200, paint);canvas.drawBitmap(bitmap, widthX, heightY, null);}}

我们再onDraw中绘制了我们的背景图片以及蒙版效果再加一个半径为200的圆,接下来做的就是不断的改变背景位置来完成移动的效果,每次移动之前要先clear掉上次的画布。

  private void restartCanvas() {// 清空上一次的绘图状态paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));mCanvas.drawPaint(paint);paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));mCanvas.drawColor(getResources().getColor(R.color.bg));}

要记清楚DSTOUT的效果哦!

/*** 移动x位置*/private void getWidthX() {widthX = startX - distanceX;if (widthX > -200) {widthX = -200;distanceX = -100;} else if (widthX < -400) {widthX = -400;distanceX = 100;}}/*** 移动y位置*/private void getHeightY() {heightY = startY - distanceY;if (heightY > -200) {heightY = -200;distanceY = -100;} else if (heightY < -600) {heightY = -600;distanceY = 100;}}@Overridepublic boolean onTouchEvent(MotionEvent event) {switch (event.getAction()) {case MotionEvent.ACTION_DOWN:x = (int) event.getX();y = (int) event.getY();break;case MotionEvent.ACTION_MOVE:distanceX = x - (int) (event.getX());distanceY = y - (int) (event.getY());getWidthX();getHeightY();break;case MotionEvent.ACTION_UP:startX = widthX;startY = heightY;break;default:break;}postInvalidate();return true;}

今天这部分的代码就到这里了,可以看到目前我们还欠缺的是随手势放大背景图片,以及最后的剪切!这就留到下一次吧。。。

项目源码

Android 仿qq上传头像(一)相关推荐

  1. android 模仿qq 上传头像,Android 仿qq上传头像(一)

    转载请注明出处http://blog.csdn.net/u014163726/article/details/44994197 这么长时间没写博客感觉手都要生了啊,最近因为工作的关系来到了上海,目前还 ...

  2. 高仿微信上传头像附带压缩,旋转图片,附加demo

    本人初学者,再做项目时要求上传头像要像微信那种,需要外面裁剪框不动,里面图片可以改变大小,android系统裁剪和所要求的完全相反,所以,对于这个问题,困扰了我将近一个月,不断的修改,不断的出现新问题 ...

  3. Android 仿QQ讨论组头像

    一.效果图 二.实现 基本实现过程: 1.将原图片读取为bitmap 2.在Canvas画布上计算出图片位置,并绘制新的图片. (ps:计算位置对我来说是难点,花了好长时间): 三.源码 1.布局文件 ...

  4. android mysql上传头像,Android自定义控件仿QQ编辑和选取圆形头像

    android大家都有很多需要用户上传头像的需求,有的是选方形,有的是圆角矩形,有的是圆形. 首先我们要做一个处理图片的自定义控件,把传入的图片,经过用户选择区域,处理成一定的形状. 有的app是通过 ...

  5. android 仿QQ,微信群组里的@功能,支持@多人,并能一键删除,能获取上传对应的id(修改版)

    首先注明该文章是借签别人的博客,原文博文地址点击打开链接 android 仿QQ,微信群组里的@功能,支持@多人,并能一键删除,能获取上传对应的id 这个需求来源:本人做集成环信聊天时,项目需要@功能 ...

  6. android 仿qq修改头像,Qt:小项目仿QQ修改头像界面,技术点记录

    最近写了一个修改头像功能的UI,布局参考了QQ目前的修改头像界面.如下图 这里主要说明一下两个地方的技术:1.头像图片上层的遮罩层,圆形外部为灰色,内部为全透明:2.上传图片宽高比例可以通过鼠标拖拽移 ...

  7. Android kotlin上传头像实现

    Android 上传头像基本上是每个app都有的功能,虽然看起来简单,但是作为新手的我实现起来却没有那么简单,实现如下 从相册获取照片,代码如下 //从相册获取照片private fun getFro ...

  8. android人脸识显示头像自定义,Android 仿QQ头像自定义截取功能

    看了Android版QQ的自定义头像功能,决定自己实现,随便熟悉下android绘制和图片处理这一块的知识. 先看看效果: 思路分析: 这个效果可以用两个View来完成,上层View是一个遮盖物,绘制 ...

  9. Android上传头像,图片剪裁,压缩图片

    点击头像的时候开始调用camera()方法 private byte[] mContent = new byte[1024];// 保存照片转换后的字节,用与上传到服务器private Bitmap ...

最新文章

  1. Darknet_Yolov3模型搭建
  2. 箭头函数参数和返回值
  3. 明日方舟抽卡模拟器wiki_明日方舟兑换码地址官服介绍 官服兑换码地址
  4. phpcms:八、show.html
  5. HDU1394(权值线段树)
  6. Oracle为什么装在XP系统,重装xp系统后oracle恢复方法
  7. 【转】Ubuntu 16.04 远程桌面
  8. ModelMapper 中高级使用 java
  9. 2020 年 Flink 最佳学习路线,学习的路上,你,并不孤单
  10. c语言最新标准 2017,2017最新C语言介绍
  11. atitit .大数据的方法,技术.attilax总结 大数据包含哪些方面 v5 s09..docx 7. 三大核心技术:拿数据,处理转换,算数据 2 8. 大数据有5个部分。数据采集,数据存储,
  12. 橘子娱乐完成华创资本千万美元B+轮融资
  13. 在页面点击“生成二维码”,直接把二维码图片下载下来
  14. 财富自由的声音:蚂蚁上市前,取消了周报
  15. 史上最全的15个苹果手机输入法使用技巧,不看后悔三年
  16. 实验一 基本逻辑门电路
  17. php 中margin-top,margin-top是什么意思-css编程词典-php中文网
  18. 面试官谈游戏开发入行--选择
  19. 中标麒麟+QT+达梦数据库
  20. POJ - 1190 - 生日蛋糕 (深搜剪枝)

热门文章

  1. 一个游戏大量合服代表什么_游戏里面合服是什么意思?对玩家有什么好处?
  2. 分享6个AI绘画网站
  3. 转:通过多线程为基于 .NET 的应用程序实现响应迅速的用户
  4. 让技术更有温度,腾讯Light 点亮公益之光
  5. arm-linux-ldd如何使用,linux - 交叉编译器ldd - Ubuntu问答
  6. 火线精英服务器怎样可以稳定,火线精英怎么操控好速度慢威力大的斩月
  7. Latex Package fontspec Warning Font FandolSong-Regular does not contain requested Script CJK
  8. Linux搭建服务器
  9. 错过Win10免费升级?别急,还有一次机会
  10. css的before和after讲解