Aspect ratio is off when scaling down and drawing a bitmap - java

The image I am using is from a 4x6. So the aspect ratio should be about .66. When I calculate the aspect ration in my code , I get around .66. However, the height of the displayed image looks squashed. The image only looks right if I set the aspect ratio manually to around .85.
Since setting the aspect ratio manually is not perfect, how can I get the can I keep the height of my image from appearing to be squashed.
public class SpotGameActivity extends Activity {
private Bitmap mBitmap;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.dpi2b);
setContentView(new BitMapView(this, mBitmap));
}
class BitMapView extends View {
Bitmap mBitmap = null;
public BitMapView(Context context, Bitmap bm) {
super(context);
mBitmap = bm;
}
#Override
protected void onDraw(Canvas canvas) {
// called when view is drawn
Paint paint = new Paint();
paint.setFilterBitmap(true);
// The image will be scaled so it will fill the width, and the
// height will preserve the image’s aspect ration
float aspectRatio = ((float) mBitmap.getWidth()) / mBitmap.getHeight();
Rect dest = new Rect(0, 0, this.getWidth(),(int) (this.getHeight() * aspectRatio));
String AR = Double.toString(aspectRatio);
//Rect dest = new Rect(0, 0, getWidth(), getHeight());
canvas.drawBitmap(mBitmap, null, dest, paint);
Toast.makeText(SpotGameActivity.this, AR, Toast.LENGTH_SHORT).show();
}
}
}

Aspect = width/height
newHeight = newWidth/Aspect
Do this,
Rect dest = new Rect(0, 0, this.getWidth(),(int) (this.getWidth() / aspectRatio));

Related

Android studio - Center non-transparent part of picture

