System.Drawing.dll usage in android
Which i'm trying to do is using System.Drawing.dll in Unity and make a texture of string. Until in editor, it works fine. But when i build and play at my android phone, it doesn't work causing error like:
DllNotFoundException: gdiplus.dll
System.Drawing.GDIPlus..cctor ()
or
DllNotFoundException: kernel32.dll
So i searched so many things and i already did everything people says like:
Api Compatibility Level: .Net 2.0 subset --> .Net 2.0
Stripping Level: Disabled
Locate System.Drawing.dll file to Assets/Plugins
System.Drawing.dll version should be same or lower than System.Drawing.dll in "C:\Program Files\Unity\Editor\Data\Mono\lib\mono\2.0" or exactly same file.
And i found someone says that System.Drawing.dll and gdiplus.dll which has dependency on System.Drawing.dll are specific library for Windows, so they can't compatible with other platform(Android, IOS, ...). Which i'm asking is.. is that true? If so, is there any way i can use System.Drawing.dll in android?
Thanks for reading.
BTW, below is my code.
SpriteTextManager.cs:
using System.Collections.Generic;
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Text;
using System.Runtime.InteropServices;
using System.Drawing.Imaging;
using Font = System.Drawing.Font;
using Graphics = System.Drawing.Graphics;
using UnityEngine;
using FontStyle = System.Drawing.FontStyle;
public class SpriteTextManager : MonoBehaviour {
private static SpriteTextManager singleton = null;
private Font font;
private Font boldFont;
private FontFamily family;
private int defaultFontSize = 20;
private Bitmap dummyBitmap = new Bitmap(1, 1);
private Dictionary<int , Sprite> sprites = new Dictionary<int, Sprite>();
private Material defaultMaterial;
public static SpriteTextManager Get() {
if ((object)singleton == null) {
var obj = new GameObject("SpriteTextManager");
singleton = obj.AddComponent<SpriteTextManager>();
DontDestroyOnLoad(obj);
}
return singleton;
}
private void Awake() {
PrivateFontCollection fonts = new PrivateFontCollection();
fonts.AddFontFile(Application.dataPath + "..\\Images\\font_1.ttf");
// Get font family
family = (FontFamily) fonts.Families.GetValue(0);
font = new Font(family, defaultFontSize);
boldFont = new Font(family, defaultFontSize, FontStyle.Bold);
defaultMaterial = new Material(Shader.Find("Sprites/Default"));
}
public Sprite GetSprite(string str) {
return GetSprite(str, defaultFontSize, false, null, 0, false, false, false, false);
}
public Sprite GetSprite(string str, UnityEngine.Color color) {
return GetSprite(str, defaultFontSize, false, color, 0, false, false, false, false);
}
public Sprite GetSprite(string str, int fontSize = -1, bool bestFit = false, UnityEngine.Color? color = null,
int boundaryWidth = 0, bool shadow = false, bool outline = false, bool bold = false, bool fittedBox = false,
int verticalAlignment = 0) {
// verticalAlignment = -1 -> left, 0 -> center, 1 -> right
if (fontSize == -1) fontSize = defaultFontSize;
int key = str.GetHashCode();
if (sprites.ContainsKey(key)) {
return sprites[key];
}
Font localFont;
if (fontSize != defaultFontSize) {
if (bold) localFont = new Font(family, fontSize, FontStyle.Bold);
else localFont = new Font(family, fontSize);
} else {
if (bold) localFont = boldFont;
else localFont = font;
}
Graphics graphics = Graphics.FromImage(dummyBitmap);
graphics.TextRenderingHint = TextRenderingHint.AntiAliasGridFit;
SizeF size = graphics.MeasureString(str, localFont);
Bitmap bmp;
RectangleF boundary;
if (fittedBox) {
bmp = new Bitmap((int)size.Width, (int)size.Height);
boundary = new RectangleF(1, 1, size.Width, (size.Height * (int)Math.Ceiling(size.Width / boundaryWidth)));
} else {
bmp = new Bitmap((int)boundaryWidth, (int) (size.Height * (int)Math.Ceiling(size.Width / boundaryWidth)));
boundary = new RectangleF(1, 1, boundaryWidth, (size.Height * (int)Math.Ceiling(size.Width / boundaryWidth)));
}
if (bestFit) {
if (size.Width > boundaryWidth) {
float fontRatio = boundaryWidth / size.Width;
if (bold) {
localFont = new Font(family, localFont.Size * fontRatio, FontStyle.Bold);
} else {
localFont = new Font(family, localFont.Size * fontRatio);
}
boundary = new RectangleF(1, 1, boundaryWidth, size.Height);
bmp = new Bitmap((int)boundaryWidth, (int) size.Height);
}
}
int width = bmp.Width, height = bmp.Height;
graphics = Graphics.FromImage(bmp);
graphics.SmoothingMode = SmoothingMode.HighSpeed;
graphics.TextRenderingHint = TextRenderingHint.AntiAliasGridFit;
graphics.PixelOffsetMode = PixelOffsetMode.HighSpeed;
graphics.InterpolationMode = InterpolationMode.Bilinear;
UnityEngine.Color textColor = color ?? UnityEngine.Color.black;
SolidBrush blackBrush = new SolidBrush(System.Drawing.Color.Black);
SolidBrush brush = new SolidBrush(System.Drawing.Color.FromArgb((int) (textColor.a * 255), (int) (textColor.r * 255),
(int) (textColor.g * 255), (int) (textColor.b * 255)));
StringFormat format = new StringFormat();
switch (verticalAlignment) {
case -1:
format.Alignment = StringAlignment.Near;
break;
case 0:
format.Alignment = StringAlignment.Center;
break;
case 1:
format.Alignment = StringAlignment.Far;
break;
}
if (outline) {
boundary.X = 2;
boundary.Y = 2;
graphics.DrawString(str, localFont, blackBrush, boundary, format);
boundary.X = 0;
graphics.DrawString(str, localFont, blackBrush, boundary, format);
boundary.X = 2;
boundary.Y = 0;
graphics.DrawString(str, localFont, blackBrush, boundary, format);
boundary.X = 0;
graphics.DrawString(str, localFont, blackBrush, boundary, format);
} else if (shadow) {
boundary.X = 2;
boundary.Y = 2;
graphics.DrawString(str, localFont, blackBrush, boundary, format);
}
boundary.X = 1;
boundary.Y = 1;
graphics.DrawString(str, localFont, brush, boundary, format);
byte[] bytes;
BitmapData bitmapData;
IntPtr Iptr = IntPtr.Zero;
bytes = new byte[width * height * 4];
// bmp.RotateFlip(RotateFlipType.RotateNoneFlipY);
Rectangle bitmapRectangle = new Rectangle(0, 0, width, height);
bitmapData = bmp.LockBits(bitmapRectangle, ImageLockMode.ReadOnly, bmp.PixelFormat);
Iptr = bitmapData.Scan0;
Marshal.Copy(Iptr, bytes, 0, bytes.Length);
Texture2D texture2D = new Texture2D(width, height, TextureFormat.BGRA32, false);
texture2D.LoadRawTextureData(bytes);
texture2D.Apply();
bmp.UnlockBits(bitmapData);
Rect spriteRect = new Rect(0, 0, width, height);
Sprite sprite = Sprite.Create(texture2D, spriteRect, Vector2.zero, 100f, 0, SpriteMeshType.FullRect);
sprites.Add(key, sprite);
return sprite;
}
public Material GetDefaultMaterial() { return defaultMaterial; }
}
SpriteTextRenderer.cs:
using System;
using UnityEngine;
using UnityEngine.UI;
public class SpriteTextRenderer : MonoBehaviour {
private Image image;
private RectTransform rectTransform;
private Sprite sprite = null;
private String _text;
public String text;
public Color color = Color.black;
public int size = 20;
public bool bestFit = false;
public bool outline = false;
public bool shadow = false;
public bool bold = false;
public bool fittedBox = false;
public int horizontalAlignment = 0;
void Start () {
image = GetComponent<Image>();
image.material = SpriteTextManager.Get().GetDefaultMaterial();
rectTransform = GetComponent<RectTransform>();
if (text != "") {
sprite = SpriteTextManager.Get().GetSprite(text, size, bestFit, color, (int)rectTransform.rect.width, shadow, outline, bold, fittedBox, horizontalAlignment);
image.sprite = sprite;
if (rectTransform.localScale.y > 0) {
rectTransform.localScale = new Vector3(rectTransform.localScale.x, rectTransform.localScale.y * -1, rectTransform.localScale.z);
}
rectTransform.sizeDelta = new Vector2(sprite.texture.width, sprite.texture.height);
_text = text;
}
}
void Update() {
if (_text != text && text != "") {
sprite = SpriteTextManager.Get().GetSprite(text, size, bestFit, color, (int)rectTransform.rect.width, shadow, outline, bold, fittedBox, horizontalAlignment);
image.sprite = sprite;
if (rectTransform.localScale.y > 0) {
rectTransform.localScale = new Vector3(rectTransform.localScale.x, rectTransform.localScale.y * -1, rectTransform.localScale.z);
}
rectTransform.sizeDelta = new Vector2(sprite.texture.width, sprite.texture.height);
_text = text;
}
}
}
@ ButterGarlic Have you maybe found a solution for this. I have adjusted Unity version of oxyplot so it can save plots as png images. It all works on windows but not on android. Is there maybe a version of drawing for android (core like)? Have you tryed it?