ImageResize on Android - android

I am trying to work on a small requirement which provides users with an option to resize an image to a given percentage. Lets say 75% is the option. Does that mean I should resize the image size to 75% or the resolution of the image to 75%?
Any thoughts on this?
I wanted to use
Bitmap yourBitmap; resized =
Bitmap.createScaledBitmap(yourBitmap,(int)(yourBitmap.getWidth()*0.75),
(int)(yourBitmap.getHeight()*0.75), true);
For the newWidth and newHeight should I blindly pass calculate like above?

I think
image resolution is 100% like 100x100 or 200x200 or 1000x1000
user want to resize it to 75%
I think scaleX, scaleY
so on the end image must be 75% like 75x75 or 150x150 or 750x750

Within the help of Bitmap.createScaledBitmap you can resize your image even without losing your image quality
Bitmap scaledBitmap = Bitmap.createScaledBitmap(unscaledBitmap, wantedWidth, wantedHeight, true);
I hope it will work for you

You can implement as following way.
/* sample code */
Bitmap srcBitmap;
Bitmap destBitmap = Bitmap.createScaledBitmap(srcBitmap, (int)(srcBitmap.getWidth()*0.75), (int)(srcBitmap.getHeight()*0.75), true);
Hopefully...

What you consider to be 75% of an image is up to you. There are several posibilities. A nice variant is to resize to a predetermined size like 1024 for width if landscape and for height if portrait.
All the here suggested techniques can often not be used as they construct a full blown original bitmap first. Often memory for that will not be available.
So scale it down while loading. BitmapFactory will do it for you.

Related

Issues resizing bitmaps with inDensity and inTargetDensity

I'm trying to resize a bitmap using inDensity and inTargetDensity following #colt-mcanlis' instructions explained at 1, 2 and 3.
So far so good, good documentation, great video. The problem is that the resulting sizes for the image makes no sense to me.
For example if I use following values:
srcWidth is 11774px and srcHeight is 6340px
dstWidth is 1440px and dstHeight is 2392px
The code I'm using is:
options.inScaled = true;
options.inSampleSize = 8;
options.inDensity = srcWidth;
options.inTargetDensity = dstWidth * 8;
options.inSampleSize;
imageBitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.image, options);
And the resulting image has width 70px and height 38px, instead 1440x2393.
I tried without using inSampleSize, and I get a very similar result. Then I assume the problem is with inTargetDensity and inDensity.
I went to the documentation and found the following:
inDensity
int inDensity
The pixel density to use for the bitmap...
As far as I know, to calculate a density I need a width, height and a display size but a display size doesn't make sense to me in this context, since I just want to calculate inDensity and inPixelDensity independent of a display size.
So, what am I doing wrong here ?
I was following Loading Large Bitmaps Efficiently by the book, but was running into the problem that the decoded bitmap ended up having way larger dimensions even than the original image (options.outWidth / options.outHeight).
I noticed that after the "decode bounds" step, inTargetDensity had a larger value than inDensity, and ultimately found that to be the cause of the larger decoded bitmap. Not sure exactly when playing with anything different on this fields would be useful...
But setting options.inTargetDensity = options.inDensity after the "decode bounds" step, worked for having the bitmap be decoded at the expected size (according to the inSampleSize you calculate).
Looking forward to the "more straightforward" API that Romain Guy announced in Google I/O (2018) :D
If you just want to resize an image while decoding, inSampleSize option is enough, but, because the aspect ratio of original and target images are not the same, you can't get the expected result through inSampleSize option directly, you need to do some extra crop operations after resizing. You can refer to the following guide for details:
http://developer.sonymobile.com/2011/06/27/how-to-scale-images-for-your-android-application/

Scale Bitmap lower than 4096x4096

I am currently working on an application that shows a Bitmap on an ImageView. Now the problem is, whenever trying to show a Bitmap larger than 4096x4096, it simply won't show up, stating that the image is too large to be shown.
For example: I want to load up an image that's 4128x2322 pixels
I to resize it to be smaller than 4096x4096.
I thought about something like this:
Bitmap bitmap;
if(b.getHeight() >= 4096) {
double f = b.getHeight() / 4096;
b = Bitmap.createScaledBitmap(b, (int)(b.getWidth() / f), (int)(b.getHeight() / f), false);
}else if(b.getWidth() >= 4096) {
double f = b.getWidth() / 4096;
b = Bitmap.createScaledBitmap(b, (int)(b.getWidth() / f), (int)(b.getHeight() / f), false);
}
imageview.setImageBitmap(b);
Somehow it won't work...
Any advices on how to scale properly?
Thanks in advance!
I got an intent which takes a picture and returns the image
That image will be stored somewhere else, which you will reference via a File or perhaps a content: Uri.
But to show the taken picture I need to scale it down first
Use BitmapFactory to load the bitmap. Use BitmapFactory.Options and its inSampleSize field to indicate how you want the image to be downsampled. This is covered in the documentation.
There is no device with resolution 4096X4096, your image going to be scaled any way. So instead trying to scale it up just top let the system to scale it down. How about taking the screen size in to calculation and provide the final scale by your self. Not only that you will save space but also improve performance.

Resize bitmap image to make 100x100 profile picture?

Hi so I need a user to be able to upload a profile picture that I have to re-size and put in their profile. The "area" for the profile picture is a 100x100 square since its on an android device. Lets assum someone posted a 300 x 600 or 600 x 300 how would I convert / crop an image to fit a 100 x 100 square and look good as a profile image? I feel like this is more of a conventional question.
I do know how to resize and crop bitmaps just can't figure out how would I go about it.
for instance
android.graphics.Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, true);
Well if you are not against wasting some of the space, I recommend just doing basic scaling. Divide the larger size by 100 gives the scale factor. Then divide by that on each dimension and you have a picture with the right aspect ratio that fits your area.

Image from resources is scaled properly but image blob from SQlite isn't - Android

I am running into a strange issue. I have multiple images in my Android project which I stored as .png files under res\drawable. I was able to easily extract the images at runtime and convert them to a bitmap like this:
Drawable d = getResources().getDrawable(R.drawable.imageId);
Bitmap bitmap = ((BitmapDrawable)d).getBitmap();
This works great and the image gets scaled correctly no matter what screen density the device has. All my images are 200 pixels by 200 pixels and my image layout is configured as 200 dip x 200 dip.
Now, I have stored all images as blobs in an SQlite database due to scalability issues and I am extracting them at runtime and converting to a bitmap like this:
byte[] bb = cursor.getBlob(columnIndex);
Bitmap bitmap = BitmapFactory.decodeByteArray(bb, 0, bb.length);
The image displays fine if the screen density is standard 160 dip. But if the density is any less or more, the image doesn't scale and remains 200 pixels x 200 pixels for 160 dip. So basically, on a smaller screen (120 dip), the image takes more space than it should and on a larger screen (240 dip), it takes less space than it should.
Has anyone else run into this bizarre issue? Any explanation, workaround, solution will be really appreciated.
Thanks much in advance!
Okay, I finally got it to work by using createScaledBitmap().
After creating a bitmap from the blob, I calculate the scaling factor and then calculate the new width and height. I then use those in the createScaledBitmap() function. Here's the code that works:
public static Bitmap getImageFromBlob(byte[] mBlob)
{
byte[] bb = mBlob;
Bitmap b = BitmapFactory.decodeByteArray(bb, 0, bb.length);
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
int newWidth = b.getWidth()*metrics.densityDpi)/DisplayMetrics.DENSITY_DEFAULT;
int newHeight = b.getHeight()*metrics.densityDpi)/DisplayMetrics.DENSITY_DEFAULT;
return Bitmap.createScaledBitmap(b, newWidth, newHeight, true);
}
This link provided the clue:
difference between methods to scale a bitmap
Use decodeByteArray(byte[] data, int offset, int length, BitmapFactory.Options opts) and in opts set inDesity to let say 160.
Worked for me, see this. But I have to say, I think SQLite is doing it right, and the android drawable is incorrectly sized.

android (Advanced)Saving a Bitmap Canvas with DrawText but textsize calculation needed

I have a Canvas that i draw text on.
(this is quite advanced i think hope you can follow me)
See attached image below.
The functionality is that I can tap on the screen to change the textsize.
Tap left screen = smaller Font.
Tap right Screen = bigger Font.
I can then also move the text on the screen.
When textsize is ok and i have moved the text where i want it,
Then I want to save it back to the original Bitmap.
I use options.inSampleSize = 4; to initially load the Bitmap
The ImageView that have the Bitmap is of course smaller then the original Image.
Some kind of calculation is needed.
This tends to be quite difficult to do.
I have the options.inSampleSize = 4 Bitmaps Ratio.
It's 0.59, 0.69 something depending on Landscape or portrait.
Im playing around with that to somehow change the new BitmapsetTextSize
to look the same as the ImageView smaller Bitmap.
What could i do here?
I have a feeling that since one never know what size an image have.
I have to somehow scale/constrain the Loaded Bitmap Ratio to a fixed Ratio.
Then i need to using percentage or something to transfer the text location
to the bigger image.
I can kind of do that when it comes to initial
(red small ball on picture) location. Hence, the starting point of the text.
But i dont know how long the text is so im stuck so so speak and asking for advice
One way i tried was to divide paint.getTextSize() with the Ratio something like 0.59. That looked like a solution at first. But the image ratio is not fixed and the Font size is not fixed something else is needed.
Here are two pictures showing the problem.
On phone Bitmap:
The saved new Bitmap:
I'm not 100% clear that I understand what you mean, but here's a go. It sounds like you were close to the right approach. Instead of using a fixed ratio, you need to calculate the ratio that the image is scaled by to fit in the view on the phone, then you can scale the text by the inverse ratio. So in steps:
Measure the width of the original image (height would do just as well, but we just need one dimension)
Measure the width of the scaled image
Calculate ratio (ratio = original / scaled)
Let the user type their text
You can then get the text size using something like: float paintSize = paint.getTextSize();
For rendering on the final image, use paint.setTextSize(paintSize / ratio);.

Categories

Resources