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?
Related
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.
so i am trying to convert an image into a string/hexadecimal array (containing pixel color values) and send it over bluetooth to my arduino controller. I have converted the image to hex array but am unable to send it over bluetooth.
Following is the image to hex-conversion block:
public void getPixelValue (View v){
Bitmap bm = ((BitmapDrawable) imgView.getDrawable()).getBitmap();
boolean hasDrawable = (bm != null);
if(hasDrawable)
{
picw = bm.getWidth();
pich = bm.getHeight();
int[] pix = new int[picw * pich];
bm.getPixels(pix, 0, picw, 0, 0, picw, pich);
int R, G, B,Y;
colorArray = new String[picw][pich];
for (int i = 0; i < picw; i++)
{
for (int j = 0; j < pich; j++)
{
int pixel = bm.getPixel(i,j);
R = Color.red(pixel);
G = Color.green(pixel);
B = Color.blue(pixel);
StringBuilder builder = new StringBuilder();
builder.append("0x");
builder.append(Integer.toHexString(R));
builder.append(Integer.toHexString(G));
builder.append(Integer.toHexString(B));
colorArray[i][j] = builder.toString();
}
}
}
else
{
Toast.makeText(this, "No Image loaded", Toast.LENGTH_SHORT).show();
}
}
Kindly guide on how to send it over bluetooth so that i receive the array as it is on the arduino (nano) side.
This here is the method i am using to send simple text/characters. I type the string, in a textbox, i want to read on the serial monitor (arduino side).
public void sendText (View v) {
try
{
String msg = txtBox.getText().toString();
msg += "\n";
mmOutputStream.write(msg.getBytes());
Toast.makeText(this, "Data Sent", Toast.LENGTH_LONG).show();
}
catch (IOException ex) { }
}
This block works perfectly so i know that the bluetooth pairing and connection is OK. Next, i want to send the string/hex array i have obtained from the 'getpixelvalue' function.
I am selecting a list of images from my SD card and the selected images as to view in a video format for the user. I don't know what to do is any idea or link to refer. Please help me. Thanks in advance.
#Harini- please follow up this link or you can try below code
try {
File file = this.getFullPath("", "video.mp4");
SequenceEncoder encoder = new SequenceEncoder(file);
// only 5 frames in total
for (int i = 1; i <= 5; i++) {
// getting bitmap from drawable path
int bitmapResId = this.getResources().getIdentifier("image" + i, "drawable", this.getPackageName());
Bitmap bitmap = this.getBitmapFromResources(this.getResources(), bitmapResId);
encoder.encodeNativeFrame(this.pictureFromBitmap(bitmap));
}
encoder.finish();
} catch (IOException e) {
e.printStackTrace();
}
// get full SD path
File getFullPath(String filePatho, String fileName) {
File extBaseDir = Environment.getExternalStorageDirectory();
if (filePatho == null || filePatho.length() == 0 || filePatho.charAt(0) != '/') filePatho = "/" + filePatho;
makeDirectory(filePatho);
File file = new File(extBaseDir.getAbsoluteFile() + filePatho);
return new File(file.getAbsolutePath() + "/" + fileName); // file;
}
// convert from Bitmap to Picture (jcodec native structure)
public Picture pictureFromBitmap(Bitmap src) {
Picture dst = Picture.create((int) src.getWidth(), (int) src.getHeight(), ColorSpace.RGB);
pictureFromBitmap(src, dst);
return dst;
}
public void pictureFromBitmap(Bitmap src, Picture dst) {
int[] dstData = dst.getPlaneData(0);
int[] packed = new int[src.getWidth() * src.getHeight()];
src.getPixels(packed, 0, src.getWidth(), 0, 0, src.getWidth(), src.getHeight());
for (int i = 0, srcOff = 0, dstOff = 0; i < src.getHeight(); i++) {
for (int j = 0; j < src.getWidth(); j++, srcOff++, dstOff += 3) {
int rgb = packed[srcOff];
dstData[dstOff] = (rgb >> 16) & 0xff;
dstData[dstOff + 1] = (rgb >> 8) & 0xff;
dstData[dstOff + 2] = rgb & 0xff;
}
}
}
http://wptrafficanalyzer.in/blog/image-slideshow-using-viewflipper-in-android/
Hope this may help you,Or you can search for image slider in android to create image slide show
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.
I'm developing an Android app that record voice using mediarecorder and play music using mediaplayer.
My goal is to make possible to mix the two audio's into one file, and because Android do not offer any API for it, I am looking for a reasonable solution.
At moment, at play time I'm using a new mediarecorder with MIC source to capture the audio and save it, but this is very poor !!!
Anyway to mix the audio? including any native solution lix SOX or FFMPEG?
Or, anyway to recorder into file using as source the mediaplayer output instead to use the MIC?
Any suggestion is appreciate.
Thank you.
When I faced the same problem I was able to find a solution for mixing the files.
Since mixing of two mp3 file is not possible, you have to first convert it in wave format , then set the header value .after that add the data field. I did this in following way. Hope my code will help you.
class MixFile extends AsyncTask{
ProgressDialog dialog;
protected void onPreExecute() {
dialog= new ProgressDialog(MainActivity.this);
dialog.setCancelable(false);
dialog.setMessage("Mixing two wav files");
dialog.show();
}
#Override
protected Void doInBackground(Void... arg0) {
short[] audioData1 = null;
short[] audioData2 = null;
int n = 0;
try {
DataInputStream in1;
// in1 = new DataInputStream(new FileInputStream(Environment.getExternalStorageDirectory() + "/Soundrecpluspro/one.wav"));
in1 = new DataInputStream(new FileInputStream(path1));
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try {
while ((n = in1.read()) != -1) {
bos.write(n);
}
} catch (IOException e) {
e.printStackTrace();
}
ByteBuffer bb = ByteBuffer.wrap(bos.toByteArray());
bb.order(ByteOrder.LITTLE_ENDIAN);
ShortBuffer sb = bb.asShortBuffer();
audioData1 = new short[sb.capacity()];
for (int i = 0; i < sb.capacity(); i++) {
audioData1[i] = sb.get(i);
}
} catch (IOException e) {
e.printStackTrace();
}
try {
DataInputStream in1;
in1 = new DataInputStream(new FileInputStream(path2));
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try {
while ((n = in1.read()) != -1) {
bos.write(n);
}
} catch (IOException e) {
e.printStackTrace();
}
ByteBuffer bb = ByteBuffer.wrap(bos.toByteArray());
bb.order(ByteOrder.LITTLE_ENDIAN);
ShortBuffer sb = bb.asShortBuffer();
audioData2= new short[sb.capacity()];
sb.get(audioData2);
System.out.println();
} catch (IOException e) {
e.printStackTrace();
}
// find the max:
float max = 0;
Log.d("File audio lenght 1 ", ""+audioData1.length);
Log.d("File audio lenght 2 ", ""+audioData2.length);
System.out.println("MainActivity.MixFile.doInBackground() 1"+audioData1.length);
System.out.println("MainActivity.MixFile.doInBackground() 2"+audioData2.length);
if(audioData1.length > audioData2.length){
for (int i = 22; i < audioData2.length; i++) {
if (Math.abs(audioData1[i] + audioData2[i]) > max)
max = Math.abs(audioData1[i] + audioData2[i]);
}
System.out.println("" + (Short.MAX_VALUE - max));
int a, b, c;
// now find the result, with scaling:
for (int i = 22; i < audioData2.length; i++) {
a = audioData1[i];
b = audioData2[i];
c = Math.round(Short.MAX_VALUE * (audioData1[i] + audioData2[i])
/ max);
if (c > Short.MAX_VALUE)
c = Short.MAX_VALUE;
if (c < Short.MIN_VALUE)
c = Short.MIN_VALUE;
audioData1[i] = (short) c;
}
// to turn shorts back to bytes.
byte[] end = new byte[audioData1.length * 2];
ByteBuffer.wrap(end).order(ByteOrder.LITTLE_ENDIAN).asShortBuffer().put(audioData1);
try {
OutputStream out = new FileOutputStream(Environment.getExternalStorageDirectory() + "/assets/mixer12.wav");
for (int i = 0; i < end.length; i++) {
out.write(end[i]);
out.flush();
}
out.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}else{
System.out.println("MainActivity.MixFile.doInBackground() smaller one");
for (int i = 22; i < audioData1.length; i++) {
if (Math.abs(audioData2[i] + audioData1[i]) > max)
max = Math.abs(audioData2[i] + audioData1[i]);
}
System.out.println("" + (Short.MAX_VALUE - max));
int a, b, c;
// now find the result, with scaling:
for (int i = 22; i < audioData1.length; i++) {
a = audioData2[i];
b = audioData1[i];
c = Math.round(Short.MAX_VALUE * (audioData2[i] + audioData1[i])
/ max);
if (c > Short.MAX_VALUE)
c = Short.MAX_VALUE;
if (c < Short.MIN_VALUE)
c = Short.MIN_VALUE;
audioData2[i] = (short) c;
}
// to turn shorts back to bytes.
byte[] end = new byte[audioData2.length * 2];
ByteBuffer.wrap(end).order(ByteOrder.LITTLE_ENDIAN).asShortBuffer().put(audioData2);
try {
OutputStream out = new FileOutputStream(Environment.getExternalStorageDirectory() + "/Assets/mixer1.wav");
for (int i = 0; i < end.length; i++) {
out.write(end[i]);
out.flush();
}
out.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return null;
}
and in activity i called it as below
public class MainActivity extends Activity implements OnClickListener {
new MixFile().execute();
}
here path1 and path2 is the path of wav file that you want to mix