当前位置: 首页 > 知识库问答 >
问题:

收缩缩放图像视图-想要将整个图像缩放到超出屏幕大小

叶展
2023-03-14

我对图像进行了收缩缩放,但是当我第一次加载应用程序时,整个图像不可见,只有一部分。图像填充了屏幕的宽度,但其上下都有空白。此外,当缩放图像时,图像变得非常短。纵横比应保持不变。

我希望在应用程序加载时使整个图像可见,然后我希望能够用两根手指缩小图像,其中图像不会小于屏幕的大小,以便屏幕始终充满(图像是地图)。

为了放大,图像应该超出手机屏幕的宽度和高度。这样我就可以平移过去查看地图的细节。

任何帮助都将不胜感激。相关代码如下。

我的主要活动代码:

public class MainActivity extends Activity
{
    private MapView image;
    private Matrix matrix = new Matrix();

    float mLastTouchX, mPosX;
    float mLastTouchY, mPosY;

    private ScaleGestureDetector mScaleDetector;
    private float mScaleFactor = 1f;

    private int mActivePointerId = MotionEvent.INVALID_POINTER_ID;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        image = (MapView)findViewById(R.id.imageView1);
        mScaleDetector = new ScaleGestureDetector(MainActivity.this, new ScaleListener());
    }

    public void onDraw(Canvas canvas)
    {
        canvas.save();

        canvas.scale(mScaleFactor, mScaleFactor);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu)
    {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item)
    {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings)
        {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }



    @Override
    public boolean onTouchEvent(MotionEvent event)
    {
        mScaleDetector.onTouchEvent(event);

        final int action = MotionEventCompat.getActionMasked(event);

        switch (action)
        {
            case MotionEvent.ACTION_DOWN:
            {
                final int pointerIndex = MotionEventCompat.getActionIndex(event);
                final float x = MotionEventCompat.getX(event, pointerIndex);
                final float y = MotionEventCompat.getY(event, pointerIndex);

                // Remember where we started (for dragging)
                mLastTouchX = x;
                mLastTouchY = y;
                // Save the ID of this pointer (for dragging)
                mActivePointerId = MotionEventCompat.getPointerId(event, 0);
                break;
            }

            case MotionEvent.ACTION_MOVE:
            {
                // Find the index of the active pointer and fetch its position
                final int pointerIndex =
                        MotionEventCompat.findPointerIndex(event, mActivePointerId);

                final float x = MotionEventCompat.getX(event, pointerIndex);
                final float y = MotionEventCompat.getY(event, pointerIndex);

                // Calculate the distance moved
                final float dx = x - mLastTouchX;
                final float dy = y - mLastTouchY;

                mPosX += dx;
                mPosY += dy;

                // Remember this touch position for the next move event
                mLastTouchX = x;
                mLastTouchY = y;

                break;
            }

            case MotionEvent.ACTION_UP:
            {
                mActivePointerId = MotionEvent.INVALID_POINTER_ID;
                break;
            }

            case MotionEvent.ACTION_CANCEL:
            {
                mActivePointerId = MotionEvent.INVALID_POINTER_ID;
                break;
            }

            case MotionEvent.ACTION_POINTER_UP:
            {
                final int pointerIndex = MotionEventCompat.getActionIndex(event);
                final int pointerId = MotionEventCompat.getPointerId(event, pointerIndex);

                if (pointerId == mActivePointerId)
                {
                    // This was our active pointer going up. Choose a new
                    // active pointer and adjust accordingly.
                    final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
                    mLastTouchX = MotionEventCompat.getX(event, newPointerIndex);
                    mLastTouchY = MotionEventCompat.getY(event, newPointerIndex);
                    mActivePointerId = MotionEventCompat.getPointerId(event, newPointerIndex);
                }
                break;
            }
        }

        image.setX(mPosX);
        image.setY(mPosY);

        return true;
    }

    private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener
    {
        @Override
        public boolean onScale(ScaleGestureDetector detector)
        {
            mScaleFactor *= detector.getScaleFactor();
            mScaleFactor = Math.max(0.1f, Math.min(mScaleFactor, 5.0f));

            matrix.setScale(mScaleFactor, mScaleFactor);
            image.setImageMatrix(matrix);

            return true;
        }
    }
}

自定义图像视图:

public class MapView extends ImageView
{
    public MapView(final Context context, final AttributeSet attrs)
    {
        super(context, attrs);
    }

    public void scaleImage(int boundBoxInDp)
    {
        Drawable drawable = getDrawable();
        Bitmap bitmap = ((BitmapDrawable)drawable).getBitmap();

        int width = bitmap.getWidth();
        int height = bitmap.getHeight();

        float xScale = ((float) boundBoxInDp) / width;
        float yScale = ((float) boundBoxInDp) / height;
        float scale = (xScale <= yScale) ? xScale : yScale;

        Matrix matrix = new Matrix();
        matrix.postScale(scale, scale);

        Bitmap scaledBitmap = Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, true);
        BitmapDrawable result = new BitmapDrawable(scaledBitmap);
        width = scaledBitmap.getWidth();
        height = scaledBitmap.getHeight();

        // Apply the scaled bitmap
        setImageDrawable(result);

        // Now change ImageView's dimensions to match the scaled image
        LinearLayout.LayoutParams params = (LinearLayout.LayoutParams)getLayoutParams();
        params.width = width;
        params.height = height;
        setLayoutParams(params);
    }

    private int dpToPx(Context c, int dp)
    {
        float density = c.getResources().getDisplayMetrics().density;
        return Math.round((float)dp * density);
    }

    @Override
    protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec)
    {
        final Drawable d = this.getDrawable();

        if (d != null)
        {
            // ceil not round - avoid thin vertical gaps along the left/right edges
            final int width = MeasureSpec.getSize(widthMeasureSpec);
            final int height = (int) Math.ceil(width * (float) d.getIntrinsicHeight() / d.getIntrinsicWidth());
            this.setMeasuredDimension(width, height);
        }
        else
        {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        }
    }
}

布局文件:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                xmlns:tools="http://schemas.android.com/tools"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:paddingLeft="@dimen/activity_horizontal_margin"
                android:paddingRight="@dimen/activity_horizontal_margin"
                android:paddingTop="@dimen/activity_vertical_margin"
                android:paddingBottom="@dimen/activity_vertical_margin"
                tools:context=".MainActivity">

    <com.kilobolt.framework.locationfinder.MapView
        android:id="@+id/imageView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:scaleType="matrix"
        android:src="@drawable/uea" />

</RelativeLayout>

共有1个答案

巫马刚洁
2023-03-14

我采取了不同的方法来解决显示自定义地图的问题。我没有显示固定大小的图像,而是使用了Google Maps Javascript API v3(https://developers.google.com/maps/documentation/javascript/examples/marker-simple)。

我将它显示在web视图中,并在javascript中创建了一个可重用的函数来创建自定义标记。

如果有人遇到这个问题,这似乎没有很好的文档记录,请尝试这个地图解决方案,并随时给我发消息。希望这有帮助。

 类似资料:
  • 问题内容: 我想拍摄一张图像并更改图像的比例,虽然它是一个numpy数组。 例如,我有一个可口可乐瓶的图像: bottle-1 转换为一个numpy的形状数组,我想调整其大小以表示第二个图像的大小: bottle-2 形状为。 如何在保持原始图像的同时将图像尺寸更改为特定形状?其他答案建议每隔一行或第三行剥离,但是我想要做的基本上是像通过图像编辑器(但在python代码中)那样收缩图像。是否有任何

  • 以下是CardView的XML代码: 我尝试对ImageView(和LinearLayout)的属性使用wrap_content,并尝试包含属性android: caleType="fitXY",但它没有帮助,似乎没有任何效果。 谁能帮我一下吗?我非常感谢您的每一句评论,也非常感谢您的帮助。

  • 我有一个无法解决的问题... 我有一个自定义的imageview,它会根据更大的尺寸改变大小——包含该视图的布局的宽度或高度。它的工作方式总是适合布局。 它的布局是这样的: 我正在努力实现的是,我有尺寸为1000x1000px的原始地图。在这张地图上,我有一些点。我必须在Android上显示这张地图,并在与原始地图相同的点上添加其他视图。 所以举个例子: > 原始地图为1000x1000px 我用

  • 问题内容: 改变的大小的图像在GWT部件改变所述图像元素的大小,但不重新调整屏幕上的图像。因此,以下操作将无效: 这是因为GWT 通过使用CSS 将HTML 元素的设置为图像来实现其Image小部件。 如何获得要调整尺寸的实际图像? 问题答案: 我看到了此博客条目,该条目通过使用GWT DataResource而不是ImageResource解决了问题。事实证明,如果您按以下方式使用它,则Imag