mélanger deux uiimages basés sur alpha / transparence de l'image supérieure
j'essaie de mélanger un fond avec une image au premier plan, où l'image au premier plan est une image transparente avec des lignes dessus.
j'essaie de le faire de cette façon.
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();
mais ne semble pas fonctionner.
toute suggestion sera appréciée.
7 réponses
C'est ce que j'ai fait dans mon application, similaire à celle de Tyler - mais sans le 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 l'image a déjà opacité, vous n'avez pas besoin de le mettre (comme dans bottomImage
) sinon vous pouvez définir (comme avec 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];
ma réponse est basée sur la réponse D'Eric , mais permet aux images @2x de conserver leur résolution après la fusion d'image. Veuillez noter L'URL REF dans mes commentaires, car je reconnais les sources qui ont contribué à mon développement de cette fonction que j'ai utilisé dans Mes Applications 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;
}
mélange avec alpha
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
cette fonction prendra deux images, et un CGSize
et retournera un optionnel UIImage
. Il fonctionne mieux lorsque les deux images sont de la même taille. Si votre image supérieure a alpha, elle affichera l'image inférieure à travers elle.
// 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
}
Utilisation
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
}
}
}
pouvez-vous préciser ce que vous entendez par "cela ne semble pas fonctionner?"Ne dessine-t-il qu'une image ou l'autre? Dessiner noir? Le bruit? Crash? Pourquoi avez-vous choisi kCGBlendModeSourceIn
; quel effet essayez-vous d'obtenir (il y a des dizaines de façons de mélanger les images)? Ne l'une de vos images alpha déjà?
je suppose que ce que vous essayez de faire est de mélanger deux images de sorte que chacune a 50% d'opacité? Utilisez CGContextSetAlpha()
pour cela plutôt que CGContextSetBlendMode()
.
vous pouvez utiliser UIImage
's drawInRect:
ou drawAtPoint:
au lieu de CGContextDrawImage (ils dessinent au contexte actuel). Leur utilisation vous donne-t-elle des résultats différents?
il peut également être utile de s'assurer que les valeurs UIImage*
que vous obtenez de imageNamed:
sont valides.