Encoding and Saving Images as Strings in Preferences in SUSI Android App

In this blog post, I’ll be telling about how to store images in preferences by encoding them into Strings and also how to retrieve them back. Many a times, you need to store an image in preferences for various purposes and then need to retrieve it back when required. In SUSI Android App, we need to store an image in preference to set the chat background. We just simply select image from gallery, convert image to a byte array, then do a Base 64 encoding to string, store it in preferences and later decode it and set the chat background. Base64 Encoding-Decoding in Java You may already know what Base 64 is but still here is a link to Wikipedia article explaining it. So, how to do a Base64 encoding-decoding in java? For that java has a class with all such methods already present. https://docs.oracle.com/javase/8/docs/api/java/util/Base64.html According to the docs: This class consists exclusively of static methods for obtaining encoders and decoders for the Base64 encoding scheme. The implementation of this class supports the following types of Base64 as specified in RFC 4648 and RFC 2045. Basic URL and Filename safe MIME So, you may just use Base64.encode to encode a byte array and Base64.decode to decode a byte array. Implementation 1. Selecting image from gallery      Start Image Picker Intent and pick an image from gallery. After selecting you may also start a Crop Intent to crop image also. After selecting and cropping image, you will get a URI of the image. override fun openImagePickerActivity() { val i = Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI) startActivityForResult(i, SELECT_PICTURE) } val thePic = data.extras.getParcelable<Bitmap>("data") val encodedImage = ImageUtils.Companion.cropImage(thePic) chatPresenter.cropPicture(encodedImage) 2. Getting image from the URI using inputstream Next step is to get the image from file using URI from the previous step and InputStream class and store it in a BitMap variable. val imageStream: InputStream = context.contentResolver.openInputStream(selectedImageUri) val selectedImage: Bitmap val filePathColumn = arrayOf(MediaStore.Images.Media.DATA) val cursor = context.contentResolver.query(getImageUrl(context.applicationContext, selectedImageUri), filePathColumn, null, null, null) cursor?.moveToFirst() selectedImage = BitmapFactory.decodeStream(imageStream) 3. Converting the bitmap to ByteArray Now, just convert the Bitmap thus obtained to a ByteArray using below code. val baos = ByteArrayOutputStream() selectedImage.compress(Bitmap.CompressFormat.JPEG, 100, baos) val b = baos.toByteArray() 4. Base64 encode the ByteArray and store in preference Encode the the byte array obtained in last step to a String and store it in preferences. val encodedImage = Base64.encodeToString(b, Base64.DEFAULT) //now you have a string. You can store it in preferences 5. Decoding the String to image Now whenever you want, you can just decode the stored Base64 encoded string to a byte array and then from byte array to a bitmap and use wherever you want. fun decodeImage(context: Context, previouslyChatImage: String): Drawable { val b = Base64.decode(previouslyChatImage, Base64.DEFAULT) val bitmap = BitmapFactory.decodeByteArray(b, 0, b.size) return BitmapDrawable(context.resources, bitmap) } Summary So, the main aim of this blog was to give an idea about how can you store images in preferences. There is no way to store them directly. So, you have to convert them to String by encoding…

Continue ReadingEncoding and Saving Images as Strings in Preferences in SUSI Android App