2011-12-27 2 views
2

내가 현재 할하려고하는 것은 다음Base64 인코딩 및

사진 촬영, PNG, 비밀 사용 Base64로로 압축하고 PHP를 통해 데이터베이스로 전송. 그것 모두는 매력처럼 작동합니다. 또한 Base64 문자열을 디코딩하여 사진을 완벽하게 표시 할 수 있습니다.

그러나 문제는 브라우저에서 사진을 볼 때 크기가 같지 않거나 최소한 생각해야한다는 것입니다.

내가 브라우저에서 인코딩 및 표시 찍은 이미지입니다 :에 관계없이 전화, (또한 갤럭시 SII 테스트)의 enter image description here

, 문제는 여전히 남아있다. 너 무슨 일이 일어날 지 아무 생각 없어? 여기 내가 가지고 있지만 확실하지 않은 몇 가지 아이디어가 있습니다 ... 1. 이미지를 너무 많이 압축하거나 압축하면 무언가가 바뀝니다 2.Base64 인코딩/디코딩은 사진을 엉망으로 만들고 올바르게 표시하지 않습니다. 3. 장소 이미지보기의 이미지는 크기를 수정합니다.

다시 전체 이미지가 전송되지 않는 것처럼 보입니다. 갤럭시 sII 이미지조차도 이미지가 작아 보이지 않기 때문입니다. 안드로이드

// CONVERT: 
     ByteArrayOutputStream bao = new ByteArrayOutputStream(); 
     picture.compress(Bitmap.CompressFormat.PNG, 100, bao); 
     Log.d(TAG, "AFTER. Height: " + picture.getHeight() + " Width: " + picture.getWidth()); 
     final byte[] ba = bao.toByteArray(); 

     //encode to string 
     String photoTest = Base64.encodeToString(ba, Base64.DEFAULT); 

//Camera on activity for result - save it as a bmp and place in imageview 
    protected void onActivityResult(int requestCode, int resultCode, Intent data) { 
     if (requestCode == CAMERA_PIC_REQUEST) { 
      // do something 
     } 

     if (resultCode == Activity.RESULT_OK) { 
      Log.d(TAG, "result ok"); 

      Bundle b = data.getExtras(); 
      picture = (Bitmap) b.get("data"); 
      imageView.setImageBitmap(picture); 
     } 
    } 

이미지보기 : 안드로이드 :

여기 내가 사용하고 코드입니다

<ImageView 
     android:id="@+id/imageView1" 
     android:layout_width="100dp" 
     android:layout_height="100dp" 
     android:src="@drawable/icon"/> 

PHP :

$image = base64_decode($_POST['image_data']); 

여러분의 도움에 감사드립니다!

+1

이 함께 할 수있는 아무것도 아니다 Base64 및 이미지 변환 방법에 관한 모든 것. 이미지를 디코딩 할 때 이미지가 너무 작 으면 이미지를 인코딩 할 때 너무 작습니다. Base64는 바이너리 데이터를 ASCII 형식으로 저장합니다. 데이터가 디코딩 될 때 정확히 동일합니다. 잘못 나온 경우 시작했을 때 잘못되었습니다. – DaveRandom

+0

답장을 보내 주셔서 감사합니다.당신이 올바르게 쓴 것을 이해한다면, 인코딩으로 넘어갈 때 이미지 크기가 원본이 아니라는 것이 문제입니다. 그래서 내 다음 질문은 이미지의 진정한 크기를 얻을 수있는 방법이 될 것입니다. – Splitusa

+1

@ Campadrenaline의 답변이 올바른 방향으로 가고 있다고 생각합니다. 이미지를 변환하는 'picture.compress()'라고 생각합니다. 이것이 이미지가 압축 된 방법의 관점에서 사용되는 경향이 있기 때문에 이것은 염두에두고 "품질"에 관한 것이 아닙니다. 문제는 클라이언트 측 코드의 어느 지점에서 이미지의 크기를 조정하거나 "다시 샘플링"하는 것입니다. 압축 코드를 꺼내고 압축 풀기없이 작동 시키려면 압축을 풀고 재생을 시작해야합니다. – DaveRandom

답변

1

어떻게 해결 했습니까? 위에서 설명한 것처럼 사진을 저장할 때 전체 크기의 사진이 아닌 사진의 축소판 버전 만 반환한다는 것을 알 수 있습니다. 내 의도에 EXTRA_OUTPUT을 추가하고 SD 카드에 저장 한 다음 압축해야했습니다. 비슷한 문제가있는 분은 저에게 메시지를 보내주십시오.

