Android : How to calculate aspect ratio of images? - android

I have 100 images of huge size (500*700 , 401*800 , 2345* 3567) , so I want all these images height same as 220. Below I'm implementing calculation for the aspect ratio of image. I want to set the fixed height of all huge size images. I'm using some arithmetic formula to calculate the aspect ratio but getting all images width as same, and height is different but I want height to be fixed. How to get the fixed height? Thanks to appreciate.
Here is my calculation code for image aspect ratio
if (bitmapResizeImage != null) {
int originalWidth = bitmapResizeImage.getWidth();
int originalHeight = bitmapResizeImage.getHeight();
Log.e("originalWidth "," = " + originalWidth +" originalHeight = " + originalHeight+" of imgElement = " + imgElement+ " Notation = " +all_Post.getStrNotationNo());
float aspect_ratio = originalWidth / originalHeight ;
Log.e("aspect_ratio "," = " + aspect_ratio);
float adjusted_width = 220 * originalWidth / originalHeight ;
Log.e("adjusted_width "," = " + adjusted_width);
float adjusted_height = originalWidth * originalHeight / originalWidth ;
Log.e("adjusted_height "," = " + adjusted_height);
pBar.setVisibility(View.GONE);
imageView.setImageBitmap(bitmapResizeImage);
}

You should probably try typecasting:
float aspect_ratio = (float)originalWidth / (float)originalHeight ;
Because this typecasting operation will return a float value.
Integer divided by Integer will give the result as integer, which will be assigned to a float variable. Hence the operands need to be converted to float, in order to make sure that the result is computed as float.

In addition to what Priyank has posted, once you have the correct values
you can create a bitmap with the new dimensions before using setImageBitmap on the ImageView. Use
imageView.setImageBitmap(Bitmap.createBitmap(int width, int height, Bitmap.Config config));

Related

How to capture exactly the image inside the rectangular overlay in Camera?

I successfully made the auto crop to some extent for small devices so far. I am facing two issues:
1) the auto crop in big devices lets say 6.5 inches is not working properly
2) i want to take picture inside the rectangle frame
Below is my code:
public static Bitmap crop(Bitmap originalBitmap)
{
double originalWidth = originalBitmap.getWidth();
double originalHeight =
originalBitmap.getHeight();
double scaleX = originalWidth / 1280;
int navBarHeightPxIn1280x720Ui
CommonUtils.px2dp(CommonUtils.get
NavigationBarHeightInPx()) * 5 ;
double scaleXMultiplier = ((double) 1280) /
((double) (1280 - navBarHeightPxIn1280x720Ui));
scaleX = scaleX * scaleXMultiplier;
double scaleY = originalHeight / 720;
int x = (int) (52 * scaleX + 0.5);
int y = (int) (80 * scaleY + 0.5);
int width = (int) (896 * scaleX + 0.5);
int height = (int) (588 * scaleY + 0.5);
return Bitmap.createBitmap(originalBitmap, x, y,
width, height);
}

Android Layout Positioing

