[java] view
plaincopy
- package org.wavefar.lib.utils;
- import java.io.ByteArrayOutputStream;
- import java.io.File;
- import java.io.FileNotFoundException;
- import java.io.FileOutputStream;
- import java.io.IOException;
- import org.wavefar.lib.Config;
- import org.wavefar.lib.R;
- import org.wavefar.lib.utils.imagecrop.CropImage;
- import android.app.Activity;
- import android.app.AlertDialog;
- import android.content.Context;
- import android.content.Intent;
- import android.database.Cursor;
- import android.graphics.Bitmap;
- import android.graphics.BitmapFactory;
- import android.graphics.Matrix;
- import android.net.Uri;
- import android.os.AsyncTask;
- import android.os.Environment;
- import android.provider.MediaStore;
- import android.view.Gravity;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.view.ViewGroup.LayoutParams;
- import android.view.Window;
- import android.widget.Toast;
- /**
- * 拍照工具类
- * <p>方法:initCutSize裁剪设置(可选)</p>
- * <p>图片入口方法:doPickPhotoAction启动图片和相册筛选</p>
- * <p>调用该类须从在activity的onActivityResult获取返回数据,回调数据实例:</p>
- * <pre>
- * protected void onActivityResult(int requestCode, int resultCode, Intent data) {
- * super.onActivityResult(requestCode, resultCode, data);
- * if (resultCode == RESULT_OK) {
- * switch (requestCode) {
- * case PictureActivityUtil.CAMERA_WITH_DATA: // 拍照返回
- * PictureActivityUtil.doCropPhoto(UserInfoActivity.this, PictureActivityUtil.CAPTURE_IMAGE_TARGET_PATH);
- * break;
- * case PictureActivityUtil.PHOTO_PICKED_WITH_DATA: // 选择相册返回
- * String path = PictureActivityUtil.getPickPhotoPath(UserInfoActivity.this, data);
- * PictureActivityUtil.doCropPhoto(UserInfoActivity.this, path);
- * break;
- * case PictureActivityUtil.PHOTO_CROP: // 裁剪图片返回
- * // 获取图片裁剪后路径
- * String cropPath = Uri.parse(data.getAction()).getPath();
- * break;
- * }
- }
- * }
- * </pre>
- * @author summer
- * @date 2014年4月30日 下午3:17:26
- */
- public class PictureActivityUtil {
- private static final String TAG = "PictureActivityUtil";
- /**
- * 获取图片压缩后保存的路径
- */
- private static final String COMPRESS_IMAGE_TARGET_DIR = FileUtil.getSDRootPath() + Config.CACHE_FILEDIR_PIC;
- /**
- * 获取照相机保存图片路径
- */
- public static final String CAPTURE_IMAGE_TARGET_PATH = FileUtil.getSDRootPath() + Config.CACHE_FILEDIR_PIC
- + "caputure_temp.jpg";
- public static final String CROP_IMAGE_TARGET_PATH = FileUtil.getSDRootPath() + Config.CACHE_FILEDIR_PIC;
- /**
- * 用来标识请求照相功能的requestCode
- */
- public static final int CAMERA_WITH_DATA = 168;
- /**
- * 用来标识请求相册的requestCode
- */
- public static final int PHOTO_PICKED_WITH_DATA = 169;
- /**
- * 用来标示请求图片裁剪 requestCode
- */
- public static final int PHOTO_CROP = 170;
- private static int cut_w; // 裁剪宽度
- private static int cut_h; // 裁剪长度
- private static int mAspectX,mAspectY; //裁剪比例
- private Context mContext;
- public PictureActivityUtil(Context mContext) {
- this.mContext = mContext;
- }
- /**
- * 设置裁剪图片尺寸
- *
- * @param w
- * @param h
- */
- public static void initCutSize(int w, int h) {
- cut_w = w;
- cut_h = h;
- }
- /**
- * 设置裁剪图片尺寸和比例
- * @param w 尺寸
- * @param h
- * @param aspectX 比例
- * @param aspectY
- */
- public static void initCutSize(int w, int h,int aspectX,int aspectY) {
- cut_w = w;
- cut_h = h;
- mAspectX = aspectX;
- mAspectX = aspectY;
- }
- /**
- * 照片处理入口
- * 开始启动照片选择框
- * @param context
- */
- public static void doPickPhotoAction(final Activity context) {
- final AlertDialog alertDialog = new AlertDialog.Builder(context).create();
- alertDialog.show();
- alertDialog.setCanceledOnTouchOutside(true);
- Window window = alertDialog.getWindow();
- window.setWindowAnimations(R.style.Animation_Dialog_Bottom);
- window.setGravity(Gravity.BOTTOM);
- window.setLayout(LayoutParams.FILL_PARENT,LayoutParams.WRAP_CONTENT);
- window.setContentView(R.layout.layout_select_image);
- View view = window.getDecorView();
- view.findViewById(R.id.takePhoto).setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- alertDialog.dismiss();
- doTakePhoto(context);// 用户点击了从照相机获取
- }
- });
- view.findViewById(R.id.pickPhoto).setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- alertDialog.dismiss();
- doPickPhotoFromGallery(context);// 从相册中去获取
- }
- });
- view.findViewById(R.id.cancel).setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- alertDialog.dismiss();
- }
- });
- }
- /**
- * 拍照获取图片
- * @param context
- */
- public static void doTakePhoto(Activity context) {
- String status = Environment.getExternalStorageState();
- if (!status.equals(Environment.MEDIA_MOUNTED)) {// 判断是否有SD卡
- AlertUtil.showToast(context, "没有找到SD卡或者正在使用请关闭usb连接模式");
- return;
- }
- try {
- Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
- intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File(CAPTURE_IMAGE_TARGET_PATH)));
- context.startActivityForResult(intent, CAMERA_WITH_DATA);
- } catch (Exception e) {
- Toast.makeText(context, R.string.photoPickerNotFoundText, Toast.LENGTH_LONG).show();
- LogUtil.e(TAG, e.toString());
- }
- }
- /**
- * 调用相册查看图片
- * @param context
- */
- public static void doPickPhotoFromGallery(Activity context) {
- String status = Environment.getExternalStorageState();
- if (!status.equals(Environment.MEDIA_MOUNTED)) {// 判断是否有SD卡
- AlertUtil.showToast(context, "没有找到SD卡或者正在使用请关闭usb连接模式");
- return;
- }
- try {
- Intent intent = new Intent(Intent.ACTION_PICK);
- intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");
- context.startActivityForResult(intent, PHOTO_PICKED_WITH_DATA);
- } catch (Exception e) {
- Toast.makeText(context, R.string.photoPickerNotFoundText1, Toast.LENGTH_LONG).show();
- e.printStackTrace();
- }
- }
- /**
- * 开始执行裁剪图片操作
- *
- * @param context
- * @param path
- * 图片资源地址
- */
- public static void doCropPhoto(Activity context, String path) {
- try {
- int outputX = cut_w != 0 ? cut_w : Config.w;
- int outputY = cut_h != 0 ? cut_h : Config.h;
- int aspectX = mAspectX != 0 ? mAspectX : Config.aspectX;
- int aspectY = mAspectY != 0 ? mAspectY : Config.aspectY;
- Intent intent = new Intent(context, CropImage.class);
- intent.setType("image/*");
- intent.putExtra("aspectX", aspectX);
- intent.putExtra("aspectY", aspectY);
- intent.putExtra("outputX", outputX);
- intent.putExtra("outputY", outputY);
- File file = new File(getCropPath());
- if (file.exists()) {
- file.delete();
- }
- intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file));
- intent.putExtra("return-data", false);
- intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG);
- intent.setData(Uri.parse("file://"+path));
- context.startActivityForResult(intent, PHOTO_CROP);
- } catch (Exception e) {
- Toast.makeText(context, R.string.photoPickerNotFoundText, Toast.LENGTH_LONG).show();
- LogUtil.e(TAG, "裁剪:" + e.toString());
- }
- }
- /**
- * 获取选择图片路径
- *
- * @param activity
- * @param data
- * @return path
- */
- public static String getPickPhotoPath(Activity activity, Intent data) {
- String path = "";
- Uri imageuri = data.getData();
- if (null != imageuri && imageuri.getScheme().compareTo("file") == 0) {
- path = imageuri.toString().replace("file://", "");
- } else {
- if (imageuri != null) {
- String[] proj = { MediaStore.Images.Media.DATA };
- Cursor cursor = activity.managedQuery(imageuri, proj, null, null, null);
- int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
- if (cursor.moveToFirst()) {
- path = cursor.getString(column_index);
- }
- }
- }
- return path;
- }
- /**
- * 压缩图片到指定大小
- *
- * @param srcPath
- * 返回压缩后图片路径
- * @param targetPath
- * 目标路径
- * @param maxSize
- * 图片允许最大空间 单位:KB(有一定的出入)
- * @return 成功返回true,否则返回false
- */
- private static boolean compressImage(String srcPath, String targetPath, int maxSize) {
- Bitmap bitmap = BitmapFactory.decodeFile(srcPath);
- if (bitmap == null)
- return false;
- bitmap = compressImage(bitmap, maxSize);
- try {
- File file = new File(targetPath);
- FileOutputStream out = new FileOutputStream(file);
- if (bitmap.compress(Bitmap.CompressFormat.JPEG, 100, out)) {
- out.flush();
- out.close();
- }
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- return false;
- } catch (IOException e) {
- e.printStackTrace();
- return false;
- }
- return true;// 压缩好比例大小后再进行质量压缩
- }
- /**
- * 压缩图片到指定大小
- *
- * @param bitmap
- * 源bitmap
- * @param maxSize
- * 图片允许最大空间 单位:KB
- * @return
- */
- private static Bitmap compressImage(Bitmap bitmap, int maxSize) {
- Bitmap resBitmap = bitmap;
- // 将bitmap放至数组中,意在bitmap的大小(与实际读取的原文件要大)
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- resBitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
- byte[] b = baos.toByteArray();
- // 将字节换成KB
- double mid = b.length / 1024;
- // 判断bitmap占用空间是否大于允许最大空间 如果大于则压缩 小于则不压缩
- if (mid > maxSize) {
- // 获取bitmap大小 是允许最大大小的多少倍
- double i = mid / maxSize;
- // 开始执行缩放操作
- resBitmap = zoomImage(resBitmap, resBitmap.getWidth() / Math.sqrt(i), resBitmap.getHeight() / Math.sqrt(i));
- }
- return resBitmap;
- }
- /***
- * 图片的缩放方法
- *
- * @param bgimage
- * :源图片资源
- * @param newWidth
- * :缩放后宽度
- * @param newHeight
- * :缩放后高度
- * @return
- */
- private static Bitmap zoomImage(Bitmap bgimage, double newWidth, double newHeight) {
- // 获取这个图片的宽和高
- float width = bgimage.getWidth();
- float height = bgimage.getHeight();
- // 创建操作图片用的matrix对象
- Matrix matrix = new Matrix();
- // 计算宽高缩放率
- float scaleWidth = ((float) newWidth) / width;
- float scaleHeight = ((float) newHeight) / height;
- // 缩放图片动作
- matrix.postScale(scaleWidth, scaleHeight);
- Bitmap bitmap = Bitmap.createBitmap(bgimage, 0, 0, (int) width, (int) height, matrix, true);
- return bitmap;
- }
- /**
- *
- * @param context
- * @param resourcePath图片路径
- *
- */
- /**
- * 开始压缩图片线程 要上传图片放到回调里去处理
- *
- * @param resourcePath
- * 原图地址
- * @param maxSize
- * 压多大 单位是kb
- * @param icr
- * 回调接口
- */
- public void startCrompressImageTask(String resourcePath, int maxSize, ICompressResult icr) {
- CompressImageTask imageTask = new CompressImageTask(icr, maxSize);
- imageTask.execute(resourcePath);
- }
- class CompressImageTask extends AsyncTask<String, Void, String> {
- ICompressResult icr;
- int maxSize;
- public CompressImageTask(ICompressResult icr, int maxSize) {
- this.icr = icr;
- this.maxSize = maxSize;
- }
- @Override
- protected void onPostExecute(String result) {
- super.onPostExecute(result);
- AlertUtil.closeProgressDialog();
- if (result != null && icr != null) {
- icr.onSuccus(result);
- this.cancel(true);
- } else {
- AlertUtil.showToast(mContext, "图片压缩失败");
- }
- }
- @Override
- protected void onPreExecute() {
- super.onPreExecute();
- AlertUtil.showProgressDialog(mContext, "", "正在压缩图片...");
- }
- @Override
- protected String doInBackground(String... params) {
- String path = params[0];
- if (path == null) {
- return null; // 裁剪失败
- }
- String compressPath = getCompressPath();
- boolean isSuccess = PictureActivityUtil.compressImage(path, compressPath, maxSize);
- if (isSuccess) {
- return compressPath;
- }
- return null;
- }
- }
- private String getCompressPath() {
- return COMPRESS_IMAGE_TARGET_DIR + "compress_temp_" + System.currentTimeMillis() + ".jpg";
- }
- /**
- * 获取图片裁剪路径
- *
- * @return
- */
- public static String getCropPath() {
- return CROP_IMAGE_TARGET_PATH + System.currentTimeMillis()+"_crop_temp.jpg";
- }
- /**
- * 压缩回调接口
- *
- * @author summer
- *
- */
- public interface ICompressResult {
- /**
- * 压缩成功才调用该方法
- *
- * @param path
- * 压缩后的图片路径
- */
- void onSuccus(String path);
- }
- }
在activity里使用方法如下:
1.首先在public void onClick(View v) { PictureActivityUtil.doPickPhotoAction(MeActivity.this);
}
调用选择弹窗截图如下:
2.回调的时候在
[java] view
plaincopy
- protected void onActivityResult(int requestCode, int resultCode, Intent data) {
- super.onActivityResult(requestCode, resultCode, data);
- if (resultCode == RESULT_OK) {
- switch (requestCode) {
- case PictureActivityUtil.CAMERA_WITH_DATA: // 拍照返回
- PictureActivityUtil.doCropPhoto(this,
- PictureActivityUtil.CAPTURE_IMAGE_TARGET_PATH);
- break;
- case PictureActivityUtil.PHOTO_PICKED_WITH_DATA: // 选择相册返回
- String path = PictureActivityUtil.getPickPhotoPath(this, data);
- PictureActivityUtil.doCropPhoto(this, path);
- break;
- case PictureActivityUtil.PHOTO_CROP: // 裁剪图片返回
- // 获取图片裁剪后路径
- String cropPath = Uri.parse(data.getAction()).getPath();
- showPic(cropPath);
- break;
- }
- }
- }
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 原生裁剪的代码库http://download.csdn.net/detail/xia296/8019117 下载导入到项目中可以直接使用,如果不需要集成到自己的代码中可以通过
调用插件的方式使用
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"