首先需要实现UIImagePickerControllerDelegate 代理 实现其imagePickerController 方法  这里用于选择图片或的拍照回调

//调用相机拍照 或者 图库选择
let picker = UIImagePickerController()
picker.sourceType = .camera //图库 .photoLibrary
picker.delegate = self
picker.allowsEditing = true #开启图片编辑裁剪 会有正方形的选框显示
UIApplication.shared.keyWindow?.rootViewController?.present(picker, animated: true, completion: nil) //图片回调方法
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
// 获取选择的裁剪后的图片 fixOrientation 处理旋转不正常问题 并压缩到300*300
let pickedImage = (info[UIImagePickerController.InfoKey.editedImage] as! UIImage).fixOrientation().scaleToSize(size: CGSize(width: 300, height: 300))
// 是否支持相册
if UIImagePickerController.isValidImagePickerType(type: UIImagePickerType.UIImagePickerTypePhotoLibrary) { // 相册
} else if (UIImagePickerController.isValidImagePickerType(type: UIImagePickerType.UIImagePickerTypeCamera)){ // 相机
// 图片保存到相册
UIImageWriteToSavedPhotosAlbum(pickedImage, self, Selector(("imageSave:error:contextInfo:")), nil)
}
//这里是个回调结构体 在使用的地方实现这个结构体即可获取到处理好的图片
if self.selectedImageBlock != nil {
self.selectedImageBlock!(pickedImage)
}
picker.dismiss(animated: true) {
}
} //取消图片选择框
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
picker.dismiss(animated: true, completion: nil)
}

  相关定义的方法

