将android.media.Image绘制到曲面
我有一个android应用程序 它使用一个将android.media.Image绘制到曲面,android,exoplayer,Android,Exoplayer,我有一个android应用程序 它使用一个SurfaceView,从这里我通过SurfaceHolder获得Surface 它还使用ExoPlayer来流式播放视频。然而,我实例化了一个图像阅读器,获取其表面,并将其传递给外部播放器 现在,我在ImageReader.OnImageAvailableListener#onImageAvailable中,访问最新的图像 我想操纵图像,并将新数据发送到“表面视图”表面 如何将android.media.Image绘制到android.view.Sur
SurfaceView
,从这里我通过SurfaceHolder
获得Surface
它还使用ExoPlayer
来流式播放视频。然而,我实例化了一个图像阅读器
,获取其表面
,并将其传递给外部播放器
现在,我在ImageReader.OnImageAvailableListener#onImageAvailable
中,访问最新的图像
我想操纵图像
,并将新数据发送到“表面视图”表面
如何将android.media.Image
绘制到android.view.Surface
?可能的重复:
首先使用lockCanvas()
(请参阅)获取画布,然后使用以下方法获取图像并使其成为可绘制的:
my_bitmap = Bitmap.createBitmap(
MediaStore.Images.Media.getBitmap(getContentResolver(), uri),
0,0,90, 90);
drawable=new BitmapDrawable(my_bitmap);
之后,您可以将可绘制画布绘制到锁定的画布上,并使用unlockCanvasAndPost(canvas canvas)
将更新后的画布发布回surfaceview。以下是您问题的答案
MainActivity.java
public class MainActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mySurfaceView mySurfaceView = new mySurfaceView(getApplicationContext());
setContentView(mySurfaceView);
}
}
public class mySurfaceView extends SurfaceView implements
SurfaceHolder.Callback {
private TutorialThread _thread;
public mySurfaceView(Context context) {
super(context);
getHolder().addCallback(this);
_thread = new TutorialThread(getHolder(), this);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Bitmap _scratch = BitmapFactory.decodeResource(getResources(),
R.drawable.icon);
canvas.drawColor(Color.BLACK);
canvas.drawBitmap(_scratch, 10, 10, null);
}
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
}
public void surfaceCreated(SurfaceHolder arg0) {
_thread.setRunning(true);
_thread.start();
}
public void surfaceDestroyed(SurfaceHolder arg0) {
boolean retry = true;
_thread.setRunning(false);
while (retry) {
try {
_thread.join();
retry = false;
} catch (InterruptedException e) {
}
}
}
class TutorialThread extends Thread {
private SurfaceHolder _surfaceHolder;
private mySurfaceView _panel;
private boolean _run = false;
public TutorialThread(SurfaceHolder surfaceHolder, mySurfaceView panel) {
_surfaceHolder = surfaceHolder;
_panel = panel;
}
public void setRunning(boolean run) {
_run = run;
}
@Override
public void run() {
Canvas c;
while (_run) {
c = null;
try {
c = _surfaceHolder.lockCanvas(null);
synchronized (_surfaceHolder) {
_panel.onDraw(c);
}
} finally {
if (c != null) {
_surfaceHolder.unlockCanvasAndPost(c);
}
}
}
}
}
}
mySurfaceView.java
public class MainActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mySurfaceView mySurfaceView = new mySurfaceView(getApplicationContext());
setContentView(mySurfaceView);
}
}
public class mySurfaceView extends SurfaceView implements
SurfaceHolder.Callback {
private TutorialThread _thread;
public mySurfaceView(Context context) {
super(context);
getHolder().addCallback(this);
_thread = new TutorialThread(getHolder(), this);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Bitmap _scratch = BitmapFactory.decodeResource(getResources(),
R.drawable.icon);
canvas.drawColor(Color.BLACK);
canvas.drawBitmap(_scratch, 10, 10, null);
}
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
}
public void surfaceCreated(SurfaceHolder arg0) {
_thread.setRunning(true);
_thread.start();
}
public void surfaceDestroyed(SurfaceHolder arg0) {
boolean retry = true;
_thread.setRunning(false);
while (retry) {
try {
_thread.join();
retry = false;
} catch (InterruptedException e) {
}
}
}
class TutorialThread extends Thread {
private SurfaceHolder _surfaceHolder;
private mySurfaceView _panel;
private boolean _run = false;
public TutorialThread(SurfaceHolder surfaceHolder, mySurfaceView panel) {
_surfaceHolder = surfaceHolder;
_panel = panel;
}
public void setRunning(boolean run) {
_run = run;
}
@Override
public void run() {
Canvas c;
while (_run) {
c = null;
try {
c = _surfaceHolder.lockCanvas(null);
synchronized (_surfaceHolder) {
_panel.onDraw(c);
}
} finally {
if (c != null) {
_surfaceHolder.unlockCanvasAndPost(c);
}
}
}
}
}
}
这个问题我不清楚。
获取android.media.Image的方法是通过Camera2 API,在那里你可以提供一个曲面,“摄影机”将在其上绘制。请参阅
获取图像对象的另一种方法是从ImageReader(例如解码视频时)获取图像对象。在这种情况下,您希望绘制图像,但无法向ImageReader提供曲面(存在未显示的内部曲面)。在这种情况下,可以在SurfaceView上绘制图像。
假设是这种情况,则需要将图像转换为位图对象
您已经讨论了如何执行此操作抱歉,但我不明白:如何使用Bitmap.createBitmap转换android.media.Image实例?我不是说图像资源…你是怎么得到媒体图像的?它应该有一个指向实际数据的uri。看看这里的答案。这是如何从图像对象中获取位图的方法。我将来自ImageReader的图像连接到MediaCodec。您应该在问题中明确指出,我不确定如何帮助您使用YUV,很抱歉。有一个代码正在浮动,用于将从MediaProjection
(Android 5.0+屏幕截图API)获取的图像转换为位图
,并考虑了步幅。不过,那些飞机只有一架。我假设对YUV图像
也有同样的方法。你能做到吗?这个答案中没有关于图像或图像视图的内容。我认为这个问题没有被理解。