Загрузите снимок, сделанный камерой, на сервер с ограниченным размером

Название звучит, может быть, немного как "вопрос нуба", но я достаточно хорошо знаю, как программировать для Android, я просто хочу выяснить, что это лучший способ достичь того, чего я хочу.

Мой пример использования: пользователь берет фотографию и отправляет ее на наш сервер с ограничением размера файла (что может означать, что мы должны изменить размер фотографии непосредственно на устройстве).

Кажется легко, правда? Моя проблема заключается в следующем:

1) Лучше использовать намерения, которые могут привести к сбою, потому что некоторые приложения камеры закодированы с задницей или создают базовый вид "сделайте фото и подтвердите" с помощью библиотек cawc? (Я сделал два, я предпочитаю намерения, но я хотел бы иметь мнение об этом).

2) Как вы справляетесь с ограничением размера файла? Я имею в виду, что получить размер фотографии довольно легко с File.length() (даже если возвращаемое значение не совсем верно), но если вы превысили предел, как вы можете сказать, насколько большим будет изображение с измененным размером? (вам нужно конвертировать в растровое изображение, чтобы изменить его размер, и тогда возникает много проблем с OOMException и вы не можете рассчитать окончательный размер растрового изображения на диске, вам нужно сжать и записать его на диск, а затем проанализировать вновь созданный файл).

Спасибо за помощь:D

3 ответа

Решение

Я делал то же самое раньше.

1. Я использую намерение вызвать другое приложение камеры, и внутри onActivityResult я возвращаю URI и обрабатываю его по мере необходимости.

  1. Мы изменяем размер изображения, но я также сохраняю исходное соотношение и поворачиваю его на основе данных exif. Надеюсь, этот блок кода изменения размера может дать вам несколько советов.

    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;
    }
    
        }
    

    Решение не причудливое, но это то, что я сделал в проекте, и у нас пока нет проблем с ним после релиза.

Вы можете перейти по ссылке Загрузка большого растрового изображения

Они очень хорошо объяснили, что касается растрового масштабирования. Пожалуйста, дайте мне знать, если вы не получили никакого смысла в этой ссылке.

Спасибо

Есть много вопросов по этой теме и надеюсь, что вы искали его.

Q) Лучше использовать намерения, которые могут привести к сбою, потому что некоторые приложения камеры кодируются задницей или создают базовый вид "сделай фото и подтверди" с помощью библиотек cawc? (Я сделал два, я предпочитаю намерения, но я хотел бы иметь мнение об этом).

А) Интенты лучше, потому что они встроены, некоторые производители устройств намерены обрезать и изменять размеры изображений, и я сталкиваюсь с аналогичной проблемой не того, чтобы иметь это на том же производителе, но на старом устройстве. Для основных операций достаточно стабильного / надежного стороннего приложения.

Q) Как вы справляетесь с ограничением размера файла? Я имею в виду, что получить размер фотографии довольно просто с помощью File.length() (даже если возвращаемое значение не совсем верно), но если вы превысили предел, как вы можете сказать, насколько большим будет изображение с измененным размером? (вам нужно преобразовать в растровое изображение, чтобы изменить его размер, и тогда возникает много проблем с OOMException, и вы не можете рассчитать окончательный размер растрового изображения на диске, вам нужно сжать и записать его на диск, а затем проанализировать вновь созданный файл),

A)

  1. Как вы справляетесь с ограничением размера файла? Ограничение размера зависит от камеры. Если у вас камера 10 Мп, результирующий размер будет больше 5 Мп (надеюсь, вы получите часть).
  2. Вам нужно конвертировать в растровое изображение, чтобы изменить его размер, и тогда возникает много проблем с OOMException, и вы не можете рассчитать конечный размер растрового изображения на диске. Вы можете рассчитать размер изображения или сэмплировать его, или обрезать или изменить его размер, пока вы сохраняете лучшие практики Android без изменений, переработайте растровое изображение, как только вы закончите с растровыми операциями. У меня есть приложение, у которого есть сотни изображений, и большинство из них отправляются на сервер, и иногда оно выдает OOM, а затем я обрабатываю его соответствующим образом.
Другие вопросы по тегам