SDWebImage / SDWebImageSwiftUI

SwiftUI Image loading and Animation framework powered by SDWebImage
https://sdwebimage.github.io/SDWebImageSwiftUI
MIT License
2.19k stars 228 forks source link

[Color] AnimatedImage tinting not getting applied #338

Open Boowman opened 1 week ago

Boowman commented 1 week ago

Hello,

I am trying to apply a tint to an svg image but it seems no matter what I try none of them work. I have already tried applying each modifier individually but I just wanted to show what I have tried.

Device

AnimatedImage(url: <svg_url>)
    .resizable()
    .renderingMode(.template)
    .onViewCreate(perform: { view, image in
        view
            .tintColor = .green
    })
    .tint(.green)
    .accentColor(.green)
    .foregroundStyle(.green)
    .colorMultiply(.green)
    .frame(width: 32, height: 32)
dreampiggy commented 1 week ago

Seems you want that UIKit imageView to apply tintColor.

I can have a check whether the SDAnimatedImageView supports tint color. Because it's a custom subclass image view from UIImageView, not all of the UIImageView static image rendering is supported😂

Boowman commented 1 week ago

If you could let me know if it supports tinting it would be great. In terms of implementation, I went based on what I found in the documentation that was provided which surprised me that it doesn't work. Scroll to Animated Image

dreampiggy commented 6 days ago

This weekend I'll have a test and check.

Currently SDAnimatedImage use custom rendering on animated image (which means, we override CALayer's content by ourselves), but only re-use the UIKit rendering on static image.

I guess this cause the root issue. We need to implements each special UIImageView rendering (like renderingMode, tintColor, resizableImage) on animated image (or find a better way to magically re-use the UIKit implementation)

dreampiggy commented 6 days ago

@Boowman Can you have a test on WebImage ? Which use normal SwiftUI rendering (actually it's simple on concept, just dynamic change the body based on Timer, to return new SwiftUI.Image)

Boowman commented 6 days ago

@dreampiggy I tested WebImage and it works when applying tint, the problem with this is that it if I use it within an animated context which is what I am doing at the moment. It doesn't animate, it seems to be fixed on the page and the content animates around it.

dreampiggy commented 6 days ago

Can you provide a real demo with these 2 use case ? It seems both of them contains issue.

  1. AnimatedImage with tint on animated image url
  2. WebImage with tint on animated image url
dreampiggy commented 5 days ago

Is this what you want ?

https://github.com/SDWebImage/SDWebImage/pull/3761

But SVG is not animtable, so it's a little strange in your demo. I use a APNG and WebP image for showing

Boowman commented 3 days ago

Can you provide a real demo with these 2 use case ? It seems both of them contains issue.

  1. AnimatedImage with tint on animated image url
  2. WebImage with tint on animated image url

I was looking to create a quick demo showing the usage but the SVG are not even loading, here is a screenshot and the full-code in case you want to test it.

import SwiftUI
import SDWebImage
import SDWebImageSwiftUI

struct ContentView: View {
    @State var fadeInContent: Bool = false

    var body: some View {
        ScrollView {
            VStack {
                LazyVGrid(columns: [.init(), .init()], content: {
                    VStack {
                        Text("No tinting")
                            .foregroundStyle(.white)

                        AnimatedImage(url: URL(string: "https://www.svgrepo.com/show/194550/online-shop.svg")!)
                            .resizable()
                            .scaledToFit()
                            .frame(width: 64, height: 64)
                            .clipped()
                            .background(.gray)

                        WebImage(url: URL(string: "https://www.svgrepo.com/show/194550/online-shop.svg")!)
                            .resizable()
                            .scaledToFit()
                            .frame(width: 64, height: 64)
                            .clipped()
                            .background(.gray)
                    }
                    VStack {
                        Text("With tinting")
                            .foregroundStyle(.white)

                        AnimatedImage(url: URL(string: "https://www.svgrepo.com/show/194550/online-shop.svg")!)
                            .resizable()
                            .renderingMode(.template)
                            .tint(.red)
                            .scaledToFit()
                            .frame(width: 64, height: 64)
                            .clipped()
                            .background(.gray)

                        WebImage(url: URL(string: "https://www.svgrepo.com/show/194550/online-shop.svg")!)
                            .resizable()
                            .renderingMode(.template)
                            .tint(.green)
                            .scaledToFit()
                            .frame(width: 64, height: 64)
                            .clipped()
                            .background(.gray)
                    }
                    .onAppear {
                        withAnimation(.timingCurve(0, 0, 0.4, 1, duration: 0.6).delay(0.5)) {
                            fadeInContent = true
                        }
                    }
                    .offset(y: 50)
                    .opacity(fadeInContent ? 1 : 0)
                    .offset(y: fadeInContent ? -50 : 0)
                })
            }
            .padding()
        }
        .background(.black)
    }
}
Boowman commented 3 days ago

Is this what you want ?

SDWebImage/SDWebImage#3761

But SVG is not animtable, so it's a little strange in your demo. I use a APNG and WebP image for showing

So if not AnimatedImage what would you use to load SVG ??

dreampiggy commented 3 days ago

So if not AnimatedImage what would you use to load SVG ??

WebImage can support SVG. It will draw bitmap version (fixed size) instead of Pure Vector Format

See why I introduce this code: https://github.com/SDWebImage/SDWebImageSwiftUI/blob/master/SDWebImageSwiftUI/Classes/WebImage.swift#L200-L217

And, you can run SwiftUI Demo in our repo to check, which shows 2 URL of SVGs

dreampiggy commented 2 days ago

but the SVG are not even loading

SVG is not official supported by Apple's ImageIO coder. It's not a normal bitmap image format

You need that https://github.com/SDWebImage/SDWebImageSVGCoder