android 图片剪裁

合集下载

android crop用法

android crop用法

android crop用法在Android 中,要裁剪(crop)图像,一种常见的方式是使用系统内置的裁剪工具或通过使用第三方库实现。

以下是两种常见的方法:方法1: 使用系统内置的裁剪工具1. 启动裁剪意图:```javaIntent cropIntent = new Intent("com.android.camera.action.CROP");cropIntent.setDataAndType(uri, "image/*");cropIntent.putExtra("crop", "true");cropIntent.putExtra("aspectX", 1);cropIntent.putExtra("aspectY", 1);cropIntent.putExtra("outputX", 256);cropIntent.putExtra("outputY", 256);cropIntent.putExtra("return-data", true);startActivityForResult(cropIntent, CROP_REQUEST_CODE);```在上述代码中,`uri` 是原始图像的URI,`aspectX` 和`aspectY` 表示裁剪框的宽高比,`outputX` 和`outputY` 表示裁剪后输出图像的宽高。

2. 处理裁剪结果:```java@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {if (requestCode == CROP_REQUEST_CODE && resultCode == RESULT_OK) {Bundle extras = data.getExtras();if (extras != null) {Bitmap croppedBitmap = extras.getParcelable("data");// 处理裁剪后的图像}}}```方法2: 使用第三方库在Android 中,你还可以使用一些第三方库来简化裁剪操作,例如`UCrop`。

Android图片裁剪功能实现代码

Android图片裁剪功能实现代码

Android图⽚裁剪功能实现代码在Android应⽤中,图⽚裁剪也是⼀个经常⽤到的功能。

Android系统中可以⽤隐式意图调⽤系统应⽤进⾏裁剪,但是这样做在不同的⼿机可能表现出不同的效果,甚⾄在某些奇葩⼿机上还会出其他更奇怪的问题,所以调⽤系统功能进⾏图⽚裁剪在很多时候对我们来说并不是⼀个好的选择。

这时候就需要我们⾃⼰去实现这种裁剪功能了。

功能分析要完成图⽚裁剪的功能,我们需要先知道图⽚裁剪的功能有哪些。

图⽚裁剪之前,我们需要有⼀个框指⽰我们需要裁剪的样式合⼤⼩。

图⽚显⽰出来后⼤⼩和位置可能并不是我们所期望的,所以我们还需要对图⽚进⾏移动、缩放等操作。

确定好位置和⼤⼩后,我们需要真正的对图⽚进⾏裁剪,并将裁剪的图⽚存起来以供使⽤。

也就是说需要实现图⽚裁剪的功能细分后如下:1、显⽰指⽰框2、图⽚移动和缩放3、图⽚裁剪并保存最终效果展⽰如下:功能实现显⽰指⽰框要实现显⽰⼀个如上图⼀样的指⽰框有很多⽅法,这⾥实现的⽅式是⽤⾃定义的Drawable作为View的背景,然后将这个View 覆盖在原图⽚上作为指⽰框。

为了在⼀定程度上满⾜更多的要求,我们让指⽰框可设置为矩形也可设置为圆形,阴影区域的颜⾊也可设置。

要绘制出作为指⽰的图层,我们可以将它拆分成两半,变成两个封闭的Path进⾏绘制,也可以先绘制出半透明的覆盖层,然后在中间裁剪⼀个洞。

显然,要考虑到这个洞的形状⼤⼩并不是固定的,裁剪的⽅式⽐拆分成两个封闭的Path要简单多了。

Canvas的canvas.clipPath(Path, Region.Op);⽅法,可以对Canvas进⾏裁剪,可以很容易得到这样的指⽰框。

然⽽Canvas的clipPath裁剪出来的曲线图形会有锯齿,我多番尝试都没能去掉锯齿,所以不得不放弃这个⽅法。

继⽽利⽤paint的paint.setXfermode(new PorterDuffXfermode(mode))⽅法来实现这个效果。

Android中自定义图片的裁剪形状

Android中自定义图片的裁剪形状
• 构造方法: • mBitmapShader = new BitmapShader(bitmap, TileMode.CLAMP, TileMode.CLAMP); • 参数1:bitmap • 参数2、参数3:TileMode; • TileMode的取值有三种:CLAMP 拉伸、REPEAT 重复、MIRROR 镜像 • 重复:就是横向、纵向不断重复这个bitmap • 镜像:横向不断翻转重复,纵向不断翻转重复; • 拉伸:拉伸图片最后一个像素;横向的最后一个横行像素,不断的重复,纵项的那一 列像素,不断的重复;
Android中自定义图片的 裁剪形状
Android中的ImageView | 问题描述
2
问题描述
如何显示类似左图中所示的椭圆形图片? 如何根据需要显示各种形状的图片?
Android中的ImageView | 问题解s/drawable中添加需要绘制的图片(原图如下所示)
Android中的ImageView | 小结
9
Shape的继承关系
6
问题解决方案
视图类ShapesOfImgs重写父类的onDraw方法如下:
Android中的ImageView | 问题解决方案
7
问题解决方案
最后,在src目录包中修改MainActivity.java:
Android中的ImageView | 小结
8
各种形状的ImageView
• 实现各种形状的ImageView要用到BitmapShader类 • BitmapShader是Shader的子类,可以通过Paint.setShader(Shader shader)进行设置、
Android中的ImageView | 问题解决方案

Android图片裁剪功能实现详解

Android图片裁剪功能实现详解

