Uploading image using Dropbox API, Android - android

After capturing an image, I'm unsure of how to upload the bitmap as a file. I get the bitmap this way:
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if(requestCode == CAM_REQUEST_CODE){
if(resultCode == RESULT_OK){
final Bitmap image = (Bitmap)data.getExtras().get("data");
}
}
}
Using Dropbox API, a file is uploaded this way:
File file = new File("working-draft.txt");
FileInputStream inputStream = new FileInputStream(file);
Entry response = mDBApi.putFile("/magnum-opus.txt", inputStream,
file.length(), null, null);
Log.i("DbExampleLog", "The uploaded file's rev is: " + response.rev);
Any help on this is greatly appreciated.

Here's one way you could do it:
Create a ByteArrayOutputStream
Call Bitmap.compress() to write the JPEG/PNG bytes to outputstream
Create a ByteArrayInputStream from the byte array you just output
Use that input stream for your putFile() method
Use the array size for your file length
I would be cautious about memory, though. It it was me, I'd try to find a way to return the bitmap source in the activity result instead of the actual bitmap.

Related

How to Reduce Image Size (Taken For Camera ) before Uploading to Firebase

In Android I am taking image from camera as usually its around 5-6 MB. So I want to Reduce this Image size before uploading.
Can't it be done using library like Picasso or Glide
Use the following code:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
if (CAMERA_REQUEST == requestCode && resultCode == RESULT_OK)
{
Bitmap uri = (Bitmap) data.getExtras().get("data");
ByteArrayOutputStream baos = new ByteArrayOutputStream();
uri.compress(Bitmap.CompressFormat.JPEG,70, baos);
//then you can handle the firebase upload here.
}
}
Bitmap class in android has this method .compress to achieve what you want here.The details of the method are as:
compress(Bitmap.CompressFormat format, int quality, OutputStream stream)
Read more about it on the developers site :https://developer.android.com/reference/android/graphics/Bitmap.html
Hope that helps

Send image to server from gallery android bitmap

I tried to send an image to server from gallery, I compressed it with Base64.
I started an activity for gallery:
private void startGalleryActivity() {
Intent intent = new Intent();
intent.setType("image/*");
String selectPicture = getResources().getString(R.string.select_picture);
intent.setAction(Intent.ACTION_GET_CONTENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
startActivityForResult(intent, GALLERY);
}
I received the result in onActivityResult:
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == GALLERY && resultCode == MainActivity.RESULT_OK) {
Uri pickedImage = data.getData();
// Let's read picked image path using content resolver
String[] filePath = {MediaStore.Images.Media.DATA};
Cursor cursor = getContentResolver().query(pickedImage, filePath, null, null, null);
cursor.moveToFirst();
String imagePath = cursor.getString(cursor.getColumnIndex(filePath[0]));
// Now we need to set the GUI ImageView data with data read from the picked file.
imageView.setImageBitmap(BitmapFactory.decodeFile(imagePath));
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
bitmap = BitmapFactory.decodeFile(imagePath, options);
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, byteArrayOutputStream);
byte[] byteArray = byteArrayOutputStream .toByteArray();
String encoded = Base64.encodeToString(byteArray, Base64.DEFAULT);
Server s = new Server("new");
s.send(encoded);
// At the end remember to close the cursor or you will end with the RuntimeException!
cursor.close();
}
super.onActivityResult(requestCode, resultCode, data);
When I send the image to serve the size of it is 4 times higher. If I write the image after I read it, this is write with double size. Why do I have this overhead?
Why do I have this overhead?
In addition to the Base64 overhead itself, you are re-encoding the image as a PNG. If the image started as something else, like a JPEG, a PNG version of that image may be substantially larger.
Also, please delete the four lines preceded by // Let's read picked image path using content resolver. First, that code will fail on hundreds of millions of Android devices, because a Uri is not a file, and you cannot assume that you can get a local filesystem path for that data. Second, you do not need it, as BitmapFactory has a decodeStream() method that you can use with getContentResolver().openInputStream(pickedImage).
In addition, please do not call decode...() on BitmapFactory twice. Load the bitmap once. Use the bitmap both for the ImageView and for your uploading.
Calling compress on a PNG will not make your file smaller as it is already compressed. Converting a binary file to a text stream
will really make it big. To avoid less overhead by converting the PNG file
to text file, just send the file as is, as a byte array. And add the file length
in the header. You can use DataOutputStream to do this.
byte[] byteArray = byteArrayOutputStream .toByteArray();
ByteArrayOutputStream btOS = new ByteArrayOutputStream();
DataOutputStream dataOS = new DataOutputStreamEx(btOS);
dataOS.writeInt(byteArray.length); // length of file
dataOS.write(byteArray); // actual file
dataOS.write(0); // end of field
dataOS.close()
I don't know what you are using in the backend, but you can just read
the first 4 bytes of what you will receive and that will be the length
of you file. And use that length to read the entire file.
It will be approximately 37% larger:
Very roughly, the final size of Base64-encoded binary data is equal to
1.37 times the original data size
Source: http://en.wikipedia.org/wiki/Base64
You are using Bitmap and BitmapFactory to convert a small jpg file to a big png file. Why aren't you sending the jpg directly? So do NOT use Bitmap and BitmapFactory to begin with. You end up else with something that was not your file.

Uploading image taken from gallery app (Quality issue)

