iOS-圖片拼接和圖片旋轉問題
阿新 • • 發佈:2019-02-18
背景:
開發中的時候,美工姐姐讓我做一條虛線包住一個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。這個也是我比較喜歡的一種做法。