Android:超大视图中的位图

发布于 2025-01-06 15:06:47 字数 941 浏览 2 评论 0原文

问题描述:
我已经测试了以下两种方法,以便从视图(例如本例中的RelativeLayout)创建位图快照。对于尺寸(例如宽度和高度)小于设备屏幕尺寸(例如 480x900)的视图,这两种方法都非常有效。视图的可见部分被捕获并写入位图中。不幸的是,位图在视图的不可见部分是黑色的。

问题:
如何捕获 View 的不可见部分?

代码:

public class NewRelativeLayout extends RelativeLayout{

private Bitmap bmp;

public NewRelativeLayout(Context context){
    super(context);
    this.setLayoutParams(new RelativeLayout.LayoutParams(2000,2000));
    // add here methods to configure the RelativeLayout or to add children
    }

//This is the first method
public void makeSnapshot_Method1(){
    this.setDrawingCacheEnabled(true);   
    bmp = Bitmap.createBitmap(this.getDrawingCache());   
    this.setDrawingCacheEnabled(false);
    }

//This is the second method
public void makeSnapshot_Method2(){
    bmp = Bitmap.createBitmap(2000, 2000, Bitmap.Config.ARGB_8888);
    Canvas helpCanvas = new Canvas(bmp);
    this.draw(helpCanvas);
    }

}

PROBLEM DESCRIPTION:
I have tested the following two methods, in order to create a bitmap snaphot from a View (e.g. a RelativeLayout in this case). Both methods work excellent for Views which dimensions (e.g. width and height) are less than the dimensions of the device screen (e.g. 480x900). The visible part of the View is captured and written into the bitmap. Unfortunately, the bitmap is black in the unvisible part of the View.

QUESTION:
How can I capture also the unvisible part of the View ?

CODE:

public class NewRelativeLayout extends RelativeLayout{

private Bitmap bmp;

public NewRelativeLayout(Context context){
    super(context);
    this.setLayoutParams(new RelativeLayout.LayoutParams(2000,2000));
    // add here methods to configure the RelativeLayout or to add children
    }

//This is the first method
public void makeSnapshot_Method1(){
    this.setDrawingCacheEnabled(true);   
    bmp = Bitmap.createBitmap(this.getDrawingCache());   
    this.setDrawingCacheEnabled(false);
    }

//This is the second method
public void makeSnapshot_Method2(){
    bmp = Bitmap.createBitmap(2000, 2000, Bitmap.Config.ARGB_8888);
    Canvas helpCanvas = new Canvas(bmp);
    this.draw(helpCanvas);
    }

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

七秒鱼° 2025-01-13 15:06:47

我也在寻找这个问题的解决方案,最后,设法想出了我自己的解决方案,实际上非常简单。

就我而言,我有一个 LinearLayout,其中包含许多 View 元素,其中一些元素有时不在屏幕上,位于屏幕边界末端的垂直下方。我能够将View另存为位图(请参阅下面的loadBitmapFromView()),但当它超出屏幕底部时遇到了麻烦。

我的解决方案是使 LinearLayout 成为 ScrollView 组合的一部分。

例如

这:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/my_linear_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
 >
<!-- Some Views added here at runtime -->
</LinearLayout>

成为:

请注意使用 wrap_content 以确保 ScrollView 缩放到内容的高度。

<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/scroll"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content" 
    >

    <LinearLayout
        android:id="@+id/my_linear_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
     >
        <!-- Some Views added here at runtime -->
    </LinearLayout>
</ScrollView>

这似乎确保了当我想将 View 保存为位图时,可以手动布置屏幕外的项目。我使用以下方法来保存位图。我很早就发现了这个问题,但我似乎找不到这个问题以便正确引用它(无论你是谁 - 谢谢!)。

对于以下方法,我传入对上面的 LinearLayout 的引用 (my_linear_layout)。

public static Bitmap loadBitmapFromView(View view) {
    Bitmap bitmap = null;

    // width measure spec
    int widthSpec = View.MeasureSpec.makeMeasureSpec(
            view.getMeasuredWidth(), View.MeasureSpec.AT_MOST);
    // height measure spec
    int heightSpec = View.MeasureSpec.makeMeasureSpec(
            view.getMeasuredHeight(), View.MeasureSpec.AT_MOST);

    // measure the view
    view.measure(widthSpec, heightSpec);

    // set the layout sizes
    int left = view.getLeft();
    int top = view.getTop();
    int width = view.getMeasuredWidth();
    int height = view.getMeasuredHeight();
    int scrollX = view.getScrollX();
    int scrollY = view.getScrollY();

    view.layout(left, top, width + left, height + top);

    // create the bitmap

    bitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(),
            Bitmap.Config.ARGB_8888);

    // create a canvas used to get the view's image and draw it on the
    // bitmap

    Canvas c = new Canvas(bitmap);
    // position the image inside the canvas
    c.translate(-view.getScrollX(), -view.getScrollY());
    // get the canvas
    view.draw(c);

    return bitmap;
}

I was searching for the solution to this too and, in the end, managed to come up with my own solution which is actually quite simple.

In my case, I had a LinearLayout which contained a number of View elements, some of which sometimes were not on screen, vertically below the end of the screen bounds. I was able to save the View as a Bitmap (see loadBitmapFromView(), below) but had trouble when it extended beyond the bottom of the screen.

My solution was to make the LinearLayout part of a ScrollView composite.

e.g.

This:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/my_linear_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
 >
<!-- Some Views added here at runtime -->
</LinearLayout>

Became:

Note use of wrap_content to ensure ScrollView scales to the height of your content.

<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/scroll"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content" 
    >

    <LinearLayout
        android:id="@+id/my_linear_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
     >
        <!-- Some Views added here at runtime -->
    </LinearLayout>
</ScrollView>

This seemed to ensure that the offscreen items could be manually laid out when I wanted to save the View as a bitmap. I used the following method to save the bitmap. I found this much earlier on SO but I can't seem to find the question in order to reference it properly (whoever you are - thank you!).

For the following method, I pass in a reference to the LinearLayout above (my_linear_layout).

public static Bitmap loadBitmapFromView(View view) {
    Bitmap bitmap = null;

    // width measure spec
    int widthSpec = View.MeasureSpec.makeMeasureSpec(
            view.getMeasuredWidth(), View.MeasureSpec.AT_MOST);
    // height measure spec
    int heightSpec = View.MeasureSpec.makeMeasureSpec(
            view.getMeasuredHeight(), View.MeasureSpec.AT_MOST);

    // measure the view
    view.measure(widthSpec, heightSpec);

    // set the layout sizes
    int left = view.getLeft();
    int top = view.getTop();
    int width = view.getMeasuredWidth();
    int height = view.getMeasuredHeight();
    int scrollX = view.getScrollX();
    int scrollY = view.getScrollY();

    view.layout(left, top, width + left, height + top);

    // create the bitmap

    bitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(),
            Bitmap.Config.ARGB_8888);

    // create a canvas used to get the view's image and draw it on the
    // bitmap

    Canvas c = new Canvas(bitmap);
    // position the image inside the canvas
    c.translate(-view.getScrollX(), -view.getScrollY());
    // get the canvas
    view.draw(c);

    return bitmap;
}
嘿哥们儿 2025-01-13 15:06:47

取决于您要捕获哪个图像,视图背景或前景的图像。无论哪种方式,您都必须从它们获取 Drawable 对象,将它们转换为 BitmapDrawable 并从它们获取 Bitmap。
代码:-

BitmapDrawable bd=(BitmapDrawable) view.getBackground(); //if you need background image
BitmapDrawable bd=(BitmapDrawable) view.getDrawable(); //if you need foreground image (Only available to some views who have an android:src xml property)
Bitmap bm=bd.getBitmap();

我希望这对您有用。

Depends upon which image you want to capture, the image from view's background or foreground. Either way you have to get the Drawable object from them, cast them to BitmapDrawable and get the Bitmap from their.
Code:-

BitmapDrawable bd=(BitmapDrawable) view.getBackground(); //if you need background image
BitmapDrawable bd=(BitmapDrawable) view.getDrawable(); //if you need foreground image (Only available to some views who have an android:src xml property)
Bitmap bm=bd.getBitmap();

I hope this will work for you.

日暮斜阳 2025-01-13 15:06:47

我还试图为 ListView 解决这个问题,以获取不在屏幕上的所有行。

我发现了很多我想分享的东西:

这里有人问是否可以从未绘制的视图创建位图:
View 中的位图未显示在 Android 上

在这里,他们声称这是重复的,并且它也得到了正确的回答(?)它包含一个 URL,其中包含一些旧的且无法编译的编码。此外,可能的重复问题对我没有帮助。
Android 获得完整的位图视图

我想我会尝试通过这个方法:
使用位图的列表视图
已经提出了同样的想法,现在我仍然需要探索如何实现。

希望您可以使用其中一些信息。

I'm also trying to figure this out for a ListView, to get all rows that are not on screen.

I have found lots of things I would like to share:

Here someone asks if a bitmap can be created from a view that's not drawn:
Bitmap from View not displayed on Android

Here they claim it's a duplicate and it's also answered correctly (?) It contains a URL with some coding that's old and doesn't compile. Also the possible duplicate question didn't help me.
Android get full View as Bitmap

I think I will try to get it done via this method:
List View using bitmap
Already came up with the same idea, now I still have to discover how.

Hope you can use some of this info.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文