Сохранение изображения из ImageView во внутреннюю память

Я создал ImageView, и я вижу предварительный просмотр камеры и загружаю захваченное изображение в ImageView, и я хотел сохранить изображение в каталоге во внутренней памяти. Я ссылался на многие сообщения и пытался, но я не мог найти свое изображение во внутренней памяти.

Это код, который я использовал:

package com.example.shravan.camera;

import android.content.Context;
import android.content.ContextWrapper;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

public class MainActivity extends AppCompatActivity {

    private final String TAG = "abc";

    static final int REQUEST_IMAGE_CAPTURE =1 ;
    ImageView iv;
    Uri imageUri;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button btn = (Button)findViewById(R.id.myB);
        iv = (ImageView) findViewById(R.id.myIV);
        //disable the button if the user has no camera
        if (!hasCamera()) {
            btn.setEnabled(false);
        }
    }

    public boolean hasCamera() {
        return getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_ANY);
    }

    //on click event handler that launches the camera
    public void launchCamera(View v) {
        Intent i = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        startActivityForResult(i, REQUEST_IMAGE_CAPTURE);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
            imageUri=data.getData();
            iv.setImageURI(imageUri);;
        }
    }

    public void SaveFile(View v) {
        BitmapDrawable drawable = (BitmapDrawable) iv.getDrawable();
        Bitmap bitmap = drawable.getBitmap();

        print("Creating cw");
        ContextWrapper cw = new ContextWrapper(this.getApplicationContext());
        print("Creating dir");
        File directory = cw.getDir("ImagesDir", Context.MODE_PRIVATE);
        print("Created dir" + directory);
        File mypath = new File(directory,"myImagesDGS.jpg");
        print("path is" + mypath);

        FileOutputStream fos = null;
        try {
            print("creating fos");
            fos = new FileOutputStream(mypath);
            print("Compressing bitmap");
            bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                fos.close();
                print("fos closed");
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    private void print(String str){
        Log.d(TAG, str);
    }

}

Я сделал много сообщений журнала для отладки, и у меня есть один путь, который я не мог найти в своем телефоне.

Это логарифм:

08-07 21:47:37.089 11030-11030/com.example.shravan.camera D/abc: Создание cw 08-07

21:47:37.089 11030-11030/com.example.shravan.camera D/abc: Создание каталога 08-07

21:47:37.099 11030-11030/com.example.shravan.camera D/abc: Created dir/data/user/0/com.example.shravan.camera/app_ImagesDir 08-07

21:47:37.099 11030-11030/com.example.shravan.camera D/abc: путь/данные/пользователь/0/com.example.shravan.camera/app_ImagesDir/myImagesDGS.jpg

08-07 21:47:37.099 11030-11030/com.example.shravan.camera D/abc: создание изображения

08-07 21:47:37.099 11030-11030/com.example.shravan.camera D/abc: Сжатие растрового изображения

08-07 21:47:42.589 11030-11030/com.example.shravan.camera D/abc: fos закрыт

Есть ли что-то, что мне нужно проверить и изменить? Пожалуйста помоги!


person Shravan DG    schedule 08.08.2016    source источник
comment
ИТ в /data/user/0/com.example.shravan.camera/app_ImagesDir/myImagesDGS.jpg. Но вам нужен root-доступ, чтобы получить доступ к приватным файлам приложения.   -  person Gabe Sechan    schedule 08.08.2016
comment
Ваше приложение сохранило файл в конкретном частном каталоге приложения. Доступ есть только у вашего приложения (нет необходимости в руте)). Не другие приложения, такие как файловые менеджеры, которые вы использовали для поиска файла.   -  person greenapps    schedule 08.08.2016
comment
@greenapps Как я могу найти его в проводнике?   -  person Shravan DG    schedule 08.08.2016
comment
@GabeSechan Как я могу получить к нему доступ из других приложений? Какие модификации мне нужно сделать?   -  person Shravan DG    schedule 08.08.2016
comment
Как сказано, вы не можете найти его с помощью проводника. Поэтому сохраняйте файл не во внутренней памяти, а во внешней.   -  person greenapps    schedule 09.08.2016
comment
У моего устройства нет внешнего хранилища. Это проблема! Что мне делать теперь в этом случае, чтобы создать отдельную папку во внутренней памяти и затем хранить мои изображения в этом каталоге?   -  person Shravan DG    schedule 09.08.2016
comment
Все устройства имеют внутреннюю и внешнюю память. Непонятно, о чем вы говорите. Если вы вставите в него карту micro SD, это будет считаться съемным хранилищем.   -  person greenapps    schedule 09.08.2016
comment
Я. Мое устройство не поддерживает микро SD. Все, что у него есть, это внутренняя память. Итак, в этом проблема   -  person Shravan DG    schedule 09.08.2016


Ответы (7)


Получил работу!

Я использовал этот код, чтобы создать каталог в моем хранилище файлов, а затем сохранить изображение:

FileOutputStream outStream = null;

// Write to SD Card
try {
    File sdCard = Environment.getExternalStorageDirectory();
    File dir = new File(sdCard.getAbsolutePath() + "/camtest");
    dir.mkdirs();

    String fileName = String.format("%d.jpg", System.currentTimeMillis());
    File outFile = new File(dir, fileName);

    outStream = new FileOutputStream(outFile);
    bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outStream);
    outStream.flush();
    outStream.close();

    Log.d(TAG, "onPictureTaken - wrote to " + outFile.getAbsolutePath());

    refreshGallery(outFile);
} catch (FileNotFoundException e) {
    print("FNF");
    e.printStackTrace();
} catch (IOException e) {
    e.printStackTrace();
} finally {

}

Мои разрешения:

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

Наконец, самое главное:

Перейдите в «Настройки устройства»> «Устройство»> «Приложения»> «Диспетчер приложений»> «Ваше приложение»> «Разрешения»> «Включить разрешение на хранение»!

person Shravan DG    schedule 11.08.2016
comment
Я видел много предложений, но это сработало для меня из-за важного последнего шага, ха-ха, большинство пропустили этот шаг, так что спасибо - person Justin Chitla; 11.11.2017
comment
Не беспокойся, дружище - person Shravan DG; 14.11.2017
comment
описывая сверху вниз, спасибо, просто пришлите параметр Bitmap bitmap, способу, отлично. - person Noor Hossain; 28.03.2020

Место, в котором сохраняются ваши текущие изображения, недоступно для другого приложения. Лучше сохранять их в доступном месте. Попробуйте вот так..

BitmapDrawable drawable = (BitmapDrawable) iv.getDrawable();
Bitmap bitmap = drawable.getBitmap();
 try {
           String root = Environment.getExternalStorageDirectory().toString();
           File file = new File(root + "/YourDirectory/myImagesDGS.jpg");
           FileOutputStream out = new FileOutputStream(file);
           bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
           out.flush();
           out.close();

                                } catch (Exception ex) {
                                    ex.printStackTrace();
                                }

то вы можете получить сохраненные изображения следующим образом.

String root = Environment.getExternalStorageDirectory().toString();
  File file = new File(root + "/YourDirectory/myImagesDGS.jpg");    
Bitmap bmap=BitmapFactory.decodeFile(file.getAbsolutePath());
person Chathu_sm    schedule 08.08.2016
comment
The location your current images are saving, cannot be accessed. Конечно вы можете. Если вы можете писать в файлы там, вы также можете их читать. Пожалуйста, перефразируйте, что вы имеете в виду. - person greenapps; 08.08.2016
comment
Я попробовал ваш код, и он дал мне исключение «файл не найден»! Что мне не хватает? - person Shravan DG; 08.08.2016
comment
Но у моего устройства нет внешнего хранилища! Как создать каталог во внутренней памяти? @greenapps - person Shravan DG; 09.08.2016
comment
@ShravanDG на самом деле вы делаете ... тот, к которому вы можете получить доступ (внутреннее хранилище), здесь называется внешним хранилищем .. - person Chathu_sm; 09.08.2016
comment
Куда будут сохраняться изображения (каталог приложения или YourDirectory) во внутренней памяти? Я ничего не нашел ни в одной из этих папок! - person Shravan DG; 09.08.2016
comment
@ShravanDG вы найдете каталог с именем yourdirectory в вашем хранилище ... именно там хранится файл - person Chathu_sm; 09.08.2016
comment
@Sandaruwan Я не могу создать каталог и сохранить изображение. Я пробовал это несколькими способами. Не могли бы вы помочь? - person Shravan DG; 09.08.2016
comment
@ShravanDG есть ли какие-либо исключения .... не могли бы вы проверить, где ломается код, используя Log.e() или что-то в этом роде? - person Chathu_sm; 10.08.2016
comment
Я получаю исключение FileNotFound! Не знаю, почему! Что мне не хватает? - person Shravan DG; 10.08.2016
comment
можете ли вы проверить, правильно ли файл хранится или нет в хранилище ... с помощью инструмента файлового менеджера или чего-то еще .. - person Chathu_sm; 10.08.2016
comment
Это проблема. Я проверил это! Он не хранится! - person Shravan DG; 10.08.2016
comment
Он хранится в каком-то случайном месте /data/user/0/com.example.shravan.asbdbsadbsabcxscsa/app_mydir/myfile, которое я не могу найти. По умолчанию я могу найти образ в папке DCIM. - person Shravan DG; 10.08.2016

попробуй это. Я изменил свой код, чтобы он соответствовал коду, который вы предоставили. Я не проверял это. Я временно сохраняю сделанную фотографию в файл с отметкой времени, а затем использую имя файла для извлечения файла. Надеюсь, поможет

private Uri mImageCaptureUri;
public void launchCamera(View v)
{
    //Intent i = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    //startActivityForResult(i, REQUEST_IMAGE_CAPTURE);

Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                    mImageCaptureUri = Uri.fromFile(new File(Environment.getExternalStorageDirectory(),
                            "tmp_avatar_" + String.valueOf(System.currentTimeMillis()) + ".jpg"));

                    intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, mImageCaptureUri);
}


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

if (mImageCaptureUri!=null){
//Do whatever you want with the uri
}

}
}
person kggoh    schedule 08.08.2016

Ваше изображение сохраняется с этого пути /data/user/0/com.example.shravan.camera/app_ImagesDir/myImagesDGS.jpg, но у вас нет доступа. Попробуйте этот код для чтения iamge. Вызовите этот метод в onCreate, этот метод возвращает вам растровое изображение.

 Bitmap mBitmap= getImageBitmap(this,"myImagesDGS","jpg");

   if(mBitmap !=null){

yourImageView.setBitmap(mBitmap);

}else{

Log.d("MainActivity","Image is not found");
}

Это отдельный метод

     public Bitmap getImageBitmap(Context context,String name,String extension){
        name=name+"."+extension;  
        try{ 
            FileInputStream fis = context.openFileInput(name);
                Bitmap b = BitmapFactory.decodeStream(fis);
                fis.close();
                return b;
            } 
            catch(Exception e){
            } 
            return null; 
        }
person Muhammad Waleed    schedule 08.08.2016

С этим кодом вы перестанете хранить свой файл в личных данных приложения. Вы не можете получить доступ к этим данным с другими приложениями, кроме самого приложения, без root-доступа. Вы можете получить общедоступный каталог изображений, используя этот код при объявлении пути к файлу, если вы хотите, чтобы к вашему файлу изображения могли получить доступ другие приложения.

File albumF;
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
    albumF = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM);
} else {
    albumF = context.getFilesDir();
}

Если вам нужно сделать свой подкаталог внутри общедоступного каталога галереи, вы можете изменить приведенный выше код следующим образом:

File albumF;
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
    albumF = new File(Environment.getExternalStoragePublicDirectory(
            Environment.DIRECTORY_DCIM), YOUR_SUB_DIRECTORY_STRING);
} else {
    albumF = new File(context.getFilesDir(), YOUR_SUB_DIRECTORY_STRING);
}

Возможно, вам понадобится добавить этот код, чтобы создать этот каталог альбомов.

if (!albumF.exists()) {
    albumF.mkdirs();
}
person HendraWD    schedule 08.08.2016
comment
Я попробовал этот код, но все еще не могу найти каталог изображений или изображение в галерее! Он просто добавляется в папку моей камеры по умолчанию. Пожалуйста помоги - person Shravan DG; 08.08.2016
comment
@ShravanDG да, в коде нет ничего плохого, потому что он должен работать именно так. Я добавлю код, чтобы сделать вашу подпапку внутри папки общедоступной галереи - person HendraWD; 10.08.2016
comment
Я только что попробовал код, и, к сожалению, мое приложение останавливается. Не могли бы вы изучить это? мой код: (я сохраняю изображение при нажатии кнопки) - person Shravan DG; 10.08.2016
comment
//после конвертации изображения в растровое изображение, затем File albumF; if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){ AlbumF = новый файл(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM), MyDir); } else { AlbumF = новый файл (context.getFilesDir(), MyDir); } альбомF.mkdirs(); Файл файл = новый файл (альбомF, a.jpg); FileOutputStream fout = новый FileOutputStream(файл); bitmap.compress(Bitmap.CompressFormat.JPEG, 85, fout); } - person Shravan DG; 10.08.2016
comment
@ShravanDG, можете ли вы показать трассировку стека ошибки? - person HendraWD; 10.08.2016
comment
Я получил это: E/System: Неперехваченное исключение, созданное финализатором, E/System: java.lang.IllegalStateException: Binder был завершен в android.os.BinderProxy.transactNative(Native Method) в android.os.BinderProxy.transact(Binder .java:503) в com.android.internal.app.IApOpsService$Stub$Proxy.stopWatchingMode(IApOpsService.java:431) в android.media.SoundPool.release(SoundPool.java:195) в android... - person Shravan DG; 10.08.2016
comment
Hendra Wijaya Djiono - Я отладил это! Приложение аварийно завершает работу в этой части: albumF.mkdirs(); Файл файл = новый файл (albumF, FILENAME + CurrentDateAndTime + .jpg); FileOutputStream fout = новый FileOutputStream(файл); Что мне делать? (ошибка при создании fout и получение исключения FileNotFound!) Помогите.. - person Shravan DG; 10.08.2016
comment
Сначала попробуйте проверить, существует ли файл. Если не существует, просто создайте файл. if(!file.exists()) { file.createNewFile(); } - person HendraWD; 11.08.2016

Попробуйте использовать ImageSaver. Это синхронный способ сохранения и загрузки изображений из внутреннего и внешнего хранилища.

Применение

  • Сохранить:

    new ImageSaver(context).
            setFileName("myImage.png").
            setDirectoryName("images").
            setExternal(true).
            save(bitmap);
    
  • Загрузить:

    Bitmap bitmap = new ImageSaver(context).
            setFileName("myImage.png").
            setDirectoryName("images").
            setExternal(true).
            load();
    
person Ilya Gazman    schedule 10.08.2016

Решение, предложенное @Shravan DG, дает мне ошибку. Я немного изменил его код, и он работает без ошибок.

 private void downloadQR()
{
    FileOutputStream outStream = null;
    
    try {
        String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
        String imageFileName = "QRCode_" + timeStamp + ".jpg";
        File storageDir = new File(Environment.getExternalStorageDirectory().toString(), "PARENT_DIR)/CHILD_DIR/");
        storageDir.mkdirs();

        File outFile = new File(storageDir, imageFileName);
        outStream = new FileOutputStream(outFile);
        BitmapDrawable drawable = (BitmapDrawable) qrCode.getDrawable();
        Bitmap bitmap = drawable.getBitmap();
        bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outStream);
        outStream.flush();
        outStream.close();

        Log.d(TAG, "onPictureTaken - wrote to " + outFile.getAbsolutePath());

    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {

    }
}

Таблетка от холода :)

person Ali Akram    schedule 09.05.2021