Android Generate QR code and Barcode using Zxing - android

Code to generate Qr code using zxing is ---
It takes string data and the imageview This works just fine
private void generateQRCode_general(String data, ImageView img)throws WriterException {
com.google.zxing.Writer writer = new QRCodeWriter();
String finaldata = Uri.encode(data, "utf-8");
BitMatrix bm = writer.encode(finaldata, BarcodeFormat.QR_CODE,150, 150);
Bitmap ImageBitmap = Bitmap.createBitmap(150, 150,Config.ARGB_8888);
for (int i = 0; i < 150; i++) {//width
for (int j = 0; j < 150; j++) {//height
ImageBitmap.setPixel(i, j, bm.get(i, j) ? Color.BLACK: Color.WHITE);
}
}
if (ImageBitmap != null) {
qrcode.setImageBitmap(ImageBitmap);
} else {
Toast.makeText(getApplicationContext(), getResources().getString(R.string.userInputError),
Toast.LENGTH_SHORT).show();
}
}
Now my question is ,how to get bar code using the same library.i saw some files related to bar codes but i am not sure how to do it.
Since I want to generate the bar code within the application and not call any web service. Since i am already using zxing,no point in including itext and barbecue jars

Like Gaskoin told... MultiFormatWrite it worked :) here is the code.
com.google.zxing. MultiFormatWriter writer =new MultiFormatWriter();
String finaldata = Uri.encode(data, "utf-8");
BitMatrix bm = writer.encode(finaldata, BarcodeFormat.CODE_128,150, 150);
Bitmap ImageBitmap = Bitmap.createBitmap(180, 40,Config.ARGB_8888);
for (int i = 0; i < 180; i++) {//width
for (int j = 0; j < 40; j++) {//height
ImageBitmap.setPixel(i, j, bm.get(i, j) ? Color.BLACK: Color.WHITE);
}
}
if (ImageBitmap != null) {
qrcode.setImageBitmap(ImageBitmap);
} else {
Toast.makeText(getApplicationContext(), getResources().getString(R.string.userInputError),
Toast.LENGTH_SHORT).show();
}

I've tested the accepted answer to generate a Barcode but the output is blurry when used in a big ImageView. To get a high quality output, the width of the BitMatrix, the Bitmap and the final ImageView should be the same. But doing so using the accepted answer will make the Barcode generation really slow (2-3 seconds). This happens because
Bitmap.setPixel()
is a slow operation, and the accepted answer is doing intensive use of that operation (2 nested for loops).
To overcome this problem I've modified a little bit the Bitmap generation algorithm (only use it for Barcode generation) to make use of Bitmap.setPixels() which is much faster:
private Bitmap createBarcodeBitmap(String data, int width, int height) throws WriterException {
MultiFormatWriter writer = new MultiFormatWriter();
String finalData = Uri.encode(data);
// Use 1 as the height of the matrix as this is a 1D Barcode.
BitMatrix bm = writer.encode(finalData, BarcodeFormat.CODE_128, width, 1);
int bmWidth = bm.getWidth();
Bitmap imageBitmap = Bitmap.createBitmap(bmWidth, height, Config.ARGB_8888);
for (int i = 0; i < bmWidth; i++) {
// Paint columns of width 1
int[] column = new int[height];
Arrays.fill(column, bm.get(i, 0) ? Color.BLACK : Color.WHITE);
imageBitmap.setPixels(column, 0, 1, i, 0, 1, height);
}
return imageBitmap;
}
This approach is really fast even for really big outputs and generates a high quality bitmap.

You are using QRCodeWriter. If you want to write another type of code, use another Writer.
Check this MultiFormatWriter - it can write any type of bar or find specific writers here in subfolders (this is from zxing library)

There you go,
public static Bitmap createBarCode (String codeData, BarcodeFormat barcodeFormat, int codeHeight, int codeWidth) {
try {
Hashtable<EncodeHintType, ErrorCorrectionLevel> hintMap = new Hashtable<EncodeHintType, ErrorCorrectionLevel> ();
hintMap.put (EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L);
Writer codeWriter;
if (barcodeFormat == BarcodeFormat.QR_CODE) {
codeWriter = new QRCodeWriter ();
} else if (barcodeFormat == BarcodeFormat.CODE_128) {
codeWriter = new Code128Writer ();
} else {
throw new RuntimeException ("Format Not supported.");
}
BitMatrix byteMatrix = codeWriter.encode (
codeData,
barcodeFormat,
codeWidth,
codeHeight,
hintMap
);
int width = byteMatrix.getWidth ();
int height = byteMatrix.getHeight ();
Bitmap imageBitmap = Bitmap.createBitmap (width, height, Config.ARGB_8888);
for (int i = 0; i < width; i ++) {
for (int j = 0; j < height; j ++) {
imageBitmap.setPixel (i, j, byteMatrix.get (i, j) ? Color.BLACK: Color.WHITE);
}
}
return imageBitmap;
} catch (WriterException e) {
e.printStackTrace ();
return null;
}
}
Of course you can support as many BarcodeFormats as you want, just change the constructor here :
Writer codeWriter;
if (barcodeFormat == BarcodeFormat.QR_CODE) {
codeWriter = new QRCodeWriter ();
} else if (barcodeFormat == BarcodeFormat.CODE_128) {
codeWriter = new Code128Writer ();
} else {
throw new RuntimeException ("Format Not supported.");
}

try this code
Context context = getActivity();
Intent intent = new Intent("com.google.zxing.client.android.ENCODE");
intent.putExtra("ENCODE_TYPE", Text);
intent.putExtra("ENCODE_DATA", "12345678901");
intent.putExtra("ENCODE_FORMAT", "UPC_A");
startActivity(intent);
hope this helps you.

Related

POS bluetooth printer leaving some margin at start and then starts printing in Android App

I am implementing POS bluetooth printer with ESC/POS commands and trying to print bitmap image.
Image is getting printing but always it is printing some white space at start and then printing an image,because of which i am not able to print 1 image per label.
following is my code for printing and image
int bmpNewWidth = bmp.getWidth();
int bmpNewHeight = bmp.getHeight();
byte[] printBMPPackageHead = ESCUtil.bmpCmdHead(bmpMode,bmpNewWidth);
int bmpBlockHeight = 0;
int bmpBlockNums =0;
if((bmpMode == 0) || (bmpMode ==1))
{
bmpBlockHeight = 8;
}
else if((bmpMode == 32) || (bmpMode ==33))
{
bmpBlockHeight = 24;
}
else
{
Log.d(TAG,"****bmpMode set error!!*****");
return (new byte[1]);
}
bmpBlockNums = ((bmpNewHeight % bmpBlockHeight) == 0)? (bmpNewHeight/bmpBlockHeight) : (bmpNewHeight/bmpBlockHeight +1);
int bmpBlockCMDSize = printBMPPackageHead.length + bmpNewWidth*bmpBlockHeight/8;
byte[] bmpPrintData = new byte[bmpBlockNums*bmpBlockCMDSize];
for(int n = 0; n < bmpBlockNums; n++)
{
byte[] bmpBlockPxBytes = getBitmapBlockData(n,bmpNewWidth,bmpBlockHeight,bmp);
byte[][] bmpBlockPrintData = {printBMPPackageHead,bmpBlockPxBytes};
System.arraycopy(ESCUtil.byteMerger(bmpBlockPrintData),0,bmpPrintData,n*bmpBlockCMDSize,bmpBlockCMDSize);
}
return bmpPrintData;
}
and
public static byte[] bmpCmdHead(int mode, int bitmapWidth)
{
//byte[] result = new byte[]{ESC,42,0,0,0};
byte[] result = new byte[]{ESC,42,0,0,0};
result[2] = (byte)mode;
result[3] = (byte)(bitmapWidth%256);
result[4] = (byte)(bitmapWidth/256);
return result;
}
public static byte[] getBitmapBlockData(int blocknum, int bmpWidth, int bmpBlockHeight, Bitmap bmp)
{
int blockHeightBytes = bmpBlockHeight/8;
byte[] blockData = new byte[bmpWidth*blockHeightBytes];
for (int i = 0;i < bmpWidth; i++)
{
for(int j = 0;j < blockHeightBytes;j++)
{
for(int p = 0; p < 8; p++)
{
byte px = px2Byte(i,blocknum * bmpBlockHeight+j*8+p,bmp);
blockData[i*blockHeightBytes+j] |= (px << (7-p));
}
}
}
return blockData;
}
this is it.Before calling this function i have called only init printer command that's it.
Please help me. Thanks in advance.

tflite.run() returning same output for different input values

I am trying to make an android app for monument recognition. The input changes on every run but output returned is always same.
Below are the code snippets
to load tflite model stored in assets directory
private ByteBuffer loadModelFile(String filename) throws IOException {
AssetFileDescriptor fileDescriptor = this.getAssets().openFd(filename);
FileInputStream inputStream = new FileInputStream(fileDescriptor.getFileDescriptor());
FileChannel fileChannel = inputStream.getChannel();
long startOffset = fileDescriptor.getStartOffset();
long declaredLength = fileDescriptor.getDeclaredLength();
return fileChannel.map(FileChannel.MapMode.READ_ONLY, startOffset, declaredLength);
}
to initialize tflite interpreter
predict.setOnClickListener(new View.OnClickListener() {
#RequiresApi(api = Build.VERSION_CODES.O)
#Override
public void onClick(View v) {
try {
tflite = new Interpreter(loadModelFile("converted_model.tflite"));
Log.println(7,"tflite", "tflite init");
doInference(picFile);
} catch (Exception e) {
System.out.println(e);
}
}
});
to run the model
#RequiresApi(api = Build.VERSION_CODES.O)
public void doInference(File photo) throws IOException {
img = findViewById(R.id.imgToDisp);
Bitmap bitmapImg = BitmapFactory.decodeFile(pathToFile);
img.setImageBitmap(bitmapImg);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmapImg.compress(Bitmap.CompressFormat.JPEG, 50, stream);
byte[] arr = stream.toByteArray();
changedim = new float[1][150][150][3];
outputval = new float[1][28];
int m = 0;
for (int i = 0; i < 1; i++) {
for (int j = 0; j < 150; j++) {
for (int k = 0; k < 150; k++) {
for (int l = 0; l < 3; l++) {
byte a = arr[m++];
changedim[i][j][k][l] = Byte.toUnsignedLong(a);
}
}
}
}
tflite.run(changedim, outputval);
for(int i=0;i<28;i++) {
Log.println(7,"outputval",i+" "+outputval[0][i]);
}
path = findViewById(R.id.path);
String out = "";
float[] op = outputval[0];
int ind = 0;
float max = op[0];
while (op[ind] != 1) {
ind++;
//Log.println(7,"op", " "+op[ind]+" "+ind);
}
for (float f : op) {
out += Float.toString(f) + ",";
}
predict.setText("result: " + labels.get(ind));
Log.println(7, "label", ind + " " + labels.get(ind));
//path.setText(""+pathToFile);
}
input to the model must be an image of size 150*150 converted to 4d float32 array of shape 1*150*150*3
Input to the model is the color values of individual pixels.
Which can be extracted using
int p = bitmapImg.getPixel(j, k);
int R = (p >> 16) & 0xff;
int G = (p >> 8) & 0xff;
int B = p & 0xff;
change that and your model will work correctly!

Generating Wrong Barcode (Code_39) in Zxing

Introduction
I am generating a Barcode in zxing inside my android app. But it is not able to scan in any of the scanner apps. I have tried to create code 39 for the same number online but I am getting a different one online and that's working fine.
My Code
public static Bitmap generateCode39BarCode(String Value) {
MultiFormatWriter writer = new MultiFormatWriter();
String finaldata = Uri.encode(Value, "utf-8");
BitMatrix bm = null;
try {
bm = writer.encode(finaldata, BarcodeFormat.CODE_39, 150, 150);
} catch (WriterException e) {
e.printStackTrace();
}
Bitmap ImageBitmap = Bitmap.createBitmap(180, 40, Bitmap.Config.ARGB_4444);
for (int i = 0; i < 180; i++) {//width
for (int j = 0; j < 40; j++) {//height
ImageBitmap.setPixel(i, j, bm.get(i, j) ? Color.BLACK : Color.WHITE);
}
}
return ImageBitmap;
}
I am passing 908765678 as input to this function.
Output
The output bitmap I am getting is-
But if you scan this with any scanner app it is unable to be scanned.
Can anyone suggest a solution to this?

Error in creating image of barcode in Android Studio

I want to create the image of the barcode/QR code etc on my app. I have searched a lot and have found different libraries to do this task but since I am already using Zxing so i would like to work in it.
Following is the code that I have writen:
This is my Scanner Activity class:
public void handleResult(Result rawResult) {
// Do something with the result here
Log.v(TAG, rawResult.getText()); // Prints scan results
Toast.makeText(SimpleScannerActivity.this, rawResult.toString() + " WOW scanned", Toast.LENGTH_LONG).show();
Toast.makeText(SimpleScannerActivity.this, rawResult.getBarcodeFormat().toString(), Toast.LENGTH_LONG).show();
Log.v(TAG, rawResult.getBarcodeFormat().toString()); // Prints the scan format (qrcode, pdf417 etc.)
//Intent scanScreenResult= new Intent("com.aaa.fyp.ScanResultScreen");
setFormat(rawResult);
Intent nextScreen = new Intent("com.aaa.fyp.ScanResultScreen");
nextScreen.putExtra("barcode",rawResult.toString());
nextScreen.putExtra("format", rawResult.getBarcodeFormat().toString());
finish();
startActivity(nextScreen);
}
public void setFormat(Result result){
r=result.getBarcodeFormat();
System.out.println("============================== setformat main"+ r);
}
public BarcodeFormat getFormat(){
System.out.println("============================== getformat main"+ r);
return r;
}
Using the results from the above activity in ScanResultScreen activity.
public class ScanResultScreen extends SimpleScannerActivity {
ImageView scanned;
TextView bc;
TextView f;
String Barcode;
String format;
BarcodeFormat form;
#Override
public void onCreate(Bundle state) {
super.onCreate(state);
setContentView(R.layout.scan_screen_with_button);
ViewGroup layout = (ViewGroup) findViewById(R.id.scanScreenWithButton);
setContentView(layout);
Intent prevScreen = getIntent(); // gets the previously created intent
Barcode=prevScreen.getStringExtra("barcode");
bc= (TextView)findViewById(R.id.barcode_label);
bc.setText(Barcode);
format=prevScreen.getStringExtra("format");
f=(TextView) findViewById(R.id.format_label);
f.setText(prevScreen.getStringExtra("format").toString());
SimpleScannerActivity obj=new SimpleScannerActivity();
form=obj.getFormat();
d=(TextView)findViewById(R.id.date_label);
String formattedDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(Calendar.getInstance().getTime());
d.setText(formattedDate);
Bitmap bitmap = null;
ImageView iv = new ImageView(this);
try {
bitmap = encodeAsBitmap(Barcode, form, 600, 300);
iv.setImageBitmap(bitmap);
} catch (WriterException e) {
e.printStackTrace();
}
layout.addView(iv);
}
private static final int WHITE = 0xFFFFFFFF;
private static final int BLACK = 0xFF000000;
Bitmap encodeAsBitmap(String contents, BarcodeFormat format, int img_width, int img_height) throws WriterException {
String contentsToEncode = contents;
if (contentsToEncode == null) {
return null;
}
Map<EncodeHintType, Object> hints = null;
String encoding = guessAppropriateEncoding(contentsToEncode);
if (encoding != null) {
hints = new EnumMap<EncodeHintType, Object>(EncodeHintType.class);
hints.put(EncodeHintType.CHARACTER_SET, encoding);
}
MultiFormatWriter writer = new MultiFormatWriter();
BitMatrix result;
try {
result = writer.encode(contentsToEncode, format, img_width, img_height, hints);
} catch (IllegalArgumentException iae) {
// Unsupported format
return null;
}
int width = result.getWidth();
int height = result.getHeight();
int[] pixels = new int[width * height];
for (int y = 0; y < height; y++) {
int offset = y * width;
for (int x = 0; x < width; x++) {
pixels[offset + x] = result.get(x, y) ? BLACK : WHITE;
}
}
Bitmap bitmap = Bitmap.createBitmap(width, height,
Bitmap.Config.ARGB_8888);
bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
return bitmap;
}
private static String guessAppropriateEncoding(CharSequence contents) {
// Very crude at the moment
for (int i = 0; i < contents.length(); i++) {
if (contents.charAt(i) > 0xFF) {
return "UTF-8";
}
}
return null;
}
Now I am getting a Null value in the variable "form". Even though I am able to get the barcodeFormat in my second activity by passing it through intent but it's in the type String. Whereas the built-in methods that I am using here requires it in BarcodeFormat that is available in Zxing.
Help!!
BarcodeFormat is an enum type. If you want to pass a String value, you have to convert it to BarcodeFormat.
For example, passing a barcode format "AZTEC":
BarcodeFormat format = Enum.valueOf(BarcodeFormat.class, "AZTEC");

How to create a QR code for my existing android application?

I want to create a QR code for my existing Android application (built in Android Studio). I need to get some ID's from the back end & generate the QR code then view it in my layout.
Please help me.
Here are some of my sample codes, you can refer, some values may be different depend on the mobile phone model. Hope this help! I use zxing library.
private void startScan(Context context, String parameter) {
Intent intent = new Intent();
intent.setAction("com.motorolasolutions.emdk.datawedge.api.ACTION_SOFTSCANTRIGGER");
intent.putExtra("com.motorolasolutions.emdk.datawedge.api.EXTRA_PARAMETER", parameter);
context.sendBroadcast(intent);
}
#Override
public boolean onKeyUp(int keyCode, #NonNull KeyEvent event) {
if ((event.getAction() == KeyEvent.ACTION_UP) && keyCode == KeyEvent.KEYCODE_...) {
startScan(this, "START_SCANNING");
registerReceiver(new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String code = intent.getExtras().getString("com.motorolasolutions.emdk.datawedge.data_string");
ImageView imageView = (ImageView) findViewById(R.id.imageView);
TextView textView = (TextView) findViewById(R.id.textView);
if ((imageView != null) && (textView != null)) {
textView.setText(code);
// barcode image
try {
mBarCodeBitmap = encodeBarCodeAsBitmap(value, BarcodeFormat.CODE_128, 200, 100);
imageView.setImageBitmap(mBarCodeBitmap);
} catch (WriterException e) {
}
}
unregisterReceiver(this);
}
}, new IntentFilter("com.example.SoftScanIntentAction")); // this value must be set in DataWedge profile (Intent Output - Intent action...)
}
return super.onKeyUp(keyCode, event);
}
private Bitmap encodeBarCodeAsBitmap(String contents, BarcodeFormat format, int width, int height) throws WriterException {
String contentsToEncode = contents;
if (contentsToEncode == null) {
return null;
}
Map<EncodeHintType, Object> hints = null;
String encoding = guessAppropriateEncoding(contentsToEncode);
if (encoding != null) {
hints = new EnumMap<>(EncodeHintType.class);
hints.put(EncodeHintType.CHARACTER_SET, encoding);
}
MultiFormatWriter writer = new MultiFormatWriter();
BitMatrix result;
try {
result = writer.encode(contentsToEncode, format, width, height, hints);
} catch (IllegalArgumentException iae) {
// Unsupported format
return null;
}
int imgWidth = result.getWidth();
int imgHeight = result.getHeight();
int[] pixels = new int[imgWidth * imgHeight];
for (int y = 0; y < imgHeight; y++) {
int offset = y * imgWidth;
for (int x = 0; x < imgWidth; x++) {
pixels[offset + x] = result.get(x, y) ? 0xFF000000 : 0xFFFFFFFF;
}
}
Bitmap bitmap = Bitmap.createBitmap(imgWidth, imgHeight,
Bitmap.Config.ARGB_8888);
bitmap.setPixels(pixels, 0, imgWidth, 0, 0, imgWidth, imgHeight);
return bitmap;
}

Categories

Resources