如何将二维码中的3个方块圈换成使用Paint Android使用zxing定制二维码? [英] how to replace 3 squares to circle in QR Code to using paint android to customize QR code using zxing?

查看:26
本文介绍了如何将二维码中的3个方块圈换成使用Paint Android使用zxing定制二维码?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我用它作为参考来定制(从正方形到圆形,使用zxing生成的二维码它是在Java中生成的,所以我尝试将其转换为在Android中使用

Generate QR codes with custom dot shapes using zxing 我在这里发布了我从Java转换为Android的代码


/*    width = 300,
      height =300,
      quiet zone= 4;
*/
    private Bitmap createQRCode2(String text, int width, int height, int quietZone) throws WriterException, IOException {
        final Map<EncodeHintType, Object> encodingHints = new HashMap<>();
        encodingHints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
        QRCode code = Encoder.encode(text, ErrorCorrectionLevel.H, encodingHints);
        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 outputWidth = Math.max(width, qrWidth);
        int outputHeight = Math.max(height, qrHeight);
        int multiple = Math.min(outputWidth / qrWidth, outputHeight / qrHeight);
        int leftPadding = (outputWidth - (inputWidth * multiple)) / 2;
        int topPadding = (outputHeight - (inputHeight * multiple)) / 2;
        final int FINDER_PATTERN_SIZE = 7;
        final float CIRCLE_SCALE_DOWN_FACTOR = 21f / 30f;
        int circleSize = (int) (multiple * CIRCLE_SCALE_DOWN_FACTOR);

        Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap);
        Paint paint = new Paint();
        paint.setStyle(Paint.Style.FILL);
        paint.setColor(Color.WHITE);
        paint.setAntiAlias(true);
        canvas.drawRect(0, 0, width, height, paint);
        paint.setColor(BLUE);

        for (int inputY = 0, outputY = topPadding; inputY < inputHeight; inputY++, outputY += multiple) {
            for (int inputX = 0, outputX = leftPadding; inputX < inputWidth; inputX++, outputX += multiple) {
                if (input.get(inputX, inputY) == 1) {
                    if (!(inputX <= FINDER_PATTERN_SIZE && inputY <= FINDER_PATTERN_SIZE ||
                            inputX >= inputWidth - FINDER_PATTERN_SIZE && inputY <= FINDER_PATTERN_SIZE ||
                            inputX <= FINDER_PATTERN_SIZE && inputY >= inputHeight - FINDER_PATTERN_SIZE)) {
//                        graphics.fillOval(outputX, outputY, circleSize, circleSize);
                        canvas.drawCircle(outputX, outputY, circleSize, paint);
                    }
                }
            }
        }
        int circleDiameter = (multiple * FINDER_PATTERN_SIZE);
        drawFinderPatternCircleStyle1(canvas, leftPadding, topPadding, circleDiameter, paint);
        drawFinderPatternCircleStyle1(canvas, leftPadding + (inputWidth - FINDER_PATTERN_SIZE) * multiple, topPadding, circleDiameter, paint);
        drawFinderPatternCircleStyle1(canvas, leftPadding, topPadding + (inputHeight - FINDER_PATTERN_SIZE) * multiple, circleDiameter, paint);
        return bitmap;
    }
 private static void drawFinderPatternCircleStyle1(Canvas canvas, int x, int y, int circleDiameter, Paint paint) {
        final int WHITE_CIRCLE_DIAMETER = circleDiameter * 5 / 7;
        final int WHITE_CIRCLE_OFFSET = circleDiameter / 7;
        final int MIDDLE_DOT_DIAMETER = circleDiameter * 3 / 7;
        final int MIDDLE_DOT_OFFSET = circleDiameter * 2 / 7;
/*
       below is  java code  which uses graphics to draw oval in andorid graphics2D and awt is not
       available so I have drawn circle using canvas and paint
*/

//        graphics.setColor(Color.black);
//        graphics.fillOval(x, y, circleDiameter, circleDiameter);
//        graphics.setColor(Color.white);
//        graphics.fillOval(x + WHITE_CIRCLE_OFFSET, y + WHITE_CIRCLE_OFFSET, WHITE_CIRCLE_DIAMETER, WHITE_CIRCLE_DIAMETER);
//        graphics.setColor(Color.black);
//        graphics.fillOval(x + MIDDLE_DOT_OFFSET, y + MIDDLE_DOT_OFFSET, MIDDLE_DOT_DIAMETER, MIDDLE_DOT_DIAMETER);

 /*
       code that i have chnanged from above to covert from java to android
*/
        paint.setColor(Color.BLACK);
        canvas.drawCircle(x, y, circleDiameter, paint);
        paint.setColor(WHITE);
        canvas.drawCircle(x + WHITE_CIRCLE_OFFSET, y + WHITE_CIRCLE_OFFSET, WHITE_CIRCLE_DIAMETER, paint);
        paint.setColor(BLUE);
        canvas.drawCircle(x + MIDDLE_DOT_OFFSET, y + MIDDLE_DOT_OFFSET, MIDDLE_DOT_DIAMETER, paint);
    }

如果我使用canvar.draOval(),它会获取左上、下、右三个值,其中我只有两个值,所以我有 用过的圆 实际绘制了内部圆圈,但有三个圆圈没有正确显示为链接 在这里发布我得到的图像日志结果

推荐答案

删除WHITE_CIRCLE_OFFSETMIDDLE_DOT_OFFSET

    paint.setColor(Color.BLACK);
    canvas.drawCircle(x + circleDiameter / 1.5f, y + circleDiameter / 1.5f, circleDiameter, paint);
    paint.setColor(WHITE);
    canvas.drawCircle(x + circleDiameter / 1.5f, y + circleDiameter / 1.5f, WHITE_CIRCLE_DIAMETER, paint);
    paint.setColor(BLUE);
    canvas.drawCircle(x + circleDiameter / 1.5f, y + circleDiameter / 1.5f, MIDDLE_DOT_DIAMETER, paint);

以下是kotlin

中的完整代码
@Throws(WriterException::class, IOException::class)
private fun roundedQRGenerator() {

    CoroutineScope(IO).launch {

        val hints = hashMapOf<EncodeHintType, Int>().also { it[EncodeHintType.MARGIN] = 1 } // Make the QR code buffer border narrower
        val code = Encoder.encode(data, ErrorCorrectionLevel.H, hints)
        val input = code.matrix ?: throw java.lang.IllegalStateException()

        val width = 900
        val height = 900
        val quietZone = 2

        val inputWidth = input.width
        val inputHeight = input.height
        val qrWidth = inputWidth + quietZone * 2
        val qrHeight = inputHeight + quietZone * 2
        val outputWidth = width.coerceAtLeast(qrWidth)
        val outputHeight = height.coerceAtLeast(qrHeight)
        val multiple = (outputWidth / qrWidth).coerceAtMost(outputHeight / qrHeight)
        val leftPadding = (outputWidth - inputWidth * multiple) / 2
        val topPadding = (outputHeight - inputHeight * multiple) / 2
        val FINDER_PATTERN_SIZE = 7
        val CIRCLE_SCALE_DOWN_FACTOR = 21f / 30f
        val circleSize = (multiple * CIRCLE_SCALE_DOWN_FACTOR).toInt()

        val bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
        val canvas = Canvas(bitmap)
        val paint = Paint()
        paint.style = Paint.Style.FILL
        paint.color = WHITE
        paint.isAntiAlias = true
        canvas.drawRect(0f, 0f, width.toFloat(), height.toFloat(), paint)
        var color = BLACK
        val background: Drawable = binding.roundedBgSetter.background
        if (background is ColorDrawable) {
            color = background.color
        }
        paint.color = color

        var inputY = 0
        var outputY = topPadding
        while (inputY < inputHeight) {
            var inputX = 0
            var outputX = leftPadding
            while (inputX < inputWidth) {
                if (input[inputX, inputY].toInt() == 1) {
                    if (!(inputX <= FINDER_PATTERN_SIZE && inputY <= FINDER_PATTERN_SIZE || inputX >= inputWidth - FINDER_PATTERN_SIZE && inputY <= FINDER_PATTERN_SIZE || inputX <= FINDER_PATTERN_SIZE && inputY >= inputHeight - FINDER_PATTERN_SIZE)) {
                        canvas.drawCircle(
                            outputX.toFloat(),
                            outputY.toFloat(),
                            circleSize * 0.6f,
                            paint
                        )
                    }
                }
                inputX++
                outputX += multiple
            }
            inputY++
            outputY += multiple
        }

        val circleDiameter = multiple * FINDER_PATTERN_SIZE / 1.8f
        drawFinderPatternCircleStyle1(canvas, leftPadding, topPadding, circleDiameter, paint)
        drawFinderPatternCircleStyle1(
            canvas,
            leftPadding + circleSize + (inputWidth - FINDER_PATTERN_SIZE) * multiple,
            topPadding,
            circleDiameter,
            paint
        )
        //        drawFinderPatternCircleStyle1(canvas, leftPadding*2-4, ((topPadding*2) + (inputHeight - FINDER_PATTERN_SIZE) * multiple)-8, circleDiameter, paint);
        drawFinderPatternCircleStyle1(
            canvas,
            leftPadding,
            topPadding + circleSize + (inputHeight - FINDER_PATTERN_SIZE) * multiple,
            circleDiameter,
            paint
        )

        withContext(Main){
            binding.qr.setImageBitmap(bitmap)
        }

    }


}

private fun drawFinderPatternCircleStyle1(
    canvas: Canvas,
    x: Int,
    y: Int,
    circleDiameter: Float,
    paint: Paint
) {
    val WHITE_CIRCLE_DIAMETER = circleDiameter * 5 / 7
    val MIDDLE_DOT_DIAMETER = circleDiameter * 3 / 7

    var color = BLACK
    val background: Drawable = binding.roundedBgSetter.background
    if (background is ColorDrawable) {
        color = background.color
    }
    paint.color = color
    canvas.drawCircle(
        x + circleDiameter / 1.5f,
        y + circleDiameter / 1.5f,
        circleDiameter,
        paint
    )
    paint.color = WHITE
    canvas.drawCircle(
        x + circleDiameter / 1.5f,
        y + circleDiameter / 1.5f,
        WHITE_CIRCLE_DIAMETER,
        paint
    )
    paint.color = color
    canvas.drawCircle(
        x + circleDiameter / 1.5f,
        y + circleDiameter / 1.5f,
        MIDDLE_DOT_DIAMETER,
        paint
    )

}

这篇关于如何将二维码中的3个方块圈换成使用Paint Android使用zxing定制二维码?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