Webサイトのテキスト文の画像化によるコピー防止
 by ip-domain-search.com
IPドメインSEARCH IPドメインLOOKUP IPドメイン半自動 IPドメイン来訪者ログ WWWサーバへ渡す情報
ドメイン基礎講座 独自ドメインの取得 自社(宅)サーバの構築 複数ドメインの運用 お問合せ・PROFEEL


--<Sponsered Link>--

ここでは(管理者自身が実行している)Webサイトの日本語テキスト文の画像化によるコピー防止や不正利用防止、無断転載防止について解説します。
 


下に掲載しているのは画像ファイルです。
 

下に掲載しているのは管理者が IP-DOMAIN-SEARCH.COM サイトとは別に運営している ご詠歌.com というサイトの内の1頁の画像です。

下記画像はそのお寺のご詠歌やお寺の情報の部分のテキスト文章を画像ファイルにしたものです。 HTML文はその画像ファイルを読み出して画面に表示する様にしていますので、

来訪者は元の文章を閲覧する事は出来ますが文章をコピーする事は出来ませんし、
HTML文のソースをみても元の文章は全く判りません。


もし、上記画像が表示されているサイトの頁の全文を見たいと思われる場合は、

ご詠歌.com:西国三十三観音霊場 ご詠歌集】 をスマホで訪れて下さい。
    そこで〔ご詠歌表示〕ボタンを押せば全文が表示されます。
  (上記画像は西国三十三観音霊場 1番札所 那智山 青岸渡寺 のご詠歌情報です。)

来訪者がHTMLソースをみても元の文章があった部分には <img src="./goeikam.png"> と画像ファイルを表示しているだけですので、HTMLソースからは元の文章は全く判りません。
 

多くの時間を使い・足を運び・資料を取寄せ・金銭も費やして調査し収集した札所ご詠歌情報は、 元々は、自分達が各札所のご詠歌を何時でも何処ででも(ご詠歌の本を持ち歩かなくても)ご詠歌をお唱え出来るようにと、収集したご詠歌をネットから見える様にしていたものです。
そして、少しでも多くの人に「日本各地の札所のご詠歌を知って喜んで頂きたい」「昔、多くの参拝で大いに賑わった札所への民衆の信心を思い偲んで頂きたい」と云う気持ちからネット上に一般公開しています。

しかし、その収集した札所情報を 
根こそぎコピーして持って行き、他のサイトで無断転載するような行為
 は断じて許容できません。

(無断転載を確かめる為に、間違った情報を一度公開した事がありましたが、見事に間違った情報が他のサイトでそのまま公開されている事を確認し、不正コピー・無断転載を確信しました。)
 

ネットで検索すれば多くの人のアイデアがあります。
 

Webサイトに公開する文章のコピーを防止・禁止する方法はネットで検索すれば多くの人のアイデアがありますが、それぞれに逃げ道や効果の無い場合が在るように思われ、又HTMLソースを見れば文章が読めます。 (HTMLソースを暗号化する対策もあるようですが)

それで私は札所情報の表示画面をその部分だけを画像にしてセーブしました。
そしてHTML文からはその画像ファイル名を指定して読み出す様にすれば、ソースをみても元の文章は全く判りません。

画像をOCRでテキスト化するソフトがあり、ASCII文字はほぼ完璧にテキスト化できそうですが、OCRの日本語出力は私が試した範囲ではまだまだ間違いが多い様に思われ、1寺毎に画像の文字とOCR出力のテキストを比較し修正する必要があり、その作業も膨大で、画像からテキスト文に書き写すのと変わらない程の大変な作業になり、そんな面倒な事は誰もしないだろうと思っています。また、そこまでの熱い情熱を持ってコピーしていくのなら許す気にもなります。

(なお私は、画像ファイル自体は幾らコピーされても構いませんが、写真家の方などで自分の撮った画像ファイルがコピーされるのを禁止したい場合は画像の上から透明画像ファイルで覆う等の対策をされる場合もあるようです。)
 

