用圆形边框View覆盖TextureView
Overlay TextureView with circle border View
Android 新手,但我正在尝试在设备摄像头的 TextureView 流上覆盖一个透明的圆形视图,但是无论我做什么,我都无法让覆盖视图出现在纹理视图。我有这样实现的 TextureView:
package org.tensorflow.demo;
import android.content.Context;
import android.util.AttributeSet;
import android.view.TextureView;
/**
* A {@link TextureView} that can be adjusted to a specified aspect ratio.
*/
public class AutoFitTextureView extends TextureView {
private int ratioWidth = 0;
private int ratioHeight = 0;
public AutoFitTextureView(final Context context) {
this(context, null);
}
public AutoFitTextureView(final Context context, final AttributeSet attrs) {
this(context, attrs, 0);
}
public AutoFitTextureView(final Context context, final AttributeSet attrs, final int defStyle) {
super(context, attrs, defStyle);
}
/**
* Sets the aspect ratio for this view. The size of the view will be measured based on the ratio
* calculated from the parameters. Note that the actual sizes of parameters don't matter, that
* is, calling setAspectRatio(2, 3) and setAspectRatio(4, 6) make the same result.
*
* @param width Relative horizontal size
* @param height Relative vertical size
*/
public void setAspectRatio(final int width, final int height) {
if (width < 0 || height < 0) {
throw new IllegalArgumentException("Size cannot be negative.");
}
ratioWidth = width;
ratioHeight = height;
requestLayout();
}
@Override
protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
final int width = MeasureSpec.getSize(widthMeasureSpec);
final int height = MeasureSpec.getSize(heightMeasureSpec);
if (0 == ratioWidth || 0 == ratioHeight) {
setMeasuredDimension(width, height);
} else {
if (width < height * ratioWidth / ratioHeight) {
setMeasuredDimension(width, width * ratioHeight / ratioWidth);
} else {
setMeasuredDimension(height * ratioWidth / ratioHeight, height);
}
}
}
}
我的叠加层目前看起来像这样(圆圈颜色当前设置为黑色以进行调试:
package org.tensorflow.demo;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;
public class OverlayView extends View {
private final Paint transparentPaint;
public OverlayView(final Context context, final AttributeSet attrs) {
super(context, attrs);
transparentPaint = new Paint();
transparentPaint.setColor(getResources().getColor(android.R.color.black));
}
@Override
public void onDraw(final Canvas canvas) {
int w = getWidth();
int h = getHeight();
int pl = getPaddingLeft();
int pr = getPaddingRight();
int pt = getPaddingTop();
int pb = getPaddingBottom();
int usableWidth = w - (pl + pr);
int usableHeight = h - (pt + pb);
int radius = Math.min(usableWidth, usableHeight) / 2;
int cx = pl + (usableWidth / 2);
int cy = pt + (usableHeight / 2);
canvas.drawCircle(cx, cy, radius, transparentPaint);
}
}
最后我得到了我的布局xml:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<org.tensorflow.demo.AutoFitTextureView
android:id="@+id/texture"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<org.tensorflow.demo.OverlayView
android:id="@+id/overlay"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<org.tensorflow.demo.RecognitionScoreView
android:id="@+id/results"
android:layout_width="match_parent"
android:layout_height="112dp" />
</FrameLayout>
最终使用 PorterDuff.Mode.SRC_OUT
从全屏矩形中切出一个圆来解决此问题:
protected void createWindowFrame() {
int w = getWidth();
int h = getHeight();
windowFrame = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
Canvas osCanvas = new Canvas(windowFrame);
RectF outerRectangle = new RectF(0, 0, getWidth(), getHeight());
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setColor(Color.parseColor("#4885ed"));
osCanvas.drawRect(outerRectangle, paint);
paint.setColor(Color.TRANSPARENT);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_OUT));
int pl = getPaddingLeft();
int pr = getPaddingRight();
int pt = getPaddingTop();
int pb = getPaddingBottom();
int usableWidth = w - (pl + pr);
int usableHeight = h - (pt + pb);
int radius = Math.min(usableWidth, usableHeight) / 2;
int cx = pl + (usableWidth / 2);
int cy = pt + (usableHeight / 2);
osCanvas.drawCircle(cx, cy, radius, paint);
}
Android 新手,但我正在尝试在设备摄像头的 TextureView 流上覆盖一个透明的圆形视图,但是无论我做什么,我都无法让覆盖视图出现在纹理视图。我有这样实现的 TextureView:
package org.tensorflow.demo;
import android.content.Context;
import android.util.AttributeSet;
import android.view.TextureView;
/**
* A {@link TextureView} that can be adjusted to a specified aspect ratio.
*/
public class AutoFitTextureView extends TextureView {
private int ratioWidth = 0;
private int ratioHeight = 0;
public AutoFitTextureView(final Context context) {
this(context, null);
}
public AutoFitTextureView(final Context context, final AttributeSet attrs) {
this(context, attrs, 0);
}
public AutoFitTextureView(final Context context, final AttributeSet attrs, final int defStyle) {
super(context, attrs, defStyle);
}
/**
* Sets the aspect ratio for this view. The size of the view will be measured based on the ratio
* calculated from the parameters. Note that the actual sizes of parameters don't matter, that
* is, calling setAspectRatio(2, 3) and setAspectRatio(4, 6) make the same result.
*
* @param width Relative horizontal size
* @param height Relative vertical size
*/
public void setAspectRatio(final int width, final int height) {
if (width < 0 || height < 0) {
throw new IllegalArgumentException("Size cannot be negative.");
}
ratioWidth = width;
ratioHeight = height;
requestLayout();
}
@Override
protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
final int width = MeasureSpec.getSize(widthMeasureSpec);
final int height = MeasureSpec.getSize(heightMeasureSpec);
if (0 == ratioWidth || 0 == ratioHeight) {
setMeasuredDimension(width, height);
} else {
if (width < height * ratioWidth / ratioHeight) {
setMeasuredDimension(width, width * ratioHeight / ratioWidth);
} else {
setMeasuredDimension(height * ratioWidth / ratioHeight, height);
}
}
}
}
我的叠加层目前看起来像这样(圆圈颜色当前设置为黑色以进行调试:
package org.tensorflow.demo;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;
public class OverlayView extends View {
private final Paint transparentPaint;
public OverlayView(final Context context, final AttributeSet attrs) {
super(context, attrs);
transparentPaint = new Paint();
transparentPaint.setColor(getResources().getColor(android.R.color.black));
}
@Override
public void onDraw(final Canvas canvas) {
int w = getWidth();
int h = getHeight();
int pl = getPaddingLeft();
int pr = getPaddingRight();
int pt = getPaddingTop();
int pb = getPaddingBottom();
int usableWidth = w - (pl + pr);
int usableHeight = h - (pt + pb);
int radius = Math.min(usableWidth, usableHeight) / 2;
int cx = pl + (usableWidth / 2);
int cy = pt + (usableHeight / 2);
canvas.drawCircle(cx, cy, radius, transparentPaint);
}
}
最后我得到了我的布局xml:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<org.tensorflow.demo.AutoFitTextureView
android:id="@+id/texture"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<org.tensorflow.demo.OverlayView
android:id="@+id/overlay"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<org.tensorflow.demo.RecognitionScoreView
android:id="@+id/results"
android:layout_width="match_parent"
android:layout_height="112dp" />
</FrameLayout>
最终使用 PorterDuff.Mode.SRC_OUT
从全屏矩形中切出一个圆来解决此问题:
protected void createWindowFrame() {
int w = getWidth();
int h = getHeight();
windowFrame = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
Canvas osCanvas = new Canvas(windowFrame);
RectF outerRectangle = new RectF(0, 0, getWidth(), getHeight());
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setColor(Color.parseColor("#4885ed"));
osCanvas.drawRect(outerRectangle, paint);
paint.setColor(Color.TRANSPARENT);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_OUT));
int pl = getPaddingLeft();
int pr = getPaddingRight();
int pt = getPaddingTop();
int pb = getPaddingBottom();
int usableWidth = w - (pl + pr);
int usableHeight = h - (pt + pb);
int radius = Math.min(usableWidth, usableHeight) / 2;
int cx = pl + (usableWidth / 2);
int cy = pt + (usableHeight / 2);
osCanvas.drawCircle(cx, cy, radius, paint);
}