Масштабирование изображений внутри 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
        }
    }
}
Другие вопросы по тегам