読者です 読者をやめる 読者になる 読者になる

B-Teck!

お仕事からゲームまで幅広く

【HTML5/jQuery/Javascript 】ローカルの画像を読み込んでJavaScriptで合成してみた

ふと思い立ったので、HTML5Canvasを使って画像を合成してみた。
なんとかブルーファンタジージェネレータ

f:id:beatdjam:20160121224709p:plain

コード

HTML

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>なんとかブルーファンタジージェネレータ</title>
    <script src="http://code.createjs.com/easeljs-0.7.1.min.js"></script>
    <script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
    <script src="main.js"></script>
</head>
    <body>
        <h1>なんとかブルーファンタジー風ジェネレータ</h1>
        <dl class="table">
            <dt>画像</dt>
            <dd><span><img src="base.png" id="preview"></span><dd>
            <dd><input type="file" accept="image/*" id="getfile"><dd>
            <dt>名前</dt>
            <dd><input type="text" name="txt01" id="txt01" placeholder="" /></dd>
            <dt>セリフ</dt>
            <dd><textarea name="txt02" id="txt02" rows="4" cols="40"></textarea></dd>
        </dl>
        <div class="btn">
            <button id="update">画像生成</button>
            <button id="left"></button>
            <button id="up"></button>
            <button id="down"></button>
            <button id="right"></button>
            <button id="zoomin">拡大</button>
            <button id="zoomout">縮小</button>
            <button id="reset">リセット</button>
        </div>

        <!-- 出力部分 -->
        <div class="module">
            <h2>生成結果</h2>
            <h1 id="alert" style="color: red"></h1>
            <canvas id="result" width="623" height="842"></canvas>
        </div>
    </body>
</html>

JavaScript

/**
 * Created by beat on 2016/01/14.
 */

(function($){
    //画像関連
    var img;
    var img2;
    var stage;

    //画像ロード
    function loadImage (imageData){
        //画像のロード
        var baseImg = new Image();
        baseImg.src = 'background.png';
        img = new createjs.Bitmap(baseImg);

        //画像が選択されている時のみ合成
        if(imageData !== null) {
            var baseImg2 = new Image();
            baseImg2.src = imageData;
            img2 = new createjs.Bitmap(baseImg2);
        }

        stage = new createjs.Stage('result');
    }

    //画像と文字を合成する処理
    function genImage (imageIni, txt){
        //合成画像の設定
        //上下は10ピクセルごと移動
        img2.x = imageIni.xPos * 10;
        img2.y = imageIni.yPos * 10;
        //拡縮は10%ずつ
        img2.scaleX = img2.scaleX * (1 + imageIni.Scale / 10);
        img2.scaleY = img2.scaleY * (1 + imageIni.Scale / 10);

        //ステージ生成
        stage.addChild(img2);
        stage.addChild(img);

        //文字オブジェクトを生成してステージに追加
        $.each(txt,function(key,value){
            //本文は入力された内容をそのまま取る
            var content = $('#' + key).val();

            //文字生成
            var obj = new createjs.Text(content);

            //文字設定
            obj.textAlign = value.align;
            obj.font = value.font;
            obj.color = value.color;
            obj.x = value.x;
            obj.y = value.y;

            stage.addChild(obj);
        });

        //ステージ反映
        stage.update();
    }

    function downloadImage(imageData){
        window.location = imageData;
    }


    $(function(){
        //読込画像のオブジェクト
        var imageIni = {
            xPos : 0,
            yPos : 0,
            Scale : 0,
            imageData : null,
            resetImage : function(){
                this.xPos = 0;
                this.yPos = 0;
                this.Scale = 0;
            },
            makeImage : function(){
                if(this.imageData !== null) {
                    loadImage(this.imageData);
                    genImage(this, txt);
                }
            }
        };

        //合成する文字の位置情報などを定義
        var txt = {
            'txt01' : {
                'x' : 18,
                'y': 555,
                'font': '23px/1.5 Meiryo,sans-serif',
                'align': 'left',
                'color': 'white'
            },
            'txt02' : {
                'x' : 25,
                'y': 595,
                'font': '30px/1.5 Meiryo,sans-serif',
                'align': 'left',
                'color': 'white'
            }
        };

        //イベント関連処理
        //初回のみCanvasを作成しておく
        $(window).on('load',function(){
            loadImage(null);
        });

        //画像読込
        $('#getfile').change(function (){
            //読み込み
            var fileList =$('#getfile').prop('files');
            var reader = new FileReader();
            reader.readAsDataURL(fileList[0]);

            //読み込み後
            $(reader).on('load',function(){
                $('#preview').prop('src',reader.result);
                imageIni.imageData = reader.result;
            });
        });


        //ボタンイベントまとめ
        $('.btn').on('click',function(e){
            if (e.target.id === "update"){
                //画像生成は個別処理なし
            }else if (e.target.id === "up"){
                imageIni.yPos -= 1;
            }else if (e.target.id === "down"){
                imageIni.yPos += 1;
            }else if (e.target.id === "left"){
                imageIni.xPos -= 1;
            }else if (e.target.id === "right") {
                imageIni.xPos += 1;
            }else if (e.target.id === "zoomin") {
                imageIni.Scale += 1;
            }else if (e.target.id === "zoomout") {
                imageIni.Scale -= 1;
            }else if (e.target.id === "reset"){
                imageIni.resetImage();
            }else if (e.target.id === "dl"){
                //TODO
                downloadImage(imageIni.imageData);
                return;
            }

            //画像操作時は再描画を行う
            if(imageIni.imageData !== null){
                imageIni.makeImage();
                $("#alert").text("");
            }else{
                $("#alert").text("画像を選択してから画像生成を行ってください");
            }
        });
    });
})($);

リポジトリ

github.com

参考記事

wood-roots.com qiita.com techacademy.jp