问题描述:

手机头像上传,遇到一个怪现象,就是拍照上传时,手机端显示头像正常,但在web端查看会有一个左旋90度的问题。

并且照片竖怕才会有此问题,横拍不存在。

原因分析:

手机拍照时,用相机拍摄出来的照片是含有EXIF信息的,在我们得到 UIImage时,可以查看此Image的imageOrientation属性,其实就是指的EXIF中的orientation信息。

如果我们忽略orientation信息,而直接对照片进行像素处理或上传等操作,得到的结果是翻转或者旋转90之后的样子。

这是因为我们执行像素处理或者drawInRect等操作之后,imageOrientaion信息被删除了,imageOrientaion被重设为0,造成照片内容和imageOrientaion不匹配。

所以,在对照片进行处理之前,先将照片旋转到正确的方向,保证返回的imageOrientaion为0。

解决方法:

Swift版:

  1. /**
  2. 照片竖拍 web显示旋转解决:图片大于2M会自动旋转90度
  3.  
  4. - parameter aImage: <#aImage description#>
  5.  
  6. - returns: <#return value description#>
  7. */
  8. class func fixOrientation(aImage:UIImage)->UIImage {
  9. if aImage.imageOrientation == UIImageOrientation.Up{
  10. return aImage
  11. }
  12.  
  13. var transform = CGAffineTransformIdentity
  14.  
  15. switch (aImage.imageOrientation) {
  16. case .Down,.DownMirrored:
  17. transform = CGAffineTransformTranslate(transform, aImage.size.width, aImage.size.height)
  18. transform = CGAffineTransformRotate(transform, CGFloat(M_PI))
  19. break;
  20.  
  21. case .Left,.LeftMirrored:
  22. transform = CGAffineTransformTranslate(transform, aImage.size.width, 0)
  23. transform = CGAffineTransformRotate(transform, CGFloat(M_PI_2))
  24. break;
  25.  
  26. case .Right,.RightMirrored:
  27. transform = CGAffineTransformTranslate(transform, 0, aImage.size.height)
  28. transform = CGAffineTransformRotate(transform, CGFloat(-M_PI_2))
  29. break;
  30. default:
  31. break;
  32. }
  33.  
  34. switch (aImage.imageOrientation) {
  35. case .UpMirrored,.DownMirrored:
  36. transform = CGAffineTransformTranslate(transform, aImage.size.width, 0)
  37. transform = CGAffineTransformScale(transform, -1, 1)
  38. break;
  39.  
  40. case .LeftMirrored,.RightMirrored:
  41. transform = CGAffineTransformTranslate(transform, aImage.size.height, 0)
  42. transform = CGAffineTransformScale(transform, -1, 1)
  43. break;
  44. default:
  45. break;
  46. }
  47.  
  48. let ctx:CGContextRef = CGBitmapContextCreate(nil, Int(aImage.size.width), Int(aImage.size.height),
  49. CGImageGetBitsPerComponent(aImage.CGImage), 0,
  50. CGImageGetColorSpace(aImage.CGImage),
  51. 1)!
  52.  
  53. CGContextConcatCTM(ctx, transform)
  54. switch (aImage.imageOrientation) {
  55. case .Left,.LeftMirrored,.Right,.RightMirrored:
  56. CGContextDrawImage(ctx, CGRectMake(0,0,aImage.size.height,aImage.size.width), aImage.CGImage)
  57. break;
  58.  
  59. default:
  60. CGContextDrawImage(ctx, CGRectMake(0,0,aImage.size.width,aImage.size.height), aImage.CGImage);
  61. break;
  62. }
  63.  
  64. let cgimg:CGImageRef = CGBitmapContextCreateImage(ctx)!
  65. let img:UIImage = UIImage(CGImage: cgimg)
  66. return img;
  67. }

  

