Как заполнить изображение внутри ImageView по пользовательской левой и верхней координате | Android

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

например, у меня есть координаты изображения 100 слева и 100 сверху, поэтому мне нужно просто показать изображение внутри ImageView, который начинается с (100,100).

может кто-нибудь сказать мне, как я могу сделать это без Bitmap, потому что мне нужно показать список кадров с несколькими изображениями внутри RecyclerView.

я использовал TouchImageView.class для функции масштабирования и перемещения для создания кадра.

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

enter image description here

2. Далее на главном экране, на котором мне нужно воспроизвести это изображение, у меня есть левая и верхняя координаты обоих изображений.Но как я могу построить это изображение внутри ImageView с помощью некоторых пользовательских x и y.

enter image description here

фрагмент кода для заполнения изображения внутри ImageView слева и сверху -

 img.setPadding((int) x, (int) y, 0, 0);

но все равно не работает.

пожалуйста, предложите мне что-то, я сделал поиск google, но не получил соответствующего решение для моего требования.

предложения действительно оценили.

заранее большое спасибо.

С Уважением.

5 ответов


Update: я добавил пример приложения в конце этого сообщения, чтобы проиллюстрировать эту концепцию.

второе обновление: добавлен код для образца приложения для размещения XY scaling

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


если я понимаю, что вы пытаетесь сделать, вы хотите, чтобы ImageView фиксированного размера показывал разные части увеличьте изображение, установив пользовательские (x,y) координаты изображения, чтобы сидеть на (0,0) координата ImageView. Это в основном обрезка изображения по верхнему и левому краям.

вероятно, есть много разных способов сделать это, и какой из них лучше всего подходит для вас, будет зависеть от ваших точных потребностей, но есть один способ:--19-->

используйте в коде следующее или несколько вариантов:

float xOffset = -100;
float yOffset = -100;
ImageView imageView = (ImageView) findViewById(R.id.shiftedView);
Matrix matrix = new Matrix();

matrix.setTranslate(xOffset, yOffset);
imageView.setImageMatrix(matrix);

настройте свой ImageView примерно следующим образом. Ключ здесь android:scaleType="matrix"

<ImageView
    android:id="@+id/shiftedView"
    android:layout_width="200dp"
    android:layout_height="match_parent"
    android:background="#FF00CCCC"
    android:scaleType="matrix"
    android:src="@drawable/image" />

надеюсь, это поможет вы.

Образец Приложение

вот быстрый макет этой концепции. Это приложение состоит из основной деятельности и одного макета. Вам нужно будет предоставить изображение, которое является источником для ImageView чтобы увидеть, как это работает.

семь кнопок будут перемещать изображение влево, вправо, вверх и вниз по щелчку в макете ImageView. Кнопки" Fit X "и" Fit Y " масштабируют изображение до соответствующего размера, доступного в пределах ImageView. Кнопка "Сброс" установит изображение обратно в исходную настройку по умолчанию ImageView.

MainActivity.java

package com.example.imageshift;

import android.graphics.Matrix;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.ImageView;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    ImageView imageView;
    float xOffset = 0f;
    float yOffset = 0f;
    float xScale = 1.0f;
    float yScale = 1.0f;

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

        imageView = (ImageView) findViewById(R.id.shiftedView);
        findViewById(R.id.shiftUp).setOnClickListener(this);
        findViewById(R.id.shiftDown).setOnClickListener(this);
        findViewById(R.id.shiftLeft).setOnClickListener(this);
        findViewById(R.id.shiftRight).setOnClickListener(this);
        findViewById(R.id.shiftReset).setOnClickListener(this);
        findViewById(R.id.fitX).setOnClickListener(this);
        findViewById(R.id.fitY).setOnClickListener(this);
    }

    public void doMatrixTransformations() {
        Matrix matrix = new Matrix();

        matrix.setTranslate(xOffset, yOffset);
        matrix.postScale(xScale, yScale);
        imageView.setImageMatrix(matrix);
    }

    @Override
    public void onClick(View view) {
        final int shiftAmount = 50;

        switch (view.getId()) {
            case R.id.shiftUp:
                yOffset -= shiftAmount;
                break;
            case R.id.shiftDown:
                yOffset += shiftAmount;
                break;

            case R.id.shiftLeft:
                xOffset -= shiftAmount;
                break;

            case R.id.shiftRight:
                xOffset += shiftAmount;
                break;

            case R.id.fitX:
                xScale = (float) imageView.getWidth() / (
                        (float) imageView.getDrawable().getIntrinsicWidth() + xOffset);
                yScale = xScale;
                break;

            case R.id.fitY:
                yScale = (float) imageView.getHeight() /
                        ((float) imageView.getDrawable().getIntrinsicHeight() + yOffset);
                xScale = yScale;
                break;

            case R.id.shiftReset:
                xOffset = 0;
                yOffset = 0;
                xScale = 1.0f;
                yScale = 1.0f;
                break;
        }
        doMatrixTransformations();
    }
}

activity_main.в XML

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.imageshift.MainActivity">

    <ImageView
        android:id="@+id/shiftedView"
        android:layout_width="200dp"
        android:layout_height="match_parent"
        android:layout_marginLeft="0dp"
        android:layout_marginTop="0dp"
        android:padding="2dp"
        android:scaleType="matrix"
        android:src="@drawable/image" />

    <Button
        android:id="@+id/shiftUp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="20dp"
        android:layout_toRightOf="@id/shiftedView"
        android:text="Up" />

    <Button
        android:id="@+id/shiftDown"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/shiftUp"
        android:layout_marginLeft="20dp"
        android:layout_toRightOf="@id/shiftedView"
        android:text="Down" />

    <Button
        android:id="@+id/shiftLeft"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/shiftDown"
        android:layout_marginLeft="20dp"
        android:layout_toRightOf="@id/shiftedView"
        android:text="Left" />

    <Button
        android:id="@+id/shiftRight"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/shiftLeft"
        android:layout_marginLeft="20dp"
        android:layout_toRightOf="@id/shiftedView"
        android:text="Right" />

    <Button
        android:id="@+id/fitX"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/shiftRight"
        android:layout_marginLeft="20dp"
        android:layout_toRightOf="@id/shiftedView"
        android:text="Fit X" />

    <Button
        android:id="@+id/fitY"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/fitX"
        android:layout_marginLeft="20dp"
        android:layout_toRightOf="@id/shiftedView"
        android:text="Fit Y" />

    <Button
        android:id="@+id/shiftReset"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/fitY"
        android:layout_marginLeft="20dp"
        android:layout_toRightOf="@id/shiftedView"
        android:text="Reset" />

</RelativeLayout>

похоже, вы хотите взять два изображения и создать новое изображение на основе некоторой комбинации двух изображений.

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

  1. расположите изображения, как вам нравится, в каком-то общем родителе и создайте растровое изображение этого родителя для использования в качестве результата изображение.

  2. создайте растровое изображение самостоятельно, рисуя изображения ваших imageviews на основе ваших собственных вычислений, которые должны имитировать структуру макета у вас есть.

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

private Bitmap getCombinedBitmap(View parentView) {
    Bitmap result = Bitmap.createBitmap(parentView.getWidth(), parentView.getHeight(), Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(result);
    parentView.draw(canvas);

    return result;
}

Если, однако, вы не хотели бы быть связаны только тем, что родительский макет рисует к экран, вы можете создать растровое изображение, которое вы хотите, рисуя изображения на аналогичном холсте. Здесь я реализовал первый макет из вашего вопроса:

private Bitmap getCombinedBitmap(Bitmap a, Bitmap b) {
    int aWidth = a.getWidth() / 2;
    int bWidth = b.getWidth() / 2;
    int resultHeight = a.getHeight() < b.getHeight()?  a.getHeight() : b.getHeight();
    Bitmap result = new Bitmap(aWidth + bWidth, resultHeight, Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(result);

    Rect aRect = new Rect(0, 0, aWidth, resultHeight);
    Rect aResultRect = new Rect(0, 0, aWidth, resultHeight);
    canvas.drawBitmap(a, aRect, aResultRect);

    Rect bRect = new Rect(0, 0, bWidth, resultHeight);
    Rect bResultRect = new Rect(bWidth, 0, bWidth, resultHeight);
    canvas.drawBitmap(b, bRect, bResultRect);

    return result;
}

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

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

надеюсь, что это помогает.


Я должен признать, что я не на 100% уверен, что я понимаю, что вы хотите сделать. Если я правильно понимаю, вам нужно поставить ImageView внутри другого элемента (я показываю пример с FrameLayout но вы могли бы использовать LinearLayout или RelativeLayout тоже). Затем вы устанавливаете прокладку на внешнем элементе.

<!-- we put the ImageView inside a Frame so that we can change -->
<!--    the padding size to create borders -->
<FrameLayout
    android:layout_width="140dp"
    android:layout_height="140dp"
    android:id="@+id/image_frame"
    >
    <ImageView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/image_view"
        />
</FrameLayout>

затем в коде: (используйте frame вместо img)

FrameLayout frame = (FrameLayout)itemLayout.findViewById(R.id.image_frame);
frame.setPadding((int) x, (int) y, 0, 0);

если я понимаю, что вы хотите сделать, это сделает это.


вы можете сделать это легко, объединив растровые изображения.

Я создал тестовый проект, который загружает 2 растровых изображения с Glide и затем объединяет их в один BitMap используя canvas, а затем установите его на любой ImageView.

вы также можете сохранить изображение в файл на SD карту, чтобы избежать тяжелых вычислений. Это выглядит так (Gif - https://github.com/hiteshsahu/Android-Merge-Bitmaps-With-Glide/blob/master/Art/demo.gif ):-

enter image description here

я использовал один вид изображения в качестве фона моего макета кадра, и я использовал панель поиска, чтобы изменить относительное положение плаката фильма Raees. Вы можете изменить координаты начала X и Y любого из растровых изображений, используя эти панели поиска.

как я это сделал:-

Это фрагмент кода, как я это сделал. Это самоочевидно

 Glide.with(context)
                .load(R.drawable.raees)
                .asBitmap()
                .into(new SimpleTarget<Bitmap>() {
                    @Override
                    public void onResourceReady(Bitmap resource, GlideAnimation<? super Bitmap> glideAnimation) {

                        // Add Bitmap in Array and load next bitmap
                        arts[0] = resource;

                        Glide.with(context)
                                .load(R.drawable.raees_edited)
                                .asBitmap()
                                .into(new SimpleTarget<Bitmap>() {
                                    @Override
                                    public void onResourceReady(Bitmap resource1, GlideAnimation<? super Bitmap> glideAnimation) {

                                        // Both Bitmap loaded do the Merging
                                        arts[1] = resource1;

                                        //Set seekbars Max
                                        satrtX1SeekBar.setMax(arts[0].getWidth());
                                        satrtX2SeekBar.setMax(arts[1].getWidth());
                                        satrtY1SeekBar.setMax(arts[0].getHeight());
                                        satrtY2SeekBar.setMax(arts[1].getHeight());

                                        Bitmap bmOverlay = Bitmap.createBitmap(arts[0].getWidth(), arts[0].getHeight(), Bitmap.Config.ARGB_8888);
                                        Canvas canvas = new Canvas(bmOverlay);

                                        if (shouldDrawLeftHalf) {
                                            // Rect(left, top, right, bottom)
                                            canvas.drawBitmap(arts[0],
                                                    new Rect(0, 0, arts[0].getWidth() / 2, arts[0].getHeight()),
                                                    new Rect(0, 0, arts[0].getWidth() / 2, arts[0].getHeight()), null);

                                        } else {
                                            canvas.drawBitmap(arts[0], startX1, startY1, null);
                                        }

                                        if (shouldDrawRightHalf) {
                                            // Rect(left, top, right, bottom)
                                            canvas.drawBitmap(arts[1],
                                                    new Rect(arts[1].getWidth() / 2, 0, arts[0].getWidth(), arts[1].getHeight()),
                                                    new Rect(arts[1].getWidth() / 2, 0, arts[1].getWidth(), arts[1].getHeight()), null);
                                        } else {
                                            canvas.drawBitmap(arts[1], startX2, startY2, null);
                                        }


                                        background.setImageBitmap(bmOverlay);

                                        // saveToDisk("Test", bmOverlay);
                                    }
                                });
                    }
                });

вы можете скачать весь проект с моего GitHub

https://github.com/hiteshsahu/Android-Merge-Bitmaps-With-Glide


В конце концов я нашел решение моего вопроса -

Спасибо за помощь.

Итак, в основном у меня есть посмотреть высота, посмотреть ширина, верхняя координата, левая координата, Высота Исходного Изображения и Оригинальная Ширина Изображения.

  1. мне нужно вычислить аспект-фактор о посмотреть и изображения.

вот формула для этого -

 float newAspectFactor = 0;


 if (viewHeight > viewWidth) {
 //Aspect factor for Height
 newAspectFactor = viewHeight / bean.getPostMedia().get(i).getImg_height();

 } else {
 //Aspect factor for Width
 newAspectFactor = viewWidth / bean.getPostMedia().get(i).getImg_width();
 }

 float imgNewHeight = newAspectFactor * imageHeight;
 float imgNewWidth = newAspectFactor * imageWidth;
 Logger.logsError(TAG, " Image New Height : " + imgNewHeight);
 Logger.logsError(TAG, " Image New Width : " + imgNewWidth);

 if (imgNewHeight < viewHeight) {
 newAspectFactor = viewHeight / bean.getPostMedia().get(i).getImg_height();
 } else if (imgNewWidth < viewWidth) {
 newAspectFactor = viewWidth / bean.getPostMedia().get(i).getImg_width();
 }
  1. Top и Left координаты.

                float x = 42.0;
                float y = 0.0;
    
  2. магия начинается здесь.

                Matrix m = img.getImageMatrix();
                RectF drawableRect = new RectF(x,
                        y,
                        ((x * newAspectFactor) + viewWidth) / newAspectFactor,
                        imageHeight);
                RectF viewRect = new RectF(0,
                        0,
                        viewWidth,
                        viewHeight);
                m.setRectToRect(drawableRect, viewRect, Matrix.ScaleToFit.FILL);
                img.setImageMatrix(m);
                img.setScaleType(ImageView.ScaleType.MATRIX);
                imageLoaderNew.displayImage("IMAGE URL", img, optionsPostImg);