import UIKit final class RDEPUBImageViewerCoordinator { private weak var presentingController: UIViewController? private let theme: RDEPUBReaderTheme init(presentingController: UIViewController, theme: RDEPUBReaderTheme) { self.presentingController = presentingController self.theme = theme } // MARK: - From Native Text Path (UIImage already resolved) func presentImage(_ image: UIImage, sourceRect: CGRect? = nil, altText: String? = nil) { let config = RDEPUBImageViewController.Configuration( image: image, sourceRect: sourceRect, altText: altText, theme: theme ) let viewerVC = RDEPUBImageViewController(configuration: config) presentingController?.present(viewerVC, animated: true) } // MARK: - From WebView Path (need to resolve from src URL) func presentImageFromWebView( src: String, baseHref: String?, resourceResolver: RDEPUBResourceResolver ) { guard let image = loadImage(src: src, baseHref: baseHref, resourceResolver: resourceResolver) else { return } presentImage(image) } // MARK: - Private private func loadImage( src: String, baseHref: String?, resourceResolver: RDEPUBResourceResolver ) -> UIImage? { let pathPart = src.components(separatedBy: "#").first ?? src guard !pathPart.isEmpty else { return nil } let fileURL: URL? if let baseHref { fileURL = resourceResolver.fileURL(forReference: pathPart, relativeToHref: baseHref) } else { let normalized = resourceResolver.normalizedHref(pathPart) fileURL = normalized.flatMap { resourceResolver.fileURL(forRelativePath: $0) } } // 经统一资源入口读取:加密图片由 provider 解密,明文图片直读磁盘 guard let fileURL, let data = resourceResolver.resourceData(at: fileURL) else { return nil } return UIImage(data: data) } }