如何在使用改造发送到服务器之前压缩捕获的图像文件大小

How to Compress the captured image file size before sending to server using retrofit

我正在使用 Retrofit retrofit:2.1.0' 将文件图像上传到服务器

如果我使用前置摄像头拍照图像上传成功但如果使用后置摄像头它没有上传我认为是因为文件很大图像没有上传在改造中发送到服务器之前有没有压缩文件大小的选项?

文件发送编码

  map.put("complaint_category", RequestBody.create(parse("text"), caty_id_str.getBytes()));

    // Map is used to multipart the file using okhttp3.RequestBody
    File file = new File(Config.uriImage);
    // Parsing any Media type file
    RequestBody requestBody = RequestBody.create(parse("*/*"), file);
    MultipartBody.Part fileToUpload = MultipartBody.Part.createFormData("photo", file.getName(), requestBody);
    RequestBody filename = RequestBody.create(parse("text/plain"), file.getName());

    Call<PostComplaint> call3 = apiInterface.postComplaint(fileToUpload, filename, map);
    call3.enqueue(new Callback<PostComplaint>() {
        @Override
        public void onResponse(Call<PostComplaint> call, Response<PostComplaint> response) {

            progressDoalog.dismiss();

            PostComplaint respon = response.body();

            PostComplaint.Response respo = respon.getResponse();

            String result = respo.getResult();
            String data = respo.getData();
            if (result.equalsIgnoreCase("Success")) {

                Toast.makeText(getApplicationContext(), data, Toast.LENGTH_SHORT).show();
                Intent intent = new Intent(Activity_Post_Complaint.this, MainActivity.class);
                startActivity(intent);

            } else {

                Toast.makeText(getApplicationContext(), data, Toast.LENGTH_SHORT).show();
            }

        }

        @Override
        public void onFailure(Call<PostComplaint> call, Throwable t) {
            progressDoalog.dismiss();
            Log.d("Error", "" + t.getMessage());
            call.cancel();
        }


    });

API 界面

@Multipart
@POST("/somelink.php?")
Call<PostComplaint> postComplaint(@Part MultipartBody.Part file,
                               @Part("photo") RequestBody name,
                               @PartMap Map<String, RequestBody> fields);

APIClient.java

public class APIClient {

    private static Retrofit retrofit = null;

    static Retrofit getClient() {

        HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
        interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
        OkHttpClient client = new OkHttpClient.Builder().addInterceptor(interceptor)
                .connectTimeout(60, TimeUnit.SECONDS)
                .readTimeout(60, TimeUnit.SECONDS)
                .writeTimeout(60, TimeUnit.SECONDS)
                .build();

        retrofit = new Retrofit.Builder()
                .baseUrl("http://192.168.1.135")
                .addConverterFactory(GsonConverterFactory.create())
                .client(client)
                .build();

        return retrofit;
    }

}

如果您正在寻找图像压缩,您可以使用这个库 https://github.com/zetbaitsu/Compressor。它非常简单而且很棒。 link 说明了一切。

尝试

int compressionRatio = 2; //1 == originalImage, 2 = 50% compression, 4=25% compress
File file = new File (imageUrl);
try {
    Bitmap bitmap = BitmapFactory.decodeFile (file.getPath ());
    bitmap.compress (Bitmap.CompressFormat.JPEG, compressionRatio, new FileOutputStream (file));
}
catch (Throwable t) {
    Log.e("ERROR", "Error compressing file." + t.toString ());
    t.printStackTrace ();
}

试试下面的代码:

Bitmap bmp = BitmapFactory.decodeFile(file);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bmp.compress(CompressFormat.JPEG, 70, bos);
InputStream in = new ByteArrayInputStream(bos.toByteArray());
ContentBody foto = new InputStreamBody(in, "image/jpeg", "filename");

将压缩的捕获图像与文本一起发送到服务器

截图:

public void captureImage() {

    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

    try {

        path = createImageFile();

        file = FileProvider.getUriForFile(MainActivity.this,
                BuildConfig.APPLICATION_ID + ".provider", path);

    } catch (IOException e) {
        e.printStackTrace();
    }

    List<ResolveInfo> resInfoList = context.getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
    for (ResolveInfo resolveInfo : resInfoList) {
        String packageName = resolveInfo.activityInfo.packageName;
        context.grantUriPermission(packageName, file, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
    }

    intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, file);
    startActivityForResult(intent, REQUEST_TAKE_PHOTO);
}

onActivityResult:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == REQUEST_TAKE_PHOTO) {
        if (resultCode == RESULT_OK) {

            Config.uriImage = String.valueOf(path);

            Intent intent = new Intent(MainActivity.this, Activity_Category.class);
            startActivity(intent);

            Toast.makeText(getApplicationContext(), Config.uriImage, Toast.LENGTH_SHORT).show();
        }
    }
}

创建路径:

