complmnt.htm

戻る

<!DOCTYPE HTML>
<HTML LANG="ja">

<HEAD>
<META CHARSET="Shift_JIS">
<TITLE>補色残像</TITLE>
</HEAD>

<BODY onResize="size_view()" STYLE="background-color:#CCFFFF">
<CENTER ID="cont">
<B>補色残像</B>
<BR>

<FORM>
<TABLE><TR><TD ALIGN=LEFT>
ファイル(画像):<BR>
<INPUT TYPE=FILE ID="file" SIZE=60 onChange="in_sel()">
</TD></TR></TABLE>
<DIV STYLE="position:relative; width:100px; height:100px; background-color:white">
<IMG ID="src" WIDTH=1 HEIGHT=1 onLoad="in_sel2()" onError="in_sel_err()" STYLE="position:absolute; left:0; top:0; visibility:hidden">
</DIV>
<DIV STYLE="white-space:nowrap; margin-top:4px">
<INPUT TYPE=CHECKBOX ID="lumi">輝度調整
<INPUT TYPE=BUTTON ID="cre" VALUE="作成" DISABLED onClick="create()" STYLE="margin-left:4px">
<SPAN ID="prog" STYLE="display:inline-block; width:4em; text-align:left; margin-left:1em; visibility:hidden">
<SPAN ID="val"></SPAN>%
</SPAN>
<INPUT TYPE=BUTTON ID="show" VALUE="補色" DISABLED onClick="show_comp()" STYLE="margin-left:2em">
</DIV>
</FORM>

<DIV ID="view" STYLE="position:relative; background-color:white; margin-top:4px; visibility:hidden">
<CANVAS ID="gray" WIDTH=1 HEIGHT=1 STYLE="position:absolute; left:0; top:0; visibility:hidden"></CANVAS>
<CANVAS ID="comp" WIDTH=1 HEIGHT=1 STYLE="position:absolute; left:0; top:0; visibility:hidden"></CANVAS>
</DIV>

<DIV STYLE="position:absolute; bottom:0; visibility:hidden">.</DIV><!-- Opera 用ダミー -->
</CENTER>

<SCRIPT TYPE="text/javascript">
<!--

function size_view() {
  if(!img_width)
    return;

  elem_view.style.width = elem_gray.style.width = elem_comp.style.width
    = elem_view.style.height = elem_gray.style.height = elem_comp.style.height = "1px";
  var width = document.documentElement.clientWidth - (elem_cont.offsetLeft << 1);
  if(width < 1)
    width = 1;
  var height = document.documentElement.clientHeight - (elem_cont.offsetTop << 1) - elem_view.offsetTop;
  if(height < 1)
    height = 1;
  if(img_width > width || img_height > height) {
    if(img_width * height > img_height * width) {
      if((height = Math.floor(img_height * width / img_width)) < 1)
        height = 1;
    }
    else {
      if((width = Math.floor(img_width * height / img_height)) < 1)
        width = 1;
    }
  }
  else {
    width = img_width;
    height = img_height;
  }
  elem_view.style.width = elem_gray.style.width = elem_comp.style.width = String(width) + "px";
  elem_view.style.height = elem_gray.style.height = elem_comp.style.height = String(height) + "px";
}

function in_sel() {
  elem_src.style.visibility = "hidden";
  elem_src.src = "";
  elem_view.style.visibility = elem_gray.style.visibility = "hidden";
  elem_gray.width = elem_comp.width = elem_gray.height = elem_comp.height = 1;
  elem_file.disabled = elem_cre.disabled = elem_show.disabled = true;

  img_width = 0;

  if(typeof FileReader == "function") {
    file_reader = new FileReader();
    file_reader.onload = in_sel_fr;
    file_reader.readAsDataURL(elem_file.files[0]);  // files.item(0) は Opera で NG
  }
  else {
    elem_src.src = elem_file.files.item(0).getAsDataURL();
  }
}

function in_sel_fr() {
  elem_src.src = file_reader.result;
  file_reader = undefined;
}

function in_sel2() {
  img_width  = elem_src.naturalWidth;
  img_height = elem_src.naturalHeight;

  // 元画像サムネイル表示
  with(elem_src) {
    if(img_width > 100 || img_height > 100) {
      if(img_width > img_height) {
        width = 100;
        height = Math.floor(100 * img_height / img_width);
      }
      else {
        height = 100;
        width = Math.floor(100 * img_width / img_height);
      }
    }
    else {
      width  = img_width;
      height = img_height;
    }
    style.left = String((100 - width)  >> 1) + "px";
    style.top  = String((100 - height) >> 1) + "px";
    style.visibility = "visible";
  }

  size_view();

  elem_view.style.visibility = "visible";
  elem_file.disabled = elem_cre.disabled = false;
}

