1. 程式人生 > >Zxing 生成二維碼和條形碼去掉白邊

Zxing 生成二維碼和條形碼去掉白邊

原始碼下載:

需求:根據輸入內容,生成條形碼或者二維碼。

我們大多數會選擇Zxing。因為jar包較小。且使用簡單。根據內容生成二維碼的工具類也是一搜一大堆。上面的原始碼裡面也提供了一個。但是我們仔細看了下。會發現。不管生成的是條形碼還是二維碼都會有一部分的白邊。如圖:

我們可以看到周圍有白邊。那我們怎麼去掉呢。

我們先把zxing的原始碼下載下來。然後看下這個白邊是如果產生的。

首先是二維碼的。

            BitMatrix bitMatrix = new QRCodeWriter().encode(content, BarcodeFormat.QR_CODE, widthPix,
                heightPix, hints);

這是根據我們輸入的內容。產生一個矩陣。我們可以看到QRCodeWriter的encode()方法裡面的最後兩行:

   QRCode code = Encoder.encode(contents, errorCorrectionLevel, hints);
        return renderResult(code, width, height, quietZone);

第一句是將我們輸入的內容轉換成code.不涉及寬高。

第二句是將code轉換成矩陣。加入白邊的程式碼就在這裡面。

private static BitMatrix renderResult(QRCode code, int width, int height, int quietZone) {
        ByteMatrix input = code.getMatrix();
        if (input == null) {
            throw new IllegalStateException();
        }
        int inputWidth = input.getWidth();
        int inputHeight = input.getHeight();

        //這裡就是在我們給定的寬高的基礎上。增加了大小。
        //int qrWidth = inputWidth + (quietZone * 2);
        //int qrHeight = inputHeight + (quietZone * 2);

        //修改--》去掉間距
        int qrWidth = inputWidth;
        int qrHeight = inputHeight;

        int outputWidth = Math.max(width, qrWidth);
        int outputHeight = Math.max(height, qrHeight);

        int multiple = Math.min(outputWidth / qrWidth, outputHeight / qrHeight);
        // Padding includes both the quiet zone and the extra white pixels to accommodate the requested
        // dimensions. For example, if input is 25x25 the QR will be 33x33 including the quiet zone.
        // If the requested size is 200x160, the multiple will be 4, for a QR of 132x132. These will
        // handle all the padding from 100x100 (the actual QR) up to 200x160.

        //計算白邊的大小。
        //int leftPadding = (outputWidth - (inputWidth * multiple)) / 2;
        //int topPadding = (outputHeight - (inputHeight * multiple)) / 2;

        //修改--》去掉間距
        int leftPadding = 0;
        int topPadding = 0;
        BitMatrix output = new BitMatrix(outputWidth, outputHeight);

        for (int inputY = 0, outputY = topPadding; inputY < inputHeight; inputY++, outputY += multiple) {
            // Write the contents of this row of the barcode
            for (int inputX = 0, outputX = leftPadding; inputX < inputWidth; inputX++, outputX += multiple) {
                if (input.get(inputX, inputY) == 1) {
                    output.setRegion(outputX, outputY, multiple, multiple);
                }
            }
        }

        return output;
    }

這樣就二維碼的白邊就去掉了。

效果圖:

再來看條形碼的。條形碼的修改稍微麻煩點。

條形碼的解析類是:Code128Writer。進去同樣可以找到encode()。呼叫的是父類的encode()。

 int sidesMargin = getDefaultMargin();
        if (hints != null && hints.containsKey(EncodeHintType.MARGIN)) {
            sidesMargin = Integer.parseInt(hints.get(EncodeHintType.MARGIN).toString());
        }

        boolean[] code = encode(contents);
        return renderResult(code, width, height, sidesMargin);

這裡有個sideMargin..emmm。看著像是白邊的大小的樣子。我試著先把這個值修改為0.預設是10.修改以後。執行起來可以發現。還是有白邊。看來這不是全部。看下renderResult()方法。

 /**
     * @return a byte array of horizontal pixels (0 = white, 1 = black)
     */
    private static BitMatrix renderResult(boolean[] code, int width, int height, int sidesMargin) {
        int inputWidth = code.length;
        // Add quiet zone on both sides.

        int fullWidth = inputWidth + sidesMargin;

        int outputWidth = Math.max(width, fullWidth);


        int outputHeight = Math.max(1, height);
        int multiple = outputWidth / fullWidth;
      
        Log.e("zmm", outputWidth + "renderResult-->" + inputWidth + "--->" + multiple);
        int leftPadding = (outputWidth - (inputWidth * multiple)) / 2;
        Log.e("zmm", "間距----------->" + leftPadding);
        BitMatrix output = new BitMatrix(outputWidth, outputHeight);
        for (int inputX = 0, outputX = leftPadding; inputX < inputWidth; inputX++, outputX +=
            multiple) {
            if (code[inputX]) {
                output.setRegion(outputX, 0, multiple, outputHeight);
            }
        }
        return output;

    }

我們可以看到leftPadding。我試著把這個值修改為0.發現還是不行,有白邊。

仔細看下。這個規則。我們的寬度是700px.我們剛剛已經把sideMargin修改成0了。所以

fullWidth=700;

inputWidth:是根據我們的內容根據128編碼生成的一個數組的長度。我們輸入1234567890:這裡的inputWidth:90

multiple=700/90=7.77777;但是這裡是int。所以multiple=7;這就產生了誤差。multiple看成是豎線之間的增量。也就是,第一個豎線座標是0,第二個豎線就應該在0+multiple的位置,以此類推。總共有90個豎線。那90*7<700.那還剩下的70.就只能平分當做左右的白邊。

leftPadding=(outputWidth - (inputWidth * multiple)) / 2;也就是(700-90*7)/2=35.所以我們算出白邊應該是35。

這樣一下來我們就知道該怎麼修改這個長度了。我們值修改leftPadding=0的話。那就會剩下70的空白。所以。不行。我們要做的事修改原始的圖片大小。故修改成:

 /**
     * @return a byte array of horizontal pixels (0 = white, 1 = black)
     */
    private static BitMatrix renderResult(boolean[] code, int width, int height, int sidesMargin) {
        int inputWidth = code.length;
        // Add quiet zone on both sides.

        int fullWidth = inputWidth + sidesMargin;

        int outputWidth = Math.max(width, fullWidth);


        int outputHeight = Math.max(1, height);
        int multiple = outputWidth / fullWidth;
        //先判斷是不是可以整除。如果可以整除。那leftPadding肯定為0,就不需要修改。
        // 如果不能整除。需要把原始的大小修改成outputWidth = multiple * fullWidth;這樣以後。leftPadding也就為0了。
        if (outputHeight % fullWidth != 0) {
            outputWidth = multiple * fullWidth;
        }
        Log.e("zmm", outputWidth + "renderResult-->" + inputWidth + "--->" + multiple);
        int leftPadding = (outputWidth - (inputWidth * multiple)) / 2;
        Log.e("zmm", "間距----------->" + leftPadding);
        BitMatrix output = new BitMatrix(outputWidth, outputHeight);
        for (int inputX = 0, outputX = leftPadding; inputX < inputWidth; inputX++, outputX +=
            multiple) {
            if (code[inputX]) {
                output.setRegion(outputX, 0, multiple, outputHeight);
            }
        }
        return output;

    }

這樣以後。我們還需要在生成條形碼那裡把真實大小修改成我們改過以後的。也就是:

/**
     * 繪製條形碼
     *
     * @param content       要生成條形碼包含的內容
     * @param widthPix      條形碼的寬度
     * @param heightPix     條形碼的高度
     * @param isShowContent 否則顯示條形碼包含的內容
     * @return 返回生成條形的點陣圖
     */
    public static Bitmap createBarcode(String content, int widthPix, int heightPix, boolean isShowContent) {
        if (TextUtils.isEmpty(content)) {
            return null;
        }
        //配置引數
        Map<EncodeHintType, Object> hints = new HashMap<>();
        hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
        // 容錯級別 這裡選擇最高H級別
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
        MultiFormatWriter writer = new MultiFormatWriter();

        try {
            // 影象資料轉換,使用了矩陣轉換 引數順序分別為:編碼內容,編碼型別,生成圖片寬度,生成圖片高度,設定引數
            BitMatrix bitMatrix = writer.encode(content, BarcodeFormat.CODE_128, widthPix, heightPix, hints);

            //增加:把寬度修改我們修改過後的真實的寬度
            widthPix = bitMatrix.getWidth();
            // Log.e("zmm", "---------->" + widthPix + "--->" + height);
            int[] pixels = new int[widthPix * heightPix];
//             下面這裡按照條形碼的演算法,逐個生成條形碼的圖片,
            // 兩個for迴圈是圖片橫列掃描的結果
            for (int y = 0; y < heightPix; y++) {
                for (int x = 0; x < widthPix; x++) {
                    if (bitMatrix.get(x, y)) {
                        pixels[y * widthPix + x] = 0xff000000; // 黑色
                    } else {
                        pixels[y * widthPix + x] = 0xffffffff;// 白色
                    }
                }
            }
            Bitmap bitmap = Bitmap.createBitmap(widthPix, heightPix, Bitmap.Config.ARGB_8888);
            bitmap.setPixels(pixels, 0, widthPix, 0, 0, widthPix, heightPix);
            if (isShowContent) {
                bitmap = showContent(bitmap, content);
            }
            return bitmap;
        } catch (WriterException e) {
            e.printStackTrace();
        }

        return null;
    }

