การบันทึกและอ่านบิตแมป / ภาพจากหน่วยความจำภายในใน Android


161

สิ่งที่ฉันต้องการจะทำคือการบันทึกภาพไปยังหน่วยความจำภายในของโทรศัพท์(ไม่ SD Card)

ฉันจะทำมันได้อย่างไร

ฉันได้รับภาพโดยตรงจากกล้องไปยังมุมมองภาพในแอพของฉันมันทำงานได้ดี

ตอนนี้สิ่งที่ฉันต้องการคือการบันทึกภาพนี้จากมุมมองภาพไปยังหน่วยความจำภายในของอุปกรณ์ Android ของฉันและเข้าถึงได้เมื่อจำเป็น

ใครช่วยกรุณาแนะนำฉันเกี่ยวกับวิธีการทำเช่นนี้?

ผมเล็ก ๆ น้อย ๆ ใหม่เพื่อหุ่นยนต์ดังนั้นโปรดฉันอยากจะขอบคุณถ้าฉันสามารถมีรายละเอียดขั้นตอน


สวัสดีอยู่ที่ไหน/data/data/yourapp/app_data/imageDirกันแน่? stackoverflow.com/questions/40323126/...
คาลิลคาลาฟ

คำตอบ:


344

ใช้รหัสด้านล่างเพื่อบันทึกภาพไปยังไดเรกทอรีภายใน

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. ไดเรกทอรีจะถูกสร้างขึ้นด้วยชื่อที่กำหนด Javadocs ใช้สำหรับบอกตำแหน่งที่จะสร้างไดเรกทอรี

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

}

ฉันสังเกตเห็นว่าคุณได้แสดงความคิดเห็นบางอย่างคุณสามารถแนะนำฉันถึงสิ่งที่มีความหมาย? ชอบเกี่ยวกับเส้นทางหรือไม่ ฉันต้องให้เส้นทางหรืออะไร?
Usama Zafar

1
ฉันจะเข้าถึงรูปภาพจากหน่วยความจำได้อย่างไร?
Usama Zafar

ฉันแก้ไขคำตอบ เพื่อเข้าถึงภาพจากหน่วยความจำ คุณตั้งค่าภาพเป็นภาพของคุณได้อย่างไร? ฉันเชื่อว่ามันไม่ใช่บิตแมปเช่นเดียวกับที่คุณสามารถส่งผ่านไปยังฟังก์ชัน
Brijesh Thakur

ทำไมจะไม่ล่ะ. ดูฟังก์ชั่นก็จะส่งกลับไฟล์พา ธ ซึ่งคุณสามารถใช้เพื่อดึงมันและแสดงให้เห็นภาพ ฉันได้ใส่รหัสเพื่อดึงภาพด้วย
Brijesh Thakur

4
คุณควรปิดสตรีมจากบล็อกในที่สุดไม่ใช่จากภายในบล็อกลอง
Kenn Cal

