настройка режима содержания помощью UIImageView после применения CIFIlter

Спасибо за просмотр.

вот мой код

 CIImage *result = _vignette.outputImage;
self.mainImageView.image = nil;
//self.mainImageView.contentMode = UIViewContentModeScaleAspectFit;
self.mainImageView.image = [UIImage imageWithCIImage:result];
self.mainImageView.contentMode = UIViewContentModeScaleAspectFit;

здесь _vignette правильно настроен фильтр, и эффект изображения применяется к изображению правильно.

Я использую исходное изображение с разрешением 500x375. Мой imageView имеет почти разрешение экрана iPhone. Поэтому, чтобы избежать растяжки, я использую AspectFit.

но после применения эффекта, когда я назначаю изображение результата обратно в мой imageView, он разбегается. Независимо от того, какой UIViewContentMode Я использую. Это не работает. Кажется, это всегда применимо ScaleToFill независимо от фильтра, который я дал.

есть идеи, почему это происходит? Любое предложение высоко ценится.

3 ответов


(1) Аспект Fit тут растянуть изображение, чтобы соответствовать. Если вы вообще не хотите растягивать изображение, используйте Center (например).

(2) imageWithCIImage дает вам очень странный зверь, UIImage не основанный на CGImage, и поэтому не восприимчивый к нормальным правилам отображения слоя. Это действительно ничего, кроме тонкой обертки вокруг CIImage, что не то, что вы хотите. Вы должны преобразовать (визуализировать) выход CIFilter через CGImage в UIImage, тем самым давая вам UIImage, который на самом деле имеет некоторые биты (CGImage, растровое изображение). Мое обсуждение здесь дает вам код, который демонстрирует:

http://www.apeth.com/iOSBook/ch15.html#_cifilter_and_ciimage

другими словами, в какой-то момент Вы должны вызвать CIContext createCGImage:fromRect: для генерации CGImageRef из вывода вашего CIFilter и передачи этого в UIImage. Пока вы этого не сделаете, у вас нет выходных данных ваших операций фильтра как реального UIImage.

кроме того, вы можете нарисовать изображения от imageWithCIImage в графическом контексте. Например, вы можете нарисовать его в графическом контексте изображения, а затем использовать это изображения.

что ты не могу do отображает изображение из imageWithCIImage напрямую. Потому что это не образ! Он не имеет базового растрового изображения (CGImage). Нет там есть. Все это набор инструкций CIFilter для получения изображения.


Я просто потратил весь день на это. Я получаю проблемы ориентации следует некачественной продукции.

после съемки изображения с помощью камеры я делаю это.

NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer];
                UIImage *image = [[UIImage alloc] initWithData:imageData];

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

