mezcla dos uiimages basadas en alfa / transparencia de la imagen superior

Intento mezclar un fondo con una imagen de primer plano, donde la imagen de primer plano es una imagen transparente con líneas.

Estoy tratando de hacerlo de esta manera.

UIGraphicsBeginImageContext(CGSizeMake(320, 480)); CGContextRef context = UIGraphicsGetCurrentContext(); // create rect that fills screen CGRect bounds = CGRectMake( 0,0, 320, 480); // This is my bkgnd image CGContextDrawImage(context, bounds, [UIImage imageNamed:@"bkgnd.jpg"].CGImage); CGContextSetBlendMode(context, kCGBlendModeSourceIn); // This is my image to blend in CGContextDrawImage(context, bounds, [UIImage imageNamed:@"over.png"].CGImage); UIImage *outputImage = UIGraphicsGetImageFromCurrentImageContext(); UIImageWriteToSavedPhotosAlbum(outputImage, self, nil, nil); // clean up drawing environment // UIGraphicsEndImageContext(); 

pero parece no funcionar

Cualquier sugerencia será apreciada.

Esto es lo que hice en mi aplicación, similar a la de Tyler, pero sin UIImageView :

 UIImage *bottomImage = [UIImage imageNamed:@"bottom.png"]; UIImage *image = [UIImage imageNamed:@"top.png"]; CGSize newSize = CGSizeMake(width, height); UIGraphicsBeginImageContext( newSize ); // Use existing opacity as is [bottomImage drawInRect:CGRectMake(0,0,newSize.width,newSize.height)]; // Apply supplied opacity [image drawInRect:CGRectMake(0,0,newSize.width,newSize.height) blendMode:kCGBlendModeNormal alpha:0.8]; UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); 

Si la imagen ya tiene opacidad, no necesita configurarla (como en la imagen bottomImage ), de lo contrario, puede configurarla (como con la image ).

 UIImage* bottomImage = [UIImage imageNamed:@"bottom.png"]; UIImage* topImage = [UIImage imageNamed:@"top.png"]; UIImageView* imageView = [[UIImageView alloc] initWithImage:bottomImage]; UIImageView* subView = [[UIImageView alloc] initWithImage:topImage]; subView.alpha = 0.5; // Customize the opacity of the top image. [imageView addSubview:subView]; UIGraphicsBeginImageContext(imageView.frame.size); [imageView.layer renderInContext:UIGraphicsGetCurrentContext()]; UIImage* blendedImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); [subView release]; [imageView release]; [self doWhateverIWantWith: blendedImage]; 

mi respuesta se basa en la respuesta de Eric , pero permite que las imágenes @ 2x conserven su resolución después de la fusión de la imagen. Tenga en cuenta la URL REF en mis comentarios, ya que estoy reconociendo las fonts que contribuyeron a la asistencia para el desarrollo de esta función que utilicé en mis aplicaciones de iOS.

 - (UIImage*) mergeTwoImages : (UIImage*) topImage : (UIImage*) bottomImage { // URL REF: http://iphoneincubator.com/blog/windows-views/image-processing-tricks // URL REF: https://stackoverflow.com/questions/1309757/blend-two-uiimages?answertab=active#tab-top // URL REF: http://www.waterworld.com.hk/en/blog/uigraphicsbeginimagecontext-and-retina-display int width = bottomImage.size.width; int height = bottomImage.size.height; CGSize newSize = CGSizeMake(width, height); static CGFloat scale = -1.0; if (scale<0.0) { UIScreen *screen = [UIScreen mainScreen]; if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 4.0) { scale = [screen scale]; } else { scale = 0.0; // Use the standard API } } if (scale>0.0) { UIGraphicsBeginImageContextWithOptions(newSize, NO, scale); } else { UIGraphicsBeginImageContext(newSize); } [bottomImage drawInRect:CGRectMake(0,0,newSize.width,newSize.height)]; [topImage drawInRect:CGRectMake(0,0,newSize.width,newSize.height) blendMode:kCGBlendModeNormal alpha:1.0]; UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return newImage; } 

Mezclando con alfa

 UIGraphicsBeginImageContext(area.size); CGContextRef context = UIGraphicsGetCurrentContext(); CGContextRetain(context); // mirroring context CGContextTranslateCTM(context, 0.0, area.size.height); CGContextScaleCTM(context, 1.0, -1.0); for (...) { CGContextBeginTransparencyLayer(context, nil); CGContextSetAlpha( context, alpha ); CGContextDrawImage(context, area, tempimg.CGImage); CGContextEndTransparencyLayer(context); } // get created image UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); CGContextRelease(context); UIGraphicsEndImageContext(); 

Swift 3

Esta función tomará dos imágenes, y un CGSize y devolverá un UIImage opcional. Funciona mejor cuando ambas imágenes son del mismo tamaño. Si su imagen superior tiene alfa, mostrará la imagen inferior a través de ella.

 // composit two images func compositeTwoImages(top: UIImage, bottom: UIImage, newSize: CGSize) -> UIImage? { // begin context with new size UIGraphicsBeginImageContextWithOptions(newSize, false, 0.0) // draw images to context bottom.draw(in: CGRect(origin: CGPoint.zero, size: newSize)) top.draw(in: CGRect(origin: CGPoint.zero, size: newSize)) // return the new image let newImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() // returns an optional return newImage } 

Uso

 let outputSize = CGSize(width: 100, height: 100) if let topImage = UIImage(named: "myTopImage") { if let bottomImage = UIImage(named: "myBottomImage") { // composite both images if let finalImage = compositeTwoImages(top: topImage, bottom: bottomImage, newSize: outputSize) { // do something with finalImage } } } 

¿Puedes proporcionar detalles sobre lo que quieres decir con “parece que no funciona”? ¿Dibuja solo una imagen o la otra imagen? Dibujar negro? ¿Ruido? ¿Choque? ¿Por qué has elegido kCGBlendModeSourceIn ; ¿Qué efecto estás tratando de lograr (hay docenas de formas de combinar imágenes)? ¿Alguna de tus imágenes ya tiene alfa?

Supongo que lo que estás tratando de hacer es mezclar dos imágenes para que cada una tenga un 50% de opacidad. Use CGContextSetAlpha() para eso en lugar de CGContextSetBlendMode() .

Puede usar drawInRect: UIImage drawInRect: o drawAtPoint: lugar de CGContextDrawImage (dibujan en el contexto actual). ¿Usarlos te da alguna diferencia en la producción?

También puede ser útil asegurarse de que los valores de UIImage* que obtiene de imageNamed: sean válidos.