2

In my activity, I want to modify an image to add a text on it.

The image is selected in the galery or taken with the camera and then stored in a file in a previous activity. Then the uri of that file is passed through extras.

Now I try to add a string on top of the image like so:

try {
        modifyThePic(imageUri);
    } catch (IOException e) {
        e.printStackTrace();
    }

here is the function's body:

public void modifyThePic(Uri imageUri) throws IOException {

    ImageDecoder.Source source = ImageDecoder.createSource(this.getContentResolver(), imageUri);
    Bitmap bitmap = ImageDecoder.decodeBitmap(source);
    Canvas canvas = new Canvas(bitmap);
    Paint paint = new Paint();
    paint.setColor(Color.BLACK);
    paint.setTextSize(10);
    canvas.drawText("Some Text here", 0, 0, paint);

    image.setImageBitmap(bitmap); //image is the imageView to control the result

}

The expected behaviour would be to display the image with "Some Text here" on top of it. But instead there is nothing displayed, however the app doesn't crash.

While debugging, I come across an error that appears between the

Bitmap bitmap = ImageDecoder.decodeBitmap(source);

and the

Canvas canvas = new Canvas(bitmap);

here is the error:

java.io.FileNotFoundException: No content provider: /storage/emulated/0/Android/data/com.emergence.pantherapp/files/Pictures/JPEG_20200829_181926_7510981182141824841.jpg

I suspect that I missuse the "ImageDecoder" as it's my first time using it. More precisely, I was not able to let the "decodeBitmap" method in onCreate, Android Studio was telling me that it could not be in the "main thread", I am not familiar at all with threading. Moving it in a dedicaded function fixed this but maybe am I supposed to do something else and it's the root of the problem.

My questions: Am I using the right tools to modify the file and add the text on it ? If yes, what do I do wrong ? If no, what library/tools should I look into to do this task ?

Thank you,

EDIT: ADDITONAL ANSWER ELEMENTS

As both @blackapps and @rmunge pointed out, I was not getting a legit URI but instead a file path. The easy fix for my problem was to get the URI from the path using this code:

Uri realuri = Uri.fromFile(new File("insert path here")));

Additionaly to edit the bitmap, it must be made mutable which is covered here for example.

The final function to extract the bitmap from the URI and adding text on top of it is this one:

public void modifyThePic(Uri imageUri) throws IOException {

    ContentResolver cr = this.getContentResolver();
    InputStream input = cr.openInputStream(imageUri);
    Bitmap bitmap = BitmapFactory.decodeStream(input).copy(Bitmap.Config.ARGB_8888,true);

    Canvas canvas = new Canvas(bitmap);
    Paint paint = new Paint();
    paint.setColor(Color.BLACK);
    paint.setTextSize(300);

    int xPos = (canvas.getWidth() / 2); //just some operations to center the text
    int yPos = (int) ((canvas.getHeight() / 2) - ((paint.descent() + paint.ascent()) / 2)) ;

    canvas.drawText("SOME TEXT TO TRY IT OUT", xPos, yPos, paint);

    image.setImageBitmap(bitmap);

}
Sica
  • 79
  • 11
  • You should tell us wich statement causes the file not found exception. Be precise! – blackapps Aug 29 '20 at 17:43
  • If you have a nice uri then open an input stream for it and use BitmapFactory.decodeStream() to make your bitmap. – blackapps Aug 29 '20 at 17:46
  • I don't know exactly what is the statement, here is the full line: 2020-08-29 19:53:40.018 4773-4773/com.emergence.pantherapp W/System.err: java.io.FileNotFoundException: No content provider: /storage/emulated/0/Android/data/com.emergence.pantherapp/files/Pictures/JPEG_20200829_195338_7754310163132666088.jpg Ok, I'm trying to open an input stream and come back – Sica Aug 29 '20 at 18:01
  • `imageUri` Is that an uri you obtained from the gallery? What is the value of imageUri.toString()? Please tell. – blackapps Aug 29 '20 at 18:07
  • In the previous activity, I get an image from the camera or the gallery (users choice), then I store this image in a file that I create. And then when I go to the next activity, I pass this uri through putExtra. The value of imageUri on my last test is: /storage/emulated/0/Android/data/com.emergence.pantherapp/files/Pictures/JPEG_20200829_200756_7382569580564697486.jpg Which actually works fine if I just want to display the unmodified picture into an imageview with image.SetImageUri(myURI). – Sica Aug 29 '20 at 18:16
  • 1
    `In the previous activity, I get an image from the camera or the gallery` Please post only one scenario. Not gallery and camera. Too complicated. `then I store this image in a file that I create. `. Why would you make a copy of a file the user choosed from the gallery? Use the uri you got from the gallery instead for creating the bitmap. – blackapps Aug 29 '20 at 18:19
  • 1
    `The value of imageUri on my last test is: /storage/emulated/0/Android/dat.....` That is no uri. That is a file system path. – blackapps Aug 29 '20 at 18:20
  • Ok I need to do some research, I really thought that the URI was the absolute path, that's probably my big confusion. The reason I copy the image is because when it's modified, I don't want the original file to be modified as well. Thank you for your help so far, I'll make my research, try a few things and get back here to validate and add answer elements. – Sica Aug 30 '20 at 12:40
  • 1
    If you want to modify then load from obtained uri and save to a new file system path. – blackapps Aug 30 '20 at 12:43

1 Answers1

1

Seems your URI is wrong. It has to start with file:///

rmunge
  • 3,653
  • 5
  • 19
  • When I use this URI to just display the unmodified picture into an imageview with image.SetImageUri(myURI) it works fine, shouldn't it work fine as well for the ImageDecoder.createSource ? – Sica Aug 29 '20 at 17:59
  • 1
    No. As you should use a content uri you can read in the message. Not a file uri. – blackapps Aug 29 '20 at 18:05
  • Ok thanks a lot for clarification, I though URI and Absolute path were the same thing, that's my big confusion. I'll do some research and get back to validate etc. – Sica Aug 30 '20 at 12:41