Вопрос по iphone – Обрезка изображения с прозрачностью в iPhone

22

Я работаю над игрой типа Jigsaw, где у меня есть два изображения для маскировки, Я реализовал этот код для маскировки

- (UIImage*) maskImage:(UIImage *)image withMaskImage:(UIImage*)maskImage {

    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGImageRef maskImageRef = [maskImage CGImage];

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

    CGImageRef newImage = CGBitmapContextCreateImage(mainViewContentContext);
    CGContextRelease(mainViewContentContext);

    UIImage *theImage = [UIImage imageWithCGImage:newImage];
    CGImageRelease(newImage);
    return theImage;
}

enter image description here

+

enter image description here

=

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

enter image description here

Теперь я хотел бы обрезать изображение в видеenter image description here а такжеenter image description here и так далее параметрически (обрезать изображение по прозрачности).

если кто-то реализовал такой код или какую-либо идею по этому сценарию, пожалуйста, поделитесь.

Благодарю.

Я использую эту строку кода какGuntis Treulands's предложение

int i=1;
    for (int x=0; x<=212; x+=106) {
        for (int y=0; y<318; y+=106) {
            CGRect rect = CGRectMake(x, y, 106, 106);
            CGRect rect2x = CGRectMake(x*2, y*2, 212, 212);

            UIImage *orgImg = [UIImage imageNamed:@"[email protected]"];
            UIImage *frmImg = [UIImage imageNamed:[NSString stringWithFormat:@"%[email protected]",i]];
            UIImage *cropImg = [self cropImage:orgImg withRect:rect2x];

            UIImageView *tmpImg = [[UIImageView alloc] initWithFrame:rect];
            [tmpImg setUserInteractionEnabled:YES];
            [tmpImg setImage:[self maskImage:cropImg withMaskImage:frmImg]];

            [self.view addSubview:tmpImg];
            i++;
        }
    }

orgImg - это оригинальное изображение кошки, общая рамка для хранения отдельного предмета, замаскированная в фотошопе, и cropImg - это 106x106 обрезанное изображение оригинального [email protected]

моя функция обрезки заключается в следующем

- (UIImage *) cropImage:(UIImage*)originalImage withRect:(CGRect)rect { 
    return [UIImage imageWithCGImage:CGImageCreateWithImageInRect([originalImage CGImage], rect)]; 
}
@ iCoder86: вы получили решение для обрезки изображения? Я тоже застрял с этим. Можете ли вы поделиться своим кодом, если он у вас работает? Kavya Indi
Я думаю, что лучший способ сделать это - замаскировать каждую фигуру, а затем создать новую картинку для каждой новой фигуры. Simon
@ Симон: Это то, что меня беспокоит, Как я могу обрезать изображение на куски с помощью прозрачности. iCoder86
@ iCoder86: у меня сейчас работает. Но новая проблема возникла, когда я применил к ней UIPanGesture. Обрезанные кусочки не получают кастрюлю с заданной формой, но в прямоугольной форме. Kavya Indi
@Harshal Извините, но я больше не работал над этим, я обязательно обновлю свой пост, как только обдумаю его. iCoder86

Ваш Ответ

1   ответ
17

UPDATE 2

Мне стало очень любопытно найти лучший способ создания головоломки, поэтому я провел два выходных и создал демонстрационный проектПазл.

Это содержит:

provide column/row count and it will generate necessary puzzle pieces with correct width/height. The more columns/rows - the smaller the width/height and outline/inline puzzle form. each time generate randomly sides can randomly position / rotate pieces at the beginning of launch each piece can be rotated by tap, or by two fingers (like a real piece) - but once released, it will snap to 90/180/270/360 degrees each piece can be moved if touched on its “touchable shape” boundary (which is mostly the - same visible puzzle shape, but WITHOUT inline shapes)

Недостатки:

no checking if piece is in its right place if more than 100 pieces - it starts to lag, because, when picking up a piece, it goes through all subviews until it finds correct piece.

UPDATE

Спасибо за обновленный вопрос.

Мне удалось получить это:

enter image description here

Как видите, элемент мозаики правильно обрезан, и он имеет квадратную форму.(green color is 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;
}

PREVIOUS ANSWER

Можете ли вы подготовить маску для каждого куска?

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

Пример - вторая часть маски:

enter image description here

Затем вы используете каждое из этих вновь созданных изображений маски на изображении кошки - каждый фрагмент маскирует все изображение, кроме одного мира. Таким образом, у вас будет 9 изображений с использованием 9 различных масок.

Для большей или другой рамки мозаики - снова создайте отдельные маски изображений.

Это базовое решение, но не идеальное, так как каждую маску мира нужно готовить отдельно.

Надеюсь, поможет..

Вы явно устанавливаете неправильную высоту и ширину, можете ли вы предоставить свой код?
@ Симон: см. Отредактированный вопрос. iCoder86
@GuntisTreulands: Привет! Это может быть отличной идеей для реализации +1, но не решает мой вопрос. В любом случае спасибо за ваше время .. iCoder86
это Treulands. Если это трудно переписать - скопируйте. Но в любом случае - действительно, ваш пример выглядит так, как будто у вас есть квадратные изображения, и изображения обрезаются, чтобы уместиться в квадрат. Возможно ли это (если вы еще не пробовали) - imageView.contentMode = UIViewContentModeScaleAspectFit; ?
Treilands: я уже реализовал то, что вы предложили, но у него такая же проблема обрезки, см. Изображение здесьi.stack.imgur.com/ZN9Qk.png iCoder86

Похожие вопросы