Go from JPG to Bitmap then store in a Database - android

I am developing an android app where I have users upload profile pictures from their phones which are then saved into a database. What I have so far is I create a bitmap from the user's picture, then I compress it with the bitmap compress function and then my server receives the byte array and stores it into the database. I can then send the byte array back but I cannot figure out how to convert the byte array into a bitmap again. Here are some code snippets of what I am doing:
(Here I am just taking a dummy picture from in the app and sending it to the server)
Bitmap t = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.j0);
mProtocol.updateUser(t);
(The updateUser command)
public void updateUser(Bitmap b){
try {
mOutput.writeObject(20);
b.compress(Bitmap.CompressFormat.JPEG, 90, mSocket.getOutputStream());
} catch (IOException e) {
e.printStackTrace();
}
}
(Finally, I try to recreate the bitmap from the byte array)
Bitmap t = BitmapFactory.decodeByteArray(user.getProPic(),0, 20000);
But after I run the app, the bitmap still remains blank. Any thoughts of what is going on?

Related

wrong Base64 string after bitmap photo encoding

So in my app I have possibility to take photo. What I want to do later is to sent this photo to server using API as Base64 String. Here's my code to encode bitmap (photo) to String :
public static String convertPhotoToBase(Bitmap bmp) {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.PNG, 100, byteArrayOutputStream);
byte[] byteArray = byteArrayOutputStream.toByteArray();
Log.e(TAG, Base64.encodeToString(byteArray, Base64.DEFAULT));
return Base64.encodeToString(byteArray, Base64.DEFAULT);
}
Looks ok, right ? Well, it's not and I don't why String I'm receiving is not encoded correctly. I add, that bitmap is ok , cuz I can display it in ImageView without any problems.
String I'm getting looks like this :
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 UHOSaACXt9dDDgZlJXClyxBszo4tmGKJp
It looks like correct Base64 string but if you check it - it's not. Do you have any idea why is that ? Is it bitmap issue ,or what ? Any help, please ?
use this method to encode the bitmap you want
public static String enBitmap64(Bitmap bitmap) {
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream);
bitmap.recycle();
byte[] array = stream.toByteArray();
return Base64.encodeToString(array, 0);
}
and this method to decode the string
public static Bitmap deBitmap64(String string) {
byte[] decodedString = Base64.decode(string, Base64.DEFAULT);
Bitmap decodedByte = BitmapFactory.decodeByteArray(decodedString, 0, decodedString.length);
return decodedByte;
}
However, before using encode64 you need to know few things
Encode and decode bitmaps needs to be done in background (NOT IN THE MAIN THREAD) it hangs the UI specially if the bitmap was large, use Asynctask, Service or Runnable (Asynctask is best choice).
It's not recommended to encode large images and upload it as string to server, encode and decode only in two cases.
First, if all you images are small.
Second, if you have large images and somewhere you app you display it as thumbnail For exp; In friends search of Facebook you see small images(thumbnail) you click it becomes large(original image). so there is small image and large image, when you are in friends search page you only request(download) the small image (low resolution) from the server no need to request(download) such large image(high resolution), but the two images are stored in the server. the small one could be saved as encoded but NOT the large one, large images is to be upload to server though HttpClient, Volley or HttpURLConnection.. there are more
I have almost the same issue,
encoding and decoding were working perfectly on the java side.
But my Base64 string couldn't be decoded on the server side.
comparing different base64s helped me to see that my base64 break into lines so using following code helped to correct base64
base64string.replace("\n", ""));

Storing and retrieving app icons of all installed apps programmatically

I am building an app in which I programmatically collect details of all the apps installed on the device (appName, packageName, appIcon, and some other appDetails).
However, I observe that fetching and storing these app details in a data structure takes a perceivable amount of time. I have tried storing some of the app details using SharedPreferences so that I can retain data between different app executions and not initiate a fetch each and every time my app is launched.
Storing the app icons (drawables) however, takes up a lot of space and makes me wonder if there is a more efficient way of retaining the above mentioned app data between app executions, unless of course, new apps are installed after the last time the installed apps were programmatically fetched.
So, my question is, is there a efficient way of storing app icons (drawables) such that they don't take up too much space, and at the same time, the app set can be retained between different app executions?
I believe your best shot is saving the list of Apps installed in your App database. You can store the drawable icon of the app as encoded string.
String image = getImageFromDrawable(app.loadIcon(pm));
where app is ApplicationInfo and pm is PackageManager.
public String getImageFromDrawable(Drawable drawable){
String img = null;
if(drawable instanceof BitmapDrawable) {
Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap();
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
byte[] arr = stream.toByteArray();
img = Base64.encodeToString(arr, Base64.URL_SAFE);
return img;
}
return null;
}
You can then store the details of the app in your application database.
This can be done by converting icons to String and storing them in a file using Parceler. To do so,
Create an App POJO class with icon as an attribute of Bitmap type
Make your class Parcelable
Initialize an ArrayList of this class type with all icons to be stored
Parcel and store these objects in a file
Now, attributes of type Bitmap are not Parcelable, so you will have to convert them to parcelable type. You may use this function for conversion:
static String bitMapToString(Bitmap bitmap) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);
return Base64.encodeToString(baos.toByteArray(), Base64.DEFAULT);
}
And the following function to convert the data back to Bitmap type.
static Bitmap stringToBitMap(String encodedString) {
try {
byte[] encodeByte = Base64.decode(encodedString, Base64.DEFAULT);
return BitmapFactory.decodeByteArray(encodeByte, 0, encodeByte.length);
} catch (Exception e) {
e.getMessage();
return null;
}
}

