drawImageを使ってトリミングする時の注意

  • 0
    いいね
  • 0
    コメント

    HTML5のCanvasのapiにdrawImageがある。

    その名の通り、Canvasに画像を描画するメソッドだ。

    基本的な使い方は、以下の通り。

    例) 100x100の画像を描画

    var canvas = document.getElemntById('canvas');
    var ctx = canvas.getContext('2d');
    var img = new Image();
    img.src = "hoge.jpg";
    img.onload = function() {
      ctx.drawImage(img, 0, 0, 100, 100);
    }
    

    またトリミングも引数を下記のように渡すことで簡単にできる。

    例) 100x100の画像をx=10,y=10の地点から50x50のサイズでトリミングして描画

    var canvas = document.getElemntById('canvas');
    var ctx = canvas.getContext('2d');
    var img = new Image();
    img.src = "hoge.jpg";
    img.onload = function() {
      ctx.drawImage(img, 10, 10, 50, 50, 0, 0, 50, 50);
    }
    

    では、x=-10,y=-10の地点から50x50のサイズでトリミングして描画してみるとどうなるか。

    var canvas = document.getElemntById('canvas');
    var ctx = canvas.getContext('2d');
    var img = new Image();
    img.src = "hoge.jpg";
    img.onload = function() {
      ctx.drawImage(img, -10, -10, 70, 70, 0, 0, 70, 70);
    }
    

    Chrome

    スクリーンショット 2017-01-29 17.45.12.png

    FireFox

    スクリーンショット 2017-01-29 17.45.23.png

    Safari

    スクリーンショット 2017-01-29 17.45.42.png

    このようにSafariだけ表示がされない。

    これはどういうことかというと、HTML5の仕様ではこのように定義されている。

    The source rectangle is the rectangle whose corners are the four points (sx, sy), (sx+sw, sy), (sx+sw, sy+sh), (sx, sy+sh).
    If the source rectangle is not entirely within the source image, or if one of the sw or sh arguments is zero, the implementation must raise an INDEX_SIZE_ERR exception.

    https://www.w3.org/TR/2010/WD-2dcontext-20100624/#images

    つまり、トリミングする際の矩形の角は元画像内からはみだしてはいけないということ。

    ということは、x=-10,y=-10をdrawImageに設定するとエラーとなり描画できないのは仕様通りとなる。

    なので今回の場合、Safariの挙動が正しく、その他のブラウザの挙動のほうがむしろ独自仕様ということのようだ。

    もしSafari(mobileも含む)を対象ブラウザとしていて、下記のようなトリミング機能を実装する場合は、トリミングの枠よりも元画像が小さくならないように制限する必要があるので注意が必要だ。

    f420af2c64c90743c30f2762b0fa78bd.gif