用戶頭像選擇或者拍照上傳,並對圖片進行大小的壓縮,和形狀的控制,能夠將用戶選擇到的圖片裁剪成圓形上傳。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); } }