首页 > 解决方案 > nullreferenceexception wenn 我将滚动视图中的所有内容转换为 Xamarin 论坛中的位图

问题描述

我正在通过以下链接:

https://www.syncfusion.com/kb/10697/how-to-convert-xaml-to-pdf-in-xamarin-using-c

只要我需要的 xaml 适合屏幕而不滚动,此代码就可以正常工作。但我希望 ScrollView 中的所有元素都保存在我的 pdf 中。我在 Xamarin 论坛链接中尝试了代码,但无法让它工作 https://forums.xamarin.com/discussion/146465/how-to-convert-the-all-content-in-scroll-view -to-bitmap-in-xamarin-forum

这是我的代码

private async void button_Clicked(object sender, EventArgs e)
    {
        
        MemoryStream stream = new MemoryStream();
        //Create a new PDF document
        using (PdfDocument document = new PdfDocument())
        {
            //Add page to the PDF document.
            PdfPage page = document.Pages.Add();

            //Create graphics instance.
            PdfGraphics graphics = page.Graphics;

            Stream imageStream = null;

            if (Device.RuntimePlatform == Device.Android )
            {
                byte[] data;
                data = await Xamarin.Forms.DependencyService.Get<ISaveWindowsPhone>().CaptureAsync();

                imageStream = new MemoryStream(data);

            }
            else
            {
                imageStream = new MemoryStream(DependencyService.Get<ISave>().CaptureAsync().Result);
            }

            //Load the image
            PdfBitmap image = new PdfBitmap(imageStream);

            //Draw the image
            graphics.DrawImage(image, 0, 0, page.GetClientSize().Width, page.GetClientSize().Height);

            //Save the document into memory stream
            document.Save(stream);

        }
        stream.Position = 0;
        if (Device.RuntimePlatform == Device.Android )
        {  
            Xamarin.Forms.DependencyService.Get<ISaveWindowsPhone>().Save("XAMLtoPDF.pdf", "application/pdf", stream);
        }
        else
        {
            Xamarin.Forms.DependencyService.Get<ISave>().Save("XAMLtoPDF.pdf", "application/pdf", stream);
        }
    
    }

并保存

public void Save(string fileName, String contentType, MemoryStream s)
    {
        string root = null;
        if (Android.OS.Environment.IsExternalStorageEmulated)
        {
            root = Android.OS.Environment.ExternalStorageDirectory.ToString();
        }
        else
            root = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
        //root = "/interner Speicher/Download/";

        Java.IO.File myDir = new Java.IO.File(root + "/Syncfusion");
        myDir.Mkdir();

        Java.IO.File file = new Java.IO.File(myDir, fileName);

        if (file.Exists()) file.Delete();

        try
        {
            FileOutputStream outs = new FileOutputStream(file);
            outs.Write(s.ToArray());

            outs.Flush();
            outs.Close();

        }
        catch (Exception e)
        {

        }
        if (file.Exists())
        {
            Android.Net.Uri path = Android.Net.Uri.FromFile(file);
            string extension = Android.Webkit.MimeTypeMap.GetFileExtensionFromUrl(Android.Net.Uri.FromFile(file).ToString());
            string mimeType = Android.Webkit.MimeTypeMap.Singleton.GetMimeTypeFromExtension(extension);
            Intent intent = new Intent(Intent.ActionView);
            intent.SetDataAndType(path, mimeType);
            Android.App.Application.Context.StartActivity(Intent.CreateChooser(intent, "Choose App"));
        }
    }

并将当前视图转换为 Xamarin Forms 中的位图

public System.Threading.Tasks.Task<byte[]> CaptureAsync()
    {
        //            scrollversion
        var activity = Forms.Context as Activity;
        ViewGroup content = activity.FindViewById<ViewGroup>(Android.Resource.Id.Content);
        ViewGroup frameLayout = (ViewGroup)content.GetChildAt(0);
        ViewGroup relativeLayout = (ViewGroup)frameLayout.GetChildAt(0);
        ViewGroup platFormRenderer = (ViewGroup)relativeLayout.GetChildAt(0);
        ViewGroup myNavigationPageRenderer = (ViewGroup)platFormRenderer.GetChildAt(0);
        ViewGroup pageRenderer = (ViewGroup)myNavigationPageRenderer.GetChildAt(0);
        ViewGroup scrollViewRenderer = (ViewGroup)pageRenderer.GetChildAt(0);// --> scrollViewRenderer

        //Adjust this to find your own scrollViewRenderer
        Android.Widget.ScrollView z = scrollViewRenderer as Android.Widget.ScrollView;
        z.SetBackgroundColor(Android.Graphics.Color.White);
        int totalHeight = z.GetChildAt(0).Height;
        int totalWidth = z.GetChildAt(0).Width;
        Bitmap bitmap = getBitmapFromView(z, (int)totalHeight, (int)totalWidth);
        byte[] bitmapData;
        using (var stream = new MemoryStream())
        {
            bitmap.Compress(Bitmap.CompressFormat.Jpeg, 0, stream);
            bitmapData = stream.ToArray();
        }


        return Task.FromResult(bitmapData);
    }

    public Bitmap getBitmapFromView(Android.Views.View view, int totalHeight, int totalWidth)
    {
        Bitmap returnedBitmap = Bitmap.CreateBitmap(totalWidth, totalHeight, Bitmap.Config.Argb8888);
        Canvas canvas = new Canvas(returnedBitmap);
        Drawable bgDrawable = view.Background;
        if (bgDrawable != null)
            bgDrawable.Draw(canvas);
        else
            canvas.DrawColor(Android.Graphics.Color.White);
        canvas.Save();
        view.Draw(canvas);
        canvas.Restore();
        return returnedBitmap;
    }

在上面的代码中 z.SetBackgroundColor(Android.Graphics.Color.White); 我收到 System.NullReferenceException:“对象引用未设置为对象的实例。” 我的 z 值为 null 我错过了什么吗?先感谢您!

标签: androidxamlpdfxamarinscrollview

解决方案


推荐阅读