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.

32
demandé sur ToolmakerSteve 2009-08-21 06:01:51

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 ).

89
répondu Eric 2018-03-09 14:30:38
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];
19
répondu Tyler 2012-06-18 19:36:43

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;
}
9
répondu Jason TEPOORTEN 2017-05-23 11:54:25

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();
4
répondu SAKrisT 2010-07-06 17:13:48

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
        }
    }
}
3
répondu skymook 2016-11-12 12:32:29

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() .

1
répondu Rob Napier 2009-08-21 03:25:07

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.

0
répondu fbrereto 2009-08-21 02:52:17