Изменение размера UIImage или CIImage перед обрезкой растягивает изображения?

Хорошо, я пробовал каждый пример, который я мог найти, чтобы сделать это, к сожалению, большинство из них относятся к 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);
     }

     }];
}];
}

Этот код является тестовым, поэтому в нем будут всевозможные попытки, извините за это.

Самое близкое, что у меня есть, это использовать код Мэтта Геммелла здесь

Но это, что бы я ни пытался, всегда растягивает изображение. Я хочу изменить размер изображения, а затем обрезать его до размера 512 пикселей. Если я просто использую фильтр CICrop, он занимает верхние левые 512 пикселей, поэтому я теряю большую часть изображения (хватая фотографию с высоким разрешением, так как позже я также захочу экспортировать изображения 1800x1800). Я думал сначала изменить размер изображения, а затем обрезать. Но что бы я ни делал, изображение растягивается.

Итак, мой вопрос: есть ли правильный рекомендуемый признанный способ изменения размера и изображения в iOS5+?

Спасибо.


person mrEmpty    schedule 07.05.2012    source источник
comment
Я нашел один способ сделать это: UIGraphicsBeginImageContext(newSize); [изображение drawInRect:CGRectMake(0,0,newSize.width,newSize.height)]; UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); Что может быть не так, как я должен, но пока это работает. Интересно, почему Apple не сделала это проще! :)   -  person mrEmpty    schedule 08.05.2012
comment
Я только что столкнулся с точно такой же проблемой, но модель, которую вы предлагаете, мне не подошла. Я разместил проблему здесь stackoverflow.com/questions/10491080/   -  person Nick ONeill    schedule 08.05.2012
comment
И я предоставил решение, которое работает для меня и в этом другом потоке (который отлично работает в iOS 5): stackoverflow.com/questions/10491080/   -  person Rob    schedule 08.05.2012
comment
@Ник, значит, ты тоже используешь свою клавиатуру в качестве тестовой модели! :) Интересно, все ли мы так делаем? Я проверю ваш метод после утренних встреч в понедельник...   -  person mrEmpty    schedule 08.05.2012
comment
@Robert - спасибо за это, я тоже это проверю.   -  person mrEmpty    schedule 08.05.2012
comment
@RobertRyan - я предполагаю - (UIImage*)scaleImageToSizeFill:(CGSize)newSize; обрежет изображение, - (UIImage*)scaleImageToSizeAspectFill:(CGSize)newSize; изменит размер, но сохранит аспект (изменить размер до кратчайшей длины?) и - (UIImage *) scaleImageToSizeAspectFit: (CGSize) newSize; изменяет размер всего изображения, чтобы оно соответствовало новым границам?   -  person mrEmpty    schedule 08.05.2012
comment
@mrEmpty, да, это намерение, чтобы соблюдать стандартные определения UIViewContentModeScaleAspectFill и andUIViewContentModeScaleAspectFit, как определено UIViewContentMode. Я надеюсь, что моя категория работает для вас...   -  person Rob    schedule 08.05.2012


Ответы (1)


Я нашел один способ сделать это:

UIGraphicsBeginImageContext( newSize );

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

UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();

UIGraphicsEndImageContext();
person mrEmpty    schedule 29.05.2012