UIImageJPEGПреобразование возвращает ноль

Я использую CIFilters для преобразования изображения в оттенки серого и применения некоторых эффектов обработки изображений. Отображение результатов работы UIImageView; изображение отображается и было изменено, как ожидалось.

Однако вызов UIImageJPEGRepresentation, как представляется, не возвращает никаких данных - каждый раз. Он никогда не работает. Вызов UIImageJPEGRпредставление с использованием исходного цветного изображения отлично работает.

Что здесь происходит? Почему может произойти сбой преобразования jpeg при отображении изображения? Исключения не выбрасываются (установка контрольной точки исключения, она не попадает), и на консоли не появляются сообщения.

let _cicontext = CIContext(options:nil)

// Set up grayscale and blur filters:
let grayIze = CIFilter(name: "CIColorControls")
let blur = CIFilter(name: "CIGaussianBlur")
grayIze.setValue(0, forKey:kCIInputSaturationKey)
grayIze.setValue(0.5, forKey: kCIInputBrightnessKey)
blur.setValue(4, forKey: kCIInputRadiusKey)

// Go!
let originalImage = CIImage(image: colorImageThatDefinitelyExists)
grayIze.setValue(originalImage, forKey: kCIInputImageKey)
blur.setValue(grayIze.outputImage, forKey: kCIInputImageKey)

let output = UIImage(CIImage: blur.outputImage)
let imageData: NSData? = UIImageJPEGRepresentation(output, 1.0) // Returns nil!?

Изменить: Вот рабочий код, основанный на Ответ Арбитра:

// Define an image context at the class level, which will only be initialized once:
static let imageContext = CIContext(options:nil)

// And here the updated code in a function:
class func convertToGrayscale(image: UIImage)->UIImage?
{
    // Set up grayscale and blur filters:
    let filter1_grayIze = CIFilter(name: "CIColorControls")
    let filter2_blur = CIFilter(name: "CIGaussianBlur")
    filter1_grayIze.setValue(0, forKey:kCIInputSaturationKey)
    filter1_grayIze.setValue(0.5, forKey: kCIInputBrightnessKey)
    filter2_blur.setValue(4, forKey: kCIInputRadiusKey)

    // Go!
    let originalImage = CIImage(image: image)
    filter1_grayIze.setValue(originalImage, forKey: kCIInputImageKey)
    filter2_blur.setValue(filter1_grayIze.outputImage, forKey: kCIInputImageKey)
    let outputCIImage = filter2_blur.outputImage

    let temp:CGImageRef = imageContext.createCGImage(outputCIImage, fromRect: outputCIImage.extent())
    let ret = UIImage(CGImage: temp)
    return ret
}

// And finally, the function call:
    if let grayImage = ProfileImage.convertToGrayscale(colorImage)
    {
        let imageData: NSData? = UIImageJPEGRepresentation(grayImage, 1.0)
    }

Ответ 1

У меня была проблема перед CIImage и для того, чтобы обойти это, я создал CGImage с CIImage, а затем UIImage с CGImage.

Ответ 2

UIImageJPEGRepresentation похоже, использует свойство CGImage для UIImage. Проблема в том, что при инициализации UIImage с помощью CIImage это свойство nil.

Моим решением было добавить следующий блок перед вызовом UIImageJPEGRepresentation:

 if image.CGImage == nil {
    guard let ciImage = image.CIImage, let cgImage = CIContext(options: nil).createCGImage(ciImage, fromRect: ciImage.extent) else { return nil }

    image = UIImage(CGImage: cgImage)
 }

Ответ 3

Ответ от Даниила отлично работает. Ниже его ответ преобразован для использования в Swift4.

Swift4

    if image?.cgImage == nil {
        guard let ciImage = image?.ciImage, let cgImage = CIContext(options: nil).createCGImage(ciImage, from: ciImage.extent) else { return }

        image = UIImage(cgImage: cgImage)
    }