木曜日, 7月 10, 2025

Let's start JavaScript 75 
HTML上で指定画像をCMYK別表示

HTML上で指定画像をVMYK別に表示します。

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, initial-scale=1.0">
<title>CMYKチャンネル分解</title>
<style>
body {
font-family: Arial, sans-serif;
text-align: center;
margin: 10px;
background-color: black;
color: white;
}
canvas {
margin: 10px;
border: 1px solid black;
}
</style>
</head>
<body>
<h3>選択した画像をCMYKを分解表示</h3>
<input type="file" id="imageInput"
accept="image/*"><br><br>

<div>
<canvas id="canvasC"></canvas>
<canvas id="canvasM"></canvas>
<canvas id="canvasY"></canvas>
<canvas id="canvasK"></canvas>
</div>

<script>
const img = new Image();
const fileInput = document.getElementById("imageInput");

fileInput.addEventListener("change", (event) => {
const file = event.target.files[0];
if (file) {
const reader = new FileReader();
reader.onload = function(e) {
img.src = e.target.result;
img.onload = processImage;
};
reader.readAsDataURL(file);
}
});

function processImage() {
const width = img.width;
const height = img.height;

// 各キャンバス設定
const canvasC = document.getElementById("canvasC");
const canvasM = document.getElementById("canvasM");
const canvasY = document.getElementById("canvasY");
const canvasK = document.getElementById("canvasK");

[canvasC, canvasM, canvasY, canvasK].
forEach(canvas => {
canvas.width = width;
canvas.height = height;
});

const ctxC = canvasC.getContext("2d");
const ctxM = canvasM.getContext("2d");
const ctxY = canvasY.getContext("2d");
const ctxK = canvasK.getContext("2d");

ctxC.drawImage(img, 0, 0);
ctxM.drawImage(img, 0, 0);
ctxY.drawImage(img, 0, 0);
ctxK.drawImage(img, 0, 0);

const imageDataC =
ctxC.getImageData(0, 0, width, height);
const imageDataM =
ctxM.getImageData(0, 0, width, height);
const imageDataY =
ctxY.getImageData(0, 0, width, height);
const imageDataK =
ctxK.getImageData(0, 0, width, height);

const dataC = imageDataC.data;
const dataM = imageDataM.data;
const dataY = imageDataY.data;
const dataK = imageDataK.data;

for (let i = 0; i < dataC.length; i += 4) {
const r = dataC[i] / 255;
const g = dataC[i + 1] / 255;
const b = dataC[i + 2] / 255;

// RGB → CMYK 変換
// CMYKの各成分は以下の式で計算
// || 0 はゼロ除算エラー防止処理
const k = 1 - Math.max(r, g, b);
const c = (1 - r - k) / (1 - k) || 0;
const m = (1 - g - k) / (1 - k) || 0;
const y = (1 - b - k) / (1 - k) || 0;
// グレースケール表示
// const gray = (r + g + b) / 3;
// dataK[i] = dataK[i + 1] = dataK[i + 2] = gray;

// 透明度の設定
// dataC[i + 3] = 128; // シアンの透明度を50%にする

// シアン
dataC[i] = (1 - c) * 255;
dataC[i + 1] = 255;
dataC[i + 2] = 255;

// マゼンタ
dataM[i] = 255;
dataM[i + 1] = (1 - m) * 255;
dataM[i + 2] = 255;

// イエロー
dataY[i] = 255;
dataY[i + 1] = 255;
dataY[i + 2] = (1 - y) * 255;

// ブラック
dataK[i] = k * 255;
dataK[i + 1] = k * 255;
dataK[i + 2] = k * 255;
}

ctxC.putImageData(imageDataC, 0, 0);
ctxM.putImageData(imageDataM, 0, 0);
ctxY.putImageData(imageDataY, 0, 0);
ctxK.putImageData(imageDataK, 0, 0);
}
</script>
</body>
</html>

用意した画像

実行したら、処理したい画像ファイルを選択すれば・・・

CMYK別に表示されます。

TCDW8458
相性や位に注意しているような方ではなかったのが

Baby Alien 099
鬼はエイリアンだった〜とか(^o^)
厚くて溶けそうです涙。そう言えば、バッグに異常な数のお守りを付けている女性を駅で見かけたのですが・・・神様の相性や位に注意しているような方ではなかったのが気になりました。

水曜日, 7月 09, 2025

手作りレンズプロジェクト 01 
100均の虫眼鏡1枚レンズ

