美文网首页
CVPixelBufferRef 旋转及设备方向问题

CVPixelBufferRef 旋转及设备方向问题

作者: 斌小狼 | 来源:发表于2021-03-29 15:15 被阅读0次

    旋转

    //此方法放在@interface XXXViewController 之前
    
    static double radians (double degrees) {return degrees * M_PI/180;}
    
    static double ScalingFactorForAngle(double angle, CGSize originalSize) {
        double oriWidth = originalSize.height;
        double oriHeight = originalSize.width;
        double horizontalSpace = fabs( oriWidth*cos(angle) ) + fabs( oriHeight*sin(angle) );
        double scalingFactor = oriWidth / horizontalSpace ;
        return scalingFactor;
    }
    
    CGColorSpaceRef rgbColorSpace = NULL;
    CIContext *context = nil;
    CIImage *ci_originalImage = nil;
    CIImage *ci_transformedImage = nil;
    CIImage *ci_userTempImage = nil;
    
    static inline void RotatePixelBufferToAngle(CVPixelBufferRef thePixelBuffer, double theAngle) {
    
        @autoreleasepool {
    
            if (context==nil) {
                rgbColorSpace = CGColorSpaceCreateDeviceRGB();
                context = [CIContext contextWithOptions:@{kCIContextWorkingColorSpace: (__bridge id)rgbColorSpace,
                                                           kCIContextOutputColorSpace : (__bridge id)rgbColorSpace}];
            }
    
            long int w = CVPixelBufferGetWidth(thePixelBuffer);
            long int h = CVPixelBufferGetHeight(thePixelBuffer);
    
            ci_originalImage = [CIImage imageWithCVPixelBuffer:thePixelBuffer];
            ci_userTempImage = [ci_originalImage imageByApplyingTransform:CGAffineTransformMakeScale(0.6, 0.6)];
            //        CGImageRef UICG_image = [context createCGImage:ci_userTempImage fromRect:[ci_userTempImage extent]];
    
            double angle = theAngle;
            angle = angle+M_PI;
            double scalingFact = ScalingFactorForAngle(angle, CGSizeMake(w, h));
    
    
            CGAffineTransform transform =  CGAffineTransformMakeTranslation(w/2.0, h/2.0);
            transform = CGAffineTransformRotate(transform, angle);
            transform = CGAffineTransformTranslate(transform, -w/2.0, -h/2.0);
    
            //rotate it by applying a transform
            ci_transformedImage = [ci_originalImage imageByApplyingTransform:transform];
    
            CVPixelBufferLockBaseAddress(thePixelBuffer, 0);
    
            CGRect extentR = [ci_transformedImage extent];
            CGPoint centerP = CGPointMake(extentR.size.width/2.0+extentR.origin.x,
                                          extentR.size.height/2.0+extentR.origin.y);
            CGSize scaledSize = CGSizeMake(w*scalingFact, h*scalingFact);
            CGRect cropRect = CGRectMake(centerP.x-scaledSize.width/2.0, centerP.y-scaledSize.height/2.0,
                                         scaledSize.width, scaledSize.height);
    
    
            CGImageRef cg_img = [context createCGImage:ci_transformedImage fromRect:cropRect];
            ci_transformedImage = [CIImage imageWithCGImage:cg_img];
    
            ci_transformedImage = [ci_transformedImage imageByApplyingTransform:CGAffineTransformMakeScale(1.0/scalingFact, 1.0/scalingFact)];
            [context render:ci_transformedImage toCVPixelBuffer:thePixelBuffer bounds:CGRectMake(0, 0, w, h) colorSpace:NULL];
    
            CGImageRelease(cg_img);
            CVPixelBufferUnlockBaseAddress(thePixelBuffer, 0);
        }
    }
    
    使用方法:
    //home键在右传270.home键在左传90
    RotatePixelBufferToAngle(pixelBuffer, radians(self.leftAngle));
    

    方向

    //手机锁定方向或者app只支持竖屏,可使用此方式获取设备方向
    @property (nonatomic, strong) CMMotionManager *mManager;//陀螺仪
    @property (nonatomic, assign) BOOL isHomeKeyLeft;//是否横屏
    @property (nonatomic, assign) int leftAngle;//旋转角度
    
    NSTimeInterval updateInterval;
    - (CMMotionManager *)mManager
    {
        if (!_mManager) {
            updateInterval = 1.0/15.0;
            _mManager = [[CMMotionManager alloc] init];
        }
        return _mManager;
    }
    - (void)startUpdateAccelerometer{
        if ([self.mManager isAccelerometerAvailable] == YES) {
    //回调会一直调用,建议获取到就调用下面的停止方法,需要再重新开始,当然如果需求是实时不间断的话可以等离开页面之后再stop
            NSMutableDictionary *dic = [[NSMutableDictionary alloc] init];
            [self.mManager setAccelerometerUpdateInterval:updateInterval];
            [self.mManager startAccelerometerUpdatesToQueue:[NSOperationQueue currentQueue] withHandler:^(CMAccelerometerData *accelerometerData, NSError *error)
             {
                 double x = accelerometerData.acceleration.x;
                 double y = accelerometerData.acceleration.y;
                 if (fabs(y) >= fabs(x))
                 {
                     if (y >= 0){
                         //Down
                         self.isHomeKeyLeft = false;
                     }
                     else{
                         //Portrait
                         self.isHomeKeyLeft = false;
                     }
                 }
                 else
                 {
                     if (x >= 0){
                         //Right:home键在左
                         self.isHomeKeyLeft = true;
                         self.leftAngle = 90;
                     }
                     else{
                         //Left:home键在右
                         self.isHomeKeyLeft = true;
                         self.leftAngle = 270;
                     }
                 }
             }];
        }
    }
    - (void)stopUpdate
    {
        if ([self.mManager isAccelerometerActive] == YES)
        {
            [self.mManager stopAccelerometerUpdates];
        }
    }
    -(void)dealloc{
        self.mManager = nil;
    }
    

    相关文章

      网友评论

          本文标题:CVPixelBufferRef 旋转及设备方向问题

          本文链接:https://www.haomeiwen.com/subject/fesbhltx.html