2015年9月26日 星期六

5d3 調焦的方式

前言

第一次機身調焦…沒啥經驗搞了一個下午,能恢復鏡頭的準度,無價。

大部份的相機(單眼) 常常覺得對焦準了,但是放大在螢幕上看卻不是那麼一回事,就是有一點糊糊的… 很多時候是因為跑焦/移焦,有時候是前移,有時候是後移,如果是這樣,並非技術問題,一定要透過設定才能解決的。不解決日後的照片永遠都是糊的。

不能機身調焦的相機,只能把鏡頭送回原廠 ( 有些廠商像sigma 有出調焦器,也可以在家裡自己來 ),當然送回去了也不一定就幫你調到張張準,最好自己來。

測焦的方式

先把機身設成最高畫質的jpg就好,不需要用raw 來拍。

準焦的判定方式,以canon 家來說,就是先透過live view 先取得準焦的照片。拍的時候,記得放大倍率,通常可以放大到10倍。你可以採自動對焦,也可以手動對焦,我自己是以自動為主。

好了之後,關掉live view,轉轉對焦環,再直接拍一張自動對焦的照片。先回到電腦看圖。盡量用可以放很大的軟體來檢查,例如 lightroom , dpp 。如果二張你實在看不出差異,恭喜你沒有跑焦。如果比較模糊,以下是我的方法,比傳統的測焦方式來的快多了。傳統還要使用者判斷前移還是後移,這牽涉到很多問題,還需要二個被攝物來測試,比較麻煩。
直接透過機身,針對這個鏡頭,調 -5~ + 5 各拍一張,共11張 ,直接拿來和 live view的對照組做比對。

假設 +2 是最準的,就再來第二輪拍攝,這一輪的拍攝會縮小加減範圍。以 + 2 為主,向前/後各拍二張,包含 + 2 共五張。也就是0,1,2,3,4。拍攝過程,中間要轉轉對焦環讓它重新對焦。

在電腦中再行比對一次,如果還是覺得 +2 最準,那就成功了。如果你覺得+1看起來好像比較準,二張相差不多的情況下,就+1,+2 再多拍幾次以求確定。

被攝物的選擇

被攝物的基準,可以找有條碼的盒子,務必是方形垂直的物體,上面有字或是很細的條碼,比較有基準做比對。真的不行找個盒子貼1000元鈔票也可以,因為上面的細節比較多。

相機的設定

相機要在 1~2 公尺左右,固定 ISO , 光圈調最大,固定好相機,快門最好來個1/100 以上避免手震。

如果這個測試方式效果不好

如果-5~+5都和準焦的差很多...可能鏡頭偏移的比較嚴重,再放大範圍一些試試。如果調好了,時準時不準,那有可能是相機對焦性能的問題...佳能低階相機的對焦模組並不是很好。這個可能就要考慮砸錢換機啦。

2015年9月20日 星期日

5D3 如何註冊對焦點,並且一鍵切換成動態拍攝的模式

問題  :

拍攝的過程中,如果是靜物,可以慢慢的用bar 來移至自己想對焦的點,半按快門拍攝結束。

如果是突然出現的跑動中的小孩/小狗,你腦中想的是

 1. 要切到61點自動對焦 => 這樣他在螢幕中可視範圍中都對的到。
 2. 切換到 AI SERVO => 目的是針對移動中的被攝物鎖定持續追焦

當你手動做二件事的時候,被攝物早就跑走了。
於是我們透過一些調整,來讓你一舉達成此任務。

目的:

A. 一鍵切成  AI SERVO
B. 一鍵切成 61 點自動對焦
C. 二鍵齊按,則同時發生,放開則回到原來的對焦模式。


方法 :

A.
  A1 透過景深預覽鍵,長按為 AI SERVO ,放開回到ONE SHOT。如何做到 ? 先進MENU,移到這邊,點擊自訂控制。


A2 紅圈處為景深預覽,我們要把它改掉。按set 進去。

A3 裡面我們要把它改成 ONT SHOT <-> AI SERVO 切換


 A4. 確認

景深預覽鈕的位置 : 在你握持時,右手無名指那邊有一個凸凸的圓點,你按的時候,注意一下機頂螢幕,就會發現它從ONE SHOT ->AI SERVO 了。放開則自動回ONE SHOT。有這樣的話代表設定成功了。


B.
光這樣是不夠的,因為AI SERVO 的目的就是在拍攝移動物(雖然靜止物也可以),當移動物跑到預設的對焦區外的時候,手動調整對焦區會來不及,所以我們還需要一個鈕,按了會變成61點自動對焦,讓被攝物逃不出我們的手掌心。這個鈕會是 AF-ON 。但是它需要二個步驟來完成。

* 雖然你也可以將61點常時開著,這樣AI SERVO 就不用再擔心對焦區的問題。但有時相機並不如你想的那麼聰明…平常還是需要將對焦點限縮的。

第一個步驟 : 將AF-ON 的FOCUS 改成「註冊的對焦點」

 這一次我們要修改的是AF-ON 的按鈕



進去之後,我們會選擇第一個「測光與自動對焦啟動」,再按INFO 做詳細設定。
進去之後,選擇右邊的「註冊的自動對焦點」,按SET 結束。
這個目的是什麼 ? 也就是按下AF-ON 的時候,本來是FOCUS 在之前選擇的對焦點,我們改成「註冊的自動對焦點」(HP) 之後,他會用我們註冊的模式來對焦。 邏輯是

  1. 因為註冊的自動對焦點是61點 ( 等一下會做 )
  2. AF-ON 的對焦設定成註冊的自動對焦點
  3. 所以AF-ON 會變成61點自動對焦


第二個步驟 : 將61點自動對焦變成註冊的自動對焦點

我們從手冊來看好了。請翻到330頁。



這邊剛剛我們已經設定過了喔,請再確定一遍是不是選到 「註冊的自動對焦點」了。沒選好的話AF-ON 不會從切換成61點。



先回到相機的拍攝模式~

1. 按下圖紅鈕的「自動對焦點」,再透過右手食指轉盤或M-FN 切成 61點自動對焦,這是第一句的意思。因為我們要的是61點,所以2的部份你就選成61點如下下圖。

圖1

61點自動選擇對焦長這樣。

圖2

先隨便拍拍看,看是不是相機自動選擇對焦點了。

3.

現在我們就要「註冊」了。
註冊的意思是說,把「當下」的對焦點模式,變成一組選擇。

 * 當然 ! 為了避免你是用背的,而不了解其義,思考一下,你怎麼倒過來,把AF-ON變成單點,而一般快門模式是61點。也是可以的! 但現下不討論這個以免離題。

如何註冊,請看圖示,依順序按。聽到嗶一聲就成功了。我們已經把61點變成註冊的自動對焦點了。




最後確認與操作流程

現在我們都設定好了。要來驗證一下是否如我們所願。我們現在的機器是這樣子 :

1 .平常我是用手冊 73 頁的對焦區域。必要的時候用BAR 移動位置。

2.  突然出現可愛小狗的處理方式


  1. 右手無名指觸發景深鍵變成AI SERVO 模式
  2. 右手姆指按下AF-ON變成 「61點自動選擇自動對焦」,並且會自動對焦+該焦點測光。
  3. 右手食指按下快門鍵久一點 : 連續釋放快門 (其它指頭不要離開喔! 這樣下一張才會保持 AI SERVO + 61 點)
3. 補充
翻到手冊 113頁,建議拍攝方式改成 「靜音連續拍攝」。這樣抓拍的時候,才會連續拍照,並且「靜音連續拍攝」,對反光鏡的壽命比較好。









2013年3月30日 星期六

如何快速在aws 上架網站

這個寫起來可能落落長,不過順序大致上是幾項:

1 申請帳號,填寫信用卡
2 啟動一個ec2 的服務,選預設免錢的那個
3 security group 要設定好http 也要allow ,不然無法存取
4 在裡面安裝apahce server

sudo yum install httpd

5 設定eip 的mapping (可設可不設)
6 放一個歡迎頁html 在  /var/www/html

細節慢慢再寫


安裝tomcat

sudo yum install tomcat6
這樣就裝好了。

記得aws console 中 security group 中要選custom tcp ,然後open 8080 port.
可以在webapps建立一個專案,放一個index.html

如何啟動關閉tomcat
sudo service tomcat6 start
sudo service tomcat6 stop

*建立windows server+sql server的時候,記得在 mgmt studio 中改回mixed mode,否則一般的使用者無法登入。

2013年3月24日 星期日

當Spring MVC+Hibernate搭配的時候出現 No Hibernate Session bound to thread


SpringMVC + Hibernate Error: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here.


這個惱人的問題在於Spring MVC 的設定方式。
首先你的DispatchServlet 對應的xml先找出來
你應該有設定
<context:component-scan base-package="tw" />
這一類的東西。
如果tw是你的根目錄,Spring 就會開始掃瞄所有有annotation的bean並加入管理。
你應該有另一個xml 是管理Spring 交易的,它那邊也會有一個
<context:component-scan base-package="tw" />
因為第一個scan已經把所有的bean load進來了,在交易管理的那個scan變成完全沒作用了。

