Closed kings1990 closed 6 months ago
I'm definitely not against giving this a go, but it will be quite a bit of work and require some investigation. Some initial things that spring to mind for me are:
I'll try looking into this when I have some free time
Here's a little update on the current state of SVG support for this plugin, mainly for me to keep track. The whole process has been a massive yak shaving exercise for me, but it has been fun and I've learned a lot! Currently none of the code mentioned below has been pushed, however I will be pushing a feature branch for this shortly.
I've written a CLI in Typescript to convert from pixel art PNGs/GIFs/JPEGs to SVGs that works quite nicely. I'll make it available on npm & Github soon, as it could actually be useful for people in contexts other than this. It should be pretty simple to write a script using it to replace the existing editSprite.sh
script.
Animated SVGs are not easily supported, which should be no surprise given Java seems to barely even support animated gifs (loading an animated gif via ImageIO.read
loses the animation info, but via new ImageIcon(URL)
does keep the animation, and repaints components as you would want).
SVG animations are also generally not designed for frame based animations, so it will probably be easier to simply work with one SVG per frame and animate it in code. To that end, I started playing with IntelliJ's AnimatedIcon
but I struggled to get it to work, and there is very little documentation around how to use it. So in the end, I've created my own AnimatedIcon
class that works better for me. It extends ImageIcon
, and implements ScalableIcon
which makes it a bit more useful than IntelliJ's anyways.
Ho boy. Java does not natively support SVGs.
I've added the Twelvemonkeys imageio-batik module, which allows loading of SVGs into BufferedImage
s using ImageIO::read
. However Since the SVG is converted in to a rasterized image in this process, it does not scale nicely, as scaling is done by directly scaling this rasterized image.
I think I'll need to integrate directly with Apache Batik instead, so that I can do scaling before rasterizing. Currently, I'm thinking of doing something along the lines of extending/wrapping BufferedImage
and holding onto the original SVG info in it. Then I can override the getScaledInstance
method so it scales the SVG and re-rasterizes it. Or perhaps I should instead implement a RenderableImage
. Another option would be to change my AnimatedIcon
to AnimatedSvgIcon
and not extend ImageIcon, then just hold onto the SVG info & implement the paintIcon
method myself.
There's also a few different SVG libraries I need to look into a bit more. In addition to Batik, I am aware of JFreeSVG (however it appears to be more to do with writing SVGs than reading them) and svgSalamander.
I've looked into svgSalamnder, and it seems it has something that will work for me. I should be able to use SVGIcon or create something similar based on it. This is good, because Batik is massive and I wanted to avoid including it if at all possible.
@2x
images anymore_r
images anymore, as SVGs can be easily flipped in memory (except for Pokemon that are noticeably different on the left vs right) Changing the sprites to SVGs has no real effect on blurriness, the issue was with scaling the sprites (regardless of format). Since this issue was raised, I've done changes to how the plugin handles scaling, which I think solves the root problem here. SVGs could still potentially be a bit nicer to use just in terms of file size (not needing to have 4 images for each frame of a Pokémon, only 1 SVG file instead), but for now it likely isn't worth it, especially if it requires adding new libraries to the plugin.
This is a hard work, I am not sure com.intellij.ui.AnimatedIcon
can help you.
The icon is too fuzzy! svg dynamic pic support?