【问题标题】:How to save image with added UIBeizerPath?如何使用添加的 UIBezierPath 保存图像?
【发布时间】:2016-01-25 09:59:09
【问题描述】:

我正试图用我愚蠢的绘图保存图像,但是当我保存图像时,只有原始图像被保存。

我预期的图像是这样的:

这是我的图像保存代码:

UIImageWriteToSavedPhotosAlbum(_imgShow.image,
                                   nil,
                                   nil,
                                   nil);

这是我的 UIImageView 自定义类:

    -(void)awakeFromNib
{
//    drawingView=[[UIView alloc]initWithFrame:self.bounds];
//    drawingView.backgroundColor=[UIColor clearColor];
//    [self addSubview:drawingView];
    clearBeizer=[[NSMutableArray alloc]init];
    [self updateMask];
}
-(void)updateMask
{
    CALayer *maskLayer=[CALayer layer];
    maskLayer.geometryFlipped=YES;
    maskLayer.contents=(id)self.image.CGImage;
    switch (self.contentMode)
    {
        case UIViewContentModeScaleToFill:
            maskLayer.contentsGravity = kCAGravityResize;
            break;
        case UIViewContentModeScaleAspectFit:
            maskLayer.contentsGravity = kCAGravityResizeAspect;
            break;
        case UIViewContentModeScaleAspectFill:
            maskLayer.contentsGravity = kCAGravityResizeAspectFill;
            break;
        case UIViewContentModeCenter:
            maskLayer.contentsGravity = kCAGravityCenter;
            break;
        case UIViewContentModeTop:
            maskLayer.contentsGravity = kCAGravityTop;
            break;
        case UIViewContentModeBottom:
            maskLayer.contentsGravity = kCAGravityBottom;
            break;
        case UIViewContentModeLeft:
            maskLayer.contentsGravity = kCAGravityLeft;
            break;
        case UIViewContentModeRight:
            maskLayer.contentsGravity = kCAGravityRight;
            break;
        case UIViewContentModeTopLeft:
            maskLayer.contentsGravity = kCAGravityTopLeft;
            break;
        case UIViewContentModeTopRight:
            maskLayer.contentsGravity = kCAGravityTopRight;
            break;
        case UIViewContentModeBottomLeft:
            maskLayer.contentsGravity = kCAGravityBottomLeft;
            break;
        case UIViewContentModeBottomRight:
            maskLayer.contentsGravity = kCAGravityBottomRight;
            break;
        default:
            break;

    }
    maskLayer.frame=self.bounds;
//    drawingView.layer.mask=maskLayer;
    self.layer.mask=maskLayer;

}
-(void)setImage:(UIImage *)image
{
    [super setImage:image];
    [self updateMask];
}
-(void)layoutSubviews
{
    [super layoutSubviews];
//    drawingView.frame=self.bounds;
//    drawingView.layer.mask.frame=drawingView.bounds;
    self.frame=self.bounds;
    self.layer.mask.frame=self.bounds;
}
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    UITouch *touch = [[event allTouches] anyObject];
    startingPoint = [touch locationInView:self];

}
-(void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    UITouch *touch = [[event allTouches] anyObject];
    touchPoint = [touch locationInView:self];

    if (!CGPointEqualToPoint(startingPoint, CGPointZero))
    {
        UIBezierPath *path = [UIBezierPath bezierPath];
        [path moveToPoint:CGPointMake(touchPoint.x,touchPoint.y)];
        [path addLineToPoint:CGPointMake(startingPoint.x,startingPoint.y)];

        CAShapeLayer *shapeLayer = [CAShapeLayer layer];
        shapeLayer.path = [path CGPath];
        shapeLayer.strokeColor = [[UIColor blueColor] CGColor];
        if([UIDevice currentDevice].userInterfaceIdiom ==UIUserInterfaceIdiomPad)
        {
            shapeLayer.lineWidth = 7.0;
        }
        else
        {
            shapeLayer.lineWidth = 5.0;

        }

        shapeLayer.fillColor = [[UIColor redColor] CGColor];
        [self.layer addSublayer:shapeLayer];
        [clearBeizer addObject:shapeLayer];
    }
    startingPoint=touchPoint;

    //    [arrLayer addObject:shapeLayer];
    NSLog(@"Touch moving point =x : %f Touch moving point =y : %f", touchPoint.x, touchPoint.y);
}

