Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions SpreadPaper/Services/NSImage+PixelSize.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import AppKit

extension NSImage {
nonisolated var pixelSize: CGSize {
if let bitmapRep = representations
.compactMap({ $0 as? NSBitmapImageRep })
.max(by: { ($0.pixelsWide * $0.pixelsHigh) < ($1.pixelsWide * $1.pixelsHigh) }) {
return CGSize(width: bitmapRep.pixelsWide, height: bitmapRep.pixelsHigh)
}

if let cgImage = cgImage(forProposedRect: nil, context: nil, hints: nil) {
return CGSize(width: cgImage.width, height: cgImage.height)
}

return size
}
}
7 changes: 4 additions & 3 deletions SpreadPaper/Services/WallpaperManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -384,7 +384,8 @@ class WallpaperManager {
deviceScale: CGFloat,
screenColorSpace: CGColorSpace?
) throws -> CGImage {
var rect = CGRect(origin: .zero, size: original.size)
let imageSize = original.pixelSize
var rect = CGRect(origin: .zero, size: imageSize)
guard let cgImage = original.cgImage(forProposedRect: &rect, context: nil, hints: nil) else {
throw WallpaperError.imageConversionFailed
}
Expand All @@ -409,8 +410,8 @@ class WallpaperManager {

let realOffsetX_Px = (offset.width / previewScale) * deviceScale
let realOffsetY_Px = (offset.height / previewScale) * deviceScale
let drawnImgWidthPx = original.size.width * imageScale * deviceScale
let drawnImgHeightPx = original.size.height * imageScale * deviceScale
let drawnImgWidthPx = imageSize.width * imageScale * deviceScale
let drawnImgHeightPx = imageSize.height * imageScale * deviceScale
let totalCanvasWidthPx = totalCanvas.width * deviceScale
let totalCanvasHeightPx = totalCanvas.height * deviceScale
let centeringX_Px = (totalCanvasWidthPx - drawnImgWidthPx) / 2.0
Expand Down
7 changes: 4 additions & 3 deletions SpreadPaper/Views/EditorCanvasView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,14 @@ struct EditorCanvasView: View {
ZStack {
// Image layer
if let img = selectedImage {
let pixelSize = img.pixelSize
Image(nsImage: img)
.resizable()
.aspectRatio(contentMode: .fill)
.scaleEffect(x: isFlipped ? -1 : 1, y: 1)
.frame(
width: img.size.width * previewScale * imageScale,
height: img.size.height * previewScale * imageScale
width: pixelSize.width * previewScale * imageScale,
height: pixelSize.height * previewScale * imageScale
)
.offset(imageOffset)
.opacity(isDragging ? 0.7 : 1.0)
Expand All @@ -47,7 +48,7 @@ struct EditorCanvasView: View {
)
imageOffset = calculateSnapping(
raw: raw,
imgSize: img.size,
imgSize: pixelSize,
canvasSize: manager.totalCanvas.size,
previewScale: previewScale,
zoomScale: imageScale
Expand Down
10 changes: 6 additions & 4 deletions SpreadPaper/Views/EditorView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -431,7 +431,7 @@ struct EditorView: View {

private var staticSubtitle: String {
guard let img = loadedImages.first else { return "Choose image…" }
return "\(Int(img.size.width))×\(Int(img.size.height))"
return dimensions(for: img)
}

private func appearanceImageRow(index: Int, label: String) -> some View {
Expand Down Expand Up @@ -499,7 +499,8 @@ struct EditorView: View {
}

private func dimensions(for image: NSImage) -> String {
"\(Int(image.size.width))×\(Int(image.size.height))"
let pixelSize = image.pixelSize
return "\(Int(pixelSize.width))×\(Int(pixelSize.height))"
}

// MARK: - Zoom
Expand Down Expand Up @@ -646,8 +647,9 @@ struct EditorView: View {
guard let image = currentImage else { return }
let canvas = manager.totalCanvas
guard canvas.width > 0, canvas.height > 0 else { return }
let widthRatio = canvas.width / image.size.width
let heightRatio = canvas.height / image.size.height
let pixelSize = image.pixelSize
let widthRatio = canvas.width / pixelSize.width
let heightRatio = canvas.height / pixelSize.height
withAnimation(.spring()) {
guard selectedVariantIndex < variants.count else { return }
variants[selectedVariantIndex].scale = max(widthRatio, heightRatio)
Expand Down
10 changes: 5 additions & 5 deletions SpreadPaper/Views/GalleryView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -699,17 +699,17 @@ private struct ThumbnailResult: @unchecked Sendable {
let image: NSImage
}

@Sendable
private func renderThumbnails(jobs: [ThumbnailJob]) -> [ThumbnailResult] {
nonisolated private func renderThumbnails(jobs: [ThumbnailJob]) -> [ThumbnailResult] {
var out: [ThumbnailResult] = []
out.reserveCapacity(jobs.count)
for job in jobs {
guard let image = NSImage(contentsOf: job.imageURL) else { continue }
let maxDim: CGFloat = 480
let ratio = min(maxDim / image.size.width, maxDim / image.size.height, 1.0)
let pixelSize = image.pixelSize
let ratio = min(maxDim / pixelSize.width, maxDim / pixelSize.height, 1.0)
let newSize = NSSize(
width: image.size.width * ratio,
height: image.size.height * ratio
width: pixelSize.width * ratio,
height: pixelSize.height * ratio
)
let thumb = NSImage(size: newSize)
thumb.lockFocus()
Expand Down