Forum Xamarin.Forms
We are excited to announce that the Xamarin Forums are moving to the new Microsoft Q&A experience. Q&A is the home for technical questions and answers at across all products at Microsoft now including Xamarin!

We encourage you to head over to Microsoft Q&A for .NET for posting new questions and get involved today.

Xamarin.Forms.Image to convert Bitmap

Blade4771Blade4771 USMember ✭✭

hello, I'm creating a project in which I need to "create" a picture in time
(in fact, is an image that I have to put a aliatoria phrase).
the DROID project
I am editing the image as well
protected override void OnDraw(Canvas canvas)
{
base.OnDraw(canvas);
Paint paint = new Paint {
AntiAlias = true,
Color = Color.Black,
TextSize = 50,
};
float middle = canvas.Width * 0.25f;
canvas.DrawBitmap (_Bmp, 100, 50, null);
canvas.DrawText (Text, 150,90, paint);
}

now I wanted to do with could be able to share the photo, but my intent method, giving this error because I'm not getting
Xamarin.Forms.Image to convert Bitmap

Best Answer

Answers

  • AndrewMobileAndrewMobile USMember ✭✭✭✭
    edited June 2015

    @Gabriel.4771
    If you need to access the native image from an Xamarin.Forms.Image control in your Android app, you can add the following function in your Android project:

    Task<Bitmap> GetBitmap(Xamarin.Forms.Image image)
    {
          var handler = new ImageLoaderSourceHandler();
          return handler. LoadImageAsync(image.Source);
    }
    

    and to use it you need to call
    Bitmap bitmap = await GetBitmap(image);

    where image is a Xamarin.Forms.Image control.

    I hope this answers your question

  • Blade4771Blade4771 USMember ✭✭
    edited June 2015

    @AndreiNitescu but the method handler. LoadImageAsync needs three arguments (ImagenSource, Context,CancellationToken)

  • Blade4771Blade4771 USMember ✭✭

    I believe that the error be in the creation of my image, because the imagemSource is coming null

    DrawingImage = new ImageWithTouch
    {
    VerticalOptions = LayoutOptions.FillAndExpand,
    HorizontalOptions = LayoutOptions.FillAndExpand,
    CurrentLineColor = Color.Black,
    };

  • AndrewMobileAndrewMobile USMember ✭✭✭✭
    edited June 2015

    Sorry for typo, LoadImageAsync does have 3 params, they are pretty much self explanatory
    when calling from a renderer, you can use this:
    LoadImageAsync(imageSource, this, null);

  • adamkempadamkemp USInsider, Developer Group Leader mod

    For a more complete example of getting a Bitmap from an ImageSource see here.

  • Blade4771Blade4771 USMember ✭✭
    edited June 2015

    @adamkemp I think the problem I'm facing is that my image the
    Imagesource be coming null

    DrawingImage = new ImageWithTouch
            {
                VerticalOptions = LayoutOptions.FillAndExpand,
                HorizontalOptions = LayoutOptions.FillAndExpand,
                CurrentLineColor = Color.Black,
    
            };
            DrawingImage.SetBinding(ImageWithTouch.TextProperty, "TextProperty");
    
  • adamkempadamkemp USInsider, Developer Group Leader mod

    I have no idea what you mean by that. There's not even an ImageSource in the code you quoted. Could you attach a full project showing the problem?

  • Blade4771Blade4771 USMember ✭✭

    My application is to the idea of a standard image, just that
    a random phrase will be generated which have to 'add' this
    image standard to allow users to share

  • adamkempadamkemp USInsider, Developer Group Leader mod

    Ok, I still have no idea what the problem is. I have your code, but you haven't told me what doesn't work in it. Please be specific. What is the problem you are having?

  • Blade4771Blade4771 USMember ✭✭
    edited June 2015

    @adamkemp on page4.cs file, do I create a DrawingImage image in which I edit and place the random phrase, btnMenu2 in the case would be the button to share the image with the phrase, the Droid project I created in a class folder SERVICE AndroidIntentService, which serves to place the image in intent and enable the sharing of the image, but I have to convert this for bitmap, I'm so to convert to bitmap, but my Image.Source always comes null, and because of that presents the error

      Task<Bitmap> GetBitmap(Xamarin.Forms.Image image)
        {
            var handler = new ImageLoaderSourceHandler();
            return handler.LoadImageAsync(image.Source,Forms.Context);
        }
    
  • adamkempadamkemp USInsider, Developer Group Leader mod

    When I run your example and click the button that says "HOMEM" the app crashes here:

    [MonoDroid] System.InvalidOperationException: Cannot convert "GeradorCantadas.ImageWithTouch" into Xamarin.Forms.ImageSource
    [MonoDroid] at XLabs.Forms.Controls.ImageSourceConverter.ConvertFrom (System.Globalization.CultureInfo,object) <IL 0x00062, 0x0021f>
    [MonoDroid] at Xamarin.Forms.TypeConverter.ConvertFrom (object) <IL 0x00007, 0x00046>
    [MonoDroid] at GeradorCantadas.Page4..ctor () [0x00073] in /Users/akemp/Downloads/GeradorCantadas/GeradorCantadas/Page4.cs:35
    [MonoDroid] at GeradorCantadas.Principal.<Principal>m__0 (object,System.EventArgs) [0x00007] in /Users/akemp/Downloads/GeradorCantadas/GeradorCantadas/Principal.cs:32
    [MonoDroid] at Xamarin.Forms.Button.Xamarin.Forms.IButtonController.SendClicked () <IL 0x00027, 0x000ca>
    [MonoDroid] at Xamarin.Forms.Platform.Android.ButtonRenderer/ButtonClickListener.OnClick (Android.Views.View) <IL 0x00015, 0x0009b>
    [MonoDroid] at Android.Views.View/IOnClickListenerInvoker.n_OnClick_Landroid_view_View_ (intptr,intptr,intptr) [0x00011] in /Users/builder/data/lanes/monodroid-mavericks-monodroid-5.1-series/d419c934/source/monodroid/src/Mono.Android/platforms/android-21/src/generated/Android.Views.View.cs:1888
    [MonoDroid] at (wrapper dynamic-method) object.f62ba846-7c5d-4c52-a794-71c631db7247 (intptr,intptr,intptr) <IL 0x00017, 0x00027>
    

    This line doesn't even make sense to me:

    DrawingImage.Source = (ImageSource)convert.ConvertFrom( DrawingImage);
    

    You can't convert an Image into an ImageSource. I don't even know what you're trying to do there.

    Also, the code you just quoted (which came from Andrei) is not sufficient to get a Bitmap from an ImageSource. You need the full code I linked to above. Regardless, I don't see anything that would call that code.

    Please upload a complete example that shows what you're describing in this post. The one you've uploaded crashes and doesn't seem to even go through the code path you're talking about. How do you expect me to help you with this example?

  • Blade4771Blade4771 USMember ✭✭

    sorry, again I have attached the project

  • adamkempadamkemp USInsider, Developer Group Leader mod

    Now you never set the ImageSource at all. What did you intend to set it to?

  • Blade4771Blade4771 USMember ✭✭

    I wanted to share the DrawingImage, but the intent only accepts bitmap, as the convert to bitmap?

    sorry for my english

  • adamkempadamkemp USInsider, Developer Group Leader mod

    I understand that you are trying to convert the ImageSource into a Bitmap, but in your example you're not even setting the ImageSource to anything. Obviously if you start with a null ImageSource you can't convert that into a Bitmap. You need to start with something. So what did you intend to set the ImageSource to?

  • Blade4771Blade4771 USMember ✭✭

    Imagesource in the case would not be the path where the image file?
    but how could set the Imagesource if I "am creating in time" image?

  • adamkempadamkemp USInsider, Developer Group Leader mod

    I have no idea what you're trying to say. Here's the problem: You have code that tries to convert an ImageSource object into a Bitmap, but you don't have any code anywhere that creates an ImageSource. You can't convert an ImageSource into a Bitmap unless you have an ImageSource to start with!

    Look at your code in Page4:

           DrawingImage = new ImageWithTouch {
                VerticalOptions = LayoutOptions.FillAndExpand,
                HorizontalOptions = LayoutOptions.FillAndExpand,
                CurrentLineColor = Color.Black,
            };
            DrawingImage.SetBinding(ImageWithTouch.TextProperty, "TextProperty");
    

    Somewhere in there you should be setting the Source property to something. The reason you're getting null is because you're never setting the source. Obviously you can't convert null into a Bitmap.

  • Blade4771Blade4771 USMember ✭✭

    I'm not sure what to put in the source

  • adamkempadamkemp USInsider, Developer Group Leader mod

    What are you trying to convert to a Bitmap then? At this point I'm not even convinced that you know what you want to do. I have no idea how to help you.

  • Blade4771Blade4771 USMember ✭✭

    I have an image that is a circle and I want to put text in the center of it. I managed to do this using DrawingImage = new ImageWithTouch. now I want to share this circle image with text

  • adamkempadamkemp USInsider, Developer Group Leader mod

    You are all kinds of confused, and I partly blame Xamarin. Let me try to clarify once again:

    Image in Xamarin.Forms is a view. It's not an actual picture. You can't convert an Image to a Bitmap. The Image view has a property called Source, which has the type ImageSource. The ImageSource type represents an actual picture. You can convert an ImageSource into a Bitmap. In your example you are trying to convert an Image into a Bitmap, but that Image has no Source set, which means it has no picture to convert to a Bitmap. It's just blank. There's nothing there to convert.

    I think what you meant to do was to convert the ImageSource into a Bitmap. Instead of passing the ImageWithTouch object (a view) to the Email method you should be just passing an ImageSource. Therefore I changed the interface to take an ImageSource and changed the call to this:

            btnMenu2.Clicked += ((sender, e) =>
            {
                service.Email("[email protected]", DrawingImage.Source);
            });
    

    I also had to set a Source for DrawingImage, and since you never did tell me what that was supposed to be set to I just set it to some random image:

            DrawingImage = new ImageWithTouch {
                VerticalOptions = LayoutOptions.FillAndExpand,
                HorizontalOptions = LayoutOptions.FillAndExpand,
                CurrentLineColor = Color.Black,
                Source = "btn.png",
            };
    

    The interface now looks like this:

    public interface IIntentService
    {
        bool Email(string mail, ImageSource mBitmap);
    }
    

    And the implementation looks like this:

        public bool Email(string mail, ImageSource mBitmap)
        {
    
            saveImageLocally(mBitmap);
    
            // ...
        }
    
        private async void saveImageLocally(ImageSource _bitmap)
        {
            // ...
    
            Bitmap bitmap = await GetBitmap(_bitmap);
    
            // ...
        }
    
        Task<Bitmap> GetBitmap(ImageSource image)
        {
            return GetImageFromImageSource(image, Forms.Context);
        }
    
        private async Task<Bitmap> GetImageFromImageSource(ImageSource imageSource, Context context)
        {
            IImageSourceHandler handler;
    
            if (imageSource is FileImageSource)
            {
                handler = new FileImageSourceHandler();
            }
            else if (imageSource is StreamImageSource)
            {
                handler = new StreamImagesourceHandler(); // sic
            }
            else if (imageSource is UriImageSource)
            {
                handler = new ImageLoaderSourceHandler(); // sic
            }
            else
            {
                throw new NotImplementedException();
            }
    
            return await handler.LoadImageAsync(imageSource, context);
        }
    

    Notice, again, that I'm using the full implementation of GetImageFromImageSource, which I linked above in my first post. That's the key thing that you needed. Andrei's suggestion was not sufficient. This is what you need.

  • Blade4771Blade4771 USMember ✭✭
    edited June 2015

    I did as you suggested, but still face the same problem because images are saved on the device are coming empty.
    I have attached images saved as a test, and was actually to save my picture with the circle and the text that was generated by app

  • Blade4771Blade4771 USMember ✭✭

    thanks, but you are only saving the image without text created random

  • adamkempadamkemp USInsider, Developer Group Leader mod

    Then that is because your code isn't drawing the text in the Bitmap.

  • Blade4771Blade4771 USMember ✭✭

    I make a ImageWithTouch and I can see my picture with text created, but in time to save not saved with the text, do not know why, if I can see the "Page4" my image with text

  • adamkempadamkemp USInsider, Developer Group Leader mod

    Again, that is a different issue. Your question before was how to create a Bitmap from an ImageSource. That's done. Now you need to render into that Bitmap. The ImageSource doesn't magically get the text you drew on top of it. You have to do that yourself.

    At this point I don't think I can help you anymore.

  • FreakyAliFreakyAli USMember ✭✭
  • EmmanuelOluwagbemigaEmmanuelOluwagbemiga USMember ✭✭
    edited September 28

    @adamkemp said:
    Again, that is a different issue. Your question before was how to create a Bitmap from an ImageSource. That's done. Now you need to render into that Bitmap. The ImageSource doesn't magically get the text you drew on top of it. You have to do that yourself.

    At this point I don't think I can help you anymore.

    Beginners can be hard to handle sometimes. Your patience is inspiring.

    I really hope OP was able to figure out all the problems... Probably should have asked a new question for the new problem.

    Well, it's over 5 years now, no one probably cares

Sign In or Register to comment.