Android 设置图像位图(位图);无法使用有效、正确缩放的位图
我正在尝试在ImageView中显示位图,就像我在项目中的其他两个位置所做的那样 首先,我知道我有一个有效的位图,因为调试器会显示它,并且它会显示在另外两个ImageView中。尽管如此,下面是我获取位图的代码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 >=
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);
}