iT邦幫忙

DAY 22
10

Rails 的簡單任務系列 第 23

[RoR] 簡單產生 Identicon 識別圖像

利用圖像來做為一個帳號的代表,可使網站的畫面生色不少,本文簡述網站本身如何提供不會重覆的圖像,給 user 作為預設的圖像的有趣的作法。
什麼是 Avatar Identicon
註冊進來邦幫忙的邦友,如果都用預設值的話,人頭圖像就會都是,就容易有都是同個人的錯覺。這個人頭圖像叫 Avatar,中文大概有人稱為頭像或者分身;而自己在建置給多人用的網頁時,就會希望有最簡單的頭像解決方案,才發現有 Gravatar 的服務,就是以您的頭像或該網站提供的頭像,放在該網站,而頭像的網址是以您所指定的 email 地址透過 MD5 編碼,所以在任何網站註刪要頭像,就可以指到該頭像網址。

而有趣的是,自己若沒有現成的頭像,該網站有提供像以前棉被或毯子上的九宮格拼圖;而他們的這個圖產生,是利用 WordPress 的 plugins WP_Identicon 畫出來的,所以用 PHP 的人,就馬上有現成畫出 Identicon 的程式碼可用 WP_Identicon v1.02

源起是個韓國人 Don Park (可惜他的網站換別的地方後,舊文都不見了,只可透過 google 的庫存檔案來看) 的概念,希望能從不同的個別圖形來識別,做為網路或身份的辨識;在他的文章中,最初想用碎形來做識別圖,是不易達成,後來看到 9-block Pattern Generator 的文章,設計利用 基本形狀,可組合成 的九宮格圖,又可再延伸為,於是利用這樣的概念及原件,再加上顏色的組合,就可以組合出無數多種的個別單一圖形;然後利用什麼 IP 可畫出怎樣的九宮格圖形,這樣從不同地方來的 IP 的留言者身份,這樣就可以從彼此可區別成不同的圖像,一眼看出哪些留言是同一個 IP。而在 Visiglyphs for IP visualisation 文章中用 PHP 實作了以 IP 產生 hash 再畫出九宮格來。

在 RoR 實作 Identicon
由於上述所提到畫出九宮格的實作,都是用 PHP 以及 GD library 畫出來,然而在 RoR 的環境卻都以 ImageMagick 為主,就打算硬著頭皮從 PHP + GD 的碼,看能不能改寫成 Ruby + ImageMagick;好在竟發現 Ruby 有現成的 quilt 這個 gem ,就是來幫忙畫 Identicon 的。

安裝工具
安裝給 ruby 用的 ImageMagic:
yum install ruby-RMagick
安裝 可產生 Identicon 的 gem
gem install quilt

參考 http://github.com/swdyh/quilt/tree/master 裡的語法,幾乎就不用花太多的心力,就可以把要的圖形就畫出來,而且是用 RMagick:
所接受要畫出資料型態的參數,可以是IP address,一般字串,32 bit 整數,不加 type 參數,就預設視為一般字串;預設輸出大小是 15x15,可加 scale 參數 10 則會以 150x150 大小顯示;而以 write 的方式是寫成一個圖型檔,通常是要存成站上的 user 圖像檔用,若用 to_blob 則會直接輸出在頁面上,比較像 send_file 中的 inline 的作用。

指令界面實作
可在作業系統端的 command-line 界面,編輯一個 testname.rb 如以下的內容:

require 'rubygems'
require 'quilt'

name = ARGV[0]
identicon = Quilt::Identicon.new "#{name}", :scale => 10
identicon.write "#{name}.png"

然後執行 ruby testname.rb twtw ,就會產生一個 twtw.png 的圖型來,也可試上述提到的不同參數。

在 RoR 中實作
現在建立在 RoR 中,編輯 app/controllers/demo_controller.rb

  def ipicon
   require 'rubygems'
   require 'quilt'
   ip = request.env['HTTP_X_REAL_IP']
# 讓 query 可設參數控制輸出圖形的大小,最大不可超過 16 ,預設 scale 10,就是大小會以 150x150 畫出
   if params[:scale].nil?
     scale = 10
   elsif params[:scale].to_i > 1 && params[:scale].to_i < 16
     scale = params[:scale].to_i
   else
     scale = 10
   end
# 這裡以 IP 為輸入參數,所以指定 type 為 IP
   identicon = Quilt::Identicon.new "#{ip}", :type => :ip, :scale => scale
   blob = identicon.to_blob() {
        self.format = 'PNG'
        self.depth = 8
      }
# 將圖寫到 cache 中再送出來
      write_fragment(params, blob)
      fragment = blob
      send_data fragment, :type => 'image/png', :disposition => 'inline'
  end

所以這樣就可以看到從您現在連線的 IP 所畫出來的 Identicon 是這個樣子:

若該圖型網址,加上參數 ?scale=5 則會讓圖較小些。

結論
已有現成的 PHP 或 Ruby 的 Library 來畫 Identicon ,就省掉了去研究從什麼字串怎麼畫出怎樣的圖形及顏色,而可以直接拿來用;最適合在讓文章的 Comments 留言中,若不顯示 IP ,又希望有各圖形來區別是否同個 IP 來留言,Identicon 是值得拿來利用;而對於要註冊身份,又希望每個身份的圖像都不一樣的話,也可以用 Identicon 來產生圖像,可以用比較會是單一的帳號名稱,或 email 來作為輸入的參數,才不會一個網站裡,不同的身份卻都共用同一個頭像的情況產生。

參考資料
Don Park 想到用 九宮格產生器 來做識別圖像的文章,可利用 google 的 cache 來看該舊文及 phishmarks 系列的文章
http://www.docuverse.com/blog/donpark/2004/05/03/secure-ui-9-block-phishmarks

九宮格圖形產生器 的原件及展示,不得不說該網站真是酷。
http://www.levitated.net/daily/lev9block.html

Visiglyphs for IP visualisation 將上述兩者用PHP實作出以 IP 畫出九宮格
http://digitalconsumption.com/forum/Visiglyphs-for-IP-visualisation

程式碼中有時會看到 to_blob,什麼是 blob?原來是 Binary Large OBject
http://en.wikipedia.org/wiki/Binary\_large\_object


上一篇
[RoR] 簡單畫出 216 網頁安全色表
下一篇
[RoR] 有趣畫出 MonsterID 怪物分身
系列文
Rails 的簡單任務33
0
dragonken
iT邦新手 3 級 ‧ 2008-10-06 09:54:56

謝謝分享

0
xxxyyyzzz
iT邦研究生 1 級 ‧ 2008-11-14 12:06:56

實用工具,謝謝分享.

0
gric
iT邦高手 1 級 ‧ 2009-03-14 13:20:12

感恩分享咯!

我要留言

立即登入留言