Попытка получить размер отображения изображения в ImageView - PullRequest
44 голосов
/ 04 октября 2010

Я пытаюсь получить реальный размер изображения, отображаемого в режиме просмотра изображений.На самом деле мое изображение больше, чем экран, и просмотр изображений изменяет размер изображения, чтобы отобразить его.Я ищу этот новый размер.

Я пытался переопределить метод onDraw ImageView в пользовательском представлении, но я не получаю правильную высоту и ширину ...

public class LandImageView extends ImageView
{
    public LandImageView( Context context )
    {
        super( context );
    }

    public LandImageView(Context context, AttributeSet attrs)
    {
        super(context, attrs);
    }

    public LandImageView(Context context, AttributeSet attrs, int defStyle)
    {
        super(context, attrs, defStyle);
    }

    @Override
    protected void onDraw( Canvas canvas )
    {
        super.onDraw( canvas );

        int test = this.getWidth();
        int test2 = this.getHeight();
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh)
    {
        super.onSizeChanged(w, h, oldw, oldh);
    }
}

У тебя есть какие-нибудь подсказки?

Ответы [ 13 ]

98 голосов
/ 21 марта 2013

Ни один из ответов здесь фактически не отвечает на вопрос:

Из Bitmap любого размера, отображаемого ImageView, найдите фактические размеры отображаемого изображения , а не размеры поставляемого Bitmap.

А именно:

  • Использование ImageView.getDrawable().getInstrinsicWidth() и getIntrinsicHeight() вернет исходные размеры.
  • Получение от Drawable до ImageView.getDrawable() и приведение его к BitmapDrawable, затем использование BitmapDrawable.getBitmap().getWidth() и getHeight() также возвращает исходное изображение и его размеры.

Единственный способ получить фактические размеры отображаемого изображения - извлечь и использовать преобразование Matrix, используемое для отображения изображения в том виде, как оно показано. Это должно быть сделано после стадии измерения, и в приведенном здесь примере она вызывается в Override из onMeasure() для пользовательского ImageView:

public class SizeAwareImageView extends ImageView {

    public SizeAwareImageView(Context context) {
        super(context);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        // Get image matrix values and place them in an array
        float[] f = new float[9];
        getImageMatrix().getValues(f);

        // Extract the scale values using the constants (if aspect ratio maintained, scaleX == scaleY)
        final float scaleX = f[Matrix.MSCALE_X];
        final float scaleY = f[Matrix.MSCALE_Y];

        // Get the drawable (could also get the bitmap behind the drawable and getWidth/getHeight)
        final Drawable d = getDrawable();
        final int origW = d.getIntrinsicWidth();
        final int origH = d.getIntrinsicHeight();

        // Calculate the actual dimensions
        final int actW = Math.round(origW * scaleX);
        final int actH = Math.round(origH * scaleY);

        Log.e("DBG", "["+origW+","+origH+"] -> ["+actW+","+actH+"] & scales: x="+scaleX+" y="+scaleY);
    }

}  

Примечание: Чтобы получить преобразование изображения Matrix из кода в целом (как в Activity), используется функция ImageView.getImageMatrix() - например, myImageView.getImageMatrix()

26 голосов
/ 14 ноября 2014

Я расширил ответ BT, чтобы создать из него статический метод и включить левое и верхнее положения изображения в ImageView:

/**
 * Returns the bitmap position inside an imageView.
 * @param imageView source ImageView
 * @return 0: left, 1: top, 2: width, 3: height
 */
public static int[] getBitmapPositionInsideImageView(ImageView imageView) {
    int[] ret = new int[4];

    if (imageView == null || imageView.getDrawable() == null)
        return ret;

    // Get image dimensions
    // Get image matrix values and place them in an array
    float[] f = new float[9];
    imageView.getImageMatrix().getValues(f);

    // Extract the scale values using the constants (if aspect ratio maintained, scaleX == scaleY)
    final float scaleX = f[Matrix.MSCALE_X];
    final float scaleY = f[Matrix.MSCALE_Y];

    // Get the drawable (could also get the bitmap behind the drawable and getWidth/getHeight)
    final Drawable d = imageView.getDrawable();
    final int origW = d.getIntrinsicWidth();
    final int origH = d.getIntrinsicHeight();

    // Calculate the actual dimensions
    final int actW = Math.round(origW * scaleX);
    final int actH = Math.round(origH * scaleY);

    ret[2] = actW;
    ret[3] = actH;

    // Get image position
    // We assume that the image is centered into ImageView
    int imgViewW = imageView.getWidth();
    int imgViewH = imageView.getHeight();

    int top = (int) (imgViewH - actH)/2;
    int left = (int) (imgViewW - actW)/2;

    ret[0] = left;
    ret[1] = top;

    return ret;
}
9 голосов
/ 07 марта 2013

