diff options
| author | Yasutake Yohei <61961825+yasutakeyohei@users.noreply.github.com> | 2026-11-01 22:09:07 +0900 |
|---|---|---|
| committer | Yasutake Yohei <61961825+yasutakeyohei@users.noreply.github.com> | 2026-11-01 22:09:07 +0900 |
| commit | 25237779af89ec78deedc63e7f75412bd7d01fde (patch) | |
| tree | 7ba2ef8bbbaddbb59874030e5715907474be6ea6 /public | |
| parent | 9a48acc5eeab8f79062dc34a02b5ec292ebdf555 (diff) | |
bluebey: 注意書きに配布の条件を追加し、JPG保存を追加
Diffstat (limited to 'public')
| -rw-r--r-- | public/bluebey-studio/guide.html | 6 | ||||
| -rw-r--r-- | public/bluebey-studio/index.html | 4 | ||||
| -rw-r--r-- | public/bluebey-studio/src/main.js | 25 | ||||
| -rw-r--r-- | public/bluebey-studio/src/panel.js | 11 | ||||
| -rw-r--r-- | public/bluebey-studio/src/presets.js | 1 | ||||
| -rw-r--r-- | public/bluebey/guide.pdf | bin | 685994 -> 631226 bytes |
6 files changed, 41 insertions, 6 deletions
diff --git a/public/bluebey-studio/guide.html b/public/bluebey-studio/guide.html index dbb520b..ea69ba5 100644 --- a/public/bluebey-studio/guide.html +++ b/public/bluebey-studio/guide.html @@ -90,7 +90,7 @@ <p>スタジオを開いたとき、利用者に次の注意書きを表示します。この内容に問題がある場合も、お知らせください。</p> <div class="notice"> <p>このスタジオは、市政・政治活動とは関係のない個人的な制作物です。</p> - <p>このスタジオで作成した画像などは、SNS への投稿を含め、自由に使っていただけます。ただし、商用利用やそのほか特殊な使い方をされる場合は、小平市の確認が必要ですので、このサイトのお問い合わせからご連絡ください。</p> + <p>このスタジオで作成した画像などは、SNS への投稿を含め、保存した画像を個人やご家族、友人などで楽しむ場合は、自由に使っていただけます。ただし、チラシ・ポスターなどのお知らせとして、多くの方に配布する場合は、小平市の確認が必要です。商用利用やそのほか特殊な使い方をされる場合も同様ですので、このサイトのお問い合わせからご連絡ください。</p> <p>次のような使い方はご遠慮ください。</p> <ul> <li>公序良俗に反する目的での利用</li> @@ -183,12 +183,12 @@ <h3>書き出し</h3> <table> <tr><th>メニュー</th><th>できること</th></tr> - <tr><td>画像</td><td>PNGの大きさ(1〜4倍)、PNGの背景を透明にする、PNGを保存、クリップボードにコピー。</td></tr> + <tr><td>画像</td><td>大きさ(1〜4倍)、PNGの背景を透明にする、PNGを保存、JPGを保存(画質50〜100%)、クリップボードにコピー。JPGはPNGよりファイルが小さくなります。</td></tr> <tr><td>まんが</td><td>今の状態をコマとして追加し、列数・大きさを選んで、まんが(コマ割り)として書き出します。</td></tr> <tr><td>共有</td><td>画像をシェア、Xで投稿、Facebookでシェア、この見た目のリンクをコピー。</td></tr> <tr><td>設定</td><td>設定を保存(JSON)/設定を読み込む。</td></tr> </table> -<p class="note">画像の保存は現在PNGのみですが、JPG形式での保存にも対応する予定です。</p> +<p class="note">画像はPNGとJPGで保存できます。JPGは画質(50〜100%)を選べて、PNGよりファイルが小さくなります(写真の背景を入れた絵に向いています)。JPGは透明にできないので、背景は「紙の色」で塗られます。</p> <p class="note">「元に戻す」「やり直す」は、どのタブを選んでいてもパネル上部に表示されます。</p> <h2>5. もし問題がある場合</h2> diff --git a/public/bluebey-studio/index.html b/public/bluebey-studio/index.html index f47a7d1..20dfc09 100644 --- a/public/bluebey-studio/index.html +++ b/public/bluebey-studio/index.html @@ -166,7 +166,7 @@ if (window.matchMedia('(max-width: 768px), (max-height: 500px) and (pointer: coa <li>「見た目」タブの「スタイル」で リアル/フラット/線画 を切り替えます。</li> <li>線画は輪郭線+白ぬり。線の太さと色、紙の色を変えられます。</li> <li>「シーン」タブの「画面・光」で「正投影」にすると遠近のゆがみがなくなり、図面のような絵になります。</li> - <li>背景は、「シーン」タブの「背景」で透明・単色・写真などから選べます。<code>PNG保存</code>は透明のまま保存できます。</li> + <li>背景は、「シーン」タブの「背景」で透明・単色・写真などから選べます。<code>PNG保存</code>は透明のまま保存できます。JPG(書き出しタブ)はPNGより小さくできます。</li> <li>自分の写真を背景にしたときは、「隠すマスクを作る」で写真の中の物(木・建物など)をタップすると、その物の裏にぶるべーを隠せます。</li> </ul> @@ -194,7 +194,7 @@ if (window.matchMedia('(max-width: 768px), (max-height: 500px) and (pointer: coa <div class="start-sheet" role="dialog" aria-modal="true" aria-labelledby="start-title"> <h2 id="start-title">ご利用の前に</h2> <p>このスタジオは、市政・政治活動とは関係のない個人的な制作物です。</p> - <p>このスタジオで作成した画像などは、SNS への投稿を含め、自由に使っていただけます。ただし、商用利用やそのほか特殊な使い方をされる場合は、小平市の確認が必要ですので、このサイトの<a href="/contact/" target="_blank" rel="noopener">お問い合わせ</a>からご連絡ください。</p> + <p>このスタジオで作成した画像などは、SNS への投稿を含め、保存した画像を個人やご家族、友人などで楽しむ場合は、自由に使っていただけます。ただし、チラシ・ポスターなどのお知らせとして、多くの方に配布する場合は、小平市の確認が必要です。商用利用やそのほか特殊な使い方をされる場合も同様ですので、このサイトの<a href="/contact/" target="_blank" rel="noopener">お問い合わせ</a>からご連絡ください。</p> <p>次のような使い方はご遠慮ください。</p> <ul> <li>公序良俗に反する目的での利用</li> diff --git a/public/bluebey-studio/src/main.js b/public/bluebey-studio/src/main.js index 57f0140..fcee21d 100644 --- a/public/bluebey-studio/src/main.js +++ b/public/bluebey-studio/src/main.js @@ -1317,6 +1317,7 @@ async function init() { syncPanel: () => app.panel?.sync(), imageCanvas: (options) => captureImage(options), savePNG: (options = {}) => savePNG(options), + saveJPG: (options = {}) => saveJPG(options), copyPNG: () => copyPNG(), addGionStamp: (item) => addGionStamp(item), saveSettings: () => exporter.downloadText(JSON.stringify(state, null, 2), `bluebey-settings-${exporter.timestamp()}.json`), @@ -2060,6 +2061,30 @@ async function init() { toast(`PNGを書き出しました(${result.width}×${result.height})`); } + /** + * JPEG: the small-file export. JPEG has no alpha, so the picture is laid on the + * paper colour first - a transparent background would otherwise come out black. + * A photo backdrop is kept at the chosen scale/quality, which makes the file a + * fraction of the same PNG. + */ + async function saveJPG({ + scale = state.render.pngScale ?? 2, + quality = state.render.jpgQuality ?? 0.9, + } = {}) { + const result = await captureImage({ scale, transparent: false }); + const out = document.createElement('canvas'); + out.width = result.width; + out.height = result.height; + const ctx = out.getContext('2d'); + ctx.fillStyle = state.render.paper || '#ffffff'; + ctx.fillRect(0, 0, out.width, out.height); + ctx.drawImage(result.canvas, 0, 0); + const blob = await new Promise((resolve) => out.toBlob(resolve, 'image/jpeg', quality)); + exporter.downloadBlob(blob, `bluebey-${exporter.timestamp()}.jpg`); + toast(`JPGを書き出しました(${result.width}×${result.height}・画質${Math.round(quality * 100)}%)`); + return { blob, width: result.width, height: result.height, quality }; + } + /** Hide the gizmo and helpers so they never end up in an export. */ async function withHiddenHelpers(fn) { const wasVisible = rig.helper.visible; diff --git a/public/bluebey-studio/src/panel.js b/public/bluebey-studio/src/panel.js index db784cb..c798d42 100644 --- a/public/bluebey-studio/src/panel.js +++ b/public/bluebey-studio/src/panel.js @@ -2109,7 +2109,7 @@ export function buildPanel(app, root) { const exportSection = section(tabExport, '画像'); exportSection.add(segmented({ - label: 'PNGの大きさ', + label: '画像の大きさ', options: [ { value: '1', label: '1倍' }, { value: '2', label: '2倍' }, @@ -2122,9 +2122,17 @@ export function buildPanel(app, root) { exportSection.add(buttons({ items: [ { id: 'png', label: 'PNGを保存', primary: true, onClick: () => app.actions.savePNG() }, + { id: 'jpg', label: 'JPGを保存', onClick: () => app.actions.saveJPG() }, { id: 'copy', label: 'クリップボードにコピー', onClick: () => app.actions.copyPNG() }, ], })); + const jpgQualitySlider = slider({ + label: 'JPGの画質', min: 0.5, max: 1, step: 0.01, value: 0.9, + format: (v) => `${Math.round(v * 100)}%`, + onInput: (v) => { state.render.jpgQuality = v; }, + }); + exportSection.add(jpgQualitySlider.el); + exportSection.add(hint('JPG は PNG よりファイルが小さくなります(写真の背景を入れた絵に向いています)。JPG は透明にできないので、背景は「紙の色」で塗られます。')); const transparentCheck = check({ label: 'PNGの背景を透明にする', value: false, onChange: (v) => { state.render.pngTransparent = v; }, @@ -2377,6 +2385,7 @@ export function buildPanel(app, root) { outlinePixelsSlider.set(state.render.outlinePixels ?? 2); leafBodyLineCheck.set(state.render.leafBodyLine !== false); transparentCheck.set(state.render.pngTransparent); + jpgQualitySlider.set(state.render.jpgQuality ?? 0.9); lightPad.set({ x: state.render.lightAzimuth / 180, y: Math.max(0, (state.render.lightElevation - 5) / 80), diff --git a/public/bluebey-studio/src/presets.js b/public/bluebey-studio/src/presets.js index d9ed3e4..fd4d467 100644 --- a/public/bluebey-studio/src/presets.js +++ b/public/bluebey-studio/src/presets.js @@ -89,6 +89,7 @@ export function defaultState() { contactBlob: false, pngScale: 2, pngTransparent: false, + jpgQuality: 0.9, // 0.5..1, used by 「JPGを保存」 svgWidth: 2048, lightAzimuth: -38, lightElevation: 40, diff --git a/public/bluebey/guide.pdf b/public/bluebey/guide.pdf Binary files differindex 6d7153d..acafdbb 100644 --- a/public/bluebey/guide.pdf +++ b/public/bluebey/guide.pdf |
