现在我正在尝试从自定义类中捕获位图图像,该类可以检测和跟踪面部。但它返回黑色图像。我认为问题是getDrawingCache()方法无法从自定义视图中获取截图图像。除了这个自定义视图,捕获其他视图进展顺利。
这是我使用的代码,
main.xml中
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/topLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:keepScreenOn="true"
android:orientation="vertical">
<LinearLayout
android:id="@+id/llCameraView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="0.1">
<com.google.android.gms.samples.vision.face.facetracker.ui.camera.CameraSourcePreview
android:id="@+id/preview"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.gms.samples.vision.face.facetracker.ui.camera.GraphicOverlay
android:id="@+id/faceOverlay"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</com.google.android.gms.samples.vision.face.facetracker.ui.camera.CameraSourcePreview>
</LinearLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="80dp"
android:orientation="horizontal"
android:background="#00ffffff">
<ImageView
android:id="@+id/ivChangeCamera"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/change_64_w"
android:layout_margin="10dp"/>
<ImageView
android:id="@+id/ivTakePicture"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/takepic"
android:layout_centerHorizontal="true"
android:layout_margin="10dp"/>
<ImageView
android:id="@+id/ivFilter"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/filter_64_w"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_margin="10dp"/>
<ImageView
android:id="@+id/ivSticker"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/sticker_64_w"
android:layout_toLeftOf="@id/ivFilter"
android:layout_margin="10dp"/>
</RelativeLayout>
</LinearLayout>
MainActivity.java的一部分
ImageView takePicture = (ImageView) findViewById(R.id.ivTakePicture);
final LinearLayout llCameraView = (LinearLayout)findViewById(R.id.llCameraView);
takePicture.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ContextWrapper wrapper = new ContextWrapper(getApplicationContext());
File file = wrapper.getDir("Images", MODE_PRIVATE);
file = new File(file, "UniqueFileName"+".jpg");
llCameraView.buildDrawingCache();
Bitmap captureView;
llCameraView.setDrawingCacheEnabled(true);
captureView = Bitmap.createBitmap(llCameraView.getDrawingCache());
llCameraView.setDrawingCacheEnabled(false);
try{
OutputStream stream = null;
stream = new FileOutputStream(file);
captureView.compress(Bitmap.CompressFormat.JPEG,100,stream);
stream.flush();
stream.close();
Toast.makeText(getApplicationContext(), "Captured!", Toast.LENGTH_LONG).show();
}catch (IOException e) // Catch the exception
{
e.printStackTrace();
Toast.makeText(getApplicationContext(), "Failed!", Toast.LENGTH_LONG).show();
}
}
});
GraphicOverlay.java
public class GraphicOverlay extends View {
private final Object mLock = new Object();
private int mPreviewWidth;
private float mWidthScaleFactor = 1.0f;
private int mPreviewHeight;
private float mHeightScaleFactor = 1.0f;
private int mFacing = CameraSource.CAMERA_FACING_BACK;
private Set<Graphic> mGraphics = new HashSet<>();
public static abstract class Graphic {
private GraphicOverlay mOverlay;
public Graphic(GraphicOverlay overlay) {
mOverlay = overlay;
}
public abstract void draw(Canvas canvas);
public float scaleX(float horizontal) {
return horizontal * mOverlay.mWidthScaleFactor;
}
public float scaleY(float vertical) {
return vertical * mOverlay.mHeightScaleFactor;
}
public float translateX(float x) {
if (mOverlay.mFacing == CameraSource.CAMERA_FACING_FRONT) {
return mOverlay.getWidth() - scaleX(x);
} else {
return scaleX(x);
}
}
public float translateY(float y) {
return scaleY(y);
}
public void postInvalidate() {
mOverlay.postInvalidate();
}
}
public GraphicOverlay(Context context, AttributeSet attrs) {
super(context, attrs);
}
public void clear() {
synchronized (mLock) {
mGraphics.clear();
}
postInvalidate();
}
public void add(Graphic graphic) {
synchronized (mLock) {
mGraphics.add(graphic);
}
postInvalidate();
}
public void remove(Graphic graphic) {
synchronized (mLock) {
mGraphics.remove(graphic);
}
postInvalidate();
}
public void setCameraInfo(int previewWidth, int previewHeight, int facing) {
synchronized (mLock) {
mPreviewWidth = previewWidth;
mPreviewHeight = previewHeight;
mFacing = facing;
}
postInvalidate();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
synchronized (mLock) {
if ((mPreviewWidth != 0) && (mPreviewHeight != 0)) {
mWidthScaleFactor = (float) canvas.getWidth() / (float) mPreviewWidth;
mHeightScaleFactor = (float) canvas.getHeight() / (float) mPreviewHeight;
}
for (Graphic graphic : mGraphics) {
graphic.draw(canvas);
}
}
}
CameraSourcePreview.java
public class CameraSourcePreview extends ViewGroup {
private static final String TAG = "CameraSourcePreview";
private Context mContext;
private SurfaceView mSurfaceView;
private boolean mStartRequested;
private boolean mSurfaceAvailable;
private CameraSource mCameraSource;
private GraphicOverlay mOverlay;
public CameraSourcePreview(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context;
mStartRequested = false;
mSurfaceAvailable = false;
mSurfaceView = new SurfaceView(context);
mSurfaceView.getHolder().addCallback(new SurfaceCallback());
addView(mSurfaceView);
}
public void start(CameraSource cameraSource) throws IOException {
if (cameraSource == null) {
stop();
}
mCameraSource = cameraSource;
if (mCameraSource != null) {
mStartRequested = true;
startIfReady();
}
}
public void start(CameraSource cameraSource, GraphicOverlay overlay) throws IOException {
mOverlay = overlay;
start(cameraSource);
}
public void stop() {
if (mCameraSource != null) {
mCameraSource.stop();
}
}
public void release() {
if (mCameraSource != null) {
mCameraSource.release();
mCameraSource = null;
}
}
private void startIfReady() throws IOException {
if (mStartRequested && mSurfaceAvailable) {
mCameraSource.start(mSurfaceView.getHolder());
if (mOverlay != null) {
Size size = mCameraSource.getPreviewSize();
int min = Math.min(size.getWidth(), size.getHeight());
int max = Math.max(size.getWidth(), size.getHeight());
if (isPortraitMode()) {
// Swap width and height sizes when in portrait, since it will be rotated by
// 90 degrees
mOverlay.setCameraInfo(min, max, mCameraSource.getCameraFacing());
} else {
mOverlay.setCameraInfo(max, min, mCameraSource.getCameraFacing());
}
mOverlay.clear();
}
mStartRequested = false;
}
}
private class SurfaceCallback implements SurfaceHolder.Callback {
@Override
public void surfaceCreated(SurfaceHolder surface) {
mSurfaceAvailable = true;
try {
startIfReady();
} catch (IOException e) {
Log.e(TAG, "Could not start camera source.", e);
}
}
@Override
public void surfaceDestroyed(SurfaceHolder surface) {
mSurfaceAvailable = false;
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
int width = 320;
int height = 240;
if (mCameraSource != null) {
Size size = mCameraSource.getPreviewSize();
if (size != null) {
width = size.getWidth();
height = size.getHeight();
}
}
// Swap width and height sizes when in portrait, since it will be rotated 90 degrees
if (isPortraitMode()) {
int tmp = width;
width = height;
height = tmp;
}
final int layoutWidth = right - left;
final int layoutHeight = bottom - top;
}
for (int i = 0; i < getChildCount(); ++i) {
getChildAt(i).layout(0, 0, layoutWidth, layoutHeight);
}
try {
startIfReady();
} catch (IOException e) {
Log.e(TAG, "Could not start camera source.", e);
}
}
private boolean isPortraitMode() {
int orientation = mContext.getResources().getConfiguration().orientation;
if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
return false;
}
if (orientation == Configuration.ORIENTATION_PORTRAIT) {
return true;
}
Log.d(TAG, "isPortraitMode returning false by default");
return false;
}
}
答案 0 :(得分:0)
我可以使用以下方法捕获图像:
mCameraSource.takePicture(null, CameraSource.PictureCallback { data ->
file = File.createTempFile("name", ".jpg")
file?.let {
var os: OutputStream? = null
try {
var bitmap = BitmapFactory.decodeByteArray(data, 0, data.size)
val bos = ByteArrayOutputStream()
bitmap.compress(Bitmap.CompressFormat.WEBP, 80, bos)
val bitmapData = bos.toByteArray()
val fos = FileOutputStream(file)
fos.write(bitmapData)
fos.flush()
fos.close()
} catch (e: IOException) {
e.printStackTrace()
} finally {
if (os != null) {
try {
os.close()
} catch (e: IOException) {
e.printStackTrace()
}
}
}
}
})
使用压缩版本创建的临时文件。现在,您可以播放临时文件了。