Bitmap and ImageView issue - problems with image width/height - android

I need to display images which are stored in database and I'm having issues with image (Bitmap) width/height and ImageView ...
Just for test - when I add same image in project's drawables I can use this:
Works:
Bitmap b = BitmapFactory.decodeResource(context.getResources(), R.drawable.menu_image);
BitmapDrawable bd = new BitmapDrawable(context.getResources(), b);
imageView.setImageDrawable(bd);
same as
imageView.setImageResource(R.drawable.menu_image);
This following isn't working because image isn't resized:
imageView.setImageBitmap(image);
same as
imageView.setImageDrawable(new BitmapDrawable(context.getResources(), image));
Where image is constructed using this:
public static Bitmap base64ToBitmap(String b64) {
byte[] imageAsBytes = Base64.decode(b64.getBytes(), Base64.DEFAULT);
BitmapFactory.Options options = new BitmapFactory.Options();
options.inDensity = context.getResources().getDisplayMetrics().densityDpi;
options.inTargetDensity = context.getResources().getDisplayMetrics().densityDpi;
Bitmap bitmap = BitmapFactory.decodeByteArray(imageAsBytes, 0, imageAsBytes.length, options);
return bitmap;
}
Image original size is 338x94.
676x188, this is image size when I'm using image from project's drawables directory. This is size that I'm looking for, in this case. I suppose a quick fix would be to use Bitmap.createScaledBitmap(), but I have couple of different image formats and I would like to use imageView.setImageBitmap or imageView.setImageDrawable to behave like I loaded Bitmap from project's drawables directory.

Use the following helper class from github
public class BitmapScaler
{
// scale and keep aspect ratio
public static Bitmap scaleToFitWidth(Bitmap b, int width)
{
float factor = width / (float) b.getWidth();
return Bitmap.createScaledBitmap(b, width, (int) (b.getHeight() * factor), true);
}
// scale and keep aspect ratio
public static Bitmap scaleToFitHeight(Bitmap b, int height)
{
float factor = height / (float) b.getHeight();
return Bitmap.createScaledBitmap(b, (int) (b.getWidth() * factor), height, true);
}
// scale and keep aspect ratio
public static Bitmap scaleToFill(Bitmap b, int width, int height)
{
float factorH = height / (float) b.getWidth();
float factorW = width / (float) b.getWidth();
float factorToUse = (factorH > factorW) ? factorW : factorH;
return Bitmap.createScaledBitmap(b, (int) (b.getWidth() * factorToUse),
(int) (b.getHeight() * factorToUse), true);
}
// scale and don't keep aspect ratio
public static Bitmap strechToFill(Bitmap b, int width, int height)
{
float factorH = height / (float) b.getHeight();
float factorW = width / (float) b.getWidth();
return Bitmap.createScaledBitmap(b, (int) (b.getWidth() * factorW),
(int) (b.getHeight() * factorH), true);
}
}

Related

How to compress multiple images size to particular(100kb) size in android?

I am new to android. I want to reduce the size of a bitmap to 100kb exactly. I get an image from the sdcard, compress it and save it to the sdcard again with a different name into a different directory. Compression works fine (3 mb like image is compressed to around 100 kb). I trying to compress 1mb image to 100kb, but i am getting size of that image is 20kb. But i need that 1mb(or 2mb (or) 3mb (or) 4mb (or) 5mb.....) image also get resize to 100kb. and my code is,,
private Bitmap getResizedBitmap(Bitmap bm, int maxSize)
{
int width = bm.getWidth();
int height = bm.getHeight();
float bitmapRatio = (float)width / (float) height;
if (bitmapRatio > 0) {
width = maxSize;
height = (int) (width / bitmapRatio);
} else {
height = maxSize;
width = (int) (height * bitmapRatio);
}
return Bitmap.createScaledBitmap(bm, width, height, true);
}
public static Bitmap getResizedBitmap(Bitmap bm, float newHeight, float newWidth) {
float width = bm.getWidth();
float height = bm.getHeight();
float scaleWidth = (newWidth) / width;
float scaleHeight = (newHeight) / height;
// create a matrix for the manipulation
Matrix matrix = new Matrix();
// resize the bit map
matrix.postScale(scaleWidth, scaleHeight);
// recreate the new Bitmap
return Bitmap.createBitmap(bm, 0, 0, (int) width, (int) height, matrix, false);
}
Using matrix
Resizing bitmap by pixel resolution is possible but resizing by its disk size is not as far as I know

How to scale bitmaps based on device screen size in Android

I want to create images with sizes relevant to the size of the screen they are on. Basically I have a scaled bitmap 50w * 50h. I want it to be 50w * 50h on a small device, slightly larger on a larger device, etc... Is there anyway to make a scaled bitmap relevant to the screen size it's on. I have that of making a dimen.xml file with different dp values for different screen width's. But it seems so demanding. Is there any easier way to do it? I have done some research but found nothing, can anyone help?
May be this:
public class BitmapScaler {
// scale and keep aspect ratio
public static Bitmap scaleToFitWidth(Bitmap b, int width) {
float factor = width / (float) b.getWidth();
return Bitmap.createScaledBitmap(b, width, (int) (b.getHeight() * factor), true);
}
// scale and keep aspect ratio
public static Bitmap scaleToFitHeight(Bitmap b, int height) {
float factor = height / (float) b.getHeight();
return Bitmap.createScaledBitmap(b, (int) (b.getWidth() * factor), height, true);
}
// scale and keep aspect ratio
public static Bitmap scaleToFill(Bitmap b, int width, int height) {
float factorH = height / (float) b.getWidth();
float factorW = width / (float) b.getWidth();
float factorToUse = (factorH > factorW) ? factorW : factorH;
return Bitmap.createScaledBitmap(b, (int) (b.getWidth() * factorToUse),
(int) (b.getHeight() * factorToUse), true);
}
// scale and don't keep aspect ratio
public static Bitmap strechToFill(Bitmap b, int width, int height) {
float factorH = height / (float) b.getHeight();
float factorW = width / (float) b.getWidth();
return Bitmap.createScaledBitmap(b, (int) (b.getWidth() * factorW),
(int) (b.getHeight() * factorH), true);
}
}
or this will help you.

Scale Down a Bitmap

I am trying to scale down a bitmap while keeping the same aspect ratio.
The following code works just ok, but I know its not the best approach.
I definitely do not like creating a holder bitmap and then another to scale it down as well.
Any suggestions on how to improve this are appreciated.
//width and height are passed in as params
Bitmap viewBM = view.getBitMap();
float aspectRatio = (float) width/height;
int newWidth= viewBM.getWidth();
int newHeight = viewBM.getHeight();
if (newHeight > newWidth) {
newHeight= (int)Math.round(newWidth * aspectRatio);
} else {
newWidth= (int)Math.round(newHeight * aspectRatio);
}
Bitmap holderBitmap = Bitmap.createBitmap(viewBM, 0, 0, newWidth, newHeight);
final Bitmap finalBitmap = Bitmap.createScaledBitmap(holderBitmap, width, height, true);

How to scale already existing bitmap in android?

I have an already decoded bitmap that I would like to temporarily scale before drawing it on a canvas. So decoding a file and setting the size before is out of the question. I would like to keep the size of the existing bitmap and just scale it to be smaller before drawing it on the canvas. Is this posible?
using Matrix postScale(sx, sy, px, py) scales it correctly but doesn't position it right. And canvas.drawBitmap doesn't have an option with matrix and x & y position from what I can see.
Any suggestions?
Here is the code:
public static Bitmap scaleBitmap(Bitmap bitmap, int width, int height) {
final int bitmapWidth = bitmap.getWidth();
final int bitmapHeight = bitmap.getHeight();
final float scale = Math.min((float) width / (float) bitmapWidth,
(float) height / (float) bitmapHeight);
final int scaledWidth = (int) (bitmapWidth * scale);
final int scaledHeight = (int) (bitmapHeight * scale);
final Bitmap decoded = Bitmap.createScaledBitmap(bitmap, scaledWidth, scaledHeight, true);
final Canvas canvas = new Canvas(decoded);
return decoded;
}
Please note: Pass the bitmap to scale and it's new height and width.

Crop-to-fit image in Android

I've been trying this for some time, I would like to create a wallpaper from a Bitmap. Let's say the desired wallpaper size is 320x480, and the source image size is 2048x2048.
I'm not sure whether crop-to-fit is the right term, but what I would like to achieve is to get most part of the picture that has the equal ratio as the desired wallpaper size (320x480).
So in this case, I would like to get 2048x1365 or (1365.333... to be exact) from the source Bitmap, and scale it down to 320x480.
The technique that I have tried is:
1) Crop the Bitmap into 2048x1365 first
bm = Bitmap.createBitmap(bm, xOffset, yOffset, 2048, 1365);
2) Scale it down to 320x480
bm = Bitmap.createScaledBitmap(bm, 320, 480, false);
which produced OutOfMemory error.
Is there any way to achieve this?
Regards,
dezull
Thanks to open source, I found the answer from Android Gallery source code here at line 230 :-D
croppedImage = Bitmap.createBitmap(mOutputX, mOutputY, Bitmap.Config.RGB_565);
Canvas canvas = new Canvas(croppedImage);
Rect srcRect = mCrop.getCropRect();
Rect dstRect = new Rect(0, 0, mOutputX, mOutputY);
int dx = (srcRect.width() - dstRect.width()) / 2;
int dy = (srcRect.height() - dstRect.height()) / 2;
// If the srcRect is too big, use the center part of it.
srcRect.inset(Math.max(0, dx), Math.max(0, dy));
// If the dstRect is too big, use the center part of it.
dstRect.inset(Math.max(0, -dx), Math.max(0, -dy));
// Draw the cropped bitmap in the center
canvas.drawBitmap(mBitmap, srcRect, dstRect, null);
I know this is an incredibly late reply, but something like this maybe:
public static Bitmap scaleCropToFit(Bitmap original, int targetWidth, int targetHeight){
//Need to scale the image, keeping the aspect ration first
int width = original.getWidth();
int height = original.getHeight();
float widthScale = (float) targetWidth / (float) width;
float heightScale = (float) targetHeight / (float) height;
float scaledWidth;
float scaledHeight;
int startY = 0;
int startX = 0;
if (widthScale > heightScale) {
scaledWidth = targetWidth;
scaledHeight = height * widthScale;
//crop height by...
startY = (int) ((scaledHeight - targetHeight) / 2);
} else {
scaledHeight = targetHeight;
scaledWidth = width * heightScale;
//crop width by..
startX = (int) ((scaledWidth - targetWidth) / 2);
}
Bitmap scaledBitmap = Bitmap.createScaledBitmap(original, (int) scaledWidth, (int) scaledHeight, true);
Bitmap resizedBitmap = Bitmap.createBitmap(scaledBitmap, startX, startY, targetWidth, targetHeight);
return resizedBitmap;
}
here is an answer that gets you most of the way there:
How to crop an image in android?

Categories

Resources