如何在将图像上传到 Firebase 存储之前对其进行压缩?
Posted
技术标签:
【中文标题】如何在将图像上传到 Firebase 存储之前对其进行压缩?【英文标题】:How to compress image before upload it to firebase storage? 【发布时间】:2022-01-18 18:57:58 【问题描述】:我想在上传到 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);
【问题讨论】:
你的图片有多大? 4 到 6 MB 之间 可能重复***.com/questions/41611294/… 是的,我检查过了,但我不知道如何在我的代码中应用它!! 【参考方案1】:您在问两个问题,一个是减小图像的大小,另一个是压缩它。我假设您打算通过减小大小而不是压缩它来以有损方式压缩图像。如果这不是您在 cmets 中的意思,请告诉我。
您可以选择手动构建解决方案。 Python 有很多很好的库可以帮助你做到这一点,对于 java,我确实找到了一些沿着这个方向工作的好资源,这个 SO 问题似乎很不错 - How can I compress images using java?
另一种选择是使用 SaaS 工具。这将真正为您简化过程,对于像这样简单的事情,除非您压缩大量图像或非常大的图像,否则它甚至可能不会花费任何成本。作为起点,您可以查看 TinyPNG - https://tinypng.com/。他们有一个开发者 API - https://tinypng.com/developers。
编辑:根据有关音量的新信息,更新我的答案。 由于您期望的图像数量很少,因此您可以只使用 TinyPNG。上手非常简单。您只需注册,即可获得 API 密钥。他们有一个很好的 API,你可以在 Java 中使用 - https://tinypng.com/developers/reference/java
【讨论】:
用户从他的画廊或相机中选择一张照片,然后当他点击保存按钮时,图像大小必须减小,例如从 4Mb 到(最大 500 Kb)并将图像上传到存储 @MohamedYacineZouaoui 好的,你期待什么样的音量?比如你每个月会做多少次压缩(结合所有用户)? 它可以在 25 到 40 之间! @MohamedYacineZouaoui 更新了我的答案,如果它解决了您的问题,请告诉我【参考方案2】:我也在尝试解决这个问题,但似乎没有其他方法对我们的情况有直接帮助。
“可能重复”示例仅在您将图像转换为位图时才有效。几乎所有您尝试使用位图实现的示例。这是该“重复”中的一些代码,应该可以帮助您。虽然在我实现了这个之后,我在处理轮换方面遇到了麻烦。
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 存储的方式。
我可能会这样做并直接处理位图,但如果可以的话,我打算寻找替代解决方案。
要添加这个extension with firebase,它会在您上传后调整大小
【讨论】:
以上是关于如何在将图像上传到 Firebase 存储之前对其进行压缩?的主要内容,如果未能解决你的问题,请参考以下文章
如何在将照片上传到 Firebase 存储时将日期或时间等用户图像详细信息添加到文件名?
是否有必要在将聊天消息存储到 Firebase 之前对其进行加密?