SDWebImageSwiftUI icon indicating copy to clipboard operation
SDWebImageSwiftUI copied to clipboard

[Color] AnimatedImage tinting not getting applied

Open Boowman opened this issue 1 year ago • 7 comments

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

  • iPhone 15 Prox Max
  • iOS 17.5
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)

Boowman avatar Oct 16 '24 10:10 Boowman

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😂

dreampiggy avatar Oct 17 '24 06:10 dreampiggy

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

Boowman avatar Oct 17 '24 08:10 Boowman

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 avatar Oct 18 '24 02:10 dreampiggy

@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)

dreampiggy avatar Oct 18 '24 02:10 dreampiggy

@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.

Boowman avatar Oct 18 '24 07:10 Boowman

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 avatar Oct 18 '24 07:10 dreampiggy

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

dreampiggy avatar Oct 19 '24 16:10 dreampiggy

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 avatar Oct 21 '24 09:10 Boowman

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 ??

Boowman avatar Oct 21 '24 09:10 Boowman

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 avatar Oct 21 '24 10:10 dreampiggy

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

dreampiggy avatar Oct 22 '24 07:10 dreampiggy

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

Oh yes, i forgot to add this in the sample project.

Boowman avatar Oct 25 '24 17:10 Boowman

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

I will make the demo and post it here, sorry it's been taking so long.

Boowman avatar Oct 25 '24 17:10 Boowman

I’m encountering the same problem as AnimatedImage doesn’t render the foregroundStyle, tint, or accent colour.

chauyong avatar Nov 28 '24 14:11 chauyong

Supported by SDWebImage's AnimationTransformer feature, see more in https://github.com/SDWebImage/SDWebImage/pull/3761

AnimatedImage(URL)
.onViewCreate { view in
    view.animationTransformer = SDImageTintTransformer(color: UIColor.red)
}

This feature is not only about tint, you can customize each animation frame to whatever you want, like scale it down, flip down, apply CIFilter blur, etc...More powerful

For WebImge you can still use tintColor from UIKit/SwiftUI, because it actually use UIKit's build box for rendering (Apple's own implementation).

But for SDAnimatedImage you must use the custom API because of implementation details is really different from how UIKit's animation rendering. (We use custom CALayer and custom draw for better performance)

dreampiggy avatar Feb 28 '25 07:02 dreampiggy

thank's this is really helpful

RadiBarq avatar Mar 03 '25 18:03 RadiBarq