使用Zxing實(shí)現(xiàn)二維碼生成器內(nèi)嵌圖片,具有一定的參考價(jià)值,具體如下:
基本思路是先使用zxing生成的二維碼圖片,然后讀取圖片,在其中插入圖標(biāo),然后整個(gè)輸出圖片。
最近的項(xiàng)目中需要生成二維碼,找了幾個(gè)例子綜合下,做出了最后的效果,二維碼可以生成圖片格式(jpg等)或者在web頁面上顯示,此片文章僅作記錄,雷同之處多多,包涵。。。。
注:需要Zxing包裝的工具類,大概的流程是讀取內(nèi)嵌的圖片,將內(nèi)容轉(zhuǎn)化成二維碼,將圖片內(nèi)嵌到二維碼中,出圖。
下面是完整代碼:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
|
import Java.awt.BasicStroke; import java.awt.Color; import java.awt.Graphics2D; import java.awt.Image; import java.awt.Shape; import java.awt.geom.AffineTransform; import java.awt.geom.RoundRectangle2D; import java.awt.image.AffineTransformOp; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.util.HashMap; import java.util.Map; import javax.imageio.ImageIO; import com.google.zxing.BarcodeFormat; import com.google.zxing.EncodeHintType; import com.google.zxing.MultiFormatWriter; import com.google.zxing.WriterException; import com.google.zxing.common.BitMatrix; import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel; public class Zxing { private static final int BLACK = 0xFF000000 ; private static final int WHITE = 0xFFFFFFFF ; // 圖片寬度的一般 private static final int IMAGE_WIDTH = 80 ; private static final int IMAGE_HEIGHT = 80 ; private static final int IMAGE_HALF_WIDTH = IMAGE_WIDTH / 2 ; private static final int FRAME_WIDTH = 2 ; // 二維碼寫碼器 private static MultiFormatWriter mutiWriter = new MultiFormatWriter(); public static void main(String[] args) { try { //BitMatrix bitMatrix = multiFormatWriter.encode(content, BarcodeFormat.QR_CODE, 400, 400,hints); String content= "13400000000" ; //二維碼的內(nèi)容 BufferedImage image = genBarcode(content, 400 , 400 , "F:\\amazed.png" ); if (!ImageIO.write(image, "jpg" , new File( "F:\\2122.jpg" ))) { throw new IOException( "Could not write an image of format " ); } /** //將上面的代碼換成此處,使用流讀入到頁面即可 OutputStream os = response.getOutputStream(); if (!ImageIO.write(image, "jpg",os)) { throw new IOException("Could not write an image of format "); } **/ } catch (WriterException e) { e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } private BufferedImage toBufferedImage(BitMatrix matrix) { int width = matrix.getWidth(); int height = matrix.getHeight(); 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, matrix.get(x, y) ? BLACK : WHITE); } } return image; } private static BufferedImage genBarcode(String content, int width, int height, String srcImagePath) throws WriterException, IOException { // 讀取源圖像 BufferedImage scaleImage = scale(srcImagePath, IMAGE_WIDTH, IMAGE_HEIGHT, true ); int [][] srcPixels = new int [IMAGE_WIDTH][IMAGE_HEIGHT]; for ( int i = 0 ; i < scaleImage.getWidth(); i++) { for ( int j = 0 ; j < scaleImage.getHeight(); j++) { srcPixels[i][j] = scaleImage.getRGB(i, j); } } Map<EncodeHintType, Object> hint = new HashMap<EncodeHintType, Object>(); hint.put(EncodeHintType.CHARACTER_SET, "utf-8" ); //內(nèi)容編碼 hint.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H); //錯誤等級 hint.put(EncodeHintType.MARGIN, 1 ); //設(shè)置二維碼外邊框的空白區(qū)域的寬度 // 生成二維碼 BitMatrix matrix = mutiWriter.encode(content, BarcodeFormat.QR_CODE, width, height, hint); // 二維矩陣轉(zhuǎn)為一維像素?cái)?shù)組 int halfW = matrix.getWidth() / 2 ; int halfH = matrix.getHeight() / 2 ; int [] pixels = new int [width * height]; for ( int y = 0 ; y < matrix.getHeight(); y++) { for ( int x = 0 ; x < matrix.getWidth(); x++) { // 讀取圖片 if (x > halfW - IMAGE_HALF_WIDTH && x < halfW + IMAGE_HALF_WIDTH && y > halfH - IMAGE_HALF_WIDTH && y < halfH + IMAGE_HALF_WIDTH) { pixels[y * width + x] = srcPixels[x - halfW + IMAGE_HALF_WIDTH][y - halfH + IMAGE_HALF_WIDTH]; } // 在圖片四周形成邊框 else if ((x > halfW - IMAGE_HALF_WIDTH - FRAME_WIDTH && x < halfW - IMAGE_HALF_WIDTH + FRAME_WIDTH && y > halfH - IMAGE_HALF_WIDTH - FRAME_WIDTH && y < halfH + IMAGE_HALF_WIDTH + FRAME_WIDTH) || (x > halfW + IMAGE_HALF_WIDTH - FRAME_WIDTH && x < halfW + IMAGE_HALF_WIDTH + FRAME_WIDTH && y > halfH - IMAGE_HALF_WIDTH - FRAME_WIDTH && y < halfH + IMAGE_HALF_WIDTH + FRAME_WIDTH) || (x > halfW - IMAGE_HALF_WIDTH - FRAME_WIDTH && x < halfW + IMAGE_HALF_WIDTH + FRAME_WIDTH && y > halfH - IMAGE_HALF_WIDTH - FRAME_WIDTH && y < halfH - IMAGE_HALF_WIDTH + FRAME_WIDTH) || (x > halfW - IMAGE_HALF_WIDTH - FRAME_WIDTH && x < halfW + IMAGE_HALF_WIDTH + FRAME_WIDTH && y > halfH + IMAGE_HALF_WIDTH - FRAME_WIDTH && y < halfH + IMAGE_HALF_WIDTH + FRAME_WIDTH)) { pixels[y * width + x] = 0xfffffff ; } else { // 此處可以修改二維碼的顏色,可以分別制定二維碼和背景的顏色; pixels[y * width + x] = matrix.get(x, y) ? 0xff000000 : 0xfffffff ; } } } BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); image.getRaster().setDataElements( 0 , 0 , width, height, pixels); return image; } /** * 把傳入的原始圖像按高度和寬度進(jìn)行縮放,生成符合要求的圖標(biāo) * * @param srcImageFile * 源文件地址 * @param height * 目標(biāo)高度 * @param width * 目標(biāo)寬度 * @param hasFiller * 比例不對時(shí)是否需要補(bǔ)白:true為補(bǔ)白; false為不補(bǔ)白; * @throws IOException */ private static BufferedImage scale(String srcImageFile, int height, int width, boolean hasFiller) throws IOException { double ratio = 0.0 ; // 縮放比例 File file = new File(srcImageFile); BufferedImage srcImage = ImageIO.read(file); Image destImage = srcImage.getScaledInstance(width, height, BufferedImage.SCALE_SMOOTH); // 計(jì)算比例 if ((srcImage.getHeight() > height) || (srcImage.getWidth() > width)) { if (srcImage.getHeight() > srcImage.getWidth()) { ratio = ( new Integer(height)).doubleValue() / srcImage.getHeight(); } else { ratio = ( new Integer(width)).doubleValue() / srcImage.getWidth(); } AffineTransformOp op = new AffineTransformOp( AffineTransform.getScaleInstance(ratio, ratio), null ); destImage = op.filter(srcImage, null ); } if (hasFiller) { // 補(bǔ)白 BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); Graphics2D graphic = image.createGraphics(); graphic.setColor(Color.PINK); graphic.fillRect( 10 , 10 , width, height); graphic.drawRect( 100 , 360 , width, height); if (width == destImage.getWidth( null )) { graphic.drawImage(destImage, 0 , (height - destImage.getHeight( null )) / 2 , destImage.getWidth( null ), destImage.getHeight( null ), Color.white, null ); Shape shape = new RoundRectangle2D.Float( 0 , (height - destImage.getHeight( null )) / 2 , width, width, 20 , 20 ); graphic.setStroke( new BasicStroke(5f)); graphic.draw(shape); } else { graphic.drawImage(destImage, (width - destImage.getWidth( null )) / 2 , 0 , destImage.getWidth( null ), destImage.getHeight( null ), Color.white, null ); Shape shape = new RoundRectangle2D.Float((width - destImage.getWidth( null )) / 2 , 0 , width, width, 20 , 20 ); graphic.setStroke( new BasicStroke(5f)); graphic.draw(shape); } graphic.dispose(); destImage = image; } return (BufferedImage) destImage; } } |
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持服務(wù)器之家。