Android图片裁剪功能实现详解最近有看到有朋友在讨论QQ头像的裁剪上传是怎么实现的,吼吼,小马也没做过,好奇之下学习下,发现以前项目中有类型的功能,结合官方文档里面的解释,就更好玩了,周末,急急忙忙写的,记录在博客里,希望能与大家交流学习,也恳请高手能解答小马在代码注释中提出的疑问,不管有没有人回答,小马先谢谢了,一样的,先看下效果图(效果图小马不解释了,直接流水写下去,小马是直接在模拟器里写的,能在真机上使用,因为很简单),再看代码是怎么实现的:一:主布局界面二:点击控件触发事件后效果图三:拍照完之后效果图四:裁剪界面效果图五:点击相册后返回的图片效果图六:裁剪完从相册PICK的保存后的效果图下面直接来看下主控制类代码,如下:1. package com.xiaoma.piccut.demo;2.3. import java.io.File;4. import android.app.Activity;5. import android.app.AlertDialog;6. import android.content.DialogInterface;7. import android.content.Intent;8. import android.graphics.Bitmap;9. import android.graphics.drawable.BitmapDrawable;10. import android.graphics.drawable.Drawable;11. import .Uri;12. import android.os.Bundle;13. import android.os.Environment;14. import android.provider.MediaStore;15. import android.view.View;16. import android.view.View.OnClickListener;17. import android.widget.Button;18. import android.widget.ImageButton;19. import android.widget.ImageView;20. /**21. * @Title: PicCutDemoActivity.java22. * @Package com.xiaoma.piccut.demo23. * @Description: 图片裁剪功能测试24. * @author XiaoMa25. */26. public class PicCutDemoActivity extends Activity implements OnClickListener {27.28. private ImageButton ib = null;29. private ImageView iv = null;30. private Button btn = null;31. private String tp = null;32.33.34. /** Called when the activity is first created. */35. @Override36. public void onCreate(Bundle savedInstanceState) {37. super.onCreate(savedInstanceState);38. setContentView(yout.main);39. //初始化40. init();41. }42.43. /**44. * 初始化方法实现45. */46. private void init() {47. ib = (ImageButton) findViewById(R.id.imageButton1);48. iv = (ImageView) findViewById(R.id.imageView1);49. btn = (Button) findViewById(R.id.button1);50. ib.setOnClickListener(this);51. iv.setOnClickListener(this);52. btn.setOnClickListener(this);53. }54.55.56. /**57. * 控件点击事件实现58. *59. * 因为有朋友问不同控件的背景图裁剪怎么实现,60. * 我就在这个地方用了三个控件,只为了自己记录学习61. * 大家觉得没用的可以跳过啦62. */63. @Override64. public void onClick(View v) {65. switch (v.getId()) {66. case R.id.imageButton1:67. ShowPickDialog();68. break;69. case R.id.imageView1:70. ShowPickDialog();71. break;72. case R.id.button1:73. ShowPickDialog();74. break;75.76. default:77. break;78. }79. }80.81. /**82. * 选择提示对话框83. */84. private void ShowPickDialog() {85. new AlertDialog.Builder(this)86. .setTitle("设置头像...")87. .setNegativeButton("相册", new DialogInterface.OnClickListener() {88. public void onClick(DialogInterface dialog, int which) {89. dialog.dismiss();90. /**91. * 刚开始,我自己也不知道ACTION_PICK是干嘛的,后来直接看Intent源码,92. * 可以发现里面很多东西,Intent是个很强大的东西,大家一定仔细阅读下93. */94. Intent intent = new Intent(Intent.ACTION_PICK, null);95.96. /**97. * 下面这句话,与其它方式写是一样的效果,如果:98. * intent.setData(MediaStore.Images.Media.EXTERNAL_CONTENT_URI);99. * intent.setType(""image/*");设置数据类型100. * 如果朋友们要限制上传到服务器的图片类型时可以直接写如:"image/jpeg 、 image/png等的类型" 101. * 这个地方小马有个疑问,希望高手解答下:就是这个数据URI与类型为什么要分两种形式来写呀?有什么区别?102. */103. intent.setDataAndType(104. MediaStore.Images.Media.EXTERNAL_CONTENT_URI,105. "image/*");106. startActivityForResult(intent, 1);107.108. }109. })110. .setPositiveButton("拍照", new DialogInterface.OnClickListener() {111. public void onClick(DialogInterface dialog, int whichButton) {112. dialog.dismiss();113. /**114. * 下面这句还是老样子,调用快速拍照功能,至于为什么叫快速拍照,大家可以参考如下官方115. * 文档,you_sdk_path/docs/guide/topics/media/camera.html116. * 我刚看的时候因为太长就认真看,其实是错的,这个里面有用的太多了,所以大家不要认为117. * 官方文档太长了就不看了,其实是错的,这个地方小马也错了,必须改正118. */119. Intent intent = new Intent(120. MediaStore.ACTION_IMAGE_CAPTURE);121. //下面这句指定调用相机拍照后的照片存储的路径122. intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri123. .fromFile(new File(Environment124. .getExternalStorageDirectory(),125. "xiaoma.jpg")));126. startActivityForResult(intent, 2);127. }128. }).show();129. }130.131. @Override132. protected void onActivityResult(int requestCode, int resultCode, Intent data) {133. switch (requestCode) {134. // 如果是直接从相册获取135. case 1:136. startPhotoZoom(data.getData());137. break;138. // 如果是调用相机拍照时139. case 2:140. File temp = new File(Environment.getExternalStorageDirectory()141. + "/xiaoma.jpg");142. startPhotoZoom(Uri.fromFile(temp));143. break;144. // 取得裁剪后的图片145. case 3:146. /**147. * 非空判断大家一定要验证,如果不验证的话,148. * 在剪裁之后如果发现不满意,要重新裁剪,丢弃149. * 当前功能时,会报NullException,小马只150. * 在这个地方加下,大家可以根据不同情况在合适的151. * 地方做判断处理类似情况152. *153. */154. if(data != null){155. setPicToView(data);156. }157. break;158. default:159. break;160.161. }162. super.onActivityResult(requestCode, resultCode, data);163. }164.165. /**166. * 裁剪图片方法实现167. * @param uri168. */169. public void startPhotoZoom(Uri uri) {170. /*171. * 至于下面这个Intent的ACTION是怎么知道的,大家可以看下自己路径下的如下网页172. * yourself_sdk_path/docs/reference/android/content/Intent.html173. * 直接在里面Ctrl+F搜:CROP ,之前小马没仔细看过,其实安卓系统早已经有自带图片裁剪功能, 174. * 是直接调本地库的,小马不懂C C++ 这个不做详细了解去了,有轮子就用轮子,不再研究轮子是怎么175. * 制做的了...吼吼176. */177. Intent intent = new Intent("com.android.camera.action.CROP");178. intent.setDataAndType(uri, "image/*");179. //下面这个crop=true是设置在开启的Intent中设置显示的VIEW可裁剪180. intent.putExtra("crop", "true");181. // aspectX aspectY 是宽高的比例182. intent.putExtra("aspectX", 1);183. intent.putExtra("aspectY", 1);184. // outputX outputY 是裁剪图片宽高185. intent.putExtra("outputX", 150);186. intent.putExtra("outputY", 150);187. intent.putExtra("return-data", true);188. startActivityForResult(intent, 3);189. }190.191. /**192. * 保存裁剪之后的图片数据193. * @param picdata194. */195. private void setPicToView(Intent picdata) {196. Bundle extras = picdata.getExtras();197. if (extras != null) {198. Bitmap photo = extras.getParcelable("data");199. Drawable drawable = new BitmapDrawable(photo);200.201. /**202. * 下面注释的方法是将裁剪之后的图片以Base64Coder的字符方式上203. * 传到服务器,QQ头像上传采用的方法跟这个类似204. */205.206. /*ByteArrayOutputStream stream = new ByteArrayOutputStream();207. press(pressFormat.JPEG, 60, stream);208. byte[] b = stream.toByteArray();209. // 将图片流以字符串形式存储下来210.211. tp = new String(Base64Coder.encodeLines(b));212. 这个地方大家可以写下给服务器上传图片的实现,直接把tp直接上传就可以了,213. 服务器处理的方法是服务器那边的事了,吼吼214.215. 如果下载到的服务器的数据还是以Base64Coder的形式的话,可以用以下方式转换216. 为我们可以用的图片类型就OK啦...吼吼217. Bitmap dBitmap = BitmapFactory.decodeFile(tp);218. Drawable drawable = new BitmapDrawable(dBitmap);219. */220. ib.setBackgroundDrawable(drawable);221. iv.setBackgroundDrawable(drawable);222. }223. }224.225. }下面来看下裁剪中用到的类,大家详细看下头注释:1. package com.xiaoma.piccut.demo;2.3.4.5.6. /**7. * 下面这些注释是下载这个类的时候本来就有的,本来要删除的,但看了下竟然是license,吼吼,8. * 好东西,留在注释里,以备不时之用,大家有需要加license的可以到下面的网址找哦9. */9. */10.11. //EPL, Eclipse Public License, V1.0 or later, /legal12. //LGPL, GNU Lesser General Public License, V2.1 or later, /licenses/lgpl.html13. //GPL, GNU General Public License, V2 or later, /licenses/gpl.html14. //AL, Apache License, V2.0 or later, /licenses15. //BSD, BSD License, /licenses/bsd-license.php16. /**17. * A Base64 encoder/decoder.18. *19. * <p>20. * This class is used to encode and decode data in Base64 format as described in RFC 1521.21. *22. * <p>23. * Project home page: <a href="/base64coder/java/">/base64coder/java</a><br>24. * Author: Christian d'Heureuse, Inventec Informatik AG, Zurich, Switzerland<br>25. * Multi-licensed: EPL / LGPL / GPL / AL / BSD.26. */27.28. /**29. * 这个类在上面注释的网址中有,大家可以自行下载下,也可以直接用这个,30. * 公开的Base64Coder类(不用深究它是怎么实现的,31. * 还是那句话,有轮子直接用轮子),好用的要死人了...32. * 小马也很无耻的引用了这个网址下的东东,吼吼...33. * @Title: Base64Coder.java34. * @Package com.xiaoma.piccut.demo35. * @Description: TODO36. * @author XiaoMa37. */38.39. public class Base64Coder {40.41. //The line separator string of the operating system.42. private static final String systemLineSeparator = System.getProperty("line.separator");43.44. //Mapping table from 6-bit nibbles to Base64 characters.45. private static char[] map1 = new char[64];46. static {47. int i=0;48. for (char c='A'; c<='Z'; c++) map1[i++] = c;49. for (char c='a'; c<='z'; c++) map1[i++] = c;50. for (char c='0'; c<='9'; c++) map1[i++] = c;51. map1[i++] = '+'; map1[i++] = '/'; }52.53. //Mapping table from Base64 characters to 6-bit nibbles.54. private static byte[] map2 = new byte[128];55. static {56. for (int i=0; i<map2.length; i++) map2[i] = -1;57. for (int i=0; i<64; i++) map2[map1[i]] = (byte)i; }58.59. /**60. * Encodes a string into Base64 format.61. * No blanks or line breaks are inserted.62. * @param s A String to be encoded.63. * @return A String containing the Base64 encoded data.64. */65. public static String encodeString (String s) {66. return new String(encode(s.getBytes())); }67.68. /**69. * Encodes a byte array into Base 64 format and breaks the output into lines of 76 characters.70. * This method is compatible with <code>sun.misc.BASE64Encoder.encodeBuffer(byte[])</code>.71. * @param in An array containing the data bytes to be encoded.72. * @return A String containing the Base64 encoded data, broken into lines.73. */74. public static String encodeLines (byte[] in) {75. return encodeLines(in, 0, in.length, 76, systemLineSeparator); }76.77. /**78. * Encodes a byte array into Base 64 format and breaks the output into lines.79. * @param in An array containing the data bytes to be encoded.80. * @param iOff Offset of the first byte in <code>in</code> to be processed.81. * @param iLen Number of bytes to be processed in <code>in</code>, starting at <code>iOff</code>.82. * @param lineLen Line length for the output data. Should be a multiple of 4.83. * @param lineSeparator The line separator to be used to separate the output lines.84. * @return A String containing the Base64 encoded data, broken into lines.85. */86. public static String encodeLines (byte[] in, int iOff, int iLen, int lineLen, String lineSeparator) {87. int blockLen = (lineLen*3) / 4;88. if (blockLen <= 0) throw new IllegalArgumentException();89. int lines = (iLen+blockLen-1) / blockLen;90. int bufLen = ((iLen+2)/3)*4 + lines*lineSeparator.length();91. StringBuilder buf = new StringBuilder(bufLen);92. int ip = 0;93. while (ip < iLen) {94. int l = Math.min(iLen-ip, blockLen);95. buf.append (encode(in, iOff+ip, l));96. buf.append (lineSeparator);97. ip += l; }98. return buf.toString(); }99.100. /**101. * Encodes a byte array into Base64 format.102. * No blanks or line breaks are inserted in the output.103. * @param in An array containing the data bytes to be encoded.104. * @return A character array containing the Base64 encoded data.105. */106. public static char[] encode (byte[] in) {107. return encode(in, 0, in.length); }108.109. /**110. * Encodes a byte array into Base64 format.111. * No blanks or line breaks are inserted in the output.112. * @param in An array containing the data bytes to be encoded.113. * @param iLen Number of bytes to process in <code>in</code>.114. * @return A character array containing the Base64 encoded data.115. */116. public static char[] encode (byte[] in, int iLen) {117. return encode(in, 0, iLen); }118.119. /**120. * Encodes a byte array into Base64 format.121. * No blanks or line breaks are inserted in the output.122. * @param in An array containing the data bytes to be encoded.123. * @param iOff Offset of the first byte in <code>in</code> to be processed.124. * @param iLen Number of bytes to process in <code>in</code>, starting at <code>iOff</code>.125. * @return A character array containing the Base64 encoded data.126. */127. public static char[] encode (byte[] in, int iOff, int iLen) {128. int oDataLen = (iLen*4+2)/3; // output length without padding129. int oLen = ((iLen+2)/3)*4; // output length including padding130. char[] out = new char[oLen];131. int ip = iOff;132. int iEnd = iOff + iLen;133. int op = 0;134. while (ip < iEnd) {135. int i0 = in[ip++] & 0xff;136. int i1 = ip < iEnd ? in[ip++] & 0xff : 0;137. int i2 = ip < iEnd ? in[ip++] & 0xff : 0;138. int o0 = i0 >>> 2;139. int o1 = ((i0 & 3) << 4) | (i1 >>> 4);140. int o2 = ((i1 & 0xf) << 2) | (i2 >>> 6);141. int o3 = i2 & 0x3F;142. out[op++] = map1[o0];143. out[op++] = map1[o1];144. out[op] = op < oDataLen ? map1[o2] : '='; op++;145. out[op] = op < oDataLen ? map1[o3] : '='; op++; }146. return out; }147.148. /**149. * Decodes a string from Base64 format.150. * No blanks or line breaks are allowed within the Base64 encoded input data.151. * @param s A Base64 String to be decoded.152. * @return A String containing the decoded data.153. * @throws IllegalArgumentException If the input is not valid Base64 encoded data.154. */155. public static String decodeString (String s) {156. return new String(decode(s)); }157.158. /**159. * Decodes a byte array from Base64 format and ignores line separators, tabs and blanks. 160. * CR, LF, Tab and Space characters are ignored in the input data.161. * This method is compatible with <code>sun.misc.BASE64Decoder.decodeBuffer(String)</code>. 162. * @param s A Base64 String to be decoded.163. * @return An array containing the decoded data bytes.164. * @throws IllegalArgumentException If the input is not valid Base64 encoded data.165. */166. public static byte[] decodeLines (String s) {167. char[] buf = new char[s.length()+3];168. int p = 0;169. for (int ip = 0; ip < s.length(); ip++) {170. char c = s.charAt(ip);171. if (c != ' ' && c != '\r' && c != '\n' && c != '\t')172. buf[p++] = c; }173. while ((p % 4) != 0)174. buf[p++] = '0';175.176. return decode(buf, 0, p); }177.178. /**179. * Decodes a byte array from Base64 format.180. * No blanks or line breaks are allowed within the Base64 encoded input data.181. * @param s A Base64 String to be decoded.182. * @return An array containing the decoded data bytes.183. * @throws IllegalArgumentException If the input is not valid Base64 encoded data.184. */185. public static byte[] decode (String s) {186. return decode(s.toCharArray()); }187.188. /**189. * Decodes a byte array from Base64 format.190. * No blanks or line breaks are allowed within the Base64 encoded input data.191. * @param in A character array containing the Base64 encoded data.192. * @return An array containing the decoded data bytes.193. * @throws IllegalArgumentException If the input is not valid Base64 encoded data.194. */195. public static byte[] decode (char[] in) {196. return decode(in, 0, in.length); }197.198. /**199. * Decodes a byte array from Base64 format.200. * No blanks or line breaks are allowed within the Base64 encoded input data.201. * @param in A character array containing the Base64 encoded data.202. * @param iOff Offset of the first character in <code>in</code> to be processed.203. * @param iLen Number of characters to process in <code>in</code>, starting at <code>iOff</code>.204. * @return An array containing the decoded data bytes.205. * @throws IllegalArgumentException If the input is not valid Base64 encoded data.206. */207. public static byte[] decode (char[] in, int iOff, int iLen) {208. if (iLen%4 != 0) throw new IllegalArgumentException ("Length of Base64 encoded input string is not a multiple of 4."); 209. while (iLen > 0 && in[iOff+iLen-1] == '=') iLen--;210. int oLen = (iLen*3) / 4;211. byte[] out = new byte[oLen];212. int ip = iOff;213. int iEnd = iOff + iLen;214. int op = 0;215. while (ip < iEnd) {216. int i0 = in[ip++];217. int i1 = in[ip++];218. int i2 = ip < iEnd ? in[ip++] : 'A';219. int i3 = ip < iEnd ? in[ip++] : 'A';220. if (i0 > 127 || i1 > 127 || i2 > 127 || i3 > 127)221. throw new IllegalArgumentException ("Illegal character in Base64 encoded data.");222. int b0 = map2[i0];223. int b1 = map2[i1];224. int b2 = map2[i2];225. int b3 = map2[i3];226. if (b0 < 0 || b1 < 0 || b2 < 0 || b3 < 0)227. throw new IllegalArgumentException ("Illegal character in Base64 encoded data.");228. int o0 = ( b0 <<2) | (b1>>>4);229. int o1 = ((b1 & 0xf)<<4) | (b2>>>2);230. int o2 = ((b2 & 3)<<6) | b3;231. out[op++] = (byte)o0;232. if (op<oLen) out[op++] = (byte)o1;233. if (op<oLen) out[op++] = (byte)o2; }234. return out; }235.236. //Dummy constructor.237. private Base64Coder() {}238.239. } // end class Base64Coder最后,小马还把小DEMO源码放在附件里面,有需要的朋友可以下载下来,共同交流学习,也恳请高人回答下小马在文章注释中提出的问题,谢谢,文章是小马急急忙忙在家写的,在网吧发的,晕...不是我有多用功,这边下雨,讨厌下雨,下雨我就郁闷,来网吧玩的,顺带发下文章,吼吼,该玩的时候死命的玩,该工作的时候死命的工作,年轻时疯狂,老了不后悔,吼吼,加油加油!大家工作,也注意身体健康,嘿嘿,你懂的,不解释...哈哈。

Android拍照剪裁功能实现步骤详解

Android拍照剪裁功能实现步骤详解
<!--ᆙᇆ਻࢏--> <LinearLayout
android:id="@+id/box_pic" android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="200dp" android:padding="4dp"> <ImageView
import java.text.SimpleDateFormat; import java.util.Date;
/** * ૡٍᔄ * Created by ਃည຋ on 2016/6/15. */
public class Utils {
/** * ᧣ᦶ‫௳מ‬ᬌ‫ڊ‬ * @param context * @param msg
if (requestCode==Cons.SELECT_PIC_BY_TACK_PHOTO && resultCode== RESULT_OK ){// ೌᆙ౮‫ ۑ‬RESULT_OK= -1 // ੒ᆙᇆᬰᤈ‫ۄ‬᤮‫ے‬ૡ startPhotoZoom(Uri.fromFile(tempFile), 150);
}
10 Ⴒ‫ے‬ଉᰁᔄ
package spl.example.takepicture;
/** * ଉᰁᔄ * @author ਃည຋ * */
public class Cons {
/** ֵአᆙፘ๢ೌᆙ឴‫ࢶݐ‬ᇆ */ public static final int SELECT_PIC_BY_TACK_PHOTO = 1; /** ֵአፘٙӾጱࢶᇆ */ public static final int SELECT_PIC_FROM_ALBUM = 2;

移动应用开发中的图片处理与特效技巧

移动应用开发中的图片处理与特效技巧

移动应用开发中的图片处理与特效技巧在移动应用开发中,图片处理与特效的运用是非常重要的一环。

通过合理的图片处理与特效技巧,可以提升用户的使用体验,增加应用的吸引力和竞争力。

本文将探讨一些常见的图片处理和特效技巧,帮助开发者们打造更加出色的移动应用。

一、图片处理技巧1. 图片压缩:移动应用的图片资源通常需要在小尺寸的屏幕上显示,并且需要快速加载。

因此,对图片进行压缩是常见的处理方式。

开发者可以通过减少图片的尺寸和色彩深度来降低图片大小,从而减小应用的体积和加载时间。

同时,利用现代的图片压缩算法,可以保证对图片质量的最小损失。

2. 图片裁剪和缩放:有时候,原始图片并不直接适配应用的需要。

开发者可以通过裁剪或者缩放图片来满足应用的设计要求。

比如,通过裁剪一张长图,可以将其变成一组小图片,并通过滑动效果来展示。

而缩放图片可以使得它们适应不同屏幕尺寸,保证在不同设备上的合适展示效果。

3. 图片格式转换:针对不同的需求,选择合适的图片格式也是一项重要工作。

JPEG格式适用于照片等色彩丰富的图片,可以在保持相对较好的质量的同时,降低文件大小。

而PNG格式则适合保留透明通道,以及对色彩准确性有较高要求的图片。

二、图片特效技巧1. 滤镜效果:滤镜可以为图片增加一定的艺术效果,例如黑白滤镜、怀旧滤镜、复古滤镜等。

移动应用中,开发者可以借助现成的滤镜库或者自行开发滤镜算法,通过调整图片参数和处理方法,给用户带来不同的视觉体验。

2. 图片叠加:通过将多张图片叠加在一起,可以创造出新的效果。

开发者可以利用这一技巧来制作图片拼接、图文相结合的效果等。

例如,在社交应用中,用户可以将自己的头像叠加在不同的主题背景上进行分享。

3. 动态特效:除了静态的图片,动态特效也是移动应用中常见的处理方式。

开发者可以通过添加动画、视频、粒子效果等来增强图片的表现力。

例如,在一款游戏应用中,通过为角色的攻击动作添加火焰特效,可以让玩家感受到更加震撼的攻击视觉效果。

【黑马程序员】Android中如何将图片裁切成三角形并设置阴影

【黑马程序员】Android中如何将图片裁切成三角形并设置阴影

【黑马程序员】Android中如何将图片裁切成三角形并设置阴影Android5.0之后,可以通过轮廓来裁切一个View 。

但是这种方式只能用来裁切矩形、圆形和圆角矩形。

不支持三角形。

所以要想实现这个效果,只能另辟蹊径。

我们知道可以利用PorterDuffXferMode 来进形图片的混合。

所以我们的思路就来了。

分两步:1. 先找一张三角形的图片。

然后采用PorterDuff.Mode.SRC_IN 将原图裁切成三角形图片,设置给一个ImageView 。

2.给这个ImageView 设置三角形的阴影。

首先材料准备:第一步,先用这个三角形的图片把这个美女裁成三角形,并设置个ImageView ,代码如下: 01 02 03 04 05 06 07 08 09 10 11 //先将原图和裁切用的三角形图片准备好Bitmap source = BitmapFactory.decodeResource (getResources (),R.drawable.girl );Bitmap mask = BitmapFactory.decodeResource (getResources (),R.drawable.triangle );//穿件一个空的Bitmap 用来存放合成的图片final Bitmap result = Bitmap.createBitmap (source.getWidth (),source.getHeight (), Config.ARGB_8888);Canvas canvas = new Canvas (result );Paint paint = new Paint (Paint.ANTI_ALIAS_FLAG );12 13 14 15 16 paint.setColor (Color.BLACK );canvas.drawBitmap (mask , 0, 0, paint );paint.setXfermode (new PorterDuffXfermode (Mode.SRC_IN ));canvas.drawBitmap (source , 0, 0, paint );paint.setXfermode (null );iv.setImageBitmap (result );第二步,给这个ImageView 设置一个三角形的阴影,代码如下: 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 iv.setOutlineProvider (new ViewOutlineProvider () {@Overridepublic void getOutline (View view , Outline outline ) { int x = (view .getWidth () - result .getWidth ()) / 2; int y = (view .getHeight () - result .getHeight ()) / 2;Path path = new Path ();path .moveTo (x , y );path .lineTo (x +result .getWidth (), y );path .lineTo (x +result .getWidth ()/2, y +result .getHeight ()); path .lineTo (x , y );path .close ();outline.setConvexPath (path );}});到此,我们完美的实现了这个效果。

【推荐下载】Android实现拍照、选择图片并裁剪图片功能

【推荐下载】Android实现拍照、选择图片并裁剪图片功能

Android 实现拍照、选择图片并裁剪图片功能2016/10/16 0 一、实现拍照、选择图片并裁剪图片效果按照之前博客的风,首先看下实现效果。

二、uCrop 项目应用想起之前看到的Yalantis/uCrop 效果比较绚,但是研究源码之后发现在定制界面方面还是有一点的限制,于是在它的基础上做了修改Android-Crop,把定制界面独立出来,让用户去自由设置。

下图为使用Android-Crop 实现的模仿微信选择图片并裁剪Demo。

三、实现思路比较简单的选择设备图片裁剪,并将裁剪后的图片保存到指定路径;调用系统拍照,将拍照图片保存在SD 卡,然后裁剪图片并将裁剪后的图片保存在指定路径。

流程图如下所示:四、选择框实现这里通过PopupWindow 来实现,当然也可以根据需求采用其他方式实现。

实现效果如下图所示:1. XML 布局?xml version= 1.0 encoding= utf-8 ? RelativeLayout xmlns:android= schemas.android/apk/res/android android:layout_width= fill_parent android:layout_height= wrap_content android:gravity= center_horizontal android:orientation= vertical LinearLayout android:id= @ id/pop_layout android:layout_width= match_parent android:layout_height= wrap_content android:layout_alignParentBottom= true android:background= #444 android:gravity= center_horizontal android:orientation= vertical Button android:id= @ id/picture_selector_take_photo_btn android:layout_width= match_parent android:layout_height= wrap_content android:layout_marginLeft= 10dip android:layout_marginRight= 10dip android:layout_marginTop= 10dp。

android心形、矩形、圆形裁剪框的实现方法

android心形、矩形、圆形裁剪框的实现方法

android心形、矩形、圆形裁剪框的实现方法
要实现在Android中对图片进行心形、矩形和圆形裁剪,可以使用以下方法:
1. 心形裁剪:
- 创建一个自定义的View,继承自ImageView。

- 在View的`onDraw()`方法中,使用`Path`类绘制一个心形的路径。

- 在View的`onDraw()`方法中,使用`Canvas.clipPath()`方法将图片裁剪为心形。

- 在Activity中使用该自定义View显示图片。

2. 矩形裁剪:
- 创建一个自定义的View,继承自ImageView。

- 在View的`onDraw()`方法中,使用`Canvas.clipRect()`方法将图片裁剪为矩形。

- 在Activity中使用该自定义View显示图片。

3. 圆形裁剪:
- 创建一个自定义的View,继承自ImageView。

- 在View的`onDraw()`方法中,使用`Canvas.drawCircle()`方
法绘制一个圆形的路径。

- 在View的`onDraw()`方法中,使用`Canvas.clipPath()`方法将图片裁剪为圆形。

- 在Activity中使用该自定义View显示图片。

注意:以上方法只是简单介绍了实现的思路,具体的实现细节还需要根据具体需求进行调整。

Android获取照片、裁剪图片、压缩图片

Android获取照片、裁剪图片、压缩图片

Android获取照⽚、裁剪图⽚、压缩图⽚前⾔在做上⼀个项⽬时深深受到了图⽚上传的苦恼。

图⽚上传主要分为两个部分,⾸先要获取图⽚,⽽获取图⽚可以分为从⽂件获取或者拍照获取。

第⼆个部分才是上传图⽚,两个部分都是⾛了不少弯路。

由于Android系统的碎⽚化⽐较严重,我们可能出现在第⼀台机⼦上能获取图⽚,但是换⼀个机⼦就不能获取图⽚的问题,并且在Android6.0,7.0之后也要做⼀定的适配,这样对于开发者来说,⽆疑很蛋疼。

由于也是初学者,很多东西没有考虑到,适配起来也是有点难度的。

这⼏天也是从github上找到了⼀个库(地址在这),经过简单的学习之后,发现⽤起来还是蛮简单的,并且在不同机型之间都能达到同样的效果。

更重要的是可以根据不同配置达到不同的效果接下来看下⽤法获取图⽚1)获取TakePhoto对象⼀)通过继承的⽅式继承TakePhotoActivity、TakePhotoFragmentActivity、TakePhotoFragment三者之⼀。

通过getTakePhoto()获取TakePhoto实例进⾏相关操作。

重写以下⽅法获取结果void takeSuccess(TResult result);void takeFail(TResult result,String msg);void takeCancel();这种⽅法使⽤起来虽然简单,但是感觉定制性不⾼,必须继承指定的Activity,⽽有时我们已经封装好了BaseActivity,不想再改了。

有时候通过继承⽆法满⾜实际项⽬的需求。

⼆)通过组装的⽅式去使⽤实现TakePhoto.TakeResultListener,InvokeListener接⼝。

在 onCreate,onActivityResult,onSaveInstanceState⽅法中调⽤TakePhoto对⽤的⽅法。

重写onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults),添加如下代码。

