つばさのーと

つばさの日常を綴るのーと

はてなブログで掲載する画像に自動でウォーターマークを表示する(仮)

f:id:tsubasa123:20170403180324j:plain

 

こんにちは、つばさ(@tsubasa123)です。

 

今日も元気にネタ系カスタマイズ、使いどころがあるかどうか微妙なラインのものをお届けします。もう少し真面目に作り込むことができれば実用性が上がるのかもしれませんが、ちょっとはてなブログでは難しそうだったので断念しました。ネタレベルでお付き合いください。

 

きっかけはブコメから

 

先日、こんな記事を書きました。

 

www.tsubasa-note.blog

 

これはこれで自己満記事に終わってしまいましたが、商品を紹介したりするブログを運営している方にとって、画像の軽量化を一括で行えるサービスというのはそこそこニーズがありそうなことがわかりましたので良しとします。セキュリティリスクを考慮しない自己中なWEBサービスでよければ作れることはわかっているので、課題が解決できたらこっそりとリリースしようかなと思っています。

 

で、この記事のブコメ経由でつっちーさんからついったーでこんなリプをいただきました。

 

できればはてな内で完結するウォーターマークのジェネレーターとかあると嬉しいっす(よろしくお願いしますw)

 

うーん、ちょっと難しいですね。これもWordPressならプラグインとかでできると思うんですが、はてなブログが提供してくれている範囲じゃ画像の結合的なことはできそうもない、というのが現時点での私の考え。アドオンでいけないかも調査してみましたが、クロスドメインの制約には勝てませんでした、ごめんなさい。

 

なんのためのウォーターマーク?

 

そもそもですが、ウォーターマークってなんのために設定するのでしょうか、圧縮よりも手間がかかるのにね。ずばり、「著作権を守るため」だと思うのですが、守り方にも2つあるというのが私の考え。

 

  • パクられたときに自分のものだと主張するため
  • そもそもパクられるのを防ぐため

 

前者はわかりやすいですね、持ち物に名前を書くあれと考え方は同じかな。画像に自分のものだと分かる内容(ロゴとか名前とか)を可視的に設定しておけば、その画像は自分が撮った(作った)ものだと主張することができます。一般的にクレジット表示とか呼ばれるものを設定しますね。うまーく消す輩もおりますが、このようなものを設定することでパクられたときに抗議しやすくなると思います。

 

反対に後者はパクる輩にけん制を行うため、「俺のものだからパクるなよ」的なプレッシャーを与えることを目的にクレジット表記を設定します。感覚的にはダミーの監視カメラを置くことで泥棒に対して精神的な抑止効果を与える的な感じでしょうか。

 

画像を動的に表示すればまぁなんとか

 

はてなブログの制約的に、元の画像に静的にウォーターマークを入れられないので、動的に入れて表示してみることに。ちょっと何言ってるかよくわかんない、って感じですね。言葉だと説明が難しいので実際にご覧ください。

 

f:id:tsubasa123:20170320160234j:plainf:id:tsubasa123:20170320160231j:plainf:id:tsubasa123:20170320160105j:plain

 

わかりにくいものもありますが、画像の左上に羽みたいなマークがついているのがわかると思います。こんな感じで、ブラウザに画像を表示する時に動的に追加するような処理を作ってみました。別々の画像を重ねているのではなく、二つの画像をcanvasという要素にレンダリングしてから元の画像と置き換えるような流れになっています。

 

右クリックして保存してもウォーターマークの入った画像が保存されますので、パクリ対策に少しは役に立てるかもですね。システムなんかを使って機械的にコンテンツを盗んでいく輩には対応できないですが、まぁやらないよりはましかというレベルの対策です。

 

メリットを上回るデメリット?

 

これはブログを運営している方の考え方によって左右されますので一概には言えませんが、個人的には、デメリットの方が目立っちゃうかなーといった印象です。

 

大きなデメリットは2つ、「表示速度に影響を与える」と「レスポンシブに対応できない」ですね。実際に測ったわけではないのですが、画像を読み込んで合成して置き換える、という処理を画像の数だけ繰り返しているので、少なからず悪影響を与えているんだろうなーと思います。まぁ、ファーストビューに画像がなければ問題ないかもしれませんが、余計なことはしないほうがレンダリング速度的に良いのは確かです。

 

レスポンシブに対応できないってのも昨今のブログデザイン的にはデメリットと言わざるを得ないですね。canvas要素を作成するタイミングで幅と高さを決めてしまうので、ブラウザのサイズが変わった時にはみ出ちゃったりします。まぁ、リサイズも監視すれば解消できるけど、その分コードが複雑になりますね。

 

コードはこちら。

 

JavaScriptの追加だけでOKです。

 

<img src="https://cdn-ak.f.st-hatena.com/images/fotolife/t/tsubasa123/20170322/20170322161612.png" id="watermark" style="display: none;">
<script>
(function() {
var watermark = document.getElementById('watermark');
function imageToCanvas(img) {
    var canvas = document.createElement('canvas');
    var w = canvas.width  = img.width;
    var h = canvas.height = img.height;
    var ctx = canvas.getContext('2d');
    ctx.drawImage(img, 0, 0, w, h);
    ctx.drawImage(watermark, 20, 20);
    img.parentNode.replaceChild(canvas, img);
}

watermark.addEventListener('load', function() {
    var photos = document.querySelectorAll('.hatena-fotolife');
    for (var i = 0, n = photos.length; i < n; i++) {
        (function(photo) {
            if (photo.complete) {
                imageToCanvas(photo);
            } else {
                photo.addEventListener('load', function() {
                    imageToCanvas(photo);
                });
            }
        })(photos[i]);
    }
});
})();
</script>

 

一行目の画像へのパスはご自身で表示したいウォーターマークへのパスに変更してください。今回は敢えてjQueryを使わないという縛りプレイで実装してみました。今年度は脱jQueryが密かな目標でもありますので。

 

あー、あと、マークダウン記法でしか確認していません。多分ですが、見たままで書かれていると動かないんじゃないかな?その時は.hatena-fotolifeの部分を修正すれば動くんじゃないかな?物好きな方、よければお試しください。わからなければ聞いてください。

 

さいごに

 

途中までは結構実用的なものができるかも、と自分でも思っていましたが、色々と技術的な制約に返り討ちに合いまして、こんな形で落ち着きました。まぁ、ウォーターマークを表示するところまではたどり着けたので良しとします。

 

canvasで画像を合成って今までやったことなかったかも、というか、canvas自体あんまり使ったことなかったのでいい勉強になりました。

 

ではでは、最後までお付き合いいただきありがとうございました。