Android开发之裁切(拍照+相冊)图像并设置头像小结

要须心地收汗马,孔孟行世目杲杲。这篇文章主要讲述Android开发之裁切(拍照+相冊)图像并设置头像小结相关的知识,希望能为你提供帮助。
先看效果:

Android开发之裁切(拍照+相冊)图像并设置头像小结

文章图片
             
Android开发之裁切(拍照+相冊)图像并设置头像小结

文章图片
               
Android开发之裁切(拍照+相冊)图像并设置头像小结

文章图片
             
Android开发之裁切(拍照+相冊)图像并设置头像小结

文章图片
Android开发之裁切(拍照+相冊)图像并设置头像小结              Android开发之裁切(拍照+相冊)图像并设置头像小结

文章图片
Android开发之裁切(拍照+相冊)图像并设置头像小结

文章图片



再贴代码:
自己定义选择照片底部弹出对话框布局:

< ?xml version=" 1.0" encoding=" utf-8" ?> < RelativeLayout xmlns:android=" http://schemas.android.com/apk/res/android" android:layout_width=" match_parent" android:layout_height=" wrap_content" android:gravity=" center_horizontal" android:orientation=" vertical" > < LinearLayout android:id=" @+id/pop_layout" android:layout_width=" fill_parent" android:layout_height=" wrap_content" android:layout_alignParentBottom=" true" android:background=" #312E3F" android:gravity=" center_horizontal" android:orientation=" vertical" > < Button android:id=" @+id/takePhotoBtn" android:layout_width=" match_parent" android:layout_height=" wrap_content" android:layout_marginLeft=" 10dip" android:layout_marginRight=" 10dip" android:layout_marginTop=" 10dp" android:background=" @drawable/btn_bg_blue" android:padding=" 10dp" android:text=" 拍照" android:textColor=" @color/colorwhite" android:textSize=" 18sp" android:textStyle=" bold" /> < Button android:id=" @+id/pickPhotoBtn" android:layout_width=" match_parent" android:layout_height=" wrap_content" android:layout_marginLeft=" 10dip" android:layout_marginRight=" 10dip" android:layout_marginTop=" 5dp" android:background=" @drawable/btn_bg_blue" android:padding=" 10dp" android:text=" 从相冊选择" android:textColor=" @color/colorwhite" android:textSize=" 18sp" android:textStyle=" bold" /> < Button android:id=" @+id/cancelBtn" android:layout_width=" match_parent" android:layout_height=" wrap_content" android:layout_marginBottom=" 15dip" android:layout_marginLeft=" 10dip" android:layout_marginRight=" 10dip" android:layout_marginTop=" 20dp" android:background=" @android:color/white" android:padding=" 10dp" android:text=" 取消" android:textColor=" #373447" android:textSize=" 18sp" android:textStyle=" bold" /> < /LinearLayout> < /RelativeLayout>


设备连接界面NavigationView header部分布局:
< ?
xml version=" 1.0" encoding=" utf-8" ?> < LinearLayout xmlns:android=" http://schemas.android.com/apk/res/android" android:id=" @+id/nav_headerView" android:layout_width=" match_parent" android:layout_height=" @dimen/nav_header_height" android:background=" @drawable/drawer_background" android:gravity=" bottom" android:orientation=" vertical" android:paddingBottom=" @dimen/activity_vertical_margin" android:paddingLeft=" @dimen/activity_horizontal_margin" android:paddingRight=" @dimen/activity_horizontal_margin" android:paddingTop=" @dimen/activity_vertical_margin" android:theme=" @style/ThemeOverlay.AppCompat.Dark" > < com.aiofm.eminem.aiofmbgp.views.controls.CircleImage android:id=" @+id/imageView" android:layout_width=" 80dp" android:layout_height=" 80dp" android:layout_centerHorizontal=" true" android:paddingTop=" @dimen/nav_header_vertical_spacing" android:src=https://www.songbingjia.com/android/" @android:drawable/sym_def_app_icon" /> < TextView android:layout_width=" match_parent" android:layout_height=" wrap_content" android:paddingTop=" @dimen/nav_header_vertical_spacing" android:text=" 鲍光普" android:textAppearance=" @style/TextAppearance.AppCompat.Body1" /> < TextView android:id=" @+id/textView" android:layout_width=" wrap_content" android:layout_height=" wrap_content" android:text=" [email? protected]" /> < /LinearLayout>


