¿Cómo recortar una imagen usando C #?


Respuestas:


228

Puede usar Graphics.DrawImagepara dibujar una imagen recortada en el objeto gráfico desde un mapa de bits.

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);
}

3
Solo una nota, la firma de DrawImage () no es válida. Le falta el parámetro GraphicsUnit .
Nathan Taylor el

2
También el segundo argumento es el rect de destino, no el rect de cultivo.
axk

8
¿Es el método DrawImageUnscaledAndClippedmás eficiente que DrawImagepara fines de cultivo?
Ivan Kochurkin

270

Echa un vistazo a este enlace: http://www.switchonthecode.com/tutorials/csharp-tutorial-image-editing-saving-cropping-and-resizing

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

56
De acuerdo, pero tenga en cuenta que si cropArea cruza el límite de img, da una excepción de "Memoria insuficiente".
ChrisJJ

1
@KvanTTT, ambos son bastante lentos si desea recortar una imagen grande en otras más pequeñas.
JBeurer

1
@ChrisJJ ¿puedes explicar más? o dar una solución para ese problema?
raym0nd

1
@ raym0nd Supongo que la solución es garantizar que las dimensiones de su rectángulo no sean más grandes que las de la imagen
stuartdotnet

44
Su sitio está caído. ¿Alguien obtuvo el código del sitio?
sangam

55

Más simple que la respuesta aceptada es esta:

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

y evita el riesgo de excepción "Sin memoria " de la respuesta más simple.

Tenga en cuenta que Bitmapy por lo tanto Graphicsson IDisposablelas usingcláusulas.

EDITAR : Creo que esto está bien con PNG guardados por Bitmap.Saveo Paint.exe, pero falla con PNG guardados por ejemplo, Paint Shop Pro 6 : el contenido se desplaza. La adición de GraphicsUnit.Pixelda un resultado incorrecto diferente. Quizás solo estos PNG defectuosos son defectuosos.


55
La mejor respuesta aquí, esta debería recibir la respuesta. Estaba experimentando la falta de memoria también en otras soluciones. Esto funcionó por primera vez.
c0d3p03t

No entiendo por qué agregar GraphicsUnit.Pixel da el resultado incorrecto, pero definitivamente lo hace.
DOKKA

Mis imágenes estaban recortando con el tamaño correcto pero a X / Y incorrectas hasta que llamé a SetResolution en la imagen de destino como se sugiere en la respuesta de @IntellyDev.
Brent Keller

77
Esta respuesta filtra el objeto Grphics.
TaW

2
Bitmapy Graphicsson IDisposable- agregue una usingcláusula
dave thieben

7

utilizar bmp.SetResolution(image.HorizontalResolution, image .VerticalResolution);

Esto puede ser necesario incluso si implementa la mejor respuesta aquí, especialmente si su imagen es realmente excelente y las resoluciones no son exactamente 96.0

Mi ejemplo de prueba:

    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");
            }
        }
    }

5

Es bastante fácil:

  • Crear un nuevo Bitmap objeto con el tamaño recortado.
  • Use Graphics.FromImagepara crear unGraphics objeto para el nuevo mapa de bits.
  • Utilice el DrawImagemétodo para dibujar la imagen en el mapa de bits con una coordenada X e Y negativa.

5

Aquí hay un ejemplo simple sobre cómo recortar una imagen

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;
    }            
}

55
Él es el único que mencionó la resolución, todos los métodos anteriores fallarán si la imagen de origen tiene una resolución no estándar.
net_prog

1
use bmp.SetResolution (imagen .Resolución horizontal, imagen .Resolución vertical); para solucionar el problema de resolución.
Morbia

2
A excepción de esto, se filtrarán objetos de imagen, bmp y gfx. ¿Por qué no envolverlos en el uso de declaraciones?
Darius Kucinskas

3

Si está utilizando AForge.NET :

using(var croppedBitmap = new Crop(new Rectangle(10, 10, 10, 10)).Apply(bitmap))
{
    // ...
}

2

Estaba buscando una función fácil y RÁPIDA sin una biblioteca adicional para hacer el trabajo. Intenté la solución Nicks , pero necesité 29,4 segundos para "extraer" 1195 imágenes de un archivo atlas. Así que más tarde me las arreglé de esta manera y necesité 2,43 segundos para hacer el mismo trabajo. Quizás esto sea útil.

// content of the Texture class
public class Texture
{
    //name of the texture
    public string name { get; set; }
    //x position of the texture in the atlas image
    public int x { get; set; }
    //y position of the texture in the atlas image
    public int y { get; set; }
    //width of the texture in the atlas image
    public int width { get; set; }
    //height of the texture in the atlas image
    public int height { get; set; }
}

