Jpeg의 exif 정보 분석에 대해서

조성현의 이미지

디지털 카메라로 찍은 파일에서, exif 정보를 뽑기 위해서 관련 자료를 보고 하나씩 찾아가던 중에 Rational(유리수) 값을 어떻게 뽑아내는지 궁금해서 글을 올립니다.

http://www.linuxstudy.pe.kr/~ntames8/photo/test/exifdump.py

위 파일로 디카로 찍은 Jpeg파일의 Exif 정보를 추출할 수 있지만, 저는 제가 원하는 값들만 추출하고 싶은 상황으로 위 파일을 참조만 하려고 합니다.

파일 중간에

EXIF_TAGS = {
        0x100:  "ImageWidth",
        0x101:  "ImageLength",
        0x102:  "BitsPerSample",
        0x103:  "Compression",
          .............중략...........
        0x9102: "CompressedBitsPerPixel",
        0x9201: "ShutterSpeedValue",
        0x9202: "ApertureValue",
        0x9203: "BrightnessValue",
        0x9204: "ExposureBiasValue",
          .............중략...........
        0xA002: "ExifImageWidth",
        0xA003: "ExifImageLength",
        0xA005: "InteroperabilityOffset",
          .............중략...........
        0xA301: "SceneType",
}

와 같이 헤더를 정의하는 곳이 있습니다. 실제 Jpeg 파일 상에도 이와 같은 헤더 코드 부분을 찾을 수 있었습니다.

