Android 批量上传图片进度回调

之前写过一个对图片进行高保真压缩的文章,把图片压缩的这么小当然是为了上传的,这次就把图片批量上传的代码也一起贴出来,这个方法是基于xUtils的Http模块

首先这个上传过程要满足一下特性

1、开启多个线程进行图片的批量同时上传

2、每张图片的上传进度都可以获取到,并且显示在界面上

3、如果有一张图片上传失败就宣布上传过程失败,然后等待用户再次发起同样的上传命令

4、所有图片均上传成功后有一个完毕的回调

5、每张图片上传完毕后要从上传服务器得到一个json记录上传图片的id

6、对于已经上传过的图片不再上传第二遍

7、对于已经压缩过的图片不再压缩第二遍

8、对于像三星这样的手机,拍摄出来的照片都是宽度大于高度的躺着的照片,需要根据exif信息将图片旋转后再上传

9、对于压缩的照片,保留原来照片的exif信息

这个工具类里面还包含了几个额外的方法

1、对于sd卡中的一张图片,添加到系统相册中并保存缩略图

2、复制一张照片的exif信息到另一张照片

下面就是上传过程加压缩的代码,其中有一部分是《Android 高质量高压缩比图像压缩》里面的代码

package com.imaginato.qravedconsumer.utils;


import android.app.ActivityManager;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.res.AssetFileDescriptor;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.media.ExifInterface;
import android.net.Uri;
import android.os.Build;
import android.provider.MediaStore;
import android.util.Log;

import com.imaginato.qravedconsumer.task.AlxAsynTask;
import com.lidroid.xutils.HttpUtils;
import com.lidroid.xutils.exception.HttpException;
import com.lidroid.xutils.http.RequestParams;
import com.lidroid.xutils.http.ResponseInfo;
import com.lidroid.xutils.http.callback.RequestCallBack;
import com.lidroid.xutils.http.client.HttpRequest;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.OutputStream;

/**
 * Created by Alex on 2016/4/6.
 */
public class AlxBitmapUtils {

    /**
     * 传入一个bitmap,根据传入比例进行大小缩放
     * @param bitmap
     * @param widthRatio 宽度比例,缩小就比1小,放大就比1大
     * @param heightRatio
     * @return
     */
    public static Bitmap scaleBitmap(Bitmap bitmap, float widthRatio, float heightRatio) {
        Matrix matrix = new Matrix();
        matrix.postScale(widthRatio,heightRatio);
        return Bitmap.createBitmap(bitmap,0,0,bitmap.getWidth(),bitmap.getHeight(),matrix,true);
    }

    /**
     * 传入图片路径,根据图片进行压缩,仅压缩大小,不压缩质量,
     * @param oriFile 源文件
     * @param targetFile 这个和 stream传一个就行,只有穿file的时候才会保留exif信息,但是都会根据旋转角度进行旋转
     * @param ifDel 是否需要在压缩完毕后删除原图
     */
    public static void compressImage(File oriFile, File targetFile, OutputStream stream,boolean ifDel,int rotateDegree,boolean keepExif) {
        if(oriFile ==null || !oriFile.isFile()|| !oriFile.exists())return;
//        Log.i("Alex","源图片为"+oriFile);
//        Log.i("Alex","目标地址为"+targetFile);
        try {
            BitmapFactory.Options opts = new BitmapFactory.Options();
            opts.inJustDecodeBounds = true; // 不读取像素数组到内存中,仅读取图片的信息,非常重要
            BitmapFactory.decodeFile(oriFile.getAbsolutePath(), opts);//读取文件信息,存放到Options对象中
            // 从Options中获取图片的分辨率
            int imageHeight = opts.outHeight;
            int imageWidth = opts.outWidth;
            int longEdge = Math.max(imageHeight,imageWidth);//取出宽高中的长边
            int pixelCount = (imageWidth*imageHeight)>>20;//看看这张照片有多少百万像素
//            Log.i("Alex","图片宽为"+imageWidth+"图片高为"+imageHeight+"图片像素数为"+pixelCount+"百万像素");

            long size = oriFile.length();
            Log.i("Alex","f.length 图片大小为"+(size>>10)+" KB");
            //走到这一步的时候,内存里还没有bitmap
            Bitmap bitmap = null;
            if(pixelCount > 3){//如果超过了3百万像素,那么就首先对大小进行压缩
                float compressRatio = longEdge /1280f;
                int compressRatioInt = Math.round(compressRatio);
                if(compressRatioInt%2!=0 && compressRatioInt!=1)compressRatioInt++;//如果是奇数的话,就给弄成偶数
//                Log.i("Alex","长宽压缩比是"+compressRatio+" 偶数化后"+compressRatioInt);
                //尺寸压缩
                BitmapFactory.Options options = new BitmapFactory.Options();
                //目标出来的大小1024*1024 1百万像素,100k
                options.inSampleSize = Math.round(compressRatioInt);//注意,此处必须是偶数,根据计算好的比例进行压缩,如果长边没有超过1280*1.5,就不去压缩,否则就压缩成原来的一半
                options.inJustDecodeBounds = false;//在decode file的时候,不仅读取图片的信息,还把像素数组到内存
                options.inPreferredConfig = Bitmap.Config.RGB_565;//每个像素占四位,即R=5,G=6,B=5,没有透明度,那么一个像素点占5+6+5=16位
                //现在开始将bitmap放入内存
                bitmap = BitmapFactory.decodeFile(oriFile.getAbsolutePath(), options);//根据压缩比取出大小已经压缩好的bitmap
                //此处会打印出存入内存的bitmap大小
            }else if(imageHeight*imageWidth>2073600){//如果图片大于1920*1080,为了减少内存开销,使用RGB——565
                BitmapFactory.Options options = new BitmapFactory.Options();
                //目标出来的大小1024*1024 1百万像素,100k
                options.inSampleSize = 1;//注意,此处必须是偶数,根据计算好的比例进行压缩,如果长边没有超过1280*1.5,就不去压缩,否则就压缩成原来的一半
                options.inJustDecodeBounds = false;//在decode file的时候,不仅读取图片的信息,还把像素数组到内存
                options.inPreferredConfig = Bitmap.Config.RGB_565;//每个像素占四位,即R=5,G=6,B=5,没有透明度,那么一个像素点占5+6+5=16位
                //现在开始将bitmap放入内存
                bitmap = BitmapFactory.decodeFile(oriFile.getAbsolutePath(), options);//根据压缩比取出大小已经压缩好的bitmap
                //此处会打印出存入内存的bitmap大小
            }else {//如果是长图或者长边短于1920的图,那么只进行质量压缩
                // 现在开始将bitmap放入内存
                bitmap = BitmapFactory.decodeFile(oriFile.getAbsolutePath());
                //此处会打印出bitmap在内存中占得大小
            }
           
  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值