執行看下效果:

至此百邊就去掉了。當然這樣不好看。你也可以。自己來定一個固定的白邊的寬度。我覺得還是不要去掉的比較好。因為。畢竟zxing這樣設計肯定有一定的原因。

每日語錄:

看到一個故事叫“刻舟求劍”,心裡覺得這個人好傻,世上怎麼會有這樣的人,難道不知道劍在江中央掉下了水,跑到江邊是找不到的?然而長大後發現,在這條歲月的長河裡,很多人在某個節點遺失的東西,之後一次又一次返回尋找,卻不知道自己只是站在船邊徘徊,江中央已經回不去了。看到一個故事叫“掩耳盜鈴”,心裡想,這又是一個傻瓜,捂著耳朵偷東西騙的了誰?然而長大後發現,自己和同學一起逃課、一起抄作業、一起考試作弊,一起做許多明知道不應該做卻剋制不住自己的事情。沒有被抓到就沾沾自喜,其實警告的鈴聲早已響起,只是自己捂著耳朵假裝聽不到。看到一個故事叫“朝三暮四”,心裡偷笑,這群猴子怎麼如此好騙,明明就是七個栗子,早晨三個晚上四個變成早晨四個晚上三個就一個個被哄得服服帖帖。然而長大後發現,女孩兒被渣男傷害,對面一個道歉就還是原諒了他;商家使個小小的心眼兒,幾塊錢紅包就引得全國人趨之若鶩……我們不比猴子聰明多少。看到一個故事叫“削足適履”,心裡哀嘆,怎麼會有這樣的蠢人,居然會蠢到砍自己的腳去適應鞋子,換一雙鞋子就那麼難嗎?然而長大後發現,明明知道自己的權益被損害,明明知道這樣的環境和體系並不科學,然而在這其中的每個人卻都默不作聲,甘心忍受。看到一個故事叫“邯鄲學步”,心裡崩潰,為什麼成語故事裡的人一個比一個傻?別人走路姿勢好看就去模仿,到了最後居然忘了自己怎麼走路?然而長大後卻發現,這個世界的確被一股股潮流所帶領,今天“假裝生活”,明天“佛系青年”;今天都在比拼“跳一跳”,明天都在晒“養青蛙”。現在誰能想象,自己扔掉手機生活的樣子?原來,成語中那些傻事兒可能沒有人會去幹,但是,成語裡那些傻瓜,卻是真實地存在著    ---------------------------------來自知乎(作者:霧雨之靈)

單曲迴圈《曾經的你》第一次找工作那段時間天天聽。。因為太迷茫了。太惶恐了。聽著這首歌。沿著一條路。一直走。一直走。想把以後的路想明白,想清楚。其實。。根本毫無用處。路都是走著走著就明白了。願看到這段話的你。可以少些苦惱。少些惶恐。加油!!!

相關推薦

Zxing 生成條形碼去掉

原始碼下載: 需求:根據輸入內容,生成條形碼或者二維碼。 我們大多數會選擇Zxing。因為jar包較小。且使用簡單。根據內容生成二維碼的工具類也是一搜一大堆。上面的原始碼裡面也提供了一個。但是我們仔細看了下。會發現。不管生成的是條形碼還是二維碼都會有一部分的白邊。如圖

zxing生成條碼

/*** * 生成二維碼方法 * @param str 生成內容 * @param widthHeight 寬度和高度 * @return * @throws WriterException */ public static Bit

c# zxing生成列印

