将当前视图另存为位图

时间:2019-10-21 14:46:55

标签: java android

我已经看到很多类似这样的问题-但是我无法理解我正在做什么(尝试了几次)。那就是为什么我问一个可能重复的问题。

在我正在开发的android测试应用程序上,我正在尝试从当前视图保存位图。但是,当我尝试保存它时,就像视图已被放置(宽度和高度为零)一样。

我怀疑它是因为保存视图的方法在OnCreate方法内部,但是我看不到另一种方法。我的代码(.java文件和xml布局)非常简单。我要做的就是从当前视图中获取位图。

感谢您的任何投入(我再次在SO周围进行搜索,并看到许多与此特定问题相关的链接)。

谢谢

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>

1 个答案:

答案 0 :(得分:1)

您尝试将此侦听器添加到onCreate事件中:

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

addOnGlobalLayoutListener将注册一个回调,以在全局布局状态或视图树中视图的可见性更改时调用。例如,当视图完全呈现时。