Создать маскирующий эффект над видом - PullRequest
1 голос
/ 09 июня 2010

Я хотел бы создать маскирующий эффект над UIView, чтобы выполнить следующее.Я выведу на экран запечатанную коробку, и пользователь сможет коснуться (поцарапать) экран, чтобы показать, что скрывается за этим изображением (UIView).Нечто похожее на те лотерейные билеты, где вы предполагаете поцарапать какой-нибудь материал для обложки, который в дополнение к результатам ..

Если бы кто-то мог указать мне правильное направление, было бы здорово, я не уверен, как начать делатьэто ...

спасибо

Ответы [ 2 ]

7 голосов
/ 11 января 2011

Извините, я опоздал. Я сделал пример кода, который может быть полезен: https://github.com/oyiptong/CGScratch

Подход

обращается к.

2 голосов
/ 09 июня 2010

Пиксельное редактирование обычно выполняется с помощью CGBitmapContext.В этом случае, я думаю, вы захотите создать растровое изображение в градациях серого, представляющее только альфа-канал рабочей области.Когда пользователь поцарапает, вы будете рисовать в этом растровом изображении.

Чтобы использовать GCBitmapContext в качестве маски для изображения, вы должны сначала создать маскирующее изображение из растрового изображения.Используйте CGImageMaskCreate и передайте поставщика данных, который указывает на те же пиксели, которые использовались для создания растрового изображения.Затем используйте CGImageCreateWithMask со скретч-изображением и изображением маски, которое является растровым изображением.

Вы не можете рисовать непосредственно в iPhone.Каждый раз, когда пользователь перемещает палец, вам нужно изменить растровое изображение маски, а затем сделать недействительным UIView, который рисует изображение.Возможно, вам просто удастся снова нарисовать одно и то же изображение, или вам может понадобиться восстанавливать маску и маскированное изображение каждый раз, когда вы рисуете.Пока изображение маски относится непосредственно к данным растрового пикселя, на самом деле выделяется очень мало памяти.

Итак, в psuedocode вы хотите что-то вроде этого:

scratchableImage = ...
width = CGImageGetWidth( scratchableImage );
height = CGImageGetHeight( scratchableImage );
colorspace = CGColorSpaceCreateDeviceGray();
pixels = CFDataCreateMutable( NULL , width * height );
bitmap = CFBitmapContextCreate( CFDataGetMutableBytePtr( pixels ) , width , height , 8 , width , colorspace , kCGImageAlphaNone );
provider = CGDataProviderCreateWithCFData( pixels );
mask = CGImageMaskCreate( width , height , 8 , 8 , width , provider , NULL , false , kCGRenderingIntentDefault );
scratched = CGImageCreateWithImageInRect( scratchableImage , mask );

На этом этапе scratched будет иметь альфа-канал, определяемый bitmap, но bitmap содержит данные для мусора.Белый pixels в растровом изображении непрозрачен, а черные пиксели прозрачны.Нарисуйте все белые пиксели в bitmap, затем, как пользователь поцарапал, нарисуйте черные пиксели.Я думаю, что изменения bitmap будут автоматически применяться при каждом рисовании scratched, но если нет, то просто воссоздайте mask и scratched каждый раз, когда вы рисуете.

Возможно, у вас есть пользовательский UIView дляотслеживание ввода пользователя.Вы можете получить свой собственный вид из UIImageView и позволить ему нарисовать изображение или сделать следующее:

-(void) drawRect:(CGRect)inDirty {
  // assume scratched is a member
  CGContextDrawImage( UIGraphicsGetCurrentContext() , [self bounds] , scratched );
}

В качестве альтернативы вы можете пропустить создание scratched и вместо этого использовать CGContextClipToMask и рисовать оригинал scratchableImage напрямую,Если нет scratchableImage, и ваша область царапин представляет собой иерархию текстур или представлений, воспользуйтесь этим подходом.

...