如何解决Xamarin Android软件渲染不支持硬件位图
我有一个需要拍照并将其转换为灰度的应用程序。它曾经在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,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
谢谢, 吉姆
解决方法
好的,这就是我所想的。在活动中,我添加了一个新类来充当OnHeaderDecoded事件的侦听器。在此类中,我将MutableRequired = true设置。
private class OnHeaderDecodedListener : Java.Lang.Object,IOnHeaderDecodedListener
{
public void OnHeaderDecoded(ImageDecoder decoder,ImageInfo info,Source source)
{
decoder.MutableRequired = true;
}
}
然后在OnActivityResult中,我更改了
Bitmap img = ImageDecoder.DecodeBitmap(src);
到
Bitmap img = ImageDecoder.DecodeBitmap(src,new OnHeaderDecodedListener());
这导致它创建了不是硬件位图的可变位图。
干杯, 吉姆
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。