private File createImageFile() throws IOException {
    // Create an image file name
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
    String imageFileName = "JPEG_" + timeStamp + "_";
    File storageDir = new File(Environment.getExternalStoragePublicDirectory(
            Environment.DIRECTORY_DCIM), "Camera");
    File image = File.createTempFile(
            imageFileName,  /* prefix */
            ".jpg",         /* suffix */
            storageDir      /* directory */
    );

    // Save a file: path for use with ACTION_VIEW intents
    mCurrentPhotoPath = "file:" + image.getAbsolutePath();
    return image;
}

文件发送编码:

private void postComplaintJSON() {

    // Set up progress before call
    final ProgressDialog progressDoalog;
    progressDoalog = new ProgressDialog(Activity_Post_Complaint.this);
    progressDoalog.setMax(100);
    progressDoalog.setCancelable(false);
    progressDoalog.setMessage("Its loading....");
    progressDoalog.setTitle("Category List");
    progressDoalog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
    // show it
    progressDoalog.show();

    int compressionRatio = 25; //1 == originalImage, 2 = 50% compression, 4=25% compress
    File file = new File (Config.uriImage);
    try {
        Bitmap bitmap = BitmapFactory.decodeFile (file.getPath ());
        bitmap.compress (Bitmap.CompressFormat.JPEG, compressionRatio, new FileOutputStream(file));
    }
    catch (Throwable t) {
        Log.e("ERROR", "Error compressing file." + t.toString ());
        t.printStackTrace ();
    }

    /**
     POST name and job Url encoded.
     **/
    Map<String, RequestBody> map = new HashMap<>();
    map.put("data_type", RequestBody.create(parse("text"), "PostComplaint".getBytes()));
    map.put("complaint_category", RequestBody.create(parse("text"), caty_id_str.getBytes()));

    // Parsing any Media type file
    RequestBody requestBody = RequestBody.create(parse("*/*"), file);
    MultipartBody.Part fileToUpload = MultipartBody.Part.createFormData("photo", file.getName(), requestBody);
    RequestBody filename = RequestBody.create(parse("text/plain"), file.getName());

    Call<PostComplaint> call3 = apiInterface.postComplaint(fileToUpload, filename, map);
    call3.enqueue(new Callback<PostComplaint>() {
        @Override
        public void onResponse(Call<PostComplaint> call, Response<PostComplaint> response) {

            progressDoalog.dismiss();

            PostComplaint respon = response.body();

            PostComplaint.Response respo = respon.getResponse();

            String result = respo.getResult();
            String data = respo.getData();

            if (result.equalsIgnoreCase("Success")) {

                Toast.makeText(getApplicationContext(), data, Toast.LENGTH_SHORT).show();
                Intent intent = new Intent(Activity_Post_Complaint.this, MainActivity.class);
                startActivity(intent);

            } else {

                Toast.makeText(getApplicationContext(), data, Toast.LENGTH_SHORT).show();
            }

        }

        @Override
        public void onFailure(Call<PostComplaint> call, Throwable t) {
            progressDoalog.dismiss();
            Log.d("Error", "" + t.getMessage());
            call.cancel();
        }


    });
}

勾选这个class压缩图片

import android.content.Context
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.Canvas
import android.graphics.Matrix
import android.graphics.Paint
import android.net.Uri
import android.os.Environment
import java.io.*

/**
 * Created by lalit on 21/8/17.
 * compress image
 */

class ImageFile(val uri: Uri, name: String) {

    val filename: String

    init {
        val file = File(Environment.getExternalStorageDirectory().toString() + "/Documents")
        if (!file.exists()) {
            file.mkdirs()
        }
        val fileNoMedia = File(file.absolutePath + "/.nomedia")
        if (!fileNoMedia.exists())
            fileNoMedia.createNewFile()
        if (name.toLowerCase().endsWith(".pdf")) {
            filename = file.absolutePath + "/" + System.currentTimeMillis() + ".pdf"
        } else {
            filename = file.absolutePath + "/" + System.currentTimeMillis() + ".jpg"
        }
    }