私が行った日本語テキスト文を画像ファイルに変換する2つの方法を公開します。
 

方法1.[コピーされたくないテキスト文を手作業で画像ファイルに変換して準備しておく]
 

方法1は原始的な手作業です。
例えば、従来の閲覧サイト用のHTML文(例えばindex.html)を複製して作者専用のHTML文(例えばindex2.html)を作っておきます。
作者はindex2.htmlにアクセスして、PC画面にテキスト文をそのまま表示させて、 画面に表示された内の画像にしたい部分を指定して画像ファイル(例えば./gazou.png)に変換し、index.htmlと同じフォルダーにセーブします。

(PC画面の一部をコピーできるソフトはフリーでも多く存在しています。 Window7や10なら標準でシステムツールに'Snipping Tool'が付属しています。)

閲覧サイト用のHTML文(index.html)を編集して、画像に変換したテキスト文の行を消して、 その部分を
<img src="./gazou.png">
に書き換えます。以上で完了です。

なお、この方法の欠点はテキスト文の原文を(1文字でも)変更する毎に画像変換の手作業が必要になる事です。

また、私のご詠歌.comサイトでは約200程の観音霊場のご詠歌を掲載していますが、各観音霊場毎に三十三ヶ所の寺院がありますので、寺院の数は約6600寺となり、準備する画像ファイルの数は約6,600必要です。更に「ご詠歌」と「御詠歌」で1文字違っても別画像となりますので、画像ファイルの数は2倍の約13,200必要です。
従って、手作業で1寺あたり1分で変換して一日8時間集中して作業しても27.5日ほど必要になり大仕事です。

ですから、今は 方法2.のCGIソフトで自動でテキスト=>画像変換・画像ファイルの保存を行い、 HTML文の <img src="./goeika.png"> コマンドで画像ファイルを表示する様にしています。

しかし、方法2.のCGIソフトはPERL言語で書かれていますので、万人向けでは無いのかも知れませんが、以下に紹介します。


方法2.CGIソフトで[コピーされたくないテキスト文をリアルタイムで画像ファイルに保存し]、HTML文で[画像表示する。]
 

方法1で手作業で準備していたテキスト=>画像変換・画像ファイルセーブを自動でリアルタイムに行います。

下のCGIソフトのリンクをクリックすれば、上記の画像と同じものが次頁に自動作製され表示されます。

gd_test.cgi
(gd_test.cgiのソースは下欄に掲載しています。)

ご詠歌.com のサイトでは全霊場の全寺のご詠歌情報をリアルタイムに画像化して、HTML文でその画像ファイルを表示しています。)


しかし、方法2.のCGIソフトはPERL言語で書かれていますので、万人向けでは無いかも知れません。

また、貴サーバー上にGD.pm という、PerlのGdグラフィックス・ライブラリがインストールされていない場合は、 ご自身が CPAN からDLしてインストールする必要があるかも知れません。

また、サーバーの基本ソフトにGdグラフィックスを稼動させる為のライブラリ(libgd等)がインストールされていない場合はインストールが必要ですが、その場合はroot権限がないとインストール出来ないかも知れません。
また、サーバーの基本ソフトに日本語フォントがインストールされていない場合はインストールが必要になります。

以上、貴方にroot権限がないとサーバーの基本ソフトをインストールできないために動作しない可能性がありますが、 もしかすると、貴方が利用されているサーバーには全て既にインストールされ準備されているかも知れません。
(Gdライブラリより使い易いImageMagickライブラリも準備されているかも知れません。)

下にgd_test.cgiのソースを掲載しますので、それを貴サーバーにコピーして下さい。(chmod:775 or 777)
gd_test.cgiが貴環境で動作してくれる事を期待します。
(背景色の黄色や2つの黄緑色の文字枠が表示されるのであればGDライブラリーはOKです。もう一歩です。日本語フォントファイルの指定が貴環境に合えば動作します。)


CGIソフト実現のためにサーバーOS(freeBSD)に施した追加インスト-ル
 

◎ freeBSD のports を使ったインストール

1:GDライブラリー
cd /usr/ports/graphics/GD
make
(su でrootになる)
make install

2:日本語フォント
cd /usr/ports/japanese/font-sazanami
make
(su でrootになる)
make install


◎ CPANからPERLのライブラリーをインストール

CPAN のモージュール配布サイト http://search.cpan.org/ にアクセスし

(1)モジュール名(GD)を入力、
(2)プルダウンメニューが出たら(GD)を選択して、
(3)「Search the CPAN」ボタンを押して、
左下の[Download] のリンクを選択 => 完了(私が行った時点ではGD-2.69.tar.gzでした。)
サーバー上の任意のフォルダーに保存。

保存した任意のフォルダーで
tar xzvf GD-2.69.tar.gz
cd GD-2.69
% perl Makefile.PL
% make
% su でrootになる
# make install
 

gd_test.cgiのソースは以下の通りです。
 

興味のある方はソースの参考になる部分をご自由に改造・改良されて、ご自由にご利用下さい。

(なお、ご詠歌.com のサイトで現在稼動しているCGIソフトは各寺院毎にデータベースを読み出す部分等が必要ですのでgd_test.cgiとは少しは異なりますが、 gd_test.cgiのソースの1頁~17頁、46頁~305頁および321頁~408頁は全く同じものを使っています。)


#!/usr/bin/perl5 -w
#
#

use strict;
use GD;        # CPANからDLしてインストールする

my $All_width = 0;  # 画像の幅
my $All_height = 0;  # 画像の高さ

  # 微調整用です
my $Adj_font_size  = 0.73;
my $Adj_nihongo_size = 0.333;

  #私の環境用です。貴環境に合わせて変更する必要があります。
my $Mincho_font_file = '/usr/local/share/font-sazanami/sazanami-mincho.ttf';
my $Gothic_font_file = '/usr/local/share/font-sazanami/sazanami-gothic.ttf';

  #寺院毎のデータ。任意の文字に変更可
my @strs =
  ('西国三十三観音霊場 第1番 青岸渡寺 のご詠歌',
   '唱え奉る 西国観音 第1番 那智山 青岸渡寺 (ご本尊:如意輪観世音菩薩) のご詠歌に',
   'となえたてまつる さいこく かんのん だい 1ばん なちざん せいがんとじ の ごえーいかに',
   '補陀洛や 岸打つ波は 三熊野の 那智のお山に 響く滝津瀬',
   'ふだらくや きしうつなみは みくまのの なちのおやまに ひびくたきつせ',
   '',
   '',
   );

  #寺院毎のデータ。任意の文字に変更可
my @add_exp_strs =
  ('宗派  : 天台宗',
   '開基  : 裸形上人',
   'ご本尊 : 如意輪観世音菩薩',
   'ご真言 : オン ハダマ シンタマニ ジバラ ウン ',
   '住所  : 〒649-5301 和歌山県東牟婁郡那智勝浦町那智山8',
   '創立  : 仁徳天皇御代(313~399) ',
   '電話  : 0735-55-0404 ',
   '拝観料 : 無料 ',
   '駐車場 : 有 ',
   '交通  : 京都 大阪 天王寺 名古屋よりJR「勝浦」下車 ',
   '',
   '',
   );

  #各行の文字の色
my @str_colr_ary =
  ( 'BLUE',  # 0 行目 # 西国三十三
   'BLACK',  # 1 行目 # 唱え奉る
   'DRKGRN', # 2 行目 # となえたてまつる
   'BLUE',  # 3 行目 # 補陀洛や 岸打つ波
   'DRKGRN', # 4 行目 # ふだらくや きしうつなみは
   'BLACK',  # 5 行目 # 雑1
   'BLACK',  # 5+1 行目 # 雑1+1
   'BLACK',  # 5+2 行目 # 雑1+2
   );

  #各行の文字サイズ
