我想从自定义surfaceView
中捕获位图图像。
我尝试在imageView中设置BitmapImage。
但是,surfaceView
不会保存任何内容。
这是我的Android代码:
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.ImageView;
public class MainActivity extends AppCompatActivity {
OurSurface ourSurface;
FrameLayout surfaceLayout;
ImageView layoutCaptured;
Button capture;
Bitmap bitmap;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
layoutCaptured = (ImageView)findViewById(R.id.layoutCaptured);
surfaceLayout = (FrameLayout)findViewById(R.id.surfaceLayout);
capture = (Button)findViewById(R.id.capture);
capture.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
surfaceLayout.setDrawingCacheEnabled(true);
surfaceLayout.buildDrawingCache(true);
Bitmap bmp = Bitmap.createBitmap(surfaceLayout.getDrawingCache());
surfaceLayout.setDrawingCacheEnabled(false);
layoutCaptured.setImageBitmap(bmp);
Log.d("MainActivity", "onClick -> setImageBitmap");
}
});
ourSurface = new OurSurface(this);
surfaceLayout.addView(ourSurface);
}
@Override
protected void onResume() {
super.onResume();
ourSurface.resume();
}
@Override
protected void onPause() {
super.onPause();
ourSurface.pause();
}
public class OurSurface extends SurfaceView implements Runnable{
public OurSurface(Context context) {
super(context);
init(context);
}
public OurSurface(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
Thread thread;
SurfaceHolder holder;
boolean isItOK;
Canvas canvas;
int x1,y1,x2,y2,x3,y3;
Paint red, green, blue;
public void init(Context context){
holder = getHolder();
red = new Paint(Paint.ANTI_ALIAS_FLAG);
red.setColor(Color.RED);
red.setStyle(Paint.Style.FILL);
green = new Paint(Paint.ANTI_ALIAS_FLAG);
green.setColor(Color.GREEN);
green.setStyle(Paint.Style.FILL);
blue = new Paint(Paint.ANTI_ALIAS_FLAG);
blue.setColor(Color.BLUE);
blue.setStyle(Paint.Style.FILL);
}
public void resume(){
isItOK = true;
thread = new Thread(this);
thread.start();
}
public void pause(){
isItOK = false;
while(true){
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
thread = null;
break;
}
}
int width, height;
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
width = w;
height = h;
Log.d("onSizeChanged", "width #"+width+", height #"+height);
bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
canvas = new Canvas(bitmap);
}
int x1Sign = 1, y1Sign = 1, x2Sign = 1, y2Sign = 1, x3Sign = 1, y3Sign = 1;
@Override
public void run() {
while(isItOK == true){
if(!holder.getSurface().isValid()){
continue;
}
canvas = holder.lockCanvas();
canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
if(x1 > width) { x1 = width; x1Sign = (-1)*x1Sign; }
else if(x1 < 0) { x1 = 0; x1Sign = (-1)*x1Sign; }
if(y1 > height) { y1 = height; y1Sign = (-1)*y1Sign; }
else if(y1 < 0) { y1 = 0; y1Sign = (-1)*y1Sign; }
if(x2 > width) { x2 = width; x2Sign = (-1)*x2Sign; }
else if(x2 < 0) { x2 = 0; x2Sign = (-1)*x2Sign; }
if(y2 > height) { y2 = height; y2Sign = (-1)*y2Sign; }
else if(y2 < 0) { y2 = 0; y2Sign = (-1)*y2Sign; }
if(x3 > width) { x3 = width; x3Sign = (-1)*x3Sign; }
else if(x3 < 0) { x3 = 0; x3Sign = (-1)*x3Sign; }
if(y3 > height) { y3 = height; y3Sign = (-1)*y3Sign; }
else if(y3 < 0) { y3 = 0; y3Sign = (-1)*y3Sign; }
x1 = x1 + 1*x1Sign;
y1 = y1 + 3*y1Sign;
x2 = x2 + 2*x2Sign;
y2 = y2 + 2*y2Sign;
x3 = x3 + 3*x3Sign;
y3 = y3 + 1*y3Sign;
canvas.drawCircle(x1, y1, 10, red);
canvas.drawCircle(x2, y2, 10, green);
canvas.drawCircle(x3, y3, 10, blue);
holder.unlockCanvasAndPost(canvas);
}
}
}
}
和,activity_main.xml代码。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity"
android:orientation="vertical"
android:weightSum="2">
<LinearLayout
android:weightSum="5"
android:orientation="vertical"
android:id="@+id/mainLayout"
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="fill_parent">
<Button
android:layout_weight="1"
android:text="capture"
android:id="@+id/capture"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<ImageView
android:id="@+id/layoutCaptured"
android:layout_weight="4"
android:layout_width="match_parent"
android:layout_height="fill_parent">
</ImageView>
</LinearLayout>
<FrameLayout
android:id="@+id/surfaceLayout"
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="fill_parent">
</FrameLayout>
</LinearLayout>
请告诉我。
答案 0 :(得分:0)
看来,直接获取SurfaceView的位图是不可能的。
实际上,有些情况下SurfaceView的显示数据 应用程序处理器甚至无法访问它 - 它可能是a的输出 与显示输出合成的硬件视频管道 app处理器通过专用的视频覆盖。 1
在你的情况下,可以将画布绘制到位图,通常的配方是2:
<强>更新强>
经过一番研究后,它可以&#34;通过这样做工作:
public Bitmap getBitmap() {
setDrawingCacheEnabled(true);
buildDrawingCache(true);
final Bitmap bitmap = Bitmap.createBitmap( getDrawingCache() );
setDrawingCacheEnabled(false);
destroyDrawingCache();
return bitmap;
}
关于它的项目,可以找到here。