Getting Android vector drawable as Path
This is a cross-post from my blog: aednlaxer.github.io
You ever wondered how to get a Path
from Android’s vector XML drawable to draw it on a canvas
? Here are some options.
Getting a vector drawable and drawing it on a canvas
with any size is easy:
val vectorDrawable = ResourcesCompat.getDrawable(resources, R.drawable.icon, null) vectorDrawable?.setBounds(0, 0, 800, 800) vectorDrawable?.draw(canvas)
This produces a vector drawable which is properly scaled and looks sharp in most cases. Although if you scale this image too much some artefacts may appear, scaled icon may become blurry. Look how sharp the text is and how pixelated the scaled shape is:
In case you want to have better scaling and implement advanced features with paint, gradients and shaders you might need to get a vector drawable as instance of Path
.
Understanding XML path data
Each vector XML file contains instructions how to draw it. Compare parts of XML and Kotlin representation of the same icon:
<path
android:fillColor="#FF000000"
android:pathData="M17.6,9.48l1.84,-3.18c0.16,-0.31 0.04,-0.69 -0.26,..."/>path.moveTo(17.6f, 9.48f) path.lineTo(19.44f, 6.3f) path.cubicTo(19.6f, 5.99f, 19.48f, 5.61f, 19.18f, 5.45f)
This XML drawable contains path instructions which can be mapped into a set of Path
calls:
M
is translated tomoveTo
l
is translated tolineTo
c
is translated tocubicTo
Uppercase is for absolute coordinates, lowercase is for coordinates relative to previous instruction. Thus, l1.84,-3.18
following M17.6,9.48
becomes lineTo(19.44f, 6.3f)
. Quick maths:
- First argument: 17.6 + 1.84 = 19.44
- Second argument 9.48 − 3.18 = 6.3
It’s possible to manually build a Path
object that matches instructions of an XML drawable. Although it’ll probably take a lot of your time. It’s also easy to make a typo.
Read more about XML path data in this awesome article.
Generating Path code from vector image using an online generator
codecrafted.net/svgtoandroid is online generator that converts an SVG file into Java code, similar to what was demonstrated in the previous section. Resulting code can be optimized and improved by converting it to Kotlin and checking that all variables have meaningful names. Always think twice before uploading any of your app code including SVG icons into 3rd party services.
Converting vector XML into Path programmatically
A Path
can be created from a String
containing path instructions. There are two main steps to convert a vector drawable into Path
:
- Parse content of a vector XML drawable and extract
pathData
attribute from it - Create new
Path
object from path data
This gist shows how you can implement a parser for a simple XML with one path
node. Getting a Path
from path data string is trivial:
import androidx.core.graphics.PathParser PathParser.createPathFromPathData(pathData)
Look how sharp this shape is after scaling a Path
using Matrix
:
A complete example will be provided later as a part of a bigger project.