Screenshot return as black image xamarin.ios

Gayatri Gokhale 1 Reputation point
2021-02-10T11:15:21.987+00:00

I am using Zxing library to generate barcodes. I am trying to capture that barcodes to store for future reference.

I have created custom barcode view. And implemented renderer for iOS and Android. But in iOS, image comes as a black image. I tried many codes from internet but without success.

Can you please tell me what is wrong in this code ?

Custom BarcodeView

public class BarcodeView : StackLayout
{
    public EventHandler OnDrawBitmap;

    public static readonly BindableProperty BarcodeUrlProperty = BindableProperty.Create(nameof(BarcodeUrl),
       typeof(string),
       typeof(string),
       default(string));

    public string BarcodeUrl
    {
        get { return (string)GetValue(BarcodeUrlProperty); }
        set { SetValue(BarcodeUrlProperty, value); }
    }
}

Xaml Implementation

<custom:BarcodeView Opacity="0" x:Name="barcodeview"><!---->                             
        <zxing:ZXingBarcodeImageView  x:Name="QRCodeView" BarcodeFormat="CODE_93"
                HeightRequest="50" WidthRequest="800" BarcodeValue="{Binding RandomBarcodeNumber}"  VerticalOptions="Center">
               <zxing:ZXingBarcodeImageView.BarcodeOptions>
                    <zxcm:EncodingOptions Width="800" Height="200"/>
               </zxing:ZXingBarcodeImageView.BarcodeOptions>
          </zxing:ZXingBarcodeImageView>                             
</custom:BarcodeView>

iOS Renderer

public class BarcodeViewRenderer : ViewRenderer<BarcodeView, UIView>
{
    public BarcodeViewRenderer()
    {
    }

    BarcodeView view;
    protected override void OnElementChanged(ElementChangedEventArgs<BarcodeView> e)
    {
        base.OnElementChanged(e);
        if (e.NewElement != null)
        {
            //register the event
            e.NewElement.OnDrawBitmap += NewElement_OnDrawBitmap;
        }
    }

    private void NewElement_OnDrawBitmap(object sender, EventArgs e)
    {
        try
        {               
            var formsView = Element;
            var rect = new CGRect(formsView.Bounds.X, formsView.Bounds.Y, formsView.Bounds.Width, formsView.Bounds.Height);
            var iOSView = ConvertFormsToNative(formsView, rect);
            UIImage image = ConvertViewToImage(iOSView);

            if (image != null)
                formsView.BarcodeUrl = image.AsPNG().GetBase64EncodedString(Foundation.NSDataBase64EncodingOptions.EndLineWithLineFeed);
            UIGraphics.EndImageContext();
        }
        catch (Exception ex)
        {
        }
    }

    private UIImage ConvertViewToImage(UIView iOSView)
    {
        try
        {
            UIGraphics.BeginImageContextWithOptions(iOSView.Bounds.Size,true, 0);
            iOSView.DrawViewHierarchy(iOSView.Bounds, true);
            var context = UIGraphics.GetCurrentContext();
            iOSView.Layer.RenderInContext(context);
            var img = UIGraphics.GetImageFromCurrentImageContext();

            return img;
        }
        catch (Exception ex)
        {
            return null;
        }
    }

    public static UIView ConvertFormsToNative(Xamarin.Forms.View view, CGRect size)
    {
        var renderer = Platform.CreateRenderer(view);

        renderer.NativeView.Frame = size;
        renderer.NativeView.AutoresizingMask = UIViewAutoresizing.All;
        renderer.NativeView.ContentMode = UIViewContentMode.ScaleToFill;
        renderer.Element.Layout(size.ToRectangle());
        var nativeView = renderer.NativeView;
        nativeView.SetNeedsLayout();

        return nativeView;
    }
}
Developer technologies | .NET | Xamarin
Developer technologies | C#
{count} votes

1 answer

Sort by: Most helpful
  1. Lucas Zhang - MSFT 341 Reputation points
    2021-02-12T05:50:16.35+00:00

    Hello,

    Welcome to Microsoft Q&A!

    The issue is caused by you set the second parameter of the following as true .

    UIGraphics.BeginImageContextWithOptions(iOSView.Bounds.Size, true, 0);
    

    opaque here is a transparent switch, set to true if the graph is not transparent at all to optimize bitmap storage. In your case , you need to set it as false

    UIGraphics.BeginImageContextWithOptions(iOSView.Bounds.Size, false, 0);
    

    Best Regards
    Lucas Zhang

    If the response is helpful, please click "Accept Answer" and upvote it.
    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.


Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.