Closed Alex009 closed 1 year ago
My 2c; but I very strongly disagree with these various calls to add GIF/SVG support - this goes outside the scope of what MokoResources should be doing, which is abstract the common resource access across platforms. iOS/Android don't have consistent SVG or GIF support out-of-the-box, and so there's nothing for Moko to abstract against.
What MokoResources does do is provide raw file access. We're doing this in our project to load SVG's with AndroidSVG / SVGKit and it's working great.
vector graphics supported by both platforms out of box. for android it VectorDrawable and for ios it pdf. goal is implement support of this types of graphics. Or by auto-conversion tool with single svg source - generate vectorDrawable for android from svg and generate pdf for ios, from svg.
about gif support i agree with you
can be helpful https://github.com/jcraane/kmm-images
SVG files are supported indirectly. Workaround is simple. However, direct use of SVG (without conversion to XML) can be taken as a limitation.
MR/assets
.
// Extension fun
fun AssetResource.toAndroidAssetUri() = "file:///android_asset/$originalPath"
// Coil + Compose val coilPainter = rememberAsyncImagePainter( model = MR.assets.your_svg_image.toAndroidAssetUri() ) Image( painter = coilPainter, contentDescription = "Some svg image" )
- On iOS side, use SDWebImage with [SVGDecoder](https://github.com/SDWebImage/SDWebImageSVGCoder) for loading images
// Swift UI WebImage(url: URL(fileURLWithPath: MR.assets.shared.nsBundle .path(forResource:"your_svg_image, ofType: "svg") ?? "") )
[Here](https://github.com/msa1422/KMM-Arch-PetSearch) is a sample project that implements this technique successfully, plus much more.
// Extension fun fun AssetResource.toAndroidAssetUri() = "file:///android_asset/$originalPath" // Coil + Compose val coilPainter = rememberAsyncImagePainter( model = MR.assets.your_svg_image.toAndroidAssetUri() ) Image( painter = coilPainter, contentDescription = "Some svg image" )
Just adding on top of this. For Compose Desktop you can use:
@Composable
fun assetPainter(resource: AssetResource): Painter =
androidx.compose.ui.res.painterResource(resourcePath = "files/${resource.originalPath}")
All stuff inside assets
folder are placed in files
directory for generated desktop (jvm) resources.
Hey @msa1422 , any ideas why my assets
aren't included in my apk
? My setup is basically the same as yours. I have also added this in the module containing the resources:
sourceSets["main"].apply {
assets.srcDir(File(buildDir, "generated/moko/androidMain/assets"))
res.srcDir(File(buildDir, "generated/moko/androidMain/res"))
}
Edit: NVM, I Invalidated my IDE cache and it worked. But it doesn't seem to load vector drawables on Android (works on Compose desktop), only pure SVG
Hi @racka98. The implementation is working in my projects for the files with .svg extension placed under Shared MR assets folder.
I haven't tried placing the vector drawables (.xml) files under the MR assets folders yet. My solution works only for KMM. I also haven't tried out KMP and compose desktop yet.
Probably, I am not able to correctly infer "it" when you said "But doesn't it seem to load vector drawables on Android". Please tell me a little bit more about the issue.
If I place them (vector drawables) inside the assets
folder, accessing them in android sources using R.drawable.xxx
works (resolves on IDE) but upon compilation it throws the Unresolved Reference: xxx
error.
But I think I'll just convert them all to SVG since it will still be a hassle to access them on iOS if they are Vector drawables.
// Coil + Compose val coilPainter = rememberAsyncImagePainter( model = MR.assets.your_svg_image.toAndroidAssetUri() ) Image( painter = coilPainter, contentDescription = "Some svg image" )
Is there anyway to do this without coil?
Out of the box solutions for Compose ImagePainter requires resourceId. Android assets do not have any id associated with them. I believe, as of now, Coil is the only way to load images from assets by using a URI of the asset image. Edit - An Image loading library basically. Glide will also do.
@msa1422 I had the exact experience with @racka98. It doesn't load the SVG. Do you have any idea why?
@racka98 Did you find any solution?
@racka98 Did you find any solution?
I have this in commonMain
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.painter.Painter
import dev.icerock.moko.resources.AssetResource
@Composable
expect fun painterResource(resource: AssetResource): Painter
On Android I now use Coil to load the Assets:
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.painter.Painter
import coil.compose.rememberAsyncImagePainter
import dev.icerock.moko.resources.AssetResource
fun AssetResource.toAndroidAssetUri() = "file:///android_asset/$originalPath"
@Composable
actual fun painterResource(resource: AssetResource): Painter =
rememberAsyncImagePainter(model = resource.toAndroidAssetUri())
On Desktop (Compose) I use this:
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.painter.Painter
import dev.icerock.moko.resources.AssetResource
@Composable
actual fun painterResource(resource: AssetResource): Painter =
androidx.compose.ui.res.painterResource(resourcePath = "files/${resource.originalPath}")
Pay attention to the imports on Desktop and Android.
After upgrading MokoResources to v0.21.1, I have run into a bizarre problem. I have upgraded to the latest version in 3 projects. PetSearch, and 2 other projects. SVG AssetResource seems to be working fine in one of my client's project. However, in the PetSearch mentioned above and an another personal project, SVG AssetResource is not working. Project setup is identical in all 3 projects.
Upon some investigation, I found out that the method AssetResource.readText(context)
is printing the SVG file content in the client project. However in Petsearch, it is throwing java.io.FileNotFoundException
.
Coil is also throwing the same java.io.FileNotFoundException
.
@Alex009, I have created this branch for you to investigate.
@racka98 Could you please upgrade the MokoResources version and see if this issue shows up in your project?
UPDATE: Adding new svg (arrow_left.svg) in assets in client project, is throwing java.io.FileNotFoundException
for the new resource (arrow_left.svg).
UPDATE: I added a couple of modules in the client project, the new resource (arrow_left.svg) is not throwing exception anymore. After repeated clean builds, all 3 projects are showing the icons, and not throwing any exception.
With that said, whenever I add a new svg, Coil throws java.io.FileNotFoundException
.
Also can be useful https://github.com/ravibhojwani86/Svg2VectorAndroid
There is another interesting way: https://github.com/DevSrSouza/svg-to-compose
will be released in 0.22.0
https://github.com/vdmeer/svg2vector may help