繁体   English   中英

如何在上传到 firebase 存储之前压缩图像?

[英]How to compress image before upload it to firebase storage?

我想在上传到 firebase 存储之前减小图像文件的大小,因为上传需要很长时间。

这是一个包含edittext + imageview的表格

单击“保存”按钮时,我同时保存数据(在实时数据库中)和图像(存储)。

那么如何减小图像大小或压缩它呢?

public class PDV_form extends AppCompatActivity {

 @Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_pdv_form);
     imgproduit.setOnClickListener(new View.OnClickListener() {
         @Override
        public void onClick(View v) {
            selectImage();
         }
    });

    Save.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
             rootNode = FirebaseDatabase.getInstance("https://dtechapp-94795-default-rtdb.europe-west1.firebasedatabase.app");
            reference = rootNode.getReference().child("pdv");

            String nomcmplt = nomCmplt.getEditText().getText().toString();
            String nompdv = nomPdv.getEditText().getText().toString();
            String phone = Phone.getEditText().getText().toString();
            String adresse = Adresse.getEditText().getText().toString();
            String commune = Commune.getEditText().getText().toString();
            String wilaya = Wilaya.getEditText().getText().toString();
            String codezip = Zip.getEditText().getText().toString();
            String email = Email.getEditText().getText().toString();
            String imagepdv = placeimgpdv.getDrawable().toString().trim();
                 UploadDialog = new ProgressDialog(PDV_form.this);
                UploadDialog.setTitle("Sauvegarde en cours.... ");
                UploadDialog.show();

                SimpleDateFormat formatter = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss", Locale.FRANCE);
                Date now = new Date();
                String fileName = formatter.format(now);
                storageReference = FirebaseStorage.getInstance().getReference("pdv/" + fileName);
                storageReference.putFile(imageUri)
                        .addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
                            @Override
                            public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {

                                placeimgpdv.setImageURI(null);
                                Toast.makeText(PDV_form.this, "Sauvegarde Terminée", Toast.LENGTH_SHORT).show();
                                if (UploadDialog.isShowing())
                                    UploadDialog.dismiss();

                            }
                        }).addOnFailureListener(new OnFailureListener() {
                    @Override
                    public void onFailure(@NonNull Exception e) {
                         if (UploadDialog.isShowing())
                            UploadDialog.dismiss();
                        Toast.makeText(PDV_form.this, "Sauvegarde Annulée", Toast.LENGTH_SHORT).show();
                     }
                });

                StorageReference filpath = storageReference;
                filpath.putFile(imageUri).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
                    @Override
                    public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
                        Task<Uri> downloadurl = taskSnapshot.getStorage().getDownloadUrl().addOnCompleteListener(new OnCompleteListener<Uri>() {
                            @Override
                            public void onComplete(@NonNull @NotNull Task<Uri> task) {
                                String t = task.getResult().toString();
                                DatabaseReference newPost = reference.child(nomcmplt + "(" + nompdv + ")");
                                newPost.child("nomcmplt").setValue(nomcmplt);
                                newPost.child("nompdv").setValue(nompdv);
                                newPost.child("phone").setValue(phone);
                                newPost.child("adresse").setValue(adresse);
                                newPost.child("commune").setValue(commune);
                                newPost.child("wilaya").setValue(wilaya);
                                newPost.child("codezip").setValue(codezip);
                                newPost.child("email").setValue(email);
                                newPost.child("imagepdv").setValue(task.getResult().toString());
                                newPost.child("user_id").setValue(uid);

                                if (task.isSuccessful()) {
                                    startActivity(new Intent(PDV_form.this, Bottom_bar.class));
                                }
                            }
                        });
                    }
                });

         }
    });

}

private void selectImage() {

    Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
    intent.setType("image/*");
    // intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
    startActivityForResult(intent, Gallery_code);

}

public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == Gallery_code && resultCode == RESULT_OK) {
        imageUri = data.getData();
        placeimgpdv.setImageURI(imageUri);

    }
}
}

您在问两个问题,一个是减小图像的大小,另一个是压缩它。 我假设您打算通过减小大小而不是 zip 来以有损方式压缩图像。 如果这不是您在评论中的意思,请告诉我。

您可以选择手动构建解决方案。 Python 有一堆很好的库可以帮助你做到这一点,对于 java,我确实找到了一些沿着这个方向工作的好资源,这个 SO 问题似乎很好 - 如何使用 Z93F7246A07423D21C 压缩图像?

另一种选择是使用 SaaS 工具。 这将真正为您简化过程,对于像这样简单的事情,除非您压缩大量图像或非常大的图像,否则它甚至可能不会花费任何成本。 作为起点,您可以查看 TinyPNG - https://tinypng.com/ 他们有一个开发人员 API - https://tinypng.com/developers

编辑:根据有关音量的新信息,更新我的答案。 由于您期望的图像数量很少,因此您可以只使用 TinyPNG。 上手非常简单。 您只需注册,即可获得 API 密钥。 他们有一个不错的 API,您可以在 Java - https://tinypng.com/developers/reference/java中使用

我也在尝试解决这个问题,但似乎没有其他任何东西对我们的情况有直接帮助。

仅当您将图像转换为 bitmap 时,“可能重复”示例才有效。 几乎所有您尝试使用位图实现的示例。 这是该“重复”中的一些代码,应该可以帮助您。

Uri selectedImageUri = data.getData();

Bitmap bmp = null;
try {
    bmp = MediaStore.Images.Media.getBitmap(getContentResolver(), selectedImageUri);
 } catch (IOException e) {
    e.printStackTrace();
 }
  ByteArrayOutputStream baos = new ByteArrayOutputStream();

 //here you can choose quality factor in third parameter(ex. i choosen 25) 
 bmp.compress(Bitmap.CompressFormat.JPEG, 25, baos);
 byte[] fileInBytes = baos.toByteArray();

 StorageReference photoref = chatPhotosStorageReference.child(selectedImageUri.getLastPathSegment());

 //here i am uploading
 photoref.putBytes(fileInBytes).addOnSuccessListener....etc

现在虽然这可能是正确的答案。 我自己更喜欢更简洁的解决方案,它允许我通过 InputStream 或 Uri 压缩文件,因为这也是我将图像上传到 firebase 存储的方式。

我可能会这样做并直接处理 bitmap,但如果可以的话,我打算寻找替代解决方案。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM