Google Analytics

2014年6月25日 星期三

Java產生QR Code - Part 2

承上篇(Java產生QR Code - Part 1)

Java產生QRCode可以使用swetake所開放的原始碼http://www.swetake.com/qrcode/java/qr_java.html來做開發。

一個基礎的QR Code產生程式碼如下:
public static void main(String[] args) throws Exception {
        String content = "http://google.com.tw";
        String charsetName =  "UTF-8";
        String qrCodeImagePath = "c:/qrCode.jpg";
   
        int version = 2; 
        char errorCorrect = 'M';
        char encodeMode ='B';
   
        Color backgroundColor = Color.WHITE;
        Color paintColor = Color.BLACK;
        int matrixWidth = 3;
        int borderWidth = 2;
        String imageFormat = "png";
   
        int matrix = 17 + version * 4;
        int imageWidth = (matrix)*matrixWidth+borderWidth*2;
   
        Qrcode qrcodeHandler = new Qrcode();
        qrcodeHandler.setQrcodeVersion(version);
        qrcodeHandler.setQrcodeErrorCorrect(errorCorrect);
        qrcodeHandler.setQrcodeEncodeMode(encodeMode); 

        byte[] contentBytes = content.getBytes(charsetName); 
       
        BufferedImage bufImg = new BufferedImage(imageWidth, imageWidth, BufferedImage.TYPE_INT_RGB); 
        Graphics2D gs = bufImg.createGraphics();   
        gs.setBackground(backgroundColor); 
        gs.clearRect(0, 0, imageWidth, imageWidth); 
        gs.setColor(paintColor);

        if (contentBytes.length > 0) { 
            boolean[][] codeOut = qrcodeHandler.calQrcode(contentBytes); 
            for (int i = 0; i < codeOut.length; i++) { 
                for (int j = 0; j < codeOut.length; j++) { 
                    if (codeOut[j][i]) { 
                        gs.fillRect(j * matrixWidth + borderWidth, i * matrixWidth + borderWidth, matrixWidth, matrixWidth); 
                    } 
                } 
            } 
        } 
       
        bufImg.flush(); 
   
        File imgFile = new File(qrCodeImagePath); 
        ImageIO.write(bufImg, imageFormat, imgFile); 

}


說明

以下幾行程式碼,其目的在定義QR Code的屬性:
        int version = 2; 
        char errorCorrect = 'M';
        char encodeMode ='B';
        ......(略)......
        Qrcode qrcodeHandler = new Qrcode();
        qrcodeHandler.setQrcodeVersion(version);
        qrcodeHandler.setQrcodeErrorCorrect(errorCorrect);
        qrcodeHandler.setQrcodeEncodeMode(encodeMode); 
根據你要放入QR Code中的資訊內容及編碼方式,查表決定QR Code的version與容錯等級。
內容編碼為'N', 'A'與其他字元,'N'代表數字(Numeric)、'A'代表英文字母加數字(Alphanumeric),我們這邊要用UTF-8,可以放入除'N'與'A'之外的任意字元,如'B';version範圍為1~40;容錯等級為'L', 'M', 'Q', 'H',分別代表7%, 15%, 25%, 30%的容錯等級(相關背景知識見Java產生QR Code - Part 1)。

以下幾行程式碼,其目的在定義產生的QR Code的圖片格式與大小:
        Color backgroundColor = Color.WHITE;
        Color paintColor = Color.BLACK;
        int matrixWidth = 3;
        int borderWidth = 2;
        String imageFormat = "png";
        ......(略)......
        BufferedImage bufImg = new BufferedImage(imageWidth, imageWidth, BufferedImage.TYPE_INT_RGB);  
        Graphics2D gs = bufImg.createGraphics();   
        gs.setBackground(backgroundColor); 
        gs.clearRect(0, 0, imageWidth, imageWidth); 

        gs.setColor(paintColor);
再此設定了QR Code的輸出圖片格式為png、前景顏色為黑色、背景顏色為白色、每一個martix的寬度(等於高度)為3px、QR Code的邊界為2px。

執行結果(連到 http://google.com.tw)



2014年6月19日 星期四

Java產生QR Code - Part 1

簡介

QR Code(Quick Response Code)是二維條碼(matrix barcode)的一種,是於1994年由日本DENSO WAVE公司發明,在2000年成為ISO國際標準,但Denso Wave公司的專利權並未被執行,所以QR Code在使用上並沒有版權上的問題。QR Code呈正方形,常見的是黑白兩色。在3個角落,印有較小,像「回」字的的正方圖案。這3個是幫助解碼軟體定位的圖案,使用者不需要對準,無論以任何角度掃描,資料仍然可以正確被讀取。(資料來源:維基百科)

QR Code Version

QR Code一共有40個version,version簡單的說就是正方形每邊的"點"的數量(英文用的是"matrix"或"module"這2個單字,但翻譯卻找不到適當的文字,還是使用"點")。version 1的一邊有21個點(21 x 21 matrix),version每加1,每邊就會多4個點。故version 2為25個點(25 x 25 matrix)、version 3為29個點、version 40為177個點。化做簡單的公式為:

matrix = 17 + version * 4


QR Code 內容編碼

QR Code的內容可以四種編碼方式:
  • 數字(numeric):0-9
  • 英文字母加數字(alphanumeric):0-9A-Z $%*+-./:
  • 8 bit的二進位碼,繁體中文請用"UTF-8"
  • 日文(因為是日本人發明)

QR Code 容錯等級

QR Code的容錯等級可理解為錯誤修正 (error correction) 的能力,會外加在原本內容上面,圖形上如果有破損或被弄髒了,可以借用錯誤修正碼來還原原本的內容,使QR Code仍然可以機器讀取內容。QR Code的容錯等級有:
  • L : 7% 的字元可被修正
  • M : 15% 的字元可被修正
  • Q : 25% 的字元可被修正
  • H : 30% 的字元可被修正

QR Code 可存放的內容字數

決定了了以上的因子,就可以使用http://www.qrcode.com/en/about/version.html的對照表,查出該version, 編碼與容錯等級下,可以使用的內容字數。

2014年6月11日 星期三

Struts2修改struts-default.xml的方法

緣起

筆者由於所屬的專案遇到struts2的安全性問題:s2-020。依照官方的建議其升級至2.3.16.2版時,發現會會受到另一個struts issue : WW-4254的影響,導致系統無法使用,所以改採用官方提供的workaround方式,修改sttuts2預設的設定檔(struts-default.xml)參數。

修改方式

1. 改web.xml
<filter>
        <filter-name>struts2</filter-name>
        <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
        <init-param>
            <param-name>config</param-name>
            <param-value>struts-default_new.xml,struts-plugin.xml,struts.xml</param-value>
        </init-param>
    </filter>

2. 於專案使用的strus2的jar檔或source code目錄(src\core\src\main\resources)下,取得該版staruts的struts-default.xml,依據官網建議,將:
<interceptor-ref name="params"> <param name="excludeParams">dojo\..*,^struts\..*,^session\..*,^request\..*,^application\..*,^servlet(Request|Response)\..*,parameters\...*</param> </interceptor-ref> 改為 <interceptor-ref name="params"> <param name="excludeParams">^class\..*,^dojo\..*,^struts\..*,^session\..*,^request\..*,^application\..*,^servlet(Request|Response)\..*,^parameters\..*,^action:.*,^method:.*</param> </interceptor-ref>

3. 修改後,另存新檔為struts-default_new.xml,放到專案中。