2013-03-15 2 views
0

갤러리에서 하나의 이미지를 선택하거나 사진을 찍어 다른 데이터와 함께 웹 사이트에 업로드 할 수있는 활동입니다.사진 업로드 관련 문제

지금까지 내가 만난이 다른 문제 : 나는 갤러리에서 사진과 함께 그것을 시도 할 경우

1), 나는 메시지와 함께 IOException를 얻을 /외부/이미지/미디어/2305 : 열려 실패 : ENOENT (해당 파일 또는 디렉토리 없음) 파일 스트림을 열 때 발생합니다. 내가 사진을 촬영하여 시도 할 경우

2), 괜찮아요 간다,하지만 인코딩 된 데이터 문자열은 정말 이상 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"(하지만 A의)로 구성되고, 그게 좋은 징조하지 같아요. 이것은 웹 사이트에 제대로 업로드 할 수 없기 때문에 추측 일 뿐이지 만 동일한 데이터 문자열을 보여주는 여러 그림이 우스운 냄새를 풍깁니다.

여기

@Override 

public void onActivityResult(int requestCode, int resultCode, Intent data) { 
    super.onActivityResult(requestCode, resultCode, data); 
    switch (requestCode) { 
    case TAKE_PICTURE: 
     if (resultCode == Activity.RESULT_OK) { 
      //Uri selectedImage = imageUri; 
      loadImage(imageUri); 

    } 
    break; 
case SELECT_PHOTO: 
    if(resultCode == Activity.RESULT_OK){ 
     imageUri = data.getData(); 
     loadImage(imageUri); 
    } 
} 
} 

코드는 이것은 내가 이미지 (촬영 그림 또는 갤러리에서 하나)를 이미지 뷰 위에로드 방법이다. 괜찮아.

public void loadImage(Uri selectedImage){ 
    mActivity.getContentResolver().notifyChange(selectedImage, null); 

    ContentResolver cr = mActivity.getContentResolver(); 
    Bitmap bitmap; 
    try { 
     bitmap = android.provider.MediaStore.Images.Media 
       .getBitmap(cr, selectedImage); 

     ivPicture.setImageBitmap(bitmap); 
     ivPicture.setVisibility(View.VISIBLE); 
     mActivity.croutonInfo(selectedImage.toString()); 

    } catch (Exception e) { 
     mActivity.croutonAlert("Failed to load"); 
     e("Camera " + e.toString()); 
    } 
} 

이것은 데이터 업로드를 모의하는 데 사용하는 방법입니다. 내가 API를 얻을 때 지금까지 그것은 단지 logicless 전송 객체

public void uploadTapa() throws IOException{ 
    mActivity.croutonInfo("subiendo tapa "); 
    d("uploadTapa new "); 
    TapaUploadParametros tup = new TapaUploadParametros(); 
    d("uploadTapa bar: " + nombreBar); 
    tup.setBarNombre(etBarName.getText().toString()); 
    d("uploadTapa tapa: " + nombreTapa); 
    tup.setNombre(etTapaName.getText().toString()); 
    d("uploadTapa municipio: " + municipio); 
    tup.setLocalidad(municipio); 
    d("uploadTapa provincia: " + provincia); 
    tup.setProvincia(provincia); 
    d("uploadTapa tipologiaId: " + tipologiaId); 
    tup.setTipo(tipologiaId); 
    d("uploadTapa precioId: " + precioId); 
    tup.setPrecio(precioId); 

    String encodedImage = encodeImgForHTTP(imageUri); 
    d("uploadTapa encoded image: " + encodedImage); 
    tup.setPic(encodedImage); 
    d("uploadTapa direccionBar: " + direccionBar); 
    tup.setBarDireccion(direccionBar); 
} 

에 데이터를 넣습니다 그리고 이것은 HTTP 전송을위한 이미지를 인코딩 할 수있는 방법은 HTTP 전송을 처리 할 수있는 AsyncTask를이있을 것이다. 갤러리의 이미지가 '스트림을 열기 전'에 만료됩니다.

private String encodeImgForHTTP (Uri imageUri) throws IOException{ 
     ContentResolver cr = mActivity.getContentResolver(); 
     d("encodeImgForHTTP before opening stream "); 
     FileInputStream fis = new FileInputStream(imageUri.getPath()); 
     d("encodeImgForHTTP after opening stream "); 
     // Get binary bytes for encode 
     byte[] imageBytes = new byte[fis.available()]; 
     d("encodeImgForHTTP after getting byte array "); 
     // base 64 encode for text transmission (HTTP) 
     d("encodeImgForHTTP pre 64: " + imageBytes); 
     String data_string = Base64.encodeToString(imageBytes, Base64.URL_SAFE); 
     d("encodeImgForHTTP before returning the encoded data string " + data_string); 
     return data_string; 
    } 

갤러리 이미지에 어떤 오류가 있습니까? 다른 그림의 인코딩이 왜 똑같은가요?

답변

0

을 나는 결국에있어 추측 작업. 먼저 Emil의 조언을 사용하여 이미지를 저장했습니다. DCIM_PATH는 DCIM 폴더의 경로입니다.

public void takePhoto() { 
    String directoryPath = DCIM_PATH; 
    d("takePhoto directoryPath: " + directoryPath); 
    this.pictureFileName = Long.toHexString(System.currentTimeMillis())+".jpg"; 
    String filePath = directoryPath + pictureFileName ; 
    File directory = new File(directoryPath); 
    if (!directory.exists()) { // in case there's no DCIM folder 
     directory.mkdirs(); // just create it 
    } 
    d("takePhoto filePath: " + filePath); 
    this.imageUri = Uri.parse(filePath); 
    d("takePhoto imageUri: " + filePath); 
    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); 
      // here's where I tell the intent where to save the file 
    intent.putExtra( 
      MediaStore.EXTRA_OUTPUT,Uri.fromFile(new File(filePath)) 
      ); 

    startActivityForResult(intent, TAKE_PICTURE); 

} 

이미지 뷰로 두 개의 다른 방법을 사용해야했습니다. 그냥 찍은 사진의 경우, 내가 사용이 하나

public void loadImageJustTaken(Uri selectedImage) { 
    mActivity.getContentResolver().notifyChange(selectedImage, null); 

    Bitmap bitmap = 
      BitmapFactory.decodeFile(imageUri.getPath()); 

    ivPicture.setImageBitmap(bitmap); 
    ivPicture.setVisibility(View.VISIBLE); 
} 

하지만 내가해야 내가 이미지를 업로드 할 때 컨텐트 리졸버

public void loadImage(Uri selectedImage){ 

    imageUri = selectedImage; 
    mActivity.getContentResolver().notifyChange(selectedImage, null); 

    ContentResolver cr = mActivity.getContentResolver(); 
    Bitmap bitmap; 
    try { 
     bitmap = android.provider.MediaStore.Images.Media 
       .getBitmap(cr, imageUri); 

     ivPicture.setImageBitmap(bitmap); 
     ivPicture.setVisibility(View.VISIBLE); 

     mActivity.croutonInfo(imageUri.getPath()); 

    } catch (Exception e) { 
     e("Camera " + e.toString()); 
    } 
} 

를 사용할 필요가 갤러리에서 하나를 사용하는 그것을 인코딩하십시오.이 방법을 사용하면 올바른 파일 경로

private String encodeImgForHTTP (Uri imageUri) throws IOException{ 
    String realPicPath = getPath(imageUri); 
    d("encodeImgForHTTP before opening stream " + realPicPath); 
    FileInputStream fis = new FileInputStream(realPicPath); 
    d("encodeImgForHTTP after opening stream "); 
    // Get binary bytes for encode 
    byte[] imageBytes = IOUtils.toByteArray(fis); 
    d("encodeImgForHTTP after getting byte array "); 

    // base 64 encode for text transmission (HTTP) 
    //String data_string = Base64.encodeToString(data, Base64.URL_SAFE); 
    d("encodeImgForHTTP pre 64: " + imageBytes); 
    String data_string = Base64.encodeToString(imageBytes, Base64.URL_SAFE); 
    d("encodeImgForHTTP before returning the encoded data string " + data_string); 
    return data_string; 
} 

를 함께 제공하는만큼 작품과 여기에 내가 그림에 대한 "실제 경로"얻는 방법은 다음과 같습니다

public String getPath(Uri uri) throws IOException { 
    String[] projection = { MediaStore.Images.Media.DATA }; 
    Cursor cursor = mActivity. 
      managedQuery(uri, projection, null, null, null); 
    if (cursor == null){ // with pictures just taken, the uri returned by the onActivityResult makes cursor to be null. Following method takes care of that 
     uri = saveMediaEntry(imageUri.getPath(), pictureFileName, ""); 
     d("cursor nulo, segundo cursor con uri " + uri.getPath()); 
     cursor = mActivity. 
       managedQuery(uri, projection, null, null, null); 
    } 
    int column_index = cursor 
      .getColumnIndexOrThrow(MediaStore.Images.Media.DATA); 
    cursor.moveToFirst(); 
    return cursor.getString(column_index); 
} 

