0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

cm 指定を整数ピクセルにする前に決めたい境界条件

0
Posted at

画像の幅と高さを cm で受け取り、整数ピクセルの計画を作る場合、換算式だけでは入力契約が完成しません。正の数でも丸めた結果が 0 になることがあります。また、幅が上限以下でも、幅と高さの積が処理予算を超えることがあります。

ここでは画像処理そのものではなく、寸法の計画だけを返す独立した JavaScript の例を示します。画像のリサンプリング、ファイルへの密度書き込み、印刷物の定規による確認は行いません。

先に決める入力と出力

幅と高さは有限の正の number、密度は 1〜65535 の整数とします。文字列の "5" は、数値に変換できても受け付けません。浮動小数点の cm 値は受け付けますが、密度 300.5 は整数条件で拒否します。

各軸の計算は cm / 2.54 * ppi を Math.round で整数にします。その結果が安全な整数で、かつ 1 ピクセル以上であることも必要です。たとえば正の 0.001 cm でも、1 ppi では 0 ピクセルに丸められるため、この例では拒否します。極小値を 1 ピクセルへ補正するのではなく、要求そのものを拒否する方針です。

さらに、丸め後の各辺を 10,000 ピクセル以下、面積を 40,000,000 ピクセル以下に制限します。これは説明用に選んだ予算であり、すべての環境に共通する限界ではありません。

export function rasterPlan(widthCm, heightCm, ppi) {
  if (![widthCm, heightCm, ppi].every(
    value => typeof value === "number" && Number.isFinite(value) && value > 0
  )) throw new RangeError("dimensions and density must be finite positive numbers");
  if (!Number.isInteger(ppi) || ppi > 65535) {
    throw new RangeError("density must be an integer from 1 to 65535");
  }
  const width = Math.round((widthCm / 2.54) * ppi);
  const height = Math.round((heightCm / 2.54) * ppi);
  if (![width, height].every(n => Number.isSafeInteger(n) && n >= 1)) {
    throw new RangeError("requested size does not produce a valid pixel grid");
  }
  if (width > 10000 || height > 10000 || width * height > 40000000) {
    throw new RangeError("requested pixel grid exceeds the example budget");
  }
  return { width, height, ppi };
}

負のケースを読む

60 × 60 cm、300 ppi は 7087 × 7087 ピクセルになります。幅も高さも 10,000 以下ですが、面積は 40,000,000 を超えます。幅だけのガードでは見逃すため、両軸と積を別々に確認します。

一方、5 × 7 cm、300 ppi は 591 × 827 ピクセルです。戻り値の ppi は要求された計画情報であり、JPEG の JFIF や PNG の pHYs に実際に書かれた密度の証拠ではありません。エンコード後の読み戻しは別の検証です。

Node.js で再現する

上の関数と次のブロックを順番に one.mjs へ保存し、node one.mjs を実行します。ES モジュールとして扱われるため、export を含んだまま実行できます。成功時は assertion の出力がありません。

import assert from "node:assert/strict";

assert.deepEqual(rasterPlan(5, 7, 300), { width: 591, height: 827, ppi: 300 });
for (const args of [
  ["5", 7, 300],
  [5, 7, 300.5],
  [0.001, 0.001, 1],
  [60, 60, 300],
]) {
  assert.throws(() => rasterPlan(...args));
}

親ハーネスでは有効 6 件、無効 16 件、丸め 4 件を数値として確認し、幅だけのガードが面積超過を見逃す負の対照も確認しました。実行環境は macOS 上の Node.js v22.23.4 です。実行したのは Codex エージェントであり、アカウント所有者本人の操作ではありません。これらは純粋な数値確認と正式ヘルパーの読み取り専用比較で、画像や PDF の生成テストではありません。

開示:この文章の初稿は Yan Wang / LensUp のために GPT-6.1 Terra が生成し、独立した AI 編集者が推敲しました。10 月 27 日に Codex エージェントが公開ページのテキスト、ローカルの正式ソース、純粋な数値ケースを確認し、事実・コード・開示のレビューを行いました。新たな画像変換、スマートフォン・プリンターでのテスト、提出先での受理、アカウント所有者本人による確認は主張していません。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?