Try to solve the SwiftUI bug of rendering EXIF UIImage in WebImage. Now we use the Image(decorative:) API to grab the CGImage and orientation instead. For vector image, draw vector image into bitmap for rescue
This commit is contained in:
parent
14a3cce8e5
commit
0a41337ed0
|
@ -39,13 +39,9 @@ class AppDelegate: NSObject, NSApplicationDelegate {
|
||||||
// Dynamic check to support vector format for both WebImage/AnimatedImage
|
// Dynamic check to support vector format for both WebImage/AnimatedImage
|
||||||
SDWebImageManager.shared.optionsProcessor = SDWebImageOptionsProcessor { url, options, context in
|
SDWebImageManager.shared.optionsProcessor = SDWebImageOptionsProcessor { url, options, context in
|
||||||
var options = options
|
var options = options
|
||||||
var context = context
|
|
||||||
if let _ = context?[.animatedImageClass] as? SDAnimatedImage.Type {
|
if let _ = context?[.animatedImageClass] as? SDAnimatedImage.Type {
|
||||||
// AnimatedImage supports vector rendering, should not force decode
|
// AnimatedImage supports vector rendering, should not force decode
|
||||||
options.insert(.avoidDecodeImage)
|
options.insert(.avoidDecodeImage)
|
||||||
} else {
|
|
||||||
// WebImage supports bitmap rendering only
|
|
||||||
context?[.imageThumbnailPixelSize] = CGSize.zero
|
|
||||||
}
|
}
|
||||||
return SDWebImageOptionsResult(options: options, context: context)
|
return SDWebImageOptionsResult(options: options, context: context)
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,13 +47,9 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
|
||||||
// Dynamic check to support vector format for both WebImage/AnimatedImage
|
// Dynamic check to support vector format for both WebImage/AnimatedImage
|
||||||
SDWebImageManager.shared.optionsProcessor = SDWebImageOptionsProcessor { url, options, context in
|
SDWebImageManager.shared.optionsProcessor = SDWebImageOptionsProcessor { url, options, context in
|
||||||
var options = options
|
var options = options
|
||||||
var context = context
|
|
||||||
if let _ = context?[.animatedImageClass] as? SDAnimatedImage.Type {
|
if let _ = context?[.animatedImageClass] as? SDAnimatedImage.Type {
|
||||||
// AnimatedImage supports vector rendering, should not force decode
|
// AnimatedImage supports vector rendering, should not force decode
|
||||||
options.insert(.avoidDecodeImage)
|
options.insert(.avoidDecodeImage)
|
||||||
} else {
|
|
||||||
// WebImage supports bitmap rendering only
|
|
||||||
context?[.imageThumbnailPixelSize] = CGSize.zero
|
|
||||||
}
|
}
|
||||||
return SDWebImageOptionsResult(options: options, context: context)
|
return SDWebImageOptionsResult(options: options, context: context)
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,13 +20,6 @@ class ExtensionDelegate: NSObject, WKExtensionDelegate {
|
||||||
SDImageCodersManager.shared.addCoder(SDImageWebPCoder.shared)
|
SDImageCodersManager.shared.addCoder(SDImageWebPCoder.shared)
|
||||||
SDImageCodersManager.shared.addCoder(SDImageSVGCoder.shared)
|
SDImageCodersManager.shared.addCoder(SDImageSVGCoder.shared)
|
||||||
SDImageCodersManager.shared.addCoder(SDImagePDFCoder.shared)
|
SDImageCodersManager.shared.addCoder(SDImagePDFCoder.shared)
|
||||||
// Dynamic check to support vector format for WebImage
|
|
||||||
SDWebImageManager.shared.optionsProcessor = SDWebImageOptionsProcessor { url, options, context in
|
|
||||||
var context = context
|
|
||||||
// WebImage supports bitmap rendering only
|
|
||||||
context?[.imageThumbnailPixelSize] = CGSize.zero
|
|
||||||
return SDWebImageOptionsResult(options: options, context: context)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func applicationDidBecomeActive() {
|
func applicationDidBecomeActive() {
|
||||||
|
|
|
@ -26,13 +26,9 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
|
||||||
// Dynamic check to support vector format for both WebImage/AnimatedImage
|
// Dynamic check to support vector format for both WebImage/AnimatedImage
|
||||||
SDWebImageManager.shared.optionsProcessor = SDWebImageOptionsProcessor { url, options, context in
|
SDWebImageManager.shared.optionsProcessor = SDWebImageOptionsProcessor { url, options, context in
|
||||||
var options = options
|
var options = options
|
||||||
var context = context
|
|
||||||
if let _ = context?[.animatedImageClass] as? SDAnimatedImage.Type {
|
if let _ = context?[.animatedImageClass] as? SDAnimatedImage.Type {
|
||||||
// AnimatedImage supports vector rendering, should not force decode
|
// AnimatedImage supports vector rendering, should not force decode
|
||||||
options.insert(.avoidDecodeImage)
|
options.insert(.avoidDecodeImage)
|
||||||
} else {
|
|
||||||
// WebImage supports bitmap rendering only
|
|
||||||
context?[.imageThumbnailPixelSize] = CGSize.zero
|
|
||||||
}
|
}
|
||||||
return SDWebImageOptionsResult(options: options, context: context)
|
return SDWebImageOptionsResult(options: options, context: context)
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,6 +81,7 @@ struct ContentView: View {
|
||||||
"https://nr-platform.s3.amazonaws.com/uploads/platform/published_extension/branding_icon/275/AmazonS3.png",
|
"https://nr-platform.s3.amazonaws.com/uploads/platform/published_extension/branding_icon/275/AmazonS3.png",
|
||||||
"https://raw.githubusercontent.com/ibireme/YYImage/master/Demo/YYImageDemo/mew_baseline.jpg",
|
"https://raw.githubusercontent.com/ibireme/YYImage/master/Demo/YYImageDemo/mew_baseline.jpg",
|
||||||
"https://via.placeholder.com/200x200.jpg",
|
"https://via.placeholder.com/200x200.jpg",
|
||||||
|
"https://dv6mh24acw2xi.cloudfront.net/public/moments/gabbr/tmpImg9143171451882065582.jpeg",
|
||||||
"https://dev.w3.org/SVG/tools/svgweb/samples/svg-files/w3c.svg",
|
"https://dev.w3.org/SVG/tools/svgweb/samples/svg-files/w3c.svg",
|
||||||
"https://dev.w3.org/SVG/tools/svgweb/samples/svg-files/wikimedia.svg",
|
"https://dev.w3.org/SVG/tools/svgweb/samples/svg-files/wikimedia.svg",
|
||||||
"https://raw.githubusercontent.com/icons8/flat-color-icons/master/pdf/stack_of_photos.pdf",
|
"https://raw.githubusercontent.com/icons8/flat-color-icons/master/pdf/stack_of_photos.pdf",
|
||||||
|
|
|
@ -75,6 +75,10 @@
|
||||||
32C43E3322FD5DF400BE87F5 /* SDWebImageSwiftUI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32C43E3122FD5DE100BE87F5 /* SDWebImageSwiftUI.swift */; };
|
32C43E3322FD5DF400BE87F5 /* SDWebImageSwiftUI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32C43E3122FD5DE100BE87F5 /* SDWebImageSwiftUI.swift */; };
|
||||||
32C43E3422FD5DF400BE87F5 /* SDWebImageSwiftUI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32C43E3122FD5DE100BE87F5 /* SDWebImageSwiftUI.swift */; };
|
32C43E3422FD5DF400BE87F5 /* SDWebImageSwiftUI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32C43E3122FD5DE100BE87F5 /* SDWebImageSwiftUI.swift */; };
|
||||||
32C43E3522FD5DF400BE87F5 /* SDWebImageSwiftUI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32C43E3122FD5DE100BE87F5 /* SDWebImageSwiftUI.swift */; };
|
32C43E3522FD5DF400BE87F5 /* SDWebImageSwiftUI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32C43E3122FD5DE100BE87F5 /* SDWebImageSwiftUI.swift */; };
|
||||||
|
32D26A022446B546005905DA /* Image.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32D26A012446B546005905DA /* Image.swift */; };
|
||||||
|
32D26A032446B546005905DA /* Image.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32D26A012446B546005905DA /* Image.swift */; };
|
||||||
|
32D26A042446B546005905DA /* Image.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32D26A012446B546005905DA /* Image.swift */; };
|
||||||
|
32D26A052446B546005905DA /* Image.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32D26A012446B546005905DA /* Image.swift */; };
|
||||||
32ED4826242A13030053338E /* ImageManagerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32ED4825242A13030053338E /* ImageManagerTests.swift */; };
|
32ED4826242A13030053338E /* ImageManagerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32ED4825242A13030053338E /* ImageManagerTests.swift */; };
|
||||||
32ED4827242A13030053338E /* ImageManagerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32ED4825242A13030053338E /* ImageManagerTests.swift */; };
|
32ED4827242A13030053338E /* ImageManagerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32ED4825242A13030053338E /* ImageManagerTests.swift */; };
|
||||||
32ED4828242A13030053338E /* ImageManagerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32ED4825242A13030053338E /* ImageManagerTests.swift */; };
|
32ED4828242A13030053338E /* ImageManagerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32ED4825242A13030053338E /* ImageManagerTests.swift */; };
|
||||||
|
@ -133,6 +137,7 @@
|
||||||
32C43E2922FD586200BE87F5 /* SDWebImage.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SDWebImage.framework; path = Carthage/Build/tvOS/SDWebImage.framework; sourceTree = "<group>"; };
|
32C43E2922FD586200BE87F5 /* SDWebImage.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SDWebImage.framework; path = Carthage/Build/tvOS/SDWebImage.framework; sourceTree = "<group>"; };
|
||||||
32C43E2D22FD586E00BE87F5 /* SDWebImage.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SDWebImage.framework; path = Carthage/Build/watchOS/SDWebImage.framework; sourceTree = "<group>"; };
|
32C43E2D22FD586E00BE87F5 /* SDWebImage.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SDWebImage.framework; path = Carthage/Build/watchOS/SDWebImage.framework; sourceTree = "<group>"; };
|
||||||
32C43E3122FD5DE100BE87F5 /* SDWebImageSwiftUI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SDWebImageSwiftUI.swift; sourceTree = "<group>"; };
|
32C43E3122FD5DE100BE87F5 /* SDWebImageSwiftUI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SDWebImageSwiftUI.swift; sourceTree = "<group>"; };
|
||||||
|
32D26A012446B546005905DA /* Image.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Image.swift; sourceTree = "<group>"; };
|
||||||
32ED4825242A13030053338E /* ImageManagerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageManagerTests.swift; sourceTree = "<group>"; };
|
32ED4825242A13030053338E /* ImageManagerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageManagerTests.swift; sourceTree = "<group>"; };
|
||||||
/* End PBXFileReference section */
|
/* End PBXFileReference section */
|
||||||
|
|
||||||
|
@ -278,6 +283,7 @@
|
||||||
32C43DDF22FD54C600BE87F5 /* AnimatedImage.swift */,
|
32C43DDF22FD54C600BE87F5 /* AnimatedImage.swift */,
|
||||||
32C43E3122FD5DE100BE87F5 /* SDWebImageSwiftUI.swift */,
|
32C43E3122FD5DE100BE87F5 /* SDWebImageSwiftUI.swift */,
|
||||||
326E480923431C0F00C633E9 /* ImageViewWrapper.swift */,
|
326E480923431C0F00C633E9 /* ImageViewWrapper.swift */,
|
||||||
|
32D26A012446B546005905DA /* Image.swift */,
|
||||||
);
|
);
|
||||||
path = Classes;
|
path = Classes;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -698,6 +704,7 @@
|
||||||
326B8487236335110011BDFB /* ActivityIndicator.swift in Sources */,
|
326B8487236335110011BDFB /* ActivityIndicator.swift in Sources */,
|
||||||
32C43E1622FD583700BE87F5 /* ImageManager.swift in Sources */,
|
32C43E1622FD583700BE87F5 /* ImageManager.swift in Sources */,
|
||||||
32C43E1822FD583700BE87F5 /* AnimatedImage.swift in Sources */,
|
32C43E1822FD583700BE87F5 /* AnimatedImage.swift in Sources */,
|
||||||
|
32D26A022446B546005905DA /* Image.swift in Sources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
@ -714,6 +721,7 @@
|
||||||
326B8488236335110011BDFB /* ActivityIndicator.swift in Sources */,
|
326B8488236335110011BDFB /* ActivityIndicator.swift in Sources */,
|
||||||
32C43E1922FD583700BE87F5 /* ImageManager.swift in Sources */,
|
32C43E1922FD583700BE87F5 /* ImageManager.swift in Sources */,
|
||||||
32C43E1B22FD583700BE87F5 /* AnimatedImage.swift in Sources */,
|
32C43E1B22FD583700BE87F5 /* AnimatedImage.swift in Sources */,
|
||||||
|
32D26A032446B546005905DA /* Image.swift in Sources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
@ -730,6 +738,7 @@
|
||||||
326B8489236335110011BDFB /* ActivityIndicator.swift in Sources */,
|
326B8489236335110011BDFB /* ActivityIndicator.swift in Sources */,
|
||||||
32C43E1C22FD583800BE87F5 /* ImageManager.swift in Sources */,
|
32C43E1C22FD583800BE87F5 /* ImageManager.swift in Sources */,
|
||||||
32C43E1E22FD583800BE87F5 /* AnimatedImage.swift in Sources */,
|
32C43E1E22FD583800BE87F5 /* AnimatedImage.swift in Sources */,
|
||||||
|
32D26A042446B546005905DA /* Image.swift in Sources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
@ -746,6 +755,7 @@
|
||||||
326B848A236335110011BDFB /* ActivityIndicator.swift in Sources */,
|
326B848A236335110011BDFB /* ActivityIndicator.swift in Sources */,
|
||||||
32C43E1F22FD583800BE87F5 /* ImageManager.swift in Sources */,
|
32C43E1F22FD583800BE87F5 /* ImageManager.swift in Sources */,
|
||||||
32C43E2122FD583800BE87F5 /* AnimatedImage.swift in Sources */,
|
32C43E2122FD583800BE87F5 /* AnimatedImage.swift in Sources */,
|
||||||
|
32D26A052446B546005905DA /* Image.swift in Sources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,77 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the SDWebImage package.
|
||||||
|
* (c) DreamPiggy <lizhuoli1126@126.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
@available(iOS 13.0, OSX 10.15, tvOS 13.0, watchOS 6.0, *)
|
||||||
|
extension Image {
|
||||||
|
@inlinable init(platformImage: PlatformImage) {
|
||||||
|
#if os(macOS)
|
||||||
|
self.init(nsImage: platformImage)
|
||||||
|
#else
|
||||||
|
self.init(uiImage: platformImage)
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@available(iOS 13.0, OSX 10.15, tvOS 13.0, watchOS 6.0, *)
|
||||||
|
extension PlatformImage {
|
||||||
|
static var empty = PlatformImage()
|
||||||
|
}
|
||||||
|
|
||||||
|
#if os(iOS) || os(tvOS) || os(watchOS)
|
||||||
|
@available(iOS 13.0, OSX 10.15, tvOS 13.0, watchOS 6.0, *)
|
||||||
|
extension PlatformImage.Orientation {
|
||||||
|
@inlinable var toSwiftUI: Image.Orientation {
|
||||||
|
switch self {
|
||||||
|
case .up:
|
||||||
|
return .up
|
||||||
|
case .upMirrored:
|
||||||
|
return .upMirrored
|
||||||
|
case .down:
|
||||||
|
return .down
|
||||||
|
case .downMirrored:
|
||||||
|
return .downMirrored
|
||||||
|
case .left:
|
||||||
|
return .left
|
||||||
|
case .leftMirrored:
|
||||||
|
return .leftMirrored
|
||||||
|
case .right:
|
||||||
|
return .right
|
||||||
|
case .rightMirrored:
|
||||||
|
return .rightMirrored
|
||||||
|
@unknown default:
|
||||||
|
return .up
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension Image.Orientation {
|
||||||
|
@inlinable var toPlatform: PlatformImage.Orientation {
|
||||||
|
switch self {
|
||||||
|
case .up:
|
||||||
|
return .up
|
||||||
|
case .upMirrored:
|
||||||
|
return .upMirrored
|
||||||
|
case .down:
|
||||||
|
return .down
|
||||||
|
case .downMirrored:
|
||||||
|
return .downMirrored
|
||||||
|
case .left:
|
||||||
|
return .left
|
||||||
|
case .leftMirrored:
|
||||||
|
return .leftMirrored
|
||||||
|
case .right:
|
||||||
|
return .right
|
||||||
|
case .rightMirrored:
|
||||||
|
return .rightMirrored
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
|
@ -18,19 +18,6 @@ public typealias PlatformImage = NSImage
|
||||||
public typealias PlatformImage = UIImage
|
public typealias PlatformImage = UIImage
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@available(iOS 13.0, OSX 10.15, tvOS 13.0, watchOS 6.0, *)
|
|
||||||
extension Image {
|
|
||||||
init(platformImage: PlatformImage) {
|
|
||||||
#if os(macOS)
|
|
||||||
self.init(nsImage: platformImage)
|
|
||||||
#else
|
|
||||||
self.init(uiImage: platformImage)
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static var empty = Image(platformImage: PlatformImage())
|
|
||||||
}
|
|
||||||
|
|
||||||
#if os(macOS)
|
#if os(macOS)
|
||||||
@available(iOS 13.0, OSX 10.15, tvOS 13.0, watchOS 6.0, *)
|
@available(iOS 13.0, OSX 10.15, tvOS 13.0, watchOS 6.0, *)
|
||||||
public typealias PlatformView = NSView
|
public typealias PlatformView = NSView
|
||||||
|
|
|
@ -63,13 +63,13 @@ public struct WebImage : View {
|
||||||
// this prefetch the memory cache of image, to immediately render it on screen
|
// this prefetch the memory cache of image, to immediately render it on screen
|
||||||
// this solve the case when `onAppear` not been called, for example, some transaction indeterminate state, SwiftUI :)
|
// this solve the case when `onAppear` not been called, for example, some transaction indeterminate state, SwiftUI :)
|
||||||
if imageManager.isFirstPrefetch {
|
if imageManager.isFirstPrefetch {
|
||||||
self.imageManager.prefetch()
|
imageManager.prefetch()
|
||||||
}
|
}
|
||||||
return Group {
|
return Group {
|
||||||
if imageManager.image != nil {
|
if imageManager.image != nil {
|
||||||
if isAnimating && !self.imageManager.isIncremental {
|
if isAnimating && !imageManager.isIncremental {
|
||||||
if currentFrame != nil {
|
if currentFrame != nil {
|
||||||
configure(image: Image(platformImage: currentFrame!))
|
configure(image: currentFrame!)
|
||||||
.onAppear {
|
.onAppear {
|
||||||
self.imagePlayer?.startPlaying()
|
self.imagePlayer?.startPlaying()
|
||||||
}
|
}
|
||||||
|
@ -84,16 +84,16 @@ public struct WebImage : View {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
configure(image: Image(platformImage: imageManager.image!))
|
configure(image: imageManager.image!)
|
||||||
.onReceive(imageManager.$image) { image in
|
.onReceive(imageManager.$image) { image in
|
||||||
self.setupPlayer(image: image)
|
self.setupPlayer(image: image)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if currentFrame != nil {
|
if currentFrame != nil {
|
||||||
configure(image: Image(platformImage: currentFrame!))
|
configure(image: currentFrame!)
|
||||||
} else {
|
} else {
|
||||||
configure(image: Image(platformImage: imageManager.image!))
|
configure(image: imageManager.image!)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -122,10 +122,47 @@ public struct WebImage : View {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func configure(image: Image) -> some View {
|
/// Configure the platform image into the SwiftUI rendering image
|
||||||
|
func configure(image: PlatformImage) -> some View {
|
||||||
|
var image = image
|
||||||
|
// Actual rendering SwiftUI image
|
||||||
|
let result: Image
|
||||||
|
// NSImage works well with SwiftUI, include Animated and Vector Image
|
||||||
|
#if os(macOS)
|
||||||
|
result = Image(nsImage: image)
|
||||||
|
#else
|
||||||
|
// Fix the SwiftUI.Image rendering issue when use UIImage based, the `.aspectRatio` does not works. SwiftUI's Bug :)
|
||||||
|
// See issue #101
|
||||||
|
// Case 1: UIAnimatedImage, grab poster image
|
||||||
|
if image.sd_isAnimated {
|
||||||
|
// check images property
|
||||||
|
if let images = image.images, images.count > 0 {
|
||||||
|
image = images[0]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Case 2: Vector Image, draw bitmap image
|
||||||
|
else if image.sd_isVector {
|
||||||
|
// ensure CGImage is nil
|
||||||
|
if image.cgImage == nil {
|
||||||
|
// draw vector into bitmap with the screen scale (behavior like AppKit)
|
||||||
|
UIGraphicsBeginImageContextWithOptions(image.size, false, UIScreen.main.scale)
|
||||||
|
image.draw(at: .zero)
|
||||||
|
image = UIGraphicsGetImageFromCurrentImageContext() ?? .empty
|
||||||
|
UIGraphicsEndImageContext()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// If we have CGImage, use CGImage based API, else use UIImage based API
|
||||||
|
if let cgImage = image.cgImage {
|
||||||
|
let orientation = image.imageOrientation.toSwiftUI
|
||||||
|
result = Image(decorative: cgImage, scale: image.scale, orientation: orientation)
|
||||||
|
} else {
|
||||||
|
result = Image(uiImage: image)
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Should not use `EmptyView`, which does not respect to the container's frame modifier
|
// Should not use `EmptyView`, which does not respect to the container's frame modifier
|
||||||
// Using a empty image instead for better compatible
|
// Using a empty image instead for better compatible
|
||||||
configurations.reduce(image) { (previous, configuration) in
|
return configurations.reduce(result) { (previous, configuration) in
|
||||||
configuration(previous)
|
configuration(previous)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -136,12 +173,12 @@ public struct WebImage : View {
|
||||||
if let placeholder = placeholder {
|
if let placeholder = placeholder {
|
||||||
// If use `.delayPlaceholder`, the placeholder is applied after loading failed, hide during loading :)
|
// If use `.delayPlaceholder`, the placeholder is applied after loading failed, hide during loading :)
|
||||||
if imageManager.options.contains(.delayPlaceholder) && imageManager.isLoading {
|
if imageManager.options.contains(.delayPlaceholder) && imageManager.isLoading {
|
||||||
return AnyView(configure(image: Image.empty))
|
return AnyView(configure(image: .empty))
|
||||||
} else {
|
} else {
|
||||||
return placeholder
|
return placeholder
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return AnyView(configure(image: Image.empty))
|
return AnyView(configure(image: .empty))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -260,7 +297,9 @@ extension WebImage {
|
||||||
/// - Parameter image: A Image view that describes the placeholder.
|
/// - Parameter image: A Image view that describes the placeholder.
|
||||||
public func placeholder(_ image: Image) -> WebImage {
|
public func placeholder(_ image: Image) -> WebImage {
|
||||||
return placeholder {
|
return placeholder {
|
||||||
configure(image: image)
|
configurations.reduce(image) { (previous, configuration) in
|
||||||
|
configuration(previous)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue