Android studio сжать изображение

Класс BitmapFactory

Класс BitmapFactory позволяет создать объект Bitmap из файла, потока или байтового массива. Данный класс часто используется в работе с изображениями.

Класс имеет несколько методов decode* (decodeByteArray(), decodeFile(), decodeResource() и др.) для создания растрового изображения из различных источников. Не забывайте, что методы пытаются выделить память под создаваемое изображение и вы можете получить ошибку из-за нехватки памяти на устройстве. Обратите внимание, что каждый метод имеет вторую перегруженную версию с тем же именем и дополнительным параметром типа BitmapFactory.Options.

Мы можем загрузить изображение из каталога assets:

Класс BitmapFactory.Options имеет несколько полезных свойств, которые нужно использовать в своих приложениях.

  • inJustDecodeBounds
  • inSampleSize
  • inBitmap
  • inPreferredConfig
  • inDensity
  • inDither
  • inPurgeable

inJustDecodeBounds

Используя свойство inJustDecodeBounds со значением true, вы можете избежать выделения памяти под изображение, при этом вы можете получить значения ширины (outWidth), высоты (outHeight) и MIME-типа (outMimeType). Подобный приём позволяет прочитать размеры картинки и использовать их для своих целей, сведя к минимуму потребление памяти.

Когда размеры изображения известны, вы уже можете решать — загружать ли полное изображение или сделать уменьшенную копию. Тут зависит от логики вашего приложения. Если это просмотр фотографий, то нужно следить за потреблением памяти. Если картинка загружается в маленький ImageView, то нет смысла использовать настоящее большое изображение. Когда вы определились, что делать дальше, то установите снова значение false для данного свойства.

inSampleSize

Чтобы декодер пережал картинку, установите inSampleSize в нужное значение в объекте BitmapFactory.Options. Например, если изображение с размерами 2048×1536 сжать до размеров 512×384 (в 4 раза), то изображение в памяти будет занимать 0.75мб вместо 12мб. Разница ощутима.

Ниже приводится метод для вычисления новых размеров изображения по заданными ширине и высоте, чтобы изменение размера было пропорциональным.

Чтобы использовать этот метод, сначала декодируйте изображение через inJustDecodeBounds = true, затем декодируйте снова, используя новые значения inSampleSize и inJustDecodeBounds = false:

Чтобы загрузить большое изображение в ImageView с размером 100х100 пикселей, используйте наш метод:

По такому же принципу вы можете написать сопутствующие методы для других декодирующих методов класса BitmapFactory.

Сама операция сжатия картинки очень трудоёмка и её не стоит делать в основном потоке приложения. Лучше её вынести в отдельный поток через AsyncTask.

Другие свойства используются реже. Поэтому информация только в ознакомительных целях.

inBitmap

Если передать в этот параметр объект Bitmap, то он и будет использован для получения итогового результата вместо создания нового объекта. В Android 4.4 (API 19) передаваемый Bitmap должен быть не меньше по размеру (в байтах), чем читаемое изображение. В старых версиях объект должен быть строго того же размера (ширина/высота), что и читаемое изображение. Также необходимо использовать свойство inSampleSize = 1.

inPreferredConfig

inDensity

Задаёт плотность для объекта Bitmap.

inDither

Сглаживание цветовой палитры. Где-то валялся пример. Если найду, то добавлю.

inPurgeable

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

Об остальных свойствах читайте в документации.

Источник

Уменьшение размера файла картинки

Как можно уменьшить размер файла (Картинки) ?
Например на входе картинка весит 2мб, а после «манипуляций» должно остаться 100кб..

Читайте также:  Звуки когда приходит смс для андроид

p.s. есть ли способ при котором максимально сохраняется качество.

Уменьшение размера шрифта Textview, если не влезает по длине или высоте
TextView в режиме width=match_parent, height=match_parent, то есть растянут на весь активити. .

Уменьшение размера картинки в таблице
Меня заинтересовал вопрос —есть таблица —одно из полей картинка —OLE —при клике картинка.

Работа с таймером: уменьшение размера картинки
Картинка высотой 750 пикселей уменьшается каждые 6 секунд на 150 рх до размеров в 150 px. Двойной.

Уменьшение размера картинки под Image
Нужно сделать предпросморт в уменьшеном виде. Любая картинка должна полностью «влезть» в Image1.

