如何擦去雾气蒙蒙的景色

发布于 2025-01-04 05:24:56 字数 2600 浏览 4 评论 0原文

我正在开发一个应用程序,它具有用户可以用手指擦拭的蒸汽视图。我尝试了一些我希望能起作用的东西,它确实起作用了,但速度非常慢。下面的代码结合了绘图代码和屏蔽代码。绘图代码绘制黑白图像,然后将其用作遮罩以遮盖雾图像。

有谁知道有任何示例代码可以实现这种效果,或者对如何使其更快有任何建议吗?

static CGPoint midPoint(CGPoint p1, CGPoint p2){
    return CGPointMake((p1.x+p2.x)*0.5f, (p1.y+p2.y)*0.5f);
}

- (UIImage *)maskImage:(UIImage *)image withMask:(UIImage *)maskImage{
    CGImageRef maskRef = [maskImage CGImage];
    CGImageRef mask = CGImageMaskCreate(CGImageGetWidth(maskRef),
                                        CGImageGetHeight(maskRef),
                                        CGImageGetBitsPerComponent(maskRef),
                                        CGImageGetBitsPerPixel(maskRef),
                                        CGImageGetBytesPerRow(maskRef),
                                        CGImageGetDataProvider(maskRef), NULL, false);
    CGImageRef masked = CGImageCreateWithMask([image CGImage], mask);
    CGImageRelease(mask);
    UIImage *maskedImage = [UIImage imageWithCGImage:masked];
    CGImageRelease(masked);
    return maskedImage;

}

- (void)setMaskImage:(UIImage *)maskImage{
    [_maskImage release];
    _maskImage = [maskImage retain];
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
    UITouch *touch = [touches anyObject];

    _previousPoint1 = [touch previousLocationInView:self];
    _previousPoint2 = [touch previousLocationInView:self];
    _currentPoint = [touch locationInView:self];
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
    UITouch *touch = [touches anyObject];

    _previousPoint2 = _previousPoint1;
    _previousPoint1 = [touch previousLocationInView:self];
    _currentPoint = [touch locationInView:self];

    CGPoint mid1 = midPoint(_previousPoint1, _previousPoint2); 
    CGPoint mid2 = midPoint(_currentPoint, _previousPoint1);

    CGRect imageRect = CGRectZero;
    imageRect.size = _fogView.frame.size;
    UIGraphicsBeginImageContext(imageRect.size);
    CGContextRef context = UIGraphicsGetCurrentContext();
    [_maskImage drawInRect:imageRect];

    CGContextMoveToPoint(context, mid1.x, mid1.y);
    CGContextAddQuadCurveToPoint(context, _previousPoint1.x, _previousPoint1.y, mid2.x, mid2.y); 

    CGContextSetLineCap(context, kCGLineCapRound);
    CGContextSetLineWidth(context, 40.0f);
    CGContextSetRGBStrokeColor(context, 1.0f, 1.0f, 1.0f, 1.0f);
    CGContextStrokePath(context);

    [self setMaskImage:UIGraphicsGetImageFromCurrentImageContext()];
    UIGraphicsEndImageContext();

    _fogView.image = [self maskImage:[UIImage imageNamed:@"Fog"] withMask:_maskImage];
}

I am working on an app that has a steamed up view that the user can wipe away with their finger. I took a crack at it with something that I hoped would work, and it does but it's super slow. The code below combines drawing code and masking code. The drawing code draws to a black and white image that is then used as a mask to mask out the fog image.

Does anyone know of any sample code to achieve this effect, or have any suggestions on how to make it faster?

static CGPoint midPoint(CGPoint p1, CGPoint p2){
    return CGPointMake((p1.x+p2.x)*0.5f, (p1.y+p2.y)*0.5f);
}

- (UIImage *)maskImage:(UIImage *)image withMask:(UIImage *)maskImage{
    CGImageRef maskRef = [maskImage CGImage];
    CGImageRef mask = CGImageMaskCreate(CGImageGetWidth(maskRef),
                                        CGImageGetHeight(maskRef),
                                        CGImageGetBitsPerComponent(maskRef),
                                        CGImageGetBitsPerPixel(maskRef),
                                        CGImageGetBytesPerRow(maskRef),
                                        CGImageGetDataProvider(maskRef), NULL, false);
    CGImageRef masked = CGImageCreateWithMask([image CGImage], mask);
    CGImageRelease(mask);
    UIImage *maskedImage = [UIImage imageWithCGImage:masked];
    CGImageRelease(masked);
    return maskedImage;

}

- (void)setMaskImage:(UIImage *)maskImage{
    [_maskImage release];
    _maskImage = [maskImage retain];
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
    UITouch *touch = [touches anyObject];

    _previousPoint1 = [touch previousLocationInView:self];
    _previousPoint2 = [touch previousLocationInView:self];
    _currentPoint = [touch locationInView:self];
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
    UITouch *touch = [touches anyObject];

    _previousPoint2 = _previousPoint1;
    _previousPoint1 = [touch previousLocationInView:self];
    _currentPoint = [touch locationInView:self];

    CGPoint mid1 = midPoint(_previousPoint1, _previousPoint2); 
    CGPoint mid2 = midPoint(_currentPoint, _previousPoint1);

    CGRect imageRect = CGRectZero;
    imageRect.size = _fogView.frame.size;
    UIGraphicsBeginImageContext(imageRect.size);
    CGContextRef context = UIGraphicsGetCurrentContext();
    [_maskImage drawInRect:imageRect];

    CGContextMoveToPoint(context, mid1.x, mid1.y);
    CGContextAddQuadCurveToPoint(context, _previousPoint1.x, _previousPoint1.y, mid2.x, mid2.y); 

    CGContextSetLineCap(context, kCGLineCapRound);
    CGContextSetLineWidth(context, 40.0f);
    CGContextSetRGBStrokeColor(context, 1.0f, 1.0f, 1.0f, 1.0f);
    CGContextStrokePath(context);

    [self setMaskImage:UIGraphicsGetImageFromCurrentImageContext()];
    UIGraphicsEndImageContext();

    _fogView.image = [self maskImage:[UIImage imageNamed:@"Fog"] withMask:_maskImage];
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

℡寂寞咖啡 2025-01-11 05:24:56

@badeen 的帮助下,解决方案是使用两个 CALayer,一个用于雾图像,一个用于雾图像mask,当用户在屏幕上移动手指时,遮罩就会被绘制进去。

With help from @badeen the solution was to use two CALayers, one for the fog image and one for the mask, the mask is drawn into when the user moves their finger around the screen.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文