截取整个视图的屏幕截图

时间:2012-03-20 17:17:16

标签: android screenshot

我已经构建了一个表,它基本上由HorizontalScrollView内的ScrollView完成。我让用户可以编辑字段。

现在我想将表保存在屏幕上,jpg,png,pdf或其他任何内容。

问题是 - 桌子几乎总是比屏幕大。

有没有办法制作整个ScrollView布局的屏幕截图?如果不是你认为可以做什么工作?

15 个答案:

答案 0 :(得分:61)

其实我找到了答案:

public static Bitmap loadBitmapFromView(View v, int width, int height) {
    Bitmap b = Bitmap.createBitmap(width , height, Bitmap.Config.ARGB_8888);                
    Canvas c = new Canvas(b);
    v.layout(0, 0, v.getLayoutParams().width, v.getLayoutParams().height);
    v.draw(c);
    return b;
}

答案 1 :(得分:17)

  ScrollView iv = (ScrollView) findViewById(R.id.scrollView);
  Bitmap bitmap = Bitmap.createBitmap(
        iv.getChildAt(0).getWidth(), 
        iv.getChildAt(0).getHeight(), 
        Bitmap.Config.ARGB_8888);
  Canvas c = new Canvas(bitmap);
  iv.getChildAt(0).draw(c);

  // Do whatever you want with your bitmap
  saveBitmap(bitmap);

答案 2 :(得分:9)

在我的情况下使用@softwaresupply回答导致问题,我的视图重新绘制并变为完全白色。有一个更简单的解决方案来获取屏幕截图,您甚至不必提供宽度和高度作为参数。 使用绘图缓存

public static Bitmap loadBitmapFromView(View v) {
    Bitmap bitmap;
    v.setDrawingCacheEnabled(true);
    bitmap = Bitmap.createBitmap(v.getDrawingCache());
    v.setDrawingCacheEnabled(false);
    return bitmap;
}

答案 3 :(得分:7)

无法制作尚未呈现内容的屏幕截图(例如ScrollView的屏幕外部分)。但是,您可以制作多个屏幕截图,在每个镜头之间滚动内容,然后加入图像。这是一个可以为您自动执行此操作的工具:https://github.com/PGSSoft/scrollscreenshot

illustration

免责声明:我是此工具的作者,由my employer发布。欢迎提出功能请求。

答案 4 :(得分:3)

您可以向视图传递基于Bitmap对象构建的Canvas的新实例。

尝试

Bitmap b = Bitmap.createBitmap(targetView.getWidth(), 
                               targetView.getHeight(), Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(b);
targetView.draw(c);
BitmapDrawable d = new BitmapDrawable(getResources(), b);
canvasView.setBackgroundDrawable(d);`

它确实为我做了这份工作。

答案 5 :(得分:3)

从此处下载源代码(Take screenshot of scrollview in android programmatically

<强> activity_main.xml中

import java.util.Random;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;

public class TotoMachine {
    public static void main(String[] args) {
        int[] array = new int[7];
        Random rand = new Random();
        for (int i = 0; i < array.length; i++)
            array[i] = rand.nextInt(65) + 1;
        //Collections.shuffle()
        Arrays.sort(array);
        System.out.println(Arrays.toString(array));
    }
}

<强> MainActivity.xml

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#efefef"
    android:orientation="vertical">

    <Button
        android:id="@+id/btn_screenshot"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:layout_margin="10dp"
        android:text="Take ScreenShot"/>

    <ScrollView
        android:id="@+id/scrollView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginBottom="10dp"
        android:background="#ffffff">

        <LinearLayout
            android:id="@+id/ll_linear"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_marginLeft="10dp"
            android:layout_marginRight="10dp"
            android:orientation="vertical">

            <ImageView
                android:layout_width="match_parent"
                android:layout_height="200dp"
                android:layout_gravity="center"
                android:layout_marginTop="10dp"
                android:scaleType="fitXY"
                android:src="@drawable/image2"/>

            <ImageView
                android:layout_width="match_parent"
                android:layout_height="200dp"
                android:layout_gravity="center"
                android:layout_marginTop="10dp"
                android:scaleType="fitXY"
                android:src="@drawable/image3"/>

            <ImageView
                android:layout_width="match_parent"
                android:layout_height="200dp"
                android:layout_gravity="center"
                android:layout_marginTop="10dp"
                android:scaleType="fitXY"
                android:src="@drawable/image5"/>

            <ImageView
                android:layout_width="match_parent"
                android:layout_height="200dp"
                android:layout_gravity="center"
                android:layout_marginTop="10dp"
                android:scaleType="fitXY"
                android:src="@drawable/image6"/>

        </LinearLayout>
    </ScrollView>
</LinearLayout>

<强>谢谢!

答案 6 :(得分:2)

这项工作对我来说,希望它对你也有帮助。

public static Bitmap getBitmapByView(ScrollView scrollView) {
    int h = 0;
    Bitmap bitmap = null;
    //get the actual height of scrollview
    for (int i = 0; i < scrollView.getChildCount(); i++) {
        h += scrollView.getChildAt(i).getHeight();
        scrollView.getChildAt(i).setBackgroundResource(R.color.white);
    }
    // create bitmap with target size
    bitmap = Bitmap.createBitmap(scrollView.getWidth(), h,
            Bitmap.Config.ARGB_8888);
    final Canvas canvas = new Canvas(bitmap);
    scrollView.draw(canvas);
    FileOutputStream out = null;
    try {
        out = new FileOutputStream("/sdcard/screen_test.png");
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    }
    try {
        if (null != out) {
            bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
            out.flush();
            out.close();
        }
    } catch (IOException e) {
        // TODO: handle exception
    }
    return bitmap;
}

答案 7 :(得分:0)

您可以使用视图的绘图缓存,但我不确定这是否会保存整个视图或仅显示呈现给屏幕的内容。

我建议你在StackOverflow上搜索类似的问题,之前很可能会问过它。

答案 8 :(得分:0)

试试这个对我来说很好用

TableLayout tabLayout = (TableLayout) findViewById(R.id.allview);

    if (tabLayout != null) {

            Bitmap image = Bitmap.createBitmap(tabLayout.getWidth(),
                    tabLayout.getHeight(), Config.ARGB_8888);
            Canvas b = new Canvas(image);

            tabLayout.draw(b);
}

答案 9 :(得分:0)

//设置按钮单击侦听器

Given:
       dict is a dictionary represented as a DFA (ex. trie or dawg)
       dictState is a state in dict
       dictStartState is the start state in dict
       dictAcceptState is a dictState arrived at after following the transitions defined by a word in dict
       editDistance is an edit distance
       laWord is a word
       la is a Levenshtein Automaton defined for laWord and editDistance
       laState is a state in la
       laStartState is the start state in la
       laAcceptState is a laState arrived at after following the transitions defined by a word that is within editDistance of laWord
       charSequence is a sequence of chars
       traversalDataStack is a stack of (dictState, laState, charSequence) tuples

Define dictState as dictStartState
Define laState as laStartState
Push (dictState, laState, "") on to traversalDataStack
While traversalDataStack is not empty
    Define currentTraversalDataTuple as the the product of a pop of traversalDataStack
    Define currentDictState as the dictState in currentTraversalDataTuple
    Define currentLAState as the laState in currentTraversalDataTuple
    Define currentCharSequence as the charSequence in currentTraversalDataTuple
    For each char in alphabet
        Check if currentDictState has outgoing transition labeled by char
        Check if currentLAState has outgoing transition labeled by char
        If both currentDictState and currentLAState have outgoing transitions labeled by char
            Define newDictState as the state arrived at after following the outgoing transition of dictState labeled by char
            Define newLAState as the state arrived at after following the outgoing transition of laState labeled by char
            Define newCharSequence as concatenation of currentCharSequence and char
            Push (newDictState, newLAState, newCharSequence) on to currentTraversalDataTuple
            If newDictState is a dictAcceptState, and if newLAState is a laAcceptState
                Add newCharSequence to resultSet
            endIf
        endIf
    endFor
endWhile

//然后你必须创建两个方法

    share = (Button)findViewById(R.id.share);
    share.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Bitmap bitmap = takeScreenshot();
            saveBitmap(bitmap);

        }
    });

将此代码添加到您的应用程序后,运行该应用程序并检查您的本地存储,您已创建整页的屏幕截图。

答案 10 :(得分:0)

public static Bitmap loadBitmapFromView(ScrollView v) {
    Bitmap b = Bitmap.createBitmap(v.getWidth() , v.getChildAt(0).getHeight(), Bitmap.Config.ARGB_8888);
    Canvas c = new Canvas(b);
    v.draw(c);
    return b;
}

答案 11 :(得分:0)

我测试了很多代码,每次点击NullPointerExeption。我发现,当我们的视图没有父视图时,提供的宽度和高度(Xml或Java)将被忽略,并将其设置为MATCH_PARENT

最后我想出了这个解决方案:

/**
 * Take screen shot of the View
 *
 * @param v the view
 * @param width_dp
 * @param height_dp
 *
 * @return screenshot of the view as bitmap
 */
public static Bitmap takeScreenShotOfView(View v, int width_dp, int height_dp) {

    v.setDrawingCacheEnabled(true);

    // this is the important code :)
    v.measure(View.MeasureSpec.makeMeasureSpec(dpToPx(v.getContext(), width_dp), View.MeasureSpec.EXACTLY),
            View.MeasureSpec.makeMeasureSpec(dpToPx(v.getContext(), height_dp), View.MeasureSpec.EXACTLY));
    v.layout(0, 0, v.getMeasuredWidth(), v.getMeasuredHeight());

    v.buildDrawingCache(true);

    // creates immutable clone
    Bitmap b = Bitmap.createBitmap(v.getDrawingCache());
    v.setDrawingCacheEnabled(false); // clear drawing cache
    return b;
}

public static int dpToPx(Context context, int dp) {
    Resources r = context.getResources();
    return Math.round(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, r.getDisplayMetrics()));
}

答案 12 :(得分:0)

获取视图的屏幕截图,然后在参数中传递视图

public static Bitmap getViewBitmap(View v) {
    v.clearFocus();
    v.setPressed(false);

    boolean willNotCache = v.willNotCacheDrawing();
    v.setWillNotCacheDrawing(false);

    int color = v.getDrawingCacheBackgroundColor();
    v.setDrawingCacheBackgroundColor(0);

    if (color != 0) {
        v.destroyDrawingCache();
    }
    v.buildDrawingCache();
    Bitmap cacheBitmap = v.getDrawingCache();
    if (cacheBitmap == null) {
        return null;
    }

    Bitmap bitmap = Bitmap.createBitmap(cacheBitmap);

    v.destroyDrawingCache();
    v.setWillNotCacheDrawing(willNotCache);
    v.setDrawingCacheBackgroundColor(color);

    return bitmap;
}

答案 13 :(得分:0)

请尝试以下代码:

Bitmap bitmap = getBitmapFromView(scrollview, scrollview.getChildAt(0).getHeight(), scrollview.getChildAt(0).getWidth());

//create bitmap from the ScrollView 
private Bitmap getBitmapFromView(View view, int height, int width) {
    Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(bitmap);
    Drawable bgDrawable = view.getBackground();
    if (bgDrawable != null)
        bgDrawable.draw(canvas);
    else
        canvas.drawColor(Color.WHITE);
    view.draw(canvas);
    return bitmap;
}

答案 14 :(得分:0)

fun View.getScreenShot():Bitmap{
    return Bitmap.createBitmap(width,height,Bitmap.Config.ARGB_8888).apply { 
        draw(Canvas(this))
    }
}