my @size_ary =
  ( 20,    # 0 行目 # 西国三十三
   17,    # 1 行目 # 唱え奉る
   17,    # 2 行目 # となえたてまつる
   24,    # 3 行目 # 補陀洛や 岸打つ波
   20,    # 4 行目 # ふだらくや きしうつなみは
   15,    # 5 行目 # 雑1
   15,    # 5+1 行目 # 雑1+1
   15,    # 5+2 行目 # 雑1+2
   );

  #各行の文字の間隔
my @space_ary =
  ( 30,    # 0 行目 # 西国三十三
   20,    # 1 行目 # 唱え奉る
   10,    # 2 行目 # となえたてまつる
   30,    # 3 行目 # 補陀洛や 岸打つ波
   10,    # 4 行目 # ふだらくや きしうつなみは
   10,    # 5 行目 # 雑1
   5,     # 5+1 行目 # 雑1+1
   5,     # 5+2 行目 # 雑1+2
   );

  #文字列が太字か否か。
my @bold_ary =
  ( 1,     # 0 行目 # 西国三十三
   0,     # 1 行目 # 唱え奉る
   0,     # 2 行目 # となえたてまつる
   1,     # 3 行目 # 補陀洛や 岸打つ波
   1,     # 4 行目 # ふだらくや きしうつなみは
   0,     # 5 行目 # 雑1
   0,     # 5+1 行目 # 雑1+1
   0,     # 5+2 行目 # 雑1+2
   );

  #文字列が枠付きか否か
my @frame_ary =
  ( 0,     # 0 行目 # 西国三十三
   1,     # 1 行目 # 唱え奉る
   0,     # 2 行目 # となえたてまつる
   1,     # 3 行目 # 補陀洛や 岸打つ波
   0,     # 4 行目 # ふだらくや きしうつなみは
   0,     # 5 行目 # 雑1
   0,     # 5+1 行目 # 雑1+1
   0,     # 5+2 行目 # 雑1+2
   );

  #各行の文字フォント(0:明朝体、1:ゴシック)
my @font_ary =
  ( 0,     # 0 行目 # 西国三十三
   0,     # 1 行目 # 唱え奉る
   0,     # 2 行目 # となえたてまつる
   0,     # 3 行目 # 補陀洛や 岸打つ波
   0,     # 4 行目 # ふだらくや きしうつなみは
   0,     # 5 行目 # 雑1
   0,     # 5+1 行目 # 雑1+1
   0,     # 5+2 行目 # 雑1+2
   );


##############
# GD:PNG画像の必要枠の計算
##############

  my @width_ary;
  my $width_max = 0;
  my $height_totl = 0;
  my $ary_val = 0;

  ##############
  # $strs[0,1,2,3,4]
  for(my $i=0;$i<5;$i++)
    {
    my $string   = $strs[$i];
    my $font_size = $size_ary[$i];
    my $space_size = $space_ary[$i];
    my $bold    = $bold_ary[$i];
    my $frame   = $frame_ary[$i];

    $ary_val = $i;
    if($string eq "")
      {
      last;
      }

    my ( $width_dt , $height_dt) = &cal_boxsize_by_one_str($string ,
      $font_size , $space_size , $bold , $frame ,$Adj_nihongo_size);

    $width_ary[$i] = $width_dt;
    $height_totl += $height_dt;
    }

  for(my $i=0;$i<=$ary_val;$i++)
    {
    if($width_max < $width_ary[$i])
      {
      $width_max = $width_ary[$i];
      }
    }

  $height_totl += $space_ary[5];

  ##############
  ##############
  # $add_exp_strs[0,1,2,3,-,-,20]
  my @width_exp_ary;
  my $exp_ary_val = 0;
  my $width_exp_max = 0;
  for(my $i=0;$i<20;$i++)
    {
    my $string   = $add_exp_strs[$i];
    my $font_size = $size_ary[5];
    my $space_size = $space_ary[6];
    my $bold    = 0;
    my $frame   = 0;

    $exp_ary_val = $i;
    if($string eq "")
      {
      last;
      }

    my ( $width_exp_dt , $height_exp_dt) = &cal_boxsize_by_one_str($string ,
      $font_size , $space_size , $bold , $frame , $Adj_nihongo_size);

    $width_exp_ary[$i] = $width_exp_dt;
    $height_totl += $height_exp_dt;
    }

  $height_totl -= $size_ary[6];
  $height_totl -= $space_ary[6];

  for(my $i=0;$i<=$exp_ary_val;$i++)
    {
    if($width_exp_max < $width_exp_ary[$i])
      {
      $width_exp_max = $width_exp_ary[$i];
      }
    }

  $All_width = $width_max + 20;
  if($width_max < $width_exp_max)
    {
    $All_width = $width_exp_max + 20;
    }

  $All_height = $height_totl;

