Question

J'essaie de créer un masque d'image à partir d'un composite de deux images existantes.

Je commence par créer le composite qui consiste en une petite image qui est l'image masquante et une image plus grande de la même taille que l'arrière-plan:

UIImage * BaseTextureImage = [UIImage imageNamed:@"background.png"];
UIImage * MaskImage = [UIImage imageNamed:@"my_mask.jpg"];
UIImage * ShapesBase = [UIImage imageNamed:@"largerimage.jpg"];
UIImage * MaskImageFull;

CGSize finalSize = CGSizeMake(480.0, 320.0);
UIGraphicsBeginImageContext(finalSize);
[ShapesBase drawInRect:CGRectMake(0, 0, 480, 320)];
[MaskImage drawInRect:CGRectMake(150, 50, 250, 250)];
MaskImageFull = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

Je peux sortir cet UIImage (MaskImageFull) et cela semble bon, c'est une taille d'arrière-plan taille réelle et il y a un arrière-plan blanc avec mon objet masque en noir, au bon endroit sur l'écran.

Je passe ensuite le MaskImageFull UIImage à travers ceci:

CGImageRef maskRef = [maskImage CGImage];
CGImageRef mask = CGImageMaskCreate(CGImageGetWidth(maskRef),
    CGImageGetHeight(maskRef),
    CGImageGetBitsPerComponent(maskRef),
    CGImageGetBitsPerPixel(maskRef),
    CGImageGetBytesPerRow(maskRef),
    CGImageGetDataProvider(maskRef), NULL, false);

CGImageRef masked = CGImageCreateWithMask([image CGImage], mask);
UIImage* retImage= [UIImage imageWithCGImage:masked];

Le problème est que retImage est tout noir. Si j’envoie un UIImage prédéfini en tant que masque, il fonctionne correctement, c’est au moment même où j’essaie de le créer à partir de plusieurs images qu’il se brise.

Je pensais que c'était une question d'espace colorimétrique, mais je n'arrivais pas à résoudre le problème. Toute aide est très appréciée!

Était-ce utile?

La solution

J'ai essayé la même chose avec CGImageCreateWithMask et obtenu le même résultat. La solution que j'ai trouvée consistait à utiliser CGContextClipToMask à la place:

CGContextRef mainViewContentContext;
CGColorSpaceRef colorSpace;

colorSpace = CGColorSpaceCreateDeviceRGB();

// create a bitmap graphics context the size of the image
mainViewContentContext = CGBitmapContextCreate (NULL, targetSize.width, targetSize.height, 8, 0, colorSpace, kCGImageAlphaPremultipliedLast);

// free the rgb colorspace
CGColorSpaceRelease(colorSpace);    

if (mainViewContentContext==NULL)
    return NULL;

CGImageRef maskImage = [[UIImage imageNamed:@"mask.png"] CGImage];
CGContextClipToMask(mainViewContentContext, CGRectMake(0, 0, targetSize.width, targetSize.height), maskImage);
CGContextDrawImage(mainViewContentContext, CGRectMake(thumbnailPoint.x, thumbnailPoint.y, scaledWidth, scaledHeight), self.CGImage);


// Create CGImageRef of the main view bitmap content, and then
// release that bitmap context
CGImageRef mainViewContentBitmapContext = CGBitmapContextCreateImage(mainViewContentContext);
CGContextRelease(mainViewContentContext);

// convert the finished resized image to a UIImage 
UIImage *theImage = [UIImage imageWithCGImage:mainViewContentBitmapContext];
// image is retained by the property setting above, so we can 
// release the original
CGImageRelease(mainViewContentBitmapContext);

// return the image
return theImage;

Autres conseils

- (UIImage*) maskImage:(UIImage *)image {

    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();

    UIImage *maskImage = [UIImage imageNamed:@"MaskFinal.png"];
    CGImageRef maskImageRef = [maskImage CGImage];

    // create a bitmap graphics context the size of the image
    CGContextRef mainViewContentContext = CGBitmapContextCreate (NULL, maskImage.size.width, maskImage.size.height, 8, 0, colorSpace, kCGImageAlphaPremultipliedLast);


    if (mainViewContentContext==NULL)
        return NULL;

    CGFloat ratio = 0;

    ratio = maskImage.size.width/ image.size.width;

    if(ratio * image.size.height < maskImage.size.height) {
        ratio = maskImage.size.height/ image.size.height;
    } 

    CGRect rect1  = {{0, 0}, {maskImage.size.width, maskImage.size.height}};
    CGRect rect2  = {{-((image.size.width*ratio)-maskImage.size.width)/2 , -((image.size.height*ratio)-maskImage.size.height)/2}, {image.size.width*ratio, image.size.height*ratio}};


    CGContextClipToMask(mainViewContentContext, rect1, maskImageRef);
    CGContextDrawImage(mainViewContentContext, rect2, image.CGImage);


    // Create CGImageRef of the main view bitmap content, and then
    // release that bitmap context
    CGImageRef newImage = CGBitmapContextCreateImage(mainViewContentContext);
    CGContextRelease(mainViewContentContext);

    UIImage *theImage = [UIImage imageWithCGImage:newImage];

    CGImageRelease(newImage);

    // return the image
    return theImage;
}

L'image à masquer DOIT être créée avec un canal alpha. Le canal alpha ne peut pas être créé à partir du code.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top