【黑马程序员】安卓中选择本地图片或拍照获取图片并裁剪...

【黑马程序员】安卓中选择本地图片或拍照获取图片并裁剪...

【黑马程序员】安卓中选择本地图片或拍照获取图片并裁剪在开发的时候我们经常遇到一种需求,就是让用户上传一张图片作为头像。

这个图片可能是从相册中选择的,也可能是使用摄像头现拍的。

不过得到的图片都会进行一步裁剪的操作。

下面我们就来实现一下这个需求。

首先我们定义一个Activity ,布局里只放置一个按钮和一个ImageView ,按钮点击的时候让用户选择并裁剪图片,ImageView 作为最终显示结果的View 对象。

布局代码如下: 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 <?xml version ="1.0" encoding ="utf-8"?><LinearLayout xmlns :android ="/apk/res/android"android :layout_width ="match_parent"android :layout_height ="match_parent"android :orientation ="vertical"><Buttonandroid :id ="@+id/btn_crop"android :layout_width ="match_parent"android :layout_height ="wrap_content"android :text ="点"/><ImageViewandroid :id ="@+id/iv_img"android :layout_width ="wrap_content"android :layout_height ="wrap_content"/></LinearLayout >接下来在Activity 中设置button 的点击事件,当按钮被点击的时候就弹出一个对话框来让用户选择是从相册还是拍照得到图片。

