如何使用.NET在内存中动态创建jpg图像?

Sla*_*uma 17 .net c# graphics jpeg

我有一个用C#编写的.NET(3.5 SP1)库(DLL).我必须通过类方法扩展此库,该方法具有以下签名:

public byte[] CreateGridImage(int maxXCells, int maxYCells,
    int cellXPosition, int cellYPosition)
{
    ...
}
Run Code Online (Sandbox Code Playgroud)

该方法应该执行以下操作:

  • 输入参数maxXCells并maxYCells定义X和Y方向上的单元格网格的大小.maxXCells并且maxYCells是每个方向上的单元格数.单个细胞是方形的.(所以它是一种不对称的棋盘.)
  • 输入参数cellXPosition并cellYPosition识别此网格中的一个特殊单元格,此单元格必须用十字形填充.
  • 不需要花哨的图形,实际上只有白色背景上的黑色网格线和其中一个单元格中的X.
  • 生成的图形必须具有jpg格式.
  • 创建此图形必须在内存中进行,任何内容都不应存储在磁盘上的文件中,也不应绘制在屏幕上.
  • 该方法将生成的图像作为a返回 byte[]

我对.NET中的图形功能非常不熟悉所以我的问题是:

  • 这是否可以使用.NET 3.5 SP1而没有额外的第三方库(我想避免)?
  • 我必须遵循的基本步骤是什么,以及为实现这一目标需要了解的重要.NET命名空间,类和方法(特别是在内存中绘制线条和其他简单的图形元素)并将结果转换为字节jpg格式的数组)?

提前感谢您的建议!

Nak*_*nch 32

以下是完整的代码示例,它将使用GDI绘制网格并放置一个十字(带有红色背景),就像下面的示例图像一样.它像其他答案一样使用GDI,但真正的工作是通过循环遍历单元格和绘制网格线来实现的.

以下代码

byte[] bytes = CreateGridImage(10,10, 9, 9, 30);
Run Code Online (Sandbox Code Playgroud)

将创建一个10x10网格,其交叉位于9x9位置:

在此输入图像描述

新增加的CreateGridImage()是添加了一个boxSize参数,用于设置网格中每个"square"的大小

public static byte[] CreateGridImage(
            int maxXCells,
            int maxYCells,
            int cellXPosition,
            int cellYPosition,
            int boxSize)
{
    using (var bmp = new System.Drawing.Bitmap(maxXCells * boxSize+1, maxYCells * boxSize+1))
    {
        using (Graphics g = Graphics.FromImage(bmp))
        {
            g.Clear(Color.Yellow);
            Pen pen = new Pen(Color.Black);
            pen.Width = 1;

            //Draw red rectangle to go behind cross
            Rectangle rect = new Rectangle(boxSize * (cellXPosition - 1), boxSize * (cellYPosition - 1), boxSize, boxSize);
            g.FillRectangle(new SolidBrush(Color.Red), rect);

            //Draw cross
            g.DrawLine(pen, boxSize * (cellXPosition - 1), boxSize * (cellYPosition - 1), boxSize * cellXPosition, boxSize * cellYPosition);
            g.DrawLine(pen, boxSize * (cellXPosition - 1), boxSize * cellYPosition, boxSize * cellXPosition, boxSize * (cellYPosition - 1));

            //Draw horizontal lines
            for (int i = 0; i <= maxXCells;i++ )
            {
                g.DrawLine(pen, (i * boxSize), 0, i * boxSize, boxSize * maxYCells);
            }

            //Draw vertical lines            
            for (int i = 0; i <= maxYCells; i++)
            {
                g.DrawLine(pen, 0, (i * boxSize), boxSize * maxXCells, i * boxSize);
            }                    
        }

        var memStream = new MemoryStream();
        bmp.Save(memStream, ImageFormat.Jpeg);
        return memStream.ToArray();
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 棒极了!我真的没想到详细的工作.非常感谢你! (3认同)

Pet*_*ate 7

  1. 创建System.Drawing.Bitmap对象.

  2. 创建一个Graphics对象来进行绘图.

  3. 将位图作为JPEG对象保存到MemoryStream.

不要忘记在临时位图上调用Dispose!

示例代码如下,您可以更改下面的像素格式和各种选项,看看MSDN文档.

    public static byte[] CreateGridImage(
        int maxXCells, 
        int maxYCells,
        int cellXPosition, 
        int cellYPosition)
    {
        // Specify pixel format if you like..
        using(var bmp = new System.Drawing.Bitmap(maxXCells, maxYCells)) 
        {
            using (Graphics g = Graphics.FromImage(bmp))
            {
                // Do your drawing here
            }

            var memStream = new MemoryStream();
            bmp.Save(memStream, ImageFormat.Jpeg);
            return memStream.ToArray();
        }
    }
Run Code Online (Sandbox Code Playgroud)