Ответ 1
ОБНОВЛЕНИЕ 2
Мне стало очень любопытно найти лучший способ создания головоломки, поэтому я провел два выходных и создал демо-проект Jigsaw puzzle.
Он содержит:
- укажите количество столбцов/строк, и оно будет генерировать необходимые кусочки головоломки с правильной шириной/высотой. Чем больше столбцов/строк - тем меньше ширина/высота и контурная/встроенная головоломка.
- каждый раз генерируют случайные стороны
- может случайно позиционировать/вращать фигуры в начале запуска
- каждая деталь может поворачиваться краном или двумя пальцами (как реальная часть), но после отпускания она будет привязываться к 90/180/270/360 градусов
- каждая деталь может быть перемещена, если коснуться ее границы "осязаемой формы" (которая в основном представляет собой ту же видимую форму головоломки, но БЕЗ встроенных фигур).
Недостатки:
- не проверяется, находится ли кусок в нужном месте.
- если более 100 штук - он начинает отставать, потому что, когда выбираете кусок, он проходит через все подпункты, пока не найдет правильный фрагмент.
UPDATE
Спасибо за обновленный вопрос.
Мне это удалось:
Как вы можете видеть - элемент головоломки обрезается правильно, и он находится в квадрате imageView (зеленый цвет - это UIImageView backgroundColor).
Итак - что я сделал:
CGRect rect = CGRectMake(105, 0, 170, 170); //~ location on cat image where second Jigsaw item will be.
UIImage *originalCatImage = [UIImage imageNamed:@"cat.png"];//original cat image
UIImage *jigSawItemMask = [UIImage imageNamed:@"JigsawItemNo2.png"];//second jigsaw item mask (visible in my answer) (same width/height as cat image.)
UIImage *fullJigSawItemImage = [jigSawItemMask maskImage:originalCatImage];//masking - so that from full cat image would be visible second jigsaw item
UIImage *croppedJigSawItemImage = [self fullJigSawItemImage withRect:rect];//cropping so that we would get small image with jigsaw item centered in it.
Для маскирования изображений я использую функцию категории UIImage: (но вы, вероятно, можете использовать свою маскирующую функцию, но я все равно отправлю ее.)
- (UIImage*) maskImage:(UIImage *)image
{
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
UIImage *maskImage = self;
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;
}
ПРЕДЫДУЩИЙ ОТВЕТ
Можете ли вы подготовить маску для каждой части?
Например, у вас есть это изображение кадра. Можете ли вы разрезать его в Photoshop в 9 отдельных изображениях, где на каждом изображении будет отображаться только соответствующая фигура. (все остальное - удалить).
Пример - вторая часть маски:
Затем вы используете каждое из этих вновь созданных изображений маски на изображении cat - каждая часть будет маскировать все изображение, но один мир. Таким образом, у вас будет 9 штук изображений с использованием 9 различных масок.
Для большего или другого фрейма головоломки - снова создайте отдельные маски изображений.
Это базовое решение, но не идеальное, так как вам нужно подготовить каждую маска по отдельности.
Надеюсь, что это поможет.