這樣會導致Spring 的交易沒有被注入,也就是你會因此看到這個錯誤訊息。

解決方法就是把二者的類別錯開,盡量讓spring mvc的scan只掃controller的目錄,不要去掃到Service 層的類別。

讓交易的那個xml去掃service那一層,這樣交易才會被注進去。

2013年3月16日 星期六

Spring 最輕鬆的完整配置方式

本文目的是要去除所有無謂的宣告,並且將多datasource與交易的設定全都建立起來,aop 的功能也要建立起來。

一般工程師抗拒使用Spring的原因通常只是為了設定很麻煩。如果能直接new 為何要設定半天 ? 不過如果連new 都不用,也不用寫什麼設定檔,不是更好嗎 ?

我看過一些實際專案的Spring的XML,有些團隊好像覺得用了Spring就是了不起的事,但是當專案越來越龐大的時候,過多的xml 絕對是痛苦的來源。真正好的設計是在專案中驗證出來的,一開始的易用,並不代表當需求開始增加時,仍能保持易用性。這個時候就可以看的出來設計上有沒有問題。

以下的配置以Spring 3.2為基礎。

學一個東西先看怎麼用,好用的話再參考。

Action



@Controller
@Scope("prototype")

public class EmeaAction {
@Autowired
EmeaService emeaService;

public String index() {

System.out.println(emeaService.list());
return "success";
}  
}

對一般人來說不清楚的就是紅色的Annotation的部份。先不說細節。

Service


@Service
public class EmeaService {
@Autowired
private QuotationDAO quotationDAO ;

@Transactional(value="quo", readOnly=true)
public List<QuoQuotationMain>  list() {
return quotationDAO.listAll();
}
}


到目前為止應該都還ok吧,Service layer的部份又看到一次 @Autowired,  這很明白的表示,請spring 自動幫我注入這個dao。其它細節也不先說。

DAO


@Repository
public class QuotationDAO { 

@Autowired

private SessionFactory sessionFactory2;

public List<QuoQuotationMain> listAll() {
return sessionFactory2.getCurrentSession().createQuery("from    QuoQuotationMain").list();
}
}


好,程式的部份就這樣子了。應該還算好用吧,如果覺得很難用的話,那就回去原來的世界吧…只是原來的寫法不可能更少,如果原來的Java寫法程式可以這麼少的話,還有誰想要學Spring。先來解釋一下這三層最上面會出現的註示。

@Controller=@Component
@Service =@Component
@Repository=@Component

這算什麼解釋啊 ? 因為這些注釋都是語意而已,其實都是代表 @Component,那@Component是做什麼的,這樣宣告可以讓Spring知道說「喔,這個就是Bean,我會自動幫你們註冊,然後id就和類別一樣吧,只是前一個字要小寫」等於Spring 自動幫你產生xml了,於是乎我們就等同有了三個已註冊的bean 在xml裡了。

@Controller 代表他是MVC 中的C,控制流程為主,下面的scope=prototype就是說每次呼叫都會產生一個新的。不信的話你在方法中去印this,得到的物件其實每次都會不同。

@Service 是中間層的處理方式,也包含了交易的部份,與dao溝通的部份。
@Repository 就是指DAO

對程式設計人員來說,你所要知道的就只要這樣子就好了。就算是Grails來說,寫法也不會再更簡單了,頂多它不用宣告Annotation,以命名方式為主,但是有一點註解其實還是比較好,一看到就知道這個類別負責的功能是哪一塊。

好了,再來你應該會想像有很多的xml要設定。但其實不會,你看上面的程式之後,一定要設定的就是datasource與session factory,這個不可能主動幫你建吧,所以這個要怎麼設定?



<bean id="dataSource1" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:comp/env/jdbc/deu"></property>
</bean>
<bean id="dataSource2" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:comp/env/jdbc/sap"></property>
</bean>


你的jndi是什麼就自己改吧。


<bean id="sessionFactory1" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource1" />
<property name="hibernateProperties" value="classpath:hibernate.cfg.xml" />  
<property name="packagesToScan" value="tw.entity.deu" />
</bean>
<bean id="sessionFactory2" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource2" />
<property name="hibernateProperties" value="classpath:hibernate.cfg.xml" />
<property name="packagesToScan" value="tw.entity.emea" />
</bean>


目前不到20 行,而且這二個東西和db 有關,通常很少再動了。就算dba 逼你連到另一個schema 來存取資料,只要加一個sessionFactory和一個dataSource即可。然後在service layer中,value記得用你取的新名字即可。整個衝擊修改過程不用1分鐘。