Using Android's gallery app to select a photo to upload with httppost later. The photo gets uploaded but it's very low quality and size. I have been reading about setting the Bitmap.CompressFormat.PNG will make it lossless but it's taking the photo from 2000x1500 to 250x187.
Is it possible that I'm getting the thumbnail and not the actual image? I'm using Photos from Google.
Code
#Override
public void onActivityResult( int requestCode, int resultCode, Intent data ) {
super.onActivityResult( requestCode, resultCode, data );
if ( resultCode == getActivity().RESULT_OK ) {
selectedImage = Uri.parse( data.getDataString() );
try {
final Bitmap v = DecodeUriImage.Decode( selectedImage, getActivity() );
ByteArrayOutputStream bao = new ByteArrayOutputStream();
v.compress( Bitmap.CompressFormat.PNG, 100, bao );
byte[] byte_arr = bao.toByteArray();
// Add image to array
images.set( selectedImageIndex, Base64.encodeToString( byte_arr, Base64.DEFAULT ) );
} catch ( FileNotFoundException e ) {
e.printStackTrace();
} catch ( Exception e ) {
e.printStackTrace();
}
}
}
}
Result
The Bitmap.CompressFormat.PNG will compress the image but It depends on what kink of format you have used on the non-compressed image. You should use a vectorial image to get the best results because on the "compressing transfer" the immage loses the quality both in getting the image bigger on not.
There is no reason to put the selected image in a Bitmap for later use. Moreover you did not show what all is happening in DecodeUriImage.Decode( selectedImage, getActivity() );. Maybe it's quality is changed there. Instead realise you have a media path in selectedImage which you can convert to a real path to the filesystem. Save that path for later use.
If you use it later than just load the file in a byte array and encode base64. Do not use Bitmapfactory.

pick image from gallery and convert into byte data how?

I need to pick an image from gallery and then convert it into byte data. I know how to pick image from gallery. Also I know how to convert image to byte data. But problem is i convert image that are in drawable but now I need to pick it from gallery and convert it to byte code. Any help
THanks
In onClick function I am using this code to pick image from gallery
Intent image = new Intent(Intent.ACTION_GET_CONTENT);
image.setType("Image/*");
startActivityForResult(image, 0);
And I have used following code to convert image that is in drawable to byte data.
bm = BitmapFactory.decodeResource(getResources(),R.drawable.ic_launcher);
data = new ByteArrayOutputStream();
bm.compress(Bitmap.CompressFormat.JPEG, 40 , data);
bitmapdata = data.toByteArray();
Now how would i convert image from gallery to byte data.
Thanks
In onActivityResult you will receive the Uri to your selected image like this:
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if(requestCode == PICK_IMAGE && data != null && data.getData() != null){
Uri imageUri = data.getData();
//....
}
}
Then to retrieve it from the MediaStore you should use :
Bitmap bitmap =
MediaStore.Images.Media.getBitmap(this.getContentResolver(), imageUri);
after that, you should process the Bitmap like you do it now.

Android: decodeFile always returns null for file in internal storage

I have a file saved locally into the application's private storage. I have verified it exists, however whenever I call BitmapFactory.decodeFile it always returns null.
If I save the file as a resource and use ImageView.setImageResource, it always shows up fine.
What is the problem?
Here is the snippet:
filename = "test.png";
if (doesFileExist(filename))
Bitmap bMap = BitmapFactory.decodeFile(filename);
I've also tried:
Bitmap bMap = BitmapFactory.decodeFile(getFilesDir().getPath()
+ filename);
This question has been answered before such as here:
BitmapFactory.decodeFile returns null even image exists
This was exactly what I needed:
String fname=new File(getFilesDir(), "test.png").getAbsolutePath();
Instead of using BitmapFactory.decodeFile, try using InputStream:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent imageReturnedIntent) {
super.onActivityResult(requestCode, resultCode, imageReturnedIntent);
if(resultCode == RESULT_OK){
Uri selectedImage = imageReturnedIntent.getData();
InputStream imageStream = getContentResolver().openInputStream(selectedImage);
Bitmap yourSelectedImage = BitmapFactory.decodeStream(imageStream);
Folks, files stored in app resource should be referenced in special way. E.g. if file is located in assets and named as "myfile.png" it has to be referenced as:
String uriString="file:///android_asset/myfile.png";
Uri uri=Uri.parse(uriString);
BitmapFactory.decodeFile expects a file path without the scheme. I.e. without the file:// in the beginning.
If you're handling a Uri, don't just .toString() it, but instead call .getPath() on it, and pass that to the method.
After adding the required permissions (READ_EXTERNAL_STORAGE, WRITE_EXTERNAL_STORAGE)
You need to add this line to manifests:
android:requestLegacyExternalStorage="true"
Could you try fileList()? It
returns an array of strings naming the
private files associated with this
Context's application package.
For me I was getting image from locally saved URL something like "file:///storage/emulated/0/...." (I have used Phonegap plugin to capture image. Plugin was giving me image path, which I need to use in native code)
Here is the code snippet which worked for me.
String captured_image_info = "file:///storage/emulated/0/Android/data/com.testapp/cache/1493809796526.jpg"
Uri uri=Uri.parse(captured_image_info);
largeLog("uri", "" + uri);
InputStream imageStream = getContentResolver().openInputStream(uri);
Bitmap bm = BitmapFactory.decodeStream(imageStream);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bm.compress(Bitmap.CompressFormat.JPEG, 100, baos); //bm is the bitmap object
byte[] decodedBytes = baos.toByteArray();
Bitmap img_captured_image = BitmapFactory.decodeByteArray(decodedBytes, 0, decodedBytes.length);
You need to setup run-time permissions for Manifest.permission.READ_EXTERNAL_STORAGE
If you don't you'll get a null without getting any error message or even an indication in the Log.
Note that you need to request the permissions both in the Manifest and at run time.

Categories

Resources