作った。
いつもイラスト描いてくれてる友達に、Chrome拡張機能作成にハマってる俺が無理に要望を引き出したところ出てきた機能。
画像をウェブ上でダウンロードする際にWebPとかでダウンロードされるのが意外とうざいらしい話。言われてみると確かに。。。
実装
変換時に外部のライブラリを使おうかと頑張ってみたけどなんか難しくて(あとめんどくさくて)諦めました。
なので素のJavaScriptでなんとかしてみた。
やり方は単純、画像をcanvasに描画してダウンロードするというもの。
const res = await fetch(location.href);
const blob = await res.blob();
const img = new Image();
img.src = URL.createObjectURL(blob);
img.onload = async () => {
const width = img.width;
const height = img.height;
const canvas = document.createElement("canvas");
canvas.width = width;
canvas.height = height;
try {
const ctx = canvas.getContext("2d");
ctx!.drawImage(img, 0, 0, width, height);
const dataURL = canvas.toDataURL("image/png");
const blob = await (await fetch(dataURL)).blob();
const link = document.createElement("a");
link.href = URL.createObjectURL(blob);
link.download = "image.png";
link.click();
} catch (e) {
/* empty */
}
};
コードの全貌はこちらから
fetch
で開いているページのURLを取得して、こねこねしてcanvas
にぶち込んでcanvas.toDataURL("image/png")
でなんとかかんとか。
try catch
しているのは、svg
で実行された時対策です。svg
はちとめんどそう、未来の自分に期待。
現在変換可能な拡張子は、PNG
JPEG
WebP
の3つ。これ以外の拡張子はChromeでは変換不可能なので、現在は未対応。FireFoxはBMP
もいけるらしい。FireFox用は作ってないですが。
他の拡張子はサーバーに送ってこねこねくねくねしないとだめなのかな。サーバーで動かすとなると金かかるので、考えもの💸
再変換はしないはず
そもそも変換が必要ない場合はそのままダウンロードするようにしています。
例えばJPG
のものをJPG
としてダウンロードすることで画像が劣化するみたいなことは防げてるはずです。えらいですね。
const byteArray = new Uint8Array(await res.clone().arrayBuffer());
let currentImageType = "unknown";
if (byteArray[0] === 255 && byteArray[1] === 216) {
currentImageType = "image/jpeg";
} else if (byteArray[0] === 137 && byteArray[1] === 80 && byteArray[2] === 78 && byteArray[3] === 71) {
currentImageType = "image/png";
} else if (
byteArray[0] === 82 &&
byteArray[1] === 73 &&
byteArray[2] === 70 &&
byteArray[3] === 70 &&
byteArray[8] === 87 &&
byteArray[9] === 69 &&
byteArray[10] === 66 &&
byteArray[11] === 80
) {
currentImageType = "image/webp";
}
こんな感じでファイル名とかではなく中身で判断してるので、正しいはず...正しいよね...?
良ければ使ってみてください。