Giter Club home page Giter Club logo

svg-to-compose's Introduction

SVG to Compose [Experimental]

Converts SVG or Android Vector Drawable to Compose code.

Why this project

On the start of the Compose for Desktop it does not support SVG files and Android Vector Drawables. This also difficulties a migration of the App to Multiplatform (Desktop and Android). Currently, it does support Android Vector Drawables in the Desktop allowing share your vectors.

Use cases

Now Compose for Desktop supports android vector drawables, this means that the first reason that the project was created does not apply anymore, this does not mean that it is not useful anymore.

Use cases:

  • Manipulate dynamic an SVG file in code, you can generate and do source code modifications.
  • Create an Icon pack similar to how Material Icons works on Compose (compose-icons is build with SVG to Compose)

How its work

The project uses Android's Svg2Vector to convert SVG to Android Drawables and uses a customized material icon code generator from the Jetpack Compose source code to generate the source code of the SVG file.

Example 1: Running with Kotlin Scripting

file: jetnews-drawables-to-compose.main.kts

@file:Repository("https://jitpack.io")
@file:Repository("https://maven.google.com")
@file:Repository("https://jetbrains.bintray.com/trove4j")

@file:DependsOn("com.github.DevSrSouza:svg-to-compose:-SNAPSHOT")
@file:DependsOn("com.google.guava:guava:23.0")
@file:DependsOn("com.android.tools:sdk-common:27.2.0-alpha16")
@file:DependsOn("com.android.tools:common:27.2.0-alpha16")
@file:DependsOn("com.squareup:kotlinpoet:1.7.2")
@file:DependsOn("org.ogce:xpp3:1.1.6")

import br.com.devsrsouza.svg2compose.Svg2Compose
import br.com.devsrsouza.svg2compose.VectorType
import java.io.File

val assetsDir = File("assets")
val srcDir = File("src/main/kotlin")

Svg2Compose.parse(
    applicationIconPackage = "assets",
    accessorName = "JetnewsAssets",
    outputSourceDirectory = srcDir,
    vectorsDirectory = assetsDir,
    type = VectorType.DRAWABLE,
    allAssetsPropertyName = "AllAssets"
)

Generating code by using executing kotlin jetnews-drawables-to-compose

Using in code: JetnewsAssets.JetnewsLogo

Svg

The only difference for SVG files is the VectorType.SVG.

Example 2: Generating a whole Icon pack

For Icon Packs, subgroups is supported: IconPack/group/icon.svg

val assetsDir = File("linea-icons")
val srcDir = File("src/main/kotlin")

Svg2Compose.parse(
    applicationIconPackage = "assets",
    accessorName = "LineaIcons",
    outputSourceDirectory = srcDir,
    vectorsDirectory = assetsDir,
    type = VectorType.SVG,
    iconNameTransformer = { name, group -> name.removePrefix(group) },
    allAssetsPropertyName = "AllIcons"
)

Using in code: LineaIcons.Arrows.Buhttps://github.com/overpas/svg-to-compose-intellijttonUp

The project also generate an accessor for all yours assets, for the given example, it should be LineaIcons.AllIcons and it also generated for child groups LineaIcons.Arrows.AllIcons

svg-to-compose's People

Contributors

c5inco avatar devsrsouza avatar ealfonso93 avatar gabrielkuhn avatar marioferreirastorytel avatar vganin avatar wiryadev avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

svg-to-compose's Issues

Static import of ImageVector.Builder cases compile error

For a generated file:

..
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.graphics.vector.ImageVector.Builder
..