packagesToScan 這個好像有一點陌生? 他可是專案膨風後的救星,因為再也不用「多一個表格 就要再去xml宣告一次」了。我一直覺得多一個資料庫表格就要在Spring設定一次真的是很無聊的事,現在你可以叫session factory 去掃那個資料夾就好。專案中多一個表格的衝擊就是 : 打開編輯器,自動從table建出annotation 式的entity後結束。當你一次要弄20幾個table出來一個一個宣告這些無意義的程式時,就知道這個屬性真棒!

好了,那xml 裡還有什麼呢?

還有交易的部份。這個訂xml也不過份啦,而且日後就很少需要改。我把會動到的用粗體標示。


<bean id="transactionManager1" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory1"></property>
<qualifier value='deu'></qualifier>
</bean>
<bean id="transactionManager2" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory2"></property>
<qualifier value='quo'></qualifier>
</bean>


交易管理員會以aop 的方式插到service layer去,一個交易管理員對應一個session factory(剛設定過了),一個session factory對應一個datasource(也設定好了),所以交易的部份現在都ready了,專案膨風後也不太需要再做設定。

你說他用aop 的部份,剛剛怎麼看不出來?


Service


@Service
public class EmeaService {
@Autowired
private QuotationDAO quotationDAO ;

@Transactional(value="quo", readOnly=true)
public List<QuoQuotationMain>  list() {
return quotationDAO.listAll();
}
}


@Transactional(value="quo", readOnly=true)這裡就是叫Spring 用aop 的方式在前、後自動補上交易管理,並且使用的是quo 這個交易管理員(transactionManager2啦,上面有)。

這邊全部已經設定完了。在xml 的最上面加上一些tag告訴Spring你要用掃瞄的方式注入。這三行一定要寫。



<context:component-scan base-package="tw"><
/context:component-scan>

<aop:aspectj-autoproxy />
<tx:annotation-driven />


第一行是叫Spring用掃的方式注入。
第二行是啟動aop +annotation來注入 ( 在之前講過不再多提)
第三行是啟動annotation+aop注入交易管理員。

再整理一次。xml 只要寫這三行,以及

  • Datasource
  • Transaction manager
  • Session Factory

之後xml 幾乎就不太需要再更動了。
至於新的Action的話,目前我是用Struts2,改成Spring後再分享一下以Spring 為 MVC 要如何設定。

2013年3月9日 星期六

Spring 宣告式交易管理

聽起來很華麗,用起來也很過癮,但是一開始沒有搞的很清楚,加上又找不到詳細的解釋,在Stackoverflow上問了問題,再參照其它的文章,才搞懂他真正的用法。


本文章的關鍵字是 : Transaction propagation , declarative transaction,Spring宣告式交易管理。



首先先講測試的架構,都是用annotation來做。前面有介紹過方法了。

1。 發起方是一個action裡的method,它會call UserService一個 testAddUserButAddCountryFail的方法。

2. 在這個service裡面,注了一個dao,與另一個service。

3. 這個testAddUserButAddCountryFail方法內我們做二件事: 首先呼叫dao 來insert 一筆資料,這邊我們會讓它insert 成功。再來用另一個service來呼叫,這個service裡面我們會對交易的方式做測試,都是要讓他fail ,但是要看他對testAddUserButAddCountryFail 產生什麼影響。

看程式比較容易:

UserService裡


     @Resource
   private UsersDAO userDao;
     @Resource
    CountryService countryService;


     @Transactional(value="deu"   )
    public void testAddUserButAddCountryFail(){
      userDao.addUser();
      countryService.addCountry();   
  }

CountryService 裡


     @Resource
   private CountryDAO countryDao;

@Transactional(value="deu"  )
public void addCountry(){  
countryDao.addCountryFail();
}

測試 一 : CountryService中的@Transactional 不做什麼設定,預設就會是串在一起的交易。所以當 countryService.addCountry(); 裡面報錯時,exception丟出來 後,整個交易都會失敗,所以user不會新增成功。

如果我們把  countryService.addCountry(); 包try catch不讓它擴散呢?  不行噢,當程式呼叫 countryService.addCountry(); 時,addCountry已被視為是同一個交易,當countryService.addCountry(); 裡出問題自動rollback 時,已經馬上影響到addUser了,也就是原來add的user在一出問題時已經被rollback了。當程式回到 testAddUserButAddCountryFail 你想再處理時已經來不及了。

測試二 : 將


@Transactional(value="deu"  )
public void addCountry(){  
countryDao.addCountryFail();
}



改為


@Transactional(value="deu", propagation=Propagation.REQUIRES_NEW  )
public void addCountry(){  
countryDao.addCountryFail();
}


