# Load Image in and outside data folder

**URL:** <https://discourse.processing.org/t/load-image-in-and-outside-data-folder/23537>\
**Category:** Processing for Android\
**Created:** [August 28, 2020, 7:21pm UTC](https://discourse.processing.org/t/load-image-in-and-outside-data-folder/23537 "2020-08-28T19:21:34Z")\
**Posts on this page:** 16\
**Page:** 1

<div class="post-metadata">

**Author:** ![NoName](https://avatars.discourse-cdn.com/v4/letter/n/58f4c7/32.png) [@NoName](https://discourse.processing.org/u/NoName)\
**Post date:** [August 28, 2020, 7:21pm UTC](https://discourse.processing.org/t/load-image-in-and-outside-data-folder/23537/1 "2020-08-28T19:21:34Z")

</div>

The question is, I can upload images via:  
img = loadImage(“img.png”);

And then they will be loaded from the sketch.  
But can I at the same time in the sketch (data folder) them:  
img = loadImage(“subfloder/img.png”);  
???

I need to distribute a lot of my images into subfolders in my sketch, but I don’t know how to do it.

---

<div class="post-metadata">

**Author:** ![NoName](https://avatars.discourse-cdn.com/v4/letter/n/58f4c7/32.png) [@NoName](https://discourse.processing.org/u/NoName)\
**Post date:** [August 28, 2020, 7:38pm UTC](https://discourse.processing.org/t/load-image-in-and-outside-data-folder/23537/2 "2020-08-28T19:38:50Z")

</div>

the person who tweaks my threads every time, THANK YOU SO MUCH AND FORGIVE ME. I TRULY TRY TO DO EVERYTHING RIGHT, BUT I ONLY USE THIS FORUM ONCE A SIX YEAR AND FORGET WHAT IS HERE AND HOW.

---

<div class="post-metadata">

**Author:** ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)\
**Post date:** [August 28, 2020, 8:02pm UTC](https://discourse.processing.org/t/load-image-in-and-outside-data-folder/23537/3 "2020-08-28T20:02:54Z")

</div>

here… this works for me…

```auto

// 
PImage pg1; 

void setup() {
  size(1222, 1222); 
  String s1=dataPath("");
  println(s1); 
  pg1 = loadImage(s1+"//"+"2016.jpg");
}

void draw() {
  image(pg1, 
    22, 22);
}
//

```

---

<div class="post-metadata">

**Author:** ![NoName](https://avatars.discourse-cdn.com/v4/letter/n/58f4c7/32.png) [@NoName](https://discourse.processing.org/u/NoName)\
**Post date:** [August 28, 2020, 8:10pm UTC](https://discourse.processing.org/t/load-image-in-and-outside-data-folder/23537/4 "2020-08-28T20:10:46Z")

</div>

You are the best!

This is really what you need. Thank. God bless you!

---

<div class="post-metadata">

**Author:** ![Nik\_Gun](https://avatars.discourse-cdn.com/v4/letter/n/919ad9/32.png) [@Nik\_Gun](https://discourse.processing.org/u/Nik_Gun)\
**Post date:** [December 7, 2020, 11:54am UTC](https://discourse.processing.org/t/load-image-in-and-outside-data-folder/23537/5 "2020-12-07T11:54:52Z")

</div>

Hello!!!  
I’m try your solution, but not working for me  
I catch `java.lang.IllegalArgumentException: File /data/user/0/com.erkgjer.test/files/sgip.png contains a path separator`

```auto
PImage i;
void setup(){
    String s1=dataPath("");
  println(s1); 
  i = loadImage(s1+"/"+"sgip.png");
}
void draw(){
   image(i, mouseX-150, mouseY-150,300, 300);
}

```

---

<div class="post-metadata">

**Author:** ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)\
**Post date:** [December 7, 2020, 4:59pm UTC](https://discourse.processing.org/t/load-image-in-and-outside-data-folder/23537/6 "2020-12-07T16:59:36Z")

</div>

> [@Nik\_Gun](#):
>
> `s1+"/"+"sgip.png"`

You need a double // here. It might depend a bit on your operating system.

```auto
s1+"//"+"sgip.png"

```

---

<div class="post-metadata">

**Author:** ![Nik\_Gun](https://avatars.discourse-cdn.com/v4/letter/n/919ad9/32.png) [@Nik\_Gun](https://discourse.processing.org/u/Nik_Gun)\
**Post date:** [December 8, 2020, 7:53pm UTC](https://discourse.processing.org/t/load-image-in-and-outside-data-folder/23537/7 "2020-12-08T19:53:37Z")

</div>

@Chrisir  
Yes,I try it but not work for me

`java.lang.IllegalArgumentException: File /data/user/0/processing.test.androidtest/files//sgip.png contains a path separator`  
I cannot open this folder and see what is there, because even through adb there is no access to it

why is the folder not being created along the path `/emulated/storage/0/Android/data/com ....?`

the data folder i add, scketch-\>addFile

---

<div class="post-metadata">

**Author:** ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)\
**Post date:** [December 9, 2020, 12:08am UTC](https://discourse.processing.org/t/load-image-in-and-outside-data-folder/23537/8 "2020-12-09T00:08:14Z")

</div>

I this for Android device?

Because it says processing in the section?

---

<div class="post-metadata">

**Author:** ![Nik\_Gun](https://avatars.discourse-cdn.com/v4/letter/n/919ad9/32.png) [@Nik\_Gun](https://discourse.processing.org/u/Nik_Gun)\
**Post date:** [December 9, 2020, 11:58am UTC](https://discourse.processing.org/t/load-image-in-and-outside-data-folder/23537/9 "2020-12-09T11:58:50Z")

</div>

oops  
Yes, I’m doing this for android, can you tell me if you know or where to write?

---

<div class="post-metadata">

**Author:** ![noel](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/noel/32/213_2.png) [@noel](https://discourse.processing.org/u/noel)\
**Post date:** [December 10, 2020, 1:22pm UTC](https://discourse.processing.org/t/load-image-in-and-outside-data-folder/23537/10 "2020-12-10T13:22:59Z")

</div>

I assume you want to load and save images outside the data folder.  
Since the latest 10/11 android versions, this is more difficult because Android is implementing “Scoped Storage”, for security reasons.  
Before you could use the method

> Environment.getExternalStorageDirectory()

but it’s deprecated above Pie (version 28) It can still be used on Android 10 using

> android:requestLegacyExternalStorage=“true”

in the Manifest, but above that, you need another solution. Tomorrow I will look into this. For the moment I’ll leave an updated code I recently wrote for all android versions to upload an image with your build-in android image explorer.  
However, you have to set your SDK target from 17 to 29.

```auto
import android.net.Uri; 
import android.database.Cursor; 
import android.content.Intent; 
import android.provider.MediaStore; 
import android.app.Activity; 
import android.content.Context; 
import android.graphics.Bitmap; 
import java.io.ByteArrayInputStream; 
import java.io.ByteArrayOutputStream; 
import java.io.File; 
import java.io.FileOutputStream; 
import android.os.Environment; 
import android.graphics.BitmapFactory; 
import android.Manifest; 
import android.content.pm.PackageManager; 
import android.os.Build; 
import android.os.Build.VERSION_CODES; 
import processing.core.PConstants;

Activity activity; 
Context context; 
PImage img; 
boolean image_loaded; 

void setup() { 
  fullScreen(); 
  background(#F9C454); 
  fill(#4A3A16); 
  textSize(38); 
  textAlign(CENTER); 
  text("Click to open Image Explorer", width/2, height/3); 
  activity = this.getActivity(); 
  context = activity.getApplicationContext(); 
  if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP_MR1) { 
    requestParticularPermission();
  }
} 

void draw() { 
  if (image_loaded) {
    background(255);
    image(img, 0, 0);
  }
} 

void mousePressed() { 
  openImageExplorer();
} 

@Override 
  void onActivityResult(int requestCode, int resultCode, Intent data) { 
  super.onActivityResult(requestCode, resultCode, data); 
  if (requestCode == 1) { 
    if (resultCode == activity.RESULT_OK) { 
      if (data != null) {
        Uri image_uri = data.getData(); 
        String[] filePathColumn = { MediaStore.Images.Media.DATA };
        Cursor cursor = context.getContentResolver().query(image_uri, filePathColumn, null, null, null); 
        cursor.moveToFirst(); 
        int columnIndex = cursor.getColumnIndex(filePathColumn[0]); 
        String imgDecodableString = cursor.getString(columnIndex); 
        cursor.close();
        println(imgDecodableString); 
        if (Build.VERSION.SDK_INT >= 28) {
          try { 
            InputStream ips = context.getContentResolver().openInputStream(image_uri); 
            Bitmap bitmap = BitmapFactory.decodeStream(ips);
            img = new PImage(bitmap.getWidth(), bitmap.getHeight(), PConstants.ARGB);
            bitmap.getPixels(img.pixels, 0, img.width, 0, 0, img.width, img.height);
            img.updatePixels();
            image_loaded = true;
          }
          catch (Exception e) { 
            e.printStackTrace();
          }
        } else { 
          img = loadImage(imgDecodableString); 
          image_loaded = true;
        }
      } else {
        println("No data");
      }
    }
  }
} 

private static String[] PERMISSIONS_STORAGE = { Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE }; 
private void requestParticularPermission() { 
  activity.requestPermissions(PERMISSIONS_STORAGE, 2020);
}

public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { 
  switch (requestCode) { 
  case 2020: 
    if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { 
      println("permissions granted");
    } else { 
      println("permissions not granted");
    } 
    break; 
  default: 
    activity.onRequestPermissionsResult(requestCode, permissions, grantResults);
  }
}

void openImageExplorer() {
  Intent intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI); 
  intent.setType("image/*"); 
  activity.startActivityForResult(intent, 1);
}

```

---

<div class="post-metadata">

**Author:** ![noel](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/noel/32/213_2.png) [@noel](https://discourse.processing.org/u/noel)\
**Post date:** [December 10, 2020, 3:35pm UTC](https://discourse.processing.org/t/load-image-in-and-outside-data-folder/23537/11 "2020-12-10T15:35:54Z")

</div>

I tested this code for loading an image placed outside the data folder on Lollipop and Android 10.

```auto
// Do not forget to give READ/WRITE permission

import android.os.Environment;
import android.Manifest; 
import android.content.pm.PackageManager; 
import android.os.Build; 
import android.os.Build.VERSION_CODES; 
import processing.core.PConstants;
import android.app.Activity; 

String image_folder = "MyPhotos"; // Must be an existing folder
PImage img;
boolean image_loaded;
Activity activity; 

void setup() {
  size(displayWidth, displayHeight);
  background(0, 0, 200); 
  textAlign(CENTER);
  String str = "Click to load image.";
  textSize(12);
  float twf = width/textWidth(str);
  textSize(8*twf);
  text(str, width/2, height/2);
  activity = this.getActivity();
  if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP_MR1) { 
    requestParticularPermission();
  }
  imageMode(CENTER);
}

void draw() {
  if (image_loaded) {
    if (img != null) {
      background(0, 0, 200); 
      image(img, width/2, height/2);
    } else {
      text("Image could not be found", width/2, height/2);
    }
  }
}

void mousePressed() {
  loadMyImage("jelly.jpg");
}

void loadMyImage(String s) {
  try {
    String directory = new String(Environment.getExternalStorageDirectory().getAbsolutePath()+"/"+image_folder+"/");
    img = loadImage(directory+s);
    image_loaded = true;
  } 
  catch (Exception e) {
    background(0, 0, 200);
    text("Image could not be found.", width/2, height/2);
  }
}

private static String[] PERMISSIONS_STORAGE = { Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE }; 
private void requestParticularPermission() { 
  activity.requestPermissions(PERMISSIONS_STORAGE, 2020);
}

public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { 
  switch (requestCode) { 
  case 2020: 
    if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { 
      println("permissions granted");
    } else { 
      println("permissions not granted");
    } 
    break; 
  default: 
    activity.onRequestPermissionsResult(requestCode, permissions, grantResults);
  }
}

```

---

<div class="post-metadata">

**Author:** ![noel](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/noel/32/213_2.png) [@noel](https://discourse.processing.org/u/noel)\
**Post date:** [December 10, 2020, 7:39pm UTC](https://discourse.processing.org/t/load-image-in-and-outside-data-folder/23537/12 "2020-12-10T19:39:01Z")

</div>

I tested this code for saving images outside the data folder on Android 10 and Lollipop.

```auto
// Do not forget to give READ/WRITE permission
import android.os.Environment;
import android.Manifest; 
import android.content.pm.PackageManager; 
import android.os.Build; 
import android.os.Build.VERSION_CODES; 
import processing.core.PConstants;
import android.app.Activity; 

PImage img;
Activity activity; 
boolean image_saved;
boolean permissions_granted;

// Folowing file name is the folder you save your image file in.
// If it does not exist it will be created automatically
String folder_name = "MyImageFolder";

// Folowing string is the name of your image file
// Be sure to include extension.
String image_file = "MyImage.png";

void setup() {
  size(displayWidth, displayHeight);
  background(0, 0, 200); 
  rectMode(CENTER);
  rect(width/2, height/2, width, height/2);
  textAlign(CENTER);
  String str = "Click to save an image.";
  textSize(12);
  float twf = width/textWidth(str);
  textSize(8*twf);
  fill(0);
  text(str, width/2, height/2);
  activity = this.getActivity();
  if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP_MR1) { 
    requestParticularPermission();
  }
  img = get();
}

void draw() {
  if (permissions_granted && image_saved) {
    background(0, 0, 200);
    fill(255);
    text("Image saved.", width/2, height/2);
  } 
}

void mousePressed() {
  saveMyImage(folder_name, image_file);
}

void saveMyImage(String sf, String tf) { 
  try { 
    String absolute_path = new String(Environment.getExternalStorageDirectory().getAbsolutePath()); 
    File file = new File(absolute_path+"/"+sf); 
    println(file);
    if (!file.exists()) { 
      boolean success = true; 
      success = file.mkdirs();
    } 
    save(file+"/"+tf);
    image_saved = true;
    println("File saved successfully.");
  } 
  catch (Exception e) { 
    println("Error while saving file: " + e);
  }
}

private static String[] PERMISSIONS_STORAGE = { Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE }; 
private void requestParticularPermission() { 
  activity.requestPermissions(PERMISSIONS_STORAGE, 2020);
}

public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { 
  switch (requestCode) { 
  case 2020: 
    if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { 
      println("permissions granted");
      permissions_granted = true;
    } else { 
      println("permissions not granted");
    } 
    break; 
  default: 
    activity.onRequestPermissionsResult(requestCode, permissions, grantResults);
  }
}

```

---

<div class="post-metadata">

**Author:** ![akenaton](https://avatars.discourse-cdn.com/v4/letter/a/a88e4f/32.png) [@akenaton](https://discourse.processing.org/u/akenaton)\
**Post date:** [December 12, 2020, 5:05pm UTC](https://discourse.processing.org/t/load-image-in-and-outside-data-folder/23537/13 "2020-12-12T17:05:25Z")

</div>

@Chrisir, @noel, @Nik_Gun ===  
there are 3 or 4 questions in this post:

- first one was (@Nik_Gun) how to load images from sub folder inside the data folder without the error explained in ths post (this file contains a path separator…) ; answer from @Chrisir does not works in this case.With android it will fire the same error . From a technical point of view that is the result of the classical way for loading an image (or some file) with P5: it uses fileInput and fileInput is waiting for the name of the file, and not the complete path (with 1 or more pathSeparators).
- @noel explains another thing= how to get a file from the external dir storage or save it.That is not the same problem i think; and the other presision (“scopedStorage”) though it could be important it does not matter here (of course what is said about permissions by @noel is exact)  
In order to answer to @Nik_Gun (and others in the same case) the best way for android is to use the android AssetManager Api and kook inside the data directory : in the code below i have 2 subfolders inside data , the first one is callled “autredos” the second is called autresousdoss; here you put your images. The code below will get a image from the “autresousdos”; that will be done through the “special” loadImages function which is able to add all images in an array: then you choose the image from the list. Try!

import android.content.Context;  
import android.app.Activity;  
import android.content.res.AssetManager;

```auto
PImage imga;// the image which is inside the subfolder called "autredos" and you want to get
Activity act;
String finalPath;
PImage[] img;// arrayList for all images

void setup(){
  size(600,400);
  background(255);
  act= this.getActivity();
  img = loadImages("autredos"+"/"+"autresousdos");// for creating the list in the subfolder
  imga = img[0];// here i suppose that i know the image i will display; in some cases you have to create a list view and can choose from it
  
  
}

void draw(){
  background(255,0,0);
  image(imga, 0, 0); //displaying the image imaga, in the subfolder
}

PImage[] loadImages(String folderName_){
  
  
  AssetManager assetManager = act.getAssets();
  try{
    String[] imgPath = assetManager.list(folderName_);
    println(imgPath.length);
    File[] files = new File[imgPath.length];
    
    img = new PImage[imgPath.length];
     for(int i=0; i<imgPath.length; i++){
       println (imgPath[i]);
    
     img[i] = loadImage(folderName_ + "/" + imgPath[i]);
     files[i] = new File(folderName_+"/" + imgPath[i]);//pour des fichiers quelconque, here you can find all folders
     println("file=====" + files[i]);
    }
    
    
  }
  catch(IOException ex){
       System.out.println (ex.toString());   
  }
  
  return img;
}

```

---

<div class="post-metadata">

**Author:** ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)\
**Post date:** [December 12, 2020, 5:07pm UTC](https://discourse.processing.org/t/load-image-in-and-outside-data-folder/23537/14 "2020-12-12T17:07:38Z")

</div>

Yeah, I assumed OP meant processing, not Android

I changed the category of the post to Android

---

<div class="post-metadata">

**Author:** ![noel](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/noel/32/213_2.png) [@noel](https://discourse.processing.org/u/noel)\
**Post date:** [December 12, 2020, 6:43pm UTC](https://discourse.processing.org/t/load-image-in-and-outside-data-folder/23537/15 "2020-12-12T18:43:17Z")

</div>

Hi @akenaton  
Great to see you back. I hope you had a complete recovery.  
And yes, you are right. That was the actual question. I did not read the whole topic.  
But anyway, someone searching will now find the whole gamma of possible image saving on Android.  
I also fixed my code because of course there, permissions are always needed.  
May I copy your code to my repo?

---

<div class="post-metadata">

**Author:** ![akenaton](https://avatars.discourse-cdn.com/v4/letter/a/a88e4f/32.png) [@akenaton](https://discourse.processing.org/u/akenaton)\
**Post date:** [December 13, 2020, 4:45pm UTC](https://discourse.processing.org/t/load-image-in-and-outside-data-folder/23537/16 "2020-12-13T16:45:46Z")

</div>

@noel === Happy to read you again, though i am always in hospital and waiting for a new operation on the 8 of Janvier; till this date i give a look to the posts and try to answer… Your idea fo a repo is defintely an excellent one and if you want to add some code from me, do as you want…I think only that you have to simplify : eg; mandelbrot has nothing to see withe menus or submenus…
