How to download images with specific size from fir

2019-02-18 05:10发布

问题:

I am using firebase storage in my android app to store images uploaded by users. all images uploaded are square in shape. I discovered that downloading this images consumes a lot of user bandwidth and i would like to reduce this consumption by reducing the size of image downloaded into a square imageview

I am using Glide to download this images and i have tried to download images of custom size but the image is not appearing on the imageview.

interface

public interface MyDataModel {
  public String buildUrl(int width, int height);
}

my class which extends BaseGlideUrlLoader

public class MyUrlLoader extends BaseGlideUrlLoader<MyDataModel> {
  public MyUrlLoader(Context context) {
    super(context);
  }

  @Override
  protected String getUrl(MyDataModel model, int width, int height) {
    // Construct the url for the correct size here.
    return model.buildUrl(width, height);
  }
}

class which implements MyDataModel interface

public class CustomImageSize implements MyDataModel {

  private String uri;

  public CustomImageSize(String uri){
    this.uri = uri;
  }

  @Override
  public String buildUrl(int width, int height) {

    return uri + "?w=" + width + "&h=" + height;
  }
}

Finally

CustomImageSize size = new CustomImageSize(uri);

  Glide.with(context)
    .using(new MyUrlLoader(context))
    .load(size)
    .centerCrop()
    .priority(Priority.HIGH)
    .into(imageView);

RESULTS OF SOLUTION ABOVE

Image is not appearing in my square imageview

SOLUTION 2: use firebase image loader

    // Reference to an image file in Firebase Storage
StorageReference storageReference = ...;

ImageView imageView = ...;

// Load the image using Glide
Glide.with(this /* context */)
        .using(new FirebaseImageLoader())
        .load(storageReference)
        .into(imageView);

RESULT OF SOLUTION 2 ABOVE

working! image is appearing BUT it's like entire image is been downloaded which consume a lot of bandwidth. I just want a custom size image e.g 200px by 200px to be downloaded.

How can I do or change in my solution 1 above to download images of custom size from firebase storage?

EDIT

I have tried to access one of my images https://firebasestorage.googleapis.com/....m.png from the browser and it was loaded successfully to the webpage. but when i try to put to size specific parameters to my image url link https://firebasestorage.googleapis.com/....m.png?w=100&h=100 an error appeared on the webpage

 {
  "error": {
    "code": 403,
    "message": "Permission denied. Could not perform this operation"
  }
}

回答1:

I was finally able to download images from firebase storage using MyUrlLoader class

You see, firebase storage urls look like this

firebasestorage.googleapis.com/XXXX.appspot.com/Folder%2Image.png?&alt=media&token=XXX

As you can see above, the link already have this special question mark character ? which stands for the start of querying string so when i use CustomImageSize class, another ? was being added so the link was ending up with two ? which made downloading to fail

firebasestorage.googleapis.com/XXXX.appspot.com/Folder%2Image.png?&alt=media&token=XXX?w=200&h=200

Solution was to remove the ? in my CustomImageSize class. so it ended up like this

    public class CustomImageSize implements MyDataModel {

  private String uri;

  public CustomImageSize(String uri){
    this.uri = uri;
  }

  @Override
  public String buildUrl(int width, int height) {

    return uri + "w=" + width + "&h=" + height;
  }
}

Although it downloaded, am not sure whether entire image was being downloaded or just the custom size one. This is because, i tried to access the image in my browser after correcting the error that was making viewing to fail, but still i was receiving an entire image. not a resized image (w=200&h=200)



回答2:

Try downloading your image using the following commands:-

StorageReference islandRef = storageRef.child("yourImage.jpg");
    // defines the specific size of your image
    final long ONE_MEGABYTE = 1024 * 1024;
    islandRef.getBytes(ONE_MEGABYTE).addOnSuccessListener(new OnSuccessListener<byte[]>() {
        @Override
        public void onSuccess(byte[] bytes) {
            // Data for "yourImage.jpg" is returns, use this as needed
        }
    }).addOnFailureListener(new OnFailureListener() {
        @Override
        public void onFailure(@NonNull Exception exception) {
            // Handle any errors
        }
    });