I'm looking for a way of obfuscating the images I store in my application and am currently considering Base46 Encoding.
I need something with minimal overhead or if possible a performance boost over standard files on the file system.
Can someone comment on the feasability of base64 encoding the images (png) and subsequently using (decoding?) on the target platforms?
Thanks.
What sort of attack are you trying to protect against? Base64 is reasonably easily recognizable and has a potentially-significant impact in terms of space (each image will take an extra 33% space).
Some sort of shifting XOR would be harder to spot just from the data, but it wouldn't be adequate protection for really significant assets.
I am sure you understand Base64 won't fool anyone who really want to get your Bitmap.
Jon Skeet is right, Base64 is nice to encode binary data in readable format but will not really help you here. An XOR against a password of yours will be faster, and won't add any size overhead.
If you really want to obfuscate your bitmaps I suggest you to store them in the "raw" ressources folder. By doing this you will be able to keep the nice Android abstraction that handles different form factors (ldpi, hdpi, ...).
Extends the ImageView class to directly work with R.raw.filename id and do the reading file/decoding stream/creating bitmap there. By doing so, you will be able to rollback easily to the standard way of doing things if needed.
Be warned that you could run into memory issues when storing multiple bitmaps within an application memory in Android. OutOfMemoryErrors seem to be a recurring problem when dealing with bitmaps in android. Here is an example: outofmemoryerror-bitmap-size-exceeds-vm-budget-android
Related
I am developing an Android app which has hundreds of .jpg files (over 300) each one of around 40kB. I would like to know if there is a way of reducing the size of my app. I looked at a similar question here Reducing Android App Size, but the problem still exists. Is there perhaps a way to compress the images and decompress them in real time when needed, or any other way to make my app more space efficient while not sacrificing speed?
If you have used tinypng for every resource you did your best with this kind of solution. In general, it's better to use vector graphics where the general icon will be <1kb. Also, a vector resource can be animated. If it's quite simply bitmaps, you can generate them in code on demand. Also, you can divide your app by dynamic features and each will be downloaded on demand with their part of the resources.
Is there perhaps a way to compress the images and decompress them in real-time when needed?
There is no standard Android solution out of the box. Probably, you can write something on your own. But this looks like too much effort.
Still, the most practical solution: use vector graphics as max as possible, generate in code what you can generate, compress with tinypng the others. That should be enough or you should have a very good reason for making some extra work.
For more info about vector graphics in android. For standard vector graphic import right in the android studio.
Web-site where you can download icons and insert them into the project.
I have found a number of resources but nothing that has quite helped me with what I am looking for. I am trying to understand the .png and.jpg file formats enough to be able to modify and/or read the exif or other meta data in the files or to create my own meta data if possible.
I want to do this in the context of an android application so we can keep if there but it is really not exclusive to that. I am trying to figure out how to do this using a simple imput stream byte array and go from there.
Android itself has to at least extract the RGB pixel information at some point when it creates a bmp image from the stream, I took a look in the BitMapFactory source to try and understand it but I got lost somewhere after delving into the Native files.
I assume the bmps are losing any exif/meta data in the files based on my research. So I guess I want to break the inputstreams down by byte arrays and remove meta data. In .pngs I know there is no 'standard' but based on this page it seems there is some organization of the meta data you can store.
With all that said, I wouldn't mind just leaving exif/png standards behind and trying to store my own information in some sort of standardized way, but I need to know more about how the image readers id the files as either jpg, png, ect. then determine where the pixel information is located.
So I guess my first question is, has anyone done something similar to this before so that they can file me in? If not, does anyone know of any good libraries that might be good for educational purposes into figuring out how to locate and extract this data?
Or even more basically, what is a good way to find meta data and/or the exif standard or even the rgb data programmatically using something like a byte array?
There are a lot of things to address in your question, but first I should clarify that when you say "Android itself has to at least extract the RGB pixel information," what you're referring to is the act of decompression, which is complicated in the case of JPEG, and non trivial even for PNG. I think it would be very useful for you to read through the wikipedias for JPEG and PNG before attempting to go any further (especially sections on header, syntax, file structure, etc).
That being said, you've got the right idea. It shouldn't be too difficult to read in the header of an image as a byte array/stream, make some changes, and replace the old file. A PNG file can be identified by the first 8 bytes, and there should be a similar way to identify a JPEG - I can't remember off the top of my head.
To modify PNG meta data, you'll have to understand "chunks" - types/names, ordering, format, CRC, etc. The libpng website has some good resources for this, here's general PNG info, as well as chunk specifications. Make sure you don't forget to recalculate the CRC if you change anything.
JPEG sections off a file using "markers," which are two bytes long and always start with FF. Exif is just a regular JPEG file with a more specific structure for meta data, and this seems like a reasonable introduction: Exit/TIFF
There are probably libraries for Android/Java that conveniently take care of this for you, but I've never used any myself. A quick google search turns up this, and I'm sure there are many other options if you don't want to take the time to write a parser yourself.
I'm currently writing Bitmaps to a png file and also reading them back to a Bitmap. I'm looking for ways to improve the speed at which writing and reading happens. The images need to be lossless since I'm reading them back to edit them.
The place where I see the worst performance is the actual BitmapFactory.decode(...).
Few questions:
1. Is there a faster solution to read/write from file to a Bitmap using NDK?
2. Is there a better library to decode a Bitmap faster?
3. What is the best way to store and read a Bitmap?
Trying to resolve the best/fastest possible way to read/write image to file came down to using plain old BitmapFactory. I have tried using NDK to do the encoding/decoding but that really didn't make a difference.
Essentially the format to use was lossless PNG since I didn't want to loose any quality after editing an image.
The main concept from all this was that I needed to understand was how long encoding took versus decoding. The encoding numbers where in the upper 300-600ms, depending on image size, and decoding was just fast, around 10-23ms.
After understanding all that I just created a worker thread that I passed images needing encoding and let it do the work without affecting the user experience. The image was kept cached in memory just in case it was needed right away before it was completely encoded and saved to file.
Application size on a phone needs to be as small as possible. If I have an image of a sword and then a very similar image of that same sword except that I've changed the color or added flames or changed the picture of the jewel or whatever, how do store things as efficiently as possible?
One possibility is to store the differences graphically. I'd store just the image differences and then combine the two images at runtime. I've already asked a question on the graphic design stackexchange site about how to do that.
Another possibility would be that there is that apk already does this or that there is already a file format or method people use to store similar images in android.
Any suggestions? Are there tools that I could use to take two pngs and generate a difference file or a file format for storing similar images or something?
I'd solve this problem at a higher level. For example, do the color change at run-time (maybe store the image with a very specific color like some ugly shade of green that you know is the color to be fixed at run-time with white or red or blue or whatever actual color you want). Then you could generate several image buffers at load-time.
For compositing the two images, just store the 'jewel' image separately, and draw it over the basic sword. Again, you could create a new image at load-time, or just do the overdraw at run-time.
This will help reduce your application's footprint on flash, but will not reduce the memory footprint when the app is active.
I believe your idea of storing the delta between 2 images to be quite good.
You would then compress the resulting delta file with a simple entropy coder, such as Huffman, and you are pretty likely to achieve a strong compression ratio if similarities with base image are important.
If the similarity are really very strong, you could even try a Range Coder, to achieve less-than-one-bit-per-pixel performance. The difference however might be noticeable only for larger images (i.e higher definition than a 12x12 sprite).
These ideas however will require you or someone to write for you such function's code. This should be quite straightforward.
An very easy approach to do this is to use an ImagePack ( one image containing many ) - so you can easy leverage the PNG or JPG compression algorithms for your purpose. You then split the images before drawing.
I am creating a simple android app to view a comic book. The pages are large(0.5-1 mb each), high quality .png's and I am loading them into a webview to make use of the built in zoom controls. So far I only have 17 files and the APK size is already about 16 mb. I'm looking to add over 200 files in future updates. I can't really reduce the quality too much because there is small text that must be zoomed-in on to read. Any suggestions? A similar question was posted here: How to reduce App (.apk) Size, but I don't want to lose the quality of the images. I'm not sure if it's appropriate to link to here, but you can have a look at my app by searching for Tracer (by Detour Mobile) on the android market if it helps at all. Thanks in advance.
You could compress them without using lossy compression- e.g. zipping/rarring them, but I don't believe this would gain you much more than a few kilobytes here and there. Otherwise, try using a more compact format than PNG, such as JPEG (you won't lose too much quality.) By the way, all of this was suggested in the referenced post.
If you do decide to scale down the images' size somewhat, be sure to use a method like bicubic sharper- it tends to look better than others when reducing image size.
Another option would be to download the images for the comic that is being read on-the-fly with pre-fetching so reading would not be interrupted as much.
Consider placing your images in Assets folder as opposed to Res. The big difference is, Assets content won't be compiled into R.java class so you will see major storage savings. You'd have to modify your code though as you won't be able to call up the images via the regular r.resID notation, but it's doable
android offers a new way to deal with it.
android app bundle apk size has a maximum size of 150mb
but you can use an asset pack to seperate the apk from the static files
and upload your app
here is a more detailed explanation about asset packs:
https://developer.android.com/guide/playcore/asset-delivery
here is the guide for integrating asset packs with regular android app:
https://developer.android.com/guide/playcore/asset-delivery/integrate-java