如何实现显示CIImage的GLKView的contentMode?

时间:2016-02-24 03:37:22

标签: ios ciimage glkview contentmode

我创建了一个GLKView子类来显示CIImage,以便更好地显示CIFilter链的输出图像。

但是,似乎我需要实施contentMode逻辑,才能在inRect调用中为drawImage(image: CIImage, inRect: CGRect, fromRect: CGRect)提供正确的drawRect(rect: CGRect)

任何人都知道如何实现这样的逻辑以符合UIImageView的contentMode行为?

2 个答案:

答案 0 :(得分:0)

在iOS 10.3中,contentMode的设置似乎不会影响glkView。 它看起来总是一个bottomLeft模式。

为了让glkView以可查看的格式显示CIImage,这对我有用。

在glkView中传递的rect(_ view:GLKView,drawIn rect:CGRect)需要由视图contentScaleFactor修改

  1. 此代码假设您已在GLKViewController的viewDidLoad方法中初始化了EAGLContext(我的glkView名为effectView2)

    context = EAGLContext.init(api: EAGLRenderingAPI.openGLES2)
    if context != nil {
    effectView2.context = self.context!
    
    EAGLContext.setCurrent(self.context)
    ciContext = CIContext.init(eaglContext: context!)
    
  2. 设置glkView后设置比例因子

    myScaleFactor = view.contentScaleFactor

  3. 你的glkView中的
  4. (_ view:GLKView,drawIn rect:CGRect)执行此操作

    let adjustedRect = CGRect(x:0.0,y:0.0,width:rect.width * myScaleFactor,height:rect.height * myScaleFactor)

  5. 然后用你的ciContext在adjustRect中绘制ciImage。使用ciImage的范围作为parm,如下所示:

    ciContext!.draw(outputImage, in: adjustedRect , from: (ciSourceImage?.extent)!)
    
    1. 哦,是的。我假设您已找到用于调整GLKView比例因子的技术说明。它在GLKView的子类中调用一行。请参阅https://developer.apple.com/library/content/qa/qa1909/_index.html
    2. 这种方法很可能需要一些调整。我目前正在研究不同来源ciImages的问题方向更改。

      我花了很长时间才找到这么多,所以我想分享这些发现.. 请发布您找到的任何改进!

      希望它有所帮助 请问L-B

答案 1 :(得分:0)

使contentMode以与UIView类似的方式工作。我做了下面的课。

final class ContenModeEnforcer {
    static func rectFor(contentMode: UIViewContentMode, fromRect: CGRect, toRect: CGRect) -> CGRect {
        switch contentMode {
        case .scaleToFill:
            return toRect

        case .scaleAspectFit:
            return aspectFit(fromRect, toRect: toRect)

        case .scaleAspectFill:
            return aspectFill(fromRect, toRect: toRect)

        case .redraw:
            return fromRect

        case .center:
            let origin = CGPoint(
                x: (toRect.size.width - fromRect.size.width) / 2,
                y: (toRect.size.height - fromRect.size.height) / 2)
            return CGRect(origin: origin, size: fromRect.size)

        case .top:
            let origin = CGPoint(
                x: (toRect.size.width - fromRect.size.width) / 2,
                y: 0.0)
            return CGRect(origin: origin, size: fromRect.size)

        case .bottom:
            let origin = CGPoint(
                x: (toRect.size.width - fromRect.size.width) / 2,
                y: toRect.size.height - fromRect.size.height)
            return CGRect(origin: origin, size: fromRect.size)

        case .left:
            let origin = CGPoint(
                x: 0.0,
                y: (toRect.size.height - fromRect.size.height) / 2)
            return CGRect(origin: origin, size: fromRect.size)

        case .right:
            let origin = CGPoint(
                x: toRect.size.width - fromRect.size.width,
                y: (toRect.size.height - fromRect.size.height) / 2)
            return CGRect(origin: origin, size: fromRect.size)


        case .topLeft:
            let origin = CGPoint(
                x: 0.0,
                y: 0.0)
            return CGRect(origin: origin, size: fromRect.size)

        case .topRight:
            let origin = CGPoint(
                x: toRect.size.width - fromRect.size.width,
                y: 0.0)
            return CGRect(origin: origin, size: fromRect.size)

        case .bottomLeft:
            let origin = CGPoint(
                x: 0.0,
                y: toRect.size.height - fromRect.size.height)
            return CGRect(origin: origin, size: fromRect.size)

        case .bottomRight:
            let origin = CGPoint(
                x: toRect.size.width - fromRect.size.width,
                y: toRect.size.height - fromRect.size.height)
            return CGRect(origin: origin, size: fromRect.size)
        }
    }

    static fileprivate func aspectFit(_ fromRect: CGRect, toRect: CGRect) -> CGRect {
        let fromAspectRatio = fromRect.size.width / fromRect.size.height;
        let toAspectRatio = toRect.size.width / toRect.size.height;

        var fitRect = toRect

        if (fromAspectRatio > toAspectRatio) {
            fitRect.size.height = toRect.size.width / fromAspectRatio;
            fitRect.origin.y += (toRect.size.height - fitRect.size.height) * 0.5;
        } else {
            fitRect.size.width = toRect.size.height  * fromAspectRatio;
            fitRect.origin.x += (toRect.size.width - fitRect.size.width) * 0.5;
        }

        return fitRect.integral
    }

    static fileprivate func aspectFill(_ fromRect: CGRect, toRect: CGRect) -> CGRect {
        let fromAspectRatio = fromRect.size.width / fromRect.size.height;
        let toAspectRatio = toRect.size.width / toRect.size.height;

        var fitRect = toRect

        if (fromAspectRatio > toAspectRatio) {
            fitRect.size.width = toRect.size.height  * fromAspectRatio;
            fitRect.origin.x += (toRect.size.width - fitRect.size.width) * 0.5;
        } else {
            fitRect.size.height = toRect.size.width / fromAspectRatio;
            fitRect.origin.y += (toRect.size.height - fitRect.size.height) * 0.5;
        }

        return fitRect.integral
    }
}

在平局中(_:CGRect)。

let inputBounds = image.extent
let drawableBounds = CGRect(x: 0, y: 0, width: self.drawableWidth, height: self.drawableHeight)
let targetBounds = ContenModeEnforcer.rectFor(contentMode: contentMode, fromRect: inputBounds, toRect: drawableBounds)
ciContext.draw(image, in: targetBounds, from: inputBounds)