Background
Currently I am working on a project that needs to deal with all images on Android phone. Android provided the MediaStore.Images.ImageColumns, together with ContentResolver I can access meta data like longtitude and latitude of all images.
Question
What if I want to mark the photos with custom tags, and query photos with these tags, like, retrieve all photos tagged with "food"? What are the possible ways to do this?
Possible solution
For jpeg files, one can use ExifInterface to add attributes(the setAttribute() and saveAttributes() method). But according to the document:
This is expensive because it involves copying all the JPG data from one file to another and deleting the old file and renaming the other.
Is it efficient enough when I have thousands of megapixel jpeg images?
I was considering building another database that syncs with the MediaStore database regularly. Better solutions?
Related
We're building an app (ios and Android) that lists ~1000 records. This list is displayed in a tableview/listview with an image related to each record displayed in the view. When a record is selected, a detail view opens up and displays multiple images related to that record.
What are some of the best (and simplest) ways to organise these image assets in both platforms and access them?
More info:
There is also a few lines of text related to each detailed screen. This also needs to be handled.
The images should be packaged with the app as the app will be used offline a lot.
For iOS ::
Collection view for display once selecting would probably be the most simple.
1000+ images? That is pretty big and will bloat your ipa for the store, also it locks you into having to add all images. You should really have those on a server and download them when needed, or download all on first load or something.
I'd have thumbnails or something for the tableview then when selected download the related images into a directory on the app bundle. That temp directory can act as your source. Just create a wrapper that reads the directory and creates and ImageObject for each image found (image and text description if available) and compile into a Dictionary with the key being whatever identifies each record.
The wrapper is an important layer when compiling all the images associated with the records because you can swap the implementation if needed as long as you maintain the interface contract of using a Dictionary to organize your data.
The tableview displays all the records and downloads the thumbnails when needed (this is pretty standard). Selecting the record then goes to a collection view that asks the wrapper for the records images/descriptions. The wrapper grabs the either from the system or the server and returns the dictionary. Then the collection view uses the dictionary as the data source displays all the images with the image descriptions
That's how I'd do it based off your vague specs anyhow.
First of all, it is definitely not recommended to store them in Core Data. Core Data has low performance and can't be cross-platform. I don't see any benefit in storing images into Core Data, and you need to serialize it when displaying.
I recommend that you store your records in a SQLite database. SQLite is a high-performance, cross-platform embedded database that is fully supported by both platforms.
Create a SQLite 3 database and store all the records, but there are two cases for the image:
The image is very small, such as the icon of the button, the number of images is less, then you can store them directly in the database.
The image is large, the number is large, then it should be stored in the system, only store the name or path of the image into database.
I recommend storing the image in the system, because blob data can't be queried and indexed. It's more troublesome when you need to do something with the image. Reading from the system will be more faster than reading from the database.
Images should be compressed before packaging. If the image is large, creating a corresponding thumbnail will improve UI fluency.
Then you just need to copy the database and images (if not stored in the database) to your apps. When the data changes in the future, you only need to replace the database for your apps.
I have an app that downloads many images that are about 50k to 100k in size. The full database can be anywhere from 50MB to 500MB.
We are currently using sqlite, but it has slow inserts. We did a test writing files and that was slow as well. It seems to be taking about 300 to 800ms per image to write - which comes out to about 250kb/sec (slower than the network speed). I did a benchmark with A1 benchmark and it says my write speed is 14MB/sec, so i'm not sure why my app is so slow?
Here are the primary requirements:
1) Fast writes
2) Fast reads/lookups via an custom integer key (this can be converted a file path for individual files)
3) Prevents user from easily accessing the images (if we save as images they can connect the external storage to their computer and browser, but we can write the files in reverse byte order)
hopefully we can still use the sqllite solution, as i like one file, but either way it seems like a storage issue?
As suggested in the comments, I think you are better off using the private memory storage for the actual images. This will have better speed then storing BLOBs in SQLite.
If you still need to keep a DB, for example for complex image searches or such, I suggest you just replace the BLOB field in your DB with a string with the actual location of the image file.
Another solution is to keep the images as app assets, but this assumes the images are always the same and can't change dynamically, and I doubt this is your use case.
I have been asked to create a tiny android app.
In everyday work i code for .NET and I have no experience connected with Android, but as it is a really small app I guess it's going to be a good experience rather than something hard.
The core of the app would be a small database (probably XML, unless somebody suggest better solution) that would contain categories, names of the institutions assigned with each category and logo (not very high resolution I guess a single file would be <100kB) of the institution.
The database also would not be very big - I expect not more than 1000 records in total. The DB has to be totally offline and local, it cannot require Internet access when operating.
The model I assume would be to ship new version of the application when the database changes (which is not going to be very frequent).
What is the best way to deal with these requirements?
My first idea was to create an XML file that would contain the records and link to the image. The XML and all the images linked to it would be stored in single file (preferably zip) that would be stored in app resources. This is very good as it is going to be very easy to update the database.
The second idea that somebody suggested me would be to use SQLite and store images in BLOB. In general I have read that it isn't a good idea to store images in database directly, and I am afraid if it's going to be possible to meet all requirements mentioned above.
Mostly I have no idea how to update the database easily and attach it to new version of application.
Any suggestions?
I would be grateful for any response.
I wouldn't go about using XML to save your data and by no means zip anything.
I think your way of thinking is ok, but you're making things really complicated for yourself.
Seeing as you're used to .NET I suppose you're also pretty confident with SQL, so I'd suggest you have a look at how to use the built-in SQLite database in Android.
If you would go the XML route you'd have to serialize and de-serialize the XML file over and over again and then parse the XML. Ok you don't have a lot of data, but searching inside an XML file with at least 1000 nodes would be slow in comparison to the performance of a database.
Also upgrading an existing SQLite database is not that hard - Android has methods for that (onUpgrade coming from the SQLiteOpenHelper).
As to saving images I'm assuming that you won't fetch new pictures from the Internet, so it would be best just to store them in the drawable folder of your app (be mindful of different screensizes) and then reading them into an ImageView when needed. To figure out what image should go for what institution I would store either the image name of each image in the SQLite database or store the resource id for each image in the database - for instance R.drawable.myawesomepictureformyinstitution.
I know my answer is somewhat "superficial", but your question is also somewhat "broad" and hard to answer without me actually writing most of the code, and that's not my intention ;-)
Hope this helps - let me know if anything is unclear.
There are few questions related to this topic on stackoverflow, But I didn't get the proper answer. I have some doubts on performance of flat files, Is it better to use flat files instead of SQLite ? Can anybody have performance statistics ? Or example of proper way to code flat file in android.
Aside from performance benefits, here's a simple list of advantages of using SQLite rather than flat file:
You can query items as you wish -- don't need to load all of them and select which ones you need.
Deleting records is a much less painful process. No rewriting of whole files into wherever.
Updating a record is as easy as removing or creating one.
Have you ever tried doing cross-referencing lookups on a flat file? Not worth it.
To summarize, it's every advantage a Database has over a text file.
It depends on your requirement.
If your storage data size is structured-bulky in size then i suggest you for SQLite. On the other hand if the data size is just a single or few lines then flat file is best option.
What makes difference between them is, SQLite stores data in structured format, so it will be easier to find a record from multiple set of records which is very tedious process in case of flat file.
However when if you are storing blob kind of data then it is suggested to use combination of both, SQLite and file system both. i.e. store the image/sound/video data as file format and store their path in SQLite.
Also visit this accessing performance.
SQlite definitely way better in terms of performance and this gets even more important as the size of your data increases.
I've been working on a flutter app where I needed to display a filtered list of items dynamically based on typed text. I initially used a json file to store data and would read and store relevant values into a list, then filter this list as the user types.
This worked just fine with a few items so I thought I was fine until I tested with a real dataset which contained over 150,000 items. Trying to filter a list this large as a user types crashed the app. I moved to a database solution and all my problems were solved. Instant filtering and no more crashes
I have an android application that allows users to upload images to their account. Im storing the images as longblob files in a mysql db and pulling them from that but I have read on here and other places that its more efficient to store your images in a file system. I know it will work for my alpha to show but its already sucking up space in the db.
Ive seen plenty of people on here and other places mentioning file systems over using a db however....no one makes any references to specific file system software or set ups. Ideally I need a system that would allow for the fastest retrieval of images from it and it has to work with a query from php.
Any tips on the matter would be awesome :)
You could store the images on the file system, and use the database to keep a file-pointer, which is simply the path to the location of the image on your system. Then, use a query to fetch the location, and use that as you would for any image.
This thread on DaniWeb shows how uploads could be handled:
http://www.daniweb.com/web-development/php/threads/162230
Also, use relative paths in case you wish to move the location of the images in the future, as mentioned in the chosen answer here:
When storing Images in the File System, Use relative paths or absolute paths?