新聞中心
iOS選擇圖片發(fā)送到服務(wù)端圖片旋轉(zhuǎn)90度問(wèn)題
1、從手機(jī)系統(tǒng)相機(jī)豎向拍照,再在APP中選擇照片發(fā)送出去會(huì)有旋轉(zhuǎn)問(wèn)題;
創(chuàng)新互聯(lián)公司是一家專注于成都網(wǎng)站設(shè)計(jì)、成都網(wǎng)站建設(shè)、外貿(mào)網(wǎng)站建設(shè)與策劃設(shè)計(jì),港北網(wǎng)站建設(shè)哪家好?創(chuàng)新互聯(lián)公司做網(wǎng)站,專注于網(wǎng)站建設(shè)十載,網(wǎng)設(shè)計(jì)領(lǐng)域的專業(yè)建站公司;建站業(yè)務(wù)涵蓋:港北等地區(qū)。港北做網(wǎng)站價(jià)格咨詢:13518219792
2、從手機(jī)系統(tǒng)相機(jī)橫向拍照,再在APP中選擇照片發(fā)送出去沒(méi)問(wèn)題;
3、在相冊(cè)中對(duì)照片編輯操作再發(fā)送也沒(méi)有問(wèn)題。
4、我們用的TZImagePickerController選擇照片和視頻,里面第三方庫(kù)已經(jīng)處理這個(gè)旋轉(zhuǎn)90度問(wèn)題,為什么還有問(wèn)題?
iOS核心動(dòng)畫(huà)之圖片旋轉(zhuǎn)、脈沖動(dòng)畫(huà)、水波紋動(dòng)畫(huà)
下邊有整體效果,希望能幫助到你!
定義一個(gè)視圖
@property (weak, nonatomic) IBOutlet UIImageView *imageView;
一、圖片旋轉(zhuǎn)三種方式:
第一種:根據(jù)CGPathAddArc 繪畫(huà)圖片旋轉(zhuǎn)路線:
/*
1、#CGMutablePathRef? _Nullable path# 路線
2、確定圓心#CGFloat x# #CGFloat y#
3、半徑#CGFloat radius#
4、起點(diǎn) #CGFloat startAngle# 結(jié)束 #CGFloat endAngle#
*/
CGPathAddArc(path, NULL, self.view.center.x, self.view.center.y, 0.1, 0, M_PI *2, 1);
CAKeyframeAnimation * frameAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
frameAnimation.path= path;
CGPathRelease(path);
frameAnimation.delegate=self;
frameAnimation.duration=10;// 持續(xù)時(shí)間
frameAnimation.repeatCount = -1;// 重復(fù)次數(shù) 如果為0表示不執(zhí)行,-1表示不限制次數(shù),默認(rèn)為0
frameAnimation.autoreverses=NO;
frameAnimation.rotationMode = kCAAnimationRotateAuto;// 樣式
frameAnimation.fillMode = kCAFillModeForwards;
[self.imageView.layeraddAnimation:frameAnimationforKey:nil];
第二種:
[UIView animateWithDuration:20.0f animations:^{
? ? if (self.imageView) {
? ? ? ?self.imageView.transform = CGAffineTransformMakeRotation(M_PI*5);
?}
}];
第三種:
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
//默認(rèn)是順時(shí)針效果,若將fromValue和toValue的值互換,則為逆時(shí)針效果
animation.fromValue = [NSNumber numberWithFloat:0.f];
animation.toValue = [NSNumber numberWithFloat: M_PI *2];
animation.duration=30;
animation.autoreverses=NO;
animation.fillMode = kCAFillModeForwards;
animation.repeatCount = MAXFLOAT; //如果這里想設(shè)置成一直自旋轉(zhuǎn),可以設(shè)置為MAXFLOAT,否則設(shè)置具體的數(shù)值則代表執(zhí)行多少次
[self.imageView.layer addAnimation:animation forKey:nil];
持續(xù)旋轉(zhuǎn):
@property(nonatomic,assign) double angle;
CGAffineTransform endAngle = CGAffineTransformMakeRotation(self.angle * (M_PI / 180.0f));
[UIView animateWithDuration:0.01 delay:0 options:UIViewAnimationOptionCurveLinear animations:^{
? ? self.imageView.transform= endAngle;
}completion:^(BOOLfinished) {
? ? self.angle+=10;
? ? [self startAnimation2];// 上邊任意一種方法回調(diào)
}];
// 當(dāng)視圖停止轉(zhuǎn)動(dòng)時(shí)調(diào)用此方法重新轉(zhuǎn)動(dòng)
-(void)endAnimation {
self.angle+=4;
[self startAnimation2];
}
二、水波紋動(dòng)畫(huà)
屬性定義:幾個(gè)波紋定義幾個(gè)X 寬度可以用一個(gè) 也可以分開(kāi)定義
@property (weak, nonatomic) IBOutlet UIView *backView;
@property(nonatomic,strong) CAShapeLayer * waterLayer1;
@property(nonatomic,strong) CAShapeLayer * waterLayer2;
@property(nonatomic,assign) CGFloat x;
@property(nonatomic,assign) CGFloat y;
@property(nonatomic,assign) CGFloat waveHeight;
@property(nonatomic,assign) CGFloat waveWidth;
@property(nonatomic,assign) int speedWave;
@property(nonatomic,assign) CGFloat waveAmplitude;
@property(nonatomic,assign) int speed;
@property(nonatomic,assign) CGFloat speed_H;
@property(nonatomic,assign) CGFloat offsetXT;
-(instancetype)init {// 給個(gè)初始值,下邊被除數(shù)不能為0
if (self == [super init]) {
self.speedWave = 3;
self.waveAmplitude = 3;
self.speed=3;
self.waveWidth = self.backView.frame.size.width;
self.waveHeight = self.backView.frame.size.height;
self.speed_H = self.backView.frame.size.height-20;
}
return self;
}
-(void)waterAnimation {
//? ? CGFloat y = _waveHeight*sinf(2.5*M_PI*i/_waveWidth + 3*_offset*M_PI/_waveWidth + M_PI/4) + _h;
self.waterLayer1 = [CAShapeLayer layer];
self.waterLayer1.fillColor = [UIColor yellowColor].CGColor;
[self.backView.layer addSublayer:self.waterLayer1];
self.waterLayer2 = [CAShapeLayer layer];
self.waterLayer2.fillColor = [UIColor redColor].CGColor;
[self.backView.layer addSublayer: self.waterLayer2];
//創(chuàng)建一個(gè)新的 CADisplayLink 對(duì)象,把它添加到一個(gè)runloop中,并給它提供一個(gè) target 和selector 在屏幕刷新的時(shí)候調(diào)用
//CADispayLink相當(dāng)于一個(gè)定時(shí)器 會(huì)一直繪制曲線波紋 看似在運(yùn)動(dòng),其實(shí)是一直在繪畫(huà)不同位置點(diǎn)的余弦函數(shù)曲線
CADisplayLink * waveDisplayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(getCurrentWave)];
[waveDisplayLinkaddToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
}
-(void)getCurrentWave {
// x位置
self.x+=self.speed;
//聲明第一條波曲線的路徑
CGMutablePathRef path = CGPathCreateMutable();
//設(shè)置起始點(diǎn)
CGPathMoveToPoint(path,nil,0,self.waveHeight);
CGFloaty =0.f;
//第一個(gè)波紋的公式
for(floatx =0.f; x =self.waveWidth; x++) {
? ? y =self.waveAmplitude*sin((200/self.waveWidth) * (x *M_PI/70) -self.x*M_PI/170) +self.speed_H*1;
? ? CGPathAddLineToPoint(path,nil, x, y);
? ? x++;
}
//把繪圖信息添加到路徑里
CGPathAddLineToPoint(path, nil, self.waveWidth, self.backView.frame.size.height);
CGPathAddLineToPoint(path, nil, 0, self.backView.frame.size.height);
//結(jié)束繪圖信息
CGPathCloseSubpath(path);
self.waterLayer1.path= path;
//釋放繪圖路徑
CGPathRelease(path);
[self? ? X2];
}
/// 第二條水波
-(void)X2 {
self.offsetXT += self.speedWave;
CGMutablePathRef pathT = CGPathCreateMutable();
CGPathMoveToPoint(pathT,nil,0,self.waveHeight+50);
CGFloatyT =0.f;
for(floatx =0.f; x =self.waveWidth; x++) {
? ? yT =self.waveAmplitude*1.6*sin((200/self.waveWidth) * (x *M_PI/100) -self.offsetXT*M_PI/170) +self.waveHeight;
? ? CGPathAddLineToPoint(pathT,nil, x, yT-10);
}
CGPathAddLineToPoint(pathT, nil, self.waveWidth, self.backView.frame.size.height);
CGPathAddLineToPoint(pathT, nil, 0, self.backView.frame.size.height);
CGPathCloseSubpath(pathT);
self.waterLayer2.path= pathT;
CGPathRelease(pathT);
}
三、脈沖效果動(dòng)畫(huà)
@property (weak, nonatomic) IBOutlet UIView *pulseView;
@property(nonatomic,strong) CAShapeLayer * pulseLayer;
-(void)pulseAnimation {
CGFloat width = self.pulseView.bounds.size.width;
self.pulseLayer = [CAShapeLayer layer];
self.pulseLayer.bounds=CGRectMake(0,0, width, width);
self.pulseLayer.position=CGPointMake(width/2, width/2);
self.pulseLayer.backgroundColor = [UIColor clearColor].CGColor;
self.pulseLayer.path = [UIBezierPath bezierPathWithOvalInRect:self.pulseLayer.bounds].CGPath;
self.pulseLayer.fillColor = [UIColor colorWithRed: 0.3490196078 green:0.737254902 blue:0.8039215686 alpha:1].CGColor;
self.pulseLayer.opacity = 0.0;
CAReplicatorLayer * replicatorLayer = [CAReplicatorLayer layer];
replicatorLayer.bounds=CGRectMake(0,0, width, width);
replicatorLayer.position=CGPointMake(width/2, width/2);
replicatorLayer.instanceCount=4;// 復(fù)制層
replicatorLayer.instanceDelay=1;/// 頻率
[replicatorLayeraddSublayer:self.pulseLayer];
[self.pulseView.layeraddSublayer:replicatorLayer];
[self.pulseView.layerinsertSublayer:replicatorLayeratIndex:0];
}
-(void)startPulseAnimation {
CABasicAnimation * opacityAnimation = [CABasicAnimation animationWithKeyPath:@"opacity"];
opacityAnimation.fromValue=@20;// 起始值 (strong 修飾的id值)
opacityAnimation.toValue=@30;// 結(jié)束值(strong 修飾的id值)
CABasicAnimation * scaleAnimation = [CABasicAnimation animationWithKeyPath:@"transform"];
scaleAnimation.fromValue = [NSValue valueWithCATransform3D:CATransform3DScale(CATransform3DIdentity, 0.0, 0.0, 0.0)];
scaleAnimation.toValue =[NSValue valueWithCATransform3D:CATransform3DScale(CATransform3DIdentity, 1.0, 1.0, 1.0)];
CAAnimationGroup * groupAnimation = [CAAnimationGroup animation];
groupAnimation.animations=@[opacityAnimation, scaleAnimation];
groupAnimation.duration=20;
groupAnimation.autoreverses=NO;
groupAnimation.repeatCount=HUGE;
[self.pulseLayeraddAnimation:groupAnimationforKey:nil];
}
在此附上效果:
聽(tīng)說(shuō)有好得三方庫(kù),我還沒(méi)有去找過(guò),歡迎各位大佬推薦一個(gè)優(yōu)質(zhì)的三方。。。。。
喜歡的朋友點(diǎn)個(gè)贊唄!
ios圖片旋轉(zhuǎn)
根據(jù)Orientation判斷圖片的方向,在把圖片旋轉(zhuǎn)回來(lái)
1:0°,
3:180°
6:順時(shí)針90°,
8:逆時(shí)針90°
也可以利用 exif.js快速處理
iOS 圖片的同時(shí)旋轉(zhuǎn)縮放
最近項(xiàng)目中的一個(gè)小需求,要求圖片同時(shí)進(jìn)行旋轉(zhuǎn)和縮放兩種操作,做一個(gè)簡(jiǎn)單的總結(jié),先看下效果圖:
originalPoint 為旋轉(zhuǎn)縮放的參考點(diǎn)比例,默認(rèn)是按視圖中心旋轉(zhuǎn),即
self.originalPoint = CGPointMake(0.5, 0.5)
然后就是正常的操作,注意,在縮放的時(shí)候,四個(gè)角的控制按鈕要相反的放縮,保證大小不變,如果有其他元素,同理。
在控制按鈕上添加平移手勢(shì),記錄每一次平移的點(diǎn) ctrlPoint ,以及上一個(gè)平移點(diǎn),就是 self.lastCtrlPoint
旋轉(zhuǎn)的角度,根據(jù)上一個(gè)平移點(diǎn)和視圖中心點(diǎn)的角度,與當(dāng)前平移點(diǎn)和視圖中心點(diǎn)的角度偏差,進(jìn)行transform處理。
縮放也是類似,計(jì)算上一個(gè)平移點(diǎn)與中心點(diǎn)的距離 preDistance ,以及當(dāng)前平移點(diǎn)和中心點(diǎn)的距離 newDistance ,那么兩次平移距離的比例,就是視圖縮放的比例。這里做了一個(gè)判斷,在縮小到一半時(shí)停止繼續(xù)變小。
GitHub:
新聞名稱:ios開(kāi)發(fā)圖片旋轉(zhuǎn),ios圖片自動(dòng)旋轉(zhuǎn)
標(biāo)題鏈接:http://fisionsoft.com.cn/article/dsdehhc.html