使用layout.getDrawingCache() 将相对布局保存为位图时出错返回 null

发布于 2025-01-11 17:15:30 字数 6249 浏览 3 评论 0原文

如何使用 MediaStore.EXTRA_OUTPUT 处理全尺寸照片?首先,我需要将图片作为全尺寸而不是缩略图放在布局上,并在其下方放置文本,如下所示:

在此处输入图像描述

我使用的想法是我正在使用layout.getDrawingCache 将其设置为位图。

下面是我的相机按钮:

private void SelectImage(){

    final CharSequence[] items={"Camera", "Cancel"};

    AlertDialog.Builder builder = new AlertDialog.Builder(PickupDrop.this);
    builder.setTitle("Add Image");

    builder.setItems(items, new DialogInterface.OnClickListener() {

        @Override
        public void onClick(DialogInterface dialogInterface, int i) {
            if (items[i].equals("Camera")) {

                Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

                if(cameraIntent.resolveActivity(getPackageManager())!= null){

                    File imageFile = null;
                    try {
                        imageFile = getImageFile();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }

                    if(imageFile!= null){
                         imageUri =FileProvider.getUriForFile(context, "com.example.android.fileprovider", imageFile);


                        cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT,imageUri);
                        cameraIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
                        startActivityForResult(cameraIntent,REQUEST_CAMERA);

                       
                    }

                }

            } else if (items[i].equals("Cancel")) {
                dialogInterface.dismiss();
            }
        }
    });
    builder.show();

}

getImageFile() 方法:

private File getImageFile(){
    String imageName = "test";
    File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);

    File imageFile = null;
    try {
        imageFile = File.createTempFile(imageName,".jpg",storageDir);
    } catch (IOException e) {
        e.printStackTrace();
    }

    currentImagePath = imageFile.getAbsolutePath();
    return imageFile;
}

正如您在上面看到的,我使用 EXTRA_OUTPUT 和 fileprovider 来获取全尺寸位图。 以下是我的清单,提供商。

清单:

<application ...
<provider
        android:authorities="com.example.android.fileprovider"
        android:name="androidx.core.content.FileProvider"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/file_path"/>
    </provider>

file_path.xml:

<?xml version="1.0" encoding="utf-8"?>
<external-path
    name="my images"
    path="Android/data/com.example.luckypasabayapp/files/Pictures"/>

我的 onActivityResult 方法:

 @Override
public void onActivityResult(int requestCode, int resultCode, Intent data){
    super.onActivityResult(requestCode, resultCode,data);

    if(resultCode== Activity.RESULT_OK){

        if(requestCode==REQUEST_CAMERA){

            Bitmap bitmap = BitmapFactory.decodeFile(currentImagePath);


            populateScreenshot(bitmap);

        

        }
    }
}

现在,当我尝试将相对布局屏幕截图保存到我的存储中时,出现问题的地方是:

public void populateScreenshot(Bitmap bitmapFromPhone){

    LayoutInflater inflater = LayoutInflater.from(PickupDrop.this);
    View v = inflater.inflate(R.layout.information_dialog, null);
    ImageView imageView_profilePic = v.findViewById(R.id.imageview_image);
    TextView txt_item_data = v.findViewById(R.id.txt_item_data);
    Button btn_cancel = v.findViewById(R.id.btn_cancel);
    Button btn_download = v.findViewById(R.id.btn_download);
    screenShot = v.findViewById(R.id.screenShot);
    screenShot.setDrawingCacheEnabled(true);
    screenShot.buildDrawingCache();

    final AlertDialog alertDialog = new AlertDialog.Builder(PickupDrop.this)
            .setView(v)
            .create();

    alertDialog.setOnKeyListener(new DialogInterface.OnKeyListener() {
        @Override
        public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
            // Prevent dialog close on back press button
            return keyCode == KeyEvent.KEYCODE_BACK;
        }
    });
    //alertDialog.setCanceledOnTouchOutside(false);
    
    
    
    
    //SETTING THE IMAGEVIEW OF LAYOUT TAKEN FROM CAMERA
    imageView_profilePic.setImageBitmap(bitmapFromPhone);
    

    btn_download.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {

            //GETTING THE RELATIVELAYOUT AS BITMAP
            Bitmap bitmap = screenShot.getDrawingCache();
            

            File filePath = Environment.getExternalStorageDirectory();
            File dir = new File(filePath.getAbsolutePath()+"/qrcode/");

            dir.mkdirs();
            File file = new File(dir, "str_specialNumber" + ".png");

            try {
                outputStream = new FileOutputStream(file);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
            
            
            //HERE IS WHERE THE ERROR OCCURS, IT SAYS BITMAP IS NULL!!!
            
            bitmap.setHasAlpha(true);
            bitmap.compress(Bitmap.CompressFormat.PNG, 100,outputStream);

            Toast.makeText(PickupDrop.this,"SCREENSHOT Downloaded",Toast.LENGTH_LONG).show();

            try {
                outputStream.flush();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                outputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }

            //notify gallery for a new picture
            galleryAddPic(filePath.getAbsolutePath()+"/qrcode/"+"str_specialNumber"+".png");


        }
    });

    alertDialog.show();



}

这里在 bitmap.setHasAlpha(true);< /em> 它说 screenshot.getDrawingCache 中的位图为空,我不明白为什么。

如何正确处理 EXTRA_OUTPUT 以便能够对位图执行我想要的操作?

How to handle full-sized photo using MediaStore.EXTRA_OUTPUT? First, I need to put the picture AS FULL-SIZED NOT THUMBNAIL on a layout and put text below it like this:

enter image description here

The idea I am using is that I am using layout.getDrawingCache to make it as bitmap.

Below is my camera button:

private void SelectImage(){

    final CharSequence[] items={"Camera", "Cancel"};

    AlertDialog.Builder builder = new AlertDialog.Builder(PickupDrop.this);
    builder.setTitle("Add Image");

    builder.setItems(items, new DialogInterface.OnClickListener() {

        @Override
        public void onClick(DialogInterface dialogInterface, int i) {
            if (items[i].equals("Camera")) {

                Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

                if(cameraIntent.resolveActivity(getPackageManager())!= null){

                    File imageFile = null;
                    try {
                        imageFile = getImageFile();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }

                    if(imageFile!= null){
                         imageUri =FileProvider.getUriForFile(context, "com.example.android.fileprovider", imageFile);


                        cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT,imageUri);
                        cameraIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
                        startActivityForResult(cameraIntent,REQUEST_CAMERA);

                       
                    }

                }

            } else if (items[i].equals("Cancel")) {
                dialogInterface.dismiss();
            }
        }
    });
    builder.show();

}

The getImageFile() method:

private File getImageFile(){
    String imageName = "test";
    File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);

    File imageFile = null;
    try {
        imageFile = File.createTempFile(imageName,".jpg",storageDir);
    } catch (IOException e) {
        e.printStackTrace();
    }

    currentImagePath = imageFile.getAbsolutePath();
    return imageFile;
}

As you can see above, I am using EXTRA_OUTPUT with fileprovider to get FULL-SIZED bitmap.
Below is my manifests, provider.

Manifest:

<application ...
<provider
        android:authorities="com.example.android.fileprovider"
        android:name="androidx.core.content.FileProvider"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/file_path"/>
    </provider>

file_path.xml:

<?xml version="1.0" encoding="utf-8"?>
<external-path
    name="my images"
    path="Android/data/com.example.luckypasabayapp/files/Pictures"/>

My onActivityResult method:

 @Override
public void onActivityResult(int requestCode, int resultCode, Intent data){
    super.onActivityResult(requestCode, resultCode,data);

    if(resultCode== Activity.RESULT_OK){

        if(requestCode==REQUEST_CAMERA){

            Bitmap bitmap = BitmapFactory.decodeFile(currentImagePath);


            populateScreenshot(bitmap);

        

        }
    }
}

Now here is where my problem occurs when I try to save the relative layout screenshot to my storage:

public void populateScreenshot(Bitmap bitmapFromPhone){

    LayoutInflater inflater = LayoutInflater.from(PickupDrop.this);
    View v = inflater.inflate(R.layout.information_dialog, null);
    ImageView imageView_profilePic = v.findViewById(R.id.imageview_image);
    TextView txt_item_data = v.findViewById(R.id.txt_item_data);
    Button btn_cancel = v.findViewById(R.id.btn_cancel);
    Button btn_download = v.findViewById(R.id.btn_download);
    screenShot = v.findViewById(R.id.screenShot);
    screenShot.setDrawingCacheEnabled(true);
    screenShot.buildDrawingCache();

    final AlertDialog alertDialog = new AlertDialog.Builder(PickupDrop.this)
            .setView(v)
            .create();

    alertDialog.setOnKeyListener(new DialogInterface.OnKeyListener() {
        @Override
        public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
            // Prevent dialog close on back press button
            return keyCode == KeyEvent.KEYCODE_BACK;
        }
    });
    //alertDialog.setCanceledOnTouchOutside(false);
    
    
    
    
    //SETTING THE IMAGEVIEW OF LAYOUT TAKEN FROM CAMERA
    imageView_profilePic.setImageBitmap(bitmapFromPhone);
    

    btn_download.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {

            //GETTING THE RELATIVELAYOUT AS BITMAP
            Bitmap bitmap = screenShot.getDrawingCache();
            

            File filePath = Environment.getExternalStorageDirectory();
            File dir = new File(filePath.getAbsolutePath()+"/qrcode/");

            dir.mkdirs();
            File file = new File(dir, "str_specialNumber" + ".png");

            try {
                outputStream = new FileOutputStream(file);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
            
            
            //HERE IS WHERE THE ERROR OCCURS, IT SAYS BITMAP IS NULL!!!
            
            bitmap.setHasAlpha(true);
            bitmap.compress(Bitmap.CompressFormat.PNG, 100,outputStream);

            Toast.makeText(PickupDrop.this,"SCREENSHOT Downloaded",Toast.LENGTH_LONG).show();

            try {
                outputStream.flush();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                outputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }

            //notify gallery for a new picture
            galleryAddPic(filePath.getAbsolutePath()+"/qrcode/"+"str_specialNumber"+".png");


        }
    });

    alertDialog.show();



}

Here in bitmap.setHasAlpha(true); it says bitmap is null from screenshot.getDrawingCache I don't understand why.

How do I handle the EXTRA_OUTPUT properly to be able to do whatever I want with the bitmap?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

少女的英雄梦 2025-01-18 17:15:32

您可以尝试一下这个答案:)

如果您想截取任何 viewRelativeLayout 的屏幕截图,您可以创建此方法 takeScreenShot() :它将返回一个位图
@Param 或此方法中的参数中,您可以通过 RelativeLayout

    public static Bitmap takeScreenShot(@NonNull View view) {
    view.setDrawingCacheEnabled(true);
    view.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_AUTO);
    view.buildDrawingCache();

    if (view.getDrawingCache() == null) return null;
    Bitmap snapshot;
    try {
        snapshot = Bitmap.createBitmap(view.getDrawingCache());
        view.setDrawingCacheEnabled(false);
        view.destroyDrawingCache();
    } catch (Exception e) {
        snapshot = null;
    }
    return snapshot;
}

告诉我这是否对您有帮助:)

You can give this answer a try :)

If you want to take the screenshot of any view or your RelativeLayout you can create this method takeScreenShot() : it will return a Bitmap
in @Param or parameter in this method, you can pass RelativeLayout

    public static Bitmap takeScreenShot(@NonNull View view) {
    view.setDrawingCacheEnabled(true);
    view.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_AUTO);
    view.buildDrawingCache();

    if (view.getDrawingCache() == null) return null;
    Bitmap snapshot;
    try {
        snapshot = Bitmap.createBitmap(view.getDrawingCache());
        view.setDrawingCacheEnabled(false);
        view.destroyDrawingCache();
    } catch (Exception e) {
        snapshot = null;
    }
    return snapshot;
}

tell me if this helps you :)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文