0
点赞
收藏
分享

微信扫一扫

android处理拍照与选择相册并可动态设置是否可裁剪上传解决方案 并且真机测试通过(小米\魔族\htc)sdk2.1-4.x系统...


    1. package org.wavefar.lib.utils;  
    2.   
    3. import java.io.ByteArrayOutputStream;  
    4. import java.io.File;  
    5. import java.io.FileNotFoundException;  
    6. import java.io.FileOutputStream;  
    7. import java.io.IOException;  
    8.   
    9. import org.wavefar.lib.Config;  
    10. import org.wavefar.lib.R;  
    11. import org.wavefar.lib.utils.imagecrop.CropImage;  
    12.   
    13. import android.app.Activity;  
    14. import android.app.AlertDialog;  
    15. import android.content.Context;  
    16. import android.content.Intent;  
    17. import android.database.Cursor;  
    18. import android.graphics.Bitmap;  
    19. import android.graphics.BitmapFactory;  
    20. import android.graphics.Matrix;  
    21. import android.net.Uri;  
    22. import android.os.AsyncTask;  
    23. import android.os.Environment;  
    24. import android.provider.MediaStore;  
    25. import android.view.Gravity;  
    26. import android.view.View;  
    27. import android.view.View.OnClickListener;  
    28. import android.view.ViewGroup.LayoutParams;  
    29. import android.view.Window;  
    30. import android.widget.Toast;  
    31.   
    32. /**
    33.  * 拍照工具类
    34.  * <p>方法:initCutSize裁剪设置(可选)</p>
    35.  * <p>图片入口方法:doPickPhotoAction启动图片和相册筛选</p>
    36.  * <p>调用该类须从在activity的onActivityResult获取返回数据,回调数据实例:</p>
    37.  * <pre>
    38.  * protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    39.  *      super.onActivityResult(requestCode, resultCode, data);
    40.  *      if (resultCode == RESULT_OK) {
    41.  *          switch (requestCode) {
    42.  *          case PictureActivityUtil.CAMERA_WITH_DATA: // 拍照返回
    43.  *              PictureActivityUtil.doCropPhoto(UserInfoActivity.this, PictureActivityUtil.CAPTURE_IMAGE_TARGET_PATH);
    44.  *              break;
    45.  *          case PictureActivityUtil.PHOTO_PICKED_WITH_DATA: // 选择相册返回
    46.  *              String path = PictureActivityUtil.getPickPhotoPath(UserInfoActivity.this, data);
    47.  *              PictureActivityUtil.doCropPhoto(UserInfoActivity.this, path);
    48.  *              break;
    49.  *          case PictureActivityUtil.PHOTO_CROP: // 裁剪图片返回
    50.  *              // 获取图片裁剪后路径
    51.  *              String cropPath = Uri.parse(data.getAction()).getPath();
    52.  *              break;
    53.  *          }
    54.         }
    55.  *  }
    56.  *  </pre>
    57.  * @author summer
    58.  * @date 2014年4月30日 下午3:17:26
    59.  */  
    60. public class PictureActivityUtil {  
    61. private static final String TAG = "PictureActivityUtil";  
    62. /**
    63.      * 获取图片压缩后保存的路径
    64.      */  
    65. private static final String COMPRESS_IMAGE_TARGET_DIR = FileUtil.getSDRootPath() + Config.CACHE_FILEDIR_PIC;  
    66. /**
    67.      * 获取照相机保存图片路径
    68.      */  
    69. public static final String CAPTURE_IMAGE_TARGET_PATH = FileUtil.getSDRootPath() + Config.CACHE_FILEDIR_PIC  
    70. "caputure_temp.jpg";  
    71.   
    72. public static final String CROP_IMAGE_TARGET_PATH = FileUtil.getSDRootPath() + Config.CACHE_FILEDIR_PIC;  
    73.   
    74. /**
    75.      * 用来标识请求照相功能的requestCode
    76.      */  
    77. public static final int CAMERA_WITH_DATA = 168;  
    78. /**
    79.      * 用来标识请求相册的requestCode
    80.      */  
    81. public static final int PHOTO_PICKED_WITH_DATA = 169;  
    82. /**
    83.      * 用来标示请求图片裁剪 requestCode
    84.      */  
    85. public static final int PHOTO_CROP = 170;  
    86.   
    87. private static int cut_w; // 裁剪宽度  
    88. private static int cut_h; // 裁剪长度  
    89. private static int mAspectX,mAspectY; //裁剪比例  
    90. private Context mContext;  
    91.   
    92. public PictureActivityUtil(Context mContext) {  
    93. this.mContext = mContext;  
    94.     }  
    95.   
    96. /**
    97.      * 设置裁剪图片尺寸
    98.      * 
    99.      * @param w
    100.      * @param h
    101.      */  
    102. public static void initCutSize(int w, int h) {  
    103.         cut_w = w;  
    104.         cut_h = h;  
    105.     }  
    106. /**
    107.      * 设置裁剪图片尺寸和比例
    108.      * @param w 尺寸
    109.      * @param h
    110.      * @param aspectX 比例
    111.      * @param aspectY
    112.      */  
    113. public static void initCutSize(int w, int h,int aspectX,int aspectY) {  
    114.         cut_w = w;  
    115.         cut_h = h;  
    116.         mAspectX = aspectX;  
    117.         mAspectX = aspectY;  
    118.     }  
    119.   
    120. /**
    121.      * 照片处理入口
    122.      * 开始启动照片选择框
    123.      * @param context
    124.      */  
    125. public static void doPickPhotoAction(final Activity context) {  
    126. final AlertDialog alertDialog = new AlertDialog.Builder(context).create();  
    127.         alertDialog.show();  
    128. true);  
    129.         Window window = alertDialog.getWindow();  
    130.         window.setWindowAnimations(R.style.Animation_Dialog_Bottom);  
    131.         window.setGravity(Gravity.BOTTOM);  
    132.         window.setLayout(LayoutParams.FILL_PARENT,LayoutParams.WRAP_CONTENT);  
    133.         window.setContentView(R.layout.layout_select_image);  
    134.         View view = window.getDecorView();  
    135.           
    136. new OnClickListener() {  
    137.               
    138. @Override  
    139. public void onClick(View v) {  
    140.                 alertDialog.dismiss();  
    141. // 用户点击了从照相机获取  
    142.                   
    143.             }  
    144.         });  
    145. new OnClickListener() {  
    146.               
    147. @Override  
    148. public void onClick(View v) {  
    149.                 alertDialog.dismiss();  
    150. // 从相册中去获取  
    151.             }  
    152.         });  
    153. new OnClickListener() {  
    154.               
    155. @Override  
    156. public void onClick(View v) {  
    157.                 alertDialog.dismiss();  
    158.             }  
    159.         });  
    160.     }  
    161.   
    162. /**
    163.      * 拍照获取图片
    164.      * @param context
    165.      */  
    166. public static void doTakePhoto(Activity context) {  
    167.         String status = Environment.getExternalStorageState();  
    168. if (!status.equals(Environment.MEDIA_MOUNTED)) {// 判断是否有SD卡  
    169. "没有找到SD卡或者正在使用请关闭usb连接模式");  
    170. return;  
    171.         }  
    172. try {  
    173. new Intent(MediaStore.ACTION_IMAGE_CAPTURE);  
    174. new File(CAPTURE_IMAGE_TARGET_PATH)));  
    175.             context.startActivityForResult(intent, CAMERA_WITH_DATA);  
    176. catch (Exception e) {  
    177.             Toast.makeText(context, R.string.photoPickerNotFoundText, Toast.LENGTH_LONG).show();  
    178.                 LogUtil.e(TAG, e.toString());  
    179.         }  
    180.     }  
    181.   
    182. /**
    183.      * 调用相册查看图片
    184.      * @param context
    185.      */  
    186. public static void doPickPhotoFromGallery(Activity context) {  
    187.         String status = Environment.getExternalStorageState();  
    188. if (!status.equals(Environment.MEDIA_MOUNTED)) {// 判断是否有SD卡  
    189. "没有找到SD卡或者正在使用请关闭usb连接模式");  
    190. return;  
    191.         }  
    192. try {  
    193. new Intent(Intent.ACTION_PICK);  
    194. "image/*");  
    195.             context.startActivityForResult(intent, PHOTO_PICKED_WITH_DATA);  
    196. catch (Exception e) {  
    197.             Toast.makeText(context, R.string.photoPickerNotFoundText1, Toast.LENGTH_LONG).show();  
    198.                 e.printStackTrace();  
    199.         }  
    200.     }  
    201.   
    202.     /**  
    203.      * 开始执行裁剪图片操作  
    204.      *   
    205. @param context  
    206. @param path  
    207.      *            图片资源地址  
    208.      */  
    209. public static void doCropPhoto(Activity context, String path) {  
    210. try {  
    211. int outputX = cut_w != 0 ? cut_w : Config.w;  
    212. int outputY = cut_h != 0 ? cut_h : Config.h;  
    213. int aspectX = mAspectX != 0 ? mAspectX : Config.aspectX;  
    214. int aspectY = mAspectY != 0 ? mAspectY : Config.aspectY;  
    215. new Intent(context, CropImage.class);  
    216. "image/*");  
    217. "aspectX", aspectX);  
    218. "aspectY", aspectY);  
    219. "outputX", outputX);  
    220. "outputY", outputY);  
    221. new File(getCropPath());  
    222. if (file.exists()) {  
    223.                 file.delete();  
    224.             }  
    225.             intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file));  
    226. "return-data", false);  
    227. "outputFormat", Bitmap.CompressFormat.JPEG);  
    228. "file://"+path));  
    229.             context.startActivityForResult(intent, PHOTO_CROP);  
    230. catch (Exception e) {  
    231.             Toast.makeText(context, R.string.photoPickerNotFoundText, Toast.LENGTH_LONG).show();  
    232. "裁剪:" + e.toString());  
    233.         }  
    234.     }  
    235.   
    236.   
    237.     /**  
    238.      * 获取选择图片路径  
    239.      *   
    240. @param activity  
    241. @param data  
    242. @return path  
    243.      */  
    244. public static String getPickPhotoPath(Activity activity, Intent data) {  
    245. "";  
    246.         Uri imageuri = data.getData();  
    247. if (null != imageuri && imageuri.getScheme().compareTo("file") == 0) {  
    248. "file://", "");  
    249. else {  
    250. if (imageuri != null) {  
    251.                 String[] proj = { MediaStore.Images.Media.DATA };  
    252. null, null, null);  
    253. int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);  
    254. if (cursor.moveToFirst()) {  
    255.                     path = cursor.getString(column_index);  
    256.                 }  
    257.             }  
    258.         }  
    259. return path;  
    260.     }  
    261.   
    262. /**
    263.      * 压缩图片到指定大小
    264.      * 
    265.      * @param srcPath
    266.      *            返回压缩后图片路径
    267.      * @param targetPath
    268.      *            目标路径
    269.      * @param maxSize
    270.      *            图片允许最大空间 单位:KB(有一定的出入)
    271.      * @return 成功返回true,否则返回false
    272.      */  
    273. private static boolean compressImage(String srcPath, String targetPath, int maxSize) {  
    274.         Bitmap bitmap = BitmapFactory.decodeFile(srcPath);  
    275. if (bitmap == null)  
    276. return false;  
    277.             bitmap = compressImage(bitmap, maxSize);  
    278. try {  
    279. new File(targetPath);  
    280. new FileOutputStream(file);  
    281. if (bitmap.compress(Bitmap.CompressFormat.JPEG, 100, out)) {  
    282.                 out.flush();  
    283.                 out.close();  
    284.             }  
    285. catch (FileNotFoundException e) {  
    286.             e.printStackTrace();  
    287. return false;  
    288. catch (IOException e) {  
    289.             e.printStackTrace();  
    290. return false;  
    291.         }  
    292. return true;// 压缩好比例大小后再进行质量压缩  
    293.     }  
    294.   
    295. /**
    296.      * 压缩图片到指定大小
    297.      * 
    298.      * @param bitmap
    299.      *            源bitmap
    300.      * @param maxSize
    301.      *            图片允许最大空间 单位:KB
    302.      * @return
    303.      */  
    304. private static Bitmap compressImage(Bitmap bitmap, int maxSize) {  
    305.         Bitmap resBitmap = bitmap;  
    306. // 将bitmap放至数组中,意在bitmap的大小(与实际读取的原文件要大)  
    307. new ByteArrayOutputStream();  
    308. 100, baos);  
    309. byte[] b = baos.toByteArray();  
    310. // 将字节换成KB  
    311. double mid = b.length / 1024;  
    312. // 判断bitmap占用空间是否大于允许最大空间 如果大于则压缩 小于则不压缩  
    313. if (mid > maxSize) {  
    314. // 获取bitmap大小 是允许最大大小的多少倍  
    315. double i = mid / maxSize;  
    316. // 开始执行缩放操作  
    317.             resBitmap = zoomImage(resBitmap, resBitmap.getWidth() / Math.sqrt(i), resBitmap.getHeight() / Math.sqrt(i));  
    318.         }  
    319.   
    320. return resBitmap;  
    321.     }  
    322.   
    323. /***
    324.      * 图片的缩放方法
    325.      * 
    326.      * @param bgimage
    327.      *            :源图片资源
    328.      * @param newWidth
    329.      *            :缩放后宽度
    330.      * @param newHeight
    331.      *            :缩放后高度
    332.      * @return
    333.      */  
    334. private static Bitmap zoomImage(Bitmap bgimage, double newWidth, double newHeight) {  
    335. // 获取这个图片的宽和高  
    336. float width = bgimage.getWidth();  
    337. float height = bgimage.getHeight();  
    338. // 创建操作图片用的matrix对象  
    339. new Matrix();  
    340. // 计算宽高缩放率  
    341. float scaleWidth = ((float) newWidth) / width;  
    342. float scaleHeight = ((float) newHeight) / height;  
    343. // 缩放图片动作  
    344.         matrix.postScale(scaleWidth, scaleHeight);  
    345. 0, 0, (int) width, (int) height, matrix, true);  
    346. return bitmap;  
    347.     }  
    348.   
    349. /**
    350.      * 
    351.      * @param context
    352.      * @param resourcePath图片路径
    353.      * 
    354.      */  
    355. /**
    356.      * 开始压缩图片线程 要上传图片放到回调里去处理
    357.      * 
    358.      * @param resourcePath
    359.      *            原图地址
    360.      * @param maxSize
    361.      *            压多大 单位是kb
    362.      * @param icr
    363.      *            回调接口
    364.      */  
    365. public void startCrompressImageTask(String resourcePath, int maxSize, ICompressResult icr) {  
    366. new CompressImageTask(icr, maxSize);  
    367.         imageTask.execute(resourcePath);  
    368.     }  
    369.   
    370. class CompressImageTask extends AsyncTask<String, Void, String> {  
    371.   
    372.         ICompressResult icr;  
    373. int maxSize;  
    374.   
    375. public CompressImageTask(ICompressResult icr, int maxSize) {  
    376. this.icr = icr;  
    377. this.maxSize = maxSize;  
    378.         }  
    379.   
    380. @Override  
    381. protected void onPostExecute(String result) {  
    382. super.onPostExecute(result);  
    383.             AlertUtil.closeProgressDialog();  
    384. if (result != null && icr != null) {  
    385.                 icr.onSuccus(result);  
    386. this.cancel(true);  
    387. else {  
    388. "图片压缩失败");  
    389.             }  
    390.         }  
    391.   
    392. @Override  
    393. protected void onPreExecute() {  
    394. super.onPreExecute();  
    395. "", "正在压缩图片...");  
    396.         }  
    397.   
    398. @Override  
    399. protected String doInBackground(String... params) {  
    400. 0];  
    401. if (path == null) {  
    402. return null; // 裁剪失败  
    403.             }  
    404.             String compressPath = getCompressPath();  
    405. boolean isSuccess = PictureActivityUtil.compressImage(path, compressPath, maxSize);  
    406. if (isSuccess) {  
    407. return compressPath;  
    408.             }  
    409. return null;  
    410.         }  
    411.   
    412.     }  
    413.   
    414. private String getCompressPath() {  
    415. return COMPRESS_IMAGE_TARGET_DIR + "compress_temp_" + System.currentTimeMillis() + ".jpg";  
    416.     }  
    417.   
    418. /**
    419.      * 获取图片裁剪路径
    420.      * 
    421.      * @return
    422.      */  
    423. public static String getCropPath() {  
    424. return CROP_IMAGE_TARGET_PATH + System.currentTimeMillis()+"_crop_temp.jpg";  
    425.     }  
    426.   
    427. /**
    428.      * 压缩回调接口
    429.      * 
    430.      * @author summer
    431.      * 
    432.      */  
    433. public interface ICompressResult {  
    434. /**
    435.          * 压缩成功才调用该方法
    436.          * 
    437.          * @param path
    438.          *            压缩后的图片路径
    439.          */  
    440. void onSuccus(String path);  
    441.     }  
    442. }



     




     

    在activity里使用方法如下:

    1.首先在public void onClick(View v) {      PictureActivityUtil.doPickPhotoAction(MeActivity.this);

    }

    调用选择弹窗截图如下:

    android处理拍照与选择相册并可动态设置是否可裁剪上传解决方案 并且真机测试通过(小米\魔族\htc)sdk2.1-4.x系统..._java

    2.回调的时候在



     

    1. protected void onActivityResult(int requestCode, int resultCode, Intent data) {  
    2. super.onActivityResult(requestCode, resultCode, data);  
    3. if (resultCode == RESULT_OK) {  
    4. switch (requestCode) {  
    5. case PictureActivityUtil.CAMERA_WITH_DATA: // 拍照返回  
    6. this,  
    7.                     PictureActivityUtil.CAPTURE_IMAGE_TARGET_PATH);  
    8. break;  
    9. case PictureActivityUtil.PHOTO_PICKED_WITH_DATA: // 选择相册返回  
    10. this, data);  
    11. this, path);  
    12. break;  
    13. case PictureActivityUtil.PHOTO_CROP: // 裁剪图片返回  
    14. // 获取图片裁剪后路径  
    15.             String cropPath = Uri.parse(data.getAction()).getPath();  
    16.             showPic(cropPath);  
    17. break;  
    18.         }  
    19.     }  
    20. }


     

     

     

    3.上传服务器代码如下:

    /**
      * 上传文件至Server的方法并返回是否上传成功数据
      * 
      * @param uri
      *            服务器请求地址
      * @param netClass
      *            网络类型
      * @param filePath
      *            文件全路径
      * @param fileName
      *            文件名
      * @return
      */
     public static String uploadFileToWebServer(String uri, String netClass,
       String filePath, String fileName) {
      String end = "\r\n";
      String twoHyphens = "--";
      String boundary = "*****";
      String HTTPBody = "";
      try {
       URL url = new URL(uri);
       HttpURLConnection conn = null;
       if (netClass.indexOf("wap") >= 0) {
        String proxyIP = getWAPGatewayIP(netClass);
        Proxy proxy = new Proxy(java.net.Proxy.Type.HTTP,
          new InetSocketAddress(proxyIP, 80));
        conn = (HttpURLConnection) url.openConnection(proxy);
       } else {
        conn = (HttpURLConnection) url.openConnection();
       }
       /* 允许Input、Output,不使用Cache */
       conn.setDoInput(true);
       conn.setDoOutput(true);
       conn.setUseCaches(false);
       /* 设置传送的method=POST */
       conn.setRequestMethod("POST");
       /* setRequestProperty */
       conn.setRequestProperty("Connection", "Keep-Alive");
       conn.setRequestProperty("Charset", "UTF-8");
       conn.setRequestProperty("Content-Type",
         "multipart/form-data;boundary=" + boundary);
       /* 设置DataOutputStream */
       DataOutputStream ds = new DataOutputStream(conn.getOutputStream());
       ds.writeBytes(twoHyphens + boundary + end);
       ds.writeBytes("Content-Disposition: form-data; "
         + "name=\"uploadfile\";filename=\"" + fileName + "\"" + end);
       ds.writeBytes(end);   /* 取得文件的FileInputStream */
       FileInputStream fStream = new FileInputStream(filePath);
       /* 设置每次写入1024bytes */
       int bufferSize = 1024;
       byte[] buffer = new byte[bufferSize];
       int length = -1;
       /* 从文件读取数据至缓冲区 */
       while ((length = fStream.read(buffer)) != -1) {
        /* 将资料写入DataOutputStream中 */
        ds.write(buffer, 0, length);
       }
       ds.writeBytes(end);
       ds.writeBytes(twoHyphens + boundary + twoHyphens + end);
       /* close streams */
       fStream.close();
       ds.flush();
       // 读取返回信息
       InputStream in = conn.getInputStream();
       int ch = 0;
       ByteArrayOutputStream out = new ByteArrayOutputStream();
       while ((ch = in.read()) != -1) {
        out.write(ch);
       }
       HTTPBody = out.toString();
       conn.disconnect();
       in.close();
       out.close();
      } catch (Exception e) {
       HTTPBody = "[数据错误]" + e.getMessage();
      }
      return HTTPBody;
     }

    另外裁剪的代码可以参照android系统源码进行修改!我这儿整理了一个android 原生裁剪的代码库javascript:void(0) 下载导入到项目中可以直接使用,如果不需要集成到自己的代码中可以通过 调用插件的方式使用

    Intent iintent = new Intent();
    iintent.setClassName("com.wavefar.camera","com.wavefar.camera.CropImage"); 这种方式必须先要安装好该插件!

    最后建议以下2种使用方式使用:

    1、以外部引用的方式到自己项目工程中 。

    2、copy相应文件到自己项目工程中。

     

    注意:

     

    有的android 3.0以上的系统默认开启了硬件加速,但裁剪函数里有的不支持,可能报UnsupportedOperationException异常!在注册清单文件里把 裁剪的activity 设置一个禁用硬件加速即可解决android:hardwareAccelerated="false"

    举报
    0 条评论