Files
edgeever/apps/ios/EdgeEver/Data/Cache/ImageCompressor.swift
T
tianma-if cd4f010d8f feat(ios): add native SwiftUI client with Android UI parity
Replace the abandoned RN iOS path with a SwiftUI app (iOS 17+) that reuses
the shared TipTap editor bundle, GRDB local mirror/outbox, and Android-aligned
shell chrome for list, create, detail, and Me. Package the editor HTML in the
app resources so Markdown renders, present edit from the workspace root with a
UIKit FAB, and keep caret stable while typing.
2026-08-07 02:52:01 +08:00

47 lines
1.9 KiB
Swift

import Foundation
import ImageIO
import UniformTypeIdentifiers
enum ImageCompressor {
/// Max edge ~2560, JPEG quality ~0.82 — spirit of mobile-image-upload.ts
static func compressIfNeeded(_ data: Data, maxEdge: CGFloat = 2560, quality: CGFloat = 0.82) -> (data: Data, mimeType: String, filename: String) {
guard let source = CGImageSourceCreateWithData(data as CFData, nil),
let cgImage = CGImageSourceCreateImageAtIndex(source, 0, nil)
else {
return (data, "application/octet-stream", "upload.bin")
}
let width = CGFloat(cgImage.width)
let height = CGFloat(cgImage.height)
let longest = max(width, height)
let scale = longest > maxEdge ? maxEdge / longest : 1
let targetSize = CGSize(width: floor(width * scale), height: floor(height * scale))
let colorSpace = CGColorSpaceCreateDeviceRGB()
guard let context = CGContext(
data: nil,
width: Int(targetSize.width),
height: Int(targetSize.height),
bitsPerComponent: 8,
bytesPerRow: 0,
space: colorSpace,
bitmapInfo: CGImageAlphaInfo.premultipliedLast.rawValue
) else {
return (data, "image/jpeg", "image.jpg")
}
context.interpolationQuality = .high
context.draw(cgImage, in: CGRect(origin: .zero, size: targetSize))
guard let scaled = context.makeImage() else {
return (data, "image/jpeg", "image.jpg")
}
let mutable = NSMutableData()
guard let dest = CGImageDestinationCreateWithData(mutable, UTType.jpeg.identifier as CFString, 1, nil) else {
return (data, "image/jpeg", "image.jpg")
}
CGImageDestinationAddImage(dest, scaled, [kCGImageDestinationLossyCompressionQuality: quality] as CFDictionary)
CGImageDestinationFinalize(dest)
return (mutable as Data, "image/jpeg", "image.jpg")
}
}