iOS Safari で canvas の画像を保存させる(download 属性 / Web Share / 長押し)

一言まとめ

iOS では `<a download>` が Blob URL で動かない不具合が繰り返し出ており、ホーム画面追加の standalone PWA では利用者を閉じ込めるバグも記録されている。一番手は `navigator.canShare({ files })` で分岐する Web Share API Level 2、次に新規タブで開いて長押し保存、`<a download>` は Android / デスクトップ向けの補助に回す。

作成 · 更新 · #ios#safari#pwa#canvas#web-share
目次 9 sections
  1. 01 <a download> の信頼性
  2. 02 Web Share API Level 2(navigator.share({ files }))
  3. 03 長押し保存のフォールバック
  4. 04 フォールバック順
  5. 05 canvas 再エンコードで EXIF / GPS が落ちる
  6. 06 対応状況の確認(2026-06)
  7. 07 未確認事項
  8. 08 関連
  9. 09 更新履歴

調査時点: 2026-06。公開プロジェクト frost-mosaic(なぞった所をモザイクにする PWA)で、加工した canvas を iPhone に保存させる方法を調べたもの。iOS のバージョンで挙動が変わる領域なので、最終確認は実機で行う。

<a download> の信頼性#

  • Safari のブラウザタブ: Blob URL のダウンロード不具合が Safari 12 時代から報告され続けている(WebKit Bug #190351)。2018 年に一度 FIXED になったが Safari 14 でも再現報告があり、iOS 17.4.1 で Blob URL が一時的に動かなくなり 17.5 beta で直った例もある
  • ホーム画面追加の standalone モード: WebKit Bug #236943 “File download link traps user in PWA” が記録されている。ダウンロードリンクをタップすると PWA 内に閉じ込められ、戻れない
  • File System Access API は iOS Safari 未対応

standalone PWA では <a download> を主な手段にしない。

Web Share API Level 2(navigator.share({ files }))#

iOS 15 以降の Safari でファイル共有に対応し、standalone モードでも使える。canvas から得た Blob を File に包んで渡すと、iOS の共有シートから「画像を保存」が選べる。

async function saveCanvas(canvas: HTMLCanvasElement): Promise<void> {
const blob = await new Promise<Blob | null>((r) => canvas.toBlob(r, "image/png"));
if (!blob) throw new Error("toBlob failed");
const file = new File([blob], "image.png", { type: "image/png" });
if (navigator.canShare?.({ files: [file] })) {
// iOS Safari では title を付けると画像ではなくテキストとして共有される報告があるため省く
await navigator.share({ files: [file] });
return;
}
// フォールバックへ
}

条件は 3 つ。HTTPS 上であること、navigator.canShare({ files }) で事前確認すること、click などのユーザー操作(transient activation)から呼ぶこと。

長押し保存のフォールバック#

window.open() で canvas を data URL として新規タブに開き、「画像を長押しして保存」と手順を文字で案内する。Web Share が使えない古い iOS や、共有シートを閉じてしまった場合の受け皿になる。

フォールバック順#

  1. navigator.canShare({ files }) が true → Web Share API Level 2 で共有シートへ
  2. 新規タブで開いて長押し保存を案内
  3. <a download>(Android / デスクトップ向けの主な手段、iOS では補助)

iOS 以外では 3 を先に試してよい。分岐は UA 判定ではなく canShare の結果で行う。

canvas 再エンコードで EXIF / GPS が落ちる#

Canvas API はピクセルデータだけを扱うため、drawImage() で描いた時点で EXIF・IPTC・XMP・GPS などのメタデータは捨てられる。canvas.toBlob("image/png") の出力には元画像のメタデータが含まれない。多くのオンライン EXIF 除去ツールがこの挙動を意図的に使っており、「保存時に位置情報が落ちる」というプライバシー説明の根拠になる。

対応状況の確認(2026-06)#

  • canvas.toBlob(): Baseline Widely Available。iOS Safari でも動く
  • imageSmoothingEnabled: Baseline Widely Available(2017 年以降)。-webkit- などのベンダープレフィックスは不要。古い記事のコードを写すと冗長なプレフィックスが残る
  • モザイク(ピクセル化)は「縮小 → imageSmoothingEnabled = false → 拡大」で実装できる。ブロックサイズはプレビューで調整できるようにする

未確認事項#

  • Safari 18 / iOS 18 で download 属性が standalone PWA で正式対応したかの一次確認
  • touchmove のスロットリングや passive: false の要否など、iOS Safari でのフリーハンド描画パスの精度に関する既知問題

関連#

更新履歴#

  • 2026-06-15: 初版(ローカル調査ノート)
  • 2026-10-17: Wiki へ移植、概念ページとして再構成

出典

  1. https://bugs.webkit.org/show_bug.cgi?id=190351
  2. https://developer.apple.com/forums/thread/751063
  3. https://developer.apple.com/forums/thread/665812
  4. https://developer.mozilla.org/en-US/docs/Web/API/Navigator/share
  5. https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toBlob
  6. https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/imageSmoothingEnabled
  7. https://whatwg.whatwg.narkive.com/390yGl2I/add-exif-metadata-support-in-canvas-toblob

同じトピック — Web