Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] add ImageModifier #815

Merged
merged 3 commits into from
Nov 30, 2017
Merged

[WIP] add ImageModifier #815

merged 3 commits into from
Nov 30, 2017

Conversation

ethansinjin
Copy link
Contributor

@ethansinjin ethansinjin commented Nov 28, 2017

Resolves #810

This adds an ImageModifier, allowing edits to be performed on a concrete type of Image (ex. UIImage) right before the image is used/displayed.

I've created the KingfisherOptionsInfoItem case and ImageModifier struct, but the actual modifier isn't being run yet. I'd like advice on where exactly to run the modifier. I think it should go in downloadAndCacheImage and tryToRetrieveImageFromCache, but I'm not sure; there might be a better place for it.

TODO:

  • add ImageModifierTests
  • execute the modifier's modify() method somewhere in KingfisherManager.swift

@ethansinjin ethansinjin changed the title add ImageModifier [WIP] add ImageModifier Nov 28, 2017
@onevcat
Copy link
Owner

onevcat commented Nov 29, 2017

@ethansinjin

Thanks for the p-r. I have to say it is a much bigger one than I expected! IMO, it would be sufficient to just provide a single and light wrapper type to meet all the needs, just similar to the existing RequestModifier. Something like this:

import Foundation

/// Request modifier of image downloader.
public protocol ImageModifier {
    func modified(for image: Image) -> Image?
}

struct DefaultImageModifier: ImageModifier {
    static let `default` = DefaultImageModifier()
    private init() {}
    func modified(for image: Image) -> Image? {
        return image
    }
}

public struct AnyImageModifier: ImageModifier {
    
    let block: (Image) -> Image?
    
    public func modified(for image: Image) -> Image? {
        return block(image)
    }
    
    public init(modify: @escaping (Image) -> Image? ) {
        block = modify
    }
}

By passing a modifying block to AnyImageModifier, users could do everything they want to apply change to the image. Currently it seems that you are following the way of ImageProcessor, to have identifier and cascading of modifiers. However, the identifiers there are mainly used for purpose of data persisting and caching. It is not the case here for image modifier.

How do you think about it? Does the identifier take any responsibility here?

@ethansinjin
Copy link
Contributor Author

That's a fair point; I guess it is a bit over-architected. I'll rework it to be more like RequestModifier.

A few thoughts:

  • I still think we should include a RenderingModeImageModifier and FlipsForRightToLeftLayoutDirectionImageModifier because I'm pretty sure those are the most common reasons this class is needed.
  • I think the return parameter should be Image instead of Image?, because at the point of execution of the ImageModifier, a valid Image is already required as a parameter. So, if the change isn't possible, couldn't the original image just be returned?

@ethansinjin
Copy link
Contributor Author

Alright, please let me know what you think of the changes! @onevcat

@onevcat
Copy link
Owner

onevcat commented Nov 30, 2017

@ethansinjin Great work!

I still think we should include a RenderingModeImageModifier and FlipsForRightToLeftLayoutDirectionImageModifier because I'm pretty sure those are the most common reasons this class is needed.

Yes, I totally agree with you.

I think the return parameter should be Image instead of Image?, because at the point of execution of the ImageModifier, a valid Image is already required as a parameter. So, if the change isn't possible, couldn't the original image just be returned?

The original thought is letting users have a chance to return nil if the do not want to set the image at the last minute. But I guess it could rarely happen so current implementation looks fine!

@onevcat
Copy link
Owner

onevcat commented Nov 30, 2017

I think I could do the last part of applying the modifier later. Once it has been done, I will release an update version. Thank you!

@onevcat onevcat merged commit b3d7e30 into onevcat:master Nov 30, 2017
@ethansinjin
Copy link
Contributor Author

Thanks for merging!

petarlazarov pushed a commit to dowjones-mobile/Kingfisher that referenced this pull request Oct 6, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants