Scale Image Size in Kotlin Android Studio - android

I am receiving a base64 image from an api that is 192x192 in size. I am using the following code to change the base64 data into a Bitmap.
fun Base64ToBitmap(myImageData: String): Bitmap {
val imageAsBytes = Base64.decode(myImageData.toByteArray(), Base64.DEFAULT)
return BitmapFactory.decodeByteArray(imageAsBytes, 0, imageAsBytes.size)
}
Then I am using the following code to replace the previous contents of my ImageView.
ImageHeader.setImageBitmap(img)
The xml for that ImageHeader are as follows.
<ImageView
android:id="#+id/ImageHeader"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="100dp"
android:contentDescription="#string/ImageHeader1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.497"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="#+id/text_home"
app:srcCompat="#drawable/defaultpng" />
As expected this makes a very small image on the app. Is there anyway I can scale it's size x2 or x4 without having to create a larger image from my base php api? Sending extra data over the API seems like a waste.

You can use Glide to resize your bitmap, see below
Glide.with(requireActivity())
.override(THUMBNAIL_SIZE, THUMBNAIL_SIZE)
.load(yourBitmap)
.into(yourImageView)

Related

Android BitmapFactory.decodeByteArray get the photo width/height is exchanged than iOS UIImage(data:)

I get a base64 string from the server, then I parse it to image, on Android side, the image is rotated to 270 degree, its width/height is exchanged than iOS side. Any idea? Thank you. Here is the code:
Android code:
val decodedByteArray: ByteArray = Base64.decode(base64Str, Base64.DEFAULT)
val bitmap = BitmapFactory.decodeByteArray(decodedByteArray, 0, decodedString.size)
Timber.i("image size: ${bitmap.width}, ${bitmap.height}")
iOS code:
if let photoData = Data(base64Encoded: base64Str, options: .ignoreUnknownCharacters),
let photo = UIImage(data: photoData) {
printLog("photo size: \(photo.size)")
cell.ivPhoto.image = photo
}
Check if your image has a rotation angle in its EXIF tag.
The Bitmapfactory does not perform any EXIF rotations/transformations at all.
Use the ExifInterface class to get such information. Remember to use the AndroidX variant instead of the deprecated framework one.
If such is the case, then you must rotate the image according to the EXIF angle.
This operation will require to create a new bitmap, therefore in order to avoid a potential OutOfMemoryError, use some of the tips provided in this link.
Check the image base64 data using any base64 to the image viewer. If it's same as uploaded. Then that might the android thing which rotates the image when it converts to base64 to image. So when you convert base64 to image you can rotate the image to a specific angle or portrait.
Android Bitmapfactory does rotate nothing.
Its the used ios code that rotates to original position using orientation information.
For example BitmapFactory does not look at orientation information in a jpg. The image can come in any position and orientation information is needed to put it in right orientation.
So in this case Android/BitmapFactory does not rotate or exchange anything.

some image not load from firebase due to different byte size in android

I have a firebase database in which multiple urls of images are stored all images have different byte size , but picasso not load all images , just some images loads. i am saving all images after crop, how can i fix issue?
Picasso.get()
.load(user_pic)
.networkPolicy(NetworkPolicy.OFFLINE) // for offline
.placeholder(R.drawable.default_profile_image)
.error(R.drawable.default_profile_image)
.into(dpImage);
<de.hdodenhof.circleimageview.CircleImageView
android:id="#+id/profileImage"
android:layout_width="170dp"
android:layout_height="170dp"
android:maxWidth="170dp"
android:maxHeight="170dp"
android:src="#drawable/default_profile_image"
app:civ_border_color="#color/colorPrimary"
app:civ_border_width="0.5dp"
/>
You can enable logging in Picasso to see what is happening.
You can find more info here: https://futurestud.io/tutorials/picasso-cache-indicators-logging-stats
Anyways, from my personal experience, I recommend switch to Glide:
https://github.com/bumptech/glide
//Setting it to (6MB)..change it as per requirement
long cacheSize = 1024 * 1024 * 6;
Picasso picasso = new Picasso.Builder(context)
.memoryCache(new LruCache(cacheSize))
.build();
You can try increasing the cache size of picasso if it still not work use Glide it can handle different formats of images better.

How to convert a bitmap to an image resource - Android

I am trying to set an image to a custom View, but my problem is that this custom view only accept the setImageResource() method.
My image files are stored locally inside the phone, so I use a code to encode them to bitmap.
Can I use the setImageResource() function to display bitmap images in some way?
No, sorry. The custom view would need to be modified to support other image sources.
For the custom view you need to modify the support, once you have do it, then
If it is encoded on Base64, you can transform that content to a image
val decodedString = Base64.decode(document.thumbnailImage, Base64.DEFAULT)
val decodedByte = BitmapFactory.decodeByteArray(decodedString, 0, decodedString.size)
imageView.setImageBitmap(decodedByte)

Avoiding an OutOfMemory Error using ImageView in Android Studio

I'm using RecyclerView and CardView for my layout and want to display a watermark which spans across 4 cards on the screen. I've chopped up the watermark image into 4 separate images, one for each card (each image already has the dimensions I want it to be displayed with). To display the images, I am using ImageView inside of each card's .xml file as such:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:id="#+id/cardview"
android:layout_width="415dp"
android:layout_height="89dp"
android:layout_marginTop="0dp"
android:elevation="100dp"
card_view:cardBackgroundColor="#ffffff">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:src="#drawable/watermark_card1"
android:scaleType="centerCrop" />
.
.
.
</RelativeLayout>
</android.support.v7.widget.CardView>
This works fine while I am only loading 2 out of the 4 images, but when I load the 3rd one, I get the following error:
java.lang.OutOfMemoryError: Failed to allocate a 210446976 byte allocation with 4194304 free bytes and 101MB until OOM
I believe that this is because the images are all very large (521K, 976K, 611K, and 933K) and I am wondering what I could do to use less memory and avoid the OutOfMemory Error. Any advice would be appreciated, thanks!
you must resize or reduce quality of image. and use image library like volly or picasso. this library can solve variety problem relate with image.
In AndroidManifest.xml file, inside the application tag add the below line
android:largeHeap="true"
But, remember this only increase the heap memory and give you solution. But, it's not the best practice. You should recycle your memory properly.
Refer the links
Strange out of memory issue while loading an image to a Bitmap object
Android: convert Immutable Bitmap into Mutable
You can downsample the image as you create it using BitmapFactory. You would just include the images as assets and get an input stream to them, then create downsampled Bitmap objects. This way, you can decide how large you want the images to be based on the device, screen size, memory available, etc. After you create the Bitmap object, use ImageView.setImageBitmap() to set it into your image view. Below is an example of a downsampling method -
public static Bitmap decodeBitmap(InputStream decodeStream, byte[] decodeArray) throws IOException
{
BitmapFactory.Options options = new BitmapFactory.Options();
Bitmap bitmap = null;
boolean useStream = ((decodeStream != null) ? true : false);
int actualFileSize;
// get the decoded object size without actually decoding and creating the object
options.inJustDecodeBounds = true;
if (useStream)
BitmapFactory.decodeStream(decodeStream, null, options);
else
BitmapFactory.decodeByteArray(decodeArray, 0, decodeArray.length, options);
actualFileSize = options.outWidth * options.outHeight * 4;
if (useStream)
decodeStream.reset(); // reset the data - we assume the underlying input stream implements reset() in a
// way that will not throw an exception in the case where the stream is not marked
if (actualFileSize > MAX_BYTES)
{
options = new BitmapFactory.Options(); // recreate the options to get the defaults back
if (actualFileSize/4 <= MAX_BYTES)
options.inSampleSize = 2; // a sample size of 2 has 1/4th the pixels
else if(actualFileSize/16 <= MAX_BYTES)
options.inSampleSize = 4; // a sample size of 4 has 1/16th the pixels
else
options.inSampleSize = 8; // if it is still too big, attempt a sample size of 8 (1/64th the pixels)
if (useStream)
bitmap = BitmapFactory.decodeStream(decodeStream, null, options);
else
bitmap = BitmapFactory.decodeByteArray(decodeArray, 0, decodeArray.length, options);
}
else
{
if (useStream)
bitmap = BitmapFactory.decodeStream(decodeStream);
else
bitmap = BitmapFactory.decodeByteArray(decodeArray, 0, decodeArray.length, null);
}
return bitmap;
}
Finally, as you're loading your images in code, I have found it helpful to force garbage collections (via System.gc()) before and after each call do decodeStream(). When you are done with the Bitmap objects, dispose of their memory explicitly using Bitmap.recycle(). Memory management with large bitmaps on Android can get a little hairy - there are some other suggestions here -
https://developer.android.com/training/displaying-bitmaps/manage-memory.html
Hope this helps.
OutOfMemory error means your images are large in size, so either you decrease quality of the image or use an image library so that it caches your image and also if it still doesnt help then make largeheap=true in your application tag in manifest file.
To avoid this error you have to follow recommendations from this link:
https://developer.android.com/training/displaying-bitmaps/load-bitmap.html
(and look the next two tutorials).
But the easiest way to do it is use one of popular libraries (as were said in one of the answers) - e.g. Picasso (http://square.github.io/picasso/).

Scaling jpg image from Bitmap.compress android

I am converting, bitmap to jpeg using
val file = File(filePath)
val fos = FileOutputStream(file)
profileImageBitmap.compress(Bitmap.CompressFormat.JPEG,100,fos)
The jpeg looks okay. But its very tiny. I thought it was the jpeg lossy nature but when I tried to convert bitmap into png, it also came down to same size. Is there a way to increase the size of jpeg, compressed from bitmap?
You can use createScaledBitmap to scale up your bitmap before converting to jpeg, try passing true as the filter boolean to get better results. (You might want to decode the bitmap from the file first).
createScaledBitmap documentation

Categories

Resources