Bitmap atlasImage = new Bitmap(@"C:\somepicture.png");
PixelFormat pixelFormat = atlasImage.PixelFormat;

foreach (Texture t in textureList)
{
     try
     {
           CroppedImage = new Bitmap(t.width, t.height, pixelFormat);
           // copy pixels over to avoid antialiasing or any other side effects of drawing
           // the subimages to the output image using Graphics
           for (int x = 0; x < t.width; x++)
               for (int y = 0; y < t.height; y++)
                   CroppedImage.SetPixel(x, y, atlasImage.GetPixel(t.x + x, t.y + y));
           CroppedImage.Save(Path.Combine(workingFolder, t.name + ".png"), ImageFormat.Png);
     }
     catch (Exception ex)
     {
          // handle the exception
     }
}

1

Recortar una imagen es muy fácil en C #. Sin embargo, hacer las cosas como vas a manejar el recorte de tu imagen será un poco más difícil.

El siguiente ejemplo es la forma de recortar una imagen en C #.

var filename = @"c:\personal\images\horizon.png";
var img = Image.FromFile(filename);
var rect = new Rectangle(new Point(0, 0), img.Size);
var cloned = new Bitmap(img).Clone(rect, img.PixelFormat);
var bitmap = new Bitmap(cloned, new Size(50, 50));
cloned.Dispose();

1

Hay un contenedor de C # para el código abierto, alojado en Codeplex llamado Recorte de imágenes web

Registrar el control

<%@ Register Assembly="CS.Web.UI.CropImage" Namespace="CS.Web.UI" TagPrefix="cs" %>

Redimensionando

<asp:Image ID="Image1" runat="server" ImageUrl="images/328.jpg" />
<cs:CropImage ID="wci1" runat="server" Image="Image1" 
     X="10" Y="10" X2="50" Y2="50" />

Recorte en el código detrás : llame al método de recorte cuando se hace clic en un botón, por ejemplo;

wci1.Crop(Server.MapPath("images/sample1.jpg"));


0

Suponiendo que quiere decir que desea tomar un archivo de imagen (JPEG, BMP, TIFF, etc.) y recortarlo y luego guardarlo como un archivo de imagen más pequeño, sugiero usar una herramienta de terceros que tenga una API .NET. Estos son algunos de los más populares que me gustan:

LeadTools
Accusoft Pegasus Snowbound Imaging SDK


0

Solo esta muestra funciona sin problema:

var crop = new Rectangle(0, y, bitmap.Width, h);
var bmp = new Bitmap(bitmap.Width, h);
var tempfile = Application.StartupPath+"\\"+"TEMP"+"\\"+Path.GetRandomFileName();


using (var gr = Graphics.FromImage(bmp))
{
    try
    {
        var dest = new Rectangle(0, 0, bitmap.Width, h);
        gr.DrawImage(image,dest , crop, GraphicsUnit.Point);
        bmp.Save(tempfile,ImageFormat.Jpeg);
        bmp.Dispose();
    }
    catch (Exception)
    {


    }

}

0

Esta es otra forma. En mi caso tengo:

  • 2 controles numéricos ascendentes (llamados LeftMargin y TopMargin)
  • 1 cuadro de imagen (pictureBox1)
  • 1 botón que llamé generar
  • 1 imagen en C: \ imagenes \ myImage.gif

Dentro del botón tengo este código:

Image myImage = Image.FromFile(@"C:\imagenes\myImage.gif");
Bitmap croppedBitmap = new Bitmap(myImage);
croppedBitmap = croppedBitmap.Clone(
            new Rectangle(
                (int)LeftMargin.Value, (int)TopMargin.Value,
                myImage.Width - (int)LeftMargin.Value,
                myImage.Height - (int)TopMargin.Value),
            System.Drawing.Imaging.PixelFormat.DontCare);
pictureBox1.Image = croppedBitmap;

Lo probé en Visual Studio 2012 usando C #. Encontré esta solución desde esta página


0

aquí está trabajando demo en github

https://github.com/SystematixIndore/Crop-SaveImageInCSharp

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="WebApplication1.WebForm1" %>

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
  <title></title>
 <link href="css/jquery.Jcrop.css" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js"></script>
