当前位置: 首页 >  资讯 >  >  详情
JavaFx 生成二维码工具类封装
2023-04-28 15:29:19    来源:博客园


(资料图片)

原文地址: JavaFx 生成二维码工具类封装 - Stars-One的杂货小窝

之前星之音乐下载器有需要生成二维码功能,当时用的是一个开源库来实现的,但是没过多久,发现那个库依赖太多,有个http-client的依赖,把软件都搞大了一倍,而且有时候开发的时候下载依赖还报错,就想换个方案

于是在网上找了下解决方案,最终只需要依赖两个zxing的两个依赖即可实现功能

本文基于TornadoFx框架进行编写,封装工具代码是kotlin版本,工具类已经封装在common-controls库中

工具支持带logo图标,带底部文本的二维码生成

代码封装1.引入依赖
    com.google.zxing    core    3.5.0    com.google.zxing    javase    3.5.0
2.使用

由于工具代码过多不便阅读,就先讲些使用,工具代码就放下面了

比较核心的就两个方法,如下面代码所示,其他的方法是带Swing关键字,就是生成Swing包中的Image对象

getQRcodeFxImg()方法就是直接生成Fx的Image对象,可以JavaFx中直接使用

/** * 初始化设置 * * @param qrcodeSize 二维码尺寸,默认为320(即320*320) * @param logoSize logo图标尺寸,默认为80(即80*80) * @param bottomTextSize 底部文字大小,默认20px * @param qrcodeType 二维码图片格式,默认为png */fun initConfig(qrcodeSize: Int = 320, logoSize: Int = 80, bottomTextSize: Int = 20, qrcodeType: String = "PNG")/** * 生成二维码图片 * * @param data 二维码文本内容 * @param logoPath 图标图片的路径 * @param bottomText 底部文字 * @return fx的img对象 */fun getQRcodeFxImg(data: String?, logoPath: String?=null, bottomText: String?=null): WritableImage

使用的话也比较简单:

//得到的swing的image对象val buImg = QRCodeUtil.getQRcodeFxImg("这是测试文本")val buImg1 = QRCodeUtil.getQRcodeFxImg("这是测试文本", null, "底部文字")val buImg2 = QRCodeUtil.getQRcodeFxImg("这是测试文本", "/x5.jpg", "底部文字")val list = listOf(buImg, buImg1, buImg2)hbox(20.0) {    list.forEach {        imageview(it) {            fitWidth = 200.0            fitHeight = 200.0        }    }}
3.工具库代码
/** * 二维码生成工具类 * Created by stars-one */object QRCodeUtil {    private var QRCODE_SIZE = 320 // 二维码尺寸,宽度和高度均是320    private var LOGO_SIZE = 80 // 二维码里logo的尺寸,宽高一致 80*80    private var BOTTOM_TEXT_SIZE = 20 // 底部文本的文字大小    private var FORMAT_TYPE = "PNG" // 二维码图片类型    /**     * 初始化设置     *     * @param qrcodeSize 二维码尺寸,默认为320(即320*320)     * @param logoSize logo图标尺寸,默认为80(即80*80)     * @param bottomTextSize 底部文字大小,默认20px     * @param qrcodeType 二维码图片格式,默认为png     */    fun initConfig(qrcodeSize: Int = 320, logoSize: Int = 80, bottomTextSize: Int = 20, qrcodeType: String = "PNG") {        QRCODE_SIZE = qrcodeSize        LOGO_SIZE = logoSize        BOTTOM_TEXT_SIZE = bottomTextSize        FORMAT_TYPE = qrcodeType    }    /**     * 生成二维码图片     *     * @param data 二维码文本内容     * @param logoPath 图标图片的路径     * @param bottomText 底部文字     * @return     */    fun getQRcodeFxImg(data: String?, logoPath: String?=null, bottomText: String?=null): WritableImage {        val resources = ResourceLookup(this)        val url = if (logoPath == null) {            null        } else {            resources.url(logoPath)        }        val swingImg = getQRCodeSwingImg(data, url, bottomText)        return SwingFXUtils.toFXImage(swingImg,null)    }    /**     * 默认需要logo,无底部文字     * 返回 BufferedImage 可以使用ImageIO.write(BufferedImage, "png", outputStream);输出     *     * @param dataStr     * @return 返回 BufferedImage 可以使用ImageIO.write(BufferedImage, "png", outputStream);输出     */    @Throws(Exception::class)    fun getQRCodeSwingImg(dataStr: String?): BufferedImage {        return getQRCodeSwingImg(dataStr, null, null)    }    /**     * 默认需要logo,无底部文字     *     * @param dataStr     * @return 返回字节数组     */    @Throws(Exception::class)    fun getQRCodeByte(dataStr: String?): ByteArray {        val bufferedImage = getQRCodeSwingImg(dataStr, null, null)        val outputStream = ByteArrayOutputStream()        ImageIO.write(bufferedImage, FORMAT_TYPE, outputStream)        return outputStream.toByteArray()    }    /**     * 默认需要logo,包含底部文字 文字为空则不显示文字     * 返回 BufferedImage 可以使用ImageIO.write(BufferedImage, "png", outputStream);输出     *     * @param dataStr     * @return     */    @Throws(Exception::class)    fun getQRCodeSwingImg(dataStr: String?, bottomText: String?): BufferedImage {        return getQRCodeSwingImg(dataStr, null, bottomText)    }    /**     * 默认需要logo,包含底部文字 文字为空则不显示文字     *     * @param dataStr     * @return 返回字节数组     */    @Throws(Exception::class)    fun getQRCodeByte(dataStr: String?, bottomText: String?): ByteArray {        val bufferedImage = getQRCodeSwingImg(dataStr, null, bottomText)        val outputStream = ByteArrayOutputStream()        ImageIO.write(bufferedImage, FORMAT_TYPE, outputStream)        return outputStream.toByteArray()    }    /**     * 获取二维码图片     *     * @param dataStr    二维码内容     * @param needLogo   是否需要添加logo     * @param bottomText 底部文字       为空则不显示     * @return     */    @Throws(Exception::class)    fun getQRCodeSwingImg(dataStr: String?, url: URL?, bottomText: String?): BufferedImage {        if (dataStr == null) {            throw RuntimeException("未包含任何信息")        }        val hints = HashMap()        hints[EncodeHintType.CHARACTER_SET] = "utf-8" //定义内容字符集的编码        hints[EncodeHintType.ERROR_CORRECTION] = ErrorCorrectionLevel.L //定义纠错等级        hints[EncodeHintType.MARGIN] = 1        val qrCodeWriter = QRCodeWriter()        val bitMatrix = qrCodeWriter.encode(dataStr, BarcodeFormat.QR_CODE, QRCODE_SIZE, QRCODE_SIZE, hints)        val width = bitMatrix.width        val height = bitMatrix.height        var tempHeight = height        if (StringUtils.isNotBlank(bottomText)) {            tempHeight = tempHeight + 12        }        val image = BufferedImage(width, tempHeight, BufferedImage.TYPE_INT_RGB)        for (x in 0 until width) {            for (y in 0 until height) {                image.setRGB(x, y, if (bitMatrix[x, y]) -0x1000000 else -0x1)            }        }        // 判断是否添加logo        if (url != null) {            insertLogoImage(image, url)        }        // 判断是否添加底部文字        if (StringUtils.isNotBlank(bottomText)) {            addFontImage(image, bottomText)        }        return image    }    /**     * 插入logo图片     *     * @param source 二维码图片     * @throws Exception     */    @Throws(Exception::class)    private fun insertLogoImage(source: BufferedImage, url: URL) {        var src: Image = ImageIO.read(url)        val width = LOGO_SIZE        val height = LOGO_SIZE        val image = src.getScaledInstance(width, height, Image.SCALE_SMOOTH)        val tag = BufferedImage(width, height, BufferedImage.TYPE_INT_RGB)        val g = tag.graphics        g.drawImage(image, 0, 0, null) // 绘制缩小后的图        g.dispose()        src = image        // 插入LOGO        val graph = source.createGraphics()        val x = (QRCODE_SIZE - width) / 2        val y = (QRCODE_SIZE - height) / 2        graph.drawImage(src, x, y, width, height, null)        val shape: Shape = RoundRectangle2D.Float(x.toFloat(), y.toFloat(), width.toFloat(), width.toFloat(), 6f, 6f)        graph.stroke = BasicStroke(3f)        graph.draw(shape)        graph.dispose()    }    private fun addFontImage(source: BufferedImage, declareText: String?) {        //生成image        val defineWidth = QRCODE_SIZE        val defineHeight = 20        val textImage = BufferedImage(defineWidth, defineHeight, BufferedImage.TYPE_INT_RGB)        val g2 = textImage.graphics as Graphics2D        //开启文字抗锯齿        g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON)        g2.background = Color.WHITE        g2.clearRect(0, 0, defineWidth, defineHeight)        g2.paint = Color.BLACK        val context = g2.fontRenderContext        //部署linux需要注意 linux无此字体会显示方块        val font = Font("宋体", Font.BOLD, BOTTOM_TEXT_SIZE)        g2.font = font        val lineMetrics = font.getLineMetrics(declareText, context)        val fontMetrics: FontMetrics = FontDesignMetrics.getMetrics(font)        val offset = ((defineWidth - fontMetrics.stringWidth(declareText)) / 2).toFloat()        val y = (defineHeight + lineMetrics.ascent - lineMetrics.descent - lineMetrics.leading) / 2        g2.drawString(declareText, offset.toInt(), y.toInt())        val graph = source.createGraphics()        //开启文字抗锯齿        graph.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON)        //添加image        val width = textImage.getWidth(null)        val height = textImage.getHeight(null)        val src: Image = textImage        graph.drawImage(src, 0, QRCODE_SIZE - 8, width, height, Color.WHITE, null)        graph.dispose()    }}

关键词:

上一篇:米游社封禁了怎么解封_环球时快讯
下一篇:最后一页