簡體   English   中英

如何將這個UIGraphics圖像操作轉換為Core Image?

[英]How to convert this UIGraphics image operation to Core Image?

我像在 Apple Motion 應用程序或 Snapchat 鏡頭中一樣編寫SplitMirror過濾器,通過使用UIGraphics將其與實時相機饋送或視頻處理一起使用,對於單個圖像請求,它像問題中的附加圖像一樣工作良好,但對於多個過濾請求則不然。 我認為它的代碼必須從UIGraphics更改為Core Image & CIContext以獲得更好的性能並減少 memory 像CIFilters這樣的使用,實際上我不知道該怎么做。 我嘗試了幾種方法來轉換它,但我堅持左右合並,這可以通過 `CICategoryCompositeOperations 過濾器來完成,但我知道哪種適合這種情況,所以需要一些幫助來解決這個問題。

使用UIGraphics過濾代碼:

//
//  SplitMirror filter.swift
//  Image Editor
// 
//  Created by Coder ACJHP on 25.02.2022.
// 
// SnapChat & Tiktok & Motion App like image filter
// Inspired from 'https://support.apple.com/tr-tr/guide/motion/motn169f94ea/mac'
// Splits an image in half vertically and reverses the left remaining half to create a reflection.

final func splitMirrorFilter(processingImage image: UIImage) -> UIImage {
    // Image size
    let imageSize = image.size

    // Left half
    let leftHalfRect = CGRect(
        origin: .zero,
        size: CGSize(
                width: imageSize.width/2,
                height: imageSize.height
                )
    )
    
    // Right half
    let rightHalfRect = CGRect(
        origin: CGPoint(
            x: imageSize.width - (imageSize.width/2).rounded(),
            y: 0
        ),
        size: CGSize(
            width: imageSize.width - (imageSize.width/2).rounded(),
            height: imageSize.height
        )
    )
    // Split image into two parts
    guard let cgRightHalf = image.cgImage?.cropping(to: rightHalfRect) else { return image }
    // Flip right side to be used as left side
    let flippedLeft = UIImage(cgImage: cgRightHalf, scale: image.scale, orientation: .upMirrored)
    let unFlippedRight = UIImage(cgImage: cgRightHalf, scale: image.scale, orientation: image.imageOrientation)
    
    UIGraphicsBeginImageContextWithOptions(imageSize, false, image.scale)
    
    flippedLeft.draw(at: leftHalfRect.origin)
    unFlippedRight.draw(at: rightHalfRect.origin)
    
    guard let splitMirroredImage = UIGraphicsGetImageFromCurrentImageContext() else { return image }
    UIGraphicsEndImageContext()
    return splitMirroredImage
}

結果看起來像

這是它對Core Image的嘗試

    // Splits an image in half vertically and reverses the left remaining half to create a reflection.
final func splitMirrorFilterCIImageVersion(processingImage image: UIImage) -> CIImage? {

    
    guard let ciImageCopy = CIImage(image: image) else { return image.ciImage }
    
    // Image size
    let imageSize = ciImageCopy.extent.size
    let imageRect = CGRect(origin: .zero, size: imageSize)

    // Left half
    let leftHalfRect = CGRect(
        origin: .zero,
        size: CGSize(
                width: imageSize.width/2,
                height: imageSize.height
                )
    )
    
    // Right half
    let rightHalfRect = CGRect(
        origin: CGPoint(
            x: imageSize.width - (imageSize.width/2).rounded(),
            y: 0
        ),
        size: CGSize(
            width: imageSize.width - (imageSize.width/2).rounded(),
            height: imageSize.height
        )
    )
    
    
    
    // Split image into two parts
    let cgRightHalf = ciImageCopy.cropped(to: rightHalfRect)
    context.draw(cgRightHalf.oriented(.upMirrored), in: leftHalfRect, from: imageRect)
    context.draw(cgRightHalf, in: rightHalfRect, from: imageRect)
    
    // I'm stuck here
    
    // Merge two images into one 
    // Here I don't know which filter can be used to merge op
    // CICategoryCompositeOperation filters may fits
}

我認為你在正確的軌道上。

您可以通過使用let leftHalf = rightHalf.transformed(by: transformation)對其應用轉換來從右半部分創建左半部分。 轉換應該對其進行鏡像並將其轉換為正確的 position,即緊鄰右半部分。

您可以使用let result = leftHalf.composited(over: rightHalf)將兩者組合成一個圖像,並使用CIContext渲染該結果。

Frank Schlegel的回答中得到正確的想法后,我重寫了過濾器代碼,現在運行良好。

 // Splits an image in half vertically and reverses the left remaining half to create a reflection.
final func splitMirrorFilterCIImageVersion(processingImage image: UIImage) -> CIImage? {
    
    guard let ciImageCopy = CIImage(image: image) else { return image.ciImage }
    
    // Image size
    let imageSize = ciImageCopy.extent.size
    
    // Right half
    let rightHalfRect = CGRect(
        origin: CGPoint(
            x: imageSize.width - (imageSize.width/2).rounded(),
            y: 0
        ),
        size: CGSize(
            width: imageSize.width - (imageSize.width/2).rounded(),
            height: imageSize.height
        )
    )
            
    // Split image into two parts
    let ciRightHalf = ciImageCopy.cropped(to: rightHalfRect)
    // Make transform to move right part to left
    let transform = CGAffineTransform(translationX: -rightHalfRect.size.width, y: -rightHalfRect.origin.y)
    // Create left part and apply transform then flip it
    let ciLeftHalf = ciRightHalf.transformed(by: transform).oriented(.upMirrored)
            
    // Merge two images into one
    return ciLeftHalf.composited(over: ciRightHalf)
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM