Skip to content

Commit 42c5806

Browse files
committed
feat: add Image Serialization Plugin
1 parent 225ea84 commit 42c5806

File tree

1 file changed

+99
-0
lines changed

1 file changed

+99
-0
lines changed
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
#if canImport(SwiftUI)
2+
import Foundation
3+
import ImageSerializationPlugin
4+
5+
#if canImport(UIKit)
6+
import UIKit
7+
#elseif canImport(AppKit)
8+
import AppKit
9+
#endif
10+
11+
/// A class responsible for encoding and decoding images using various image serialization plugins.
12+
///
13+
/// The `ImageSerializer` class leverages plugins that conform to the `ImageSerialization` protocol to encode and decode images in different formats.
14+
/// It automatically retrieves all available image serialization plugins from the `PluginRegistry` and uses them based on the specified `ImageSerializationFormat`.
15+
/// If no plugin is found for the requested format, it defaults to using PNG encoding/decoding.
16+
public class ImageSerializer {
17+
18+
/// A collection of plugins that conform to the `ImageSerialization` protocol.
19+
let plugins: [ImageSerialization]
20+
21+
public init() {
22+
self.plugins = PluginRegistry.allPlugins()
23+
}
24+
25+
// TODO: async throws will be added later
26+
/// Encodes a given image into the specified image format using the appropriate plugin.
27+
///
28+
/// This method attempts to encode the provided `SnapImage` into the desired format using the first plugin that supports the specified `ImageSerializationFormat`.
29+
/// If no plugin is found for the format, it defaults to encoding the image as PNG.
30+
///
31+
/// - Parameters:
32+
/// - image: The `SnapImage` to encode.
33+
/// - imageFormat: The format in which to encode the image.
34+
/// - Returns: The encoded image data, or `nil` if encoding fails.
35+
public func encodeImage(_ image: SnapImage, imageFormat: ImageSerializationFormat) /*async throws*/ -> Data? {
36+
for plugin in self.plugins {
37+
if type(of: plugin).imageFormat == imageFormat {
38+
return plugin.encodeImage(image)
39+
}
40+
}
41+
// Default to PNG
42+
return encodePNG(image)
43+
}
44+
45+
// TODO: async throws will be added later
46+
/// Decodes image data into a `SnapImage` using the appropriate plugin based on the specified image format.
47+
///
48+
/// This method attempts to decode the provided data into a `SnapImage` using the first plugin that supports the specified `ImageSerializationFormat`.
49+
/// If no plugin is found for the format, it defaults to decoding the data as PNG.
50+
///
51+
/// - Parameters:
52+
/// - data: The image data to decode.
53+
/// - imageFormat: The format in which the image data is encoded.
54+
/// - Returns: The decoded `SnapImage`, or `nil` if decoding fails.
55+
public func decodeImage(_ data: Data, imageFormat: ImageSerializationFormat) /*async throws*/ -> SnapImage? {
56+
for plugin in self.plugins {
57+
if type(of: plugin).imageFormat == imageFormat {
58+
return plugin.decodeImage(data)
59+
}
60+
}
61+
// Default to PNG
62+
return decodePNG(data)
63+
}
64+
65+
// MARK: - Actual default Image Serializer
66+
67+
/// Encodes a `SnapImage` as PNG data.
68+
///
69+
/// This method provides a default implementation for encoding images as PNG. It is used as a fallback if no suitable plugin is found for the requested format.
70+
///
71+
/// - Parameter image: The `SnapImage` to encode.
72+
/// - Returns: The encoded PNG data, or `nil` if encoding fails.
73+
private func encodePNG(_ image: SnapImage) -> Data? {
74+
#if canImport(UIKit)
75+
return image.pngData()
76+
#elseif canImport(AppKit)
77+
guard let cgImage = image.cgImage(forProposedRect: nil, context: nil, hints: nil) else {
78+
return nil
79+
}
80+
let bitmapRep = NSBitmapImageRep(cgImage: cgImage)
81+
return bitmapRep.representation(using: .png, properties: [:])
82+
#endif
83+
}
84+
85+
/// Decodes PNG data into a `SnapImage`.
86+
///
87+
/// This method provides a default implementation for decoding PNG data into a `SnapImage`. It is used as a fallback if no suitable plugin is found for the requested format.
88+
///
89+
/// - Parameter data: The PNG data to decode.
90+
/// - Returns: The decoded `SnapImage`, or `nil` if decoding fails.
91+
private func decodePNG(_ data: Data) -> SnapImage? {
92+
#if canImport(UIKit)
93+
return UIImage(data: data)
94+
#elseif canImport(AppKit)
95+
return NSImage(data: data)
96+
#endif
97+
}
98+
}
99+
#endif

0 commit comments

Comments
 (0)