如何通过自定义左侧和顶部坐标填充 ImageView 中的图像 | Android

How to populate Image inside ImageView by custom left and top coordinate | Android

我需要在框架内显示一些图像 (多个图像框架),我有 lefttop coordinates对应每个Image.

例如,我有图像坐标 100 从左边和 100 从顶部,所以我需要做的只是在 ImageView 中显示图像(100,100).

开始

谁能告诉我如何在没有位图的情况下做到这一点,因为我需要在 RecyclerView[=55= 中显示包含多个图像的帧列表].

我已使用 TouchImageView.class 缩放和移动功能来创建框架。

1.下面是我选择布局时的屏幕截图,你可以清楚地看到两张图片彼此非常接近。我的意思是我选择了每张图片的一半。

2。接下来是我需要重新绘制该图像的主屏幕,我有 images.But 的左坐标和上坐标我如何通过一些自定义 x 和 y 在 ImageView 中绘制该图像。

用于在 ImageView 中从左侧和顶部填充图像的代码片段 -

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

但还是不行。

请给我一些建议,我已经进行了 google 搜索,但没有找到适合我要求的解决方案。

非常感谢您的建议。

非常感谢。

亲切的问候。

听起来您想拍摄两张图片并根据两张图片的某种组合创建一张新图片。

有很多不同的方法可以解决这个问题。最直接的方法涉及使用位图。我可以看到两种主要方法可以直接实现此目的。

  1. 将您的图像视图按照您喜欢的方式放置在某个公共父级中,并创建该父级的位图以用作生成的图像。

  2. 通过根据您自己的计算绘制图像视图的图像来自己创建位图,该计算应模仿您拥有的布局结构。

由于您似乎已经按照您希望生成的图像看起来的方式在屏幕上显示了两个图像,因此第一个将是最直接的,不需要您重做计算您的布局和图像视图已经在执行。

我们要做的是利用这样一个事实,即每个视图都会将自己绘制到 canvas 上,最终只是将自己转化为图像本身。要获得父布局的位图,您只需创建一个相同大小的位图,然后告诉父布局将自己绘制到位图的 canvas 上,如下所示:

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

但是,如果您不想被父布局绘制到屏幕上的内容所束缚,您可以通过将图像绘制到类似的 canvas 上来创建所需的位图。在这里,我实现了您问题中的第一个布局:

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 等来优化这一点,并通常简化您的计算。但是您可以使用这种方法将您的任何布局重新创建到单个位图上,您只需要更改计算即可。

我们正在做的是首先创建一个位图,其宽度为第一个图像的一半加上第二个图像的一半,高度为两个图像中最小图像的高度。然后我们取第一张图像的一部分,即最左边的半宽度和与结果高度一样高的部分,我们将其绘制到我们的结果上。然后我们对第二张图片做同样的事情,除了这次部分是最右边的半宽度。

希望这对您有所帮助。

更新:我在这个 post 的末尾添加了一个示例应用程序来说明这个概念。

第二次更新:向示例应用添加了一些代码以适应 xy 缩放

我已经更改了示例应用程序以包含将适合图像的代码,无论是小于还是大于 ImageView,以适应视图大小,同时尊重宽高比。这可能不是您要找的东西,但它应该能让您进入大致范围。这是示例代码,因此在实际应用程序中肯定还有其他内容。例如,xScaleyScale 在极端情况下可能会变为负数。我不确定如果他们这样做会发生什么,但可能会导致崩溃,因此需要进行边界检查。


如果我明白你想做什么,你想要一个固定大小的 ImageView 来显示一个图像的不同部分 通过将图像的自定义 (x,y) 坐标设置为位于 ImageView 的 (0,0) 坐标来放大图像。 这基本上是对图像的顶部和左侧边缘进行裁剪。

可能有很多不同的方法可以做到这一点,哪一种最适合您将取决于您的具体需求, 但这是一种方式:

在您的代码中使用以下内容或一些变体:

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" />

希望对您有所帮助。

示例应用程序

这是此概念的快速模型。此应用程序由主要 activity 和一个布局组成。您必须提供作为 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>

我不得不承认我不是 100% 确定我明白你想做什么。如果我理解正确,你需要的是将 ImageView 放在另一个元素中(我展示了一个带有 FrameLayout 的示例,但你也可以使用 LinearLayoutRelativeLayout)。然后在外部元素上设置填充。

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

如果我明白你想做什么,这就可以了。

您可以通过合并位图轻松地做到这一点。

我创建了一个测试项目,它使用 Glide 加载 2 个图像位图,然后使用 canvas 将它们合并为一个 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);
                                    }
                                });
                    }
                });

您可以从我的 GitHub 下载整个项目

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

最终我找到了问题的解决方案 -

感谢您提供的所有帮助。

所以,基本上我有视图高度视图宽度顶部坐标左坐标原始图像高度原始图像宽度.

  1. 我需要计算关于 ViewImage.[=48 的 aspect factor =]

这是公式 -

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