質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

Q&A

解決済

1回答

1382閲覧

socket通信での画像転送(android)

Mustard

総合スコア11

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

0グッド

1クリップ

投稿2019/05/04 12:44

編集2019/05/10 14:58

Wi-Fi Directを使いP2P通信で画像を転送するandroidアプリを作ろうとしています(android 7.0)。
WiFiDirectServiceDiscoveryを参考に接続の構築は実装できたのですが、接続完了後にソケットを通じて画像を送ると受信側には真っ黒の画像が表示されてしまいます。
現在はbitmapをbyte配列に変換した上でstreamに流し込み、受信側で再度bitmapに変換していますがreadやwriteの手順がおかしいのか正常な画像が転送できません。
以下に実装したコードを示します。問題点のご指摘および実装案の提示にご助力お願いいたします。

SendFragment

1 2public class WiFiChatFragment extends Fragment { 3--(略)-- 4 @Override 5 public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) { 6 --(略)-- 7 //ボタンのタッチでカメラから画像を取得・送信 8 view.findViewById(R.id.button1).setOnClickListener( 9 new View.OnClickListener() { 10 11 @Override 12 public void onClick(View arg0) { 13 Bitmap bmp = null; 14 try { 15 mCaptureSession.stopRepeating(); // プレビューの更新を止める 16 if(mTextureView.isAvailable()) { 17 bmp= mTextureView.getBitmap();//bitmapを取得 18 if(bmp != null && imgManager != null){ 19 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 20 bmp.compress(Bitmap.CompressFormat.JPEG, 100, baos);//bitmap -> byte(jpeg) 21 byte[] jpgarr = baos.toByteArray(); 22 StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder().permitAll().build()); 23 chatManager.write(jpgarr);//Streamへ流す 24 25 } 26 } 27 mTextureView.findViewById(R.id.myTextureView).setVisibility(View.GONE); 28 } catch (CameraAccessException e) { 29 e.printStackTrace(); 30 } 31 } 32 }); 33 return view; 34 } 35}

chatManager

1public class ChatManager implements Runnable{ 2 private Socket socket = null; 3 private Handler handler; 4 public ChatManager(Socket socket, Handler handler) { 5 this.socket = socket; 6 this.handler = handler; 7 } 8 private InputStream iStream; 9 private OutputStream oStream; 10 private static final String TAG = "ChatHandler"; 11 @Override 12 public void run() { 13 try { 14 iStream = socket.getInputStream(); 15 oStream = socket.getOutputStream(); 16 byte[] buffer = new byte[1024]; 17 int bytes; 18 while (true) { 19 try { 20 // Read from the InputStream 21 bytes = iStream.read(buffer); 22 if (bytes == -1) { 23 break; 24 } 25 // Send the obtained bytes to the UI Activity 26 handler.obtainMessage(WiFiServiceDiscoveryActivity.MESSAGE_READ,bytes, -1, buffer).sendToTarget(); 27 } catch (IOException e) { 28 Log.e(TAG, "disconnected", e); 29 } 30 } 31 } catch (IOException e) { 32 e.printStackTrace(); 33 } finally { 34 try { 35 socket.close(); 36 } catch (IOException e) { 37 e.printStackTrace(); 38 } 39 } 40 } 41 42 public void write(byte[] buffer) { 43 try { 44 oStream.write(buffer); 45 } catch (IOException e) { 46 Log.e(TAG, "Exception during write", e); 47 } 48 } 49}

Activity

1//取得した画像を表示 2 @Override 3 public boolean handleMessage(Message msg) { 4 switch (msg.what) { 5 case MESSAGE_READ: 6 byte[] readBuf = (byte[]) msg.obj; 7 Bitmap readImg = null; 8 readImg = BitmapFactory.decodeByteArray(readBuf, 0, readBuf.length);//byte -> bitmap 9 10 (sendFragment).pushMessage(readImg);//List<Bitmap>へデータをプッシュ 11 12 break; 13 14 case MY_HANDLE: 15 --(略)-- 16 } 17 return true; 18 }

試したこととして、sendFragment内でbitmapをbyte配列に変換後にstreamに流す代わりにその場でbyteからbitmapに戻し描画させたところ、正常な画像が表示されました。このことから通信以外の理由で画像データが壊れた可能性は低いと考えています。

sendFragmentTest

1 try { 2 mCaptureSession.stopRepeating(); // プレビューの更新を止める 3 if(mTextureView.isAvailable()) { 4 bmp= mTextureView.getBitmap();//bitmapを取得 5 if(bmp != null && imgManager != null){ 6 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 7 bmp.compress(Bitmap.CompressFormat.JPEG, 100, baos);//bitmap -> byte(jpeg) 8 byte[] jpgarr = baos.toByteArray(); 9 StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder().permitAll().build()); 10 //chatManager.write(jpgarr); 11 //再度byteからBitmapへ(この場合正しい画像が描画された) 12 Bitmap readImg = null; 13 readImg = BitmapFactory.decodeByteArray(jpgarr, 0, jpgarr.length);//byte -> bitmap 14 pushMessage(readImg);//List<Bitmap>へデータをプッシュ 15 } 16 }

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

jimbe

2019/05/04 18:16

受信側で, 送信したデータが全て受信されているか確認はされましたでしょうか?
Mustard

2019/05/05 03:42

jimbeさん、質問ありがとうございます。 送信側の変数jpgarrおよび受信側の変数readImgを確認したところ jpgarr={byte[1158931]@4672} 0=-1 1=-40 2=-1 3=-32 4=0 5=16 --(略)-- readImg={byte[1024]@4710} 0=25 1=-68 2=-23 3=-98 4=65 5=70 --(略)-- となっており、配列の大きさが全く異なっていました。 受信した黒画像も一枚ではなく複数枚受信していることもわかりましたので、buffer単位で分割されていまっていると考えています。 これらを一つの画像として受信する方法などご存知でしょうか。
guest

回答1

0

自己解決

obtainMessageの位置を画像データを全て受信した後に呼び出すことで解決いたしました。
下記のように変更したところ正しい画像が転送されました。
方針を決定づける質問をして頂いたjimbeさん本当にありがとうございました。

chatManager

1--(略)-- 2public void run() { 3 4 try { 5 6 iStream = socket.getInputStream(); 7 oStream = socket.getOutputStream(); 8 byte[] buffer = new byte[1024]; 9 int bytes; 10 11 ByteArrayOutputStream bospv = new ByteArrayOutputStream(); 12 copyFile(iStream,bospv); 13 pvbyte=bospv.toByteArray(); 14 handler.obtainMessage(WiFiServiceDiscoveryActivity.MESSAGE_READ,pvbyte).sendToTarget(); 15 16 } catch (IOException e) { 17 e.printStackTrace(); 18 } finally { 19 try { 20 socket.close(); 21 } catch (IOException e) { 22 e.printStackTrace(); 23 } 24 } 25 } 26--(略)--

copyFile

1public static boolean copyFile(InputStream inputStream, OutputStream out) { 2 byte buf[] = new byte[1024]; 3 int len; 4 try { 5 while ((len = inputStream.read(buf)) != -1) { 6 out.write(buf, 0, len); 7 } 8 out.close(); 9 inputStream.close(); 10 } catch (IOException e) { 11 return false; 12 } 13 return true; 14 }

投稿2019/05/05 05:22

Mustard

総合スコア11

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問