Android上超好用的图片处理App

Android上超好用的图片处理App

Android上超好⽤的图⽚处理App在截图编辑和 GIF 制作⽅⾯,iOS 平台有诸多独占且优秀的应⽤可以使⽤,例如利⽤ Picsew 截图拼接、Annotable 截图标注、OneScreen 带壳截图以及 ImgPlay Pro 制作 GIF 动图。

⽽当我将主⼒机切换到 Android 后(⾮国内定制的各类 ROM),⼀时之间却不知道该⽤哪些应⽤来替代它们。

经过对多款应⽤的长时间使⽤和对⽐,我想我已经在 Android 平台上找到了不少同类优秀应⽤,特与⼤家进⾏分享。

截图标注及打码标注与打码是我们对截图进⾏最多的编辑⼯作。

在 Android 9.0 中,⾕歌已为我们加⼊系统级的截图编辑⼯具 Markup,截图后便可下拉通知栏中点击「编辑」进⾏标注。

但遗憾的是,Markup 仅⽀持裁剪和简单的画笔标注,打码及更复杂的标注均不⽀持,所以还是需要与第三⽅应⽤搭配使⽤。

为打码⽽⽣:纯纯打码正如其名,纯纯打码是⼀款专注打码的应⽤,为我们提供了马赛克、⽑玻璃、Low Poly、涂抹马赛克、⽑玻璃、⾼亮等 6 种打码模式。

