J'essaie de mélanger un arrière-plan avec une image de premier plan, où l'image de 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.
Voici ce que j'ai fait dans mon application, similaire à 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à l'opacité, vous n'avez pas besoin de la définir (comme dans bottomImage
) sinon vous pouvez la 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 de l'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ée 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
Cette fonction prendra deux images et un CGSize
et renverra un UIImage
facultatif. Cela fonctionne mieux lorsque les deux images sont de la même taille. Si votre image supérieure a alpha, elle montrera 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
}
tilisation
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 fournir des détails sur ce que vous entendez par "cela ne semble pas fonctionner?" Dessine-t-il une seule image ou l'autre image? Dessiner en noir? Bruit? Crash? Pourquoi avez-vous choisi kCGBlendModeSourceIn
; quel effet essayez-vous d'obtenir (il existe des dizaines de façons de mélanger les images)? L'une de vos images contient-elle déjà de l'alpha?
Je suppose que ce que vous essayez de faire est de mélanger deux images de sorte que chacune ait une opacité de 50%? Utilisez CGContextSetAlpha()
pour cela plutôt que CGContextSetBlendMode()
.
Vous pouvez utiliser UIImage
's drawInRect:
ou drawAtPoint:
au lieu de CGContextDrawImage (ils dessinent dans le contexte actuel). Leur utilisation vous donne-t-elle une différence de sortie?
Il peut également être utile de s'assurer que UIImage*
valeurs dont vous récupérez imageNamed:
sont valides.