如何将文件 .png 转换为位图?什么都不适合我。错误“'Failed to decode image. The provided image must be a Bitmap.'”Xamarin.forms

How can i convert a file .png to a Bitmap? Nothing works for me. Error "'Failed to decode image. The provided image must be a Bitmap.'" Xamarin.forms

我在 Xamarin.Forms 部分使用 Xamarin 我需要将文件 ("image.png") 转换为位图,因为当项目 运行 进入“中断模式”并显示此消息“Java.Lang.IllegalArgumentException:'Failed to decode image. The provided image must be a Bitmap.'”。所以我尝试以多种方式转换文件,例如:

1_ 使用 System.Drawing.Bitmap 中的方法,但显示此异常“此平台不支持此操作”

2_ 无法使用 Android.Graphics,因为我在 xamarin.forms 工作,而不是 xamarin.android。

3_ 我尝试将“image.png”转换为 base64 或 byte[] 数组,然后转换为位图,但问题与第一个问题相同,因为要从 byte[] 数组或base64 到 Bitmap 我使用了 System.Drawing.Bitmap.

中的方法

4_ 我尝试使用库 SkiaSharp 但我没有成功,因为我没有找到太多关于如何将 .png 转换为 SKBitmap 然后将 SKBitmap 转换为位图的信息(即使我不知道是否这是可能的)。

5_ 最后,我使用应用程序将“image.png”转换为“image.bmp”,并在我的项目中使用了 .bmp 文件,但它也不起作用。

我必须将“image.png”保存在一个字符串变量中,这就是我的想法。

如果你有 SkiaSharp 的解决方案,我会很高兴

编辑

这是我的代码的一部分,我只是将图像保存在一个变量中

Icon = "pin_blue.png";
//i can't use a path because in xamarin you have many size from the same 
//image for the different size of the screen

编辑 2 这是我在 google 地图

中显示图钉的方法
private void ShowPins(List<PointsOfInterest> resultPointsOfInterest)
        {
            if (resultPointsOfInterest != null && resultPointsOfInterest.Any())
            {
                var location = Geolocation.GetLastKnownLocationAsync();
                PointsOfInterest position = new PointsOfInterest();
                if (location != null)
                {
                    position.ccsm0166latitud = location.Result.Latitude;
                   position.ccsm0166longitud = location.Result.Longitude;
                
            }
            else {
                position = resultPointsOfInterest.First();
            }
            //Distance = Distance.FromKilometers(new Random().Next(23,35));
            Distance = Distance.FromKilometers(3);
            Position = new Position(position.ccsm0166latitud, position.ccsm0166longitud);
            PinsFiltered= Pins = new List<PinCustom>(resultPointsOfInterest.Select(
                x => new PinCustom()
                {
                    Position =
                        new Position(x.ccsm0166latitud, x.ccsm0166longitud),
                    Address = x.ccsm0166direccion,
                    Label = x.ccsm0166nombre,
                    Type = PinType.Place,
                    TypePointOfInterest = x.ccsm0166tipositio,
                    IconBM = Int32.Parse(x.ccsm0166tipositio) == (int)PointOfInterestType.branch ?  PinCustom.ConvertToBitmap("pin_blue.png") :
                        Int32.Parse(x.ccsm0166tipositio) == (int)PointOfInterestType.branch ? "pin_blue.png" :
                        Int32.Parse(x.ccsm0166tipositio) == (int)PointOfInterestType.branchWithExtendedHours ? "pin_black.png" :
                        Int32.Parse(x.ccsm0166tipositio) == (int)PointOfInterestType.branchWithExtendedHours2 ? "pin_black.png" :
                        Int32.Parse(x.ccsm0166tipositio) == (int)PointOfInterestType.branchWithExtendedHours3 ? "pin_black.png" :
                        Int32.Parse(x.ccsm0166tipositio) == (int)PointOfInterestType.selfServiceTerminal ? "pin_green.png" :
                        Int32.Parse(x.ccsm0166tipositio) == (int)PointOfInterestType.atmServBox ? "pin_yellow.png" : string.Empty
                }).ToList());
        }
        else
        {
            Pins = new List<PinCustom>();
        }
    }

