WordPressのサイズ別画像出力 テキストエディタ用

絵を飾る
©いらすとや.

最近のWordPressは記事作成支援のブロックエディタが優秀。画像を記事中に埋めるときちんとサイズ別に送信するようになっているので狭い画面向けに小さいサイズの画像が送信できる。これは送信データ量と転送遅延の低減につながるので好ましい。

WordPressでサイズ別画像出力 1
ブロックエディタ(Gutenbergエディタ)を使ってメディアライブラリから画像を選んで記事に入れるだけ。とっても簡単だけど個人的には大嫌い。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
<figure class="wp-block-image size-large">
  <img loading="lazy"
       width="1024"
       height="682" 
       src="https://example.com/wp-content/uploads/2022/06/hoge-1024x682.jpg"
       alt="画像の説明"
       class="wp-image-199"
       srcset="https://example.com/wp-content/uploads/2022/06/hoge-1024x682.jpg 1024w,
               https://example.com/wp-content/uploads/2022/06/hoge-300x200.jpg 300w,
               https://example.com/wp-content/uploads/2022/06/hoge-768x512.jpg 768w,
               https://example.com/wp-content/uploads/2022/06/hoge.jpg 1040w"
       sizes="(max-width: 1024px) 100vw, 1024px" />
</figure>

ブロックエディタで画像を挿入した場合の画像タグ(HTML)の出力例。ここでは見やすいよう13行に分けているが、実際は1〜3行で出力される。本来はsrcで指定される画像がブラウザで表示されるが、srcsetが指定されている場合はそちらが優先。この例ではスマホのような狭画面では300wで指定された画像が、もう少し幅広のブラウザだと768wで指定された画像が、ブラウザのウィンドウ幅が1024px近くまたはそれ以上であれば1024Wで指定された画像が出力される。

WordPressでサイズ別画像出力 2
「がとらぼ」の中の人はHTML手書き派なのでブロックエディタは性に合わない。旧来のエディタ、それも「ビジュアルエディタ」ではなく「テキストエディタ」を使っている。できるだけ単純化するようにしているので皆が思うほどはHTMLタグを書くことはない感じ。

で、画像タグも単純化して書きたいので
<img src="/dir/imagefile.avif" width="1200" height="1000" alt="画像説明" />
のようにしたい。間違いが少なくて済むし。srcsetで複数の画像のURLを書くのは手間だしコードの視認性が悪くなるし間違いの元。

しかし、この書き方だと大きなサイズの画像があると必ずその大サイズの画像が送信されることになるのでPageSpeed Insightsでの評価が僅かに下がる。画像サイズや数にもよるかとは思われるが微妙に1点とか2点ほど削られることになり100点が取れないことが増える。PageSpeed Insightsで100点取れなくてはならないという訳では全くないが気分が良くない。

WordPressでサイズ別画像出力 3
ケースによっては100点を得られることもあるが、画像のように「適切なサイズの画像」という指摘は間違いなく食らうことになる。

そこで、WordPressのテキストエディタでは <img src="/dir/画像大.avif" width="1200" height="1000" alt="画像説明" /> の様に 書いてWordPressのデータベースに保存。ページ表示時にそれを読み出して「自動変換」して <img src="/dir/imagefile.avif" width="1200" height="1000" alt="画像説明" srcset="/dir/画像小.avif 320w, /dir/画像中.avif 640w, /dir/画像大.avif 800w" /> の様に出力させたい。

WordPressで使用しているテーマのfunctions.phpに追加
/wordpress-path/wp-content/themes/your-theme/functions.php
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
function bny_img_srcset_attachments( $content ) {
    $buf  = '<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /></head><body>';
    $buf .= $content;
    $dom = new DOMDocument();
    @$dom->loadHTML($buf, LIBXML_HTML_NODEFDTD | LIBXML_NOERROR);

    foreach ($dom->getElementsByTagName('img') as $node) {
        $nodes[] = $node;
    }
    if (isset($nodes)){
        foreach ($nodes as $node) {
            $nsrc = $node->getAttribute('src');
            $nwidth = $node->getAttribute('width');
            if (!$node->hasAttribute('srcset')) { 
                if(strpos($nsrc,'wp-content/uploads') === false){
                    $exten = '.' .  pathinfo($nsrc, PATHINFO_EXTENSION);
                    $srcset  = str_replace ($exten , "-320$exten", $nsrc) . ' 320w, ';
                    $srcset .= str_replace ($exten , "-640$exten", $nsrc) . ' 640w, ';
                    if ($node->hasAttribute('width')) {
                        $srcset .= $nsrc . ' ' . $nwidth . 'w';
                    }
                    $node->setAttribute('srcset', $srcset);

                    if ($node->hasAttribute('width')) {
                        $sizeval = '(max-width: 360px) 320px, (max-width: 680px) 640px, ' . $nwidth .'px';
                        $node->setAttribute('sizes', $sizeval);
                    }
                }
            }
        }
    }
    unset($nodes);
    $buf = preg_replace('/^\<html\>.*?\<body\>/', '', $dom->saveHTML());
    $buf = preg_replace('/\<\/body\>.*?\<\/html\>\n/', '', $buf);
    return $buf;
}
add_filter( 'the_content', 'bny_img_srcset_attachments', 10, 2 );

記事本文(HTML)をXMLのDOMとして読み込みimgタグにsrcset属性を付けるという処理。単純な文字列の置換だとどうしてもヘンに漏れる可能性があるのでXMLの要素に属性を付ける方が確実(と思っている)。
ただし、記事本文の中でタグの閉じ忘れがあると勝手に補完されることがあるので注意。
通常は補完されて困ることはないだろうが意図的にイレギュラーなコードにしていると勝手に補完されて造り手の意図と違う表示になる。造り手のミスで不完全なXML(HTML)になっていた場合でも望まれない箇所で補完されることでレイアウト崩れが発生する可能性も無くはない。

2022年9月11日修正:
上のPHPコードで一部修正を行いました。WordPress標準が出すのを真似たsizesを付けていたところ、PageSpeed Insightsではサイズの最適化がなされていないという評価になることがあったので画面幅が360px以下であれば320w用、画面幅が680px以下であれば640w、それ以上であれば元の画像幅というクドい指定にした。元の画像幅が360px, 680px以下である可能性もあるだろうが問題無いはず。

もちろん、少サイズ, 中サイズの画像は別途用意する必要がある。ImageMagickが入っているシステム用のスクリプトを用意した。

img_small.sh (新規)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
#!/usr/local/bin/bash

#引数にpathを指定して実行のこと。
if [ $# -ne 1 ]; then
  echo "利用方法: $0 path" 1>&2
  echo "実行するには引数としてpathが必要です。" 1>&2
  exit 1
fi

#WebP  -  width 640px
find ${1}/ -type f -name "*.webp" -not -name '*-640.webp' -not -name '*-320.webp' -print0 | xargs -0 -I {} sh -c 'convert -resize "640x>" `echo "$(dirname "{}")/$(basename "{}")  $(dirname "{}")/$(basename "{}" .webp)-640.webp"`'

#WebP  -  width 320px
find ${1}/ -type f -name "*.avif" -not -name '*-640.avif' -not -name '*-320.avif' -print0 | xargs -0 -I {} sh -c 'convert -resize "320x>" `echo "$(dirname "{}")/$(basename "{}" .avif).webp  $(dirname "{}")/$(basename "{}" .avif)-320.avif"`'
$ img_small /path

これで、/pathディレクトリの中の下層にある(○○-320.webpと○○-640.webpを除く)「全て」のWebP画像が変換される。
画像があるディレクトリで実行するなら img_small ./ ね。
file.webpからfile-320.webpfile-640.webpが出力される。もちろん元のfile.webpは残る。
また、元画像の横幅が320pxまたは640px以下の場合はサイズは変換されない。(ようにしたつもり)。
なお、ちょっと手抜きなのでディレクトリ名やファイル名に"_"(アンダーバー)が含まれるとファイル名の出力が失敗して{}-320.webpや{}-640.webpというファイル名になってしまうことがある。(スミマセン)
上の例だとWebP画像しか変換しないがもちろん拡張子を変えることでJpegやPNGにも対応する。
ImageMagickのバージョンによってはAVIF画像の扱いに対応していないかもしれないのでその場合はavifは失敗する。

なお、「がとらぼ」ではブログ用記事ではWordPressのメディアライブラリは使っていなくて/imagesディレクトリを作ってそこに独自のルールで画像ファイルを置いている。この記事はこの構成に対応している。
WordPressのメディアライブラリを使っている場合はこの記事の方法では対応が難しいかも。

まぁ、WordPressを素の状態で普通に使うならこの記事は全然参考にならないということで。

関連記事:

回らなくなった扇風機を注油(グリス)で復活させる

潤滑油
©いらすとや.

広電25cm工業扇 アルミ羽根 据置き型 KSF2572-K
2018年に購入した広電の据置き型扇風機。毎年夏にサーバラックに風を吹きかけるために使用している。今年が使用4年めで、製品の寿命としては「設計上の標準使用期間5年」ということになっているのでこの記事を書いている2022年夏の時点であと1年は使えてもおかしくはない。ただ、この製品、2年めからモーターの軸が焼き付いたように重くなり回転が遅くなったりスイッチオン時になかなか回転しなくなっていた。前面(扇風機の羽がある側)の軸部分に機械油を注油すれば復活するので使用シーズンの始めと終わりに注油することでトラブルを避けていたつもりだったが、昨年は注油しても羽の回りがシブいのでモーターの後ろ側の軸受けにも注油。今年は使い始めに前面側の軸受に注油したものの1ヶ月経たずに羽が回らなくなった。機械油ではすぐに油切れになるのかな?

回らなくなった扇風機に注油 1
扇風機のモーター部分。上面に電源スイッチ兼風量調整用ダイヤルと首振りのオンオフスイッチがある。モーターのカバーを外すにはこれらのスイッチ2つを引き抜く。

回らなくなった扇風機に注油 2
ダイヤルの方は素直にスボッと抜けるが首振りスイッチの方は根本近くにツメがあるのでかなり力を入れないと抜けないし無理に引き抜くとツメが割れそうで怖い。超小型ドライバのマイナスの先端(など)をツメにひっかけて浮かせてやると簡単に抜ける。

回らなくなった扇風機に注油 3
モーター部のカバーは背面のネジ2本を抜くことで外すことができる。

回らなくなった扇風機に注油 4
この扇風機はダイヤルスイッチの本体部分がネジ留めになっているので2本のネジを外す。(製品によって異なるかと)

回らなくなった扇風機に注油 5
ダイヤルスイッチの本体部分を邪魔にならないところに移動。スイッチ下面のコードが千切れないよう注意。
ギヤボックスの蓋を留めているネジ2本を外す。(製品によって異なるかと)

回らなくなった扇風機に注油 6
ギヤボックスの蓋を上に抜く。このとき首振り用スイッチを一緒に引き上げる。この首振りスイッチの軸をギヤボックス側に残すと次の画像の金属球がギヤボックス内に落ちて面倒なことになるかも。

回らなくなった扇風機に注油 7

首振りスイッチの軸には貫通する横穴が開いていて、バネが入っている。そのバネの両端には金属球がハマるようになっている。この金属球は普段はギヤボックスの蓋の穴の中に収まるがギヤボックスの蓋から軸を抜くと金属球が飛び出てくる。飛び出してしまうと穴に納めるのが結構面倒。金属球が片方だけならラクだけどね。

回らなくなった扇風機に注油 8
この首振り機構用のギヤボックスは油が底から1/3程度溜まっているべきだと思うが、昨年初めて開けたところ白いギヤの上にグリスがチョンと1滴程度付けられていて、それが歯車の歯には全く届かないところでしかもカピカピ。まったく油分の供給にはなっていなかった。まぁ首振り機構自体はオイルレスでも構わないかもだが。昨年はカピカピグリスはペリペリ剥がして歯車にしっかり当たるようにグリスを付けておいた。今年見たところ黄色になっていたがまだ油分の提供は行われているよう。
モーターの軸受けはベアリングではなくメタル軸受っぽいのだが、オイルレスタイプではなさそうなのにすぐに油切れになるみたい。軸と軸受けの間にホコリが変な具合に入り込んでいて油を排出する状態になってるのかしら?小型モーターの軸受けにはグリスよりも機械油の方が良いだろうと思って昨年は軸受け部分には機械油を注油したのだが焼き付いたようにかたい状態。
ギヤボックスが完全に密閉で軸受けがオイルシールド付きならギヤボックスにクルマ用のエンジンエイルでも入れてやるのが一番良いのだろうが、オイルシールドは無さそうなのでクルマ用オイルだと使っているうちにオイルがどんどんモーターの中に入っていきそう。このギヤボックスの場合はすぐに油切れにならないようにするにはグリスが良さそう?

回らなくなった扇風機に注油 9
カメラのフラッシュのせいかグリスが緑っぽく見えているが軸受け部分にモリモリに付けてみた。(その前に少しだけ機械油を軸受けに挿して固着状態を解いた)
また、モーターの軸受けだけでなく首振り機構部分の4箇所もグリスを塗った。さらにギヤボックスの底に捨てグリスを。ただしモーター側の側面の穴より低いところだけ。羽をグルグル回してなじませる。機械油を少し挿したとはいえ羽を回すと最初は渋っていたのがグリスが馴染むとどんどん軽くなるのがわかる。
自分的には満足したのでギヤボックスを閉じてモーターカバーを嵌めて背面側は元通り。

回らなくなった扇風機に注油 10
扇風機の前面側の羽の裏の軸受け部分。最近の扇風機は知らないが20年くらい前の家庭用扇風機って軸受け部分に円筒状の出っ張りがあって中にフェルトが詰められていてそこに注油してやることで軸受けの油切れを防ぐ仕組みになってたように記憶しているが、この扇風機にはそんなものはなくて直に軸受けが見えている。機械油を挿してもすぐに油切れになるのは仕方がない?これまでは機械油だったが今回はここにもグリスを塗ってやった。で、爪楊枝で軸受部分にグリスを押し込むようにグニグニしながら羽を回してなじませる。これで、手で羽を回すと非常に軽く手を離しても2回転ほど回るようになったので作業完了。

と、いうことで今回は、4年めの扇風機の羽が回らないの、いよいよ機械油でダメだったのでグリスを使ってみたという内容。そしてグリスをつけて1週間経つが今のところは調子が良い。来シーズンどうなるかが心配だけど。

2024年5月21日追記:
グリスを使った翌年までは回転が軽めでしたが、2年後はグリスが固まって回転も悪くなりました。そこで超極圧潤滑剤のAZ CKM-002を注してみました。極圧剤は非常に調子が良いようです。

Amazon商品画像
AZ(エーゼット) CKM-002 超極圧・極潤滑 オイル 450ml AZ524

参考価格: 1,375 円
販売価格: 1,245 円

(2024年05月21日 の参考価格)

扇風機のモーターが回らないけど羽を持った状態で電源入れてみると動こうとしているのは感じられるという場合は軸が固まっているだけだと思われるのでこの記事のように注油やグリスでなんとかなるかもしれない。注油だけで回復できるものならすぐに捨てて新しいのを買うのはもったいない話。

ただ、10年以上経つような古い扇風機とか過度に使用したのとかを注油して無理して使い続けるというのは怖いことでもあるので「真似してくださいとは書きません」。回らなくなって加熱して燃えて火事とかシャレにならないからね。

サラサラな機械油が良いかクルマ用エンジンオイルのような少し粘度があるオイルが良いか練物のグリスが良いか、軸受けの種類に応じて使い分けるのが正しいのだろうが、詳しい人であってもモーター自体を開けて軸受けを直に確認しなければどんな軸受けか判らないかも。まして「がとらぼ」の中の人を含め素人だと直に軸受けを見てもオイルレスタイプなのか油が要るタイプなのかさえ判らないだろう。この記事の扇風機では最初は注油で解決していてグリスに変えたが問題無かったが他の扇風機ではモーターが弱くてグリスはダメということもあるかもしれないし軸受けの温度が上がりすぎてダメかもしれない。モノによってはそもそも油ダメかもしれないし。
おもちゃではなくて家庭用の扇風機で樹脂軸受けってあるのかしら?家庭用扇風機で軸受けが高価なベアリングってことはないだろうけど安物のメタル軸受けを採用するにしてもちょっとは気を使って欲しいところ。あまりにも粗悪な軸受けはカンベンして欲しい。

最後に、CRC 5-56はダメよ、絶対。油汚れや古いグリスを落とすのにはアリなのかもしれないけど注油用じゃない。

Up