Creo que la NDA es hacia abajo, por lo que puede hacer esta pregunta. Tengo una UIView subclase:

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

Hace su trabajo hasta el momento en la captura de la pantalla, pero ahora quiero movidas que ver. ¿Cómo ir sobre esto? Por lo que he leído me necesita para capturar el contenido actual de la vista (contexto?!) y convertir a CIImage (¿no?) y, a continuación, aplicar una CIGaussianBlur y dibujar de nuevo la vista.

Exactamente cómo lo hago?

P. S. a La vista no es animado, por lo que se debe ACEPTAR rendimiento sabio.

EDIT: Aquí está lo que tengo hasta ahora. El problema es que yo no puedo capturar la instantánea de un UIImage, me sale una pantalla en negro. Pero si añado a la vista como una subvista directamente, puedo ver la instantánea está ahí.

//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;
}
  • Hay un UIImageView categoría en la WWDC2013 código de ejemplo.
  • He comprobado, pero utiliza una imagen de los activos como de una fuente, mientras que necesito utilizar una instantánea. Lo que no puedo entender.

4 Comentarios

  1. 9

    Código de ejemplo de la WWDC ios_uiimageeffects

    Hay un UIImage categoría denominada UIImage+ImageEffects

    Aquí es su API:

    - (UIImage *)applyLightEffect;
    - (UIImage *)applyExtraLightEffect;
    - (UIImage *)applyDarkEffect;
    - (UIImage *)applyTintEffectWithColor:(UIColor *)tintColor;
    
    - (UIImage *)applyBlurWithRadius:(CGFloat)blurRadius 
                           tintColor:(UIColor *)tintColor 
               saturationDeltaFactor:(CGFloat)saturationDeltaFactor 
                           maskImage:(UIImage *)maskImage;

    Jurídica de la razón que no se puede mostrar la implementación de aquí, hay un proyecto de demostración en ella. debe ser bastante fácil para empezar con.

    • Que responde sólo a la mitad de mi pregunta. Todavía tengo que conseguir un UIImage para aplicar los efectos a, y este método me da un negro de la imagen: stackoverflow.com/questions/4334233/…
    • Si usted desea que la imagen, no es necesario para la instantánea de la API. simplemente mostrar la imagen directamente en self.view?
    • Así que ¿dónde puedo conseguir la imagen si no me instantánea de la pantalla?
    • UIGraphicsBeginImageContextWithOptions(self.view.bounds.size, self.view.opaque, 0.0); luego [self.view.layer renderInContext:UIGraphicsGetCurrentContext]
    • Tienen que encontrar una solución para este negro de la imagen?
    • No creo que este va a trabajar nunca. Creo que la razón de esto no está funcionando (pantalla en negro) es que el punto de vista devuelto por la instantánea en realidad NO es de pleno derecho de la vista. Si el paso a través del depurador, verás que el tipo es ‘_UIReplicantView’. Esto me hace pensar que es sólo un optimizado copia de el otro punto de vista y no tiene el mismo «capa» características de un ‘completo’ UIView…

  2. 13

    La mitad de esta pregunta no contestadas, así que pensé que la pena añadir.

    El problema con UIScreen del

    - (UIView *)snapshotViewAfterScreenUpdates:(BOOL)afterUpdates

    y UIView del

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

    Es que no se puede derivar una UIImage de ellos – la «pantalla negra» problema.

    En iOS7 de Apple ofrece una tercera pieza de la API para la extracción de UIImages, un método de UIView

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

    No es tan rápido como snapshotView, pero no está mal en comparación con renderInContext (en el ejemplo proporcionado por Apple es cinco veces más rápido que renderInContext y tres veces más lento que snapshotView)

    Ejemplo de uso:

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

    A continuación, obtener una versión borrosa

     UIImage* lightImage = [newImage applyLightEffect];  

    donde applyLightEffect es uno de esos Desenfoque de la categoría de métodos de Apple UIImage+ImageEffects categoría mencionada en la respuesta (la tentadora enlace a este ejemplo de código en la aceptó respuesta no funciona, pero este te llevará a la página de la derecha: el archivo que desea es iOS_UIImageEffects).

    La principal referencia es WWDC2013 sesión 226, la Aplicación de Atractiva interfaz de usuario en iOS

    Por cierto, hay una interesante nota en la Manzana de referencia de google docs para renderInContext que alude a la pantalla negra problema..

    Importante: El OS X v10.5 aplicación de este método no es compatible con el Núcleo completo de Animación modelo de composición. QCCompositionLayer, CAOpenGLLayer, y QTMovieLayer capas no son prestados. Además, las capas que utilizan las transformaciones 3D no se representan ni son capas que especificar backgroundFilters, filtros, compositingFilter, o una máscara de valores. Las futuras versiones de OS X puede añadir soporte para la representación de estas capas y propiedades.

    La nota no ha sido actualizado desde 10.5, así que supongo que el futuro de las versiones’ todavía puede ser un tiempo, y podemos agregar nuestro nuevo CASnapshotLayer (o lo que sea) a la lista.

    • Realmente, yo no estaba consiguiendo nada borroso con este método. Usted consigue una mucho mejor efecto mediante el uso de UIVisualEffect: stackoverflow.com/a/40016528/35690
  3. 4

    Para resumir cómo hacer esto con la fundición del código de ejemplo, utilice el siguiente:

    Quería desenfocar toda la pantalla, solo levemente, de modo que para mis propósitos, así que voy a utilizar la pantalla principal de límites.

    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!

    Notas en la pantalla de captura de parte

    UIGraphicsBeginImageContextWithOptions() 2º argumento es la opacidad. Debe ser NO a menos que usted no tiene nada con cualquier alpha otros que 1. Si usted vuelve en sí la captura de pantalla no se verá en los valores de transparencia, así que irá más rápido, pero probablemente va a ser malo.

    UIGraphicsBeginImageContextWithOptions() 3er argumento es la escala. Probablemente quiere poner en la escala del dispositivo como yo lo hice para asegurarse y diferenciar entre la retina y no retina. Pero realmente no he probado esto y creo que 0.0f también funciona.

    drawViewHierarchyInRect:afterScreenUpdates: cuidado de lo que el retorno de las actualizaciones de pantalla BOOL. He intentado hacer esto justo antes de fondo de la página y si yo no he puesto NO la aplicación se vuelva loco con fallos cuando he regresado al primer plano. Usted puede ser capaz de salirse con la YES aunque si no tienes que salir de la aplicación.

    Notas sobre el desenfoque

    Tengo un muy ligero desenfoque de aquí. El cambio de la blurRadius hará borrosa, y usted puede cambiar el matiz de color y alfa para hacer todo tipo de efectos.

    También necesita agregar una categoría para el desenfoque de los métodos de trabajo…

    Cómo agregar el UIImage+ImageEffects categoría

    Usted necesita para descargar la categoría UIImage+ImageEffects para el desenfoque de trabajo. Descargar aquí después de iniciar sesión en: https://developer.apple.com/downloads/index.action?name=WWDC%202013

    De la búsqueda para «UIImageEffects» y lo encontrarás. Solo tiene que sacar los 2 archivos necesarios y agregarlos a su proyecto. UIImage+ImageEffects.h y UIImage+ImageEffects.m.

    También, tuve que Habilitar los Módulos en mi configuración de generación, porque tenía un proyecto que no fue creada con xCode 5. Para ello, vaya a su objetivo de construir la configuración y la búsqueda para «módulos» y asegúrese de que «Habilitar Módulos» y «Enlace de Marcos de forma Automática» se establecen para sí o tendrás errores del compilador con la nueva categoría.

    Buena suerte desenfoque!

  4. 0

    Comprobar la WWDC 2013 de la aplicación de ejemplo «correr con un complemento».

    El desenfoque es allí implementado como una categoría.

Dejar respuesta

Please enter your comment!
Please enter your name here