这是我保存图像的 class Pin 图

public class PinCustom : Pin
    {
        public string TypePointOfInterest { get; set; }
        public string Icon { get; set; }
        public Bitmap { get; set; }
        //Here  i create this variable to save a bitmap but i don't know if i do the things well
    }

这是我要在google地图

中显示的图标.png

Pin Blue Image

使用ffmpeg 为此命令:ffmpeg -i image.png image.bmp

打开文件并将其转换为字节数组:

string directory = Path.Combine(Android.OS.Environment.ExternalStorageDirectory.AbsolutePath, Android.OS.Environment.DirectoryDownloads); 
// or your image directory, just replace it
var stream = File.OpenWrite(Path.Combine(directory, "image.png"));
byte[] buff = ConvertStreamToByteArray(stream);
stream.Close();

public static byte[] ConvertStreamToByteArray(Stream stream)
        {
            byte[] byteArray = new byte[16 * 1024];
            using (MemoryStream mStream = new MemoryStream())
            {
                int bit;
                while ((bit = stream.Read(byteArray, 0, byteArray.Length)) > 0)
                {
                    mStream.Write(byteArray, 0, bit);
                }
                return mStream.ToArray();
            }
        }

然后,将此字节数组传递给 SKBitmap:

SKBitmap bmp = SKBitmap.Decode(buff);

编辑:

如果你想在没有ConvertStreamToByteArray()的情况下尝试:

byte[] buff = null;
stream.Write(buff, 0, buff.Length);

Write 将取决于您的 stream 的类型。在这个例子中,我使用 FileStream.

编辑 2:

string resourceID = "image.png";
Assembly assembly = GetType().GetTypeInfo().Assembly;

using (Stream stream = assembly.GetManifestResourceStream(resourceID))
{
   resourceBitmap = SKBitmap.Decode(stream);
   SKBitmap bmp = SKImage.FromBitmap(resourceBitmap);
}

然后你可以使用这个位图来绘制和填充你的 SKCanvas:

canvas.DrawBitmap(bmp, 0, 0);

i have 5 types of pins (pins are the image .png) when i put the pins in format .png

如果您想自定义地图中的图钉,只需使用 Custom Renderers 即可。

可以通过调用MarkerOptions.SetIcon方法自定义用于表示标记的图标。这可以通过覆盖 CreateMarker 方法来实现,该方法会为添加到地图的每个 Pin 调用:

protected override MarkerOptions CreateMarker(Pin pin)
{
    var marker = new MarkerOptions();
    marker.SetPosition(new LatLng(pin.Position.Latitude, pin.Position.Longitude));
    marker.SetTitle(pin.Label);
    marker.SetSnippet(pin.Address);
    marker.SetIcon(BitmapDescriptorFactory.FromResource(Resource.Drawable.pin));
    return marker;
}

如果想显示不同的图标,可以参考下面的代码:

protected override MarkerOptions CreateMarker(Pin pin)
    {
        var marker = new MarkerOptions();
        marker.SetPosition(new LatLng(pin.Position.Latitude, pin.Position.Longitude));
        marker.SetTitle(pin.Label);
        marker.SetSnippet(pin.Address);
        var customPin = (Element as CustomMap).CustomPins.FirstOrDefault(p => p.Position == pin.Position);
        if (customPin != null)
        {
            if (customPin.IconType == "corporate")
            {
                marker.SetIcon(BitmapDescriptorFactory.FromResource(Resource.Drawable.corporate));
            }
            else if (customPin.IconType == "pickup")
            {
                marker.SetIcon(BitmapDescriptorFactory.FromResource(Resource.Drawable.bus));
            }
        }

        return marker;
    }

更多信息,请查看:Customizing the Marker