Danny의 iOS 컨닝페이퍼
article thumbnail

시작

해리포터에서 나오는 신문을 다들 기억하시나요?

 

오늘 만들어 볼 것은 신문이나 책 위의 이미지를 인식하여 마치 해리포터에서 나오는 신문 같이

인식된 이미지 위에 동영상을 재생시키는 앱을 만들어 보려 합니다.

 

여기에서 사용되는 기술은 3D 공간에서 이미지를 인식을 하고 객체를 만들어내는 SceneKit이 사용되며

또한 2D로 된 비디오 장면을 추가하기 위해 따로 SpriteKit도 사용이 됩니다.

 

간단히 설명할 예정이라 자세한 내용은 이전 글을 참고하시길 바랍니다.

SceneKit의 사용법 (1) - 정육면체와 달을 만들어 보자

SceneKit의 사용법 (2) - 주사위 만들기

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 입니다.

 

참고로 SpriteKitsceneKit은 서로 호환이 잘됩니다.

 

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.contentsvideoScene 으로 바꿔줘야 합니다.

 

여기서 contents에 대한 간단 설명

 

색상, 이미지 또는 애니메이션 및 동영상 등을 나타내는 시각적 콘텐츠입니다.

 

자세한 내용은 공식문서를 참고해 주세요.

 

Apple Developer Documentation

 

developer.apple.com

 

이미지를 인식시키고 그 위에 평면 만들기

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의 다른 예제를 보고 싶다면 아래 링크를 참고하세요

 

[iOS/Swift] SceneKit의 사용법 (1) - 정육면체와 달을 만들어 보자

시작 AR 주사위 던지는 앱을 만들기 앞서 이해를 돕기 위해 들어가기 앞서 간단한 Cube(정육면체)와 Shpere(구)를 만들어 봅시다. 사용법 iOS -> Augmented Reality App 선택 Content Technology : SceneKit을 선택해

ios-daniel-yang.tistory.com

 

[iOS/Swift] SceneKit의 사용법 (2) - 주사위 만들기

시작 오늘은 SceneKit으로 주사위 생성 및 굴리기를 해봅시다. 순서는 이전에 만든 Cube와 달 만들기와 거의 동일하니 못 보셨다면 여기를 참고하세요. 바로 시작하겠습니다. 주사위로 사용할 모델

ios-daniel-yang.tistory.com

 

[iOS/Swift] SceneKit의 사용법 (3) - 카메라 줄자, 거리 측정하기

시작 오늘은 SceneKit으로 카메라를 통한 줄자를 만들어 보겠습니다. 간단히 설명할 예정이라 자세한 내용은 이전 글을 참고하시길 바랍니다. SceneKit의 사용법 (1) - 정육면체와 달을 만들어 보자 Sc

ios-daniel-yang.tistory.com

 

[iOS/Swift] SceneKit의 사용법 (4) - 이미지를 인식하여 3D형상 만들기

시작 오늘은 SceneKit으로 이미지를 인식하여 그 위에 캐릭터를 올려볼 예정입니다. 간단히 설명할 예정이라 자세한 내용은 이전 글을 참고하시길 바랍니다. SceneKit의 사용법 (1) - 정육면체와 달을

ios-daniel-yang.tistory.com

 

 

참고

 

iOS & Swift - The Complete iOS App Development Bootcamp

From Beginner to iOS App Developer with Just One Course! Fully Updated with a Comprehensive Module Dedicated to SwiftUI!

www.udemy.com

반응형
profile

Danny의 iOS 컨닝페이퍼

@Danny's iOS

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!