Android: Efficient way to grab image from camera and send it to server

I need my App to take a photo using the camera, show it in my Activities ImageView, and then sent it to a server using an HttpClient. So far, so good. Unfortunately, I stumbled upon the well described MemoryOutOfBoundsException. So I want to compress my image using JPG or PNG.
Now - after some excessive googling - do I get this right:
a) The camera will always output an uncompressed Bitmap, which is directly written to the file system. I.e. like this:
Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
this.imageTempFile = new File(android.os.Environment.getExternalStorageDirectory(), "myTempFileName"); // write the camera output to a tmpFile
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(this.imageTempFile)); // link the tmpFile to a member for convenience later on
startActivityForResult(cameraIntent, CAMERA_REQUEST);
So there is no way to resize / compress it right away?
b) If I want to display an image in a ImageView, I need to pass a Bitmap to it using ImageView.setImageBitmap(Bitmap bm). So showing the result is extremely memory consuming...!?
c) If I want to alter the Bitmap (resize / compress), I need to read it from this file into memory using a BitmapFactory
d) Now I can resize the Bitmap using Bitmap.createScaledBitmap()
e) But if I want to compress the image, I need to write it back to the file system using an OutputStream via Bitmap.compress()...
f) So for the task of taking an image, resizing it, showing it, and then sending it to a server, I need to actually write it to a file, then read it, then write it to a file again, then read it - and then send it? WTF? I there no easier way?
PS: Here's my code for b) to e):
// c) read the Bitmap from file
Bitmap bitmap;
BitmapFactory.Options bitmapOptions = new BitmapFactory.Options();
bitmap = BitmapFactory.decodeFile(this.imageTempFile.getAbsolutePath(), bitmapOptions);
// d) do some resizing
bitmap = Bitmap.createScaledBitmap(bitmap, (int) mywidth, (int) myheight, true);
// e) compress
OutputStream out = new ByteArrayOutputStream(50);
this.imageTempFile.delete();
File file = new File(this.imageTempFile.getAbsolutePath());
try {
out = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.JPEG, 85, out);
out.flush();
out.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
// NOW we could read it again from the file to send it afterwards...
Bitmap newBitmap = BitmapFactory.decodeFile(this.imageTempFile.getAbsolutePath(), bitmapOptions);

BitmapFactory decode function for Android

I encounter problem with .decodeStream function.
File cacheMap = new File(context.getCacheDir(), "test.GIF");
if(cacheMap.exist()){
FileInputStream is = new FileInputStream(cacheMap);
Bitmap bitmap = BitmapFactory.decodeStream(is);
puzzle.add(test);
}else{
//retrieved from server and cache the image
}
The decode function always return null value. And from the internet, I found that in order to display the image, the Bitmap is always set to an ImageView. But what I am doing here is storing it into a ArrayList of Bitmap and display it later on in a Canvas. Can anyone tell me how to get back the image after decoding it?
From this page, it states the following,
public static Bitmap decodeStream (InputStream is)
Decode an input stream into a bitmap. If the input stream is null, or cannot be used to decode a bitmap, the function returns null. The stream's position will be where ever it was after the encoded data was read.
Parameters: The input stream that holds the raw data to be decoded into a bitmap.
Returns:The decoded bitmap, or null if the image data could not be decoded."
Does it means that the image that was cached previously cannot be use to decode it even though I had run the few line of code to cached the image?
cacheMap.createNewFile();
fos = new FileOutputStream(cacheMap);
bitmap.compress(CompressFormat.JPEG, 100, fos);
fos.flush();
fos.close();
Does anyone know what is wrong with my code? i have been tackling this issue for days and is driving me crazy!

How to display image from blob data in android sqlite?

I have been trying to store image form android sdcard to the sqlite database. And it worked fine. The image is getting stored into the database as blob. This is the rough code I have been using for that.
Bitmap bitmap = BitmapFactory.decodeFile(filePath);
imgView.setImageBitmap(bitmap);
int size = bitmap.getWidth() * bitmap.getHeight();
ByteArrayOutputStream out = new ByteArrayOutputStream(size);
bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
try {
out.flush();
out.close();
} catch (IOException e) {
e.printStackTrace();}
byte[] x = out.toByteArray();
In the database side, the code is like this
ContentValues values = new ContentValues();
byte[] bytes = null;
bytes = img_bytes.getBytes();
values.put("IMAGE", bytes);
And for displaying I have used the code as below.
ImageView image = new ImageView(this);
byte[] img_bytes = result.get("IMAGE").getBytes();
Bitmap bMap = BitmapFactory.decodeByteArray(img_bytes, 0, img_bytes.length);
image.setImageBitmap(bMap);
When I printed the string value of the byate array, it was getting like [B#44da2db0. But the byte array is not getting displayed into image.
Somebody please help me with this.
Thanks
I have found a solution. Thanks to all.
I have used base64 encoding method.
ie; For displaying the image, I have been using a hash map to get the result first of all from the database table.
So before saving into the map, I have encoded the bytes to string using base 64 method.
Then On the Activity side for displaying the image, I have decoded back the string using base 64 again and then converted to bytes and the image got displayed.

Categories

Resources