Skip to content

Instantly share code, notes, and snippets.

@motsu0
Created October 6, 2021 13:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save motsu0/fafe8b3882b036c5aae82f0065d863a0 to your computer and use it in GitHub Desktop.
Save motsu0/fafe8b3882b036c5aae82f0065d863a0 to your computer and use it in GitHub Desktop.
画像のサイズが印刷に適しているか計算するツール
.input-data{
width: 5em;
}
#cb-inpaper{
transform: scale(1.5);
margin: 0 5px;
}
#canvas{
box-sizing: border-box;
width: 100%;
height: 500px;
border: 1px solid #333;
}
.mark{
display: inline-block;
padding: 0 5px;
margin: 2px 0;
}
.mark-gray{
border: 2px solid #9E9E9E;
}
.mark-red{
border: 2px solid #F44336;
}
<div id="control">
<div class="control-row">
<h3>印刷したい画像のサイズ</h3>
w=<input type="number" id="input-w" class="input-data" placeholder="1000" value="3000">px<br>
h=<input type="number" id="input-h" class="input-data" placeholder="1000" value="4000">px
</div>
<div class="control-row">
<h3>印刷用紙</h3>
<select name="sel-paper" id="sel-paper">
<option value="DSC">DSC 89mm×119mm</option>
<option value="L">L 89mm×127mm</option>
<option value="KG">KG 102mm×152mm</option>
<option value="hagaki">ハガキ 100mm×148mm</option>
<option value="HV">HV 89mm×158mm</option>
<option value="LL">2L 127mm×178mm</option>
<option value="A0">A0 841mm×1189mm</option>
<option value="A1">A1 594mm×841mm</option>
<option value="A2">A2 420mm×594mm</option>
<option value="A3">A3 297mm×420mm</option>
<option value="A4">A4 210mm×297mm</option>
<option value="A5">A5 148mm×210mm</option>
<option value="A6">A6 105mm×148mm</option>
<option value="A7">A7 74mm×105mm</option>
<option value="B0">B0 1030mm×1456mm</option>
<option value="B1">B1 728mm×1030mm</option>
<option value="B2">B2 515mm×728mm</option>
<option value="B3">B3 364mm×515mm</option>
<option value="B4">B4 257mm×364mm</option>
<option value="B5">B5 182mm×257mm</option>
<option value="B6">B6 128mm×182mm</option>
<option value="B7">B7 91mm×128mm</option>
</select>
</div>
<div class="control-row">
<h3>解像度</h3>
<p>
<input type="number" id="input-kaizoudo" min="1" class="input-data" value="350">dpi<br>
モノクロの場合600dpi、カラーの場合350dpiが目安
</p>
</div>
<div class="control-row">
<h3>オプション</h3>
<input type="checkbox" id="cb-inpaper">画像を用紙内に収める
</div>
</div>
<h3>早見図</h3>
<div id="message" class="hide">
入力値に誤りがあります。
</div>
<canvas id="canvas"></canvas>
<div>
<span class="mark mark-gray">灰色…用紙</span><br>
<span class="mark mark-red">赤色…画像</span>
</div>
<div id="notes"></div>
const input_w = document.getElementById('input-w');
const input_h = document.getElementById('input-h');
const sel_paper = document.getElementById('sel-paper');
const input_k = document.getElementById('input-kaizoudo');
const input_data = document.getElementsByClassName('input-data');
const cb_inpaper = document.getElementById('cb-inpaper');
const msg = document.getElementById('message');
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
const notes = document.getElementById('notes');
const paper_data = {
DSC: [89,119],
L: [89,127],
KG: [102,152],
hagaki: [100,148],
HV: [89,158],
LL: [127,178],
A0: [841,1189],
A1: [594,841],
A2: [420,594],
A3: [297,420],
A4: [210,297],
A5: [148,210],
A6: [105,148],
A7: [74,105],
B0: [1030,1456],
B1: [728,1030],
B2: [515,728],
B3: [364,515],
B4: [257,364],
B5: [182,257],
B6: [128,182],
B7: [91,128]
};
//
[...input_data].forEach(el=>{
el.addEventListener('input',draw);
});
sel_paper.addEventListener('input',draw);
cb_inpaper.addEventListener('change',draw);
//
draw();
function draw(){
//例外処理
msg.classList.add('hide');
for(let i=0;i<input_data.length;i++){
if(!Number.isInteger(Number(input_data[i].value))){
mesError();
return;
}
if(Number(input_data[i].value)<1){
mesError();
return;
}
}
//変数定義
canvas.width = canvas.clientWidth;
canvas.height = canvas.clientHeight;
const can_w = canvas.clientWidth - 20;
const can_h = canvas.clientHeight - 20;
const paper_w = paper_data[sel_paper.value][0] * Number(input_k.value) / 25.4;
const paper_h = paper_data[sel_paper.value][1] * Number(input_k.value) / 25.4;
const pic_w = Number(input_w.value);
const pic_h = Number(input_h.value);
//計算
const mode_w = (()=>{
if(can_w>=can_h){
return true;
}else{
return false;
}
})();
const rate_paper = Math.min(Math.min(can_w,can_h)/Math.min(paper_w,paper_h), Math.max(can_w,can_h)/Math.max(paper_w,paper_h));
const rate_pic = Math.min(Math.min(can_w,can_h)/Math.min(pic_w,pic_h), Math.max(can_w,can_h)/Math.max(pic_w,pic_h));
const rate = Math.min(rate_paper,rate_pic);
const rate_pp = Math.min(paper_w/Math.min(pic_w,pic_h), paper_h/Math.max(pic_w,pic_h));
const can_paper_w = paper_w * rate;
const can_paper_h = paper_h * rate;
const can_pic_w = (()=>{
if(cb_inpaper.checked&&rate_pp<1){
return pic_w * rate_pp * rate;
}else{
return pic_w * rate;
}
})();
const can_pic_h = (()=>{
if(cb_inpaper.checked&&rate_pp<1){
return pic_h * rate_pp * rate;
}else{
return pic_h * rate;
}
})();
//描画
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.globalCompositeOperation = 'multiply';
ctx.fillStyle = '#9E9E9E';
if(mode_w){
ctx.fillRect(10, 10, Math.max(can_paper_w,can_paper_h), Math.min(can_paper_w,can_paper_h));
}else{
ctx.fillRect(10, 10, Math.min(can_paper_w,can_paper_h), Math.max(can_paper_w,can_paper_h));
}
ctx.fillStyle = '#F44336';
if(mode_w){
ctx.fillRect(10, 10, Math.max(can_pic_w,can_pic_h), Math.min(can_pic_w,can_pic_h));
}else{
ctx.fillRect(10, 10, Math.min(can_pic_w,can_pic_h), Math.max(can_pic_w,can_pic_h));
}
//notes
const note_w = Math.round(paper_data[sel_paper.value][0]*Number(input_k.value)/25.4);
const note_h = Math.round(paper_data[sel_paper.value][1]*Number(input_k.value)/25.4);
notes.textContent = `用紙「${sel_paper.options[sel_paper.selectedIndex].textContent}」、解像度「${Number(input_k.value)}」dpiでの推奨画像サイズは「${note_w}px × ${note_h}px」`;
}
function mesError(){
msg.classList.remove('hide');
ctx.clearRect(0, 0, canvas.width, canvas.height);
notes.textContent = '';
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment