【发布时间】:2020-09-09 02:25:45
【问题描述】:
我有一个应用程序,我需要在其中拍照并将其转换为灰度。它曾经在Android 9.0下工作。我升级到 Android 11.0,显然有一个重大变化。我创建了一个可以重现问题的独立活动:
using Android.App;
using Android.Content;
using Android.Content.PM;
using Android.Graphics;
using Android.OS;
using Android.Provider;
using Android.Support.Design.Widget;
using Android.Support.V7.App;
using Android.Views;
using Android.Widget;
using System;
namespace BitmapRenderIssue
{
[Activity(Label = "@string/app_name", Theme = "@style/AppTheme.NoActionBar", MainLauncher = true)]
public class MainActivity : AppCompatActivity
{
private const int CAPTURE_PHOTO = 100;
private static Android.Net.Uri ImageUri;
ImageView imageView1;
private static Bitmap CurrImage;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.activity_main);
Android.Support.V7.Widget.Toolbar toolbar = FindViewById<Android.Support.V7.Widget.Toolbar>(Resource.Id.toolbar);
SetSupportActionBar(toolbar);
imageView1 = FindViewById<ImageView>(Resource.Id.imageView1);
FloatingActionButton fab = FindViewById<FloatingActionButton>(Resource.Id.fab);
fab.Click += FabOnClick;
}
public override bool OnCreateOptionsMenu(IMenu menu)
{
MenuInflater.Inflate(Resource.Menu.menu_main, menu);
return true;
}
public override bool OnOptionsItemSelected(IMenuItem item)
{
int id = item.ItemId;
if (id == Resource.Id.action_settings)
{
return true;
}
return base.OnOptionsItemSelected(item);
}
private void FabOnClick(object sender, EventArgs eventArgs)
{
TakePicture();
}
public bool isCameraPermissionGranted()
{
if (Build.VERSION.SdkInt >= BuildVersionCodes.M)
{
if (CheckSelfPermission(Android.Manifest.Permission.Camera)
== Permission.Granted)
{
return true;
}
else
{
RequestPermissions(new String[] { Android.Manifest.Permission.Camera }, 1);
return false;
}
}
else
{ //permission is automatically granted on sdk<23 upon installation
return true;
}
}
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, Permission[] grantResults)
{
base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
if (grantResults[0] == Permission.Granted)
{
CapturePhoto();
}
}
public void CapturePhoto()
{
ImageUri = ContentResolver.Insert(MediaStore.Images.Media.ExternalContentUri, new ContentValues());
var i = new Intent(MediaStore.ActionImageCapture);
i.PutExtra(MediaStore.ExtraOutput, ImageUri);
StartActivityForResult(i, CAPTURE_PHOTO);
}
public void TakePicture()
{
if (isCameraPermissionGranted())
CapturePhoto();
}
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
{
if (resultCode == Result.Ok && requestCode == CAPTURE_PHOTO && ImageUri != null)
{
Android.Util.Log.Info("CameraScanning", "Getting Picture");
var src = ImageDecoder.CreateSource(ContentResolver, ImageUri);
Bitmap img = ImageDecoder.DecodeBitmap(src);
CurrImage = ImageProcessing.Grayscale_ColorMatrixColorFilter(img);
img.Recycle();
img.Dispose();
imageView1.SetImageBitmap(CurrImage);
Java.IO.File xFile = new Java.IO.File(ImageUri.Path);
if (xFile.Exists())
xFile.Delete();
ImageUri = null;
}
}
}
}
这是有问题的函数的代码:
public static class ImageProcessing
{
public static Bitmap Grayscale_ColorMatrixColorFilter(Bitmap src)
{
int width = src.Width;
int height = src.Height;
Bitmap dest = Bitmap.CreateBitmap(width, height, Bitmap.Config.Rgb565);
Canvas canvas = new Canvas(dest);
Paint paint = new Paint();
ColorMatrix colorMatrix = new ColorMatrix();
colorMatrix.SetSaturation(0); //value of 0 maps the color to gray-scale
ColorMatrixColorFilter filter = new ColorMatrixColorFilter(colorMatrix);
paint.SetColorFilter(filter);
canvas.DrawBitmap(src, 0, 0, paint);
return dest;
}
}
此函数在调用 canvas.DrawBitmap(src, 0, 0, paint); 时抛出“软件渲染不支持硬件位图”;
我已经尝试了Software rendering doesn't support hardware bitmap in Oreo 此处找到的所有 hardwareAccelerated 选项
我创建了一个包含可以重现此错误的 Visual Studio 项目的存储库。只需运行该应用程序。单击浮动操作按钮。拍一张照片。点击确定。会发生错误。
https://github.com/JimWilcox3/BitmapRenderIssue
谢谢, 吉姆
【问题讨论】:
标签: android xamarin xamarin.android