Osheep

时光不回头,当下最重要。

iOS-红蓝3D图片制作

本文主要是使用『GPUImage』进行图像的处理,下载方式和安装方法,请参考Github,链接:https://github.com/BradLarson/GPUImage

《iOS-红蓝3D图片制作》

效果图

制作方式和使用PS的做红蓝图的方式一样,需要三张图片,一是原图,二和三分别处理图片的颜色通道,生成红蓝两张图,移动二或者三到合适的位置,向左移动有出屏效果,向右则有入屏效果,但值得一提的是真正的红蓝3D图片是需要在不同的角度进行拍摄的两张图,然后再合成,使用红蓝眼睛会有出屏的效果。本文做的这个红蓝效果只能说是伪红蓝,效果自然差了不少。当然如果你有两张不同角度的图片,也可以通过本文的方式进行合成,只需要稍加修改就可以了,还是有一定的参考价值的!!!

接下来上代码:

#import <GPUImage.h>
#define kArallax 30  //视差
-(UIImage *)redImage:(UIImage *)image{
    //处理成红图片
    GPUImageRGBFilter *passthroughFilter = [[GPUImageRGBFilter alloc]init];
    passthroughFilter.green = 0;
    passthroughFilter.blue = 0;
    
    [passthroughFilter setupFilterForSize:image.size];

    [passthroughFilter useNextFrameForImageCapture];
    
    //获取数据源
    GPUImagePicture *stillImageSource = [[GPUImagePicture alloc]initWithImage:image];
    
    [stillImageSource addTarget:passthroughFilter];
    
    //开始渲染
    [stillImageSource processImage];
    
    UIImage *finallImage = [passthroughFilter imageFromCurrentFramebuffer];

    return finallImage;
}
《iOS-红蓝3D图片制作》

红孩儿
-(UIImage *)greenBlueImage:(UIImage *)image{
    //处理成蓝图片
    GPUImageRGBFilter *passthroughFilter = [[GPUImageRGBFilter alloc]init];
    passthroughFilter.red = 0;
    [passthroughFilter setupFilterForSize:image.size];
    
    [passthroughFilter useNextFrameForImageCapture];
    
    //获取数据源
    GPUImagePicture *stillImageSource = [[GPUImagePicture alloc]initWithImage:image];
    
    [stillImageSource addTarget:passthroughFilter];
    
    //开始渲染
    [stillImageSource processImage];
    
    UIImage *finallImage = [passthroughFilter imageFromCurrentFramebuffer];
    
    return finallImage;
}
《iOS-红蓝3D图片制作》

蓝孩儿
最后一步『合成一张图片』
- (UIImage *)redBlue3DImage:(UIImage *)redImage andBlueImage:(UIImage *)blueImage{
    //处理成红蓝图片
    UIImageView *image1 = [[UIImageView alloc]initWithImage:redImage];
    
    UIImageView *image2 = [[UIImageView alloc]initWithImage:blueImage];
    
    image2.alpha = 0.5;
    //我设的是30的原因为了增加视差,也不一定非要30,自己调试到一个合适的值即可
    image2.frame = CGRectMake(-kArallax, 0, image1.frame.size.width, image1.frame.size.height);
    
    [image1 addSubview:image2];
    
    UIImage *resultImage = [self clipWithImageRect:image1.frame clipImage:image1];
    
    return resultImage;
}
//MARK:裁剪图片
- (UIImage *)clipWithImageRect:(CGRect)clipRect clipImage:(UIImageView *)clipImage;

{
    //图片的原始比例
    CGFloat oriRatio = clipRect.size.width/clipRect.size.height;
    //开启剪切大小的图形上下文,要按照图片的原始比例且保证剪切后的红蓝图片比例不变
    UIGraphicsBeginImageContext(CGSizeMake(clipRect.size.width-kArallax, (clipRect.size.width-kArallax)/oriRatio));
    
    [clipImage.layer renderInContext:UIGraphicsGetCurrentContext()];
    
    UIImage *resultImage = UIGraphicsGetImageFromCurrentImageContext();
    
    UIGraphicsEndImageContext();
    //写入相册
    //UIImageWriteToSavedPhotosAlbum(resultImage, nil, nil, nil);
    
    return resultImage;
}
如果你的图片是从相册中选择出来的需要调用一下下面的方法,校正图片的方向,否则会出现竖屏图片变成横屏显示的问题,生成的红蓝图也会因此出现问题,请悉知
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info{
    [picker dismissViewControllerAnimated:YES completion:nil];
    //裁剪图片
    UIImage *image = info[UIImagePickerControllerOriginalImage];
    
    //校正后的图片
    image = [self fixOrientation:image];

    //UI显示(必须使用校正后的图片进行合成)
   self.RBImage.image =[self redBlue3DImage:[self redImage:image] andBlueImage:[self greenBlueImage:image]];

}
//MARK:校正图片方向
- (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;
}
《iOS-红蓝3D图片制作》

结束!!!
如果你有更好的处理方法,请在下方留言让更多的人看到,感谢赐教!!!

点赞