如何仅截取UIBezierPath绘制内容生成图像而非整个视图?
解决手绘内容裁剪到有效区域的问题
嘿,我明白你遇到的麻烦了——直接用单条路径的bounds创建上下文导致空白,核心问题是坐标系不匹配,而且你可能有多条路径需要合并计算整体有效区域。下面给你一步步的解决方案:
问题根源
你用signPath.bounds创建图像上下文时,这个bounds是路径自身的局部坐标系(原点是路径的左上角),但你的手绘路径是基于300x300视图的全局坐标系绘制的。直接在新上下文里绘制这些路径,它们的位置会超出上下文范围(甚至在负坐标区域),所以你看到的是空白。
另外,如果你有多个手绘路径(self.pathArray),只取单条路径的bounds也会漏掉其他路径的区域,得先计算所有路径的整体边界。
解决方案代码
替换你原来的生成图像代码,用下面的逻辑:
// 1. 计算所有手绘路径的整体边界 CGRect totalBounds = CGRectZero; for (UIBezierPath *path in self.pathArray) { if (CGRectEqualToRect(totalBounds, CGRectZero)) { totalBounds = path.bounds; } else { totalBounds = CGRectUnion(totalBounds, path.bounds); } } // 处理没有绘制内容的情况 if (CGRectEqualToRect(totalBounds, CGRectZero)) { // 可以返回空图像或者默认图像 return nil; } // 2. 创建对应尺寸的图像上下文(用带缩放因子的方法避免模糊) UIGraphicsBeginImageContextWithOptions(totalBounds.size, NO, [UIScreen mainScreen].scale); CGContextRef context = UIGraphicsGetCurrentContext(); // 3. 平移上下文,让路径的左上角对齐上下文的原点(关键!) CGContextTranslateCTM(context, -totalBounds.origin.x, -totalBounds.origin.y); // 4. 绘制所有路径 [self.lineColor setStroke]; for (UIBezierPath *path in self.pathArray) { [path stroke]; } // 5. 获取图像并结束上下文 UIImage *croppedImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext();
关键步骤解释
- 合并所有路径的bounds:用
CGRectUnion把每条路径的边界合并,得到包含所有手绘内容的最小矩形。 - 坐标系平移:通过
CGContextTranslateCTM把上下文的原点偏移到路径整体边界的左上角,这样原来在视图坐标系里的路径,就能完整显示在新的小尺寸上下文里。 - 使用
UIGraphicsBeginImageContextWithOptions:第三个参数传入屏幕缩放因子,保证生成的图像不会模糊。
这样生成的图像就只会包含有手绘线条的区域,不管你画的是50x50还是其他尺寸,都能精准裁剪啦!
内容的提问来源于stack exchange,提问作者Maulik
相关产品推荐
相关产品推荐