public val Icons.Coin: ImageVector
    get() {
        if (_coin != null) {
            return _coin!!
        }
        _coin = Builder(
            name = "Coin",
            defaultWidth = 24.0.dp,
            defaultHeight = 24.0.dp,
      ..

The static import of the Builder here causes the following Compile Time Exception:

<classpath>/icons/CoinKt.java:5: error: cannot access Builder
import androidx.compose.ui.graphics.vector.ImageVector.Builder;
                                                      ^
  bad class file: /Users/nik/.gradle/caches/transforms-3/bd3521848bdffd1987d2b8593e215954/transformed/jetified-ui-1.3.0-api.jar(/androidx/compose/ui/graphics/vector/ImageVector$Builder.class)
    undeclared type variable: T
    Please remove or make sure it appears in the correct subdirectory of the classpath.

By removing the static import and using _coin = ImageVector.Builder( ... it works fine.

Build a CLI to use

We can bundle core logic into a shadow Jar and make it executable, use it in Shell like:

svg-to-compose dir/to/input dir/to/output

Also we can publish it to Brew repo.

Fill by gradients not supported

Hi, In the beginning, thx for the cool converter.
I discovered filling color is null if used any gradient. For example, you can take this SVG and convert it to kt

<svg height="150" width="400">
    <defs>
        <linearGradient id="grad1" x1="0%" y1="0%" x2="100%" y2="0%">
            <stop offset="0%" style="stop-color:rgb(255,255,0);stop-opacity:1" />
            <stop offset="100%" style="stop-color:rgb(255,0,0);stop-opacity:1" />
        </linearGradient>
    </defs>
    <ellipse cx="200" cy="70" rx="85" ry="55" fill="url(#grad1)" />
</svg>
public val ImagesGroup.Gradient: ImageVector
    get() {
        if (_gradient != null) {
            return _gradient!!
        }
        _gradient = Builder(
            name = "Gradient", defaultWidth = 400.0.dp, defaultHeight = 150.0.dp,
            viewportWidth = 400.0f, viewportHeight = 150.0f
        ).apply {
            path(
                fill = null,
                /* expected
                          Brush.linearGradient(
                                              colors = listOf(Color.Yellow, Color.Red),
                                              start = Offset(0f, 0f),
                                              end = Offset(Float.POSITIVE_INFINITY, 0f)
                                          ),
                */
                stroke = null,
                strokeLineWidth = 0.0f,
                strokeLineCap = Butt,
                strokeLineJoin = Miter,
                strokeLineMiter = 4.0f,
                pathFillType = NonZero
            ) {
                moveTo(115.0f, 70.0f)
                arcToRelative(85.0f, 55.0f, 0.0f, true, false, 170.0f, 0.0f)
                arcToRelative(85.0f, 55.0f, 0.0f, true, false, -170.0f, 0.0f)
                close()
            }

        }
            .build()
        return _gradient!!
    }

private var _gradient: ImageVector? = null

[Question] Elaborate on the usage of Kotlin scripting

Can you elaborate on how we can execute the scripting mentioned in the readme?

Because running kotlin <something>.main.kts not working for me

$ kotlin sample.main.kts
:: problems summary ::
:::: WARNINGS
		module not found: com.github.DevSrSouza#svg-to-compose;0.8.1

	==== central: tried

	  https://repo1.maven.org/maven2/com/github/DevSrSouza/svg-to-compose/0.8.1/svg-to-compose-0.8.1.pom

	  -- artifact com.github.DevSrSouza#svg-to-compose;0.8.1!svg-to-compose.jar:

	  https://repo1.maven.org/maven2/com/github/DevSrSouza/svg-to-compose/0.8.1/svg-to-compose-0.8.1.jar

error: cannot access script base class 'org.jetbrains.kotlin.mainKts.MainKtsScript'. Check your module classpath for missing or conflicting dependencies (sample.main.kts:1:1)
error: unresolved reference: Repository (sample.main.kts:1:7)
error: unresolved reference: Repository (sample.main.kts:2:7)
error: unresolved reference: Repository (sample.main.kts:3:7)
error: unresolved reference: DependsOn (sample.main.kts:5:7)
error: unresolved reference: DependsOn (sample.main.kts:6:7)
...

Large SVG causing MethodTooLargeException

when the vector is big, it has given MethodTooLargeException

example: Caused by: org.jetbrains.org.objectweb.asm.MethodTooLargeException: Method too large: ./assets/vectors/AppMonetizationKt.getAppMonetization (./assets/VectorsGroup;)Landroidx/compose/ui/graphics/vector/ImageVector;

IDE Plugin

Hi, I've created an Android Studio plugin wrapper around your project, in order to make it possible to generate icons in IDE. Here's it is https://github.com/overpas/svg-to-compose-intellij. It would be nice to hear your opinion on its reasonableness, usability, convenience, suggestions for improvement, etc. If you think it's worth the effort, could you mention it in the README of your project?

Add licence file and headers to the project

This includes having licence file in the root of the repo as well as having licence headers in each file.

The licence allows the tool to be used in commercial codebases and may be crucial for a lot of companies around. It's especially important now as Compose is being adopted by many for production.

Consider using a PathParser

Instead of constructing images like this:

path(fill = SolidColor(Color(0xFFfcf7d2)), stroke = null, strokeLineWidth = 0.0f,
        strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,
        pathFillType = NonZero) {
    moveTo(1037.06f, 87.81f)
    horizontalLineToRelative(92.36f)
    lineTo(1129.42f, 22.7f)
    lineTo(1026.06f, 22.7f)
    verticalLineToRelative(54.12f)
    curveToRelative(0.0f, 6.07f, 4.93f, 11.0f, 11.0f, 11.0f)
}

Consider using a PathParser

addPath(
    PathParser().parsePathString(
        "M256 0 c4.6 0 9.2 1 13.4 2.9 l188.3 79.9 c22 9.3 38.4 31 38.3 57.2 -0.5 99.2 -41.3 280.7 -213.6 363.2 -16.7 8 -36.1 8 -52.8 0 C57.3 420.7 16.5 239.2 16 140 c-0.1 -26.2 16.3 -47.9 38.3 -57.2 L242.7 2.9 C246.8 1 251.4 0 256 0z m0 66.8 v378 C394 378 431.1 230.1 432 141.4 L256 66.8z"
    ).toNodes()
)

This would make the result code much shorter and possibly help (partially) solve #16 with MethodTooLargeException.

EOF Exception for some icons

Issue

  • I try to convert bootstrap icons svg to compose. For the Fill icons it works, but for the normal icon it gives me exception. I have not checked which icon exactly that will cause the issue. But i have tried to use Svg2Vector to check if any of this svg will cause any error in the process.
  • Then i try to use the drawable and change the type to VectorType.DRAWABLE, but it still shows the same error.
  • Any suggestion to trace which icon that may cause the issue?

Logcat

Exception in thread "main" java.io.EOFException: input contained no data
	at org.xmlpull.mxp1.MXParser.fillBuf(MXParser.java:3003)
	at org.xmlpull.mxp1.MXParser.more(MXParser.java:3046)
	at org.xmlpull.mxp1.MXParser.parseProlog(MXParser.java:1410)
	at org.xmlpull.mxp1.MXParser.nextImpl(MXParser.java:1395)
	at org.xmlpull.mxp1.MXParser.next(MXParser.java:1093)
	at androidx.compose.material.icons.generator.IconParserKt.seekToStartTag(IconParser.kt:136)
	at androidx.compose.material.icons.generator.IconParserKt.access$seekToStartTag(IconParser.kt:1)
	at androidx.compose.material.icons.generator.IconParser.parse(IconParser.kt:40)
	at androidx.compose.material.icons.generator.IconWriter.generateTo(IconWriter.kt:58)
	at br.com.devsrsouza.svg2compose.Svg2Compose$parse$3.invoke(Svg2Compose.kt:92)
	at br.com.devsrsouza.svg2compose.Svg2Compose$parse$3.invoke(Svg2Compose.kt:13)
	at kotlin.io.FileTreeWalk$FileTreeWalkIterator$TopDownDirectoryState.step(FileTreeWalk.kt:168)
	at kotlin.io.FileTreeWalk$FileTreeWalkIterator.gotoNext(FileTreeWalk.kt:98)
	at kotlin.io.FileTreeWalk$FileTreeWalkIterator.computeNext(FileTreeWalk.kt:80)
	at kotlin.collections.AbstractIterator.tryToComputeNext(AbstractIterator.kt:42)
	at kotlin.collections.AbstractIterator.hasNext(AbstractIterator.kt:29)
	at kotlin.sequences.SequencesKt___SequencesKt.toCollection(_Sequences.kt:742)
	at kotlin.sequences.SequencesKt___SequencesKt.toMutableList(_Sequences.kt:772)
	at kotlin.sequences.SequencesKt___SequencesKt.toList(_Sequences.kt:763)
	at br.com.devsrsouza.svg2compose.Svg2Compose.parse(Svg2Compose.kt:138)
	at br.com.devsrsouza.svg2compose.Svg2Compose.parse$default(Svg2Compose.kt:30)
	at br.com.devsrsouza.svg2compose.MainKt.main(Main.kt:9)
	at br.com.devsrsouza.svg2compose.MainKt.main(Main.kt)

Process finished with exit code 1

Pixelated results

Hello,
So far I've not had any issues with the plugin. It's great! So thank you.
But I got one SVG from the designers that would not convert correctly for some reason. Everything is a mess of squares that looks a bit Minecraft-y. I tried with older versions but the result is the same.
It might not be an issue with the plugin but do you have any idea what the problem might be?
Thanks for the attention.

Plugin crashes in Android Studio Iguana

I've recently downloaded the plugin and it crashes on startup.
Environment:

  • mac, M1
  • Android Studio Iguana | 2023.2.1 Canary 16 [Build #AI-232.10227.8.2321.11161997]

Usage as android library

is it possible to use this as svg/xml text to image vector text as android library, ie saving to svg and reading from svg or xml is leads on developer, library just converts one code text to another and gives it to save or copy

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.