Подтвердить что ты не робот

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

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

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

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

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

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

введите описание изображения здесь

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

введите описание изображения здесь

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

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

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

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

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

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

С уважением.

4b9b3361

Ответ 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. Верхняя и левая координаты.

                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);
    

Ответ 2

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

Второе обновление: добавлен некоторый код для примера приложения для размещения масштабирования xy

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


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

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

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

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. Кнопка "Reset" вернет исходное значение по умолчанию 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>

Ответ 3

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

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

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

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

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

То, что мы собираемся сделать, - это воспользоваться тем фактом, что каждое представление будет нарисовано на холсте, а в конце дня просто преобразуется в само изображение. Чтобы получить растровое изображение вашего родительского макета, вы можете просто создать растровое изображение того же размера, а затем сообщить родительскому макету, чтобы он нарисовал себя на холсте растрового изображения, например:

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;
}

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

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

Надеюсь, что это поможет.

Ответ 4

Я должен признать, что я не уверен на 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);

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

Ответ 5

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

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

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

введите описание изображения здесь

Я использовал одно изображение в качестве фона моего макета кадра, и я использовал панель поиска, чтобы изменить относительное положение рекламного ролика 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);
                                    }
                                });
                    }
                });

Вы можете загрузить весь проект из My GitHub

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