zoukankan      html  css  js  c++  java
  • iOS拍照上传后,在web端显示旋转 Swift+OC版解决方案

    问题描述:

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

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

    原因分析:

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

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

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

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

    解决方法:

    Swift版:

    /**
         照片竖拍  web显示旋转解决:图片大于2M会自动旋转90度
         
         - parameter aImage: <#aImage description#>
         
         - returns: <#return value description#>
         */
        class func fixOrientation(aImage:UIImage)->UIImage  {
            if aImage.imageOrientation == UIImageOrientation.Up{
                return aImage
            }
        
            var transform = CGAffineTransformIdentity
            
            switch (aImage.imageOrientation) {
            case .Down,.DownMirrored:
            transform = CGAffineTransformTranslate(transform, aImage.size.width, aImage.size.height)
            transform = CGAffineTransformRotate(transform, CGFloat(M_PI))
            break;
            
            case .Left,.LeftMirrored:
            transform = CGAffineTransformTranslate(transform, aImage.size.width, 0)
            transform = CGAffineTransformRotate(transform, CGFloat(M_PI_2))
            break;
            
            case .Right,.RightMirrored:
            transform = CGAffineTransformTranslate(transform, 0, aImage.size.height)
            transform = CGAffineTransformRotate(transform, CGFloat(-M_PI_2))
            break;
            default:
            break;
            }
            
            switch (aImage.imageOrientation) {
            case .UpMirrored,.DownMirrored:
            transform = CGAffineTransformTranslate(transform, aImage.size.width, 0)
            transform = CGAffineTransformScale(transform, -1, 1)
            break;
            
            case .LeftMirrored,.RightMirrored:
            transform = CGAffineTransformTranslate(transform, aImage.size.height, 0)
            transform = CGAffineTransformScale(transform, -1, 1)
            break;
            default:
            break;
            }
            
            let ctx:CGContextRef = CGBitmapContextCreate(nil, Int(aImage.size.width), Int(aImage.size.height),
            CGImageGetBitsPerComponent(aImage.CGImage), 0,
            CGImageGetColorSpace(aImage.CGImage),
            1)!
    
    
            
            CGContextConcatCTM(ctx, transform)
            switch (aImage.imageOrientation) {
            case .Left,.LeftMirrored,.Right,.RightMirrored:
            CGContextDrawImage(ctx, CGRectMake(0,0,aImage.size.height,aImage.size.width), aImage.CGImage)
            break;
            
            default:
            CGContextDrawImage(ctx, CGRectMake(0,0,aImage.size.width,aImage.size.height), aImage.CGImage);
            break;
            }
            
            let cgimg:CGImageRef = CGBitmapContextCreateImage(ctx)!
            let img:UIImage = UIImage(CGImage: cgimg)
            return img;
            }
    

      

    OC版:

    - (UIImage *)fixOrientation:(UIImage *)aImage {  
        
      // No-op if the orientation is already correct  
      if (aImage.imageOrientation == UIImageOrientationUp)   
        return aImage;  
        
      // We need to calculate the proper transformation to make the image upright.  
      // We do it in 2 steps: Rotate if Left/Right/Down, and then flip if Mirrored.  
      CGAffineTransform transform = CGAffineTransformIdentity;  
        
      switch (aImage.imageOrientation) {  
        case UIImageOrientationDown:  
        case UIImageOrientationDownMirrored:  
          transform = CGAffineTransformTranslate(transform, aImage.size.width, aImage.size.height);  
          transform = CGAffineTransformRotate(transform, M_PI);  
          break;  
            
        case UIImageOrientationLeft:  
        case UIImageOrientationLeftMirrored:  
          transform = CGAffineTransformTranslate(transform, aImage.size.width, 0);  
          transform = CGAffineTransformRotate(transform, M_PI_2);  
          break;  
            
        case UIImageOrientationRight:  
        case UIImageOrientationRightMirrored:  
          transform = CGAffineTransformTranslate(transform, 0, aImage.size.height);  
          transform = CGAffineTransformRotate(transform, -M_PI_2);  
          break;  
        default:  
          break;  
      }  
        
      switch (aImage.imageOrientation) {  
        case UIImageOrientationUpMirrored:  
        case UIImageOrientationDownMirrored:  
          transform = CGAffineTransformTranslate(transform, aImage.size.width, 0);  
          transform = CGAffineTransformScale(transform, -1, 1);  
          break;  
            
        case UIImageOrientationLeftMirrored:  
        case UIImageOrientationRightMirrored:  
          transform = CGAffineTransformTranslate(transform, aImage.size.height, 0);  
          transform = CGAffineTransformScale(transform, -1, 1);  
          break;  
        default:  
          break;  
      }  
        
      // Now we draw the underlying CGImage into a new context, applying the transform  
      // calculated above.  
      CGContextRef ctx = CGBitmapContextCreate(NULL, aImage.size.width, aImage.size.height,  
                           CGImageGetBitsPerComponent(aImage.CGImage), 0,  
                           CGImageGetColorSpace(aImage.CGImage),  
                           CGImageGetBitmapInfo(aImage.CGImage));  
      CGContextConcatCTM(ctx, transform);  
      switch (aImage.imageOrientation) {  
        case UIImageOrientationLeft:  
        case UIImageOrientationLeftMirrored:  
        case UIImageOrientationRight:  
        case UIImageOrientationRightMirrored:  
          // Grr...  
          CGContextDrawImage(ctx, CGRectMake(0,0,aImage.size.height,aImage.size.width), aImage.CGImage);  
          break;  
            
        default:  
          CGContextDrawImage(ctx, CGRectMake(0,0,aImage.size.width,aImage.size.height), aImage.CGImage);  
          break;  
      }  
        
      // And now we just create a new UIImage from the drawing context  
      CGImageRef cgimg = CGBitmapContextCreateImage(ctx);  
      UIImage *img = [UIImage imageWithCGImage:cgimg];  
      CGContextRelease(ctx);  
      CGImageRelease(cgimg);  
      return img;  
    } 
    

      

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

                //若是图片
                var img:UIImage = info[UIImagePickerControllerOriginalImage] as! UIImage
                //保存相册
                UIImageWriteToSavedPhotosAlbum(img, self, nil, nil)
                
                img = PublicMethod.fixOrientation(img)
                
                //压缩图片
                let imgData:NSData = UIImageJPEGRepresentation(img, 0.2)!
                //上传服务器
                self.uploadHeadImg(imgData, headImage: img)
        
    

      

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

    如果有疑问,欢迎留言。

  • 相关阅读:
    算法练习(16)-水平翻转一颗二叉树
    算法练习(15)-设计1个二叉树的序列化与反序列化实现?
    算法练习(14)-二叉树中2个节点的最近公共祖先?
    算法练习(13)-打印纸条对折的折痕类型(凹痕?凸痕?)
    算法练习(12)-二叉树的递归套路
    算法练习(11)-二叉树的各种遍历
    算法练习(10)-求2个(可能有环的)单链表的相交节点
    算法练习(9)-复杂带随机指针的单链表
    mac升级后第三方下载程序无法打开cannot be opened because the developer cannot be verified的解决办法
    算法练习(8)-判断单链表是否回文链表
  • 原文地址:https://www.cnblogs.com/yajunLi/p/5796084.html
Copyright © 2011-2022 走看看