Skip to content

WICompress 2.0.0

Choose a tag to compare

@Weixi779 Weixi779 released this 02 Aug 13:00
· 1 commit to main since this release

WICompress 2.0.0

WICompress 2.0 is a deliberate breaking release built around two explicit workflows:

  • Process — choose the crop, resizing, quality, and output requirements.
  • Target — declare a hard byte ceiling and let WICompress search quality and dimensions.

Both workflows accept encoded Data or file URLs, remain UIKit/AppKit-free, and return one typed WIResult.

Highlights

A clearer compression API

let processed = try await WICompressor.process(imageData)

let target = try WICompressionTarget(maxBytes: 500_000)
let constrained = try await WICompressor.compress(imageData, to: target)

Every successful Target operation guarantees that result.byteCount <= target.maxBytes. Process and Target share the same output model and expose encoded data, format, pixel size, and byte count through WIResult.

Synchronous and cancellable asynchronous terminals

Every Data and file Process/Target terminal now has synchronous and Swift 6.2 @concurrent asynchronous overloads.

Async work leaves the caller's actor and observes cancellation between pipeline stages and Target search attempts. Cancellation remains the standard CancellationError; image-processing failures remain WICompressError.

Explicit image operations

2.0 introduces typed models for:

  • extensible resizing through WIImageResizing
  • built-in algorithms, including the new default WIImageResize.lubanV2
  • aspect-ratio crop with normalized anchors
  • JPEG, PNG, HEIC, source-preserving, and alpha-aware output
  • selective metadata preservation and removal
  • explicit color-space preservation or conversion

JPEG conversion never silently discards transparency. Callers must choose an opaque background when flattening an alpha source.

WIImageIO as an independent product

The package now publishes WIImageIO for applications that need typed static-image primitives without the compression workflow:

import UniformTypeIdentifiers
import WIImageIO

let reader = try ImageReader(imageData)
let descriptor = reader.descriptor

let encoded = try reader
    .thumbnail(options: .init(maximumPixelSize: 1_200))
    .encode(
        as: .jpeg,
        options: .init(compressionQuality: 0.75)
    )

WIImageIO provides synchronous inspection, decode, thumbnail, transcode, and encode operations while hiding CGImageSource, CGImageDestination, property dictionaries, and finalization mechanics.

Documentation, examples, and measurement

This release also includes:

  • a rebuilt SwiftUI Process/Target example with cancellation
  • bilingual DocC and architecture documentation
  • a detailed 1.x migration guide
  • a reproducible Target compression benchmark with fixed corpora, hard-limit validation, quality metrics, and environment fingerprints

Breaking Changes and Migration

WICompress 2.0 does not provide a 1.x compatibility facade. Applications that cannot migrate yet should remain on 1.4.0.

The most important changes are:

  • High-level terminals move from WICompress to WICompressor.
  • WICompressOptions and the unified policy surface are replaced by WIImageProcess and WICompressionTarget.
  • Process and Target now return WIResult; use result.data when only encoded bytes are needed.
  • WICompressionOutput becomes the shared WIImageOutput.
  • WICompressionResult, WIImageFormat, and WISize are replaced by WIResult, ImageFormat, WIPixelSize, and WIAspectRatio.
  • The default Process resizing algorithm is Luban 2. The corrected Luban 1 behavior remains available as WIImageResize.luban.
  • Target dimensions are now soft starting constraints for byte-budget search. The old hard fill, exactCanvas, placement, and candidate-preference contracts have no direct replacement.
  • Rendered Target output now defaults to sRGB instead of preserving the source color space.
  • In an async context, Swift selects the new same-name async overload. Existing calls must add await, or deliberately invoke a synchronous overload outside that context.

Read the complete 1.x migration guide before upgrading an existing integration.

Requirements

  • Swift 6.2
  • Xcode 26 or later
  • iOS 14+
  • macOS 11+
  • Mac Catalyst 14+
  • tvOS 14+
  • watchOS 7+
  • visionOS 1+

Install with Swift Package Manager:

.package(
    url: "https://github.com/Weixi779/WICompress.git",
    from: "2.0.0"
)

The package publishes the WICompress and WIImageIO library products.

Links