programing

Android 내장 메모리에서 비트맵/이미지 저장 및 읽기

javajsp 2023. 9. 6. 21:49

Android 내장 메모리에서 비트맵/이미지 저장 및 읽기

제가 하고 싶은 일은 전화기의 내부 메모리(SD 카드가 아닌)에 이미지를 저장하는 것입니다.

어떻게 하면 되죠?

카메라에서 제 앱의 이미지 보기로 직접 이미지를 가져왔는데 모두 잘 작동합니다.

이제 제가 원하는 것은 이 이미지를 이미지 보기에서 안드로이드 장치의 내부 메모리에 저장하고 필요할 때 액세스하는 것입니다.

누가 이것을 어떻게 하는지 안내해 줄 수 있습니까?

안드로이드가 처음이라 자세한 절차 부탁드립니다.

아래 코드를 사용하여 내부 디렉토리에 이미지를 저장합니다.

private String saveToInternalStorage(Bitmap bitmapImage){
        ContextWrapper cw = new ContextWrapper(getApplicationContext());
         // path to /data/data/yourapp/app_data/imageDir
        File directory = cw.getDir("imageDir", Context.MODE_PRIVATE);
        // Create imageDir
        File mypath=new File(directory,"profile.jpg");

        FileOutputStream fos = null;
        try {           
            fos = new FileOutputStream(mypath);
       // Use the compress method on the BitMap object to write image to the OutputStream
            bitmapImage.compress(Bitmap.CompressFormat.PNG, 100, fos);
        } catch (Exception e) {
              e.printStackTrace();
        } finally {
            try {
              fos.close();
            } catch (IOException e) {
              e.printStackTrace();
            }
        } 
        return directory.getAbsolutePath();
    }

설명:

1.디렉토리가 지정된 이름으로 만들어집니다.자바독스는 디렉토리를 생성할 정확한 위치를 알려주기 위한 것입니다.

2. 저장할 이미지 이름을 지정해야 합니다.

내부 메모리에서 파일을 읽습니다.아래코드사용

private void loadImageFromStorage(String path)
{

    try {
        File f=new File(path, "profile.jpg");
        Bitmap b = BitmapFactory.decodeStream(new FileInputStream(f));
            ImageView img=(ImageView)findViewById(R.id.imgPicker);
        img.setImageBitmap(b);
    } 
    catch (FileNotFoundException e) 
    {
        e.printStackTrace();
    }

}
/**
 * Created by Ilya Gazman on 3/6/2016.
 */
public class ImageSaver {

    private String directoryName = "images";
    private String fileName = "image.png";
    private Context context;
    private boolean external;

    public ImageSaver(Context context) {
        this.context = context;
    }

    public ImageSaver setFileName(String fileName) {
        this.fileName = fileName;
        return this;
    }

    public ImageSaver setExternal(boolean external) {
        this.external = external;
        return this;
    }

    public ImageSaver setDirectoryName(String directoryName) {
        this.directoryName = directoryName;
        return this;
    }