function in_sel_err() {
  elem_file.disabled = false;
}

function create() {
  elem_gray.style.visibility = "hidden";
  elem_file.disabled = elem_cre.disabled = elem_show.disabled = true;

  elem_val.textContent = "0";
  elem_prog.style.visibility = "visible";

  document.documentElement.style.cursor = "wait";
  setTimeout(create2, 0);
}

function create2() {
  elem_gray.width = elem_comp.width = img_width;
  elem_gray.height = elem_comp.height = img_height;

  ctx_gray.fillStyle = "white";  // 元画像に透過部分がある場合を考慮
  ctx_gray.fillRect(0, 0, img_width, img_height);
  ctx_gray.drawImage(elem_src, 0, 0);
  gray_imgdat = ctx_gray.getImageData(0, 0, img_width, img_height);
  comp_imgdat = ctx_comp.createImageData(img_width, img_height);
  gray_data = gray_imgdat.data;
  comp_data = comp_imgdat.data;

  i_data = gray_data.length;
  w_len = gray_imgdat.width << 2;
  lumi = elem_lumi.checked;

  cre_img();
}

function cre_img() {
  for(var i_data_end = i_data - w_len; i_data > i_data_end; ) {
    i_data -= 4;

    var r = gray_data[i_data    ];
    var g = gray_data[i_data + 1];
    var b = gray_data[i_data + 2];
    var Y = 306 * r + 601 * g + 117 * b;
    gray_data[i_data] = gray_data[i_data + 1] = gray_data[i_data + 2] = Y >> 10;

    if(lumi) {  // 輝度調整あり
      var d = 131072 - Y;
      r = (r << 10) + d;
      g = (g << 10) + d;
      b = (b << 10) + d;
      var min = (r < g) ? r : g;
      if(b < min)
        min = b;
      if(min < 0) {
          min -= 131072;
          r = 131072 - (r - 131072) * 131072 / min;
          g = 131072 - (g - 131072) * 131072 / min;
          b = 131072 - (b - 131072) * 131072 / min;
      }
      var max = (r > g) ? r : g;
      if(b > max)
        max = b;
      if(max > 261120) {
          max -= 131072;
          r = 131072 + (r - 131072) * 130048 / max;
          g = 131072 + (g - 131072) * 130048 / max;
          b = 131072 + (b - 131072) * 130048 / max;
      }
      r >>= 10;
      g >>= 10;
      b >>= 10;
    }

    comp_data[i_data    ] = r ^ 0xff;
    comp_data[i_data + 1] = g ^ 0xff;
    comp_data[i_data + 2] = b ^ 0xff;
    comp_data[i_data + 3] = 255;
  }

  elem_val.textContent = (100 - i_data * 100 / gray_data.length).toFixed(0);

  setTimeout((i_data) ? cre_img : cre_img_end, 0);
}

function cre_img_end() {
  ctx_gray.putImageData(gray_imgdat, 0, 0);
  ctx_comp.putImageData(comp_imgdat, 0, 0);
  gray_imgdat = comp_imgdat = gray_data = comp_data = undefined;

  elem_prog.style.visibility = "hidden";

  elem_gray.style.visibility = "visible";
  elem_file.disabled = elem_cre.disabled = elem_show.disabled = false;

  document.documentElement.style.cursor = "auto";
}

function show_comp() {
  elem_comp.style.visibility = "visible";
  elem_gray.style.visibility = "hidden";
  elem_file.disabled = elem_cre.disabled = elem_show.disabled = true;

  setTimeout(hide_comp, 20000);
}

function hide_comp() {
  elem_gray.style.visibility = "visible";
  elem_comp.style.visibility = "hidden";
  elem_file.disabled = elem_cre.disabled = elem_show.disabled = false;
}

  elem_cont = document.getElementById("cont");
  elem_file = document.getElementById("file");
  elem_src = document.getElementById("src");
  elem_lumi = document.getElementById("lumi");
  elem_cre = document.getElementById("cre");
  elem_prog = document.getElementById("prog");
  elem_val = document.getElementById("val");
  elem_show = document.getElementById("show");
  elem_view = document.getElementById("view");
  elem_gray = document.getElementById("gray");
  elem_comp = document.getElementById("comp");

  ctx_gray = elem_gray.getContext("2d");
  ctx_comp = elem_comp.getContext("2d");
  ctx_gray.globalCompositeOperation = ctx_comp.globalCompositeOperation = "copy";

  img_width = 0;

  // ページを再ロードしたときのため
  document.forms[0].reset();
  elem_file.disabled = false;

//-->
</SCRIPT>

</BODY>

</HTML>