Я обнаружил, что предложение WarrenFaith об использовании setAdjustViewBounds сработало, но мне пришлось изменить layout_width / layout_height ImageView на «wrap_content» (с «match_parent» setAdjustViewBounds ничего не делал).Чтобы получить желаемое поведение высоты / ширины / гравитации, мне нужно было обернуть ImageView в FrameLayout:

<FrameLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:scaleType="fitCenter"
        android:adjustViewBounds="true"
        />
</FrameLayout>

. После этого размеры ImageView (возвращаемые getWidth () и getHeight ())соответствует размеру дисплея изображения.

6 голосов
/ 23 октября 2010

Попробуйте

ImageView.getDrawable().getIntrinsicHeight()
ImageView.getDrawable().getIntrinsicWidth()
1 голос
/ 21 июня 2018

Вы можете использовать viewtreeobserver и addonDrawListener.

ViewTreeObserver vto = imageView.getViewTreeObserver();
    vto.addOnDrawListener(new ViewTreeObserver.OnDrawListener() {
        @Override
        public void onDraw() {

            float[] f = new float[9];
            imageView.getImageMatrix().getValues(f);

            // Extract the scale values using the constants (if aspect ratio maintained, scaleX == scaleY)
            final float scaleX = f[Matrix.MSCALE_X];
            final float scaleY = f[Matrix.MSCALE_Y];


            // Get the drawable (could also get the bitmap behind the drawable and getWidth/getHeight)
            final Drawable d = imageView. getDrawable();
            final int origW = d.getIntrinsicWidth();
            final int origH = d.getIntrinsicHeight();

            // Calculate the actual dimensions
            final int actW = Math.round(origW * scaleX);
            final int actH = Math.round(origH * scaleY);

        }
    });
1 голос
/ 25 декабря 2017

Я думаю, вам нужен размер изображения, видимого на экране, для этого вам просто нужно сделать это:

@Override
    public void onWindowFocusChanged(boolean hasWindowFocus) {
        super.onWindowFocusChanged(hasWindowFocus);
        initialWidth = this.getMeasuredWidth();
        initialHeight = this.getMeasuredHeight();
    }

И взгляните на документацию по таким методам, как: getWidht(), getHeight(), getMeasuredWidth(), getMeasuredHeight() и т. Д. *

РЕДАКТИРОВАТЬ: Если вы хотите фактические width и height изображения, загружаемого в imageView. Вы можете изменить вызовы методов с getMeasuredWidth() на getIntrinsicWidth() и getMeasuredHeight() на getIntrinsicHeight() следующим образом:

  Drawable drawable = getDrawable();
  actualWidth = drawable.getIntrinsicWidth();
  actualHeight = drawable.getIntrinsicHeight();
1 голос
/ 26 октября 2010

Я просто проезжаю мимо, но надеюсь, что это все еще помогает. Я предполагаю, что вы говорите о растровых изображениях в вашем imageView

, что вы хотите понять, это разница между

bmpBack.getWidth() -> это дает вам размер вашего растрового изображения и bmpBack.getScaledWidth(canvas);-> это даст вам размер растрового изображения, отображаемого на экране.

Я никогда не использовал ImageView, потому что относительное отображение сводило меня с ума, поэтому в конце я просто переопределил onDraw и сделал свой холст очень похожим образомto opengl.

Я думаю, что это ваша проблема

ура

Джейсон

0 голосов
/ 09 марта 2011

Я искал решение для установки размера представления изображения для масштабированного изображения, чтобы предотвратить пустое пространство сверху / снизу или слева / справа (потому что размер представления не изменяется, чтобы соответствовать масштабированному изображению) .

Я обнаружил, что для этого использовался метод mImageView.setAdjustViewBounds(true);, который дает правильный размер макета. У меня нет масштабированного изображения, но я получил результат, который искал ... просто если кому-то это нужно ...

0 голосов
/ 10 ноября 2010
public class images extends Activity {
ImageView i1;
LinearLayout l1;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
     i1=(ImageView)findViewById(R.id.iv);
     l1 = new LinearLayout(this);
    ImageView i = new ImageView(this);
    ImageView i1 = new ImageView(this);
    i.setImageResource(R.drawable.  imagename.........);

    l1.addView(i);
    l1.addView(i1);
    setContentView(l1);
    }
}

сначала добавьте изображения в папку ресурсов ur ....... и в файле xml создайте представление изображения ....

0 голосов
/ 24 октября 2010

Попробуйте загрузить свой ресурс, используя BitmapFactory.decodeResource (Resources res, int id, опции BitmapFactory.Options) с классом BitmapFactory.Options (). BitmapFactory.Options() имеет флаг, который называется "inJustDecodeBounds" и дает только измерения ресурса.

Надеюсь, это помогло.

...