无法在ImageView中显示从图库导出的图片 [英] Cannot show in ImageView a picture exported from the gallery

查看:331
本文介绍了无法在ImageView中显示从图库导出的图片的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在创建一个Android应用程序,该应用程序需要在内部存储中存储一些多媒体文件.用户可以从选择器中选择该多媒体文件.即使用户删除了这些文件,这些文件也必须是可用的,因此它们会被复制到内部存储器中.

I am creating an Android application that needs to store some multimedia files in the internal storage. The user can choose that multimedia files from the picker. Those files must be available even when the user removes them, so they are copied to the internal storage.

这是我的代码:

final Bitmap bitm = MediaStore.Images.Media.getBitmap( this.getContentResolver(), uri );
final int bitmapRawLength = bitm.getAllocationByteCount();
final ByteBuffer byteBuffer = ByteBuffer.allocate( bitmapRawLength );

bitm.copyPixelsToBuffer( byteBuffer );
data = byteBuffer.array();

final ByteArrayInputStream in = new ByteArrayInputStream( data );
db.store( in );

因此,组成图像的字节通过 InputStream 复制到内部存储中的平均文件中.显然,它可以工作,因为该文件包含内容.

So, the bytes composing the image are copied into an average file inside the internal store through an InputStream. Apparently it works, since the file has contents.

稍后将图像加载到 ImageView :

private void loadImage(File imgFile)
{
    if ( imgFile.exists() ) {
        final Bitmap bitmap = BitmapFactory.decodeFile( mediaFile.getPath() );

        this.ivPictureBox.setImageBitmap( bitmap );
    } else {
        this.abortDueToMissingFile( imgFile );
    }

    return;
}

不幸的是,这不起作用.是时候加载该图像了, ImageView 变为空白,什么也没有显示.

Unfortunately, this does not work. When it is time to load that image, the ImageView goes blank, nothing is shown.

实际上,在日志中显示以下消息:

Actually, in the log appears the following message:

D/skia: --- Failed to create image decoder with message 'unimplemented'

如果我在Android Studio中使用文件资源管理器并将图像导出到计算机,则GwenView失败,并显示消息无法加载元数据".

If I use the file explorer in Android Studio and export the image to my computer, then GwenView fails with the message "Failed to load metadata".

无论是更简单还是可行的方法,如何正确存储包含完整信息的图像,或正确显示图像?

How can I correctly store the image, with the complete information, or show it correctly, whatever is easier or feasible?

推荐答案

在这种情况下,我已经开发并测试了一些代码.希望对您有帮助.

I have develop and test some code in this case. I hope it helps you.

定义请求代码:

private static final int REQUEST_CODE_KITKAT_PICK_PHOTO = 11;
private static final int REQUEST_CODE_PICK_PHOTO = 12;

呼叫图像选择器:

if (Build.VERSION.SDK_INT < 19) {
    Intent intent = new Intent();
    intent.setType("image/*");
    intent.setAction(Intent.ACTION_GET_CONTENT);
    startActivityForResult(Intent.createChooser(intent, "Choose a photo"), REQUEST_CODE_PICK_PHOTO);
} else {
    Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
    intent.addCategory(Intent.CATEGORY_OPENABLE);
    intent.setType("image/*");
    startActivityForResult(intent, REQUEST_CODE_KITKAT_PICK_PHOTO);
}

要接收选择的图像并将其复制,请在您的活动中:

To receive the picked image and copy it, in your Activity:

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (resultCode == Activity.RESULT_OK) {
        if (requestCode == REQUEST_CODE_PICK_PHOTO) {
            if (data == null || data.getData() == null) {
                Toast.makeText(getApplicationContext(), "Error in retrieving photo!", Toast.LENGTH_SHORT).show();
                return;
            }
            Uri uri = data.getData();
            String destPath = getFilesDir() + File.separator + "image.jpg"; // an example path

            File imageFile = null;
            try {
                imageFile = copy(uri, destPath);
            } catch (IOException e) {
                e.printStackTrace();
            }

            if (imageFile != null) {
                Bitmap bitmap = BitmapFactory.decodeFile(imageFile.getAbsolutePath());
                ivPictureBox.setImageBitmap(bitmap);
            }
        } else if (requestCode == REQUEST_CODE_KITKAT_PICK_PHOTO) {
            if (data == null || data.getData() == null) {
                Toast.makeText(getApplicationContext(), "Error in retrieving photo!", Toast.LENGTH_SHORT).show();
                return;
            }
            Uri originalUri = data.getData();
            final int takeFlags = data.getFlags()
                    & (Intent.FLAG_GRANT_READ_URI_PERMISSION
                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
            // Check for the freshest data.
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                getContentResolver().takePersistableUriPermission(originalUri, takeFlags);
            }
            String destPath = getFilesDir() + File.separator + "image.jpg"; // an example path

            File imageFile = null;
            try {
                imageFile = copy(originalUri, destPath);
            } catch (IOException e) {
                e.printStackTrace();
            }

            if (imageFile != null) {
                Bitmap bitmap = BitmapFactory.decodeFile(imageFile.getAbsolutePath());
                ivPictureBox.setImageBitmap(bitmap);
            }
        }
    }
}

