Skip to content

Commit

Permalink
生成二维码的时候可以加入logo
Browse files Browse the repository at this point in the history
  • Loading branch information
devilsen committed Jul 24, 2019
1 parent 17391d5 commit c527762
Show file tree
Hide file tree
Showing 10 changed files with 128 additions and 45 deletions.
Empty file added .gitattributes
Empty file.
69 changes: 56 additions & 13 deletions czxing/src/main/java/me/devilsen/czxing/BarcodeWriter.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package me.devilsen.czxing;

import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;

/**
Expand All @@ -14,32 +15,74 @@ public class BarcodeWriter {
/**
* 生成二维码
*
* @param text 要生成的文本
* @param width bitmap 宽
* @param height bitmap 高
* @param text 要生成的文本
* @param size 边长
* @return bitmap二维码
*/
public Bitmap write(String text, int width, int height) {
return write(text, width, height, Color.BLACK);
public Bitmap write(String text, int size) {
return write(text, size, Color.BLACK);
}

/**
* 生成二维码
*
* @param text 要生成的文本
* @param width bitmap 宽
* @param height bitmap 高
* @param color 要生成的二维码颜色
* @param text 要生成的文本
* @param size 边长
* @param color 要生成的二维码颜色
* @return bitmap二维码
*/
public Bitmap write(String text, int width, int height, int color) {
public Bitmap write(String text, int size, int color) {
return write(text, size, color, null);
}

/**
* 生成带logo的二维码
*
* @param text 要生成的文本
* @param size 边长
* @param color 要生成的二维码颜色
* @return bitmap二维码
*/
public Bitmap write(String text, int size, int color, Bitmap logo) {
Object[] result = new Object[1];
int resultCode = writeBarcode(text, width, height, color, result);
int resultCode = writeBarcode(text, size, size, color, result);
Bitmap bitmap = null;
if (resultCode > -1) {
int[] pixels = (int[]) result[0];
return Bitmap.createBitmap(pixels, width, height, Bitmap.Config.ARGB_8888);
bitmap = Bitmap.createBitmap(pixels, size, size, Bitmap.Config.ARGB_8888);
// 添加logo
if (logo != null) {
bitmap = addLogoInQRCode(bitmap, logo);
}
}
return bitmap;
}

/**
* 添加logo到二维码图片上
*/
private static Bitmap addLogoInQRCode(Bitmap src, Bitmap logo) {
if (src == null || logo == null) {
return src;
}

int srcWidth = src.getWidth();
int srcHeight = src.getHeight();
int logoWidth = logo.getWidth();
int logoHeight = logo.getHeight();

Bitmap bitmap = Bitmap.createBitmap(srcWidth, srcHeight, Bitmap.Config.ARGB_8888);
try {
Canvas canvas = new Canvas(bitmap);
canvas.drawBitmap(src, 0, 0, null);
canvas.drawBitmap(logo, (srcWidth - logoWidth) >> 1, (srcHeight - logoHeight) >> 1, null);
canvas.save();
canvas.restore();
} catch (Exception e) {
e.printStackTrace();
bitmap = src;
}
return null;
return bitmap;
}

public static native int writeBarcode(String content, int width, int height, int color, Object[] result);
Expand Down
3 changes: 0 additions & 3 deletions czxing/src/main/java/me/devilsen/czxing/ScanActivity.java
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
package me.devilsen.czxing;

import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;

import me.devilsen.czxing.thread.ExecutorUtil;
import me.devilsen.czxing.util.BarCodeUtil;
import me.devilsen.czxing.util.ScreenUtil;
import me.devilsen.czxing.view.ScanActivityDelegate;
Expand Down
11 changes: 6 additions & 5 deletions czxing/src/main/java/me/devilsen/czxing/thread/Dispatcher.java
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
package me.devilsen.czxing.thread;

import android.util.Log;

import java.util.Deque;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import me.devilsen.czxing.util.BarCodeUtil;

/**
* desc : 任务分发器
* date : 2019-06-29 11:32
Expand Down Expand Up @@ -41,13 +41,14 @@ public ProcessRunnable newRunnable(byte[] data, int left, int top, int width, in
return newRunnable(new FrameData(data, left, top, width, height, rowWidth), callback);
}

synchronized void enqueue(ProcessRunnable runnable) {
synchronized int enqueue(ProcessRunnable runnable) {
if (blockingDeque.size() > MAX_RUNNABLE) {
blockingDeque.remove();
}

execute(runnable);
Log.e(TAG, " blockingDeque: " + blockingDeque.size());
BarCodeUtil.d("blockingDeque: " + blockingDeque.size());
return blockingDeque.size();
}

private synchronized void execute(Runnable runnable) {
Expand Down Expand Up @@ -78,7 +79,7 @@ private synchronized void promoteCalls() {

public synchronized void cancelAll() {
for (Runnable runnable : blockingDeque) {
((ProcessRunnable)runnable).cancel();
((ProcessRunnable) runnable).cancel();
}
blockingDeque.clear();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ void cancel() {
mBarcodeProcessor.cancel();
}

public void enqueue() {
dispatcher.enqueue(this);
public int enqueue() {
return dispatcher.enqueue(this);
}
}
47 changes: 33 additions & 14 deletions czxing/src/main/java/me/devilsen/czxing/view/BarCoderView.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ abstract class BarCoderView extends FrameLayout implements Camera.PreviewCallbac

private static final int NO_CAMERA_ID = -1;
private static final int DEFAULT_ZOOM_SCALE = 4;
private static final long ONE_HUNDRED_MILLISECONDS = 100_000_000;
private final static long DELAY_STEP_TIME = 20000000;

private int mCameraId = Camera.CameraInfo.CAMERA_FACING_BACK;
private Camera mCamera;
Expand All @@ -34,12 +36,14 @@ abstract class BarCoderView extends FrameLayout implements Camera.PreviewCallbac

protected boolean mSpotAble;
private int scanSequence;
private long processLastTime;
private long mLastAutoZoomTime;

protected ScanListener mScanListener;
private ValueAnimator mAutoZoomAnimator;

private long processLastTime;
private long mLastAutoZoomTime;
private long mDelayTime = 3 * ONE_HUNDRED_MILLISECONDS;

public BarCoderView(Context context) {
this(context, null);
}
Expand Down Expand Up @@ -75,7 +79,7 @@ protected void onLayout(boolean changed, int left, int top, int right, int botto
@Override
public void onPreviewFrame(byte[] data, Camera camera) {
long now = System.nanoTime();
if (Math.abs(now - processLastTime) < 300000000) {
if (Math.abs(now - processLastTime) < mDelayTime) {
return;
}
processLastTime = now;
Expand All @@ -88,19 +92,15 @@ public void onPreviewFrame(byte[] data, Camera camera) {

int left;
int top;
int rowWidth;
int rowHeight;
int rowWidth = size.width;
int rowHeight = size.height;
// 这里需要把得到的数据也翻转
if (CameraUtil.isPortrait(getContext())) {
left = scanBoxRect.top;
top = scanBoxRect.left;
rowWidth = size.width;
rowHeight = size.height;
} else {
left = scanBoxRect.left;
top = scanBoxRect.top;
rowWidth = size.height;
rowHeight = size.width;
}
onPreviewFrame(data, left, top, scanBoxSize, scanBoxSize, rowWidth);

Expand Down Expand Up @@ -280,7 +280,7 @@ private void handleAutoZoom(int len) {

int scanBoxWidth = mScanBoxView.getScanBoxSize();
if (len > scanBoxWidth / DEFAULT_ZOOM_SCALE) {
if (mAutoZoomAnimator.isRunning()) {
if (mAutoZoomAnimator != null && mAutoZoomAnimator.isRunning()) {
mAutoZoomAnimator.cancel();
}
return;
Expand All @@ -290,7 +290,7 @@ private void handleAutoZoom(int len) {
return;
}

if (System.currentTimeMillis() - mLastAutoZoomTime < 500) {
if (System.currentTimeMillis() - mLastAutoZoomTime < 450) {
return;
}

Expand All @@ -301,11 +301,13 @@ private void handleAutoZoom(int len) {

// 二维码在扫描框中的宽度小于扫描框的 1/4,放大镜头
final int maxZoom = parameters.getMaxZoom();
// 在一些低端机上放太大,可能会造成画面过于模糊,无法识别
final int maxCanZoom = maxZoom * 3 / 4;
final int zoomStep = maxZoom / 4;
final int zoom = parameters.getZoom();
BarCodeUtil.e(maxZoom + " " + zoom + " " + len);
BarCodeUtil.e("maxZoom: " + maxZoom + " maxCanZoom:" + maxCanZoom + " current: " + zoom + " len:" + len);

ExecutorUtil.runOnUiThread(() -> startAutoZoom(zoom, Math.min(zoom + zoomStep, maxZoom)));
ExecutorUtil.runOnUiThread(() -> startAutoZoom(zoom, Math.min(zoom + zoomStep, maxCanZoom)));
}


Expand All @@ -320,7 +322,7 @@ private void startAutoZoom(int oldZoom, int newZoom) {
parameters.setZoom(zoom);
mCamera.setParameters(parameters);
});
mAutoZoomAnimator.setDuration(450);
mAutoZoomAnimator.setDuration(420);
mAutoZoomAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
mAutoZoomAnimator.start();
mLastAutoZoomTime = System.currentTimeMillis();
Expand All @@ -334,6 +336,23 @@ protected void onDetachedFromWindow() {
}
}

/**
* 设置时间回调处理间隔
*
* @param queueSize 阻塞线程中正在处理的线程数
*/
void setQueueSize(int queueSize) {
if (queueSize == 0 && mDelayTime > ONE_HUNDRED_MILLISECONDS) {
mDelayTime -= DELAY_STEP_TIME;
}

if (queueSize > 1) {
mDelayTime += DELAY_STEP_TIME;
}

BarCodeUtil.d("delay time : " + mDelayTime / 1000000);
}

public void onDestroy() {
closeCamera();
mScanListener = null;
Expand Down
3 changes: 2 additions & 1 deletion czxing/src/main/java/me/devilsen/czxing/view/ScanView.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ public void onPreviewFrame(byte[] data, int left, int top, int width, int height
return;
}
// SaveImageUtil.saveData(data, left, top, width, height, rowWidth);
mDispatcher.newRunnable(data, left, top, width, height, rowWidth, this).enqueue();
int queueSize = mDispatcher.newRunnable(data, left, top, width, height, rowWidth, this).enqueue();
setQueueSize(queueSize);
// BarcodeReader.Result result = reader.read(data, left, top, width, height, rowWidth);
//
// if (result != null) {
Expand Down
4 changes: 2 additions & 2 deletions sample/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ android {

dependencies {

// implementation project(':czxing')
implementation 'me.devilsen:CZXing:0.3'
implementation project(':czxing')
// implementation 'me.devilsen:CZXing:0.3'

implementation rootProject.ext.appcompat
testImplementation rootProject.ext.junit
Expand Down
24 changes: 20 additions & 4 deletions sample/src/main/java/me/sam/czxing/WriteCodeActivity.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package me.sam.czxing;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.os.Bundle;
import android.widget.ImageView;

Expand All @@ -25,13 +27,27 @@ protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_write_code);

ImageView imageView = findViewById(R.id.image_view_qr_code);
ImageView qrcodeImage = findViewById(R.id.image_view_qr_code_1);
ImageView qrcodeLogoImage = findViewById(R.id.image_view_qr_code_2);

BarcodeWriter reader = new BarcodeWriter();
Bitmap bitmap = reader.write("Hello World", BarCodeUtil.dp2px(this, 200), BarCodeUtil.dp2px(this, 200));
Bitmap bitmap1 = reader.write("Hello World",
BarCodeUtil.dp2px(this, 200),
Color.BLACK);

if (bitmap != null) {
imageView.setImageBitmap(bitmap);
Bitmap logoBitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher);

Bitmap bitmap2 = reader.write("Hello World",
BarCodeUtil.dp2px(this, 200),
Color.parseColor("#2196F3"),
logoBitmap);

if (bitmap1 != null) {
qrcodeImage.setImageBitmap(bitmap1);
}

if (bitmap2 != null) {
qrcodeLogoImage.setImageBitmap(bitmap2);
}

}
Expand Down
8 changes: 7 additions & 1 deletion sample/src/main/res/layout/activity_write_code.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,14 @@
android:orientation="vertical">

<ImageView
android:id="@+id/image_view_qr_code"
android:id="@+id/image_view_qr_code_1"
android:layout_width="200dp"
android:layout_height="200dp" />

<ImageView
android:id="@+id/image_view_qr_code_2"
android:layout_width="200dp"
android:layout_height="200dp"
android:layout_marginTop="20dp" />

</LinearLayout>

0 comments on commit c527762

Please sign in to comment.