Подтвердить что ты не робот

Масштаб изображения основан на UIPinch

Я так смущен тем, как делать то, что мне нужно! Любая помощь очень ценится! У меня есть прозрачное изображение, на котором есть другое изображение, которое имеет UIPanGestureRecognizer и UIPinchGestureRecognizer, прикрепленные к нему. Верхнее изображение имеет полностью прозрачную середину, которая служит "стеклянным" видом. Я пытаюсь обрезать нижнее изображение на "стеклянную" часть, основанную на кастрюле и щепотке. (см. изображение ниже, чтобы увидеть, о чем я говорю) Я успешно позаботился об урожае панорамирования, но у меня проблемы с его обрезкой, когда применяется щепотка.

Я не использую snapshotViewAfterScreenUpdates.

Вот код, который у меня есть до сих пор:

 UIImage *snapshotImage;

/* draw the image of all the views below our view */
UIGraphicsBeginImageContextWithOptions(self.pendantImageView.bounds.size, NO, 0);
BOOL successfulDrawHierarchy = [self.pendantImageView drawViewHierarchyInRect:self.pendantImageView.bounds afterScreenUpdates:YES];
if ( successfulDrawHierarchy ) {
    snapshotImage = UIGraphicsGetImageFromCurrentImageContext();
} else {
    NSLog(@"drawViewHierarchyInRect:afterScreenUpdates: failed - there nothing to draw...");
}
UIGraphicsEndImageContext();
UIImage *croppedImage;
if ( successfulDrawHierarchy ) {

    /* calculate the coordinates of the rectangle we're interested in within the returned image */
    CGRect cropRect = CGRectOffset(pendantFrame, - self.pendantImageView.frame.origin.x, - self.pendantImageView.frame.origin.y);

    /* draw the cropped section with a clipping region */
    UIGraphicsBeginImageContextWithOptions(cropRect.size, YES, 0);
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextClipToRect(context, CGRectMake(0, 0, cropRect.size.width, cropRect.size.height));
    CGRect targetRectangeForCrop = CGRectMake(-cropRect.origin.x, -cropRect.origin.y, snapshotImage.size.width, snapshotImage.size.height);
    [snapshotImage drawInRect:targetRectangeForCrop];
    croppedImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();  
}

pendantImageView - это нижнее изображениеView и pendantFrame - это средние координаты области, в которой я пытаюсь обрезать.

Спасибо заранее!

обрезать изображение в область посередине

4b9b3361

Ответ 1

Я не уверен, правильно ли я понял вас, но вот мой результат:

(нажмите на видео, чтобы посмотреть полную версию)

Demo CountPages alpha

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    UIImageView *theImageView = [UIImageView new];
    [self.view addSubview:theImageView];
    theImageView.image = [UIImage imageNamed:@"image1.jpg"];
    theImageView.frame = self.view.frame;
    theImageView.userInteractionEnabled = YES;
    theImageView.alpha = 0.6;

    UIImageView *thePanImageView = [UIImageView new];
    [self.view addSubview:thePanImageView];
    thePanImageView.frame = CGRectMake(0, 0, 100, 100);
    thePanImageView.center = CGPointMake(theImageView.frame.size.width/2, theImageView.frame.size.height/2);
    thePanImageView.image = [self screenshotFromRect:thePanImageView.frame fromView:theImageView];
    thePanImageView.userInteractionEnabled = YES;
    thePanImageView.layer.cornerRadius = thePanImageView.frame.size.width/2;
    thePanImageView.clipsToBounds = YES;
    thePanImageView.theWeakObject = theImageView;
    {
        UIPanGestureRecognizer *thePanGesture = [UIPanGestureRecognizer new];
        [thePanGesture addTarget:self action:@selector(handlePanGesture:)];
        [thePanImageView addGestureRecognizer:thePanGesture];

        UIPinchGestureRecognizer *thePinchGesture = [UIPinchGestureRecognizer new];
        [thePinchGesture addTarget:self action:@selector(handlePinchGesture:)];
        [thePanImageView addGestureRecognizer:thePinchGesture];
    }
}

- (void)handlePanGesture:(UIPanGestureRecognizer *)thePanGesture
{
    UIImageView *thePanImageView = (id)thePanGesture.view;

    UIImageView *theImageView = thePanImageView.theWeakObject;
    thePanImageView.center = [thePanGesture locationInView:theImageView];

    thePanImageView.image = [self screenshotFromRect:thePanImageView.frame fromView:theImageView];
}

- (void)handlePinchGesture:(UIPinchGestureRecognizer *)thePinchGesture
{
    UIImageView *thePanImageView = (id)thePinchGesture.view;
    static CGRect theInitialFrame;
    if (thePinchGesture.state == UIGestureRecognizerStateBegan)
    {
        theInitialFrame = thePanImageView.frame;
    }
    else
    {
        CGRect theFrame = theInitialFrame;
        theFrame.size.width *= thePinchGesture.scale;
        theFrame.size.height *= thePinchGesture.scale;
        thePanImageView.frame = theFrame;
    }

    thePanImageView.layer.cornerRadius = thePanImageView.frame.size.width/2;

    UIImageView *theImageView = thePanImageView.theWeakObject;
    thePanImageView.center = [thePinchGesture locationInView:theImageView];

    thePanImageView.image = [self screenshotFromRect:thePanImageView.frame fromView:theImageView];
}