OC版:

  1. - (UIImage *)fixOrientation:(UIImage *)aImage {
  2.  
  3. // No-op if the orientation is already correct
  4. if (aImage.imageOrientation == UIImageOrientationUp)
  5. return aImage;
  6.  
  7. // We need to calculate the proper transformation to make the image upright.
  8. // We do it in 2 steps: Rotate if Left/Right/Down, and then flip if Mirrored.
  9. CGAffineTransform transform = CGAffineTransformIdentity;
  10.  
  11. switch (aImage.imageOrientation) {
  12. case UIImageOrientationDown:
  13. case UIImageOrientationDownMirrored:
  14. transform = CGAffineTransformTranslate(transform, aImage.size.width, aImage.size.height);
  15. transform = CGAffineTransformRotate(transform, M_PI);
  16. break;
  17.  
  18. case UIImageOrientationLeft:
  19. case UIImageOrientationLeftMirrored:
  20. transform = CGAffineTransformTranslate(transform, aImage.size.width, 0);
  21. transform = CGAffineTransformRotate(transform, M_PI_2);
  22. break;
  23.  
  24. case UIImageOrientationRight:
  25. case UIImageOrientationRightMirrored:
  26. transform = CGAffineTransformTranslate(transform, 0, aImage.size.height);
  27. transform = CGAffineTransformRotate(transform, -M_PI_2);
  28. break;
  29. default:
  30. break;
  31. }
  32.  
  33. switch (aImage.imageOrientation) {
  34. case UIImageOrientationUpMirrored:
  35. case UIImageOrientationDownMirrored:
  36. transform = CGAffineTransformTranslate(transform, aImage.size.width, 0);
  37. transform = CGAffineTransformScale(transform, -1, 1);
  38. break;
  39.  
  40. case UIImageOrientationLeftMirrored:
  41. case UIImageOrientationRightMirrored:
  42. transform = CGAffineTransformTranslate(transform, aImage.size.height, 0);
  43. transform = CGAffineTransformScale(transform, -1, 1);
  44. break;
  45. default:
  46. break;
  47. }
  48.  
  49. // Now we draw the underlying CGImage into a new context, applying the transform
  50. // calculated above.
  51. CGContextRef ctx = CGBitmapContextCreate(NULL, aImage.size.width, aImage.size.height,
  52. CGImageGetBitsPerComponent(aImage.CGImage), 0,
  53. CGImageGetColorSpace(aImage.CGImage),
  54. CGImageGetBitmapInfo(aImage.CGImage));
  55. CGContextConcatCTM(ctx, transform);
  56. switch (aImage.imageOrientation) {
  57. case UIImageOrientationLeft:
  58. case UIImageOrientationLeftMirrored:
  59. case UIImageOrientationRight:
  60. case UIImageOrientationRightMirrored:
  61. // Grr...
  62. CGContextDrawImage(ctx, CGRectMake(0,0,aImage.size.height,aImage.size.width), aImage.CGImage);
  63. break;
  64.  
  65. default:
  66. CGContextDrawImage(ctx, CGRectMake(0,0,aImage.size.width,aImage.size.height), aImage.CGImage);
  67. break;
  68. }
  69.  
  70. // And now we just create a new UIImage from the drawing context
  71. CGImageRef cgimg = CGBitmapContextCreateImage(ctx);
  72. UIImage *img = [UIImage imageWithCGImage:cgimg];
  73. CGContextRelease(ctx);
  74. CGImageRelease(cgimg);
  75. return img;
  76. }

  

亲测,在完成拍照代理里,获取到图片后,用此方法处理后,再上传服务器,可解决该问题。

  1. //若是图片
  2. var img:UIImage = info[UIImagePickerControllerOriginalImage] as! UIImage
  3. //保存相册
  4. UIImageWriteToSavedPhotosAlbum(img, self, nil, nil)
  5.  
  6. img = PublicMethod.fixOrientation(img)
  7.  
  8. //压缩图片
  9. let imgData:NSData = UIImageJPEGRepresentation(img, 0.2)!
  10. //上传服务器
  11. self.uploadHeadImg(imgData, headImage: img)

  

参考文献:http://blog.csdn.net/hitwhylz/article/details/39518463

如果有疑问,欢迎留言。

