Android 从图片目录在 canvas 上绘制位图

Android draw bitmap on canvas from pictures directory

使用下面的代码将一个jpg加载到一个位图中并在canvas

上绘制
File extStore = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
        File myFile = new File(extStore.getAbsolutePath() + "/MyPicture.jpg");

        if(myFile.exists()){
            Toast.makeText(getBaseContext(),"yes",Toast.LENGTH_LONG).show();
        }


        Bitmap b1 = BitmapFactory.decodeFile(myFile.toString());
        canvas.drawBitmap (b1, 0,  0, null);

应用程序崩溃并出现 2 个错误

BitmapFactory:无法解码流:java.io.FileNotFoundException:/storage/emulated/0/Pictures/MyPicture.jpg:打开失败:EACCES(权限被拒绝)

再往下说

java.lang.NullPointerException: 尝试在空对象引用

上调用虚拟方法'boolean android.graphics.Bitmap.isRecycled()'

我在 manaifest 中设置了如下权限

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

应用的目标人群是 API 19 岁,所以应该无关紧要

查看文件是否存在的检查有效,因此它是正确的位置

在我出错的地方它不会起作用

提前致谢

马克

您遇到文件未找到异常,因为未找到文件。 /storage/emulated/0/Pictures/MyPicture.jpg

处没有图像文件

如果你这样做的话,你应该做一个非常基本的警告对话框并让它能够 select 文件。

Choose File Dialog

这实际上有一个非常好的设置,使用起来非常简单,但实际上您可以浏览一下并找到合适的文件。然后加载它并使其实际存在。

回收是因为没有真正载入图片,所以回收了。你可以在加载失败后检查图像是否被回收我认为命令是isRecycled()然后退出。


如果你自己抛出错误,你可能会感觉更好。而不是做 file.toString() 如果 toString() 工作它应该是 getCanonicalPath() 是偶然而不是设计,甚至可能是你的整个错误。

但是您可以自己打开文件并将输入流传递给 BitmapFactory,这可能会更早地抛出错误,即当您尝试打开不存在的文件时。


这是用于 decodeFile() 位的内部源代码。

386    public static Bitmap More ...decodeFile(String pathName, Options opts) {
387        Bitmap bm = null;
388        InputStream stream = null;
389        try {
390            stream = new FileInputStream(pathName);
391            bm = decodeStream(stream, null, opts);
392        } catch (Exception e) {
393            /*  do nothing.
394                If the exception happened on open, bm will be null.
395            */
396            Log.e("BitmapFactory", "Unable to decode stream: " + e);
397        } finally {
398            if (stream != null) {
399                try {
400                    stream.close();
401                } catch (IOException e) {
402                    // do nothing here
403                }
404            }
405        }
406        return bm;
407    }

理论上,如果您查看 logcat,您很可能会看到它发出的 Log.e(),但它不会抛出错误,它会在内部捕获错误。尝试自己打开文件。这样你就可以更好地调试哪里出了问题,以及它抛出了哪个特定的 IO 错误。