使用ImageDecoder从URI加载位图并添加文本。

huangapple go评论89阅读模式
英文:

Loading a bitmap with ImageDecoder from URI and adding text

问题

以下是您要翻译的内容:

在我的活动中,我想修改一张图片,在上面添加一段文字。

图片是在图库中选择的,或者使用相机拍摄的,然后存储在先前活动中的文件中。然后将该文件的 URI 通过额外信息传递。

现在我尝试在图片顶部添加一串文字,像这样:

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

以下是函数的主体部分:

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 是用来控制结果的 ImageView
}

预期的行为应该是在图片顶部显示带有 "Some Text here" 的文字。但实际上没有显示任何内容,尽管应用程序没有崩溃。

在调试过程中,我遇到了一个错误,出现在以下两行代码之间:

Bitmap bitmap = ImageDecoder.decodeBitmap(source);

Canvas canvas = new Canvas(bitmap);

以下是错误信息:

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

我怀疑我误用了 "ImageDecoder",因为这是我第一次使用它。更确切地说,我无法在 onCreate 中使用 "decodeBitmap" 方法,Android Studio 告诉我它不能在 "主线程" 中使用,我对线程一点也不熟悉。将其移到专门的函数中可以解决这个问题,但也许我应该做一些其他的事情,这可能是问题的根源。

我的问题:
我是否在使用正确的工具来修改文件并在其上添加文字?
如果是,我做错了什么?
如果不是,我应该查阅哪些库/工具来执行此任务?

谢谢,

编辑:额外的回答部分

正如 @blackapps 和 @rmunge 所指出的,我没有得到合法的 URI,而是文件路径。解决我的问题的简单方法是使用以下代码从路径获取 URI:

Uri realuri = Uri.fromFile(new File("插入路径"));

此外,要编辑位图,必须使其可变,可以在这里找到相关内容。

从 URI 提取位图并在其上添加文本的最终函数如下:

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); // 一些操作,将文本居中
    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);
}
英文:

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

}

答案1

得分: 1

看起来你的URI有误。它必须以 file:/// 开头。

英文:

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

huangapple
  • 本文由 发表于 2020年8月30日 01:00:30
  • 转载请务必保留本文链接:https://go.coder-hub.com/63649635.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定