blog.Ring.idv.tw

Articles

Google Street View 心得

Google在今日正式對外開放在台灣的街景服務(Google Street View),根據幕後秘辛的說明,Google街景拍攝車的上頭主要使用「9」部朝向不同方向的照相機所組成,以提供「水平 360°」和垂直「290°」的街道全景圖,雖然目前只有提供台北地區的街景,不過未來還會有下述地點:

P.S. 筆者幼時的家鄉「鹿港」居然也包含在內 ^^

雖然台灣街景服務今天才剛正式開放,不過已經有許多先行者分享了相關心得(請見底下相關資訊),所以本篇的介紹傾向從Web的角度來看。

Google Street View - 淡江中學

筆者以不能說的秘密電影拍攝地「淡江中學」來介紹,透過上圖的影像可以得知,左方側欄是提供Google Maps的相關資訊,右方側欄則是一個採用Flash動畫的街景服務,利用Firefox外掛Firebug的資訊攔截,在XHR的面版上可以得知有三個請求,其一就是提供左方側欄資訊的JSON資料交換格式(實際範例)。

第二個應該是提供可替換的「衣夾人」組態設定(這個名字的由來是因為它的形狀像一個衣夾。),他出現在「Google 地圖」視窗左側的縮放工具列上方。若他變成黃色,即表示目前的位置可提供「街景服務」,從這個實際例子中可以得知,裡頭包含了五個不同的衣夾人圖形,不過筆者實際測試的結果,目前所提供的五個圖形URL只有兩個是正確的,它們分別為「Legopeg」和「Panda」,這部份未來也許是可以替換的。

至於最後一個請求則是提供右側Flash形式的街景服務中的XML文字資訊(如上圖:真理街),這部份應該是直接透過街景服務的Flash直接下請求(筆者猜測),透過此Flash動畫資訊中的metadata得知它是採用Adobe Flex 3開發的,此動畫裡頭包含了11張基本工具列的影像資訊:

至於實際的街景影像則是一張張512*512由Google處理過的JPEG影像去組合起來的(如:實際影像),而關於如何組合這樣的全景影像可參考The Stanford CityBlock Project,最後暫且不論Google為何採用Flash來呈現街景服務,Flash在網路上不可或缺的地位又提升了不少。

附帶提一下,Google的伺服器不只多~ 主機名稱也挺多的,上述這些請求的伺服器主機名稱就有「gws」(這比較好猜)、「LocalTrends/1.0」、「mfe」和「Alleycat Server 1.0」(野貓?)

相關資訊

Google Maps開放台灣版街景地圖(Street View)

oogle Maps Street View 台北街景地圖上線&!上網遊覽台北101 | 電腦玩物

台北的Google Street View(Google街景)上線了!

iPhone上的Google Street View (Google街景)

2009-08-18 23:29:49 | Add Comment

標籤雲(Tag Cloud)

Tag Cloud(或word cloud).它屬於視覺化介面的一種呈現方式~ 基本上是透過字母的排列順序和次數權重來決定字型大小的呈現,根據wikipedia的記載~ Tag Cloud最初是由Flickr率先開始使用,至於這個詞是由誰提出來的.. 筆者尚未找到有力的參考文獻~

另外Tag Cloud - Wiki也提供了「Computation of the tag size」公式計算,如下所示:

套用此公式的結果:

從上圖的結果可以發現,上述公式對於權重和字型大小之間的運算結果,會導致字型範圍「1px」至「20px」的情形發生,但基本上當字型大小小於「10px」就不容易閱讀和點選,所以筆者修改了此公式,希望它能自行定義Tag Cloud的字型大小範圍「10px」至「20px」,如下圖所示:

如此便能依照權重比例和字型大小形成相互的對應:

index.py

#! /usr/bin/python
from mod_python import psp

def index(req):
        param = {}
        req.content_type = 'text/html'
        tags = [('aggregators',2),('blogs',3),('wikis',4),('usability',5),('widgets',6),('ajax',7),('social',10),('Folksonomy',15)]
        tags.sort()
        param['Tags'] = tags

        tmpl = psp.PSP(req,'index.tmpl')
        tmpl.run(param)

index.tmpl

<html>
<head>
<title>Tag Cloud</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<style type="text/css" media="all">
.tagcloud
{
        width: 200px;
        height: 100px;
}
</style>
</head>
<body>
<div class="tagcloud">
<%
Clist = [_t[1] for _t in Tags]
Tmax = max(Clist)
Tmin = min(Clist)
Fmax = 20
T = Tmax - Tmin

for _t in Tags:
        if _t[1] > Tmin:
                si = Fmax * (_t[1] - Tmin) / T 
        else:
                si = 1
        
%>
<span style='font-size: <%=si%>px'><a href="#"><%=_t[0]%></a></span> 
<%
# end for
%>
</div>
<div class="tagcloud">
<%
Fmin = 10

for _t in Tags:
        if _t[1] > Tmin:
                si = (Fmax - Fmin) * (_t[1] - Tmin) / T + Fmin
        else:
                si = Fmin
        
%>
<span style='font-size: <%=si%>px'><a href="#"><%=_t[0]%></a></span> 
<%
# end for
%>
</div>
</body>
</html>

2009-08-12 01:02:07 | Add Comment

Read Later - bookmarklet 分析

去年筆者曾寫了一篇「Instapaper - 網頁暫存器」po文來介紹此工具~ 前陣子發覺它的「Bookmarklet - 書籤小程式」有了改版~

它的Bookmarklet主要利用「Dynamic Script Tag」的方式載入一個外部的js檔,下述是此js檔的原始碼:

var d=document;
d.title = d.title.substring(12);
if (document.location.href == 'http://www.instapaper.com/i4') { alert("The bookmarklet is correctly installed."); throw(0); }
var w=window,
    e=w.getSelection,
    k=d.getSelection,
    x=d.selection,
    s=(e? e(): (k)? k(): (x?x.createRange().text: 0)),
    l=d.location,
    e=encodeURIComponent,
    n=d.getElementsByTagName('html'),
    h=0,    z=d.createElement('scr'+'ipt'),
    p='k=CHN8G1125OCh&u=' + e(l.href) + '&t=' + e(d.title) + '&s=' + e(s.length > 6144 ? s : '');
/* Lauderdale, start your photocopiers! http://bit.ly/NdDJj :) */
i=document.createElement('iframe');
i.setAttribute('name', 'ipb596873');
i.setAttribute('id', 'ipb596873');
    c = 'left:10px;top:10px;width:168px;';
i.setAttribute('style', 'z-index: 2147483647; position: fixed;'+c+'width:168px;height: 100px; border: 3px solid #aaa;');
document.body.appendChild(i);
i.onload = function(){ setTimeout(ipb596873_close, 350); }

function ipb596873_close() 
{ 
    var f = document.getElementById('ipb596873');
    f.style.display = 'none'; 
    f.parentNode.removeChild(f);
}

window['ipb596873'].document.write(
    '<html><body style="color: #555; background-color: #fff; text-align: center; margin: 0px; font-family: Georgia, Times, serif; font-size: 26px;">' +
    '<img style="display: block; position: fixed; bottom: 4px; left: 72px;" src="data:image/gif;base64,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"/>' +
    '<div style="text-align: center; width: 80%; padding-bottom: 1px; margin: 0 auto 15px auto; font-size: 13px; border-bottom: 1px solid #ccc; color: #333;">Instapaper</div>' +
    'Saving...' +
    '<form action="http://www.instapaper.com/bookmarklet/post_v5" method="post" id="f">' +
    '<input type="hidden" name="p" value="'+p+'"/>' +
    '<input type="hidden" name="b" id="b" value=""/>' +
    '</form>' +
    '<scr'+'ipt>setTimeout(function() { document.getElementById("b").value = decodeURIComponent("'+e(h)+'"); document.getElementById("f").submit(); }, 1);</scr'+'ipt>' +
    '</body></html>'
);

從它的原始碼可以發現,它主要採用「iframe」的方式並設定CSS z-index為:2147483647,以及透過「Base64」的編碼方式將GIF圖檔內容直接內嵌在js檔中,最後利用「form」來觸發後端的記錄動作,實在是一個不錯的技巧!!

經由筆者測試之後,透過這樣的方式就算在瀏覽全版面的Flash網站時,仍然可以讓視窗保持在最上層!

2009-07-24 00:55:28 | Add Comment

Panasonic LX3 - 初試HDR

HDR(High Dynamic Range).簡單來說就是利用多張不同曝光值的影像,並藉由軟體的合成來營造出能呈現亮部及暗部曝光細節的影像。

而攝影的動態範圍(Dynamic Range)指的就是亮度從最暗到最亮之間的距離,假設考量一個拍攝場景的亮度差異極大時,這時候亮部或暗部的細節就需要有所取捨,因為相機的感光元件可能無法捕捉到所有的細節,這時HDR就相當適合發揮,下述是筆者初試的結果(還有很大的努力空間^^")

0 EV

+1 EV

-1 EV

HDR

(請注意屋簷下柱子所呈現的細節)

相機:Panasonic LX3

軟體:Photomatix Pro

拍攝:Joby Gorillapod 章魚小腳架、自拍模式2秒(防止按下快門時的震動)、ISO 80(盡量壓低,因為合成後顆粒會變明顯)、手動模式、手動對焦、自動曝光包圍(0EV, -1EV, +1EV)

心得:好想要有一台單眼來玩看看~ XDDD

參考資訊

HDR Tutorial: How to create ‘High Dynamic Range’ images using Photomatix

2009-07-17 22:24:21 | Add Comment

A picture is worth a thousand words

她.從小帶著我長大... 換個說法,也只有我讓她帶著長大~

小時候只要她一句話,我從來不會敢有任何過多的要求~ 那時候的我乖的像隻忠狗~

當我過的不是很好的時候,她... 曾塞了一千元到我的口袋~

當我不懂事的時候,她... 從來沒有放棄過我~

當我生日的時候,她... 會準備火鍋等我回去幫我慶生~

另外每次過年的時候,回去鹿港幫忙打掃貼春聯一定有我的份! 不過以後很難再有了~

她.總是希望我多賺點錢... 但我總是回話給她說~ 我是要來做事的,不是要來賺錢的~ (也許這是她的時代環境背景下的影響)

她.已經不記得我是誰了... 也不會說話了... 現在只會對著人微笑...

她.是我的阿嬤。

2009-06-29 00:45:23 | Comments (4)

Next Posts~:::~Previous Posts
Copyright (C) Ching-Shen Chen. All rights reserved.

::: 分類 :::

::: 最新文章 :::

::: 最新回應 :::