如何将位图保存到Firebase

7

我创建了一个简单的应用程序来裁剪图片。现在我想将这个图片保存到Firebase。

photo.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            //Intent imageDownload = new 
Intent(Intent.ACTION_PICK,MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
      Intent imageDownload=new Intent();
      imageDownload.setAction(Intent.ACTION_GET_CONTENT);
      imageDownload.setType("image/*");
      imageDownload.putExtra("crop", "true");
      imageDownload.putExtra("aspectX", 1);
      imageDownload.putExtra("aspectY", 1);
      imageDownload.putExtra("outputX", 200);
      imageDownload.putExtra("outputY", 200);
      imageDownload.putExtra("return-data", true);
      startActivityForResult(imageDownload, GALLERY_REQUEST_CODE);


        }
    });
 }
  @Override
protected void onActivityResult(int requestCode, int resultCode, Intent 
  data) {
    super.onActivityResult(requestCode, resultCode, data);
    if(requestCode == GALLERY_REQUEST_CODE && resultCode == RESULT_OK && 
   data != null) {
        Bundle extras = data.getExtras();
        image = extras.getParcelable("data");
        photo.setImageBitmap(image);

   }






}

如何将此图像保存到Firebase。我尝试了许多教程,但都没有成功。请使用简单的代码进行验证。

3个回答

21

你必须先将 Firebase Storage 的依赖项添加到你的 build.gradle 文件中:

compile 'com.google.firebase:firebase-storage:10.0.1'
compile 'com.google.firebase:firebase-auth:10.0.1'

然后创建一个FirebaseStorage的实例:

FirebaseStorage storage = FirebaseStorage.getInstance();
创建对 Firebase 存储中文件的引用时,您需要包含文件名在内的完整文件路径。
// Create a storage reference from our app
StorageReference storageRef = storage.getReferenceFromUrl("gs://<your-bucket-name>");

// Create a reference to "mountains.jpg"
StorageReference mountainsRef = storageRef.child("mountains.jpg");

// Create a reference to 'images/mountains.jpg'
StorageReference mountainImagesRef = storageRef.child("images/mountains.jpg");

// While the file names are the same, the references point to different files
mountainsRef.getName().equals(mountainImagesRef.getName());    // true
mountainsRef.getPath().equals(mountainImagesRef.getPath());    // false

创建适当的引用后,使用putBytes()、putFile()或putStream()方法将文件上传到Firebase Storage。

putBytes()方法是将文件上传到Firebase Storage的最简单方式。putBytes()接受一个byte[]参数,并返回一个UploadTask,您可以使用它来管理和监视上传的状态。

// Get the data from an ImageView as bytes
imageView.setDrawingCacheEnabled(true);
imageView.buildDrawingCache();
Bitmap bitmap = imageView.getDrawingCache();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
byte[] data = baos.toByteArray();

UploadTask uploadTask = mountainsRef.putBytes(data);
uploadTask.addOnFailureListener(new OnFailureListener() {
    @Override
    public void onFailure(@NonNull Exception exception) {
        // Handle unsuccessful uploads
    }
}).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
    @Override
    public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
        // taskSnapshot.getMetadata() contains file metadata such as size, content-type, and download URL.
        Uri downloadUrl = taskSnapshot.getDownloadUrl();
    }
});

如果我想将这个位图转换为URI,那么该怎么做呢? - wiki wi
1
public Uri getImageUri(Context inContext, Bitmap inImage) { ByteArrayOutputStream bytes = new ByteArrayOutputStream(); inImage.compress(Bitmap.CompressFormat.PNG,100, bytes); String path = MediaStore.Images.Media.insertImage(inContext.getContentResolver(), inImage, "Title", null); return Uri.parse(path); } - Akshay Kumar Both
1
你真是个救命恩人!当我需要将位图图像转换为字节时,这使得工作变得更加容易。 - dave o grady

4
Firebase不支持二进制数据,因此您需要将图像数据转换为base64格式或使用Firebase Storage方法1(推荐)
 sref = FirebaseStorage.getInstance().getReference(); // please go to above link and setup firebase storage for android

 public void uploadFile(Uri imagUri) {
    if (imagUri != null) {

        final StorageReference imageRef = sref.child("android/media") // folder path in firebase storage
                .child(imagUri.getLastPathSegment());

        photoRef.putFile(imagUri)
                .addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
                    @Override
                    public void onSuccess(UploadTask.TaskSnapshot snapshot) {
                        // Get the download URL
                        Uri downloadUri = snapshot.getMetadata().getDownloadUrl();
                        // use this download url with imageview for viewing & store this linke to firebase message data

                    }
                })
                .addOnFailureListener(new OnFailureListener() {
                    @Override
                    public void onFailure(@NonNull Exception exception) {
                         // show message on failure may be network/disk ?
                    }
                });
    }
}

方法2

对于小图像,我们仍然可以使用此解决方案,但存在Firebase字段值限制(1MB字段值) 有关详细信息,请查看官方文档

public void getImageData(Bitmap bmp) {  

  ByteArrayOutputStream bao = new ByteArrayOutputStream();
  bmp.compress(Bitmap.CompressFormat.PNG, 100, bao); // bmp is bitmap from user image file
  bmp.recycle();
  byte[] byteArray = bao.toByteArray();
  String imageB64 = Base64.encodeToString(byteArray, Base64.URL_SAFE); 
  //  store & retrieve this string which is URL safe(can be used to store in FBDB) to firebase
  // Use either Realtime Database or Firestore
  }

为什么不推荐使用方法2? - Arjun
1
这是因为尺寸的原因!对于小图像,我们仍然可以使用此方法,请检查Firebase限制(1MB字段值)https://firebase.google.com/docs/firestore/quotas。 - Renjith Thankachan
1
已更新答案并附上细节,祝你编程愉快 :) - Renjith Thankachan
1
@RenjithThankachan,您的意思是说为了使用Base64,我们需要设置实时数据库而不是云Firestore? - H.Karatsanov
1
@H.Karatsanov 一旦设置了base64,您可以将其存储在任何服务的firestore或realtimedatabase中。 - Renjith Thankachan
显示剩余3条评论

0

"firebase-storage 16.0.1"

task.getDowloadUrl()未定义。您可以使用此进行检查,它完美地工作。

 private void firebaseUploadBitmap(Bitmap bitmap) {
    ByteArrayOutputStream stream = new ByteArrayOutputStream();
    bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
    byte[] data = stream.toByteArray();
    StorageReference imageStorage = storage.getReference();
    StorageReference imageRef = imageStorage.child("images/" + "imageName");

    Task<Uri> urlTask = imageRef.putBytes(data).continueWithTask(task -> {
        if (!task.isSuccessful()) {
            throw task.getException();
        }

        // Continue with the task to get the download URL
        return imageRef.getDownloadUrl();
    }).addOnCompleteListener(task -> {
        if (task.isSuccessful()) {
            Uri downloadUri = task.getResult();
            String uri = downloadUri.toString();
            sendMessageWithFile(uri);
        } else {
            // Handle failures
            // ...
        }
        progressBar.setVisibility(View.GONE);
    });
    
}
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == PICK_IMAGE && resultCode == Activity.RESULT_OK) {
        //      Bitmap imageBitmap = data.getData() ;
        Bitmap photo = (Bitmap) data.getExtras().get("data");
        if (photo != null)
            firebaseUploadBitmap(photo);

    } else if (requestCode == SELECT_IMAGE && resultCode == Activity.RESULT_OK) {

        Uri uri = data.getData();
        if (uri != null)
            firebaseUploadImage(uri);
    }

}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接