This is a little bit complicated to explain, so apologies.
The basic requirement is annotator app on Android, which allows the user to draw over the desktop, take a snapshot and one or two other things.
When the app starts it shows a single icon. This can be moved about the desktop.
When this icon is single clicked (touch) 6 icons spread evenly centred around the central icon appear.
So far so good. Now we move the central icon, and re-calculate the positions of the 6 outer icons centred around the new position of the central icon.
What we find is the outer icons are off centre relative to the central icon. The displacement looks to be roughly equal (bot X and Y) by the position of the touch within the central icon.
I will attempt to draw what happens.
First when the touch point on the drag/move is in the centre, everything lines up perfectly:
When the touch point is to the right, the displacement is leftwards as below:
When the touch is at the bottom the displacement is upwards:
The position of the "x" relative to the icon is it seems from
int shiftX = event.getX();
int shiftY = event.getY();
The position of the moved icon is from :
view.getLocationInWindow(locWXY);
int X = locWXY[0];
int Y = locWXY[1];
So, the positions of the satellite icons are calculated as:
final double angle = 30.000;
final double rad = angle * Math.PI / 180.000;
final int radius = 100;
final int penX = (int) (X + radius * cos(rad) + shiftX);
final int penY = (int) (Y - radius * sin(rad) + shiftY);
final int clearX = X ;
final int clearY = (int) (Y - radius + shiftY);
final int closeX = (int) (X - radius * cos(rad) + shiftX);
final int closeY = (int) (Y - radius * sin(rad) + shiftY);
final int iFlipX = (int) (X - radius * cos(rad) + shiftX);
final int iFlipY = (int) (Y + radius * sin(rad) + shiftY);
final int sshotX = X + shiftX;
final int sshotY = (int) (Y + radius + shiftY);
final int iFolderX = (int) (X + radius * cos(rad) + shiftX);
final int iFolderY = (int) (Y + radius * sin(rad) + shiftY);
penLP= new RelativeLayout.LayoutParams(70, 70);
penLP.leftMargin = penX;
penLP.topMargin = penY;
imbBlackPen.setLayoutParams(penLP);
clearLP = new RelativeLayout.LayoutParams(70, 70);
clearLP .leftMargin = clearX;
clearLP .topMargin = clearY;
imbClearScreen.setLayoutParams(clearLP );
folderLP = new RelativeLayout.LayoutParams(70, 70);
folderLP .leftMargin = iFolderX ;
folderLP .topMargin = iFolderY;
imbFolder.setLayoutParams(folderLP );
sshotLP = new RelativeLayout.LayoutParams(70, 70);
sshotLP .leftMargin = sshotX ;
sshotLP .topMargin = sshotY;
imbScreenCapture.setLayoutParams(sshotLP );
iFlipLP = new RelativeLayout.LayoutParams(70, 70);
iFlipLP .leftMargin = iFlipX ;
iFlipLP .topMargin = iFlipY;
imbIflipChart.setLayoutParams(iFlipLP );
closeLP = new RelativeLayout.LayoutParams(70, 70);
closeLP .leftMargin = closeX ;
closeLP .topMargin = closeY;
imbClose.setLayoutParams(closeLP );
I have tried setting shiftX and shiftY to zero, calculating X and X + shiftX/2. All to no avail. The strange thing is that on a small 10 inch tablet with resolution 1920 x 1200 it looks almost perfect, but on a large 65 inch touch screen the displacement is extremely pronounced.
We must be missing something, but I cannot figure out what.
As commented above ...
Fixed. The icon position calculation code above needed to be executed on ACTION_UP as well as ACTION_DOWN. Refactored this as a method and called it on both these events.

Android- View height is changing during the running time

I am trying to create dynamic buttons at the center of spesific areas of the ImageView. To figure out center of any area, I am using this function:
TextView createButton(int i, String[] boundingBoxArray) {
String[] coorArray = boundingBoxArray[i].split(",");
int[] coordinates = new int[4];
int x11 = Integer.parseInt(coorArray[0].replace(" ", ""));
int y11 = Integer.parseInt(coorArray[1].replace(" ", ""));
int x22 = Integer.parseInt(coorArray[2].replace(" ", ""));
int y22 = Integer.parseInt(coorArray[3].replace(" ", ""));
coordinates[0] = x11;
coordinates[1] = y11;
coordinates[2] = x22;
coordinates[3] = y22;
TextView buttonn = new TextView(context);
buttonn.setText(String.valueOf(i + 1));
buttonn.setTextSize(15);
buttonn.setId(i + 1);
buttonn.setBackgroundResource(R.drawable.circle);
RelativeLayout.LayoutParams rel_btn
= new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
Rect bounds = imageView.getDrawable().getBounds();
int scaledHeight = bounds.height();
int scaledWidth = bounds.width();
double scale;
double differWidth = 0;
double differHeight = 0;
imageViewHeight = imageView.getHeight();
imageViewWidth = imageView.getWidth();
if (scaledHeight > scaledWidth) {
scale = ((double) imageViewHeight / (double) scaledHeight);
differWidth = (imageViewWidth - (scaledWidth * scale)) / 2;
} else {
scale = ((double) imageViewWidth / (double) scaledWidth);
differHeight = (imageViewHeight - (scaledHeight * scale)) / 2;
}
DisplayMetrics displaymetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
int swidth = displaymetrics.widthPixels;
int buttonWidth = swidth / 30;
double a = ((double) (x11 + x22) / 2) * scale - buttonWidth + differWidth;
double b = ((double) (y11 + y22) / 2) * scale - buttonWidth + differHeight;
rel_btn.leftMargin = (int) a;
rel_btn.topMargin = (int) b;
rel_btn.width = 2 * buttonWidth;
rel_btn.height = 2 * buttonWidth;
buttonn.setGravity(Gravity.CENTER);
buttonn.setLayoutParams(rel_btn);
return buttonn;
}
When the activity starts, this function is called in for loop (number of loop is depends on number of areas) to create buttons on the ImageView. When all buttons are created, user can click on one of any dynamic button to focus on the spesific area.
If the user click on any button, the createButton() function is called again (it doesnt necessary but it doesnt make an issue either) for some purposes.
The problem is height of ImageView is not fixed. At the first time of calling createButton() function, the height returns as greater than the normal height. Then if you call createButton() again, the height returns the normal value.
imageViewHeight = imageView.getHeight();
imageViewWidth = imageView.getWidth();
The class has 2-3 nested thread, so maybe this is cause of problem. But I tried lots of things like:
I used CountDownLatch to handle threads and functions
I used mImageView.post(new Runnable...) to be sure to call functions after imageView is created.
I called imageView.getHeight() lots of
different places, but nothing is changed.
I keep the expression long, because I couldn't decided if the information is enough to understand. And as you realize, English is not my native. Thank you.
Edit: I forgot to mention: Below API 19, everything is cool (getHeight() value is returning as the normal size, either at the first time of calling createButton() methor or later ). API 20 and above, I get this error.
I luckily found the solution.. I use fullscreen mode at my app, but I didn't use AreaSelectActivity in fullscreen. After activity opened, status bar is coming down in a while. That's why height is changed but length is not. I put AreaSelectActivity in fullscreen mode and bum ! it is fixed now.

