下面列出了android.util.Size#getWidth ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/**
* Given {@code choices} of {@code Size}s supported by a camera, chooses the smallest one whose
* width and height are at least as large as the respective requested values, and whose aspect
* ratio matches with the specified value.
*
* @param choices The list of sizes that the camera supports for the intended output class
* @param width The minimum desired width
* @param height The minimum desired height
* @param aspectRatio The aspect ratio
* @return The optimal {@code Size}, or an arbitrary one if none were big enough
*/
private static Size chooseOptimalSize(Size[] choices, int width, int height, Size aspectRatio) {
Log.d(TAG, "chooseOptimalSize: ");
// Collect the supported resolutions that are at least as big as the preview Surface
List<Size> bigEnough = new ArrayList<Size>();
int w = aspectRatio.getWidth();
int h = aspectRatio.getHeight();
for (Size option : choices) {
if (option.getHeight() == option.getWidth() * h / w &&
option.getWidth() >= width && option.getHeight() >= height) {
bigEnough.add(option);
}
}
// Pick the smallest of those, assuming we found any
if (bigEnough.size() > 0) {
return Collections.min(bigEnough, new CompareSizesByArea());
} else {
Log.e(TAG, "Couldn't find any suitable preview size");
return choices[0];
}
}
/**
* Given {@code choices} of {@code Size}s supported by a camera, chooses the smallest one whose
* width and height are at least as large as the respective requested values, and whose aspect
* ratio matches with the specified value.
*
* @param choices The list of sizes that the camera supports for the intended output class
* @param width The minimum desired width
* @param height The minimum desired height
* @param aspectRatio The aspect ratio
* @return The optimal {@code Size}, or an arbitrary one if none were big enough
*/
public static Size chooseOptimalSize(Size[] choices, int width, int height, Size aspectRatio) {
// Collect the supported resolutions that are at least as big as the preview Surface
List<Size> bigEnough = new ArrayList<>();
int w = aspectRatio.getWidth();
int h = aspectRatio.getHeight();
for (Size option : choices) {
if (option.getHeight() == option.getWidth() * h / w &&
option.getWidth() >= width && option.getHeight() >= height) {
bigEnough.add(option);
}
}
// Pick the smallest of those, assuming we found any
if (bigEnough.size() > 0) {
return Collections.min(bigEnough, new CompareSizesByArea());
} else {
Log.e(TAG, "Couldn't find any suitable preview size");
return choices[0];
}
}
/**
* Returns the current bounds (or the default bounds if there are no current bounds) with the
* specified aspect ratio.
*/
Rect transformBoundsToAspectRatio(Rect stackBounds, float aspectRatio,
boolean useCurrentMinEdgeSize) {
// Save the snap fraction, calculate the aspect ratio based on screen size
final float snapFraction = mSnapAlgorithm.getSnapFraction(stackBounds,
getMovementBounds(stackBounds));
final int minEdgeSize = useCurrentMinEdgeSize ? mCurrentMinSize : mDefaultMinSize;
final Size size = mSnapAlgorithm.getSizeForAspectRatio(aspectRatio, minEdgeSize,
mDisplayInfo.logicalWidth, mDisplayInfo.logicalHeight);
final int left = (int) (stackBounds.centerX() - size.getWidth() / 2f);
final int top = (int) (stackBounds.centerY() - size.getHeight() / 2f);
stackBounds.set(left, top, left + size.getWidth(), top + size.getHeight());
mSnapAlgorithm.applySnapFraction(stackBounds, getMovementBounds(stackBounds), snapFraction);
if (mIsMinimized) {
applyMinimizedOffset(stackBounds, getMovementBounds(stackBounds));
}
return stackBounds;
}
@Override
public void onPreviewSizeChosen(final Size size, final int rotation) {
previewWidth = size.getWidth();
previewHeight = size.getHeight();
final int sensorOrientation = rotation - getScreenOrientation();
rgbFrameBitmap = Bitmap.createBitmap(previewWidth, previewHeight, Config.ARGB_8888);
croppedBitmap = Bitmap.createBitmap(INPUT_SIZE, INPUT_SIZE, Config.ARGB_8888);
frameToCropTransform = ImageUtils.getTransformationMatrix(
previewWidth, previewHeight,
INPUT_SIZE, INPUT_SIZE,
sensorOrientation, MAINTAIN_ASPECT);
final Matrix cropToFrameTransform = new Matrix();
frameToCropTransform.invert(cropToFrameTransform);
}
static Size findClosestSize(Size size, Size[] supportedSizes) {
if (size == null || supportedSizes == null) {
return null;
}
Size bestSize = null;
for (Size s : supportedSizes) {
if (s.equals(size)) {
return size;
} else if (s.getWidth() <= MAX_DIMEN_FOR_ROUNDING && (bestSize == null ||
LegacyCameraDevice.findEuclidDistSquare(size, s) <
LegacyCameraDevice.findEuclidDistSquare(bestSize, s))) {
bestSize = s;
}
}
return bestSize;
}
@Override
public void onPreviewSizeChosen(final Size size, final int rotation) {
final float textSizePx = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
TEXT_SIZE_DIP, getResources().getDisplayMetrics());
borderedText = new BorderedText(textSizePx);
borderedText.setTypeface(Typeface.MONOSPACE);
recognizer = TensorFlowImageRecognizer.create(getAssets());
overlayView = (OverlayView) findViewById(R.id.overlay);
previewWidth = size.getWidth();
previewHeight = size.getHeight();
final int screenOrientation = getWindowManager().getDefaultDisplay().getRotation();
Log.i(LOGGING_TAG, String.format("Sensor orientation: %d, Screen orientation: %d",
rotation, screenOrientation));
sensorOrientation = rotation + screenOrientation;
Log.i(LOGGING_TAG, String.format("Initializing at size %dx%d", previewWidth, previewHeight));
croppedBitmap = Bitmap.createBitmap(INPUT_SIZE, INPUT_SIZE, Config.ARGB_8888);
frameToCropTransform = ImageUtils.getTransformationMatrix(previewWidth, previewHeight,
INPUT_SIZE, INPUT_SIZE, sensorOrientation, MAINTAIN_ASPECT);
frameToCropTransform.invert(new Matrix());
addCallback((final Canvas canvas) -> renderAdditionalInformation(canvas));
}
/**
* Given {@code choices} of {@code Size}s supported by a camera, choose the smallest one that
* is at least as large as the respective texture view size, and that is at most as large as the
* respective max size, and whose aspect ratio matches with the specified value. If such size
* doesn't exist, choose the largest one that is at most as large as the respective max size,
* and whose aspect ratio matches with the specified value.
*
* @param choices The list of sizes that the camera supports for the intended output
* class
* @param textureViewWidth The width of the texture view relative to sensor coordinate
* @param textureViewHeight The height of the texture view relative to sensor coordinate
* @param maxWidth The maximum width that can be chosen
* @param maxHeight The maximum height that can be chosen
* @param aspectRatio The aspect ratio
* @return The optimal {@code Size}, or an arbitrary one if none were big enough
*/
static Size chooseOptimalSize(Size[] choices, int textureViewWidth,
int textureViewHeight, int maxWidth, int maxHeight, Size aspectRatio) {
// Collect the supported resolutions that are at least as big as the preview Surface
List<Size> bigEnough = new ArrayList<>();
// Collect the supported resolutions that are smaller than the preview Surface
List<Size> notBigEnough = new ArrayList<>();
int w = aspectRatio.getWidth();
int h = aspectRatio.getHeight();
double minRatio = ((double) w) / ((double) h) * 0.95;
double maxRatio = ((double) w) / ((double) h) * 1.05;
for (Size option : choices) {
double ratio = ((double) option.getWidth()) / ((double) option.getHeight());
if (option.getWidth() <= maxWidth && option.getHeight() <= maxHeight &&
/**
* 现在允许宽高比相对于16:9有正负5%的误差.
*/
ratio >= minRatio && ratio <= maxRatio) {
if (option.getWidth() >= textureViewWidth && option.getHeight() >= textureViewHeight) {
bigEnough.add(option);
} else {
notBigEnough.add(option);
}
}
}
// Pick the smallest of those big enough. If there is no one big enough, pick the
// largest of those not big enough.
if (bigEnough.size() > 0) {
return Collections.min(bigEnough, new CompareSizesByArea());
} else if (notBigEnough.size() > 0) {
return Collections.max(notBigEnough, new CompareSizesByArea());
} else {
Log.e(TAG, "Couldn't find any suitable preview size");
return choices[0];
}
}
private Size chooseOptimalSize(Size[] choices, int textureViewWidth, int textureViewHeight,
int maxWidth, int maxHeight, Size aspectRatio) {
// Collect the supported resolutions that are at least as big as the preview Surface
List<Size> bigEnough = new ArrayList<>();
// Collect the supported resolutions that are smaller than the preview Surface
List<Size> notBigEnough = new ArrayList<>();
int w = aspectRatio.getWidth();
int h = aspectRatio.getHeight();
for (Size option : choices) {
if (option.getWidth() <= maxWidth && option.getHeight() <= maxHeight &&
option.getHeight() == option.getWidth() * h / w) {
if (option.getWidth() >= textureViewWidth &&
option.getHeight() >= textureViewHeight) {
bigEnough.add(option);
} else {
notBigEnough.add(option);
}
}
}
// Pick the smallest of those big enough. If there is no one big enough, pick the
// largest of those not big enough.
if (bigEnough.size() > 0) {
return Collections.min(bigEnough, new CompareSizesByArea());
} else if (notBigEnough.size() > 0) {
return Collections.max(notBigEnough, new CompareSizesByArea());
} else {
return choices[0];
}
}
private Size calculateViewSize(int width, int height, Size viewSize) {
int h = (int) (height * (viewSize.getWidth() / (float) width));
if (viewSize.getHeight() < h) {
int w = (int) (width * (viewSize.getHeight() / (float) height));
if (w % 2 != 0) {
w--;
}
return new Size(w, viewSize.getHeight());
}
return new Size(viewSize.getWidth(), h);
}
/**
* カメラの撮影サイズを設定します.
*
* @param pictureSize カメラの撮影サイズ
*/
public void setPictureSize(final Size pictureSize) {
List<Size> sizes = getSupportedPictureSizes();
for (Size size : sizes) {
if (size.getWidth() == pictureSize.getWidth() && size.getHeight() == pictureSize.getHeight()) {
mPictureSize = pictureSize;
return;
}
}
throw new RuntimeException("Not found a match size.");
}
/**
* Initialize the camera device
*/
@SuppressLint("MissingPermission")
public void initializeCamera(Context context, Handler backgroundHandler, Size minSize,
ImageReader.OnImageAvailableListener imageAvailableListener)
throws CameraAccessException {
if (initialized) {
throw new IllegalStateException(
"CameraHandler is already initialized or is initializing");
}
initialized = true;
// Discover the camera instance
CameraManager manager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE);
String camId = getCameraId(context);
// Initialize the image processor with the largest available size.
CameraCharacteristics characteristics = manager.getCameraCharacteristics(camId);
StreamConfigurationMap map = characteristics.get(
CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
Size bestSize = getBestCameraSize(map.getOutputSizes(ImageFormat.JPEG), minSize);
if (bestSize == null) {
throw new RuntimeException("We could not find a camera resolution that is larger than "
+ minSize.getWidth() + "x" + minSize.getHeight());
}
mImageReader = ImageReader.newInstance(bestSize.getWidth(), bestSize.getHeight(),
ImageFormat.JPEG, MAX_IMAGES);
mImageDimensions = bestSize;
Log.d(TAG, "Will capture photos that are " + mImageDimensions.getWidth() + " x " +
mImageDimensions.getHeight());
mImageReader.setOnImageAvailableListener(imageAvailableListener, backgroundHandler);
// Open the camera resource
try {
manager.openCamera(camId, mStateCallback, backgroundHandler);
} catch (CameraAccessException cae) {
Log.e(TAG, "Camera access exception", cae);
}
}
/**
* Given {@code choices} of {@code Size}s supported by a camera, choose the smallest one that
* is at least as large as the respective texture view size, and that is at most as large as the
* respective max size, and whose aspect ratio matches with the specified value. If such size
* doesn't exist, choose the largest one that is at most as large as the respective max size,
* and whose aspect ratio matches with the specified value.
*
* @param choices The list of sizes that the camera supports for the intended output
* class
* @param textureViewWidth The width of the texture view relative to sensor coordinate
* @param textureViewHeight The height of the texture view relative to sensor coordinate
* @param maxWidth The maximum width that can be chosen
* @param maxHeight The maximum height that can be chosen
* @param aspectRatio The aspect ratio
* @return The optimal {@code Size}, or an arbitrary one if none were big enough
*/
private static Size chooseOptimalSize(Size[] choices, int textureViewWidth,
int textureViewHeight, int maxWidth, int maxHeight, Size aspectRatio) {
// Collect the supported resolutions that are at least as big as the preview Surface
List<Size> bigEnough = new ArrayList<>();
// Collect the supported resolutions that are smaller than the preview Surface
List<Size> notBigEnough = new ArrayList<>();
int w = aspectRatio.getWidth();
int h = aspectRatio.getHeight();
for (Size option : choices) {
if (option.getWidth() <= maxWidth && option.getHeight() <= maxHeight &&
option.getHeight() == option.getWidth() * h / w) {
if (option.getWidth() >= textureViewWidth &&
option.getHeight() >= textureViewHeight) {
bigEnough.add(option);
} else {
notBigEnough.add(option);
}
}
}
// Pick the smallest of those big enough. If there is no one big enough, pick the
// largest of those not big enough.
if (bigEnough.size() > 0) {
return Collections.min(bigEnough, new CompareSizesByArea());
} else if (notBigEnough.size() > 0) {
return Collections.max(notBigEnough, new CompareSizesByArea());
} else {
Log.e(TAG, "Couldn't find any suitable preview size");
return choices[0];
}
}
@RequiresApi(21)
private static boolean isPortrait(Size size) {
return size.getWidth() < size.getHeight();
}
private void updateImage(Size resolution, boolean isEInkModeEnabled, float rotation) {
Context context = getContext();
if (context == null) return;
mResolution = resolution;
mIsEInkModeEnabled = isEInkModeEnabled;
mImageRotationDegrees = rotation;
final int width = mResolution.getWidth();
final int height = mResolution.getHeight();
// Save selected resolution
SharedPreferences settings = context.getSharedPreferences(kPreferences, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = settings.edit();
editor.putInt(kPreferences_resolutionWidth, width);
editor.putInt(kPreferences_resolutionHeight, height);
editor.putBoolean(kPreferences_isEInkModeEnabled, isEInkModeEnabled);
editor.apply();
// Change UI to adjust aspect ratio of the displayed image
final float resolutionAspectRatio = resolution.getWidth() / (float) resolution.getHeight();
final int maxWidth = mResolutionContainerViewGroup.getWidth();
final int maxHeight = mResolutionContainerViewGroup.getHeight();
RelativeLayout.LayoutParams relativeLayoutParams = (RelativeLayout.LayoutParams) mResolutionViewGroup.getLayoutParams();
if (maxWidth > maxHeight * resolutionAspectRatio) {
relativeLayoutParams.height = maxHeight;//(int) MetricsUtils.convertPixelsToDp(context, maxHeight);
relativeLayoutParams.width = (int) (relativeLayoutParams.height * resolutionAspectRatio);
} else {
relativeLayoutParams.width = maxWidth;//(int) MetricsUtils.convertPixelsToDp(context, maxWidth);
relativeLayoutParams.height = (int) (relativeLayoutParams.width * (1.f / resolutionAspectRatio));
}
mResolutionViewGroup.requestLayout();
// Calculate transformed image
if (mBitmap != null) {
Bitmap transformedBitmap = ImageUtils.scaleAndRotateImage(mBitmap, mResolution, mImageRotationDegrees, Color.BLACK);
if (isEInkModeEnabled) {
transformedBitmap = ImageUtils.applyEInkModeToImage(context, transformedBitmap);
}
BitmapDrawable bitmapDrawable = new BitmapDrawable(getResources(), transformedBitmap); // Create bitmap drawable to control filtering method
bitmapDrawable.setFilterBitmap(false);
mCameraImageView.setImageDrawable(bitmapDrawable);
}
//
updateResolutionUI();
}
/**
* Given {@code choices} of {@code Size}s supported by a camera, chooses the smallest one whose
* width and height are at least as large as the minimum of both, or an exact match if possible.
*
* @param choices The list of sizes that the camera supports for the intended output class
* @param width The minimum desired width
* @param height The minimum desired height
* @return The optimal {@code Size}, or an arbitrary one if none were big enough
*/
protected static Size chooseOptimalSize(final Size[] choices, final int width, final int height) {
final int minSize = Math.max(Math.min(width, height), MINIMUM_PREVIEW_SIZE);
final Size desiredSize = new Size(width, height);
// Collect the supported resolutions that are at least as big as the preview Surface
boolean exactSizeFound = false;
final List<Size> bigEnough = new ArrayList<Size>();
final List<Size> tooSmall = new ArrayList<Size>();
for (final Size option : choices) {
if (option.equals(desiredSize)) {
// Set the size but don't return yet so that remaining sizes will still be logged.
exactSizeFound = true;
}
if (option.getHeight() >= minSize && option.getWidth() >= minSize) {
bigEnough.add(option);
} else {
tooSmall.add(option);
}
}
Log.d(TAG, "Desired size: " + desiredSize + ", min size: " + minSize + "x" + minSize);
Log.d(TAG, "Valid preview sizes: [" + TextUtils.join(", ", bigEnough) + "]");
Log.d(TAG, "Rejected preview sizes: [" + TextUtils.join(", ", tooSmall) + "]");
if (exactSizeFound) {
Log.d(TAG, "Exact size match found.");
return desiredSize;
}
// Pick the smallest of those, assuming we found any
if (bigEnough.size() > 0) {
final Size chosenSize = Collections.min(bigEnough, new CompareSizesByArea());
Log.d(TAG, "Chosen size: " + chosenSize.getWidth() + "x" + chosenSize.getHeight());
return chosenSize;
} else {
Log.e(TAG, "Couldn't find any suitable preview size");
return choices[0];
}
}
/**
* Given {@code choices} of {@code Size}s supported by a camera, chooses the smallest one whose
* width and height are at least as large as the minimum of both, or an exact match if possible.
*
* @param choices The list of sizes that the camera supports for the intended output class
* @param width The minimum desired width
* @param height The minimum desired height
* @return The optimal {@code Size}, or an arbitrary one if none were big enough
*/
protected static Size chooseOptimalSize(final Size[] choices, final int width, final int height) {
final int minSize = Math.max(Math.min(width, height), MINIMUM_PREVIEW_SIZE);
final Size desiredSize = new Size(width, height);
// Collect the supported resolutions that are at least as big as the preview Surface
boolean exactSizeFound = false;
final List<Size> bigEnough = new ArrayList<Size>();
final List<Size> tooSmall = new ArrayList<Size>();
for (final Size option : choices) {
if (option.equals(desiredSize)) {
// Set the size but don't return yet so that remaining sizes will still be logged.
exactSizeFound = true;
}
if (option.getHeight() >= minSize && option.getWidth() >= minSize) {
bigEnough.add(option);
} else {
tooSmall.add(option);
}
}
Log.d(TAG, "Desired size: " + desiredSize + ", min size: " + minSize + "x" + minSize);
Log.d(TAG, "Valid preview sizes: [" + TextUtils.join(", ", bigEnough) + "]");
Log.d(TAG, "Rejected preview sizes: [" + TextUtils.join(", ", tooSmall) + "]");
if (exactSizeFound) {
Log.d(TAG, "Exact size match found.");
return desiredSize;
}
// Pick the smallest of those, assuming we found any
if (bigEnough.size() > 0) {
final Size chosenSize = Collections.min(bigEnough, new CompareSizesByArea());
Log.d(TAG, "Chosen size: " + chosenSize.getWidth() + "x" + chosenSize.getHeight());
return chosenSize;
} else {
Log.e(TAG, "Couldn't find any suitable preview size");
return choices[0];
}
}
/**
* Given {@code choices} of {@code Size}s supported by a camera, chooses the smallest one whose
* width and height are at least as large as the minimum of both, or an exact match if possible.
*
* @param choices The list of sizes that the camera supports for the intended output class
* @param width The minimum desired width
* @param height The minimum desired height
* @return The optimal {@code Size}, or an arbitrary one if none were big enough
*/
protected static Size chooseOptimalSize(final Size[] choices, final int width, final int height) {
final int minSize = Math.max(Math.min(width, height), MINIMUM_PREVIEW_SIZE);
final Size desiredSize = new Size(width, height);
// Collect the supported resolutions that are at least as big as the preview Surface
boolean exactSizeFound = false;
final List<Size> bigEnough = new ArrayList<Size>();
final List<Size> tooSmall = new ArrayList<Size>();
for (final Size option : choices) {
if (option.equals(desiredSize)) {
// Set the size but don't return yet so that remaining sizes will still be logged.
exactSizeFound = true;
}
if (option.getHeight() >= minSize && option.getWidth() >= minSize) {
bigEnough.add(option);
} else {
tooSmall.add(option);
}
}
Log.d(TAG, "Desired size: " + desiredSize + ", min size: " + minSize + "x" + minSize);
Log.d(TAG, "Valid preview sizes: [" + TextUtils.join(", ", bigEnough) + "]");
Log.d(TAG, "Rejected preview sizes: [" + TextUtils.join(", ", tooSmall) + "]");
if (exactSizeFound) {
Log.d(TAG, "Exact size match found.");
return desiredSize;
}
// Pick the smallest of those, assuming we found any
if (bigEnough.size() > 0) {
final Size chosenSize = Collections.min(bigEnough, new CompareSizesByArea());
Log.d(TAG, "Chosen size: " + chosenSize.getWidth() + "x" + chosenSize.getHeight());
return chosenSize;
} else {
Log.e(TAG, "Couldn't find any suitable preview size");
return choices[0];
}
}
private void drawFrame(SurfaceTexture st, int width, int height, int flipType)
throws LegacyExceptionUtils.BufferQueueAbandonedException {
checkGlError("onDrawFrame start");
st.getTransformMatrix(mSTMatrix);
Matrix.setIdentityM(mMVPMatrix, /*smOffset*/0);
// Find intermediate buffer dimensions
Size dimens;
try {
dimens = LegacyCameraDevice.getTextureSize(st);
} catch (LegacyExceptionUtils.BufferQueueAbandonedException e) {
// Should never hit this.
throw new IllegalStateException("Surface abandoned, skipping drawFrame...", e);
}
float texWidth = dimens.getWidth();
float texHeight = dimens.getHeight();
if (texWidth <= 0 || texHeight <= 0) {
throw new IllegalStateException("Illegal intermediate texture with dimension of 0");
}
// Letterbox or pillar-box output dimensions into intermediate dimensions.
RectF intermediate = new RectF(/*left*/0, /*top*/0, /*right*/texWidth, /*bottom*/texHeight);
RectF output = new RectF(/*left*/0, /*top*/0, /*right*/width, /*bottom*/height);
android.graphics.Matrix boxingXform = new android.graphics.Matrix();
boxingXform.setRectToRect(output, intermediate, android.graphics.Matrix.ScaleToFit.CENTER);
boxingXform.mapRect(output);
// Find scaling factor from pillar-boxed/letter-boxed output dimensions to intermediate
// buffer dimensions.
float scaleX = intermediate.width() / output.width();
float scaleY = intermediate.height() / output.height();
// Intermediate texture is implicitly scaled to 'fill' the output dimensions in clip space
// coordinates in the shader. To avoid stretching, we need to scale the larger dimension
// of the intermediate buffer so that the output buffer is actually letter-boxed
// or pillar-boxed into the intermediate buffer after clipping.
Matrix.scaleM(mMVPMatrix, /*offset*/0, /*x*/scaleX, /*y*/scaleY, /*z*/1);
if (DEBUG) {
Log.d(TAG, "Scaling factors (S_x = " + scaleX + ",S_y = " + scaleY + ") used for " +
width + "x" + height + " surface, intermediate buffer size is " + texWidth +
"x" + texHeight);
}
// Set viewport to be output buffer dimensions
GLES20.glViewport(0, 0, width, height);
if (DEBUG) {
GLES20.glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
GLES20.glClear(GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);
}
GLES20.glUseProgram(mProgram);
checkGlError("glUseProgram");
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, mTextureID);
FloatBuffer triangleVertices;
switch(flipType) {
case FLIP_TYPE_HORIZONTAL:
triangleVertices = mHorizontalFlipTriangleVertices;
break;
case FLIP_TYPE_VERTICAL:
triangleVertices = mVerticalFlipTriangleVertices;
break;
case FLIP_TYPE_BOTH:
triangleVertices = mBothFlipTriangleVertices;
break;
default:
triangleVertices = mRegularTriangleVertices;
break;
}
triangleVertices.position(TRIANGLE_VERTICES_DATA_POS_OFFSET);
GLES20.glVertexAttribPointer(maPositionHandle, VERTEX_POS_SIZE, GLES20.GL_FLOAT,
/*normalized*/ false, TRIANGLE_VERTICES_DATA_STRIDE_BYTES, triangleVertices);
checkGlError("glVertexAttribPointer maPosition");
GLES20.glEnableVertexAttribArray(maPositionHandle);
checkGlError("glEnableVertexAttribArray maPositionHandle");
triangleVertices.position(TRIANGLE_VERTICES_DATA_UV_OFFSET);
GLES20.glVertexAttribPointer(maTextureHandle, VERTEX_UV_SIZE, GLES20.GL_FLOAT,
/*normalized*/ false, TRIANGLE_VERTICES_DATA_STRIDE_BYTES, triangleVertices);
checkGlError("glVertexAttribPointer maTextureHandle");
GLES20.glEnableVertexAttribArray(maTextureHandle);
checkGlError("glEnableVertexAttribArray maTextureHandle");
GLES20.glUniformMatrix4fv(muMVPMatrixHandle, /*count*/ 1, /*transpose*/ false, mMVPMatrix,
/*offset*/ 0);
GLES20.glUniformMatrix4fv(muSTMatrixHandle, /*count*/ 1, /*transpose*/ false, mSTMatrix,
/*offset*/ 0);
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, /*offset*/ 0, /*count*/ 4);
checkGlDrawError("glDrawArrays");
}
static long findEuclidDistSquare(Size a, Size b) {
long d0 = a.getWidth() - b.getWidth();
long d1 = a.getHeight() - b.getHeight();
return d0 * d0 + d1 * d1;
}
private static boolean checkAspectRatiosMatch(Size a, Size b) {
float aAspect = a.getWidth() / (float) a.getHeight();
float bAspect = b.getWidth() / (float) b.getHeight();
return Math.abs(aAspect - bAspect) < ASPECT_RATIO_TOLERANCE;
}