diff --git a/SwiftProject/SwiftProject.xcodeproj/project.pbxproj b/SwiftProject/SwiftProject.xcodeproj/project.pbxproj index 4e76b0c..54f575f 100644 --- a/SwiftProject/SwiftProject.xcodeproj/project.pbxproj +++ b/SwiftProject/SwiftProject.xcodeproj/project.pbxproj @@ -34,6 +34,7 @@ 009DFB112BC8E2E9007B56E8 /* MenuVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 009DFB102BC8E2E9007B56E8 /* MenuVC.swift */; }; 009DFB132BC8EA90007B56E8 /* MenuVCCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 009DFB122BC8EA90007B56E8 /* MenuVCCell.swift */; }; 00B946252B67B7DE00DA668F /* CCSpatialPlayView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 00B946242B67B7DE00DA668F /* CCSpatialPlayView.swift */; }; + 00BD87862BDE595F0014E8B3 /* CCSpatialPhotoDisplayEx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 00BD87852BDE595F0014E8B3 /* CCSpatialPhotoDisplayEx.swift */; }; 00C665732BAA81F900C309C3 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 00C665722BAA81F900C309C3 /* GoogleService-Info.plist */; }; 00C665792BAA94EA00C309C3 /* CopyCrashHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 00C665772BAA941E00C309C3 /* CopyCrashHandler.swift */; }; 00D33BF42B998BF700604A44 /* SpatialImageConvertor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 00D33BF32B998BF700604A44 /* SpatialImageConvertor.swift */; }; @@ -147,6 +148,7 @@ 009DFB102BC8E2E9007B56E8 /* MenuVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuVC.swift; sourceTree = ""; }; 009DFB122BC8EA90007B56E8 /* MenuVCCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuVCCell.swift; sourceTree = ""; }; 00B946242B67B7DE00DA668F /* CCSpatialPlayView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CCSpatialPlayView.swift; sourceTree = ""; }; + 00BD87852BDE595F0014E8B3 /* CCSpatialPhotoDisplayEx.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CCSpatialPhotoDisplayEx.swift; sourceTree = ""; }; 00C665722BAA81F900C309C3 /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = ""; }; 00C665772BAA941E00C309C3 /* CopyCrashHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CopyCrashHandler.swift; sourceTree = ""; }; 00D33BF32B998BF700604A44 /* SpatialImageConvertor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SpatialImageConvertor.swift; sourceTree = ""; }; @@ -326,6 +328,7 @@ isa = PBXGroup; children = ( 1E1EA2872B9325D300A5D5D2 /* CCSpatialPhotoDisplayController.swift */, + 00BD87852BDE595F0014E8B3 /* CCSpatialPhotoDisplayEx.swift */, ); path = CCSpatialPhotoDisplayController; sourceTree = ""; @@ -818,6 +821,7 @@ AF2120CA2B4E95DA00400B7F /* UITableView+Add.swift in Sources */, 1EFAF0BA2B8AF5EF002A1773 /* UIView+CCExtension.swift in Sources */, 009DFB0E2BC8CFA2007B56E8 /* FeedbackView.swift in Sources */, + 00BD87862BDE595F0014E8B3 /* CCSpatialPhotoDisplayEx.swift in Sources */, AF2120C42B4E95DA00400B7F /* UIImage+Add.swift in Sources */, 1EFAF0C02B8B7A59002A1773 /* VRPhotoTransformController.swift in Sources */, AF2120D82B4E9AC500400B7F /* CCAddImageView.swift in Sources */, diff --git a/SwiftProject/SwiftProject/Project/Controller/RecordingVideo/CCSpatialPhotoDisplayController/CCSpatialPhotoDisplayController.swift b/SwiftProject/SwiftProject/Project/Controller/RecordingVideo/CCSpatialPhotoDisplayController/CCSpatialPhotoDisplayController.swift index 001a0f1..6b6125a 100644 --- a/SwiftProject/SwiftProject/Project/Controller/RecordingVideo/CCSpatialPhotoDisplayController/CCSpatialPhotoDisplayController.swift +++ b/SwiftProject/SwiftProject/Project/Controller/RecordingVideo/CCSpatialPhotoDisplayController/CCSpatialPhotoDisplayController.swift @@ -26,7 +26,8 @@ class CCSpatialPhotoDisplayController: BaseController { // lazy var externalWindow:UIWindow = { // return UIWindow(frame: self.view.bounds) // }() - + //标记是否为横屏 + var isLandscape:Bool = false var externalVC:ZZHExternalViewController? var externalDispalylink:CADisplayLink? var externalImageView:UIImageView? @@ -46,6 +47,27 @@ class CCSpatialPhotoDisplayController: BaseController { //空间视频 交叉眼 红蓝立体 高斯模糊 var type = 0 + //增加一个瞳距、缩放的调节按钮 + var edBtn:UIButton? + var temScale:CGFloat = 1.0 + var currentScale:CGFloat = 1.0 {//当前缩放值 + didSet { + if imgData != nil { + selectedSpatialType(selectedIndex: currentSpatialType) + } + } + } + var currentED:Int = 0{//当前的瞳距 + didSet { + if imgData != nil { + selectedSpatialType(selectedIndex: currentSpatialType) + } + } + } + var currentSpatialType = 0//标记当前选中的浏览种类 + + //标记是否正在串流中:目前就是用于控制是否显示瞳距调节的slider部分 + var isPlayingOnExternalScreen = false lazy var mTopImgView:UIImageView = { //393*236 @@ -65,9 +87,6 @@ class CCSpatialPhotoDisplayController: BaseController { let img2:UIImage = UIImage.init(named: NSLocalizedString("displayvc_desc", comment: ""))! button.setImage(img2, for: UIControl.State.normal) button.frame = CGRect(x: 0, y: 0, width: 173, height: 42) -// button.titleLabel?.font = KFont_Regular(14) -// button.titleLabel?.adjustsFontSizeToFitWidth = true -// button.updateBtnEdgeInsets(style: .Left, space: 8) button.centerY = KScreenHeight - 120 button.centerX = self.view.centerX @@ -129,6 +148,10 @@ class CCSpatialPhotoDisplayController: BaseController { return imageView }() + lazy var imgMaskView:UIView = { + return UIView() + }() + var typeData:[(icon:String,title:String,isHiden:Bool)] = [(icon:"type_check",title:NSLocalizedString("平行眼", comment: ""),isHiden:false), (icon:"type_check",title:NSLocalizedString("单眼2D", comment: ""),isHiden:false), @@ -160,6 +183,7 @@ class CCSpatialPhotoDisplayController: BaseController { didSet{ //更新串流UI setttinisScreenMirroring(isScreenMirroring: isAirPlayActive) + isPlayingOnExternalScreen = isAirPlayActive } } @@ -183,28 +207,40 @@ class CCSpatialPhotoDisplayController: BaseController { let orientation = UIDevice.current.orientation switch orientation { case .portrait , .portraitUpsideDown: + isLandscape = false print("Portrait") navtionBar?.snp.updateConstraints { make in make.top.equalToSuperview().offset(0) } mImgView.snp.updateConstraints { make in - make.height.equalTo(KScreenWidth) + make.height.equalTo(240) + } + edBtn!.snp.updateConstraints { make in + make.centerY.equalTo((edBtn?.superview!.snp.bottom)!).offset( -120) } self.view.layoutIfNeeded() self.navtionBar?.isHidden = false mTopImgView.isHidden = false + edBtn?.isHidden = false break case .landscapeLeft , .landscapeRight: + isLandscape = true print("Landscape ...") navtionBar?.snp.updateConstraints { make in - make.top.equalToSuperview().offset(-KStatusBarHeight * 0.5) + make.top.equalToSuperview().offset(-30) } + + edBtn!.snp.updateConstraints { make in + make.centerY.equalTo((edBtn?.superview!.snp.bottom)!).offset( -50) + } + mImgView.snp.updateConstraints { make in - make.height.equalTo(240) + make.height.equalTo(KScreenWidth) } self.view.layoutIfNeeded() self.navtionBar?.isHidden = true mTopImgView.isHidden = true + edBtn?.isHidden = true break default: print("Other") @@ -214,6 +250,24 @@ class CCSpatialPhotoDisplayController: BaseController { override func viewDidLoad() { super.viewDidLoad() + + //提前初始化配置参数 + if let defaultScale = UserDefaults.standard.value(forKey: userdefaultValueKey_scale) as? CGFloat { + currentScale = defaultScale + } + else { + UserDefaults.standard.setValue(currentScale, forKey: userdefaultValueKey_scale) + UserDefaults.standard.synchronize() + } + + if let defaultED = UserDefaults.standard.value(forKey: userdefaultValueKey_ed) as? Int { + currentED = defaultED + } + else{ + UserDefaults.standard.setValue(currentED, forKey: userdefaultValueKey_ed) + UserDefaults.standard.synchronize() + } + KAppDelegate?.allowRotation = true listingScreenOrientatinChange() updateNavgationBarColorImgMakeConstraint() @@ -241,7 +295,7 @@ class CCSpatialPhotoDisplayController: BaseController { let image = UIImage(data: originalData!) // mImgView.image = image imgOritentation = image?.imageOrientation ?? .left - selectedSpatialType(selectedIndex: 0) + selectedSpatialType(selectedIndex: currentSpatialType) let isSpatial = isSpatialImage(originalData: originalData!) if !isSpatial { print("这不是一张空间图片") @@ -281,10 +335,30 @@ class CCSpatialPhotoDisplayController: BaseController { make.height.equalTo(240) make.centerY.equalToSuperview() } + self.view.addSubview(imgMaskView) + imgMaskView.snp.makeConstraints { make in + make.left.top.right.bottom.equalTo(mImgView) + } + imgMaskView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(tapPlayerMaskView(sender: )))) + imgMaskView.addGestureRecognizer(UIPinchGestureRecognizer(target: self, action: #selector(pinchPlayerMaskView(sender: )))) self.view.addSubview(tipsButton) + + edBtn = UIButton() + edBtn?.setImage(UIImage(named: "custom_TuningBtn"), for: .normal) + edBtn?.addTarget(self, action: #selector(showEDView(sender:)), for: .touchUpInside) + self.view.addSubview(edBtn!) + edBtn!.snp.makeConstraints { make in + make.centerY.equalTo((edBtn?.superview!.snp.bottom)!).offset( -120) +// make.bottom.equalToSuperview().offset(-70) + make.width.height.equalTo(40) + make.right.equalToSuperview().offset(-20) + } + + checkAirPlayStatus() + } override func viewDidDisappear(_ animated: Bool) { @@ -415,10 +489,9 @@ class CCSpatialPhotoDisplayController: BaseController { func selectedSpatialType(selectedIndex:Int) { // 处理分段选择器值改变事件 - - print("选中了第 \(selectedIndex) 个选项") -// player.pause() - mImgView.frame = CGRect.init(x: 0, y: 200, width: self.view.frame.size.width, height: 240) + currentSpatialType = selectedIndex +// print("选中了第 \(selectedIndex) 个选项") +// mImgView.frame = CGRect.init(x: 0, y: 200, width: self.view.frame.size.width, height: 240) guard let imageSource = CGImageSourceCreateWithData(imgData! as CFData, nil) else { return @@ -440,72 +513,32 @@ class CCSpatialPhotoDisplayController: BaseController { if(selectedIndex == 1){ //空间照片 --- 单眼2D(展示原照片或者广角或者主摄其中一个) let image = UIImage(data: photoOriginalData!) - mImgView.image = image + mImgView.image = monocular2DImgWith(drawImg: image!, scale: currentScale) }else if(selectedIndex == 0){ //平行眼 - let newpb = joinImages( leftImage: lciImage, rightImage:rciImage ) - let lastImg = convertCIImageToUIImage(ciImage: newpb)! - DispatchQueue.main.async { [weak self] in - self!.mImgView.image = lastImg - } + let newpb = joinImages(leftImage: lciImage, rightImage: rciImage, scale: currentScale, ed: currentED) + let lastImg = UIImage(ciImage: newpb) +// DispatchQueue.main.async { [weak self] in + self.mImgView.image = lastImg +// } }else if(selectedIndex == 2){ - //红蓝立体 - let redColorMatrix: [CGFloat] = [ - 0.0, 0.0, 0.0, 0.0, 0.0, // 红色通道 - 0.0, 0.0, 0.0, 0.0, 0.0, // 绿色通道 - 0.0, 0.0, 0.5, 0.0, 0.0, // 蓝色通道 - 0.0, 0.0, 0.0, 1.0, 0.0 // 透明通道 - ] - - let blueColorMatrix: [CGFloat] = [ - 0.5, 0.0, 0.0, 0.0, 0.0, // 红色通道 - 0.0, 0.0, 0.0, 0.0, 0.0, // 绿色通道 - 0.0, 0.0, 0.0, 0.0, 0.0, // 蓝色通道 - 0.0, 0.0, 0.0, 1.0, 0.0 // 透明通道 - ] - - let redFilter = CIFilter(name: "CIColorMatrix")! - redFilter.setValue(lciImage, forKey: kCIInputImageKey) - redFilter.setValue(CIVector(values: redColorMatrix, count: redColorMatrix.count), forKey: "inputRVector") - - let blueFilter = CIFilter(name: "CIColorMatrix")! - blueFilter.setValue(rciImage, forKey: kCIInputImageKey) - blueFilter.setValue(CIVector(values: blueColorMatrix, count: blueColorMatrix.count), forKey: "inputBVector") - - // 获取处理后的图像 - if let redOutputImage = redFilter.outputImage, - let blueOutputImage = blueFilter.outputImage { - - // CIScreenBlendMode: 通过将颜色通道值反转并相乘,然后将结果反转回来,将两个图像合成为屏幕混合效果。 - // CIHardLightBlendMode: 使用源图像的亮度来决定如何混合两个图像。较亮的像素将更多地影响结果。 - // CILightenBlendMode: 比较两个图像的像素,并选择较亮的像素作为最终结果。 - // CIColorDodgeBlendMode: 使用源图像的颜色信息来增加目标图像的颜色亮度。 - // CIColorBurnBlendMode: 使用源图像的颜色信息来降低目标图像的颜色亮度。 - // CIDarkenBlendMode: 比较两个图像的像素,并选择较暗的像素作为最终结果。 - // CILinearDodgeBlendMode: 使用线性增加的方式将两个图像相加,产生一种亮度叠加的效果。 - // CIMultiplyBlendMode: 将两个图像的像素值相乘,产生一种乘法混合效果。 - // CISourceOverCompositing: 将源图像放在目标图像上方,产生一种覆盖混合效果。 - let compositeFilter = CIFilter(name: "CIScreenBlendMode")! - compositeFilter.setValue(redOutputImage, forKey: kCIInputImageKey) - compositeFilter.setValue(blueOutputImage, forKey: kCIInputBackgroundImageKey) - let lastImg = compositeFilter.outputImage! - DispatchQueue.main.async { [weak self] in - var ri = UIImage(ciImage: lastImg) - ri = ri.getUpImg(imgOrigOritentation: self?.imgOritentation ?? .left) - self!.mImgView.image = ri - } - } + + let lastImg = joinImages_red_blue(lciImage: lciImage, rciImage: rciImage, scale: currentScale) + var ri = UIImage(ciImage: lastImg) + ri = ri.getUpImg(imgOrigOritentation: self.imgOritentation ) + self.mImgView.image = ri + }else if(selectedIndex == 3){ //交叉眼 - let newpb = joinImages( leftImage:rciImage , rightImage:lciImage ) - let lastImg = convertCIImageToUIImage(ciImage: newpb)! - DispatchQueue.main.async { [weak self] in - self!.mImgView.image = lastImg - } + let newpb = joinImages(leftImage: rciImage , rightImage:lciImage , scale: currentScale, ed: currentED) + let lastImg = UIImage(ciImage: newpb) +// DispatchQueue.main.async { [weak self] in + self.mImgView.image = lastImg +// } } } @@ -569,24 +602,6 @@ class CCSpatialPhotoDisplayController: BaseController { - //将两张图片合成一张图片 - func joinImages2( leftImage:CIImage, rightImage:CIImage) -> CIImage { - let left = UIImage(ciImage: leftImage ) - let right = UIImage(ciImage: rightImage ) - - let imageWidth = left.size.width/2 + right.size.width/2 - let imageHeight = left.size.height/2 - - let newImageSize = CGSize(width:imageWidth, height: imageHeight); - UIGraphicsBeginImageContextWithOptions(newImageSize, false, 1); - left.draw(in: CGRect(x:0, y:0, width:imageWidth/2, height:imageHeight)) - right.draw(in: CGRect(x:imageWidth/2, y:0, width:imageWidth/2, height:imageHeight)) - let image = UIGraphicsGetImageFromCurrentImageContext()! - UIGraphicsEndImageContext(); - - let ci = CIImage(cgImage: image.cgImage!) - return ci - } @@ -600,58 +615,5 @@ class CCSpatialPhotoDisplayController: BaseController { } - func convertCIImageToUIImage(ciImage: CIImage) -> UIImage? { - let context = CIContext(options: nil) - if let cgImage = context.createCGImage(ciImage, from: ciImage.extent) { - let uiImage = UIImage(cgImage: cgImage) - return uiImage - } - return nil - } - - //将两张图片合成一张图片 - func joinImages( leftImage:CIImage, rightImage:CIImage) -> CIImage { - var left = UIImage(ciImage: leftImage ) - left = left.getUpImg(imgOrigOritentation: imgOritentation) - var right = UIImage(ciImage: rightImage ) - right = right.getUpImg(imgOrigOritentation: imgOritentation) - - let imageWidth = left.size.width/2 + right.size.width/2 - let imageHeight = left.size.height/2 - - let newImageSize = CGSize(width:imageWidth, height: imageHeight); - UIGraphicsBeginImageContextWithOptions(newImageSize, false, 1); - left.draw(in: CGRect(x:0, y:0, width:imageWidth/2, height:imageHeight)) - right.draw(in: CGRect(x:imageWidth/2, y:0, width:imageWidth/2, height:imageHeight)) - let image = UIGraphicsGetImageFromCurrentImageContext()! - UIGraphicsEndImageContext(); - - let ci = CIImage(cgImage: image.cgImage!) - return ci - } - - func pixelBuffer(from ciImage: CIImage) -> CVPixelBuffer? { - var pixelBuffer: CVPixelBuffer? - let attributes: [String: Any] = [ - kCVPixelBufferCGImageCompatibilityKey as String: kCFBooleanTrue, - kCVPixelBufferCGBitmapContextCompatibilityKey as String: kCFBooleanTrue - ] - - let width = Int(ciImage.extent.width) - let height = Int(ciImage.extent.height) - - let status = CVPixelBufferCreate(kCFAllocatorDefault, width, height, kCVPixelFormatType_32ARGB, attributes as CFDictionary, &pixelBuffer) - - if status == kCVReturnSuccess, let pixelBuffer = pixelBuffer { - let context = CIContext() - context.render(ciImage, to: pixelBuffer) - return pixelBuffer - } - - return nil - } - - - } diff --git a/SwiftProject/SwiftProject/Project/Controller/RecordingVideo/CCSpatialPhotoDisplayController/CCSpatialPhotoDisplayEx.swift b/SwiftProject/SwiftProject/Project/Controller/RecordingVideo/CCSpatialPhotoDisplayController/CCSpatialPhotoDisplayEx.swift new file mode 100644 index 0000000..8fd9bee --- /dev/null +++ b/SwiftProject/SwiftProject/Project/Controller/RecordingVideo/CCSpatialPhotoDisplayController/CCSpatialPhotoDisplayEx.swift @@ -0,0 +1,235 @@ +// +// CCSpatialPhotoDisplayEx.swift +// SwiftProject +// +// Created by aaa on 2024/4/28. +// + +import Foundation +import UIKit + +extension CCSpatialPhotoDisplayController { + //点击了player 的maskview + @objc func tapPlayerMaskView(sender:UITapGestureRecognizer) { + if isLandscape { +// if let mcallback = maskViewTapCallback { +// mcallback() +// } +// self.timeSlider?.isHidden = !self.timeSlider!.isHidden +// self.edBtn?.isHidden = !self.edBtn!.isHidden + self.navtionBar?.isHidden = !((self.navtionBar?.isHidden)!) + edBtn?.isHidden = !((edBtn?.isHidden)!) + } + + } + + //缩放手势 正在player的maskview进行缩放 + @objc func pinchPlayerMaskView(sender:UIPinchGestureRecognizer) { + if sender.state == .began { + temScale = 1.0 + } + + currentScale = currentScale - (temScale - sender.scale) + currentScale = min(currentScale, 1.8) + currentScale = max(currentScale, 0.3) + temScale = sender.scale + print("\(sender.scale) currentScale....\(currentScale)") + } + + @objc func showEDView(sender:UIButton) { + print("showedview....") + CustomParamBoardView.showBoard(scaleCallback: {[weak self] scale in + self?.currentScale = scale + }, edCallback: {[weak self] ed in + self?.currentED = ed + },resetCallback:{[weak self] in + self?.currentScale = 1.0 + self?.currentED = 0 + }, dismissCallback:{[weak self] in + self?.saveParams() + },scale: currentScale, ed: currentED,canChangeED: isPlayingOnExternalScreen) + + } + + func saveParams(){ + UserDefaults.standard.setValue(currentScale, forKey: userdefaultValueKey_scale ) + UserDefaults.standard.setValue(currentED, forKey: userdefaultValueKey_ed) + UserDefaults.standard.synchronize() + } + + //单眼2D + func monocular2DImgWith(drawImg:UIImage,scale:CGFloat)->UIImage { + if scale > 1 || scale < 1 { + let drawImageSize = drawImg.size + let newImgSize = CGSizeMake(drawImageSize.width * scale, drawImageSize.height * scale) + let newRect = CGRect(origin: CGPoint(x: (drawImageSize.width - newImgSize.width) * 0.5, y: (drawImageSize.height - newImgSize.height) * 0.5), size: newImgSize) + UIGraphicsBeginImageContextWithOptions(drawImageSize, false, 1); + drawImg.draw(in: newRect) + let image = UIGraphicsGetImageFromCurrentImageContext()! + UIGraphicsEndImageContext(); + return image + } + else { + return drawImg + } + } + + + + + //合成红蓝立体图片 + func joinImages_red_blue(lciImage:CIImage,rciImage:CIImage,scale: CGFloat) -> CIImage { + // 创建红色和蓝色滤镜 + let redColorMatrix: [CGFloat] = [ + 0.0, 0.0, 0.0, 0.0, 0.0, // 红色通道 + 0.0, 0.0, 0.0, 0.0, 0.0, // 绿色通道 + 0.0, 0.0, 1.0, 0.0, 0.0, // 蓝色通道 + 0.0, 0.0, 0.0, 1.0, 0.0 // 透明通道 + ] + + let blueColorMatrix: [CGFloat] = [ + 1.0, 0.0, 0.0, 0.0, 0.0, // 红色通道 + 0.0, 0.0, 0.0, 0.0, 0.0, // 绿色通道 + 0.0, 0.0, 0.0, 0.0, 0.0, // 蓝色通道 + 0.0, 0.0, 0.0, 1.0, 0.0 // 透明通道 + ] + + let redFilter = CIFilter(name: "CIColorMatrix")! + redFilter.setValue(lciImage, forKey: kCIInputImageKey) + redFilter.setValue(CIVector(values: redColorMatrix, count: redColorMatrix.count), forKey: "inputRVector") + + let blueFilter = CIFilter(name: "CIColorMatrix")! + blueFilter.setValue(rciImage, forKey: kCIInputImageKey) + blueFilter.setValue(CIVector(values: blueColorMatrix, count: blueColorMatrix.count), forKey: "inputBVector") + var lastImg:CIImage? = nil + // 获取处理后的图像 + if let redOutputImage = redFilter.outputImage, + let blueOutputImage = blueFilter.outputImage { + + let compositeFilter = CIFilter(name: "CIScreenBlendMode")! + compositeFilter.setValue(redOutputImage, forKey: kCIInputImageKey) + compositeFilter.setValue(blueOutputImage, forKey: kCIInputBackgroundImageKey) + + let sharpenedFilter = CIFilter(name: "CISharpenLuminance")! + sharpenedFilter.setValue(compositeFilter.outputImage, forKey: kCIInputImageKey) + sharpenedFilter.setValue(2, forKey: kCIInputSharpnessKey) + lastImg = sharpenedFilter.outputImage! + } + if scale == 1 { + return lastImg! + } + else { + let drawImg = UIImage(ciImage: lastImg!) + let drawImageSize = drawImg.size + let newImgSize = CGSizeMake(drawImageSize.width * scale, drawImageSize.height * scale) + let newRect = CGRect(origin: CGPoint(x: (drawImageSize.width - newImgSize.width) * 0.5, y: (drawImageSize.height - newImgSize.height) * 0.5), size: newImgSize) + UIGraphicsBeginImageContextWithOptions(drawImageSize, false, 1); + drawImg.draw(in: newRect) + let image = UIGraphicsGetImageFromCurrentImageContext()! + UIGraphicsEndImageContext(); + + + let ci = CIImage(cgImage: image.cgImage!) + return ci + } + } + + + + + + + //平行眼、交叉眼 + func joinImages( leftImage:CIImage, rightImage:CIImage,scale:CGFloat,ed:Int) -> CIImage { + +//缩放参数,此处必须大于0.5 +//瞳距参数,暂定 瞳距与像素点的比例为1:2,瞳距的值范围为 -30 ~ +30 之间的整数 + let edS = 20 //比列 + + var left = UIImage(ciImage: leftImage ) + left = left.getUpImg(imgOrigOritentation: imgOritentation) + + var right = UIImage(ciImage: rightImage ) + right = right.getUpImg(imgOrigOritentation: imgOritentation) + + //获取缩放图片 + let (n_left,n_left_size) = getImgWithScale(image: left, scale: scale) + let (n_right,n_right_size) = getImgWithScale(image: right, scale: scale) + + //获取调整了瞳距的图片 + let x_offset = CGFloat(abs(ed) * edS) //关于瞳距的x偏移量 + let imageWidth = left.size.width*0.5 - x_offset + let imageHeight = left.size.height + let (ed_left,last_left_size) = getImgWithED(image: n_left, drawImgWidth: imageWidth,drawSize: n_left_size) + let (ed_right,last_right_size) = getImgWithED(image: n_right, drawImgWidth: imageWidth,drawSize: n_right_size) + let newImageSize = left.size + UIGraphicsBeginImageContextWithOptions(newImageSize, false, 1) + + if (ed > 0) {//左视图宽度减小,同时x点的坐标值为0;右视图宽度减小,同时x点的坐标值增加 + ed_left.draw(in: CGRect(x:0, y:(imageHeight - last_left_size.height) * 0.5, width:last_left_size.width, height:last_left_size.height)) + ed_right.draw(in: CGRect(x:newImageSize.width - last_right_size.width, y:(imageHeight - last_right_size.height) * 0.5, width:last_right_size.width, height:last_right_size.height)) + + } + else if (ed < 0) { + ed_left.draw(in: CGRect(x:newImageSize.width*0.5 - last_left_size.width, y:(imageHeight - n_left_size.height) * 0.5, width:last_left_size.width, height:last_left_size.height)) + ed_right.draw(in: CGRect(x:newImageSize.width*0.5, y:(imageHeight - n_right_size.height) * 0.5, width:last_right_size.width, height:last_right_size.height)) + } + else {//瞳距没有改变的情况 + let leftRect = CGRect(x:(imageWidth - n_left_size.width) * 0.5, y:(imageHeight - n_left_size.height) * 0.5 , width:n_left_size.width, height:n_left_size.height) + ed_left.draw(in:leftRect ) + + let rightRect = CGRect(x:imageWidth + (imageWidth - n_right_size.width) * 0.5 , y:(imageHeight - n_right_size.height) * 0.5, width:n_right_size.width, height:n_right_size.height) + ed_right.draw(in:rightRect ) + } + + + let image = UIGraphicsGetImageFromCurrentImageContext()! + UIGraphicsEndImageContext(); + + let ci = CIImage(cgImage: image.cgImage!) + return ci + } + + //图像缩放 调整默认scale,默认值应当为1 + func getImgWithScale(image:UIImage,scale:CGFloat) -> (UIImage,CGSize) { + //获取原始的rect + let originSize = CGSize(width: image.size.width*0.5, height: image.size.height*0.5) + + var newImage = image + var newSize = originSize//作图的区域 + + if scale > 1 {//图片会被裁减,但size的宽度不会改变,而高度会随scale发生改变 + //计算放大图片需要用于截取图片的size, + //本次height在画布上的增量 + let Hs_add = (image.size.height - image.size.height*0.5)*(scale - 1) + //根据本次在画布上的增量height重新计算画布size + newSize = CGSizeMake(originSize.width, originSize.height + Hs_add) + + //本次根据scale进行初步计算的裁剪区域size + let cutSize = CGSizeMake((2 - scale)*(image.size.height * newSize.width/newSize.height),(2 - scale) * image.size.height) + + let cutRect = CGRectMake((image.size.width - cutSize.width)*0.5, (image.size.height - cutSize.height) * 0.5, cutSize.width, cutSize.height) + newImage = image.imageAtRect(rect: cutRect)! + } + else if scale < 1 {//图片不会被裁减,但size会被缩小 + //计算被等比缩小的size + newSize = CGSizeMake(scale*originSize.width, scale*originSize.height) + } + return (newImage,newSize) + } + + //图像瞳距,参数条件必须满足:image能够等比缩放后填充满drawSize,即image的真实size与drawSize预期size并不要求一致,但要求等比 + func getImgWithED(image:UIImage,drawImgWidth:CGFloat,drawSize:CGSize) -> (UIImage,CGSize) { + if drawSize.width <= drawImgWidth { + + print("瞳距返回,不用处理") + return (image,drawSize) + } + print("瞳距要处理") + let newImageWidth = drawImgWidth * image.size.height / drawSize.height + let dRect = CGRectMake((image.size.width - newImageWidth) * 0.5, 0, newImageWidth, image.size.height) + let newImage = image.imageAtRect(rect: dRect) + return (newImage!,CGSize(width: drawImgWidth, height: drawSize.height)) + } + +} diff --git a/SwiftProject/SwiftProject/Project/Controller/RecordingVideo/CCSpatialVideoDisplayController/CCSpatialVideoDisplayController.swift b/SwiftProject/SwiftProject/Project/Controller/RecordingVideo/CCSpatialVideoDisplayController/CCSpatialVideoDisplayController.swift index 7d46665..ad3427a 100644 --- a/SwiftProject/SwiftProject/Project/Controller/RecordingVideo/CCSpatialVideoDisplayController/CCSpatialVideoDisplayController.swift +++ b/SwiftProject/SwiftProject/Project/Controller/RecordingVideo/CCSpatialVideoDisplayController/CCSpatialVideoDisplayController.swift @@ -294,7 +294,7 @@ class CCSpatialVideoDisplayController: BaseController { } navtionBar?.snp.updateConstraints { make in - make.top.equalToSuperview().offset(-KStatusBarHeight * 0.5) + make.top.equalToSuperview().offset(-30) } self.view.layoutIfNeeded() self.customPlayer.layoutViewWhenScreenLandscape(value: true) diff --git a/SwiftProject/SwiftProject/Project/Controller/RecordingVideo/CCSpatialVideoDisplayController/ZZHCustomPlayer.swift b/SwiftProject/SwiftProject/Project/Controller/RecordingVideo/CCSpatialVideoDisplayController/ZZHCustomPlayer.swift index 26a8942..3a466c6 100644 --- a/SwiftProject/SwiftProject/Project/Controller/RecordingVideo/CCSpatialVideoDisplayController/ZZHCustomPlayer.swift +++ b/SwiftProject/SwiftProject/Project/Controller/RecordingVideo/CCSpatialVideoDisplayController/ZZHCustomPlayer.swift @@ -10,7 +10,8 @@ import UIKit import AVKit typealias CustomMaskViewTapCallback = ()->Void - +let userdefaultValueKey_scale = "userdefaultValueKey_scale" +let userdefaultValueKey_ed = "userdefaultValueKey_ed" class ZZHCustomPlayer: UIView { //点击maskview 的回调,主要用于方向旋转 @@ -55,8 +56,7 @@ class ZZHCustomPlayer: UIView { var temScale:CGFloat = 1.0 var currentScale:CGFloat = 1.0//当前缩放值 var currentED:Int = 0//当前的瞳距 - let userdefaultValueKey_scale = "userdefaultValueKey_scale" - let userdefaultValueKey_ed = "userdefaultValueKey_ed" + //ui var playerLayerBgView:UIView? @@ -108,8 +108,8 @@ class ZZHCustomPlayer: UIView { } func saveParams(){ - UserDefaults.standard.setValue(currentScale, forKey: self.userdefaultValueKey_scale ) - UserDefaults.standard.setValue(currentED, forKey: self.userdefaultValueKey_ed) + UserDefaults.standard.setValue(currentScale, forKey: userdefaultValueKey_scale ) + UserDefaults.standard.setValue(currentED, forKey: userdefaultValueKey_ed) UserDefaults.standard.synchronize() }