ORMLite and Images saved as BLOB on Android - android

So I recently switched my database stuff over to ORMLite in my android tablet application I am writing. So far so good, got most things refactored/recoded. Though I am having issues to what was originally stored in the database as a BLOB. In my original data model it looked like this:
byte[] imageBytes;
but I don't think I can use that in ORMLite, best I could tell it has to be a string so now I have:
#DatabaseField
String picture;
But now, I am confused as to how to read and write those data bits as bytes, etc...I was using code like this to ferry data to and from the database:
...
//Set the clients image to what was captured...
Bitmap resized2= android.graphics.Bitmap.createScaledBitmap(thumbnail, thumbnail.getWidth()/2, thumbnail.getHeight()/2, true);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
resized2.compress(Bitmap.CompressFormat.PNG, 100, baos); //bm is the bitmap object
byte[] b = baos.toByteArray();
mClient.setImageBytes(b);
myImage.setImageBitmap(resized2);
//do save to the database of the image to the blob whose column is picture
ContentValues initialValues = new ContentValues();
initialValues.put("picture", mClient.getImageBytes());
String [] strArray = {""+sid};
long n = dbAdapter.updateRecordsInDB("clients", initialValues, "_id=?", strArray);
So now thats how I WAS saving the image, I am not sure how to do this if there are no BLOBS in the ORMLite and I have to use strings?
for completeness this is how i would display the image:
if(mClient.getImageBytes().length <= 1) //no image in database, thats fine use generic
myImage.setImageResource(R.drawable.sillo); // create a sillouhtette face icon here...
else
myImage.setImageBitmap((BitmapFactory.decodeByteArray(mClient.getImageBytes(),0, (mClient.getImageBytes()).length)));
So what do i have to do to get these images in and out of the database, and is the field type of String correct for a "Blob" ?

You can indeed store byte[] fields in ORMLite. To quote the manual about byte arrays:
Array of bytes (byte[]) persisted as SQL type VARBINARY. This is different from the DataType.SERIALIZABLE type which serializes an object as an array of bytes.
NOTE: Because of backwards compatibility, any fields that are of type byte[] must be specified as DataType.BYTE_ARRAY or DataType.SERIALIZABLE using the dataType field and will not be auto-detected.
So, to use byte[] you will need to specify the type of the data:
#DatabaseField(dataType = DataType.BYTE_ARRAY)
byte[] imageBytes;
The trick is that ORMLite does not automatically detect the type of the byte[] because of some backwards compatibility issues.

Related

TfLite Android: Garbage values when running inference for multiple output model