Android Getting coordinates of an image

I have a custom ImageView that re positions a an image on a web page. The image that is seen on the phone screen should represent the image on the web page.
I am using Matrix.mapPoints(float[] dst, float[] src) to try and get the how much the image is off-set when scaled to correctly frame the image. I am also taking into account the how much the image is scaled, and the size if the image view on the phone compared to the image tag width on the web page.
UpdateImage() in Image view class
public void updateImage() {
final float phoneDisplayScale = (float) getWidth() / (float) getDrawable().getIntrinsicWidth();
float[] m = new float[9];
matrix.getValues(m);
float scale = m[Matrix.MSCALE_X];
float[] arr = {0, 0};
matrix.mapPoints(arr, arr);
//holder.rect = {image_x, image_y, imageWidth, imageHeight}
if (holder != null) {
holder.getRect()[0] = arr[0] / phoneDisplayScale;
holder.getRect()[1] = arr[1] / phoneDisplayScale;
holder.getRect()[2] = scale * (getImageWidth() / phoneDisplayScale);
holder.getRect()[3] = scale * (getImageHeight() / phoneDisplayScale);
Log.i(TAG, "doInBackground: " + Arrays.toString(holder.getRect()));
Log.i(TAG, "doInBackground: " + Arrays.toString(holder.getRect()));
Log.i(TAG, "doInBackground: " + Arrays.toString(holder.getRect()));
}
//
//
// Socket io code
//
//
}
this works when the image is scaled and aligned to so that the top left of the image is in the top left of the ImageView, but you can never zoom in on the bottom right of the image. I also noticed that if I zoom in to the max that the map points method returns the width and height (minus values) of the image.
Ok my logic was a bit off I have changed the position calculation to the following and it now works.
holder.getRect()[0] = (arr[0] / scale) * phoneDisplayScale;
holder.getRect()[1] = (arr[1] / scale) * phoneDisplayScale;

Resizing image for XXHDPI

I have an image that is being displayed perfectly for MDPI.
Its resolution is 191 x 255.
Then I resize it to XXDPI, using 1:3 proportion, it gets to 573 x 765.
Still, when the emulator displays it, the quality is not as good as the MDPI one.
It gets clearly poor.
For both cases, I am using it Wrap Content
If I display both images on a image editor, they have perfect quality.
Why does that happen? Am I missing something here?
DisplayMetrics metrics = new DisplayMetrics();
getActivity().getWindowManager().getDefaultDisplay().getRealMetrics(metrics);
int widthPixels = metrics.widthPixels;
int heightPixels = metrics.heightPixels;
float widthDpi = metrics.xdpi;
float heightDpi = metrics.ydpi;
float widthInches = widthPixels / widthDpi;
float heightInches = heightPixels / heightDpi;
double diagonalInches = Math.sqrt((widthInches * widthInches) + (heightInches * heightInches)); // this code returns the actual screen size (eg. 7,8,9,10 inches in double format ex: 7.932189832)
diagonalInches = (double) Math.round(diagonalInches * 10) / 10; // round up to first decimal places
ArrayList<Integer> imageId = new ArrayList<>();
imageId.clear();
for (Integer i : imageNum){ // uses loop since im using TransitionDrawable to change images in single view
String stringID;
if (isPortrait) {
stringID = "featured_img_" + i.toString() + "_port"; // portrait images
} else {
if (diagonalInches >= 7 && diagonalInches <=8){
stringID = "featured_img_" + i.toString() + "_land_b"; // landscape images this is the drawable filename
} else {
stringID = "featured_img_" + i.toString() + "_land_a"; //landscape images this is the drawable filename
}
}
int drawableId = getResId(stringID);
imageId.add(drawableId); // adding it to arraylist
}
you can add android:scaleType=" . . . " on what you want for your image to be displayed

Categories

Resources