Search code examples
iosuiimagecalayerquartz-2d

How do I skew the lower section of a UIImage


I would like to skew the lower portion of a UIImage like this:

enter image description here

What would the best approach be?


Solution

  • Here's the solution I came up with. It divides the image in two and then shears the bottom one:

    CGFloat foldHeightInPercent = 0.9f;
    CGFloat totalHeight = 39;
    CGRect topImageRect = CGRectMake(0, 0, 50, totalHeight * foldHeightInPercent);
    
    //top image
    CGFloat scale = [[UIScreen mainScreen] scale];
    CGRect topCropRect = CGRectMake(0, 0, image.size.width * scale, image.size.height * foldHeightInPercent * scale);
    CGImageRef topImageRef = CGImageCreateWithImageInRect(image.CGImage, topCropRect);
    UIImageView *topImageView = [[UIImageView alloc] initWithFrame:topImageRect];
    [topImageView setImage:[UIImage imageWithCGImage:topImageRef]];
    CGImageRelease(topImageRef);    
    [self.view addSubview:topImageView];
    
    //bottom image
    CGRect bottomImageRect = CGRectMake(1, totalHeight * foldHeightInPercent, 50, totalHeight * (1.0f - foldHeightInPercent));
    CGFloat yPos = image.size.height * foldHeightInPercent * scale;
    CGRect bottomCropRect = CGRectMake(0, yPos, image.size.width * scale, image.size.height * (1.0f - foldHeightInPercent) * scale);
    CGImageRef bottomImageRef = CGImageCreateWithImageInRect(image.CGImage, bottomCropRect);
    UIImageView *bottomImageView = [[UIImageView alloc] initWithFrame:bottomImageRect];
    [bottomImageView setImage:[UIImage imageWithCGImage:bottomImageRef]];
    CGImageRelease(bottomImageRef);  
    
    CGFloat skewAngle = 20.0f;
    CGFloat skew = tan(skewAngle * M_PI / 180.f);
    CGAffineTransform t = CGAffineTransformMake(1.0, 0.0, skew, 1.0, 0.0, 0.0);
    bottomImageView.transform = t;
    [self.view addSubview:bottomImageView];