iOS-图片拼接和图片旋转问题

背景:

开发中的时候,美工姐姐让我做一条虚线包住一个WebView,但是,她给我的虚线只有两个小节那么长。我就很纳闷,给我这么短的虚线,我怎么显示啊?当时,我就想到拼接图片的做法。图片拼接是解决了长度问题,但是方向问题还没解决啊。我想到就是图片旋转。往下看,你就知道怎么回事了。果然,这样是可以的。如果你懒,那你叫美工姐姐给你重新切一个完全符合你的图咯。


实际情况

美工姐姐给我的图是这样的:

iOS-图片拼接和图片旋转问题_第1张图片

然而,她让我做出来的效果是这样的:

iOS-图片拼接和图片旋转问题_第2张图片

给我的图片只有水平的两个小结那么长,要我做出一个包裹住UIWebView的框框。水平方向,直接拼接图片就能解决。竖直方向嘛,先让图片旋转90度,然后再拼接旋转之后的图片就好啦~~~


解决办法

拼接图片核心代码:

UIGraphicsBeginImageContextWithOptions(useImage.size ,NO, 0.0);
//这里才是主要,看你要拼接的位置
[maskImage drawInRect:CGRectMake(X, Y, W, H)];
//这里的图片就是拼接完成的图片
    UIImage *resultingImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

旋转图片核心代码:

+(UIImage *)image:(UIImage *)image rotation:(UIImageOrientation)orientation
{
    long double rotate = 0.0;
    CGRect rect;
    float translateX = 0;
    float translateY = 0;
    float scaleX = 1.0;
    float scaleY = 1.0;

    switch (orientation) {
        case UIImageOrientationLeft:
            rotate = M_PI_2;
            rect = CGRectMake(0, 0, image.size.height, image.size.width);
            translateX = 0;
            translateY = -rect.size.width;
            scaleY = rect.size.width/rect.size.height;
            scaleX = rect.size.height/rect.size.width;
            break;
        case UIImageOrientationRight:
            rotate = 3 * M_PI_2;
            rect = CGRectMake(0, 0, image.size.height, image.size.width);
            translateX = -rect.size.height;
            translateY = 0;
            scaleY = rect.size.width/rect.size.height;
            scaleX = rect.size.height/rect.size.width;
            break;
        case UIImageOrientationDown:
            rotate = M_PI;
            rect = CGRectMake(0, 0, image.size.width, image.size.height);
            translateX = -rect.size.width;
            translateY = -rect.size.height;
            break;
        default:
            rotate = 0.0;
            rect = CGRectMake(0, 0, image.size.width, image.size.height);
            translateX = 0;
            translateY = 0;
            break;
    }

    UIGraphicsBeginImageContext(rect.size);
    CGContextRef context = UIGraphicsGetCurrentContext();
    //做CTM变换
    CGContextTranslateCTM(context, 0.0, rect.size.height);
    CGContextScaleCTM(context, 1.0, -1.0);
    CGContextRotateCTM(context, rotate);
    CGContextTranslateCTM(context, translateX, translateY);

    CGContextScaleCTM(context, scaleX, scaleY);
    //绘制图片
    CGContextDrawImage(context, CGRectMake(0, 0, rect.size.width, rect.size.height), image.CGImage);

    UIImage *newPic = UIGraphicsGetImageFromCurrentImageContext();

    return newPic;
}

完整例子

//
//  ViewController.m
//  pinjie
//
//  Created by HZhenF on 2017/9/8.
//  Copyright © 2017年 GZHYTechnology. All rights reserved.
//

#import "ViewController.h"
#import "UIImage+Extension.h"

