Как применить ориентацию изображения к CIImage? - PullRequest
0 голосов
/ 07 мая 2020

Я пытаюсь скомпоновать 2 изображения с помощью CIFilter, но не могу правильно обработать ориентацию изображения.

В следующем примере я снял ту же сцену, но с двумя разными ориентациями телефона (кнопки регулировки громкости вверху для первого изображения, внизу для второго изображения). На следующем снимке экрана первое изображение отображается сверху, а второе - посередине. Я проверил, что 2 ориентации изображения различаются (см. print call).

SwiftUI правильно обрабатывает ориентацию изображения. Если я теперь скомпоную 2 изображения с помощью CIFilter (третье изображение), ориентация изображений не будет принята во внимание, и компоновка будет не такой, какой я хочу (я хочу, чтобы две кружки были рядом).

Это явно не ошибка. Но как повернуть входные изображения в зависимости от их ориентации перед применением композитного CIFIlter? Каков стандартный способ сделать это?

Спасибо за вашу помощь.

Вот код, соответствующий этому простому примеру:

import SwiftUI

struct ContentView: View {

    @State var input1 = UIImage(named: "image1.jpg")
    @State var input2 = UIImage(named: "image2.jpg")
    @State var output : UIImage?

    var body: some View {
        VStack {

            Image(uiImage: input1!)
                .resizable()
                .scaledToFit()

            Image(uiImage: input2!)
                .resizable()
                .scaledToFit()

            if output != nil {
                Image(uiImage: output!)
                    .resizable()
                    .scaledToFit()
            }

        }
        .onAppear(){
            self.compose()
        }
    }

    func compose() {

        print("Orientation of input1: \(input1!.imageOrientation.rawValue)")
        print("Orientation of input2: \(input2!.imageOrientation.rawValue)")

        let ciContext = CIContext(options: nil)

        let ciInput1 = CIImage(image: input1!)
        let ciInput2 = CIImage(image: input2!)

        let filter = CIFilter(name: "CILinearDodgeBlendMode")!
        filter.setValue(ciInput1, forKey: "inputImage")
        filter.setValue(ciInput2, forKey: "inputBackgroundImage")

        let ciOutput = filter.value(forKey: kCIOutputImageKey) as! CIImage

        let cgOutput = ciContext.createCGImage(ciOutput, from: ciOutput.extent)!

        output = UIImage(cgImage: cgOutput)
    }
}

А вот соответствующий скриншот:

enter image description here

1 Ответ

1 голос
/ 07 мая 2020

Вы можете указать Core Image учитывать ориентацию изображения при загрузке:

let ciInput1 = CIImage(image: input1!, options: [.applyOrientationProperty: true])
let ciInput2 = CIImage(image: input2!, options: [.applyOrientationProperty: true])

Edit:

Таким образом, похоже, что вышеуказанное работает только при загрузке изображение из URL или из данных, а не из UIImage.

Однако вы можете применить ориентацию самостоятельно. Вот удобное расширение:

extension UIImage.Orientation {
    var exifOrientation: Int32 {
        switch self {
            case .up: return 1
            case .down: return 3
            case .left: return 8
            case .right: return 6
            case .upMirrored: return 2
            case .downMirrored: return 4
            case .leftMirrored: return 5
            case .rightMirrored: return 7
        }
    }
}

Затем вы можете преобразовать изображение следующим образом:

let ciInput1 = CIImage(image: input1!).oriented(forExifOrientation: image1.imageOrientation.exifOrientation)
let ciInput2 = CIImage(image: input2!).oriented(forExifOrientation: image2.imageOrientation.exifOrientation)
...