• <acronym id='gh9hu'><em id='gh9hu'></em><td id='gh9hu'><div id='gh9hu'></div></td></acronym><address id='gh9hu'><big id='gh9hu'><big id='gh9hu'></big><legend id='gh9hu'></legend></big></address>
    <fieldset id='gh9hu'></fieldset><i id='gh9hu'><div id='gh9hu'><ins id='gh9hu'></ins></div></i>
      <ins id='gh9hu'></ins>

        <code id='gh9hu'><strong id='gh9hu'></strong></code>

        <dl id='gh9hu'></dl>
      1. <tr id='gh9hu'><strong id='gh9hu'></strong><small id='gh9hu'></small><button id='gh9hu'></button><li id='gh9hu'><noscript id='gh9hu'><big id='gh9hu'></big><dt id='gh9hu'></dt></noscript></li></tr><ol id='gh9hu'><table id='gh9hu'><blockquote id='gh9hu'><tbody id='gh9hu'></tbody></blockquote></table></ol><u id='gh9hu'></u><kbd id='gh9hu'><kbd id='gh9hu'></kbd></kbd>

          <span id='gh9hu'></span>
          <i id='gh9hu'></i>

          1. iOS模仿系统相机拍照你不曾注意过的细节

            • 时间:
            • 浏览:10
            • 来源:124软件资讯网

              需求

              由于我们APP集成了有道翻译的SDK ,需要将拍出来的图片翻译成对应的语言  ,可是有道的SDK现在还做的不是很完善(好比:照片倾斜的时间 ,返回的角度不是很对  ,有道的手艺说下个版本可能会更新)  。于是产物要求照相页面做成跟系统相机类似  ,当用户横屏拍摄的时间  ,需要客户端自己将图片纠正回来  ,倒着拍的时间亦然  。

              自界说相机功效就不多说了  ,网上有大量的优异文章  ,这里随便从网上找了一个  ,需要的可以参考下

              基础知识

              首先我们需要知道每一个UIImage工具  ,都有一个imageOrientation属性  ,内里生存着偏向信息:

              typedef NS_ENUM(NSIntegerUIImageOrientation) {
                  UIImageOrientationUp,            // default orientation
                  UIImageOrientationDown,          // 180 deg rotation
                  UIImageOrientationLeft,          // 90 deg CCW
                  UIImageOrientationRight,         // 90 deg CW
                  UIImageOrientationUpMirrored,    // as above but image mirrored along other axis. horizontal flip
                  UIImageOrientationDownMirrored,  // horizontal flip
                  UIImageOrientationLeftMirrored,  // vertical flip
                  UIImageOrientationRightMirrored// vertical flip
              };

              凭据这个属性信息 ,我们便可以对图像举行响应的旋转  ,将图片转到准确的偏向  ,怎样旋转  ? ?有两种解决方案

              第一种:给UIImage添加Category

              - (UIImage *)fixOrientation {

                  // No-op if the orientation is already correct
                  if (self.imageOrientation == UIImageOrientationUpreturn self;

                  // 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 (self.imageOrientation) {
                      case UIImageOrientationDown:
                      case UIImageOrientationDownMirrored:
                          transform = CGAffineTransformTranslate(transform, self.size.width, self.size.height);
                          transform = CGAffineTransformRotate(transform, M_PI);
                          break;

                      case UIImageOrientationLeft:
                      case UIImageOrientationLeftMirrored:
                          transform = CGAffineTransformTranslate(transform, self.size.width, 0);
                          transform = CGAffineTransformRotate(transform, M_PI_2);
                          break;

                      case UIImageOrientationRight:
                      case UIImageOrientationRightMirrored:
                          transform = CGAffineTransformTranslate(transform, 0self.size.height);
                          transform = CGAffineTransformRotate(transform, -M_PI_2);
                          break;
                      case UIImageOrientationUp:
                      case UIImageOrientationUpMirrored:
                          break;
                  }

                  switch (self.imageOrientation) {
                      case UIImageOrientationUpMirrored:
                      case UIImageOrientationDownMirrored:
                          transform = CGAffineTransformTranslate(transform, self.size.width, 0);
                          transform = CGAffineTransformScale(transform, -11);
                          break;

                      case UIImageOrientationLeftMirrored:
                      case UIImageOrientationRightMirrored:
                          transform = CGAffineTransformTranslate(transform, self.size.height, 0);
                          transform = CGAffineTransformScale(transform, -11);
                          break;
                      case UIImageOrientationUp:
                      case UIImageOrientationDown:
                      case UIImageOrientationLeft:
                      case UIImageOrientationRight:
                          break;
                  }

                  // Now we draw the underlying CGImage into a new context, applying the transform
                  // calculated above.
                  CGContextRef ctx = CGBitmapContextCreate(NULLself.size.width, self.size.height,
                                                           CGImageGetBitsPerComponent(self.CGImage), 0,
                                                           CGImageGetColorSpace(self.CGImage),
                                                           CGImageGetBitmapInfo(self.CGImage));
                  CGContextConcatCTM(ctx, transform);
                  switch (self.imageOrientation) {
                      case UIImageOrientationLeft:
                      case UIImageOrientationLeftMirrored:
                      case UIImageOrientationRight:
                      case UIImageOrientationRightMirrored:
                          // Grr...
                          CGContextDrawImage(ctx, CGRectMake(0,0,self.size.height,self.size.width), self.CGImage);
                          break;

                      default:
                          CGContextDrawImage(ctx, CGRectMake(0,0,self.size.width,self.size.height), self.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;
              }


              第二种:使用drawInRect要领将图像画到画布上

              - (UIImage *)normalizedImage {
                  if (self.imageOrientation == UIImageOrientationUpreturn self

                  UIGraphicsBeginImageContextWithOptions(self.size, NOself.scale);
                  [self drawInRect:(CGRect){00self.size}];
                  UIImage *normalizedImage = UIGraphicsGetImageFromCurrentImageContext();
                  UIGraphicsEndImageContext();
                  return normalizedImage;
              }

              通过上面两种方式转换之后的UIImage工具  ,其imageOrientation属性  ,都市被修改成UIImageOrientationUp ,这样将图片传到后台  ,或者导出相册的时间  ,就不会泛起照片旋转90度的问题  。

              可是有时间我们希望图片该旋转的时间  ,根据我们的意愿旋转(好比横评拍摄的时间) ,竖直拍摄的时间  ,图像正常显示  ,这时间我们就不能直接用上面的要领来判断了  。仔细视察系统相机的拍摄  ,我发现除了竖直拍摄以外 ,此外情形下拍摄  ,图片都市自动旋转 ,这个时间就需要我们使用iPhone手机自带的硬件传感器对偏向举行判断  ,以到达我们想要的效果  ,这里主要用到加速仪

              加速仪(类型:CMAcceleration)

              加速仪可以检测三维空间中的加速率  ,坐标对应如下:

              例如:当垂直手持手机且顶部向上  ,Y坐标上接纳到 -1G的加速率  ,(0 ,-1  ,0)  ,当手机头部朝下  ,获得的各个坐标为:(0  ,1 ,0)

              主要代码如下:

              - (void)startDeviceMotion{
                  if (![self.motionManager isDeviceMotionAvailable]) {return;}

                  [self.motionManager setDeviceMotionUpdateInterval:1.f];
                  [self.motionManager startDeviceMotionUpdatesToQueue:[NSOperationQueue mainQueue] withHandler:^(CMDeviceMotion * _Nullable motion, NSError * _Nullable error) {

                      double gravityX = motion.gravity.x;
                      double gravityY = motion.gravity.y;

                      if (fabs(gravityY)>=fabs(gravityX)) {

                          if (gravityY >= 0) {

                              // UIDeviceOrientationPortraitUpsideDown
                              [self setDeviceDirection:SSDeviceDirectionDown];
                              NSLog(@"头向下");

                          } else {

                              // UIDeviceOrientationPortrait
                              [self setDeviceDirection:SSDeviceDirectionUp];
                              NSLog(@"竖屏");
                          }

                      } else {

                          if (gravityX >= 0) {
                              // UIDeviceOrientationLandscapeRight
                              [self setDeviceDirection:SSDeviceDirectionRight];
                              NSLog(@"头向右");
                          } else {

                              // UIDeviceOrientationLandscapeLef
                              [self setDeviceDirection:SSDeviceDirectionLeft];
                              NSLog(@"头向左");
                          }
                      }
                  }];
              }

              获取到偏向信息 ,下面就可以对图片举行对应的处置惩罚了 ,主要用到了下面的这个要领:

              - (instancetype)initWithCIImage:(CIImage *)ciImage scale:(CGFloat)scale orientation:(UIImageOrientation)orientation NS_AVAILABLE_IOS(6_0);

              该要领的作用是: