从asynctask捕获android java摄像头
我正在尝试在一个异步任务中执行一个代码,该任务从相机拍摄一张照片,并通过UDP将其发送到服务器100次。但是,PictureCallback没有被调用。有人能帮我吗 这就是我所尝试的:从asynctask捕获android java摄像头,java,android,sockets,camera,udp,Java,Android,Sockets,Camera,Udp,我正在尝试在一个异步任务中执行一个代码,该任务从相机拍摄一张照片,并通过UDP将其发送到服务器100次。但是,PictureCallback没有被调用。有人能帮我吗 这就是我所尝试的: public class MainAsyncTask extends AsyncTask<Void, String, Void> { protected static final String TAG = null; public MainActivity mainAct; public Main
public class MainAsyncTask extends AsyncTask<Void, String, Void> {
protected static final String TAG = null;
public MainActivity mainAct;
public MainAsyncTask(MainActivity mainActivity)
{
super();
this.mainAct = mainActivity;
}
@Override
protected Void doInBackground(Void... params) {
DatagramSocket clientSocket = null;
InetAddress IPAddress = null;
try {
clientSocket = new DatagramSocket();
IPAddress = InetAddress.getByName("192.168.1.15");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
byte [] data;
DatagramPacket sendPacket;
try {
for (int i=0; i < 100; i++)
{
publishProgress("");
File file = new File(Environment.getExternalStorageDirectory()+ File.separator +"img.jpg");
while (!file.exists() || file.length() == 0);
Bitmap screen = BitmapFactory.decodeFile(Environment.getExternalStorageDirectory()+ File.separator +"img.jpg");
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
screen.compress(Bitmap.CompressFormat.JPEG, 15, bytes);
data = bytes.toByteArray();
sendPacket = new DatagramPacket(data, data.length, IPAddress, 3107);
clientSocket.send(sendPacket);
file.delete();
}
clientSocket.close();
} catch (Exception e) {
// TODO Auto-generated catch block
publishProgress(e.getMessage());
}
return null;
}
public static void takeSnapShots(MainActivity mainAct)
{
PictureCallback jpegCallback = new PictureCallback() {
public void onPictureTaken(byte[] data, Camera camera)
{
FileOutputStream outStream = null;
try {
outStream = new FileOutputStream(Environment.getExternalStorageDirectory()+File.separator+"img"+".jpg");
outStream.write(data);
outStream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally
{
camera.stopPreview();
camera.release();
camera = null;
}
Log.d(TAG, "onPictureTaken - jpeg");
}
};
SurfaceView surface = new SurfaceView(mainAct.getApplicationContext());
Camera camera = Camera.open();
try {
camera.setPreviewDisplay(surface.getHolder());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
camera.startPreview();
camera.takePicture(null,null,jpegCallback);
}
protected void onProgressUpdate(String... progress) {
takeSnapShots(mainAct);
}
@Override
protected void onPostExecute(Void result)
{
}
公共类MainAsyncTask扩展了AsyncTask{
受保护的静态最终字符串标记=null;
公共活动法;
公共MainAsyncTask(MainActivity MainActivity)
{
超级();
this.mainAct=mainActivity;
}
@凌驾
受保护的Void doInBackground(Void…参数){
DatagramSocket clientSocket=null;
InetAddress IPAddress=null;
试一试{
clientSocket=newdatagramsocket();
IPAddress=InetAddress.getByName(“192.168.1.15”);
}捕获(例外e){
//TODO自动生成的捕捉块
e、 printStackTrace();
}
字节[]数据;
数据包发送包;
试一试{
对于(int i=0;i<100;i++)
{
出版进度(“”);
File File=新文件(Environment.getExternalStorageDirectory()+File.separator+“img.jpg”);
而(!file.exists()| | file.length()==0);
位图屏幕=位图工厂.decodeFile(Environment.getExternalStorageDirectory()+File.separator+“img.jpg”);
ByteArrayOutputStream字节=新建ByteArrayOutputStream();
screen.compress(位图.CompressFormat.JPEG,15,字节);
数据=字节。toByteArray();
sendPacket=新数据包(data,data.length,IPAddress,3107);
clientSocket.send(sendPacket);
delete();
}
clientSocket.close();
}捕获(例外e){
//TODO自动生成的捕捉块
发布进度(如getMessage());
}
返回null;
}
公共静态无效快照(MainActivity mainAct)
{
PictureCallback jpegCallback=新建PictureCallback(){
公共void onPictureTaken(字节[]数据,摄像头)
{
FileOutputStream扩展流=null;
试一试{
outStream=新文件OutputStream(Environment.getExternalStorageDirectory()+File.separator+“img”+“.jpg”);
外扩。写入(数据);
exptream.close();
}catch(filenotfounde异常){
e、 printStackTrace();
}捕获(IOE异常){
e、 printStackTrace();
}最后
{
camera.stopPreview();
相机。释放();
摄像机=零;
}
Log.d(标签“onPictureTaken-jpeg”);
}
};
SurfaceView surface=新的SurfaceView(mainAct.getApplicationContext());
Camera=Camera.open();
试一试{
camera.setPreviewDisplay(surface.getHolder());
}捕获(IOE异常){
//TODO自动生成的捕捉块
e、 printStackTrace();
}
camera.startPreview();
拍照(空、空、JPEG);
}
受保护的void onProgressUpdate(字符串…进度){
takeSnapShots(mainAct);
}
@凌驾
受保护的void onPostExecute(void结果)
{
}
}您是否像这样调用异步任务?仅仅创建AsyncTask是不够的
new MainAsyncTask(ActivityContext).execute();
你不能这么做
camera.setPreviewDisplay(surface.getHolder());
从文档中:
调用此方法时,SurfaceHolder必须已经包含曲面。如果使用SurfaceView,则需要使用addCallback(SurfaceHolder.Callback)注册SurfaceHolder.Callback,并在调用setPreviewDisplay()或启动预览之前等待surfaceCreated(SurfaceHolder)
你必须这样做:
SurfaceHolder surfaceHolder = surface.getHolder();
surfaceHolder.addCallback(new Callback() {
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {}
@Override
public void surfaceCreated(SurfaceHolder holder) {
try {
camera.setPreviewDisplay(holder);
camera.startPreview();
camera.takePicture(null,null,jpegCallback);
} catch (IOException e) {
}
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {}
}
);
我不认为
AsyncTask
是做这项工作最方便的工具
您需要一个SurfaceView
,它不是凭空创建的,而是连接到屏幕上的。您应该只初始化相机一次,并且不能在循环中调用camera.takePicture()
。您可以从onPictureTaken()
回调调用takePicture()
,但还应该记住,您不能从UI线程使用套接字。幸运的是,你可以遵循谷歌的建议
及
如图所示,如果在新HandlerThread中打开camera,图片回调将到达beckground线程,该线程也可用于联网
此外,我建议您直接发送从相机接收的JPEG缓冲区。我认为将图像保存到文件、将文件读取到位图以及将位图压缩到另一个JPEG的开销可能太大了。要控制图像大小。请注意,应从中选择尺寸
上面的类是从几个项目编译而来的,为了简洁起见,错误检查减少到最小。它可能需要一些修复来编译。您只需将一个
添加到您的活动布局中,并在用户单击按钮或其他东西时调用它的拍摄图片。是的,那么我需要做什么?
public class CameraView extends SurfaceView
implements SurfaceHolder.Callback, Camera.PictureCallback {
private static final String TAG = "CameraView";
private Camera camera;
private HandlerThread cameraThread;
private Handler handler;
private boolean bCameraInitialized = false;
private int picturesToTake = 0;
public CameraView(Context context, AttributeSet attr) {
super(context, attr);
// install a SurfaceHolder.Callback so we get notified when the
// underlying surface is created and destroyed.
getHolder().addCallback(this);
}
@Override public void surfaceCreated(SurfaceHolder holder) {
cameraThread = new HandlerThread("CameraHandlerThread");
cameraThread.start();
handler = new Handler(cameraThread.getLooper());
hanlder.post(new Runnable() {
@Override public void run() {
openRearCamera();
bCameraInitialized = false;
}
});
}
@Override public void surfaceDestroyed(SurfaceHolder holder) {
if (camera != null) {
Log.d(TAG, "Camera release");
camera.release();
camera = null;
bCameraInitialized = false;
}
}
// finalize the camera init now that we know preview size
@Override public void surfaceChanged(SurfaceHolder holder, int format, final int w, final int h) {
Log.w(TAG, "surfaceChanged(" + w + ", " + h + ")");
if (!bCameraInitialized) {
cameraSetup(w, h);
bCameraInitialized = true;
}
}
private void openRearCamera() {
if (camera != null) {
Log.e(TAG, "openRearCamera(): camera is not null");
return;
}
try {
camera = Camera.open(0);
Log.d(TAG, "Camera ready " + String.valueOf(camera));
}
catch (Throwable e) {
Log.e(TAG, "openRearCamera(): Camera.open() failed", e);
}
}
private void cameraSetup(int w, int h) {
if (camera == null) {
Log.e(TAG, "cameraSetup(): camera is null");
return;
}
Log.d(TAG, "Camera setup");
try {
Camera.Parameters params = camera.getParameters();
// still picture settings - be close to preview size
Camera.Size pictureSize = params.getSupportedPictureSizes()[0];
params.setPictureSize(pictureSize.width, optimalPictureSize.height);
camera.setParameters(params);
camera.setPreviewDisplay(getHolder());
camera.startPreview();
}
catch (Throwable e) {
Log.e(TAG, "Failed to finalize camera setup", e);
}
}
private void sendJpeg(byte[] data) {
DatagramSocket clientSocket = null;
InetAddress IPAddress = null;
try {
clientSocket = new DatagramSocket();
IPAddress = InetAddress.getByName("192.168.1.15");
}
catch (Exception e) {
Log.e(TAG, "failed to initialize client socket", e);
}
DatagramPacket sendPacket;
sendPacket = new DatagramPacket(data, data.length, IPAddress, 3107);
clientSocket.send(sendPacket);
Log.d(TAG, "sent image");
}
@Override public void onPictureTaken(byte[] data, Camera camera) {
sendJpeg(data);
camera.startPreview();
takePictures(picturesToTake-1);
}
public void takePictures(int n) {
if (n > 0) {
picturesToTake = n;
Log.d(TAG, "take " + n + " images");
camera.takePicture(null, null, this);
}
else {
Log.d(TAG, "all images captured");
}
}
}