extension UIImage {
/// 修复图⽚旋转
func fixOrientation() -> UIImage {
if self.imageOrientation == .up {
return self
}
var transform = CGAffineTransform.identity
switch self.imageOrientation {
case .down, .downMirrored:
transform = transform.translatedBy(x: self.size.width, y: self.size.height)
transform = transform.rotated(by: .pi)
break
case .left, .leftMirrored:
transform = transform.translatedBy(x: self.size.width, y: 0)
transform = transform.rotated(by: .pi / 2)
break
case .right, .rightMirrored:
transform = transform.translatedBy(x: 0, y: self.size.height)
transform = transform.rotated(by: -.pi / 2)
break
default:
break
}
switch self.imageOrientation {
case .upMirrored, .downMirrored:
transform = transform.translatedBy(x: self.size.width, y: 0)
transform = transform.scaledBy(x: -1, y: 1)
break
case .leftMirrored, .rightMirrored:
transform = transform.translatedBy(x: self.size.height, y: 0);
transform = transform.scaledBy(x: -1, y: 1)
break
default:
break
}
let ctx = CGContext(data: nil, width: Int(self.size.width), height:
Int(self.size.height), bitsPerComponent: self.cgImage!.bitsPerComponent,
bytesPerRow: 0, space: self.cgImage!.colorSpace!, bitmapInfo:
self.cgImage!.bitmapInfo.rawValue)
ctx?.concatenate(transform)
switch self.imageOrientation {
case .left, .leftMirrored, .right, .rightMirrored:
ctx?.draw(self.cgImage!, in: CGRect(x: CGFloat(0), y: CGFloat(0), width:
CGFloat(size.height), height: CGFloat(size.width)))
break
default:
ctx?.draw(self.cgImage!, in: CGRect(x: CGFloat(0), y: CGFloat(0), width:
CGFloat(size.width), height: CGFloat(size.height)))
break
}
let cgimg: CGImage = (ctx?.makeImage())!
let img = UIImage(cgImage: cgimg)
return img
} //将图⽚裁剪成指定⽐例(多余部分⾃动删除)
func crop(ratio: CGFloat) -> UIImage {
//计算最终尺⼨
var newSize:CGSize!
if size.width/size.height > ratio {
newSize = CGSize(width: size.height * ratio, height: size.height)
}else{
newSize = CGSize(width: size.width, height: size.width / ratio)
} ////图⽚绘制区域
var rect = CGRect.zero
rect.size.width = size.width
rect.size.height = size.height
rect.origin.x = (newSize.width - size.width ) / 2.0
rect.origin.y = (newSize.height - size.height ) / 2.0 //绘制并获取最终图⽚
UIGraphicsBeginImageContext(newSize)
draw(in: rect)
let scaledImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return scaledImage!
} //压缩图⽚宽⾼
func scaleToSize(size:CGSize) -> UIImage{
UIGraphicsBeginImageContext(size)
self.draw(in: CGRect(x: 0, y: 0, width: size.width, height: size.height))
let scaledImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return scaledImage!
}
}
// 相机相关扩展类⽅法
import UIKit
import Photos
/// 相⽚选择器类型:相册 PhotoLibrary,图库 SavedPhotosAlbum,相机Camera,前置摄像头 Front,后置摄像头 Rear
public enum UIImagePickerType:Int {
/// 相册 PhotoLibrary
case UIImagePickerTypePhotoLibrary = 1
/// 图库 SavedPhotosAlbum
case UIImagePickerTypeSavedPhotosAlbum = 2
/// 相机 Camera
case UIImagePickerTypeCamera = 3
/// 前置摄像头 Front
case UIImagePickerTypeCameraFront = 4
/// 后置摄像头 Rear
case UIImagePickerTypeCameraRear = 5
}
extension UIImagePickerController {
// MARK: - 设备使⽤有效性判断
// 相册 PhotoLibrary,图库 SavedPhotosAlbum,相机 Camera,前置摄像头Front,后置摄像头 Rear
public class func isValidImagePickerType(type
imagePickerType:UIImagePickerType) -> Bool {
switch imagePickerType {
case .UIImagePickerTypePhotoLibrary:
if self.isValidPhotoLibrary {
return true
}
return false
case .UIImagePickerTypeSavedPhotosAlbum:
if self.isValidSavedPhotosAlbum {
return true
}
return false
case .UIImagePickerTypeCamera:
if self.isValidCameraEnable && self.isValidCamera {
return true
}
return false
case .UIImagePickerTypeCameraFront:
if self.isValidCameraEnable && self.isValidCameraFront {
return true
}
return false
case .UIImagePickerTypeCameraRear:
if self.isValidCamera && self.isValidCameraRear {
return true
}
return false
}
} /// 相机设备是否启⽤
public class var isValidCameraEnable:Bool{
get {
let cameraStatus =
AVCaptureDevice.authorizationStatus(for: AVMediaType.audio)
if cameraStatus == AVAuthorizationStatus.denied {
return false
}
return true
}
} /// 相机Camera是否可⽤(是否有摄像头)
public class var isValidCamera:Bool{
get {
if
UIImagePickerController.isSourceTypeAvailable(UIImagePickerController.Sourc
eType.camera){
return true
}
return false
}
} /// 前置相机是否可⽤
public class var isValidCameraFront:Bool{
get {
if
UIImagePickerController.isCameraDeviceAvailable(UIImagePickerController.Ca
meraDevice.front){
return true
}
return false
}
} /// 后置相机是否可⽤
public class var isValidCameraRear:Bool{
get {
if
UIImagePickerController.isCameraDeviceAvailable(UIImagePickerController.Ca
meraDevice.rear){
return true
}
return false
}
} /// 相册PhotoLibrary是否可⽤
public class var isValidPhotoLibrary:Bool{
get {
if
UIImagePickerController.isSourceTypeAvailable(UIImagePickerController.Sourc
eType.photoLibrary) {
return true
}
return false
}
} /// 图库SavedPhotosAlbum是否可⽤
public class var isValidSavedPhotosAlbum:Bool {
get {
if
UIImagePickerController.isSourceTypeAvailable(UIImagePickerController.Sourc
eType.savedPhotosAlbum) {
return true
}
return false
}
} // MARK: - 属性设置
func setImagePickerStyle(bgroundColor:UIColor?, titleColor:UIColor?,
buttonTitleColor:UIColor?) {
// 改navigationBar背景⾊
if let bgroundColor:UIColor = bgroundColor {
self.navigationBar.barTintColor = bgroundColor
} // 改navigationBar标题⾊
if let titleColor:UIColor = titleColor {
self.navigationBar.titleTextAttributes =
[NSAttributedString.Key.foregroundColor: titleColor]
} // 改navigationBar的button字体⾊
if let buttonTitleColor:UIColor = buttonTitleColor {
self.navigationBar.tintColor = buttonTitleColor
}
}
}

  

//拿到图片后我们使用ALamofire上传

//url 上传url地址
//image 需要上传的uiimage
//execute 回调函数
func upload(_ url:String,image:UIImage,execute:@escaping (Int,JSON) -> Void){
let headers:HTTPHeaders = [
"headerkey": "headerVal",
]
//Alamofire.upload(image.jpegData(compressionQuality: 0.5)!, to: url)
Alamofire.upload(multipartFormData: {(data) in
data.append(image.jpegData(compressionQuality: 0.6)!, withName: "file",fileName: "\(Date().timeIntervalSince1970).jpg",mimeType: "image/jpeg")
},to: url as URLConvertible,method: .post,headers: headers, encodingCompletion: {(result) in
switch result{
case .success(let upload,_,_):
upload.responseJSON{response in
guard let result = response.result.value else { return }
print("json:\(result)")
let json = JSON(result)
execute(json["code"].intValue,,nil)
}
break
case .failure(let err):
print(err)
execute(-1,nil)
break
}
print(result)
})
}

  

