用户头像选择或者拍照上传,并对图片进行大小的压缩,和形状的控制,能够将用户选择到的图片裁剪成圆形上传。java
<!--读写sd卡权限--> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
第一步写两个工具类android
package com.example.xiangce; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.PorterDuff; import android.graphics.PorterDuffXfermode; import android.graphics.Rect; import android.graphics.RectF; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; /** * Created by asus on 2017/11/29. */ public class ImageUtils { /** * Save image to the SD card * * @param photoBitmap * @param photoName * @param path */ public static String savePhoto(Bitmap photoBitmap, String path, String photoName) { String localPath = null; if (android.os.Environment.getExternalStorageState().equals( android.os.Environment.MEDIA_MOUNTED)) { File dir = new File(path); if (!dir.exists()) { dir.mkdirs(); } File photoFile = new File(path, photoName + ".png"); FileOutputStream fileOutputStream = null; try { fileOutputStream = new FileOutputStream(photoFile); if (photoBitmap != null) { if (photoBitmap.compress(Bitmap.CompressFormat.PNG, 100, fileOutputStream)) { // 转换完成 localPath = photoFile.getPath(); fileOutputStream.flush(); } } } catch (FileNotFoundException e) { photoFile.delete(); localPath = null; e.printStackTrace(); } catch (IOException e) { photoFile.delete(); localPath = null; e.printStackTrace(); } finally { try { if (fileOutputStream != null) { fileOutputStream.close(); fileOutputStream = null; } } catch (IOException e) { e.printStackTrace(); } } } return localPath; } /** * 转换图片成圆形 * * @param bitmap 传入Bitmap对象 * @return */ public static Bitmap toRoundBitmap(Bitmap bitmap) { int width = bitmap.getWidth(); int height = bitmap.getHeight(); float roundPx; float left,top,right,bottom,dst_left,dst_top,dst_right,dst_bottom; if (width <= height) { roundPx = width / 2; top = 0; bottom = width; left = 0; right = width; height = width; dst_left = 0; dst_top = 0; dst_right = width; dst_bottom = width; } else { roundPx = height / 2; float clip = (width - height) / 2; left = clip; right = width - clip; top = 0; bottom = height; width = height; dst_left = 0; dst_top = 0; dst_right = height; dst_bottom = height; } Bitmap output = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(output); final int color = 0xff424242; final Paint paint = new Paint(); final Rect src = new Rect((int)left, (int)top, (int)right, (int)bottom); final Rect dst = new Rect((int)dst_left, (int)dst_top, (int)dst_right, (int)dst_bottom); final RectF rectF = new RectF(dst); paint.setAntiAlias(true); canvas.drawARGB(0, 0, 0, 0); paint.setColor(color); canvas.drawRoundRect(rectF, roundPx, roundPx, paint); paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN)); canvas.drawBitmap(bitmap, src, dst, paint); return output; } }
package com.example.xiangce; import android.content.Context; import android.os.Environment; import java.io.File; /** * Created by yuerq on 2016/5/30. */ public class AppConfig { public static final String APP_PATH = Environment .getExternalStorageDirectory() + File.separator + "pandatv" + File.separator; /** 默认存放图片的路径 */ public final static String DEFAULT_IMAGE_PATH = APP_PATH + "camera" + File.separator; /** 默认存放文件的路径 */ public final static String DEFAULT_CACHE_PATH = APP_PATH + "cache" + File.separator; private Context mContext; private static AppConfig appConfig; private AppConfig() { } public static AppConfig getAppConfig() { if (appConfig == null) { appConfig = new AppConfig(); } return appConfig; } public void init(Context context) { File file = new File(DEFAULT_IMAGE_PATH); if (!file.exists()) { file.mkdirs(); } file = new File(DEFAULT_CACHE_PATH); if (!file.exists()) { file.mkdirs(); } // DBInterface.getInstance().initDbHelp(context); // // //设置okhttp缓存 // File cacheFolder = context.getCacheDir(); // Cache cache = new Cache(cacheFolder, 50 * 1024 * 1024); //100Mb // OkHttpClient okHttpClient = new OkHttpClient.Builder() // .cache(cache) //// .addInterceptor(InterceptorFactory.getLoggingInterceptor()) // .build(); // Network.getInstance().init(okHttpClient); mContext = context.getApplicationContext(); } }
第二步Aci'ticanvas
package com.example.xiangce; import android.Manifest; import android.content.DialogInterface; import android.content.Intent; import android.content.pm.PackageManager; import android.graphics.Bitmap; import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.os.Environment; import android.provider.MediaStore; import android.support.annotation.NonNull; import android.support.v4.content.ContextCompat; import android.support.v4.content.FileProvider; import android.support.v7.app.AlertDialog; import android.support.v7.app.AppCompatActivity; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.ImageView; import android.widget.Toast; import java.io.File; public class MainActivity extends AppCompatActivity { private static final String TAG = "MainActivity"; protected static final int CHOOSE_PICTURE = 0; protected static final int TAKE_PICTURE = 1; private static final int CROP_SMALL_PICTURE = 2; protected static Uri tempUri; private ImageView iv_personal_icon; private Button but; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initView(); iv_personal_icon = (ImageView) findViewById(R.id.iv_personal_icon); but.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { showChoosePicDialog(but); } }); } /** * 显示修改头像的对话框 */ public void showChoosePicDialog(View v) { AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setTitle("设置头像"); String[] items = {"选择本地照片", "拍照"}; builder.setNegativeButton("取消", null); builder.setItems(items, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { switch (which) { case CHOOSE_PICTURE: // 选择本地照片 Intent openAlbumIntent = new Intent(Intent.ACTION_GET_CONTENT); openAlbumIntent.setType("image/*"); startActivityForResult(openAlbumIntent, CHOOSE_PICTURE); break; case TAKE_PICTURE: // 拍照 takePicture(); break; } } }); builder.create().show(); } private void takePicture() { String[] permissions = {Manifest.permission.WRITE_EXTERNAL_STORAGE}; if (Build.VERSION.SDK_INT >= 23) { // 须要申请动态权限 int check = ContextCompat.checkSelfPermission(this, permissions[0]); // 权限是否已经 受权 GRANTED---受权 DINIED---拒绝 if (check != PackageManager.PERMISSION_GRANTED) { requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1); } } Intent openCameraIntent = new Intent( MediaStore.ACTION_IMAGE_CAPTURE); File file = new File(Environment .getExternalStorageDirectory(), "image.jpg"); //判断是不是AndroidN以及更高的版本 if (Build.VERSION.SDK_INT >= 24) { openCameraIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); tempUri = FileProvider.getUriForFile(MainActivity.this, "com.lt.uploadpicdemo.fileProvider", file); } else { tempUri = Uri.fromFile(new File(Environment .getExternalStorageDirectory(), "image.jpg")); } // 指定照片保存路径(SD卡),image.jpg为一个临时文件,每次拍照后这个图片都会被替换 openCameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, tempUri); startActivityForResult(openCameraIntent, TAKE_PICTURE); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (resultCode == RESULT_OK) { // 若是返回码是能够用的 switch (requestCode) { case TAKE_PICTURE: startPhotoZoom(tempUri); // 开始对图片进行裁剪处理 break; case CHOOSE_PICTURE: startPhotoZoom(data.getData()); // 开始对图片进行裁剪处理 break; case CROP_SMALL_PICTURE: if (data != null) { setImageToView(data); // 让刚才选择裁剪获得的图片显示在界面上 } break; } } } /** * 裁剪图片方法实现 * * @param uri */ protected void startPhotoZoom(Uri uri) { if (uri == null) { Log.i("tag", "The uri is not exist."); } tempUri = 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", 150); intent.putExtra("outputY", 150); intent.putExtra("return-data", true); startActivityForResult(intent, CROP_SMALL_PICTURE); } /** * 保存裁剪以后的图片数据 * * @param */ protected void setImageToView(Intent data) { Bundle extras = data.getExtras(); if (extras != null) { Bitmap photo = extras.getParcelable("data"); Log.d(TAG, "setImageToView:" + photo); photo = ImageUtils.toRoundBitmap(photo); // 这个时候的图片已经被处理成圆形的了 iv_personal_icon.setImageBitmap(photo); uploadPic(photo); } } private void uploadPic(Bitmap bitmap) { // 上传至服务器 // ... 能够在这里把Bitmap转换成file,而后获得file的url,作文件上传操做 // 注意这里获得的图片已是圆形图片了 // bitmap是没有作个圆形处理的,但已经被裁剪了 String imagePath = ImageUtils.savePhoto(bitmap, Environment .getExternalStorageDirectory().getAbsolutePath(), String .valueOf(System.currentTimeMillis())); Log.e("imagePath", imagePath + ""); if (imagePath != null) { // 拿着imagePath上传了 // ... Log.d(TAG, "imagePath:" + imagePath); } } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { } else { // 没有获取 到权限,重新请求,或者关闭app Toast.makeText(this, "须要存储权限", Toast.LENGTH_SHORT).show(); } } private void initView() { but = (Button) findViewById(R.id.but); } }