You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
CameraView/cameraview/src/main/java/com/otaliastudios/cameraview/AspectRatio.java

142 lines
3.4 KiB

package com.otaliastudios.cameraview;
import androidx.annotation.NonNull;
import java.util.HashMap;
/**
* A simple class representing an aspect ratio.
*/
public class AspectRatio implements Comparable<AspectRatio> {
final static HashMap<String, AspectRatio> sCache = new HashMap<>(16);
/**
* Creates an aspect ratio for the given size.
* @param size the size
* @return a (possibly cached) aspect ratio
*/
@NonNull
public static AspectRatio of(Size size) {
return AspectRatio.of(size.getWidth(), size.getHeight());
}
/**
* Creates an aspect ratio with the given values.
* @param x the width
* @param y the height
* @return a (possibly cached) aspect ratio
*/
@NonNull
public static AspectRatio of(int x, int y) {
int gcd = gcd(x, y);
x /= gcd;
y /= gcd;
String key = x + ":" + y;
AspectRatio cached = sCache.get(key);
if (cached == null) {
cached = new AspectRatio(x, y);
sCache.put(key, cached);
}
return cached;
}
/**
* Parses an aspect ratio string, for example those previously obtained
* with {@link #toString()}.
*
* @param string a string of the format x:y where x and y are integers
* @return a (possibly cached) aspect ratio
*/
@NonNull
@SuppressWarnings("WeakerAccess")
public static AspectRatio parse(@NonNull String string) {
String[] parts = string.split(":");
if (parts.length != 2) {
throw new NumberFormatException("Illegal AspectRatio string. Must be x:y");
}
int x = Integer.valueOf(parts[0]);
int y = Integer.valueOf(parts[1]);
return of(x, y);
}
private final int mX;
private final int mY;
private AspectRatio(int x, int y) {
mX = x;
mY = y;
}
public int getX() {
return mX;
}
public int getY() {
return mY;
}
@SuppressWarnings("WeakerAccess")
public boolean matches(@NonNull Size size) {
int gcd = gcd(size.getWidth(), size.getHeight());
int x = size.getWidth() / gcd;
int y = size.getHeight() / gcd;
return mX == x && mY == y;
}
@Override
public boolean equals(Object o) {
if (o == null) {
return false;
}
if (this == o) {
return true;
}
if (o instanceof AspectRatio) {
AspectRatio ratio = (AspectRatio) o;
return mX == ratio.mX && mY == ratio.mY;
}
return false;
}
@Override
public String toString() {
return mX + ":" + mY;
}
@SuppressWarnings("WeakerAccess")
public float toFloat() {
return (float) mX / mY;
}
@Override
public int hashCode() {
return mY ^ ((mX << (Integer.SIZE / 2)) | (mX >>> (Integer.SIZE / 2)));
}
@Override
public int compareTo(@NonNull AspectRatio another) {
if (equals(another)) {
return 0;
} else if (toFloat() - another.toFloat() > 0) {
return 1;
}
return -1;
}
@SuppressWarnings("SuspiciousNameCombination")
@NonNull
public AspectRatio inverse() {
return AspectRatio.of(mY, mX);
}
private static int gcd(int a, int b) {
while (b != 0) {
int c = b;
b = a % b;
a = c;
}
return a;
}
}