ios uiimagepickercontroller 选择相册或者拍照上传的更多相关文章

  1. 相册选择头像或者拍照 上传头像以NSData 图片二进制格式 表单上传

    一.点击头像图片 或者按钮 在相册选择照片返回img,网络上传头像要用data表单上传 (1)上传头像属性 // 图片二进制格式 表单上传 @property (nonatomic, strong) ...

  2. ios系统下,html5拍照上传的压缩处理

    http://gokercebeci.com/dev/canvasresize 通过canvas和base64的处理方式实现大尺寸照片的压缩和上传 介绍: https://github.com/zev ...

  3. Android选择系统相册或拍照上传

    PhotoUtils.rar

  4. 微信JS-SDK选择相册或拍照并上传PHP实现

    理解:微信上传接口是拍照,或者选择本地照片,上传到微信的服务器,获取到一个id,通过token与这个id获取到图片,保存到服务器即可. 效果 通过微信js接口,调用底层程序. 需要引入js文件,并进行 ...

  5. iOS拍照上传后,在web端显示旋转 Swift+OC版解决方案

    问题描述: 手机头像上传,遇到一个怪现象,就是拍照上传时,手机端显示头像正常,但在web端查看会有一个左旋90度的问题. 并且照片竖怕才会有此问题,横拍不存在. 原因分析: 手机拍照时,用相机拍摄出来 ...

  6. webAPP如何实现移动端拍照上传(Vue组件示例)?

    摘要:使用HTML5编写移动Web应用,主要是为了尝试一下“一套代码多处运行”,一个webapp几乎可以不加修改的运行在PC/Android/iOS等上面运行.但是写到现在觉得虽然这种方式弊大于利,不 ...

  7. 【Demo】HTML5 拍照上传

    本文主要讲解 手机浏览器 如何拍照 为什么会有这个需求 最近做一个项目要用到拍照然后上传照片,但是网页拍照一般都是用Flash做的,而我们主要是H5页面,如果在微信里面有权限就可以通过JSSDK调起摄 ...

  8. Android仿微信图片上传,可以选择多张图片,缩放预览,拍照上传等

    仿照微信,朋友圈分享图片功能 .可以进行图片的多张选择,拍照添加图片,以及进行图片的预览,预览时可以进行缩放,并且可以删除选中状态的图片 .很不错的源码,大家有需要可以下载看看 . 微信 微信 微信 ...

  9. Android与js交互拍照上传资料

    应用场景:h5通知android端拍照,选相册,然后将图片路径上传成功之后,获取到网络路径,将此路径返还给h5界面,并展示出来. android与js快速交互 效果图如下:   1.在Activity ...

随机推荐

  1. 七、React表单详解 约束性和非约束性组件 input text checkbox radio select textarea 以及获取表单的内容

    一.约束性和非约束性组件: 非约束性组: MV: <input type="text" defaultValue="a" /> 这个 default ...

  2. Apache nifi 第一篇(概述)

    1.什么是Apache NiFi? 简单地说,NiFi是为了自动化系统之间的数据流.虽然数据流这种形式很容易理解,但我们在此使用它来表示系统之间的自动化和不同系统之间数据的流转.企业拥有多个系统,其中 ...

  3. 线段树&树状数组与离散化的妙用

    牛客2019多校联盟Day7 Fine the median 题意:  每次给数组插入区间[Li,Ri] 内的所有数,每操作一次查询中位数. 遇到这题真的算是巧合,然而就是这种冥冥之中的缘分,给了我线 ...

  4. 将已有微信小程序转换为多端应用

    文档地址 https://nervjs.github.io/taro/

  5. UML图的种类

    一.作为一种建模语言,UML的定义包括UML语义和UML表示法两个部分. UML语义:描述基于UML的精确元模型定义. UML表示法:定义UML符号的表示法,为开发者或开发工具使用这些图形符号和文本语 ...

  6. BZOJ 2749 [HAOI2012]外星人

    题解:对每一个>2的质数分解,最后统计2的个数 注意:如果一开始没有2则ans需+1,因为第一次求phi的时候并没有消耗2 WA了好几遍 #include<iostream> #in ...

  7. java课程课后作业190502之单词统计

    自己想的方法一直都不是很好,但是又一直忘了改自己的算法,只能硬着头皮接着用自己以前的老方法了 第0步:输出某个英文文本文件中 26 字母出现的频率,由高到低排列,并显示字母出现的百分比,精确到小数点后 ...

  8. ng : File C:\Users\baron\AppData\Roaming\npm\ng.ps1 cannot be loaded because running

    一. Windos PowerShell 选择 管理员身份运行二.set-ExecutionPolicy RemoteSigned 然后更改权限为A 三.get-ExecutionPolicy 查看当 ...

  9. Codeforces 446C 线段树 递推Fibonacci公式

    聪哥推荐的题目 区间修改和区间查询,但是此题新颖之处就在于他的区间修改不是个定值,而是从L 到 R 分别加 F1.F2....Fr-l+1 (F为斐波那契数列) 想了一下之后,觉得用fib的前缀和来解 ...

  10. Android进阶——多线程系列之四大线程池的使用介绍

    线程池一直是初学者最抵触的东西,由于刚开始学习做项目并不会涉及到线程池的使用,但是不去学习它,心里又好像有个石头一直沉着,一直放心不下,其实是很简单的东西,早晚都要学,不如趁现在吧.由于文章从初学者的 ...