C#从大图像生成切片时出错

时间:2016-03-22 14:23:35

标签: c# image-processing

示例全景图片网址https://upload.wikimedia.org/wikipedia/commons/3/3b/360%C2%B0_Hoher_Freschen_Panorama_2.jpg,我保存在我的电脑中并以编程方式从该图片生成图块

  

错误就像内存不足

     

此行抛出错误Bitmap bmLevelSource =   (位图)Bitmap.FromFile(levelSourceImage);

这是我在c#中的程序代码抛出错误

   double maxZoom = 5;
    string FILEPATH = @"C:\test\img.jpg";
    string TARGETFOLDER = @"C:\test\Src";
    bool REMOVEXISTINGFILES = true;

    if (!System.IO.File.Exists(FILEPATH))
    {
        Console.WriteLine("file not exist");
        return;
    }

    if (maxZoom >= 10)
    {
        Console.WriteLine("Scale multiplier should be  an integer <=10");
        return;
    }

    //Read image                    
    Bitmap bmSource;
    try
    {
        bmSource = (Bitmap)Bitmap.FromFile(FILEPATH);
    }
    catch
    {
        Console.WriteLine("image file not valid");
        return;
    }

    //check directory exist
    if (!System.IO.Directory.Exists(TARGETFOLDER))
    {
        System.IO.Directory.CreateDirectory(TARGETFOLDER);
    }
    else if (REMOVEXISTINGFILES)
    {
        string[] files = System.IO.Directory.GetFiles(TARGETFOLDER);
        foreach (string file in files)
            System.IO.File.Delete(file);

        string[] dirs = System.IO.Directory.GetDirectories(TARGETFOLDER);
        foreach (string dir in dirs)
            System.IO.Directory.Delete(dir, true);
    }

    int actualHeight = bmSource.Height;
    int actualWidth = bmSource.Width;

    if (((actualHeight % 256) != 0)
        ||
        ((actualWidth % 256) != 0))
    {
        Console.WriteLine("image width and height pixels should be multiples of 256");
        return;
    }

    int actualResizeSizeWidth = 1;

    int level = 0;
    while (level <= maxZoom)
    {
        string leveldirectory = System.IO.Path.Combine(TARGETFOLDER, String.Format("{0}", level));
        if (!System.IO.Directory.Exists(leveldirectory))
            System.IO.Directory.CreateDirectory(leveldirectory);

        int rowsInLevel = Convert.ToInt32(Math.Pow(2, level));
        actualResizeSizeWidth = 256 * rowsInLevel;

        //create image to parse
        int actualResizeSizeHeight = (actualHeight * actualResizeSizeWidth) / actualWidth;
        Bitmap resized = new Bitmap(bmSource, new Size(actualResizeSizeWidth, actualResizeSizeHeight));
        string levelSourceImage = System.IO.Path.Combine(leveldirectory, "level.png");
        resized.Save(levelSourceImage);

        for (int x = 0; x < rowsInLevel; x++)
        {
            string levelrowdirectory = System.IO.Path.Combine(leveldirectory, String.Format("{0}", x));
            if (!System.IO.Directory.Exists(levelrowdirectory))
                System.IO.Directory.CreateDirectory(levelrowdirectory);

            Bitmap bmLevelSource = (Bitmap)Bitmap.FromFile(levelSourceImage);

            //generate tiles
            int numberTilesHeight = Convert.ToInt32(Math.Ceiling(actualResizeSizeHeight / 256.0));
            for (int y = 0; y < numberTilesHeight; y++)
            {
                Console.WriteLine("Generating Tiles  " + level.ToString() + " " + x.ToString() + " " + y.ToString()); int heightToCrop = actualResizeSizeHeight >= 256 ? 256 : actualResizeSizeHeight;
                Rectangle destRect = new Rectangle(x * 256, y * 256, 256, heightToCrop);
                //croped
                Bitmap bmTile = bmLevelSource.Clone(destRect, System.Drawing.Imaging.PixelFormat.DontCare);
                //full tile
                Bitmap bmFullTile = new Bitmap(256, 256);
                Graphics gfx = Graphics.FromImage(bmFullTile);
                gfx.DrawImageUnscaled(bmTile, 0, 0);
                bmFullTile.Save(System.IO.Path.Combine(levelrowdirectory, String.Format("{0}.png", y)));
                bmFullTile.Dispose();
                bmTile.Dispose();
            }
        }
        level++;
    }

我在运行程序时评论以下代码

    if (((actualHeight % 256) != 0)
        ||
        ((actualWidth % 256) != 0))
    {
        Console.WriteLine("image width and height pixels should be multiples of 256");
        return;
    }

我得到错误的错误是什么?#34; Out of Memory&#34;

由于

修改

实际图片的高度和宽度为1250 and 2500

actualResizeSizeWidth   256
actualResizeSizeHeight  128

我在此帖子中包含一张全景图片网址。你可以下载url并在你的最后执行我的代码以查看内存问题即将到来吗?

代码更新

我稍微修改一下代码并处理一些Bitmap。

像这样处理

bmLevelSource.Dispose(); and resized.Dispose();

while (level <= maxZoom)
    {
        string leveldirectory = System.IO.Path.Combine(TARGETFOLDER, String.Format("{0}", level));
        if (!System.IO.Directory.Exists(leveldirectory))
            System.IO.Directory.CreateDirectory(leveldirectory);

        int rowsInLevel = Convert.ToInt32(Math.Pow(2, level));
        actualResizeSizeWidth = 256 * rowsInLevel;

        //create image to parse
        int actualResizeSizeHeight = (actualHeight * actualResizeSizeWidth) / actualWidth;
        Bitmap resized = new Bitmap(bmSource, new Size(actualResizeSizeWidth, actualResizeSizeHeight));
        string levelSourceImage = System.IO.Path.Combine(leveldirectory, "level.png");
        resized.Save(levelSourceImage);

        for (int x = 0; x < rowsInLevel; x++)
        {
            string levelrowdirectory = System.IO.Path.Combine(leveldirectory, String.Format("{0}", x));
            if (!System.IO.Directory.Exists(levelrowdirectory))
                System.IO.Directory.CreateDirectory(levelrowdirectory);

            Bitmap bmLevelSource = (Bitmap)Bitmap.FromFile(levelSourceImage);

            //generate tiles
            int numberTilesHeight = Convert.ToInt32(Math.Ceiling(actualResizeSizeHeight / 256.0));
            for (int y = 0; y < numberTilesHeight; y++)
            {
                Console.WriteLine("Generating Tiles  " + level.ToString() + " " + x.ToString() + " " + y.ToString()); int heightToCrop = actualResizeSizeHeight >= 256 ? 256 : actualResizeSizeHeight;
                Rectangle destRect = new Rectangle(x * 256, y * 256, 256, heightToCrop);
                //croped
                Bitmap bmTile = bmLevelSource.Clone(destRect, System.Drawing.Imaging.PixelFormat.DontCare);
                //full tile
                Bitmap bmFullTile = new Bitmap(256, 256);
                Graphics gfx = Graphics.FromImage(bmFullTile);
                gfx.DrawImageUnscaled(bmTile, 0, 0);
                bmFullTile.Save(System.IO.Path.Combine(levelrowdirectory, String.Format("{0}.png", y)));
                bmFullTile.Dispose();
                bmTile.Dispose();
            }
            bmLevelSource.Dispose();
        }
        level++;
        resized.Dispose();
    }

请查看我的位修改代码并立即提出建议。

0 个答案:

没有答案