1. 程式人生 > >iOS-圖片拼接和圖片旋轉問題

iOS-圖片拼接和圖片旋轉問題

背景:

開發中的時候,美工姐姐讓我做一條虛線包住一個WebView,但是,她給我的虛線只有兩個小節那麼長。我就很納悶,給我這麼短的虛線,我怎麼顯示啊?當時,我就想到拼接圖片的做法。圖片拼接是解決了長度問題,但是方向問題還沒解決啊。我想到就是圖片旋轉。往下看,你就知道怎麼回事了。果然,這樣是可以的。如果你懶,那你叫美工姐姐給你重新切一個完全符合你的圖咯。

實際情況

美工姐姐給我的圖是這樣的:

這裡寫圖片描述

然而,她讓我做出來的效果是這樣的:

這裡寫圖片描述

給我的圖片只有水平的兩個小結那麼長,要我做出一個包裹住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 <UIKit/UIKit.h>

@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




效果圖:
這裡寫圖片描述

額外提示

細心的小夥伴,你可能會發現,包裹住WebView的虛線,兩個拐角是有點圓的。之前呢,我想著是改變線條的layer實現圓角的做法,實際上不太理想。但是,這個肯定是能做的,至於要實現拐角處像圖片那麼圓,layer的半徑慢慢去除錯吧,反正我是放棄了。
另一種做法呢,就是用一個UIView包裹住裡面的線條和WebView。然後直接取改變這個大的UIView的layer。這個也是我比較喜歡的一種做法。