web-dev-qa-db-ja.com

ビュー全体のスクリーンショットを撮る

基本的にHorizontalScrollView内のScrollViewによって行われるテーブルを作成しました。ユーザーがフィールドを編集できるようにしました。

次に、テーブルを画面、jpg、png、pdfなどに保存します。

問題は、テーブルが画面よりも常に大きいことです。

ScrollViewレイアウト全体のスクリーンショットを作成する方法はありますか?そうでない場合は、何ができると思いますか?

39
softwaresupply

実際に私は答えを見つけました:

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;
}
62
softwaresupply
  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);
17
hackjutsu

@softwaresupply answerを使用すると、ビューが再描画されて完全に白くなった場合に問題が発生します。パラメータとして幅と高さを指定する必要がない場合、スクリーンショットを取得する簡単なソリューションがあります。 キャッシュの描画を使用します。

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

まだレンダリングされていないコンテンツのスクリーンショットを作成することはできません(ScrollViewの画面外の部分など)。ただし、複数のスクリーンショットを作成し、各ショット間でコンテンツをスクロールしてから、画像を結合できます。これを自動化できるツールを次に示します。 https://github.com/PGSSoft/scrollscreenshot

illustration

免責事項:私はこのツールの著者であり、 私の雇用者 によって発行されました。機能のリクエストは大歓迎です。

7
tomash

ここからソースコードをダウンロードします( scrollviewのスクリーンショットをAndroidプログラムで で取得します)

activity_main.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>

MainActivity.xml

package deepshikha.com.screenshot;
import Android.Manifest;
import Android.content.Intent;
import Android.content.pm.PackageManager;
import Android.graphics.Bitmap;
import Android.graphics.Canvas;
import Android.os.Bundle;
import Android.support.v4.app.ActivityCompat;
import Android.support.v4.content.ContextCompat;
import Android.support.v7.app.AppCompatActivity;
import Android.util.Log;
import Android.view.View;
import Android.widget.Button;
import Android.widget.LinearLayout;
import Android.widget.ScrollView;
import Android.widget.Toast;

import Java.io.File;
import Java.io.FileNotFoundException;
import Java.io.FileOutputStream;
import Java.io.IOException;

public class MainActivity extends AppCompatActivity {

Button btn_screenshot;
ScrollView scrollView;
LinearLayout ll_linear;
public static int REQUEST_PERMISSIONS = 1;
boolean boolean_permission;
boolean boolean_save;

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

private void init() {
    btn_screenshot = findViewById(R.id.btn_screenshot);
    scrollView = findViewById(R.id.scrollView);
    ll_linear = findViewById(R.id.ll_linear);

    btn_screenshot.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            if (boolean_save) {
                Intent intent = new Intent(getApplicationContext(), Screenshot.class);
                startActivity(intent);

            } else {
                if (boolean_permission) {
                    Bitmap bitmap1 = loadBitmapFromView(ll_linear, ll_linear.getWidth(), ll_linear.getHeight());
                    saveBitmap(bitmap1);
                } else {

                }
            }

        }
    });
}

public void saveBitmap(Bitmap bitmap) {
    File imagePath = new File("/sdcard/screenshotdemo.jpg");
    FileOutputStream fos;
    try {
        fos = new FileOutputStream(imagePath);
        bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);
        fos.flush();
        fos.close();
        Toast.makeText(getApplicationContext(), imagePath.getAbsolutePath() + "", Toast.LENGTH_SHORT).show();
        boolean_save = true;

        btn_screenshot.setText("Check image");

        Log.e("ImageSave", "Saveimage");
    } catch (IOException e) {
        Log.e("GREC", e.getMessage(), e);
    }
}

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.draw(c);

    return b;
}

private void fn_permission() {
    if ((ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) ||
            (ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED)) {
        if ((!ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE))) {
            ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
                    REQUEST_PERMISSIONS);
        }

        if ((!ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE))) {
            ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
                    REQUEST_PERMISSIONS);
        }
    } else {
        boolean_permission = true;
    }
}


@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);

    if (requestCode == REQUEST_PERMISSIONS) {
        if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            boolean_permission = true;

        } else {
            Toast.makeText(getApplicationContext(), "Please allow the permission", Toast.LENGTH_LONG).show();

        }
    }
}
}

ありがとう!

3
Deepshikha Puri

ビューに、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);`

実際に仕事をしてくれました。

3
appoll

私のためにこの仕事は、あなたにも役立つことを願っています。

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

私は多くのコードをテストし、毎回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()));
}

これを試してみてください

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);
}
0
Mahtab

ビューのスクリーンショットを撮り、パラメーターでビューを渡します

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;
}
0
Mohit Singh
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;
}
0

//ボタンクリックリスナーを設定します

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

        }
    });

//次に、2つのメソッドを作成する必要があります

    public Bitmap takeScreenshot() {
    View rootView = findViewById(Android.R.id.content).getRootView();
    rootView.setDrawingCacheEnabled(true);
    return rootView.getDrawingCache();
    }

    public void saveBitmap(Bitmap bitmap) {
    File imagePath = new File(Environment.getExternalStorageDirectory() + "/screenshot.png");
    FileOutputStream fos;
    try {
        fos = new FileOutputStream(imagePath);
        bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);
        fos.flush();
        fos.close();
    } catch (FileNotFoundException e) {
        Log.e("GREC", e.getMessage(), e);
    } catch (IOException e) {
        Log.e("GREC", e.getMessage(), e);
    }
   }

このコードをアプリに追加し、アプリを実行してローカルストレージを確認すると、ページ全体のスクリーンショットが作成されました。

0
Mani kandan

ビューの描画キャッシュを使用できるかもしれませんが、これがビュー全体を保持するのか、画面にレンダリングされるものだけを保持するのかはわかりません。

同様の質問についてはStackOverflowを探し回ることをお勧めします。これは以前に尋ねられた可能性が高いものです。

0
Mimminito

このコードを試してください:

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;
}
0
Masoud Mokhtari