#define ScreenW [UIScreen mainScreen].bounds.size.width
#define ScreenH [UIScreen mainScreen].bounds.size.height

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

    //原始的图片
    UIImage *originImage = [UIImage imageNamed:@"组-221"];

    CGFloat padding = 5;
    CGFloat lineWOrH = 2;

    CGFloat W = ScreenW - 2*lineWOrH - 2*padding;
    CGFloat H = 200;
    CGFloat X = (ScreenW - W) * 0.5;
    CGFloat Y = ScreenH - H;
    UIWebView *webView = [[UIWebView alloc] initWithFrame:CGRectMake(X, Y, W, H)];
    NSURL *url = [NSURL URLWithString:@"https://www.baidu.com"];
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
    [webView loadRequest:request];
    [self.view addSubview:webView];

    CGFloat topImageViewX = 0;
    CGFloat topImageViewW = ScreenW;
    CGFloat topImageViewH = lineWOrH;
    CGFloat topImageViewY = CGRectGetMinY(webView.frame) - padding - lineWOrH;
    UIImageView *topImageView = [[UIImageView alloc] initWithFrame:CGRectMake(topImageViewX, topImageViewY, topImageViewW, topImageViewH)];
    topImageView.image = [UIImage imageAddLocalImage:originImage addMsakImage:originImage loopTimes:7 rotation:UIImageOrientationUp];
    [self.view addSubview:topImageView];


    CGFloat leftImageViewX = 0;
    CGFloat leftImageViewY = ScreenH - H - padding;
    CGFloat leftImageViewW = lineWOrH;
    CGFloat leftImageViewH = ScreenH - leftImageViewY;
    UIImageView *leftImageView = [[UIImageView alloc] initWithFrame:CGRectMake(leftImageViewX, leftImageViewY, leftImageViewW, leftImageViewH)];
    //旋转后的图片
    UIImage *leftOrientImg = [UIImage image:originImage rotation:UIImageOrientationRight];
    leftImageView.image = [UIImage imageAddLocalImage:leftOrientImg addMsakImage:leftOrientImg loopTimes:4 rotation:UIImageOrientationLeft];
    [self.view addSubview:leftImageView];

    CGFloat rightImageViewX = ScreenW - 2;
    CGFloat rightImageViewY = CGRectGetMinY(leftImageView.frame);
    CGFloat rightImageViewW = CGRectGetWidth(leftImageView.frame);
    CGFloat rightImageViewH = CGRectGetHeight(leftImageView.frame);
    UIImageView *rightImageView = [[UIImageView alloc] initWithFrame:CGRectMake(rightImageViewX, rightImageViewY, rightImageViewW, rightImageViewH)];
    //旋转后的图片
    UIImage *rightOrientImg = [UIImage image:originImage rotation:UIImageOrientationLeft];
    rightImageView.image = [UIImage imageAddLocalImage:rightOrientImg addMsakImage:rightOrientImg loopTimes:4 rotation:UIImageOrientationRight];
    [self.view addSubview:rightImageView];

}


- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}


@end
//
//  UIImage+Extension.h
//  pinjie
//
//  Created by HZhenF on 2017/9/8.
//  Copyright © 2017年 GZHYTechnology. All rights reserved.
//

#import 

@interface UIImage (Extension)

/**
 将图片旋转

 @param image 要旋转的图片
 @param orientation 图片旋转方向
 @return 旋转之后的图片
 */
+(UIImage *)image:(UIImage *)image rotation:(UIImageOrientation)orientation;

/**
 把图片合成

 @param useImage 当前图片
 @param maskImage 要合成的图片
 @param loopTimes 要合成的次数
 @param orientation 当前的方向
 @return 合成完成的图片
 */
+(UIImage *)imageAddLocalImage:(UIImage *)useImage addMsakImage:(UIImage *)maskImage loopTimes:(NSInteger)loopTimes rotation:(UIImageOrientation)orientation;

@end
//
//  UIImage+Extension.m
//  pinjie
//
//  Created by HZhenF on 2017/9/8.
//  Copyright © 2017年 GZHYTechnology. All rights reserved.
//

#import "UIImage+Extension.h"

@implementation UIImage (Extension)

