Маска изображения без прозрачной части - PullRequest
0 голосов
/ 30 марта 2012

Я уже давно это изучаю.

Я пытаюсь поставить серое изображение поверх чашки

enter image description here

В настоящее время яЯ растягиваю uiimageview с серым фоном до такой степени, что ползунок исчез.

-(void) sliderChanged:(CGFloat) value{
drinksView.grayArea.frame = CGRectMake( 0 , -value ,372 ,value);

Я знаю, что это очень грязно, не то, что я хочу ...

ЧтоЯ хочу, чтобы серая часть покрывала только ту часть, где находится чашка (например, часть, где изображение не является прозрачным) .Изображение чашки просто имеет прозрачный фон

У кого-нибудь есть идеи, как этого добиться?Я новичок с масками, и многие уроки ни к чему меня не привели, и я даже не знаю, возможно ли это.

PS: нарисовать путь вокруг чашки невозможно, потому что изображение чашки может измениться настекло

Ответы [ 3 ]

1 голос
/ 30 марта 2012

Самый простой способ, который я могу придумать, это использовать маскированный CALayer.Вот что вам нужно сделать:

  1. Вместо использования UIImageView используйте CALayer с серым фоном в качестве наложения.Ваш sliderChanged: метод останется нетронутым, за исключением того, что drinksView.grayArea будет слоем вместо вида.
  2. Пока эффект будет точно таким же, как и раньше.Теперь вам нужно установить маску grayArea.Сделайте следующее:

    CALayer * maskLayer = [CALayer new];
    maskLayer.contents = myCupImage.CGImage;
    grayArea.mask = maskLayer;
    
  3. Я думаю, что по умолчанию слой будет растягивать содержимое при изменении масштаба.Мы этого не хотим.Вы можете исправить это, установив для слоя contentsGravity, скажем, kCAGravityTop.

Это должно делать то, что вы хотите.

Одно предупреждение: яНе совсем уверен, как маски справляются с изменением содержания гравитации.Если у вас есть проблемы на этом фронте, вы можете исправить их, добавив слой контейнера:

  1. Установите фиксированную рамку для grayArea (равную размеру изображения чашки).

  2. Вместо непосредственного добавления grayArea введите для него слой контейнера:

    CALayer * container = [CALayer new];
    container.masksToBounds = YES;
    [container addSublayer:grayArea];
    [drinksView.layer addSublayer:container];
    
  3. В вашем sliderChanged: измените рамкуcontainer вместо grayArea.

Надеюсь, это сработает.

1 голос
/ 30 марта 2012

Прежде всего вам необходимо ознакомиться с этим методом

    // masks the item based on the MaskImage
- (UIImage*) itemMask : (UIImage*)image withMask:(UIImage*)maskImage
{
    UIImage* afterMasking = nil;

    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);
    CFRelease(mask);
    afterMasking = [UIImage imageWithCGImage:masked];
    CFRelease(masked);
    return afterMasking;
}

То, что вы делаете, это то, что вы кормите свое изображение Кубка и изображение маски вместе, и оно маскирует ваше изображение чашки. Это только замаскирует ваше изображение чашки и ничего под ним, так что вам не о чем беспокоиться.

Проблема в том, что размер серого поля изменяется. Как бы я подошел к этому, чтобы обрезать маску в соответствии со значением слайдера. Так что создайте черный ящик и измените его размер, как вы делаете с grayBG, ДО того, как вы передадите его через метод. Это должно быть быстро, поэтому я не буду вдаваться в подробности, но в конце у вас будет что-то вроде этого. Прошу прощения за половину проработанной графики

Image With large sliderImage With small slider

0 голосов
/ 02 апреля 2012
    drinksView.grayLayer = [CALayer new];
    drinksView.grayLayer.frame = CGRectMake(0, 0, 372, 0);
    drinksView.grayLayer.contentsGravity = kCAGravityTop;

    CALayer * topLayer = [CALayer new];
    topLayer.frame = CGRectMake(0, 0, 372, 367);
    UIImage * grayImage = [UIImage imageNamed:@"grayDrink.png"];
    topLayer.contents = (id) grayImage.CGImage;

    CALayer * maskLayer = [CALayer new];
    maskLayer.contents = (id)cupImage.CGImage;
    maskLayer.masksToBounds = YES;

    maskLayer.bounds = CGRectMake(0, 0, 372, 367);
    maskLayer.position = CGPointMake(186,184);

    [topLayer setMask:maskLayer];
    [drinksView.grayLayer addSublayer:topLayer];
    [drinksView.grayLayer setMasksToBounds:YES];
    [[drinksView layer]addSublayer:drinksView.grayLayer];
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...