Pytanie Tworzenie maski z CGImageMaskCreate jest czarne (iphone)


Próbuję utworzyć maskę obrazu, która pochodzi z dwóch istniejących obrazów.

Najpierw rozpoczynam od utworzenia kompozytu, który składa się z małego obrazu, który jest obrazem maskującym, oraz większego obrazu, który ma taki sam rozmiar jak tło:

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

Mogę wydrukować ten UIImage (MaskImageFull) i wygląda na to, że jest to pełnowymiarowy rozmiar tła i jest to białe tło z moim obiektem maski w kolorze czarnym, we właściwym miejscu na ekranie.

Następnie przekazuję UIImage MaskImageFull poprzez:

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

Problem polega na tym, że retImage jest cały czarny. Jeśli wyślesz gotowy UIImage jako maskę, działa dobrze, to właśnie kiedy próbuję zrobić to z wielu obrazów, które zepsuł.

Myślałem, że to coś w przestrzeni kolorów, ale nie mogłem tego naprawić. Każda pomoc jest doceniana!


14
2018-03-11 01:57


pochodzenie




Odpowiedzi:


Próbowałem tego samego z CGImageCreateWithMask i otrzymałem ten sam wynik. Rozwiązaniem, które znalazłem, było użycie CGContextClipToMask zamiast:

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;

19
2018-03-11 11:25



Pomógł mi bardzo. Czy możesz dodać nagłówek i stopkę funkcji, aby ją skompletować? - Eden
Czym dokładnie jest thumbnailPoint.x? @catlan - Reza.Ab
@ Reza.Ab przepraszam, nie pamiętam. scaled * również wygląda dziwnie 9 lat później. W większości przypadków zakładam mask rect, a obraz rect powinien być taki sam. Wypróbuj go i daj nam znać, co znajdziesz, - catlan


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

4
2018-05-18 11:40



Naprawdę nie działa ... - Reza.Ab


Obraz, który ma być maskowany MUSI zostać utworzony za pomocą kanału alfa. Kanał alfa nie może zostać utworzony z kodu.


1
2017-10-26 15:01