1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

MGO2のクランエンブレム作成するやつ作った

Last updated at Posted at 2017-12-21

※そもそも、MGO2とはメタルギアオンラインというゲームです。

ソースとサイト

作成方法の参考サイト(Windows向け)

なぜ作るか

  • Mac向けの参考サイトがない
  • 各ツールを駆使して作れなくもないが面倒。
    • →ツール作るか。webで。

なにで作るか

  • parcel + babel + node-scss
    • parcelを使ってみたかった

実装について

やることは大きく分けて4つ

  • 画像を32*32にリサイズ
    • MGOのエンブレムサイズが32*32
  • 16色に減色
    • MGOのエンブレムで使用できる色が16色
  • 選択色ごとにハイライト表示
    • 最終的にはゲーム画面でぽちぽち手打ちする必要があるため、同色がどこに使われているかわかりやすくする
  • カラーコードの表示を8.21で割る
    • MGOでエンブレムを作成する際のカラーピッカーが0〜31のため

画像選択

  • ドラッグアンドドロップまたは、選択されたファイルをFileReader APIで読み込み
  • ファイル選択はchange、ドラッグアンドドロップはdropイベントでデータを取得
  • 読み込んだファイルデータをcanvasに書き出し
  // イベント設定
  uploadArea.addEventListener('change', (e) => {
    this.changeHandler(e);
  });
  uploadArea.addEventListener('dragenter', (e) => { e.preventDefault(); });
  uploadArea.addEventListener('dragover', (e) => { e.preventDefault(); });
  uploadArea.addEventListener('dragleave', (e) => { e.preventDefault(); });
  uploadArea.addEventListener('drop', (e) => {
    e.preventDefault();
    this.changeHandler(e, e.dataTransfer.files[0]);
  });

  /**
   * 画像アップロード時のcallback
   */
  changeHandler(e, data) {
    // drag and dropの場合は e.dataTransfer.files[0] を使用
    let file = data === undefined ? e.target.files[0] : data;

    let image = new Image();
    let fileReader = new FileReader();

    fileReader.onload = (e) => {
      let base64 = e.target.result;

      image.onload = () => {
        this.canvasCropper.width = image.width;
        this.canvasCropper.height = image.height;
        let originalCtx = this.canvasCropper.getContext('2d');

        // s:sourceImage, d:destinationCanvas
        // ctx.drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh)
        originalCtx.drawImage(image, 0, 0, image.width, image.height, 0, 0, image.width, image.height);
      };
      image.src = base64;
    };

    fileReader.readAsDataURL(file);
  }

クロッピング

  • Cropper.jsを使用
  • エンブレムは正方形なのでaspectRatio1に指定
  • crop時のイベント引数からクロップ時のサイズ・位置が取得できるので
    crop範囲だけ別の32*32サイズのcanvasに描画
  this.cropper = new Cropper(canvas, {
    aspectRatio: 1,
    preview: '.cropper-preview__img',
    crop: (e) => {
      ctx.drawImage(canvas,
        e.detail.x,
        e.detail.y,
        e.detail.width,
        e.detail.height,
        0,
        0,
        CANVAS_SIZE,
        CANVAS_SIZE
      );
    }
  });

メディアンカット(中央値分割法)による減色

  • node-kmeansを使用
  • mediancutを使用
  • クロッピング時に作成した32*32サイズのcanvasのピクセルデータを取得して減色を行う
let imagedata = ctx.getImageData(0, 0, CANVAS_SIZE, CANVAS_SIZE);

// reduced color (減色)
let medianCut = new MedianCut(imagedata);
medianCut.run(16);

減色後の表示

  • クラスタリング後のデータで16色に減色されたカラーコードを取得して、canvasに描画して終わり

最後に

  • MGO2全盛期の7〜8年前に作れていれば。。。
  • TODOもたくさん。。。
1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?