VariableBlurImageView logo

VariableBlurImageView

为 UIKit、AppKit 和 SwiftUI 中的图像添加可变模糊效果。可在使用 Metal 的 Apple 平台上运行。

A hill with a horizontal variable blur from the leading edge to the middle

左侧图像具有从前缘到中间的水平可变模糊。右侧图像具有从顶缘到中间的垂直可变模糊。

SwiftUI、UIKit 和 AppKit 的演示应用可在 Documentation 下找到。

目录

可能的种类

垂直 水平 两点之间 渐变 多种模糊
Vertical progressive blur Horizontal progressive blur Progressive blur between two points Progressive blur from the lightness in a gradient image Multiple progressive blurs

要求

安装

要在 SwiftPM 项目中使用此软件包,您需要将其设置为软件包依赖项

// swift-tools-version:5.9
import PackageDescription

let package = Package(
  name: "MyPackage",
  dependencies: [
    .package(
      url: "https://github.com/Eskils/VariableBlurImageView", 
      .upToNextMinor(from: "1.1.2") // or `.upToNextMajor
    )
  ],
  targets: [
    .target(
      name: "MyTarget",
      dependencies: [
        .product(name: "VariableBlurImageView", package: "VariableBlurImageView")
      ]
    )
  ]
)

用法

此框架为 UIImageView 和 NSImageView 提供了子类,以及 SwiftUI 视图和修饰符,用于将可变模糊应用于图像。

还有一个类可用于将可变模糊应用于 CGImages。

与 UIKit 和 AppKit 一起使用

VariableBlurImageViewUIImageView / NSImageView 的子类,它异步应用所需渐进式模糊。

您需要提供图像、起始点、结束点以及它们各自的模糊半径。

示例

let imageView = VariableBlurImageView()
imageView.contentMode = .scaleAspectFill
let backgroundImage = UIImage(resource: .onboardingBackground)
imageView.verticalVariableBlur(
    image: backgroundImage, 
    startPoint: 0, 
    endPoint: backgroundImage.size.height / 4, 
    startRadius: 15, 
    endRadius: 0
)

Vertical progressive blur of an iOS app onboarding screen from the top to the middle

可用方法

/// Adds a vertical variable blur to your image.
VariableBlurImageView.verticalVariableBlur(image:startPoint:endPoint:startRadius:endRadius:)

/// Adds a horizontal variable blur to your image.
VariableBlurImageView.horizontalVariableBlur(image:startPoint:endPoint:startRadius:endRadius:)

// Adds a variable blur between two points to your image.
VariableBlurImageView.variableBlur(image:startPoint:endPoint:startRadius:endRadius:)

/// Adds a variable blur following the lightness in the provided gradient image.
VariableBlurImageView.gradientBlur(image:gradient:maxRadius:)

/// Adds multiple variable blurs
VariableBlurImageView.mutlipleBlurs(image:descriptions:)

与 SwiftUI 一起使用

Image 上的视图和视图修饰符可用于异步应用所需的渐进式模糊。

您需要提供图像、起始点、结束点以及它们各自的模糊半径。

注意: ViewModifier 仅在 iOS 16.0 和 macOS 13.0 及更高版本中可用,并且不支持图像变体(例如,深色模式图像)

示例

let backgroundImage = UIImage(resource: .onboardingBackground)

var body: some View {
    VStack {
        VerticalVariableBlurImage(
            image: backgroundImage, 
            startPoint: 0, 
            endPoint: backgroundImage.size.height / 4, 
            startRadius: 15, 
            endRadius: 0
        )
    }
}

可用视图

/// Adds a vertical variable blur to your image.
VerticalVariableBlurImage(image:startPoint:endPoint:startRadius:endRadius:)

/// Adds a horizontal variable blur to your image.
HorizontalVariableBlurImage(image:startPoint:endPoint:startRadius:endRadius:)

// Adds a variable blur between two points to your image.
VariableBlurImage(image:startPoint:endPoint:startRadius:endRadius:)

/// Adds a variable blur following the lightness in the provided gradient image.
GradientBlurImage(image:gradient:maxRadius:)

/// Adds multiple variable blurs
MultipleBlursImage(image:descriptions:)

可用图像 ViewModifier

/// Adds a vertical variable blur to your image.
Image.verticalVariableBlur(startPoint:endPoint:startRadius:endRadius:)

/// Adds a horizontal variable blur to your image.
Image.horizontalVariableBlur(startPoint:endPoint:startRadius:endRadius:)

// Adds a variable blur between two points to your image.
Image.variableBlur(startPoint:endPoint:startRadius:endRadius:)

/// Adds a variable blur following the lightness in the provided gradient image.
Image.gradientBlur(gradient:maxRadius:)

/// Adds multiple variable blurs
Image.mutlipleBlurs(descriptions:)

与 CGImages 一起使用

VariableBlurEngine 是一个用于将渐进式模糊应用于 CGImages 的对象。

您需要提供 CGImage、起始点、结束点以及它们各自的模糊半径。将返回具有可变模糊效果的新 CGImage。

示例

let variableBlurEngine = VariableBlurEngine()
let leavesImage = UIImage(resource: .leaves)
let blurredImage = variableBlurEngine.applyVerticalVariableBlur(
    toImage: leavesImage, 
    startPoint: 0, 
    endPoint: leavesImage.size.height / 4, 
    startRadius: 15, 
    endRadius: 0
)

Vertical progressive blur from the top to the middle over colorful leaves

可用方法

/// Adds a vertical variable blur to your image.
VariableBlurEngine.applyVerticalVariableBlur(image:startPoint:endPoint:startRadius:endRadius:)

/// Adds a horizontal variable blur to your image.
VariableBlurEngine.applyHorizontalVariableBlur(image:startPoint:endPoint:startRadius:endRadius:)

// Adds a variable blur between two points to your image.
VariableBlurEngine.applyVariableBlur(image:startPoint:endPoint:startRadius:endRadius:)

/// Adds a variable blur following the lightness in the provided gradient image.
VariableBlurEngine.applyGradientVariableBlur(image:gradient:maxRadius:)

/// Adds multiple variable blurs
VariableBlurEngine.applyMultipleVariableBlurs(image:descriptions:)

路线图

项目组织

此框架使用 Swift 和 Metal 编写。

VariableBlurImageView 是主要框架。
GenerateTestImages 是一个小型可执行文件,用于生成用于测试的图像。

VariableBlurImageView 的测试检查代码的当前状态是否生成与先前由 GenerateTestImages 生成的图像集相同的图像集。

当实现更改现有模糊类型的外观时,预计测试会失败。从 Xcode 运行 GenerateTestImages 将生成新图像并使测试成功。

在进行性能改进时,理想情况下测试不应失败。

实现新的模糊类型

当实现新的模糊类型时,需要提供新的测试和生成方法。

实现新的模糊类型的步骤

提供测试

通常,每种模糊类型至少编写两个测试——一个检查生成的图像是否符合预期,另一个测量性能。

可以使用 ìsEqual(inputImageName:expectedImageName:afterPerformingImageOperations:) 方法检查相似性,如下所示

func testVerticalVariableBlur() throws {
    XCTAssertTrue(
        try isEqual(
            inputImageName: inputImageName,
            expectedImageName: "\(inputImageName)-VerticalBlur...",
            afterPerformingImageOperations: { input in
                try variableBlurEngine.applyVerticalVariableBlur(
                    toImage: input,
                    startPoint: 0,
                    endPoint: CGFloat(input.height / 2),
                    startRadius: 20,
                    endRadius: 0
                )
            }
        )
    )
}

可以使用 provideInputImage(inputImageName:)measure 方法测量性能,如下所示

func testPerformanceOfVerticalVariableBlur() throws {
    let inputImage = try provideInputImage(inputImageName: inputImageName)
    measure {
        _ = try! variableBlurEngine.applyVerticalVariableBlur(
            toImage: inputImage,
            startPoint: 0,
            endPoint: CGFloat(inputImage.height / 2),
            startRadius: 20,
            endRadius: 0
        )
    }
}

生成用于测试的图像

GenerateTestImages 中的 GenerateImages.swift 文件提供了生成图像的实现。

在 OutputImage 上使用 from(image:named:performingOperations:) 方法,并将结果添加到 outputImages 数组。此数组中的条目将写入 Tests 下的 ExpectedOutputs 目录。

// Vertical blur
OutputImage
    .from(image: inputImage, named: "\(name)-Vertical...") { input in
        try variableBlurEngine.applyVerticalVariableBlur(
            toImage: input,
            startPoint: 0,
            endPoint: CGFloat(input.height / 2),
            startRadius: 20,
            endRadius: 0
        )
    }?
    .adding(to: &outputImages)

为 VariableBlurImageView 做出贡献

欢迎并鼓励贡献。随时查看项目,提交问题和代码补丁。