이 방법은 saveMediaEntry가에 항목을 만듭니다 장치의 미디어 데이터베이스는 Uri를 반환합니다. 우리가 사진을 확인로드되는 모든 이후

private Uri saveMediaEntry(
     String imagePath,String title,String description) throws IOException { 

    ExifInterface exif = new ExifInterface(imagePath); 

    ContentValues v = new ContentValues(); 
    v.put(Images.Media.TITLE, title); 
    v.put(Images.Media.DISPLAY_NAME, title); 
    v.put(Images.Media.DESCRIPTION, description); 
    v.put(Images.Media.DATE_ADDED, System.currentTimeMillis()); 
    v.put(Images.Media.DATE_TAKEN, exif.getAttribute(ExifInterface.TAG_DATETIME)); 
    //v.put(Images.Media.DATE_MODIFIED, dateTaken) ; 
    v.put(Images.Media.MIME_TYPE, "image/jpeg"); 
    v.put(Images.Media.ORIENTATION, exif.getAttribute(ExifInterface.TAG_ORIENTATION)); 
    File f = new File(imagePath) ; 
    File parent = f.getParentFile() ; 
    String path = parent.toString().toLowerCase() ; 
    String name = parent.getName().toLowerCase() ; 
    v.put(Images.ImageColumns.BUCKET_ID, path.hashCode()); 
    v.put(Images.ImageColumns.BUCKET_DISPLAY_NAME, name); 
    v.put(Images.Media.SIZE,f.length()) ; 
    f = null ; 

    v.put(Images.Media.LATITUDE, exif.getAttribute(ExifInterface.TAG_GPS_LATITUDE)); 
    v.put(Images.Media.LONGITUDE, exif.getAttribute(ExifInterface.TAG_GPS_LONGITUDE)); 

    v.put("_data",imagePath) ; 
    ContentResolver c = mActivity.getContentResolver() ; 
    return c.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, v); 
} 

을 원하고 Base64.encodeToString 반환 다른 사진을 다른 :)

이 희망 열린 우리당이 커서 이제 그림 파일을 가리 킵니다 것을 사용 누군가에게 도움을줍니다.

1

나는 작은 바이트 배열로 입력 스트림을 버퍼해야한다고 생각하고, 인코딩 함수에서 예상대로 시작하려면 available 함수를 사용하지 마십시오. 당신이 저장 한 이미지를 좋아하고, 예를 들어, 목적에 추가로 되었 것이다 경로를 결정해야 사진 걸릴하기 위해

:

private void capture(){ 
    String directoryPath = Environment.getExternalStorageDirectory() + "/" + IMAGE_DIRECTORY + "/"; 
    String filePath = directoryPath+Long.toHexString(System.currentTimeMillis())+".jpg"; 
    File directory = new File(directoryPath); 
    if (!directory.exists()) { 
     directory.mkdirs(); 
    } 
    this.capturePath = filePath; // you will process the image from this path if the capture goes well 
    Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE); 
    intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File(filePath))); 
    startActivityForResult(intent, REQUEST_CAPTURE);     

} 
+0

그래, 나는 거기에 개선의 여지가 많다는 것을 확신합니다. 방금 네이티브 리소스를 사용하여 구현하고 싶었습니다. 대부분의 예제에서 아파치와 같은 외부 라이브러리를 사용했기 때문에 (그리고 이미이 앱에서 꽤 많이 사용하고 있습니다). 사진 정보 : 사진을 업로드하려면 이미지를 저장해야합니까? 카메라의 의도에서 얻은 임시 URI가 유효하지 않습니까? – Frank

+0

@ 프랭크 카메라의 의도에 따른 임시 URI를 기억하지 못하지만 장치간에이 캡처 동작에 많은 불일치가 있음을 알려드립니다. 예를 들어 여기에 구현하려고 할 때 겪었던 문제가 있습니다. http://stackoverflow.com/questions/6390163/deleting-a-gallery-image-after-camera-intent-photo-taken/8555925#8555925 –

+0

' 이 스 니펫을 시험해보고 이제는 사진을 찍은 후 내 "누르기"에 반응하지 않을 것입니다. 화면은 찍은 사진에 남아 있습니다. 취소하고 다시 내 활동으로 돌아 가기 위해 "X"를 누르면 작동합니다 ... – Frank