使用zxing生成&识别二维码

引入依赖

Gradle

implementation 'com.google.zxing:core:3.4.1'

Maven

<dependency>
    <groupId>com.google.zxing</groupId>
    <artifactId>core</artifactId>
    <version>3.4.1</version>
</dependency>

示例代码

import com.google.zxing.*
import com.google.zxing.common.HybridBinarizer
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel
import java.awt.geom.AffineTransform
import java.awt.image.BufferedImage


object QrUtil {
    private val mfw = MultiFormatWriter()
    private val encodeHints = object : HashMap<EncodeHintType, Any>() {
        init {
            put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H)
            put(EncodeHintType.CHARACTER_SET, Charsets.UTF_8)
            put(EncodeHintType.MARGIN, 1)
        }
    }
    
    private val decodeHints = object : HashMap<DecodeHintType, Any>() {
        init {
            put(DecodeHintType.CHARACTER_SET, Charsets.UTF_8)
            //优化精度
            put(DecodeHintType.TRY_HARDER, true)
            //复杂模式,开启PURE_BARCODE模式
            put(DecodeHintType.PURE_BARCODE, true)
        }
    }

    /**
     * 生成二维码
     *
     * 若宽/高小于生成的二维码的最小宽度则会忽略此宽/高度, 否则会生成此宽/高度的二维码图片
     *
     * @param content 正文
     * @param width 目标图片宽度
     * @param height 目标图片高度
     * @param color1 二维码颜色
     * @param color2 二维码背景
     * @return 二维码图片
     */
    @Throws(WriterException::class)
    fun getQrImage(
        content: String,
        width: Int,
        height: Int,
        color1: Int,
        color2: Int,
    ): BufferedImage {
        val bitMatrix = mfw.encode(content, BarcodeFormat.QR_CODE, width, height, encodeHints)
        val w = bitMatrix.width
        val h = bitMatrix.height
        val image = BufferedImage(w, h, 1)
        for (x in 0 until w) for (y in 0 until h) image.setRGB(x, y, if (bitMatrix[x, y]) color1 else color2)
        return image
    }

    /**
     * 识别二维码
     *
     * @param image 要识别的图片
     * @return 识别的结果
     */
    @Throws(NotFoundException::class)
    fun decode(image: BufferedImage): String {
        val source = BufferedImageLuminanceSource(image)
        val bitmap = BinaryBitmap(HybridBinarizer(source))
        return MultiFormatReader().decode(bitmap, decodeHints).text
    }

    class BufferedImageLuminanceSource(
        image: BufferedImage,
        left: Int = 0,
        top: Int = 0,
        width: Int = image.width,
        height: Int = image.height,
    ) :
        LuminanceSource(width, height) {
        private val image: BufferedImage
        private val left: Int
        private val top: Int
        override fun getRow(y: Int, rowBytes: ByteArray): ByteArray {
            var row = rowBytes
            require(!(y < 0 || y >= height)) { "Requested row is outside the image: $y" }
            if (row.size < width) row = ByteArray(width)
            image.raster.getDataElements(left, top + y, width, 1, row)
            return row
        }

        override fun getMatrix(): ByteArray {
            val width = width
            val height = height
            val area = width * height
            val matrix = ByteArray(area)
            image.raster.getDataElements(left, top, width, height, matrix)
            return matrix
        }

        override fun isCropSupported() = true
        override fun crop(left: Int, top: Int, width: Int, height: Int) =
            BufferedImageLuminanceSource(image, this.left + left, this.top + top, width, height)

        override fun isRotateSupported() = true

        override fun rotateCounterClockwise(): LuminanceSource {
            val sourceWidth = image.width
            val sourceHeight = image.height
            val transform = AffineTransform(0.0, -1.0, 1.0, 0.0, 0.0, sourceWidth.toDouble())
            val rotatedImage = BufferedImage(sourceHeight, sourceWidth, BufferedImage.TYPE_BYTE_GRAY)
            val g = rotatedImage.createGraphics()
            g.drawImage(image, transform, null)
            g.dispose()
            val width = width
            return BufferedImageLuminanceSource(rotatedImage, top, sourceWidth - (left + width), height, width)
        }

        init {
            val sourceWidth = image.width
            val sourceHeight = image.height
            require(!(left + width > sourceWidth || top + height > sourceHeight)) { "Crop rectangle does not fit within image data." }
            for (y in top until top + height) {
                for (x in left until left + width) {
                    if (image.getRGB(x, y) and -0x1000000 == 0) {
                        image.setRGB(x, y, -0x1) // = white
                    }
                }
            }
            this.image = BufferedImage(sourceWidth, sourceHeight, BufferedImage.TYPE_BYTE_GRAY)
            this.image.graphics.drawImage(image, 0, 0, null)
            this.left = left
            this.top = top
        }
    }
}
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