Skip to content

Commit

Permalink
添加DataMatrix格式的二维码生成
Browse files Browse the repository at this point in the history
  • Loading branch information
yunzhouhua committed Aug 20, 2018
1 parent 3066b65 commit 021dfd9
Show file tree
Hide file tree
Showing 4 changed files with 179 additions and 22 deletions.
36 changes: 26 additions & 10 deletions app/src/main/java/com/yunzhou/qrcodeutils/MainActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,16 @@ protected void onCreate(Bundle savedInstanceState) {

rxPermissions = new RxPermissions(this);

mQrResultView = (TextView) findViewById(R.id.qr_code_result);
mQrCodeView = (ImageView) findViewById(R.id.img_qrcode);
mScanResultView = (TextView) findViewById(R.id.scan_qr_code_result);
mQrEditView = (EditText) findViewById(R.id.qr_code_text);
mQrResultView = findViewById(R.id.qr_code_result);
mQrCodeView = findViewById(R.id.img_qrcode);
mScanResultView = findViewById(R.id.scan_qr_code_result);
mQrEditView = findViewById(R.id.qr_code_text);

findViewById(R.id.start_qr_scan).setOnClickListener(this);
findViewById(R.id.create).setOnClickListener(this);
findViewById(R.id.create_logo).setOnClickListener(this);
findViewById(R.id.dm_create).setOnClickListener(this);
findViewById(R.id.dm_create_logo).setOnClickListener(this);
findViewById(R.id.scan_qr_code).setOnClickListener(this);

}
Expand All @@ -61,10 +63,16 @@ public void onClick(View v) {
scan4QRCode();
break;
case R.id.create:
createQrCode();
createQrCode(1);
break;
case R.id.create_logo:
createQrCodeWithLogo();
createQrCodeWithLogo(1);
break;
case R.id.dm_create:
createQrCode(2);
break;
case R.id.dm_create_logo:
createQrCodeWithLogo(2);
break;
case R.id.scan_qr_code:
if(mBitmap != null) {
Expand All @@ -76,7 +84,7 @@ public void onClick(View v) {
}
}

private void createQrCodeWithLogo() {
private void createQrCodeWithLogo(int flag) {
Bitmap bitmap = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
Expand All @@ -85,12 +93,20 @@ private void createQrCodeWithLogo() {
canvas.drawCircle(50, 50, 50, paint);

//mBitmap = QRCodeManager.getInstance().createQRCode("二维码内容", 300, 300, bitmap);
mBitmap = EncodingUtils.createQRCode(this, mQrEditView.getText().toString(), 300, 300, R.mipmap.ic_launcher);
if(flag == 1) {
mBitmap = EncodingUtils.createQRCode(this, mQrEditView.getText().toString(), 300, 300, R.mipmap.ic_launcher);
}else if(flag == 2){
mBitmap = EncodingUtils.createDataMatrix(this, mQrEditView.getText().toString(), 300, 300, R.mipmap.ic_launcher);
}
mQrCodeView.setImageBitmap(mBitmap);
}

private void createQrCode() {
mBitmap = EncodingUtils.createQRCode(mQrEditView.getText().toString(), 300, 300);
private void createQrCode(int flag) {
if(flag == 1) {
mBitmap = EncodingUtils.createQRCode(mQrEditView.getText().toString(), 300, 300);
}else if(flag == 2){
mBitmap = EncodingUtils.createDataMatrix(mQrEditView.getText().toString(), 300, 300);
}
mQrCodeView.setImageBitmap(mBitmap);
}

Expand Down
20 changes: 20 additions & 0 deletions app/src/main/res/layout/activity_main.xml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,26 @@

</LinearLayout>

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">

<Button
android:id="@+id/dm_create"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="生成DataMatrix二维码" />
<Button
android:id="@+id/dm_create_logo"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="生成带logoDataMatrix二维码" />

</LinearLayout>

<ImageView
android:id="@+id/img_qrcode"
android:layout_width="match_parent"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import com.yunzhou.qrcodelib.zxing.utils.BitmapFlex;

import java.util.HashMap;
import java.util.Map;
Expand All @@ -29,10 +31,12 @@ public class EncodingUtils {
* @param content content
* @param widthPix widthPix
* @param heightPix heightPix
* @param format 二维码格式
* @param logoBm logoBm
* @return 二维码
*/
public static Bitmap createQRCode(String content, int widthPix, int heightPix, Bitmap logoBm) {
public static Bitmap create2DCode(String content, int widthPix, int heightPix, BarcodeFormat format,
Bitmap logoBm) {
try {
if (content == null || "".equals(content)) {
return null;
Expand All @@ -45,23 +49,46 @@ public static Bitmap createQRCode(String content, int widthPix, int heightPix, B
// 设置二维码边距
hints.put(EncodeHintType.MARGIN, 0);
// 图像数据转换,使用了矩阵转换
BitMatrix bitMatrix = new QRCodeWriter().encode(content, BarcodeFormat.QR_CODE, widthPix,
BitMatrix bitMatrix = new MultiFormatWriter().encode(content, format, widthPix,
heightPix, hints);
int[] pixels = new int[widthPix * heightPix];

int bitWidth = bitMatrix.getWidth();
int bitHeight = bitMatrix.getHeight();
int[] pixels = new int[bitWidth * bitHeight];
// 下面这里按照二维码的算法,逐个生成二维码的图片,
// 两个for循环是图片横列扫描的结果
for (int y = 0; y < heightPix; y++) {
for (int x = 0; x < widthPix; x++) {
for (int y = 0; y < bitHeight; y++) {
for (int x = 0; x < bitWidth; x++) {
if (bitMatrix.get(x, y)) {
pixels[y * widthPix + x] = 0xff000000;
pixels[y * bitWidth + x] = 0xff000000;
} else {
pixels[y * widthPix + x] = 0xffffffff;
pixels[y * bitWidth + x] = 0xffffffff;
}
}
}
// 生成二维码图片的格式,使用ARGB_8888
Bitmap bitmap = Bitmap.createBitmap(widthPix, heightPix, Bitmap.Config.ARGB_8888);
bitmap.setPixels(pixels, 0, widthPix, 0, 0, widthPix, heightPix);
Bitmap bitmap = Bitmap.createBitmap(bitWidth, bitHeight, Bitmap.Config.RGB_565);
bitmap.setPixels(pixels, 0, bitWidth, 0, 0, bitWidth, bitHeight);

// 因为bitmap可能并不等于预先设置的width和height,需要进行等比缩放,
// 尤其是BarcodeFormat.DATA_MATRIX格式,小的不可想象
if(bitWidth != widthPix){
float wMultiple = ((float) bitWidth) / (float) widthPix;//生成的bitmap的宽除以预期的宽
float hMultiple = ((float) bitHeight) / (float) heightPix;//生成的bitmap的高除以预期的高

if (wMultiple > hMultiple) {//说明宽超出范围更多,以宽的比例为标准进行缩放。
int dstWidth = widthPix;// bitWidth / wMultiple
int dstHeight = (int) (bitHeight / wMultiple);

bitmap = BitmapFlex.flex(bitmap, dstWidth, dstHeight);//等间采样算法进行缩放
} else {//说明相当或高超出范围更多,以高的比例为标准进行缩放。
int dstHeight = heightPix;// bitHeight / hMultiple
int dstWidth = (int) (bitWidth / hMultiple);

bitmap = BitmapFlex.flex(bitmap, dstWidth, dstHeight);//等间采样算法进行缩放
}
}
// 是否添加logo
if (logoBm != null) {
bitmap = addLogo(bitmap, logoBm);
}
Expand Down Expand Up @@ -112,18 +139,46 @@ private static Bitmap addLogo(Bitmap src, Bitmap logo) {
}

/**
* 创建二维码
* 创建QR二维码
*
* @param content content
* @param widthPix widthPix
* @param heightPix heightPix
* @return 二维码
*/
public static Bitmap createQRCode(String content, int widthPix, int heightPix){
return createQRCode(content, widthPix, heightPix, null);
return create2DCode(content, widthPix, heightPix, BarcodeFormat.QR_CODE, null);
}

public static Bitmap createQRCode(Context context, String content, int widthPix, int heightPix, int resId){
Bitmap logoBitmap = getScaleBitmap(context, resId);
return create2DCode(content, widthPix, heightPix, BarcodeFormat.QR_CODE, logoBitmap);
}

/**
* 创建DataMatrix生成的二维码
* @param content
* @param widthPix
* @param heightPix
* @return
*/
public static Bitmap createDataMatrix(String content, int widthPix, int heightPix){
return create2DCode(content, widthPix, heightPix, BarcodeFormat.DATA_MATRIX, null);
}

public static Bitmap createDataMatrix(Context context, String content, int widthPix, int heightPix, int resId){
Bitmap logoBitmap = getScaleBitmap(context, resId);
return create2DCode(content, widthPix, heightPix, BarcodeFormat.DATA_MATRIX, logoBitmap);
}


/**
* 根据资源id获取logo图片,并根据需求压缩
* @param context
* @param resId
* @return
*/
private static Bitmap getScaleBitmap(Context context, int resId){
Bitmap logoBitmap = null;
/**
* 避免图片过大导致过高的内存消耗,这边对大图进行了压缩操作
Expand All @@ -148,7 +203,7 @@ public static Bitmap createQRCode(Context context, String content, int widthPix,
e.printStackTrace();
logoBitmap = null;
}
return createQRCode(content, widthPix, heightPix, logoBitmap);
return logoBitmap;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package com.yunzhou.qrcodelib.zxing.utils;

import android.graphics.Bitmap;
import android.util.Log;

/**
* Created with Android Studio.
* Description:主要用于等间采样缩放。等间采样缩放在单一色彩的图中表现较好,不会产生模糊,可用于放大 DATA_MATRIX 二维码。
* User: huayunzhou
* Date: 2018-08-20
* Time: 10:19
*/

public class BitmapFlex {

/**
* 等间隔采样的图像缩放
* @param bitmap 要缩放的图像对象
* @param dstWidth 缩放后图像的宽
* @param dstHeight 缩放后图像的高
* @return 返回处理后的图像对象
*/
public static Bitmap flex(Bitmap bitmap, int dstWidth, int dstHeight) {
float wScale = (float) dstWidth / bitmap.getWidth();
float hScale = (float) dstHeight / bitmap.getHeight();
return flex(bitmap, wScale, hScale);
}

/**
* 等间隔采样的图像缩放
* @param bitmap 要缩放的bitap对象
* @param wScale 要缩放的横列(宽)比列
* @param hScale 要缩放的纵行(高)比列
* @return 返回处理后的图像对象
*/
public static Bitmap flex(Bitmap bitmap, float wScale, float hScale) {
if (wScale <= 0 || hScale <= 0){
return null;
}
float ii = 1 / wScale; //采样的行间距
float jj = 1 / hScale; //采样的列间距

int width = bitmap.getWidth();
int height = bitmap.getHeight();
int dstWidth = (int) (wScale * width);
int dstHeight = (int) (hScale * height);

int[] pixels = new int[width * height];
bitmap.getPixels(pixels, 0, width, 0, 0, width, height);

int[] dstPixels = new int[dstWidth * dstHeight];

for (int j = 0; j < dstHeight; j++) {
for (int i = 0; i < dstWidth; i++) {
dstPixels[j * dstWidth + i] = pixels[(int) (jj * j) * width + (int) (ii * i)];
}
}
System.out.println((int) ((dstWidth - 1) * ii));
Log.d(">>>",""+"dstPixels:"+dstWidth+" x "+dstHeight);

Bitmap outBitmap = Bitmap.createBitmap(dstWidth, dstHeight, Bitmap.Config.RGB_565);
outBitmap.setPixels(dstPixels, 0, dstWidth, 0, 0, dstWidth, dstHeight);

return outBitmap;
}
}

0 comments on commit 021dfd9

Please sign in to comment.