生活随笔
收集整理的這篇文章主要介紹了
java制作带有logo的二维码,解决zxing中文乱码
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
目標
使用谷歌zxing生成帶有logo二維碼便捷地解決二維碼中文亂碼問題
過程
下載依賴:
maven坐標:
<dependency><groupId>com.google.zxing
</groupId><artifactId>core
</artifactId><version>3.3.3
</version>
</dependency>
編寫java代碼生成二維碼,并繪制logo
public static void drawQrCode(String qrUrl
, String logoUrl
, String outputPath
, String note
, int width
, int height
) throws Exception{MultiFormatWriter multiFormatWriter
= new MultiFormatWriter();BitMatrix bitMatrix
= multiFormatWriter
.encode(qrUrl
, BarcodeFormat.QR_CODE
, width
, height
, new HashMap<EncodeHintType, Object>() {private static final long serialVersionUID
= 1L;{put(EncodeHintType.ERROR_CORRECTION
, ErrorCorrectionLevel.H);put(EncodeHintType.CHARACTER_SET
, "UTF-8");put(EncodeHintType.MARGIN
, 0);}});BufferedImage image
= new BufferedImage(width
, height
, BufferedImage.TYPE_INT_RGB
);for (int x
= 0; x
< width
; x
++) {for (int y
= 0; y
< height
; y
++) {image
.setRGB(x
, y
, bitMatrix
.get(x
, y
) ? 0xFF000000 : 0xFFFFFFFF);}}if (logoUrl
!= null && !"".equals(logoUrl
) ){Graphics2D graphics
= image
.createGraphics();BufferedImage logoImg
= ImageIO.read( new URL(logoUrl
) );graphics
.drawImage(logoImg
, width
* 2 / 6, height
* 2 / 6, width
* 3 / 10, height
* 3 / 10, null);graphics
.dispose();logoImg
.flush();}if (note
!= null && !"".equals(note
)){BufferedImage outImage
= new BufferedImage(width
, height
+ 45, BufferedImage.TYPE_4BYTE_ABGR
);Graphics2D outGraphics
= outImage
.createGraphics();outGraphics
.drawImage(image
, 0, 0, image
.getWidth(), image
.getHeight(), null);outGraphics
.setColor(Color.BLACK
);outGraphics
.setFont( new Font("Arial", Font.BOLD
, 26) );int noteWidth
= outGraphics
.getFontMetrics().stringWidth(note
);outGraphics
.drawString(new QrCodeAttributedCharacter(note
), (width
- noteWidth
) / 2, image
.getHeight() + (outImage
.getHeight() - image
.getHeight()) / 2 + 12);outGraphics
.dispose();outImage
.flush();image
= outImage
;}image
.flush();ImageIO.write(image
, "png", Paths.get(outputPath
).toFile());}
編寫QrCodeAttributedCharacter解決中文亂碼問題
public class QrCodeAttributedCharacter implements AttributedCharacterIterator {private int index
;private char[] textChars
;public QrCodeAttributedCharacter(String text
) {this.textChars
= text
.toCharArray();}@Overridepublic int getRunStart() {return 0;}@Overridepublic int getRunStart(Attribute attribute
) {return 0;}@Overridepublic int getRunStart(Set<? extends Attribute> attributes
) {return 0;}@Overridepublic int getRunLimit() {return this.textChars
.length
;}@Overridepublic int getRunLimit(Attribute attribute
) {return this.textChars
.length
;}@Overridepublic int getRunLimit(Set<? extends Attribute> attributes
) {return this.textChars
.length
;}@Overridepublic Map<Attribute, Object> getAttributes() {return Collections.EMPTY_MAP
;}@Overridepublic Object getAttribute(Attribute attribute
) {return Collections.EMPTY_MAP
;}@Overridepublic Set<Attribute> getAllAttributeKeys() {return Collections.EMPTY_SET
;}@Overridepublic char first() {this.index
= 0;return this.textChars
[0];}@Overridepublic char last() {return this.textChars
[ this.textChars
.length
- 1 ];}@Overridepublic char current() {return this.textChars
[this.index
];}@Overridepublic char next() {if (this.index
== this.textChars
.length
- 1){return CharacterIterator.DONE
;}return this.textChars
[ ++this.index
];}@Overridepublic char previous() {if (this.index
== 0){return CharacterIterator.DONE
;}return this.textChars
[this.index
- 1];}@Overridepublic char setIndex(int position
) {this.index
= position
;return textChars
[position
];}@Overridepublic int getBeginIndex() {return 0;}@Overridepublic int getEndIndex() {return this.textChars
.length
;}@Overridepublic int getIndex() {return this.index
;}@Overridepublic Object clone() {return new String(textChars
);}
}
中文亂碼問題分析與解決依據 - 亂碼原因:
通過查看zxing的Encoder類可以發現默認編碼方式是ISO-8859-1。
- 通過新建QrCodeAttributedCharacter類修復亂碼問題原理.
進入Graphics2D的drawString(AttributedCharacterIterator iterator, int x, int y)方法找到其讀取字符串內容邏輯如下:
從圖中可以看出其是通過調用AttributedCharacterIterator的實現類的方法來獲取字符串內容的,因此可以通過實現AttributedCharacterIterator接口來控制獲取的字符串內容。
測試
測試代碼:
public static void main(String[] args
) throws Exception {String qrUrl
= "https://blog.csdn.net/qq_41633199";String logoUrl
= "http://www.finac.site/logo.png";String outputPath
= "B:\\logo.jpg";drawQrCode(qrUrl
, logoUrl
, outputPath
, "博文地址", 400, 400);}
測試結果:
總結
以上是生活随笔為你收集整理的java制作带有logo的二维码,解决zxing中文乱码的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。