[자바스크립트]iPhone에서 찍은 사진을 게시하면 회전하는 것을 빨리 고쳐줍니다.

어떤 느낌이 되는지



왠지 세로로 찍은 이미지가 누워 ...


여기에서 iPhone에서 찍은 사진을 선택해보십시오.
ht tp // 룬 s단 t. 코 m/시미라 아아/p 로지ぇcts/에9에후에5c7
세로로 찍은 사진이라면 90도 회전합니다.

회전하지 않는 샘플



사용한 라이브러리



htps : // 기주 b. 코 m / b 에이 mp / 그럼 ぁ Sc 리 pt ぉ 아 d
이 라이브러리의 v2.6.2를 rawgit.com의 cdn화 서비스를 사용하여 아래 URL에서 읽습니다.
htps // cd 응. 등 w t. 이 m / b ぅ 에이 mp / 그럼 ゔ ぁ Sc 리 pt ぉ 아 d 뺨 / v2. A l. 모두. js

샘플



ht tp // 룬 s단 t. 코 m / 시미라 아 아 / p 로지 cts / ぉ 아 마에 에우 후 리엔 온
여기에서 iPhone에서 찍은 사진을 선택해보십시오.
회전하지 않고 표시된다고 생각합니다.

코드 설명



HTML 부분


<head> 태그 내에서 라이브러리를 읽습니다.

<!-- 省略 -->
<script src="https://cdn.rawgit.com/blueimp/JavaScript-Load-Image/v2.6.2/js/load-image.all.min.js"></script>
<!-- 省略 -->

<body> 태그내는, 파일 선택용의 <input type="file"> 와, 표시용의 <div> 가 써 있습니다.


<div>
  <label>iPhoneで縦向きに撮った写真を選択してください。
    <input type="file" name="file" id="file" />
  </label>
</div>
<div id="dst">
  <p>画像クリックで別ウィンドウで開く</p>

</div>


CSS 부분



별로 상관없지만 큰 이미지가 그대로 표시되면 보이지 않기 때문에 width를 300px가 되도록 합니다.


canvas {
  width: 300px;
}


스크립트 부분



코멘트에 세세하게 써 있으므로, 자쿠리 흐름을 설명합니다.
  • 우선, window.onload 속에서 처리를 하고 있습니다.
  • input[file]onchange에서 이미지 파일이 선택되면 3으로
  • load 함수에 이미지가 로드되면 div#dstcanvas 를 추가하는 함수를 전달합니다.
  • load 함수는 먼저 loadImage.parseMetaData를 실행하여 회전하는지 확인합니다.
  • 회전에 관한 정보는 exif 라는 데이터 안에 저장되어 있으므로 exif 가 있는 경우에만 회전시키는 옵션을 설정합니다.
  • loadImage 함수를 호출하여 이미지 로드가 완료되면 3.의 canvas를 추가하는 함수가 호출됩니다.
  • 
    
    onload = function() {
      var input = document.getElementById('file');
      var dst = document.getElementById('dst');
    
      input.onchange = function() {
        // 選択中のファイルの一つ目
        var file = this.files[0];
        // ファイルを選択しなかった場合
        if(!file) return;
        // ファイル形式
        console.log(file.type);
        // ファイル形式の中にimageが含まれない場合
        if(!/image/.test(file.type)) {
          alert('画像を選択してください。');
          return;
        }
    
        // 読み込み用の関数で読み込み完了時に、HTMLにcanvas追加
        load(file, function(canvas) {
          dst.appendChild(canvas);
    
          // canvas がクリックされた時に、別ウィンドウで画像を開く
          canvas.onclick = function() {
            open(this.toDataURL('image/png'));
          };
        });
    
      };
    
      function load(file, callback) {
        // canvas: true にすると canvas に画像を描画する(回転させる場合は必須オプション)
        var options = {canvas: true};
    
        loadImage.parseMetaData(file, function (data) {
          if (data.exif) {
            console.log("exifに格納されている情報:\n", data.exif.getAll());
    
            // options の orientation は小文字。 exif.getの 'Orientation' は先頭大文字
            // ここでcanvasの回転を指定している
            options.orientation = data.exif.get('Orientation');
            console.log('Orientation: ' + options.orientation);
          }
          // 画像の読み込み。完了時に callback が呼び出される
          loadImage(file, callback, options);
        });
      }
    };
    
    

    canvas로 나오고 있으므로, 서버에 보낼 때는, FormData API나, canvas.toDataURL() 등으로, 화상 데이터를 보내 주면, 회전하지 않는 화상을 등록할 수 있다고 생각합니다. (서버 측의 처리에 따라 적절한 방법으로 전송하십시오)

    회전하는 원인



    Script 부분의 설명에서도 나온 exif에 포함된 Orientation이라는 회전을 나타내는 데이터가 원인입니다.
    exif에 대해서는, 나도 상세하게는 이해할 수 없지만, jpeg 이미지의 최초의 바이트열에 저장되고 있는 것 같습니다.
    이미지를 표시할 수 있는 앱의 대부분은, 이 exif에 의해, 표시의 방식이 바뀌어 있어, Orientation가 있으면, 자동적으로 지정된 각도로 회전해 표시하고 있는 것이 아닐까 생각합니다.

    브라우저라면 iPhone의 <img> 태그를 제외하고는, 기본적으로 Orientation에 의한 회전은 자동적으로는 되지 않기 때문에, 거기를 스스로 구현할 필요가 있다고 하는 것이라고 생각하고 있습니다.

    또, exif의 Orientation에 회전의 지정이 있으면, iPhone에 한정되지 않고, 디지털 카메라 등으로 찍은 사진에서도 발생하는 현상이라고 생각합니다.

    이 근처는 모호하기 때문에, 잘못되어 있는 부분이 있으면, 지적해 주시면 고맙습니다.

    좋은 웹페이지 즐겨찾기