Решение

Для уменьшения размера битмапа в BitmapFactory.Options есть поле inSampleSize.Пример «манипуляций» тут.

Добавлено через 4 минуты
Для сохранения сохранения битмапа в FileOutputStream используется метод битмапа compress

Уменьшение размера картинки при открытии (Image)
Приветствую! Нужна ваша помощь! При загрузке картинки использую функцию LoadFromFile. Напишите.

Изменение размера картинки (увеличение, уменьшение) — остаются белые полосы по краям
Доброго времени суток! Есть проект, необходимо открыть картинку, сделать ресайз и сохранить под.

Уменьшение размера файла на php
Для фотогалереи требуется превью картинки, то есть копия загруженного на сервер файла, только.

Уменьшение размера исполняемого файла
обычный printf занимает 30 кб после компиляции, как уменьшить размер? в настройках ничего ненашел.

Источник

Русские Блоги

Оптимизация растровых изображений Android-сжатие изображений

Оригинальный адрес: http://anany.me/2015/10/15/bitmap1/

Растровое изображение всегда было очень сложной проблемой при разработке. Это проблема легендарного OOM (переполнение памяти java.lang.OutofMemoryError). Так почему растровое изображение так теряется и раздражается многими разработчиками Android?

Во-первых, причина OOM вызвана растровым изображением

Поскольку каждая модель компилирует ПЗУ, верхний предел значения виртуальной машины в куче памяти приложения установлен на dalvik.vm.heapgrowthlimit, который используется для ограничения максимального объема памяти, доступной для каждого приложения. Если это максимальное значение будет превышено, будет сообщено о OOM. Этот порог обычно увеличивается в зависимости от размера точек на дюйм экрана мобильного телефона. Чем меньше разрешение, тем меньше максимальный объем памяти, доступный для каждого приложения. Например, в моем Z3c пороговое значение виртуальной машины xhdpi составляет 192M, но только незначительное значение 48M на hdpi для Nexus. Таким образом, когда в мероприятии загружается несколько больших изображений, легко получить OOM. Для справки о порогах памяти приложения смотрите раздел 3.7 здесь:
http://static.googleusercontent.com/media/source.android.com/en//compatibility/android-cdd.pdf

