您的位置:首页 > 移动开发 > Android开发

Android获取图片、裁剪、压缩、上传头像

2017-03-17 19:42 423 查看

上传方式为post,上传图片格式为multipart/form-data

自己在做毕设找了很多方法,但是没有找到一个符合我需求的,最后自己汇总了一下大家的方法,集成为我需要的方式

布局文件(自定义的原型头像):

<com.example.ff.bishe2.ui.CircleImageView
android:id="@+id/civ_information"
android:layout_width="60dp"
android:layout_height="60dp"
android:src="@drawable/ic_mine_head"
android:layout_margin="15dp"/>


Activity(这个activity还有一些其他的功能,所以有一些多余的代码):

public class InformationActivity extends AppCompatActivity implements View.OnClickListener {
private View view;
private TextView tvBack, tvName, tvPhone, tvAddress;
private LinearLayout ll_popup;
private LinearLayout llHead, llName, llPhone, llAddress;
private SharePreferenceUtil sharePreferenceUtil;
private String userid;

//下面这些变量是与题目有关的
private File photoFile;  //存放图片文件,最后是上传这个file
private CircleImageView civInformation;  //头像控件
private PopUtil pop;  //弹出框,选择是从相册选择还是拍照
protected LoadingDialog loadingDialog;  //上传如果延迟的话,会显示一个不停转圈的dialog
private PictureCutUtil pictureCutUtil;   //图片压缩工具
private String filename = System.currentTimeMillis() + ".png"; //如果拍照的话会存放在一个临时文件,所以文件名也是随时生成,以免混淆
public final static int CONSULT_DOC_PICTURE = 1000;  //相册
public final static int CONSULT_DOC_CAMERA = 1001;  //拍照
public final static int CONSULT_DOC_CUTTING = 1002;  //裁剪
private Uri outputFileUri;  //拍照获得的图片的uri

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
view = getLayoutInflater().inflate(R.layout.activity_information, null);
setContentView(view);

initView();
initPop();

}

//初始化view
private void initView() {
if (loadingDialog == null) {
loadingDialog = new LoadingDialog(this, R.style.DialogTheme);
}
pictureCutUtil = new PictureCutUtil(this);
tvBack = (TextView) findViewById(R.id.tv_information_back);
tvName = (TextView) findViewById(R.id.tv_information_name);
tvPhone = (TextView) findViewById(R.id.tv_information_phone);
tvAddress = (TextView) findViewById(R.id.tv_information_address);
civInformation = (CircleImageView) findViewById(R.id.civ_information);

llHead = (LinearLayout) findViewById(R.id.ll_information_head);
llName = (LinearLayout) findViewById(R.id.ll_information_name);
llPhone = (LinearLayout) findViewById(R.id.ll_information_phone);
llAddress = (LinearLayout) findViewById(R.id.ll_information_address);

tvBack.setOnClickListener(this);
llHead.setOnClickListener(this);
llName.setOnClickListener(this);
llPhone.setOnClickListener(this);
llAddress.setOnClickListener(this);
}

//初始化弹出框
private void initPop() {
pop = new PopUtil(InformationActivity.this, R.layout.item_popupwindows, false);
ll_popup = pop.getLl_popup();

TextView bt1 = (TextView) ll_popup.findViewById(R.id.item_popupwindows_camera);//拍照
TextView bt2 = (TextView) ll_popup.findViewById(R.id.item_popupwindows_Photo);//从相册中选择
TextView bt3 = (TextView) ll_popup.findViewById(R.id.item_popupwindows_cancel);//取消

bt1.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
File file = new File(Environment.getExternalStorageDirectory(), filename);
outputFileUri = Uri.fromFile(file);
Intent intentPhoto = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intentPhoto.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
startActivityForResult(intentPhoto, CONSULT_DOC_CAMERA);
overridePendingTransition(R.anim.translate_bottom_in, R.anim.translate_nomal);
pop.dismiss();
ll_popup.clearAnimation();
}
});
bt2.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("image/*");
startActivityForResult(Intent.createChooser(intent, "选择图片"), CONSULT_DOC_PICTURE);
overridePendingTransition(R.anim.translate_bottom_in, R.anim.translate_nomal);
pop.dismiss();
ll_popup.clearAnimation();
}
});
bt3.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
pop.dismiss();
}
});
}

