【黑马程序员】安卓中选择本地图片或拍照获取图片并裁剪...
android中打开相机、打开相册进行图片的获取示例
android中打开相机、打开相册进⾏图⽚的获取⽰例这⾥介绍在Android中实现相机调取、拍照⽚、获取照⽚、存储新路径等已经打开相册、选择照⽚等功能⾸先看⼀下界⾯,很简单配置读取内存卡和调⽤照相头的功能<!-- 使⽤⽹络权限 --><uses-permission android:name="android.permission.INTERNET"/><!-- 写sd卡的权限 --><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/><!-- 读sd卡权限 --><uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/><uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />下⾯是代码的主题public class TakePhotos extends Activity implementsandroid.view.View.OnClickListener {Button takePhoto;Bitmap photo;String picPath;Button capture;@Overrideprotected void onCreate(Bundle savedInstanceState) {// TODO Auto-generated method stubsuper.onCreate(savedInstanceState);setContentView(yout.activity_photo);takePhoto = (Button) findViewById(R.id.button1);capture = (Button) findViewById(R.id.capture);takePhoto.setOnClickListener(this);capture.setOnClickListener(this);}@Overridepublic void onClick(View viewid) {switch (viewid.getId()) {case R.id.button1: {// 打开相机String state = Environment.getExternalStorageState();// 获取内存卡可⽤状态if (state.equals(Environment.MEDIA_MOUNTED)) {// 内存卡状态可⽤Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");startActivityForResult(intent, 1);} else {// 不可⽤Toast.makeText(TakePhotos.this, "内存不可⽤", Toast.LENGTH_LONG).show();}break;}case R.id.capture: {// 打开相册// 打开本地相册Intent i = new Intent(Intent.ACTION_PICK,android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);// 设定结果返回startActivityForResult(i, 2);break;}default:break;}}@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {// TODO Auto-generated method stubsuper.onActivityResult(requestCode, resultCode, data);if (data != null) {switch (requestCode) {// 两种⽅式获取拍好的图⽚if (data.getData() != null || data.getExtras() != null) { // 防⽌没有返回结果Uri uri = data.getData();if (uri != null) {this.photo = BitmapFactory.decodeFile(uri.getPath()); // 拿到图⽚}if (photo == null) {Bundle bundle = data.getExtras();if (bundle != null) {photo = (Bitmap) bundle.get("data");FileOutputStream fileOutputStream = null;try {// 获取 SD 卡根⽬录⽣成图⽚并String saveDir = Environment.getExternalStorageDirectory()+ "/dhj_Photos";// 新建⽬录File dir = new File(saveDir);if (!dir.exists())dir.mkdir();// ⽣成⽂件名SimpleDateFormat t = new SimpleDateFormat( "yyyyMMddssSSS");String filename = "MT" + (t.format(new Date()))+ ".jpg";// 新建⽂件File file = new File(saveDir, filename);// 打开⽂件输出流fileOutputStream = new FileOutputStream(file);// ⽣成图⽚⽂件press(pressFormat.JPEG,100, fileOutputStream);// 相⽚的完整路径this.picPath = file.getPath();ImageView imageView = (ImageView) findViewById(R.id.imageView1); imageView.setImageBitmap(this.photo);} catch (Exception e) {e.printStackTrace();} finally {if (fileOutputStream != null) {try {fileOutputStream.close();} catch (Exception e) {e.printStackTrace();}}}Toast.makeText(getApplicationContext(), "获取到了",Toast.LENGTH_SHORT).show();} else {Toast.makeText(getApplicationContext(), "找不到图⽚",Toast.LENGTH_SHORT).show();}}}break;case 2: {//打开相册并选择照⽚,这个⽅式选择单张// 获取返回的数据,这⾥是android⾃定义的Uri地址Uri selectedImage = data.getData();String[] filePathColumn = { MediaStore.Images.Media.DATA };// 获取选择照⽚的数据视图Cursor cursor = getContentResolver().query(selectedImage, filePathColumn, null, null, null);cursor.moveToFirst();// 从数据视图中获取已选择图⽚的路径int columnIndex = cursor.getColumnIndex(filePathColumn[0]);String picturePath = cursor.getString(columnIndex);cursor.close();// 将图⽚显⽰到界⾯上ImageView imageView = (ImageView) findViewById(R.id.imageView1); imageView.setImageBitmap(BitmapFactory.decodeFile(picturePath)); break;}default:}}}}注释的很详细,⾃⼰分析吧。
从android系统图库中取图片的代码
从android系统图库中取图片的代码在自己应用中,从系统图库中取图片,然后截取其中一部分,再返回到自己应用中。
这是很多有关图片的应用需要的功能。
写了一个示例,上来就是个大按钮,连布局都不要了。
最终,用选取图片中的一部分作为按钮的背景。
这里需要注意几点:l从图库中选取出来保存的图片剪辑,需要保存在sd卡目录,不能保存在应用自己的在内存的目录,因为是系统图库来保存这个文件,它没有访问你应用的权限;l intent.putExtra("crop", "true")才能出剪辑的小方框,不然没有剪辑功能,只能选取图片;l intent.putExtra("aspectX", 1),是剪辑方框的比例,可用于强制图片的长宽比。
l Java代码1.packagecom.easymorse.gallery;2.3.importjava.io.File;4.5.importandroid.app.Activity;6.importandroid.content.Intent;7.importandroid.graphics.drawable.Drawable;.Uri;9.importandroid.os.Bundle;10.importandroid.view.View;11.importandroid.view.View.OnClickListener;12.importandroid.widget.Button;13.14.publicclassGalleryActivityextendsActivity{15.16.privatestaticintSELECT_PICTURE;17.18.privateFiletempFile;19.20.Buttonbutton;21.22./**Calledwhentheactivityisfirstcreated.*/23.@Override24.publicvoidonCreate(BundlesavedInstanceState){25.super.onCreate(savedInstanceState);26.this.tempFile=newFile("/sdcard/a.jpg");27.button=newButton(this);28.button.setText("获取图片");29.button.setOnClickListener(newOnClickListener(){30.31.@Override32.publicvoidonClick(Viewv){33.Intentintent=newIntent(Intent.ACTION_GET_CONTENT);34.intent.setType("image/*");35.intent.putExtra("crop","true");36.37.//intent.putExtra("aspectX",1);38.//intent.putExtra("aspectY",2);39.40.intent.putExtra("output",Uri.fromFile(tempFile));41.intent.putExtra("outputFormat","JPEG");42.43.startActivityForResult(Intent.createChooser(intent,"选择图片"),44.SELECT_PICTURE);45.}46.});47.setContentView(button);48.}49.50.@Override51.protectedvoidonActivityResult(intrequestCode,intresultCode,Intentdata){52.if(resultCode==RESULT_OK){53.if(requestCode==SELECT_PICTURE){54.button.setBackgroundDrawable(Drawable.createFromPath(tempFile55..getAbsolutePath()));56.}57.}58.}59.60.}。
Android开发实现从相册中选择照片功能详解
Android开发实现从相册中选择照⽚功能详解本⽂实例讲述了Android开发实现从相册中选择照⽚功能。
分享给⼤家供⼤家参考,具体如下:实际效果图:代码实现:1. 权限配置2. 点击事件绑定3. 相册访问4. 根据路径设置图⽚5. 其他⽅法权限⾸先,现在 mainfest.xml ⽂件中添加以下权限:<!--获取照⽚权限--><uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />点击事件点击跳转相册imageView01.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {if(ContextCompat.checkSelfPermission(MainActivity.this,Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED){ActivityCompat.requestPermissions(MainActivity.this,new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},1);}Intent intent = new Intent(Intent.ACTION_PICK,android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);startActivityForResult(intent, IMAGE_REQUEST_CODE);}});不同⼿机返回图⽚uri不同,此处进⾏转换可以不添加(如果,不添加,则其他⽅法也没⽤)@TargetApi(19)private void handleImageOmKitKat(Intent data){String imagePath = null;Uri uri = data.getData();if (DocumentsContract.isDocumentUri(this,uri)){//如果document类型是U⽇,则通过document id处理String docId = DocumentsContract.getDocumentId(uri);if ("com.android.providers.media.documents".equals(uri.getAuthority())){String id = docId.split(":")[1];//解析出数字格式idString selection = MediaStore.Images.Media._ID + "=" + id;imagePath = getImagePath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,selection);}else if ("com.android.providers.downloads.documents".equals(uri.getAuthority())){Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"),Long.valueOf(docId));imagePath = getImagePath(contentUri,null);}}else if ("content".equalsIgnoreCase(uri.getScheme())){//如果是普通类型⽤普通⽅法处理imagePath = getImagePath(uri,null);}else if ("file".equalsIgnoreCase(uri.getScheme())){//如果file类型位uri直街获取图⽚路径即可imagePath = uri.getPath();}displayImage(imagePath);}关于⽅法:onActivityResult()在这⾥通过放回路径设置头像,但由于图⽚路径⽣成可能有⼀定延时,所以这⾥开⼀个线程等待:/*定义⼀个Handler,定义延时执⾏的⾏为*/public void chnage(){new Thread(){@Overridepublic void run() {while ( bitmap == null ){bitmap = BitmapFactory.decodeFile(path);Log.v("qwe","123");}Message message = handler.obtainMessage();message.obj = 0;handler.sendMessage(message);}}.start();}其他⽅法:private void handleImageBeforeKitKat(Intent data){Uri uri = data.getData();String imagePath = getImagePath(uri,null);displayImage(imagePath);}private String getImagePath(Uri uri, String selection){String path = null;//通过Uri和selection来获取真实图⽚路径Cursor cursor = getContentResolver().query(uri, null, selection, null, null);if (cursor != null){if (cursor.moveToFirst()){path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));}cursor.close();}return path;}private void displayImage(String imagePath){if (imagePath != null){Bitmap bitmap = BitmapFactory.decodeFile(imagePath);imageView01.setImageBitmap(bitmap);}else {Toast.makeText(MainActivity.this,"fail to get image",Toast.LENGTH_SHORT).show();}}相关变量://从相册获得图⽚Bitmap bitmap;//判断返回到的Activityprivate static final int IMAGE_REQUEST_CODE = 0;//图⽚路径private String path ;private Handler handler = new Handler(){@Overridepublic void handleMessage(Message msg) {if((Integer)msg.obj==0){imageView01.setImageBitmap(bitmap);}super.handleMessage(msg);}};Demo源码点击此处。
微信小程序chooseImage(从本地相册选择图片或使用相机拍照)
微信⼩程序chooseImage(从本地相册选择图⽚或使⽤相机拍照)⼀、使⽤APIvar util = require('../../utils/util.js')Page({data:{src:"../image/pic4.jpg"},gotoShow: function(){var _this = thiswx.chooseImage({count: 9, // 最多可以选择的图⽚张数,默认9sizeType: ['original', 'compressed'], // original 原图,compressed 压缩图,默认⼆者都有sourceType: ['album', 'camera'], // album 从相册选图,camera 使⽤相机,默认⼆者都有success: function(res){// successconsole.log(res)_this.setData({src:res.tempFilePaths})},fail: function() {// fail},complete: function() {// complete}})}⼆、图⽚路径进⾏数据绑定<view class="container"><view><button type="default" bindtap="gotoShow" >点击上传照⽚</button></view><view><image class= "show-image" mode="aspectFitf" src="{{src}}"></image></view></view>号外: 1、wx.chooseImage 调⽤相机或相册 2、<image class= "show-image" mode="aspectFitf" src="{{src}}"></image> 3、js中动态修改⽂件路径var _this = thiswx.chooseImage({count: 9, // 最多可以选择的图⽚张数,默认9sizeType: ['original', 'compressed'], // original 原图,compressed 压缩图,默认⼆者都有sourceType: ['album', 'camera'], // album 从相册选图,camera 使⽤相机,默认⼆者都有success: function(res){// successconsole.log(res)_this.setData({src:res.tempFilePaths})},fail: function() {// fail},complete: function() {// complete}。
黑马程序员安卓教程:图片特效处理
图片特效处理图片的特效包括图形的缩放、镜面、倒影、旋转、平移等。
图片的特效处理方式是将原图的图形矩阵乘以一个特效矩阵,形成一个新的图形矩阵来实现的。
矩阵Matrix类,维护了一个3*3的矩阵去更改像素点的坐标。
Android 手机的屏幕坐标系如下图所示。
横轴是X 坐标轴,从左往右变大,纵轴是Y 坐标轴,从上往下变大,坐标原点位于屏幕的左上角,用(0,0)表示。
6图1-2 屏幕坐标系图形的矩阵用数组表示为:{ 1, 0, 0, 第一行表示像素点的x 坐标:x = 1*x + 0*y + 0*z 0, 1,0, 第二行表示像素点的y 坐标:y = 0*x + 1*y + 0*z 0, 0, 1 }第三行表示像素点的z 坐标:z = 0*x + 0*y + 1*z图片的特效处理正是通过更改图形矩阵的值来实现的,下面分别给出各种特效实现的代码,在代码中会有详细的注释。
1.2.1准备工作创建一个Android工程“02-图片特效”,准备一张原始图片,然后在该应用界面水平放置缩放、平移、镜面、倒影、旋转等5个按钮,点击不同的按钮,在原始图正下方显示处理后的图片效果。
效果如图1-3所示。
图1-3 图片特效原始图7布局文件如下所示:【文件1-2】activity_main.xml1.<LinearLayout xmlns:android="/apk/res/android"2.xmlns:tools="/tools"3.android:layout_width="match_parent"4.android:layout_height="match_parent"5.android:orientation="vertical">6.7.<LinearLayout8.android:layout_width="match_parent"9.android:layout_height="wrap_content"10.android:orientation="horizontal"11.>12.<Button13.android:layout_width="0dp"14.android:layout_weight="1"15.android:layout_height="wrap_content"16.android:text="缩放"17.android:onClick="scale"18./>19.20.<Button21.android:layout_weight="1"22.android:layout_width="0dp"23.android:layout_height="wrap_content"24.android:text="平移"25.android:onClick="translate"26./>27.28.<Button29.android:layout_weight="1"30.android:layout_width="0dp"31.android:layout_height="wrap_content"32.android:text="镜面"33.android:onClick="mirror"34./>35.36.<Button37. android:layout_width="0dp"38. android:layout_weight="1"39. android:layout_height="wrap_content"40. android:text=" 倒影"41. android:onClick="invert"42. />843. <Button44. android:layout_width="0dp"45. android:layout_weight="1"46. android:layout_height="wrap_content"47. android:text=" 旋转"48. android:onClick="rotate"49. />50.51.</LinearLayout>52.53.<ImageView54.android:layout_gravity="center_horizontal"55.android:layout_width="wrap_content"56.android:layout_height="wrap_content"57.android:src="@drawable/logo"58./>59.<ImageView60.android:id="@+id/iv"61.android:layout_gravity="center_horizontal"62.android:layout_width="wrap_content"63.android:layout_height="wrap_content"64./>65.66.67.</LinearLayout>。
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读取本地照⽚和视频相册实例代码前⾔项⽬中经常要选择本地照⽚或者视频的需求,如果去扫描整个SD卡就太耗时间,其实Android系统在启动时就已经把整个设备中的多媒体⽂件信息(⽂件名,类型,⼤⼩等)都存到了数据库,然后提供了ContentPrivider这个API来管理这个数据库,我们可以利⽤ContentPrivider来获取所有的照⽚和视频。
ContentPrivider初识先看下管理的的数据库在哪data/data/⽬录下:有很多这种⽂件夹(⽇历,联系⼈,下载管理,多媒体等)我们需要的照⽚和视频就在media下⾯,进去看看。
进去找到database然后打开external.db,就可以看到多张表(⾳频,⽂件,Log,图像,视频等)照⽚相册那么获取照⽚直接通过 ContentProvider读取Images这个数据库就OK了,这⾥开启⼯作线程读取所有.jpeg和.png的图⽚,附上代码段:/*** 读取⼿机中所有图⽚信息*/private void getAllPhotoInfo() {new Thread(new Runnable() {@Overridepublic void run() {List<MediaBean> mediaBeen = new ArrayList<>();HashMap<String,List<MediaBean>> allPhotosTemp = new HashMap<>();//所有照⽚Uri mImageUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;String[] projImage = { MediaStore.Images.Media._ID, MediaStore.Images.Media.DATA,MediaStore.Images.Media.SIZE,MediaStore.Images.Media.DISPLAY_NAME};Cursor mCursor = getContentResolver().query(mImageUri,projImage,MediaStore.Images.Media.MIME_TYPE + "=? or " + MediaStore.Images.Media.MIME_TYPE + "=?",new String[]{"image/jpeg", "image/png"},MediaStore.Images.Media.DATE_MODIFIED+" desc");if(mCursor!=null){while (mCursor.moveToNext()) {// 获取图⽚的路径String path = mCursor.getString(mCursor.getColumnIndex(MediaStore.Images.Media.DATA));int size = mCursor.getInt(mCursor.getColumnIndex(MediaStore.Images.Media.SIZE))/1024;String displayName = mCursor.getString(mCursor.getColumnIndex(MediaStore.Images.Media.DISPLAY_NAME));//⽤于展⽰相册初始化界⾯mediaBeen.add(new MediaBean(MediaBean.Type.Image,path,size,displayName));// 获取该图⽚的⽗路径名String dirPath = new File(path).getParentFile().getAbsolutePath();//存储对应关系if (allPhotosTemp.containsKey(dirPath)) {List<MediaBean> data = allPhotosTemp.get(dirPath);data.add(new MediaBean(MediaBean.Type.Image,path,size,displayName));continue;} else {List<MediaBean> data = new ArrayList<>();data.add(new MediaBean(MediaBean.Type.Image,path,size,displayName));allPhotosTemp.put(dirPath,data);}}mCursor.close();}//更新界⾯runOnUiThread(new Runnable() {@Overridepublic void run() {//...}});}}).start();}有四点需要注意:1. MediaBean是⽂件实体类,代码就不贴了2. 照⽚集合不是放在List<MediaBean>这样存储的,⽽是HashMap<String,List<MediaBean>>,这样把图⽚已⽂件夹(也就是⽗⽬录)分类,更节省内存,其次⽀持相册展⽰不同⽂件夹的照⽚3. 貌似没办法获取当前设备的拍照默认路径,有的设备是/DCIM,有的是/100andro还有/camera,那相册就默认展⽰最近所有照⽚吧。
Android拍照剪裁功能实现步骤详解
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;
【推荐下载】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。
黑马程序员安卓教程:微信画板案例之保存
微信画板案例之保存
在微信画板案例中,我们已经实现了基本功能的项目需求。
下面我们要做的是:保存画板的图画到本地。
当点击按钮时,将绘制成功的图片保存在本地。
代码如理1-1所示:
例1-1
例1-1调用Bitmap的compress方法将一个位图保存文件中。
查看文档,如图1-1所示:
Compress方法将一个位图压缩到文件输入流。
该方法的三个参数分别表示图片压缩的格式,图片的质量(最大值为100),写入文件的输入流。
当文件压缩保存成功,则放回true,否则放回false。
运行程序,效果如图1-2所示:
保存图
图1-2所示
虽然文件可以保存到本地,但是在图库中并不能查询到保存的图片。
原因是:系统只会在开机重启和SD卡重新挂载的时候更新图库。
为了使图库加载我们保存的图片,我们可以发送SD卡挂载广播,系统收到广播就会更新图库,如此,我们就可以在图库中查看到保存的图片。
具体代码如例1-2:
运行程序,在点击保存按钮之后,图库会加载保存的图片,如图
图库的图片
图1-3所示提示:在编写本案例时,需要添加SD卡的读写权限。
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),添加如下代码。
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获取本地相册图⽚和拍照获取图⽚的实现⽅法需求:从本地相册找图⽚,或通过调⽤系统相机拍照得到图⽚。
容易出错的地⽅:1、当我们指定了照⽚的uri路径,我们就不能通过data.getData();来获取uri,⽽应该直接拿到uri(⽤全局变量或者其他⽅式)然后设置给imageViewimageView.setImageURI(uri);2、我发现⼿机前置摄像头拍出来的照⽚只有⼏百KB,直接⽤imageView.setImageURI(uri);没有很⼤问题,但是后置摄像头拍出来的照⽚⽐较⼤,这个时候使⽤imageView.setImageURI(uri);就容易出现 out of memory(oom)错误,我们需要先把URI 转换为Bitmap,再压缩bitmap,然后通过imageView.setImageBitmap(bitmap);来显⽰图⽚。
3、将照⽚存放到SD卡中后,照⽚不能⽴即出现在系统相册中,因此我们需要发送⼴播去提醒相册更新照⽚。
4、这⾥⽤到了sharepreference,要注意⽤完之后移除缓存。
代码:MainActivity:package .test;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.support.v7.app.AppCompatActivity;import android.util.Log;import android.view.View;import android.widget.ImageView;import .test.tools.ImageTools;import java.io.File;import java.io.IOException;import java.text.SimpleDateFormat;import java.util.Date;public class MainActivity extends AppCompatActivity {private static final int PHOTO_FROM_GALLERY = 1;private static final int PHOTO_FROM_CAMERA = 2;private ImageView imageView;private File appDir;private Uri uriForCamera;private Date date;private String str = "";private SharePreference sharePreference;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(yout.activity_main);//Android不推荐使⽤全局变量,我在这⾥使⽤了sharePreferencesharePreference = SharePreference.getInstance(this);imageView = (ImageView) findViewById(R.id.imageView);}//从相册取图⽚public void gallery(View view) {Intent intent = new Intent();intent.setType("image/*");intent.setAction(Intent.ACTION_GET_CONTENT);startActivityForResult(intent, PHOTO_FROM_GALLERY);}//拍照取图⽚public void camera(View view) {Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);uriForCamera = Uri.fromFile(createImageStoragePath());sharePreference.setCache("uri", String.valueOf(uriForCamera));/*** 指定了uri路径,startActivityForResult不返回intent,* 所以在onActivityResult()中不能通过data.getData()获取到uri;*/intent.putExtra(MediaStore.EXTRA_OUTPUT, uriForCamera);startActivityForResult(intent, PHOTO_FROM_CAMERA);}@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {super.onActivityResult(requestCode, resultCode, data);//第⼀层switchswitch (requestCode) {case PHOTO_FROM_GALLERY://第⼆层switchswitch (resultCode) {case RESULT_OK:if (data != null) {Uri uri = data.getData();imageView.setImageURI(uri);}break;case RESULT_CANCELED:break;}break;case PHOTO_FROM_CAMERA:if (resultCode == RESULT_OK) {Uri uri = Uri.parse(sharePreference.getString("uri"));updateDCIM(uri);try {//把URI转换为Bitmap,并将bitmap压缩,防⽌OOM(out of memory)Bitmap bitmap = ImageTools.getBitmapFromUri(uri, this);imageView.setImageBitmap(bitmap);} catch (IOException e) {e.printStackTrace();}removeCache("uri");} else {Log.e("result", "is not ok" + resultCode);}break;default:break;}}/*** 设置相⽚存放路径,先将照⽚存放到SD卡中,再操作** @return*/private File createImageStoragePath() {if (hasSdcard()) {appDir = new File("/sdcard/testImage/");if (!appDir.exists()) {appDir.mkdirs();}SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmss"); date = new Date();str = simpleDateFormat.format(date);String fileName = str + ".jpg";File file = new File(appDir, fileName);return file;} else {Log.e("sd", "is not load");return null;}}/*** 将照⽚插⼊系统相册,提醒相册更新** @param uri*/private void updateDCIM(Uri uri) {Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);intent.setData(uri);this.sendBroadcast(intent);Bitmap bitmap = BitmapFactory.decodeFile(uri.getPath());MediaStore.Images.Media.insertImage(getContentResolver(), bitmap, "", "");}/*** 判断SD卡是否可⽤** @return*/private boolean hasSdcard() {if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { return true;} else {return false;}}/*** 移除缓存** @param cache*/private void removeCache(String cache) {if (sharePreference.ifHaveShare(cache)) {sharePreference.removeOneCache(cache);} else {Log.e("this cache", "is not exist.");}}}ImageTools:package .test.tools;import android.app.Activity;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import .Uri;import java.io.ByteArrayInputStream;import java.io.ByteArrayOutputStream;import java.io.FileNotFoundException;import java.io.IOException;import java.io.InputStream;public class ImageTools {/*** 通过uri获取图⽚并进⾏压缩** @param uri* @param activity* @return* @throws IOException*/public static Bitmap getBitmapFromUri(Uri uri, Activity activity) throws IOException { InputStream inputStream = activity.getContentResolver().openInputStream(uri);BitmapFactory.Options options = new BitmapFactory.Options();options.inJustDecodeBounds = true;options.inDither = true;options.inPreferredConfig = Bitmap.Config.ARGB_8888;BitmapFactory.decodeStream(inputStream, null, options);inputStream.close();int originalWidth = options.outWidth;int originalHeight = options.outHeight;if (originalWidth == -1 || originalHeight == -1) {return null;}float height = 800f;float width = 480f;int be = 1; //be=1表⽰不缩放if (originalWidth > originalHeight && originalWidth > width) {be = (int) (originalWidth / width);} else if (originalWidth < originalHeight && originalHeight > height) {be = (int) (originalHeight / height);}if (be <= 0) {be = 1;}BitmapFactory.Options bitmapOptinos = new BitmapFactory.Options();bitmapOptinos.inSampleSize = be;bitmapOptinos.inDither = true;bitmapOptinos.inPreferredConfig = Bitmap.Config.ARGB_8888;inputStream = activity.getContentResolver().openInputStream(uri);Bitmap bitmap = BitmapFactory.decodeStream(inputStream, null, bitmapOptinos);inputStream.close();return compressImage(bitmap);}/*** 质量压缩⽅法** @param bitmap* @return*/public static Bitmap compressImage(Bitmap bitmap) {ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();press(pressFormat.JPEG, 100, byteArrayOutputStream);int options = 100;while (byteArrayOutputStream.toByteArray().length / 1024 > 100) {byteArrayOutputStream.reset();//第⼀个参数:图⽚格式,第⼆个参数:图⽚质量,100为最⾼,0为最差,第三个参数:保存压缩后的数据的流 press(pressFormat.JPEG, options, byteArrayOutputStream);options -= 10;}ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray()); Bitmap bitmapImage = BitmapFactory.decodeStream(byteArrayInputStream, null, null);return bitmapImage;}}AndroidMainfest.xml:<?xml version="1.0" encoding="utf-8"?><manifest package=".test"xmlns:android="/apk/res/android"><uses-featureandroid:name="android.hardware.camera"android:required="true"/><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/><uses-permission android:name="android.permission.CAMERA"/><uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/><uses-permission android:name="com.miui.whetstone.permission.ACCESS_PROVIDER"/><uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/><uses-feature android:name="android.hardware.camera.autofocus" /><applicationandroid:allowBackup="true"android:icon="@mipmap/ic_launcher"android:label="@string/app_name"android:supportsRtl="true"android:theme="@style/AppTheme"><activity android:name=".MainActivity"><intent-filter><action android:name="android.intent.action.MAIN"/><category android:name="UNCHER"/></intent-filter></activity></application></manifest>activity_main.xml:<?xml version="1.0" encoding="utf-8"?><LinearLayoutxmlns:android="/apk/res/android"xmlns:tools="/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:background="#fff"android:orientation="vertical"tools:context=".test.MainActivity"><Buttonandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="从图库找图⽚"android:id="@+id/gallery"android:onClick="gallery"android:background="#ccc"android:textSize="20sp"android:padding="10dp"android:layout_marginLeft="30dp"android:layout_marginTop="40dp"/><Buttonandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="拍照获取图⽚"android:id="@+id/camera"android:onClick="camera"android:background="#ccc"android:textSize="20sp"android:padding="10dp"android:layout_marginLeft="30dp"android:layout_marginTop="40dp"/><ImageViewandroid:layout_width="300dp"android:layout_height="300dp"android:id="@+id/imageView"android:scaleType="fitXY"android:background="@mipmap/ic_launcher"android:layout_marginTop="40dp"android:layout_marginLeft="30dp"/></LinearLayout>效果图:或许有⼈会问,在Android6.0上⾯怎么点击拍照就出现闪退,那是因为我设置的最⾼SDK版本⼤于23,⽽我现在还没对运⾏时权限做处理,也许我会在下⼀篇博客⾥处理这个问题。
黑马程序员基础测试题答案
黑马程序员基础测试题答案一、选择题1. 以下哪一项不是Java基本数据类型?答案:D. String解析:Java基本数据类型共有8种,分别为byte、short、int、long、float、double、char、boolean。
String是Java 中的一个类,不属于基本数据类型。
2. 在Java中,下列哪个操作符用于取模?答案:C. %解析:在Java中,取模操作符是%。
例如,5 % 2的结果为1。
3. 下列哪个方法可以实现字符串的截取?答案:B. substring(int start, int end)解析:substring(int start, int end)方法是String类中用于截取字符串的方法,其中start表示开始截取的位置,end表示结束截取的位置。
二、填空题1. Java中,定义一个整型变量需要使用______关键字。
答案:int2. 在Java中,数组的默认初始化值为______。
答案:0(对于数值类型),false(对于布尔类型),null (对于引用类型)3. 下列哪个方法可以实现字符串的拼接?答案:concat(String str)三、判断题1. 在Java中,所有的对象都继承自Object类。
答案:正确解析:在Java中,所有的类都直接或间接继承自Object类,Object类是Java类库中的根类。
2. Java中的方法可以重载,即可以有多个同名方法,但参数列表必须不同。
答案:正确解析:Java中的方法重载是指同一个类中可以有多个同名方法,但参数列表必须不同,包括参数个数和参数类型。
3. 在Java中,数组是一种引用类型。
答案:正确解析:在Java中,数组是一种引用类型,它可以存储多个相同类型的元素。
数组的声明、创建和初始化如下:```javaint[] arr = new int[10]; // 声明并创建一个整型数组,长度为10arr[0] = 1; // 初始化数组第一个元素```四、编程题1. 编写一个Java程序,实现以下功能:输入一个字符串,输出字符串中字母和数字的个数。
Android实现拍照或者选取本地图片
Android实现拍照或者选取本地图⽚本⽂实例为⼤家分享了Android实现拍照或者选取本地图⽚的具体代码,供⼤家参考,具体内容如下总体流程从selectPhotoActivity中启动图册或者相机,再根据获取的uri进⾏裁剪,返回uri,再对这个uri执⾏⼀系列操纵。
从相册选取图⽚private void pickPhoto() {Intent intent = new Intent(Intent.ACTION_PICK,android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);startActivityForResult(intent, SELECT_PIC_BY_PICK_PHOTO);}使⽤隐式intent启动相机。
拍照获取图⽚private void takePhoto() {// 执⾏拍照前,应该先判断SD卡是否存在String SDState = Environment.getExternalStorageState();if (SDState.equals(Environment.MEDIA_MOUNTED)) {Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);// "android.media.action.IMAGE_CAPTURE"File path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM);File file = new File(path, IMAGE_FILE_NAME);takePhoto = Uri.fromFile(file);intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, takePhoto);startActivityForResult(intent, SELECT_PIC_BY_TACK_PHOTO);} else {Toast.makeText(getApplicationContext(), "内存卡不存在",Toast.LENGTH_SHORT).show();}}值得注意的⼀点是,intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, takePhoto)中,设置了拍完照照⽚的存放路径takePhoto,在此情况下,部分机型的onActivityResult()中不会返回数据,即data.getData()为空,因为可以根据存放路径即可获取拍照图⽚。
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 takephoto用法(一)
android takephoto用法(一)Android TakePhoto使用方法详解Android TakePhoto是一个功能强大的拍照和相册选择库。
它提供了简单易用的API,可以轻松地在Android应用中实现拍照、相册选择和图片裁剪等功能。
下面是Android TakePhoto的一些主要用法:1. 基本用法Android TakePhoto的基本用法非常简单,在Activity或Fragment中通过以下步骤即可实现拍照或相册选择功能:1.创建TakePhoto实例:TakePhoto takePhoto = getTakePhoto();2.启动拍照或相册选择:(imageUri);// 或();3.处理拍照或相册选择结果:@Overridepublic void onActivityResult(int requestCode, int r esultCode, Intent data) {(requestCode, resultCode, data);(requestCode, resultCode, data);}2. 图片裁剪Android TakePhoto还提供了图片裁剪功能,可以对拍照或相册选择的图片进行裁剪操作。
以下是图片裁剪的用法:1.创建TakePhoto实例(同基本用法)。
2.设置裁剪参数:builder = new ();(1).setAspectY(1); // 设置裁剪比例为1:1(false); // 使用系统裁剪工具CropOptions cropOptions = ();(cropOptions);3.启动图片裁剪:(imageUri, cropOptions);// 或(imageUri, cropOptions);4.处理图片裁剪结果(同基本用法)。
3. 自定义配置Android TakePhoto还提供了丰富的自定义配置选项,可以根据需要定制拍照和相册选择的行为。
在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 方法;另外一种就是自动外观的摄像头用户界面,要求编写更多的代码。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
【黑马程序员】安卓中选择本地图片或拍照获取图片并裁剪在开发的时候我们经常遇到一种需求,就是让用户上传一张图片作为头像。
这个图片可能是从相册中选择的,也可能是使用摄像头现拍的。
不过得到的图片都会进行一步裁剪的操作。
下面我们就来实现一下这个需求。
首先我们定义一个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 的点击事件,当按钮被点击的时候就弹出一个对话框来让用户选择是从相册还是拍照得到图片。
弹窗代码如下: 01 02 03 04 05 06 07 08 09 10 private void showDialog () {new AlertDialog.Builder (this ).setTitle ("设置头像").setItems (items , new DialogInterface.OnClickListener () {@Overridepublic void onClick (DialogInterface dialog , int which ) { switch (which ) {case 0:Intent intentFromGallery = new Intent ();intentFromGallery.setType ("image/*"); // 设置文件类型intentFromGallery.setAction (Intent.ACTION_GET_CONT ENT );startActivityForResult (intentFromGallery ,IMAGE_REQ UEST_CODE );break;case 1:Intent intentFromCapture = new1 1 12 13 14 15 16 17 18 19 2 0 2 1 2 2 2 3 2 4 2 5 2 6 2 7 2 8 2 9 3 0 3 1 3 2Intent(MediaStore.ACTION_IMAGE_CAPTURE);//判断存储卡是否可以用,可用进行存储if(hasSdcard()){intentFromCapture.putExtra(MediaStore.EXTRA_OU TPUT,Uri.fromFile(newFile(Environment.getExternalStorageDirectory(),IMAGE_FILE_NAME)));}startActivityForResult(intentFromCapture,CAMERA_RE QUEST_CODE);break;}}}).setNegativeButton("取消",new DialogInterface.OnClickListener(){@Overridepublic void onClick(DialogInterface dialog, int which){dialog.dismiss();}}).show();}3334 35 36其中,点击第一个选项会打开相册。
通过Intent 打开系统相册,通过intentFromGallery.setType("image/*")设置文件类型为图片;通过intentFromGallery.setAction(Intent.ACTION_GET_CONTENT)设置要打开系统的相册应用,然后拉起界面打开相册。
当用户选择相册中的图片时,会回调到onActivityResult 方法。
在这个里面我们可以处理返回的图片进行裁剪。
点击第二个选项会调用系统的摄像机应用,通过设置action 为MediaStore.ACTION_IMAGE_CAPTURE 拉起摄像机。
其中通过intentFromCapture.putExtra(MediaStore.EXTRA_OUTPUT,Uri.fromFile(new File(Environment.getExternalStorageDirectory(),IMAGE_FILE_NAME)))设置拍摄的照片的存储位置。
然后拍照成功后回调到onActivityResult 方法。
同样的,我们对拍摄的图片进行裁剪。
01 02 03 04 05 06 07 08 09 10 11 12 13 14 @Overrideprotected void onActivityResult (int requestCode , int resultCode , Intent data ) {// 结果码不等于取消时候if (resultCode != RESULT_CANCELED ) {switch (requestCode ) {case IMAGE_REQUEST_CODE :startPhotoZoom (data .getData ());break;case CAMERA_REQUEST_CODE :if (hasSdcard ()) {File tempFile = newFile (Environment.getExternalStorageDirectory (),IMAGE_FILE_NAME );startPhotoZoom (Uri.fromFile (tempFile ));15 16 17 18 19 20 21 22 23 24 25 26 } else {Toast.makeText (context , "未找到存储卡,无法存储照片!", Toast.LENGTH_SHORT ).show ();}break;case RESULT_REQUEST_CODE :if (data != null ) {setImageToView (data );}break;}}super.onActivityResult (requestCode , resultCode , data );}当用户没有选择取消的时候会走到switch 的 IMAGE_REQUEST_CODE 分支或CAMERA_REQUEST_CODE 分支,从而调用startPhotoZoom 进行图片的裁剪。
我们一起来看看如何实现裁剪的逻辑吧。
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 /*** 裁剪图片方法实现** @param uri*/public void startPhotoZoom (Uri uri ) {if (uri ==null ){Log.i ("tag", "The uri is not exist.");}Intent intent = new Intent ("com.android.camera.action.CROP");intent.setDataAndType (uri , "image/*");// 设置裁剪intent.putExtra ("crop", "true");// aspectX aspectY 是宽高的比例intent.putExtra ("aspectX", 1);intent.putExtra ("aspectY", 1);// outputX outputY 是裁剪图片宽高intent.putExtra ("outputX", 320);intent.putExtra ("outputY", 320);intent.putExtra ("return-data", true );startActivityForResult (intent , 2);22 }很简单,还是拉起界面,Intent的action设置为com.android.camera.action.CROP 即可,不过需要设置一下参数。
首先crop代表是否进行裁剪,我们设置为true,aspectX 和aspectY代表的事宽高的比例,我们保持1:1的比例。
outputX和outputY是输出裁剪之后的图片宽高,是以像素为单位的,这里我设置了320,具体大小根据自己的项目需求设置。
然后return-data代表需要返回图片。
拉起Activity,进入裁剪的界面。
途中的橙色方框就是裁剪的范围,可自由拖动,点击保存后还是会把结果返回到我们最初的Activity 的onActivityResult 方法里。
这一次触发switch 的RESULT_REQUEST_CODE 分支,得到最终的图片结果。