Работа с графической подсистемой (Lecture 10 – Graphics)

Preview:

Citation preview

Работа с графическойподсистемой

Android

Дмитрий Колесников

Поддерживаемые форматы.

JPEGPNGGIF (только чтение, с некоторыми приседаниями можно запустить анимацию)BMP (только чтение)

Остальные форматы.

Есть разные библиотекиЕсть C++ и NDKЕсть спецификации форматов

Как отображать

ImageView.Любому View можно назначить фон (android:background).Загрузить во встроенный браузер (WebView).Отрисовывать через OpenGL и SurfaceView.Отрисовывать вручную через Canvas.

Класс Bitmap.

Представление картинки в памяти.Может быть mutable и immutable.Создаётся или напрямую статическим методом createBitmap, или при чтении из источникаданных (файл, поток, ресурс и т. д.) статическими методами класса BitmapFactoryМожно узнать размеры изображения.Можно скопировать/отмасштабировать изображение.Можно закрасить пиксель/всё изображение/часть изображения.Можно хапнуть горя с памятью.

Класс Bitmap.

Память под Bitmap выделяется 2 кусками:

До Android 3.0:Метаданные и прочая Java-обёрткаСобственно данные о пикселях в нативной куче (которой Dalvik VM не управляет)

С Android 3.0:Всё лежит в Dalvik (ART) heap.

Класс Bitmap.

Bitmap Занимает в памяти 4 * width * height.

Можно использовать RGB-565 и лишиться прозрачности.Можно использовать ARGB-4444, который давно deprecated, и картинка не будет радоватьцветами.

Dalvik VM не дефрагментирует память, поэтому даже если в куче хватает места,OutOfMemoryError следит за вами.

Класс Bitmap.

Bitmap освобождает память в 2 случаях:

при сборке мусора и вызове finalize()при явном вызове метода recycle()

После вызова recycle() картинка не может быть использована — выбрасывается исключение. В старых версиях Android (API <= 10) использование recycle() настоятельно рекомендуется, в

новых - не является обязательным, но хуже не будет

Итого

Делаем recycle(), как только картинка становится не нужна. В том числе, если в тот жеBitmap загружаем новое изображениеЕсли нужно много изображений — выделяем память при старте приложения, создаём пулкартинок.При создании через BitmapFactory ставим нужные флаги в BitmapFactory.Options.Проверить размер картинки (BitmapOptions.inJustDecodeBounds).Открыть картинку сразу с масштабированием.Пробовать ловить OutOfMemoryError и в случае нехватки памяти грузить картинку с другойцветовой палитрой или ещё уменьшить размер.

Класс Drawable.

Класс-обёртка для различных видов изображений. Может содержать внутри:

BitmapГеометрическую фигуру с закраской9-patch изображениеАнимациюНесколько слоёвИ кучу всего ещё (читайте про android.graphics.drawable)

Класс BitmapDrawable.

BitmapDrawable создаётся «вокруг» обычного Bitmap.

Он создаётся неявно, когда мы ставим картинку в ImageView через задание android:src.Мы получаем весь тот же набор проблем с памятью.Можно достать картинку через getBitmap() и удалить как раньше.Обязательно не забудьте установить перед удалением callback для Drawable в null длясборки памяти (по умолчанию ставится на вьюху-родитель)

Класс ImageView.

Мы можем задать, как масштабировать изображение.Можем применить матрицу преобразования, обрезать или сжать/растянуть в зависимостиот размеров.Подробнее о том, как что преобразуется

9-patch

Когда у нас есть кнопка/поле ввода/любой другой элемент, у которого мы не знаем размеротображаемых данных — как ставить фон?

Можем растянуть, но тогда будет некрасиво или появятся артефакты по углам.Можем замостить узором, но не всегда это приемлемо.

9-patch

State drawables.

У кнопки есть несколько состояний: обычное, нажатое, выделенное.Возможно, понадобится отображать её разным цветом в зависимости от ситуации.Придётся вешать обработчики на все события и менять фон/изображение?

State drawables.

Нас спасёт State Drawable!

1 <?xml version="1.0" encoding="utf-8"?> 2 <selector xmlns:android="http://schemas.android.com/apk/res/android"> 3 <item android:drawable="@drawable/button_pressed" 4 android:state_pressed="true"/> 5 <item android:drawable="@drawable/button_default"/> 6 </selector>

Такой же трюк можно провернуть с цветами, установив их для текста.

Shape drawables

Простые графические примитивы не обязательно рисовать руками в любимом фотошопе.Можно их задать через Shape Drawable в xml.

1 <shape xmlns:android="http://schemas.android.com/apk/res/android" 2 android:shape="rectangle"> 3 <corners android:radius="5dip" /> 4 <gradient 5 android:angle="270" 6 android:type="linear" 7 android:startColor="#000000" 8 android:endColor="#ffffff"/> 9 </shape>

Canvas.

Наследуемся от View, переопределяем onDraw() или используем SurfaceViewinvalidate() и postInvalidate()Можем рисовать геометрические примитивы напрямую руками.Не стоит забывать о буферизации и не делать слишком часто перерисовку (быстрее 60кадров в секунду не будет, а вот батарею скушать можно бодро).

Canvas.

.moveTo(), .lineTo() — и мы рисуем линии.

.drawBitmap(), drawRect(), drawText()Drawable.draw(Canvas)Используем класс Path, если нам надо нарисовать сложную ломаную или многопримитивов, тогда отрисовка будет проходить быстрее.Класс Picture позволяет кэшировать запросы к Canvas (отрисовали раз, потом из неговоспроизводим гораздо быстрее) — но он не работает при аппаратном ускорении.Класс Paint — настройки кисти. Не создавайте лишний раз, иногда лучше создатьстатический объект или поле экземпляра.

Canvas.

Можно нарисовать тот же Bitmap.Можно написать текст.Можно «изогнуть» текст вдоль кривой или ломаной.Можно применять матрицы преобразований.

Работа с сетью

http://square.github.io/picassoМожно поставить URL в ImageView (.setImageUrl())Руками.

Полезные ссылки.

http://developer.android.com/guide/topics/graphics/2d-graphics.htmlhttp://developer.android.com/training/displaying-bitmaps/index.htmlhttps://romannurik.github.io/AndroidAssetStudio/http://androiddrawables.com

Recommended