iOS – CoreImage: agrega un efecto a una image parcial

Solo echar un vistazo a CoreImage framework en iOS 5, encontró que es fácil agregar un efecto a la image completa. Me pregunto si es posible agregar un efecto en una parte especial de la image (un rectángulo). por ejemplo, agregar efecto de escala de grises en una parte de la image /

Espero su ayuda.

Gracias, Huy

Mira la session 510 de los videos de la WWDC 2012. Presentan una técnica de cómo aplicar una máscara a un CIImage . Necesita aprender a encadenar los filters. En particular, eche un vistazo a:

  • CICrop , CILinearGradient , CIRadialGradient (se podría usar para crear la máscara)
  • CISourceOverCompositing (poner imágenes de máscara juntas)
  • CIBlendWithMask (cree la image final)

Ejemplo: caras de Pixelate

Los filters están documentados aquí:

https://developer.apple.com/library/mac/#documentation/graphicsimaging/reference/CoreImageFilterReference/Reference/reference.html

Su mejor opción sería copyr el CIImage (por lo que ahora tiene dos), recortar el CIImage copydo en el rectángulo que desea efectuar, realizar el efecto en esa versión recortada y luego usar un efecto de superposition para crear un nuevo CIImage basado en el dos viejos CIImages.

Parece un gran esfuerzo, pero cuando entiendes que todo esto está configurado como un montón de sombreadores de GPU, tiene mucho más sentido.

  typedef enum { ALPHA = 0, BLUE = 1, GREEN = 2, RED = 3 

} PIXELS;

 - (UIImage *)convertToGrayscale:(UIImage *) originalImage inRect: (CGRect) rect{ CGSize size = [originalImage size]; int width = size.width; int height = size.height; // the pixels will be painted to this array uint32_t *pixels = (uint32_t *) malloc(width * height * sizeof(uint32_t)); // clear the pixels so any transparency is preserved memset(pixels, 0, width * height * sizeof(uint32_t)); CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); // create a context with RGBA pixels CGContextRef context = CGBitmapContextCreate(pixels, width, height, 8, width * sizeof(uint32_t), colorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedLast); // paint the bitmap to our context which will fill in the pixels array CGContextDrawImage(context, CGRectMake(0, 0, width, height), [originalImage CGImage]); for(int y = 0; y < height; y++) { for(int x = 0; x < width; x++) { uint8_t *rgbaPixel = (uint8_t *) &pixels[y * width + x]; if(x > rect.origin.x && y > rect.origin.y && x < rect.origin.x + rect.size.width && y < rect.origin.y + rect.size.height) { // convert to grayscale using recommended method: http://en.wikipedia.org/wiki/Grayscale#Converting_color_to_grayscale uint32_t gray = 0.3 * rgbaPixel[RED] + 0.59 * rgbaPixel[GREEN] + 0.11 * rgbaPixel[BLUE]; // set the pixels to gray in your rect rgbaPixel[RED] = gray; rgbaPixel[GREEN] = gray; rgbaPixel[BLUE] = gray; } } } // create a new CGImageRef from our context with the modified pixels CGImageRef image = CGBitmapContextCreateImage(context); // we're done with the context, color space, and pixels CGContextRelease(context); CGColorSpaceRelease(colorSpace); free(pixels); // make a new UIImage to return UIImage *resultUIImage = [UIImage imageWithCGImage:image]; // we're done with image now too CGImageRelease(image); return resultUIImage; 

}

Puedes probarlo en un UIImageView:

  imageview.image = [self convertToGrayscale:imageview.image inRect:CGRectMake(50, 50, 100, 100)];