ios 如何屏蔽 UIImageView?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5757386/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I mask a UIImageView?
提问by Mc.Lover
I am trying to mask an image with something like this:
我试图用这样的东西来掩盖图像:
Would you please help me?
你能帮我吗?
I am using this code:
我正在使用此代码:
- (void) viewDidLoad {
UIImage *OrigImage = [UIImage imageNamed:@"dogs.png"];
UIImage *mask = [UIImage imageNamed:@"mask.png"];
UIImage *maskedImage = [self maskImage:OrigImage withMask:mask];
myUIIMage.image = maskedImage;
}
回答by Bartosz Ciechanowski
There's an easier way.
有一个更简单的方法。
#import <QuartzCore/QuartzCore.h>
// remember to include Framework as well
CALayer *mask = [CALayer layer];
mask.contents = (id)[[UIImage imageNamed:@"mask.png"] CGImage];
mask.frame = CGRectMake(0, 0, <img_width>, <img_height>);
yourImageView.layer.mask = mask;
yourImageView.layer.masksToBounds = YES;
For Swift 4 and plus follow code below
对于 Swift 4 及以上,请遵循以下代码
let mask = CALayer()
mask.contents = [ UIImage(named: "right_challenge_bg")?.cgImage] as Any
mask.frame = CGRect(x: 0, y: 0, width: leftBGImage.frame.size.width, height: leftBGImage.frame.size.height)
leftBGImage.layer.mask = mask
leftBGImage.layer.masksToBounds = true
回答by Nick Weaver
The tutorial uses this method with two parameters: image
and maskImage
, these you have to set when you call the method. An example call could look like this, assuming the method is in the same class and the pictures are in your bundle:
本教程使用带有两个参数的此方法:image
和maskImage
,您必须在调用该方法时设置这些参数。示例调用可能如下所示,假设该方法在同一个类中并且图片在您的包中:
Note - amazingly the images do not even have to be the same size.
注意 - 令人惊讶的是,图像甚至不必是相同的大小。
...
UIImage *image = [UIImage imageNamed:@"dogs.png"];
UIImage *mask = [UIImage imageNamed:@"mask.png"];
// result of the masking method
UIImage *maskedImage = [self maskImage:image withMask:mask];
...
- (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 maskedImageRef = CGImageCreateWithMask([image CGImage], mask);
UIImage *maskedImage = [UIImage imageWithCGImage:maskedImageRef];
CGImageRelease(mask);
CGImageRelease(maskedImageRef);
// returns new image with mask applied
return maskedImage;
}
After you provided your code I have added some numbers as comments to it for reference. You still have two options. This whole thing is a method, which you are calling somewhere. You don't need to create the images inside it: this reduces the reusability of the method to zero.
在您提供代码后,我添加了一些数字作为注释以供参考。你还有两个选择。这整个事情是一个方法,你在某处调用它。您不需要在其中创建图像:这会将方法的可重用性降低到零。
To get your code working. Change the methods head (1.) to
让你的代码工作。将方法头 ( 1.)更改为
- (UIImage *)maskImageMyImages {
Then change the name of the variable in 2.to
然后将2.中的变量名称更改为
UIImage *maskImage = [UIImage imageNamed:@"mask.png"];
The method will return your masked images so you'll have to call this method in some place. Can you show us the code where you are calling your method?
该方法将返回您的蒙版图像,因此您必须在某个地方调用此方法。你能告诉我们你调用方法的代码吗?
回答by Mark Moeykens
Swift 3 - Simplest Solution I Found
Swift 3 - 我找到的最简单的解决方案
I created an @IBDesignable
for this so you could see the effect right away on your storyboard.
我@IBDesignable
为此创建了一个,以便您可以立即在故事板上看到效果。
import UIKit
@IBDesignable
class UIImageViewWithMask: UIImageView {
var maskImageView = UIImageView()
@IBInspectable
var maskImage: UIImage? {
didSet {
maskImageView.image = maskImage
updateView()
}
}
// This updates mask size when changing device orientation (portrait/landscape)
override func layoutSubviews() {
super.layoutSubviews()
updateView()
}
func updateView() {
if maskImageView.image != nil {
maskImageView.frame = bounds
mask = maskImageView
}
}
}
How to use
如何使用
- Create a new file and paste in that code above.
- Add UIImageView to your storyboard (assign an image if you want).
- On Identity Inspector: Change the custom class to "UIImageViewWithMask" (custom class name above).
- On Attributes Inspector: Select mask image you want to use.
- 创建一个新文件并粘贴上面的代码。
- 将 UIImageView 添加到您的故事板(如果需要,可以分配图像)。
- 在 Identity Inspector 上:将自定义类更改为“UIImageViewWithMask”(上面的自定义类名)。
- 在属性检查器上:选择要使用的蒙版图像。
Example
例子
Notes
笔记
- Your mask image should have a transparent background (PNG) for the non-black part.
- 您的蒙版图像的非黑色部分应具有透明背景 (PNG)。
回答by Ninji
I tried both code using either CALayer or CGImageCreateWithMask but none of them didn't work for me
我使用 CALayer 或 CGImageCreateWithMask 尝试了这两个代码,但没有一个对我不起作用
But i found out that the problem is with png file format, NOT the code!!
so just to share my finding!
但我发现问题在于 png 文件格式,而不是代码!!
所以只是分享我的发现!
If you want to use
如果你想使用
- (UIImage*) maskImage:(UIImage *)image withMask:(UIImage *)maskImage
you must use 24bitpng withoutalpha channel
你必须使用没有alpha 通道的24 位png
If you want to use CALayer mask, you must use (24bit or 8bit) png withalpha channel where transparent part of your png will mask the image (for smooth gradient alpha mask.. use 24bit png with alpha channel)
如果要使用 CALayer 蒙版,则必须使用(24 位或 8 位)png和alpha 通道,其中 png 的透明部分将掩盖图像(对于平滑渐变 alpha 蒙版..使用 24 位 png 和 alpha 通道)
回答by ZYiOS
- (UIImage*) maskImage:(UIImage *)image withMask:(UIImage *)maskImage {
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGImageRef maskImageRef = [maskImage CGImage];
// create a bitmap graphics context the size of the image
CGContextRef mainViewContentContext = CGBitmapContextCreate (NULL, maskImage.size.width, maskImage.size.height, 8, 0, colorSpace, kCGImageAlphaPremultipliedLast);
CGColorSpaceRelease(colorSpace);
if (mainViewContentContext==NULL)
return NULL;
CGFloat ratio = 0;
ratio = maskImage.size.width/ image.size.width;
if(ratio * image.size.height < maskImage.size.height) {
ratio = maskImage.size.height/ image.size.height;
}
CGRect rect1 = {{0, 0}, {maskImage.size.width, maskImage.size.height}};
CGRect rect2 = {{-((image.size.width*ratio)-maskImage.size.width)/2 , -((image.size.height*ratio)-maskImage.size.height)/2}, {image.size.width*ratio, image.size.height*ratio}};
CGContextClipToMask(mainViewContentContext, rect1, maskImageRef);
CGContextDrawImage(mainViewContentContext, rect2, image.CGImage);
// Create CGImageRef of the main view bitmap content, and then
// release that bitmap context
CGImageRef newImage = CGBitmapContextCreateImage(mainViewContentContext);
CGContextRelease(mainViewContentContext);
UIImage *theImage = [UIImage imageWithCGImage:newImage];
CGImageRelease(newImage);
// return the image
return theImage;
}
This works for me.
这对我有用。
回答by Ahmed Safadi
SWIFT 3 XCODE 8.1
SWIFT 3 XCODE 8.1
func maskImage(image: UIImage, withMask maskImage: UIImage) -> UIImage {
let maskRef = maskImage.cgImage
let mask = CGImage(
maskWidth: maskRef!.width,
height: maskRef!.height,
bitsPerComponent: maskRef!.bitsPerComponent,
bitsPerPixel: maskRef!.bitsPerPixel,
bytesPerRow: maskRef!.bytesPerRow,
provider: maskRef!.dataProvider!,
decode: nil,
shouldInterpolate: false)
let masked = image.cgImage!.masking(mask!)
let maskedImage = UIImage(cgImage: masked!)
// No need to release. Core Foundation objects are automatically memory managed.
return maskedImage
}
// for use
// 用来
testImage.image = maskImage(image: UIImage(named: "OriginalImage")!, withMask: UIImage(named: "maskImage")!)
回答by Juan Valera
Swift version of the accepted solution:
已接受解决方案的 Swift 版本:
func maskImage(image: UIImage, withMask maskImage: UIImage) -> UIImage {
let maskRef = maskImage.CGImage
let mask = CGImageMaskCreate(
CGImageGetWidth(maskRef),
CGImageGetHeight(maskRef),
CGImageGetBitsPerComponent(maskRef),
CGImageGetBitsPerPixel(maskRef),
CGImageGetBytesPerRow(maskRef),
CGImageGetDataProvider(maskRef),
nil,
false)
let masked = CGImageCreateWithMask(image.CGImage, mask)
let maskedImage = UIImage(CGImage: masked)!
// No need to release. Core Foundation objects are automatically memory managed.
return maskedImage
}
Just in case someone need it.
以防万一有人需要它。
It`s working for me flawlessly.
它完美地为我工作。
回答by werbary
we found, that correct answer is not working now and implemented little drop-in class, which helps to mask any image in UIImageView.
我们发现,正确的答案现在不起作用,并实现了小的插入类,这有助于屏蔽 UIImageView 中的任何图像。
It's available here: https://github.com/Werbary/WBMaskedImageView
它可以在这里找到:https: //github.com/Werbary/WBMaskedImageView
Example:
例子:
WBMaskedImageView *imgView = [[WBMaskedImageView alloc] initWithFrame:frame];
imgView.originalImage = [UIImage imageNamed:@"original_image.png"];
imgView.maskImage = [UIImage imageNamed:@"mask_image.png"];