web-dev-qa-db-fra.com

Prendre une capture d'écran d'une vue entière

J'ai construit une table qui est essentiellement faite par HorizontalScrollView à l'intérieur d'un ScrollView. J'ai fait que l'utilisateur puisse éditer les champs.

Maintenant, je veux enregistrer le tableau sur un écran, jpg, png, pdf ou toute autre chose.

Le problème est que la table est presque toujours plus grande que l'écran.

Existe-t-il un moyen de faire une capture d'écran de l'ensemble de la disposition ScrollView? Si non, que pensez-vous pouvoir faire le travail?

39
softwaresupply

En fait, j'ai trouvé la réponse:

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

L'utilisation de la réponse @softwaresupply pose problème dans mon cas où ma vue se redessinait et devenait complètement blanche. Il existe une solution plus facile pour obtenir une capture d'écran où vous n'avez même pas besoin de fournir la largeur et la hauteur comme paramètres. Utilisez Cache de dessin.

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

Il est impossible de faire une capture d'écran du contenu non encore rendu (comme les parties hors écran de ScrollView). Cependant, vous pouvez faire plusieurs captures d'écran, faire défiler le contenu entre chaque prise de vue, puis joindre des images. Voici un outil qui peut automatiser cela pour vous: https://github.com/PGSSoft/scrollscreenshot

illustration

Avertissement: je suis l'auteur de cet outil, il a été publié par mon employeur . Les demandes de fonctionnalités sont les bienvenues.

7
tomash

Téléchargez le code source à partir d'ici ( Prenez une capture d'écran de scrollview dans Android par programme )

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

        }
    }
}
}

Merci!

3
Deepshikha Puri

Vous pouvez transmettre à la vue une nouvelle instance d'un canevas construit sur un objet Bitmap.

Essayez avec

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

En fait, cela a fait le travail pour moi.

3
appoll

ce travail pour moi, j'espère qu'il vous sera utile aussi.

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

J'ai testé beaucoup de codes et à chaque fois que je tape NullPointerExeption. J'ai découvert que lorsque notre vue n'a pas de vue parent, la largeur et la hauteur fournies (Xml ou Java) sont ignorées et réglées sur MATCH_PARENT.

Enfin, j'ai trouvé cette solution:

/**
 * 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()));
}
0

essayez cela fonctionne bien pour moi

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

Prendre une capture d'écran d'une vue, passez la vue dans le paramètre

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
Sameer Chamankar

// set list click click listener

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

        }
    });

// alors vous devez créer deux méthodes

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

Après avoir ajouté ce code dans votre application, exécutez l'application et vérifiez votre stockage local, vous avez créé une capture d'écran de la page entière.

0
Mani kandan

Vous pourrez peut-être utiliser le cache de dessin d'une vue, mais je ne sais pas si cela contiendra la vue entière ou juste ce qui est rendu à l'écran.

Je vous conseillerais de chercher sur StackOverflow pour des questions similaires, cela a plus que probablement été posé auparavant.

0
Mimminito

Veuillez essayer ce code:

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