2013-09-22 3 views
3

Я считаю, что NDA не работает, поэтому я могу задать этот вопрос. У меня есть UIView подкласс:Скрытый экран с моментальным снимком iOS 7

BlurView *blurredView = ((BlurView *)[self.view snapshotViewAfterScreenUpdates:NO]); 
blurredView.frame = self.view.frame; 
[self.view addSubview:blurredView]; 

Он делает свою работу до сих пор захватить экран, но теперь я хочу, чтобы размыть эту точку зрения. Как именно я это делаю? Из того, что я прочитал, мне нужно зафиксировать текущее содержимое представления (контекст ?!) и преобразовать его в CIImage (нет?), А затем применить к нему CIGaussianBlur и вернуть его обратно в представление.

Как именно я это делаю?

P.S. Представление не анимировано, поэтому оно должно быть в порядке.

EDIT: Вот что у меня есть до сих пор. Проблема в том, что я не могу захватить снимок в UIImage, я получаю черный экран. Но если я добавлю представление в качестве подзаголовка напрямую, я вижу, что снимок есть.

// Snapshot 
UIView *view = [self.view snapshotViewAfterScreenUpdates:NO]; 

// Convert to UIImage 
UIGraphicsBeginImageContextWithOptions(view.bounds.size, view.opaque, 0.0); 
[view.layer renderInContext:UIGraphicsGetCurrentContext()]; 
UIImage *img = UIGraphicsGetImageFromCurrentImageContext(); 
UIGraphicsEndImageContext(); 

// Apply the UIImage to a UIImageView 
BlurView *blurredView = [[BlurView alloc] initWithFrame:CGRectMake(0, 0, 500, 500)]; 
[self.view addSubview:blurredView]; 
blurredView.imageView.image = img; 

// Black screen -.- 

BlurView.m:

- (id)initWithFrame:(CGRect)frame { 
    self = [super initWithFrame:frame]; 

    if (self) { 
     // Initialization code 
     self.imageView = [[UIImageView alloc] init]; 
     self.imageView.frame = CGRectMake(20, 20, 200, 200); 
     [self addSubview:self.imageView]; 
    } 
    return self; 
} 
+1

В образце кода WWDC2013 имеется категория UIImageView. –

+0

Я проверил его, но он использует изображение из активов в качестве источника, в то время как мне нужно использовать моментальный снимок. Который я не могу понять. –

ответ

9

Пример код от WWDC ios_uiimageeffects

Существует UIImage категории имени UIImage+ImageEffects

Вот его API:

- (UIImage *)applyLightEffect; 
- (UIImage *)applyExtraLightEffect; 
- (UIImage *)applyDarkEffect; 
- (UIImage *)applyTintEffectWithColor:(UIColor *)tintColor; 

- (UIImage *)applyBlurWithRadius:(CGFloat)blurRadius 
         tintColor:(UIColor *)tintColor 
      saturationDeltaFactor:(CGFloat)saturationDeltaFactor 
         maskImage:(UIImage *)maskImage; 

Для юридических причин я не могу показать реализацию здесь, есть демонстрационный проект в нем. должно быть довольно легко начать.

+3

Это отвечает только на половину моего вопроса. Мне все еще нужно получить UIImage для применения этих эффектов, и этот метод дает мне черное изображение: http://stackoverflow.com/questions/4334233/how-to-capture-uiview-to-uiimage-without-loss- of-quality-on-retina-display –

+0

Если вы хотите только изображение, вам не нужно использовать API-интерфейс моментального снимка. просто визуализируйте изображение непосредственно на 'self.view'? –

+0

Итак, где я могу получить изображение, если не снимок экрана? –

0

Проверить WWDC 2013 демонстрационное приложение "работает с оснасткой".

Размытие реализовано как категория.

12

Половина этого вопроса не получила ответа, поэтому я подумал, что стоит добавить.

Проблема с

- (UIView *)resizableSnapshotViewFromRect:(CGRect)rect 
         afterScreenUpdates:(BOOL)afterUpdates 
          withCapInsets:(UIEdgeInsets)capInsets 

UIScreen в

- (UIView *)snapshotViewAfterScreenUpdates:(BOOL)afterUpdates 

и UIView является то, что вы не можете вывести UIImage из них - 'черный экран' проблемы.

В iOS7 Apple, обеспечивает третий кусок API для извлечения UIImages, метод на UIView

- (BOOL)drawViewHierarchyInRect:(CGRect)rect 
      afterScreenUpdates:(BOOL)afterUpdates 

Это не так быстро, как snapshotView, но не плохо по сравнению с renderInContext (в приведенном примере Яблоком так ли в пять раз быстрее, чем renderInContext и три раза медленнее, чем snapshotView)

Пример использования:

UIGraphicsBeginImageContextWithOptions(image.size, NULL, 0); 
[view drawViewHierarchyInRect:rect]; 
UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext(); 
UIGraphicsEndImageContext(); 

Тогда, чтобы получить размытую версию

UIImage* lightImage = [newImage applyLightEffect]; 

где applyLightEffect является один из этих методов категории Размытия по UIImage+ImageEffects категории Apple, упомянутой в принятом ответе (Соблазнительная ссылка на этот образец кода в принятом ответе не работает, но this one will get you to the right page: файл, который вы хотите, - iOS_UIImageEffects).

Основная ссылка на WWDC2013 сессии 226, Реализации Если включаются интерфейс на прошивке

Кстати, есть интригующая нота в справочных материалах компании Apple для renderInContext, что намекает на черной проблеме экрана ..

Важно: реализация этого метода OS X v10.5 не поддерживает всю модель композиции Core Animation. Уровни QCCompositionLayer, CAOpenGLLayer и QTMovieLayer не отображаются. Кроме того, слои, которые используют 3D-преобразования, не отображаются, а также слои, которые определяют backgroundFilters, фильтры, compositingFilter или значения маски. Будущие версии OS X могут добавить поддержку для рендеринга этих слоев и свойств.

В записке не обновлялся с 10.5, так что я предполагаю, что «будущие версии» все еще может быть некоторое время прочь, и мы можем добавить наш новый CASnapshotLayer (или любой другой) в списке.

4

Итак, как это сделать с образцом кода литейной, используйте следующее:

Я хотел лишь слегка размыть весь экран так что для моих целей, поэтому я буду использовать основные экранные границы.

CGRect screenCaptureRect = [UIScreen mainScreen].bounds; 
UIView *viewWhereYouWantToScreenCapture = [[UIApplication sharedApplication] keyWindow]; 

//screen capture code 
UIGraphicsBeginImageContextWithOptions(screenCaptureRect.size, NO, [UIScreen mainScreen].scale); 
[viewWhereYouWantToScreenCapture drawViewHierarchyInRect:screenCaptureRect afterScreenUpdates:NO]; 
UIImage *capturedImage = UIGraphicsGetImageFromCurrentImageContext(); 
UIGraphicsEndImageContext(); 

//blur code 
UIColor *tintColor = [UIColor colorWithWhite:1.0 alpha:0]; 
UIImage *blurredImage = [capturedImage applyBlurWithRadius:1.5 tintColor:tintColor saturationDeltaFactor:1.2 maskImage:nil]; 
//or use [capturedImage applyLightAffect] but I thought that was too much for me 

//use blurredImage in whatever way you so desire! 

Замечания по части захвата экрана

UIGraphicsBeginImageContextWithOptions() второй аргумент непрозрачности. Он должен быть NO, если у вас нет ничего с alpha кроме 1. Если вы вернетесь да, захват экрана не будет смотреть на значения прозрачности, поэтому он будет работать быстрее, но, вероятно, будет ошибкой.

UIGraphicsBeginImageContextWithOptions() Третий аргумент - масштаб. Вероятно, вы хотите поместить в шкалу устройства, как я сделал, чтобы убедиться и провести различие между сетчаткой и сетчаткой. Но я не тестировал это, и думаю, 0.0f также работает.

drawViewHierarchyInRect:afterScreenUpdates: следить за тем, что вы возвращаете для обновления экрана BOOL. Я попытался сделать это прямо перед началом работы, и если бы я не положил NO, приложение перестало бы срываться с ошибками, когда я вернусь на передний план. Вы можете уйти с YES, хотя если вы не покинете приложение.

Заметки о размытости

У меня есть очень легкая размытость здесь. Изменение blurRadius сделает его более размытым, и вы можете изменить цвет оттенка и альфа, чтобы сделать всевозможные другие эффекты.

Кроме того, необходимо добавить категорию методов размывания, чтобы работать ...

Как добавить к категории UIImage + ImageEffects

Вы должны загрузить категории UIImage + ImageEffects для размытия работать. Загрузить его здесь после регистрации: https://developer.apple.com/downloads/index.action?name=WWDC%202013

Поиск "UIImageEffects" и вы найдете его. Просто вытащите 2 необходимых файла и добавьте их в свой проект. UIImage + ImageEffects.h и UIImage + ImageEffects.m.

Кроме того, мне пришлось включить модули в моих настройках сборки, потому что у меня был проект, который не был создан с помощью xCode 5. Для этого перейдите к настройкам вашей целевой сборки и найдите «модули» и убедитесь, что «Включить «Модули» и «Автоматические рамки ссылок» установлены на «да» или у вас будут ошибки компилятора с новой категорией.

Удача размытия!

Смежные вопросы