【问题标题】:Can't Pass Image Path From Decode File Bitmap (Xamarin Android) Path return Null Exception Error无法从解码文件位图传递图像路径(Xamarin Android)路径返回 Null 异常错误
【发布时间】:2020-08-13 15:51:50
【问题描述】:

我正在尝试使用 C# 在 Xamarin Android 中传递我的图像。在第一个活动中,我使用BitmapFactory.DecodeFile(uri_path);将我的图像路径解码为位图文件。我还使用imgView.SetImageBitmap(BitMap); 设置了该位图图片,然后,我在按钮单击中传递该URI 路径,该按钮将使用intent.PutExtra("path", mCurrentPhotoPath); 将图片引用到下一个活动。在下一个活动中,我想从第一个活动中获取传递路径值。

string path = intent.GetStringExtra("path");

            if (path != null)
            {
                Bitmap bitmap = BitmapFactory.DecodeFile(path);
                m_imageView.SetImageBitmap(bitmap);
            }

            else
            {
                Toast.MakeText(this, "Your picture empty!", ToastLength.Long).Show();
            }

但是,我收到一个带有空异常错误的错误。路径返回 null 并且程序正在崩溃。请帮我!几个小时后我感觉卡住了。有什么帮助吗? 这是我的完整代码:

第一个活动 - 我的 onActivityResult

private Button btnContinue, btnCapture;
        private ImageView imgView;
        public Bitmap BitMap;
        private Android.Net.Uri filePath;
        private const int c_TAKE_IMAGE_REQUSET = 72;
        private ProgressBar progressBar;
        public String mCurrentPhotoPath = null;

public override void OnActivityResult(int requestCode, int resultCode, Intent data) 
    {
        base.OnActivityResult(requestCode, resultCode, data);

    if (requestCode == c_TAKE_IMAGE_REQUSET &&
        resultCode == (int)Result.Ok &&
        data != null)
    {
        filePath = data.Data;
        //String mCurrentPhotoPath = null;
        try
        {
            mCurrentPhotoPath = GetRealPathFromURI(filePath);
        }
        catch (Exception ex)
        {
            // Failed for some reason.
        }

        try
        {
            BitMap = (Bitmap)data.Extras.Get("data");
            imgView.SetImageBitmap(BitMap);
            BitMap = BitmapFactory.DecodeFile(mCurrentPhotoPath);
            System.Diagnostics.Debug.WriteLine("Image path == " + mCurrentPhotoPath);
        }
        catch (System.IO.IOException ex)
        {
            System.Console.WriteLine(ex);
        }

        var bitmap = BitmapFactory.DecodeFile(mCurrentPhotoPath); // decode the path into bitmap 
        imgView.SetImageBitmap(bitmap);
    }
}

private string GetRealPathFromURI(Android.Net.Uri uri)
    {
        string doc_id = "";
        using (var c1 = this.View.Context.ContentResolver.Query(uri, null, null, null, null))
        {
            c1.MoveToFirst();
            string document_id = c1.GetString(0);
            doc_id = document_id.Substring(document_id.LastIndexOf(":") + 1);
        }

        string path = null;

        // The projection contains the columns we want to return in our query.
        string selection = Android.Provider.MediaStore.Images.Media.InterfaceConsts.Id + " =? ";
        using (var cursor = this.View.Context.ContentResolver.Query(Android.Provider.MediaStore.Images.Media.ExternalContentUri, null, selection, new string[] { doc_id }, null))
        {
            if (cursor == null) return path;
            var columnIndex = cursor.GetColumnIndexOrThrow(Android.Provider.MediaStore.Images.Media.InterfaceConsts.Data);
            cursor.MoveToFirst();
            path = cursor.GetString(columnIndex);
        }
        return path;
    }
}

第二个活动 - onCreate protected override void OnCreate(Bundle savedInstanceState) { base.OnCreate(savedInstanceState);

        SetContentView(Resource.Layout.Upload);

        string path = intent.GetStringExtra("path");

        if (path != null)
        {
            Bitmap bitmap = BitmapFactory.DecodeFile(path);
            m_imageView.SetImageBitmap(bitmap);
        }

        else
        {
            Toast.MakeText(this, "Your picture empty!", ToastLength.Long).Show();
        }

        m_upload.Click += M_upload_Click;

    }

编辑:我将我的放置字符串额外放在我的按钮中。按钮是 Button Continue,它是对下一个活动的引用

private void btnContinue_Click(object sender, EventArgs e)
        {
            Busy();
            Intent intent = new Intent(Activity, typeof(UploadActivity));
            intent.PutExtra("path", mCurrentPhotoPath);
            StartActivity(intent);
        }

【问题讨论】:

  • 我在你的代码中没有看到你调用PutExtra的任何地方
  • 编辑:我把我的 PutExtra 放在我的按钮上。请检查我编辑的问题

标签: c# android xamarin xamarin.android


【解决方案1】:

我认为这只有在你拍照后才会发生,因为filePath = data.Data;返回null,如果你从照片中选择一张照片,它会返回它的uri。

所以你可以尝试使用其他方法,你可以在拍照后传递位图的byte[]数据:

public override void OnActivityResult(int requestCode, int resultCode, Intent data)
    {
        base.OnActivityResult(requestCode, resultCode, data);

        if (requestCode == c_TAKE_IMAGE_REQUSET &&
            resultCode == (int)Result.Ok &&
            data != null)
        {

            try
            {
                mBitMap = (Bitmap)data.Extras.Get("data");
                imgView.SetImageBitmap(mBitMap);
                using (var stream = new MemoryStream())
                {
                    mBitMap.Compress(Bitmap.CompressFormat.Jpeg, 100, stream);
                    bitmapData = stream.ToArray();
                }
            }
            catch (System.IO.IOException ex)
            {
                System.Console.WriteLine(ex);
            }
        }
    }

那么你可以通过bitmapData:

Intent intent = new Intent(Activity, typeof(UploadActivity));
intent.PutExtra("img", bitmapData);
StartActivity(intent);

在新活动中展示它:

byte[] bitmapbyte = Intent.GetByteArrayExtra("img");
Bitmap bitmap = BitmapFactory.DecodeByteArray(bitmapbyte, 0, bitmapbyte.Length);
m_imageView.SetImageBitmap(bitmap);

更新:

如果你想使用文件路径,你可以这样做:

private Java.IO.File outputImage;
private Android.Net.Uri photoUri;   // the camera takes a photo and returns the image path    

//Create a file object to store the image after the photo is taken, which is also the photo path after the photo is taken successfully
Java.IO.File outputImage = new Java.IO.File(xxx,xxx);
//determine the current Android version
if (Build.VERSION.SdkInt >= BuildVersionCodes.N)
    {
      photoUri = FileProvider.GetUriForFile(this, "xxxxx", outputImage);
    }
else
    {
      photoUri = Android.Net.Uri.FromFile(outputImage);
    }

 Intent intent = new Intent(MediaStore.ActionImageCapture);
 intent.PutExtra(MediaStore.ExtraOutput, photoUri);
 StartActivityForResult(intent, TAKE_IMAGE_REQUSET);

那么你可以使用photoUri。

在某些设备上,您可以使用以下方法保存图片并获取路径。

filePath = Android.Net.Uri.Parse(MediaStore.Images.Media.InsertImage(Activity.ContentResolver, mBitMap, null, null)); 

注意:

FileProvider用于Android 7.0及以上。

【讨论】:

  • 感谢您的回答。但是,严重的是我不能传递我的路径然后将路径解码为位图?有人说传字节不好,因为它需要你手机的内存。 mbitmap.Compress(Bitmap.CompressFormat.Jpeg, 100, stream); 怎么样?如果我不压缩位图,可以吗?
  • @Anastasia 最好压缩一下,因为有时候bitamp会太大导致oom,如果要使用路径,可以先定义一个文件路径,然后设置为输出路径。我会给你一个更新
  • 啊,我明白了,好吧,在我看来,我不认为如果我们压缩位图,那将是最好的技术。我在 google 上阅读了一些文章,如果我们压缩位图,那么位图将丢失其图像细节。因此,图像质量会很差。但是,谢谢你的信息!我会先尝试定义一个文件路径!
  • @Anastasia 我上面已经更新了,你可以参考一下,不是完整的代码
  • 好吧,我明白了!我会试试看。我想问一下,在new Java.IO.File(xxx, xxx);的xxx部分,xxx应该放什么?还有photoUri = FileProvider.GetUriForFile(this, "xxxxx", outputImage);中的xxx是我的图片名?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-16
  • 1970-01-01
相关资源
最近更新 更多