Skip to content

Commit

Permalink
Support for UIImage(data:) and Image(uiImage:) for displaying images …
Browse files Browse the repository at this point in the history
…from Data
  • Loading branch information
aabewhite committed Jul 9, 2024
1 parent 823e429 commit 1d224da
Show file tree
Hide file tree
Showing 3 changed files with 305 additions and 24 deletions.
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -506,6 +506,7 @@ Support levels:
<li><code>init(_ name: String, bundle: Bundle? = Bundle.main)</code></li>
<li><code>init(_ name: String, bundle: Bundle? = Bundle.main, label: Text)</code></li>
<li><code>init(systemName: String)</code></li>
<li><code>init(uiImage: UIImage)</code></li>
<li>See <a href="#images">Images</a></li>
</ul>
</details>
Expand Down Expand Up @@ -1523,6 +1524,19 @@ Support levels:
</details>
</td>
</tr>
<tr>
<td>🟠</td>
<td>
<details>
<summary><code>UIImage</code></summary>
<ul>
<li><code>init?(contentsOfFile: String)</code></li>
<li><code>init?(data: Data)</code></li>
<li><code>init?(data: Data, scale: CGFloat)</code></li>
</ul>
</details>
</td>
</tr>
<tr>
<td>✅</td>
<td><code>UIImpactFeedbackGenerator</code></td>
Expand Down
48 changes: 25 additions & 23 deletions Sources/SkipUI/SkipUI/Components/Image.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

import Foundation
#if SKIP
import android.graphics.Bitmap
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.wrapContentSize
Expand All @@ -23,23 +24,25 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.Rect
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.asAndroidPath
import androidx.compose.ui.graphics.asComposePath
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.graphics.Path
import androidx.compose.ui.graphics.PathFillType
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.graphics.StrokeCap
import androidx.compose.ui.graphics.StrokeJoin
import androidx.compose.ui.graphics.asAndroidPath
import androidx.compose.ui.graphics.asComposePath
import androidx.compose.ui.graphics.asImageBitmap
import androidx.compose.ui.graphics.painter.BitmapPainter
import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.graphics.vector.PathBuilder
import androidx.compose.ui.graphics.vector.PathParser
import androidx.compose.ui.graphics.vector.VectorPath
import androidx.compose.ui.graphics.vector.toPath
import androidx.compose.ui.graphics.vector.rememberVectorPainter
import androidx.compose.ui.graphics.PathFillType
import androidx.compose.ui.graphics.StrokeCap
import androidx.compose.ui.graphics.StrokeJoin
import androidx.compose.ui.graphics.vector.PathBuilder
import androidx.compose.ui.graphics.vector.path
import androidx.compose.ui.graphics.vector.group
import androidx.compose.ui.graphics.vector.path
import androidx.compose.ui.graphics.vector.rememberVectorPainter
import androidx.compose.ui.graphics.vector.toPath
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.layout.ScaleFactor
import androidx.compose.ui.platform.LocalContext
Expand All @@ -64,6 +67,7 @@ public struct Image : View, Equatable {
case decorative(name: String, bundle: Bundle?)
case system(systemName: String)
#if SKIP
case bitmap(bitmap: Bitmap, scale: CGFloat)
case painter(painter: Painter, scale: CGFloat)
#endif
}
Expand All @@ -85,6 +89,10 @@ public struct Image : View, Equatable {
}

#if SKIP
public init(uiImage: UIImage) {
self.image = .bitmap(bitmap: uiImage.bitmap!, scale: uiImage.scale)
}

public init(painter: Painter, scale: CGFloat) {
self.image = .painter(painter: painter, scale: scale)
}
Expand All @@ -96,6 +104,8 @@ public struct Image : View, Equatable {
// Put given modifiers on the containing Box so that the image can scale itself without affecting them
Box(modifier: context.modifier, contentAlignment: androidx.compose.ui.Alignment.Center) {
switch image {
case .bitmap(let bitmap, let scale):
ComposeBitmap(bitmap: bitmap, scale: scale, aspectRatio: aspect?.0, contentMode: aspect?.1)
case .painter(let painter, let scale):
ComposePainter(painter: painter, scale: scale, aspectRatio: aspect?.0, contentMode: aspect?.1)
case .system(let systemName):
Expand Down Expand Up @@ -297,6 +307,12 @@ public struct Image : View, Equatable {
}
}

@Composable private func ComposeBitmap(bitmap: Bitmap, scale: CGFloat, aspectRatio: Double?, contentMode: ContentMode?) {
let imageBitmap = bitmap.asImageBitmap()
let painter = BitmapPainter(imageBitmap)
ComposePainter(painter: painter, scale: scale, aspectRatio: aspectRatio, contentMode: contentMode)
}

@Composable private func ComposePainter(painter: Painter, scale: CGFloat = 1.0, colorFilter: ColorFilter? = nil, aspectRatio: Double?, contentMode: ContentMode?) {
switch resizingMode {
case .stretch:
Expand Down Expand Up @@ -1271,20 +1287,6 @@ extension Image {
public init(decorative cgImage: CGImage, scale: CGFloat, orientation: Image.Orientation = .up) { fatalError() }
}

#if canImport(UIKit)
import class UIKit.UIImage

@available(iOS 13.0, tvOS 13.0, watchOS 6.0, *)
@available(macOS, unavailable)
extension Image {

/// Creates a SkipUI image from a UIKit image instance.
/// - Parameter uiImage: The UIKit image to wrap with a SkipUI ``Image``
/// instance.
public init(uiImage: UIImage) { fatalError() }
}
#endif

@available(iOS 16.0, macOS 13.0, tvOS 16.0, watchOS 9.0, *)
extension Image {

Expand Down
Loading

0 comments on commit 1d224da

Please sign in to comment.