0

resized

original

As you can see in the image, SVG images are losing their quality when I resize them to 200X200. Isn't that against SVG images logic? I think the SVG images should not be corrupted no matter how big I enlarge it. What can I do for it? Which method can i follow?

I resized the SVG image like this in SwiftUI

  Image(uiImage: .flame.resize(targetSize: CGSize(width: 200, height: 200)))

I used this piece of code to resize image. This not working. You can see in the resized image above. I found this solution here. Click

extension UIImage {
    func resize(targetSize: CGSize) -> UIImage {
        return UIGraphicsImageRenderer(size:targetSize).image { _ in
            self.draw(in: CGRect(origin: .zero, size: targetSize))
        }
    }
}
Betul Aksu
  • 15
  • 4
  • 1
    "found this solution here" Well, that code is wrong for an svg. What you're getting is exactly to be expected. You are rendering to a bitmap and then resizing, thus losing all the svg advantage you were wishing for. – matt Dec 11 '22 at 20:05
  • @matt I can't find any documentation for using this. I put it in the Asset Catalog and I'm trying to use it. Svg is said to be supported after iOS 13+. Am I missing something? – Betul Aksu Dec 11 '22 at 20:11
  • You can put an SVG into the asset catalog, but when you build, it will be turned into a bitmap. You need to make it a regular resource and then use a 3rd party lib to render — see https://stackoverflow.com/questions/35691839/how-to-display-svg-image-using-swift – Lou Franco Dec 11 '22 at 20:50
  • Alternatively you could render with WebKit. – Lou Franco Dec 11 '22 at 20:51
  • "Am I missing something?" @BetulAksu Well it appears to _me_ that you're missing _everything_. See my answer below for a counterexample. – matt Dec 12 '22 at 01:08

2 Answers2

3

I don't know much about SwiftUI, but here's an example of a single SVG displaying accurately at multiple sizes in UIKit image views:

enter image description here

That was done without code. All I did was to configure the SVG in the asset catalog to have a single size and to preserve vector data:

enter image description here

That is completely different from what you're doing; you are drawing the SVG into a graphics context, so you are throwing away the vector data and substituting a bitmap, which of course does not scale perfectly.

matt
  • 515,959
  • 87
  • 875
  • 1,141
-1

Not pretending to give a full answer, just a few ideas:

  1. Please check this nice tutorial which explains the need of using .interpolation(.none) in such cases for SwiftUI.Image.
  2. Don't resize the UI image - resize only SwiftUI image, as now you know a very simple way to deny interpolation.
  3. If the step 2 won't work (e.g. no transparency(alpha channel) or some other problems), probably you'll have to pre-process that UIImage with CoreGraphics (this is definitely not performant, but may look good).
  4. In the worst-case scenario, you'll have to implement that UIImage.resize function using CGContext, paying attention to the interpolation quality.

So, the main ideas are:

  1. You tried UIGraphicsImageRenderer, but there still are a lot of other options to explore, and you should check them one-by-one to get some intuition of what works and what doesn't.
  2. Your resized image looks blurry, so the main issue is probably with the interpolation (mixing a neighbouring pixels' alpha channel when you downscale), so you should deny the interpolation. You can investigate how to fix the performance issues once everything is rendered well.
olha
  • 2,132
  • 1
  • 18
  • 39