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

C#位图处理:如何避免使用Marshal.Copy?适配WebService场景

从TIF提取瓦片并转JPG的WebService兼容方案

替代Marshal.Copy的内存复制方案(推荐)

如果你的WebService基于.NET Core/.NET 5+,可以用MemoryMarshal直接操作内存区域,避开Marshal.Copy的权限限制:

using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;

// ...

using (var image = new Bitmap(W, H, PixelFormat.Format24bppRgb))
{
    var bmpData = image.LockBits(
        new Rectangle(0, 0, W, H), 
        ImageLockMode.WriteOnly, 
        PixelFormat.Format24bppRgb
    );
    try
    {
        // 将output字节数组复制到Bitmap的内存缓冲区
        var targetSpan = MemoryMarshal.CreateSpan<byte>(
            bmpData.Scan0.ToPointer(), 
            bmpData.Stride * bmpData.Height
        );
        output.AsSpan().CopyTo(targetSpan);
    }
    finally
    {
        image.UnlockBits(bmpData);
    }
    // 保存为JPG(替换原代码的PNG格式)
    image.Save(Path.Combine(origin, TileName), ImageFormat.Jpeg);
}

逐像素设置的兼容方案(全.NET版本支持)

如果必须用逐像素方式,需注意24bppRgb格式的BGR字节顺序和扫描行的4字节对齐规则,代码如下:

using System.Drawing;
using System.Drawing.Imaging;

// ...

using (var image = new Bitmap(W, H, PixelFormat.Format24bppRgb))
{
    // 计算对齐后的扫描行宽度(24bppRgb每行需是4字节的倍数)
    int stride = ((W * 3) + 3) & ~3;
    
    for (int y = 0; y < H; y++)
    {
        for (int x = 0; x < W; x++)
        {
            // 定位当前像素在output数组中的起始索引
            int pixelIndex = y * stride + x * 3;
            // 24bppRgb的字节顺序是B-G-R
            byte blue = output[pixelIndex];
            byte green = output[pixelIndex + 1];
            byte red = output[pixelIndex + 2];
            
            // 设置像素颜色
            image.SetPixel(x, y, Color.FromArgb(red, green, blue));
        }
    }
    
    image.Save(Path.Combine(origin, TileName), ImageFormat.Jpeg);
}

逐像素方案注意点

  • 若你的output数组未做字节对齐(长度为W*3*H),需将pixelIndex改为y * W * 3 + x * 3
  • 逐像素方式性能远低于内存复制,大尺寸瓦片建议优先用第一个方案

关于Marshal.Copy失效的排查

即使开启Full Trust,WebService环境仍可能受限:

  • IIS宿主可能禁用了非托管内存访问权限
  • 早期ASP.NET的沙箱环境可能仍限制此类操作
  • .NET Core/.NET 5+项目需确保已安装System.Drawing.Common NuGet包(仅Windows环境支持)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 14:02:42