14

Sto provando a creare una maschera immagine che da un composito di due immagini esistenti.Creazione di una maschera con CGImageMaskCreate è tutto nero (iphone)

Prima che inizia con la creazione del composito che consiste di una piccola immagine che rappresenta l'immagine della chiusura, ed un'immagine ingrandita che è la stessa dimensione come sfondo:

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

posso uscita questo UIImage (MaskImageFull) e sembra giusto, è una dimensione di sfondo a tutto schermo ed è uno sfondo bianco con il mio oggetto maschera in nero, nel posto giusto sullo schermo.

Ho poi passare il MaskImageFull UIImage attraverso questo:

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]; 

Il problema è che il retImage è tutto nero. Se invio una UIImage preimpostata come maschera funziona correttamente, è proprio quando provo a farla da più immagini che si rompe.

Ho pensato che fosse una cosa dello spazio dei colori ma non riuscivo a risolverlo. Ogni aiuto è molto apprezzato!

risposta

19

Ho provato la stessa cosa con CGImageCreateWithMask e ho ottenuto lo stesso risultato. La soluzione che ho trovato è stato quello di utilizzare CGContextClipToMask invece:

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; 
+1

Mi ha aiutato moltissimo. Potresti aggiungere l'intestazione e il piè di pagina della funzione per completarla? – Eden

+0

Che cosa è thumbnailPoint.x esattamente ??! @catlan –

+0

@ Reza.Abbiace, non ricordo. ridimensionato * sembra strano anche 9 anni dopo. Presumo nella maggior parte dei casi la maschera rect e l'immagine rect dovrebbe essere la stessa. Per favore provalo e facci sapere cosa trovi, – catlan

1

l'immagine da mascherare deve essere creato con un canale alfa. Il canale Alpha non può essere creato dal codice.

4
- (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; 
} 
+0

Non funziona davvero ... –

Problemi correlati