このブログはGoogleのブログサービス、Bloggerを使っています。無料で広告が出ず、アドセンスOKという神対応のようなブログサービスですが、レスポンスが遅かったり、機能が少ない、情報も少ないなどデメリットもあります。
Bloggerで画像を挿入した際、スマホなどモバイル端末で画像の表示が粗くなってしまうことに気づいたので原因と対応方法を記事にしてみます。
前提条件と利用するもの
前提条件として、Googleのブログサービス、Bloggerを利用しているものとします。
Python3のライブラリ、BeautifulSoup4を使い画像のURLを変更します。
画像挿入時に作成されるHTML
例えば、Bloggerで画像を「中サイズ」挿入した際、HTMLは下記のようになります。
<img alt="" border="0" width="320"
data-original-height="427"
data-original-width="640"
src="https://blogger.googleusercontent.com/
img/a/AVvXsEgP_Oc9HB9maKwSYsZKg60Gt6YZGC
tnYwjoHXbnfLtN-2n7Sp3unjVVNKXt1n_1
ZZB1s3uX69wlgNk6IVvU2tIm5VgpiGG_f
Q0aASgGp2dqBqun35fBtya5kBDiSyeUwn
8R-uO9atA7DH-H7ei2fNzZD8F3ZPh3C
m-pRm6SBA1mWD1MI1l4Bh8VTt3g
=s320"/>
(srcの中身が長いので改行しています)ここで注目するのは、width="320"
とsrc
タグの長い文字列の最後、s=320
、そしてdata-original-width
です。縦長の画像の場合は、widthのところがheightになっていると思います。
width
はもちろん画像の表示ピクセル幅です。
src
タグのs=320
は、画像自体のピクセル幅です。Bloggerは、アップロードした画像そのままの大きさではなく、ここで指定したサイズにリサイズします。s
の意味は、長辺のサイズが指定した大きさになり、w
だと幅、h
は高さが指定され、c
がつくとトリミングされたりします。ここではs
で長辺を指定したものとして話を進めます。
少し古い記事だと、src
タグの中の末尾のs=320
の代わりに、途中に/s320/
という形になっています。
モバイルで画像の解像度が低い理由
さて、s=320
で320ピクセルにリサイズされた画像を、width=320
を指定し320ピクセルで表示したので何も問題無いように思えます。実際、PCで表示した場合はきれいに表示されます。
問題はモバイルの場合です。最近のモバイル端末は画面が小さいわりに解像度が高いため、320ピクセルの画像を320ピクセルで表示すると端末上で非常に小さな画像になってしまいます。そこで、HTMLやCSSでのピクセル値と、実際の画面のピクセル値が異なり、端末上の640ピクセルを使って320ピクセルの画像を表示したりします。この場合、「ピクセル密度は2」と言います。
ということで、ピクセル密度2のモバイル端末を使っている場合、HTMLのimg
タグでwidth=320
とした場合、実際には640ピクセル分の幅が確保されます。そこにsrc
属性でs=320
、すなわち320ピクセルの画像を用意すると2倍に引き伸ばされるため解像感の足りない画像になってしまします。
下が320ピクセルの画像をwidth=320
で表示した例です。
次に640ピクセルの画像をwidth=320
で表示した例です。PCでは違いがわからないと思います。モバイル端末では上の画像より芝や木などが細かく表示されているのがわかるでしょうか。
imgタグで複数の解像度を指定する
では、解像度2倍の画像を用意するには、単純にwidth=320
のsrc
に640ピクセルの画像を用意すればよいですが、これだとPC、すなわちピクセル密度1の端末で見る場合には無駄に大きな画像を読み込むことになります。
imgタグで複数の解像度の画像を用意し、切り替えることができます。書式は下記のようにsrcset
属性を使います。(他にもpicture
タグを使うなどやり方があります)
<img src="ピクセル密度1の画像"
srcset="ピクセル密度1の画像 1x,
ピクセル密度2の画像 2x">
もうおわかりですね、ピクセル密度1の画像には、Bloggerで普通に挿入した画像のURLを入れます(中サイズだと、320ピクセルで、URLの最後が=s320
で終わります。)
ピクセル密度2の画像は、ピクセル密度1の画像のURLの最後=s320
を=s640
に書き換えればOKです。
PythonのBeautifulSoupでタグを書き換える
いきなりソースコードです。下記を例えばimg-srcset.py
などの名前で保存します。Bloggerの記事を画像を入れて書き終えたら、メモ帳などにコピペし同じフォルダにindex.html
の名前で保存します。img-srcset.py
を実行するとsrcset
にピクセル密度2の画像URLが追加されたout.html
ができるのでこれをまたBloggerにコピペします。
自分で実際に使っているコードですが、うまく行かなかった場合はindex.html
に変更前の記事が残っているので戻してください。
from bs4 import BeautifulSoup
import sys
= BeautifulSoup(open("index.html","r",encoding='utf-8'),'lxml')
soup = soup.find_all('img')
imgs
for imgtag in imgs:
if(imgtag.has_attr('data-original-width')):
= "{0} 2x, {1} 1x".format(imgtag['src'].replace('=s320','=s640').replace('=s400','=s800').replace('/s320/','/s640/').replace('/s400/', '/s800/') ,imgtag['src'])
srcset 'srcset'] = srcset
imgtag[= int(imgtag['data-original-height']) / int(imgtag['data-original-width'])
aspect_ratio if(imgtag.has_attr('width')):
'height'] = round(int(imgtag['width']) * aspect_ratio)
imgtag[elif(imgtag.has_attr('height')):
'width'] = round(int(imgtag['height']) / aspect_ratio)
imgtag['loading'] = "lazy"
imgtag[
soup.html.unwrap()
soup.body.unwrap()= soup.prettify()
buff = open('out.html', 'w', encoding='utf-8')
f
f.writelines(buff)
f.flush()print(buff)
BeautifulSoupでDOMツリーを作成し、imgタグ全てを抽出してdata-original-width
属性のあるimgタグに対してsrcset
を追加しています。画像サイズ「中」は、320px→640pxに、「大」は、400px→800pxにしています。新しい画像URL形式と古い形式両方に対応しています。
ついでにwidth
, height
属性やLazy Loadingも追加しています。
Windowsの場合は、pyperclipを使ってクリップボードへコピーして変更後もクリップボードへ渡してもいいですね。Linuxではpyperclipが動かなかったので標準入力から読み、標準出力へ出すようにし、Emacsのshell-command-on-region
で呼び出しています。
まとめ
Bloggerの画像は、モバイル端末で見た場合に解像感に欠ける画像になってしまいますが、img
タグにsrcset
属性を追加することで解像感の高い画像にすることができます。画像がたくさんあると手作業では大変なのでPythonを使いある程度自動でできるようにしました。
関連記事
Bloggerのフィードからブログカードを一気に作成(1)ーHTMLのテンプレートとCSSを準備ー
ブログ内に関連記事やおすすめの記事などのリンクを入れる際に、画像、題名、要約をまとめてブログカードに ...
Blogger 人気の投稿ガジェットをカスタマイズ
このブログはGoogleのブログサービスであるBloggerで書いています。 ブログサービスと ...
Bloggerに日本ブログ村のバナーを見映えよく貼る方法
このブログを始めたとき、少しでも多くの人に読んでもらえればと思い 日本ブログ村(以下ブログ村)に ...
Bloggerを始めよう!-今さらBloggerのすすめ
このブログは自転車の改造ネタをメインに忘備録を兼ねて情報をまとめていこ うと2018年に始め ...
0 件のコメント:
コメントを投稿