获取仅绘制区域边界的UIImage - PaintView

10

我已经使用以下方式实现了绘画 / 画图:

- (void) touchesBegan: (NSSet *) touches withEvent: (UIEvent *) event
-(void) touchesMoved: (NSSet *) touches withEvent: (UIEvent *) event
- (void) touchesEnded: (NSSet *) touches withEvent: (UIEvent *) event

现在的问题是,对于任何画出的线条,我想要获取该特定线条/绘画图像。我不希望获得整个屏幕的图像,只需获得线条/绘画的区域/边界。

原因是我想要在该线条/绘画上执行平移手势/删除功能。

用户可以绘制多条线,因此需要为所有这些线分别获取UIImage

任何逻辑或代码片段都将非常有帮助。

提前致谢

2个回答

1
根据您的应用程序,特别是您计划连续执行多少次此操作,您可以为每个绘制线创建不同的图像/图层。最终图像实质上将是所有单独线条在彼此之上绘制的结果。
创建自定义视图以捕获触摸事件可能更有效率。您可以存储每个绘画线的触摸坐标列表,并在自定义drawRect中一次性渲染它们全部。这样,您将为每个绘画线存储坐标列表,并仍然可以访问每个列表,而不是图像列表。您可以从用于渲染该线的坐标计算出其面积/范围。
更多上下文和代码可能会有所帮助,我不确定您试图完成什么!

如果您发布您的绘制/绘画方法,那么我或其他人可能更容易地完成它,这将非常有帮助。 - bradkratky

1
我来看一下MVPaint项目。看起来你有一个对象: _drawing;
它包含一个< MVPaintTransaction >数组。你可以迭代这些< MVPaintTransaction >来绘制一个< UIImage >。
所以,首先你可以添加一个从< MVPaintTransaction >获取图像的方法:
- (UIImage *) imageToDrawWithSize:(CGSize) size xScale:(CGFloat)xScale yScale:(CGFloat)yScale {

    UIGraphicsBeginImageContext(size);
    CGContextScaleCTM(UIGraphicsGetCurrentContext(), xScale, yScale);

    // call the existing draw method    
    [self draw];

    UIImage *result = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return result;
}

然后在MVPaintDrawing类中添加一个方法,用于从MVPaintTransaction数组中获取图像数组:

- (NSArray *) getImagesFromDrawingOnSurface: (UIImageView *) surface xScale: (CGFloat) xScale yScale: (CGFloat) yScale{

    NSMutableArray *imageArray = [NSMutableArray new];
    for (MVPaintTransaction * transaction in _drawing) {
        UIImage *image = [transaction imageToDrawWithSize:surface.frame.size xScale:xScale yScale:yScale];
        [imageArray addObject:image];
    }

    return imageArray;
}

以这种方式,您将拥有一个数组,其中包含与您绘制的每行对应的UIImage。如果您希望这些图像具有“最小”可能的大小(即没有额外的alpha部分),则可以应用this method(我已将其添加到MVPaintTransaction类中):
- (UIImage *)trimmedImage:(UIImage *)img {

    CGImageRef inImage = img.CGImage;
    CFDataRef m_DataRef;
    m_DataRef = CGDataProviderCopyData(CGImageGetDataProvider(inImage));

    UInt8 * m_PixelBuf = (UInt8 *) CFDataGetBytePtr(m_DataRef);

    size_t width = CGImageGetWidth(inImage);
    size_t height = CGImageGetHeight(inImage);

    CGPoint top,left,right,bottom;

    BOOL breakOut = NO;
    for (int x = 0;breakOut==NO && x < width; x++) {
        for (int y = 0; y < height; y++) {
            int loc = x + (y * width);
            loc *= 4;
            if (m_PixelBuf[loc + 3] != 0) {
                left = CGPointMake(x, y);
                breakOut = YES;
                break;
            }
        }
    }

    breakOut = NO;
    for (int y = 0;breakOut==NO && y < height; y++) {

        for (int x = 0; x < width; x++) {

            int loc = x + (y * width);
            loc *= 4;
            if (m_PixelBuf[loc + 3] != 0) {
                top = CGPointMake(x, y);
                breakOut = YES;
                break;
            }

        }
    }

    breakOut = NO;
    for (int y = height-1;breakOut==NO && y >= 0; y--) {

        for (int x = width-1; x >= 0; x--) {

            int loc = x + (y * width);
            loc *= 4;
            if (m_PixelBuf[loc + 3] != 0) {
                bottom = CGPointMake(x, y);
                breakOut = YES;
                break;
            }

        }
    }

    breakOut = NO;
    for (int x = width-1;breakOut==NO && x >= 0; x--) {

        for (int y = height-1; y >= 0; y--) {

            int loc = x + (y * width);
            loc *= 4;
            if (m_PixelBuf[loc + 3] != 0) {
                right = CGPointMake(x, y);
                breakOut = YES;
                break;
            }

        }
    }


    CGFloat scale = img.scale;

    CGRect cropRect = CGRectMake(left.x / scale, top.y/scale, (right.x - left.x)/scale, (bottom.y - top.y) / scale);
    UIGraphicsBeginImageContextWithOptions( cropRect.size,
                                           NO,
                                           scale);
    [img drawAtPoint:CGPointMake(-cropRect.origin.x, -cropRect.origin.y)
            blendMode:kCGBlendModeCopy
                alpha:1.];
    UIImage *croppedImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    CFRelease(m_DataRef);
    return croppedImage;
}

然后在第一个方法中简单地替换:
return result;

by

return [self trimmedImage:result];

在发布之前,我也尝试过调用getImagesFromDrawingOnSurface方法,这样我就可以得到一个UIImage数组(每个图像代表一条绘制的线,这正是您所要求的)。我的代码不会改变线条显示的方式(如果要实现这一点,您可能需要创建一个UIImageView数组)。 - Y.Bonafons

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接