gpt4 book ai didi

java - 从asynctask捕获android java相机

转载 作者:行者123 更新时间:2023-11-30 11:07:09 25 4
gpt4 key购买 nike

我正在尝试在异步任务中编写代码,该代码从相机拍摄照片并通过 UDP 将其发送到服务器 100 次。但是,不会调用 PictureCallback。有人可以帮帮我吗?

这是我尝试过的:

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)
{
}

最佳答案

我不认为AsyncTask是完成这项工作最方便的工具。

你需要一个SurfaceView那不是凭空创造出来的,而是连接到屏幕上的。你应该只初始化你的相机一次,你不能调用camera.takePicture()在一个循环中。您可以调用takePicture()来自 onPictureTaken()回调,但您还应该记住,您不能使用 UI 线程中的套接字。幸运的是,您可以遵循 Google 的建议。

the recommended way to access the camera is to open Camera on a separate thread.

Callbacks will be invoked on the event thread open(int) was called from.

如果在新的HandlerThread中开启camera,如图here ,图片回调将到达该背景线程,该线程也可用于联网。

此外,我建议您直接发送从相机接收到的 JPEG 缓冲区。我认为将图像保存到文件、将文件读取为位图并将后者压缩为另一个 JPEG 的开销可能太多了。要控制图像大小,choose appropriate picture size .注意尺寸应该从list of sizes supported by the specific camera中选择.

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");
}
}
}

上面的类是几个项目的汇编,为简洁起见,错误检查减少到最少。它可能需要一些修复才能编译。您只需添加 <CameraView />到您的 Activity 布局,并调用其 takePictures当用户点击按钮或其他东西时。

关于java - 从asynctask捕获android java相机,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29021629/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com