asp.net 如何避免在C#中进行Marshal.copy位图处理

sr4lhrrt  于 2023-03-09  发布在  .NET
关注(0)|答案(2)|浏览(115)

我需要从tif图像中提取瓦片,并将它们写成jpg格式。
基于之前的搜索,我在桌面上编写了一些C#代码,可以在C# WinForm项目中使用,然后我想将其作为WebService,但我无法实现,因为此代码使用的Marshal.Copy无法在远程服务器上使用(尽管我有full trust模式。我看过一些评论说这可能是问题所在,但在我的情况下不是)。
源图像是Tif,因此我已经读取了图像中对应于该图块的部分,并保存在名为output的缓冲区中。如果没有更好的方法,我可以接受逐个像素地设置结果图像,但我不知道如何在C#中执行此操作。换句话说,我无法设置结果图像中的像素。使用我从Tif中提取的bytes[]。
在桌面上工作的代码是:

using (var image = new Bitmap(W, H, System.Drawing.Imaging.PixelFormat.Format24bppRgb))
{
     var bmpData = image.LockBits(new Rectangle(0, 0, W, H),ImageLockMode.WriteOnly, 
                                               Image.PixelFormat);
     var ptr = bmpData.Scan0;
     Marshal.Copy(output, 0, ptr, output.Length);
     image.UnlockBits(bmpData);
     image.Save(origin + "\\" + TileName, ImageFormat.Png)
}
643ylb08

643ylb081#

顺便说一句,@JuanR的建议让我解决了这个问题。下面的代码工作,尽管它给我一个内存不足的错误,在创建一些瓷砖。这后一个错误应该与我原来的问题无关。我从微软的文档代码。我感到惊讶的是,尽管它被描述为使用解码器,我注解掉它,并直接使用位图,如你所见如下:

private static void CopyRegionIntoImage(Bitmap srcBitmap, Rectangle srcRegion, ref Bitmap destBitmap, Rectangle destRegion)
    {
        using (Graphics grD = Graphics.FromImage(destBitmap))
        {
            grD.DrawImage(srcBitmap, destRegion, srcRegion, GraphicsUnit.Pixel);
        }
    }

    private static void MakeTile(string Original, int X, int Y, int W, int H, string TileName)
    {
        Stream imageStreamSource = new FileStream(Original, FileMode.Open, FileAccess.Read, FileShare.Read);
        // var decoder = new TiffBitmapDecoder(imageStreamSource, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
        //BitmapSource bitmapSource = decoder.Frames[0];
        Rectangle srcRegion = new Rectangle(X, Y, W, H);
        Rectangle dstRegion = new Rectangle(0, 0, W, H);
        var srcImage = new Bitmap(imageStreamSource);
        var image = new Bitmap(W, H, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
        CopyRegionIntoImage(srcImage, srcRegion, ref image, dstRegion);
        image.Save(TileName, ImageFormat.Png);
    }
ctehm74n

ctehm74n2#

没有内存不足的最终版本:

private static void MakeTile(string Original, int X, int Y, int W, int H, string TileName)
    {
        using (Stream imageStreamSource = new FileStream(Original, FileMode.Open, FileAccess.Read, FileShare.Read))
        {
            Rectangle srcRegion = new Rectangle(X, Y, W, H);
            Rectangle dstRegion = new Rectangle(0, 0, W, H);
            using (var srcImage = new Bitmap(imageStreamSource))
            {
                using (var image = new Bitmap(W, H, System.Drawing.Imaging.PixelFormat.Format24bppRgb))
                {
                    Bitmap outImage = new Bitmap(image);
                    CopyRegionIntoImage(srcImage, srcRegion, ref outImage, dstRegion);
                    outImage.Save(TileName, ImageFormat.Png);
                    outImage.Dispose();

                }
            }
        }
    }

相关问题