UIImage *scaleAndRotateImage(UIImage *image)
{
    int kMaxResolution = image.size.height; // Or whatever

    CGImageRef imgRef = image.CGImage;

    CGFloat width = CGImageGetWidth(imgRef);
    CGFloat height = CGImageGetHeight(imgRef);

    CGAffineTransform transform = CGAffineTransformIdentity;
    CGRect bounds = CGRectMake(0, 0, width, height);
    if (width > kMaxResolution || height > kMaxResolution) {
        CGFloat ratio = width/height;
        if (ratio > 1) {
            bounds.size.width = kMaxResolution;
            bounds.size.height = bounds.size.width / ratio;
        }
        else {
            bounds.size.height = kMaxResolution;
            bounds.size.width = bounds.size.height * ratio;
        }
    }

    CGFloat scaleRatio = bounds.size.width / width;
    CGSize imageSize = CGSizeMake(CGImageGetWidth(imgRef), CGImageGetHeight(imgRef));
    CGFloat boundHeight;
    UIImageOrientation orient = image.imageOrientation;
    switch(orient) {

        case UIImageOrientationUp: //EXIF = 1
            transform = CGAffineTransformIdentity;
            break;

        case UIImageOrientationUpMirrored: //EXIF = 2
            transform = CGAffineTransformMakeTranslation(imageSize.width, 0.0);
            transform = CGAffineTransformScale(transform, -1.0, 1.0);
            break;

        case UIImageOrientationDown: //EXIF = 3
            transform = CGAffineTransformMakeTranslation(imageSize.width, imageSize.height);
            transform = CGAffineTransformRotate(transform, M_PI);
            break;

        case UIImageOrientationDownMirrored: //EXIF = 4
            transform = CGAffineTransformMakeTranslation(0.0, imageSize.height);
            transform = CGAffineTransformScale(transform, 1.0, -1.0);
            break;

        case UIImageOrientationLeftMirrored: //EXIF = 5
            boundHeight = bounds.size.height;
            bounds.size.height = bounds.size.width;
            bounds.size.width = boundHeight;
            transform = CGAffineTransformMakeTranslation(imageSize.height, imageSize.width);
            transform = CGAffineTransformScale(transform, -1.0, 1.0);
            transform = CGAffineTransformRotate(transform, 3.0 * M_PI / 2.0);
            break;

        case UIImageOrientationLeft: //EXIF = 6
            boundHeight = bounds.size.height;
            bounds.size.height = bounds.size.width;
            bounds.size.width = boundHeight;
            transform = CGAffineTransformMakeTranslation(0.0, imageSize.width);
            transform = CGAffineTransformRotate(transform, 3.0 * M_PI / 2.0);
            break;

        case UIImageOrientationRightMirrored: //EXIF = 7
            boundHeight = bounds.size.height;
            bounds.size.height = bounds.size.width;
            bounds.size.width = boundHeight;
            transform = CGAffineTransformMakeScale(-1.0, 1.0);
            transform = CGAffineTransformRotate(transform, M_PI / 2.0);
            break;

        case UIImageOrientationRight: //EXIF = 8
            boundHeight = bounds.size.height;
            bounds.size.height = bounds.size.width;
            bounds.size.width = boundHeight;
            transform = CGAffineTransformMakeTranslation(imageSize.height, 0.0);
            transform = CGAffineTransformRotate(transform, M_PI / 2.0);
            break;

        default:
            [NSException raise:NSInternalInconsistencyException format:@"Invalid image orientation"];

    }

    UIGraphicsBeginImageContext(bounds.size);

    CGContextRef context = UIGraphicsGetCurrentContext();

    if (orient == UIImageOrientationRight || orient == UIImageOrientationLeft) {
        CGContextScaleCTM(context, -scaleRatio, scaleRatio);
        CGContextTranslateCTM(context, -height, 0);
    }
    else {
        CGContextScaleCTM(context, scaleRatio, -scaleRatio);
        CGContextTranslateCTM(context, 0, -height);
    }

    CGContextConcatCTM(context, transform);

    CGContextDrawImage(UIGraphicsGetCurrentContext(), CGRectMake(0, 0, width, height), imgRef);
    UIImage *imageCopy = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();  

    return imageCopy;  
}

затем, когда я применяю свой фильтр, я делаю это (с особой благодарностью этому потоку - в частности, matt и Wex)

    -(UIImage*)processImage:(UIImage*)image {

            CIImage *inImage = [CIImage imageWithCGImage:image.CGImage];

            CIFilter *filter = [CIFilter filterWithName:@"CIColorControls" keysAndValues:
                        kCIInputImageKey, inImage,
                        @"inputContrast", [NSNumber numberWithFloat:1.0],
                        nil];

    UIImage *outImage = [filter outputImage];

//Juicy bit
            CGImageRef cgimageref = [[CIContext contextWithOptions:nil] createCGImage:outImage fromRect:[outImage extent]];

            return [UIImage imageWithCGImage:cgimageref];
        }

Это ответ для Swift, вдохновленный этот вопрос и решение по user1951992.

let imageView = UIImageView(frame: CGRect(x: 100, y: 200, width: 100, height: 50))
imageView.contentMode = .scaleAspectFit

//just an example for a CIFilter
//NOTE: we're using implicit unwrapping here because we're sure there is a filter
//(and an image) named exactly this
let filter = CIFilter(name: "CISepiaTone")!
let image = UIImage(named: "image")!
filter.setValue(CIImage(image: image), forKey: kCIInputImageKey)
filter.setValue(0.5, forKey: kCIInputIntensityKey)

guard let outputCGImage = filter?.outputImage,
    let outputImage = CIContext().createCGImage(outputCGImage, from: outputCGImage.extent) else {
        return
}

imageView.image = UIImage(cgImage: outputImage)