You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为UIImage特定区域添加带动画的颜色填充效果?

UIImage带动画的泛洪填充需求实现方案

需求背景

  • 已基于UIImageScanlineFloodfill库完成UIImage的泛洪填充功能,运行正常
  • 需要给UIImage的特定区域添加带动画的颜色填充效果,动画样式参考指定视频的呈现形式

实现思路与代码示例

1. 核心思路:拆分填充过程为逐帧渲染

泛洪填充的核心逻辑已经可用,只需把一次性完成的填充拆分成多步,每一步生成部分填充的图像帧,再将这些帧组合成动画即可。

2. 分步渲染的代码实现

方案一:修改原库支持分步填充

如果可以修改UIImageScanlineFloodfill库的代码,给填充逻辑加入分步回调,每完成一部分扫描线就生成当前帧:

let originalImage = yourImageView.image!
let fillColor = UIColor.red // 目标填充色
let startPoint = CGPoint(x: 100, y: 100) // 填充起始点
var animationFrames: [UIImage] = []

// 初始化填充工具
let floodfill = UIImageScanlineFloodfill(image: originalImage)
floodfill.fillColor = fillColor
floodfill.tolerance = 30 // 容差参数

// 自定义分步填充,每步生成一帧
let totalSteps = 30 // 动画总帧数,可调整
for step in 0..<totalSteps {
    // 调用修改后的库方法,执行单步填充并返回当前图像
    if let partialImage = floodfill.performSingleFillStep(startPoint: startPoint) {
        animationFrames.append(partialImage)
    }
}
// 添加最终完整填充的图像
if let finalImage = floodfill.fill(from: startPoint) {
    animationFrames.append(finalImage)
}

// 启动动画
yourImageView.animationImages = animationFrames
yourImageView.animationDuration = 1.2 // 动画时长
yourImageView.startAnimating()

// 动画结束后固定显示最终结果
DispatchQueue.main.asyncAfter(deadline: .now() + 1.2) {
    yourImageView.image = animationFrames.last
    yourImageView.animationImages = nil
}

方案二:预取填充区域再分批绘制

如果不想修改原库,可以先获取所有需要填充的像素点,再分批绘制到图像上生成动画帧:

let originalImage = yourImageView.image!
let fillColor = UIColor.blue
let startPoint = CGPoint(x: 150, y: 150)
var animationFrames: [UIImage] = []

// 用原库获取所有填充区域的像素点
let floodfill = UIImageScanlineFloodfill(image: originalImage)
floodfill.fillColor = fillColor
floodfill.tolerance = 30
let allFillPoints = floodfill.getAllFillPoints(from: startPoint) // 假设库有此方法获取所有点

// 拆分点为多批次
let batchCount = 25
let pointsPerBatch = allFillPoints.count / batchCount

for batchIndex in 0..<batchCount {
    let endIndex = min((batchIndex + 1) * pointsPerBatch, allFillPoints.count)
    let currentBatch = allFillPoints[0..<endIndex]
    
    // 绘制当前批次的点,生成帧
    UIGraphicsBeginImageContextWithOptions(originalImage.size, false, originalImage.scale)
    originalImage.draw(at: .zero)
    fillColor.setFill()
    currentBatch.forEach { point in
        UIRectFill(CGRect(x: point.x, y: point.y, width: 1, height: 1))
    }
    if let frameImage = UIGraphicsGetImageFromCurrentImageContext() {
        animationFrames.append(frameImage)
    }
    UIGraphicsEndImageContext()
}
// 添加最终帧
animationFrames.append(floodfill.fill(from: startPoint)!)

// 启动动画
yourImageView.animationImages = animationFrames
yourImageView.animationDuration = 1.0
yourImageView.startAnimating()

// 动画结束后保留最终图
DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
    yourImageView.image = animationFrames.last
}

3. 优化建议

  • 帧数控制在20-40之间,平衡流畅度与内存占用
  • 若填充区域较大,可降低单帧绘制的像素点数量,避免卡顿
  • 动画时长建议1-2秒,符合用户视觉预期

内容的提问来源于stack exchange,提问作者Berlin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 04:02:41