14

Я пытаюсь создать маску изображения из композита из двух существующих изображений.Создание маски с CGImageMaskCreate все черное (iphone)

Сначала я начать с создания композитного материала, который состоит из небольшого изображения, которое является маскировка изображения, и увеличенное изображение, которое имеет такой же размер, как фон:

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

я может выводить этот UIImage (MaskImageFull), и это выглядит правильно, это полноэкранный размер фона, и это белый фон с моим объектом маски в черном, в нужном месте на экране.

Я затем передать MaskImageFull UIImage через это:

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

Проблема заключается в том, что retImage все черное. Если я отправлю готовый UIImage в качестве маски, он отлично работает, это просто, когда я пытаюсь сделать это из нескольких изображений, которые он ломает.

Я думал, что это была вещь в цветовом пространстве, но, похоже, ее не исправить. Любая помощь высоко ценится!

ответ

19

Я пробовал то же самое с CGImageCreateWithMask и получил тот же результат. Решение, которое я нашел в том, чтобы использовать вместо CGContextClipToMask:

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

Помогло мне очень. Не могли бы вы добавить верхний и нижний колонтитул функции, чтобы завершить? – Eden

+0

Что такое thumbnailPoint.x точно ??! @catlan –

+0

@ Reza.Ab извините, я не помню. scaled * также выглядит странно 9 лет спустя. Я предполагаю, что в большинстве случаев маска rect и прямоугольник изображения должны быть одинаковыми. Пожалуйста, попробуйте его и сообщите нам, что вы найдете, – catlan

1

изображение, чтобы быть замаскирован должен быть создан с альфа-каналом. Альфа-канал не может быть создан из кода.

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

Не работает действительно ... –