Chrome拡張でPixiv作品を効率的に保存する「Pixiv Downloader」を作った話
はじめに
創作活動のプラットフォームとして圧倒的な支持を集めている「Pixiv」。
イラスト・漫画・小説を自由に投稿・閲覧できるこのサービスは、プロ・アマ問わずクリエイターやファンにとって欠かせない存在です。
しかし、Pixivの作品は「見る」ことには優れていても、「保存」にはやや不便さがあると感じたことはないでしょうか?
こんな悩み、ありませんか?
- 気に入った作品を保存したいが、1ページずつ手動で保存するのが面倒…
- 複数ページにわたる漫画を一括で保存したい…
- 小説作品をコピー&ペーストで保存すると整形が崩れてしまう…
- 作品タイトルやIDをもとに整理したいが、保存ファイル名がバラバラ…
その悩み、「Pixiv Downloader」で解決できます
Pixiv Downloaderは、Pixiv上のあらゆる作品をワンクリックで効率的に保存できるChrome拡張機能です。
連作・シリーズ投稿も一括保存可能。小説もPDFとして綺麗に保存されます。
「好きな作品を、整理して、安心して、自分の手元に残しておける」── そんな当たり前の体験を実現するためのツールです。
- Chrome ウェブストア: Pixiv Downloader
- ホームページ: HP
なぜChrome拡張として開発したのか
1. シームレスなユーザー体験
Chrome拡張の最大のメリットは、Pixivのサイトに直接機能を追加できることです。ユーザーは別のツールを起動したり、URLをコピー&ペーストしたりする必要がありません。作品ページに自動的に表示されるダウンロードボタンをクリックするだけで、すぐに保存が開始されます。
2. クロスオリジンリソース共有(CORS)の回避
Webアプリケーションから直接Pixivの画像にアクセスしようとすると、CORSポリシーによってブロックされます。Chrome拡張では、適切なパーミッションを設定することで、この制限を回避できます。
"host_permissions": [
"*://www.pixiv.net/*",
"*://*.pximg.net/*"
]
3. バックグラウンド処理
Service Workerを使用することで、ユーザーがタブを閉じても、バックグラウンドでダウンロード処理を継続できます。大量の作品を一括ダウンロードする際に特に有効です。
技術スタック
フロントエンド
- Vue 3 + TypeScript: リアクティブなUIとタイプセーフティを実現
- Pinia: 状態管理(ダウンロード進捗、ユーザー設定など)
- Tailwind CSS: 効率的なスタイリング
- Font Awesome: アイコン表示
PDF生成
- pdf-lib: PDFの生成と操作
- jsPDF: 補助的なPDF機能
- Canvas API: 画像の前処理
ビルドツール
- Vite: 高速な開発環境とビルド
- @crxjs/vite-plugin: Chrome拡張開発の効率化
その他の主要ライブラリ
- axios: HTTP通信
- cheerio: HTML解析(作品情報の抽出)
- webextension-polyfill: ブラウザAPI の統一化
アーキテクチャの特徴
1. コンテンツスクリプトとService Workerの分離
// content-scripts/main.ts
// DOMの操作とUI表示を担当
const app = createApp(App)
app.mount(shadowRoot)
// background.ts
// ダウンロード処理とデータ管理を担当
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
// ダウンロードロジック
})
2. Manifest V3対応
Chrome拡張の新しい仕様であるManifest V3に準拠。セキュリティとパフォーマンスが向上しています。
export default defineManifest(async (env) => ({
manifest_version: 3,
name: "Pixiv Downloader",
permissions: [
"identity",
"storage",
"webRequest",
"declarativeNetRequestWithHostAccess"
],
background: {
service_worker: './src/background.ts',
type: "module"
}
}))
3. Shadow DOMの活用
コンテンツスクリプトで挿入するUIはShadow DOMを使用。Pixivのスタイルとの競合を避け、独立したスタイル環境を確保しています。
const shadowRoot = container.attachShadow({ mode: 'closed' })
主な技術的チャレンジと解決策
1. 大量画像の効率的な処理
複数ページの漫画作品では、数十枚の高解像度画像を処理する必要があります。メモリ効率を考慮し、以下のアプローチを採用:
- 画像の逐次処理(並列度の制御)
- Canvas APIを使用した画像の最適化
- 不要なデータの早期解放
2. 日本語フォントの埋め込み
PDFに日本語テキストを含める場合、フォントの埋め込みが必要です。
// フォントファイルをアセットとして含める
import fontUrl from '@assets/fonts/NotoSansSC-VariableFont_wght.ttf'
// pdf-libでカスタムフォントを登録
const font = await pdfDoc.embedFont(fontBytes)
3. 動的なファイル名生成
ユーザーが自由にファイル名テンプレートを設定できる機能を実装。作品情報から動的に変数を展開します。
const template = "{title}_{author}_{date}"
const filename = template
.replace("{title}", workTitle)
.replace("{author}", authorName)
.replace("{date}", downloadDate)
パフォーマンス最適化
1. Viteによる開発体験の向上
- HMR(Hot Module Replacement)による即座の反映
- 効率的なバンドルとコード分割
- TypeScriptの高速トランスパイル
2. ストレージの効率的な利用
Chrome拡張のStorage APIを活用し、設定やダウンロード履歴を効率的に管理:
// useStorageフックでリアクティブなストレージ管理
const settings = useStorage('settings', defaultSettings)
セキュリティ対策
1. 最小権限の原則
必要最小限のパーミッションのみを要求。ユーザーのプライバシーを保護します。
2. Content Security Policy
XSS攻撃を防ぐため、厳格なCSPを設定。
3. OAuth 2.0認証
プレミアム機能ではGoogle OAuth 2.0を使用し、安全な認証を実現。
oauth2: {
client_id: process.env.VUE_APP_OAUTH2_CLIENT_ID,
scopes: [
'https://www.googleapis.com/auth/userinfo.email',
'https://www.googleapis.com/auth/userinfo.profile'
]
}
今後の展望
技術的な改善点
- Web Workerの活用: 重い処理をさらに分離し、UIの応答性を向上
- IndexedDBの活用: 一時的なキャッシュによるパフォーマンス向上
- WebAssemblyの導入: 画像処理の高速化
機能拡張
- より高度なフィルタリング機能
- カスタマイズ可能なPDFレイアウト
- 他のイラスト投稿サイトへの対応
まとめ
Pixiv Downloaderは、モダンなWeb技術スタックを活用して、ユーザーに快適な作品保存体験を提供するChrome拡張です。Vue 3とTypeScriptによる堅牢な実装、Viteによる高速な開発環境、そしてManifest V3準拠による将来性を兼ね備えています。
技術的な詳細について質問がある方や、開発に興味がある方は、ぜひコメントでお知らせください。
リンク
開発者向けの技術的な内容を中心に記事を構成しました。実装の詳細に立ち入りすぎず、Chrome拡張開発の特徴や使用技術スタックの概要を説明しています。