[{"data":1,"prerenderedAt":566},["ShallowReactive",2],{"blog-tag-ja-tech":3},[4,332],{"id":5,"title":6,"author":7,"body":8,"category":314,"coverImage":315,"description":316,"draft":317,"extension":318,"locale":319,"meta":320,"navigation":321,"noindex":317,"path":322,"publishedAt":323,"seo":324,"slug":325,"stem":326,"tags":327,"updatedAt":323,"__hash__":331},"blog\u002Fblog\u002Fbrowser-only-limits.md","ブラウザ内でファイル処理は「どこまで」できるか — 2026 年の現在地","Zerosend Editorial",{"type":9,"value":10,"toc":281},"minimark",[11,15,20,25,37,40,43,46,50,62,66,73,77,88,92,111,114,118,121,125,131,135,138,142,146,153,157,164,168,171,175,179,189,193,200,204,215,225,228,232,248,251,254,261,270],[12,13,14],"p",{},"「ファイルをサーバーに送らずに処理する」は、2026 年のブラウザでかなりの範囲が実現可能です。ただし万能ではありません。Zerosend が採用している技術と、その限界を正直に整理します。",[16,17,19],"h2",{"id":18},"なぜブラウザだけで処理する選択を採るのか","なぜ「ブラウザだけで処理する」選択を採るのか",[21,22,24],"h3",{"id":23},"送らないので漏れないという直球の設計","送らないので漏れない、という直球の設計",[12,26,27,28,32,33,36],{},"サーバー送信を伴わない構造そのものが、",[29,30,31],"strong",{},"個人情報漏洩・誤操作・第三者共有"," のリスクを原理的にゼロにします。「漏れない仕組み」を語るより、",[29,34,35],{},"漏れる場所をなくす","ほうが検証しやすい設計です。",[21,38,39],{"id":39},"設定や権限に依存しない単純さ",[12,41,42],{},"サーバー側で暗号化キーを守る \u002F ログを消す \u002F バックアップから除外する、という細かい運用は継続的な手間がかかります。ブラウザ内で完結するなら、そもそもその運用自体が発生しません。",[16,44,45],{"id":45},"使っている技術スタック",[21,47,49],{"id":48},"canvas-api-画像の基礎処理","Canvas API — 画像の基礎処理",[12,51,52,53,57,58,61],{},"2D 描画と画像ピクセル操作の標準 API。Zerosend の画像圧縮・リサイズ・形式変換はすべて Canvas 経由です。",[54,55,56],"code",{},"drawImage()"," で任意の描画、",[54,59,60],{},"toBlob()"," で指定フォーマットに書き出せます。",[21,63,65],{"id":64},"web-worker-メインスレッドを止めない","Web Worker — メインスレッドを止めない",[12,67,68,69,72],{},"重い処理をメインスレッドで回すと UI がフリーズします。Web Worker で別スレッドに逃がすことでスムーズな UX を維持します。",[54,70,71],{},"browser-image-compression"," のように Worker を内包しているライブラリは、そのまま使うだけでメインスレッドを解放してくれます。",[21,74,76],{"id":75},"webassembly-ffmpeg-pdf-系ライブラリの移植","WebAssembly — ffmpeg \u002F pdf 系ライブラリの移植",[12,78,79,80,83,84,87],{},"C \u002F C++ で書かれたネイティブライブラリを WASM 化することで、ブラウザで直接実行できます。Zerosend では ",[29,81,82],{},"ffmpeg.wasm"," (動画・音声) と ",[29,85,86],{},"pdfjs-dist"," (PDF レンダリング) が WASM ベースです。",[21,89,91],{"id":90},"file-system-access-api-blob-入出力","File System Access API \u002F Blob — 入出力",[12,93,94,95,98,99,102,103,106,107,110],{},"モダンブラウザは ",[54,96,97],{},"showOpenFilePicker()"," \u002F ",[54,100,101],{},"showSaveFilePicker()"," で OS のファイル選択ダイアログを呼べます。非対応の環境でも ",[54,104,105],{},"\u003Cinput type=\"file\">"," + ",[54,108,109],{},"Blob + URL.createObjectURL"," でダウンロードできるため、互換性の最低ラインは広いです。",[16,112,113],{"id":113},"できること",[21,115,117],{"id":116},"数-mb-数十-mb-のファイル処理","数 MB 〜数十 MB のファイル処理",[12,119,120],{},"現代のブラウザは 100MB 級のファイルでも (メモリ次第で) 安定して扱えます。JPG\u002FPNG 画像の圧縮・リサイズ・一括 ZIP 生成は問題なく動作します。",[21,122,124],{"id":123},"バッチ処理-zip-生成を含む","バッチ処理 (ZIP 生成を含む)",[12,126,127,130],{},[54,128,129],{},"jszip"," を使えば複数ファイルの圧縮まとめもブラウザ内で完結します。100 ファイル程度の一括処理は実用範囲です。",[21,132,134],{"id":133},"逆圧縮形式変換","逆圧縮・形式変換",[12,136,137],{},"JPG → WebP、HEIC → JPG、PDF → PNG、MP4 → GIF などの変換は、すべてブラウザ内で実行できます。",[16,139,141],{"id":140},"苦手なことできないこと","苦手なこと・できないこと",[21,143,145],{"id":144},"数-gb-級の動画処理はメモリが持たない","数 GB 級の動画処理はメモリが持たない",[12,147,148,149,152],{},"ブラウザのプロセスメモリ上限はだいたい 2〜4 GB 程度。それ以上の動画をまるごと処理するのは困難です。",[29,150,151],{},"1 GB を超える動画はデスクトップツール"," (ffmpeg CLI 等) のほうが安定します。",[21,154,156],{"id":155},"機械学習推論は遅い-onnx-runtime-web-は軽量モデル限定","機械学習推論は遅い (ONNX Runtime Web は軽量モデル限定)",[12,158,159,160,163],{},"ONNX Runtime Web や TensorFlow.js で推論は可能ですが、",[29,161,162],{},"数 GB 級のモデル","はブラウザで回すとかなり遅く、UX が実用的ではありません。軽量モデル (数百 MB) に限定するか、サーバー推論と割り切るのが現実的です。",[21,165,167],{"id":166},"os-ネイティブ機能への直接アクセス","OS ネイティブ機能への直接アクセス",[12,169,170],{},"ブラウザはサンドボックス内で動くので、OS のファイルシステム全体を書き換えるような処理・プロセス起動はできません。セキュリティの観点からも妥当な制約です。",[16,172,174],{"id":173},"zerosend-での実装のコツ-開発者向け","Zerosend での実装のコツ (開発者向け)",[21,176,178],{"id":177},"ドメイン層を-ui-から分離する","ドメイン層を UI から分離する",[12,180,181,184,185,188],{},[54,182,183],{},"domain\u002Fprocessors\u002F"," 配下に",[29,186,187],{},"純粋関数","を置き、Vue \u002F DOM API に依存させない設計にしています。テストが書きやすく、将来的に CLI 化・API 化もしやすくなります。",[21,190,192],{"id":191},"web-worker-に重い処理を分離する判断基準","Web Worker に重い処理を分離する判断基準",[12,194,195,196,199],{},"目安は ",[29,197,198],{},"100 ms を超える処理はすべて Worker","。メインスレッドがそれ以上ブロックすると、ユーザー操作への応答 (クリック・スクロール) が目に見えて遅延します。",[21,201,203],{"id":202},"csp-を破らずに-wasm-を読み込む","CSP を破らずに WASM を読み込む",[12,205,206,207,210,211,214],{},"CSP (Content Security Policy) に ",[54,208,209],{},"wasm-unsafe-eval"," を追加する必要があります。Zerosend では meta と ",[54,212,213],{},"_headers"," の両方に設定し、本番でも正しく動作することを確認しています。",[216,217,222],"pre",{"className":218,"code":220,"language":221},[219],"language-text","Content-Security-Policy: script-src 'self' 'wasm-unsafe-eval'\n","text",[54,223,220],{"__ignoreMap":224},"",[16,226,227],{"id":227},"今後の展望",[21,229,231],{"id":230},"webgpu-opfs-の成熟","WebGPU \u002F OPFS の成熟",[233,234,235,242],"ul",{},[236,237,238,241],"li",{},[29,239,240],{},"WebGPU",": GPU を直接使える API。機械学習推論や 3D レンダリングで大きく速度改善が見込まれます",[236,243,244,247],{},[29,245,246],{},"OPFS (Origin Private File System)",": Origin ごとにブラウザが管理する高速ファイル領域。大容量ファイル処理時の中間ストレージに使えます",[12,249,250],{},"これらが広く使える前提になれば、現状「苦手」としている領域の多くがブラウザだけで片付くようになります。",[16,252,253],{"id":253},"まとめ",[12,255,256,257,260],{},"ブラウザ内ファイル処理は ",[29,258,259],{},"Canvas \u002F Web Worker \u002F WebAssembly \u002F File System Access API"," の組み合わせで、日常的な軽作業のほぼ全域をカバーできます。GB 級や重い ML 推論は依然として苦手ですが、Zerosend が対象とする画像・PDF・音声・短い動画の範囲では実用レベルです。",[12,262,263,264,269],{},"この設計の結果、",[265,266,268],"a",{"href":267},"\u002F#tools","Zerosend のツール群"," はサーバーに何も送らずに動作し、DevTools で自ら検証できる透明性を持っています。",[12,271,272,273,98,277],{},"関連: ",[265,274,276],{"href":275},"\u002Fblog\u002Fwhy-browser-only","なぜ Zerosend はブラウザ内処理にこだわるのか",[265,278,280],{"href":279},"\u002Fguide\u002Fprivacy-online-tools","ピラー記事",{"title":224,"searchDepth":282,"depth":282,"links":283},2,[284,289,295,300,305,310,313],{"id":18,"depth":282,"text":19,"children":285},[286,288],{"id":23,"depth":287,"text":24},3,{"id":39,"depth":287,"text":39},{"id":45,"depth":282,"text":45,"children":290},[291,292,293,294],{"id":48,"depth":287,"text":49},{"id":64,"depth":287,"text":65},{"id":75,"depth":287,"text":76},{"id":90,"depth":287,"text":91},{"id":113,"depth":282,"text":113,"children":296},[297,298,299],{"id":116,"depth":287,"text":117},{"id":123,"depth":287,"text":124},{"id":133,"depth":287,"text":134},{"id":140,"depth":282,"text":141,"children":301},[302,303,304],{"id":144,"depth":287,"text":145},{"id":155,"depth":287,"text":156},{"id":166,"depth":287,"text":167},{"id":173,"depth":282,"text":174,"children":306},[307,308,309],{"id":177,"depth":287,"text":178},{"id":191,"depth":287,"text":192},{"id":202,"depth":287,"text":203},{"id":227,"depth":282,"text":227,"children":311},[312],{"id":230,"depth":287,"text":231},{"id":253,"depth":282,"text":253},"tech",null,"ブラウザだけで画像・PDF・動画を扱うには、どんな技術を使いどこまでできるのか。Canvas \u002F Web Worker \u002F WebAssembly \u002F File System Access API の採用ポイントと、率直な限界を整理します。",false,"md","ja",{},true,"\u002Fblog\u002Fbrowser-only-limits","2026-04-19",{"title":6,"description":316},"browser-only-limits","blog\u002Fbrowser-only-limits",[328,329,330],"WebAssembly","ブラウザ","技術解説","DVMRpha441VjgXVwUg-Ky9ljmdcZEo-shW86ze3x7Uo",{"id":333,"title":334,"author":7,"body":335,"category":315,"coverImage":315,"description":557,"draft":317,"extension":318,"locale":319,"meta":558,"navigation":321,"noindex":317,"path":559,"publishedAt":323,"seo":560,"slug":561,"stem":562,"tags":563,"updatedAt":323,"__hash__":565},"blog\u002Fblog\u002Ffavicon-generator-intro.md","ブラウザだけで作るファビコン一式 — \u002Ftools\u002Ffavicon-generator の舞台裏",{"type":9,"value":336,"toc":546},[337,340,343,346,349,356,359,362,411,414,450,454,461,464,484,491,494,506,512,515,518,521,537,539],[16,338,339],{"id":339},"ファビコンが必要な理由",[12,341,342],{},"ファビコンは、ブラウザのタブやブックマーク一覧でサイトを識別する小さなアイコンです。スマートフォンのホーム画面に「追加」したときに表示されるアイコン (apple-touch-icon \u002F PWA アイコン) も、ファビコン一式の一部です。「ファビコンがない」「サイズが揃っていない」といった状態は、ユーザーの信頼感を下げ、PWA 対応の妨げにもなります。",[16,344,345],{"id":345},"背景",[12,347,348],{},"サイトのファビコンを更新する作業は、新規サイトでも既存サイトのリブランディングでも発生します。ロゴ画像 1 枚から必要なアイコンセットを揃えるのは地味に手間のかかる工程です。",[12,350,351,355],{},[265,352,354],{"href":353},"\u002Ftools\u002Ffavicon-generator","Zerosend のファビコン生成ツール"," は、この工程をブラウザ内で完結させます。ロゴ画像を外部に送らずに一式を作成できるので、NDA 下の受託案件や未公開のブランディング作業でも安心して使えます。",[16,357,358],{"id":358},"何が出力されるか",[12,360,361],{},"1 枚の画像 (PNG \u002F JPG \u002F WebP \u002F SVG) から次の 9 ファイルを生成し、ZIP で配布します。",[233,363,364,370,381,387,396,401],{},[236,365,366,369],{},[54,367,368],{},"favicon.ico"," — 16 \u002F 32 \u002F 48px のマルチサイズ ICO",[236,371,372,98,375,98,378],{},[54,373,374],{},"favicon-16.png",[54,376,377],{},"favicon-32.png",[54,379,380],{},"favicon-48.png",[236,382,383,386],{},[54,384,385],{},"apple-touch-icon.png"," (180×180)",[236,388,389,98,392,395],{},[54,390,391],{},"icon-192.png",[54,393,394],{},"icon-512.png"," (PWA)",[236,397,398],{},[54,399,400],{},"site.webmanifest",[236,402,403,406,407,410],{},[54,404,405],{},"snippet.html"," — ",[54,408,409],{},"\u003Chead>"," に貼り付ける link タグ",[16,412,413],{"id":413},"使い方ステップ",[415,416,417,423,433,439],"ol",{},[236,418,419,422],{},[29,420,421],{},"画像を準備する"," — 正方形の PNG \u002F JPG \u002F WebP \u002F SVG を用意。最低でも 512×512px 推奨",[236,424,425,406,428,432],{},[29,426,427],{},"ドロップする",[265,429,430],{"href":353},[54,431,353],{}," を開いてドラッグ&ドロップ",[236,434,435,438],{},[29,436,437],{},"ZIP をダウンロードする"," — ボタンを押すと 9 ファイルが入った ZIP が生成される",[236,440,441,406,444,446,447,449],{},[29,442,443],{},"HTML に貼り付ける",[54,445,405],{}," の内容をサイトの ",[54,448,409],{}," にコピーして完了",[16,451,453],{"id":452},"ico-を自前で書き出す","ICO を自前で書き出す",[12,455,456,457,460],{},"PNG は Canvas API で簡単に書き出せますが、ICO は少し工夫が必要です。とはいえ、Windows Vista 以降の ICO は ",[29,458,459],{},"PNG バイト列をそのまま埋め込める"," ため、意外と単純です。",[12,462,463],{},"構造:",[233,465,466,472,478],{},[236,467,468,471],{},[29,469,470],{},"ICONDIR"," (6 バイト): reserved \u002F type \u002F image count",[236,473,474,477],{},[29,475,476],{},"ICONDIRENTRY"," (16 バイト × 画像数): 幅 \u002F 高さ \u002F bpp \u002F サイズ \u002F オフセット",[236,479,480,483],{},[29,481,482],{},"画像データ",": PNG のバイト列を順に連結",[12,485,486,487,490],{},"依存ゼロで 30 行程度に収まります。",[54,488,489],{},"domain\u002Fprocessors\u002FfaviconGenerator.ts"," で実装を公開しています。",[16,492,493],{"id":493},"よくある質問",[12,495,496,499,500,502,503,505],{},[29,497,498],{},"Q. どのサイズが必要ですか？","\nA. 最低限は ",[54,501,368],{}," (16\u002F32px) と ",[54,504,385],{}," (180px) です。PWA 対応するなら 192px と 512px も必要です。本ツールはこれらをすべて一括生成します。",[12,507,508,511],{},[29,509,510],{},"Q. SVG のロゴから生成できますか？","\nA. はい。SVG を入力するとブラウザ側で各サイズにラスタライズしてから ICO \u002F PNG を生成します。",[16,513,514],{"id":514},"検証の楽しさ",[12,516,517],{},"作ったあとは DevTools の Network タブで確認できます。画像選択 → 生成 → ダウンロードの全てで、あなたのロゴが外に出ないことを自分で検証できます。",[16,519,520],{"id":520},"関連ツール",[233,522,523,530],{},[236,524,525,529],{},[265,526,528],{"href":527},"\u002Ftools\u002Fimage-compress","画像圧縮"," — 入力画像が大きすぎる場合、事前に軽量化",[236,531,532,536],{},[265,533,535],{"href":534},"\u002Ftools\u002Fimage-resize","画像リサイズ"," — 正方形にトリミングしてからファビコン生成すると精度が上がる",[16,538,253],{"id":253},[12,540,541,542,545],{},"1 枚の画像から ICO \u002F PNG \u002F apple-touch-icon \u002F manifest \u002F HTML スニペットを、あなたの端末だけで生成できます。",[265,543,544],{"href":353},"試してみてください","。",{"title":224,"searchDepth":282,"depth":282,"links":547},[548,549,550,551,552,553,554,555,556],{"id":339,"depth":282,"text":339},{"id":345,"depth":282,"text":345},{"id":358,"depth":282,"text":358},{"id":413,"depth":282,"text":413},{"id":452,"depth":282,"text":453},{"id":493,"depth":282,"text":493},{"id":514,"depth":282,"text":514},{"id":520,"depth":282,"text":520},{"id":253,"depth":282,"text":253},"1 枚の画像から ICO \u002F PNG \u002F apple-touch-icon \u002F site.webmanifest を生成するファビコン生成ツールを公開しました。ICO フォーマットを自前で書き出す実装のポイントを紹介します。",{},"\u002Fblog\u002Ffavicon-generator-intro",{"title":334,"description":557},"favicon-generator-intro","blog\u002Ffavicon-generator-intro",[564,330],"ツール","3t3z-Zm-s-OgpewxhvXXeVAxzDosMQLq8XTZRneQGs4",1777617517651]