XML attrs, improve AspectRatio cache

pull/99/head
Mattia Iavarone 8 years ago
parent aa74a0d2a1
commit 6ae9694108
  1. 53
      cameraview/src/main/java/com/otaliastudios/cameraview/AspectRatio.java
  2. 89
      cameraview/src/main/java/com/otaliastudios/cameraview/CameraView.java
  3. 24
      cameraview/src/main/res/values/attrs.xml

@ -7,10 +7,50 @@ import android.util.SparseArray;
import java.util.HashMap; import java.util.HashMap;
/**
* A simple class representing an aspect ratio.
*/
public class AspectRatio implements Comparable<AspectRatio> { public class AspectRatio implements Comparable<AspectRatio> {
final static HashMap<String, AspectRatio> sCache = new HashMap<>(16); final static HashMap<String, AspectRatio> sCache = new HashMap<>(16);
/**
* Creates an aspect ratio with the given values.
* @param x the width
* @param y the height
* @return a (possibly cached) aspect ratio
*/
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
*/
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 mX;
private final int mY; private final int mY;
@ -78,19 +118,6 @@ public class AspectRatio implements Comparable<AspectRatio> {
return AspectRatio.of(mY, mX); return AspectRatio.of(mY, mX);
} }
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;
}
private static int gcd(int a, int b) { private static int gcd(int a, int b) {
while (b != 0) { while (b != 0) {
int c = b; int c = b;

@ -92,6 +92,7 @@ public class CameraView extends FrameLayout {
private void init(@NonNull Context context, @Nullable AttributeSet attrs) { private void init(@NonNull Context context, @Nullable AttributeSet attrs) {
setWillNotDraw(false); setWillNotDraw(false);
TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.CameraView, 0, 0); TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.CameraView, 0, 0);
// Self managed // Self managed
int jpegQuality = a.getInteger(R.styleable.CameraView_cameraJpegQuality, DEFAULT_JPEG_QUALITY); int jpegQuality = a.getInteger(R.styleable.CameraView_cameraJpegQuality, DEFAULT_JPEG_QUALITY);
boolean cropOutput = a.getBoolean(R.styleable.CameraView_cameraCropOutput, DEFAULT_CROP_OUTPUT); boolean cropOutput = a.getBoolean(R.styleable.CameraView_cameraCropOutput, DEFAULT_CROP_OUTPUT);
@ -107,6 +108,36 @@ public class CameraView extends FrameLayout {
Hdr hdr = Hdr.fromValue(a.getInteger(R.styleable.CameraView_cameraHdr, Hdr.DEFAULT.value())); Hdr hdr = Hdr.fromValue(a.getInteger(R.styleable.CameraView_cameraHdr, Hdr.DEFAULT.value()));
Audio audio = Audio.fromValue(a.getInteger(R.styleable.CameraView_cameraAudio, Audio.DEFAULT.value())); Audio audio = Audio.fromValue(a.getInteger(R.styleable.CameraView_cameraAudio, Audio.DEFAULT.value()));
// Size selectors
List<SizeSelector> constraints = new ArrayList<>(3);
if (a.hasValue(R.styleable.CameraView_cameraPictureSizeMinWidth)) {
constraints.add(SizeSelectors.minWidth(a.getInteger(R.styleable.CameraView_cameraPictureSizeMinWidth, 0)));
}
if (a.hasValue(R.styleable.CameraView_cameraPictureSizeMaxWidth)) {
constraints.add(SizeSelectors.maxWidth(a.getInteger(R.styleable.CameraView_cameraPictureSizeMaxWidth, 0)));
}
if (a.hasValue(R.styleable.CameraView_cameraPictureSizeMinHeight)) {
constraints.add(SizeSelectors.minHeight(a.getInteger(R.styleable.CameraView_cameraPictureSizeMinHeight, 0)));
}
if (a.hasValue(R.styleable.CameraView_cameraPictureSizeMaxHeight)) {
constraints.add(SizeSelectors.maxHeight(a.getInteger(R.styleable.CameraView_cameraPictureSizeMaxHeight, 0)));
}
if (a.hasValue(R.styleable.CameraView_cameraPictureSizeMinArea)) {
constraints.add(SizeSelectors.minArea(a.getInteger(R.styleable.CameraView_cameraPictureSizeMinArea, 0)));
}
if (a.hasValue(R.styleable.CameraView_cameraPictureSizeMaxArea)) {
constraints.add(SizeSelectors.maxArea(a.getInteger(R.styleable.CameraView_cameraPictureSizeMaxArea, 0)));
}
if (a.hasValue(R.styleable.CameraView_cameraPictureSizeAspectRatio)) {
//noinspection ConstantConditions
constraints.add(SizeSelectors.aspectRatio(AspectRatio.parse(a.getString(R.styleable.CameraView_cameraPictureSizeAspectRatio)), 0));
}
if (a.getBoolean(R.styleable.CameraView_cameraPictureSizeMin, false)) constraints.add(SizeSelectors.min());
if (a.getBoolean(R.styleable.CameraView_cameraPictureSizeMax, false)) constraints.add(SizeSelectors.max());
SizeSelector selector = !constraints.isEmpty() ?
SizeSelectors.and(constraints.toArray(new SizeSelector[constraints.size()])) :
SizeSelectors.max();
// Gestures // Gestures
GestureAction tapGesture = GestureAction.fromValue(a.getInteger(R.styleable.CameraView_cameraGestureTap, GestureAction.DEFAULT_TAP.value())); GestureAction tapGesture = GestureAction.fromValue(a.getInteger(R.styleable.CameraView_cameraGestureTap, GestureAction.DEFAULT_TAP.value()));
GestureAction longTapGesture = GestureAction.fromValue(a.getInteger(R.styleable.CameraView_cameraGestureLongTap, GestureAction.DEFAULT_LONG_TAP.value())); GestureAction longTapGesture = GestureAction.fromValue(a.getInteger(R.styleable.CameraView_cameraGestureLongTap, GestureAction.DEFAULT_LONG_TAP.value()));
@ -146,8 +177,7 @@ public class CameraView extends FrameLayout {
setGrid(grid); setGrid(grid);
setHdr(hdr); setHdr(hdr);
setAudio(audio); setAudio(audio);
// TODO: add from XML setPictureSize(selector);
setPictureSize(SizeSelectors.max());
// Apply gestures // Apply gestures
mapGesture(Gesture.TAP, tapGesture); mapGesture(Gesture.TAP, tapGesture);
@ -516,8 +546,8 @@ public class CameraView extends FrameLayout {
/** /**
* Checks that we have appropriate permissions for this session type. * Checks that we have appropriate permissions for this session type.
* Throws if session = audio and manifest did not add the microphone permissions. * Throws if session = audio and manifest did not add the microphone permissions.
* @param sessionType * @param sessionType the sessionType to be checked
* @param audio * @param audio the audio setting to be checked
* @return true if we can go on, false otherwise. * @return true if we can go on, false otherwise.
*/ */
@SuppressLint("NewApi") @SuppressLint("NewApi")
@ -849,33 +879,6 @@ public class CameraView extends FrameLayout {
} }
/**
* Toggles the flash mode between {@link Flash#OFF},
* {@link Flash#ON} and {@link Flash#AUTO}, in this order.
*
* @return the new flash value
*/
public Flash toggleFlash() {
Flash flash = mCameraController.getFlash();
switch (flash) {
case OFF:
setFlash(Flash.ON);
break;
case ON:
setFlash(Flash.AUTO);
break;
case AUTO:
case TORCH:
setFlash(Flash.OFF);
break;
}
return mCameraController.getFlash();
}
/** /**
* Controls the audio mode. * Controls the audio mode.
* *
@ -1638,6 +1641,10 @@ public class CameraView extends FrameLayout {
} }
} }
//endregion
//region deprecated APIs
/** /**
* @deprecated use {@link #getPictureSize()} instead. * @deprecated use {@link #getPictureSize()} instead.
*/ */
@ -1647,5 +1654,25 @@ public class CameraView extends FrameLayout {
return getPictureSize(); return getPictureSize();
} }
/**
* Toggles the flash mode between {@link Flash#OFF},
* {@link Flash#ON} and {@link Flash#AUTO}, in this order.
*
* @deprecated Don't use this. Flash values might not be supported,
* and the return value is unreliable.
*
* @return the new flash value
*/
@Deprecated
public Flash toggleFlash() {
Flash flash = mCameraController.getFlash();
switch (flash) {
case OFF: setFlash(Flash.ON); break;
case ON: setFlash(Flash.AUTO); break;
case AUTO: case TORCH: setFlash(Flash.OFF); break;
}
return mCameraController.getFlash();
}
//endregion //endregion
} }

@ -1,12 +1,24 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<declare-styleable name="CameraView"> <declare-styleable name="CameraView">
<!-- WIP attr name="cameraGestureDoubleTap" format="enum">
<enum name="none" value="0" /> <attr name="cameraPictureSizeMinWidth" format="integer|reference"/>
<enum name="focus" value="1" />
<enum name="focusWithMarker" value="2" /> <attr name="cameraPictureSizeMaxWidth" format="integer|reference"/>
<enum name="capture" value="3" />
</attr--> <attr name="cameraPictureSizeMinHeight" format="integer|reference"/>
<attr name="cameraPictureSizeMaxHeight" format="integer|reference"/>
<attr name="cameraPictureSizeMinArea" format="integer|reference" />
<attr name="cameraPictureSizeMaxArea" format="integer|reference" />
<attr name="cameraPictureSizeMin" format="boolean"/>
<attr name="cameraPictureSizeMax" format="boolean"/>
<attr name="cameraPictureSizeAspectRatio" format="string|reference"/>
<attr name="cameraGestureTap" format="enum"> <attr name="cameraGestureTap" format="enum">
<enum name="none" value="0" /> <enum name="none" value="0" />

Loading…
Cancel
Save