生成二維碼程式碼 asset=“要生成的字串”; public static Bitmap CreateQRCode(string asset) { EncodingOptions options = new QrCodeEncodingOptions {

Zxing生成新增Logo

1.一個專案開始,都需要做準備,準備一個Zxing。jar包來支撐生成二維碼   接下來直接上程式碼,   生成普通二維碼    先寫一個生成二維碼的方法 //生成二維碼 private B

【java】google的zxing架包生成讀取【可帶文字logo】

oms cga dispose framework 增加 span 記錄 ora obj 承接RC4生成不重復字符串的需求之後,因為優惠碼要方便用戶使用的緣故,所以思來想去,覺得還是直接生成二維碼給用戶直接掃比較實用,也不用用戶專門記錄冗長的優惠碼編號。 =========

ZXing-core生成解析

現在二維碼這麼流行的時刻,也必須知道二維碼是怎麼生成。現在我們就來看看,是怎麼生成的。 其實主要是利用goggle釋出的jar來使用:本文轉自點選開啟連結 1、二維碼的生成    二維碼的生成需要藉助MatrixToImageWriter類,該類是由Google提供的

ZXing 相簿中識別條形碼(直接引用就可以了)

*百度了很久一直沒有找到關於相簿獲取條形碼的Demo,真心是醉了,只能苦逼的去自己看 閒話不說直接搞起 分析: *核心 1,通過路徑轉換成bitmp物件 2,再bitmap物件轉換成二進位制圖片(二值化) == 將影象進行二值化處理,1 , 0 代

java 使用zxing生成(帶logo文字說明的)

jar包maven地址        <dependency>             <groupId>com.google.zxing</groupId>             <artifactId>core<

zxing生成

fault awt .com void auth args dom systems import <dependency> <groupId>com.google.zxing</groupId> <artifact

Android:使用ZXing生成(支持加入Logo圖案)

over rmi api note sta size argb_8888 reat for循環 ZXing是谷歌的一個開源庫。能夠用來生成二維碼、掃描二維碼。本文所介紹的是第一部分。 首先上效果圖: ZXing相關各種文件官方下載地址:https://g

zxing生成設置邊框顏色

嘗試 edi osi 循環 span static right 開始 top 真是研究了很久很久,滿滿的淚啊 zxing生成二維碼,默認是可以增加空白邊框的,但是並沒有說設置邊框顏色的屬性。 其中增加空白邊框的屬性的一句話是: Map hints = new Ha

WPF調用zxing生成

大小 pac xaml returns pri 進行 writer 創建 idt 1.登錄http://zxingnet.codeplex.com/,下載對應.net版本的zxing庫 2.引入zxing.dll 3.新建界面控件 using System; using

java學習-zxing生成矩陣的簡單例子

map obj 基於 The output 圖片 .get imageio sts 這個例子需要使用google的開源項目zxing的核心jar包 core-3.2.0.jar 可以百度搜索下載jar文件 也可使用maven添加依賴 <de

C# TSC列印條形碼(轉) C#呼叫dll提示"試圖載入格式不正確的程式"解決方法

效果圖   開發、使用環境說明 安裝TSC_7.3.8_M-3.exe印表機驅動,安裝時選擇對應的ttp 244 pro 將TSCLIB.dll複製到C:\Windows\system 驅動安裝說明     選擇下一步   &nbs

zxing生成以流式傳到頁面

@RequestMapping(“/makeQrCode”) public void madeQrCode(HttpServletResponse res,String content,Integer width,Integer height) throws IOException{

php識別條形碼

使用php-zxing,github地址:https://github.com/dsiddharth2/php-zxing 在使用之前先確保已安裝java環境 另外參考連結: https://blog.csdn.net/mrwangweijin/article/details/79145

前端動態生成條形碼

二維碼 1.匯入qrcode.js vue專案:在main.js中引入匯入的qrcode.js檔案 import '../static/js/qrcode.js' 在需要顯示二維碼的頁面 <div>      &n

Zxing 生成

首先新增依賴 implementation ‘cn.bingoogolapple:bga-qrcode-zxing:1.2.5’ 新增許可權 佈局 MainActivity package com.lll.zxingsc; import android.Manifes

使用zxing生成工具類

public class QRCodeUtils { /** * 建立二維碼(有白邊) * * @param string * @return */ public static Bitmap c

SpringBoot 使用 zxing 生成 返回Base64編碼

前置知識 生成二維碼目前的技術目前有兩大類:QRCode 和 Zxing QRCode 是日本原生的二維碼生成技術,目前只有 0.5Beta 版且不能通過maven等構件工具引入 Zxing 是google 對二維碼生成技術的包裝,提供給Android系統用,不過也可以