Android 上传头像自定义(剪切、平移,缩放)
来源:互联网 发布:淘宝开店如何退保证金 编辑:程序博客网 时间:2024/05/16 12:57
点击进入下载源码
今天是愚人节,但是我发表的内容可不是用来愚人的。上传图片时很多应用的硬需求,我们的应用也不例外。以前上传头像时感觉是那样的so-easy,但是前几天的上传图片让我很是头疼。原本的上传头像代码直接搬过来使用时发现在三星手机上面不能使用,于是就大改特该,改过之后终于可以使用了,没想到在华为手机上面又不能使用了,仔细debug一下看个究竟原来是Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE)的设置问题,三星的Action和华为的还有小米的是不一样的,怎么办呢?于是就想到了获取手机的机型根据机型进行拍照上传。但是更头疼的事情还在后面呢,由于调用的是系统的拍照剪切,没想到三星的手机系统默认的是旋转90度,真是TMD让我伤心啊,于是就用根据旋转的角度方法进行旋转,方法如下:
public Bitmap rotaingImageView(int angle, Bitmap bitmap) { // 旋转图片 动作 Matrix matrix = new Matrix(); matrix.postRotate(angle); // 创建新的图片 Bitmap resizedBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true); return resizedBitmap; } private int readPictureDegree(String path) { int degree = 0; try { ExifInterface exifInterface = new ExifInterface(path); int orientation = exifInterface.getAttributeInt( ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL); 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; } } catch (IOException e) { e.printStackTrace(); } return degree; }
没想到的是读取旋转的角度却是0,当然是旋转不过来了,实在是没有办法了就看看微信是怎么整的,原来微信是自定义的剪切图片,在拍照后不调用系统的剪切功能,而是直接在拍照后使用自定义的裁剪方法,因为拍照时的旋转角度还是可以获取到的,然后根据旋转的角度进行逆向旋转回来。于是自己就进行了自定义裁剪的代码实现拍照裁剪。同时解决的过程中也解决了一些机型的不兼容,只是本次实现的拍照上传裁剪和选择相册裁剪在三星(S6)、华为、小米、魅族手机上面是没有问题的。
以下是实现裁剪平移缩放效果的代码如下
public class CutView extends View { private Paint paint = new Paint(); private Paint borderPaint = new Paint(); /** 自定义顶部栏高度,如不是自定义,则默认为0即可 */ private int customTopBarHeight = 0; /** 裁剪框长宽比,默认4:3 */ private double clipRatio = 0.75; /** 裁剪框宽度 */ private int clipWidth = -1; /** 裁剪框高度 */ private int clipHeight = -1; /** 裁剪框左边空留宽度 */ private int clipLeftMargin = 0; /** 裁剪框上边空留宽度 */ private int clipTopMargin = 0; /** 裁剪框边框宽度 */ private int clipBorderWidth = 1; private boolean isSetMargin = false; private OnDrawListenerComplete listenerComplete; public CutView(Context context) { super(context); } public CutView(Context context, AttributeSet attrs) { super(context, attrs); } public CutView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); int width = this.getWidth(); int height = this.getHeight(); // 如没有显示设置裁剪框高度和宽度,取默认值 if (clipWidth == -1 || clipHeight == -1) { clipWidth = width - 50; clipHeight = (int) (clipWidth * clipRatio); // 横屏 if (width > height) { clipHeight = height - 50; clipWidth = (int) (clipHeight / clipRatio); } } // 如没有显示设置裁剪框左和上预留宽度,取默认值 if (!isSetMargin) { clipLeftMargin = (width - clipWidth) / 2; clipTopMargin = (height - clipHeight) / 2; } // 画阴影 paint.setAlpha(100); // top canvas.drawRect(0, customTopBarHeight, width, clipTopMargin, paint); // left canvas.drawRect(0, clipTopMargin, clipLeftMargin, clipTopMargin + clipHeight, paint); // right canvas.drawRect(clipLeftMargin + clipWidth, clipTopMargin, width, clipTopMargin + clipHeight, paint); // bottom canvas.drawRect(0, clipTopMargin + clipHeight, width, height, paint); // 画边框 borderPaint.setStyle(Style.STROKE); borderPaint.setColor(Color.WHITE); borderPaint.setStrokeWidth(clipBorderWidth); canvas.drawRect(clipLeftMargin, clipTopMargin, clipLeftMargin + clipWidth, clipTopMargin + clipHeight, borderPaint); if (listenerComplete != null) { listenerComplete.onDrawCompelete(); } } public int getCustomTopBarHeight() { return customTopBarHeight; } public void setCustomTopBarHeight(int customTopBarHeight) { this.customTopBarHeight = customTopBarHeight; } public double getClipRatio() { return clipRatio; } public void setClipRatio(double clipRatio) { this.clipRatio = clipRatio; } public int getClipWidth() { // 减clipBorderWidth原因:截图时去除边框白线 return clipWidth - clipBorderWidth; } public void setClipWidth(int clipWidth) { this.clipWidth = clipWidth; } public int getClipHeight() { return clipHeight - clipBorderWidth; } public void setClipHeight(int clipHeight) { this.clipHeight = clipHeight; } public int getClipLeftMargin() { return clipLeftMargin + clipBorderWidth; } public void setClipLeftMargin(int clipLeftMargin) { this.clipLeftMargin = clipLeftMargin; isSetMargin = true; } public int getClipTopMargin() { return clipTopMargin + clipBorderWidth; } public void setClipTopMargin(int clipTopMargin) { this.clipTopMargin = clipTopMargin; isSetMargin = true; } public void addOnDrawCompleteListener(OnDrawListenerComplete listener) { this.listenerComplete = listener; } public void removeOnDrawCompleteListener() { this.listenerComplete = null; } /** * 裁剪区域画完时调用接口 * * @author Cow * */ public interface OnDrawListenerComplete { public void onDrawCompelete(); }}
下面是实现拍照和选择相册的代码
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == FLAG_CHOOSE_IMG && resultCode == RESULT_OK) { if (data != null) { Uri uri = data.getData(); if (!TextUtils.isEmpty(uri.getAuthority())) { Cursor cursor = getContentResolver().query(uri, new String[] { MediaStore.Images.Media.DATA }, null, null, null); if (null == cursor) { Toast.makeText(getApplicationContext(), "图片没找到", 0) .show(); return; } cursor.moveToFirst(); String path = cursor.getString(cursor .getColumnIndex(MediaStore.Images.Media.DATA)); cursor.close(); Intent intent = new Intent(this, CutPictureAty.class); intent.putExtra("path", path); startActivityForResult(intent, FLAG_MODIFY_FINISH); } else { Intent intent = new Intent(this, CutPictureAty.class); intent.putExtra("path", uri.getPath()); startActivityForResult(intent, FLAG_MODIFY_FINISH); } } } else if (requestCode == FLAG_MODIFY_FINISH && resultCode == RESULT_OK) { if (data != null) { final String path = data.getStringExtra("path"); Bitmap b = BitmapFactory.decodeFile(path); img_pic.setImageBitmap(b); } } switch (requestCode) { case CAMERA_WITH_DATA: // 照相机程序返回的,再次调用图片剪辑程序去修剪图片 startCropImageActivity(Environment.getExternalStorageDirectory() + "/" + TMP_PATH); break; } } // 裁剪图片的Activity private void startCropImageActivity(String path) { Intent intent = new Intent(this, CutPictureAty.class); intent.putExtra("path", path); startActivityForResult(intent, FLAG_MODIFY_FINISH); } private void startAlbum() { Intent intent = new Intent(); intent.setAction(Intent.ACTION_PICK); intent.setType("image/*"); startActivityForResult(intent, FLAG_CHOOSE_IMG); }
实现效果图
拍照裁剪效果图
相册裁剪效果图
平移缩放效果图
如有疑问欢迎加群Android技术交流群 50208422或Android交流群 470707794,探讨技术,欢迎加入。
点击进入下载源码
Github下载地址
- Android 上传头像自定义(剪切、平移,缩放)
- Android 7.0 图片剪切问题,选择头像上传
- 实现头像上传及剪切功能(cakephp+jquery)
- android动画(平移,旋转,缩放,透明度)
- WPF 自定义图片剪切器 - 头像剪切(扩展与完善、实时截图)
- android 拍照,裁切,上传圆形头像, 图片等比缩放
- Quartz2D——旋转、平移、缩放、剪切圆形图片
- WPF 自定义图片剪切器 - 头像剪切。你懂得
- Android 图片旋转 缩放 平移
- Android图片居中缩放剪切
- Android图片双击缩放,多点缩放,平移
- Flask 上传自定义头像
- Struts2 图片上传、缩放、剪切处理 第一节
- Android图形处理基本api(缩放,旋转,平移)
- android 中四种补间动画(透明,平移,缩放,旋转)
- 会员中心上传头像时的,上传图片并剪切
- Android开发实现圆形头像剪切
- 混合App应用实现本地头像剪切,压缩上传功能(支持任何H5框架)
- CI框架随记1
- [unix]secureCRT使用常见命令
- 关于JVM的常见问题(二)
- 如何实现友盟第三方登录与分享
- uboot下gpio驱动移植
- Android 上传头像自定义(剪切、平移,缩放)
- storm实战入门一
- Hadoop的FileStatus简单使用
- shiny-server 安装与配置、问题汇总
- 聚类分析
- [转载]Linux中profile、bashrc、bash_profile之间的区别和联系
- 使用O-LLVM和NDK对Android应用进行混淆
- List<E>类
- svn更改登录用户和密码