72
/**
 * 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


13
นี่เป็นอีกวิธีที่มีประโยชน์ที่จะนำมาใส่ในชั้นเรียน:public boolean deleteFile(){ File file = createFile(); return file.delete(); }
Micro

เมื่อฉันต้องการแชร์ภาพที่บันทึกไว้มันจะส่งคืน "ไดเรกทอรีที่ไม่ได้สร้าง" และรูปภาพล้มเหลว คุณสามารถช่วยฉันได้ไหม?
A. N

คุณสามารถเพิ่มคำแถลงเกี่ยวกับสิทธิ์ใช้งานรหัสนี้ภายใต้เพื่อให้สามารถรวมในโครงการได้หรือไม่
Don Park

2
@DonPark ไม่จำเป็นต้องรหัสใด ๆ บน stackoverflowis อยู่ภายใต้ใบอนุญาต StackOverflow คุณสามารถใช้นี้กับไม่ต้องกังวล :)
Ilya Gazman

ฉันพยายามใช้สิ่งนี้ แต่พบปัญหา ความช่วยเหลือในคำถามนี้ฉันโพสต์? stackoverflow.com/questions/51276641/cannot-find-image-stored @IlyaGazman
Lion789

28

มาข้ามคำถามนี้วันนี้และนี่คือวิธีที่ฉันทำ เพียงเรียกใช้ฟังก์ชันนี้พร้อมพารามิเตอร์ที่จำเป็น

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

คุณจะส่งผ่านข้อโต้แย้งbไปยังฟังก์ชั่นsaveImageได้อย่างไร ฉันวางภาพลงบนอุปกรณ์ Android ของฉันแล้ว แต่ฉันไม่สามารถหาเส้นทางของพวกเขาได้ saveImageถ้าฉันไม่สามารถได้รับเส้นทางของพวกเขาฉันไม่สามารถผ่านพวกเขาเป็นข้อโต้แย้งที่จะฟังก์ชั่น
อิสระ

ฉันมีรูปนั้นในอุปกรณ์ ฉันสามารถดูได้จากแอพพลิเคชั่นสำรวจไฟล์เช่นเดียวกับ adb shell แต่ฉันไม่สามารถรับที่อยู่ของโปรแกรมได้ ดังนั้นฉันจึงขอให้ฉันเขียนโดยใช้รหัสแล้วอ่านอีกครั้ง การอ่านเป็นเป้าหมายสูงสุดของฉัน แต่ฉันมักจะได้รับnilเมื่อฉันพยายามอ่านภาพนั้น
อิสระ

1
ตกลงดังนั้นเมื่อคุณบอกว่าคุณเขียนมันอีกครั้งฉันคิดว่าคุณมีข้อมูลภาพนั้นเป็นบิตแมปหรือข้อมูลดิบในรูปแบบของอาร์เรย์ไบต์ หากคุณมีบิตแมปคุณสามารถใช้ฟังก์ชันข้างต้นได้โดยตรง ถ้าคุณมีมันในรูปแบบของอาร์เรย์ไบต์ให้ใช้สิ่งนี้เพื่อแปลงเป็นบิตแมปบิตแมปบิตแมปบิตแมป = บิตแมปFactory.decodeByteArray (bitmapdata, 0, bitmapdata .length); หรือแม้ว่ามันจะอยู่ในรูปแบบอื่น ๆ เพียงแค่แปลงเป็นบิตแมปและใช้ฟังก์ชั่นด้านบน
Anurag

"แก้ไขคำตอบ" ด้วยส่วนขยายในกรณีที่ปัญหาของฉันถูกยกขึ้นดังนั้นหลังจากทั้งหมดที่ฉันพบปัญหาที่ควรจะเพิ่มส่วนขยายเป็นพารามิเตอร์
อาเหม็ด Naveed

ขอบคุณสำหรับการแก้ไขฉันถือว่าส่วนขยายเป็นส่วนหนึ่งของชื่อตัวเอง
Anurag

6

สำหรับผู้ใช้ 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()
        }
    }
}

อ่านเพิ่มเติมได้ที่นี่


คุณต้องใช้พา ธ สัมบูรณ์ที่ได้รับจาก saveToInternalStorage () เพื่อดึงข้อมูลด้วย getImageFromInternalStorage () หรือเพียงแค่ชื่อไฟล์?
Leo Droidcoder

1
เพียงแค่imageFileNameจะพอที่จะเอามัน
Amiraslan

ผู้ชายฉันใช้เวลา 10 ชั่วโมงในการทำสิ่งนี้
Pb ศึกษา

0
    public static String saveImage(String folderName, String imageName, RelativeLayout layoutCollage) {
        String selectedOutputPath = "";
        if (isSDCARDMounted()) {
            File mediaStorageDir = new File(
                    Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), folderName);
            // Create a storage directory if it does not exist
            if (!mediaStorageDir.exists()) {
                if (!mediaStorageDir.mkdirs()) {
                    Log.d("PhotoEditorSDK", "Failed to create directory");
                }
            }
            // Create a media file name
            selectedOutputPath = mediaStorageDir.getPath() + File.separator + imageName;
            Log.d("PhotoEditorSDK", "selected camera path " + selectedOutputPath);
            File file = new File(selectedOutputPath);
            try {
                FileOutputStream out = new FileOutputStream(file);
                if (layoutCollage != null) {
                    layoutCollage.setDrawingCacheEnabled(true);
                    layoutCollage.getDrawingCache().compress(Bitmap.CompressFormat.JPEG, 80, out);
                }
                out.flush();
                out.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return selectedOutputPath;
    }



private static boolean isSDCARDMounted() {
        String status = Environment.getExternalStorageState();
        return status.equals(Environment.MEDIA_MOUNTED);
    }

คำถามเกี่ยวกับการจัดเก็บข้อมูลภายใน
Denny Kurniawan

0

// การดึงภาพหลายภาพ

 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();
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.