2009-07-18 76 views
8

我想裁剪和调整图像大小。这里是我的代码:图形对象到图像文件

Image image = Image.FromFile(AppDomain.CurrentDomain.BaseDirectory + "Cropper/tests/castle.jpg"); 

// Crop and resize the image. 
Rectangle destination = new Rectangle(0, 0, 200, 120); 
Graphics graphic = Graphics.FromImage(image); 
graphic.DrawImage(image, destination, int.Parse(X1.Value), int.Parse(Y1.Value), int.Parse(Width.Value), int.Parse(Height.Value), GraphicsUnit.Pixel); 

现在我认为我得到的裁剪/调整后的图像存储在图形对象。问题是 - 如何将其保存到文件?

回答

10

GraphicsGraphics.FromImage得到的对象是图像的绘图表面。所以你可以在完成后简单地保存图像对象。

string fileName = AppDomain.CurrentDomain.BaseDirectory + "Cropper/tests/castle.jpg"); 
using (Image image = Image.FromFile(fileName) 
{ 
    using (Graphics graphic = Graphics.FromImage(image)) 
    { 
     // Crop and resize the image. 
     Rectangle destination = new Rectangle(0, 0, 200, 120); 
     graphic.DrawImage(image, destination, int.Parse(X1.Value), int.Parse(Y1.Value), int.Parse(Width.Value), int.Parse(Height.Value), GraphicsUnit.Pixel); 
    } 
    image.Save(fileName); 
} 

虽然在jpg图像上反复做这件事可能不是一件好事,每次都会重新编码图像,由于jpg使用破坏性压缩方法,因此每次都会丢失一些图像质量。不过,如果这是一个每图像一次的操作,我不会担心。

5

不,Graphics对象不包含任何图像数据,它用于绘制一个画布,通常是画布或一个Bitmap对象。

因此,您需要创建一个具有正确大小的Bitmap对象进行绘制,并为该位图创建Graphics对象。然后你可以保存它。请记住,对象实施IDisposable应该用using子句配置,例如:

using (Image image = Image.FromFile(AppDomain.CurrentDomain.BaseDirectory + "Cropper/tests/castle.jpg")) { 

    // Create bitmap 
    using (Bitmap newImage = new Bitmap(200, 120)) { 

     // Crop and resize the image. 
     Rectangle destination = new Rectangle(0, 0, 200, 120); 
     using (Graphics graphic = Graphics.FromImage(newImage)) { 
     graphic.DrawImage(image, destination, int.Parse(X1.Value), int.Parse(Y1.Value), int.Parse(Width.Value), int.Parse(Height.Value), GraphicsUnit.Pixel); 
     } 
     newImage.Save(AppDomain.CurrentDomain.BaseDirectory + "Cropper/tests/castle_icon.jpg", ImageFormat.Jpeg); 
    } 
} 
1

这不是一个直接的答案OP的问题,但它是一个经常被忽视的工具,它可以让你接近的东西一个不同的方式,如果证明是必要的。

人们经常说,无法获取Graphics对象的内容。这根本不是真的。使用正确的方法,您可以使用HDC和BitBlt在画布上访问数据。以下是使用C#执行此操作的一种方法:

enum TernaryRasterOperations : uint 
    { 
     /// <summary>dest = source</summary> 
     SRCCOPY = 0x00CC0020, 
     /// <summary>dest = source OR dest</summary> 
     SRCPAINT = 0x00EE0086, 
     /// <summary>dest = source AND dest</summary> 
     SRCAND = 0x008800C6, 
     /// <summary>dest = source XOR dest</summary> 
     SRCINVERT = 0x00660046, 
     /// <summary>dest = source AND (NOT dest)</summary> 
     SRCERASE = 0x00440328, 
     /// <summary>dest = (NOT source)</summary> 
     NOTSRCCOPY = 0x00330008, 
     /// <summary>dest = (NOT src) AND (NOT dest)</summary> 
     NOTSRCERASE = 0x001100A6, 
     /// <summary>dest = (source AND pattern)</summary> 
     MERGECOPY = 0x00C000CA, 
     /// <summary>dest = (NOT source) OR dest</summary> 
     MERGEPAINT = 0x00BB0226, 
     /// <summary>dest = pattern</summary> 
     PATCOPY = 0x00F00021, 
     /// <summary>dest = DPSnoo</summary> 
     PATPAINT = 0x00FB0A09, 
     /// <summary>dest = pattern XOR dest</summary> 
     PATINVERT = 0x005A0049, 
     /// <summary>dest = (NOT dest)</summary> 
     DSTINVERT = 0x00550009, 
     /// <summary>dest = BLACK</summary> 
     BLACKNESS = 0x00000042, 
     /// <summary>dest = WHITE</summary> 
     WHITENESS = 0x00FF0062, 
     /// <summary> 
     /// Capture window as seen on screen. This includes layered windows 
     /// such as WPF windows with AllowsTransparency="true" 
     /// </summary> 
     CAPTUREBLT = 0x40000000 
    } 

    [DllImport("gdi32.dll", EntryPoint = "BitBlt", SetLastError = true)] 
    [return: MarshalAs(UnmanagedType.Bool)] 
    static extern bool BitBlt([In] IntPtr hdc, int nXDest, int nYDest, int nWidth, int nHeight, [In] IntPtr hdcSrc, int nXSrc, int nYSrc, TernaryRasterOperations dwRop); 

    public static Bitmap CopyGraphicsContent(Graphics source, Rectangle rect) 
    { 
     Bitmap bmp = new Bitmap(rect.Width, rect.Height); 

     using (Graphics dest = Graphics.FromImage(bmp)) 
     { 
      IntPtr hdcSource = source.GetHdc(); 
      IntPtr hdcDest = dest.GetHdc(); 

      BitBlt(hdcDest, 0, 0, rect.Width, rect.Height, hdcSource, rect.X, rect.Y, TernaryRasterOperations.SRCCOPY); 

      source.ReleaseHdc(hdcSource); 
      dest.ReleaseHdc(hdcDest); 
     } 

     return bmp; 
    } 
+2

是否回答此问题?请解释如何回答这个问题 – CocoNess 2018-01-24 13:09:29