##############
# 画像の全体枠の作製
##############

  my $im = new GD::Image($All_width, $All_height);

##############
  # 色変数
  my $colr_white  = $im->colorAllocate(255,255,255);
  my $colr_black  = $im->colorAllocate(0,0,0);   
  my $colr_red   = $im->colorAllocate(255,0,0);   
  my $colr_blue  = $im->colorAllocate(0,0,255);
  my $colr_yelow  = $im->colorAllocate(255, 255, 221);
  my $colr_lgtblue = $im->colorAllocate(223, 255, 223);
  my $colr_drkgrn = $im->colorAllocate(0,128,0);
  my $bgcolor   = $im->colorAllocate(255, 255, 221);

##############
# 背景色塗りつぶしの四角BOXを描く
##############

  $im->filledRectangle(0, 0, $All_width, $All_height, $bgcolor);

##############
#  札所文字データのPNG画像表示
##############

  my $pos_y_totl = 0;
  for(my $ii=0;$ii<5;$ii++)
    {
    my $string = $strs[$ii];

    if($string eq "")
      {
      last;
      }

    my $str_color = $colr_black;
    if($str_colr_ary[$ii] eq 'BLUE')    { $str_color = $colr_blue; }
    elsif($str_colr_ary[$ii] eq 'DRKGRN') { $str_color = $colr_drkgrn; }

    my $font_file = $Mincho_font_file;
    if($font_ary[$ii] eq 1)
      {
      my $font_file = $Gothic_font_file;
      }

    my $font_size   = $size_ary[$ii];
    my $frm_fl_colr  = $colr_lgtblue;
    my $frm_wk_colr  = $colr_black;
    my $cntr_x    = int($All_width / 2);
    my $pos_y     = $space_ary[$ii];
    my $bold     = $bold_ary[$ii];
    my $frame     = $frame_ary[$ii];

    $pos_y_totl += $pos_y;

    &string_to_png($string ,$str_color, $font_file , $font_size,
      $frm_fl_colr, $frm_wk_colr, $cntr_x, $pos_y_totl , $bold ,
      $frame ,$Adj_font_size ,$Adj_nihongo_size);

    $pos_y_totl += $font_size;
    }

  ###############
  $pos_y_totl += $space_ary[5];
  ###############
  for(my $iii=0;$iii<20;$iii++)
    {
    my $string = $add_exp_strs[$iii];

    if($string eq "")
      {
      last;
      }

    my $str_color = $colr_black;
    my $font_file = $Mincho_font_file;

    my $font_size = $size_ary[6];
    my $start_x  = int(( $All_width - $width_exp_max ) / 2 );
    my $pos_y   = $space_ary[6];

    &string_exp_to_png($string ,$str_color, $font_file , $font_size,
      $start_x, $pos_y_totl ,$Adj_font_size ,$Adj_nihongo_size);

    $pos_y_totl += $font_size;
    $pos_y_totl += $pos_y;
    }

##############

  my $png_filenm = "./goeika.png";

  my $png_dt = $im->png;
  open (GFILE,"> $png_filenm") || die;
  binmode GFILE;
  print GFILE $png_dt;
  close GFILE;

print "Content-type: text/html\n\n";
print "<HTML>\n<HEAD>\n";
print "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n";
print "</HTML>\n";
print "<BODY>\n";
print "<center>\n";
print "<img src=\"./goeika.png\">\n";
print "</center>\n";
print "</BODY>\n";
print "</HTML>\n";

exit 0;


sub cal_boxsize_by_one_str
  {
  my ($string ,$font_size ,$space_size ,$bold ,$frame ,$nihongosz_adj) =@_;
  my $len = (length($string) + 2 ) * $nihongosz_adj;

  my $width_cal = int($font_size * $len);
  my $height_cal = $font_size + $space_size ;
  if($bold ne 0)
    {
    $width_cal += 2;
    $height_cal += 2;
    }
  if($frame ne 0)
    {
    $width_cal += 6;
    $height_cal += 6;
    }
  return($width_cal , $height_cal);
  }

sub string_to_png {
  my ($string ,$str_color, $font_file , $font_size, $frm_fl_colr, $frm_wk_colr,
     $cntr_x, $pos_y , $bold , $frame ,$fontsz_adj ,$nihongosz_adj) = @_;

  my $width = $font_size * length($string) * $nihongosz_adj;
  my $start_x = $cntr_x - $width / 2;

  #枠なら
  if($frame != 0)
    {
    # 背景色
    $im->filledRectangle($start_x, $pos_y - $font_size,
      $start_x + $width, $pos_y+5, $frm_fl_colr);

    # 外枠
    $im->rectangle($start_x - 2-3, $pos_y - $font_size - 1,
      $start_x + $width + 2+3, $pos_y + 5, $frm_wk_colr);
    $im->rectangle($start_x - 3-3, $pos_y - $font_size - 2,
      $start_x + $width + 3+3, $pos_y + 6, $colr_white);
    $im->rectangle($start_x - 4-3, $pos_y - $font_size- 3,
      $start_x + $width + 4+3, $pos_y + 7, $frm_wk_colr);

    }

  #太字なら
  if($bold != 0)
    {
  #    # 文字の影を描画:
  #  $im->stringFT($str_color,    # 色
  #    $font_file,$font_size * $fontsz_adj,# フォント,サイズ
  #    0      ,        # 回転角度
  #    $start_x+0, $pos_y+1,    # X座標,Y 座標
  #    $string           # 表示文字列
  #    ); 

    $im->stringFT($str_color,    # 色
      $font_file,$font_size * $fontsz_adj, # フォント,サイズ
      0,              # 回転角度
      $start_x+1, $pos_y+0,    # X座標,Y 座標
      $string           # 表示文字列
      ); 
    }

  # 文字を描画 :
  $im->stringFT($str_color,    # 色
     $font_file,$font_size * $fontsz_adj, # フォント,サイズ
     0,             # 回転角度
     $start_x, $pos_y,     # X座標,Y 座標
     $string          # 表示文字列
     ); 

  return(0);
  }

sub string_exp_to_png {
  my ($string ,$str_color, $font_file , $font_size,
    $start_x , $pos_y ,$fontsz_adj ,$nihongosz_adj) = @_;

  # 文字を描画 :
  $im->stringFT($str_color,          # 色
     $font_file, $font_size * $fontsz_adj, # フォント,サイズ
     0,                  # 回転角度
     $start_x, $pos_y,           # X座標,Y 座標
     $string                # 表示文字列
     ); 

  return(0);
  }




個々のご質問にはお答えいたしませんが、ご質問の回答をこのサイトに追加掲載する可能性はあります。


IP-DOMAIN-SEARCH.COM 管理者

Copyright(c) 2020 ip-domain-search.com  All rights reserved.

--<Sponsered Link>--




--<Sponsered Link>--

IPドメインSEARCH IPドメインLOOKUP IPドメイン半自動 IPドメイン来訪者ログ WWWサーバへ渡す情報
ドメイン基礎講座 独自ドメインの取得 自社(宅)サーバの構築 複数ドメインの運用 お問合せ・PROFEEL
goeika.com ご詠歌.com 御詠歌.com