文件操作工具类代码:
package com.aiofm.eminem.aiofmbgp.common; /** * 文件工具类 * Created by eminem on 2016/4/10 */ import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Locale; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Bitmap.CompressFormat; import android.os.Environment; public class FileUtil { /** * 将Bitmap 图片保存到本地路径。并返回路径 * @param c 上下文 * @param fileName 文件名 * @param bitmap 图片资源 * @return * Added by Bao guangpu on 2016/4/10 */ public static String saveFile(Context c, String fileName, Bitmap bitmap) { return saveFile(c, " " , fileName, bitmap); }/** * 保存位图文件 * @param c 上下文 * @param filePath 保存文件路径 * @param fileName 文件名 * @param bitmap 图片资源 * @return * Added by Bao guangpu on 2016/4/10 */ public static String saveFile(Context c, String filePath, String fileName, Bitmap bitmap) { byte[] bytes = bitmapToBytes(bitmap); return saveFile(c, filePath, fileName, bytes); }/** * 将位图转换为字节数组 * @param bm 图片资源 * @return * Added by Bao guangpu on 2016/4/10 */ public static byte[] bitmapToBytes(Bitmap bm) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); bm.compress(CompressFormat.JPEG, 100, baos); return baos.toByteArray(); }/** * 保存字节数组文件 * @param c 上下文 * @param filePath 保存文件路径 * @param fileName 文件名 * @param bytes 字节数组 * @return * Added by Bao guangpu on 2016/4/10 */ public static String saveFile(Context c, String filePath, String fileName, byte[] bytes) { String fileFullName = " " ; FileOutputStream fos = null; String dateFolder = new SimpleDateFormat(" yyyyMMdd" , Locale.CHINA) .format(new Date()); try { String suffix = " " ; if (filePath == null || filePath.trim().length() == 0) { filePath = Environment.getExternalStorageDirectory() + " /JiaXT/" + dateFolder + " /" ; } File file = new File(filePath); if (!file.exists()) { file.mkdirs(); } File fullFile = new File(filePath, fileName + suffix); fileFullName = fullFile.getPath(); fos = new FileOutputStream(new File(filePath, fileName + suffix)); fos.write(bytes); } catch (Exception e) { fileFullName = " " ; } finally { if (fos != null) { try { fos.close(); } catch (IOException e) { fileFullName = " " ; } } } return fileFullName; } }


