시작
해리포터에서 나오는 신문을 다들 기억하시나요?
오늘 만들어 볼 것은 신문이나 책 위의 이미지를 인식하여 마치 해리포터에서 나오는 신문 같이
인식된 이미지 위에 동영상을 재생시키는 앱을 만들어 보려 합니다.
여기에서 사용되는 기술은 3D 공간에서 이미지를 인식을 하고 객체를 만들어내는 SceneKit
이 사용되며
또한 2D로 된 비디오 장면을 추가하기 위해 따로 SpriteKit
도 사용이 됩니다.
간단히 설명할 예정이라 자세한 내용은 이전 글을 참고하시길 바랍니다.
SceneKit의 사용법 (1) - 정육면체와 달을 만들어 보자
SceneKit의 사용법 (3) - 카메라 줄자, 거리 측정하기
SceneKit의 사용법 (4) - 이미지를 인식하여 3D형상 만들기
준비물 및 기본 세팅
1. 이미지가 있는 신문이나 책을 준비하기
2. 인식할 이미지를 이미지를 저장하기 (png, jpg)
2. 재생을 위해 그 이미지에 대한 동영상 찾아서 저장하기 (mp4 파일)
이미지와 동영상이 준비 됐으면 두 파일 모두 정확히 동일한 이름으로 바꿔줍시다.
재생할 mp4파일을 MagicPaper 폴더에 넣어 주세요
동영상을 넣을 때 꼭 Add to targets을 체크해 주세요.
순서는 전에 만들어봤던 SceneKit의 사용법 (4) - 이미지를 인식하여 3D형상 만들기 과 동일 합니다.
자세한 내용은 링크를 참고해 주세요.
자 그럼 이미지도 인식할 수 있게 넣어 줍시다.
이렇게 준비 과정은 끝났습니다.
Configuration 설정
이미지 인식을 위해 ARImageTrackingConfiguration
설정을 해줍시다.
Configuration설정 방법에 대해 자세히 알고 싶다면
SceneKit의 사용법 (4) - 이미지를 인식하여 3D형상 만들기 링크를 참고해 주세요.
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
let configuration = ARImageTrackingConfiguration()
// Assets 폴더의 AR 이미지를 불러오기
if let trackToImage = ARReferenceImage.referenceImages(inGroupNamed: "NewsPapaerImages", bundle: Bundle.main) {
// 인식할 이미지
configuration.trackingImages = trackToImage
// 인식한 이미지의 개수
configuration.maximumNumberOfTrackedImages = 1
}
sceneView.session.run(configuration)
}
비디오 재생을 위해 SpriteKit 사용
기본적으로 비디오 재생은 2D화면으로 구성이 돼있습니다.
2D 콘텐츠를 사용하기 위해 필요한 도구는 바로 SpriteKit
입니다.
참고로 SpriteKit
과 sceneKit
은 서로 호환이 잘됩니다.
addVideo()
메서드를 만들어 줬습니다. 주석을 참고하세요.
func addVideo() -> SKScene {
// 동영상 재생을 위해 SpriteKit의 SKVideoNode를 생성해 줍니다.
// 저장해 둔 비디오파일을 읽어줍시다.
let videoNode = SKVideoNode(fileNamed: "Harrypotter.mp4")
// 동영상 재생
videoNode.play()
// SpriteKit의 비디오 재생 요소를 sceneKit에 추가를 해줘야 합니다.
// SKScene을 추가 해줍시다. SKScene은 SpriteKit의 요소입니다.
// 장면의 크기는 동영상의 크기로 맞춰 줍시다 (제가 저장한 동영상은 720p 이므로 720 x 1080 설정)
let videoScene = SKScene(size: CGSize(width: 1080, height: 720))
// 위치를 조정해줍시다.
// videoNode의 위치를 videoScene의 중간에 위치하게 만들어 줍시다.
videoNode.position = CGPoint(x: videoScene.size.width / 2,
y: videoScene.size.height / 2)
// 회전을 시키기 위해서는 두가지 옵션이 있다.
// 1. zRotation을 통해 180° 돌려주기
// 2. yScale는 기본값이 +1 입니다 -1로 설정해주면 반전 됨
// 필자는 스케일도 조절하고 싶어 2번 사용
// videoNode.zRotation = CGFloat(Float.pi)
videoNode.yScale = -1.35
// 비디오를 추가해 줬으니 이제 2D로 표시할 준비가 됐습니다.
videoScene.addChild(videoNode)
return videoScene
}
참고로 카메라로 인식은 3D 환경에서 작업을 하는 것이므로 2D인 비디오는 나타나지 않습니다.
그러므로 밑에 만들 평면의 material.diffuse.contents
를 videoScene
으로 바꿔줘야 합니다.
여기서 contents에 대한 간단 설명
색상, 이미지 또는 애니메이션 및 동영상 등을 나타내는 시각적 콘텐츠입니다.
자세한 내용은 공식문서를 참고해 주세요.
이미지를 인식시키고 그 위에 평면 만들기
addPlane()
함수를 만들어 줬습니다. 이 부분에서 가장 중요한 건 contents
설정입니다.
자세한 순서와 내용은 SceneKit의 사용법 (4) - 이미지를 인식하여 3D형상 만들기 링크를 참고해 주세요.
func addPlane(on imageAnchor: ARImageAnchor, addVideo: SKScene) -> SCNNode {
let plane = SCNPlane(width: imageAnchor.referenceImage.physicalSize.width,
height: imageAnchor.referenceImage.physicalSize.height)
// ⭐️ 표시할 콘텐츠를 위에서 만든 타입 SKScene으로 설정 해줍니다.
plane.firstMaterial?.diffuse.contents = addVideo
let planeNode = SCNNode(geometry: plane)
planeNode.eulerAngles.x = -(Float.pi/2)
return planeNode
}
만들어 놓은 메서드 addPlane()
, addVideo()
를 사용하여 카메라에 감지된 이미지 위로 올려 줍시다.
extension ViewController: ARSCNViewDelegate {
func renderer(_ renderer: SCNSceneRenderer, nodeFor anchor: ARAnchor) -> SCNNode? {
let node = SCNNode()
guard let imageAnchor = anchor as? ARImageAnchor else { return node }
let videoScene = addVideo()
let planeNode = addPlane(on: imageAnchor, addVideo: videoScene)
node.addChildNode(planeNode)
return node
}
}
완성
화면을 움직여도 그 자리에서 재생이 되네요. 이미지 인식이 잘 되는 것 같아요!
완성된 코드를 보고 싶다면 Github 를 참고하세요.
ScnenKit의 다른 예제를 보고 싶다면 아래 링크를 참고하세요
참고
'Xcode > Framework' 카테고리의 다른 글
[iOS/Swift] SceneKit의 사용법 (4) - 이미지를 인식하여 3D형상 만들기 (0) | 2023.01.11 |
---|---|
[iOS/Swift] SceneKit의 사용법 (3) - 카메라 줄자, 거리 측정하기 (0) | 2023.01.10 |
[iOS/Swift] SceneKit의 사용법 (2) - 주사위 만들기 (0) | 2023.01.08 |
[iOS/Swift] SceneKit의 사용법 (1) - 정육면체와 달을 만들어 보자 (0) | 2023.01.07 |
[iOS/Swift] ARKit의 종류 (0) | 2023.01.07 |