From 8714e4298e01796afeb83b80c488ec57ab6fb0bd Mon Sep 17 00:00:00 2001 From: Clark Date: Thu, 29 Jun 2023 15:32:04 -0400 Subject: [PATCH] Specify scale type for glide thumbnails. --- .../transforms/SignalDownsampleStrategy.kt | 44 +++++++++++++++++++ .../components/RecentPhotoViewRail.java | 1 + .../securesms/components/ThumbnailView.java | 4 ++ .../webrtc/CallParticipantView.java | 1 + .../ConversationStickerSuggestionAdapter.java | 1 + .../giph/mp4/GiphyMp4ViewHolder.java | 1 + .../mediasend/MediaSendGifFragment.java | 2 +- .../revealable/ViewOnceMessageActivity.java | 1 + .../stickers/StickerManagementAdapter.java | 1 + .../stickers/StickerPackPreviewActivity.java | 1 + .../stickers/StickerPackPreviewAdapter.java | 1 + .../stickers/StickerPreviewPopup.java | 1 + .../securesms/util/AvatarUtil.java | 1 + 13 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 app/src/main/java/org/signal/glide/transforms/SignalDownsampleStrategy.kt diff --git a/app/src/main/java/org/signal/glide/transforms/SignalDownsampleStrategy.kt b/app/src/main/java/org/signal/glide/transforms/SignalDownsampleStrategy.kt new file mode 100644 index 0000000000..3b8dca8652 --- /dev/null +++ b/app/src/main/java/org/signal/glide/transforms/SignalDownsampleStrategy.kt @@ -0,0 +1,44 @@ +/* + * Copyright 2023 Signal Messenger, LLC + * SPDX-License-Identifier: AGPL-3.0-only + */ +package org.signal.glide.transforms + +import com.bumptech.glide.load.resource.bitmap.DownsampleStrategy +import kotlin.math.max +import kotlin.math.min + +object SignalDownsampleStrategy { + /** + * Center outside, but don't up-scale, only downscale. You should be setting centerOutside + * on the target image view to still maintain center outside behavior. + */ + @JvmField + val CENTER_OUTSIDE_NO_UPSCALE: DownsampleStrategy = CenterOutsideNoUpscale() + + private class CenterOutsideNoUpscale : DownsampleStrategy() { + override fun getScaleFactor( + sourceWidth: Int, + sourceHeight: Int, + requestedWidth: Int, + requestedHeight: Int + ): Float { + val widthPercentage = requestedWidth / sourceWidth.toFloat() + val heightPercentage = requestedHeight / sourceHeight.toFloat() + return min(MAX_SCALE_FACTOR, max(widthPercentage, heightPercentage)) + } + + override fun getSampleSizeRounding( + sourceWidth: Int, + sourceHeight: Int, + requestedWidth: Int, + requestedHeight: Int + ): SampleSizeRounding { + return SampleSizeRounding.QUALITY + } + + companion object { + private const val MAX_SCALE_FACTOR = 1f + } + } +} diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/RecentPhotoViewRail.java b/app/src/main/java/org/thoughtcrime/securesms/components/RecentPhotoViewRail.java index 03b464c2fc..ff7d20f174 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/RecentPhotoViewRail.java +++ b/app/src/main/java/org/thoughtcrime/securesms/components/RecentPhotoViewRail.java @@ -125,6 +125,7 @@ public class RecentPhotoViewRail extends FrameLayout implements LoaderManager.Lo .signature(signature) .diskCacheStrategy(DiskCacheStrategy.NONE) .transition(DrawableTransitionOptions.withCrossFade()) + .centerCrop() .into(viewHolder.imageView); viewHolder.imageView.setOnClickListener(v -> { diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/ThumbnailView.java b/app/src/main/java/org/thoughtcrime/securesms/components/ThumbnailView.java index 36e4137b63..8acc77c0be 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/ThumbnailView.java +++ b/app/src/main/java/org/thoughtcrime/securesms/components/ThumbnailView.java @@ -28,6 +28,7 @@ import com.bumptech.glide.request.RequestListener; import com.bumptech.glide.request.RequestOptions; import org.signal.core.util.logging.Log; +import org.signal.glide.transforms.SignalDownsampleStrategy; import org.thoughtcrime.securesms.R; import org.thoughtcrime.securesms.blurhash.BlurHash; import org.thoughtcrime.securesms.database.AttachmentTable; @@ -454,6 +455,7 @@ public class ThumbnailView extends FrameLayout { GlideRequest request = glideRequests.load(new DecryptableUri(uri)) .diskCacheStrategy(DiskCacheStrategy.NONE) + .downsample(SignalDownsampleStrategy.CENTER_OUTSIDE_NO_UPSCALE) .listener(listener); if (animate) { @@ -486,6 +488,7 @@ public class ThumbnailView extends FrameLayout { GlideRequest request = glideRequests.load(model) .diskCacheStrategy(DiskCacheStrategy.NONE) .placeholder(model.getPlaceholder()) + .downsample(SignalDownsampleStrategy.CENTER_OUTSIDE_NO_UPSCALE) .transition(withCrossFade()); request = override(request, width, height); @@ -554,6 +557,7 @@ public class ThumbnailView extends FrameLayout { private GlideRequest buildThumbnailGlideRequest(@NonNull GlideRequests glideRequests, @NonNull Slide slide) { GlideRequest request = applySizing(glideRequests.load(new DecryptableUri(Objects.requireNonNull(slide.getUri()))) .diskCacheStrategy(DiskCacheStrategy.RESOURCE) + .downsample(SignalDownsampleStrategy.CENTER_OUTSIDE_NO_UPSCALE) .transition(withCrossFade())); boolean doNotShowMissingThumbnailImage = Build.VERSION.SDK_INT < 23; diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/webrtc/CallParticipantView.java b/app/src/main/java/org/thoughtcrime/securesms/components/webrtc/CallParticipantView.java index f5a6ed3384..dc26d5d2ae 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/webrtc/CallParticipantView.java +++ b/app/src/main/java/org/thoughtcrime/securesms/components/webrtc/CallParticipantView.java @@ -263,6 +263,7 @@ public class CallParticipantView extends ConstraintLayout { .fallback(fallbackPhoto.asCallCard(getContext())) .error(fallbackPhoto.asCallCard(getContext())) .diskCacheStrategy(DiskCacheStrategy.ALL) + .fitCenter() .into(pipAvatar); pipAvatar.setScaleType(contactPhoto == null ? ImageView.ScaleType.CENTER_INSIDE : ImageView.ScaleType.CENTER_CROP); diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationStickerSuggestionAdapter.java b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationStickerSuggestionAdapter.java index 0eec9603e1..dae2642e0a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationStickerSuggestionAdapter.java +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationStickerSuggestionAdapter.java @@ -68,6 +68,7 @@ public class ConversationStickerSuggestionAdapter extends RecyclerView.Adapter { diff --git a/app/src/main/java/org/thoughtcrime/securesms/giph/mp4/GiphyMp4ViewHolder.java b/app/src/main/java/org/thoughtcrime/securesms/giph/mp4/GiphyMp4ViewHolder.java index 37e25c19b0..0478e27d2f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/giph/mp4/GiphyMp4ViewHolder.java +++ b/app/src/main/java/org/thoughtcrime/securesms/giph/mp4/GiphyMp4ViewHolder.java @@ -100,6 +100,7 @@ final class GiphyMp4ViewHolder extends MappingViewHolder implements .placeholder(placeholder) .diskCacheStrategy(DiskCacheStrategy.ALL) .transition(DrawableTransitionOptions.withCrossFade()) + .centerCrop() .into(stillImage); } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/mediasend/MediaSendGifFragment.java b/app/src/main/java/org/thoughtcrime/securesms/mediasend/MediaSendGifFragment.java index 49266f071f..ccfe025c9e 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/mediasend/MediaSendGifFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/mediasend/MediaSendGifFragment.java @@ -41,7 +41,7 @@ public class MediaSendGifFragment extends Fragment implements MediaSendPageFragm super.onViewCreated(view, savedInstanceState); uri = getArguments().getParcelable(KEY_URI); - GlideApp.with(this).load(new DecryptableStreamUriLoader.DecryptableUri(uri)).into((ImageView) view); + GlideApp.with(this).load(new DecryptableStreamUriLoader.DecryptableUri(uri)).fitCenter().into((ImageView) view); } @Override diff --git a/app/src/main/java/org/thoughtcrime/securesms/revealable/ViewOnceMessageActivity.java b/app/src/main/java/org/thoughtcrime/securesms/revealable/ViewOnceMessageActivity.java index b79d03bdbe..c89d001c37 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/revealable/ViewOnceMessageActivity.java +++ b/app/src/main/java/org/thoughtcrime/securesms/revealable/ViewOnceMessageActivity.java @@ -143,6 +143,7 @@ public class ViewOnceMessageActivity extends PassphraseRequiredActivity implemen GlideApp.with(this) .load(new DecryptableUri(uri)) + .fitCenter() .into(image); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/stickers/StickerManagementAdapter.java b/app/src/main/java/org/thoughtcrime/securesms/stickers/StickerManagementAdapter.java index c6fcb39678..f0b3aff133 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/stickers/StickerManagementAdapter.java +++ b/app/src/main/java/org/thoughtcrime/securesms/stickers/StickerManagementAdapter.java @@ -273,6 +273,7 @@ final class StickerManagementAdapter extends SectionedRecyclerViewAdapter { diff --git a/app/src/main/java/org/thoughtcrime/securesms/stickers/StickerPreviewPopup.java b/app/src/main/java/org/thoughtcrime/securesms/stickers/StickerPreviewPopup.java index c84eafe8fb..53999f25f1 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/stickers/StickerPreviewPopup.java +++ b/app/src/main/java/org/thoughtcrime/securesms/stickers/StickerPreviewPopup.java @@ -40,6 +40,7 @@ final class StickerPreviewPopup extends PopupWindow { emojiText.setText(emoji); glideRequests.load(stickerGlideModel) .diskCacheStrategy(DiskCacheStrategy.NONE) + .fitCenter() .into(image); } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/AvatarUtil.java b/app/src/main/java/org/thoughtcrime/securesms/util/AvatarUtil.java index 4915b8f68a..f45c56e78a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/util/AvatarUtil.java +++ b/app/src/main/java/org/thoughtcrime/securesms/util/AvatarUtil.java @@ -58,6 +58,7 @@ public final class AvatarUtil { GlideApp.with(target) .load(photo) .transform(new BlurTransformation(context, 0.25f, BlurTransformation.MAX_RADIUS)) + .centerCrop() .into(new CustomViewTarget(target) { @Override public void onLoadFailed(@Nullable Drawable errorDrawable) {