应⽤整体的界⾯⼗分简洁,6 种打码模式都列于下⽅,并在界⾯中间提供了⼀张⽰例图⽚,供⽤户选择模式后进⾏打码测验效果。

在 6 种打码模式下⽅,还提供了打码属性程度的调节(如:马赛克模式下格⼦的宽度;⽑玻璃模式下的⽑化程度),让我们能根据⾃⾝需求或者界⾯进⾏调节,让打码后也可以显得更「好看」。

全能标注⼯具:截屏⼤师使⽤该款应⽤时,⾸先要明确的⼀点是它有着⾮常多的⼴告。

如果想要去掉⼴告,需要升级⾄专业版(约⼈民币 26 元)。

打开应⽤后,可以选择「开启截屏功能」,开启两种截屏⽅式:悬浮按钮截屏:点击或双击悬浮按钮截屏,可设置⼤⼩、颜⾊以及透明度摇⼀摇截屏:摇晃⼿机即可截屏,可设置⾼、中、低三个等级的摇晃灵敏度利⽤这两种截屏⽅式成功截图后,都能快速进⼊编辑界⾯,更好地与其「标注」功能结合起来,带来连贯的⽤户体验。

Android实现裁剪照片功能

Android实现裁剪照片功能

Android实现裁剪照⽚功能本⽂实例为⼤家分享了Android实现裁剪照⽚功能的具体代码,供⼤家参考,具体内容如下1. 从相册选择照⽚进⾏裁剪从相册选择照⽚并裁剪:/*** 从相册选择照⽚进⾏裁剪*/private void cropFromGallery() {// TODO Auto-generated method stubIntent intent=new Intent();intent.setAction(Intent.ACTION_PICK);//Pick an item from the dataintent.setType("image/*");//从所有图⽚中进⾏选择intent.putExtra("crop", "true");//设置为裁切intent.putExtra("aspectX", 1);//裁切的宽⽐例intent.putExtra("aspectY", 1);//裁切的⾼⽐例intent.putExtra("outputX", 600);//裁切的宽度intent.putExtra("outputY", 600);//裁切的⾼度intent.putExtra("scale", true);//⽀持缩放intent.putExtra("return-data", false);intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);//将裁切的结果输出到指定的Uriintent.putExtra("outputFormat", pressFormat.JPEG.toString());//裁切成的图⽚的格式intent.putExtra("noFaceDetection", true); // no face detectionstartActivityForResult(intent, SELECT_PIC);}将裁减好的照⽚显⽰在显⽰在ImagaView上:case SELECT_PIC:if (resultCode==RESULT_OK) {try {Bitmap bitmap=BitmapFactory.decodeStream(getContentResolver().openInputStream(imageUri));//将imageUri对象的图⽚加载到内存imgShow.setImageBitmap(bitmap);} catch (FileNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();}}break;程序运⾏效果图:2. 从相机拍取照⽚进⾏裁剪控制相机拍照并将照⽚保存到指定位置:/*** 从相机拍取照⽚进⾏裁剪*/private void cropFromTake() {// TODO Auto-generated method stubIntent intent=new Intent();intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE);//设置Action为拍照intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);//将拍取的照⽚保存到指定URIstartActivityForResult(intent, TAKE_PIC);}裁剪已经排好的照⽚并显⽰在ImageView上:case TAKE_PIC:if (resultCode==RESULT_OK) {cropImageUri(imageUri, 600, 600, CROP_PIC);}break;/*** 裁剪指定uri对应的照⽚* @param imageUri:uri对应的照⽚* @param outputX:裁剪宽* @param outputY:裁剪⾼* @param requestCode:请求码*/private void cropImageUri(Uri imageUri, int outputX, int outputY, int requestCode){Intent intent = new Intent("com.android.camera.action.CROP");intent.setDataAndType(imageUri, "image/*");intent.putExtra("crop", "true");intent.putExtra("aspectX", 1);intent.putExtra("aspectY", 1);intent.putExtra("outputX", outputX);intent.putExtra("outputY", outputY);intent.putExtra("scale", true);intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);intent.putExtra("return-data", false);intent.putExtra("outputFormat", pressFormat.JPEG.toString());intent.putExtra("noFaceDetection", true); // no face detectionstartActivityForResult(intent, requestCode);}程序运⾏效果图:3.完整项⽬代码:package com.jph.cp;import java.io.File;import java.io.FileNotFoundException;import android.support.v7.app.ActionBarActivity;import android.content.Intent;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import .Uri;import android.os.Bundle;import android.os.Environment;import android.provider.MediaStore;import android.view.View;import android.widget.ImageView;/*** 从相册选择照⽚进⾏裁剪,从相机拍取照⽚进⾏裁剪* @author JPH* Date:2014.10.09*/public class MainActivity extends ActionBarActivity {private final static int SELECT_PIC=0x123;private final static int TAKE_PIC=0x124;private final static int CROP_PIC=0x125;private Uri imageUri;private ImageView imgShow;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(yout.activity_main);//初始化imageUriimageUri=Uri.fromFile(new File(Environment.getExternalStorageDirectory(), "test.jpg")); imgShow=(ImageView)findViewById(R.id.imgShow);}@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {// TODO Auto-generated method stubswitch (requestCode) {case SELECT_PIC:if (resultCode==RESULT_OK) {try {Bitmap bitmap=BitmapFactory.decodeStream(getContentResolver().openInputStream(imageUri));//将imageUri对象的图⽚加载到内存imgShow.setImageBitmap(bitmap);} catch (FileNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();}}break;case TAKE_PIC:if (resultCode==RESULT_OK) {cropImageUri(imageUri, 600, 600, CROP_PIC);}break;case CROP_PIC:if (resultCode==RESULT_OK) {try {Bitmap bitmap=BitmapFactory.decodeStream(getContentResolver().openInputStream(imageUri));//将imageUri对象的图⽚加载到内存imgShow.setImageBitmap(bitmap);} catch (FileNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();}}break;default:break;}super.onActivityResult(requestCode, resultCode, data);}/*** 裁剪指定uri对应的照⽚* @param imageUri:uri对应的照⽚* @param outputX:裁剪宽* @param outputY:裁剪⾼* @param requestCode:请求码*/private void cropImageUri(Uri imageUri, int outputX, int outputY, int requestCode){Intent intent = new Intent("com.android.camera.action.CROP");intent.setDataAndType(imageUri, "image/*");intent.putExtra("crop", "true");intent.putExtra("aspectX", 1);intent.putExtra("aspectY", 1);intent.putExtra("outputX", outputX);intent.putExtra("outputY", outputY);intent.putExtra("scale", true);intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);intent.putExtra("return-data", false);intent.putExtra("outputFormat", pressFormat.JPEG.toString());intent.putExtra("noFaceDetection", true); // no face detectionstartActivityForResult(intent, requestCode);}public void cropPic(View view) {switch (view.getId()) {case R.id.btnCropFromGallery://从相册选择照⽚进⾏裁剪cropFromGallery();break;case R.id.btnCropFromTake://从相机拍取照⽚进⾏裁剪cropFromTake();break;default:break;}}/*** 从相机拍取照⽚进⾏裁剪*/private void cropFromTake() {// TODO Auto-generated method stubIntent intent=new Intent();intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE);//设置Action为拍照intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);//将拍取的照⽚保存到指定URI startActivityForResult(intent, TAKE_PIC);}/*** 从相册选择照⽚进⾏裁剪*/private void cropFromGallery() {// TODO Auto-generated method stubIntent intent=new Intent();intent.setAction(Intent.ACTION_PICK);//Pick an item from the dataintent.setType("image/*");//从所有图⽚中进⾏选择intent.putExtra("crop", "true");//设置为裁切intent.putExtra("aspectX", 1);//裁切的宽⽐例intent.putExtra("aspectY", 1);//裁切的⾼⽐例intent.putExtra("outputX", 600);//裁切的宽度intent.putExtra("outputY", 600);//裁切的⾼度intent.putExtra("scale", true);//⽀持缩放intent.putExtra("return-data", false);intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);//将裁切的结果输出到指定的Uriintent.putExtra("outputFormat", pressFormat.JPEG.toString());//裁切成的图⽚的格式 intent.putExtra("noFaceDetection", true); // no face detectionstartActivityForResult(intent, SELECT_PIC);}}以上就是本⽂的全部内容,希望对⼤家的学习有所帮助,也希望⼤家多多⽀持。

Android调用系统的照相,浏览图片,转存并裁剪!

Android调用系统的照相,浏览图片,转存并裁剪!

Android调用系统的照相,浏览图片,转存并裁剪![java]view plaincopy1.public class AddCardActivity extends Activity {2.3.4.private Button add;5.6.private Button take_p;7.8.private Button app_ol;9.10.private File sdCard;11.12.private File sdPhoto;13.14.private AlphaAnimation anim_alpha;15.16.private int menu = -1;17.18.private final int LOCAL = 0;19.20.private final int TAKE = 1;21.22.private final int APP = 2;23.24.25.26.public void onCreate(Bundle savedInstanceState) {27.28.super.onCreate(savedInstanceState);29.30.//全屏显示31.32.ActivityUtil.noNotificationBar(this);33.34.ActivityUtil.noTitleBar(this);35.36.37.setContentView(yout.addcard);38.39.//转存出的路径40.41.sdPhoto = new File("/sdcard/card_xx/photo_xx");42.43.if(!sdPhoto.exists()){44.45.sdPhoto.mkdirs();46.47.}48.49.//转存出的文件50.51.sdCard = new File("/sdcard/card_xx/aa.png");52.53.54.55.add = (Button)findViewById(R.id.add);56.57.take_p = (Button)findViewById(R.id.take_p);59.app_ol = (Button)findViewById(R.id.app_ol);60.61.62.63./* 事件处理 */64.65.setListener();66.67.68.69.anim_alpha = new AlphaAnimation(0.5f, 0.5f);70.71.anim_alpha.setDuration(80);72.73.anim_alpha.setRepeatCount(1);74.75.anim_alpha.setAnimationListener(new AnimationListe ner() {76.77.public void onAnimationStart(Animation animation) {78.79.}80.81.public void onAnimationRepeat(Animation animation) {82.83.}84.85.public void onAnimationEnd(Animation animation) {87.switch (menu) {88.89.case LOCAL:90.91.Intent intent = new Intent(Intent.ACTION_GET_CONTE NT);92.93.intent.setType("image/*");94.95.startActivityForResult(intent, 1);96.97.break;98.99.case TAKE:100.101.intent=new Intent(MediaStore.ACTION_IMAGE_CAPTU RE);102.103.File out = new File(Environment.getExternalStorageDir ectory(),"camera.png");104.105.Uri uri = Uri.fromFile(out);106.107.intent.putExtra(MediaStore.EXTRA_OUTPUT,uri);108.109.110.startActivityForResult(intent, 3);111.112.break;114.case APP:115.116.intent = new Intent();117.118.intent.setClass(AddCardActivity.this, TemplateListActivi ty.class);119.120.startActivityForResult(intent, 9);121.122.break;123.124.}125.126.}127.128.});129.130.}131.132.133.134.private void setListener()135.136.{137.138./* 本地导入按钮事件处理 */139.140.add.setOnClickListener(new OnClickListener() {141.142.public void onClick(View v) {143.144.menu = LOCAL;145.146.add.setAnimation(anim_alpha);147.148.anim_alpha.startNow();149.150.add.invalidate();151.152.}153.154.});155.156.157.158./* 拍照按钮事件处理 */159.160.take_p.setOnClickListener(new OnClickListener() { 161.162.public void onClick(View v) {163.164.menu = TAKE;165.166.take_p.setAnimation(anim_alpha);167.168.anim_alpha.startNow();169.170.take_p.invalidate();171.172.}173.174.});175.176.177.178./* 在线申请事件处理 */179.180.app_ol.setOnClickListener(new OnClickListener() 181.182.{183.184.public void onClick(View v)185.186.{187.188.menu = APP;189.190.app_ol.setAnimation(anim_alpha);191.192.anim_alpha.startNow();193.194.app_ol.invalidate();195.196.}197.198.}199.200.);201.202.203.204.}205.206./* 返回值处理 */207.208.protected void onActivityResult(int requestCode, int re sultCode, Intent data) {209.210.if (resultCode == RESULT_OK){211.212.switch (requestCode) {213.214./* 裁剪功能 ,裁剪后跳到2保存*/215.216.case 1:217.218.Intent cj = new Intent("com.android.camera.action.CR OP");219.220.cj.setData( data.getData());221.222.cj.putExtra("crop", "true");223.224.cj.putExtra("aspectX", 3);225.226.cj.putExtra("aspectY", 2);227.228.cj.putExtra("outputX",384 );229.230.cj.putExtra("outputY", 256);231.232.cj.putExtra("noFaceDetection", true);233.234.cj.putExtra("return-data", true);235.236.startActivityForResult(Intent.createChooser(cj, "裁剪") , 2);237.238.break;239.240./* 保存并跳转 */241.242.case 2:243.244.Intent intent = new Intent();245.246.Bundle extras = data.getExtras();247.248.if(extras != null ) {249.250.Bitmap photo = extras.getParcelable("data");251.252.try {253.254.FileOutputStream outStreamz = new FileOutputStrea m(sdCard);255.press(pressFormat.PNG, 50, ou tStreamz);257.258.outStreamz.close();259.260.} catch (FileNotFoundException e) {261.262. e.printStackTrace();263.264.}265.266.catch (IOException e) {267.268. e.printStackTrace();269.270.}271.272.intent.setClass(AddCardActivity.this,ChooseABActivity. class);273.274.startActivity(intent);275.276.finish();277.278.}279.280.break;281.282./* 拍照后保存图片,并跳到裁剪功能 */283.284.case 3:285.286.Intent cj1 = new Intent("com.android.camera.action.C ROP");287.288.try {289.290.cj1.setData(Uri.parse(android.provider.MediaStore.Ima ges.Media.291.292.insertImage(getContentResolver(),"/sdcard/camera.pn g", null, null)));293.294.} catch (FileNotFoundException e) {295.296. e.printStackTrace();297.298.}299.300.cj1.putExtra("crop", "true");301.302.cj1.putExtra("aspectX", 3);303.304.cj1.putExtra("aspectY", 2);305.306.cj1.putExtra("outputX",384 );307.308.cj1.putExtra("outputY", 256);309.310.cj1.putExtra("return-data", true);311.312.startActivityForResult(cj1, 2);314.File camera = new File("/sdcard/camera.png"); 315.316.if(camera.exists())317.318.camera.delete();319.320.break;321.322.}323.324.}325.326.327.328.if (requestCode == 9) {329.330.Intent i=new Intent(this,MainMenuActivity.class); 331.332.startActivity(i);333.334.finish();335.336.}337.338.}339.340.341.342.@Override344.public boolean onKeyDown(int keyCode, KeyEvent eve nt) {345.346.347.348.if(keyCode==KeyEvent.KEYCODE_BACK)349.350.{351.352.Intent i=new Intent(this,MainMenuActivity.class);353.354.startActivity(i);355.356.finish();357.358.}359.360.return super.onKeyDown(keyCode, event);361.362.}363.364.365.366.}367.368./******************************************************** ******************************************************************* ***********************/369.370.如果照相之后要添加裁剪:371.372.class TakePicture implements OnClickListener{373.374.public void onClick(View v) {375.takePic();376.377.File picture = new File("/sdcard/picture.jpg");378.Intent intent = new Intent("com.android.camera.action .CROP");379.380./**************如果不加这句话,会报错,找不到裁剪的Activity******/381.intent.setDataAndType( Uri.fromFile(file),"image/*);382.383./******************************************************** ************************/384.385.intent.putExtra("crop", "true");386.intent.putExtra("aspectX", 3);387.intent.putExtra("aspectY", 2);388.intent.putExtra("outputX",384 );389.intent.putExtra("outputY", 256);390.intent.putExtra("return-data", true);391.startActivityForResult(intent, OVER);392.finish();393.}394.}395.396./*************************************************************************************************************************** ********************/。

android实现图片裁剪的两种方法

android实现图片裁剪的两种方法

android实现图⽚裁剪的两种⽅法两种android图⽚裁剪⽅式,供⼤家参考,具体内容如下⼀、相机拍完照之后利⽤系统⾃带裁剪⼯具进⾏截取public static void cropImage(Activity activity, Uri srcUri) {cropImageUri = srcUri;Intent intent = new Intent("com.android.camera.action.CROP");intent.setDataAndType(srcUri, "image/*");intent.putExtra("crop", "true");// 1.宽⾼和⽐例都不设置时,裁剪框可以⾃⾏调整(⽐例和⼤⼩都可以随意调整)////////////////////////////////////////////////////////////////// 2.只设置裁剪框宽⾼⽐(aspect)后,裁剪框⽐例固定不可调整,只能调整⼤⼩////////////////////////////////////////////////////////////////// 3.裁剪后⽣成图⽚宽⾼(output)的设置和裁剪框⽆关,只决定最终⽣成图⽚⼤⼩////////////////////////////////////////////////////////////////// 4.裁剪框宽⾼⽐例(aspect)可以和裁剪后⽣成图⽚⽐例(output)不同,此时,// 会以裁剪框的宽为准,按照裁剪宽⾼⽐例⽣成⼀个图⽚,该图和框选部分可能不同,// 不同的情况可能是截取框选的⼀部分,也可能超出框选部分,向下延伸补⾜////////////////////////////////////////////////////////////////// aspectX aspectY 是裁剪框宽⾼的⽐例// intent.putExtra("aspectX", 1);// intent.putExtra("aspectY", 1);// // outputX outputY 是裁剪后⽣成图⽚的宽⾼// intent.putExtra("outputX", 300);// intent.putExtra("outputY", 300);// return-data为true时,会直接返回bitmap数据,但是⼤图裁剪时会出现问题,推荐下⾯为false时的⽅式// return-data为false时,不会返回bitmap,但需要指定⼀个MediaStore.EXTRA_OUTPUT保存图⽚uriintent.putExtra(MediaStore.EXTRA_OUTPUT, cropImageUri);intent.putExtra("return-data", false);activity.startActivityForResult(intent, CROP_IMAGE);}这样图⽚可以通过⼿势来⾃由裁剪⼆、⾃定义相机拍照界⾯,裁剪固定区域的图⽚这⾥⽤到了⼀个叫idcardcamera的三⽅,在此向原作者致敬,附上项⽬引⽤地址 ‘com.github.wildma:IDCardCamera:1.0.0'有⼏个地⽅,需要修改⼀下,我是在相机中间加了⼀个长⽅形的框,代码⽚段如下:float screenMinSize = Math.min(getResources().getDisplayMetrics().widthPixels, getResources().getDisplayMetrics().heightPixels);//根据screenMinSize,计算出cameraPreview的较宽的⼀边,长宽⽐为标准的16:9float maxSize = screenMinSize / 9.0f * 16.0f;youtParams layoutParams = new youtParams((int) maxSize, (int) screenMinSize);layoutParams.addRule(RelativeLayout.CENTER_IN_PARENT);mCameraPreview.setLayoutParams(layoutParams);float height = (int) (screenMinSize * 0.3);float density = getResources().getDisplayMetrics().density; // 屏幕密度(0.75 / 1.0 / 1.5)float mywdith =(int) 136*density;int widthPixels = getResources().getDisplayMetrics().widthPixels;float width = (int) (widthPixels-mywdith);//75 47youtParams containerParams = new youtParams((int) width, youtParams.MATCH_PARENT);youtParams cropParams = new youtParams((int) width, (int) height);mLlCameraCropContainer.setLayoutParams(containerParams);mIvCameraCrop.setLayoutParams(cropParams);修改了 mIvCameraCrop的⼤⼩,给这个长⽅形框添加⼀个背景边框,刚开始⽼是显⽰不出来右边的边框,后来发现,拍照按钮⽗布局的宽度为136dp,⽤代码计算出实际占⽤的px,然后设置长⽅形的合适宽度,这样就遮挡不住了,右边的边框就能够显⽰出来了,附上拍照的逻辑,选择⾃动剪裁/*** 拍照*/private void takePhoto() {mCameraPreview.setEnabled(false);mCameraPreview.takePhoto(new Camera.PictureCallback() {@Overridepublic void onPictureTaken(final byte[] data, Camera camera) {// camera.stopPreview();camera.startPreview();//⼦线程处理图⽚,防⽌ANR// setCropLayout();new Thread(new Runnable() {@Overridepublic void run() {bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);String imagePath = path;ImageUtils.save(bitmap, imagePath, pressFormat.JPEG);int rotation = getWindowManager().getDefaultDisplay().getRotation();int angle = ImageUtils.getBitmapDegree(imagePath);if (mOrientation==90){bitmap = ImageUtils.rotateBitmap(CameraActivity.this.bitmap, 180);}/*** 计算裁剪位置*/float left, top, right, bottom;left = ((float) mLlCameraCropContainer.getLeft() - (float) mCameraPreview.getLeft()) / (float) mCameraPreview.getWidth();top = (float) mIvCameraCrop.getTop() / (float) mCameraPreview.getHeight();right = (float) mLlCameraCropContainer.getRight() / (float) mCameraPreview.getWidth();bottom = (float) mIvCameraCrop.getBottom() / (float) mCameraPreview.getHeight();/*** ⾃动裁剪**/mCropBitmap = Bitmap.createBitmap(bitmap,(int) (left * (float) bitmap.getWidth()),(int) (top * (float) bitmap.getHeight()),(int) ((right - left) * (float) bitmap.getWidth()),(int) ((bottom - top) * (float) bitmap.getHeight()));/*** ⼿动裁剪**/runOnUiThread(new Runnable() {@Overridepublic void run() {//将裁剪区域设置成与扫描框⼀样⼤setCropLayout();mCropImageView.setLayoutParams(new youtParams(mIvCameraCrop.getWidth(), mIvCameraCrop.getHeight())); mCropImageView.setImageBitmap( mCropBitmap);}});}}).start();safeToTakePicture = true;}});}以上就是本⽂的全部内容,希望对⼤家的学习有所帮助,也希望⼤家多多⽀持。

在Android中实现视频抓拍与照片自由裁剪的编程方法

在Android中实现视频抓拍与照片自由裁剪的编程方法

在Android中实现视频抓拍与照片自由裁剪的编程方法在Android操作系统下可通过编程实现对视频图像进行抓拍并对图片的裁剪与上传功能。

简单的实现方法采用Android 自带有关于照片的自由裁剪,非常适用及视频抓拍的接口功能。

一、视频抓拍1、基本类Android 框架通过Camera API 或者camer Intent 的方式,支持捕捉图像和视频。

相关的大类主要有以下几个:(1)Camera 摄像时候必须调用到的类;(2)SurfaceView 提供摄像头预览。

(3)MediaRecorder 录像时候用到的类;(4)Intent 如果不通过Camera 对象来操控摄像头,那么用两个intent 动作MediaSto re.ACTION_IMAGE_CAPTURE or MediaStore.ACTION_VIDEO_CAPTURE也能够实现摄影和录像。

o MediaStore.ACTION_IMAGE_CAPTURE——向内置摄像头程序请求图像的意图活动类型。

o MediaStore.ACTION_VIDEO_CAPTURE——向内置摄像头程序请求视频的意图活动类型。

2、Manifest 声明在使用Camera API前,必须做出使用Camera 硬件的声明。

主要有下面点:(1)Camera 允许:(注意,如果是通过intent 意图来操控的,则不需要下面声明)<uses-permission android:name="android.permission.CAMERA" />(2)Camera 特征,比如说名字<uses-feature android:name="android.hardware.camera" />(3)如果你要在SD卡中保存照片和视频,那么就得开启SD卡权限<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />(4)录音权限<uses-permission android:name="android.permission.RECORD_AUDIO" />(5)如果希望在照片中插入GPS当地信息,还得开启GPS<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> 3、使用方法使用摄像头的方法有两种:一种是编写代码比较少的,快速使用摄像头的意图Intent 方法;另外一种就是自动外观的摄像头用户界面,要求编写更多的代码。

[Android]图片裁剪总结——调用系统裁剪

[Android]图片裁剪总结——调用系统裁剪

[Android]图⽚裁剪总结——调⽤系统裁剪花了两天时间看了下android的图⽚裁剪功能的实现。

其实刚开始做这个我挺虚的,以为整个功能都需要⾃⼰写出来,但查了些资料,发现android已经提供了裁剪功能,需要的话⾃⼰调⽤就成了。

soga,这下轻松多了。

⾸先推荐⼏篇博客要想弄明⽩裁剪功能,这系列博客⾮常重要,你可以不看我下⾯总结的,但你⼀定要看他这系列的⼏篇⽂章。

这篇也不错,⽐较喜欢他的注释。

虽然也有些误导,⽐如说他有⼀段对setData,setType和setDataAndType⽅法的区别疑问,他说两种写法⼀样效果,我就信了,害得我找bug找了两个⼩时,⼀直怀疑别的参数出问题,实际上是这两个⽅法的差别。

这⼀点后⾯会说。

其他的相关博客有很多,但基本上⼤同⼩异,包括我这篇。

有了上⾯的两个博客,就可以⼤概搞懂这⽅⾯的原理了。

我要写的,就是多写⼀些注释,改变⼀些写法,增加点说明,积累点经验,为了⾃⼰以后⽅便重温⾃⼰做过的东西,⽽已。

不再浪费你我的时间,开始了。

丑得不能忍的分割区RyanHoo的Demo写的很详细。

但要学习,我习惯先把代码简化,看的逻辑清楚些。

我选择了最适应⾃⼰需求的选择⼤图⽚裁剪的部分代码我测试的简化代码1<LinearLayout xmlns:android="/apk/res/android"2 xmlns:tools="/tools"3 android:layout_width="match_parent"4 android:layout_height="match_parent"5 tools:context=".MainActivity">67<Button8android:id="@+id/button"9 android:layout_width="wrap_content"10 android:layout_height="wrap_content"11 android:text="click me!"/>1213<ImageView14android:id="@+id/imageview"15 android:layout_width="match_parent"16 android:layout_height="match_parent"17 android:scaleType="centerInside"/>1819</LinearLayout>1public class MainActivity extends Activity implements OnClickListener {23private Uri imageUri;4private static final String IMAGE_FILE_LOCATION = "file:///sdcard/temp.jpg";5private Button btn;6private ImageView iv;78 @Override9protected void onCreate(Bundle savedInstanceState) {10super.onCreate(savedInstanceState);11 setContentView(yout.activity_main);12 btn = (Button) findViewById(R.id.button);13 btn.setOnClickListener(this);14 imageUri = Uri.parse(IMAGE_FILE_LOCATION);15 iv = (ImageView) findViewById(R.id.imageview);16 }1718 @Override19public boolean onCreateOptionsMenu(Menu menu) {20// Inflate the menu; this adds items to the action bar if it is present.21 getMenuInflater().inflate(R.menu.activity_main, menu);22return true;23 }2425 @Override26public void onClick(View v) {27// TODO Auto-generated method stub2829// 试着改成打开⾃⼰写的图⽚浏览器30switch (v.getId()) {31case R.id.button:32//33 Intent intent = new Intent(Intent.ACTION_GET_CONTENT, null);34// Intent intent = new Intent(Intent.ACTION_PICK, null);3536// 如果使⽤com.android.camera.action.CROP 则直接打开裁剪照⽚的activity 那么可以⽤⾃⼰的图⽚浏览器选择图⽚传⼊参数并使⽤之37// Intent intent = new Intent("com.android.camera.action.CROP");3839// 如果不设置type,则 ACTION_GET_CONTENT 会弹出异常FATAL EXCEPTION:main android.content.ActivityNotFoundException40// ⽽ ACTION_PICK 会弹出可⽤程序列表但没有打开图⽚相关的程序(在我的两个设备上是这样)41 intent.setType("image/*");4243// 设置在开启的Intent中设置显⽰的view可裁剪44// 这段代码⾥设置成false也能裁剪啊。

android学习笔记进阶十二之裁截图片

android学习笔记进阶十二之裁截图片

package xiaosi.cut;import java.io.File;import android.app.Activity;import android.content.Intent;import android.graphics.drawable.Drawable; import .Uri;import android.os.Bundle;import android.view.View;import android.view.View.OnClickListener;import youtParams; import android.widget.Button;public class CutActivity extends Activity {private static int SELECT_PICTURE;//返回标志位 filedprivate File tempFile;private Button button;/** Called when the activity is first created. */@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);//setContentView(yout.main);this.tempFile = new File("/sdcard/song/a.jpg");button = new Button(this);button.setText("获取图片");button.setOnClickListener(new OnClickListener() {public void onClick(View v) {Intent intent = new Intent(Intent.ACTION_GET_CONTENT);intent.setType("image/*");intent.putExtra("crop", "true");// crop=true 有这句才能出来最后的裁剪页面.intent.putExtra("aspectX", 1);// 这两项为裁剪框的比例.intent.putExtra("aspectY", 2);// x:y=1:2intent.putExtra("output", Uri.fromFile(tempFile));intent.putExtra("outputFormat", "JPEG");//返回格式startActivityForResult(Intent.createChooser(intent, "选择图片"), SELECT_PICTURE); }});setContentView(button);}/*** 裁剪完图片后系统调用的方法:onActivityResult*/@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) { if (resultCode == RESULT_OK)if (requestCode == SELECT_PICTURE)button.setBackgroundDrawable(Drawable.createFromPath(tempFile.getAbsolutePath()));}}。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

1.
Canvas类用来实现绘制.通过组合使用Canva s类的成员函数可以实现随心随欲地绘制图片的任何部分.
Canvas.clipRect:设置显示区域
Canvas.drawBitmap:绘制
例子:
Bitmap b=Bitma pFactory.decodeStream("图片编号", null);//读取图片
...
Canvas c = null;//实例Canvas
c.save();//记录原来的ca nvas状态
c.clipRect(100,100,200,300);//显示从(100,100)到(200,300)的区域(单位:象素)
c.drawBitmap(b,10,0,null); //将阉割过的图片画到(10,0)位置
c.restore();//恢复canva s状态
2.
android 从sdcard 读取图片剪切粘贴
文章分类:移动开发
android 图片编辑时需要从外界(sdcard ,res/.png...,xml)读取图片到画布,其中从sdcard读取图片到画布的过程如下:
public void drawBitMapFromSDcard(String dir) {
if(dir ==null || dir.equals("")){
return ;
}
bitMap = BitmapFactory.decodeFile(dir);
int width = bitMap.getWidth();
int height = bitMap.getHeight();
如果图片像素太大超过手机屏幕大小可以按照手机屏比例进行缩放
if (width > 320 && height > 480) {
int newWidth = 320;
int newHeight = 480;
float scaleWidth = ((float) newWidth) / width;
float scaleHeight = ((float) newHeight) / height;
float minScale = Math.min(scaleWidth, scaleHeight);
matrix = new Matrix();
matrix.postScale(minScale, minScale);
bitMap = Bitmap.createBitmap(bitMap, 0, 0, width, height,
matrix, true);
}
显示图片到手机屏幕
mCanvas.drawBitmap(bitMap, 0, 0, mPaint);
invalidate();
(二)图片剪切
在android 画布上对图像进行剪切时,首先选中一块区域,得到所选区域的像素点,然后放到到要粘贴的位置。

剪切代码如下
public int[] getClipRectangePix(RectF rectf, Bitmap bitmap) {
int width = (int) rectf.width();
int height = (int) rectf.height();
int[] clipRectangePix = new int[(width * height)];// ????
int x = (int) rectf.left;
int y = (int) rectf.top;
bitmap.getPixels(clipRectangePix, 0, width, x, y, width, height); // Log.v("pix Color:",""+ clipRectangePix[0] );
return clipRectangePix;
}。

相关文档
最新文档