I am using Compressor third party library for compress the captured images size its working fine and now size is showing KB's but when i convert this images to BASE64 file size becomes 6MB or more size showing my code is below can some one help me please what should i do for resolve this issue
code:
File file= new Compressor(this).compressToFile(f);
String base64File = getBase64StringFile(file);
// Converting File to Base64.encode String type using Method
public static String getBase64StringFile(File f) {
InputStream inputStream = null;
String encodedFile= "", lastVal;
try {
inputStream = new FileInputStream(f.getAbsolutePath());
byte[] buffer = new byte[10240];//specify the size to allow
int bytesRead;
ByteArrayOutputStream output = new ByteArrayOutputStream();
Base64OutputStream output64 = new Base64OutputStream(output, Base64.DEFAULT);
while ((bytesRead = inputStream.read(buffer)) != -1) {
output64.write(buffer, 0, bytesRead);
}
output64.close();
encodedFile = output.toString();
}
catch (FileNotFoundException e1 ) {
e1.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
lastVal = encodedFile;
return lastVal;
}
You can resolve this issue using some other Compressor tools like FFMPEG.
Base64 always increase your file size
Base64 is often used on binary data that needs to be transmitted across a system that isn't really designed for binary. Depending on what you're doing, you may not even need to encode it. And per the wikipedia, on average, a file is expected to grow about 37% when you base64 encode it, which is almost exactly what your numbers are.
Related
I have a large size of the image file which is nearly 16MB size. I want to load this image in my imageView and zoom it after that add markers. I tried this with subsampling-scale-image-view. I am following the below link https://github.com/davemorrissey/subsampling-scale-image-view .
The important point is I am loading image from url. The above library not supporting that. So I just downloaded the image and save to SD card after that load from that local file. Technically which is working.
Issue:
Now the issue is it is taking too much of time for the first time downloading. Also even second time it takes nearly a minute.
My Idea:
Due to this issue, I try to load image byte by byte. Once the image is downloading 100bytes then show that in imageView next download the next part of the image from url. Is it possible to doing like that?
Currently I am loading image like the following code:
URL url = new URL(url_);
URLConnection conection = url.openConnection();
conection.connect();
// getting file length
int lenghtOfFile = conection.getContentLength();
// input stream to read file - with 8k buffer
InputStream input = new BufferedInputStream(url.openStream(), 8192);
// Output stream to write file
OutputStream output = new FileOutputStream(root+"/"+ fileName);
byte data[] = new byte[1024];
long total = 0;
while ((count = input.read(data)) != -1) {
total += count;
// writing data to file
output.write(data, 0, count);
}
// flushing output
output.flush();
// closing streams
output.close();
input.close();
runOnUiThread(new Runnable() {
#Override
public void run() {
image.setImage(ImageSource.uri(root+"/"+ fileName));
}
});
Can somebody help me to solve this riddle?
Note: If there are any possibilities other than this library pls add your suggestions.
Never tried this but you can check if this work.
Get the data from url in form of byte Array.
data = getImageStream(url); //should call in async Task..
Now convert byte array into bitmap and set in imageView.
Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
image.setImageBitmap(bitmap)
Not writing into file.This will help with some performance improvement.
public byte[] getImageStream(String url){
ByteArrayOutputStream baos = new ByteArrayOutputStream();
InputStream is = null;
try {
is = url.openStream ();
byte[] byteChunk = new byte[4096]; // Or whatever size you want to read in at a time.
int n;
while ( (n = is.read(byteChunk)) > 0 ) {
baos.write(byteChunk, 0, n);
}
}
catch (IOException e) {
System.err.printf ("Failed while reading bytes from %s: %s", url.toExternalForm(), e.getMessage());
e.printStackTrace ();
// Perform any other exception handling that's appropriate.
}
finally {
if (is != null) { is.close(); }
}
return baos.toByteArray();
}
I select image from gallery, convert into Base64 and sends to server. For JPEG image, it works fine; the image I upload from gallery on server same gets shown in server folder. However, when I upload PNG format image from mobile gallery, it doesn't show same on server; instead it creates black edges around it. I really don't know what's going wrong?
Also, my actual image is as equal as given JPEG image.
Reference images:
JPEG:
PNG:
I just want to get rid of BLACK borders which should not appear for PNG format images.
Below is my code snippet
FileInputStream mFileInputStream = null;
try {
mFileInputStream = new FileInputStream(imagePathFromSDCard);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
byte[] b = new byte[1024];
int bytesRead = 0;
while ((bytesRead = mFileInputStream.read(b)) != -1) {
bos.write(b, 0, bytesRead);
}
Bitmap bitmap = safeImageProcessing.decodeFile(uri);
bitmap.compress(Bitmap.CompressFormat.PNG, 100, bos);
byte[] ba = bos.toByteArray();
String encodedImage = Base64.encodeToString(ba, Base64.NO_WRAP);
//this line sends image base64 to server & there i decode into original
new ImageAsync().sendImageProcess(getActivity(), encodedImage, this);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
You want to upload image files. But you use BitmapFactory to make a Bitmap out of them first. Then you compress the bitmap to a jpg or png byte array. After that you base64 encode the bytes to a string which you upload.
What a waiste. And you have changed the files. Do away with the intermediate bitmap.
Instead load the files directly in a byte array. Then continue with the byte array as usual.
Having said that i think its a bad idea to base64 encode the bytes of a file first as it increases the amount of bytes that have to be transferred with 30%.
I'm trying to convert files to Base64 string. For small size file it works perfectly, for files larger like 500mb it throws OutOfMemoryError. I'm to convert the file to Base64 encodedString because it is my server side requirement to upload a file through Base64 encodedstring. is it possible to convert and send a 500mb file through this method ? Thanks in advance.
byte[] bytes = null;
InputStream inputStream;
try {
inputStream = new FileInputStream(mFilepath);
byte[] buffer = new byte[1024];
int bytesRead;
ByteArrayOutputStream output = new ByteArrayOutputStream();
try {
while ((bytesRead = inputStream.read(buffer)) != -1) {
output.write(buffer, 0, bytesRead);
}
inputStream.close();
output.flush();
output.close();
} catch (IOException e) {
e.printStackTrace();
}
bytes = output.toByteArray();
} catch (FileNotFoundException e1) {
e1.printStackTrace();
}
// Here it throws OutOfMemoryError
String encodedString = Base64.encodeToString(bytes, Base64.DEFAULT);
Then I'm passing encodedString to server using HttpURLConnection.
for files larger like 500mb it throws OutOfMemoryError
Of course. The heap limit of a Java-based Android app is going to be a lot smaller than 500MB, let alone two copies of the data, one in an expanded (Base64) format. There are hundreds of millions of devices that do not even have that much RAM for the whole device, let alone for use by your app.
is it possible to convert and send a 500mb file through this method ?
Only if you can somehow stream up the converted bytes. Convert a handful of bytes, write them to the socket, convert the next handful of bytes, write them to the socket, and so forth. You have no practical way of converting the entire 500MB file into Base64 in memory and transferring it as a string.
There are good resource over converting JPEG to base64.
I am particularly interested in doing it without decoding to bimap, avoiding any memory inflation. I also understand that any file can be encoded into Base64 by converting it into byte array first.
So if we can directly create a byte array of JPEG / PNG file which is far less than the byte array of a decoded jpeg bitmap we can convert it to base64 using less memory footprint.
The closest answer I have come across is this https://stackoverflow.com/a/10160856/499752
public void getGalleryDetails(String path) throws FileNotFoundException {
InputStream inputStream = new FileInputStream(path);
byte[] bytes;
byte[] buffer = new byte[8192];
int bytesRead;
ByteArrayOutputStream output = new ByteArrayOutputStream();
try{
while((bytesRead = inputStream.read(buffer)) != -1){
output.write(buffer, 0, bytesRead);
}
}catch(IOException e){
e.printStackTrace();
}
bytes = output.toByteArray();
encodedImage = Base64.encodeToString(bytes, Base64.DEFAULT);
Log.i("ENCODED", encodedImage);
}
You could actually use this ... where you can provide the path of the file to be converted to Base64. Sorry for the late post ... Just say this post.
currently I'm using kSoap to publish data to C# web services. Now I've come to the part where I need to upload images from my machine using Base64Binary. I searched everywehre internet but couldn't come up with a proper solution.
there is a solution with external Base64 class example but I'm interested in native solution as there is a API from Android 2.2.
Since I'm a newbie I couldn't do it myself. Basically I have a sd card file path of images, I want to convert them into Base64 format to upload.
Hope someone can help me or direct me to proper documents.
Thanks in advance.
Please try this, use Base64.java from link you have specified.
Bitmap bmImage = BitmapFactory.decodeFile(Environment.getExternalStorageDirectory() + File.separator + "Your filename");
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bmImage.compress(Bitmap.CompressFormat.JPEG, 100, baos);
String encodedString = Base64.encodeBytes( baos.toByteArray() );
You should change extension of this Bitmap.CompressFormat.JPEG statement according to your file type. You can decode a base 64 string to image using following code
byte[] b;
b = Base64.decode("base 64 string");
final Bitmap unscaledBitmap = BitmapFactory.decodeByteArray(b, 0, b.length );
I figured out the issue
String Image64 = null;
try {
Image64 = Base64.encodeToString((getBytesFromFile(new File(path))), DEFAULT);
} catch (IOException e) {
e.printStackTrace();
}
//encording
public static byte[] getBytesFromFile(File file) throws IOException {
InputStream is = new FileInputStream(file);
// Get the size of the file
long length = file.length();
// You cannot create an array using a long type.
// It needs to be an int type.
// Before converting to an int type, check
// to ensure that file is not larger than Integer.MAX_VALUE.
if (length > Integer.MAX_VALUE) {
// File is too large
}
// Create the byte array to hold the data
byte[] bytes = new byte[(int)length];
// Read in the bytes
int offset = 0;
int numRead = 0;
while (offset < bytes.length
&& (numRead=is.read(bytes, offset, bytes.length-offset)) >= 0) {
offset += numRead;
}
// Ensure all the bytes have been read in
if (offset < bytes.length) {
throw new IOException("Could not completely read file "+file.getName());
}
// Close the input stream and return bytes
is.close();
return bytes;
}