完成图片的缩放、瞳距
This commit is contained in:
parent
03ae208bd7
commit
b176c459c2
@ -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 = "<group>"; };
|
||||
009DFB122BC8EA90007B56E8 /* MenuVCCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuVCCell.swift; sourceTree = "<group>"; };
|
||||
00B946242B67B7DE00DA668F /* CCSpatialPlayView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CCSpatialPlayView.swift; sourceTree = "<group>"; };
|
||||
00BD87852BDE595F0014E8B3 /* CCSpatialPhotoDisplayEx.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CCSpatialPhotoDisplayEx.swift; sourceTree = "<group>"; };
|
||||
00C665722BAA81F900C309C3 /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = "<group>"; };
|
||||
00C665772BAA941E00C309C3 /* CopyCrashHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CopyCrashHandler.swift; sourceTree = "<group>"; };
|
||||
00D33BF32B998BF700604A44 /* SpatialImageConvertor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SpatialImageConvertor.swift; sourceTree = "<group>"; };
|
||||
@ -326,6 +328,7 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
1E1EA2872B9325D300A5D5D2 /* CCSpatialPhotoDisplayController.swift */,
|
||||
00BD87852BDE595F0014E8B3 /* CCSpatialPhotoDisplayEx.swift */,
|
||||
);
|
||||
path = CCSpatialPhotoDisplayController;
|
||||
sourceTree = "<group>";
|
||||
@ -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 */,
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -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))
|
||||
}
|
||||
|
||||
}
|
||||
@ -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)
|
||||
|
||||
@ -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()
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user