diff --git a/sample/src/main/java/com/mylhyl/zxing/scanner/sample/MainActivity.java b/sample/src/main/java/com/mylhyl/zxing/scanner/sample/MainActivity.java index 9a0c9cb..cb8e8de 100644 --- a/sample/src/main/java/com/mylhyl/zxing/scanner/sample/MainActivity.java +++ b/sample/src/main/java/com/mylhyl/zxing/scanner/sample/MainActivity.java @@ -25,6 +25,7 @@ import com.google.zxing.client.result.ParsedResultType; import com.mylhyl.zxing.scanner.common.Scanner; import com.mylhyl.zxing.scanner.encode.QREncode; +import com.mylhyl.zxing.scanner.encode.QRLogoBorderType; import java.io.ByteArrayOutputStream; @@ -130,8 +131,9 @@ public void onClick(View v) { // R.mipmap.connect_logo) R.mipmap.wb_wlog_blow_bg_night) ) - .setLogoBorder(10) + .setLogoBorder(20) .setLogoBorderColor(Color.GREEN) + .setLogoBorderType(QRLogoBorderType.CIRCLE) .build() .encodeAsBitmap(); imageView.setImageBitmap(bitmap); diff --git a/zxingscanner/src/main/java/com/mylhyl/zxing/scanner/encode/QRCodeEncoder.java b/zxingscanner/src/main/java/com/mylhyl/zxing/scanner/encode/QRCodeEncoder.java index 5fd596b..a2261bd 100644 --- a/zxingscanner/src/main/java/com/mylhyl/zxing/scanner/encode/QRCodeEncoder.java +++ b/zxingscanner/src/main/java/com/mylhyl/zxing/scanner/encode/QRCodeEncoder.java @@ -23,7 +23,10 @@ import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.Point; +import android.graphics.PorterDuff; +import android.graphics.PorterDuffXfermode; import android.graphics.Rect; +import android.graphics.RectF; import android.net.Uri; import android.os.Bundle; import android.provider.ContactsContract; @@ -57,6 +60,44 @@ final class QRCodeEncoder { private Context context; private QREncode.Builder encodeBuild; + private static Bitmap getRoundedBitmap(Bitmap bitmap, float roundPx, int color) { + Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888); + Canvas canvas = new Canvas(output); + + final Paint paint = new Paint(); + final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight()); + final RectF rectF = new RectF(rect); + + paint.setAntiAlias(true); + canvas.drawARGB(0, 0, 0, 0); + paint.setColor(color); + canvas.drawRoundRect(rectF, roundPx, roundPx, paint); + + paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN)); + canvas.drawBitmap(bitmap, rect, rect, paint); + + return output; + } + + private static Bitmap getCircleBitmap(Bitmap bitmap, int color) { + Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888); + Canvas canvas = new Canvas(output); + + final Paint paint = new Paint(); + final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight()); + final RectF rectF = new RectF(rect); + + paint.setAntiAlias(true); + canvas.drawARGB(0, 0, 0, 0); + paint.setColor(color); + canvas.drawOval(rectF, paint); + + paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN)); + canvas.drawBitmap(bitmap, rect, rect, paint); + + return output; + } + QRCodeEncoder(QREncode.Builder build, Context context) { this.context = context; this.encodeBuild = build; @@ -144,18 +185,41 @@ private Bitmap addLogo(Bitmap src) { Bitmap bitmapLogo = Bitmap.createBitmap(srcLogo, 0, 0, logoWidth, logoHeight, matrix, false); float logoBorder = encodeBuild.getLogoBorder(); - // 先画边框 + // 先画边框 if (logoBorder > 0) { - int logoBorderColor = encodeBuild.getLogoBorderColor(); + int borderColor = encodeBuild.getLogoBorderColor() == -1 ? Color.WHITE : encodeBuild.getLogoBorderColor(); Bitmap borderBitmap = Bitmap.createBitmap((int) (bitmapLogo.getWidth() + logoBorder), (int) (bitmapLogo.getHeight() + logoBorder), Bitmap.Config.ARGB_8888); - Canvas canvasLogoBorder = new Canvas(borderBitmap); - canvasLogoBorder.drawBitmap(srcLogo, 0, 0, null); + Canvas borderCanvas = new Canvas(borderBitmap); + borderCanvas.drawARGB(0, 0, 0, 0); + + Paint borderPaint = new Paint(); + borderPaint.setAntiAlias(true); + borderPaint.setColor(borderColor); + + QRLogoBorderType logoBorderType = encodeBuild.getLogoBorderType(); + Rect rectBorder = borderCanvas.getClipBounds(); + // 矩形 + if (logoBorderType == QRLogoBorderType.RECTANGLE) { + borderCanvas.drawRect(rectBorder, borderPaint); + } + // 圆形 + else if (logoBorderType == QRLogoBorderType.CIRCLE) { + borderCanvas.drawOval(new RectF(rectBorder), borderPaint); + borderPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN)); + + bitmapLogo = getCircleBitmap(bitmapLogo, borderColor); + } + // 圆角矩形 + else { + float logoBorderRadius = encodeBuild.getLogoBorderRadius(); + borderCanvas.drawRoundRect(new RectF(rectBorder), logoBorderRadius, logoBorderRadius, borderPaint); + borderPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN)); + + // 原logo图片也画成圆角 + bitmapLogo = getRoundedBitmap(bitmapLogo, logoBorderRadius, borderColor); + } - Rect rect = canvasLogoBorder.getClipBounds(); - Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); - paint.setColor(logoBorderColor == -1 ? Color.WHITE : logoBorderColor); - canvasLogoBorder.drawRect(rect, paint); canvas.drawBitmap(borderBitmap, left - (logoBorder / 2), top - (logoBorder / 2), null); if (!borderBitmap.isRecycled()) { borderBitmap.recycle(); diff --git a/zxingscanner/src/main/java/com/mylhyl/zxing/scanner/encode/QREncode.java b/zxingscanner/src/main/java/com/mylhyl/zxing/scanner/encode/QREncode.java index 9278dd8..d8ade75 100644 --- a/zxingscanner/src/main/java/com/mylhyl/zxing/scanner/encode/QREncode.java +++ b/zxingscanner/src/main/java/com/mylhyl/zxing/scanner/encode/QREncode.java @@ -87,6 +87,8 @@ public static class Builder { private int logoSize; private float logoBorder; private int logoBorderColor = -1; + private QRLogoBorderType logoBorderType = QRLogoBorderType.ROUNDED; + private float logoBorderRadius = 30f; private Bitmap qrBackground; private int qrBackgroundColor; private int margin = 4; @@ -285,6 +287,38 @@ public Builder setLogoBorderColor(int color) { return this; } + QRLogoBorderType getLogoBorderType() { + return logoBorderType; + } + + /** + * 二维码logo边框类型 + * + * @param type 矩形,圆角矩形,圆形 + * @return + * @since 2.1.8 + */ + public Builder setLogoBorderType(QRLogoBorderType type) { + this.logoBorderType = type; + return this; + } + + float getLogoBorderRadius() { + return logoBorderRadius; + } + + /** + * 二维码logo边框圆角矩形半径 + * + * @param radius 圆角半径,默认30 + * @return + * @since 2.1.8 + */ + public Builder setLogoBorderRadius(float radius) { + this.logoBorderRadius = radius; + return this; + } + /** * @return * @deprecated {@link #build()} diff --git a/zxingscanner/src/main/java/com/mylhyl/zxing/scanner/encode/QRLogoBorderType.java b/zxingscanner/src/main/java/com/mylhyl/zxing/scanner/encode/QRLogoBorderType.java new file mode 100644 index 0000000..76dbb64 --- /dev/null +++ b/zxingscanner/src/main/java/com/mylhyl/zxing/scanner/encode/QRLogoBorderType.java @@ -0,0 +1,28 @@ +package com.mylhyl.zxing.scanner.encode; + +/** + * Created by hupei on 2020/11/20. + *

+ * 功能描述:二维码logo边框枚举类型 + * + *

+ * + * + * + * + * + * @author hupei + * @since 2.1.8 + */ +public enum QRLogoBorderType { + RECTANGLE, ROUNDED, CIRCLE +}