Android(安卓)图片获取及上传
16lz
2021-01-26
一、实现逻辑与思路
在Android中实现图片上传,有两种途径:本地上传,照相上传。
在整体框架中,需要实现,打开两种图片上传的方式,然后是接受获取到的图片,并做基本的展示。在主页面中,实现2个Button,用于跳转获取图片的触发事件。在底下实现GridView,用于接受获取到的图片。
图片可上传,当然也可去除选中的图片。为每个Item实现长按事件,从而展示删除按钮,实现对图片的管理。
1,本地上传
应用Button跳转事件,展示本地所有的图片列表。根据选中事件,跳转展示图片列表对应的图片详情。当前图片展示页面只用于展示图片,对图片进行了缩放。添加图片被选中框,能够管理图片是否被选中状态。
整个过程实现了主页面---图片列表页面--图片展示详情页面,点击完成,图片需要被传回主页面。当前采用广播的模式将选中的图片信息,传回主页面。同时,主页面需要有广播接收器,接受回传的图片信息。
需要加载本地图片文件列表,获取全部图片地址的方法。
为实现图片的压缩,需要获取图片原有大小。
抽取图片处理相关方法:
public class Util { Context context; public Util(Context context) { this.context = context; } /** * 获取全部图片地址 * * @return */ public ArrayList<String> listAlldir() { Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI); Uri uri = intent.getData(); ArrayList<String> list = new ArrayList<String>(); String[] proj = {MediaStore.Images.Media.DATA}; Cursor cursor = context.getContentResolver().query(uri, proj, null, null, null);//managedQuery(uri, proj, null, null, null); if (cursor != null) { while (cursor.moveToNext()) { String path = cursor.getString(0); list.add(new File(path).getAbsolutePath()); } } return list; } /** * 本地图片文件列表 * @return */ public List<FileTraversal> LocalImgFileList() { List<FileTraversal> data = new ArrayList<FileTraversal>(); String filename = ""; List<String> allimglist = listAlldir(); List<String> retulist = new ArrayList<String>(); if (allimglist != null) { Set set = new TreeSet(); String[] str; for (int i = 0; i < allimglist.size(); i++) { retulist.add(getfileinfo(allimglist.get(i))); } for (int i = 0; i < retulist.size(); i++) { set.add(retulist.get(i)); } str = (String[]) set.toArray(new String[0]); for(int i = 0; i < str.length; i++) { filename = str[i]; FileTraversal ftl = new FileTraversal(); ftl.filename = filename; data.add(ftl); } for (int i = 0; i < data.size(); i++) { for (int j = 0; j < allimglist.size(); j++) { if (data.get(i).filename.equals(getfileinfo(allimglist.get(j)))) { data.get(i).filecontent.add(allimglist.get(j)); } } } } return data; } //显示原生图片尺寸大小 public Bitmap getPathBitmap(Uri imageFilePath, int dw, int dh) throws FileNotFoundException { //获取屏幕的宽和高 /** * 为了计算缩放的比例,我们需要获取整个图片的尺寸,而不是图片 * BitmapFactory.Options类中有一个布尔型变量inJustDecodeBounds,将其设置为true * 这样,我们获取到的就是图片的尺寸,而不用加载图片了。 * 当我们设置这个值的时候,我们接着就可以从BitmapFactory.Options的outWidth和outHeight中获取到值 */ BitmapFactory.Options op = new BitmapFactory.Options(); op.inJustDecodeBounds = true; //由于使用了MediaStore存储,这里根据URI获取输入流的形式 Bitmap pic = BitmapFactory.decodeStream(context.getContentResolver().openInputStream(imageFilePath), null, op); int wRatio = (int) Math.ceil(op.outWidth / (float) dw); //计算宽度比例 int hRatio = (int) Math.ceil(op.outHeight / (float) dh); //计算高度比例 /** * 接下来,我们就需要判断是否需要缩放以及到底对宽还是高进行缩放。 * 如果高和宽不是全都超出了屏幕,那么无需缩放。 * 如果高和宽都超出了屏幕大小,则如何选择缩放呢》 * 这需要判断wRatio和hRatio的大小 * 大的一个将被缩放,因为缩放大的时,小的应该自动进行同比率缩放。 * 缩放使用的还是inSampleSize变量 */ if (wRatio > 1 && hRatio > 1) { if (wRatio > hRatio) { op.inSampleSize = wRatio; } else { op.inSampleSize = hRatio; } } op.inJustDecodeBounds = false; //注意这里,一定要设置为false,因为上面我们将其设置为true来获取图片尺寸了 pic = BitmapFactory.decodeStream(context.getContentResolver() .openInputStream(imageFilePath), null, op); return pic; } /** * 获取文件信息 * @param data * @return */ public String getfileinfo(String data) { String filename[] = data.split("/"); if (filename != null) { return filename[filename.length - 2]; } return null; } public void imgExcute(ImageView imageView, ImgCallBack icb, String... params) { LoadBitAsynk loadBitAsynk = new LoadBitAsynk(imageView, icb); loadBitAsynk.execute(params); } /** * 异步加载图片信息 */ public class LoadBitAsynk extends AsyncTask<String, Integer, Bitmap> { ImageView imageView; ImgCallBack icb; LoadBitAsynk(ImageView imageView, ImgCallBack icb) { this.imageView = imageView; this.icb = icb; } @Override protected Bitmap doInBackground(String... params) { Bitmap bitmap = null; try { if (params != null) { for (int i = 0; i < params.length; i++) { bitmap = getPathBitmap(Uri.fromFile(new File(params[i])), 200, 200); } } } catch (FileNotFoundException e) { e.printStackTrace(); } return bitmap; } @Override protected void onPostExecute(Bitmap result) { super.onPostExecute(result); if (result != null) { icb.resultImgCall(imageView, result); } } }}本地加载图片效果:
2,照相上传
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); startActivityForResult(intent, 2);调用系统照相方法即可实现。
注意整体权限添加。
二、注意说明
1,两种展示数据的方式不同:
本地上传应用广播回传,照片上传使用:startActivityForResult。
2,上传图片需要对图片进行压缩、加密:
常用方法是将图片编码为base64。
/** * 获取base64字符串[ 上传图片前将所有图片编码成为base64字符串,然后以一个参数的方式上传图片 ] * * @return */ protected String getImageFiles16() { StringBuilder builder = new StringBuilder(); try { for (BitmapDrawable drawable : bitmaps) { builder.append(BitmapUtil.bitmaptoString(drawable.getBitmap())); builder.append("|"); } if (builder.length() != 0) { builder.deleteCharAt(builder.length() - 1); } else { return null; } } catch (Exception e) { e.printStackTrace(); return null; } return builder.toString(); }获取到base64的图片内容,使用String的模式上传数据即可。
生活总是让我们遍体鳞伤,但到后来,那些受伤的地方一定会变成我们最强壮的地方.
更多相关文章
- 使用Glide替换Picasso经验小结
- Android中新建的文件在R没有显示对应的文件解决办法总结
- Android多点触控实现图片缩放预览
- android 的外部存储的挂载的理解
- Android(安卓)分享功能之 微信 图片分享
- Android创建应用快捷方式(ShortCut)的有效方式
- android在TextView的最后一行后面拼接view(类似长文本的查看更多
- 【自定义控件系列一】android画图类---Canvas浅谈
- 【Android】获取当前 Wifi 的 MAC 地址(BSSID),注意并非是手机的MAC