@Override
protected void onResume() {
super.onResume();

initData();
}
//做一些数据初始化,与我们讨论的东西无关
private void initData() {
sharePreferenceUtil = new SharePreferenceUtil(this);
civInformation.setImageBitmap(sharePreferenceUtil.getImg(BitmapFactory.decodeResource(getResources(), R.drawable.ic_mine_head)));
tvName.setText(sharePreferenceUt
13675
il.getUsername());
tvPhone.setText(sharePreferenceUtil.getPhone());
tvAddress.setText(sharePreferenceUtil.getAddress());
userid = sharePreferenceUtil.getUserID();
}

//在弹出框中选择不同选项,在这里处理返回方法
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode){

case CONSULT_DOC_PICTURE: //相册选择

uriphoto = data.getData();  //图片已经存在,所以data中就是图片的uri
try {
startPhotoZoom(data.getData());  //头像一般都要裁剪

} catch (Exception e) {
e.printStackTrace();
}
break;

case CONSULT_DOC_CAMERA:  //拍照
if (outputFileUri != null) {
startPhotoZoom(outputFileUri);  //裁剪
}
break;

case CONSULT_DOC_CUTTING:  //裁剪完之后,压缩保存并上传
if (data != null) {
setPicToView(data);
}
break;
}
super.onActivityResult(requestCode, resultCode, data);
}

/**
* 裁剪图片方法实现
* @param uri
*/
public void startPhotoZoom(Uri uri) {
Intent intent = new Intent("com.android.camera.action.CROP");
intent.setDataAndType(uri, "image/*");
// 设置裁剪
intent.putExtra("crop", "true");
// aspectX aspectY 是宽高的比例
intent.putExtra("aspectX", 1);
intent.putExtra("aspectY", 1);
// outputX outputY 是裁剪图片宽高
intent.putExtra("outputX", 320);
intent.putExtra("outputY", 320);
intent.putExtra("return-data", true);
startActivityForResult(intent, CONSULT_DOC_CUTTING);  //返回去
}

//裁剪之后的图片不能放回原地址,所以要存放在一个临时file中再上传
private void setPicToView(Intent data) {
Bundle extras = data.getExtras();
if (extras != null) {
// 取得SDCard图片路径做显示
Bitmap photo = extras.getParcelable("data");
sharePreferenceUtil.setImg(photo); //我用sharePreference保存图片

photoFile = pictureCutUtil.cutPictureQuality(photo, "ff");  //压缩并保存
if (loadingDialog != null) {  //上传可能要延迟,先弹出等待框
loadingDialog.show();
}
postIcon(); //上传
}
}

//新建子线程上传头像,返回数据提交给handler刷新ui
private void postIcon() {
Thread t = new Thread() {
@Override
public void run() {
String url = "http://119.29.173.118/api/User/SetUserIcon?userid=" + userid;
String response = UploadImage.uploadFile(photoFile, url);  //方法后面给出

Message msg = new Message();
msg.obj = response;
msg.what= 1;
handler.sendMessage(msg);
}
};
t.start();
}

// 此方法在主线程中调用,可以更新UI
Handler handler = new Handler() {
public void handleMessage(android.os.Message msg) {
// 处理消息时需要知道是成功的消息还是失败的消息
if (!isFinishing()) loadingDialog.dismiss(); //上传返回后,等待框消失
switch (msg.what) {
case 1:
Toast.makeText(InformationActivity.this, msg.obj.toString() , Toast.LENGTH_LONG).show();
break;
case 0:
Toast.makeText(InformationActivity.this, "请求失败", Toast.LENGTH_LONG).show();
break;
default:
break;
}

}
};

@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.tv_information_back:
finish();
break;
case R.id.ll_information_head:
pop.showAtLocation(view, Gravity.BOTTOM, 0, 0);
break;
case R.id.ll_information_name:
IntentUtils.turnTo(InformationActivity.this, NameActivity.class, false);
break;
case R.id.ll_information_phone:
IntentUtils.turnTo(InformationActivity.this, PhoneActivity.class, false);
break;
case R.id.ll_information_address:
IntentUtils.turnTo(InformationActivity.this, AddressActivity.class, false);
break;
}
}
}


PopUtil弹出框:

public class PopUtil extends PopupWindow {
private AutoLinearLayout ll_popup;
private long mLastTime = -1;
private boolean isAnimation;
private Activity activity;
private int layout;
private View bgview;
private View view;

public PopUtil(Activity activity, int layout, boolean isAnimation) {
this.activity = activity;
this.layout = layout;
this.isAnimation = isAnimation;
initPop();
}

public AutoLinearLayout getLl_popup() {
return ll_popup;
}

public View getview() {
return view;
}

public void initPop() {
view = activity.getLayoutInflater().inflate(layout, null);
//      pop = new PopupWindow();
ll_popup = (AutoLinearLayout) view.findViewById(R.id.ll_popup);

setWidth(ViewGroup.LayoutParams.MATCH_PARENT);
setHeight(ViewGroup.LayoutParams.WRAP_CONTENT);
setBackgroundDrawable(new BitmapDrawable());
setFocusable(true);
setOutsideTouchable(true);
setContentView(view);
//      setBackgroundDrawable(new ColorDrawable(activity.getResources().getColor(R.color.black)));

bgview = ll_popup.findViewById(R.id.view);
bgview.setAlpha(0.5f);
//      消失的时候设置窗体背景变亮
//      setOnDismissListener(new PopupWindow.OnDismissListener() {
//      @Override
//      public void onDismiss() {
//      }
//      });

ll_popup.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dismiss();
//                if (isAnimation){
//                    endAnimationPopup(getAnimation());
//                }
}
});
}

public Animation getAnimation() {
final Animation endAnimation = AnimationUtils.loadAnimation(activity, R.anim.translate_bottom_out);
endAnimation.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {

}

@Override
public void onAnimationEnd(Animation animation) {
dismiss();

}

@Override
public void onAnimationRepeat(Animation animation) {

}
});
return endAnimation;
}

@Override
public void showAtLocation(View parent, int gravity, int x, int y) {
super.showAtLocation(parent, gravity, x, y);
//       backgroundAlpha(0.5f);
//       bgview.setVisibility(View.VISIBLE);

}

/**
* 防止重复点击关闭pop动画
*
* @param endAnimation
*/
public void endAnimationPopup(Animation endAnimation) {
if (mLastTime == -1) {
ll_popup.startAnimation(endAnimation);
} else {
long currentTimeMillis = System.currentTimeMillis();
long interval = currentTimeMillis - mLastTime;
if (interval < 300) {
return;
} else {
ll_popup.startAnimation(endAnimation);
}
}
mLastTime = System.currentTimeMillis();
}

@Override
public void dismiss() {
super.dismiss();
//        backgroundAlpha(1f);
}

/**
* 设置添加屏幕的背景透明度
*
* @param bgAlpha
*/
public void backgroundAlpha(float bgAlpha) {
WindowManager.LayoutParams lp = activity.getWindow().getAttributes();
lp.alpha = bgAlpha; //0.0-1.0
activity.getWindow().setAttributes(lp);
}
}


Pop的布局文件:

<?xml version="1.0" encoding="utf-8"?>
<com.zhy.autolayout.AutoLinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/ll_popup"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/transparent"
android:fitsSystemWindows="false"
android:orientation="vertical">

<View
android:id="@+id/view"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:background="@color/black"></View>

<TextView
android:layout_width="match_parent"
android:layout_height="1px"
android:background="@color/grayEFEFEF" />

<TextView
android:id="@+id/item_popupwindows_camera"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/white"
android:gravity="center"
android:padding="20px"
android:text="拍照"
android:textColor="@color/gray585858"
android:textSize="16sp" />

<TextView
android:layout_width="match_parent"
android:layout_height="1px"
android:background="@color/grayEFEFEF" />

<TextView
android:id="@+id/item_popupwindows_Photo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/white"
android:gravity="center"
android:padding="20px"
android:text="从相册中选取"
android:textColor="@color/gray585858"
android:textSize="16sp" />

<TextView
android:layout_width="match_parent"
android:layout_height="1px"
android:background="@color/grayf3f3f3" />

<TextView
android:id="@+id/item_popupwindows_cancel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/white"
android:gravity="center"
android:padding="20px"
android:text="取消"
android:textColor="@color/gray585858"
android:textSize="16sp" />

</com.zhy.autolayout.AutoLinearLayout>


PictureCutUtil图片工具类:

public class PictureCutUtil {
private File temp;
private Context context;

/**
* 构造器
*
* @param context
*/
public PictureCutUtil(Context context) {
this.context = context;
}

/**
* 计算图片的缩放值
*
* @param options
* @param reqWidth
* @param reqHeight
* @return
*/
private int cutBySize(BitmapFactory.Options options, int reqWidth, int reqHeight) {

final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;

if (height > reqHeight || width > reqWidth) {

final int heightRatio = Math.round((float) height / (float) reqHeight);
final int widthRatio = Math.round((float) width / (float) reqWidth);

inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
}

return inSampleSize;
}

/**
* 根据路径获得图片并压缩返回bitmap
*
* @param filePath
* @return
*/
public Bitmap cutPictureSize(String filePath) {

Display mDisplay = ((Activity) context).getWindowManager().getDefaultDisplay();
int width = mDisplay.getWidth();
int height = mDisplay.getHeight();

final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(filePath, options);
options.inSampleSize = cutBySize(options, width, height);
options.inJustDecodeBounds = false;

return BitmapFactory.decodeFile(filePath, options);
}

/**
* 存储图片
*
* @param bitmap
* @param savePackage
* @return
*/
public File cutPictureQuality(Bitmap bitmap, String savePackage) {

String fileName = UUID.randomUUID().toString().replace("-","") + ".png";
String filePath = Environment.getExternalStorageDirectory() + File.separator + savePackage;
// 判断文件夹存在
File file = new File(filePath);
if (file != null && !file.exists()) {
file.mkdirs();
}

try {

// 第一次压缩
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
temp = new File(filePath, fileName);
FileOutputStream fos = new FileOutputStream(temp);

int options = 100;
// 如果大于150kb则再次压缩,最多压缩三次
while (baos.toByteArray().length / 1024 > 150 && options != 10) {
// 清空baos
baos.reset();
// 这里压缩options%,把压缩后的数据存放到baos中
bitmap.compress(Bitmap.CompressFormat.JPEG, options, baos);
options -= 30;
}
fos.write(baos.toByteArray());
fos.close();
baos.close();

} catch (Exception e) {
}
return temp;
}
}


上传头像UploadImage(post方式,multipart/form-data格式):

public class UploadImage {
private static final String TAG = "uploadFile";
private static final int TIME_OUT = 10*10000000; //超时时间
private static final String CHARSET = "utf-8"; //设置编码
private static final String BOUNDARY = "FlPm4LpSXsE" ; //UUID.randomUUID().toString(); //边界标识 随机生成 String PREFIX = "--" , LINE_END = "\r\n";
private static final String PREFIX="--";
private static final String LINE_END="\r\n";
private static final String CONTENT_TYPE = "multipart/form-data"; //内容类型

/** * android上传文件到服务器
* @param file 需要上传的文件
* @param requestURL 请求的rul
* @return 返回响应的内容
*/
public static String uploadFile(File file, String requestURL) {
try {
URL url = new URL(requestURL);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(TIME_OUT);
conn.setConnectTimeout(TIME_OUT);
conn.setDoInput(true); //允许输入流
conn.setDoOutput(true); //允许输出流
conn.setUseCaches(false); //不允许使用缓存
conn.setRequestMethod("POST"); //请求方式
conn.setRequestProperty("Charset", CHARSET);//设置编码
//头信息

conn.setRequestProperty("Content-Type", CONTENT_TYPE + ";boundary=" + BOUNDARY);
if(file!=null) {
/** * 当文件不为空,把文件包装并且上传 */
OutputStream outputSteam=conn.getOutputStream();
DataOutputStream dos = new DataOutputStream(outputSteam);

StringBuffer sb = new StringBuffer();
sb.append(PREFIX);
sb.append(BOUNDARY);
sb.append(LINE_END);

sb.append("Content-Disposition: form-data; name=\"file\";filename=" + "\"" + file.getName() + "\"" + LINE_END);
sb.append("Content-Type: image/jpg"+LINE_END);
sb.append(LINE_END);
dos.write(sb.toString().getBytes());
//读取文件的内容
InputStream is = new FileInputStream(file);
byte[] bytes = new byte[1024];
int len = 0;
while((len=is.read(bytes))!=-1)
{
dos.write(bytes, 0, len);
}
is.close();
//写入文件二进制内容
dos.write(LINE_END.getBytes());
//写入end data
byte[] end_data = (PREFIX+BOUNDARY+PREFIX+LINE_END).getBytes();
dos.write(end_data);
dos.flush();
/**
* 获取响应码 200=成功
* 当响应成功,获取响应的流
*/
int res = conn.getResponseCode();
if(res==200) {
String oneLine;
StringBuffer response = new StringBuffer();
BufferedReader input = new BufferedReader(new InputStreamReader(conn.getInputStream()));
while ((oneLine = input.readLine()) != null) {
response.append(oneLine);
}
return response.toString();
}else{
return ""+res;
}
}else{
return "file not found";
}
} catch (MalformedURLException e) {
e.printStackTrace();
return "Malformed failed";
} catch (IOException e) {
e.printStackTrace();
return "IO failed";
}
}

}


效果图:







内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  头像 android
相关文章推荐