+(UIImage *)image:(UIImage *)image rotation:(UIImageOrientation)orientation
{
    long double rotate = 0.0;
    CGRect rect;
    float translateX = 0;
    float translateY = 0;
    float scaleX = 1.0;
    float scaleY = 1.0;

    switch (orientation) {
        case UIImageOrientationLeft:
            rotate = M_PI_2;
            rect = CGRectMake(0, 0, image.size.height, image.size.width);
            translateX = 0;
            translateY = -rect.size.width;
            scaleY = rect.size.width/rect.size.height;
            scaleX = rect.size.height/rect.size.width;
            break;
        case UIImageOrientationRight:
            rotate = 3 * M_PI_2;
            rect = CGRectMake(0, 0, image.size.height, image.size.width);
            translateX = -rect.size.height;
            translateY = 0;
            scaleY = rect.size.width/rect.size.height;
            scaleX = rect.size.height/rect.size.width;
            break;
        case UIImageOrientationDown:
            rotate = M_PI;
            rect = CGRectMake(0, 0, image.size.width, image.size.height);
            translateX = -rect.size.width;
            translateY = -rect.size.height;
            break;
        default:
            rotate = 0.0;
            rect = CGRectMake(0, 0, image.size.width, image.size.height);
            translateX = 0;
            translateY = 0;
            break;
    }

    UIGraphicsBeginImageContext(rect.size);
    CGContextRef context = UIGraphicsGetCurrentContext();
    //做CTM变换
    CGContextTranslateCTM(context, 0.0, rect.size.height);
    CGContextScaleCTM(context, 1.0, -1.0);
    CGContextRotateCTM(context, rotate);
    CGContextTranslateCTM(context, translateX, translateY);

    CGContextScaleCTM(context, scaleX, scaleY);
    //绘制图片
    CGContextDrawImage(context, CGRectMake(0, 0, rect.size.width, rect.size.height), image.CGImage);

    UIImage *newPic = UIGraphicsGetImageFromCurrentImageContext();

    return newPic;
}

+(UIImage *)imageAddLocalImage:(UIImage *)useImage addMsakImage:(UIImage *)maskImage loopTimes:(NSInteger)loopTimes rotation:(UIImageOrientation)orientation
{

    UIGraphicsBeginImageContextWithOptions(useImage.size ,NO, 0.0);
    //四个参数为水印图片的位置
    //如果要多个位置显示,继续drawInRect就行
    switch (orientation) {
        case UIImageOrientationUp:
            for (int i = 0; i < loopTimes; i ++)
            {
                CGFloat X = useImage.size.width/loopTimes*i;
                CGFloat W = useImage.size.width/loopTimes;
                CGFloat H = useImage.size.height;
                CGFloat Y = 0;
                [maskImage drawInRect:CGRectMake(X, Y, W, H)];
            }
            break;
        case UIImageOrientationLeft :
            for (int i = 0; i < loopTimes; i ++)
            {
                CGFloat X = 0;
                CGFloat W = useImage.size.width;
                CGFloat H = useImage.size.height / loopTimes;
                CGFloat Y = useImage.size.height / loopTimes * i;
                [maskImage drawInRect:CGRectMake(X, Y, W, H)];
            }
            break;
        case UIImageOrientationRight:
            for (int i = 0; i < loopTimes; i ++)
            {
                CGFloat X = 0;
                CGFloat W = useImage.size.width;
                CGFloat H = useImage.size.height / loopTimes;
                CGFloat Y = useImage.size.height / loopTimes * i;
                [maskImage drawInRect:CGRectMake(X, Y, W, H)];
            }
            break;

        default:
            break;



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

@end




效果图:
iOS-图片拼接和图片旋转问题_第3张图片


额外提示

细心的小伙伴,你可能会发现,包裹住WebView的虚线,两个拐角是有点圆的。之前呢,我想着是改变线条的layer实现圆角的做法,实际上不太理想。但是,这个肯定是能做的,至于要实现拐角处像图片那么圆,layer的半径慢慢去调试吧,反正我是放弃了。
另一种做法呢,就是用一个UIView包裹住里面的线条和WebView。然后直接取改变这个大的UIView的layer。这个也是我比较喜欢的一种做法。

你可能感兴趣的:(iOS-控件详解,iOS-系统类的详解)