Масштабирование изображений внутри textview с использованием ImageGetter
Я пытаюсь масштабировать изображения, показанные в текстовом представлении, но я просто не могу.
Я использую этот код, но, несмотря ни на что, он показывает изображение, обрезанное внутри контейнера, или не показывает его вообще.
int width, height;
DisplayMetrics metrics = new DisplayMetrics();
metrics = Resources.getSystem().getDisplayMetrics();
int originalWidthScaled = (int) (result.getIntrinsicWidth() * metrics.density);
int originalHeightScaled = (int) (result.getIntrinsicHeight() * metrics.density);
if (originalWidthScaled > metrics.widthPixels) {
height = result.getIntrinsicHeight() * metrics.widthPixels
/ result.getIntrinsicWidth();
width = metrics.widthPixels;
} else {
height = originalHeightScaled;
width = originalWidthScaled;
}
urlDrawable.drawable = result;
urlDrawable.setBounds(0, 0, 0+width, 0+height);
// change the reference of the current drawable to the result
// from the HTTP call
// redraw the image by invalidating the container
container.invalidate();
// For ICS
container.setHeight(
container.getHeight() +
result.getIntrinsicHeight());
// Pre ICS
container.setEllipsize(null);
2 ответа
Я отвечаю сам, я изменился
if (originalWidthScaled > metrics.widthPixels) {
height = result.getIntrinsicHeight() * metrics.widthPixels
/ result.getIntrinsicWidth();
width = metrics.widthPixels;
}
за
if (originalWidthScaled > (metrics.widthPixels * 70) / 100) {
width = (metrics.widthPixels * 70) / 100;
height = result.getIntrinsicHeight() * width
/ result.getIntrinsicWidth();
}
И теперь он занимает 70% пространства экрана, что в точности соответствует максимальному размеру контейнера.
Для тех, кто все еще ищет ответ, используя новые API, эта пользовательская реализация
ImageGetter
должно позволять вам увеличивать изображение, которое будет занимать ширину экрана устройства, уменьшать масштаб, если данное изображение больше, чем ширина экрана устройства, или сохранять исходный размер, если оно меньше.
/**
* Custom ImageGetter for [HtmlCompat.fromHtml] which accept both Url and Base64 from img tag.
* */
class HtmlImageGetter(
private val scope: LifecycleCoroutineScope,
private val res: Resources,
private val glide: RequestManager,
private val htmlTextView: AppCompatTextView,
@DrawableRes
private val errorImage: Int = 0,
private val matchParent: Boolean = true
) : ImageGetter {
override fun getDrawable(source: String): Drawable {
val holder = BitmapDrawablePlaceHolder(res, null)
scope.launch(Dispatchers.IO) {
runCatching {
glide
.asBitmap()
.load(
if (source.matches(Regex("data:image.*base64.*")))
Base64.decode(
source.replace("data:image.*base64".toRegex(), ""),
Base64.DEFAULT
) // Image tag used Base64
else
source // Image tag used URL
)
.submit()
.get()
}
.onSuccess { setDrawable(holder, it) }
.onFailure {
if (errorImage != 0)
BitmapFactory.decodeResource(res, errorImage)?.let {
setDrawable(holder, it)
}
}
}
return holder
}
private suspend fun setDrawable(holder: BitmapDrawablePlaceHolder, bitmap: Bitmap) {
val drawable = BitmapDrawable(res, bitmap)
val width: Int
val height: Int
val metrics = res.displayMetrics
val displayWidth = metrics.widthPixels - (htmlTextView.paddingStart + htmlTextView.paddingEnd + htmlTextView.marginStart + htmlTextView.marginEnd) * 100 / 100
val imageWidthScaled = (drawable.intrinsicWidth * metrics.density)
val imageHeightScaled = (drawable.intrinsicHeight * metrics.density)
// Scale up if matchParent is true
// Scale down if matchParent is false
if (matchParent || imageWidthScaled > displayWidth) {
width = displayWidth
height = (drawable.intrinsicHeight * width / drawable.intrinsicWidth)
}
else {
height = imageHeightScaled.roundToInt()
width = imageWidthScaled.roundToInt()
}
drawable.setBounds(0, 0, width, height)
holder.setDrawable(drawable)
holder.setBounds(0, 0, width, height)
withContext(Dispatchers.Main) { htmlTextView.text = htmlTextView.text }
}
internal class BitmapDrawablePlaceHolder(res: Resources, bitmap: Bitmap?) :
BitmapDrawable(res, bitmap) {
private var drawable: Drawable? = null
override fun draw(canvas: Canvas) {
drawable?.run { draw(canvas) }
}
fun setDrawable(drawable: Drawable) {
this.drawable = drawable
}
}
}