0000000: ffd8 ffe1 25fd 4578 6966 0000 4949 2a00  ....%.Exif..II*.
0000010: 0800 0000 0700 0f01 0200 1600 0000 6200  ..............b.
0000020: 0000 1001 0200 1c00 0000 7800 0000 1a01  ..........x.....
0000030: 0500 0100 0000 9400 0000 1b01 0500 0100  ................
0000040: 0000 9c00 0000 2801 0300 0100 0000 0200  ......(.........
0000050: 0000 1302 0300 0100 0000 0200 0000 6987  ..............i.
0000060: 0400 0100 0000 a400 0000 f201 0000 5361  ..............Sa
0000070: 6d73 756e 6720 2020 2020 2020 2020 2020  msung
0000080: 2020 2000 4469 6769 6d61 7820 3230 3020     .Digimax 200
0000090: 2020 2020 2020 2020 2020 2020 2020 2000                 .
00000a0: 4800 0000 0100 0000 4800 0000 0100 0000  H.......H.......
00000b0: 0f00 0090 0700 0400 0000 3032 3130 0390  ..........0210..
00000c0: 0200 1400 0000 5e01 0000 0490 0200 1400  ......^.........
00000d0: 0000 7201 0000 0191 0700 0400 0000 0102  ..r.............
00000e0: 0300 00a0 0700 0400 0000 3031 3030 01a0  ..........0100..
00000f0: 0300 0100 0000 0100 0000 02a0 0400 0100  ................
0000100: 0000 2003 0000 03a0 0400 0100 0000 5802  .. ...........X.
0000110: 0000 0992 0300 0100 0000 0000 0000 0291  ................
0000120: 0500 0100 0000 8601 0000 0292 0500 0100  ................
0000130: 0000 8e01 0000 9a82 0500 0100 0000 9601  ................
0000140: 0000 0ba2 0500 0100 0000 9e01 0000 8692  ................
0000150: 0700 2e00 0000 a601 0000 05a0 0400 0100  ................
0000160: 0000 d401 0000 0000 0000 3230 3034 3a30  ..........2004:0
0000170: 393a 3239 2030 333a 3134 3a33 3400 3230  9:29 03:14:34.20
0000180: 3031 3a30 353a 3330 2031 353a 3330 3a33  01:05:30 15:30:3
0000190: 3000 0200 0000 0100 0000 0500 0000 0100  0...............
00001a0: 0000 1d00 0000 1027 0000 0400 0000 0100  .......'........
00001b0: 0000 4153 4349 4900 0000 2020 2020 2020  ..ASCII...
00001c0: 2020 2020 2020 2020 2020 2020 2020 2020
00001d0: 2020 2020 2020 2020 2020 2020 2020 2020
00001e0: 0200 0100 0200 0400 0000 5239 3800 0200  ..........R98...
.......................................생략.............................

위 코드 화면과 같이 xxd 유틸리티를 이용해서 Jpeg 파일을 열어보았습니다.
보시다시피, 0xA002 헤더부분은 ExifImageWidth 값입니다.

00000f0: 0300 0100 0000 0100 0000 02a0 0400 0100  ................
0000100: 0000 2003 0000 03a0 0400 0100 0000 5802  .. ...........X.

Jpeg의 Offset 0x00FA에 0x02a0가 보이실 겁니다. 이 부분은 Intel Order식으로 해석하자면, 0xa002가 되므로 Width부분이 확실합니다.
0400 0100 0000 2003 0000 까지가 여기에 해당되는 값이 되는 것인데,
맨 앞 2Word는 각각 0x0004와 0x0001로 제 생각에는 Exif을 보는 유틸리티 파일에서
def print_IFD(fields, dict=EXIF_TAGS):
  for (tag,type,values) in fields:
    try:
      stag = dict[tag]
    except:
      stag = '0x%04X' % tag
    stype = ['B',       # BYTE
             'A',       # ASCII
             'S',       # SHORT
             'L',       # LONG
             'R',       # RATIONAL
             'SB',      # SBYTE
             'U',       # UNDEFINED
             'SS',      # SSHORT
             'SL',      # SLONG
             'SR',      # SRATIONAL
            ] [type-1]
 ..........생략...........

와 같이 4번째 'L'을 뜻하는 것 같습니다. 실제 실행해본 결과 값으로

Quote:
ExifImageWidth(L)=[800]
ExifImageLength(L)=[600]
Flash(S)=[0]
CompressedBitsPerPixel(R)=[2/1]
ApertureValue(R)=[5/1]
ExposureTime(R)=[29/10000]
FlashEnergy(R)=[4/1]

와 같이 나왔습니다. 괄호가 값 형태를 의미하는 것이겠죠? 그래서 L이라는 겁니다.
그다음 0x0001은 인식하는 갯수를 의미하는 것 같습니다. 2로 되어 있다면 값으로 [xxx,yyy] 식으로 나오게 됩니다. 1이므로 [xxx]와 같이 나오는 것이죠(테스트의 결과로 확신하는 것입니다).
2003값은 0x0320으로 10진수로 800이 되는 겁니다.

여기까지는 제가 해석한 부분이고 이제 질문을 드리겠습니다.

바로 위 인용부분에서 보이다시피, CompressedBitsPerPixel(R)과 같은 Rational 값입니다. 어떻게 저렇게 2/1이란 값이 나오게 되었는지 모르겠습니다. 부연 설명 더 들어갑니다.

0000110: 0000 0992 0300 0100 0000 0000 0000 0291  ................
0000120: 0500 0100 0000 8601 0000 0292 0500 0100  ................
0000130: 0000 8e01 0000 9a82 0500 0100 0000 9601  ................
0000140: 0000 0ba2 0500 0100 0000 9e01 0000 8692  ................

CompressedBitsPerPixel은 0x9102(offset 0x000011E) 부분으로 시작하게 됩니다. 0500 0100 0000 8601 0000 까지인데, 앞의 4Bytes는 이 값이 5번째 'R'이고, 1개의 값이라는 것을 알려줍니다. 뒤값 0000 8601 0000 이 어떻게 [2/1]이 나오게 되는지가 궁금합니다.

마찬가지로 Rational 으로 표현되는 값들을 더 쓰자면, 0x9202는 ApertureValue(조리개) 값으로 0500 0100 0000 8301 0000까지 입니다. 역시 'R'에 1개의 값입니다. 이것은 [5/1]입니다.

추가로 제가 임의로 위의 CompressedBitsPerPixel의 값을 변경해보았었습니다. 0000 8501 0000로 해보니까 값으로 [512/256]이 나왔었습니다.

제 수학적인 지식으로는 풀기 어려워서 이곳에 문의를 드립니다. 조금이라도 이쪽으로 관심이 있으거나, 약간의 지식이 있으신 분 조금의 도움이라도 주시면 감사하겠습니다.;; 참고로 내일 군대 복귀날입니다..ㅜ.ㅜ;; 그 전까지는..

http://blog.empas.com/changyong2/781655 에서 개인적으로 많은 참조를 하고 있었습니다.
제가 기록하고 있는 위키도 참고적으로 알려드립니다.
http://linuxstudy.pe.kr/~ntames8/wiki/wiki.php/exif

조성현의 이미지

0x8601 에 0x9601로 값을 고쳐보니,

ExposureTime(R)=[29/10000]와 같이 CompressedBitsPerPixel(R)=[29/10000]이 나오는 것입니다.

한참 헤맨 끝에 이 것이 offset이라는 것을 알았습니다.

Exif의 offset(0xc)에 0x9102 TAG가 가지고 있는 값 0x8601은 0x0186이므로 더하게 되면 0x000c + 0x0186 = 0x0192

0000190: 3000 0200 0000 0100 0000 0500 0000 0100 0...............

메뉴얼 wrote:
5 = RATIONAL Two LONGs. The first LONG is the numerator and the second LONG expresses the denominator.,

처음 0200 0000 은 2, 0100 0000 은 1 해서 이렇게 2/1이 나온겁니다.

제가 :lol: 참 바보스럽네요. 읽어주신 분들께 감사드립니다.

이거 덕분에 내일 잘 복귀할 수 있을 듯 ㅡㅡ;;

atie의 이미지

http://www.drewnoakes.com/code/exif/
혹시 필요할 때를 위해서 링크 걸어놉니다.

----
I paint objects as I think them, not as I see them.
atie's minipage

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.