这是我的自定义类。

【问题讨论】:

  • 据我了解,您使用的是自定义UIImageView 子类,它操纵图像的渲染,而不是图像的数据本身。显示您的自定义子类;确保 image 的 getter 正在返回修改后的数据。
  • @JanGreve 好的兄弟等一下

标签: ios objective-c uiimageview calayer


【解决方案1】:

您只是更改图像的渲染,而不是图像本身的数据,然后写入该数据并期望它反映您的视图渲染。

您可以使用snapshotViewAfterScreenUpdates: 和来自this question 的结果来管理您实际想要归档的内容。

【讨论】:

    【解决方案2】:

    您需要做的是对您的窗口进行屏幕截图,一旦您获得屏幕截图,您将获得该图像。但是您将需要根据您的要求进行更改。当您截取窗口的屏幕截图时,您还将获得导航栏和工具栏。因此,您需要拍摄一张屏幕截图,然后再拍摄第二张屏幕截图以获取没有导航栏和工具栏的图像。 用于保存图像 pl。访问以下网址:

    这就是我所做的:

    - (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
       UITouch *touch = [touches anyObject];
       endPoint = [touch locationInView:self.IBImgView];
    
       SPUserResizableView *spResizable = [[SPUserResizableView alloc] initWithFrame:CGRectMake(0,0,100,200)];
    
       UIView *contentView = [[UIView alloc] initWithFrame:spResizable.frame];
       [contentView setBackgroundColor:[UIColor clearColor]];
    
       CAShapeLayer *lines = [CAShapeLayer layer];
       lines.path = self.drawPath.CGPath;
       lines.lineCap = kCALineCapSquare;
       [self.drawPath removeAllPoints];
       lines.bounds = CGPathGetBoundingBox(lines.path);
       lines.strokeColor = [UIColor blackColor].CGColor;
       lines.fillColor = [UIColor blackColor].CGColor; /*if you just want lines*/
       lines.lineWidth = 3;
       lines.position = CGPointMake(spResizable.frame.size.width/2.0f-10, spResizable.frame.size.height/2.0f-10);
       lines.anchorPoint = CGPointMake(.5, .5);
       [contentView.layer addSublayer:lines];
    
       spResizable.contentView = contentView;
    
       [spResizable hideEditingHandles];    
       [self.view addSubview:spResizable];
       [self.view setNeedsDisplay];
    }
    

    保存图片

    - (IBAction)btnSaveTapped:(id)sender {
    [UIImagePNGRepresentation(self.IBImgView.image) writeToFile:[self saveDataInDirectory:@"Img1"] atomically:YES];
    }
    
    
    - (NSString *) saveDataInDirectory:(NSString *)strFileName {
    NSString *strDocPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
    NSString *strDirName;
    NSFileManager *fileManager = [[NSFileManager alloc] init];
        // Original Image
        strDirName = [strDocPath stringByAppendingPathComponent:kDocOriginalImg];
        if (![fileManager fileExistsAtPath:strDirName]) {
            [fileManager createDirectoryAtPath:strDirName withIntermediateDirectories:NO attributes:nil error:nil];
        }
        strDirName = [[strDirName stringByAppendingPathComponent:strFileName] stringByAppendingPathExtension:@"png"];
    return strDirName;
    

    }

    但请确保您的 spResizable 视图位于 UIImageView 上方。

    Taking ScreenShot Programmatically

    如果你想用相同的路径重绘图像,然后删除当前路径并绘制新路径,你可以使用SPUserResizableView。但为此,您需要将数据存储在字典中以进行编辑。

    希望这将有助于解决您的问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多