+0

비슷한 문제가 발생했는데 해결책이 무엇을 의미하는지 이해하지 못합니다. – Andrew

1

Base64는 바이너리 데이터를 그대로 유지하며 크기 조절 특수 효과를 수행하지 않습니다. 나는 문제가되는 라인이 picture.compress(Bitmap.CompressFormat.PNG, 100, bao);이라고 추측하고있다. 그러나 이것은 정말로 나의 분야가 아니다.

+0

답장을 보내 주셔서 감사합니다. 내가 틀렸다면 정정하십시오. 그러나 PNG는 압축의 품질 측면을 무시하므로 100-0의 값은 중요하지 않습니다. Im 확실하지 tho – Splitusa

+0

PNG는 품질 AFAIK를 무시하지 않습니다. 내 이해는 품질 변수에 기반한 무손실 알고리즘의 여러 패스를 실행한다는 것입니다 (실제로 품질의 절충이 아니라 크기에 대한 인코딩/디코드 시간). 지금 나는 그렇게 확신하지 못한다. 그럼에도 불구하고 문제가있는 이미지 전처리 파이프 라인에 분명히 있습니다. 일단 Base64에 들어가면 기본적으로 해독 될 때까지 그런 종류의 절단으로부터 안전합니다. – Campadrenalin

0

나는이 문제가 어떻게 내 문제를 해결했는지,이 방법은 기본 카메라 응용 프로그램을 열고 이미지를 임시 폴더에 저장하고 Base64/ByteArray로 변환합니다.

1 - 카메라 응용 프로그램

// My ImageButton click Listener 
ibt_foto.setOnClickListener(new View.OnClickListener() { 
    @Override 
    public void onClick(View v) { 

     String tempDir = Environment.getExternalStorageDirectory() + "/folder/"; 
     String path = Environment.getExternalStorageDirectory() + "/folder/photo1.jpg"; 
     prepareDirectory(); 
     File file = new File(path); 
     Uri outputFileUri = Uri.fromFile(file); 
     Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE); 
     intent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri); 
     startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE); 
    } 
}); 

2 열 리스너를 클릭 - 폴더를 생성에게

private boolean prepareDirectory() { 
    try { 
     if (makedirs()) { 
      return true; 
     } else { 
      return false; 
     } 
    } catch (Exception e) { 
     e.printStackTrace(); 
     Toast.makeText(this, "Could not initiate File System.. Is Sdcard mounted properly?", Toast.LENGTH_LONG).show(); 
     return false; 
    } 
} 

private boolean makedirs() { 

    File tempdir = new File(tempDir); 
    if (!tempdir.exists()) { 
     tempdir.mkdirs(); 
    } 

    /* 
    // Use this if you want to delete older files 
    if (tempdir.isDirectory()) { 
     File[] files = tempdir.listFiles(); 
     for (File file : files) { 
      if (!file.delete()) { 
       System.out.println("Failed to delete " + file); 
      } 
     } 
    } 
    */ 

    return (tempdir.isDirectory()); 
} 

3 - 카메라 응용 프로그램에서 결과를 처리

protected void onActivityResult(int requestCode, int resultCode, Intent data) { 

    System.gc(); 

    if (requestCode == CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE) { 
     if (resultCode == RESULT_OK) { 
      try { 

       // Get image 
       BitmapFactory.Options options = new BitmapFactory.Options(); 
       options.inSampleSize = 3; 
       Bitmap imageBitmap = BitmapFactory.decodeFile(path, options); 

       // Converting to ByteArray and Base64 
       ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); 
       boolean validaCompressao = imageBitmap.compress(Bitmap.CompressFormat.JPEG, 75, outputStream); 
       byte[] fotoBinario = outputStream.toByteArray(); 

       String encodedImage = Base64.encodeToString(fotoBinario, Base64.DEFAULT); 

       // setting image to my ImageButton 
       ibt_foto.setImageBitmap(imageBitmap); 

      } catch (Exception e) { 
       Toast.makeText(this, "Picture Not taken",Toast.LENGTH_LONG).show();e.printStackTrace(); 
      } 
     } else if (resultCode == RESULT_CANCELED) { 
      Toast.makeText(this, "Picture was not taken 1 ", Toast.LENGTH_SHORT); 
     } else { 
      Toast.makeText(this, "Picture was not taken 2 ", Toast.LENGTH_SHORT); 
     } 
    } 
} 
관련 문제