You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Unity3D项目中添加C# System.Drawing引用?

Unity中使用System.Drawing类的引用问题及解决方案

问题说明

在Unity3D项目的FindPoints方法中,尝试使用Bitmap、GraphicsPath、BitmapData、Rectangle等System.Drawing下的类时,始终提示缺少引用。修改Unity编辑器Project Settings>Player的API兼容性级别为.NET 2.1后,仅能获取部分System.Drawing内容,无法使用完整的GDI+相关功能,导致代码无法正常运行。原代码如下:

private void FindPoints()
{
    Bitmap bmptest;
    GraphicsPath gp = new GraphicsPath();
    int x, y, p, j, wdthHght;
    int bytes;
    byte[] rgbValuesWithClouds;
    byte[] rgbValuesWithoutClouds;
    IntPtr ptr;
    Rectangle rect;
    BitmapData bitmap_Data;

    Bitmap bmpWithClouds; //No memory is allocated
    Bitmap bmpWithoutClouds; //No memory is allocated

    gp.AddEllipse(new RectangleF(73, 72, 367, 367));

    //using the using statement, bmpWithClouds bitmap is automatically disposed at the end of statement. No memory leaks :)
    using (bmpWithClouds = new Bitmap(mymem))
    {
        rect = new Rectangle(0, 0, bmpWithClouds.Width, bmpWithClouds.Height);
        wdthHght = bmpWithClouds.Width;

        //Lock bitmap to copy its color information fast
        bitmap_Data = bmpWithClouds.LockBits(rect, ImageLockMode.ReadWrite, bmpWithClouds.PixelFormat);
        ptr = bitmap_Data.Scan0;
        bytes = bitmap_Data.Stride * bmpWithClouds.Height;

        rgbValuesWithClouds = new byte[bytes];

        //copy color information to rgbValues array
        System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValuesWithClouds, 0, bytes);
        //we are done copying so unlock bitmap. We dont need it anymore
        bmpWithClouds.UnlockBits(bitmap_Data);
    }

    //using the using statement, bmpWithClouds bitmap is automatically disposed at the end of statement. No memory leaks :)
    using (bmpWithoutClouds = new Bitmap(@"F:\Drive Backup\Samsung Galaxy S9\Danny Backup\Recovered data 02-10 18_32_36\1  (D) NTFS\C-Sharp\Weather Radar\WithoutClouds.bmp")) //24 bit bitmap
    {
        rect = new Rectangle(0, 0, bmpWithoutClouds.Width, bmpWithoutClouds.Height);

        //Lock bitmap to copy its color information fast
        bitmap_Data = bmpWithoutClouds.LockBits(rect, ImageLockMode.ReadWrite, bmpWithoutClouds.PixelFormat);
        ptr = bitmap_Data.Scan0;
        bytes = bitmap_Data.Stride * bmpWithoutClouds.Height;

        rgbValuesWithoutClouds = new byte[bytes];

        //copy color information to rgbValues array
        System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValuesWithoutClouds, 0, bytes);
        //we are done copying so unlock bitmap. We dont need it anymore
        bmpWithoutClouds.UnlockBits(bitmap_Data);
    }

    // Each position in these arrays, rgbValuesWithoutClouds and rgbValuesWithClouds, corresponds a color. eg
    // First pixel   Second pixel   Third pixel   Forth pixel .... // bitmaps
    //    B G R          B G R         B G R         B G R    .... // rgbValues arrays
    bmptest = new Bitmap(512, 512);
    cloudPoints = new List<Point>();

    for (y = 0; y < wdthHght; y++)
    {
        j = 0;
        for (x = 0; x < wdthHght; x++)
        {
            p = y * wdthHght * 3 + j;

            if (rgbValuesWithClouds[p] != rgbValuesWithoutClouds[p])
            {
                cloudPoints.Add(new Point(x, y));
                bmptest.SetPixel(x, y, Color.Red);
            }

            j += 3;
        }
    }
}

解决方案

1. 理解Unity对System.Drawing的限制

System.Drawing是Windows平台GDI+的实现,Unity的跨平台运行时(Mono/.NET Core)并未完整包含该库,仅提供了少量基础类型。因此即使修改API兼容性级别,也无法获取完整的GDI+功能,且该库在非Windows平台完全无法使用。

2. 推荐方案:使用Unity原生Texture2D替代Bitmap

Unity提供了Texture2D类用于图像操作,完全跨平台,且能无缝集成到Unity的渲染系统中。以下是用Texture2D重写的FindPoints方法:

using UnityEngine;
using System.Collections.Generic;
using System.IO;

private List<Vector2> cloudPoints; // 用Unity的Vector2替代System.Drawing.Point

private void FindPoints()
{
    // 读取带云层的图片(替换原mymem为实际路径或Texture2D对象)
    Texture2D bmpWithClouds = LoadTextureFromPath("你的带云层图片路径");
    Texture2D bmpWithoutClouds = LoadTextureFromPath(@"F:\Drive Backup\Samsung Galaxy S9\Danny Backup\Recovered data 02-10 18_32_36\1  (D) NTFS\C-Sharp\Weather Radar\WithoutClouds.bmp");

    if (bmpWithClouds == null || bmpWithoutClouds == null)
    {
        Debug.LogError("图片加载失败");
        return;
    }

    int width = bmpWithClouds.width;
    int height = bmpWithClouds.height;

    // 获取像素数据(RGBA格式,每个像素4字节)
    Color32[] pixelsWithClouds = bmpWithClouds.GetPixels32();
    Color32[] pixelsWithoutClouds = bmpWithoutClouds.GetPixels32();

    cloudPoints = new List<Vector2>();
    Texture2D bmptest = new Texture2D(width, height);
    Color32[] testPixels = bmptest.GetPixels32();

    for (int y = 0; y < height; y++)
    {
        for (int x = 0; x < width; x++)
        {
            int index = y * width + x;
            // 对比蓝色通道(对应原代码的B分量)
            if (pixelsWithClouds[index].b != pixelsWithoutClouds[index].b)
            {
                cloudPoints.Add(new Vector2(x, y));
                testPixels[index] = Color.red;
            }
            else
            {
                testPixels[index] = Color.clear;
            }
        }
    }

    bmptest.SetPixels32(testPixels);
    bmptest.Apply();

    // 释放临时Texture资源(如果不再使用)
    Object.Destroy(bmpWithClouds);
    Object.Destroy(bmpWithoutClouds);
}

// 辅助方法:从本地路径加载Texture2D
private Texture2D LoadTextureFromPath(string path)
{
    if (!File.Exists(path))
    {
        Debug.LogError($"文件不存在:{path}");
        return null;
    }

    byte[] fileData = File.ReadAllBytes(path);
    Texture2D texture = new Texture2D(2, 2);
    texture.LoadImage(fileData); // 自动识别图片格式
    return texture;
}

3. 临时方案:仅Windows平台使用System.Drawing

如果必须保留原有System.Drawing代码,仅在Windows平台运行项目,可按以下步骤操作:

  • 在Unity项目的Assets文件夹下创建Plugins目录;
  • 从本地.NET框架目录(如C:\Windows\Microsoft.NET\Framework\v4.0.30319)复制System.Drawing.dll、System.Drawing.Design.dll到Plugins文件夹;
  • 选中复制的DLL文件,在Inspector面板中设置Platform Settings:勾选Windows,其他平台设为Exclude;
  • 重新打开Unity,即可使用完整的System.Drawing类。注意此方法仅支持Windows编辑器和Windows打包版本,跨平台项目请勿使用。

内容的提问来源于stack exchange,提问作者Daniel Lip

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 02:35:55