마스터Q&A 안드로이드는 안드로이드 개발자들의 질문과 답변을 위한 지식 커뮤니티 사이트입니다. 안드로이드펍에서 운영하고 있습니다. [사용법, 운영진]

바이트배열을 이미지 데이터를 imageview에 출력

0 추천
image view에 이미지를 띄우려고 하는데요 임베디드에서 전송하는 데이터는 이미지의 16byte 씩 문자열로 보내고, 문자열은 받은 스마트폰은 문자열을 나눠 정수로 변환 후 바이트로 바꾸어 buffer에 넣는 방식으로 하였구요 buffer의 사이즈는 8000000로 구성했습니다.

private void updataThread() {
 String[] temp132 = data.split(" ");

 if(temp132[0].equals("I")) {
  for(int imct=1; imct<=((temp132.length)-1); imct++){
   yyy = Integer.parseInt(temp132[imct]);
   output2.append("yyy : " + yyy);
   buffer[count10] = (byte) yyy;
   ++count10;
  }
 }
}

 

이 부분은 이미지를 출력하기 위해 버튼을 구성하였습니다.

그런데 이렇게 출력을 하면 SKImage::Decode Factory returned null 라는 오류 메세지가 발생하네요 ㅠㅠ

어디를 수정해야하죠? ㅜ

 

Button btn4 = (Button) findViewById(R.id.img);
btn4.setOnClickListener(new OnClickListener() {
 public void onClick(View v) {
  //byte[] buffer = stream.toByteArray();
  Log.w("size : ", String.valueOf(buffer.length));
  Bitmap bitmap = BitmapFactory.decodeByteArray(buffer, 0, buffer.length);
  image.setImageBitmap(bitmap);

 }
});

 

-------------- 수정, 추가 내용

제가 설명이 제대로 안드린것 같아요 ..

일단 문자열에 I는 이미지를 분류하려고 추가하였구요(이 부분은 다른 통신도 하기 위해서 헤더(?)를 주었습니다.) 핸드폰에서 실질적으로 받는 것은 I를 제외한 데이터를 변환하도록 하였는데 보시면 아시겠지만 %d로 구문하여 file에서 불러온 것을 정수로 표현한 데이터를 문자열로 보내기 때문에 받은 문자열을 정수로 바꾸고 바이트로 변경하였어요 ㅜㅜ
"I %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d \n" 이렇게 전송하였습니다

아래 코드는 임베디드에서 전송하는 부분입니다

 

       printf("file size [%d]\n", fsize);

        fsize2 = htonl(fsize);

        printf("file size [%d] \n", fsize2);

        fclose(camera);

 

        while(nsize != fsize){

                fpsize = fread(buf, 1, 16, file);

                nsize = nsize + fpsize;

                sprintf(str1, "I %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d \n", buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7], buf[8], buf[9], buf[10], buf[11], buf[12], buf[13], buf[14], buf[15]);

                fsize4 = strlen(str1);

                send(connSock[0], str1, fsize4, 0);

        }
라즈베리파이 (340 포인트) 님이 2016년 8월 1일 질문
라즈베리파이님이 2016년 8월 1일 수정

1개의 답변

0 추천

보내는 쪽 코드가 없긴 하지만 전체적으로 이상하네요.

우선 data.split(" "); 도 이상합니다. 보내는 쪽에서 base64로 인코딩해서 보냈으면 몰라도,

빈칸의 경우 아스키코드로 0x20인데, 이미지 데이터가 0x20일 떄와 구분이 불가능할 듯 합니다.

마찬가지로 "|" 문자 구분도 무의미 할 듯 하고요..

또한 16byte 씩 문자열로 보냈는데, int로 변환할 이유가 없을 듯 합니다.

전송 부분을 전부 다시 짜셔야 할 듯 합니다.

 

익명사용자 님이 2016년 8월 1일 답변
제가 설명이 제대로 안드린것 같아요 .. 죄송합니다. ㅠㅠ
-------------- 수정, 추가 내용 아래로 다시 설명을 하였는데요..

말씀해주신 부분은 제가 space 0x20을 %d 넣으면서 데시멀로 32 로 변환되고 이 상태에서 문자열에 space를 주기 때문에 문제가 없다고 생각했거든요 ㅠㅠ

space를 예로 들면
전송에서는 byte, 0x20 > int, 34 > string "34 "
수신에서는 string "34 "(공백으로 구분 " ") > string132[0] = 34 > int 34 > byte 0x20
이런식으로 변환하면 제가 대입한 공백은 구분이 가능하다고 판단하였습니다. ㅠ
적어주신 코드로 구현을 하셨으면, 이해는 가네요.

단지
strlen 로 길이를 구하셨는데, memset 등으로 str1 값을 초기화 한게 아니며,
매번 16개 버퍼 모두 값을 넣다보니,
파일 사이즈가 16의 배수가 아닐 경우에도  길이를 잘 못 인식해서  더미 데이터가 날아갈 듯 하네요.

또한  " \n" 도 맨뒤에 보내셨던데, 받는데서 이에 대한 처리를 제대로 안 한듯 합니다..

마지막으로 int로 변환하여 전송을 하셨는데,
꼭 String으로 받아야 하는 이유가 없다면,

전송단의 경우
while(nsize != fsize){

        fpsize = fread(buf, 1, 16, file);

        nsize = nsize + fpsize;

        send(connSock[0], buf, fpsize, 0);
}

만 하셔도 충분히  이미지 내용이 다 전송될 듯 하며,

받은코드가 안보입니다만.
불필요하게 String으로 변환하여 받아 다시 int로 변경하지 마시고,
받은 byte로 그대로 BitmapFactory에 적용하시는게 좋을 듯 합니다.

코드 자체가 파일 내용을 전부 보내는 방식인듯 한데,
받는데서 파일로 떨궈서,
원본과 비교 해 보시면서 구현하시는게 좋을 듯 합니다.
처음에 말씀해주신 아래와 같은 코드를 사용했었는데요.. 받는 부분이 String으로 받고 있어서 어떻게 해야할지 모르겠더라구요..ㅠㅠ
Base64를 사용하면 애플리케이션이 다운되고 해서 지금과 같이 사용했어요 ㅜ


while(nsize != fsize){

         fpsize = fread(buf, 1, 16, file);

         nsize = nsize + fpsize;

         send(connSock[0], buf, fpsize, 0);
 }


안드로이드(수신) 받는 쪽은 아래 코드와 같이 작성하였구요

수신되는 부분은 아래와 같이 String data로 받았습니다. 나머지는 본문에 스레드에서 처리했습니다

String data = "";

        final Thread mCheckRecv = new Thread(){
            public void run(){
                try {
                    while (true) {
                        data = socket_in.readLine();
                        Recv.sendEmptyMessage(0);
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        };

한번 바이트로 다시 변환하여 테스트 해보겠습니다!
근데 이 상태에서는 문자열로 하는 방법이 불가능할까요? ㅜㅜ
가능이야 하죠...  단지
쓸데 없는 코드가 추가되어 간단히 짠 것에 비해  문제가 발생할 가능성이 높고,
불필요한 연산으로 인한 퍼포먼스 이슈 및 데이터 전송 속도 및 패킷 소모로 인한 과금 문제,추후 유지보수에도 좋지 않으니,  원칙대로 구현하는게 좋다는 애기입니다.

비유를 들어 설명드리면  
1+1=2 로 계산되는 코드를 짜면 되는데 덧셈을 하는 방식을 구현 못 하셔서,
구현 법을 찾는 중  마이너스 값을 더하는 코드를 찾아서,
 마이너스 값을 더 한 후 마이너스를 곱하는    (((1 x -1) + (1 x -1)) x -1) = 2  로 계산하는 코드를 짜셨는데,
중간에 괄호가 같은게 잘 못 되어서 원하는 값이 나오지 않는다고,
어떻게 고치면 되는냐고 물으신거죠.^^;;

이번 경우는 byte를 바로 쓰면 되니. base64가 필요없지만
base64가 문제가 생겼으면, 문제가 생긴 원인을 찾아야하지..
문제가 있다고  안쓰면, 비슷한 상황이 발생해도 계속 못 씁니다.
이것저것 조합해서 이번만 통과하면 된다고 생각하시면,
개발자를 하지 않는다면 몰라도, 못 버티실 겁니다.

아무튼 String으로 읽는건  readLine 으로 읽으셔서 그렇습니다.
아래 코드를 참조하셔서 byte로 받아보세요.
http://stackoverflow.com/questions/9520911/java-sending-and-receiving-file-byte-over-sockets
헉, 그렇군요..
이전에 base64로 인코딩 해야한다고 하셨는데, 저는 아무것도 한게 없어서 한번 해보고 안되니까 바로 포기해버렸어요 ㅠㅠ
아무튼 무리수를 두고 구현하고 있었네요...
말씀해주신 것 참고해서 다시 구현해볼께요!
감사합니다! ^^
...