【问题标题】:iOS How to Save Image from UIView without lose quality of imageiOS如何从UIView保存图像而不损失图像质量
【发布时间】:2015-09-16 13:02:43
【问题描述】:

我有在 UIView 中绘制的图像,然后在它们上绘制线条。如何将带有画线的图像保存到 UIImage 对象中,该对象具有与开始时相同的图像大小,并且不会丢失任何图像质量?

即。我有一张尺寸为(3264、2448)的图像。 这是在 AspectFit 与图像相匹配的 UIView(大小 375、281)中绘制的, 然后在图像上画一条线。最后,如何将 UIView 中的图像保存到大小为 (3264, 2448) 的 UIImage 而不损失图像质量?

如果这不是最好的方法,请推荐一种更好的方法来完成此操作。

class DrawingView: UIImageView {

    private var pts = [CGPoint](count: 5, repeatedValue: CGPoint())
    private var ctr: uint!

    var lineWidth: CGFloat = 4.0
    var lineColor: UIColor = UIColor.darkGrayColor()

    required init(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    init(frame: CGRect, image: UIImage) {
        super.init(frame: frame)
        self.image = image
        beginDrawingView()
   }

   private func beginDrawingView() {
        userInteractionEnabled = true
   }

   override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
        ctr = 0
        if let touch = touches.first as? UITouch {
            pts[0] = touch.locationInView(self) as CGPoint
        }
    }

    override func touchesMoved(touches: Set<NSObject>, withEvent event: UIEvent) {
        if let touch = touches.first as? UITouch {
            let p: CGPoint = touch.locationInView(self)
            ctr = ctr + 1
            pts[Int(ctr)] = p
            if ctr == 4 {
                pts[3] = CGPointMake((pts[2].x + pts[4].x)/2.0, (pts[2].y + pts[4].y)/2.0); 

                UIGraphicsBeginImageContextWithOptions(bounds.size, false, 0.0)
                let context = UIGraphicsGetCurrentContext()

                image!.drawInRect(CGRect(x: 0, y: 0, width: bounds.width, height: bounds.height))
                CGContextSaveGState(context)

                CGContextSetShouldAntialias(context, true)
                CGContextSetLineCap(context, kCGLineCapRound)
                CGContextSetLineWidth(context, lineWidth)
                CGContextSetStrokeColorWithColor(context, lineColor.CGColor)

                let path = CGPathCreateMutable()
                CGPathMoveToPoint(path, nil, pts[0].x, pts[0].y)
                CGPathAddCurveToPoint(path, nil, pts[1].x, pts[1].y, pts[2].x, pts[2].y, pts[3].x, pts[3].y)

                CGContextSetBlendMode(context, kCGBlendModeNormal)

                CGContextAddPath(context, path)
                CGContextStrokePath(context)


                image = UIGraphicsGetImageFromCurrentImageContext()
                CGContextRestoreGState(context)
                UIGraphicsEndImageContext()

                pts[0] = pts[3]
                pts[1] = pts[4]
                ctr = 1
            }
        }
    }

}

【问题讨论】:

  • 图片来源在哪里?为什么不直接保存源代码?
  • 您可以将图片链接保存为字符串或尝试将图片数据保存为NSData格式。
  • 您能否在此处分享您的代码,以便在保存图像时更多地了解您在做什么。
  • @u.gen 我希望图像是背景并且可以在其上画线,然后将图像背景和画线保存到最后一张图像。所以我无法保存源代码。

标签: ios iphone image uiview uiimage


【解决方案1】:

我不确定这是否正是您要查找的内容,但如果您已经有一个UIImage 对象,您可以将其保存为Base64String。这是我用于此的一些代码(您会注意到我还对任何 JPG 图像执行压缩,因为我将字符串保存到数据库,但当然您不需要该组件,因为您不想要失去图像质量):

//Convert the image to Base64String with optional JPG compression
//
-(NSString*)convertImageToBase64String:(UIImage*)image withImageType:(NSString*)imageType
{
    NSData* data;
    if ([imageType isEqualToString:@"PNG"]) {
        data = UIImagePNGRepresentation(image);
    } else if ([imageType isEqualToString:@"JPG"] || [imageType isEqualToString:@"JPEG"]) {
        data = UIImageJPEGRepresentation(image, 0.9);
    }

return [data base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];
}

不过,如果您还没有 UIImage 对象,您可以通过如下截图来获取它:

+ (UIImage *) imageWithView:(UIView *)view
{
    UIGraphicsBeginImageContextWithOptions(view.bounds.size, view.opaque, 0.0);
    [view.layer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage * img = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return img;
}

我还没有测试最后一段代码,但我怀疑它会给你一个整个屏幕的截图,所以你需要view.bounds.size 组件来获得你正在寻找的确切区域。希望对您有所帮助!

【讨论】:

  • 谢谢,但我测试了最后一个块,它将我的视图绘制为小区域,并且在我的图像中剩余空间为浅灰色。 (我从断点看)
  • 就像我说的,我还没有测试过第二个代码块;您可能需要调整 view.bounds.size 或其他选项才能使此代码正常工作。
猜你喜欢
  • 2012-07-26
  • 2014-03-22
  • 2012-10-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-18
相关资源
最近更新 更多