1. 程式人生 > >帶動態背景圖的二維碼生成器

帶動態背景圖的二維碼生成器

ani graph 設置 idt thead for循環 分解 處理 jar

BitQR-Code

Through image generate QR-Code .

一個優雅的 QR 二維碼生成器

Github項目地址 : https://github.com/CasterWx/BitQR-Code


樣例

拿起你的手機掃描下面的二維碼試試吧!

原圖 Version-3
技術分享圖片 技術分享圖片
Version-5 直接拼湊GIF 分解生成
技術分享圖片 技術分享圖片 技術分享圖片
原圖1 原圖2 原圖3
技術分享圖片 技術分享圖片 技術分享圖片
GIF1 GIF2 GIF3
技術分享圖片 技術分享圖片 技術分享圖片

GIF分解為多個幀

原GIF 第四幀 第七幀 第十幀
技術分享圖片 技術分享圖片 技術分享圖片 技術分享圖片
第十三幀 第十六幀 第二十幀 生成GIF
技術分享圖片 技術分享圖片 技術分享圖片 技術分享圖片

2018年最後一天的最後一篇

引用

在項目中導入 QRCode.jar 以添加依賴:

<component name="libraryTable">
  <library name="QRCode">
    <CLASSES>
      <root url="jar://$PROJECT_DIR$/src/lib/QRCode.jar!/" />
    </CLASSES>
    <JAVADOC />
    <SOURCES />
  </library>
</component>

快速上手

1. "快速導入背景圖片"

只想顯示一張麻衣學姐的照片

BufferedImage writeImg = ImageIO.read(new File("麻衣學姐.jpg"));
BufferedImage bf = new BufferedImage(writeImg.getWidth(),writeImg.getHeight(),BufferedImage.TYPE_INT_RGB);
Graphics2D gs = bf.createGraphics() ;
gs.clearRect(0,0,bf.getWidth(),bf.getHeight());
gs.drawImage(writeImg,0,0,bf.getWidth(),bf.getHeight(),null);

writeImg是讀取到的圖片,然後根據這張照片創建Graphics的大小。

gs.drawImage(writeImg,0,0,bf.getWidth(),bf.getHeight(),null);

便可以將writeImg繪制到Graphics中了。

File imagefile = new File(imgPath);
ImageIO.write(bf,"png",imagefile);

現在就可以利用ImageIO將圖片存儲到本地了

效果
技術分享圖片

2. "圖片中使用畫筆"

Graphics2D gs = bf.createGraphics() ;
gs.setBackground(Color.white);
gs.clearRect(0,0,bf.getWidth(),bf.getHeight());
gs.drawImage(writeImg,0,0,bf.getWidth(),bf.getHeight(),null);

gs是創建出的畫布,setBackground可以設置其背景色,也可以直接drawImage()將圖片繪制進去。

gs.setColor(Color.BLACK);
gs.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP,1.0f));
gs.fillRect(j*mini+begin,i*mini+begin,mini,mini );
  • setColor用於設置畫筆顏色。
  • setComposite用於設置透明度
  • fillRect是繪制動作,參數值為起始坐標和結束坐標。

3. "二維碼的本質是_______"

二維碼的本質是二進制表示數據

二維碼的黑白格,其實就代表了0和1兩位數據,我們只需要將數據轉化為bytes數組,然後根據數組的0-1值直接繪制到圖片上,即可生成相應的二維碼。

byte []contentByte = "需要表示的數據".getBytes("utf-8");
boolean [][]cidesOut = qrcode.calQrcode(contentByte) ;

這樣就可以生成一個cidesOut數組來表示二維碼的黑白格。

qrcode是二維碼的生成配置,容錯率和Qrcode版本等。

Qrcode qrcode = new Qrcode();
qrcode.setQrcodeErrorCorrect('M');
qrcode.setQrcodeEncodeMode('B');
qrcode.setQrcodeVersion(3);

4. "黑白格襯衫!!!"

二維碼的本質是黑白格襯衫!!!

雙層for循環遍歷cidesOut這個boolean數組,如果是true就繪制黑色。

 for(int i=0;i<cidesOut.length;i++){
    for(int j=0;j<cidesOut.length;j++){
        if(cidesOut[j][i]){
            gs.fillRect(j*mini+begin,i*mini+begin,mini,mini );
        }
    }
}

GIF動畫幀繪制

1. "如何繪制一個GIF"

AnimatedGifEncoder e = new AnimatedGifEncoder();
e.setRepeat(0);
e.start(newPic);
BufferedImage src[] = new BufferedImage[pic.length];
for (int i = 0; i < src.length; i++) {
    e.setDelay(playTime); 
    src[i] = ImageIO.read(new File(pic[i])); 
    e.addFrame(src[i]);  //添加到幀中
}
e.finish();

首先定義一個GIF生成類.

AnimatedGifEncoder e = new AnimatedGifEncoder();

e.start(newPic);

newPic代表最後生成的gif文件名.

e.setDelay(playTime);

設置播放的延遲時間playTime.

e.setDelay(playTime);

src[i] = ImageIO.read(new File(pic[i]));
e.addFrame(src[i]);

最後將BufferedImage圖片添加到幀中.

e.finish();

GIF
技術分享圖片

2. "如何分解一個GIF"

  • 加載gif
GifDecoder gd = new GifDecoder();//要處理的圖片
int status = gd.read(new FileInputStream(new File("marry.gif")));
if (status != GifDecoder.STATUS_OK) {
  return;
}
  • GIF幀數為gd.getFrameCount();

我們可以直接獲取每一幀的圖片並且保存到本地。

for (int i = 0; i < gd.getFrameCount(); i++) {
  //取得gif的每一幀
  BufferedImage frame = gd.getFrame(i);
  // 存儲frame到本地
}

可以將一個GIF分解成幀之後,我們就可以將這一幀添加二維碼,然後加入到一個新的GIF中了。

  for (int i = 0; i < gd.getFrameCount(); i++) {
    //取得gif的每一幀
    BufferedImage frame = gd.getFrame(i);
    Graphics2D gs = frame.createGraphics() ;
    gs.drawImage(frame,0,0,frame.getWidth(),frame.getHeight(),null);
    int qrLength = frame.getHeight()-2*frame.getHeight()/10 ;
    int mini = qrLength/cidesOut.length ;
    int begin = (frame.getWidth() - mini*cidesOut.length)/2 ;
    for(int k=0;k<cidesOut.length;k++){
      for(int j=0;j<cidesOut.length;j++){
        if(cidesOut[j][k]){
          gs.setColor(Color.BLACK);
          gs.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP,1.0f));
          gs.fillRect(j*mini+begin,k*mini+begin/4,mini,mini );
        }
      }
    }

  int delay = gd.getDelay(i);
  ge.setDelay(delay);
  ge.addFrame(frame);
原圖 GIF
技術分享圖片 技術分享圖片
原圖 GIF
技術分享圖片 技術分享圖片
原圖 GIF
技術分享圖片 技術分享圖片

帶動態背景圖的二維碼生成器