我正在尝试编写一个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转换为Bytes的类
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);
无法将其转换成正确的图像。
任何帮助将不胜感激,让我知道,如果我张贴的问题以适当的方式。
2条答案
按热度按时间r3i60tvu1#
如果它有像素的列和行,你可以单独抓取每个像素,你可以设置一个位图并填充它的像素。
然后将位图压缩为jpg或png格式的ByteArrayOutputStream,并转换为字节数组。
像现在一样发送字节数组。
am46iovg2#
将Mat帧转换为PNG,我设法在设备之间传输图像。我张贴更正的代码(如果我不应该这样做,告诉我,我要删除它)。
再次感谢greenapps。