繁体   English   中英

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

[英]How to implement contentMode for GLKView displaying a CIImage?

我已经制作了一个GLKView子类来显示CIImage以获得更好的性能,以显示CIFilter链的输出图像。

然而,似乎是我需要实现contentMode逻辑才能有一个正确的inRectdrawImage(image: CIImage, inRect: CGRect, fromRect: CGRect)drawRect(rect: CGRect)调用。

有谁知道如何实现这样的逻辑以便与UIImageView的contentMode行为保持一致?

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

为了使glkView以可见的格式显示CIImage,这对我有用。

在glkView(_视图:GLKView,drawIn rect:CGRect)中传递的rect需要由视图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(_视图:GLKView,drawIn rect:CGRect)中执行此操作

    让AdjustedRect = CGRect(x:0.0,y:0.0,width:rect.width * myScaleFactor,height:rect.height * myScaleFactor)

然后使用ciContext在AdjustedRect中绘制ciImage。 使用ciImage的范围作为from参数,如下所示:

ciContext!.draw(outputImage, in: adjustedRect , from: (ciSourceImage?.extent)!)
  1. 哦,是的。 我认为您已经找到了用于调整GLKView比例因子的技术说明。 它在GLKView的子类中需要一行。 参见https://developer.apple.com/library/content/qa/qa1909/_index.html

您很有可能需要对该方法进行一些调整。 我目前正在针对不同源ciImage进行问题方向更改。

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

希望对Will LB有所帮助

用于使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
    }
}

在draw(_: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)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM