Configuración del modo de contenido de UIImageView después de aplicar un CIFIlter

Gracias por mirar.

Aquí está mi código

CIImage *result = _vignette.outputImage; self.mainImageView.image = nil; //self.mainImageView.contentMode = UIViewContentModeScaleAspectFit; self.mainImageView.image = [UIImage imageWithCIImage:result]; self.mainImageView.contentMode = UIViewContentModeScaleAspectFit; 

aquí la _vignette está configurada correctamente, el filter y el efecto de la image se aplican a la image correctamente.

Estoy usando una image de origen con resolución de 500×375. Mi imageView tiene casi la resolución de la pantalla de iPhone. Entonces para evitar estiramientos estoy usando AspectFit.

Pero después de aplicar el efecto cuando estoy asignando la image del resultado de vuelta a mi image, se estira. No importa qué UIViewContentMode que uso. No funciona. Parece que siempre se aplica ScaleToFill independientemente del filter que haya proporcionado.

¿Alguna idea de por qué sucede esto? Cualquier sugerencia es muy apreciada.

(1) Aspect Fit ajusta la image para que se ajuste. Si no desea que la image se extienda en absoluto, use Center (por ejemplo).

(2) imageWithCIImage te ofrece una bestia muy extraña, un UIImage no basado en CGImage, y por lo tanto no es susceptible a las reglas normales de visualización de capas. Realmente no es más que una envoltura delgada alnetworkingedor de CIImage, que no es lo que quieres. Debe convertir (renderizar) la salida CIFilter a través de CGImage a UIImage, dándole así un UIImage que realmente tiene algunos bits (CGImage, un bitmap). Mi discusión aquí te da un código que demuestra:

http://www.apeth.com/iOSBook/ch15.html#_cifilter_and_ciimage

En otras palabras, en algún momento debe llamar a CIContext createCGImage:fromRect: para generar un CGImageRef desde la salida de su CIFilter, y pasar eso a un UIImage. Hasta que hagas eso, no tienes la salida de tus operaciones de filter como un UIImage real.

Alternativamente, puede dibujar la image de imageWithCIImage en un context de charts. Por ejemplo, puede dibujarlo en un context de charts de imágenes y luego usar esa image.

Lo que no puede hacer es mostrar la image de imageWithCIImage directamente. ¡Eso es porque no es una image! No tiene un bitmap subyacente (CGImage). No hay alli alli Todo lo que es es un set de instrucciones CIFilter para derivar la image.

Acabo de pasar todo el día en esto. Estaba recibiendo problemas de orientación, seguido de una producción de baja calidad.

Después de tomar una image con la camera, hago esto.

 NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer]; UIImage *image = [[UIImage alloc] initWithData:imageData]; 

Esto provoca un problema de rotation, así que necesitaba hacer esto.

 UIImage *scaleAndRotateImage(UIImage *image) { int kMaxResolution = image.size.height; // Or whatever CGImageRef imgRef = image.CGImage; CGFloat width = CGImageGetWidth(imgRef); CGFloat height = CGImageGetHeight(imgRef); CGAffineTransform transform = CGAffineTransformIdentity; CGRect bounds = CGRectMake(0, 0, width, height); if (width > kMaxResolution || height > kMaxResolution) { CGFloat ratio = width/height; if (ratio > 1) { bounds.size.width = kMaxResolution; bounds.size.height = bounds.size.width / ratio; } else { bounds.size.height = kMaxResolution; bounds.size.width = bounds.size.height * ratio; } } CGFloat scaleRatio = bounds.size.width / width; CGSize imageSize = CGSizeMake(CGImageGetWidth(imgRef), CGImageGetHeight(imgRef)); CGFloat boundHeight; UIImageOrientation orient = image.imageOrientation; switch(orient) { case UIImageOrientationUp: //EXIF = 1 transform = CGAffineTransformIdentity; break; case UIImageOrientationUpMirronetworking: //EXIF = 2 transform = CGAffineTransformMakeTranslation(imageSize.width, 0.0); transform = CGAffineTransformScale(transform, -1.0, 1.0); break; case UIImageOrientationDown: //EXIF = 3 transform = CGAffineTransformMakeTranslation(imageSize.width, imageSize.height); transform = CGAffineTransformRotate(transform, M_PI); break; case UIImageOrientationDownMirronetworking: //EXIF = 4 transform = CGAffineTransformMakeTranslation(0.0, imageSize.height); transform = CGAffineTransformScale(transform, 1.0, -1.0); break; case UIImageOrientationLeftMirronetworking: //EXIF = 5 boundHeight = bounds.size.height; bounds.size.height = bounds.size.width; bounds.size.width = boundHeight; transform = CGAffineTransformMakeTranslation(imageSize.height, imageSize.width); transform = CGAffineTransformScale(transform, -1.0, 1.0); transform = CGAffineTransformRotate(transform, 3.0 * M_PI / 2.0); break; case UIImageOrientationLeft: //EXIF = 6 boundHeight = bounds.size.height; bounds.size.height = bounds.size.width; bounds.size.width = boundHeight; transform = CGAffineTransformMakeTranslation(0.0, imageSize.width); transform = CGAffineTransformRotate(transform, 3.0 * M_PI / 2.0); break; case UIImageOrientationRightMirronetworking: //EXIF = 7 boundHeight = bounds.size.height; bounds.size.height = bounds.size.width; bounds.size.width = boundHeight; transform = CGAffineTransformMakeScale(-1.0, 1.0); transform = CGAffineTransformRotate(transform, M_PI / 2.0); break; case UIImageOrientationRight: //EXIF = 8 boundHeight = bounds.size.height; bounds.size.height = bounds.size.width; bounds.size.width = boundHeight; transform = CGAffineTransformMakeTranslation(imageSize.height, 0.0); transform = CGAffineTransformRotate(transform, M_PI / 2.0); break; default: [NSException raise:NSInternalInconsistencyException format:@"Invalid image orientation"]; } UIGraphicsBeginImageContext(bounds.size); CGContextRef context = UIGraphicsGetCurrentContext(); if (orient == UIImageOrientationRight || orient == UIImageOrientationLeft) { CGContextScaleCTM(context, -scaleRatio, scaleRatio); CGContextTranslateCTM(context, -height, 0); } else { CGContextScaleCTM(context, scaleRatio, -scaleRatio); CGContextTranslateCTM(context, 0, -height); } CGContextConcatCTM(context, transform); CGContextDrawImage(UIGraphicsGetCurrentContext(), CGRectMake(0, 0, width, height), imgRef); UIImage *imageCopy = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return imageCopy; } 

Luego, cuando aplique mi filter, hago esto (con un agradecimiento especial a este hilo, específicamente mate y Wex)

  -(UIImage*)processImage:(UIImage*)image { CIImage *inImage = [CIImage imageWithCGImage:image.CGImage]; CIFilter *filter = [CIFilter filterWithName:@"CIColorControls" keysAndValues: kCIInputImageKey, inImage, @"inputContrast", [NSNumber numberWithFloat:1.0], nil]; UIImage *outImage = [filter outputImage]; //Juicy bit CGImageRef cgimageref = [[CIContext contextWithOptions:nil] createCGImage:outImage fromRect:[outImage extent]]; return [UIImage imageWithCGImage:cgimageref]; }