view source

JavaScript

var imageData;
var img = new Image();
var fileName = 'google-logo.jpg';

document.title = 'モザイク画像加工(ピクセレート処理) ドラッグ&ドロップで画像投稿';
var labelDot = document.createElement('label');
var labelWhite = document.createElement('label');
var label = document.createElement('label');
labelDot.innerText = 'dot:';
labelWhite.innerText = 'white:';
var inputDot = document.createElement('input');
var inputWhite = document.createElement('input');
var div = document.createElement('div');
inputDot.setAttribute('type','number');
inputDot.setAttribute('value',12);
inputDot.setAttribute('max',64);
inputDot.setAttribute('min',2);
inputWhite.setAttribute('type','number');
inputWhite.setAttribute('value',235);
inputWhite.setAttribute('max',255);
inputWhite.setAttribute('min',128);


labelDot.appendChild(inputDot);
labelWhite.appendChild(inputWhite);
demo.appendChild(labelDot);
demo.appendChild(labelWhite);
demo.appendChild(label);
label.appendChild(div);

var input = document.createElement('input');
input.setAttribute('type','file');
input.style.display = 'none';
label.appendChild(input);

function draw() {
  console.log('draw');
  div.innerHTML = '';
  var canvas = document.createElement('canvas');
  var canvasM = document.createElement('canvas');
  var w = document.body.clientWidth;
  var h = document.body.clientHeight;
  canvas.setAttribute('width',w);
  canvas.setAttribute('height',h);
  let demo = document.getElementById('demo');
  div.appendChild(canvas);
  div.appendChild(canvasM);


  if (!canvas || !canvas.getContext) {
    return false;
  }
  img.src = fileName; //
  img.onload = function onImageLoad() {
    canvas.width = img.width;
    canvas.height = img.height;
    canvas.setAttribute('width',img.width);
    canvas.setAttribute('height',img.height);
    canvasM.setAttribute('width',img.width);
    canvasM.setAttribute('height',img.height);
    var ctx = canvas.getContext('2d');
    var ctxM = canvasM.getContext('2d');

    var rgba = "rgba(255,255,255,1)"
    ctx.fillStyle = rgba;
    ctx.fillRect(0, 0, canvas.width, canvas.height);
    ctx.drawImage(img, 0, 0);


    var dot = parseInt(inputDot.value) || 2;
    console.log(dot);
    imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
    convertMosaic(ctx,ctxM, canvas.width, canvas.height, dot);
    whiteToAlpfa(ctxM, canvasM)
    //ctx.drawImage(imageData, 0, 0);

  }

}

function convertMosaic(ctx,ctxM, width, height, dot) {

  for (y = 0; y < height; y+=dot) {
    for (x = 0; x < width; x+=dot) {
      if (x % width < dot) {
        x -= x % width;
      }
      var i = (y * width + x) * 4;
      var cR = imageData.data[i ];
      var cG = imageData.data[i + 1];
      var cB = imageData.data[i + 2];
      var cA = imageData.data[i + 3];
      
      var data = {
        R:cR,
        G:cG,
        B:cB,
        A:cA,
      };
      cA = cA*1/255;
      var rgba = "rgba("+cR+","+cG+","+cB+","+cA+")"
      //console.log(rgba)
      ctxM.fillStyle = rgba;
      ctxM.fillRect(x, y, x + dot, y + dot);
    }
  }
}

function whiteToAlpfa(ctx, canvas) {
  //白に近い色部位を透過する
  var whiteLine = parseInt(inputWhite.value);
  var r = whiteLine;
  var g = whiteLine;
  var b = whiteLine;
  var rgb = r+g+b;

  var imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
  for(var i = 0; i < (imageData.width*imageData.height); i++) {

    var rP = imageData.data[i*4  ];
    var gP = imageData.data[i*4+1];
    var bP = imageData.data[i*4+2];
    var rgbP = rP+gP+bP;
    var rgbDiff = rgb - rgbP;

    if(rgbDiff < 0) {
        imageData.data[i*4+3] = 0;
    } else if (rgbDiff < 40){
        imageData.data[i*4+3] = 1/rgbDiff*40;
    }
  }
  ctx.putImageData(imageData, 0, 0);
}

window.onload = function() {
  draw()
  $('#demo').css({backgroundColor:'#eee'})
}



var dragArea = document.getElementById('demo');
dragArea.addEventListener('dragstart', function(event){
  event.dataTranfer.addElement(container);
});
dragArea.addEventListener('dragover', function(event){
  event.preventDefault();
});
dragArea.addEventListener('dragleave', function(event){
  event.preventDefault();
});

dragArea.addEventListener('drop', function(event){
  event.preventDefault();
  console.log(event.dataTransfer.files);
  if(!event.dataTransfer.files.length){
    return;
  }
  var file = event.dataTransfer.files[0];
  fileName = file.name.substring(0,12).split('.')[0] || 'name';
  console.log(file);

  var reader = new FileReader();
  reader.readAsDataURL(file)

  reader.addEventListener('load', function(){
    var dataURL = reader.result;
    console.log(dataURL);

    var newImage = new Image();
    newImage.src = dataURL;
    newImage.onload = function(){
      src = newImage.src;
      fileName = src;
      draw();
      //insertCanvas(dataURL, this);
    }
  });
});

$(document).on('change', '[type="file"]', function(e){
  var ele = $(this);
  var event = e.originalEvent;
  var file = event.target.files[0];
  if (!file.type.match('image.*')){
      return;
  }
  var reader = new FileReader();
  var newImage = new Image();
  reader.onload = function(){
    var dataURL = reader.result;
    console.log(dataURL);
    newImage.src = dataURL;
    newImage.onload = function(){
      src = newImage.src;
      fileName = src;
      draw();
      //insertCanvas(dataURL, this);
    }
  }
  reader.readAsDataURL(file);
});


$('#demo input').on('change', function(){
  draw();
})

CSS

HTML

ページのソースを表示 : Ctrl+U , DevTools : F12

view-source:https://hi0a.com/demo/-js/js-canvas-image-mosic-pixel/

ABOUT

hi0a.com 「ひまアプリ」は無料で遊べるミニゲームや便利ツールを公開しています。

プログラミング言語の動作デモやWEBデザイン、ソースコード、フロントエンド等の開発者のための技術を公開しています。

必要な機能の関数をコピペ利用したり勉強に活用できます。

プログラムの動作サンプル結果は画面上部に出力表示されています。

環境:最新のブラウザ GoogleChrome / Windows / Android / iPhone 等の端末で動作確認しています。

画像素材や音素材は半分自作でフリー素材配布サイトも利用しています。LINK参照。

動く便利なものが好きなだけで技術自体に興味はないのでコードは汚いです。

途中放置や実験状態、仕様変更、API廃止等で動かないページもあります。