我正在尝试编写一个Android应用程序,通过相机将从第一台设备拍摄的图像流式传输到另一台使用WiFi Direct的设备。
我设法连接两个设备,并从手机图库交换图像,但我无法直接从相机交换图像。
开始编辑
要使用OpenCV模块获取相机帧,我的mainActivity扩展了CvCameraViewListener。
这应该是我得到我的框架的课程:
public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
appData.image_got++;
myInputFrame = inputFrame.rgba();
// if(myInputFrame != null){Log.e("on camera frame","input frame");}
timestampQ.push(System.currentTimeMillis());
byte[] img = Mat2Byte(myInputFrame);
return myInputFrame;
}
应将Mat转换为字节的类
public byte[] Mat2Byte(Mat img){
int total_bytes = img.cols() * img.rows() * img.channels();
byte[] return_byte = new byte[total_bytes];
img.get(0, 0, return_byte);
return return_byte;
}
编辑结束
这是应该发送获得的帧的代码:
Thread myThread = new Thread(){
@Override
public void run(){
while (appData.image_got <= 0) {
Log.d(TAG, "Waiting for image");
try {
Thread.sleep(1000);
}catch (Exception e){
e.printStackTrace();
}
}
int image_got_local = -1;
mOpenCvCameraView.turnFlashOn();
mOpenCvCameraView.setFrameRate(30000, 30000); //We are trying to get 30FPS constant rate
while(keep_thread_running & !myThread.isInterrupted()){
//We will wait till a new frame is received
while(image_got_local == appData.image_got){
//Sleeping part may lead to timing problems
try {
Thread.sleep(11);
}catch (Exception e){
e.printStackTrace();
}
}
appData.frameSz = myInputFrame.size();
ArrayList<Mat> img_comp = new ArrayList<Mat>(3);
Core.split(myInputFrame, img_comp);
if(myInputFrame == null) {Log.e("main thread","input frame is null");}
//Get the red component of the image
Mat myMat = img_comp.get(0);
byte[] byte_img = Mat2Byte(myMat);
if(byte_img == null)Log.e("main thread","byte_img is null");
conta = conta +1;
try
{
if (byte_img !=null){
Socket socket = new Socket();
int port = 8988;
try
{
socket.bind(null);
socket.connect((new InetSocketAddress(OwnerIp, port)));
OutputStream stream = socket.getOutputStream();
InputStream is = null;
try
{
is = new ByteArrayInputStream(byte_img);
Log.e("main thread","input stream not null: " + is.toString());
}
catch (Exception e){Log.e("main thread","byte array input stream " +
"exception: " + e.getMessage());}
DeviceDetailFragment.copyFile(is, stream);
Log.d("main thread", "Client: Data written");
}
catch (Exception e){Log.e("main thread","connect or bind exception: "
+ e.getMessage());}
finally {
if (socket != null) {
if (socket.isConnected()) {
try {
socket.close();
} catch (IOException e) {
// Give up
Log.e("file transfer service","exception socket close: " +
e.getMessage());
}
}
}
}
}
}
catch(Exception e ){Log.e("main thread","exception: " + e.getMessage());}
appData.frameAv = getMatAvg(myMat);
//We cannot access UI objects from background threads, hence need to pass this data to UI thread
Message uiMessage = mHandler.obtainMessage(1,appData);
uiMessage.sendToTarget();
handleInputData(appData.frameAv);
image_got_local = appData.image_got;
}
}
};
这是代码,在应该读取所获得的帧的另一个应用程序上:
public class FileServerAsyncTask extends AsyncTask<String, String, String> {
private Context mFilecontext;
private String Extension, Key;
private File EncryptedFile;
private long ReceivedFileLength;
private int PORT;
public FileServerAsyncTask(Context context, int port) {
this.mFilecontext = context;
handler = new Handler();
this.PORT = port;
}
@Override
protected String doInBackground(String... params) {
try {
ServerSocket serverSocket = new ServerSocket(8988);
Log.d(WiFiDirectActivity.TAG, "Server: Socket opened");
Socket client = serverSocket.accept();
Log.d(WiFiDirectActivity.TAG, "Server: connection done");
final File f = new File(Environment.getExternalStorageDirectory() + "/"
+ getContext().getPackageName() + "/wifip2pshared-" + System.currentTimeMillis()
+ ".jpg");
File dirs = new File(f.getParent());
if (!dirs.exists())
dirs.mkdirs();
f.createNewFile();
Log.d(WiFiDirectActivity.TAG, "server: copying files " + f.toString());
InputStream inputstream = client.getInputStream();
Message msg = Message.obtain();
msg.what = 1;
try
{
// send the images to the image view through handler
Bitmap bitmap = BitmapFactory.decodeStream(inputstream);
if(bitmap!=null) {
Bundle b = new Bundle();
b.putParcelable("bitmap", bitmap);
msg.setData(b);
messageHandler.sendMessage(msg);
}
else Log.e("dev deta fragm","bitmap is null");
}
catch (Exception e)
{
Log.e("device detail fragment","stream not decoded into bitmap with" +
"exception: " + e.toString());
}
copyFile(inputstream, new FileOutputStream(f));
serverSocket.close();
return f.getAbsolutePath();
} catch (IOException e) {
Log.e(WiFiDirectActivity.TAG, e.getMessage());
return null;
}
}
@Override
protected void onPostExecute(String result) {
if (result!=null) {
/**
* To initiate socket again we are initiating async task
* in this condition.
*/
FileServerAsyncTask FileServerobj = new FileServerAsyncTask(getContext(),
FileTransferService.PORT);
Log.e("on post execute", "file server obj: " + FileServerobj.toString());
if (FileServerobj != null) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
FileServerobj.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, new String[]{null});
Log.e("Post Execute", "FileServerobj.execute on executor");
} else
{
FileServerobj.execute();
Log.e("Post Execute", "FileServerobj.execute");
}
}
}
}
@Override
protected void onPreExecute() {
if(imageView == null){
imageView = new ImageView(mFilecontext);
}
}
}
我对自己做错了什么的想法?我认为问题在于我发送帧的字节表示然后是:
Bitmap bitmap = BitmapFactory.decodeStream(inputstream);
不会以合适的图像转换它。
如果我以正确的方式发布问题,请与我们联系。
答案 0 :(得分:1)
int total_bytes = img.cols() * img.rows()
如果它有像素的cols和row,并且你可以单独获取每个像素,你可以设置一个Bitmap并填充它的像素。
然后将位图压缩为ByteArrayOutputStream为jpg或png并转换为字节数组。
像现在一样发送字节数组。
答案 1 :(得分:0)
将Mat帧转换为png我设法在设备之间流式传输图像。我发布了更正的代码(如果我不应该告诉我,我将删除它)。
Thread myThread = new Thread(){
@Override
public void run(){
while (appData.image_got <= 0) {
Log.d(TAG, "Waiting for image");
try {
Thread.sleep(1000);
}catch (Exception e){
e.printStackTrace();
}
}
int image_got_local = -1;
mOpenCvCameraView.turnFlashOn();
mOpenCvCameraView.setFrameRate(30000, 30000); //We are trying to get 30FPS constant rate
while(keep_thread_running & !myThread.isInterrupted()){
//We will wait till a new frame is received
while(image_got_local == appData.image_got){
//Sleeping part may lead to timing problems
try {
Thread.sleep(11);
}catch (Exception e){
e.printStackTrace();
}
}
appData.frameSz = myInputFrame.size();
ArrayList<Mat> img_comp = new ArrayList<Mat>(3);
Core.split(myInputFrame, img_comp);
if(myInputFrame == null) {Log.e("main thread","input frame is null");}
//Get the red component of the image
Mat myMat = img_comp.get(0);
/******************************************************************************/
Bitmap bmp = null;
try {
bmp = Bitmap.createBitmap(myMat.cols(), myMat.rows(), Bitmap.Config.ARGB_8888);
org.opencv.android.Utils.matToBitmap(myMat,bmp);
} catch (Exception e) {
Log.e(TAG, e.getMessage());
}
myMat.release();
FileOutputStream out = null;
String filename = "frame" + conta + ".png";
conta = conta +1;
File sd = new File(Environment.getExternalStorageDirectory() + "/frames");
boolean success = true;
if (!sd.exists()) {
success = sd.mkdir();
}
if (success) {
File dest = new File(sd, filename);
try {
out = new FileOutputStream(dest);
Log.e("main thread","file written: " + out.toString());
bmp.compress(Bitmap.CompressFormat.PNG, 100, out); // bmp is your Bitmap instance
// PNG is a lossless format, the compression factor (100) is ignored
try
{
if (dest !=null){
Socket socket = new Socket();
int port = 8988;
try
{
socket.bind(null);
socket.connect((new InetSocketAddress(OwnerIp, port)));
OutputStream stream = socket.getOutputStream();
InputStream is = null;
try
{
{
if(dest!=null) {
is = new FileInputStream(dest);
Log.e("main thread", "input stream not null: " + is.toString());
}
}
}
catch (Exception e){Log.e("main thread", "exception: "+ e.getMessage());}
DeviceDetailFragment.copyFile(is, stream);
Log.d("main thread", "Client: Data written");
}
catch (Exception e){Log.e("main thread","connect or bind exception: "
+ e.getMessage());}
finally {
if (socket != null) {
if (socket.isConnected()) {
try {
socket.close();
} catch (IOException e) {
// Give up
Log.e("file transfer service","exception socket close: " +
e.getMessage());
}
}
}
}
}
}
catch(Exception e ){Log.e("main thread","exception: " + e.getMessage());}
} catch (Exception e) {
e.printStackTrace();
Log.e(TAG, e.getMessage());
} finally {
try {
if (out != null) {
out.close();
Log.e(TAG, "OK!!");
}
} catch (IOException e) {
Log.e(TAG, e.getMessage() + "Error");
e.printStackTrace();
}
}
}
else {
Log.e("main thread","file dest is null");
}
/****************************************************************************/
appData.frameAv = getMatAvg(myMat);
//We cannot access UI objects from background threads, hence need to pass this data to UI thread
Message uiMessage = mHandler.obtainMessage(1,appData);
uiMessage.sendToTarget();
handleInputData(appData.frameAv);
image_got_local = appData.image_got;
}
}
};
再次感谢greenapps。