    public void save(Bitmap bitmapImage) {
        FileOutputStream fileOutputStream = null;
        try {
            fileOutputStream = new FileOutputStream(createFile());
            bitmapImage.compress(Bitmap.CompressFormat.PNG, 100, fileOutputStream);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (fileOutputStream != null) {
                    fileOutputStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    @NonNull
    private File createFile() {
        File directory;
        if(external){
            directory = getAlbumStorageDir(directoryName);
        }
        else {
            directory = context.getDir(directoryName, Context.MODE_PRIVATE);
        }
        if(!directory.exists() && !directory.mkdirs()){
            Log.e("ImageSaver","Error creating directory " + directory);
        }

        return new File(directory, fileName);
    }

    private File getAlbumStorageDir(String albumName) {
        return new File(Environment.getExternalStoragePublicDirectory(
                Environment.DIRECTORY_PICTURES), albumName);
    }

    public static boolean isExternalStorageWritable() {
        String state = Environment.getExternalStorageState();
        return Environment.MEDIA_MOUNTED.equals(state);
    }

    public static boolean isExternalStorageReadable() {
        String state = Environment.getExternalStorageState();
        return Environment.MEDIA_MOUNTED.equals(state) ||
                Environment.MEDIA_MOUNTED_READ_ONLY.equals(state);
    }

    public Bitmap load() {
        FileInputStream inputStream = null;
        try {
            inputStream = new FileInputStream(createFile());
            return BitmapFactory.decodeStream(inputStream);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (inputStream != null) {
                    inputStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }
}

사용.

  • 저장 방법:

    new ImageSaver(context).
            setFileName("myImage.png").
            setDirectoryName("images").
            save(bitmap);
    
  • 로드 방법:

    Bitmap bitmap = new ImageSaver(context).
            setFileName("myImage.png").
            setDirectoryName("images").
            load();
    

편집:

추가된ImageSaver.setExternal(boolean)Google 예제를 기반으로 외부 저장소에 저장할 수 있도록 지원합니다.

오늘 이 질문을 접했는데 이렇게 합니다.필요한 매개 변수를 사용하여 이 함수를 호출합니다.

public void saveImage(Context context, Bitmap bitmap, String name, String extension){
    name = name + "." + extension;
    FileOutputStream fileOutputStream;
    try {
        fileOutputStream = context.openFileOutput(name, Context.MODE_PRIVATE);
        bitmap.compress(Bitmap.CompressFormat.JPEG, 90, fileOutputStream);
        fileOutputStream.close();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

마찬가지로, 동일한 것을 읽을 때는 이것을 사용합니다.

public Bitmap loadImageBitmap(Context context,String name,String extension){
    name = name + "." + extension
    FileInputStream fileInputStream
    Bitmap bitmap = null;
    try{
        fileInputStream = context.openFileInput(name);
        bitmap = BitmapFactory.decodeStream(fileInputStream);
        fileInputStream.close();
    } catch(Exception e) {
        e.printStackTrace();
    }
     return bitmap;
}

Kotlin 사용자들을 위해 저는.ImageStorageManager이미지에 대한 저장, 가져오기 및 삭제 작업을 쉽게 처리하는 클래스:

class ImageStorageManager {
    companion object {
        fun saveToInternalStorage(context: Context, bitmapImage: Bitmap, imageFileName: String): String {
            context.openFileOutput(imageFileName, Context.MODE_PRIVATE).use { fos ->
                bitmapImage.compress(Bitmap.CompressFormat.PNG, 25, fos)
            }
            return context.filesDir.absolutePath
        }

        fun getImageFromInternalStorage(context: Context, imageFileName: String): Bitmap? {
            val directory = context.filesDir
            val file = File(directory, imageFileName)
            return BitmapFactory.decodeStream(FileInputStream(file))
        }

        fun deleteImageFromInternalStorage(context: Context, imageFileName: String): Boolean {
            val dir = context.filesDir
            val file = File(dir, imageFileName)
            return file.delete()
        }
    }
}

여기서 자세히 보기

이 코드는 최대 Android 11+를 지원합니다.

프래그먼트를 사용 인 프래그먼트/액티비티에 대한 권한 결과 선언

private val askPermissions =
    registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { permissions ->
        val isGranted = permissions.entries.all {
            it.value == true
        }

        if (isGranted) {
            viewModel.saveImageToGallery(requireContext().contentResolver,
                getString(R.string.my_deshi_qr_code),
                bitmap)
        } else {
            askForWritePermission()
        }
    }

트리거 이벤트

bindingView.downloadQrButton.setOnClickListener {
        requestPermission()
    }
private fun requestPermission() {
    val minSDK = Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q
    val isWritePermissionGranted = (ContextCompat.checkSelfPermission(requireContext(),
        Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) || minSDK

    if (!isWritePermissionGranted) {
        askForWritePermission()
    } else {
        viewModel.saveImageToGallery(requireContext().contentResolver,
            getString(R.string.my_deshi_qr_code),
            bitmap)
    }
}


private fun askForWritePermission() {
    askPermissions.launch(listOf(Manifest.permission.WRITE_EXTERNAL_STORAGE).toTypedArray())
}

모델보기

fun saveImageToGallery(contentResolver: ContentResolver, imageName: String, bitmap: Bitmap?) {
    val imageUri: Uri?
    val contentValues = ContentValues().apply {
        put(MediaStore.MediaColumns.DISPLAY_NAME, "$imageName.jpg")
        put(MediaStore.MediaColumns.MIME_TYPE, "image/jpeg")
        bitmap?.let {
            put(MediaStore.Images.Media.WIDTH, bitmap.width)
            put(MediaStore.Images.Media.HEIGHT, bitmap.height)
        }
    }

    imageUri = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
        contentValues.put(MediaStore.MediaColumns.RELATIVE_PATH,
            Environment.DIRECTORY_PICTURES + File.separator.toString() + "YourFolderName")
        MediaStore.Images.Media.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY)
    } else {
        MediaStore.Images.Media.EXTERNAL_CONTENT_URI
    }

    try {
        val uri = contentResolver.insert(imageUri, contentValues)
        val fos = uri?.let { contentResolver.openOutputStream(it) }
        bitmap?.compress(Bitmap.CompressFormat.JPEG, 100, fos)
        Objects.requireNonNull(fos)
        _showMessage.postValue(Event("Image Saved"))
    } catch (e: Exception) {
        _showMessage.postValue(Event("Image Not Saved \n$e"))
    }
}

// 다중 이미지 검색

 File folPath = new File(getIntent().getStringExtra("folder_path"));
 File[] imagep = folPath.listFiles();

 for (int i = 0; i < imagep.length ; i++) {
     imageModelList.add(new ImageModel(imagep[i].getAbsolutePath(), Uri.parse(imagep[i].getAbsolutePath())));
 }
 imagesAdapter.notifyDataSetChanged();

Android 10을 사용하여 스토리지에 쓰기를 원한다면 여기를 확인하고 이미지를 앱별로만 저장하려면 여기확인하십시오. 예를 들어 앱에서 사용하기 위한 이미지를 저장하려면 다음을 참조하십시오.

viewModelScope.launch(Dispatchers.IO) {
            getApplication<Application>().openFileOutput(filename, Context.MODE_PRIVATE).use {
                bitmap.compress(Bitmap.CompressFormat.PNG, 50, it)
            }
        }

getApplication은 ViewModel에 대한 컨텍스트를 제공하는 방법이며 나중에 읽고 싶다면 AndroidViewModel의 일부입니다.

viewModelScope.launch(Dispatchers.IO) {
            val savedBitmap = BitmapFactory.decodeStream(
                getApplication<App>().openFileInput(filename).readBytes().inputStream()
            )
        }

동일한 품질로 더 많은 공간을 절약하려면 WEBP를 미디어 포맷으로 사용해야 합니다.

fun saveImage(context: Context, bitmap: Bitmap, name: String): String {
        context.openFileOutput(name, Context.MODE_PRIVATE).use { fos ->
            bitmap.compress(Bitmap.CompressFormat.WEBP, 25, fos)
        }
    return context.filesDir.absolutePath
 }

언급URL : https://stackoverflow.com/questions/17674634/saving-and-reading-bitmaps-images-from-internal-memory-in-android