我以递归方式(使用计时器)对UIImageView中的图像应用蒙版,我想根据用户触摸屏幕的位置在某个区域应用蒙版。
要定义该区域,用户触摸屏幕并读取触摸当前位置。此位置定义了我想要修改的区域的中心。
到目前为止,我只能使用CGImageCreateWithMask
将蒙版应用于整个图像。我用来应用掩码的代码是:
- (UIImage *)maskImageWithCurrentContext:(UIImage *)image withMask:(UIImage *)maskImage{
UIImage *maskedImage;
float width = image.size.width;
float height = image.size.height;
CGRect rect = CGRectMake(0, 0, width, height);
UIGraphicsBeginImageContext(rect.size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextTranslateCTM(context, 0, height);
CGContextScaleCTM(context, 1.0, -1.0);
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);
CGContextDrawImage(context, rect, masked);
maskedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
CGImageRelease(mask);
CGImageRelease(masked);
return maskedImage;
}
我调用该方法的方式是self.imageViewGelo.image = [self maskImageWithCurrentContext:self.imageViewGelo.image withMask:self.imageMask];
(在触摸视图时激活的计时器内部),然后将生成的图像应用于我想要修改的视图。
我面临的问题是,我希望得到整个图像的区域,将遮罩应用于它,然后在原始图像中应用新区域,以显示修改。例如,如果我有一个尺寸为1024x768的图像,并且用户用坐标(300,200)触摸该点,我想选择尺寸为50x50的区域,应用蒙版,然后将得到的图像放在同一区域。
我使用的面具几乎都是黑色的,并且有一些区域略微更多"光" (就像真正的深色灰色),以便产生缓慢融冰的效果。
我已经阅读过文档并搜索了几个小时有关任何类似问题,但没有运气。
在iPad 4上运行的上述代码的性能,定时器设置为每0.1秒触发一次(仅测试值)非常好,没有任何内存问题和相对较低的处理器使用率。
如果有人可以帮我解决这个问题,请提前多多感谢。
答案 0 :(得分:0)
最后,我的代码按照我的意图运行。
首先,我使用基于Matt在following post.中提供的代码来裁剪用户触摸的位置中的部分图像。谢谢Matt。 :)
裁剪图片的代码是:
- (UIImage *)cropImage:(UIImage *)original{
UIGraphicsBeginImageContextWithOptions(CGSizeMake(kSizeMaskImageWidth, kSizeMaskImageHeight), NO, original.scale);
[original drawAtPoint:CGPointMake(-((int)touchLocation.x - kSizeMaskImageWidth / 2), -((int)touchLocation.y - kSizeMaskImageHeight / 2))];
UIImage *cropped = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return cropped;
}
接下来,我在完全相同的位置绘制一个透明矩形,具有完全相同的尺寸,在那里我应用我在前面的代码中获得的裁剪图像。为实现这一切,我使用以下代码:
- (UIImage *)maskImageWithCurrentContext:(UIImage *)originalImage withMask:(UIImage *)maskImage inCroppedImage:(UIImage *)croppedImage{
float width = originalImage.size.width;
float height = originalImage.size.height;
CGRect rect = CGRectMake(0, 0, width, height);
UIGraphicsBeginImageContextWithOptions(rect.size, NO, originalImage.scale);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextTranslateCTM(context, 0, height);
CGContextScaleCTM(context, 1.0, -1.0);
CGImageRef maskRef = maskImage.CGImage;
CGImageRef mask = CGImageMaskCreate(CGImageGetWidth(maskRef),
CGImageGetHeight(maskRef),
CGImageGetBitsPerComponent(maskRef),
CGImageGetBitsPerPixel(maskRef),
CGImageGetBytesPerRow(maskRef),
CGImageGetDataProvider(maskRef),
NULL,
false);
CGImageRef masked = CGImageCreateWithMask(croppedImage.CGImage, mask);
CGContextDrawImage(context, rect, originalImage.CGImage);
CGContextClearRect(context, CGRectMake(((int)touchLocation.x - kSizeMaskImageWidth / 2), height - ((int)touchLocation.y + kSizeMaskImageHeight / 2), kSizeMaskImageWidth, kSizeMaskImageHeight));
CGContextDrawImage(context, CGRectMake(((int)touchLocation.x - kSizeMaskImageWidth / 2), height - ((int)touchLocation.y + kSizeMaskImageHeight / 2), kSizeMaskImageWidth, kSizeMaskImageHeight), masked);
UIImage *maskedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
CGImageRelease(mask);
CGImageRelease(masked);
return maskedImage;
}
使用此代码绘制原始图像,然后在原始图像的顶部绘制透明矩形,最后在透明矩形内绘制裁剪后的图像。
我在视网膜iPad上的触摸位置有一些问题,因为触摸是通过点检测到的。当我试图绘制图像时,有时位置是x,5,所以我必须将它转换为int,以便摆脱小数位。
现在我实现了冰融化的效果,使用计时器递归地应用蒙版,并将其应用于用户触摸屏幕的位置。 :)
作为最后一点,由于检测到的触摸比我正在使用的定时器间隔检测得快,我在绘制前禁用视图中的触摸,并在绘制完成后再次启用它们。