我們想要知道,根據Spring的文件來說,這邊會變成一個新的交易,我們要讓它出錯,看影響的狀況如何。我們預期它是一個新的交易,所以它出錯不會影響到新增的User.

結果呢…新增的user還是被rollback了。這一點讓我百思不解。後來研究了網站上的說明,才發現 addCountry雖然是一個新的交易,它自己也rollback了,但是它的exception還是會丟回外部的交易(也就是原來addUser開的那一個),因為我們在

@Transactional(value="deu"  )

public void testAddUserButAddCountryFail(){
   userDao.addUser();
   countryService.addCountry();    
 }

中沒有做任何處理,這個exception間接導致了 testAddUserButAddCountryFail 也rollback了。

解決方式 : 在    countryService.addCountry(); 加try catch,白話來說就是 : 它是一個獨立的交易,要是裡面出錯了,它的exception不對我( testAddUserButAddCountryFail ) 產生任何影響。

這邊懂了之後,順便講一下Spring的術語:

當程式一進去 testAddUserButAddCountryFail 時,因為我們有@Transactional ,所以這邊是一個新的交易,叫outer transaction,也就是外面的交易。當我們  countryService.addCountry(); 的時候,因為  addCountry() 裡也是一個交易,這邊叫 inner transaction (內部) 。整個測試案例就是在測試,inner一但有exception時如何對 outer 產生影響。

propagation=Propagation.REQUIRES_NEW會把inner transaction變成一個獨立交易,不寫的話會變成inner的一部份。雖然透過 propagation=Propagation.REQUIRES_NEW變成了一個獨立交易,但是outer還是要對它丟出的例外做處理,都不處理的話,這個例外會影響到原有的交易行為,變成跟著也rollback了。

我這邊順便再貼一下JB Nizet 的回應,他講的夠清楚了。

You got it right. 

If the second service uses REQUIRED, both services are in the same transaction, and the transaction will be marked for rollback if an exception is thrown by the second (or first) service. Catching the exception in the first service won't change anything: the transaction is marked for rollback already. 

If the second service uses REQUIRES_NEW and throws an exception, it has its own transaction, which will be rollbacked. But the exception, as any other exception, will propagate to the caller (the first service). So if it doesn't catch it, its transaction will also be rollbacked. – JB Nizet









2013年1月20日 星期日

spring aop + transaction 控制

整個aop的目的在於 : 如果你會一直寫一樣的東西,那就抽出來,用動態的方式安插在需要的地方即可。

交易是在aop 中一定會被提及的部份,除非你的程式都是單純的報表查詢,否則交易需求是一定會被提到。

在這裡透過aop + annotation 可以超簡單的達成。

spring的xml中要有這幾樣東西。


  1. <context:annotation-config />
  2. <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
  3.         <property name="sessionFactory" ref="sessionFactory"></property>
  4.  </bean>
  5.  <tx:annotation-driven transaction-manager="transactionManager" />

最後一行是說,我要用過annotation的方式來設定transaction。如果不加這一行是無法達成用anno 的方式來設定。

(sessionFactory我假設你已經設定好了…)

再來,只要在你想要做交易的地方宣告@transactional即可。


  1.      @Transactional
  2.      public class UserService {
  3.        @Reso urce
  4.         private UsersDAO userDao;
  5.        
  6.        @Transactional
  7.         public List<Users> list() {
  8.             userDao.addUserErrorTest();
  9.             return userDao.listAll();
  10.         }
  11.         public void testInsertError(){
  12.            
  13.         }
  14. }


我userDao裡的這個方法,會故意新增一個成功,另一個失敗,當這樣宣告的時候,此方法裡呼叫的程式將會被視為一次交易,要就是全部成功,否則就是全部失敗。

aop + transaction的顆粒度極限是方法。所以在dao某個方法中,要重新思考,若不需要交易的程式區塊,要再重構出新的方法,畢竟交易是需要佔時間與資源的。

以下補充一下sessionFactory 的設定方式,我的範例是以 jndi 的方式來做。


  1. <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
  2.         <property name="dataSource" ref="dataSource" />
  3.         <property name="hibernateProperties">
  4.             <value>
  5.             hibernate.dialect=org.hibernate.dialect.SQLServerDialect
  6.               hibernate.show_sql=true
  7.             </value>
  8.         </property>
  9.         <property name="annotatedClasses">
  10.             <list>
  11.                 <value>entity.Users</value>
  12.             </list>
  13.         </property>
  14.     </bean>
  15.     <bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
  16.         <property name="jndiName" value="java:comp/env/jdbc/deu"></property>
  17.     </bean>