自己定义ImageView代码:
package com.aiofm.eminem.aiofmbgp.views.controls; /** * 自己定义ImageView * Created by eminem on 2016/4/11. */ import android.content.Context; import android.content.res.TypedArray; import android.graphics.Bitmap; import android.graphics.BitmapShader; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.RectF; import android.graphics.Shader; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.util.AttributeSet; import android.widget.ImageView; import com.aiofm.eminem.aiofmbgp.R; public class CircleImage extends ImageView {private static final ScaleType SCALE_TYPE = ScaleType.CENTER_CROP; private static final Bitmap.Config BITMAP_CONFIG = Bitmap.Config.ARGB_8888; private static final int COLORDRAWABLE_DIMENSION = 1; private static final int DEFAULT_BORDER_WIDTH = 0; private static final int DEFAULT_BORDER_COLOR = Color.BLACK; private final RectF mDrawableRect = new RectF(); private final RectF mBorderRect = new RectF(); private final Matrix mShaderMatrix = new Matrix(); private final Paint mBitmapPaint = new Paint(); private final Paint mBorderPaint = new Paint(); private int mBorderColor = DEFAULT_BORDER_COLOR; private int mBorderWidth = DEFAULT_BORDER_WIDTH; private Bitmap mBitmap; private BitmapShader mBitmapShader; private int mBitmapWidth; private int mBitmapHeight; private float mDrawableRadius; private float mBorderRadius; private boolean mReady; private boolean mSetupPending; public CircleImage(Context context) { super(context); }public CircleImage(Context context, AttributeSet attrs) { this(context, attrs, 0); }public CircleImage(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); super.setScaleType(SCALE_TYPE); TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CircleImageView, defStyle, 0); mBorderWidth = a.getDimensionPixelSize(R.styleable.CircleImageView_border_width, DEFAULT_BORDER_WIDTH); mBorderColor = a.getColor(R.styleable.CircleImageView_border_color, DEFAULT_BORDER_COLOR); a.recycle(); mReady = true; if (mSetupPending) { setup(); mSetupPending = false; } }@Override public ScaleType getScaleType() { return SCALE_TYPE; }@Override public void setScaleType(ScaleType scaleType) { if (scaleType != SCALE_TYPE) { throw new IllegalArgumentException(String.format(" ScaleType %s not supported." , scaleType)); } }@Override protected void onDraw(Canvas canvas) { if (getDrawable() == null) { return; }canvas.drawCircle(getWidth() / 2, getHeight() / 2, mDrawableRadius, mBitmapPaint); canvas.drawCircle(getWidth() / 2, getHeight() / 2, mBorderRadius, mBorderPaint); }@Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); setup(); }public int getBorderColor() { return mBorderColor; }public void setBorderColor(int borderColor) { if (borderColor == mBorderColor) { return; }mBorderColor = borderColor; mBorderPaint.setColor(mBorderColor); invalidate(); }public int getBorderWidth() { return mBorderWidth; }public void setBorderWidth(int borderWidth) { if (borderWidth == mBorderWidth) { return; }mBorderWidth = borderWidth; setup(); }@Override public void setImageBitmap(Bitmap bm) { super.setImageBitmap(bm); mBitmap = bm; setup(); }@Override public void setImageDrawable(Drawable drawable) { super.setImageDrawable(drawable); mBitmap = getBitmapFromDrawable(drawable); setup(); }@Override public void setImageResource(int resId) { super.setImageResource(resId); mBitmap = getBitmapFromDrawable(getDrawable()); setup(); }private Bitmap getBitmapFromDrawable(Drawable drawable) { if (drawable == null) { return null; }if (drawable instanceof BitmapDrawable) { return ((BitmapDrawable) drawable).getBitmap(); }try { Bitmap bitmap; if (drawable instanceof ColorDrawable) { bitmap = Bitmap.createBitmap(COLORDRAWABLE_DIMENSION, COLORDRAWABLE_DIMENSION, BITMAP_CONFIG); } else { bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), BITMAP_CONFIG); }Canvas canvas = new Canvas(bitmap); drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight()); drawable.draw(canvas); return bitmap; } catch (OutOfMemoryError e) { return null; } }private void setup() { if (!mReady) { mSetupPending = true; return; }if (mBitmap == null) { return; }mBitmapShader = new BitmapShader(mBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); mBitmapPaint.setAntiAlias(true); mBitmapPaint.setShader(mBitmapShader); mBorderPaint.setStyle(Paint.Style.STROKE); mBorderPaint.setAntiAlias(true); mBorderPaint.setColor(mBorderColor); mBorderPaint.setStrokeWidth(mBorderWidth); mBitmapHeight = mBitmap.getHeight(); mBitmapWidth = mBitmap.getWidth(); mBorderRect.set(0, 0, getWidth(), getHeight()); mBorderRadius = Math.min((mBorderRect.height() - mBorderWidth) / 2, (mBorderRect.width() - mBorderWidth) / 2); mDrawableRect.set(mBorderWidth, mBorderWidth, mBorderRect.width() - mBorderWidth, mBorderRect.height() - mBorderWidth); mDrawableRadius = Math.min(mDrawableRect.height() / 2, mDrawableRect.width() / 2); updateShaderMatrix(); invalidate(); }private void updateShaderMatrix() { float scale; float dx = 0; float dy = 0; mShaderMatrix.set(null); if (mBitmapWidth * mDrawableRect.height() > mDrawableRect.width() * mBitmapHeight) { scale = mDrawableRect.height() / (float) mBitmapHeight; dx = (mDrawableRect.width() - mBitmapWidth * scale) * 0.5f; } else { scale = mDrawableRect.width() / (float) mBitmapWidth; dy = (mDrawableRect.height() - mBitmapHeight * scale) * 0.5f; }mShaderMatrix.setScale(scale, scale); mShaderMatrix.postTranslate((int) (dx + 0.5f) + mBorderWidth, (int) (dy + 0.5f) + mBorderWidth); mBitmapShader.setLocalMatrix(mShaderMatrix); }}

