Android 设置图像位图(位图);无法使用有效、正确缩放的位图

Android 设置图像位图(位图);无法使用有效、正确缩放的位图,android,bitmap,imageview,Android,Bitmap,Imageview,我正在尝试在ImageView中显示位图,就像我在项目中的其他两个位置所做的那样 首先,我知道我有一个有效的位图,因为调试器会显示它,并且它会显示在另外两个ImageView中。尽管如此,下面是我获取位图的代码 public static Bitmap getThumbnail(AudioUri audioURI, Context context){ Bitmap bitmap = null; if (Build.VERSION.SDK_INT >=

我正在尝试在ImageView中显示位图,就像我在项目中的其他两个位置所做的那样

首先,我知道我有一个有效的位图,因为调试器会显示它,并且它会显示在另外两个ImageView中。尽管如此,下面是我获取位图的代码

    public static Bitmap getThumbnail(AudioUri audioURI, Context context){
        Bitmap bitmap = null;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            try {
                bitmap = context.getContentResolver().loadThumbnail(
                        audioURI.getUri(), new Size(128, 128), null);
            } catch (IOException e) {
                e.printStackTrace();
            }
        } else {
            MediaMetadataRetriever mmr = new MediaMetadataRetriever();
            try {
                mmr.setDataSource(context.getContentResolver().openFileDescriptor(
                        audioURI.getUri(), "r").getFileDescriptor());
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
            InputStream inputStream = null;
            if (mmr.getEmbeddedPicture() != null) {
                inputStream = new ByteArrayInputStream(mmr.getEmbeddedPicture());
            }
            mmr.release();
            bitmap = BitmapFactory.decodeStream(inputStream);
        }
        return bitmap;
    }
我不确定其他部分是否有效,因为我还没有测试它

下面是我第一次将位图加载到ImageView中的成功尝试

xml

    <ImageView
        android:id="@+id/image_view_song_art"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp"
        android:layout_marginEnd="8dp"
        android:layout_marginBottom="8dp"
        android:layout_weight="14"
        app:srcCompat="@drawable/music_note_black_48dp"
        android:background="@color/colorPrimary"/>
    <ImageView
        android:id="@+id/imageViewSongPaneSongArt"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginEnd="4dp"
        android:background="@color/colorPrimary"
        android:src="@drawable/music_note_black_48dp" />
我假设我在这里很幸运,因为我没有做任何动态调整。这让我相信我的动态调整大小是错误的。 我在上面的代码中添加了动态调整大小,位图显示正确

    private void updateSongArt() {
        ImageView imageViewSongArt = findViewById(R.id.image_view_song_art);
        if (imageViewSongArt != null && serviceMain != null) {
            Bitmap bitmap =
                    AudioUri.getThumbnail(serviceMain.getCurrentSong(), getApplicationContext());
            if (bitmap == null) {
                imageViewSongArt.setImageDrawable(ResourcesCompat.getDrawable(
                        getResources(), R.drawable.music_note_black_48dp, null));
                imageViewSongArt.setBackgroundColor(
                        getResources().getColor(R.color.colorPrimary));
            } else {
                    int songArtHeight = imageViewSongArt.getMeasuredHeight();
                    if (songArtHeight < 1) {
                        songArtHeight = bitmap.getHeight();
                    }
                int songArtWidth = imageViewSongArt.getMeasuredWidth();
                if (songArtWidth < 1) {
                    songArtWidth = bitmap.getWidth();
                }
                if(songArtWidth > songArtHeight){
                    songArtWidth = songArtHeight;
                } else{
                    songArtHeight = songArtWidth;
                }
                Bitmap bitmap2 = FragmentPaneSong.getResizedBitmap(bitmap, songArtWidth, songArtHeight);
                if(bitmap2 != null) {
                    imageViewSongArt.setImageBitmap(bitmap2);
                } else {
                    imageViewSongArt.setImageBitmap(bitmap);
                }
                imageViewSongArt.setBackgroundColor(
                        getResources().getColor(R.color.colorOnPrimary));
            }
        }
    }
我尝试过从维度中删除边距,但这不起作用。getResizedBitmap()方法生成的位图大小正确;调试器验证它。它匹配宽度
int-songArtWidth=imageViewSongPaneSongArt.getMeasuredWidth()作为宽度返回。我不知道发生了什么事

我可以在不调整大小的情况下设置位图,并将其扩展为大尺寸,但它仍然使用可绘制的图像。即使在
imageViewSongPaneSongArt.setImageDrawable之后(空)。这些是我的代码中ImageView发生变化的唯一点,调试器显示
imageViewSongPaneSongArt.setImageBitmap(defaultBitmap)未被调用

我还试图使ImageView无效,但没有成功


发生了什么?

尝试为ImageView指定一个确定的大小,以便测试位图是否显示。您不需要
imageViewSongPaneSongArt.setImageDrawable(null)
。现在还不清楚到底展示了什么。ImageView在显示时是否有任何大小。MCVE对任何想回答这个问题的人都有帮助。是的,ImageView有一个大小。xml中的drawable是显示的内容。即使位图没有显示,ImageView也会显示位图的大小。什么是
getDefaultBitmap()
?请允许我说这是最复杂的。为了获取相册艺术(在我的例子中是相册艺术的缩略图),我使用了一个简单的Uri方法,然后直接将Uri设置为图像视图?我在StackOverflow上做了很多尝试,因为Google的开发人员决定只记录如何支持新的API。这是使用MediaStore URI的唯一方法。请尝试为ImageView指定一个确定的大小,以便测试位图是否显示。您不需要
imageViewSongPaneSongArt.setImageDrawable(null)
。现在还不清楚到底展示了什么。ImageView在显示时是否有任何大小。MCVE对任何想回答这个问题的人都有帮助。是的,ImageView有一个大小。xml中的drawable是显示的内容。即使位图没有显示,ImageView也会显示位图的大小。什么是
getDefaultBitmap()
?请允许我说这是最复杂的。为了获取相册艺术(在我的例子中是相册艺术的缩略图),我使用了一个简单的Uri方法,然后直接将Uri设置为图像视图?我在StackOverflow上做了很多尝试,因为Google的开发人员决定只记录如何支持新的API。这是唯一一个可以使用MediaStore URI的东西。
    <ImageView
        android:id="@+id/imageViewSongPaneSongArt"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginEnd="4dp"
        android:background="@color/colorPrimary"
        android:src="@drawable/music_note_black_48dp" />
 private void updateSongPaneArt() {
        int songArtHeight = getSongArtHeight();
        int songArtWidth = getSongArtWidth();
        setImageViewSongPaneArt(songArtWidth, songArtHeight);
    }

    private int getSongArtHeight() {
        ImageView imageViewSongPaneSongArt = findViewById(R.id.imageViewSongPaneSongArt);
        if (imageViewSongPaneSongArt != null && serviceMain != null) {
            int songArtHeight = imageViewSongPaneSongArt.getMeasuredHeight();
            if (songArtHeight > 0) {
                serviceMain.setSongPaneArtHeight(songArtHeight);
            } else {
                songArtHeight = serviceMain.getSongPaneArtHeight();
            }
            return songArtHeight;
        }
        return -1;
    }

    private int getSongArtWidth() {
        ImageView imageViewSongPaneSongArt = findViewById(R.id.imageViewSongPaneSongArt);
        if (imageViewSongPaneSongArt != null && serviceMain != null) {
            int songArtWidth = imageViewSongPaneSongArt.getMeasuredWidth();
            if (songArtWidth > 0) {
                serviceMain.setSongPaneArtWidth(songArtWidth);
            } else {
                songArtWidth = serviceMain.getSongPaneArtWidth();
            }
            return songArtWidth;
        }
        return -1;
    }

    private void setImageViewSongPaneArt(int songArtWidth, int songArtHeight) {
        ImageView imageViewSongPaneSongArt = findViewById(R.id.imageViewSongPaneSongArt);
        if (imageViewSongPaneSongArt != null && serviceMain != null) {
            Bitmap bitmapSongArt = AudioUri.getThumbnail(
                    serviceMain.getCurrentSong(), getApplicationContext());
            if (bitmapSongArt != null) {
                Bitmap bitmapSongArtResized = FragmentPaneSong.getResizedBitmap(
                        bitmapSongArt, songArtWidth, songArtHeight);
                imageViewSongPaneSongArt.setImageDrawable(null);
                imageViewSongPaneSongArt.setImageBitmap(bitmapSongArtResized);
                imageViewSongPaneSongArt.invalidate();
            } else {
                Bitmap defaultBitmap = getDefaultBitmap(songArtWidth, songArtHeight);
                if (defaultBitmap != null) {
                    imageViewSongPaneSongArt.setImageBitmap(defaultBitmap);
                }
            }
        }
    }

    public static Bitmap getResizedBitmap(Bitmap bm, int newWidth, int newHeight) {
        int width = bm.getWidth();
        int height = bm.getHeight();
        float scaleWidth = ((float) newWidth) / width;
        float scaleHeight = ((float) newHeight) / height;
        Matrix matrix = new Matrix();
        matrix.postScale(scaleWidth, scaleHeight);
        return Bitmap.createBitmap(
                bm, 0, 0, width, height, matrix, false);
    }