我目前正在将MVC Web应用程序转换为Xamarin应用程序。但是现在事实证明,.netcore不支持绘图。
public MemoryStream GetGraph_StakeholderMap()
{
var smallfont = 20;
var mediumfont = 25;
var largefont = 40;
var width = 1920;
var height = 1080;
var blockwidth = 1650;
var blockheight = 900;
var arrowoffset = 40;
var blockleft = 200;
var blocktop = 50;
var smallblockwidth = blockwidth / 2;
var smallblockheight = blockheight / 2;
MemoryStream memoryStream = new MemoryStream();
using (Bitmap bitmap = new Bitmap(width, height))
using (Graphics graphics = Graphics.FromImage(bitmap))
using (FontFamily fontFamily = new FontFamily("Arial"))
using (Font fontLarge = new Font(fontFamily, largefont, FontStyle.Regular))
using (Font fontMedium = new Font(fontFamily, mediumfont, FontStyle.Regular))
using (Font fontSmall = new Font(fontFamily, smallfont, FontStyle.Regular))
using (SolidBrush blueBrush = new SolidBrush(Color.FromArgb(79, 193, 233)))
using (SolidBrush grayBrush = new SolidBrush(Color.LightGray))
using (SolidBrush whiteBrush = new SolidBrush(Color.White))
using (StringFormat alignlefttop = new StringFormat())
using (StringFormat alignleftbottom = new StringFormat())
using (StringFormat alignrighttop = new StringFormat())
using (StringFormat alignrightbottom = new StringFormat())
using (StringFormat alignleft = new StringFormat())
using (StringFormat aligncenter = new StringFormat())
using (StringFormat aligncenterhor = new StringFormat())
using (StringFormat alignright = new StringFormat())
{
alignleft.LineAlignment = StringAlignment.Center;
alignleft.Alignment = StringAlignment.Near;
aligncenter.LineAlignment = StringAlignment.Center;
aligncenter.Alignment = StringAlignment.Center;
aligncenterhor.LineAlignment = StringAlignment.Center;
aligncenterhor.Alignment = StringAlignment.Center;
aligncenterhor.FormatFlags = StringFormatFlags.DirectionVertical;
alignright.LineAlignment = StringAlignment.Center;
alignright.Alignment = StringAlignment.Far;
alignlefttop.LineAlignment = StringAlignment.Near;
alignlefttop.Alignment = StringAlignment.Near;
alignleftbottom.LineAlignment = StringAlignment.Far;
alignleftbottom.Alignment = StringAlignment.Near;
alignrighttop.LineAlignment = StringAlignment.Near;
alignrighttop.Alignment = StringAlignment.Far;
alignrightbottom.LineAlignment = StringAlignment.Far;
alignrightbottom.Alignment = StringAlignment.Far;
// Fill
graphics.FillRectangle(whiteBrush, new Rectangle(0, 0, width, height));
// Achtergrond
graphics.FillRectangle(blueBrush, new Rectangle(blockleft, blocktop, smallblockwidth, smallblockheight));
graphics.FillRectangle(grayBrush, new Rectangle(blockleft + smallblockwidth, blocktop, smallblockwidth, smallblockheight));
graphics.FillRectangle(grayBrush, new Rectangle(blockleft, blocktop + smallblockheight, smallblockwidth, smallblockheight));
graphics.FillRectangle(blueBrush, new Rectangle(blockleft + smallblockwidth, blocktop + smallblockheight, smallblockwidth, smallblockheight));
// Arrows
using (Pen p = new Pen(Color.Black, 10))
using (GraphicsPath capPath = new GraphicsPath())
{
// A triangle
capPath.AddLine(-2, 0, 2, 0);
capPath.AddLine(-2, 0, 0, 2);
capPath.AddLine(0, 2, 2, 0);
capPath.AddLine(-2, 0, 2, 0);
p.CustomEndCap = new CustomLineCap(null, capPath);
// Y-as arrow
graphics.DrawLine(p,
blockleft - arrowoffset, blocktop + blockheight + arrowoffset,
blockleft - arrowoffset, blocktop + 20);
// X-as arrow
graphics.DrawLine(p,
blockleft - arrowoffset, blocktop + blockheight + arrowoffset,
blockleft + blockwidth - 20, blocktop + blockheight + arrowoffset);
}
// Y-as
graphics.DrawString("HIGH", fontSmall, Brushes.Black,
new Rectangle(0, blocktop, blockleft - arrowoffset * 2, smallfont + 2), alignright);
graphics.DrawString("LOW", fontSmall, Brushes.Black,
new Rectangle(0, blocktop + blockheight + arrowoffset * 2, blockleft - arrowoffset * 2, smallfont + 2), alignright);
graphics.DrawString("POWER", fontMedium, Brushes.Black,
new Rectangle(0, blocktop, blockleft - arrowoffset * 2, blockheight + 2), aligncenterhor);
// X-as
graphics.DrawString("HIGH", fontSmall, Brushes.Black,
new Rectangle(blockleft, blocktop + blockheight + arrowoffset * 2, blockwidth, smallfont + 2), alignright);
graphics.DrawString("LEVEL OF INTEREST", fontMedium, Brushes.Black,
new Rectangle(blockleft, blocktop + blockheight + arrowoffset * 2, blockwidth, height - (blocktop + blockheight + arrowoffset * 2)), aligncenter);
// Texten
graphics.DrawString("KEEP SATISFIED", fontSmall, Brushes.Black,
new Rectangle(blockleft, blocktop, blockwidth, blockheight), alignlefttop);
graphics.DrawString("KEY PLAYERS", fontSmall, Brushes.Black,
new Rectangle(blockleft, blocktop, blockwidth, blockheight), alignrighttop);
graphics.DrawString("MINIMAL EFFORT", fontSmall, Brushes.Black,
new Rectangle(blockleft, blocktop, blockwidth, blockheight), alignleftbottom);
graphics.DrawString("KEEP INFORMED", fontSmall, Brushes.Black,
new Rectangle(blockleft, blocktop, blockwidth, blockheight), alignrightbottom);
var rect = new Rectangle(blockleft, blocktop, blockwidth, blockheight);
Draw_Helper.DrawDots(graphics, rect, Stakeholders);
// Opslaan
bitmap.Save(memoryStream, System.Drawing.Imaging.ImageFormat.Png);
}
memoryStream.Position = 0;
return memoryStream;
}
我大约有15个这些函数可以通过system.drawing.commen参考进行编译。但是,当我运行代码时,在“使用(位图位图=新位图(宽度,高度))”部分出现此错误:
System.PlatformNotSupportedException: 'System.Drawing is not supported on this platform.'
经过大量搜索后,似乎还没有解决办法。但是我真的不想重写所有这15个函数,那么有人对此有很好的解决方案吗?
答案 0 :(得分:0)
我制作了自己的库,将其转换为javascript画布图像:
public class Graphics
{
public Graphics(string name, int width, int height)
{
Name = name;
Width = width;
Height = height;
Construct();
}
public string Name { get; private set; }
public int Width { get; private set; }
public int Height { get; private set; }
public string Script { get; private set; }
void Construct()
{
Script = "";
Script += "var c" + Name + " = document.getElementById(\"canvas" + Name + "\");\n";
Script += "var ctx" + Name + " = c" + Name + ".getContext(\"2d\");\n";
}
public void FillRectangle(SolidBrush brush, Rectangle rect)
{
FillRectangle(brush, rect.Left, rect.Top, rect.Width, rect.Height);
}
public void FillRectangle(SolidBrush brush, int x, int y, int width, int height)
{
Script += "ctx" + Name + ".fillStyle = \"" + brush.Color.ToRgbaCode() + "\";\n";
Script += "ctx" + Name + ".fillRect(" + x + ", " + y + ", " + width + ", " + height + ");\n";
}
internal void DrawLine(Pen pen, Point point1, Point point2)
{
DrawLine(pen, point1.X, point1.Y, point2.X, point2.Y);
}
public void DrawLine(Pen pen, int x, int y, int x2, int y2)
{
Script += "ctx" + Name + ".beginPath();";
Script += "ctx" + Name + ".strokeStyle = \"" + pen.Color.ToRgbaCode() + "\";\n";
Script += "ctx" + Name + ".lineWidth = \"" + pen.Width + "\";\n";
Script += "ctx" + Name + ".moveTo(" + x + ", " + y + ");\n";
Script += "ctx" + Name + ".lineTo(" + x2 + ", " + y2 + ");\n";
Script += "ctx" + Name + ".stroke();\n";
Script += "ctx" + Name + ".closePath();\n";
}
public void DrawArrow(Pen pen, int x, int y, int x2, int y2)
{
var headlen = 32; // length of head in pixels
var dx = x2 - x;
var dy = y2 - y;
var angle = Math.Atan2(dy, dx);
Script += "ctx" + Name + ".beginPath();";
Script += "ctx" + Name + ".strokeStyle = \"" + pen.Color.ToRgbaCode() + "\";\n";
Script += "ctx" + Name + ".lineWidth = \"" + pen.Width + "\";\n";
Script += "ctx" + Name + ".moveTo(" + x.ToString("F0") + ", " + y.ToString("F0") + ");\n";
Script += "ctx" + Name + ".lineTo(" + x2.ToString("F0") + ", " + y2.ToString("F0") + ");\n";
Script += "ctx" + Name + ".lineTo(" + (x2 - headlen * Math.Cos(angle - Math.PI / 6)).ToString("F0") + ", " + (y2 - headlen * Math.Sin(angle - Math.PI / 6)).ToString("F0") + ");\n";
Script += "ctx" + Name + ".moveTo(" + x2.ToString("F0") + ", " + y2.ToString("F0") + ");\n";
Script += "ctx" + Name + ".lineTo(" + (x2 - headlen * Math.Cos(angle + Math.PI / 6)).ToString("F0") + ", " + (y2 - headlen * Math.Sin(angle + Math.PI / 6)).ToString("F0") + ");\n";
Script += "ctx" + Name + ".stroke();\n";
Script += "ctx" + Name + ".closePath();\n";
}
public void DrawString(string text, Font font, SolidBrush color, Rectangle rectangle, StringFormat format)
{
var topoffset = 0;
if (format.LineAlignment == StringAlignment.Far)
{
topoffset = rectangle.Height;
}
else if (format.LineAlignment == StringAlignment.Center)
{
topoffset = (rectangle.Height - font.Size) / 2 + font.Size;
}
else
{
topoffset = font.Size;
}
Script += "ctx" + Name + ".font = \"" + font.Size + "px " + font.FontFamily.Name + "\";\n";
Script += "ctx" + Name + ".fillStyle = \"" + color.Color.ToRgbaCode() + "\";\n";
//if (format.FormatFlags == StringFormatFlags.DirectionVertical)
//{
// Script += "ctx" + Name + ".rotate(90 * Math.PI / 180);\n";
//}
if (format.Alignment == StringAlignment.Far)
{
// Horizontal Right
var left = rectangle.Left + rectangle.Width;
var top = rectangle.Top + topoffset;
Script += "ctx" + Name + ".textAlign = \"right\";\n";
Script += "ctx" + Name + ".fillText(\"" + text + "\", \"" + left + "\", \"" + top + "\");\n";
}
else if (format.Alignment == StringAlignment.Center)
{
// Horizontal Center
var left = rectangle.Left + rectangle.Width / 2;
var top = rectangle.Top + topoffset;
Script += "ctx" + Name + ".textAlign = \"center\";\n";
Script += "ctx" + Name + ".fillText(\"" + text + "\", \"" + left + "\", \"" + top + "\");\n";
}
else
{
// Horizontal Left
var left = rectangle.Left;
var top = rectangle.Top + topoffset;
Script += "ctx" + Name + ".textAlign = \"left\";\n";
Script += "ctx" + Name + ".fillText(\"" + text + "\", \"" + left + "\", \"" + top + "\");\n";
}
//if (format.FormatFlags == StringFormatFlags.DirectionVertical)
//{
// Script += "ctx" + Name + ".rotate(0);\n";
//}
}
public void DrawRectangle(Pen pen, Rectangle rect)
{
Script += "ctx" + Name + ".beginPath();\n";
Script += "ctx" + Name + ".lineWidth = \"" + pen.Width + "\";\n";
Script += "ctx" + Name + ".strokeStyle = \"" + pen.Color.ToRgbaCode() + "\";\n";
Script += "ctx" + Name + ".rect(" + rect.Left + ", " + rect.Top + ", " + rect.Width + ", " + rect.Height + ");\n";
Script += "ctx" + Name + ".stroke();\n";
}
public void DrawEllipse(Pen pen, double x, double y, double w, double h)
{
Script += "ctx" + Name + ".beginPath();\n";
var kappa = .5522848;
var ox = (w / 2) * kappa; // control point offset horizontal
var oy = (h / 2) * kappa; // control point offset vertical
var xe = x + w; // x-end
var ye = y + h; // y-end
var xm = x + w / 2; // x-middle
var ym = y + h / 2; // y-middle
Script += "ctx" + Name + ".beginPath();";
Script += "ctx" + Name + ".strokeStyle = \"" + pen.Color.ToRgbaCode() + "\";\n";
Script += "ctx" + Name + ".lineWidth = \"" + pen.Width + "\";\n";
Script += "ctx" + Name + ".moveTo(" + x + ", " + ym + ");";
Script += "ctx" + Name + ".bezierCurveTo(" + x + ", " + (ym - oy) + ", " + (xm - ox) + ", " + y + ", " + xm + ", " + y + ");";
Script += "ctx" + Name + ".bezierCurveTo(" + (xm + ox) + ", " + y + ", " + xe + ", " + (ym - oy) + ", " + xe + ", " + ym + ");";
Script += "ctx" + Name + ".bezierCurveTo(" + xe + ", " + (ym + oy) + ", " + (xm + ox) + ", " + ye + ", " + xm + ", " + ye + ");";
Script += "ctx" + Name + ".bezierCurveTo(" + (xm - ox) + ", " + ye + ", " + x + ", " + (ym + oy) + ", " + x + ", " + ym + ");";
Script += "ctx" + Name + ".lineWidth = \"" + pen.Width + "\";\n";
Script += "ctx" + Name + ".strokeStyle = \"" + pen.Color.ToRgbaCode() + "\";\n";
Script += "ctx" + Name + ".stroke();\n";
Script += "ctx" + Name + ".closePath();\n";
}
public void FillEllipse(SolidBrush brush, double x, double y, double w, double h)
{
Script += "ctx" + Name + ".beginPath();\n";
var kappa = .5522848;
var ox = (w / 2) * kappa; // control point offset horizontal
var oy = (h / 2) * kappa; // control point offset vertical
var xe = x + w; // x-end
var ye = y + h; // y-end
var xm = x + w / 2; // x-middle
var ym = y + h / 2; // y-middle
Script += "ctx" + Name + ".beginPath();";
Script += "ctx" + Name + ".fillStyle = \"" + brush.Color.ToRgbaCode() + "\";\n";
Script += "ctx" + Name + ".moveTo(" + x + ", " + ym + ");";
Script += "ctx" + Name + ".bezierCurveTo(" + x + ", " + (ym - oy) + ", " + (xm - ox) + ", " + y + ", " + xm + ", " + y + ");";
Script += "ctx" + Name + ".bezierCurveTo(" + (xm + ox) + ", " + y + ", " + xe + ", " + (ym - oy) + ", " + xe + ", " + ym + ");";
Script += "ctx" + Name + ".bezierCurveTo(" + xe + ", " + (ym + oy) + ", " + (xm + ox) + ", " + ye + ", " + xm + ", " + ye + ");";
Script += "ctx" + Name + ".bezierCurveTo("+ (xm - ox) + ", " + ye + ", " + x + ", " + (ym + oy) + ", " + x + ", " + ym + ");";
Script += "ctx" + Name + ".fill();\n";
Script += "ctx" + Name + ".closePath();\n";
}
public void DrawImage(Image img, Rectangle rectangle)
{
Script += "var img" + img.Id + " = new Image;\n";
Script += "ctx" + Name + ".onload = function() {\n";
Script += " ctx" + Name + ".drawImage(img" + img.Id + ", 0, 0);\n";
Script += "};\n";
Script += "img" + img.Id + ".src = \"" + img.Url + "\";\n";
}
}
public static class Brushes
{
public static SolidBrush Black => new SolidBrush(Color.Black);
public static SolidBrush White => new SolidBrush(Color.White);
}
public class Color
{
public Color(int a, int r, int g, int b)
{
A = a;
R = r;
G = g;
B = b;
}
public int A { get; private set; }
public int R { get; private set; }
public int G { get; private set; }
public int B { get; private set; }
public static Color FromArgb(int r, int g, int b)
{
return new Color(255, r, g, b);
}
public string ToRgbaCode() => "rgba(" + R + ", " + G + ", " + B + ", " + A + ")";
public static Color LightGray => new Color(255, 192, 192, 192);
public static Color White => new Color(255, 255, 255, 255);
public static Color Black => new Color(255, 0, 0, 0);
public static Color LightBlue => new Color(255, 128, 128, 255);
public static Color DarkBlue => new Color(255, 0, 0, 128);
public static Color Gray => new Color(255, 128, 128, 128);
public static Color Green => new Color(255, 0, 255, 0);
}
public class Font : IDisposable
{
public Font(FontFamily fontFamily, int largefont, FontStyle regular)
{
this.FontFamily = fontFamily;
this.Size = largefont;
this.FontStyle = regular;
}
public FontFamily FontFamily { get; set; }
public int Size { get; set; }
public FontStyle FontStyle { get; set; }
public void Dispose()
{
}
}
public class FontFamily : IDisposable
{
public FontFamily(string name)
{
this.Name = name;
}
public string Name { get; private set; }
public void Dispose()
{
}
}
public enum FontStyle
{
Regular
}
public class Image : IDisposable
{
static long _Id { get; set; }
public long Id { get; } = ++_Id;
public Image(string url)
{
this.Url = url;
}
public string Url { get; set; }
public static Image FromFile(string url)
{
return new Image(url);
}
public void Dispose()
{
}
}
public class Pen : IDisposable
{
public Pen(SolidBrush black)
{
this.Brush = black;
}
public Pen(Color color, int width)
{
this.Brush = new SolidBrush(color, width);
}
public SolidBrush Brush { get; private set; }
public Color Color => Brush.Color;
public int Width => Brush.Width;
public float[] DashPattern { get; internal set; }
public void Dispose()
{
}
}
public class Point
{
public int X { get; set; }
public int Y { get; set; }
public Point(int x, int y)
{
this.X = x;
this.Y = y;
}
}
public class Rectangle
{
public Rectangle()
{
}
public Rectangle(int left, int top, int width, int height)
{
this.Left = left;
this.Top = top;
this.Width = width;
this.Height = height;
}
public int Left { get; set; }
public int Top { get; set; }
public int Width { get; set; }
public int Height { get; set; }
public int Right => Left + Width;
public int Bottom => Top + Height;
}
public class SolidBrush : IDisposable
{
public SolidBrush(Color color, int width = 1)
{
this.Color = color;
this.Width = width;
}
public Color Color { get; set; }
public int Width { get; set; }
public void Dispose()
{
}
}
public enum StringAlignment
{
Near,
Center,
Far
}
public class StringFormat : IDisposable
{
public StringAlignment LineAlignment { get; set; } = StringAlignment.Near;
public StringAlignment Alignment { get; set; } = StringAlignment.Near;
public StringFormatFlags FormatFlags { get; set; } = StringFormatFlags.DirectionHorizontal;
public void Dispose()
{
}
}
public enum StringFormatFlags
{
DirectionHorizontal,
DirectionVertical
}
答案 1 :(得分:0)
您可以使用Aspose.Drawing作为System.Drawing.Common的跨平台替代品。它提供了完全兼容的API,因此您不必更改现有代码。 (我是开发人员之一。)