m图像中分割图像

m图像中分割图像

本文介绍了在n x m图像中分割图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在程序中使用了一些大的精灵表(最大2048 x 2048像素,png 32位).

现在,我有以下选择:
1.在图像编辑器中分割图像,然后将各个精灵作为资源添加到我的程序中(我不喜欢这种方法)
2.加载图像,将其拆分,保留零件,然后进行处理. (我最喜欢这个,因为这项工作只完成了一次)
3.加载图像,保留它,并在需要时从其中除去精灵.

至于实际的拆分,我想到了两个选择:
1.首先将其拆分为行,然后使用ImageList s将其拆分为单个单元格中的行.

I have some large sprite sheets (up to 2048 x 2048 pixels, png 32 bit) which I use in my programs.

Now, I have the following options:
1. Split the image in an image editor and add the individual sprites to my program as resources (I don''t like this approach)
2. Load the image, split it, keep the parts and then dispose it. (I like this most, as the job is done only once)
3. Load the image, keep it and get the sprites out of it when needed.

As for the actual splitting, I thought of two options:
1. Split it first in rows and then the rows in individual cells using ImageLists.

private static ImageList Split(Bitmap image, int width, int height)
{
    ImageList rows = new ImageList();
    rows.ImageSize = new Size(image.Width, height);
    rows.Images.AddStrip(image);
    ImageList cells = new ImageList();
    cells.ImageSize = new Size(width, height);
    foreach (Image row in Rows.Images)
    {
        cells.Images.AddStrip(row);
    }
    return cells;
}


(粗糙的代码,仅用于示例)


2.使用Graphics在画布上绘制它的一部分.


(rough code, just for purpose of exemplification)


2. Draw portions of it on a canvas using Graphics.

private static ImageList Split(Bitmap image, int width, int height)
{
    ImageList cells = new ImageList();
    cells.ImageSize = new Size(width, height);
    Bitmap bmp = new Bitmap(width, height);
    Graphics g = Graphics.FromImage(bmp);
    for (int i = 0; i < image.Width / width; i++)
    {
        for (int j = 0; i < image.Height / height; j++)
        {
            g.DrawImageUnscaled(image, -i * width, -j * height);
            cells.Images.Add((Bitmap)bmp.Clone());
        }
    }
    return cells;
}


(粗糙的代码,仅用于示例)


但是,这两种方法都相当慢... :(
必须有更好的方法!
有人可以给我一些想法吗?
谢谢.

如果您认为这是一个好问题,请投票.


(rough code, just for purpose of exemplification)


However, both methods are quite slow... :(
There must be a better way!
Can someone give me a few ideas?
Thank you.

If you think this is a good question, please vote it.

推荐答案



private static int Main(string[] args)
{
    if (args.Length < 3)
    {
        Console.WriteLine("Error 1: Not enough arguments. Usage: SplitImage filename cellwidth cellheight");
        return -1;
    }
    string filename = args[0];
    if (!File.Exists(filename))
    {
        Console.WriteLine("Error 2: File not found.");
        return -2;
    }
    ushort width;
    ushort height;
    if (!ushort.TryParse(args[1], out width))
    {
        Console.WriteLine("Error 3: Cannot parse cell width.");
        return -3;
    }
    if (!ushort.TryParse(args[2], out height))
    {
        Console.WriteLine("Error 4: Cannot parse cell height.");
        return -4;
    }
    Bitmap bmp = null;
    try
    {
        bmp = (Bitmap)Image.FromFile(filename);
    }
    catch
    {
        Console.WriteLine("Error 5: Cannot load image from file.");
        return -5;
    }
    if (width == 0)
        width = (ushort)bmp.Width;
    if (height == 0)
        height = (ushort)bmp.Height;
    int columns = bmp.Width / width;
    int rows = bmp.Height / height;
    int cells = columns * rows;
    if (cells == 0)
    {
        Console.WriteLine("Warning: Cannot split image in 0 cells.");
        return 0;
    }
    string dir;
    try
    {
        dir = Path.GetDirectoryName(filename) + Path.DirectorySeparatorChar + Path.GetFileNameWithoutExtension(filename);
        if (!Directory.Exists(dir))
            Directory.CreateDirectory(dir);
    }
    catch
    {
        Console.WriteLine("Error 6: Cannot create directory for cells.");
        return -6;
    }
    Console.WriteLine();
    Console.WriteLine("About to split image in {0} rows x {1} columns = {2} cells...", rows, columns, cells);
    Console.WriteLine();
    int cellpadding = (cells - 1).ToString().Length;
    int rowpadding = (rows - 1).ToString().Length;
    string cellfile;
    string cellpath;
    try
    {
        for (int row = 0; row < rows; row++)
        {
            Console.Write("Row " + row.ToString().PadLeft(rowpadding, ' ') + ":  ");
            for (int column = 0; column < columns; column++)
            {
                cellfile = (row * columns + column).ToString().PadLeft(cellpadding, '0');
                cellpath = dir + Path.DirectorySeparatorChar + cellfile + ".png";
                bmp.Clone(new Rectangle(column * width, row * height, width, height), bmp.PixelFormat).Save(cellpath, ImageFormat.Png);
                Console.Write(cellfile + "  ");
            }
            Console.WriteLine();
        }
        Console.WriteLine();
        Console.WriteLine("{0} files written to disk.", cells);
        Console.WriteLine();
    }
    catch (Exception ex)
    {
        Console.WriteLine("Error 7: " + ex.Message);
        return -7;
    }
    return cells;
}


这篇关于在n x m图像中分割图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-11 19:38