<script type="text/javascript" src="js/jquery.Jcrop.js"></script>
</head>
<body>
  <form id="form2" runat="server">
  <div>
    <asp:Panel ID="pnlUpload" runat="server">
      <asp:FileUpload ID="Upload" runat="server" />
      <br />
      <asp:Button ID="btnUpload" runat="server" OnClick="btnUpload_Click" Text="Upload" />
      <asp:Label ID="lblError" runat="server" Visible="false" />
    </asp:Panel>
    <asp:Panel ID="pnlCrop" runat="server" Visible="false">
      <asp:Image ID="imgCrop" runat="server" />
      <br />
      <asp:HiddenField ID="X" runat="server" />
      <asp:HiddenField ID="Y" runat="server" />
      <asp:HiddenField ID="W" runat="server" />
      <asp:HiddenField ID="H" runat="server" />
      <asp:Button ID="btnCrop" runat="server" Text="Crop" OnClick="btnCrop_Click" />
    </asp:Panel>
    <asp:Panel ID="pnlCropped" runat="server" Visible="false">
      <asp:Image ID="imgCropped" runat="server" />
    </asp:Panel>
  </div>
  </form>
    <script type="text/javascript">
  jQuery(document).ready(function() {
    jQuery('#imgCrop').Jcrop({
      onSelect: storeCoords
    });
  });

  function storeCoords(c) {
    jQuery('#X').val(c.x);
    jQuery('#Y').val(c.y);
    jQuery('#W').val(c.w);
    jQuery('#H').val(c.h);
  };

</script>
</body>
</html>

Lógica de código C # para cargar y recortar.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.IO;
using SD = System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;

namespace WebApplication1
{
    public partial class WebForm1 : System.Web.UI.Page
    {
        String path = HttpContext.Current.Request.PhysicalApplicationPath + "images\\";
        protected void Page_Load(object sender, EventArgs e)
        {

        }
        protected void btnUpload_Click(object sender, EventArgs e)
        {
            Boolean FileOK = false;
            Boolean FileSaved = false;

            if (Upload.HasFile)
            {
                Session["WorkingImage"] = Upload.FileName;
                String FileExtension = Path.GetExtension(Session["WorkingImage"].ToString()).ToLower();
                String[] allowedExtensions = { ".png", ".jpeg", ".jpg", ".gif" };
                for (int i = 0; i < allowedExtensions.Length; i++)
                {
                    if (FileExtension == allowedExtensions[i])
                    {
                        FileOK = true;
                    }
                }
            }

            if (FileOK)
            {
                try
                {
                    Upload.PostedFile.SaveAs(path + Session["WorkingImage"]);
                    FileSaved = true;
                }
                catch (Exception ex)
                {
                    lblError.Text = "File could not be uploaded." + ex.Message.ToString();
                    lblError.Visible = true;
                    FileSaved = false;
                }
            }
            else
            {
                lblError.Text = "Cannot accept files of this type.";
                lblError.Visible = true;
            }

            if (FileSaved)
            {
                pnlUpload.Visible = false;
                pnlCrop.Visible = true;
                imgCrop.ImageUrl = "images/" + Session["WorkingImage"].ToString();
            }
        }

        protected void btnCrop_Click(object sender, EventArgs e)
        {
            string ImageName = Session["WorkingImage"].ToString();
            int w = Convert.ToInt32(W.Value);
            int h = Convert.ToInt32(H.Value);
            int x = Convert.ToInt32(X.Value);
            int y = Convert.ToInt32(Y.Value);

            byte[] CropImage = Crop(path + ImageName, w, h, x, y);
            using (MemoryStream ms = new MemoryStream(CropImage, 0, CropImage.Length))
            {
                ms.Write(CropImage, 0, CropImage.Length);
                using (SD.Image CroppedImage = SD.Image.FromStream(ms, true))
                {
                    string SaveTo = path + "crop" + ImageName;
                    CroppedImage.Save(SaveTo, CroppedImage.RawFormat);
                    pnlCrop.Visible = false;
                    pnlCropped.Visible = true;
                    imgCropped.ImageUrl = "images/crop" + ImageName;
                }
            }
        }

        static byte[] Crop(string Img, int Width, int Height, int X, int Y)
        {
            try
            {
                using (SD.Image OriginalImage = SD.Image.FromFile(Img))
                {
                    using (SD.Bitmap bmp = new SD.Bitmap(Width, Height))
                    {
                        bmp.SetResolution(OriginalImage.HorizontalResolution, OriginalImage.VerticalResolution);
                        using (SD.Graphics Graphic = SD.Graphics.FromImage(bmp))
                        {
                            Graphic.SmoothingMode = SmoothingMode.AntiAlias;
                            Graphic.InterpolationMode = InterpolationMode.HighQualityBicubic;
                            Graphic.PixelOffsetMode = PixelOffsetMode.HighQuality;
                            Graphic.DrawImage(OriginalImage, new SD.Rectangle(0, 0, Width, Height), X, Y, Width, Height, SD.GraphicsUnit.Pixel);
                            MemoryStream ms = new MemoryStream();
                            bmp.Save(ms, OriginalImage.RawFormat);
                            return ms.GetBuffer();
                        }
                    }
                }
            }
            catch (Exception Ex)
            {
                throw (Ex);
            }
        }
    }
}
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.