【基於zxing的編解碼實戰】精簡Barcode Scanner篇

經過《【搞定條形碼】zxing項目源碼解讀(2.3.0版本,Android部分)》的分析,如今能夠實現最終目標了:精簡Barcode Scanner並將其中的編碼和解碼分離爲兩個獨立的部分,方便往後快速集成到本身的項目中去。html

編碼

在上一篇分析中,對於編碼部分已經有所透露,核心部分只有兩個package。如今將分享的部分再去掉分享app、分享書籤的功能,保留分享剪切板和分享聯繫人以及編碼文本的功能:java

image

編碼部分的邏輯清晰,代碼組織整齊,在前面瞭解zxing總體結構的基礎上一直作減法便可。android

精簡事後該項目起名爲XBarcodeGeneratorgit

能夠實現的功能包括:微信

  • 分享聯繫人app

  • 分享剪切板佈局

  • 編碼輸入文本ui

主界面佈局稍稍修改了下,新增了一個按鈕。代碼託管至:Zxing-Simplificationgoogle


解碼

在Barcode Scanner的基礎上,作出如下調整:編碼

  • 去掉編碼部分。去掉整個com.google.zxing.client.android.encode包及相應佈局

  • 去掉分享部分。去掉com.google.zxing.client.android.share包及相應佈局

  • 精簡設置。去掉「自定義搜索網址」,修改前燈的描述,默認使用自動對焦,去掉搜索國家,沒有持續關注

  • 調整橫屏爲豎屏展現

  • 美化viewfinderview(可選)

調整橫屏爲豎屏進行掃描共分爲5步:

1. 調整CaptureActivity的方向爲豎屏顯示

修改AndroidManifest.xml中:

android:screenOrientation=「landscape"

android:screenOrientation="portrait"


2. 調整相機預覽界面方向

在CameraConfigurationManager.setDesiredCameraParameters的最後增長一行代碼:

camera.setDisplayOrientation(90);

調整相機preview的時鐘方向與手機豎屏的天然方向一致。該方法必須在startPreview以前被調用,在預覽界面展現出來後設置是無效的。

參考:Camera.setDisplayOrientation(int)


3. 調整掃描窗口尺寸

修改CameraManager.getFramingRectInPreview()中的

public synchronized Rect getFramingRectInPreview() {
...
		rect.left = rect.left * cameraResolution.x / screenResolution.x;
		rect.right = rect.right * cameraResolution.x / screenResolution.x;
		rect.top = rect.top * cameraResolution.y / screenResolution.y;
		rect.bottom = rect.bottom * cameraResolution.y / screenResolution.y;
		framingRectInPreview = rect;
...
}

修改成:

public synchronized Rect getFramingRectInPreview() {
...
		rect.left = rect.left * cameraResolution.y / screenResolution.x;
		rect.right = rect.right * cameraResolution.y / screenResolution.x;
		rect.top = rect.top * cameraResolution.x / screenResolution.y;
		rect.bottom = rect.bottom * cameraResolution.x / screenResolution.y;
		framingRectInPreview = rect;
...
}

因爲修改了屏幕的初始方向,手機分辨率由原來的width*height變爲height*width形式,可是相機的分辨率則是固定的,所以這裏需作些調整以計算出正確的縮放比率。


4. 將掃描框設置爲正方形

    public synchronized Rect getFramingRect() {
        if (framingRect == null) {
            if (camera == null) {
                return null;
            }
            Point screenResolution = configManager.getScreenResolution();
            if (screenResolution == null) {
                // Called early, before init even finished
                return null;
            }

            int width = findDesiredDimensionInRange(screenResolution.x, MIN_FRAME_WIDTH,
                    MAX_FRAME_WIDTH);
            // 將掃描框設置成一個正方形
            int height = width;

            int leftOffset = (screenResolution.x - width) / 2;
            int topOffset = (screenResolution.y - height) / 2;
            framingRect = new Rect(leftOffset, topOffset, leftOffset + width, topOffset + height);
            
            Log.d(TAG, "Calculated framing rect: " + framingRect);
        }
        
        return framingRect;
    }

讓height=width便可


5. 反轉掃描到的圖形

修改DecodeHandler.decode方法,增長如下代碼

private void decode(byte[] data, int width, int height) {
	long start = System.currentTimeMillis();
	Result rawResult = null;
	
	
	// 新增反轉數據代碼開始
	byte[] rotatedData = new byte[data.length];
	for (int y = 0; y < height; y++) {
		for (int x = 0; x < width; x++)
			rotatedData[x * height + height - y - 1] = data[x + y * width];
	}
	int tmp = width; 
	width = height;
	height = tmp;
	// 新增結束
	
	PlanarYUVLuminanceSource source = activity.getCameraManager().buildLuminanceSource(rotatedData,
			width, height);
	if (source != null) {
		BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
		try {
			// 預覽界面最終取到的是個bitmap,而後對其進行解碼
			rawResult = multiFormatReader.decodeWithState(bitmap);
		} catch (ReaderException re) {
			// continue
		} finally {
			multiFormatReader.reset();
		}
	}
...


若是要仿照微信作一個掃描窗口,可參考《基於google Zxing實現二維碼、條形碼掃描,仿微信二維碼掃描效果》

精簡事後該項目起名爲XBarcodeScanner,代碼託管至:Zxing-Simplification

相關文章
相關標籤/搜索