iphone - transparente - mezcla dos uiimages basadas en alpha/transparencia de la imagen superior
gimp transparentar fondo (7)
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.
¿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()
.
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
).
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();
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.
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 fuentes 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://.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;
}
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
}
}
}
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];