Создать UIImage из теневого вида, сохраняя при этом альфа? - PullRequest
1 голос
/ 27 октября 2011

У меня несколько необычная проблема. В моем приложении я затеню UIImageView, используя базовое затенение слоя Quartz2d. Вот мой код:

imageView.layer.shadowOpacity = 1.0; // Pretty self explanatory
imageView.layer.shadowRadius = 8.0; // My softness
imageView.layer.shadowColor = [UIColor blackColor].CGColor; // Color of the shadow
imageView.layer.shadowOffset = CGSizeMake(0.0, 0.0); // Offset of the shadow

Это создает хорошее размытие за изображением. Однако я делаю некоторую анимацию с этим видом, и постоянный пересчет затенения во время переходов вызывает очень изменчивый переход. То, что я хотел бы сделать, это создать файл UIImage или .png из представления изображения с размытием и его альфа-неповрежденным . Вот что я уже пробовал:

UIGraphicsBeginImageContext(CGSizeMake(320, 396)); 
[imageView.layer renderInContext:UIGraphicsGetCurrentContext()]; 
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageWriteToSavedPhotosAlbum(viewImage, nil, nil, nil);

Поскольку у меня есть тень, которая "выходит за пределы" вида изображения, я не могу просто передать его размер в функции UIGraphicsBeginImageContext. Я установил правильный размер, но полученное изображение не сохраняет мою альфу, вместо этого он помещает белый фон позади тени, что не будет работать для меня, потому что мой реальный фон - текстура дерева. Кроме того, представление не центрируется в результирующем файле.

Я неплохо справляюсь с UIKit, но я настоящий нуби с Quartz 2d графикой, так что, если есть очевидный ответ, отправьте его в любом случае. :)

Ответы [ 3 ]

1 голос
/ 08 ноября 2011

Попробуйте установить backgroundColor *1002* на [UIColor clearColor] - это может позволить вашему текущему решению работать.

imageView.backgroundColor = [UIColor clearColor];
UIGraphicsBeginImageContext(CGSizeMake(320, 396)); 
[imageView.layer renderInContext:UIGraphicsGetCurrentContext()]; 
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

Источник: Преобразование CGLayer в * прозрачный *UIImage и файл PNG в CoreGraphics iphone

1 голос
/ 27 октября 2012

Добавить путь тени для просмотра вот так

[view.layer setShadowPath:[[UIBezierPath bezierPathWithRect:view.bounds] CGPath]]; //add path
view.layer.shadowColor = [[UIColor blackColor] CGColor];
view.layer.shadowOffset = CGSizeMake(x, y);
view.layer.shadowRadius = rad;
view.layer.shadowOpacity = 0.2f;
1 голос
/ 27 октября 2011

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

[imageView setContentMode:UIViewContentModeScaleAspectFit];
imageView.layer.masksToBounds = NO;
imageView.layer.shadowOffset = CGSizeMake(5, 5);
imageView.layer.shadowRadius = 200;
imageView.layer.shadowOpacity = 0.5;
CGRect rect = [self rectFromImageView:imageView];
imageView.layer.shadowPath = [UIBezierPath bezierPathWithRect:rect].CGPath;

, которая использует следующую функцию, которая предполагает, что изображение установлено в соответствии с форматом изображения:

-(CGRect)rectFromImageView:(UIImageView *)iv {
    CGRect rect = (CGRect){{0,0},iv.frame.size};
    if (iv.image.size.width/iv.frame.size.width > iv.image.size.height/iv.frame.size.height) {
        //rect.origin.x == 0
        CGFloat sf = iv.frame.size.width/iv.image.size.width;
        rect.size.height = sf*iv.image.size.height;
        rect.origin.y = floor((iv.frame.size.height - rect.size.height)/2);
    } else {
        //rect.origin.y == 0;
        CGFloat sf = iv.frame.size.height/iv.image.size.height;
        rect.size.width = sf*iv.image.size.width;
        rect.origin.x = floor((iv.frame.size.width - rect.size.width)/2);       
    }
    return rect;
}

Если ваше изображение только что заполнено, тогда достаточно использовать imageView.bounds

...