2017-03-13 16 views
1

이 프로젝트로 가려움증을 앓는 종류 ​​- 또는 두 가지가 있습니다. 하나는 Xcode를 사용하여 macOS 응용 프로그램을 작성하려고 시도하고 다른 하나는 3D 사진 (또는 당신이 완전히 정확하다면 StereoPhotos)과 관련이 있습니다.MPO 파일을 열고 포함 된 이미지를 추출하십시오

나는 이것을 LiveCode에서 시도했지만, 느리고 번거 롭다. 내가 좋아하는 것을 얻고 있었지만 성능 벽을 꽤 빨리 쳤습니다. 그래서 Xcode에서 다시 시작하기로 결정했습니다. 한 가지해야 할 일은 Fuji 3D 카메라에서 MPO 파일을 가져 와서 왼쪽 및 오른쪽 이미지를 추출하여 응용 프로그램에 표시하는 것입니다. LiveCode에서이 작업은 쉬웠습니다 (너무 쉬울 수도 있음) - MPO 파일을 텍스트 문자열로 가져 와서 JPEG 마커를 사용하여 배열로 분할 한 다음 해당 데이터를 이미지 개체로 설정했습니다. 결과는 두 개의 JPEG 파일이었습니다.

나는 이것을 스위프트에서 시도해 보았고, 나쁘게 실패하고있다. 지금까지 놀이터에서 아이디어를 응용 프로그램에 추가하기 전에 시도했습니다. 필자는 LiveCode에서와 같은 논리를 채택하고 있습니다. 데이터를로드하고, 마커로 파일을 분할하고, 데이터를 저장합니다.

import Cocoa 
import Foundation 

// Files and destinations 
let MPOString = "/path/to/DSCF0523.MPO" 
let myLeft = URL(string:"file:///path/to/left.jpg") 
let myRight = URL(string:"file:///path/to/right.jpg") 

var leftImage:NSImage 
var rightImage:NSImage 

//JPEG Marker FFD8FFE1 
let myJpegMarker = "\u{FF}\u{D8}\u{FF}\u{E1}" 

do { 
    myMPOData = try String(contentsOfFile: MPOString , encoding:String.Encoding.isoLatin1) as NSString 
} 
catch { 
    print("Error getting MPO - \(myMPOData)\n\(MPOString)") 
} 

/* 
At this point, I realise that while the data has been split, 
the markers are removed, so I add them back. 
This is wrong (but worked in LiveCode) 
*/ 
let imageArray = myMPOData.components(separatedBy: myJpegMarker) 

var myLeftImage = myJpegMarker+imageArray[1] 
var myRightImage = myJpegMarker+imageArray[2] 

do { 
    try myLeftImage.write(to: myLeft! , atomically: false, encoding: String.Encoding.utf8) 
} 
catch { 
    print("Error writing file: " + error.localizedDescription) 
} 

print ("Saving image \(myRight)") 
do { 
    try myRightImage.write(to: myRight! , atomically: false, encoding: String.Encoding.utf8) 
} 
catch { 
    print("Error writing file: " + error.localizedDescription) 
} 

위의 코드는 뭔가 가까이 않지만 충분히 닫을 수 없습니다. 즉, 데이터가 분리되어 두 개의 파일을 덤프한다는 의미입니다. 그러나 파일이 올바르지 않습니다. 16 진수 덤프는 JPEG 마커가 올바르지 않다는 것을 보여줍니다. (파일의 시작 부분에서 FFD8FFE1을 찾고 있는데, 거기에 없기 때문에 8 개의 여분의 문자가 있습니다. 인코딩의 결과입니다.) 또한 파일 크기가 너무 작습니다 - 예상 된 4 대신 6.5Mb, 어떤 것이 옳지 않다고 알려줍니다.

나는이 문제에 대한 해결책을 찾기 위해 상당한 시간을 보냈지 만 동일한 Google 결과를 사용하여 서클을 돌았습니다.

나는 이미지를 객체에로드하고 object [0] 및 object [1]을 참조하여 이미지를 가져올 수 있어야한다고 설명합니다. 어쨌든, 해결책이 무엇이든, 나는 아마 내가 기대했던 것보다 더 간단 할 것으로 기대한다.

모든 사람들이 도움이된다고 생각한다면 참조 용으로 DropBox에 샘플 MPO 파일을 배치했습니다. https://dl.dropboxusercontent.com/u/613685/DSCF0523.MPO.zip

답변

0

나는이 문제가 (NS) String보다는 (NS) Data가 당신의 접근 방법의 기초라고 생각합니다.

아마하지 산뜻한 솔루션 동안 (내 마음은 오브젝티브 C 모드, 그래서 매우 많은 다음 스위프트는 두 가지의 교란 혼합 될 수있다 의심),하지만이 포함 된 이미지를 추출해야합니다

import Foundation 

let jpegMarker:Data = Data(bytes: UnsafePointer<UInt8>([0xFF, 0xD8, 0xFF, 0xE1] as [uint8]), count: 4) 

let baseURL = "file:///path/to/images/" 
let mpoURL = URL(string: baseURL + "DSCF0523.MPO") 
var mpoData:Data 

do { 
    try mpoData = Data.init(contentsOf: mpoURL!) 
    var markerLocations:[Int] = [] 
    var markerOffset:Range? = mpoData.range(of: jpegMarker, options:[], in:0 ..< mpoData.count) 

    while (markerOffset != nil) { 

     // We've found a marker - add it to our array 
     markerLocations.append(markerOffset!.lowerBound) 

     // Update our current offset before we iterate 
     markerOffset = mpoData.range(of: jpegMarker as Data, options:[], in:markerOffset!.upperBound ..< mpoData.count) 
    } 


    // Did we find any markers? 
    if (markerLocations.count != 0) { 

     // Time to extract the data betwen the markers 
     for (index, currentMarkerOffset) in markerLocations.enumerated() { 

      let endDataOffset = index == markerLocations.count - 1 ? mpoData.count : markerLocations[index + 1] 
      let imageBytes:Data = mpoData.subdata(in:currentMarkerOffset ..< endDataOffset) 

      // Write the image data to disk 
      do { 
       let outputPath = baseURL + "Image-" + String(index) + ".jpeg" 
       try imageBytes.write(to: URL(string: outputPath)!) 
      } 
      catch { 
       print("Unable to write image file - " + error.localizedDescription) 
      } 
     } 

    } else { 
     print("JPEG marker not found in source MPO file.") 
    } 

} catch { 
    print("Unable to open source MPO file - " + error.localizedDescription) 
} 

내가하고있는 일은 while 반복문에 파일의 모든 마커를 가져 오는 것입니다 (두 개 이상의 삽입 된 이미지가있을 수 있으므로). 반복자를 하나씩 반복하여 추출합니다.

이 반복 중에 최종 마커의 경우를 처리해야하므로 오히려보기 흉한 삼항 조건 연산자를 사용해야합니다.

덧붙여서 Swift 3의 데이터 (2.x 스타일 NSData가 아닌) 등을 사용합니다.

+1

고마워요! 놀이터와 내가 작업하고있는 앱 모두에서 이것을 시도해 보았습니다. 그리고 그것이 내가 원하는 바를하고 있습니다. 나중에 문자열을 사용하지 말고 데이터를 사용해야한다는 질문을 게시 한 후 알게되었습니다. 범위를 읽었습니다. –