您的位置:首页 > 移动开发 > Android开发

Android 图片获取及上传

2016-05-03 15:57 393 查看
一、实现逻辑与思路

在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的模式上传数据即可。

生活总是让我们遍体鳞伤,但到后来,那些受伤的地方一定会变成我们最强壮的地方.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: