CGImageCreateWithMask с изображением в качестве маски - PullRequest
0 голосов
/ 31 мая 2010

Я пытаюсь использовать изображение (270 градусов по кругу, похожее на логотип pacman, нарисованное как Core Graphics) для создания маски. Что я делаю, так это

1. создание основного графического пути

    CGContextSaveGState(context);
    CGContextBeginPath(context);
    CGContextMoveToPoint(context,circleCenter.x,circleCenter.y);
    //CGContextSetAllowsAntialiasing(myBitmapContext, YES);
    CGContextAddArc(context,circleCenter.x, circleCenter.y,circleRadius,startingAngle, endingAngle, 0); // 0 is counterclockwise
    CGContextClosePath(context);
    CGContextSetRGBStrokeColor(context,1.0,0.0,0.0,1.0);
    CGContextSetRGBFillColor(context,1.0,0.0,0.0,0.2);
    CGContextDrawPath(context, kCGPathFillStroke);

2. затем я создаю образ пути, который только что нарисовал путь

    CGImageRef pacmanImage              = CGBitmapContextCreateImage (context); 

3. восстановление контекста

CGContextRestoreGState(context);
CGContextSaveGState(context);

4. создание 1-битной маски (которая обеспечит черно-белую маску)

bitsPerComponent                    = 1;
bitsPerPixel                        = bitsPerComponent * 1 ;
bytesPerRow                         = (CGImageGetWidth(imgToMaskRef) * bitsPerPixel);
mask                                = CGImageCreate(CGImageGetWidth(imgToMaskRef), 
                                                CGImageGetHeight(imgToMaskRef), 
                                                bitsPerComponent,
                                                bitsPerPixel, 
                                                bytesPerRow, 
                                                greyColorSpace,
                                                kCGImageAlphaNone, 
                                                CGImageGetDataProvider(pacmanImage), 
                                                NULL, //decode
                                                YES, //shouldInterpolate
                                                kCGRenderingIntentDefault);

5. маскировка imgToMaskRef (который является CGImageRef imgToMaskRef = imgToMask.CGImage;) только что созданной маской

    imageMaskedWithImage                = CGImageCreateWithMask(imgToMaskRef, mask);
CGContextDrawImage(context,imgRectBox, imageMaskedWithImage);
CGImageRef maskedImageFinal         = CGBitmapContextCreateImage (context);

6. возвращая maskedImageFinal вызывающей стороне этого метода (как wheelChoiceMadeState, которая является CGImageRef), который затем обновляет свойство содержимого CALayer с изображением

 theLayer.contents                  = (id) wheelChoiceMadeState;

Проблема, которую я вижу, состоит в том, что маска не работает должным образом и выглядит очень странно. Я получаю странные узоры на пути, нарисованном Core Graphics. Я догадываюсь, что с CGImageGetDataProvider () что-то есть, но я не уверен.

Любая помощь будет оценена

спасибо

1 Ответ

1 голос
/ 31 мая 2010

CGImageGetDataProvider не изменяет данные вообще. Если данные pacmanImage точно не соответствуют параметрам, передаваемым в CGImageCreate (bitsPer, bytesPer, colorSpace, ...), результат не определен. Если он точно совпадает, не было бы смысла создавать маску.

Вам необходимо создать CGBitmapContext в градациях серого для рисования маски и CGImage, который использует те же пиксели и параметры, что и растровое изображение. Затем вы можете использовать CGImage, чтобы замаскировать другое изображение.

Используйте CGBitmapContextCreateImage только в том случае, если вам нужен снимок CGBitmapContext, который вы будете продолжать изменять. Для одноразового использования растрового изображения передайте тот же буфер в растровое изображение и соответствующий созданный вами CGImage.

Edit:

finalRect - размер, которым должно быть окончательное изображение. Он либо достаточно большой, чтобы вмещать исходное изображение, и pacman расположен внутри него, либо он достаточно большой, чтобы вмещать pacman, и исходное изображение обрезается для соответствия. В этом примере исходное изображение обрезается. В противном случае путь Pacman должен быть расположен относительно исходного изображения.

maskContext = CGBitmapContextCreate( ... , finalRect.size.width , finalRect.size.height , ... );
// add the pacman path and set the stroke and fill colors
CGContextDrawPath( maskContext , kCGPathFillStroke );
maskImage = CGBitmapContextCreateImage( maskContext );
imageToMask = CGImageCreateWithImageInRect( originalImage , finalRect );
finalImage = CGImageCreateWithMask( imageToMask , maskImage );
...