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

时间:2017-04-14 09:57:22

标签: android retrofit2 image-compression

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

如果我使用前置摄像头图像获取图像上传成功,但如果取回侧摄像头未上传我认为由于大文件大小图像未上传,是否有任何选项压缩文件大小,然后在改造中发送到服务器? / p>

文件发送编码

  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;
    }

}

6 个答案:

答案 0 :(得分:4)

如果您正在寻找图像压缩,可以使用此库https://github.com/zetbaitsu/Compressor。它非常简单而且非常棒。该链接解释了一切。

答案 1 :(得分:2)

尝试以下代码:

test passed
('outputs equal', True)

Timings:
OP               12099.189901 ms
PP                26.705098 ms

答案 2 :(得分:1)

尝试

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 ();
}

答案 3 :(得分:1)

使用文本

将压缩的捕获图像发送到服务器

捕获图片

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();
        }


    });
}

答案 4 :(得分:1)

您可以使用ImageZipper中的图像进行压缩, 您可以更改其大小和质量

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

px,py

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

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

自定义压缩器:

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);

答案 5 :(得分:-1)

选中此类以压缩图像

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