I have a Sqlite database in which a base64 code string is stored as a BLOB. I want to fetch this BLOB from the db and decode the base64 and show the image in an ImageView.
I have read about encoding and decoding base64 and this is what I am using now.
String[] image = new String[100000];
if (cursor.moveToFirst()){
int i = 0;
do {image[i] = cursor.getString(1);
i++;}
while (cursor.moveToNext());
String imagebyte = image[0];
byte[] decodedString = Base64.decode(imagebyte, Base64.DEFAULT);
Bitmap decodedByte = BitmapFactory.decodeByteArray(decodedString, 0, decodedString.length);
mImage.setImageBitmap(decodedByte);
But nothing shows up and I don't get any error messages. In order to pinpoint the problem I tried encoding and decoding an image, and then the bitmap showed. Is this the right way to decode it? I am here using cursor.getString(1), I have tried with using getBlob(1) also, but still nothing shows. Should I use getString or getBlob?
Is there an easy way to check validity of the base64 code? THanks!
I have a Sqlite database in which a base64 code string is stored as a BLOB.
Why? Why not just put the image in the BLOB? What are you gaining by Base64-encoding it? It is costing you CPU time, garbage collection time, and storage space.
String[] image = new String[100000];
Why do you think you need 100,000 String objects?
do {image[i] = cursor.getString(1);
i++;}
while (cursor.moveToNext());
Why are you retrieving this column for all rows in your result set, when you are only using one of them? Particularly considering you are obviously doing all of this on the main application thread, and therefore you will eventually crash with an application-not-responding (ANR) error?
Also, if this column is declared in your database a BLOB, are you sure that getString() will work as you expect?
Is this the right way to decode it?
That would depend upon how you encoded it.
Should I use getString or getBlob?
That depends on how you put the data in the table and what data type the column has. They should all match.
But I would just get rid of all the Base64 stuff and store the image byte array in the BLOB column, if you want an image in a table.
Related
I've seen a huge number of related questions, but none of them actually answer the question, and many just use code snippets out of context with undefined variables.
I need to store images in a database (which to the best of my knowledge I should do using Base64 encoded strings), and use them as Image objects in the android code.
From what I've worked out, I need to convert the Image to a Bitmap, then Bitmap can be turned into a Base64 string. But I can't for the life of me work out how to convert the Image into a Bitmap. Any help is appreciated.
EDIT: While other questions do convert an image from a file location to a string, I don't have a file location. The image is stored solely as an instance of android.media.Image, and I don't know how to access that using a file path or anything similar.
EDIT 2: Okay, so here's my setup: the images will be stored in Firebase database as Base64 encoded strings. When I need them, I will pull the string from there and convert it into an Image object, which is just a variable I have temporarily. They are never stored locally, the only time they're on the actual app they are the Image object.
Just convert your base64 string into bitmap than load that bitmap into imageview using below code
byte[] decodedString = Base64.decode(encodedImage, Base64.DEFAULT);
Bitmap decodedByte = BitmapFactory.decodeByteArray(decodedString, 0, decodedString.length);
image.setImageBitmap(decodedByte);
In my android app, each string stored in mysql database is encoded.
I do this because i have emoji in strings, and this is the only way i found.
Encode :
byte[] data = str.getBytes("UTF-8");
String base64String = Base64.encodeToString(data, Base64.DEFAULT);
Decode :
byte[] data = Base64.decode(userObject.getString("mystr"), Base64.DEFAULT);
String question = new String(data, "UTF-8");
You're right, you should save the text data in a simpler way. The problem you mention with emojis can be resolved changing the default character set of your database tables to utf8mb4.
You can accomplish that by doing the next steps:
Change the character set of your tables in the MySQL database using this SQL statement
like this:
ALTER TABLE your_table_name charset=utf8mb4,
MODIFY COLUMN your_fieldname1 VARCHAR(255) CHARACTER SET utf8mb4,
MODIFY COLUMN your_fieldname2 VARCHAR(255) CHARACTER SET utf8mb4;
Add this to the MySQL conf file and restart or reload the server (usually located at /etc/mysql/my.cnf or similar)
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
Everytime you access your database in your Android application
execute the next query: SET NAMES utf8mb4;
Query your text column as a normal String object in Java and you should see the emojis correctly displayed (no need for byte array or Base64 encoding).
According to wikipedia:
Base64 encoding schemes are commonly used when there is a need to encode binary data that needs be stored and transferred over media that are designed to deal with textual data. This is to ensure that the data remains intact without modification during transport.
Unless you have a specific reason for doing so, I don't recommend passing everything from your app to the backend web service in Base64.
Maybe, you can use a BLOB type field on your sqlite database...
BLOB. The value is a blob of data, stored exactly as it was input.
Sqlite.Org - DataTypes
Is there a way to know if a byte array is a valid image?
I am taking a photograph, In OnActivityResult:
Bitmap imageBitmap = (Bitmap) extras.get("data");
imageBitmap.compress(Bitmap.CompressFormat.JPEG, 75, out);
//arrayFotos is an ArrayList
arrayFotos.add(new BeanFotos("", imageBitmap, lastKnwonLocation.getLatitude(), lastKnwonLocation.getLongitude()));
I am storing it in database:
//listaFotos and arrayFotos are the same array, but with different names, because I am storing it in another class in my app
for(int i=0;i<listaFotos.size();i++){
values.clear();
values.put("codficha", codficha);
int bytes=listaFotos.get(i).getFoto().getByteCount();
ByteBuffer buffer = ByteBuffer.allocate(bytes);
listaFotos.get(i).getFoto().copyPixelsToBuffer(buffer);
values.put("foto", buffer.array());
db.insert("fotos", null, values);
}
Later, I need that image to be shown:
byte[] arrayFoto = csr2.getBlob(0);
Bitmap fotoBitmap=BitmapFactory.decodeByteArray(arrayFoto, 0, arrayFoto.length);
The problem is, no matter what i do, the decodeByteArray method always returns null. I have tried with external libraries, and it is always null, so I am thinking maybe I am storing it in the wrong way. The arrayFoto variable is NOT null, I am receiving bytes (84584, to be exact) but the decodeByteArray method returns null.
So, is there a way for me to be sure that the byte array is a correct image?
Thanks.
It seems you are writing the uncompressed Bitmap to the database. You need to compress it to jpeg or png first if you want to be able to decode it using BitmapFactory.
Also, storing images in a database is a bad idea since the cursor window size is limited to 1MB. You should not store binary data in a SQLite db unless it's very small.
i have one questions, how to convert Multiple picture to byte array (byte []), cause i have case to save many picture in my database sqlite, i have array list which contains picture in drawable folder..
ArrayList<Integer> imageId = new ArrayList<Integer>();
imageId.add(R.drawable.a1);
imageId.add(R.drawable.a2);
imageId.add(R.drawable.a3);
imageId.add(R.drawable.a4);
imageId.add(R.drawable.a5);
Then i have tried this code to convert into byte arrray
Bitmap b = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.a1);
//calculate how many bytes our image consists of.
int bytes = b.getByteCount();
ByteBuffer buffer = ByteBuffer.allocate(bytes); //Create a new buffer
b.copyPixelsToBuffer(buffer); //Move the byte data to the buffer
byte[] array = buffer.array();
System.out.println(array);
The code below is working, but the problem is how the code below is convert one picture, and now i need to convert multiple picture in arrayList, can anybody help me? cause i have tried with looping, it give me an error, java.lang.OutOfMemoryError..
Ok,
first of all do not save whole pictures to SqLite. It is not a suitable way. There's a very easy solution but a little risky..
Just save images to SD Card as WhatsApp do and save their path to SqLite. So whenever you want to access your pictures you can read their paths from Sqlite and access them.
But the risk is pictures are in user control, so they can remove it. But you can hide the pictures in a deep way :)
Recently I was working on MySql and Sql, where I found I can almost insert everything primitive type data but is it possible to store a jpeg/jpg/bmp/png (image)file in a database. If so then can you please write the code. Don't need to explain the whole thing just the key point.
Thanks
1 Perhaps convert the image to a Byte Array (if it's not bmp, then convert it), then store it in MySql as a Blob type, then when reading it, you can create a Bitmap through the code (I don't know what language you're using) with the Byte Array with what you read, or perhaps just get the code associated with the image and store that and read it.
Converting an image to a Byte Array
2 Use an image hosting API (like Imgur) and have the user's image upload to that site, and just read the URI from the database whenever you want to use it.
Imgur API, Android Example
there is 3 cases how to make it (that is i know)
Save path from SD card like String in database
Save int value if image is in res folder of your app.
Save url like String if image is in Internet.
Sorry for the late response. However, I found a way to convert the image to String and then store it in the mysql.
This answer is just for those who are still looking for a easy solution:
code:
Bitmap bm = BitmapFactory.decodeFile("/path/to/myImage.jpg");
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bm.compress(Bitmap.CompressFormat.JPEG, 100, baos);
byte[] b = baos.toByteArray();
and then:
String encodedImage = Base64.encodeToString(byteArrayImage, Base64.DEFAULT);
Then the encodedImage which is a String format, I can insert into the db.
Hope that helps other who are still looking for the answer.