iOS拍照上传后,在web端显示旋转 Swift+OC版解决方案的更多相关文章

  1. iOS和小米手机拍照上传后,在web端显示旋转

    ( ′◔ ‸◔`)现在的公司啊都流行混合开发,我们公司也不例外,非要把交互非常多的社区模块用内嵌web页展示,好吧好吧,毕竟有的应用也是这么做的,那既然是社区就肯定少不了用户上传图片的操作,在开发阶段 ...

  2. ios端浏览器拍照上传到服务器,图片被旋转90度 php 解决方案

    1.可以通过前端进行解决,本案例通过后端解决的 判断请求的浏览器的ua,如果是ios浏览器则进行90度旋转 重点来了: 必须确保检测的图片是ios设备上传的完整图片,不要在前端压缩过的,因为压缩后的图 ...

  3. iOS图片上传后被旋转的问题

    最近用PHP做了一个图片合成程序,前端是通过HTML的file input选取自定图片,POST到php后台调整尺寸后与事先准备好的背景图进行合成. 通过测试发现,上传后的自定图片有的被旋转了,有的是 ...

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

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

  5. 利用exif.js解决ios手机上传竖拍照片旋转90度问题

    html5+canvas进行移动端手机照片上传时,发现ios手机上传竖拍照片会逆时针旋转90度,横拍照片无此问题:Android手机没这个问题. 因此解决这个问题的思路是:获取到照片拍摄的方向角,对非 ...

  6. html5调用手机摄像头,实现拍照上传功能

    今天做手机网站,想实现手机扫描二维码功能.首先实现在浏览器中调用手机摄像头,实现拍照功能并且把拍下的照片显示在页面并上传到服务器上,然后再在服务器端进行分析. 首先实现在浏览器中调用摄像头,当然用现在 ...

  7. 修正ios h5上传图时的图片方向问题

     .ios上传会在exif中带一个 Orientation的属性,这个属性在windows中不会生效,在ios浏览器中会生效,造成图片在windows资源管理器中与ios浏览器中方向不一致  为了用户 ...

  8. Android4.4 + WebAPI 实现拍照上传

    网上有很多关于拍照上传的实现方法,如果用新版本android去运行有可能会发现根本实现不了.主要原因是android从4.4版本开始通过intent.ACTION_GET_CONTENT打开选择器后, ...

  9. php实现手机拍照上传头像功能

    现在手机拍照很火,那么如何使用手机拍照并上传头像呢?原因很简单,就是数据传递,首先手机传递照片信息,这个就不是post传递 也不是get函数传递, 这个另外一种数据格式传递,使用的是$GLOBALS ...

随机推荐

  1. Scalaz(17)- Monad:泛函状态类型-State Monad

    我们经常提到函数式编程就是F[T].这个F可以被视为一种运算模式.我们是在F运算模式的壳子内对T进行计算.理论上来讲,函数式程序的运行状态也应该是在这个运算模式壳子内的,也是在F[]内更新的.那么我们 ...

  2. POJ 1061 青蛙的约会 扩展欧几里得

    扩展欧几里得模板套一下就A了,不过要注意刚好整除的时候,代码中有注释 #include <iostream> #include <cstdio> #include <cs ...

  3. [翻译] Autofac 控制范围和生命周期

    原文链接:http://docs.autofac.org/en/latest/lifetime/index.html Lifetime 是指服务的实例在程序中存活多久 – 从最初的实例化到清理(dis ...

  4. java RSA加解密以及用途

    在公司当前版本的中间件通信框架中,为了防止非授权第三方和到期客户端的连接,我们通过AES和RSA两种方式的加解密策略进行认证.对于非对称RSA加解密,因为其性能耗费较大,一般仅用于认证连接,不会用于每 ...

  5. IO流(五)__文件的递归、Properties、打印流PrintStream与PrintWriter、序列流SequenceInputStream

    一.文件的遍历 1.需求:对指定目录进行所有的内容的列出(包含子目录的内容)-文件的深度遍历 思想:递归的思想,在递归的时候要记住递归的层次. public class FileTest { publ ...

  6. SPRING SECURITY 拦截静态资源

    情景: <security:intercept-url pattern="/**" access="USER"/> 当在spring securti ...

  7. 【初探Underscore】再说模版引擎

    前言 Underscore 是一个JavaScript实用库,提供了类似Prototype.js (或 Ruby)的一些功能,但是没有扩展任何JavaScript内置对象. 它弥补了部分jQuery没 ...

  8. 频率直方图(hist)

    频率直方图(frequency histogram)亦称频率分布直方图.统计学中表示频率分布的图形.在直角坐标系中,用横轴表示随机变量的取值,横轴上的每个小区间对应一个组的组距,作为小矩形的底边:纵轴 ...

  9. ContentProvider实现流程

    个人记录 public class DataBaseContentProvider extends ContentProvider { private SQLiteOpenHelper mSQLite ...

  10. System.Web.HttpException: 无法序列化会话状态。在“StateServer”或“SQLServer”模式下,ASP.NET 将序列化会话状态对象,因此不允许使用无法序列化的对象或 MarshalByRef 对象。如果自定义会话状态存储在“Custom”模式下执行了类似的序列化,则适用同样的限制。 ---> System.Runtime.Serialization.Seria

    序列化问题:查询度娘各种答案不一  多为修改web.config找到SessionState节,将Mode 设置为 InProc   ,还有舍弃Session用cookie存储,多经试验觉得还是写一个 ...