Audio File Encoding and Decoding - java

What is the efficient way to encode and decode an audio file in android
I have tried the Base64 as below but after decoding the file size get increased.
Encode
ByteArrayOutputStream objByteArrayOS = new ByteArrayOutputStream();
File file = new File(path);
FileInputStream objFileIS;
try {
objFileIS = new FileInputStream(file);
byte[] byteBufferString = new byte[1024];
for (int readNum; (readNum = objFileIS.read(byteBufferString)) != -1;) {
objByteArrayOS.write(byteBufferString, 0, readNum);
System.out.println("read " + readNum + " bytes,");
byte[] bytes = FileUtils.readFileToByteArray(file);
strAttachmentCoded = Base64.encodeToString(bytes,
Base64.DEFAULT);
Decode
byte[] decoded = Base64.decode(strAttachmentCoded,
Base64.DEFAULT);
// byte[] decoded1 = Base64.decode(byteBinaryData1, 0);
File file1 = new File(pathAudio);
FileOutputStream os = new FileOutputStream(file1, true);
os.write(decoded);
os.close();
i want audio in String format to send to server and retrieve the same as per the user requirement.

wikipedia:base64 (rfc3548) is the right method to choose I would think. It is most common now I think having taken over from wikipedia:uuencoding.
To answer the question . . .
You could add some padding. The wikipedia article on base64 gives a good example of padding.
Or you could add a header to your audio string including length. The header could also include other control data so it may be something you want to include anyway.

Related

How to convert Bytes Array to a String in order to see it printed onto the console?

I am trying to convert a Byte Array to a String in order to be able to see this Vector/Array and analyse how these bytes are organized.
I'm using the code below to do it:
byte[] bytes = bos.toByteArray();
String msgDecode = new String(bytes); // trying to convert byte in String
System.out.println("Vetor de bytes [" + msgDecode + "]"); // Showing it
But it's not working. Why the code above it's no working?
It is worth mentioning that the Byte Array is being constructed according to this other code here:
String path = Environment.getExternalStorageDirectory().getAbsolutePath()+"/"+UUID.randomUUID().toString()+"audio_record.3gp";
public byte[] convert(String path) throws IOException {
FileInputStream fis = new FileInputStream(path);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
byte[] b = new byte[1024];
for (int readNum; (readNum = fis.read(b)) != -1; ) {
bos.write(b, 0, readNum);
}
byte[] bytes = bos.toByteArray();
return bytes;
}
The general idea is to record an audio with the smartphone and convert this audio file to a array of bytes. This String path is the path where the audio is being saved after recording. Then I use this path (that represents the audio file) and convert it to a byte array according to the code above.
More information you can find and help me here: How to solve this error: Android resource linking failed?
if you want to see value of bytes you can use as below:
Log.d("TAG", Arrays.toString(bytes));
What I'll try to do, based in what you guys said:
String decode = Arrays.toString(bytes);
Log.d("mytag", decode);
byte[] bytes = "ABCDEFG".getBytes();
System.out.println(new String(bytes)); // ABCDEFG
System.out.println(Arrays.toString(bytes)); // [65, 66, 67, 68, 69, 70, 71]

can't create a image file from BASE64

Well, i'm trying to send a picture from android to java, if i make it with compression it works really good, but i need to make it without compression beacuse i need a good or normal quality.
FixBitmap is my current Bitmap picture
//Android
FixBitmap.compress(Bitmap.CompressFormat.PNG, 100, byteArrayOutputStream);
byteArray = byteArrayOutputStream.toByteArray();
ConvertImage = Base64.encodeToString(byteArray, Base64.DEFAULT);
Log.e(TAG,"LENGTH"+ConvertImage.length());
Length 43388
//Java
try{
String file=request.getParameter("image_data");
String filename=rt.getId()+"_"+rt.getName()+".png";
BufferedImage image = null;
byte[] imageByte;
BASE64Decoder decoder = new BASE64Decoder();
imageByte = decoder.decodeBuffer(file);
ByteArrayInputStream bis = new ByteArrayInputStream(imageByte);
image = ImageIO.read(bis);
bis.close();
File outputfile = new File(filename);
ImageIO.write(image, "png", outputfile);
Path destinationFile = Paths.get(getServletContext().getRealPath("/")+"uploads\\", filename);
Files.write(destinationFile,imageByte);
}catch(Exception ex){
System.out.println("Error :"+ex.getMessage());
}
This code actually works as i said, but the compression make it looks in a very bad quality, so i tried to make it without compression, just converting my bitmap to a byte array, just like this
ByteBuffer buffer = ByteBuffer.allocate(FixBitmap.getRowBytes() *
FixBitmap.getHeight());
FixBitmap.copyPixelsToBuffer(buffer);
byteArray = buffer.array();
ConvertImage = Base64.encodeToString(byteArray, Base64.DEFAULT);
Log.e(TAG,"LENGTH"+ConvertImage.length());
Length 252107
The code on my java side it's the same but now it doesn't work, it just shows me this error :
java.lang.IllegalArgumentException: image == null!
So I decided to print the length because maybe there is some restrictions about this...
so I hope you can help me with this (just send/get the picture without compression)

Incorrect upload file use FileOutputStream. Incorrect size

When I try upload the file from server, I use this code. I get the file size of 500kb, when the original file size about 300kb.
What am I doing wrong?
attachmentContent = applicationApi.getApplicationAttachmentContent(applicationame);
InputStream in = new BufferedInputStream(attachmentContent.getAttachmentContent().getInputStream());
ByteArrayOutputStream out = new ByteArrayOutputStream();
byte[] buf = new byte[1024];
int n=0;
while (-1 !=(n=in.read(buf)))
{
out.write(buf,0,n);
}
out.close();
in.close();
byte[] response = out.toByteArray();
File transferredFile = new File(attachmentName);
FileOutputStream outStream = new FileOutputStream(transferredFile);
attachmentContent.getAttachmentContent().writeTo(outStream);
outStream.write(response);
outStream.close();
Simplify. The same result:
File transferredFile = new File(attachmentName);
FileOutputStream outStream = new FileOutputStream(transferredFile);
attachmentContent.getAttachmentContent().writeTo(outStream);
outStream.close();
The ByteArrayOutputStream is a complete waste of time and space. You're reading the attachment twice, and writing it twice too. Just read from the attachment and write directly to the file. Simplify, simplify. You don't need 90% of this.

can't get the url of a image with jsoup

I'm trying to get the url of a range of images like that:
for(Element img : document.select(".left-column .strillo-content .lazy img[src]")) {
InputStream input = new java.net.URL(imageMainUrl).openStream();
Bitmap bitmap = BitmapFactory.decodeStream(input);
images.add(bitmap);
}
but everytime I trying to run my app I get this warning:
java.net.MalformedURLException: Unknown protocol: data
at java.net.URL.<init>(URL.java:184)
at java.net.URL.<init>(URL.java:127)
so I have tried to print the URL and I get this:
data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7
and I can figure out why, because I'm 100% sure that the element I select is corrent and also I do the same process with other section of the website and it works..
UPDATE 1:
I have tried this method to decode the ´base64´ image:
byte[] decodedString = Base64.decode(imageMainUrl, Base64.DEFAULT);
Bitmap bitmap = BitmapFactory.decodeByteArray(decodedString, 0, decodedString.length);
but the result is the same..
It's the data URI scheme
http://en.wikipedia.org/wiki/Data_URI_scheme
It allows to add inline data in your URI.
Extract the base64 part of the URI and get a byte array with parseBase64Binary, more information here : http://docs.oracle.com/javase/7/docs/api/javax/xml/bind/DatatypeConverter.html#parseBase64Binary%28java.lang.String%29
Use this array to build a ByteArrayInputStream
Use your BitmapFactory to decode it into a Bitmap
edit
This code works, it give a 1px*1px gif image. I used org.apache.commons.codec.binary.Base64 from commons-codec
String uri = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7";
byte[] decodedString = Base64.decodeBase64(uri.substring(uri.indexOf("data:image/gif;base64,") + "data:image/gif;base64,".length()));
ByteArrayInputStream is = new ByteArrayInputStream(decodedString);
FileOutputStream os = new FileOutputStream(new File("/tmp/test.gif"));
byte[] buffer = new byte[1024];
int length;
// copy the file content in bytes
while ((length = is.read(buffer)) > 0)
{
os.write(buffer, 0, length);
}
is.close();
os.close();

Java: Error creating a GZIPInputStream: Not in GZIP format

I am trying to use the following Java code to compress and uncompress a String. But the line that creates a new GZipInputStream object out of a new ByteArrayInputStream object throws a "java.util.zip.ZipException: Not in GZIP format" exception. Does anyone know how to solve this?
String orig = ".............";
// compress it
ByteArrayOutputStream baostream = new ByteArrayOutputStream();
OutputStream outStream = new GZIPOutputStream(baostream);
outStream.write(orig.getBytes());
outStream.close();
String compressedStr = baostream.toString();
// uncompress it
InputStream inStream = new GZIPInputStream(new ByteArrayInputStream(compressedStr.getBytes()));
ByteArrayOutputStream baoStream2 = new ByteArrayOutputStream();
byte[] buffer = new byte[8192];
int len;
while((len = inStream.read(buffer))>0)
baoStream2.write(buffer, 0, len);
String uncompressedStr = baoStream2.toString();
Mixing String and byte[]; that does never fit. And only works on the the same OS with same encoding. Not every byte[] can be converted to a String, and the conversion back could give other bytes.
The compressedBytes need not represent a String.
Explicitly set the encoding in getBytes and new String.
String orig = ".............";
// Compress it
ByteArrayOutputStream baostream = new ByteArrayOutputStream();
OutputStream outStream = new GZIPOutputStream(baostream);
outStream.write(orig.getBytes("UTF-8"));
outStream.close();
byte[] compressedBytes = baostream.toByteArray(); // toString not always possible
// Uncompress it
InputStream inStream = new GZIPInputStream(
new ByteArrayInputStream(compressedBytes));
ByteArrayOutputStream baoStream2 = new ByteArrayOutputStream();
byte[] buffer = new byte[8192];
int len;
while ((len = inStream.read(buffer)) > 0) {
baoStream2.write(buffer, 0, len);
}
String uncompressedStr = baoStream2.toString("UTF-8");
System.out.println("orig: " + orig);
System.out.println("unc: " + uncompressedStr);
Joop seems to have the solution up there, but I feel I must add this:
Compression in general, and GZIP in particular will produce a binary stream.
You MUST not try to construct a String from this stream - it WILL break.
If you need to take it to a plain text representation, look into Base64 encoding, hex encoding, heck, even simple binary encoding.
In short, String objects are for things that humans read. Byte arrays (and many other things) are for things machines read.
You encoded baostream to a string with your default platform encoding, probably UTF-8. You should be using baostream.getBytes() to work with binary data, not strings.
If you insist on a string, use an 8-bit encoding, e.h. baostream.toString("ISO-8859-1"), and read it back with the same charset.

Categories