Xamarin Forms - Image To/From IRandomAccessStreamReference

纵然是瞬间 提交于 2020-07-09 09:23:45

问题


For personal needs, for the Xamarin.Forms.Map control, I need to create a CustomPin extension. UWP part (PCL project)

I create a MapIcon like it:

nativeMap.MapElements.Add(new MapIcon()
{
    Title = pin.Name,
    Image = RandomAccessStreamReference.CreateFromUri(new Uri("ms-appx:///Assets/Pin/customicon.png")),
    Location = new Geopoint(new BasicGeoposition() { Latitude = pin.Position.Latitude, Longitude = pin.Position.Longitude }),
    NormalizedAnchorPoint = new Windows.Foundation.Point(0.5, 1.0)
});

However, by this way, I can't set the Image's size.

I then want to use an Image from my PCL part, resize it and convert it into a IRandomAccessStreamReference. To realize it, I need to convert my Image into a stream, but I can't find the way to make it works ><

Example of the function needed:

private IRandomAccessStreamReference ImageToIRandomAccessStreamReference(Image image)
{
    //Here I can set the size of my Image

    //I convert it into a stream
    IRandomAccessStreamReference irasr = RandomAccessStreamReference.CreateFromStream(/* img? */);

    //irasr is then created from img

    //I return the IRandomAccessStreamReference needed by the MapIcon element
    return irasr;
}

Note: The Image paramter img is a Xamarin.Forms.Image

So first, is it possible? If yes, then thank for any help which could help me.. I already search about how to resize the MapIcon and it's not possible directly from the class [MapIcon].(https://msdn.microsoft.com/library/windows/apps/windows.ui.xaml.controls.maps.mapicon.aspx)

Thank for help !


回答1:


You are right. We can't resize the MapIcon directly as it doesn't provide such properties or methods. MapIcon's size is mostly controlled by the size of image which is set by MapIcon.Image property. And we can set this image's size without using Xamarin.Forms.Image.

To set this image's size, we can take advantage of BitmapDecoder class, BitmapEncoder class and BitmapTransform class like following:

private async System.Threading.Tasks.Task<RandomAccessStreamReference> ResizeImage(StorageFile imageFile, uint scaledWidth, uint scaledHeight)
{
    using (IRandomAccessStream fileStream = await imageFile.OpenAsync(FileAccessMode.Read))
    {
        var decoder = await BitmapDecoder.CreateAsync(fileStream);

        //create a RandomAccessStream as output stream
        var memStream = new InMemoryRandomAccessStream();

        //creates a new BitmapEncoder and initializes it using data from an existing BitmapDecoder
        BitmapEncoder encoder = await BitmapEncoder.CreateForTranscodingAsync(memStream, decoder);

        //resize the image
        encoder.BitmapTransform.ScaledWidth = scaledWidth;
        encoder.BitmapTransform.ScaledHeight = scaledHeight;

        //commits and flushes all of the image data
        await encoder.FlushAsync();

        //return the output stream as RandomAccessStreamReference
        return RandomAccessStreamReference.CreateFromStream(memStream);
    }
}

And then we can use this method to create a resized image stream reference first and then set it as MapIcon's Image like:

var file = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///Assets/Pin/customicon.png"));
var imageReference = await ResizeImage(file, 64, 64);

nativeMap.MapElements.Add(new MapIcon()
{
    Title = pin.Name,
    Image = imageReference,
    Location = new Geopoint(new BasicGeoposition() { Latitude = pin.Position.Latitude, Longitude = pin.Position.Longitude }),
    NormalizedAnchorPoint = new Windows.Foundation.Point(0.5, 1.0)
});


来源:https://stackoverflow.com/questions/39618846/xamarin-forms-image-to-from-irandomaccessstreamreference

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!