I'm making an app that can freehand crop a picture using a canvas in android studio. My problem is that after cropping the picture, the cropped part stays in the same exact position as it was originally, whereas i want it to get centered and enlargened. Is there any way to take the non-transparent part and center it, or maybe remove the transparent part all-together?
Screenshot of my app where i want the banana to be centered
https://i.stack.imgur.com/8OKNT.png
Bitmap bitmap;
Path path = new Path();
Paint paint;
int width;
int height;
Rect src;
Rect dest;
public CutImage(Context context, Bitmap bitmap2) {
super(context);
bitmap = bitmap2;
paint = new Paint();
paint.setStyle(Paint.Style.STROKE);
paint.setColor(Color.RED);
paint.setStrokeWidth(5f);
width = getWindowManager().getDefaultDisplay().getWidth();
height = getWindowManager().getDefaultDisplay().getHeight();
src = new Rect(0, 0, bitmap.getWidth() - 1, bitmap.getHeight() - 1);
dest = new Rect(0, 0, width - 1, height - 1);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.getHeight();
canvas.drawBitmap(bitmap,src,dest, null);
canvas.drawPath(path, paint);
}
private void crop() {
Bitmap croppedBitmap =
Bitmap.createBitmap(bitmap.getWidth(),bitmap.getHeight(),bitmap.getConfig());
Canvas cropCanvas = new Canvas(croppedBitmap);
Paint paint = new Paint();
cropCanvas.drawPath(path,paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
cropCanvas.drawBitmap(bitmap,src,dest,paint);
bitmap = croppedBitmap;
showImage2(bitmap);
}
} ```

How to make images on Bitmap smaller?

I am trying to build a simple game on android and while setting the background image and other image assets on my main screen it is appearing too big as shown in the below image.
The actual size of the image is 1920x1080 and I want it to fit my screen like the image shown below:
The code for I have used is:
public class PoliceView extends View {
private Bitmap police;
private Bitmap background;
private Paint scorePaint = new Paint();
private Bitmap life[] = new Bitmap[2];
public PoliceView(Context context) {
super(context);
police = BitmapFactory.decodeResource(getResources(),R.drawable.police);
background = BitmapFactory.decodeResource(getResources(),R.drawable.gamebackground);
scorePaint.setColor(Color.BLACK);
scorePaint.setTextSize(70);
scorePaint.setTypeface(Typeface.DEFAULT_BOLD);
scorePaint.setAntiAlias(true);
life[0] = BitmapFactory.decodeResource(getResources(),R.drawable.heart);
life[1] = BitmapFactory.decodeResource(getResources(),R.drawable.brokenheart);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//The order of draw matters as objects are drawn in this same order
canvas.drawBitmap(background,0,0,null);
canvas.drawBitmap(police, 0, 0, null);
canvas.drawText("Score:",20, 60, scorePaint);
//Three lives for the police
canvas.drawBitmap(life[0],580, 10, null);
canvas.drawBitmap(life[0],680, 10, null);
canvas.drawBitmap(life[0],780, 10, null);
}}
How can I resize the images to fit the screen??
i use this code for resize image
Bitmap tmp = BitmapFactory.decodeFile(mPath);
ResizeWidth = (int) (your size);
ResizeHeight = (int) (your size);
Bitmap bitmap = Bitmap.createBitmap(ResizeWidth, ResizeHeight, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
Bitmap scaled = Bitmap.createScaledBitmap(tmp, ResizeWidth, ResizeHeight, true);
int leftOffset = 0;
int topOffset = 0;
canvas.drawBitmap(scaled, leftOffset, topOffset, null);
How to resize bitmap in canvas?
canvas.save(); // Save current canvas params (not only scale)
canvas.scale(scaleX, scaleY);
canvas.restore(); // Restore current canvas params
scale = 1.0f will draw the same visible size bitmap

Using Picasso to load an image into a bitmap

I`m tring to to load an image from an URL into a Bitmap using the Picasso library , but most of the examples i found refer to loading a Bitmap to a ImageView or something similar.
The code should be something like this , according to the documentation.
public void loadImage() {
Picasso.with(getBaseContext()).load("image url").into(new Target() {
#Override
public void onPrepareLoad(Drawable arg0) {
}
#Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom arg1) {
Bitmap bitImage = Bitmap(getApplicationContext(),bitmap);
}
#Override
public void onBitmapFailed(Drawable arg0) {
}
});
}
But Bitmap bitImage = Bitmap(getApplicationContext(),bitmap); doesn't seem to be correct, since i`m getting a Method call expected error.
It looks like you are not creating the Bitmap properly, but if I was in your position I would create a scaled bitmap like so:
public Bitmap getResizedBitmap(Bitmap bm, int newWidth, int newHeight) {
int width = bm.getWidth();
int height = bm.getHeight();
float scaleWidth = ((float) newWidth) / width;
float scaleHeight = ((float) newHeight) / height;
// CREATE A MATRIX FOR THE MANIPULATION
Matrix matrix = new Matrix();
// RESIZE THE BIT MAP
matrix.postScale(scaleWidth, scaleHeight);
// "RECREATE" THE NEW BITMAP
Bitmap resizedBitmap = Bitmap.createBitmap(
bm, 0, 0, width, height, matrix, false);
bm.recycle();
return resizedBitmap;
}
Then set it to an imageView like so:
mImg.setImageBitmap(img);
Overall it would look like this:
public void loadImage() {
Picasso.with(getBaseContext()).load("image url").into(new Target() {
// ....
#Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom arg1) {
// Pick arbitrary values for width and height
Bitmap resizedBitmap = getResizedBitmap(bitmap, newWidth, newHeight);
mImageView.setBitmap(resizedBitmap);
}
// ....
});
}
}
public Bitmap getResizedBitmap(Bitmap bm, int newWidth, int newHeight) {
int width = bm.getWidth();
int height = bm.getHeight();
float scaleWidth = ((float) newWidth) / width;
float scaleHeight = ((float) newHeight) / height;
// CREATE A MATRIX FOR THE MANIPULATION
Matrix matrix = new Matrix();
// RESIZE THE BIT MAP
matrix.postScale(scaleWidth, scaleHeight);
// "RECREATE" THE NEW BITMAP
Bitmap resizedBitmap = Bitmap.createBitmap(
bm, 0, 0, width, height, matrix, false);
bm.recycle();
return resizedBitmap;
}
But I question you using Target altogether, usually that is for a very specialized case. You should be calling the singleton of Picasso in the same class you will be displaying images. Usually this is in an Adapter (RecyclerView Adapter maybe) like so:
Picasso.with(mContext)
.load("image url")
.into(mImageView);

Android: How to draw over downloaded bitmap and then populate it to ImageView?

My application is downloading a bitmap which is later populated into custom ImageView. However I want this bitmap to be updated before it is actually drawn on a canvas (I want to add some points over it). However as the result I see only populated bitmap without changes I made. Can anyone help?
Here is my onDraw method. "bitmap" object is set via setImageBitmap received from AsyncTask in onPostExecute() method.
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (bitmap != null) {
Display display = ((WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int width = size.x;
int padding = (width - bitmap.getWidth()) / 2;
canvas.drawBitmap(bitmap, padding, 0, null);
paint.setColor(Color.RED);
paint.setStrokeWidth(5f);
for (Face face : getPhotoObject().getFaces()) {
canvas.drawPoint(face.getLeftEye().x, face.getLeftEye().y, paint);
canvas.drawPoint(face.getRightEye().x, face.getRightEye().y, paint);
}
}
}
You can create a canvas with a bitmap at any time:
Canvas canvas = new Canvas(myBitmap);
// draw code
// the resulting bitmap will be edited.
Hope this helps

How can I center this rectangle and image in the y axis?

So far, my image starts at 0,0 and scales properly. There is a black bar under it. How can I align it so that it is centered along the y, with a black bar above and below the image?
edit: also, what are "this.getWidth(), this.getHeight()" referring to when I make the object "dest" - the width of mBitmap? The documentation does say they represent the width of the view, I just want to make sure I'm correct in thinking that is it mBitmap.
public class SpotGameActivity extends Activity {
private Bitmap mBitmap;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.dpi2b);
setContentView(new BitMapView(this, mBitmap));
}
class BitMapView extends View {
Bitmap mBitmap = null;
public BitMapView(Context context, Bitmap bm) {
super(context);
mBitmap = bm;
}
#Override
protected void onDraw(Canvas canvas) {
//DisplayMetrics metrics = new DisplayMetrics();
//getWindowManager().getDefaultDisplay().getMetrics(metrics);
// called when view is drawn
Paint paint = new Paint();
paint.setFilterBitmap(true);
// The image will be scaled so it will fill the width, and the
// height will preserve the image’s aspect ration
float aspectRatio = ((float) mBitmap.getWidth()) / mBitmap.getHeight();
Rect dest = new Rect(0, 0, this.getWidth(),(int) (this.getWidth() / aspectRatio));
String AR = Double.toString(aspectRatio);
canvas.drawBitmap(mBitmap, null, dest, paint);
Toast.makeText(SpotGameActivity.this, AR, Toast.LENGTH_SHORT).show();
}
I've now gotten the difference between the view size and image size. I've divided the difference by 2 but now, my image is align to the bottom of the screen rather than the middle of the y-axis. any tips?:
#Override
protected void onDraw(Canvas canvas) {
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
int scrHeight = this.getHeight();
String sH = Integer.toString(scrHeight);
Log.v(TAG, "scrHeight =" + sH );
int imgHeight= mBitmap.getHeight();
String iH = Integer.toString(imgHeight);
Log.v(TAG, "imgHeight =" + iH );
int diff = scrHeight - imgHeight;
String dif = Integer.toString(diff);
Log.v(TAG, "diff =" + dif );
int dvd= diff/2;
// called when view is drawn
Paint paint = new Paint();
paint.setFilterBitmap(true);
// The image will be scaled so it will fill the width, and the
// height will preserve the image’s aspect ration
float aspectRatio = ((float) mBitmap.getWidth()) / mBitmap.getHeight();
Rect dest = new Rect(0, dvd, this.getWidth(),(int) (this.getWidth() / aspectRatio)+dvd);
String AR = Double.toString(dvd);
canvas.drawBitmap(mBitmap, null, dest, paint);
Toast.makeText(SpotGameActivity.this, AR, Toast.LENGTH_SHORT).show();

Categories

Resources