最初は100均でゲットした4倍の虫眼鏡を分解せずにレンズとしてみました。
虫眼鏡のレンズと絞りの位置か関係などが解らないので試行錯誤で2ヶ月ほどかかりました。制作には100均で手に入れた黒の色画用紙を丸めて筒を作っています。

手作りレンズプロジェクト 

上は試行錯誤の残骸の一部です。

ということで今回の部品が完成です。

フォーカシングは原始的に筒を前後させます。全体を延長リングにねじ込み、それをマウントアダプターでカメラにセッティングします。

なお、絞り穴は2〜12mmまで2mm間隔で用意しましたg、2〜6mmぐらいが現実的ですね。後日比較してみます。

セッティングした状態です。レンズから直径4.5mmの絞り穴までの距離は20mmです。

Panasonic LUMIX DMC-G3
LUMIX G VARIO 14-42mm/F3.5-5.6 ASPH

で、撮影してみました。絞り穴は4.5mm相当でF8.3となります。中心部は取りあえずピント(※)が合っていますが、周辺はボケていますね。まるで、Kenko Tokina Lensbaby Sweet 22で撮影したような感じで面白い結果です。これは絞り穴の作成が雑だった∴切り口のほころびが影響したことが原因です。とにかく 虫眼鏡でも撮影できるんですね〜

※ピントは"Tricker Treat"の文字に合わせて絞り優先で撮影しました。

ここで絞り穴を綺麗に開けるために、穴開けポンチを研いで1週間後に再撮影しました。

再撮影では絞り穴は2mmでF19となります。

SONY α NEX-6
KAZNEX 38mm F19


比較のために、絞り穴10mm相当でF3.8出撮影してみましたが、ありえないですね。少なくとも絞り穴は4mmのF9.5以下が現実的ですね。ただし、この構造で絵はピント合わせが恐ろしく難しいので、今後の課題になりました。

