如何使用C#裁剪图像?

san*_*101 234 c# image-processing

如何编写将在C#中裁剪图像的应用程序?

Nic*_*ick 258

看看这个链接:http://www.switchonthecode.com/tutorials/csharp-tutorial-image-editing-saving-cropping-and-resizing [<== Link is DEAD]

private static Image cropImage(Image img, Rectangle cropArea)
{
   Bitmap bmpImage = new Bitmap(img);
   return bmpImage.Clone(cropArea, bmpImage.PixelFormat);
}
Run Code Online (Sandbox Code Playgroud)

  • 同意,但请注意,如果cropArea跨越img边界,则会出现"Out of memory"异常. (53认同)
  • 他们的网站已关闭.有人从网站上获得了代码吗? (4认同)
  • 这是性能最差的解决方案。Graphics.DrawImage 解决方案要好得多。 (2认同)

Dan*_*ant 223

您可以使用Graphics.DrawImage从位图将裁剪的图像绘制到图形对象上.

Rectangle cropRect = new Rectangle(...);
Bitmap src = Image.FromFile(fileName) as Bitmap;
Bitmap target = new Bitmap(cropRect.Width, cropRect.Height);

using(Graphics g = Graphics.FromImage(target))
{
   g.DrawImage(src, new Rectangle(0, 0, target.Width, target.Height), 
                    cropRect,                        
                    GraphicsUnit.Pixel);
}
Run Code Online (Sandbox Code Playgroud)

  • 为了裁剪目的,方法`DrawImageUnscaledAndClipped`比`DrawImage`更有效吗? (7认同)
  • 只是注意,DrawImage()的签名无效.[它缺少GraphicsUnit参数](http://msdn.microsoft.com/en-us/library/ms142040.aspx). (3认同)
  • 第二个参数是目标rect,而不是crop rect. (2认同)

Chr*_*sJJ 48

比接受的答案更简单的是:

public static Bitmap cropAtRect(this Bitmap b, Rectangle r)
{
  Bitmap nb = new Bitmap(r.Width, r.Height);
  Graphics g = Graphics.FromImage(nb);
  g.DrawImage(b, -r.X, -r.Y);
  return nb;
}
Run Code Online (Sandbox Code Playgroud)

并且它避免了最简单答案的" 内存不足 "异常风险.

编辑:我发现这可以保存Bitmap.Save或由Paint.exe 保存的PNG ,但由于例如Paint Shop Pro 6保存的PNG失败- 内容被取代.添加GraphicsUnit.Pixel会产生不同的错误结果.也许只是这些失败的PNG是错误的.

  • 最好的回复在这里,这应该是答案.在其他解决方案中,我也遇到了"内存不足".这是第一次工作. (5认同)
  • 此答案泄漏了Grphics对象。 (3认同)
  • 我的图像以正确的尺寸进行裁剪,但 X/Y 方向不正确,直到我按照 @IntellyDev 的答案中的建议对目标图像调用 SetResolution。 (2认同)
  • `Bitmap` 和 `Graphics` 是 `IDisposable` - 添加一个 `using` 子句 (2认同)

小智 7

使用bmp.SetResolution(image.Horizo​​ntalResolution,image .VerticalResolution);

这可能是必要的,即使你在这里实现最佳答案,特别是如果你的图像真的很棒,分辨率不是96.0

我的测试示例:

    static Bitmap LoadImage()
    {
        return (Bitmap)Bitmap.FromFile( @"e:\Tests\d_bigImage.bmp" ); // here is large image 9222x9222 pixels and 95.96 dpi resolutions
    }

    static void TestBigImagePartDrawing()
    {
        using( var absentRectangleImage = LoadImage() )
        {
            using( var currentTile = new Bitmap( 256, 256 ) )
            {
                currentTile.SetResolution(absentRectangleImage.HorizontalResolution, absentRectangleImage.VerticalResolution);

                using( var currentTileGraphics = Graphics.FromImage( currentTile ) )
                {
                    currentTileGraphics.Clear( Color.Black );
                    var absentRectangleArea = new Rectangle( 3, 8963, 256, 256 );
                    currentTileGraphics.DrawImage( absentRectangleImage, 0, 0, absentRectangleArea, GraphicsUnit.Pixel );
                }

                currentTile.Save(@"e:\Tests\Tile.bmp");
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)


Psy*_*der 6

这是裁剪图像的简单示例

public Image Crop(string img, int width, int height, int x, int y)
{
    try
    {
        Image image = Image.FromFile(img);
        Bitmap bmp = new Bitmap(width, height, PixelFormat.Format24bppRgb);
        bmp.SetResolution(80, 60);

        Graphics gfx = Graphics.FromImage(bmp);
        gfx.SmoothingMode = SmoothingMode.AntiAlias;
        gfx.InterpolationMode = InterpolationMode.HighQualityBicubic;
        gfx.PixelOffsetMode = PixelOffsetMode.HighQuality;
        gfx.DrawImage(image, new Rectangle(0, 0, width, height), x, y, width, height, GraphicsUnit.Pixel);
        // Dispose to free up resources
        image.Dispose();
        bmp.Dispose();
        gfx.Dispose();

        return bmp;
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
        return null;
    }            
}
Run Code Online (Sandbox Code Playgroud)

  • 他是唯一一个提到分辨率的人,如果源图像的分辨率不标准,上述所有方法都会失败。 (6认同)
  • 在例外情况下,这会泄漏图像、bmp 和 gfx 对象。为什么不将它们包装在 using 语句中? (3认同)

Guf*_*ffa 5

这很容易:

  • Bitmap使用裁剪大小创建一个新对象.
  • 使用Graphics.FromImage创建Graphics对象的新位图.
  • 使用此DrawImage方法将图像绘制到具有负X和Y坐标的位图上.