Чем выше разрешение изображения, тем выше потребление памяти.При загрузке изображений с высоким разрешением оно будет занимать много памяти и будет OOM, если с ним не будут обращаться должным образом. Например, разрешение фотографии с разрешением 500 Вт составляет 2592×1936. Если для отображения мозаики в Bitmap используется 32-битный ARGB_8888, занятая память составляет 2592x1936x4 байта, занимая почти 19 Мб памяти. Боже мой, можно загрузить менее 10 таких высококачественных фотографий, приложение будет напрямую зависать и сообщаться в OOM

  • Когда вы используете ListView, GridView и другие компоненты, которые загружают много представлений, если вы не обрабатываете кэш разумно, вы также легко запустите OOM, когда загрузите много битовых карт.
  • Введение в растровое изображение

    Чтобы работать хорошо, вы должны сначала отточить свои инструменты. Чтобы эффективно загружать Bitmap, необходимо понимать Bitmap. Bitmap имеет несколько важных переменных-членов и методов, которые представлены ниже:

    2.1 Bitmap.Config

    Растровая память, занятая изображением =Длина изображения x Ширина изображения x Количество байтов, занимаемых одним пикселем
    Bitmap.Config — это важный параметр для указания количества байтов, занимаемых единичным пикселем.

    где A — прозрачность; R — красный; G — зеленый; B — синий.

    • ALPHA_8
      означает 8-битное альфа-изображение, то есть A = 8, пиксель занимает 1 байт, у него нет цвета, только прозрачность
    • ARGB_4444
      означает 16-битное растровое изображение ARGB, то есть A = 4, R = 4, G = 4, B = 4, один пиксель занимает 4 + 4 + 4 + 4 = 16 бит, 2 байтов
    • ARGB_8888
      представляет 32-битное растровое изображение ARGB, то есть A = 8, R = 8, G = 8, B = 8, один пиксель занимает 8 + 8 + 8 + 8 = 32 бита, 4 байтов
    • RGB_565
      означает 16-битное растровое изображение RGB, то есть R = 5, G = 6, B = 5, оно не имеет прозрачности, один пиксель занимает 5 + 6 + 5 = 16 бит, 2 слова фестиваль
    Читайте также:  Oukitel c21 android 11

    Основная функция Bitmap.Config: каким образом хранится пиксель.Различные конфигурации будут влиять на качество изображения (глубину цвета) изображения. Чем больше количество бит, тем выше качество изображения. Очевидно, что ARGB_8888 занимает здесь больше всего памяти. Конечно, чем выше качество изображения, тем больше памяти требуется.

    Советы: поскольку качество изображения ARGB_4444 ужасно, если для изображения не требуется прозрачность, вы можете изменить его на RGB_565, что сэкономит половину накладных расходов памяти по сравнению с ARGB_8888.

    2.1.1 Настройка использования памяти разных Bitmap.Config с одинаковым разрешением

    Память, занимаемая изображением Битовая карта = длина изображения x ширина изображения x количество байтов, занимаемых одним пикселем

    Bitmap.Config Объем памяти с разрешением 100×100
    ALPHA_8 100x100x1 = 10000 byte

    = 9.77 KB

    ARGB_4444 100x100x2 = 20000 byte

    = 19.53 kb

    ARGB_8888 100x100x4 = 40000 byte

    = 39.06 KB

    RGB_565 100x100x2 = 20000 byte

    В Android вы можете установить скорость декодирования с помощью следующего кода

    2.2 Bitmap.CompressFormat

    Буквально это означает:Формат сжатия растрового изображения

    Источник

    Как я ускорил обработку изображений на Android в 15 раз

    Как оптимизировать обработку изображений в рантайме, когда необходимо создать 6 изображений, каждое из которых состоит из последовательно наложенных 15-16 PNG, не получив OutOfMemoryException по дороге?

    При разработке своего pet-приложения столкнулся с проблемой обработки изображений. Гугление хороших юзкейсов предоставить не смогло, поэтому пришлось ходить по своим граблям и изобретать велосипед самостоятельно.
    Также во время разработки произошла миграция с Java на Kotlin, поэтому код в определенный момент будет переведен.

    Задача

    Приложение для занятий в тренажерном зале. Необходимо построение карты работы мышц по результатам тренировок в рантайме приложения.
    Два пола: М и Ж. Рассмотрим вариант М, т. к. для Ж все аналогично.
    Должно строится одновременно 6 изображений: 3 периода (одна тренировка, за неделю, за месяц) х 2 вида (спереди, сзади)

    Каждое такое изображение состоит из 15 изображений групп мышц для вида спереди и 14 для вида сзади. Плюс по 1 изображению основы (голова, кисти рук и ступни ног). Итого, чтобы собрать вид спереди необходимо наложить 16 изображений, сзади – 15.

    Всего 23 группы мышц для обеих сторон (для тех, у кого 15+14 != 23, небольшое пояснение – некоторые мышцы «видны» с обеих сторон).

    Алгоритм наложения в первом приближении:

    1. На основе данных завершенных тренировок строится HashMap , String – название группы мышц, Float – степень нагрузки от 0 до 10.
    2. Каждая из 23 мышц перекрашивается в цвет от 0 (не участвовала) до 10 (макс. нагрузка).
    3. Накладываем перекрашенные изображения мыщц в два изображения (спереди, сзади).
    4. Сохраняем все 6 изображений.

    Для хранения 31 (16+15) изображения размером 1500х1500 px при 24-битном режиме требуется 31х1500х1500х24бит = 199 MB оперативной памяти. Примерно при превышении

    30-40 МБ вы получаете OutOfMemoryException. Соотвественно, одновременно загрузить все изображения из ресурсов вы не можете, т. к. необходимо освобождать ресурсы для неполучения эксепшена. Это означает, что необходимо последовательно выполнять наложение изображений. Алгоритм трансформируется в следующий:

    На основе данных завершенных тренировок строится HashMap , String – мышца, Float – степень нагрузки от 0 до 10.

    Цикл для каждого из 6 изображений:

    1. Получили ресурс BitmapFactory.decodeResource().
    2. Каждая из 23 мышц перекрашивается в цвет от 0 (не участвовала) до 10 (макс. нагрузка).
    3. Накладываем перекрашенные изображения мыщц на один Canvas.
    4. Bitmap.recycle() освободили ресурс.

    Задачу выполняем в отдельном потоке с помощью AsyncTask. В каждом Таске создается последовательно два изображения: вид спереди и сзади.

    Вспомогательный класс DoubleMusclesBitmaps нужен только для того, чтобы вернуть две переменные Bitmap-а: вид спереди и сзади. Забегая вперед Java-класс DoubleMusclesBitmaps заменяется на Pair в Kotlin-е.

    Рисование

    Цвета colors.xml в ресурсах values.

    Создание одного вида

    Наложение одной мышцы

    Запускаем генерацию 3 пар изображений.

    Необходимо отметить, что очень много времени занимает чтение ресурсов. Для каждой пары изображений декодируется 29 PNG-файлов из ресурсов. В моем случае из общих затрат на создание изображений функция BitmapFactory.decodeResource() тратит

    1. Периодически получаю OutOfMemoryException.
    2. Обработка занимает более 9 секунд, и это на эмуляторе(!) В «среднем» (старом моем) телефоне доходило до 20 секунд.
    3. AsyncTask со всеми вытекающими утечками [памяти].

    Плюсы:
    С вероятностью (1-OutOfMemoryException) изображения рисуются.

    AsyncTask в IntentService

    Для ухода от AsyncTask решено было перейти на IntentServiсe, в котором выполнялось задание по созданию изображений. После завершения работы сервиса, при наличия запущенного BroadcastReceiver-а получаем Uri всех шести сгенерированных изображений, иначе просто изображения сохранялись, для того, чтобы при следующем открытии пользователем приложения не было необходимости ожидать процесс создания. Время работы при этом никак не изменилось, но с одним минусом – утечками памяти разобрались, осталось еще два минуса.

    Заставлять пользователей ожидать создание изображений такое количество времени, конечно же, нельзя. Нужно оптимизировать.

    Намечаю пути оптимизации:

    1. Обработка изображений.
    2. Добавление LruCache.

    Обработка изображений

    Все исходные PNG-ресурсы имеют размер 1500х1500 пх. Уменьшаем их до 1080х1080.
    Как видно на второй фотографии все исходники квадратные, мышцы находятся на своем месте, а реальные полезные пиксели занимают небольшую площадь. То, что все группы мышц уже находятся на своем месте — это удобно для программиста, но не рационально для производительности. Кропаем (отрезаем) лишнее во всех исходниках, записывая положение (x, y) каждой группы мышц, чтобы наложить в последствии в нужное место.

    В первом подходе перекрашивались и накладывались все 29 изображений групп мышц на основу. Основа же включала в себя только голову, кисти рук и части ног. Изменяем основу: теперь она включает в себя помимо головы, рук и ног, все остальные группы мышц. Всё красим в серый цвет color_muscle0. Это позволит не перекрашивать и не накладывать те группы мышцы, которые не были задействованы.

    Теперь все исходники выглядят так:

    LruCache

    После дополнительной обработке исходных изображений, некоторые стали занимать немного памяти, что привело к мысли о переиспользовании (не освобождать их после каждого наложения методом .recycle() ) с помощью LruCache. Создаем класс для хранения исходных изображений, который одновременно берет на себя функцию чтения из ресурсов:

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

    Корутины

    Код с использованием IntentService работает, но читаемость кода с колбэками не назовешь приятной.

    Добавим желание посмотреть на корутины Котлина в работе. Добавим понимание того, что через пару месяцев читать свой синхронный код будет приятнее, чем поиск места возврата Uri файлов сгенерированных изображений.

    Также ускорение обработки изображений натолкнуло на мысль использовать фичу в нескольких новых местах приложения, в частности в описании упражнений, а не только после тренировки.

    Стандартная связка errorHandler, job и scope – скоуп корутин с хендлером ошибок, если корутина сломается.

    uries – HashMap, который хранит в себе 6 изображений для последующего вывода в UI:
    uries[«last_back»]=Uri?
    uries[«last_front»]=Uri?
    uries[«week_back»]=Uri?
    uries[«week_front»]=Uri?
    uries[«month_back»]=Uri?
    uries[«month_front»]=Uri?

    Замеряем время обработки.

    С 9313 мс обработка уменьшилась до 596 мс

    Если есть идеи по дополнительной оптимизации – велком в комментарии.

    Источник

    Читайте также:  Все для прошивки андроид alcatel
    Оцените статью