ということで・・・
KAZNEX(カズネックス 38mm F19
の完成です。
なお、画角と絞り値は以下の計算で割り出しました。

■焦点距離と拡大率の関係式
M = 焦点距離 / 拡大率
M:焦点距離(mm)
e:拡大率(倍率)
250mm:人間の平均明視の距離(近点距離)
M = 250 / 4 = 62.5mm

■撮像面の対角長
D:撮像面の対角長
D = √(センサーの横幅の二乗 + センサーの縦幅二乗)
w:センサーの横幅(mm)
h:センサーの縦幅(mm)

■フルサイズ:36×24mmの撮像面の対角長
D = √(36×36 + 24×24)
= √1296+576
= 43.266 = 43.3mm

■画角の割り出し
画角 = 2 × ArcTan(撮像面の対角長 /(2×焦点距離))
= 2 × ArcTan(43.3 /(2 × 62.5))
= 2 × 19.10 = 38.21 = 38mm相当

■絞り値の割り出し
F値 = 焦点距離 / 絞りの直径
= 38 / 2 = 19

よって・・・
KAZNEX 38mm F19
です。計算が合っているか心配ですが・・・。
なお、カメラはAPS-CのSONY α NEX-6なので、38×1.5で57mm相当ということになります。

TCDW8457
しつこい郵便DMにウンザリしています

しつこい郵便DMにウンザリしていますが、1年近く送り続けている根性には呆れてしまいます。宛先が明記されているのでシュレッダー直結の刑はいつまで続くのやら〜。

火曜日, 7月 08, 2025

スカスカな綿棒ケースの対処方法

使い込んで、残りの本数が少なくなってくると・・・



綿棒が寝てしまうので、ソレを回避する緩い方法があります。


お菓子の箱なのの厚紙を・・・

※上のパッケージはダミーです。


適当にケットしてからカーリングの癖を付けて・・・


入れるだけです。写真はチョットいまいちに見えますが、まっ、気にしなければ心配はないですが(^o^)

ポイントは「軽く丸め込む」です。それによって綿棒が減っても対応してくれます。

TCDW8456
東京では下手な場所でやると迷惑になりそうですね

唐突に電動のシャボン玉作成機がほしくなってしまったのですが・・・冷静に考えると、使う場所が無いかも。東京では下手な場所でやると迷惑になりそうですね。残念(>_<)

月曜日, 7月 07, 2025

HTML_CSS_18 
HTMLでフォントサイズの設定比較


HTMLで3つのフォントサイズの設定を比較してみました。

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content=
        "width=device-width, initial-scale=1.0">
<title>フォントサイズ指定</title>
<style>
body {
background-color: lemonchiffon;
}
.f_sizu16 {
font-size: 16px;
}
.mainbox {
width: 350px;
height: 300px;
margin: 0px auto;
margin-top: 50px;
}
</style>
</head>
<body>
<div class="mainbox">
<div class="f_sizu16">
このフォントサイズは16px指定です</div>
<p>このフォントサイズはP指定です</p>
<h4>このフォントサイズはH4指定です</h4>
<br>
<div class="f_sizu16"><b>
このフォントサイズは16px指定Boldです</b></div>
<p><b>このフォントサイズはP指定Boldです</b></p>
<h4>このフォントサイズはH4指定です</h4>
</div>
</body>
</html>


上は処理結果です。<P>と<;H4>は16ptと同等です。ただし、<;H4>は太字になるので、16ptと<P>はBold指定すると<;H4>と同じに見えます。

TCDW8455
昭和時代は日射病と言っていましたね

この暑さは相当ヤバイみたいですね。若い人も熱中症でかなり倒れているようです。この炎天下で近くの小学校や中学校で、校庭で体育の授業が行われている事に恐怖すら感じます。まっ、我々の時代も普通にやってましたが、昭和時代は日射病と言っていましたね。具合が悪くなった生徒の記憶はありませんが、時代が違うということでしょうか?

日曜日, 7月 06, 2025

Let's start JavaScript 74 
HTML上で指定画像をRGB別表示

HTML上で指定画像をRGB別に表示します。

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, initial-scale=1.0">
<title>RGBチャンネル分解</title>
<style>
body {
font-family: Arial, sans-serif;
text-align: center;
margin: 10px;
background-color: black;
color: white;
}
canvas {
margin: 10px;
border: 1px solid black;
}
</style>
</head>
<body>
<h3>選択した画像をRGBを分解表示</h3>
<input type="file" id="imageInput"
accept="image/*"><br><br>

<div>
<canvas id="canvasR"></canvas>
<canvas id="canvasG"></canvas>
<canvas id="canvasB"></canvas>
</div>

<script>
const img = new Image();
const fileInput =
document.getElementById("imageInput");

fileInput.addEventListener("change", (event) => {
const file = event.target.files[0];
if (file) {
const reader = new FileReader();
reader.onload = function(e) {
img.src = e.target.result;
img.onload = processImage;
};
reader.readAsDataURL(file);
}
});

function processImage() {
const width = img.width;
const height = img.height;

// 各キャンバス設定
const canvasR = document.getElementById("canvasR");
const canvasG = document.getElementById("canvasG");
const canvasB = document.getElementById("canvasB");

[canvasR, canvasG, canvasB].forEach(canvas => {
canvas.width = width;
canvas.height = height;
});

const ctxR = canvasR.getContext("2d");
const ctxG = canvasG.getContext("2d");
const ctxB = canvasB.getContext("2d");

ctxR.drawImage(img, 0, 0);
ctxG.drawImage(img, 0, 0);
ctxB.drawImage(img, 0, 0);

// getImageData() でピクセルデータを取得
const imageDataR =
ctxR.getImageData(0, 0, width, height);
const imageDataG =
ctxG.getImageData(0, 0, width, height);
const imageDataB =
ctxB.getImageData(0, 0, width, height);

const dataR = imageDataR.data;
const dataG = imageDataG.data;
const dataB = imageDataB.data;

// data[i] (R), data[i+1] (G), data[i+2] (B) を個別に操作
for (let i = 0; i < dataR.length; i += 4) {
const r = dataR[i];
const g = dataR[i + 1];
const b = dataR[i + 2];

// 赤のみ(緑・青を0にする)
dataR[i] = r;
dataR[i + 1] = 0;
dataR[i + 2] = 0;

// 緑のみ(赤・青を0にする)
dataG[i] = 0;
dataG[i + 1] = g;
dataG[i + 2] = 0;

// 青のみ(赤・緑を0にする)
dataB[i] = 0;
dataB[i + 1] = 0;
dataB[i + 2] = b;
}

// putImageData() で加工後の画像を表示
ctxR.putImageData(imageDataR, 0, 0);
ctxG.putImageData(imageDataG, 0, 0);
ctxB.putImageData(imageDataB, 0, 0);
}
</script>
</body>
</html>

用意した画像

実行したら、処理したい画像ファイルを選択すれば・・・

RGB別に表示されます。

TCDW8454
「本当のXデーは・・・」とか始まりそうですね

Baby Alien 098
滴系?エイリアン(^o^)
7/5は何もなかったですね。なにかあった? 次はいつなんですかね? 「本当のXデーは・・・」とか始まりそうですね。