Check-in [c43811222b]

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:QR code work in progress
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | trunk
Files: files | file ages | folders
SHA1:c43811222bfde55f9244a67ef9b7d8b44ea42b20
User & Date: xiekevin 2018-01-25 17:11:44
Context
2018-01-25
17:11
QR code work in progress Leaf check-in: c43811222b user: xiekevin tags: trunk
2018-01-22
05:12
Work in progress of QR code image generation check-in: 8050fa743a user: xiekevin tags: trunk
Changes

Changes to src/fanxi/barcode/Qr.java.

1
2






3
4
5
6




7
8
9
10
11
12
13
..
20
21
22
23
24
25
26





27
28
29
30
31
32
33
..
72
73
74
75
76
77
78
79




80
81
82
83
84
85
86
...
175
176
177
178
179
180
181
182

183
184
185
186
187
188
189
...
628
629
630
631
632
633
634
635










































































































636
637
638
639

640
641
package fanxi.barcode;







import java.util.BitSet;
import java.util.HashMap;
import java.util.Map;





public class Qr {

	public short modulePixes = 3;
	
	protected final String				code;
	protected final Mode				mode;
	protected ErrorCorrectionLevel		level	= ErrorCorrectionLevel.Q; // 25% error correction
................................................................................
	protected final BitStream		finalBitStream; 

	//[numBlocks[data/ec codewords]
	protected int[][][]				codewords;

	public static final String UTF_8_BOM = new String( new char[] {0xEF,0xBB,0xBF} );
	





	// bits is bit string in literal format, ie, 10110101...
	public static BitSet getBitSet(String bits) throws Exception {
		if( bits==null ) throw new Exception("Null input");
		int len = bits.length();
		BitSet bSet = new BitSet(len);
		for(int i=0; i<len; i++) {
			if( bits.charAt(i)=='1' ) { 
................................................................................
		this.computeBitStream();
		
		// data codewords and error correction codewords will be saved in this.codewords
		this.computeErrorCorrectCodewords();
		
		// data will be save to this.finalBitStream
		this.interleaveCodewords();
		




		System.out.println("Bit Stream:\n" + this.dataBitStream.toString(this.dataOffset));
		System.out.println("Decimal Stream:\n" + this.dataBitStream.toStringDecimal(0, this.dataOffset));
	}
	
	public static boolean isAlphanumeric(char[] code) {
		boolean retval = true;
		
................................................................................
					this.finalBitStream.and(ecOffset, ecCodewords[idx], 8);
					ecOffset = ecOffset + 8;
					ttl = false;
				}
			}
			idx++;
		}
		System.out.println(this.finalBitStream.toStringDecimal(0));

	}
	
	protected int[] computeErrorCorrectCodewords(int[] dataCodeword) throws Exception {
		int[] ecCodeword = null;
		Poly msgPoly = new Poly();
		for( int i=0; i<dataCodeword.length; i++ ) {
			msgPoly.addTerm(dataCodeword[i], dataCodeword.length - i - 1 + this.lvData.numEcCwPerBlock);
................................................................................
			this.numDataCwPerBlocksG2 = nDataCwG2;
			this.numDataCodewords = this.numBlocksG1*this.numDataCwPerBlocksG1 
					+ this.numBlocksG2*this.numDataCwPerBlocksG2;
			this.numEcCodewords = (this.numBlocksG1 + this.numBlocksG2)*this.numEcCwPerBlock;
			this.numTotalCodewords = this.numDataCodewords + this.numEcCodewords;
		}
	}
	










































































































	public static void main(String[] args) throws Exception {
		Qr qr;
		qr = new Qr("HELLO WORLD", Qr.ErrorCorrectionLevel.M);
		System.out.println(qr);

	}
}


>
>
>
>
>
>




>
>
>
>







 







>
>
>
>
>







 







|
>
>
>
>







 







|
>







 








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


|
<
>


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
..
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
..
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
...
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
...
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764

765
766
767
package fanxi.barcode;

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
import java.io.File;
import java.util.BitSet;
import java.util.HashMap;
import java.util.Map;

import javax.imageio.ImageIO;

import fanxi.barcode.Barcode.ImageFormat;

public class Qr {

	public short modulePixes = 3;
	
	protected final String				code;
	protected final Mode				mode;
	protected ErrorCorrectionLevel		level	= ErrorCorrectionLevel.Q; // 25% error correction
................................................................................
	protected final BitStream		finalBitStream; 

	//[numBlocks[data/ec codewords]
	protected int[][][]				codewords;

	public static final String UTF_8_BOM = new String( new char[] {0xEF,0xBB,0xBF} );
	
	// image dimensions
	// size in pixels
	private int sizePixel	= 0;
	private int sizeModule	= 0;
	
	// bits is bit string in literal format, ie, 10110101...
	public static BitSet getBitSet(String bits) throws Exception {
		if( bits==null ) throw new Exception("Null input");
		int len = bits.length();
		BitSet bSet = new BitSet(len);
		for(int i=0; i<len; i++) {
			if( bits.charAt(i)=='1' ) { 
................................................................................
		this.computeBitStream();
		
		// data codewords and error correction codewords will be saved in this.codewords
		this.computeErrorCorrectCodewords();
		
		// data will be save to this.finalBitStream
		this.interleaveCodewords();

		// the image size in pixels
		this.sizeModule = 21 + 4*(this.version - 1);
		this.sizePixel = this.sizeModule*this.modulePixes;

		System.out.println("Bit Stream:\n" + this.dataBitStream.toString(this.dataOffset));
		System.out.println("Decimal Stream:\n" + this.dataBitStream.toStringDecimal(0, this.dataOffset));
	}
	
	public static boolean isAlphanumeric(char[] code) {
		boolean retval = true;
		
................................................................................
					this.finalBitStream.and(ecOffset, ecCodewords[idx], 8);
					ecOffset = ecOffset + 8;
					ttl = false;
				}
			}
			idx++;
		}
		// add remainder bits
		this.finalBitStream.and(ecOffset, 0, Qr.remainderBits(this.version));
	}
	
	protected int[] computeErrorCorrectCodewords(int[] dataCodeword) throws Exception {
		int[] ecCodeword = null;
		Poly msgPoly = new Poly();
		for( int i=0; i<dataCodeword.length; i++ ) {
			msgPoly.addTerm(dataCodeword[i], dataCodeword.length - i - 1 + this.lvData.numEcCwPerBlock);
................................................................................
			this.numDataCwPerBlocksG2 = nDataCwG2;
			this.numDataCodewords = this.numBlocksG1*this.numDataCwPerBlocksG1 
					+ this.numBlocksG2*this.numDataCwPerBlocksG2;
			this.numEcCodewords = (this.numBlocksG1 + this.numBlocksG2)*this.numEcCwPerBlock;
			this.numTotalCodewords = this.numDataCodewords + this.numEcCodewords;
		}
	}
	
	public static int remainderBits(int version) {
		int retval = 0;
		
		if( version>1 && version<7 ) {
			retval = 7;
		}else if( (version>13 && version<21) || (version>27 && version<35) ) {
			retval = 3;
		}else if( version>20 && version<28 ) {
			retval = 4;
		}

		return retval;
	}
	
	public void save(File imageFile, ImageFormat format) throws Exception {
		if( imageFile==null || format==null ) return;
		
		RenderedImage rendImage = this.getImage();

		ImageIO.write(rendImage, format.toString(), imageFile);
	}
	
	public BufferedImage getImage() {
		BufferedImage bufferedImage = new BufferedImage(sizePixel, sizePixel, BufferedImage.TYPE_INT_RGB);
		Graphics2D g = bufferedImage.createGraphics();
		g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
		g.setColor(Color.GRAY);
		g.fillRect(0, 0, sizePixel, sizePixel);
		this.printFinderPattern(g);
		this.printSeparators(g);
		g.dispose();
		
		/**
		int w = bufferedImage.getWidth();
		int h = bufferedImage.getHeight();
		BufferedImage after = new BufferedImage(w*this.modulePixes, h*this.modulePixes, BufferedImage.TYPE_INT_ARGB);
		AffineTransform at = new AffineTransform();
		at.scale(this.modulePixes, this.modulePixes);
		AffineTransformOp scaleOp = 
		   new AffineTransformOp(at, AffineTransformOp.TYPE_BILINEAR);
		after = scaleOp.filter(bufferedImage, after);
		*/

		return bufferedImage;
	}

	private void printFinderPattern(Graphics2D g) {
		int x, y; // position in module
		
		// print parttern top-left
		x = 0; y = 0;
		g.setColor(Color.BLACK);
		g.fillRect(x*this.modulePixes, y*this.modulePixes, 7*this.modulePixes, 7*this.modulePixes);
		g.setColor(Color.WHITE);
		g.fillRect((x+1)*this.modulePixes, (y+1)*this.modulePixes, 5*this.modulePixes, 5*this.modulePixes);
		g.setColor(Color.BLACK);
		g.fillRect((x+2)*this.modulePixes, (y+2)*this.modulePixes, 3*this.modulePixes, 3*this.modulePixes);
		
		// print parttern bottom-left
		x = 0; y = this.sizeModule - 7;
		g.setColor(Color.BLACK);
		g.fillRect(x*this.modulePixes, y*this.modulePixes, 7*this.modulePixes, 7*this.modulePixes);
		g.setColor(Color.WHITE);
		g.fillRect((x+1)*this.modulePixes, (y+1)*this.modulePixes, 5*this.modulePixes, 5*this.modulePixes);
		g.setColor(Color.BLACK);
		g.fillRect((x+2)*this.modulePixes, (y+2)*this.modulePixes, 3*this.modulePixes, 3*this.modulePixes);

		// print parttern top-right
		x = this.sizeModule - 7; y = 0;
		g.setColor(Color.BLACK);
		g.fillRect(x*this.modulePixes, y*this.modulePixes, 7*this.modulePixes, 7*this.modulePixes);
		g.setColor(Color.WHITE);
		g.fillRect((x+1)*this.modulePixes, (y+1)*this.modulePixes, 5*this.modulePixes, 5*this.modulePixes);
		g.setColor(Color.BLACK);
		g.fillRect((x+2)*this.modulePixes, (y+2)*this.modulePixes, 3*this.modulePixes, 3*this.modulePixes);
	}
	
	private void printSeparators(Graphics2D g) {
		int x, y; // position in module
		
		// print parttern top-left
		// separater
		x = 7; y = 7;
		g.setColor(Color.WHITE);
		g.fillRect((x-7)*this.modulePixes, y*this.modulePixes, 8*this.modulePixes, this.modulePixes);
		g.fillRect(x*this.modulePixes, (y-7)*this.modulePixes, this.modulePixes, 8*this.modulePixes);
		
		// print parttern bottom-left
		// separater
		x = 7; y = this.sizeModule - 8;
		g.setColor(Color.WHITE);
		g.fillRect((x-7)*this.modulePixes, y*this.modulePixes, 8*this.modulePixes, this.modulePixes);
		g.fillRect(x*this.modulePixes, y*this.modulePixes, this.modulePixes, 8*this.modulePixes);

		// print parttern top-right
		// separater
		x = this.sizeModule - 8; y = 7;
		g.setColor(Color.WHITE);
		g.fillRect(x*this.modulePixes, y*this.modulePixes, 8*this.modulePixes, this.modulePixes);
		g.fillRect(x*this.modulePixes, (y-7)*this.modulePixes, this.modulePixes, 8*this.modulePixes);
	}
	
	private void printAlignmentPatterns(Graphics2D g) {
	
	}
	
	public static void main(String[] args) throws Exception {
		Qr qr;
		qr = new Qr("HELLO WORLD", Qr.ErrorCorrectionLevel.Q, 5);

		qr.save(new File("C:\\Users\\Kevin Xie\\Documents\\qr.png"), Barcode.ImageFormat.PNG);
	}
}