I have a model that predicts the age and gender of the input image of size 160X160. I am creating a byte buffer to input the image to the model and everything works just fine when using a model with only one output.
But when I am using the tflite.runForMultipleInputsOutputs(), I am getting garbage values which are of the form -> [[F#e233 etc.
I have followed the documentation and the sample apps to the detail and have been stuck at this for almost 2 days. Please help.
I am posting my code below for reference.
The model has 2 outputs:
Edit:
age -> float32 [1, 101]
gender -> float32 [1,2]
P.S - I am not doing anything with the output as of now. I just want to see the result of the model.
String classifyImage(Bitmap bitmap){
try{
ByteBuffer byteBuffer = convertBitmaptoByteBuffer(bitmap);
float[][] out_gender = new float[1][2];
float[][] out_age = new float[1][101];
Object[] input = {byteBuffer};
Map<Integer, Object> outputs = new HashMap();
outputs.put(0, out_age);
outputs.put(1, out_gender);
interpreter.runForMultipleInputsOutputs(input, outputs);
}catch (Exception e){
e.printStackTrace();
}
return "";
}
First, I would suggest that you double-check that the outputs from your model match your output map. It seems strange to me that the gender would be a 101-dimensional array and the age a 2-dimensional one. Have you by any chance mixed those up?
Secondly, I think you are calling toString() on the float arrays. Consider using e.g. System.out.println(Arrays.deepToString(out_age)); to present the result.

How can I store images and strings in the same database table and retrieve them

I have a form that accepts texts and images and I want to store the data in the same database table. Below is the declaration for my record but they are all strings so how do i convert the images to strings to add to this list:
site_info_record.createSiteInfoRecord(sql_sysaid_id, sql_site_id, sql_link_id, sql_customer_name, sql_site_contact,
sql_task_type, sql_address, sql_region, sql_phone, sql_fax, sql_mobile, sql_email,
sql_landlord_name, sql_rent_status, sql_loc_cords, sql_power_status, sql_voltage, sql_aircon, sql_server_room,
sql_location_idu, sql_earthing, sql_distance_idu, sql_security, sql_ducts, sql_unit, sql_install_type,
sql_isp, sql_radio_type, sql_isp_type, sql_isp_name, sql_snr_rx, sql_bs, sql_remark);
And when i want to retrieve, its also in string format:
public String getInfoData() {
String[] columns = new String[]{ROW_ID, SYSAID_ID, SITE_ID, LINK_ID, CUSTOMER_NAME, SITE_CONTACT, TASK_TYPE, ADDRESS,
REGION, PHONE, FAX, MOBILE, EMAIL, LANDLORD_NAME, RENT_STATUS, LOCATION, POWER_STATUS, VOLTAGE_MEASUREMENT, AIRCON,
SERVER_ROOM_STATUS, LOCATION_IDU, EARTHING, DISTANCE_IDU, SECURITY_CABLES, DUCTS, UNIT_TYPE, INST_TYPE,
HAVE_ISP, RADIO, ISP_TYPE, ISP_NAME, SNR_RX, BS, REMARKS};
How do i fix images data in these
This will slow your database and application. Instead of this you can try to save to SDCard and keep URI at the db.
Very easy
Two options
one:
byte[] bytes = {...}
String str = new String(bytes, "UTF-8");
or
public static String encodeTobase64(Bitmap image)
{
Bitmap immagex=image;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
immagex.compress(Bitmap.CompressFormat.JPEG, 100, baos);
byte[] b = baos.toByteArray();
String imageEncoded = Base64.encodeToString(b,Base64.DEFAULT);
Log.e("LOOK", imageEncoded);
return imageEncoded;
}
public static Bitmap decodeBase64(String input)
{
byte[] decodedByte = Base64.decode(input, 0);
return BitmapFactory.decodeByteArray(decodedByte, 0, decodedByte.length);
}
two:
You can use GSON and make an object from all your text and ByteArray and what ever you want and than just do: GSON.toJson();
In a table , you can have many columns . To have text and images in same table you can have different columns for them with following data types :-
Text - VARCHAR
Images - BLOB
Sqlite is having a data type BLOB which can hold objects .

Which field is suitable for image. varchar or blob. sqlite

Which field is suitable for the image. varchar or blob and why?
I'm using the following code to convert the image:
public String getStringFromBitmap(Bitmap bitmap) {
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(CompressFormat.JPEG, 70, stream);
return Base64.encodeToString(stream.toByteArray(), Base64.NO_WRAP);
}
public Bitmap getBitmapFromString(String imageString) {
byte[] decodedString = Base64.decode(imageString, Base64.NO_WRAP);
Bitmap decodedByte = BitmapFactory.decodeByteArray(decodedString, 0,
decodedString.length);
return decodedByte;
}
my field is varchar. Is This The Way is better? Or do I have to change my way
Neither one is good.
Image data tends to take a lot of space and the Android sqlite wrapper (CursorWindow specifically) doesn't work very well when a lot of data is being pulled from the database.
Instead, store the binary data in the filesystem and just store a path in the database.
there is no varchar(exactly) in SQLite!!!(SQLite DataType)
NULL. The value is a NULL value.
INTEGER. The value is a signed integer, stored in 1, 2, 3, 4, 6, or 8
bytes depending on the magnitude of the value.
REAL. The value is a floating point value, stored as an 8-byte IEEE
floating point number.
TEXT. The value is a text string, stored using the database encoding
(UTF-8, UTF-16BE or UTF-16LE).
BLOB. The value is a blob of data, stored exactly as it was input.
seem blob is better than other for image

how can I store image and retrieve the same in sqlite-android

I am developing an application that stores some static images in sqlite and I want to retrieve the same in a imageview.
how do I do this
thanks.
sqlite3 supports the blob type, you can save the bitmap content using the blob type.
However, the blob type has a size limit, and to save to a blob type is difficult.
So, I suggest to save the bitmap local or on the sdcard, and save the path in the database.
added :
table define a column with name 'image' using blob type
Bitmap map = ...;
ByteArrayOutputStream bufferStream = new ByteArrayOutputStream(16*1024);
map.compress(CompressFormat.JPEG, 80, bufferStream);
byte[] bytes = bufferStream.toByteArray();
ContentValues values = new ContentValues();
values.put("image", bytes);
convert the image byte array, using SQLiteDatabase class method or content provider as you like:
public long insert (String table, String nullColumnHack, ContentValues values)
to insert to table, so it save the image to blob.
and then: when you query the blob data, you can create the image like this:
BitmapFactory.Options option2 = new BitmapFactory.Options();
option2.inPreferredConfig = Bitmap.Config.RGB_565;
// added for reducing the memory
option2.inDither = false;
option2.inPurgeable = true;
return BitmapFactory.decodeByteArray(bytes, 0, bytes.length, option2);
hope it can implement your request. -):

How do you store the contents of a POJO in the preference store?

I am looking to find a way to store the value of a POJO (containing Strings, booleans, ints) in a preference variable that I can then retrieve by the key used when I store it.
The POJO contains many String / boolean / int attributes, so I don't want to store them each individually. The problem I'm running into is that the only preference variable types are String, boolean, float, and int. Is there some way to convert the POJO to a String that I could then retrieve back per it's key and convert back to the POJO, sort of like casting it>
1) Populate the POJO
2) Convert the POJO to a String
3) Store the String in the preference Store with a key value (normal preference store stuff)
4) When needed, retrieve the data back from the preference store as a String and convert it back to the POJO.
Not the most elegant solution but:
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
objectOutputStream = new ObjectOutputStream(outputStream);
objectOutputStream.writeObject(instance);
objectOutputStream.flush();
val = Base64.encodeBase64String(outputStream.toByteArray()));
To deserialise:
byte[] data = Base64.decodeBase64(dataStr);
ObjectInputStream objectInputStream = null;
try
{
ByteArrayInputStream inputStream = new ByteArrayInputStream(data);
objectInputStream = new ObjectInputStream(inputStream);
return (T)objectInputStream.readObject();
}
finally {
if (objectInputStream != null)
objectInputStream.close();
}
Where T is the object type.

Categories

Resources