自己定义选择照片底部弹出对话框代码:
package com.aiofm.eminem.aiofmbgp.views.controls; /** * Created by eminem on 2016/4/11. */ import android.annotation.SuppressLint; import android.content.Context; import android.graphics.drawable.ColorDrawable; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; import android.view.View.OnClickListener; import android.view.View.OnTouchListener; import android.view.ViewGroup.LayoutParams; import android.widget.Button; import android.widget.PopupWindow; import com.aiofm.eminem.aiofmbgp.R; public class SelectPicPopupWindow extends PopupWindow {private Button takePhotoBtn, pickPhotoBtn, cancelBtn; private View mMenuView; @SuppressLint(" InflateParams" ) public SelectPicPopupWindow(Context context, OnClickListener itemsOnClick) { super(context); LayoutInflater inflater = (LayoutInflater) context .getSystemService(Context.LAYOUT_INFLATER_SERVICE); mMenuView = inflater.inflate(R.layout.layout_dialog_pic, null); takePhotoBtn = (Button) mMenuView.findViewById(R.id.takePhotoBtn); pickPhotoBtn = (Button) mMenuView.findViewById(R.id.pickPhotoBtn); cancelBtn = (Button) mMenuView.findViewById(R.id.cancelBtn); cancelBtn.setOnClickListener(itemsOnClick); pickPhotoBtn.setOnClickListener(itemsOnClick); takePhotoBtn.setOnClickListener(itemsOnClick); this.setContentView(mMenuView); this.setWidth(LayoutParams.MATCH_PARENT); this.setHeight(LayoutParams.WRAP_CONTENT); this.setFocusable(true); this.setAnimationStyle(R.style.PopupAnimation); ColorDrawable dw = new ColorDrawable(0x80000000); this.setBackgroundDrawable(dw); mMenuView.setOnTouchListener(new OnTouchListener() {@Override @SuppressLint(" ClickableViewAccessibility" ) public boolean onTouch(View v, MotionEvent event) {int height = mMenuView.findViewById(R.id.pop_layout).getTop(); int y = (int) event.getY(); if (event.getAction() == MotionEvent.ACTION_UP) { if (y < height) { dismiss(); } } return true; } }); }}


设备连接界面部分相关代码:
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_mainview); navigationView.setNavigationItemSelectedListener(this); View headerView = navigationView.getHeaderView(0); avatarImg = (CircleImage) headerView.findViewById(R.id.imageView); avatarImg.setOnClickListener(this);


@Override public void onClick(View v) { switch (v.getId()) { case R.id.imageView: menuWindow = new SelectPicPopupWindow(mContext, itemsOnClick); menuWindow.showAtLocation(findViewById(R.id.drawer_layout), Gravity.BOTTOM|Gravity.CENTER_HORIZONTAL, 0, 0); break; } }

private View.OnClickListener itemsOnClick = new View.OnClickListener() { @Override public void onClick(View v) { menuWindow.dismiss(); switch (v.getId()) { case R.id.takePhotoBtn: Intent takeIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); takeIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File(Environment.getExternalStorageDirectory(), IMAGE_FILE_NAME))); startActivityForResult(takeIntent, REQUESTCODE_TAKE); break; case R.id.pickPhotoBtn: Intent pickIntent = new Intent(Intent.ACTION_PICK, null); pickIntent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, " image/*" ); startActivityForResult(pickIntent, REQUESTCODE_PICK); break; default: break; } } }; @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { switch (requestCode) { case REQUESTCODE_PICK: try { startPhotoZoom(data.getData()); } catch (NullPointerException e) { e.printStackTrace(); } break; case REQUESTCODE_TAKE: File temp = new File(Environment.getExternalStorageDirectory() + " /" + IMAGE_FILE_NAME); startPhotoZoom(Uri.fromFile(temp)); break; case REQUESTCODE_CUTTING: if (data != null) { setPicToView(data); } break; } super.onActivityResult(requestCode, resultCode, data); }public void startPhotoZoom(Uri uri) { 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(" outputX" , 300); intent.putExtra(" outputY" , 300); intent.putExtra(" return-data" , true); startActivityForResult(intent, REQUESTCODE_CUTTING); }private void setPicToView(Intent picdata) { Bundle extras = picdata.getExtras(); if (extras != null) { Bitmap photo = extras.getParcelable(" data" ); Drawable drawable = new BitmapDrawable(null, photo); urlpath = FileUtil.saveFile(mContext, " temphead.jpg" , photo); avatarImg.setImageDrawable(drawable); } }











【Android开发之裁切(拍照+相冊)图像并设置头像小结】






















    推荐阅读