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);
}
调用选择弹窗截图如下:
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"