Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
377 views
in Technique[技术] by (71.8m points)

java - Saving the current view as a bitmap

I've already saw lots of questions like this one around SO - but i can't get what i'm doing working (tried several times). Thats why i'm asking a probably repeated question.

On the android test app i'm developing, i'm trying to save a bitmap from the current view. However, when i try to save it its like the view has been disposed (its width and height are zero).

I suspect its because the method for saving the view is inside the OnCreate method but i can't see another way of doing that. My code (.java files and xml layout) are pretty basic and simples. All i'm trying to accomplish is to get the bitmap from this current view.

Any input is appreciated (and again i've searched around SO and saw many links related to this specific issue).

Thanks

MainActivity.Java

package com.example.saveview;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.media.MediaScannerConnection;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.View;
import android.widget.Toast;

import com.example.saveview.views.ViewParaSalvar;

import java.io.File;
import java.io.FileOutputStream;
import java.util.Date;
import java.util.Random;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        final ViewParaSalvar MyCustomView = new ViewParaSalvar(this);
       //Trying to save a screenshot of MyCustomView
        // Bitmap BmpFromView = loadBitmapFromView(MyCustomView);
        //saveImageToExternalStorage(BmpFromView);
    }
    public static Bitmap loadBitmapFromView(View v) {
        Bitmap b = Bitmap.createBitmap( v.getLayoutParams().width, v.getLayoutParams().height, Bitmap.Config.ARGB_8888);
        Canvas c = new Canvas(b);
        v.layout(v.getLeft(), v.getTop(), v.getRight(), v.getBottom());
        v.draw(c);
        return b;
    }
    public void ExibirMensagemAlerta(String msg)
    {
        Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
    }
    private void saveImageToExternalStorage(Bitmap finalBitmap) {
        String root = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).toString();
        File myDir = new File(root + "/saved_images");
        myDir.mkdirs();
        Random generator = new Random();
        int n = 10000;
        n = generator.nextInt(n);
        String fname = "Image-" + n + ".jpg";
        File file = new File(myDir, fname);

        try {
            FileOutputStream out = new FileOutputStream(file);
            if(file.isDirectory())
            {
                finalBitmap.compress(Bitmap.CompressFormat.JPEG, 90, out);
                MediaScannerConnection.scanFile(this, new String[] { file.toString() }, null,
                        new MediaScannerConnection.OnScanCompletedListener() {
                            public void onScanCompleted(String path, Uri uri) {
                                Log.i("ExternalStorage", "Scanned " + path + ":");
                                Log.i("ExternalStorage", "-> uri=" + uri);
                            }
                        });
                ExibirMensagemAlerta(file.toString());
                out.flush();
                out.close();
            }
            else
            {
                ExibirMensagemAlerta("Path not created");
            }


        } catch (Exception e) {
            e.printStackTrace();
        }
    }


}

CustomView.Java

package com.example.saveview.views;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.View;
import android.widget.Toast;

import androidx.annotation.Nullable;

public class ViewParaSalvar  extends View {

    private static final int SQUARE_SIZE = 100;
    private Rect mRectSquare;
    private Paint mPaintSquare;
    public Canvas pbCanvas;

    public ViewParaSalvar(Context context) {

        super(context);
        init(null);
    }

    public ViewParaSalvar(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init(attrs);
    }

    public ViewParaSalvar(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(attrs);
    }

    public ViewParaSalvar(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        init(attrs);
    }
    private void init(@Nullable AttributeSet set)
    {
        mRectSquare = new Rect();
        mPaintSquare = new Paint(Paint.ANTI_ALIAS_FLAG);

    }
    @Override
    protected void onDraw(Canvas canvas)
    {

        mRectSquare.top = 0;
        mRectSquare.left = 10;
        mRectSquare.bottom = mRectSquare.top + SQUARE_SIZE;
        mRectSquare.right  = mRectSquare.left + SQUARE_SIZE;
        mPaintSquare.setColor(Color.RED);
        mPaintSquare.setTextSize(60);
        canvas.drawText("TEST DRAW CUSTOM VIEW",10,50,mPaintSquare);
        pbCanvas = canvas;
    }

}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
    <com.example.saveview.views.ViewParaSalvar
        android:layout_width="match_parent"
        android:layout_height="150dp"
        android:id="@+id/idDaViewParaSalvar"/>


</RelativeLayout>
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You try to add this listener to the onCreate event:

myCustomView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
    @Override
    public void onGlobalLayout() {
        myCustomView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
        do_your_logic_to_save_bitmap_from_view;
    }
});

addOnGlobalLayoutListener will register a callback to be invoked when the global layout state or the visibility of views within the view tree changes. For example when the view is rendered completely.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

57.0k users

...