メニューを閉じる

テクノデジタルグループ

メニューを開く

2017.11.27

プログラミング

javascriptで画像を分割してみた

アイキャッチで使用させていただいた画像はPixabay様からお借りしました。

こんにちは、新卒のshiroです。

便利なフレームワークなどが多々存在する現在、今回はあえてそれらを使わずjavascript(と、記述の簡便さを求めてjQuery)で画像の分割処理を作成していきます。

作成するものはセンタリングしてトリミングであったり、幅や高さに合わせたトリミングであったりはしません。
同一サイズのタイルが複数枚で1つになっている画像ファイルを分割するものになります。
下記がイメージとなります。

sample

なお、今回はローカルでの動作はfirefoxで確認しました。
chromeの場合、通常はクロスドメイン制約で弾かれます。

まずは画面呼出後の処理です。

$(function() {
  // 分割する幅と高さを指定する
  // 画像を割り切れれば幅と高さは何でもよい
  var width = 32, height = 32;
  //画像の取得からロード後処理まで
  var img = new Image();
  img.onload = function() {
    segmentationImage(img, width, height);
  }
  img.src = "img/sample.png";
});

onloadの中で、segmentationImage関数に画像データを渡しています。
srcを設定する前にonloadを設定しないと、動かない場合があるらしいので注意してください。
ここも関数作ってやればよかったかも……。

次に画像分割処理を作成します。

function segmentationImage(img, width, height) {
  // 分割用のキャンバスを作成する
  // 画面には表示されない
  let canvas = $("").get(0);
  let ctx = canvas.getContext("2d");
  // 分割後のデータを保存する
  let imgList = [];
  // 縦横の個数を取得する
  let wLength = img.width / width;
  let hLength = img.height / height;
  // 分割数だけリストに入れる
  for(let num = 0; num < wLength * hLength; num++) {
    ctx.clearRect(0,0,canvas.width,canvas.height);
    ctx.drawImage(img, width * (num % wLength), height * Math.floor(num / wLength), width, height, 0, 0, width, height);
    imgList.push(canvas.toDataURL());
  }
  drawContent(imgList);
}

画像の分割はcanvasで行うため、作成します。
canvasを作成する際、同時にwidthとheightを指定することでcanvasサイズが初期値になってしまうトラブルを回避しています。
トラブルに関して詳しく知りたい人は調べてください。
wLengthとhLengthは画像の幅と高さをそれぞれ、先ほど指定していた幅と高さで割った数を入れています。
for文では横の数と縦の数を掛けた回数未満繰り返すようにします。
先ほどの文で

ctx.drawImage(img, width * (num % wLength), height * Math.floor(num / wLength), width, height, 0, 0, width, height);

と書いている箇所があります。
ここを説明していきます。

drawImageには引数で違うものが3種類あります。
今回はその中の

drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight);

を使用します。
他のdrawImageに関してはMDNを確認してください。
まずはわかりやすいsWidth以降です。
順に「切り取る幅、切り取る高さ、描写するx座標、描写するy座標、描写する幅、描写する高さ」になります。
なので最初に指定した幅、高さで切り取り、それを原点から最初に指定した幅、高さで描写するようにしています。
sxは「num % wLength」で、num=wLength-1まで1ずつ増やしていき、num=wLengthのとき再び0になるようにしています。それをwidthと掛けることで、画像の端まで行ったら最初に戻るのを繰り返すようにしています。
syは「Math.floor(num / wLength)」で0行目から始まる何行目を取得するか判定し、それにheightを掛けて高さを取得しています。
こうすることで左上から右に進み、端に着いたら一段下がって再び右に……と取得していくことが可能です。

最後に分割した画像を表示します。

function drawContent(imgList) {
  // 分割後の画像数だけliを作成してulに入れる
  for(let num = 0; num < imgList.length; num++) {
    let list = $("

“); list.css(“background-image”, “url(” + imgList[num] + “)”); $(“ul”).append(list); } }

imgListの要素数だけ回してli要素を作成、ul要素の中に入れています。
この書き方ではhtml内にul要素があり、cssでli要素のサイズが指定されている前提ですが、これで分割した画像を表示することができます。

実際作ってみると、意外と簡単ですね。

快適な画像処理ライフを!

EOF.


【記事への感想募集中!】

記事への感想・ご意見がありましたら、ぜひフォームからご投稿ください!
  • こんな記事が読んでみたい、こんなことが知りたい、調べてほしい!という意見も募集中!
  • いただいた感想は今後の記事に活かしたいと思います!

感想フォームはこちら


【テクノデジタルではエンジニア/デザイナーを積極採用中です!】

下記項目に1つでも当てはまる方は是非、詳細ページへ!
  • 自分でアプリを作ってみたい
  • ITで世の中にワクワクを生み出したい
  • 使いやすさ、デザインにこだわったWebサイトを開発したい

採用情報の詳細はこちら


Qangaroo(カンガルー)

  • 徹底した見やすさと優れた操作性で、テストの「見える化」を実現。
  • テストの進捗が見える。開発がスマートに進む。
  • クラウド型テスト管理ツール『Qangaroo(カンガルー)』

【テクノデジタルのインフラサービス】

当社では、多数のサービスの開発実績を活かし、
アプリケーションのパフォーマンスを最大限に引き出すインフラ設計・構築を行います。
AWSなどへのクラウド移行、既存インフラの監視・運用保守も承りますので、ぜひご相談ください。
詳細は下記ページをご覧ください。

https://www.tcdigital.jp/infrastructure/

最近の記事