Upload a picture taken by the camera to a server with limited size
Asked Answered
M

3

9

the title sounds maybe a bit like a "noob question" but I know quite well how to program for Android, I just to figure out what it is the best way to achieve what I want.

My use case is: the user takes a photo and sends it to our server which have a file-size limit (which could mean that we have to resize the photo directly on the device).

Seems easy, right? My problem are the following:

1) Better use intents which could crash because some camera apps are coded with the ass or build a basic view "take photo and confirm" with cawc camera libs ? (I did the two, I prefer intents but I'd like to have an opinion on that).

2) How do you handle the file size limit? I mean getting the size of the photo is quite easy with the File.length() (even if the returned value is not perfectly right) but if you goes over the limit, how can you say how big will be the resized picture? (you need to convert in bitmap to resize it and it's then a lot of problems with OOMException and you cannot calculate final size of a bitmap on the disk, you need to compress and write it to the disk and analyse the newly created file after).

Thanks for help :D

Mainland answered 20/5, 2015 at 16:20 Comment(1)
To limit the pic size, you need resampling the pic before uploadCalipee
T
4

I did the same thing before.

1.I use intent to call the other camera app, and inside onActivityResult, I get back the URI and process it as I need.

  1. We do resize the pic, but I also keep the original ratio, and rotate it based on exif data. Hopefully this resizing code block can give you some hints.

    public static Bitmap DecodeImage(String path, int resolution) {
    BitmapFactory.Options opts = new BitmapFactory.Options();
    
    opts.inJustDecodeBounds = true;
    BitmapFactory.decodeFile(path, opts);
    opts.inSampleSize = computeSampleSize(opts, -1, resolution);
    opts.inJustDecodeBounds = false;
    return BitmapFactory.decodeFile(path, opts);
        }
    
    public static int computeSampleSize(BitmapFactory.Options options,
                                    int minSideLength, int maxNumOfPixels) {
    int initialSize = computeInitialSampleSize(options, minSideLength,
            maxNumOfPixels);
    
    int roundedSize;
    
    if (initialSize <= 8) {
        roundedSize = 1;
        while (roundedSize < initialSize) {
            roundedSize <<= 1;
        }
    } else {
        roundedSize = (initialSize + 7) / 8 * 8;
    }
    
    return roundedSize;
        }
    
    private static int computeInitialSampleSize(BitmapFactory.Options options, int minSideLength, int maxNumOfPixels) {
    double w = options.outWidth;
    double h = options.outHeight;
    
    int lowerBound = (maxNumOfPixels == -1) ? 1 :
            (int) Math.ceil(Math.sqrt(w * h / maxNumOfPixels));
    
    int upperBound = (minSideLength == -1) ? 128 :
            (int) Math.min(Math.floor(w / minSideLength),
                    Math.floor(h / minSideLength));
    
    if (upperBound < lowerBound) {
        // return the larger one when there is no overlapping zone.
        return lowerBound;
    }
    
    if ((maxNumOfPixels == -1) &&
    
            (minSideLength == -1)) {
        return 1;
    } else if (minSideLength == -1) {
        return lowerBound;
    } else {
        return upperBound;
    }
    
        }
    

    The solution is not fancy but it is what I did it in the project, and we so far have no problems with it after release.

Trinitrobenzene answered 23/5, 2015 at 10:58 Comment(0)
A
1

There are lots of question over this topic and hope you searched for it.

Q) Better use intents which could crash because some camera apps are coded with the ass or build a basic view "take photo and confirm" with cawc camera libs ? (I did the two, I prefer intents but I'd like to have an opinion on that).

A) Intents are best because they are build in, some device manufacturers intents for cropping and re-sizing images and I face similar problem of not having that on same manufacturer but on Older device. A stable/relible third party app would suffice for basic operations.

Q) How do you handle the file size limit? I mean getting the size of the photo is quite easy with the File.length() (even if the returned value is not perfectly right) but if you goes over the limit, how can you say how big will be the resized picture? (you need to convert in bitmap to resize it and it's then a lot of problems with OOMException and you cannot calculate final size of a bitmap on the disk, you need to compress and write it to the disk and analyse the newly created file after).

A)

  1. How do you handle the file size limit? Size limit depends on Camera, if you have 10MP camera then the resultant size would be greater than 5MP (hope you get the part).
  2. You need to convert in bitmap to resize it and it's then a lot of problems with OOMException and you cannot calculate final size of a bitmap on the disk You can calculate the image size or sample it or crop it or resize it as far as you keep best practices of Android intact, recycle the bitmap as soon as you done with the bitmap operations. I have a app which has 100s of Images and most of them being send to server and some times it throws OOM, then I handle it accordingly.
Americaamerican answered 26/5, 2015 at 5:53 Comment(0)
F
1

You can gone through the link Loading Large Bitmap

They explained really well regarding bitmap scaling. Please let me know if you don't get any point in this link.

Thanks

Foss answered 29/5, 2015 at 4:45 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.