Android开发之裁切(拍照+相冊)图像并设置头像小结
先看效果:
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" width="320" height="480" alt="">
再贴代码:
自己定义选择照片底部弹出对话框布局:
<?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="@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="eminem13@mail.ustc.edu.cn" /> </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开发之裁切(拍照+相冊)图像并设置头像小结的更多相关文章
- iOS开发中訪问相冊摄像像头
iOS开发中訪问相冊摄像像头 源代码下载地址http://download.csdn.net/download/jingjingxujiayou/7270479 在AppDelegate.m文件里 - ...
- android开发真机调试 相关东东
android开发真机调试 相关东东 我们做android开发的时候,可以用模拟器,也可以真机调试,但是电脑配置不高的话,模拟器,真的是慢的有的一说,所以我一直倾向于用真机调试,但是问题也就来了,模拟 ...
- Android开发技巧——Camera拍照功能
本篇是我对开发项目的拍照功能过程中,对Camera拍照使用的总结.由于camera2是在api level 21(5.0.1)才引入的,而Camera到6.0仍可使用,所以暂未考虑camera2. 文 ...
- Android开发 ---基本UI组件2:图像按钮、单选按钮监听、多选按钮监听、开关
Android开发 ---基本UI组件2 1.activity_main.xml 描述: 定义一个按钮 <?xml version="1.0" encoding=" ...
- Android开发之漫漫长途 XI——从I到X的小结
该文章是一个系列文章,是本人在Android开发的漫漫长途上的一点感想和记录,我会尽量按照先易后难的顺序进行编写该系列.该系列引用了<Android开发艺术探索>以及<深入理解And ...
- 求助帖:android开发初期:为什么我在活动二设置的singInstance模式跑到活动三去了???
求android开发的高手帮我看看这个问题吧: <activity android:name=".SecondActivity" android:label="Th ...
- Android开发 - 掌握ConstraintLayout(十)按比例设置视图大小
有时候在布局界面的时候,UI要求某个View或者某张图片按比例显示,以适应不同的屏幕分辨率. 通常我们时通过自定义View或者引入第三方的库来解决.现在我们既然已经使用了ConstraintLayou ...
- Android 从本地图库或拍照后裁剪图片并设置头像
在QQ和微信等应用都会有设置头像,一般都是从本地图库选取或相机拍照,然后再截图自己喜欢的部分,然后设置.最后一步把截取好的图片再保存到本地,来保存头像.为了大家使用方便,我把自己完整的代码贴出来,大家 ...
- android仿最新版本号微信相冊--附源代码
更改排版为 markdown: http://blog.csdn.net/self_study/article/details/69397859
随机推荐
- BZOJ 4821 [Sdoi2017]相关分析 ——线段树
打开题面,看到许多$\sum$ woc,好神啊,SDOI好强啊 然后展开之后,woc,SDOI好弱啊,怎么T3出个线段树裸题啊. 最后写代码的时候,woc,SDOI怎么出个这么码农的题啊,怎么调啊. ...
- 洛谷 P3391 模板Splay
#include<bits/stdc++.h> using namespace std; #define maxn 200000 int read() { ,w=; ;ch=getchar ...
- Jvm运行时数据区 —— Java虚拟机结构小记
关于jvm虚拟机的文章网上都讲烂了.尤其是jvm运行时数据区的内容. 抱着眼见为实的想法,自己翻了翻JVM规范,花了点时间稍微梳理了一下. 以下是阅读Java虚拟机规范(Java SE 8版)的第二章 ...
- 【Visual Studio】Error: forget to add '#include "stdafx.h"' to your source (转)
原文转自 http://www.cnblogs.com/qunews/articles/2200313.html [问题原因]在编译时使用了预编译头文件, [解决方法]Project-->Pro ...
- 转 Python爬虫实战二之爬取百度贴吧帖子
静觅 » Python爬虫实战二之爬取百度贴吧帖子 大家好,上次我们实验了爬取了糗事百科的段子,那么这次我们来尝试一下爬取百度贴吧的帖子.与上一篇不同的是,这次我们需要用到文件的相关操作. 本篇目标 ...
- HDU 2767:Proving Equivalences(强连通)
题意: 一个有向图,问最少加几条边,能让它强连通 方法: 1:tarjan 缩点 2:采用如下构造法: 缩点后的图找到所有头结点和尾结点,那么,可以这么构造:把所有的尾结点连一条边到头结点,就必然可以 ...
- LeetCode OJ--Binary Tree Preorder Traversal
http://oj.leetcode.com/problems/binary-tree-preorder-traversal/ 二叉树的先跟遍历,写的是递归版本,也可以使用stack来进行,替代了递归 ...
- 获取某个元素相对于视窗的位置-getBoundingClientRect
1. getBoundingClientRect用于获取某个元素相对于视窗的位置集合.集合中有top, right, bottom, left等属性. 语法:这个方法没有参数 rectObject = ...
- js拖拽效果的实现
1.最基础的写法 <!DOCTYPE HTML> <html> <head> <meta charset="utf-8"> < ...
- VUE之命令行报错:Component template should contain exactly one root element. If you are using v-if on multiple elements, use v-else-if to chain them instead 解决办法
Failed to compile. ./node_modules/vue-loader/lib/template-compiler?{"id":"data-v-5992 ...