// To copy the file:
private File copy(Uri inputUri, String destPath) throws IOException {
    File inputFile = new File(ImageUtils.getPathFromUri(getApplicationContext(), inputUri));
    File outputFile = new File(destPath);
    if (!outputFile.exists()) {
        outputFile.createNewFile();
    }
    FileInputStream inStream = new FileInputStream(inputFile);
    FileOutputStream outStream = new FileOutputStream(outputFile);
    FileChannel inChannel = inStream.getChannel();
    FileChannel outChannel = outStream.getChannel();
    inChannel.transferTo(0, inChannel.size(), outChannel);
    inStream.close();
    outStream.close();
    return outputFile;
}

ImageUtils.java:

ImageUtils.java:

import android.annotation.SuppressLint;
import android.content.ContentUris;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.provider.DocumentsContract;
import android.provider.MediaStore;

public class ImageUtils {

    @SuppressLint("NewApi")
    public static String getPathFromUri(final Context context, final Uri uri) {

        final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;

        // DocumentProvider
        if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
            // ExternalStorageProvider
            if (isExternalStorageDocument(uri)) {
                final String docId = DocumentsContract.getDocumentId(uri);
                final String[] split = docId.split(":");
                final String type = split[0];

                if ("primary".equalsIgnoreCase(type)) {
                    return Environment.getExternalStorageDirectory() + "/" + split[1];
                }

                // TODO handle non-primary volumes
            }
            // DownloadsProvider
            else if (isDownloadsDocument(uri)) {

                final String id = DocumentsContract.getDocumentId(uri);
                final Uri contentUri = ContentUris.withAppendedId(
                        Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));

                return getDataColumn(context, contentUri, null, null);
            }
            // MediaProvider
            else if (isMediaDocument(uri)) {
                final String docId = DocumentsContract.getDocumentId(uri);
                final String[] split = docId.split(":");
                final String type = split[0];

                Uri contentUri = null;
                if ("image".equals(type)) {
                    contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
                } else if ("video".equals(type)) {
                    contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
                } else if ("audio".equals(type)) {
                    contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
                }

                final String selection = "_id=?";
                final String[] selectionArgs = new String[]{
                        split[1]
                };

                return getDataColumn(context, contentUri, selection, selectionArgs);
            }
        }
        // MediaStore (and general)
        else if ("content".equalsIgnoreCase(uri.getScheme())) {

            // Return the remote address
            if (isGooglePhotosUri(uri))
                return uri.getLastPathSegment();

            return getDataColumn(context, uri, null, null);
        }
        // File
        else if ("file".equalsIgnoreCase(uri.getScheme())) {
            return uri.getPath();
        }

        return null;
    }

    public static String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) {

        Cursor cursor = null;
        final String column = "_data";
        final String[] projection = {
                column
        };

        try {
            cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs,
                    null);
            if (cursor != null && cursor.moveToFirst()) {
                final int index = cursor.getColumnIndexOrThrow(column);
                return cursor.getString(index);
            }
        } finally {
            if (cursor != null)
                cursor.close();
        }
        return null;
    }


    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is ExternalStorageProvider.
     */
    public static boolean isExternalStorageDocument(Uri uri) {
        return "com.android.externalstorage.documents".equals(uri.getAuthority());
    }

    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is DownloadsProvider.
     */
    public static boolean isDownloadsDocument(Uri uri) {
        return "com.android.providers.downloads.documents".equals(uri.getAuthority());
    }

    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is MediaProvider.
     */
    public static boolean isMediaDocument(Uri uri) {
        return "com.android.providers.media.documents".equals(uri.getAuthority());
    }

    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is Google Photos.
     */
    public static boolean isGooglePhotosUri(Uri uri) {
        return "com.google.android.apps.photos.content".equals(uri.getAuthority());
    }
}

这是结果:

这篇关于无法在ImageView中显示从图库导出的图片的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