LibGDX| SVG | Android

Пошаговое руководство для работы с SVG в LibGDX только с Android.

Vladislav Shesternin
5 min readJan 16, 2022

Что Вы Узнаете?

В даной статье Вы узнаете как отображать SVG в LibGDX Android.

Зачем использовать SVG?

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

SVG(векторная графика) — это (код) инструкция как рисовать ваше изображение (фигурами) тоесть имеем возможность вносить изменения (размер, цвет) и изображения подстроится под эти параметры.

PNG|JPG(растровая графика) — это массив цветов, возможности редактирования нет, какой массив цветов скачал такой и используй, для качественного отображения должно быть ровное количество пикселей, сколько имеет изображение столько должно предоставить и устройство, если же пикселей устройства меньше изображение удалит свои пиксели (качество соответственно ухудшается) если же пикселей больше (тоесть предоставляем область которую изображение должно заполнит) пиксели згенерируются но это ещё хуже чем их удаление.

В чём идея?

Так как для LibGDX парсеров SVG можно сказать что нет, то Я решил поискать парсеры для Android, так как Я работаю только с этой платформой, и нашол SVG Kit который предоставляет абсолютно бесплатный архив с кодом парсера который можно просто вставить в свой Android проэкт и использовать, но Нам же нужно SVG для LibGDX которое можно поместить в Texture, да всё верно, парсер возвращает Bitmap который Мы можем конвертировать в Pixmap и уже эго поместить в Нашу Texture, вот и всё.

ПРАКТИКА:

  1. Реализуйте проэкт по инструкции: https://veldan1202.medium.com/libgdx-%D1%82%D0%BE%D0%BB%D1%8C%D0%BA%D0%BE-%D0%B4%D0%BB%D1%8F-android-4858e26734cf

Главное получить Android context.

2. Скачайте libsvg https://drive.google.com/drive/folders/1mAfn5chT0pwqHgVcS-N8KtrSLB7y1Bbi?usp=sharing

3. Извлеките содержимое архива и скопируйте scand:

libsvg/src/main/java/com

4. Откройте Свой проэкт по пути YouProjectName/app/src/main/java/com и поместите сюда scand:

5. Поместите Свой SVG фйл в app/src/main/res/raw:

Тестовое изображение → https://drive.google.com/file/d/1nHhRRi42vELnKEWqlysx7N9017TGL920/view?usp=sharing

6. Основное ради чего Вы здесь, Код отображения SVG:

package com.veldan.loaders

import android.opengl.GLES20
import android.opengl.GLUtils
import com.badlogic.gdx.ApplicationAdapter
import com.badlogic.gdx.graphics.Color
import com.badlogic.gdx.graphics.Pixmap
import com.badlogic.gdx.graphics.Texture
import com.badlogic.gdx.graphics.g2d.SpriteBatch
import com.badlogic.gdx.utils.ScreenUtils
import com.scand.svg.SVGHelper

class LibGDXGame : ApplicationAdapter() {

lateinit var img: Texture

override fun create() {
val bitmap = SVGHelper.useContext(activityContext).open(R.raw.img).bitmap

img = Texture(bitmap.width, bitmap.height, Pixmap.Format.RGBA8888)
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, img.textureObjectHandle)
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0)
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0)
bitmap.recycle()
}

override fun render() {
ScreenUtils.clear(Color.PURPLE)
SpriteBatch().apply {
begin()
draw(img, 0f, 0f, 500f, 500f)
end()
}
}

}
  1. Как использовать SVGHelper Вы можете прочитать в документации SVG Kit но Я опишу основное простыми словами:

0. Для использования ресурсов с assets folder пример кода:

val bitmap = SVGHelper.noContext().open(
activityContext.assets.open("aaa.svg").bufferedReader().use {
it
.readText()
}
).bitmap

SVGHelper — единственный класс с которым Вы будете взаимодействовать для парсинга SVG.

Функции SVGHelper:

— Первым делом необходимо вызвать функцию указывающую будет ли участвовать Android context в получении SVG или нет, для этого есть 2 функции: useContext | noContext

useContext(context: Context) — используется при получении ресурса с внутреннего хранилища.

noContext() — используется при получении ресурса с внешнего хранилища.

— После указания среды откуда будет браться ресурс указываем путь к ресурсу или сам xml svg файла в качестве аргумента функции open(svg).

— Если SVG не имеет размеров (полей width|height) используем:

setBaseBounds(int, int) — задает начальные размеры SVG без них будет ошибка.

checkSVGSize() — автоматически определяет размер.

Нет размеров svg

Есть размеры svg

— Дополнительные (промежуточные) функции:

setScale(float, float) — увеличивает SVG в указаных пропорциях.

setRequestBounds(int, int) — очень полезная функция эсли Вы знаете размеры областы в которую будет помещаться SVG, изображение будет можно сказать идеальным так как будет пиксель в пиксуль, эсли соотношение сторон изображениия и Вашей области для него разные то используйте следующую функцию со значением false.

setKeepAspectRatio(boolean) — включает | отключает соблюдении соотношения сторон исходного SVG, если Ваша область соответствует исходному изображению неиспользуйте эту функцию так как по умолчанию соотношение включено.

setCropImage(boolean) — название говорит само за себя, но на практике не применял.

— Последней функцией Вы должны указать результат парсинга.

В Наем случае, так как Мы будем конвертировать Bitmap в Pixmap то Нам соответственно нужен Bitmap. Но можно получить и следуюющие результаты:

  • Bitmap
  • BitmapDrawable
  • Picture
  • PictureDrawable

2. Если Вы берёте SVG с Figma Вам могут помочь следующие рекомендации:

Так как SVG Figma очень продвинутые и имеют теги которые libsvg не умеет парсить, нам придется немного их подправлять.

  • Тег фигуры <rect|elips|…..> должен быть после тега <defs>
  • Альфа канал градиента должен быть не в самом цвете а в поле stop-opacity
  • stop-opacity должен быть в паре с stop-color
  • В SVG с Figma отсутствует offset первой точки градиента, offset должен быть у кажтого градиентного тега <stop> со значением от 0 до 1 (подсказка у первой точки градиента это 0)

Наиболее хорошо подходят изображения с AdobeIllustrator и BoxySVG, Вы можете открыть изображения созданные в Figma в этих программах и немножко поперемещать части которые не отображаются в Ваших текстурах для (замены трансформаций Figma) применения трансформаций данных программ в Ваши SVG файлы, особенно это касается градиентов с перемещением центра, изменнение его угла, и маштабирование.

О использовании эффектов Figma типа (теней, размытия) и градиентов типа (Diamond|Angular) можете даже не думать, придумайте им альтернативы, например размытие можно сделать с помощью прозрачности линейного или радиального градиента.

Наиболее хорошее решение создавать свои SVG сразу в AdobeIllustrator или BoxySVG.

PS. Vel_daN: Love what You DO 💚.

--

--