如何让CIAttributedTextGenerator滤镜实现文本自动换行?
Core Image实现文本自动换行的可行方案
首先明确:Core Image内置的CIAttributedTextGenerator滤镜不支持自动换行,它仅能渲染单行或已手动拆分好的多行文本,你尝试的几种方法走不通的原因如下:
CIClamp的作用是限制像素颜色通道的取值范围(比如把RGB值约束在0-1之间),并非用于约束文本绘制区域,传入CIVector(cgRect:)属于参数误用,输出nil是预期结果。- 内置滤镜的实现是封装好的,确实无法通过
CIFilterShape约束绘制范围,这个参数仅对自定义CIKernel的调用生效。 - 内置滤镜的
CIKernel是私有实现,无法提取复用,所以这条路完全走不通。
如果不想手动计算换行,推荐用以下替代方案,和UILabel的换行逻辑完全一致:
方案:先通过UIKit/CoreText生成换行后的文本图像,再转成CIImage叠加
先用UILabel(或CoreText的CTFramesetter)处理文本自动换行,渲染成CGImage后再转为CIImage,最后叠加到原图上。示例代码如下:
func generateWrappedTextCIImage(text: String, maxWidth: CGFloat, attributes: [NSAttributedString.Key: Any]) -> CIImage? { // 用UILabel处理自动换行 let label = UILabel() label.attributedText = NSAttributedString(string: text, attributes: attributes) label.numberOfLines = 0 label.preferredMaxLayoutWidth = maxWidth label.sizeToFit() // 渲染label为CGImage UIGraphicsBeginImageContextWithOptions(label.bounds.size, false, UIScreen.main.scale) defer { UIGraphicsEndImageContext() } label.layer.render(in: UIGraphicsGetCurrentContext()!) guard let cgImage = UIGraphicsGetImageFromCurrentImageContext() else { return nil } // 转为CIImage返回 return CIImage(cgImage: cgImage) }
之后你可以用CISourceOverCompositing滤镜把生成的文本CIImage叠加到原图上。
补充
如果一定要用纯Core Image滤镜链,只能先手动拆分文本为多行,再用多个CIAttributedTextGenerator分别渲染每行,最后拼接成完整的文本图像,但这种方式反而比用UIKit更繁琐,完全没必要。
内容的提问来源于stack exchange,提问作者jefflovejapan
相关产品推荐
相关产品推荐

