2013-03-15 3 views
0

У меня есть эта активность, в которой пользователь может выбрать одно изображение из галереи или просто сделать снимок и (вместе с другими данными) загрузить его на сайт.Проблемы с загрузкой изображения

До сих пор я столкнулся 2 разные проблемы:

1) Если я пытаюсь его с картинкой из галереи, я получаю IOException с сообщением /внешние/изображения/СМИ/2305: открытой failed: ENOENT (Нет такого файла или каталога) Это происходит, когда дело доходит до открытия потока файлов.

2) Если я пытаюсь его фотосъемке, она идет хорошо, но строка в кодировке данных состоит из «AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA» (на самом деле больше, но только), и я предполагаю, что это не очень хороший знак. Это только предположение, поскольку я до сих пор не могу загрузить его на веб-сайт, но разные картинки, показывающие одну и ту же строку данных, просто пахнут смешно.

Код здесь

@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); 
    } 
} 
} 

Это, как я загрузить изображение (либо взятый рис или из галереи) на ImageView. Он работает нормально.

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 он будет иметь AsyncTask иметь дело с передачей HTTP, до сих пор он только помещает данные в объект передачи 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. Изображения из галереи не срабатывают сразу после «до открытия потока»

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

Я предполагаю, что я, наконец, получил его Работа. Сначала я использовал совет Эмиля и сохранил изображение. 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); 
} 

Но использовать одну из галереи я должен использовать contentResolver

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. С помощью этого 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); 
} 

После всего этого, фотографии загружаются OK, и возвращается 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

Да, я более чем уверен (так как я полностью зеленый в файлах кодирования и т. д.), что там есть много возможностей для улучшения. Я просто хотел добиться этого, используя собственные ресурсы, поскольку большинство примеров, которые я нашел, использовали внешние библиотеки из apache и т. П. (И я уже использую немало в этом приложении). О фотографиях: мне нужно сохранить изображение, чтобы загрузить его? Недействительно временный uri, который я получаю от намерения камеры? – Frank

+0

@Frank Я не помню временный URI от намерения камеры, но я скажу вам, что существует много несоответствий в отношении этого поведения захвата между устройствами. Например, вот проблема, с которой я столкнулся при попытке ее реализации: http://stackoverflow.com/questions/6390163/deleting-a-gallery-image-after-camera-intent-photo-taken/8555925#8555925 –

+0

I ' m пытается выполнить этот фрагмент, и теперь он не будет реагировать на мою «проверку» после съемки рисунка. Экран остается на снимке. Он работает, если я нажимаю «X», чтобы отменить и вернуться к своей деятельности ... – Frank

Смежные вопросы