- (UIImage * __nonnull)screenshotFromRect:(CGRect)theRect fromView:(UIView * __nonnull)theView;
{
    if (!theView)
    {
        abort();
    }
    if (theRect.size.height < 1 || theRect.size.width < 1)
    {
        abort();
    }

    if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)])
    {
        UIGraphicsBeginImageContextWithOptions(theRect.size, YES, [UIScreen mainScreen].scale);
    }
    else
    {
        UIGraphicsBeginImageContext(theRect.size);
    }

    CGContextRef ctx = UIGraphicsGetCurrentContext();
    CGContextTranslateCTM(ctx, -theRect.origin.x, -theRect.origin.y);
    [theView.layer renderInContext:ctx];

    UIImage *snapshotImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return snapshotImage;
}

EDIT:

Вышеупомянутое решение неэффективно с точки зрения процессора, потому что при каждом просмотре просмотра он снимает скриншоты.

Более эффективным способом было бы создать дополнительный UIImageView и просто переместить его внутри вашего thePanImageView

Код следующий:

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    UIImageView *theImageView = [UIImageView new];
    [self.view addSubview:theImageView];
    theImageView.image = [UIImage imageNamed:@"image1.jpg"];
    theImageView.frame = self.view.frame;
    theImageView.userInteractionEnabled = YES;
    theImageView.alpha = 0.6;

    UIImageView *thePanImageView = [UIImageView new];
    [self.view addSubview:thePanImageView];
    thePanImageView.frame = CGRectMake(0, 0, 100, 100);
    thePanImageView.center = CGPointMake(theImageView.frame.size.width/2, theImageView.frame.size.height/2);
    thePanImageView.userInteractionEnabled = YES;
    thePanImageView.layer.cornerRadius = thePanImageView.frame.size.width/2;
    thePanImageView.clipsToBounds = YES;
    thePanImageView.layer.borderColor = [UIColor redColor].CGColor;
    thePanImageView.layer.borderWidth = 1;
    thePanImageView.theWeakObject = theImageView;
    {
        UIPanGestureRecognizer *thePanGesture = [UIPanGestureRecognizer new];
        [thePanGesture addTarget:self action:@selector(handlePanGesture:)];
        [thePanImageView addGestureRecognizer:thePanGesture];

        UIPinchGestureRecognizer *thePinchGesture = [UIPinchGestureRecognizer new];
        [thePinchGesture addTarget:self action:@selector(handlePinchGesture:)];
        [thePanImageView addGestureRecognizer:thePinchGesture];

        UIImageView *theExtraImageView = [UIImageView new];
        [thePanImageView addSubview:theExtraImageView];
        theExtraImageView.frame = CGRectMake(-thePanImageView.frame.origin.x, -thePanImageView.frame.origin.y, theImageView.frame.size.width, theImageView.frame.size.height);
        theExtraImageView.image = theImageView.image;
    }
}

- (void)handlePanGesture:(UIPanGestureRecognizer *)thePanGesture
{
    UIImageView *thePanImageView = (id)thePanGesture.view;

    UIImageView *theImageView = thePanImageView.theWeakObject;
    thePanImageView.center = [thePanGesture locationInView:theImageView];

    UIImageView *theExtraImageView = thePanImageView.subviews.firstObject;
    theExtraImageView.frame = CGRectMake(-thePanImageView.frame.origin.x, -thePanImageView.frame.origin.y, theExtraImageView.frame.size.width, theExtraImageView.frame.size.height);
}

- (void)handlePinchGesture:(UIPinchGestureRecognizer *)thePinchGesture
{
    UIImageView *thePanImageView = (id)thePinchGesture.view;
    static CGRect theInitialFrame;
    if (thePinchGesture.state == UIGestureRecognizerStateBegan)
    {
        theInitialFrame = thePanImageView.frame;
    }
    else
    {
        CGRect theFrame = theInitialFrame;
        theFrame.size.width *= thePinchGesture.scale;
        theFrame.size.height *= thePinchGesture.scale;
        thePanImageView.frame = theFrame;
    }

    thePanImageView.layer.cornerRadius = thePanImageView.frame.size.width/2;

    UIImageView *theImageView = thePanImageView.theWeakObject;
    thePanImageView.center = [thePinchGesture locationInView:theImageView];

    UIImageView *theExtraImageView = thePanImageView.subviews.firstObject;
    theExtraImageView.frame = CGRectMake(-thePanImageView.frame.origin.x, -thePanImageView.frame.origin.y, theExtraImageView.frame.size.width, theExtraImageView.frame.size.height);
}

FYI:

theWeakObject - это только мое настраиваемое свойство NSObject. Я использовал его, потому что был ленив и не хотел создавать глобально видимые @property

Ответ 2

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

CGContextClipToMask возвращает пустое изображение

вам нужно изменить:

CGContextClipToRect(context, CGRectMake(0, 0, cropRect.size.width, cropRect.size.height));

к чему-то вроде:

CGContextClipToMask(context, CGRectMake(0, 0, cropRect.size.width, cropRect.size.height), maskImage);