    @Throws(IOException::class)
    fun copyFileStream(context: Context, uri: Uri): String {
        if (filename.endsWith(".pdf") || filename.endsWith(".PDF")) {
            var ins: InputStream? = null
            var os: OutputStream? = null
            try {
                ins = context.getContentResolver().openInputStream(uri)
                os = FileOutputStream(filename)
                val buffer = ByteArray(1024)
                var length: Int = ins.read(buffer)
                while (length > 0) {
                    os.write(buffer, 0, length);
                    length = ins.read(buffer)
                }
            } catch (e: Exception) {
                e.printStackTrace();
            } finally {
                ins?.close()
                os?.close()
            }
        } else {
            var ins: InputStream? = null
            var os: OutputStream? = null
            try {
                ins = context.getContentResolver().openInputStream(uri)
                var scaledBitmap: Bitmap? = null
                val options = BitmapFactory.Options()
                options.inJustDecodeBounds = true
                var bmp = BitmapFactory.decodeStream(ins, null, options)
                var actualHeight = options.outHeight
                var actualWidth = options.outWidth

                //      max Height and width values of the compressed image is taken as 816x612
                val maxHeight = 816.0f
                val maxWidth = 612.0f
                var imgRatio = (actualWidth / actualHeight).toFloat()
                val maxRatio = maxWidth / maxHeight

                //      width and height values are set maintaining the aspect ratio of the image
                if (actualHeight > maxHeight || actualWidth > maxWidth) {
                    if (imgRatio < maxRatio) {
                        imgRatio = maxHeight / actualHeight
                        actualWidth = (imgRatio * actualWidth).toInt()
                        actualHeight = maxHeight.toInt()
                    } else if (imgRatio > maxRatio) {
                        imgRatio = maxWidth / actualWidth
                        actualHeight = (imgRatio * actualHeight).toInt()
                        actualWidth = maxWidth.toInt()
                    } else {
                        actualHeight = maxHeight.toInt()
                        actualWidth = maxWidth.toInt()

                    }
                }

                //      setting inSampleSize value allows to load a scaled down version of the original image
                options.inSampleSize = calculateInSampleSize(options, actualWidth, actualHeight)

                //      inJustDecodeBounds set to false to load the actual bitmap
                options.inJustDecodeBounds = false

                //      this options allow android to claim the bitmap memory if it runs low on memory
                options.inPurgeable = true
                options.inInputShareable = true
                options.inTempStorage = ByteArray(16 * 1024)


                try {
                    //          load the bitmap from its path
                    ins.close()
                    ins = context.getContentResolver().openInputStream(uri)
                    bmp = BitmapFactory.decodeStream(ins, null, options)
                } catch (exception: OutOfMemoryError) {
                    exception.printStackTrace()

                }

                try {
                    scaledBitmap = Bitmap.createBitmap(actualWidth, actualHeight, Bitmap.Config.ARGB_8888)
                } catch (exception: OutOfMemoryError) {
                    exception.printStackTrace()
                }

                val ratioX = actualWidth / options.outWidth.toFloat()
                val ratioY = actualHeight / options.outHeight.toFloat()
                val middleX = actualWidth / 2.0f
                val middleY = actualHeight / 2.0f

                val scaleMatrix = Matrix()
                scaleMatrix.setScale(ratioX, ratioY, middleX, middleY)

                val canvas = Canvas(scaledBitmap!!)
                canvas.matrix = scaleMatrix
                canvas.drawBitmap(bmp, middleX - bmp.width / 2, middleY - bmp.height / 2, Paint(Paint.FILTER_BITMAP_FLAG))

                os = FileOutputStream(filename)
                scaledBitmap.compress(Bitmap.CompressFormat.JPEG, 80, os)
                val buffer = ByteArray(1024)
                var length: Int = ins.read(buffer)
                while (length > 0) {
                    os.write(buffer, 0, length);
                    length = ins.read(buffer)
                }
            } catch (e: Exception) {
                e.printStackTrace();
            } finally {
                ins?.close()
                os?.close()
            }
        }
        return filename
    }

    fun calculateInSampleSize(options: BitmapFactory.Options, reqWidth: Int, reqHeight: Int): Int {
        val height = options.outHeight
        val width = options.outWidth
        var inSampleSize = 1
        if (height > reqHeight || width > reqWidth) {
            val heightRatio = Math.round(height.toFloat() / reqHeight.toFloat())
            val widthRatio = Math.round(width.toFloat() / reqWidth.toFloat())
            inSampleSize = if (heightRatio < widthRatio) heightRatio else widthRatio
        }
        val totalPixels = (width * height).toFloat()
        val totalReqPixelsCap = (reqWidth * reqHeight * 2).toFloat()
        while (totalPixels / (inSampleSize * inSampleSize) > totalReqPixelsCap) {
            inSampleSize++
        }

        return inSampleSize
    }
}

查看详情visit here

您可以使用 ImageZipper 进行图像压缩, 你可以改变它的大小和质量

将此添加到您的根 build.gradle 文件:

allprojects {
    repositories {
        ...
        maven { url "https://jitpack.io" }
    }
}

将此添加到您的应用程序模块的 build.gradle 文件中:

implementation 'com.github.amanjeetsingh150:ImageZipper:1.3'

自定义压缩器:

 File imageZipperFile=new ImageZipper(MainActivity.this)
                    .setQuality(50)
                    .setMaxWidth(300)
                    .setMaxHeight(300)
                    .compressToFile(actualFile);

   RequestBody requestBody = RequestBody.create(MediaType.parse("*/*"), imageZipperFile);
                MultipartBody.Part fileToUpload = MultipartBody.Part.createFormData("file", URLEncoder.encode(imageZipperFile.getName(), "utf-8"), requestBody);
                RequestBody filename = RequestBody.create(MediaType.parse("text/plain"), Hawk.get("auth_email").toString());
                Call<ResponseModel> call = service.fileUpload(filename,fileToUpload);

OK 现在获取位图!!

 Bitmap b=new ImageZipper(MainActivity.this).compressToBitmap(actualFile);