사진파일 메타데이터(Metadata) 값 가져오기

LESA·2023년 1월 6일
0
post-thumbnail

사진에 있는 메타데이터를 가져와보자

exif-js 라이브러리를 사용하여 사진 Metadata 가져오기

[npm docs] Exif-js

들어가기에 앞서 exif-js 라이브러리를 사용하는것을 비추천한다.

exif-js 는 사진의 메타데이터를 읽는 라이브러리로 사용횟수가 가장 많고 그나마 구글링되는 정보가 있는 라이브러리이다.
하지만 5년전에 나온 라이브러리이고 업데이트가 몇년동안 되지않았다.
게다가 아이폰의 사진정보만 제공하는듯 하다.
실제로 해당 라이브러리의 이슈탭에 가보면 다른 라이브러리를 사용하라고 추천하고있다.

Issues Comment

사진의 메타데이터의 유무로 이벤트 처리

아래의 코드는 파일을 선택했을때, 사진으로부터 위도, 경도, 촬영일자를 받아온다.
만약 값이 없으면 사용자가 직접 입력할 수 있게 이벤트를 나누었다.

input.onchange = async () => {
      setFinalLo(undefined);
      setFinalLa(undefined);
      setFinalTakenAt(undefined);
      setCalValue(new Date());

      const [file]: any = input.files;
      const { url: imgUrl, id: imgId } = await getPresignedURL(file);

      setImgUrl(imgId);

      const quill = quillRef.current.getEditor();

      const range = quillRef.current.getEditorSelection();
      quill.insertEmbed(range.index, 'image', imgUrl);
      quill.setSelection(range.index + 1);

      if (file) {
        const fileInfo: any = file;

        EXIF.getData(fileInfo, () => {
          const tags = EXIF.getAllTags(fileInfo);
          const longitude = tags.GPSLongitude;
          const longitudeRef = tags.GPSLongitudeRef;
          const latitude = tags.GPSLatitude;
          const latitudeRef = tags.GPSLatitudeRef;

          let takenTime = tags.DateTimeDigitized;
          if (takenTime) {
            for (let i = 0; i <= 1; i++)
              takenTime = takenTime.replace(':', '-');

            const changeDate = new Date(takenTime).toISOString().split('T')[0];
            setCalValue(new Date(changeDate));

            setFinalTakenAt(new Date(takenTime).toISOString());
          }

          if (longitude && longitudeRef && latitude && latitudeRef) {
            // 위도 latitude, 경도 longitude
            if (latitudeRef === 'S')
              setFinalLa(
                -1 * latitude[0] +
                  (-60 * latitude[1] + -1 * latitude[2]) / 3600,
              );
            if (latitudeRef === 'N')
              setFinalLa(latitude[0] + (60 * latitude[1] + latitude[2]) / 3600);

            if (longitudeRef === 'W')
              setFinalLo(
                -1 * longitude[0] +
                  (-60 * longitude[1] + -1 * longitude[2]) / 3600,
              );
            if (longitudeRef === 'E')
              setFinalLo(
                longitude[0] + (60 * longitude[1] + longitude[2]) / 3600,
              );
          } else {
            setNoneLocation(true);
          }
        });
      }
    };

메타데이터 O


메타데이터 X


결론

메타데이터를 가져오는 것 자체는 크게 어렵지 않다.
가져와서 원하는 형태로 이벤트를 나누는 부분이 까다로웠다.
이 외에도 개발 당시엔 exif-js 라이브러리가 안드로이드를 지원하지 않는것을 몰랐다.
원작자의 레포에가서 주기적으로 업데이트 하는지, 라이브러리의 사용횟수가 많이있는지 체크하고 라이브러리를 선택하는 것이 좋다는 결론이다.

profile
Always All ways

0개의 댓글