在裁剪之前调整 UIImage 或 CIImage 的大小会拉伸图像吗?

Posted

技术标签:

【中文标题】在裁剪之前调整 UIImage 或 CIImage 的大小会拉伸图像吗?【英文标题】:Resizing a UIImage, or CIImage, before cropping, stretches the images? 【发布时间】:2012-05-07 17:17:23 【问题描述】:

好的,我已经尝试了每一个我能找到的例子来做到这一点,遗憾的是它们中的大多数都是从 2008 年到 2009 年,而 ios5 似乎非常不同。我只是想调整大小和图像,以便短边是我指定的大小,并且保持成比例。

我正在使用 AVFoundation 从相机中获取图像,我通过 UIImage 将其转换为 CIImage,这样我就可以应用过滤器并对其进行处理,然后再转换回 UIImage 进行保存。

- (void) startCamera 

session = [[AVCaptureSession alloc] init];
session.sessionPreset = AVCaptureSessionPresetPhoto;

AVCaptureVideoPreviewLayer *captureVideoPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:session];
captureVideoPreviewLayer.frame = _cameraView.bounds;
[_cameraView.layer addSublayer:captureVideoPreviewLayer];
captureVideoPreviewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;

AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
NSError *error = nil;

AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device error:&error];
if (!input) 
    //no cam, handle error - need to put up a nice happy note here
    NSLog(@"ERROR: %@", error);


[session addInput:input];

stillImage = [[AVCaptureStillImageOutput alloc] init];
NSDictionary *outputSettings = [[NSDictionary alloc] initWithObjectsAndKeys:AVVideoCodecJPEG , AVVideoCodecKey, nil];
[stillImage setOutputSettings:outputSettings];

[session addOutput:stillImage];
[session startRunning];


- (IBAction) _cameraButtonPress:(id)sender 

AVCaptureConnection *videoConnection = nil;
for (AVCaptureConnection *connection in stillImage.connections)

    for (AVCaptureInputPort *port in [connection inputPorts])
    
        if ([[port mediaType] isEqual:AVMediaTypeVideo] )
        
            videoConnection = connection;
            break;
        
    
    if (videoConnection) 
        break;
    


[stillImage captureStillImageAsynchronouslyFromConnection:videoConnection completionHandler:^(CMSampleBufferRef imageSampleBuffer, NSError *error) 

    NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageSampleBuffer];
    UIImage *startImage = [[UIImage alloc] initWithData:imageData];

    //resizing of image to take place before anything else
    UIImage *image = [startImage imageScaledToFitSize:_exportSSize];  //resizes to the size given in the prefs

    //change the context to render using cpu, so on app exit renders get completed
    context = [CIContext contextWithOptions:
               [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES]
                                           forKey:kCIContextUseSoftwareRenderer]];

    //set up the saving library
    ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];

    //create a new ciimage
    CIImage *greyImage = [[CIImage alloc] initWithCGImage:[image CGImage]];

    //create a CIMonochrome filter 
    desaturate = [CIFilter filterWithName:@"CIColorMonochrome" keysAndValues:kCIInputImageKey, greyImage, @"inputIntensity", [NSNumber numberWithFloat:0.00], nil];

    //[crop setValue:ciImage forKey:@"inputImage"];
    //[crop setValue:[CIVector vectorWithX:0.0f Y:0.0f Z:_exportSize W:_exportSize] forKey:@"inputRectangle"];

    CIImage *croppedColourImage = [desaturate valueForKey:@"outputImage"];
    //convert it to a cgimage for saving
    CGImageRef cropColourImage = [context createCGImage:croppedColourImage fromRect:[croppedColourImage extent]];

     //saving of the images         
     [library writeImageToSavedPhotosAlbum:cropColourImage metadata:[croppedColourImage properties] completionBlock:^(NSURL *assetURL, NSError *error)
     if (error) 
         NSLog(@"ERROR in image save: %@", error);
      else
     
         NSLog(@"SUCCESS in image save");
         //in here we'll put a nice animation or something
         CGImageRelease(cropColourImage);
     

     ];
];

此代码是测试代码,因此会有各种尝试,对此表示歉意。

我最接近的是使用 Matt Gemmell 的代码 here

但是,无论我尝试什么,总是会拉伸图像。我想调整图像大小,然后将其裁剪为 512 像素正方形。如果我只是做一个 CICrop 过滤器,它会占用左上角的 512 像素,所以我会丢失很多图像(抓取高分辨率照片,因为稍后我还想导出 1800x1800 图像)。我的想法是先调整图像大小,然后裁剪。但无论我做什么,图像都会被拉伸。

所以我的问题是,在 iOS5+ 中是否有适当的建议可识别方法来调整大小和图像?

谢谢。

【问题讨论】:

我找到了一种方法:UIGraphicsBeginImageContext(newSize); [图像 drawInRect:CGRectMake(0,0,newSize.width,newSize.height)]; UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext();这可能不是我应该的方式,但它现在正在工作。想知道为什么苹果没有让这更容易! :) 我刚刚遇到了同样的问题,但是您建议的模型似乎对我不起作用。我在这里发布了这个问题***.com/questions/10491080/… 我提供了一个在其他线程中也适用于我的解决方案(在 iOS 5 中运行良好):***.com/questions/10491080/… @Nick,所以您也可以将键盘用作测试模型! :) 我想知道我们是否都在这样做?我会在星期一早上的会议之后检查你的方法...... @Robert - 谢谢你,我也会检查一下。 【参考方案1】:

我找到了一种方法:

UIGraphicsBeginImageContext( newSize );

[image drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];

UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();

UIGraphicsEndImageContext();

【讨论】:

以上是关于在裁剪之前调整 UIImage 或 CIImage 的大小会拉伸图像吗?的主要内容,如果未能解决你的问题,请参考以下文章

在 iOS 7 之前的项目中编译警告“不兼容的指针类型初始化 'UIImage *' 使用类型为'CIImage * _Nullable”的表达式

无法使用CIFilter从CIImage中提取UIImage

UIImage 调整大小并裁剪以适合

swift UIImage使用UIImageView调整方面填充和裁剪

从 UIImage (Swift) 获取 CIImage

如何将 UIImage 转换为 CIImage,反之亦然